From: NeilBrown Date: Fri, 8 Sep 2023 05:19:39 +0000 (+1000) Subject: emacs: put a menu on the selection. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=38e9db12d543ae47ed6f710a594c9b90e35dd1e1;p=edlib.git emacs: put a menu on the selection. The selection can now trigger a menu (right-click) to which other modules can easily add entries. Also: don't claim selection until we are clearly starting one. A single click doesn't start a menu. Also: allow menus to be placed at-mouse rather than always at start of the active region. Signed-off-by: NeilBrown --- diff --git a/DOC/TODO.md b/DOC/TODO.md index 0e6df9d5..698954d2 100644 --- a/DOC/TODO.md +++ b/DOC/TODO.md @@ -9,7 +9,20 @@ the file. ### Triage +- [ ] find-document - if default doc has <>, displays wrongly. +- [ ] From start-of-file move to end, then up, then down. + Display jumps. Why? +- [ ] Add menubar menu with recent documents? +- [ ] why does clicking on status line go to top-of-file? +- [ ] should Docs menu go on doc name in status bar? - [X] search hangs when seeking "^( *)" +- [ ] selection-menu item to show git-commit from list of known git + trees +- [ ] selection-menu item for word-count +- [ ] selection-menu item for QR-code +- [ ] selection-menu sub-menu for UPPER lower Caps ?? +- [ ] selection-menu item for text-fill +- [ ] selection-menu item for spell-check ?? ### Small @@ -19,8 +32,8 @@ the file. - [X] fill mode to handle all punctuation at start of this line - [X] Enable lib-menu to show short-cut keys - [X] Add menu-bar to lib-menu. Pop it up on F10 with simple commands -- [ ] attach an extensible menu to the selection - copy, paste-in, QR, git-view +- [X] attach an extensible menu to the selection + cut, copy, paste-in, QR, git-view ### Medium diff --git a/lib-menu.c b/lib-menu.c index 03efa03b..41c3cb58 100644 --- a/lib-menu.c +++ b/lib-menu.c @@ -132,6 +132,11 @@ DEF_CMD(menu_attach) * V means show value in menu as well as name * F means to use the focus as the doc, and its * parent as the focus. + * ->str2 gives command to call on completion, else + * "menu-done" is used. + * ->x,y are co-ordinated relative to ->focus where menu + * (Top-Left) appears + * ->comm2 returns the created pane. */ struct pane *docp, *p, *p2; /* Multi-line temporary popup with x,y location provided. */ diff --git a/mode-emacs.c b/mode-emacs.c index 82476411..119ff35a 100644 --- a/mode-emacs.c +++ b/mode-emacs.c @@ -2330,7 +2330,7 @@ DEF_CMD(emacs_attrs) { struct call_return cr; int active; - char *selection = "bg:white-80,vis-nl"; // grey + char *selection = "bg:white-80,vis-nl,menu-at-mouse,action-menu:emacs:selection-menu"; // grey if (!ci->str) return Enoarg; @@ -2372,6 +2372,64 @@ DEF_CMD(emacs_attrs) return Efallthrough; } +DEF_CMD(emacs_selection_menu) +{ + struct pane *p; + + call("Message", ci->focus, 0, NULL, "So .... you want a menu do you?"); + p = call_ret(pane, "attach-menu", ci->focus, 0, NULL, "V", 0, NULL, + "emacs:selection-menu-action", ci->x, ci->y+1); + if (!p) + return Efail; + call("global-multicall-selection-menu:add-", p); + call("menu-add", p, 0, NULL, "de-select", 0, NULL, ":ESC"); + return 1; +} + +DEF_CMD(emacs_selection_menu_action) +{ + struct pane *home = ci->home; + char *dash; + const char *e; + const char *c = ci->str; + + if (!c) + return 1; + if (*c == ' ') { + /* command for focus */ + call(c+1, ci->focus, 0, ci->mark); + return 1; + } + + while ((e = strchr(c, ' ')) != NULL) { + int ret; + + dash = ""; + if (*c != ':' || e == c+1) + dash = "-"; + ret = call("Keystroke", home, 0, NULL, + strconcat(home, dash, + strnsave(home, c, e - c))); + if (ret < 0) + return Efail; + c = e+1; + } + dash = ""; + if (*c != ':' || c[1] == '\0') + dash = "-"; + call("Keystroke", home, 0, NULL, strconcat(home, dash, c)); + return 1; +} + +DEF_CMD(emacs_selection_menu_add) +{ + struct pane *p = ci->focus; + call("menu-add", p, 0, NULL, "Cut", 0, NULL, ":C-W"); + call("menu-add", p, 0, NULL, "Copy", 0, NULL, ":A-w"); + call("menu-add", p, 0, NULL, "Paste-in", 0, NULL, ":C-Y"); + return 1; +} + DEF_CMD(emacs_goto_line) { if (ci->num == NO_NUMERIC) @@ -2448,9 +2506,14 @@ static void update_sel(struct pane *p safe, } } - /* Must call 'claim' first as it might be claiming from us */ - call("selection:claim", p); - set_selection(p, pt, mk, 2); + /* Don't set selection until range is non-empty, else we + * might clear some other selection too early. + */ + if (!mark_same(pt, mk)) { + /* Must call 'claim' first as it might be claiming from us */ + call("selection:claim", p); + set_selection(p, pt, mk, 2); + } } DEF_CMD(emacs_press) @@ -3417,6 +3480,8 @@ static void emacs_init(void) key_add(m, "K:C-Y", &emacs_yank); key_add(m, "K:A-y", &emacs_yank_pop); key_add(m, "map-attr", &emacs_attrs); + key_add(m, "emacs:selection-menu", &emacs_selection_menu); + key_add(m, "emacs:selection-menu-action", &emacs_selection_menu_action); key_add(m, "K:A-g", &emacs_goto_line); key_add(m, "K:A-x", &emacs_command); @@ -3518,4 +3583,6 @@ void edlib_init(struct pane *ed safe) call_comm("global-set-command", ed, &attach_mode_emacs, 0, NULL, "attach-mode-emacs"); call_comm("global-set-command", ed, &attach_file_entry, 0, NULL, "attach-file-entry"); call_comm("global-set-command", ed, &emacs_shell, 0, NULL, "attach-shell-prompt"); + call_comm("global-set-command", ed, &emacs_selection_menu_add, + 0, NULL, "selection-menu:add-00-emacs"); } diff --git a/render-lines.c b/render-lines.c index 3b6567d2..4283ce28 100644 --- a/render-lines.c +++ b/render-lines.c @@ -1577,7 +1577,8 @@ DEF_CMD(render_lines_set_cursor) * Only works for menus below * the line. */ - if (sscanf(xyattr, "%dx%d,", &x, &y) == 2) { + if (!strstr(xyattr, ",menu-at-mouse,") && + sscanf(xyattr, "%dx%d,", &x, &y) == 2) { cih.x = x; cih.y = m->mdata->y + y + attr_find_int(m->mdata->attrs, diff --git a/tests.d/00-mouse b/tests.d/00-mouse index be1d50b0..c95ab82f 100644 --- a/tests.d/00-mouse +++ b/tests.d/00-mouse @@ -34,10 +34,10 @@ Display 80,30 EDD4933334AF53A85CD54C73B19D6437 60,11 Mouse ":Release-1" 60,20 Display 80,30 116D6953BCA4DDBCC5EA46655EACE0CD 60,20 Mouse ":Press-1" 17,7 -Display 80,30 31E7D3F3FFEBF4B1C289521A167ACBC4 17,7 +Display 80,30 E43145302EC09BB7FAB2DE0BFA4D2C02 17,7 Mouse ":Release-1" 17,20 Display 80,30 23156FABB80FCF0B81AC12E2F65E1AB4 17,20 Mouse ":Press-1" 8,4 Display 80,30 19C6B209451B5890F566C3855120E34D 8,4 Mouse ":Release-1" 8,4 -Close 244 +Close 246