mirror of
https://github.com/hykilpikonna/hyfetch.git
synced 2026-03-21 17:24:51 -05:00
Merge 20fa7b0e16 into 352a1ba086
This commit is contained in:
commit
78039b1965
35
Cargo.lock
generated
35
Cargo.lock
generated
|
|
@ -115,8 +115,11 @@ dependencies = [
|
|||
"bitflags",
|
||||
"crossterm_winapi",
|
||||
"document-features",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"rustix",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
|
|
@ -411,6 +414,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
|
@ -703,6 +707,37 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-mio"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
|
||||
dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.1"
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ ansi_colours = { workspace = true, features = [] }
|
|||
anstream = { workspace = true, features = [], optional = true }
|
||||
anyhow = { workspace = true, features = ["std"] }
|
||||
bpaf = { workspace = true, features = [] }
|
||||
crossterm = { workspace = true, features = [] }
|
||||
crossterm = { workspace = true, features = ["events"] }
|
||||
deranged = { workspace = true, features = ["serde", "std"] }
|
||||
directories = { workspace = true, features = [] }
|
||||
enterpolation = { workspace = true, features = ["bspline", "std"] }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::borrow::Cow;
|
|||
use std::cmp;
|
||||
use std::fmt::Write as _;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{self, IsTerminal as _, Read as _};
|
||||
use std::io::{self, IsTerminal as _, Read as _, Write};
|
||||
use std::iter;
|
||||
use std::iter::zip;
|
||||
use std::num::NonZeroU8;
|
||||
|
|
@ -10,6 +10,8 @@ use std::path::{Path, PathBuf};
|
|||
|
||||
use aho_corasick::AhoCorasick;
|
||||
use anyhow::{Context as _, Result};
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind, KeyModifiers};
|
||||
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
|
||||
use deranged::RangedU8;
|
||||
use enterpolation::bspline::BSpline;
|
||||
use enterpolation::{Curve as _, Generator as _};
|
||||
|
|
@ -453,6 +455,40 @@ fn create_config(
|
|||
//////////////////////////////
|
||||
// 3. Choose preset
|
||||
|
||||
struct RawModeGuard {
|
||||
enabled: bool,
|
||||
}
|
||||
|
||||
impl RawModeGuard {
|
||||
fn new() -> Result<Self> {
|
||||
Ok(Self { enabled: false })
|
||||
}
|
||||
|
||||
fn enable(&mut self) -> Result<()> {
|
||||
if !self.enabled {
|
||||
enable_raw_mode().context("failed to enable terminal raw mode")?;
|
||||
self.enabled = true;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn disable(&mut self) -> Result<()> {
|
||||
if self.enabled {
|
||||
disable_raw_mode().context("failed to disable terminal raw mode")?;
|
||||
self.enabled = false;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for RawModeGuard {
|
||||
fn drop(&mut self) {
|
||||
if self.enabled {
|
||||
let _ = disable_raw_mode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create flag lines
|
||||
let mut flags = Vec::with_capacity(Preset::COUNT);
|
||||
let spacing = {
|
||||
|
|
@ -479,7 +515,11 @@ fn create_config(
|
|||
name = preset.as_ref(),
|
||||
spacing = usize::from(spacing)
|
||||
);
|
||||
flags.push([name, flag.clone(), flag.clone(), flag]);
|
||||
flags.push((
|
||||
preset.clone(),
|
||||
[name, flag.clone(), flag.clone(), flag],
|
||||
preset.as_ref().to_ascii_lowercase(),
|
||||
));
|
||||
}
|
||||
|
||||
// Calculate flags per row
|
||||
|
|
@ -489,34 +529,28 @@ fn create_config(
|
|||
let rows_per_page = (term_h.saturating_sub(13) / 5).clamp(1, u8::MAX.into()) as u8;
|
||||
(flags_per_row, rows_per_page)
|
||||
};
|
||||
let num_pages = (Preset::COUNT.div_ceil(flags_per_row as usize * rows_per_page as usize)).clamp(0, u8::MAX.into()) as u8;
|
||||
let flags_per_page = usize::from(flags_per_row) * usize::from(rows_per_page);
|
||||
|
||||
// Create pages
|
||||
let mut pages = Vec::with_capacity(usize::from(num_pages));
|
||||
for flags in flags.chunks(usize::from(
|
||||
u16::from(flags_per_row)
|
||||
.checked_mul(u16::from(rows_per_page))
|
||||
.unwrap(),
|
||||
)) {
|
||||
let mut page = Vec::with_capacity(usize::from(rows_per_page));
|
||||
for flags in flags.chunks(usize::from(flags_per_row)) {
|
||||
page.push(flags);
|
||||
fn filter_flag_indices(query: &str, flags: &[(Preset, [String; 4], String)]) -> Vec<usize> {
|
||||
if query.is_empty() {
|
||||
return (0..flags.len()).collect();
|
||||
}
|
||||
pages.push(page);
|
||||
|
||||
let mut matched = flags
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(idx, (_, _, preset_name))| {
|
||||
let position = preset_name.find(query)?;
|
||||
Some((idx, preset_name.starts_with(query), position))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Prefix matches are shown first, then other substring matches ordered by earliest index.
|
||||
matched.sort_by_key(|&(idx, is_prefix, position)| (!is_prefix, position, idx));
|
||||
matched.into_iter().map(|(idx, _, _)| idx).collect()
|
||||
}
|
||||
|
||||
let print_flag_page = |page, page_num: u8| -> Result<()> {
|
||||
clear_screen(Some(&title), color_mode, debug_mode).context("failed to clear screen")?;
|
||||
print_title_prompt(option_counter, "Let's choose a flag!");
|
||||
println!("Available flag presets:\nPage: {page_num} of {num_pages}\n", page_num = page_num + 1);
|
||||
for &row in page {
|
||||
print_flag_row(row, color_mode).context("failed to print flag row")?;
|
||||
}
|
||||
println!();
|
||||
Ok(())
|
||||
};
|
||||
|
||||
fn print_flag_row(row: &[[String; 4]], color_mode: AnsiMode) -> Result<()> {
|
||||
fn print_flag_row(row: &[&[String; 4]], color_mode: AnsiMode) -> Result<()> {
|
||||
for i in 0..4 {
|
||||
let mut line = Vec::new();
|
||||
for flag in row {
|
||||
|
|
@ -539,32 +573,138 @@ fn create_config(
|
|||
)
|
||||
.expect("coloring text with default preset should not fail");
|
||||
|
||||
let print_flag_page = |filtered_indices: &[usize],
|
||||
page_num: usize,
|
||||
filter: &str,
|
||||
hint: Option<&str>|
|
||||
-> Result<()> {
|
||||
let num_pages = filtered_indices.len().div_ceil(flags_per_page).max(1);
|
||||
clear_screen(Some(&title), color_mode, debug_mode).context("failed to clear screen")?;
|
||||
print_title_prompt(option_counter, "Let's choose a flag!");
|
||||
println!(
|
||||
"Available flag presets:\nPage: {page} of {num_pages}\n",
|
||||
page = page_num + 1
|
||||
);
|
||||
|
||||
let start = page_num * flags_per_page;
|
||||
let end = (start + flags_per_page).min(filtered_indices.len());
|
||||
let mut visible_rows: usize = 0;
|
||||
if start >= end {
|
||||
println!("No presets matched this filter.\n");
|
||||
} else {
|
||||
for row in filtered_indices[start..end].chunks(usize::from(flags_per_row)) {
|
||||
let row = row
|
||||
.iter()
|
||||
.map(|&idx| &flags[idx].1)
|
||||
.collect::<Vec<&[String; 4]>>();
|
||||
print_flag_row(&row, color_mode).context("failed to print flag row")?;
|
||||
visible_rows += 1;
|
||||
}
|
||||
println!();
|
||||
}
|
||||
// Keep the prompt anchored by reserving a full page worth of flag rows.
|
||||
for _ in visible_rows..usize::from(rows_per_page) {
|
||||
for _ in 0..5 {
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
||||
println!(
|
||||
"Use arrow keys to go to the previous/next page. Type to filter and press Enter to select."
|
||||
);
|
||||
printc(
|
||||
format!(
|
||||
"Which {preset_default_colored} do you want to use? (default: {})",
|
||||
Preset::Rainbow.as_ref()
|
||||
),
|
||||
color_mode,
|
||||
)
|
||||
.context("failed to print preset prompt")?;
|
||||
print!("> {filter}");
|
||||
io::stdout().flush().context("failed to flush preset prompt")?;
|
||||
|
||||
if let Some(hint) = hint {
|
||||
println!("{hint}");
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let preset: Preset;
|
||||
let color_profile;
|
||||
|
||||
let mut page: u8 = 0;
|
||||
let mut page: usize = 0;
|
||||
let mut filter = String::new();
|
||||
let mut hint: Option<&str> = None;
|
||||
let mut raw_mode = RawModeGuard::new().context("failed to initialize raw input mode")?;
|
||||
loop {
|
||||
print_flag_page(&pages[usize::from(page)], page).context("failed to print flag page")?;
|
||||
raw_mode
|
||||
.disable()
|
||||
.context("failed to disable raw mode for rendering")?;
|
||||
let filter_lower = filter.to_ascii_lowercase();
|
||||
let filtered_indices = filter_flag_indices(&filter_lower, &flags);
|
||||
let num_pages = filtered_indices.len().div_ceil(flags_per_page).max(1);
|
||||
page = page.min(num_pages - 1);
|
||||
|
||||
let mut opts: Vec<&str> = <Preset as VariantNames>::VARIANTS.into();
|
||||
opts.extend(["next", "n", "prev", "p"]);
|
||||
print_flag_page(&filtered_indices, page, &filter, hint)
|
||||
.context("failed to print flag page")?;
|
||||
hint = None;
|
||||
|
||||
println!("Enter '[n]ext' to go to the next page and '[p]rev' to go to the previous page.");
|
||||
let selection = literal_input(
|
||||
format!("Which {preset_default_colored} do you want to use? "),
|
||||
&opts[..],
|
||||
Preset::Rainbow.as_ref(),
|
||||
false,
|
||||
color_mode,
|
||||
)
|
||||
.context("failed to ask for choice input")
|
||||
.context("failed to select preset")?;
|
||||
if selection == "next" || selection == "n" {
|
||||
page = (page + 1) % num_pages;
|
||||
} else if selection == "prev" || selection == "p" {
|
||||
raw_mode
|
||||
.enable()
|
||||
.context("failed to enable raw mode for key input")?;
|
||||
let event = event::read().context("failed to read keyboard event")?;
|
||||
let Event::Key(key) = event else {
|
||||
continue;
|
||||
};
|
||||
if !matches!(key.kind, KeyEventKind::Press | KeyEventKind::Repeat) {
|
||||
continue;
|
||||
}
|
||||
|
||||
match key.code {
|
||||
KeyCode::Enter => {
|
||||
let selection = flags
|
||||
.iter()
|
||||
.find(|(_, _, name)| *name == filter_lower)
|
||||
.map(|(preset, _, _)| *preset)
|
||||
.or_else(|| filtered_indices.first().map(|&idx| flags[idx].0));
|
||||
preset = selection.unwrap_or(Preset::Rainbow);
|
||||
break;
|
||||
},
|
||||
KeyCode::Left | KeyCode::Up => {
|
||||
page = (page + num_pages - 1) % num_pages;
|
||||
} else {
|
||||
preset = selection.parse().expect("selected preset should be valid");
|
||||
},
|
||||
KeyCode::Right | KeyCode::Down => {
|
||||
page = (page + 1) % num_pages;
|
||||
},
|
||||
KeyCode::Backspace => {
|
||||
filter.pop();
|
||||
page = 0;
|
||||
},
|
||||
KeyCode::Esc => {
|
||||
filter.clear();
|
||||
page = 0;
|
||||
},
|
||||
KeyCode::Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
raw_mode
|
||||
.disable()
|
||||
.context("failed to disable raw mode before interrupting")?;
|
||||
println!();
|
||||
return Err(anyhow::anyhow!("interrupted by user"));
|
||||
},
|
||||
KeyCode::Char(c)
|
||||
if !key.modifiers.contains(KeyModifiers::CONTROL)
|
||||
&& !key.modifiers.contains(KeyModifiers::ALT) =>
|
||||
{
|
||||
filter.push(c);
|
||||
page = 0;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
raw_mode
|
||||
.disable()
|
||||
.context("failed to disable raw mode after preset selection")?;
|
||||
|
||||
debug!(?preset, "selected preset");
|
||||
color_profile = preset.color_profile();
|
||||
update_title(
|
||||
|
|
@ -581,9 +721,14 @@ fn create_config(
|
|||
)
|
||||
.expect("coloring text with selected preset should not fail"),
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
printc(
|
||||
format!(
|
||||
"Which {preset_default_colored} do you want to use? {}\n",
|
||||
preset.as_ref()
|
||||
),
|
||||
color_mode,
|
||||
)
|
||||
.context("failed to print preset selection summary")?;
|
||||
|
||||
//////////////////////////////
|
||||
// 4. Dim/lighten colors
|
||||
|
|
|
|||
182
hyfetch/main.py
182
hyfetch/main.py
|
|
@ -7,6 +7,7 @@ import importlib.util
|
|||
import json
|
||||
import os
|
||||
import random
|
||||
import sys
|
||||
import traceback
|
||||
from itertools import permutations, islice
|
||||
from math import ceil
|
||||
|
|
@ -126,62 +127,169 @@ def create_config() -> Config:
|
|||
##############################
|
||||
# 3. Choose preset
|
||||
# Create flags = [[lines]]
|
||||
flags = []
|
||||
flag_entries = []
|
||||
spacing = max(max(len(k) for k in PRESETS.keys()), 20)
|
||||
for name, preset in PRESETS.items():
|
||||
flag = preset.color_text(' ' * spacing, foreground=False)
|
||||
flags.append([name.center(spacing), flag, flag, flag])
|
||||
flag_entries.append((name, [name.center(spacing), flag, flag, flag], name.lower()))
|
||||
|
||||
# Calculate flags per row
|
||||
flags_per_row = term_size()[0] // (spacing + 2)
|
||||
flags_per_row = max(1, term_size()[0] // (spacing + 2))
|
||||
row_per_page = max(1, (term_size()[1] - 13) // 5)
|
||||
num_pages = ceil(len(flags) / (flags_per_row * row_per_page))
|
||||
flags_per_page = flags_per_row * row_per_page
|
||||
|
||||
# Create pages
|
||||
pages = []
|
||||
for i in range(num_pages):
|
||||
page = []
|
||||
for j in range(row_per_page):
|
||||
page.append(flags[:flags_per_row])
|
||||
flags = flags[flags_per_row:]
|
||||
if not flags:
|
||||
break
|
||||
pages.append(page)
|
||||
def filter_flag_indices(query: str) -> list[int]:
|
||||
if not query:
|
||||
return list(range(len(flag_entries)))
|
||||
|
||||
def print_flag_page(page: list[list[list[str]]], page_num: int):
|
||||
matched = []
|
||||
for idx, (_, _, lower_name) in enumerate(flag_entries):
|
||||
pos = lower_name.find(query)
|
||||
if pos == -1:
|
||||
continue
|
||||
matched.append((0 if lower_name.startswith(query) else 1, pos, idx))
|
||||
matched.sort()
|
||||
return [idx for _, _, idx in matched]
|
||||
|
||||
def print_flag_page(filtered_indices: list[int], page_num: int, text_filter: str, hint: str | None):
|
||||
num_pages = max(1, ceil(len(filtered_indices) / flags_per_page))
|
||||
clear_screen(title)
|
||||
print_title_prompt("Let's choose a flag!")
|
||||
printc('Available flag presets:')
|
||||
print(f'Page: {page_num + 1} of {num_pages}')
|
||||
print()
|
||||
for i in page:
|
||||
print_flag_row(i)
|
||||
print()
|
||||
|
||||
start = page_num * flags_per_page
|
||||
end = min(start + flags_per_page, len(filtered_indices))
|
||||
|
||||
if start >= end:
|
||||
print('No presets matched this filter.')
|
||||
print()
|
||||
else:
|
||||
current = filtered_indices[start:end]
|
||||
for i in range(0, len(current), flags_per_row):
|
||||
row = [flag_entries[idx][1] for idx in current[i:i + flags_per_row]]
|
||||
print_flag_row(row)
|
||||
print()
|
||||
|
||||
tmp = PRESETS['rainbow'].set_light_dl_def(light_dark).color_text('preset')
|
||||
print('Use arrow keys to go to the previous/next page. Type to filter and press Enter to select.')
|
||||
printc(f'Which {tmp} do you want to use? (default: rainbow)')
|
||||
print(f'> {text_filter}', end='', flush=True)
|
||||
if hint:
|
||||
print(f'\n{hint}', end='')
|
||||
|
||||
def print_flag_row(current: list[list[str]]):
|
||||
[printc(' '.join(line)) for line in zip(*current)]
|
||||
print()
|
||||
|
||||
page = 0
|
||||
while True:
|
||||
print_flag_page(pages[page], page)
|
||||
def select_preset_prompt_toolkit() -> str:
|
||||
from prompt_toolkit import PromptSession
|
||||
from prompt_toolkit.application.current import get_app
|
||||
from prompt_toolkit.formatted_text import ANSI
|
||||
from prompt_toolkit.key_binding import KeyBindings
|
||||
|
||||
tmp = PRESETS['rainbow'].set_light_dl_def(light_dark).color_text('preset')
|
||||
opts = list(PRESETS.keys())
|
||||
if page < num_pages - 1:
|
||||
opts.append('next')
|
||||
if page > 0:
|
||||
opts.append('prev')
|
||||
print("Enter 'next' to go to the next page and 'prev' to go to the previous page.")
|
||||
preset = literal_input(f'Which {tmp} do you want to use? ', opts, 'rainbow', show_ops=False)
|
||||
if preset == 'next':
|
||||
page += 1
|
||||
elif preset == 'prev':
|
||||
page -= 1
|
||||
else:
|
||||
_prs = PRESETS[preset]
|
||||
update_title('Selected flag', _prs.set_light_dl_def(light_dark).color_text(preset))
|
||||
break
|
||||
page_num = 0
|
||||
prompt_header = PRESETS['rainbow'].set_light_dl_def(light_dark).color_text('preset')
|
||||
kb = KeyBindings()
|
||||
last_filter = ''
|
||||
|
||||
def current_num_pages() -> int:
|
||||
text = get_app().current_buffer.text.lower().strip()
|
||||
indices = filter_flag_indices(text)
|
||||
return max(1, ceil(len(indices) / flags_per_page))
|
||||
|
||||
@kb.add('left')
|
||||
@kb.add('up')
|
||||
def _prev_page(event):
|
||||
nonlocal page_num
|
||||
page_num = (page_num + current_num_pages() - 1) % current_num_pages()
|
||||
event.app.invalidate()
|
||||
|
||||
@kb.add('right')
|
||||
@kb.add('down')
|
||||
def _next_page(event):
|
||||
nonlocal page_num
|
||||
page_num = (page_num + 1) % current_num_pages()
|
||||
event.app.invalidate()
|
||||
|
||||
@kb.add('escape')
|
||||
def _clear_filter(event):
|
||||
nonlocal page_num
|
||||
event.current_buffer.text = ''
|
||||
event.current_buffer.cursor_position = 0
|
||||
page_num = 0
|
||||
event.app.invalidate()
|
||||
|
||||
def build_preset_lines(text_filter: str):
|
||||
nonlocal page_num
|
||||
filtered_indices = filter_flag_indices(text_filter.lower().strip())
|
||||
num_pages = max(1, ceil(len(filtered_indices) / flags_per_page))
|
||||
page_num = min(page_num, num_pages - 1)
|
||||
|
||||
lines = [
|
||||
color(f"&a{option_counter}. Let's choose a flag!&r"),
|
||||
"Available flag presets:",
|
||||
f"Page: {page_num + 1} of {num_pages}",
|
||||
"",
|
||||
]
|
||||
|
||||
start = page_num * flags_per_page
|
||||
end = min(start + flags_per_page, len(filtered_indices))
|
||||
visible_row_count = 0
|
||||
if start >= end:
|
||||
lines.append("No presets matched this filter.")
|
||||
lines.append("")
|
||||
visible_row_count = 0
|
||||
else:
|
||||
current = filtered_indices[start:end]
|
||||
for i in range(0, len(current), flags_per_row):
|
||||
row = [flag_entries[idx][1] for idx in current[i:i + flags_per_row]]
|
||||
lines.extend(' '.join(line) for line in zip(*row))
|
||||
lines.append("")
|
||||
visible_row_count += 1
|
||||
|
||||
# Keep prompt at a fixed vertical position by padding to a full page height.
|
||||
missing_rows = max(0, row_per_page - visible_row_count)
|
||||
lines.extend([""] * (missing_rows * 5))
|
||||
|
||||
lines.append(
|
||||
"Use arrow keys to go to the previous/next page. Type to filter and press Enter to select."
|
||||
)
|
||||
lines.append(f"Which {prompt_header} do you want to use? (default: rainbow)")
|
||||
return lines
|
||||
|
||||
def prompt_message():
|
||||
nonlocal last_filter
|
||||
app = get_app()
|
||||
text_filter = app.current_buffer.text
|
||||
last_filter = text_filter
|
||||
|
||||
lines = build_preset_lines(text_filter)
|
||||
return ANSI('\n'.join(lines) + '\n> ')
|
||||
|
||||
clear_screen(title)
|
||||
session = PromptSession(key_bindings=kb)
|
||||
try:
|
||||
selection = session.prompt(prompt_message).strip().lower()
|
||||
except KeyboardInterrupt:
|
||||
clear_screen(title)
|
||||
for line in build_preset_lines(last_filter):
|
||||
print(line)
|
||||
print(f"> {last_filter}")
|
||||
raise
|
||||
|
||||
filtered_indices = filter_flag_indices(selection)
|
||||
if selection in PRESETS:
|
||||
return selection
|
||||
if filtered_indices:
|
||||
return flag_entries[filtered_indices[0]][0]
|
||||
return 'rainbow'
|
||||
|
||||
preset = select_preset_prompt_toolkit()
|
||||
|
||||
_prs = PRESETS[preset]
|
||||
update_title('Selected flag', _prs.set_light_dl_def(light_dark).color_text(preset))
|
||||
|
||||
#############################
|
||||
# 4. Dim/lighten colors
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ classifiers = [
|
|||
dependencies = [
|
||||
# Universal dependencies
|
||||
'typing_extensions; python_version < "3.8"',
|
||||
'prompt_toolkit>=3.0.36',
|
||||
|
||||
# Windows dependencies
|
||||
'psutil ; platform_system=="Windows"',
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user