linux-qubasis
linux oasis port as a qubes template
git clone https://9o.is/git/linux-qubasis.git
commit 7bff9c20503b9b04d346be8b295e4f0e0e9475c8 parent 1363433159926b3a8467f25b8915ce03c59182f2 Author: Jul <jul@9o.is> Date: Wed, 6 Aug 2025 06:00:00 -0400 final fzy patches cleanup Diffstat:
| M | pkg/fzy/config.h | | | 1 | - |
| D | pkg/fzy/patches/0001-add-carriage-return-to-tty_clearline.patch | | | 25 | ------------------------- |
| A | pkg/fzy/patches/0001-fix-clearline-issues-for-use-in-editor.patch | | | 46 | ++++++++++++++++++++++++++++++++++++++++++++++ |
| D | pkg/fzy/patches/0002-Reduce-screen-and-cursor-flickering.patch | | | 95 | ------------------------------------------------------------------------------- |
| A | pkg/fzy/patches/0002-center-scrolling.patch | | | 55 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| D | pkg/fzy/patches/0003-add-multi-selection.patch | | | 271 | ------------------------------------------------------------------------------- |
| A | pkg/fzy/patches/0003-truncate-lines-to-terminal-width.patch | | | 27 | +++++++++++++++++++++++++++ |
| A | pkg/fzy/patches/0004-add-halfpage-up-down-vi-bindings.patch | | | 49 | +++++++++++++++++++++++++++++++++++++++++++++++++ |
| D | pkg/fzy/patches/0004-truncate-entries-to-terminal-width.patch | | | 27 | --------------------------- |
| D | pkg/fzy/patches/0005-add-half-page-up-down-vi-actions.patch | | | 66 | ------------------------------------------------------------------ |
| A | pkg/fzy/patches/0005-inline-info.patch | | | 37 | +++++++++++++++++++++++++++++++++++++ |
| A | pkg/fzy/patches/0006-add-partial-multi-selection.patch | | | 261 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| D | pkg/fzy/patches/0006-inline-info-data.patch | | | 52 | ---------------------------------------------------- |
13 files changed, 475 insertions(+), 537 deletions(-)
diff --git a/pkg/fzy/config.h b/pkg/fzy/config.h @@ -21,7 +21,6 @@ extern "C" { #define DEFAULT_NUM_LINES 25 #define DEFAULT_WORKERS 0 #define DEFAULT_SHOW_INFO 1 -#define DEFAULT_MULTI 1 #ifdef __cplusplus } diff --git a/pkg/fzy/patches/0001-add-carriage-return-to-tty_clearline.patch b/pkg/fzy/patches/0001-add-carriage-return-to-tty_clearline.patch @@ -1,25 +0,0 @@ -From 7cd948b993f9ad5a9dfe69ed023c2091f79e93dc Mon Sep 17 00:00:00 2001 -From: Jul <jul@qh.is> -Date: Thu, 31 Jul 2025 00:13:39 -0400 -Subject: [PATCH 1/6] add carriage return to tty_clearline - ---- - src/tty.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/tty.c b/src/tty.c -index b8a555d..a8f0826 100644 ---- a/src/tty.c -+++ b/src/tty.c -@@ -165,7 +165,7 @@ void tty_newline(tty_t *tty) { - } - - void tty_clearline(tty_t *tty) { -- tty_printf(tty, "%c%cK", 0x1b, '['); -+ tty_printf(tty, "%c%cK\r", 0x1b, '['); - } - - void tty_setcol(tty_t *tty, int col) { --- -2.50.1 - diff --git a/pkg/fzy/patches/0001-fix-clearline-issues-for-use-in-editor.patch b/pkg/fzy/patches/0001-fix-clearline-issues-for-use-in-editor.patch @@ -0,0 +1,46 @@ +From 15e99555ab310f4c6d776fb305dd4050ea9939ff Mon Sep 17 00:00:00 2001 +From: Jul <jul@qh.is> +Date: Tue, 5 Aug 2025 02:37:51 -0400 +Subject: [PATCH 1/6] fix clearline issues for use in editor + +--- + src/tty.c | 2 +- + src/tty_interface.c | 5 +++-- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/tty.c b/src/tty.c +index b8a555d..bc20c0a 100644 +--- a/src/tty.c ++++ b/src/tty.c +@@ -165,7 +165,7 @@ void tty_newline(tty_t *tty) { + } + + void tty_clearline(tty_t *tty) { +- tty_printf(tty, "%c%cK", 0x1b, '['); ++ tty_printf(tty, "%c%c2K\r", 0x1b, '['); + } + + void tty_setcol(tty_t *tty, int col) { +diff --git a/src/tty_interface.c b/src/tty_interface.c +index 343dde8..59c9c74 100644 +--- a/src/tty_interface.c ++++ b/src/tty_interface.c +@@ -92,12 +92,13 @@ static void draw(tty_interface_t *state) { + } + + tty_setcol(tty, 0); +- tty_printf(tty, "%s%s", options->prompt, state->search); + tty_clearline(tty); ++ tty_printf(tty, "%s%s", options->prompt, state->search); + + if (options->show_info) { +- tty_printf(tty, "\n[%lu/%lu]", choices->available, choices->size); ++ tty_printf(tty, "\n"); + tty_clearline(tty); ++ tty_printf(tty, "[%lu/%lu]", choices->available, choices->size); + } + + for (size_t i = start; i < start + num_lines; i++) { +-- +2.50.1 + diff --git a/pkg/fzy/patches/0002-Reduce-screen-and-cursor-flickering.patch b/pkg/fzy/patches/0002-Reduce-screen-and-cursor-flickering.patch @@ -1,95 +0,0 @@ -From 4a167fd5abf1ff1abd4a8234624290edfa05e0e9 Mon Sep 17 00:00:00 2001 -From: leo-arch <leonardoabramovich2@gmail.com> -Date: Fri, 18 Jul 2025 21:39:07 -0300 -Subject: [PATCH 2/6] Reduce screen and cursor flickering - ---- - src/tty.c | 8 ++++++++ - src/tty.h | 3 +++ - src/tty_interface.c | 14 +++++++++++--- - 3 files changed, 22 insertions(+), 3 deletions(-) - -diff --git a/src/tty.c b/src/tty.c -index a8f0826..ae4e000 100644 ---- a/src/tty.c -+++ b/src/tty.c -@@ -198,3 +198,11 @@ size_t tty_getwidth(tty_t *tty) { - size_t tty_getheight(tty_t *tty) { - return tty->maxheight; - } -+ -+void tty_hide_cursor(tty_t *tty) { -+ fputs("\x1b[?25l", tty->fout); -+} -+ -+void tty_unhide_cursor(tty_t *tty) { -+ fputs("\x1b[?25h", tty->fout); -+} -diff --git a/src/tty.h b/src/tty.h -index 210f690..3c54f1d 100644 ---- a/src/tty.h -+++ b/src/tty.h -@@ -63,6 +63,9 @@ void tty_flush(tty_t *tty); - size_t tty_getwidth(tty_t *tty); - size_t tty_getheight(tty_t *tty); - -+void tty_hide_cursor(tty_t *tty); -+void tty_unhide_cursor(tty_t *tty); -+ - #ifdef __cplusplus - } - #endif -diff --git a/src/tty_interface.c b/src/tty_interface.c -index 343dde8..6828be8 100644 ---- a/src/tty_interface.c -+++ b/src/tty_interface.c -@@ -91,6 +91,7 @@ static void draw(tty_interface_t *state) { - } - } - -+ tty_hide_cursor(tty); - tty_setcol(tty, 0); - tty_printf(tty, "%s%s", options->prompt, state->search); - tty_clearline(tty); -@@ -116,6 +117,8 @@ static void draw(tty_interface_t *state) { - fputs(options->prompt, tty->fout); - for (size_t i = 0; i < state->cursor; i++) - fputc(state->search[i], tty->fout); -+ -+ tty_unhide_cursor(tty); - tty_flush(tty); - } - -@@ -353,14 +356,16 @@ static void handle_input(tty_interface_t *state, const char *s, int handle_ambig - - /* We could have a complete keybinding, or could be in the middle of one. - * We'll need to wait a few milliseconds to find out. */ -- if (found_keybinding != -1 && in_middle) { -+/* if (found_keybinding != -1 && in_middle) { - state->ambiguous_key_pending = 1; - return; -- } -+ } */ - - /* Wait for more if we are in the middle of a keybinding */ -- if (in_middle) -+ if (in_middle) { -+ state->ambiguous_key_pending = 1; - return; -+ } - - /* No matching keybinding, add to search */ - for (int i = 0; input[i]; i++) -@@ -384,6 +389,9 @@ int tty_interface_run(tty_interface_t *state) { - char s[2] = {tty_getchar(state->tty), '\0'}; - handle_input(state, s, 0); - -+ if (state->ambiguous_key_pending == 1) -+ continue; -+ - if (state->exit >= 0) - return state->exit; - --- -2.50.1 - diff --git a/pkg/fzy/patches/0002-center-scrolling.patch b/pkg/fzy/patches/0002-center-scrolling.patch @@ -0,0 +1,55 @@ +From 950782fb37e0dba49f28349fdbd93acb58f91da8 Mon Sep 17 00:00:00 2001 +From: Jul <jul@qh.is> +Date: Tue, 5 Aug 2025 02:50:21 -0400 +Subject: [PATCH 2/6] center scrolling + +--- + src/options.c | 1 - + src/options.h | 1 - + src/tty_interface.c | 5 +++-- + 3 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/options.c b/src/options.c +index 485fc98..5fd9d2a 100644 +--- a/src/options.c ++++ b/src/options.c +@@ -47,7 +47,6 @@ void options_init(options_t *options) { + options->filter = NULL; + options->init_search = NULL; + options->show_scores = 0; +- options->scrolloff = 1; + options->tty_filename = DEFAULT_TTY; + options->num_lines = DEFAULT_NUM_LINES; + options->prompt = DEFAULT_PROMPT; +diff --git a/src/options.h b/src/options.h +index 1a0886e..bfc3fa4 100644 +--- a/src/options.h ++++ b/src/options.h +@@ -12,7 +12,6 @@ typedef struct { + const char *tty_filename; + int show_scores; + unsigned int num_lines; +- unsigned int scrolloff; + const char *prompt; + unsigned int workers; + char input_delimiter; +diff --git a/src/tty_interface.c b/src/tty_interface.c +index 59c9c74..02c26a0 100644 +--- a/src/tty_interface.c ++++ b/src/tty_interface.c +@@ -82,9 +82,10 @@ static void draw(tty_interface_t *state) { + + unsigned int num_lines = options->num_lines; + size_t start = 0; ++ size_t scroll_threshold = (num_lines / 2) + 1; + size_t current_selection = choices->selection; +- if (current_selection + options->scrolloff >= num_lines) { +- start = current_selection + options->scrolloff - num_lines + 1; ++ if (current_selection >= scroll_threshold) { ++ start = current_selection - scroll_threshold + 1; + size_t available = choices_available(choices); + if (start + num_lines >= available && available > 0) { + start = available - num_lines; +-- +2.50.1 + diff --git a/pkg/fzy/patches/0003-add-multi-selection.patch b/pkg/fzy/patches/0003-add-multi-selection.patch @@ -1,271 +0,0 @@ -From 4ce0a1d7d2c98f5f1d02aad2a26207fa2c7fb296 Mon Sep 17 00:00:00 2001 -From: Jul <jul@qh.is> -Date: Thu, 31 Jul 2025 03:34:16 -0400 -Subject: [PATCH 3/6] add multi-selection - ---- - src/config.def.h | 1 + - src/tty_interface.c | 167 ++++++++++++++++++++++++++++++++++++++++++-- - 2 files changed, 162 insertions(+), 6 deletions(-) - -diff --git a/src/config.def.h b/src/config.def.h -index 00d3740..27a83ce 100644 ---- a/src/config.def.h -+++ b/src/config.def.h -@@ -21,6 +21,7 @@ extern "C" { - #define DEFAULT_NUM_LINES 10 - #define DEFAULT_WORKERS 0 - #define DEFAULT_SHOW_INFO 0 -+#define DEFAULT_MULTI 0 - - #ifdef __cplusplus - } -diff --git a/src/tty_interface.c b/src/tty_interface.c -index 6828be8..ee36845 100644 ---- a/src/tty_interface.c -+++ b/src/tty_interface.c -@@ -7,6 +7,126 @@ - #include "tty_interface.h" - #include "../config.h" - -+/* An array numbers to store the index of selected entries (choices) */ -+static size_t *selection_marks = (size_t *)NULL; -+ -+/* -+ * Create a size_t array big enough to hold all availalable choices, -+ * and initialize it to zero -+ */ -+static void -+init_selection_marks(tty_interface_t *state) -+{ -+ if (DEFAULT_MULTI == 0) { -+ return; -+ } -+ -+ selection_marks = (size_t *)malloc(state->choices->available * sizeof(size_t)); -+ for (size_t i = 0; i < state->choices->available; i++) { -+ selection_marks[i] = 0; -+ } -+} -+ -+/* Return the amount of selected entries in the list of matches */ -+static size_t -+count_selections(tty_interface_t *state) -+{ -+ size_t c = 0; -+ for (size_t i = 0; i < state->choices->available; i++) { -+ if (selection_marks[i] == 1) { -+ c++; -+ } -+ } -+ -+ return c; -+} -+ -+/* -+ * Store current selected entries into an array to print each of them -+ * at exit. Return this array of strings if success and NULL in case -+ * of error or no selected entries -+ */ -+static char ** -+save_selections(tty_interface_t *state) -+{ -+ size_t i, c = 0; -+ size_t n = count_selections(state); -+ if (n == 0) { -+ return (char **)NULL; -+ } -+ -+ char **s = (char **)malloc((n + 2) * sizeof(char *)); -+ -+ for (i = 0; i < state->choices->available; i++) { -+ if (selection_marks[i] != 1) { -+ continue; -+ } -+ -+ const char *name = choices_get(state->choices, i); -+ if (!name) { -+ continue; -+ } -+ -+ s[c] = (char *)malloc((strlen(name) + 1) * sizeof(char)); -+ strcpy(s[c], name); -+ c++; -+ -+ if (c == n) { -+ break; -+ } -+ } -+ -+ if (c == 0) { -+ free(s); -+ return (char **)NULL; -+ } -+ -+ s[c] = (char *)NULL; -+ return s; -+} -+ -+/* Free the array of selected entries generated by save_selections() */ -+static void -+free_selections(char **s) -+{ -+ size_t i; -+ for (i = 0; s[i]; i++) { -+ free(s[i]); -+ } -+ free(s); -+} -+ -+/* Print the list of selected entries generated by save_selections() */ -+static void -+print_selections(char **s) -+{ -+ size_t i; -+ for (i = 0; s[i]; i++) { -+ printf("%s\n", s[i]); -+ } -+} -+ -+/* Free the size_t array generated by init_selection_marks() */ -+static void -+free_selection_marks() -+{ -+ if (DEFAULT_MULTI == 1) { -+ free(selection_marks); -+ selection_marks = (size_t *)NULL; -+ } -+} -+ -+/* -+ * Set to 1 the index of the current/selected entry in the selection_marks -+ * array. If this entry is already marked/selected, set it to zero -+ */ -+static void -+action_select(tty_interface_t *state) -+{ -+ size_t s = selection_marks[state->choices->selection]; -+ selection_marks[state->choices->selection] = s == 1 ? 0 : 1; -+} -+ - static int isprint_unicode(char c) { - return isprint(c) || c & (1 << 7); - } -@@ -18,7 +138,7 @@ static int is_boundary(char c) { - static void clear(tty_interface_t *state) { - tty_t *tty = state->tty; - -- tty_setcol(tty, 0); -+ tty_setcol(tty, DEFAULT_MULTI ? 2 : 0); - size_t line = 0; - while (line++ < state->options->num_lines + (state->options->show_info ? 1 : 0)) { - tty_newline(tty); -@@ -92,11 +212,16 @@ static void draw(tty_interface_t *state) { - } - - tty_hide_cursor(tty); -- tty_setcol(tty, 0); -+ tty_setcol(tty, 0); -+ tty_clearline(tty); -+ tty_setcol(tty, DEFAULT_MULTI ? 2 : 0); - tty_printf(tty, "%s%s", options->prompt, state->search); - tty_clearline(tty); - -- if (options->show_info) { -+ if (options->show_info && DEFAULT_MULTI) { -+ tty_printf(tty, "\n[%lu/%lu/%lu]", count_selections(state), choices->available, choices->size); -+ tty_clearline(tty); -+ } else if (options->show_info) { - tty_printf(tty, "\n[%lu/%lu]", choices->available, choices->size); - tty_clearline(tty); - } -@@ -106,6 +231,11 @@ static void draw(tty_interface_t *state) { - tty_clearline(tty); - const char *choice = choices_get(choices, i); - if (choice) { -+ if (DEFAULT_MULTI == 1 && selection_marks[i] == 1) { -+ tty_printf(tty, "%*c %s", 1, '*', ""); -+ } else { -+ tty_printf(tty, "%*s", 2, ""); -+ } - draw_match(state, choice, i == choices->selection); - } - } -@@ -113,7 +243,7 @@ static void draw(tty_interface_t *state) { - if (num_lines + options->show_info) - tty_moveup(tty, num_lines + options->show_info); - -- tty_setcol(tty, 0); -+ tty_setcol(tty, DEFAULT_MULTI ? 2 : 0); - fputs(options->prompt, tty->fout); - for (size_t i = 0; i < state->cursor; i++) - fputc(state->search[i], tty->fout); -@@ -137,6 +267,22 @@ static void update_state(tty_interface_t *state) { - static void action_emit(tty_interface_t *state) { - update_state(state); - -+ if (DEFAULT_MULTI == 1) { -+ char **s = save_selections(state); -+ free_selection_marks(); -+ -+ if (s) { -+ clear(state); -+ tty_close(state->tty); -+ -+ print_selections(s); -+ free_selections(s); -+ -+ state->exit = EXIT_SUCCESS; -+ return; -+ } -+ } -+ - /* Reset the tty as close as possible to the previous state */ - clear(state); - -@@ -239,6 +385,10 @@ static void action_pagedown(tty_interface_t *state) { - } - - static void action_autocomplete(tty_interface_t *state) { -+ if (DEFAULT_MULTI == 1) { -+ action_select(state); -+ return; -+ } - update_state(state); - const char *current_selection = choices_get(state->choices, state->choices->selection); - if (current_selection) { -@@ -377,6 +527,7 @@ static void handle_input(tty_interface_t *state, const char *s, int handle_ambig - } - - int tty_interface_run(tty_interface_t *state) { -+ init_selection_marks(state); - draw(state); - - for (;;) { -@@ -392,8 +543,10 @@ int tty_interface_run(tty_interface_t *state) { - if (state->ambiguous_key_pending == 1) - continue; - -- if (state->exit >= 0) -+ if (state->exit >= 0) { -+ free_selection_marks(); - return state->exit; -+ } - - draw(state); - } while (tty_input_ready(state->tty, state->ambiguous_key_pending ? KEYTIMEOUT : 0, 0)); -@@ -402,8 +555,10 @@ int tty_interface_run(tty_interface_t *state) { - char s[1] = ""; - handle_input(state, s, 1); - -- if (state->exit >= 0) -+ if (state->exit >= 0) { -+ free_selection_marks(); - return state->exit; -+ } - } - - update_state(state); --- -2.50.1 - diff --git a/pkg/fzy/patches/0003-truncate-lines-to-terminal-width.patch b/pkg/fzy/patches/0003-truncate-lines-to-terminal-width.patch @@ -0,0 +1,27 @@ +From ebe328796dbf17f2c86d63afa512c73b7c00fba7 Mon Sep 17 00:00:00 2001 +From: Jul <jul@qh.is> +Date: Thu, 31 Jul 2025 05:34:48 -0400 +Subject: [PATCH 3/6] truncate lines to terminal width + +--- + src/tty_interface.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/tty_interface.c b/src/tty_interface.c +index 02c26a0..aed8a21 100644 +--- a/src/tty_interface.c ++++ b/src/tty_interface.c +@@ -59,6 +59,10 @@ static void draw_match(tty_interface_t *state, const char *choice, int selected) + + tty_setnowrap(tty); + for (size_t i = 0, p = 0; choice[i] != '\0'; i++) { ++ if (i >= tty_getwidth(state->tty) - 5) { ++ tty_printf(tty, "..."); ++ break; ++ } + if (positions[p] == i) { + tty_setfg(tty, TTY_COLOR_HIGHLIGHT); + p++; +-- +2.50.1 + diff --git a/pkg/fzy/patches/0004-add-halfpage-up-down-vi-bindings.patch b/pkg/fzy/patches/0004-add-halfpage-up-down-vi-bindings.patch @@ -0,0 +1,49 @@ +From f9238875892ab2a302026c7e61ab59ac5f066747 Mon Sep 17 00:00:00 2001 +From: Jul <jul@qh.is> +Date: Tue, 5 Aug 2025 03:20:20 -0400 +Subject: [PATCH 4/6] add halfpage up/down vi bindings + +--- + src/tty_interface.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/src/tty_interface.c b/src/tty_interface.c +index aed8a21..b4a99c1 100644 +--- a/src/tty_interface.c ++++ b/src/tty_interface.c +@@ -186,9 +186,16 @@ static void action_del_word(tty_interface_t *state) { + state->cursor = cursor; + } + +-static void action_del_all(tty_interface_t *state) { +- memmove(state->search, &state->search[state->cursor], strlen(state->search) - state->cursor + 1); +- state->cursor = 0; ++static void action_halfpageup(tty_interface_t *state) { ++ update_state(state); ++ for (size_t i = 0; i < (state->options->num_lines / 2) && state->choices->selection > 0; i++) ++ choices_prev(state->choices); ++} ++ ++static void action_halfpagedown(tty_interface_t *state) { ++ update_state(state); ++ for (size_t i = 0; i < (state->options->num_lines / 2) && state->choices->selection < state->choices->available - 1; i++) ++ choices_next(state->choices); + } + + static void action_prev(tty_interface_t *state) { +@@ -300,10 +307,10 @@ static const keybinding_t keybindings[] = {{"\x1b", action_exit}, /* ESC * + + {KEY_CTRL('H'), action_del_char}, /* Backspace (C-H) */ + {KEY_CTRL('W'), action_del_word}, /* C-W */ +- {KEY_CTRL('U'), action_del_all}, /* C-U */ + {KEY_CTRL('I'), action_autocomplete}, /* TAB (C-I ) */ ++ {KEY_CTRL('U'), action_halfpageup}, /* C-U */ ++ {KEY_CTRL('D'), action_halfpagedown}, /* C-D */ + {KEY_CTRL('C'), action_exit}, /* C-C */ +- {KEY_CTRL('D'), action_exit}, /* C-D */ + {KEY_CTRL('G'), action_exit}, /* C-G */ + {KEY_CTRL('M'), action_emit}, /* CR */ + {KEY_CTRL('P'), action_prev}, /* C-P */ +-- +2.50.1 + diff --git a/pkg/fzy/patches/0004-truncate-entries-to-terminal-width.patch b/pkg/fzy/patches/0004-truncate-entries-to-terminal-width.patch @@ -1,27 +0,0 @@ -From 0dce1ecf12d53a03d89d33f81c0bd6f441189373 Mon Sep 17 00:00:00 2001 -From: Jul <jul@qh.is> -Date: Thu, 31 Jul 2025 05:34:48 -0400 -Subject: [PATCH 4/6] truncate entries to terminal width - ---- - src/tty_interface.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/tty_interface.c b/src/tty_interface.c -index ee36845..2025abb 100644 ---- a/src/tty_interface.c -+++ b/src/tty_interface.c -@@ -179,6 +179,10 @@ static void draw_match(tty_interface_t *state, const char *choice, int selected) - - tty_setnowrap(tty); - for (size_t i = 0, p = 0; choice[i] != '\0'; i++) { -+ if (i >= tty_getwidth(state->tty) - 5) { -+ tty_printf(tty, "..."); -+ break; -+ } - if (positions[p] == i) { - tty_setfg(tty, TTY_COLOR_HIGHLIGHT); - p++; --- -2.50.1 - diff --git a/pkg/fzy/patches/0005-add-half-page-up-down-vi-actions.patch b/pkg/fzy/patches/0005-add-half-page-up-down-vi-actions.patch @@ -1,66 +0,0 @@ -From e312ce929748ea9e0d29de04da93ef0100f561fc Mon Sep 17 00:00:00 2001 -From: Jul <jul@qh.is> -Date: Thu, 31 Jul 2025 22:37:31 -0400 -Subject: [PATCH 5/6] add half page up down vi actions - ---- - src/tty_interface.c | 21 ++++++++++++++------- - 1 file changed, 14 insertions(+), 7 deletions(-) - -diff --git a/src/tty_interface.c b/src/tty_interface.c -index 2025abb..18e40f1 100644 ---- a/src/tty_interface.c -+++ b/src/tty_interface.c -@@ -333,11 +333,6 @@ static void action_del_word(tty_interface_t *state) { - state->cursor = cursor; - } - --static void action_del_all(tty_interface_t *state) { -- memmove(state->search, &state->search[state->cursor], strlen(state->search) - state->cursor + 1); -- state->cursor = 0; --} -- - static void action_prev(tty_interface_t *state) { - update_state(state); - choices_prev(state->choices); -@@ -352,6 +347,18 @@ static void action_next(tty_interface_t *state) { - choices_next(state->choices); - } - -+static void action_halfpagedown(tty_interface_t *state) { -+ update_state(state); -+ for (size_t i = 0; i < state->options->num_lines / 2 && state->choices->selection < state->choices->available - 1; i++) -+ choices_next(state->choices); -+} -+ -+static void action_halfpageup(tty_interface_t *state) { -+ update_state(state); -+ for (size_t i = 0; i < state->options->num_lines / 2 && state->choices->selection > 0; i++) -+ choices_prev(state->choices); -+} -+ - static void action_left(tty_interface_t *state) { - if (state->cursor > 0) { - state->cursor--; -@@ -451,16 +458,16 @@ static const keybinding_t keybindings[] = {{"\x1b", action_exit}, /* ESC * - - {KEY_CTRL('H'), action_del_char}, /* Backspace (C-H) */ - {KEY_CTRL('W'), action_del_word}, /* C-W */ -- {KEY_CTRL('U'), action_del_all}, /* C-U */ - {KEY_CTRL('I'), action_autocomplete}, /* TAB (C-I ) */ - {KEY_CTRL('C'), action_exit}, /* C-C */ -- {KEY_CTRL('D'), action_exit}, /* C-D */ - {KEY_CTRL('G'), action_exit}, /* C-G */ - {KEY_CTRL('M'), action_emit}, /* CR */ - {KEY_CTRL('P'), action_prev}, /* C-P */ - {KEY_CTRL('N'), action_next}, /* C-N */ - {KEY_CTRL('K'), action_prev}, /* C-K */ - {KEY_CTRL('J'), action_next}, /* C-J */ -+ {KEY_CTRL('U'), action_halfpageup}, /* C-U */ -+ {KEY_CTRL('D'), action_halfpagedown}, /* C-D */ - {KEY_CTRL('A'), action_beginning}, /* C-A */ - {KEY_CTRL('E'), action_end}, /* C-E */ - --- -2.50.1 - diff --git a/pkg/fzy/patches/0005-inline-info.patch b/pkg/fzy/patches/0005-inline-info.patch @@ -0,0 +1,37 @@ +From abbd962e4891ff3f07ccbc0d56f29c7f633b867e Mon Sep 17 00:00:00 2001 +From: Jul <jul@qh.is> +Date: Tue, 5 Aug 2025 04:26:59 -0400 +Subject: [PATCH 5/6] inline info + +--- + src/tty_interface.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/tty_interface.c b/src/tty_interface.c +index b4a99c1..18ccd59 100644 +--- a/src/tty_interface.c ++++ b/src/tty_interface.c +@@ -101,8 +101,7 @@ static void draw(tty_interface_t *state) { + tty_printf(tty, "%s%s", options->prompt, state->search); + + if (options->show_info) { +- tty_printf(tty, "\n"); +- tty_clearline(tty); ++ tty_printf(tty, " "); + tty_printf(tty, "[%lu/%lu]", choices->available, choices->size); + } + +@@ -115,8 +114,8 @@ static void draw(tty_interface_t *state) { + } + } + +- if (num_lines + options->show_info) +- tty_moveup(tty, num_lines + options->show_info); ++ if (num_lines) ++ tty_moveup(tty, num_lines); + + tty_setcol(tty, 0); + fputs(options->prompt, tty->fout); +-- +2.50.1 + diff --git a/pkg/fzy/patches/0006-add-partial-multi-selection.patch b/pkg/fzy/patches/0006-add-partial-multi-selection.patch @@ -0,0 +1,261 @@ +From b15050410a3d95ff60145febcfaf24096b4defb4 Mon Sep 17 00:00:00 2001 +From: Jul <jul@qh.is> +Date: Wed, 6 Aug 2025 05:57:32 -0400 +Subject: [PATCH 6/6] add partial multi-selection + +--- + src/choices.c | 31 +++++++++++++++++++++++++++++-- + src/choices.h | 4 ++++ + src/options.c | 8 +++++++- + src/options.h | 1 + + src/tty_interface.c | 44 +++++++++++++++++++++++++++++++++++++++++--- + 5 files changed, 82 insertions(+), 6 deletions(-) + +diff --git a/src/choices.c b/src/choices.c +index 4b6a0ca..9c7e2e4 100644 +--- a/src/choices.c ++++ b/src/choices.c +@@ -94,8 +94,10 @@ static void choices_resize(choices_t *c, size_t new_capacity) { + + static void choices_reset_search(choices_t *c) { + free(c->results); +- c->selection = c->available = 0; ++ free(c->multiselections); ++ c->selection = c->available = c->multiselection_size = 0; + c->results = NULL; ++ c->multiselections = NULL; + } + + void choices_init(choices_t *c, options_t *options) { +@@ -127,8 +129,10 @@ void choices_destroy(choices_t *c) { + c->capacity = c->size = 0; + + free(c->results); ++ free(c->multiselections); + c->results = NULL; +- c->available = c->selection = 0; ++ c->multiselections = NULL; ++ c->available = c->selection = c->multiselection_size = 0; + } + + void choices_add(choices_t *c, const char *choice) { +@@ -261,6 +265,14 @@ static void *choices_search_worker(void *data) { + return NULL; + } + ++void multiselection_init(choices_t *c) { ++ c->multiselection_size = 0; ++ c->multiselections = (unsigned char *) malloc(c->available * sizeof(unsigned char)); ++ for (size_t i = 0; i < c->available; i++) { ++ c->multiselections[i] = 0; ++ } ++} ++ + void choices_search(choices_t *c, const char *search) { + choices_reset_search(c); + +@@ -307,6 +319,7 @@ void choices_search(choices_t *c, const char *search) { + c->results = workers[0].result.list; + c->available = workers[0].result.size; + ++ multiselection_init(c); + free(workers); + pthread_mutex_destroy(&job->lock); + free(job); +@@ -333,3 +346,17 @@ void choices_next(choices_t *c) { + if (c->available) + c->selection = (c->selection + 1) % c->available; + } ++ ++void choices_multiselect_toggle(choices_t *c) { ++ if (!c->available) return; ++ unsigned char selected = 1 == c->multiselections[c->selection]; ++ ++ if (selected) { ++ c->multiselections[c->selection] = 0; ++ c->multiselection_size--; ++ } else { ++ c->multiselections[c->selection] = 1; ++ c->multiselection_size++; ++ } ++} ++ +diff --git a/src/choices.h b/src/choices.h +index 9a77ccb..bbc0075 100644 +--- a/src/choices.h ++++ b/src/choices.h +@@ -28,6 +28,9 @@ typedef struct { + size_t available; + size_t selection; + ++ unsigned char *multiselections; ++ size_t multiselection_size; ++ + unsigned int worker_count; + } choices_t; + +@@ -41,6 +44,7 @@ const char *choices_get(choices_t *c, size_t n); + score_t choices_getscore(choices_t *c, size_t n); + void choices_prev(choices_t *c); + void choices_next(choices_t *c); ++void choices_multiselect_toggle(choices_t *c); + + #ifdef __cplusplus + } +diff --git a/src/options.c b/src/options.c +index 5fd9d2a..ba452a3 100644 +--- a/src/options.c ++++ b/src/options.c +@@ -20,6 +20,7 @@ static const char *usage_str = + " -0, --read-null Read input delimited by ASCII NUL characters\n" + " -j, --workers NUM Use NUM workers for searching. (default is # of CPUs)\n" + " -i, --show-info Show selection info line\n" ++ " -m, --multi Enable multi-selection\n" + " -h, --help Display this help and exit\n" + " -v, --version Output version information and exit\n"; + +@@ -38,6 +39,7 @@ static struct option longopts[] = {{"show-matches", required_argument, NULL, 'e' + {"benchmark", optional_argument, NULL, 'b'}, + {"workers", required_argument, NULL, 'j'}, + {"show-info", no_argument, NULL, 'i'}, ++ {"multi", no_argument, NULL, 'm'}, + {"help", no_argument, NULL, 'h'}, + {NULL, 0, NULL, 0}}; + +@@ -53,13 +55,14 @@ void options_init(options_t *options) { + options->workers = DEFAULT_WORKERS; + options->input_delimiter = '\n'; + options->show_info = DEFAULT_SHOW_INFO; ++ options->multi = 0; + } + + void options_parse(options_t *options, int argc, char *argv[]) { + options_init(options); + + int c; +- while ((c = getopt_long(argc, argv, "vhs0e:q:l:t:p:j:i", longopts, NULL)) != -1) { ++ while ((c = getopt_long(argc, argv, "vhs0me:q:l:t:p:j:i", longopts, NULL)) != -1) { + switch (c) { + case 'v': + printf("%s " VERSION " © 2014-2025 John Hawthorn\n", argv[0]); +@@ -113,6 +116,9 @@ void options_parse(options_t *options, int argc, char *argv[]) { + case 'i': + options->show_info = 1; + break; ++ case 'm': ++ options->multi = 1; ++ break; + case 'h': + default: + usage(argv[0]); +diff --git a/src/options.h b/src/options.h +index bfc3fa4..5c8be3b 100644 +--- a/src/options.h ++++ b/src/options.h +@@ -16,6 +16,7 @@ typedef struct { + unsigned int workers; + char input_delimiter; + int show_info; ++ int multi; + } options_t; + + void options_init(options_t *options); +diff --git a/src/tty_interface.c b/src/tty_interface.c +index 18ccd59..ddcbb59 100644 +--- a/src/tty_interface.c ++++ b/src/tty_interface.c +@@ -96,11 +96,14 @@ static void draw(tty_interface_t *state) { + } + } + +- tty_setcol(tty, 0); + tty_clearline(tty); ++ tty_setcol(tty, options->multi ? 2 : 0); + tty_printf(tty, "%s%s", options->prompt, state->search); + +- if (options->show_info) { ++ if (options->show_info && options->multi) { ++ tty_printf(tty, " "); ++ tty_printf(tty, "[%lu/%lu/%lu]", choices->multiselection_size, choices->available, choices->size); ++ } else if (options->show_info) { + tty_printf(tty, " "); + tty_printf(tty, "[%lu/%lu]", choices->available, choices->size); + } +@@ -110,6 +113,7 @@ static void draw(tty_interface_t *state) { + tty_clearline(tty); + const char *choice = choices_get(choices, i); + if (choice) { ++ if (options->multi) tty_printf(tty, choices->multiselections[i] == 1 ? "* " : " "); + draw_match(state, choice, i == choices->selection); + } + } +@@ -117,7 +121,7 @@ static void draw(tty_interface_t *state) { + if (num_lines) + tty_moveup(tty, num_lines); + +- tty_setcol(tty, 0); ++ tty_setcol(tty, options->multi ? 2 : 0); + fputs(options->prompt, tty->fout); + for (size_t i = 0; i < state->cursor; i++) + fputc(state->search[i], tty->fout); +@@ -136,9 +140,41 @@ static void update_state(tty_interface_t *state) { + } + } + ++static void action_multiselect(tty_interface_t *state) { ++ if (!state->options->multi) return; ++ ++ choices_multiselect_toggle(state->choices); ++ choices_next(state->choices); ++ draw(state); ++} ++ + static void action_emit(tty_interface_t *state) { + update_state(state); + ++ if (state->options->multi) { ++ int multiselected = 0; ++ ++ for (size_t i = 0; i < state->choices->available; i++) { ++ if (state->choices->multiselections[i] != 1) continue; ++ ++ const char *name = choices_get(state->choices, i); ++ if (!name) continue; ++ ++ if (!multiselected) { ++ clear(state); ++ tty_close(state->tty); ++ multiselected = 1; ++ } ++ ++ printf("%s\n", name); ++ } ++ ++ if (multiselected) { ++ state->exit = EXIT_SUCCESS; ++ return; ++ } ++ } ++ + /* Reset the tty as close as possible to the previous state */ + clear(state); + +@@ -249,6 +285,7 @@ static void action_pagedown(tty_interface_t *state) { + + static void action_autocomplete(tty_interface_t *state) { + update_state(state); ++ + const char *current_selection = choices_get(state->choices, state->choices->selection); + if (current_selection) { + strncpy(state->search, choices_get(state->choices, state->choices->selection), SEARCH_SIZE_MAX); +@@ -318,6 +355,7 @@ static const keybinding_t keybindings[] = {{"\x1b", action_exit}, /* ESC * + {KEY_CTRL('J'), action_next}, /* C-J */ + {KEY_CTRL('A'), action_beginning}, /* C-A */ + {KEY_CTRL('E'), action_end}, /* C-E */ ++ {KEY_CTRL('@'), action_multiselect}, /* Space (C-@) */ + + {"\x1bOD", action_left}, /* LEFT */ + {"\x1b[D", action_left}, /* LEFT */ +-- +2.50.1 + diff --git a/pkg/fzy/patches/0006-inline-info-data.patch b/pkg/fzy/patches/0006-inline-info-data.patch @@ -1,52 +0,0 @@ -From f1db793ef8f73ac9d853b98a01a7af0cba96a3a0 Mon Sep 17 00:00:00 2001 -From: Jul <jul@qh.is> -Date: Thu, 31 Jul 2025 23:25:23 -0400 -Subject: [PATCH 6/6] inline info data - ---- - src/tty_interface.c | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - -diff --git a/src/tty_interface.c b/src/tty_interface.c -index 18e40f1..0e63989 100644 ---- a/src/tty_interface.c -+++ b/src/tty_interface.c -@@ -140,7 +140,7 @@ static void clear(tty_interface_t *state) { - - tty_setcol(tty, DEFAULT_MULTI ? 2 : 0); - size_t line = 0; -- while (line++ < state->options->num_lines + (state->options->show_info ? 1 : 0)) { -+ while (line++ < state->options->num_lines) { - tty_newline(tty); - } - tty_clearline(tty); -@@ -220,13 +220,12 @@ static void draw(tty_interface_t *state) { - tty_clearline(tty); - tty_setcol(tty, DEFAULT_MULTI ? 2 : 0); - tty_printf(tty, "%s%s", options->prompt, state->search); -- tty_clearline(tty); - - if (options->show_info && DEFAULT_MULTI) { -- tty_printf(tty, "\n[%lu/%lu/%lu]", count_selections(state), choices->available, choices->size); -+ tty_printf(tty, " [%lu/%lu/%lu]", count_selections(state), choices->available, choices->size); - tty_clearline(tty); - } else if (options->show_info) { -- tty_printf(tty, "\n[%lu/%lu]", choices->available, choices->size); -+ tty_printf(tty, " [%lu/%lu]", choices->available, choices->size); - tty_clearline(tty); - } - -@@ -244,8 +243,8 @@ static void draw(tty_interface_t *state) { - } - } - -- if (num_lines + options->show_info) -- tty_moveup(tty, num_lines + options->show_info); -+ if (num_lines) -+ tty_moveup(tty, num_lines); - - tty_setcol(tty, DEFAULT_MULTI ? 2 : 0); - fputs(options->prompt, tty->fout); --- -2.50.1 -