Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package bemenu for openSUSE:Factory checked 
in at 2022-12-16 17:52:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/bemenu (Old)
 and      /work/SRC/openSUSE:Factory/.bemenu.new.1835 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "bemenu"

Fri Dec 16 17:52:14 2022 rev:18 rq:1043312 version:0.6.14

Changes:
--------
--- /work/SRC/openSUSE:Factory/bemenu/bemenu.changes    2022-10-11 
18:04:55.106023567 +0200
+++ /work/SRC/openSUSE:Factory/.bemenu.new.1835/bemenu.changes  2022-12-16 
17:52:19.492239968 +0100
@@ -1,0 +2,9 @@
+Fri Dec 16 10:12:42 UTC 2022 - Michael Vetter <[email protected]>
+
+- Update to 0.6.14:
+  * Add basic vim bindings #314
+  * Make pkg-config configurable #316
+  * improve exit code docs #320
+  * Fix --filter #322
+
+-------------------------------------------------------------------

Old:
----
  bemenu-0.6.13.tar.gz

New:
----
  bemenu-0.6.14.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ bemenu.spec ++++++
--- /var/tmp/diff_new_pack.sFzp31/_old  2022-12-16 17:52:19.928242368 +0100
+++ /var/tmp/diff_new_pack.sFzp31/_new  2022-12-16 17:52:19.936242411 +0100
@@ -18,7 +18,7 @@
 
 %define bcond_with curses
 Name:           bemenu
-Version:        0.6.13
+Version:        0.6.14
 Release:        0
 Summary:        Dynamic menu library and client program inspired by dmenu
 License:        MIT

++++++ bemenu-0.6.13.tar.gz -> bemenu-0.6.14.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bemenu-0.6.13/GNUmakefile 
new/bemenu-0.6.14/GNUmakefile
--- old/bemenu-0.6.13/GNUmakefile       2022-10-11 07:49:11.000000000 +0200
+++ new/bemenu-0.6.14/GNUmakefile       2022-12-16 01:15:13.000000000 +0100
@@ -4,6 +4,7 @@
 bindir ?= /bin
 libdir ?= /lib
 mandir ?= /share/man/man1
+PKG_CONFIG ?= pkg-config
 
 GIT_SHA1 = $(shell git rev-parse HEAD 2>/dev/null || printf 'nogit')
 GIT_TAG = $(shell git tag --points-at HEAD 2>/dev/null || cat VERSION)
@@ -64,18 +65,18 @@
 util.a: lib/util.c lib/internal.h
 
 libbemenu.so: private override LDLIBS += -ldl
-libbemenu.so: lib/bemenu.h lib/internal.h lib/filter.c lib/item.c 
lib/library.c lib/list.c lib/menu.c util.a cdl.a
+libbemenu.so: lib/bemenu.h lib/internal.h lib/filter.c lib/item.c 
lib/library.c lib/list.c lib/menu.c lib/vim.c util.a cdl.a
 
-bemenu-renderer-curses.so: private override LDLIBS += $(shell pkg-config 
--libs ncursesw) -lm
-bemenu-renderer-curses.so: private override CPPFLAGS += $(shell pkg-config 
--cflags-only-I ncursesw)
+bemenu-renderer-curses.so: private override LDLIBS += $(shell $(PKG_CONFIG) 
--libs ncursesw) -lm
+bemenu-renderer-curses.so: private override CPPFLAGS += $(shell $(PKG_CONFIG) 
--cflags-only-I ncursesw)
 bemenu-renderer-curses.so: lib/renderers/curses/curses.c util.a
 
-bemenu-renderer-x11.so: private override LDLIBS += $(shell pkg-config --libs 
x11 xinerama cairo pango pangocairo)
-bemenu-renderer-x11.so: private override CPPFLAGS += $(shell pkg-config 
--cflags-only-I x11 xinerama cairo pango pangocairo)
+bemenu-renderer-x11.so: private override LDLIBS += $(shell $(PKG_CONFIG) 
--libs x11 xinerama cairo pango pangocairo)
+bemenu-renderer-x11.so: private override CPPFLAGS += $(shell $(PKG_CONFIG) 
--cflags-only-I x11 xinerama cairo pango pangocairo)
 bemenu-renderer-x11.so: lib/renderers/cairo_renderer.h lib/renderers/x11/x11.c 
lib/renderers/x11/x11.h lib/renderers/x11/window.c 
lib/renderers/x11/xkb_unicode.c lib/renderers/x11/xkb_unicode.h util.a
 
 lib/renderers/wayland/xdg-shell.c:
-       wayland-scanner private-code < "$$(pkg-config --variable=pkgdatadir 
wayland-protocols)/stable/xdg-shell/xdg-shell.xml" > $@
+       wayland-scanner private-code < "$$($(PKG_CONFIG) --variable=pkgdatadir 
wayland-protocols)/stable/xdg-shell/xdg-shell.xml" > $@
 
 lib/renderers/wayland/wlr-layer-shell-unstable-v1.h: 
lib/renderers/wayland/wlr-layer-shell-unstable-v1.xml
        wayland-scanner client-header < $^ > $@
@@ -90,16 +91,16 @@
        wayland-scanner private-code < $^ > $@
 
 xdg-shell.a: private override LDFLAGS += -fPIC
-xdg-shell.a: private override CPPFLAGS += $(shell pkg-config --cflags-only-I 
wayland-client)
+xdg-shell.a: private override CPPFLAGS += $(shell $(PKG_CONFIG) 
--cflags-only-I wayland-client)
 xdg-shell.a: lib/renderers/wayland/xdg-shell.c
 wlr-layer-shell.a: private override LDFLAGS += -fPIC
-wlr-layer-shell.a: private override CPPFLAGS += $(shell pkg-config 
--cflags-only-I wayland-client)
+wlr-layer-shell.a: private override CPPFLAGS += $(shell $(PKG_CONFIG) 
--cflags-only-I wayland-client)
 wlr-layer-shell.a: lib/renderers/wayland/wlr-layer-shell-unstable-v1.c 
lib/renderers/wayland/wlr-layer-shell-unstable-v1.h
 xdg-output.a: private override LDFLAGS += -fPIC
-xdg-output.a: private override CPPFLAGS += $(shell pkg-config --cflags-only-I 
wayland-client)
+xdg-output.a: private override CPPFLAGS += $(shell $(PKG_CONFIG) 
--cflags-only-I wayland-client)
 xdg-output.a: lib/renderers/wayland/xdg-output-unstable-v1.c 
lib/renderers/wayland/xdg-output-unstable-v1.h
-bemenu-renderer-wayland.so: private override LDLIBS += $(shell pkg-config 
--libs wayland-client cairo pango pangocairo xkbcommon)
-bemenu-renderer-wayland.so: private override CPPFLAGS += $(shell pkg-config 
--cflags-only-I wayland-client cairo pango pangocairo xkbcommon)
+bemenu-renderer-wayland.so: private override LDLIBS += $(shell $(PKG_CONFIG) 
--libs wayland-client cairo pango pangocairo xkbcommon)
+bemenu-renderer-wayland.so: private override CPPFLAGS += $(shell $(PKG_CONFIG) 
--cflags-only-I wayland-client cairo pango pangocairo xkbcommon)
 bemenu-renderer-wayland.so: lib/renderers/cairo_renderer.h 
lib/renderers/wayland/wayland.c lib/renderers/wayland/wayland.h 
lib/renderers/wayland/registry.c lib/renderers/wayland/window.c xdg-shell.a 
wlr-layer-shell.a xdg-output.a util.a
 
 common.a: client/common/common.c client/common/common.h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bemenu-0.6.13/README.md new/bemenu-0.6.14/README.md
--- old/bemenu-0.6.13/README.md 2022-10-11 07:49:11.000000000 +0200
+++ new/bemenu-0.6.14/README.md 2022-12-16 01:15:13.000000000 +0100
@@ -112,7 +112,7 @@
 
 ## Keybindings
 
-
+### Default Bindings
 |         Key         |                             Binding                    
        |
 
|---------------------|----------------------------------------------------------------|
 | Left Arrow          |  Move cursor left                                      
        |
@@ -159,6 +159,51 @@
 | Ctrl + m            |  Execute selected item                                 
        |
 | Ctrl + y            |  Paste clipboard                                       
        |
 
+### Vim Bindings
+Vim bindings can be activated via the `--binding vim` option. All bindings are 
in vim
+`normal` mode. When bemenu is started with vim bindings it will be in `insert` 
mode. By 
+pressing `escape`, `normal` mode can be activated.
+
+**Note**: The default bindings can still be used for actions that do not have 
a separate
+vim binding such as launching a program or pasting.
+
+|  Key  |                    Binding                    |
+|-------|-----------------------------------------------|
+|  j/n  | Goto next item                                |
+|  k/p  | Goto previous item                            |
+|  h    | Move cursor left                              |
+|  l    | Move cursor right                             |
+|  q    | Quit bemenu                                   |
+|  v    | Toggle item selection                         |
+|  i    | Enter insert mode                             |
+|  I    | Move to line start and enter insert mode      |
+|  a    | Move to the right and enter insert mode       |
+|  A    | Move to line end and enter insert mode        |
+|  w    | Move a word                                   |
+|  b    | Move a word backwards                         |
+|  e    | Move to end of word                           |
+|  x    | Delete a character                            |
+|  X    | Delete a character before the cursor          |
+|  0    | Move to line start                            |
+|  $    | Move to line end                              |
+|  gg   | Goto first item                               |
+|  G    | Goto last item                                |
+|  H    | Goto first item in view                       |
+|  M    | Goto middle item in view                      |
+|  L    | Goto last item in view                        |
+|  F    | Scroll one page of items down                 |
+|  B    | Scroll one page of items up                   |
+|  dd   | Delete the whole line                         |
+|  dw   | Delete a word                                 |
+|  db   | Delete a word backwards                       |
+|  d0   | Delete to start of line                       |
+|  d$   | Delete to end of line                         |
+|  cc   | Change the whole line                         |
+|  cw   | Change a word                                 |
+|  cb   | Change a word backwards                       |
+|  c0   | Change to start of line                       |
+|  c$   | Change to end of line                         |
+
 ## Projects using bemenu
 
 * [pinentry-bemenu](https://github.com/t-8ch/pinentry-bemenu)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bemenu-0.6.13/VERSION new/bemenu-0.6.14/VERSION
--- old/bemenu-0.6.13/VERSION   2022-10-11 07:49:11.000000000 +0200
+++ new/bemenu-0.6.14/VERSION   2022-12-16 01:15:13.000000000 +0100
@@ -1 +1 @@
-0.6.13
+0.6.14
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bemenu-0.6.13/client/common/common.c 
new/bemenu-0.6.14/client/common/common.c
--- old/bemenu-0.6.13/client/common/common.c    2022-10-11 07:49:11.000000000 
+0200
+++ new/bemenu-0.6.14/client/common/common.c    2022-12-16 01:15:13.000000000 
+0100
@@ -181,6 +181,7 @@
           " -C, --no-cursor       ignore cursor events.\n"
           " -T, --no-touch        ignore touch events.\n"
           " -K, --no-keyboard     ignore keyboard events.\n"
+          " --binding             use alternative key bindings. Available 
options: vim\n"
           " --scrollbar           display scrollbar. (none (default), always, 
autohide)\n"
           " --accept-single       immediately return if there is only one 
item.\n"
           " --ifne                only display menu if there are items.\n"
@@ -308,6 +309,7 @@
         { "scb",          required_argument, 0, 0x114 },
         { "scf",          required_argument, 0, 0x115 },
         { "bdr",          required_argument, 0, 0x121 },
+        { "binding",      required_argument, 0, 0x128 },
 
         { "disco",       no_argument,       0, 0x116 },
         { 0, 0, 0, 0 }
@@ -320,7 +322,7 @@
     for (optind = 0;;) {
         int32_t opt;
 
-        if ((opt = getopt_long(*argc, *argv, 
"hviwxcl:I:p:P:I:bfm:H:M:W:B:nsCTK", opts, NULL)) < 0)
+        if ((opt = getopt_long(*argc, *argv, 
"hviwxcl:I:p:P:I:bfF:m:H:M:W:B:nsCTK", opts, NULL)) < 0)
             break;
 
         switch (opt) {
@@ -479,6 +481,13 @@
             case 0x121:
                 client->colors[BM_COLOR_BORDER] = optarg;
                 break;
+            case 0x128:
+                if(strcmp(optarg, "vim") == 0){
+                    client->key_binding = BM_KEY_BINDING_VIM;
+                } else {
+                    client->key_binding = BM_KEY_BINDING_DEFAULT;
+                }
+                break;
 
             case 0x116:
                 disco();
@@ -534,6 +543,7 @@
     bm_menu_set_password(menu, client->password);
     bm_menu_set_width(menu, client->hmargin_size, client->width_factor);
     bm_menu_set_border_size(menu, client->border_size);
+    bm_menu_set_key_binding(menu, client->key_binding);
 
     if (client->center) {
         bm_menu_set_align(menu, BM_ALIGN_CENTER);
@@ -559,6 +569,10 @@
 enum bm_run_result
 run_menu(const struct client *client, struct bm_menu *menu, void 
(*item_cb)(const struct client *client, struct bm_item *item))
 {
+    bm_menu_set_highlighted_index(menu, client->selected);
+    bm_menu_grab_keyboard(menu, true);
+    bm_menu_set_filter(menu, client->initial_filter);
+
     {
     uint32_t total_item_count;
     struct bm_item **items = bm_menu_get_items(menu, &total_item_count);
@@ -574,10 +588,6 @@
 
     }
 
-    bm_menu_set_highlighted_index(menu, client->selected);
-    bm_menu_grab_keyboard(menu, true);
-    bm_menu_set_filter(menu, client->initial_filter);
-
     uint32_t unicode;
     enum bm_key key = BM_KEY_NONE;
     struct bm_pointer pointer;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bemenu-0.6.13/client/common/common.h 
new/bemenu-0.6.14/client/common/common.h
--- old/bemenu-0.6.13/client/common/common.h    2022-10-11 07:49:11.000000000 
+0200
+++ new/bemenu-0.6.14/client/common/common.h    2022-12-16 01:15:13.000000000 
+0100
@@ -36,6 +36,7 @@
     bool force_fork, fork;
     bool no_exec;
     bool password;
+    enum bm_key_binding key_binding;
     char *monitor_name;
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bemenu-0.6.13/lib/bemenu.h 
new/bemenu-0.6.14/lib/bemenu.h
--- old/bemenu-0.6.13/lib/bemenu.h      2022-10-11 07:49:11.000000000 +0200
+++ new/bemenu-0.6.14/lib/bemenu.h      2022-12-16 01:15:13.000000000 +0100
@@ -353,6 +353,16 @@
     BM_COLOR_LAST
 };
 
+
+/**
+ * Key bindings
+ */
+enum bm_key_binding {
+    BM_KEY_BINDING_DEFAULT,
+    BM_KEY_BINDING_VIM,
+};
+
+
 /**
  * @name Menu Memory
  * @{ */
@@ -788,6 +798,15 @@
 BM_PUBLIC bool bm_menu_get_password(struct bm_menu *menu);
 
 
+/**
+ * Specify the key bindings that should be used. 
+ *
+ * @param menu bm_menu instance to set the key binding on.
+ * @param key_binding binding that should be used.
+ */
+BM_PUBLIC void bm_menu_set_key_binding(struct bm_menu *menu, enum 
bm_key_binding);
+
+
 /**  @} Properties */
 
 /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bemenu-0.6.13/lib/internal.h 
new/bemenu-0.6.14/lib/internal.h
--- old/bemenu-0.6.13/lib/internal.h    2022-10-11 07:49:11.000000000 +0200
+++ new/bemenu-0.6.14/lib/internal.h    2022-12-16 01:15:13.000000000 +0100
@@ -411,6 +411,17 @@
      * Is the menu needing a redraw ?
      */
     bool dirty;
+
+    /**
+     * Key binding that should be used.
+     */
+    enum bm_key_binding key_binding;
+
+    /**
+     * Vim binding specific variables.
+     */
+    char vim_mode;
+    uint32_t vim_last_key;
 };
 
 /* library.c */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bemenu-0.6.13/lib/menu.c new/bemenu-0.6.14/lib/menu.c
--- old/bemenu-0.6.13/lib/menu.c        2022-10-11 07:49:11.000000000 +0200
+++ new/bemenu-0.6.14/lib/menu.c        2022-12-16 01:15:13.000000000 +0100
@@ -6,6 +6,8 @@
 #include <unistd.h>
 #include <assert.h>
 
+#include "vim.h"
+
 /**
  * Default font.
  */
@@ -53,6 +55,10 @@
 
     menu->dirty = true;
 
+    menu->key_binding = BM_KEY_BINDING_DEFAULT;
+    menu->vim_mode = 'i';
+    menu->vim_last_key = 0;
+
     uint32_t count;
     const struct bm_renderer **renderers = bm_get_renderers(&count);
 
@@ -683,6 +689,11 @@
     return list_set_items_no_copy(&menu->selection, new_items, nmemb);
 }
 
+void
+bm_menu_set_key_binding(struct bm_menu *menu, enum bm_key_binding key_binding){
+    menu->key_binding = key_binding;
+}
+
 struct bm_item**
 bm_menu_get_selected_items(const struct bm_menu *menu, uint32_t *out_nmemb)
 {
@@ -939,6 +950,20 @@
     if (key != BM_KEY_NONE)
         menu->dirty = true;
 
+    if(menu->key_binding == BM_KEY_BINDING_VIM){
+        enum bm_vim_code code = bm_vim_key_press(menu, key, unicode, count, 
displayed);
+
+        switch(code){
+            case BM_VIM_CONSUME:
+                return BM_RUN_RESULT_RUNNING;
+            case BM_VIM_EXIT:
+                list_free_list(&menu->selection);
+                return BM_RUN_RESULT_CANCEL;
+            case BM_VIM_IGNORE:
+                break;
+        }
+    }
+
     switch (key) {
         case BM_KEY_LEFT:
             if (menu->filter) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bemenu-0.6.13/lib/renderers/wayland/wayland.c 
new/bemenu-0.6.14/lib/renderers/wayland/wayland.c
--- old/bemenu-0.6.13/lib/renderers/wayland/wayland.c   2022-10-11 
07:49:11.000000000 +0200
+++ new/bemenu-0.6.14/lib/renderers/wayland/wayland.c   2022-12-16 
01:15:13.000000000 +0100
@@ -54,7 +54,8 @@
             // be(re)created. We need to do the render ASAP (not schedule it) 
because otherwise,
             // since we lack a window, we may not receive further events and 
will get deadlocked
             render_windows_if_pending(menu, wayland);
-        } else if (menu->dirty) {
+        }
+        if (menu->dirty) {
             bm_wl_window_schedule_render(window);
         }
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bemenu-0.6.13/lib/vim.c new/bemenu-0.6.14/lib/vim.c
--- old/bemenu-0.6.13/lib/vim.c 1970-01-01 01:00:00.000000000 +0100
+++ new/bemenu-0.6.14/lib/vim.c 2022-12-16 01:15:13.000000000 +0100
@@ -0,0 +1,368 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include "vim.h"
+
+
+static enum bm_vim_code vim_on_first_key(struct bm_menu *menu, uint32_t 
unicode, uint32_t item_count, uint32_t items_displayed);
+static enum bm_vim_code vim_on_second_key(struct bm_menu *menu, uint32_t 
unicode, uint32_t item_count, uint32_t items_displayed);
+
+
+static void move_left(struct bm_menu *menu){
+    if(menu->filter && menu->cursor > 0){
+        uint32_t old_cursor = menu->cursor;
+        menu->cursor -= bm_utf8_rune_prev(menu->filter, menu->cursor);
+        menu->curses_cursor -= bm_utf8_rune_width(menu->filter + menu->cursor, 
old_cursor - menu->cursor);
+    }
+}
+
+static void move_right(struct bm_menu *menu, size_t filter_length){
+    if(menu->cursor < filter_length){
+        uint32_t old_cursor = menu->cursor;
+        menu->cursor += bm_utf8_rune_next(menu->filter, menu->cursor);
+        menu->curses_cursor += bm_utf8_rune_width(menu->filter + old_cursor, 
menu->cursor - old_cursor);
+    }
+}
+
+static void move_line_start(struct bm_menu *menu){
+    menu->cursor = 0;
+    menu->curses_cursor = 0;
+}
+
+static void move_line_end(struct bm_menu *menu){
+    menu->cursor = (menu->filter ? strlen(menu->filter) : 0);
+    menu->curses_cursor = (menu->filter ? 
bm_utf8_string_screen_width(menu->filter) : 0);
+}
+
+static void menu_next(struct bm_menu *menu, uint32_t count, bool wrap){
+    if (menu->index < count - 1) {
+        bm_menu_set_highlighted_index(menu, menu->index + 1);
+    } else if (wrap) {
+        bm_menu_set_highlighted_index(menu, 0);
+    }
+}
+
+static void menu_prev(struct bm_menu *menu, uint32_t count, bool wrap){
+    if (menu->index > 0) {
+        bm_menu_set_highlighted_index(menu, menu->index - 1);
+    } else if (wrap) {
+        bm_menu_set_highlighted_index(menu, count - 1);
+    }
+}
+
+static void menu_first(struct bm_menu *menu, uint32_t count){
+    if(count > 0){
+        bm_menu_set_highlighted_index(menu, 0);
+    }
+}
+
+static void menu_last(struct bm_menu *menu, uint32_t count){
+    if(count > 0){
+        bm_menu_set_highlighted_index(menu, count - 1);
+    }
+}
+
+static void menu_view_high(struct bm_menu *menu, uint32_t count){
+    if(count > 0){
+        uint32_t nth_view_item = menu->index % menu->lines;
+        bm_menu_set_highlighted_index(menu, menu->index - nth_view_item);
+    }
+}
+
+static void menu_view_mid(struct bm_menu *menu, uint32_t count, uint32_t 
displayed){
+    if(count > 0){
+        uint32_t nth_view_item = menu->index % menu->lines;
+        uint32_t half_view_height = (displayed - 1) / 2;
+        bm_menu_set_highlighted_index(menu, menu->index - nth_view_item + 
half_view_height);
+    }
+}
+
+static void menu_view_low(struct bm_menu *menu, uint32_t count, uint32_t 
displayed){
+    if(count > 0){
+        uint32_t nth_view_item = menu->index % menu->lines;
+        uint32_t view_bottom_offset = (displayed - 2) - nth_view_item;
+        bm_menu_set_highlighted_index(menu, menu->index + view_bottom_offset);
+    }
+}
+
+static void menu_page_down(struct bm_menu *menu, uint32_t count, uint32_t 
displayed){
+    bm_menu_set_highlighted_index(menu, (menu->index + displayed >= count ? 
count - 1 : menu->index + (displayed - 1)));
+}
+
+static void menu_page_up(struct bm_menu *menu, uint32_t displayed){
+    bm_menu_set_highlighted_index(menu, (menu->index < displayed ? 0 : 
menu->index - (displayed - 1)));
+}
+
+static void move_word(struct bm_menu *menu){
+    if(!menu->filter) return;
+
+    size_t filter_length = strlen(menu->filter);
+    while (menu->cursor < filter_length && 
!isspace(menu->filter[menu->cursor])) move_right(menu, filter_length);
+    while (menu->cursor < filter_length && 
isspace(menu->filter[menu->cursor])) move_right(menu, filter_length);
+}
+
+static void move_word_back(struct bm_menu *menu){
+    while (menu->cursor > 0 && isspace(menu->filter[menu->cursor - 1])) 
move_left(menu);
+    while (menu->cursor > 0 && !isspace(menu->filter[menu->cursor - 1])) 
move_left(menu);
+}
+
+static void move_word_end(struct bm_menu *menu){
+    if(!menu->filter) return;
+
+    size_t filter_length = strlen(menu->filter);
+    size_t old_cursor = menu->cursor;
+    size_t old_curses_cursor = menu->curses_cursor;
+
+    while (menu->cursor < filter_length && isspace(menu->filter[menu->cursor + 
1])) move_right(menu, filter_length);
+    while (menu->cursor < filter_length && !isspace(menu->filter[menu->cursor 
+ 1])) move_right(menu, filter_length);
+
+    if(menu->cursor == filter_length){
+        menu->cursor = old_cursor;
+        menu->curses_cursor = old_curses_cursor;
+    }
+}
+
+static void delete_char(struct bm_menu *menu){
+    if(menu->filter){
+        if(menu->cursor < strlen(menu->filter)){
+            size_t width;
+            bm_utf8_rune_remove(menu->filter, menu->cursor + 1, &width);
+        }
+    }
+}
+
+static void delete_char_back(struct bm_menu *menu){
+    if(menu->filter){
+        if(menu->cursor > 0){
+            size_t width;
+            bm_utf8_rune_remove(menu->filter, menu->cursor, &width);
+            move_left(menu);
+        }
+    }
+}
+
+static void delete_word(struct bm_menu *menu){
+    if(!menu->filter) return;
+
+    size_t filter_length = strlen(menu->filter);
+    while (menu->cursor < filter_length && 
!isspace(menu->filter[menu->cursor])) delete_char(menu);
+    while (menu->cursor < filter_length && 
isspace(menu->filter[menu->cursor])) delete_char(menu);
+}
+
+static void delete_word_back(struct bm_menu *menu){
+    while (menu->cursor > 0 && isspace(menu->filter[menu->cursor - 1])){
+        move_left(menu);
+        delete_char(menu);
+    }
+
+    while (menu->cursor > 0 && !isspace(menu->filter[menu->cursor - 1])){
+        move_left(menu);
+        delete_char(menu);
+    } 
+}
+
+static void delete_line(struct bm_menu *menu){
+    if(menu->filter){
+        menu->filter[0] = 0;
+        menu->cursor = 0;
+        menu->curses_cursor = 0;
+    }
+}
+
+static void delete_to_line_end(struct bm_menu *menu){
+    if(menu->filter){
+        menu->filter[menu->cursor] = 0;
+    }
+}
+
+static void delete_to_line_start(struct bm_menu *menu){
+    if(menu->filter){
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wrestrict"
+        strcpy(menu->filter, menu->filter + menu->cursor);
+#pragma GCC diagnostic pop
+
+        menu->cursor = 0;
+        menu->curses_cursor = 0;
+    }
+}
+
+static void toggle_item_selection(struct bm_menu *menu){
+    struct bm_item *highlighted = bm_menu_get_highlighted_item(menu);
+    if (highlighted){
+        if(!bm_menu_item_is_selected(menu, highlighted)){
+            list_add_item(&menu->selection, highlighted);
+        } else {
+            list_remove_item(&menu->selection, highlighted);
+        }
+    }
+}
+
+enum bm_vim_code bm_vim_key_press(struct bm_menu *menu, enum bm_key key, 
uint32_t unicode, uint32_t item_count, uint32_t items_displayed){
+    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(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);
+        else return vim_on_second_key(menu, unicode, item_count, 
items_displayed);
+    } else if(menu->vim_mode == 'i'){
+        if(key == BM_KEY_ESCAPE && unicode == 0){
+            menu->vim_mode = 'n';
+            return BM_VIM_CONSUME;
+        }
+    }
+
+    return BM_VIM_IGNORE;
+}
+
+static enum bm_vim_code vim_on_first_key(struct bm_menu *menu, uint32_t 
unicode, uint32_t item_count, uint32_t items_displayed){
+    size_t filter_length = 0;
+
+    switch(unicode){
+        case 'q':
+            return BM_VIM_EXIT;
+        case 'v':
+            toggle_item_selection(menu);
+            goto action_executed;
+        case 'i':
+            goto insert_action_executed;
+        case 'I':
+            move_line_start(menu);
+            goto insert_action_executed;
+        case 'a':
+            if(menu->filter) filter_length = strlen(menu->filter);
+            move_right(menu, filter_length);
+            goto insert_action_executed;
+        case 'A':
+            move_line_end(menu);
+            goto insert_action_executed;
+        case 'h':
+            move_left(menu);
+            goto action_executed;
+        case 'n':
+        case 'j':
+            menu_next(menu, item_count, menu->wrap);
+            goto action_executed;
+        case 'p':
+        case 'k':
+            menu_prev(menu, item_count, menu->wrap);
+            goto action_executed;
+        case 'l':
+            if(menu->filter) filter_length = strlen(menu->filter);
+            move_right(menu, filter_length);
+            goto action_executed;
+        case 'w':
+            move_word(menu);
+            goto action_executed;
+        case 'b':
+            move_word_back(menu);
+            goto action_executed;
+        case 'e':
+            move_word_end(menu);
+            goto action_executed;
+        case 'x':
+            delete_char(menu);
+            goto action_executed;
+        case 'X':
+            delete_char_back(menu);
+            goto action_executed;
+        case '0':
+            move_line_start(menu);
+            goto action_executed;
+        case '$':
+            move_line_end(menu);
+            goto action_executed;
+        case 'G':
+            menu_last(menu, item_count);
+            goto action_executed;
+        case 'H':
+            menu_view_high(menu, item_count);
+            goto action_executed;
+        case 'M':
+            menu_view_mid(menu, item_count, items_displayed);
+            goto action_executed;
+        case 'L':
+            menu_view_low(menu, item_count, items_displayed);
+            goto action_executed;
+        case 'F':
+            menu_page_down(menu, item_count, items_displayed);
+            goto action_executed;
+        case 'B':
+            menu_page_up(menu, items_displayed);
+            goto action_executed;
+        case 'c':
+        case 'd':
+        case 'g':
+            menu->vim_last_key = unicode;
+            return BM_VIM_CONSUME;
+        default:
+            menu->vim_last_key = 0;
+            return BM_VIM_CONSUME;
+    }
+
+insert_action_executed:
+    menu->vim_mode = 'i';
+action_executed:
+    menu->vim_last_key = 0;
+    return BM_VIM_CONSUME;
+}
+
+static enum bm_vim_code vim_on_second_key(struct bm_menu *menu, uint32_t 
unicode, uint32_t item_count, uint32_t items_displayed){
+    if(menu->vim_last_key == 'd'){
+        switch(unicode){
+            case 'd':
+                delete_line(menu);
+                goto action_executed;
+            case 'w':
+                delete_word(menu);
+                goto action_executed;
+            case 'b':
+                delete_word_back(menu);
+                goto action_executed;
+            case '$':
+                delete_to_line_end(menu);
+                goto action_executed;
+            case '0':
+                delete_to_line_start(menu);
+                goto action_executed;
+        }
+    } else if(menu->vim_last_key == 'c'){
+        switch(unicode){
+            case 'c':
+                delete_line(menu);
+                goto insert_action_executed;
+            case 'w':
+                delete_word(menu);
+                goto insert_action_executed;
+            case 'b':
+                delete_word_back(menu);
+                goto insert_action_executed;
+            case '$':
+                delete_to_line_end(menu);
+                goto insert_action_executed;
+            case '0':
+                delete_to_line_start(menu);
+                goto insert_action_executed;
+        }
+    } else if(menu->vim_last_key == 'g'){
+        switch(unicode){
+            case 'g':
+                menu_first(menu, item_count);
+                goto action_executed;
+        }
+    }
+
+    return vim_on_first_key(menu, unicode, item_count, items_displayed);
+
+insert_action_executed:
+    menu->vim_mode = 'i';
+action_executed:
+    menu->vim_last_key = 0;
+    return BM_VIM_CONSUME;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bemenu-0.6.13/lib/vim.h new/bemenu-0.6.14/lib/vim.h
--- old/bemenu-0.6.13/lib/vim.h 1970-01-01 01:00:00.000000000 +0100
+++ new/bemenu-0.6.14/lib/vim.h 2022-12-16 01:15:13.000000000 +0100
@@ -0,0 +1,14 @@
+#ifndef _VIM_H_
+#define _VIM_H_
+
+#include "internal.h"
+
+enum bm_vim_code {
+    BM_VIM_CONSUME,
+    BM_VIM_IGNORE,
+    BM_VIM_EXIT
+};
+
+enum bm_vim_code bm_vim_key_press(struct bm_menu *menu, enum bm_key key, 
uint32_t unicode, uint32_t item_count, uint32_t items_displayed);
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bemenu-0.6.13/man/bemenu.1.scd.in 
new/bemenu-0.6.14/man/bemenu.1.scd.in
--- old/bemenu-0.6.13/man/bemenu.1.scd.in       2022-10-11 07:49:11.000000000 
+0200
+++ new/bemenu-0.6.14/man/bemenu.1.scd.in       2022-12-16 01:15:13.000000000 
+0100
@@ -234,9 +234,13 @@
 *C-y*
        Paste the clipboard.
 
-*M-[0-9]*
-       Print selected items and exit with a custom error code. See _EXIT
-       STATUS_.
+*M-[1-9]*
+       Print selected items and exit with a custom error code 10 (*M-1*)
+        through 18 (*M-9*), see _EXIT STATUS_.
+
+*M-0*
+       Print selected items and exit with the custom error code 19, see _EXIT
+        STATUS_.
 
 # ENVIRONMENT
 
@@ -256,8 +260,15 @@
 
 # EXIT STATUS
 
-*bemenu* exits 0 on success, 1 if the user exited without selecting or an 
error,
-and if exiting with a custom error code, 10 plus the number specified.
+*0*
+       bemenu ran successfully.
+
+*1*
+       The user exited without selecting, or bemenu encountered an error.
+
+*10-19*
+       The user specified a custom exit code with *M-[0-9]*, see _KEYBOARD
+       COMMANDS_.
 
 # SEE ALSO
 

Reply via email to