sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit f8394ead0e20e16a37fcb0d427914b4a048f48d5
parent 41a6f1fc48b828be0f509752a49dcdc5b17e90f7
Author: Justinas Grigas <dev@jstnas.com>
Date:   Mon, 17 Jun 2024 03:32:24 +0100

dmenu(fuzzymatch): update to 5.3

updated version adds the flag to the manpage

Diffstat:
Atools.suckless.org/dmenu/patches/fuzzymatch/dmenu-fuzzymatch-5.3.diff | 196+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtools.suckless.org/dmenu/patches/fuzzymatch/index.md | 52++++++++++++++++++++++++++--------------------------
2 files changed, 222 insertions(+), 26 deletions(-)

diff --git a/tools.suckless.org/dmenu/patches/fuzzymatch/dmenu-fuzzymatch-5.3.diff b/tools.suckless.org/dmenu/patches/fuzzymatch/dmenu-fuzzymatch-5.3.diff @@ -0,0 +1,196 @@ +From d166c2c90f777f5a80f628d493cdcf7bf03034b8 Mon Sep 17 00:00:00 2001 +From: Justinas Grigas <dev@jstnas.com> +Date: Mon, 17 Jun 2024 02:52:15 +0100 +Subject: [PATCH] fuzzymatch: Add support for fuzzy-matching + +This version of the patch updates the manpage. +--- + config.def.h | 1 + + config.mk | 2 +- + dmenu.1 | 5 ++- + dmenu.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++- + 4 files changed, 95 insertions(+), 3 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 1edb647..a4e6174 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -2,6 +2,7 @@ + /* Default settings; can be overriden by command line. */ + + static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ ++static int fuzzy = 1; /* -F option; if 0, dmenu doesn't use fuzzy matching */ + /* -fn option overrides fonts[0]; default X11 font or font set */ + static const char *fonts[] = { + "monospace:size=10" +diff --git a/config.mk b/config.mk +index 137f7c8..6a19175 100644 +--- a/config.mk ++++ b/config.mk +@@ -21,7 +21,7 @@ FREETYPEINC = /usr/include/freetype2 + + # includes and libs + INCS = -I$(X11INC) -I$(FREETYPEINC) +-LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) ++LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lm + + # flags + CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) +diff --git a/dmenu.1 b/dmenu.1 +index 323f93c..e2c5ef4 100644 +--- a/dmenu.1 ++++ b/dmenu.1 +@@ -3,7 +3,7 @@ + dmenu \- dynamic menu + .SH SYNOPSIS + .B dmenu +-.RB [ \-bfiv ] ++.RB [ \-bFfiv ] + .RB [ \-l + .IR lines ] + .RB [ \-m +@@ -40,6 +40,9 @@ which lists programs in the user's $PATH and runs the result in their $SHELL. + .B \-b + dmenu appears at the bottom of the screen. + .TP ++.B \-F ++disables fuzzy matching. ++.TP + .B \-f + dmenu grabs the keyboard before reading stdin if not reading from a tty. This + is faster, but will lock up X until stdin reaches end\-of\-file. +diff --git a/dmenu.c b/dmenu.c +index 40f93e0..03e1f45 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -1,6 +1,7 @@ + /* See LICENSE file for copyright and license details. */ + #include <ctype.h> + #include <locale.h> ++#include <math.h> + #include <stdio.h> + #include <stdlib.h> + #include <string.h> +@@ -31,6 +32,7 @@ struct item { + char *text; + struct item *left, *right; + int out; ++ double distance; + }; + + static char text[BUFSIZ] = ""; +@@ -226,9 +228,93 @@ grabkeyboard(void) + die("cannot grab keyboard"); + } + ++int ++compare_distance(const void *a, const void *b) ++{ ++ struct item *da = *(struct item **) a; ++ struct item *db = *(struct item **) b; ++ ++ if (!db) ++ return 1; ++ if (!da) ++ return -1; ++ ++ return da->distance == db->distance ? 0 : da->distance < db->distance ? -1 : 1; ++} ++ ++void ++fuzzymatch(void) ++{ ++ /* bang - we have so much memory */ ++ struct item *it; ++ struct item **fuzzymatches = NULL; ++ char c; ++ int number_of_matches = 0, i, pidx, sidx, eidx; ++ int text_len = strlen(text), itext_len; ++ ++ matches = matchend = NULL; ++ ++ /* walk through all items */ ++ for (it = items; it && it->text; ++it) { ++ if (text_len) { ++ itext_len = strlen(it->text); ++ pidx = 0; /* pointer */ ++ sidx = eidx = -1; /* start of match, end of match */ ++ /* walk through item text */ ++ for (i = 0; i < itext_len && (c = it->text[i]); ++i) { ++ /* fuzzy match pattern */ ++ if (!fstrncmp(&text[pidx], &c, 1)) { ++ if(sidx == -1) ++ sidx = i; ++ ++pidx; ++ if (pidx == text_len) { ++ eidx = i; ++ break; ++ } ++ } ++ } ++ /* build list of matches */ ++ if (eidx != -1) { ++ /* compute distance */ ++ /* add penalty if match starts late (log(sidx+2)) ++ * add penalty for long a match without many matching characters */ ++ it->distance = log(sidx + 2) + (double)(eidx - sidx - text_len); ++ /* fprintf(stderr, "distance %s %f\n", it->text, it->distance); */ ++ appenditem(it, &matches, &matchend); ++ ++number_of_matches; ++ } ++ } else { ++ appenditem(it, &matches, &matchend); ++ } ++ } ++ ++ if (number_of_matches) { ++ /* initialize array with matches */ ++ if (!(fuzzymatches = realloc(fuzzymatches, ++ number_of_matches * sizeof(struct item *)))) ++ die("cannot realloc %u bytes:", number_of_matches * sizeof(struct item *)); ++ for (i = 0, it = matches; it && i < number_of_matches; ++i, it = it->right) ++ fuzzymatches[i] = it; ++ /* sort matches according to distance */ ++ qsort(fuzzymatches, number_of_matches, sizeof(struct item*), compare_distance); ++ /* rebuild list of matches */ ++ matches = matchend = NULL; ++ for (i = 0, it = fuzzymatches[i]; i < number_of_matches && it && ++ it->text; ++i, it = fuzzymatches[i]) ++ appenditem(it, &matches, &matchend); ++ free(fuzzymatches); ++ } ++ curr = sel = matches; ++ calcoffsets(); ++} ++ + static void + match(void) + { ++ if (fuzzy) { ++ fuzzymatch(); ++ return; ++ } + static char **tokv = NULL; + static int tokn = 0; + +@@ -715,7 +801,7 @@ setup(void) + static void + usage(void) + { +- die("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" ++ die("usage: dmenu [-bFfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]"); + } + +@@ -732,6 +818,8 @@ main(int argc, char *argv[]) + exit(0); + } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ + topbar = 0; ++ else if (!strcmp(argv[i], "-F")) /* disables fuzzy matching */ ++ fuzzy = 0; + else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ + fast = 1; + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ +-- +2.45.2 + diff --git a/tools.suckless.org/dmenu/patches/fuzzymatch/index.md b/tools.suckless.org/dmenu/patches/fuzzymatch/index.md @@ -1,26 +1,26 @@ -fuzzymatch -========== - -Description ------------ -This patch adds support for fuzzy-matching to dmenu, allowing users to type -non-consecutive portions of the string to be matched. - -Adds the option *fuzzy* to config.def.h and the flag *-F* to dmenu which enable -to turn fuzzy-matching on and off. - -Notes ------ -* Supports dmenu's case insensitive switch (`-i`) - -Download --------- -* [dmenu-fuzzymatch-4.9.diff](dmenu-fuzzymatch-4.9.diff) -* [dmenu-fuzzymatch-20170603-f428f3e.diff](dmenu-fuzzymatch-20170603-f428f3e.diff) -* [dmenu-fuzzymatch-4.6.diff](dmenu-fuzzymatch-4.6.diff) - -Authors -------- -* Jan Christoph Ebersbach - jceb@e-jc.de -* Laslo Hunhold - dev@frign.de (dmenu-4.6) -* Aleksandrs Stier (4.9) +# fuzzymatch + +## Description + +Add support for fuzzy-matching to dmenu, enabling matching using non-consecutive +portions of items. + +Add option `fuzzy` to `config.def.h` and the flag `-F` to toggle fuzzy-matching. + +## Notes + +- Supports dmenu's case insensitive switch (`-i`) + +## Download + +- [dmenu-fuzzymatch-4.6.diff](dmenu-fuzzymatch-4.6.diff) +- [dmenu-fuzzymatch-20170603-f428f3e.diff](dmenu-fuzzymatch-20170603-f428f3e.diff) +- [dmenu-fuzzymatch-4.9.diff](dmenu-fuzzymatch-4.9.diff) +- [dmenu-fuzzymatch-5.3.diff](./) + +## Authors + +- Jan Christoph Ebersbach - jceb@e-jc.de +- Laslo Hunhold - dev@frign.de (4.6) +- Aleksandrs Stier (4.9) +- Justinas Grigas <dev@jstnas.com> (5.3)