commit baae6b1c0e2820a3e39f0dc2c1bfad4b9381dfa1
parent bfeedacdd9985196deb970d4b1405c37737ed5d2
Author: Bharatvaj Hemanth <bharatvaj@yahoo.com>
Date: Tue, 13 Oct 2026 23:05:14 +0530
parent bfeedacdd9985196deb970d4b1405c37737ed5d2
Author: Bharatvaj Hemanth <bharatvaj@yahoo.com>
Date: Tue, 13 Oct 2026 23:05:14 +0530
Use byte-safe subsequence matching without fzy dependency
5 files changed, 31 insertions(+), 35 deletions(-)
diff --git a/HACKING b/HACKING @@ -12,21 +12,9 @@ Build Dependencies ------------ -External source is pulled with mor from requirements.ini: - - bash /path/to/mor.sh . - -This fetches fzy v1.1 into deps/fzy (requirements.ini pins the tag). -For an existing checkout, remove deps/fzy before rerunning mor: mor does not -update directories already present. The build uses only fzy's matcher: - - deps/fzy/src/match.c - deps/fzy/src/match.h - -Makefile generates two tiny compatibility files inside deps/ when needed: - - deps/fzy/config.h - deps/fzy/src/strings.h +No external source dependencies. The byte-safe subsequence matcher lives in +wmenu.c; ASCII matching retains fzy's old behavior, while non-ASCII UTF-8 +bytes are compared literally. Program shape ------------- @@ -113,7 +101,7 @@ Known simplifications It never yields while holding items_lock. The reader remains a separate thread. It publishes item_count with InterlockedIncrement after inserting a row; UI count reads use loaded_count(), and item pointers are read under - items_lock. Matching rows are indexed in source order (fzy subsequence matching, + items_lock. Matching rows are indexed in source order (subsequence matching, not score-ranked). No silent row cap. LB_SETCOUNT is wrapped with redraw suppression: unchanged visible rows are not invalidated as the row count grows; only newly visible rows are, and those are painted immediately so
diff --git a/Makefile b/Makefile @@ -6,21 +6,15 @@ DEBUG=/D_WIN32 /D_DEBUG /D_CONSOLE /D_CRT_SECURE_NO_WARNINGS CFLAGS = $(DEBUG) -wmenu.exe: wmenu.c arg.h deps/fzy/src/match.c deps/fzy/config.h deps/fzy/src/strings.h - cl wmenu.c deps/fzy/src/match.c /I deps/fzy/src $(CFLAGS) user32.lib comctl32.lib gdi32.lib +wmenu.exe: wmenu.c arg.h + cl wmenu.c $(CFLAGS) user32.lib comctl32.lib gdi32.lib -test: test_stream.c wmenu.c arg.h deps/fzy/src/match.c deps/fzy/config.h deps/fzy/src/strings.h - cl test_stream.c deps/fzy/src/match.c /I deps/fzy/src $(CFLAGS) user32.lib comctl32.lib gdi32.lib /Fe:test_stream.exe +test: test_stream.c wmenu.c arg.h + cl test_stream.c $(CFLAGS) user32.lib comctl32.lib gdi32.lib /Fe:test_stream.exe ./test_stream.exe stress: test ./test_stream.exe stress -deps/fzy/config.h: deps/fzy/src/config.def.h - printf '#include "src/config.def.h"\n' > deps/fzy/config.h - -deps/fzy/src/strings.h: - printf '/* generated for MSVC: fzy match.c does not need strings.h here */\n' > deps/fzy/src/strings.h - -wmenu-mingw.exe: wmenu.c arg.h deps/fzy/src/match.c deps/fzy/config.h deps/fzy/src/strings.h - /usr/bin/x86_64-w64-mingw32-gcc -municode -I deps/fzy/src -o wmenu-mingw.exe wmenu.c deps/fzy/src/match.c -luser32 -lcomctl32 -lgdi32 +wmenu-mingw.exe: wmenu.c arg.h + /usr/bin/x86_64-w64-mingw32-gcc -municode -o wmenu-mingw.exe wmenu.c -luser32 -lcomctl32 -lgdi32
diff --git a/requirements.ini b/requirements.ini @@ -1,5 +0,0 @@ -[$] -/=deps - -[.] -fzy=https://github.com/jhawthorn/fzy.git@v1.1
diff --git a/test_stream.c b/test_stream.c @@ -17,6 +17,10 @@ static LRESULT CALLBACK TestWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) int main(int argc, char **argv) { + assert(has_match("aC", "ABC")); + assert(!has_match("Ab", "abc")); /* Preserve fzy's ASCII query casing. */ + assert(has_match("\xc3\xa9", "caf\xc3\xa9")); + assert(!has_match("\xc3\xa9", "caf\xc3\x89")); FILE *input = tmpfile(); assert(input); char long_row[8193]; @@ -229,6 +233,10 @@ int main(int argc, char **argv) input_done = true; update_progress(); assert(SendMessageW(list_hwnd, LB_GETCOUNT, 0, 0) == 1); + assert(add_item("caf\xc3\xa9")); + SetWindowTextW(input_hwnd, L"\x00e9"); /* UTF-8 edit text goes through the search path. */ + while (search_pos < loaded_count()) search_step(); + assert(match_count == 1 && matches[0] == 60003); DeleteFiber(search_fiber); ConvertFiberToThread(); DestroyWindow(main_hwnd);
diff --git a/wmenu.c b/wmenu.c @@ -12,8 +12,6 @@ #include <wctype.h> #include "arg.h" -#include "deps/fzy/src/match.h" - #ifdef _MSC_VER #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") #endif @@ -185,6 +183,19 @@ static DWORD WINAPI read_stdin_thread(void *unused) return 0; } +/* fzy-style subsequence matching, with non-ASCII UTF-8 bytes compared literally. */ +static bool has_match(const char *query, const char *line) +{ + while (*query) { + unsigned char ch = (unsigned char)*query++; + unsigned char upper = ch >= 'a' && ch <= 'z' ? ch - 'a' + 'A' : ch; + while (*line && (unsigned char)*line != ch && (unsigned char)*line != upper) ++line; + if (!*line) return false; + ++line; + } + return true; +} + /* The ListBox stores only a count. Its row IDs map into items or matches. */ static int row_item(int row) {
: nply/wmenu