]> git.neil.brown.name Git - edlib.git/commitdiff
keymap: add key_add_prefix()
authorNeilBrown <neil@brown.name>
Tue, 1 Oct 2019 10:45:51 +0000 (20:45 +1000)
committerNeilBrown <neil@brown.name>
Tue, 1 Oct 2019 10:45:51 +0000 (20:45 +1000)
This is similar to key_add_range(), but the end of the range
is automatically generated to be the last thing that
could (reasonably) start with given prefix.

Signed-off-by: NeilBrown <neil@brown.name>
13 files changed:
DOC/TODO.md
core-doc.c
core-editor.c
core-keymap.c
core.h
doc-multipart.c
lang-python.c
lib-crop.c
lib-input.c
python/module-notmuch.py
python/render-present.py
render-complete.c
render-lines.c

index 98c418c0bed4e2cd5c962a3a834fc8feced1f53f..069a9ed19d1b5e967393efb6466fa1d0aba2e104 100644 (file)
@@ -61,7 +61,7 @@ Core features
       K:M:C:Up  is Meta-Control-Up
       K:M:C-U   is Meta-Control-U
       K:Cx-f    is Control-X f -- assuming K:C-x causes Cx to be set as prefix.
-- [ ] add key_add_prefix()
+- [X] add key_add_prefix()
 - [ ]  ?? restrict prefix key lookup to punctuation.
 
       Current ranges are:
@@ -185,6 +185,7 @@ Module features
 
 ### grep/make
 
+- [ ] leave marks at every match as soon as possible
 - [ ] clarify and document the role of numeric args to git-grep
 - [ ] make/grep - when insert at end-of-file, a pointer that was at EOF should
       stay there.
index 64f56527db48e52153c03df2f15335601f58de3c..c5afec5a18f7628ca8f2dd0605bbb106dd9d5292 100644 (file)
@@ -978,7 +978,7 @@ static void init_doc_cmds(void)
        doc_default_cmd = key_alloc();
        doc_handle_cmd = key_alloc();
 
-       key_add_range(doc_handle_cmd, "doc:", "doc;", &doc_pass_on);
+       key_add_prefix(doc_handle_cmd, "doc:", &doc_pass_on);
 
        key_add(doc_handle_cmd, "Move-Char", &doc_char);
        key_add(doc_handle_cmd, "Move-Word", &doc_word);
@@ -1015,12 +1015,9 @@ static void init_doc_cmds(void)
        key_add(doc_default_cmd, "doc:pop-point", &doc_pop_point);
        key_add(doc_default_cmd, "doc:attach-view", &doc_attach_view);
 
-       key_add_range(doc_default_cmd, "doc:Request:Notify:", "doc:Request:Notify;",
-                     &doc_request_notify);
-       key_add_range(doc_default_cmd, "doc:Notify:", "doc:Notify;",
-                     &doc_notify);
-       key_add_range(doc_default_cmd, "doc:set:", "doc:set;",
-                     &doc_set);
+       key_add_prefix(doc_default_cmd, "doc:Request:Notify:", &doc_request_notify);
+       key_add_prefix(doc_default_cmd, "doc:Notify:", &doc_notify);
+       key_add_prefix(doc_default_cmd, "doc:set:", &doc_set);
 }
 
 static void do_doc_assign(struct pane *p safe, struct pane *doc safe)
index e0b75524b3d8298949e267b15d3f2ccabcd82070..f62c4f9b86ceb759eca784f00194222b2f627a20 100644 (file)
@@ -346,14 +346,13 @@ struct pane *editor_new(void)
                key_add(ed_map, "global-get-command", &global_get_command);
                key_add(ed_map, "global-load-module", &editor_load_module);
                key_add(ed_map, "editor-on-idle", &editor_on_idle);
-               key_add_range(ed_map, "attach-", "attach.", &editor_auto_load);
-               key_add_range(ed_map, "event:", "event;", &editor_auto_event);
-               key_add_range(ed_map, "global-multicall-", "global-multicall.",
-                             &editor_multicall);
-               key_add_range(ed_map, "Request:Notify:global-", "Request:Notify:global.",
-                             &editor_global_request_notify);
-               key_add_range(ed_map, "Call:Notify:global-", "Call:Notify:global.",
-                             &editor_global_notify);
+               key_add_prefix(ed_map, "attach-", &editor_auto_load);
+               key_add_prefix(ed_map, "event:", &editor_auto_event);
+               key_add_prefix(ed_map, "global-multicall-", &editor_multicall);
+               key_add_prefix(ed_map, "Request:Notify:global-",
+                              &editor_global_request_notify);
+               key_add_prefix(ed_map, "Call:Notify:global-",
+                              &editor_global_notify);
                key_add(ed_map, "Close", &editor_close);
        }
        ei->map = key_alloc();
index 6fb5e0d3907416eaee95329ecbed5441b2d1c8af..0888cc22df063515aa61c6f81189dca37123c479 100644 (file)
@@ -7,7 +7,7 @@
  * A keymap maps a key to a command.
  * Keys are ordered for fast binary-search lookup.
  * A "key" is an arbitrary string which typically contains
- * some 'mode' pr efix and some specific tail.
+ * some 'mode' prefix and some specific tail.
  * e.g emacs-M-C-Chr-x is Meta-Control-X in emacs mode.
  * As far as the map is concerned, it is just a lexically order string.
  *
@@ -24,7 +24,7 @@
  * lsb clear.
  *
  * If a key is registered a second time, the new over-rides the old.
- * This is particularly useful for registering a range, and then some exception.
+ * This is particularly useful for registering a range, and then some exceptions.
  * To delete a key from a range we need to make two ranges, one that ends
  * just before the new key, one that starts just after.
  * The 'ends just before' is easy - we just add the new key or range.
@@ -255,7 +255,8 @@ void key_add_range(struct map *map safe, char *first safe, char *last safe,
         * Then insert a stand-alone for 'last' and update 'pos' to be a range-start.
         */
        if (pos2 - 1 > pos && IS_RANGE(map->comms[pos2-1])) {
-               map->keys[pos2-1] = last;
+               free(map->keys[pos2-1]);
+               map->keys[pos2-1] = strdup(last);
                pos2 -= 1;
        }
        /* Need to insert 'last', and remove extras. so +1 and -(pos2-pos-1); */
diff --git a/core.h b/core.h
index 8310322de133f8ed2a66a39847a2e5938f36bc82..cbee09938fb4b81d77e601d8d19a1c5bbeabb31a 100644 (file)
--- a/core.h
+++ b/core.h
@@ -128,7 +128,7 @@ void * safe memsave(struct pane *p safe, char *buf, int len);
 char *strsave(struct pane *p safe, char *buf);
 char *strnsave(struct pane *p safe, char *buf, int len);
 char * safe __strconcat(struct pane *p safe, char *s1 safe, ...);
-#define strconcat(p, s1, ...) __strconcat(p, s1, __VA_ARGS__, NULL)
+#define strconcat(p, ...) __strconcat(p, __VA_ARGS__, NULL)
 
 /* This is declared here so sparse knows it is global */
 void edlib_init(struct pane *ed safe);
@@ -340,6 +340,8 @@ struct command *key_lookup_cmd(struct map *m safe, char *c safe, char **cret, in
 void key_add(struct map *map safe, char *k safe, struct command *comm);
 void key_add_range(struct map *map safe, char *first safe, char *last safe,
                   struct command *comm);
+#define key_add_prefix(map, prefix, comm) \
+       key_add_range(map, prefix, prefix "\xFF\xFF\xFF\xFF", comm)
 void key_add_chain(struct map *map safe, struct map *chain);
 struct command *key_register_prefix(char *name safe);
 
index 3f838ec8c2fe8c771d9b3941fa920b11efa4cb0c..57c50a2fcb60966539a947bf337284614f7ae2c5 100644 (file)
@@ -546,9 +546,9 @@ static void mp_init_map(void)
        key_add(mp_map, "Notify:Close", &mp_notify_close);
        key_add(mp_map, "Notify:doc:viewers", &mp_notify_viewers);
        key_add(mp_map, "multipart-add", &mp_add);
-       key_add_range(mp_map, "multipart-this:", "multipart-this;", &mp_forward);
-       key_add_range(mp_map, "multipart-next:", "multipart-next;", &mp_forward);
-       key_add_range(mp_map, "multipart-prev:", "multipart-prev;", &mp_forward);
+       key_add_prefix(mp_map, "multipart-this:", &mp_forward);
+       key_add_prefix(mp_map, "multipart-next:", &mp_forward);
+       key_add_prefix(mp_map, "multipart-prev:", &mp_forward);
 }
 DEF_LOOKUP_CMD(mp_handle, mp_map);
 
index 3b9bb4afb2b165135c84631ca69d680d2ca630e9..9b7cffd54019577217d38847ece289ea2ddfd2b9 100644 (file)
@@ -369,7 +369,7 @@ static void do_map_init(Pane *self safe)
        PyObject *l = PyObject_Dir(refer);
        int n = PyList_Size(l);
 
-       if (!self->map)
+       if (!self->map || !self->pane)
                return;
        for (i = 0; i < n ; i++) {
                PyObject *e = PyList_GetItem(l, i);
@@ -415,6 +415,22 @@ static void do_map_init(Pane *self safe)
                                                command_put(&comm->c);
                                        }
                                }
+                               if (docs &&
+                                   strncmp(docs, "handle-prefix:", 14) == 0) {
+                                       char *a = strconcat(self->pane, docs+14);
+                                       char *b = strconcat(self->pane,
+                                                           a, "\xFF\xFF\xFF\xFF");
+                                       struct python_command *comm =
+                                               malloc(sizeof(*comm));
+                                       comm->c = python_call;
+                                       comm->c.free = python_free_command;
+                                       command_get(&comm->c);
+                                       Py_INCREF(m);
+                                       comm->callable = m;
+                                       key_add_range(self->map, a, b,
+                                                             &comm->c);
+                                       command_put(&comm->c);
+                               }
                                if (docs &&
                                    strncmp(docs, "handle-list", 11) == 0 &&
                                    docs[11]) {
index 4a2b643f349e8026d77ce3219d7246a65eff2cc5..2ef1a80812340cdd508296ebf7a85d45b9b693b1 100644 (file)
@@ -176,7 +176,7 @@ void edlib_init(struct pane *ed safe)
        if ((void*)crop_map)
                return;
        crop_map = key_alloc();
-       key_add_range(crop_map, "doc:", "doc;", &crop_generic);
+       key_add_prefix(crop_map, "doc:", &crop_generic);
        key_add(crop_map, "Close", &crop_close);
        key_add(crop_map, "doc:write_file", &crop_write);
        key_add(crop_map, "doc:step", &crop_step);
index 1ae55d39b26be92dc94556ffc857f5157b17e9dc..a8b92db37bf0ee920cbabbc142453cb101138422 100644 (file)
@@ -221,7 +221,7 @@ static void register_map(void)
        key_add(im_map, "Mode:set-num2", &set_num2);
        key_add(im_map, "pane:refocus", &refocus);
        key_add(im_map, "Notify:Close", &close_focus);
-       key_add_range(im_map, "Request:Notify:", "Request:Notify;", &request_notify);
+       key_add_prefix(im_map, "Request:Notify:", &request_notify);
 }
 
 DEF_LOOKUP_CMD(input_handle, im_map);
index 0c99fb91c7ef266ef6a852dcdee106ecc24e008f..2a71b2bfcfa41416c5d1099d137a565568f14824 100644 (file)
@@ -434,7 +434,7 @@ class notmuch_main(edlib.Doc):
         return 1
 
     def handle_notmuch_remove_tag(self, key, str, str2, **a):
-        "handle-range/doc:notmuch:remove-tag-/doc:notmuch:remove-tag./"
+        "handle-prefix:doc:notmuch:remove-tag-"
         tag = key[23:]
         with self.db.get_write() as db:
             if str2:
index 14ad4add0854c1e67c561bb9f541af0a81ba2c55..dbd988628c2a1d2f328c1009f6f5ee8207e35601 100644 (file)
@@ -430,7 +430,7 @@ class PresenterPane(edlib.Pane):
         return os.path.dirname(path)+'/'+f
 
     def handle_present_bg(self, key, focus, mark, mark2, num, comm2, **a):
-        "handle-range/Present-BG:/Present-BG;/"
+        "handle-prefix:Present-BG:"
         cmds = key[11:].split(',')
         ret = 0
         for c in cmds:
index 4a3da2f01b09f413c43a514b29ff420460fc40e0..a1fb4874b7de9eb177343aa714b580f1a1c25ae9 100644 (file)
@@ -529,7 +529,7 @@ static void register_map(void)
        key_add_range(rc_map, "Chr- ", "Chr-~", &complete_char);
        key_add(rc_map, "Backspace", &complete_bs);
 
-       key_add_range(rc_map, "Move-", "Move-\377", &complete_nomove);
+       key_add_prefix(rc_map, "Move-", &complete_nomove);
        key_add(rc_map, "Move-EOL", &complete_eol);
 
        key_add(rc_map, "Enter", &complete_return);
index 76901c1b271fdbf9a7d355f6d58101a67dcb1e0c..98140e0b989ff5abed9aa2eae7cd20afd95685e1 100644 (file)
@@ -1795,7 +1795,7 @@ static void render_lines_register_map(void)
 {
        rl_map = key_alloc();
 
-       key_add_range(rl_map, "Move-", "Move-\377", &render_lines_other_move);
+       key_add_prefix(rl_map, "Move-", &render_lines_other_move);
        key_add(rl_map, "Move-View-Small", &render_lines_move);
        key_add(rl_map, "Move-View-Large", &render_lines_move);
        key_add(rl_map, "Move-View-Pos", &render_lines_move_pos);