diff --git a/README.md b/README.md index 48f49014..19d1b166 100644 --- a/README.md +++ b/README.md @@ -63,9 +63,9 @@ PKG_CONFIG_PATH="/usr/local/opt/ncurses/lib/pkgconfig" sh build-osx.sh curses ### Nix -There is darwin.nix provided in this repo, you can install bemenu with it by running +There is default.nix provided in this repo, you can install bemenu with it by running ```sh -nix-env -i -f darwin.nix +nix-env -i -f default.nix ``` This installs only the curses backend. diff --git a/VERSION b/VERSION index 6769f67e..c4c2d2b1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.6.15 +0.6.16 diff --git a/client/common/common.c b/client/common/common.c index 0c545e18..5022fd14 100644 --- a/client/common/common.c +++ b/client/common/common.c @@ -170,7 +170,7 @@ usage(FILE *out, const char *name) " -h, --help display this help and exit.\n" " -v, --version display version.\n" " -i, --ignorecase match items case insensitively.\n" - " -F, --filter filter entries for a given string.\n" + " -F, --filter filter entries for a given string before showing the menu.\n" " -w, --wrap wraps cursor selection.\n" " -l, --list list items vertically with the given number of lines.\n" " -p, --prompt defines the prompt text to be displayed.\n" @@ -185,6 +185,7 @@ usage(FILE *out, const char *name) " --fixed-height prevent the display from changing height on filter.\n" " --scrollbar display scrollbar. (none (default), always, autohide)\n" " --counter display a matched/total items counter. (none (default), always)\n" + " -e, --vim-esc-exits exit bemenu when pressing escape in normal mode for vim bindings\n" " --accept-single immediately return if there is only one item.\n" " --ifne only display menu if there are items.\n" " --fork always fork. (bemenu-run)\n" @@ -275,6 +276,7 @@ do_getopt(struct client *client, int *argc, char **argv[]) { "fixed-height", no_argument, 0, 0x090 }, { "scrollbar", required_argument, 0, 0x100 }, { "counter", required_argument, 0, 0x10a }, + { "vim-esc-exits",no_argument, 0, 'e' }, { "accept-single",no_argument, 0, 0x11a }, { "ifne", no_argument, 0, 0x117 }, { "fork", no_argument, 0, 0x118 }, @@ -372,6 +374,9 @@ do_getopt(struct client *client, int *argc, char **argv[]) case 0x10a: client->counter = (!strcmp(optarg, "always")); break; + case 'e': + client->vim_esc_exits = true; + break; case 0x11a: client->accept_single = true; break; @@ -555,6 +560,7 @@ menu_with_options(struct client *client) bm_menu_set_fixed_height(menu, client->fixed_height); bm_menu_set_scrollbar(menu, client->scrollbar); bm_menu_set_counter(menu, client->counter); + bm_menu_set_vim_esc_exits(menu, client->vim_esc_exits); bm_menu_set_panel_overlap(menu, !client->no_overlap); bm_menu_set_spacing(menu, !client->no_spacing); bm_menu_set_password(menu, client->password); @@ -590,16 +596,17 @@ run_menu(const struct client *client, struct bm_menu *menu, void (*item_cb)(cons bm_menu_set_highlighted_index(menu, client->selected); bm_menu_grab_keyboard(menu, true); bm_menu_set_filter(menu, client->initial_filter); + bm_menu_filter(menu); { - uint32_t total_item_count; - struct bm_item **items = bm_menu_get_items(menu, &total_item_count); + uint32_t item_count; + struct bm_item **items = bm_menu_get_filtered_items(menu, &item_count); - if (client->ifne && total_item_count == 0) { + if (client->ifne && item_count == 0) { return BM_RUN_RESULT_CANCEL; } - if (client->accept_single && total_item_count == 1) { + if (client->accept_single && item_count == 1) { item_cb(client, *items); return BM_RUN_RESULT_SELECTED; } diff --git a/client/common/common.h b/client/common/common.h index 98c9b4c4..b1fa433c 100644 --- a/client/common/common.h +++ b/client/common/common.h @@ -29,6 +29,7 @@ struct client { bool wrap; bool fixed_height; bool counter; + bool vim_esc_exits; bool accept_single; bool ifne; bool no_overlap; diff --git a/darwin.nix b/default.nix similarity index 51% rename from darwin.nix rename to default.nix index 9b1f2832..e8532389 100644 --- a/darwin.nix +++ b/default.nix @@ -1,4 +1,4 @@ -{ pkgs ? import {} }: +{ pkgs ? import {}, lib ? pkgs.lib, stdenv ? pkgs.stdenv }: let src = pkgs.copyPathToStore ./.; @@ -6,23 +6,44 @@ let revision = builtins.readFile (pkgs.runCommand "get-rev" { nativeBuildInputs = with pkgs; [ git ]; } "GIT_DIR=${src}/.git git rev-parse --short HEAD | tr -d '\n' > $out"); -in pkgs.stdenv.mkDerivation rec { +in stdenv.mkDerivation { inherit src; pname = "bemenu"; version = "${semver}${revision}"; - nativeBuildInputs = with pkgs; [ pkg-config scdoc ]; - buildInputs = with pkgs; [ ncurses ]; - postPatch = '' + strictDeps = true; + nativeBuildInputs = with pkgs; [ + pkg-config + scdoc + ] ++ lib.optionals (stdenv.isLinux) [ + wayland-scanner + ]; + + buildInputs = with pkgs; [ + ncurses + ] ++ lib.optionals (stdenv.isLinux) [ + cairo + fribidi + harfbuzz + libxkbcommon + pango + # Wayland + wayland wayland-protocols + # X11 + xorg.libX11 xorg.libXinerama xorg.libXft + xorg.libXdmcp xorg.libpthreadstubs xorg.libxcb + ]; + + postPatch = "" + lib.optionalString (stdenv.isDarwin) '' substituteInPlace GNUmakefile --replace '-soname' '-install_name' ''; - makeFlags = ["PREFIX=$(out)"]; - buildFlags = ["PREFIX=$(out)" "clients" "curses"]; + makeFlags = [ "PREFIX=$(out)" ]; + buildFlags = [ "PREFIX=$(out)" "clients" "curses" ] ++ lib.optionals (stdenv.isLinux) [ "wayland" "x11" ]; # https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/setup-hooks/fix-darwin-dylib-names.sh # ^ does not handle .so files - postInstall = '' + postInstall = "" + lib.optionalString (stdenv.isDarwin) '' so="$(find "$out/lib" -name "libbemenu.so.[0-9]" -print -quit)" for f in "$out/bin/"*; do install_name_tool -change "$(basename $so)" "$so" $f @@ -33,6 +54,6 @@ in pkgs.stdenv.mkDerivation rec { homepage = "https://github.com/Cloudef/bemenu"; description = "Dynamic menu library and client program inspired by dmenu"; license = licenses.gpl3Plus; - platforms = with platforms; darwin; + platforms = with platforms; darwin ++ linux; }; } diff --git a/lib/bemenu.h b/lib/bemenu.h index 2679f373..0e730ad1 100644 --- a/lib/bemenu.h +++ b/lib/bemenu.h @@ -733,6 +733,24 @@ BM_PUBLIC void bm_menu_set_counter(struct bm_menu *menu, bool mode); BM_PUBLIC bool bm_menu_get_counter(struct bm_menu *menu); +/** + * Set vim escape exit mode of the bar. + * + * @param menu bm_menu to set the vim escape exit mode for. + * @param mode to be set. + */ + +BM_PUBLIC void bm_menu_set_vim_esc_exits(struct bm_menu *menu, bool mode); + +/** + * Get the vim escape exit mode of the bar. + * + * @param menu bm_menu to get the vim escape exit mode from. + * @param mode current vim escape exit mode + */ + +BM_PUBLIC bool bm_menu_get_vim_esc_exits(struct bm_menu *menu); + /** * Set the vertical alignment of the bar. * diff --git a/lib/filter.c b/lib/filter.c index 14b003bc..2b4e4655 100644 --- a/lib/filter.c +++ b/lib/filter.c @@ -113,6 +113,7 @@ filter_dmenu_fun(struct bm_menu *menu, char addition, char* (*fstrstr)(const cha if (!(buffer = tokenize(menu, &tokv, &tokc))) goto fail; + const char *filter = menu->filter ? menu->filter : ""; size_t len = (tokc ? strlen(tokv[0]) : 0); uint32_t i, f, e; for (e = f = i = 0; i < count; ++i) { @@ -127,14 +128,14 @@ filter_dmenu_fun(struct bm_menu *menu, char addition, char* (*fstrstr)(const cha continue; } - if (tokc && item->text && !fstrncmp(tokv[0], item->text, len + 1)) { /* exact matches */ + if (tokc && item->text && strlen(filter) == strlen(item->text) && !fstrncmp(filter, item->text, strlen(filter))) { /* exact matches */ memmove(&filtered[1], filtered, f * sizeof(struct bm_item*)); filtered[0] = item; e++; /* where do exact matches end */ } else if (tokc && item->text && !fstrncmp(tokv[0], item->text, len)) { /* prefixes */ memmove(&filtered[e + 1], &filtered[e], (f - e) * sizeof(struct bm_item*)); filtered[e] = item; - e++; /* where do exact matches end */ + e++; /* where do prefix matches end */ } else { filtered[f] = item; } diff --git a/lib/internal.h b/lib/internal.h index bc5e6537..d6f46942 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -362,6 +362,11 @@ struct bm_menu { */ enum bm_scrollbar_mode scrollbar; + /** + * Current vim escape exit mode. + */ + bool vim_esc_exits; + /** * Current counter display mode. */ diff --git a/lib/menu.c b/lib/menu.c index bb59f90d..245a59a9 100644 --- a/lib/menu.c +++ b/lib/menu.c @@ -458,6 +458,18 @@ bm_menu_get_scrollbar(struct bm_menu *menu) return menu->scrollbar; } +void +bm_menu_set_vim_esc_exits(struct bm_menu *menu, bool mode) +{ + menu->vim_esc_exits = mode; +} + +bool +bm_menu_get_vim_esc_exits(struct bm_menu *menu) +{ + return menu->vim_esc_exits; +} + void bm_menu_set_counter(struct bm_menu *menu, bool mode) { diff --git a/lib/vim.c b/lib/vim.c index e8549cff..b61948c3 100644 --- a/lib/vim.c +++ b/lib/vim.c @@ -206,7 +206,11 @@ enum bm_vim_code bm_vim_key_press(struct bm_menu *menu, enum bm_key key, uint32_ if(key == BM_KEY_ESCAPE && unicode == 99) return BM_VIM_EXIT; if(menu->vim_mode == 'n'){ - if(key == BM_KEY_ESCAPE) return BM_VIM_CONSUME; + if(key == BM_KEY_ESCAPE){ + if(menu->vim_esc_exits) return BM_VIM_EXIT; + return BM_VIM_CONSUME; + } + if(unicode == 0 || unicode > 128) return BM_VIM_IGNORE; if(menu->vim_last_key == 0) return vim_on_first_key(menu, unicode, item_count, items_displayed); diff --git a/man/bemenu.1.scd.in b/man/bemenu.1.scd.in index 08755069..2d9d1bb9 100644 --- a/man/bemenu.1.scd.in +++ b/man/bemenu.1.scd.in @@ -73,6 +73,12 @@ list of executables under PATH and the selected items are executed. *-x, --password* Hide filter text. +*--fixed-height* + Prevent the display from changing height on filter. + +*--accept-single* + Immediately return if there is only one item. + *--binding* Use alternative key bindings. Available options: vim @@ -80,6 +86,9 @@ list of executables under PATH and the selected items are executed. Always *fork*(2) before executing the selections. Disabled by default when using the terminal backend. +*--ifne* + Only display menu if there are items. + *--no-exec* Print the selected items to standard output instead of executing them. @@ -93,6 +102,13 @@ list of executables under PATH and the selected items are executed. : Only display a scrollbar when the number of items exceeds the number of lines. +*-e, --vim-esc-exits* + Exit bemenu when pressing escape in normal mode for vim bindings. + +*-F, --filter* + Filter items for a given string before showing the menu. + Affects *--ifne* and *--accept-single* + ## Backend options These options are only available on backends specified in the parentheses: @@ -100,12 +116,30 @@ These options are only available on backends specified in the parentheses: *-b, --bottom* (Wayland, X11) The list will appear at the bottom of the screen. +*-c, --center* (Wayland, X11) + The list will appear at the center of the screen. (wx) + *-f, --grab* (Wayland, X11) Show the *bemenu* window whilst reading the items. +*-B, --border* (Wayland, X11) + Specify the width of the border in pixels around the menu. + +*--bdr* (Wayland, X11) + Specify the border color. + +*-R, --border-radius* (Wayland, X11) + Specify the radius of the border around the menu (0 = no curved borders). + *-H, --line-height* <_height_> (Wayland, X11) Specify the _height_ in point size to make each entry. +*--ch* (Wayland, X11) + Specify the height of the cursor (0 = scales with line height). + +*--cw* (Wayland, X11) + Specify the width of the cursor. + *-m, --monitor* <_index_> (Wayland, X11) Specify the monitor _index_ where the list should appear. Monitor indices start at zero. The interpretation of the given argument depends @@ -123,6 +157,9 @@ These options are only available on backends specified in the parentheses: vertical view borders. *bemenu* will reduce it's size to fit in space between gaps. +*--hp* (Wayland, X11) + Specify the horizontal padding for the entries in single line mode. + *-W, --width-factor* <_factor_> (Wayland, X11) Specify the relative width factor as a floating point number. It makes sense to set it between 0 and 1 to define how much of the screen width