From 09edcf2711035b0d62991a4a0adab6a416002d10 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 30 Sep 2023 09:57:02 +1000 Subject: [PATCH] Add Documents menu to the menubar The Documents menu shows the 10 most recently used docs. This also fixes some problems with lib-menu and lib-menubar Signed-off-by: NeilBrown --- DOC/TODO.md | 4 ++-- doc-list.c | 2 +- lib-menu.c | 5 +++-- lib-menubar.c | 12 ++++++++--- mode-emacs.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 72 insertions(+), 8 deletions(-) diff --git a/DOC/TODO.md b/DOC/TODO.md index f81ef9ab..fdb26f7f 100644 --- a/DOC/TODO.md +++ b/DOC/TODO.md @@ -21,9 +21,8 @@ the file. - [X] find-document - if default doc has <>, displays wrongly. - [X] From start-of-file move to end, then up, then down. Display jumps. Why? -- [ ] Add menubar menu with recent documents? +- [X] Add menubar menu with recent documents? - [X] 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 @@ -487,6 +486,7 @@ Module features - [ ] review decision about that to do when high < 3*border-height. Current (disabled) code makes a mess when differing scales causes borders to be shorter than content. +- [ ] Place docs menu on the doc name in status line ### grep/make diff --git a/doc-list.c b/doc-list.c index 61c28196..13fe48a1 100644 --- a/doc-list.c +++ b/doc-list.c @@ -143,7 +143,7 @@ DEF_CMD(list_add_elmnt) m->ref.p = e; return 1; } - + DEF_CMD(list_del_elmnt) { struct list *l = ci->home->doc_data; diff --git a/lib-menu.c b/lib-menu.c index ff8ed21b..33bc6e18 100644 --- a/lib-menu.c +++ b/lib-menu.c @@ -47,8 +47,8 @@ DEF_CMD(menu_clear) { struct mark *m = vmark_new(ci->focus, MARK_UNGROUPED, NULL); - call("doc:set-ref", ci->home, 1, m); - while (call("doc:list-del", ci->home, 0, m) > 0) + call("doc:set-ref", ci->focus, 1, m); + while (call("doc:list-del", ci->focus, 0, m) > 0) ; return 1; } @@ -181,6 +181,7 @@ DEF_CMD(menu_attach) pane_close(p); return Efail; } + call("doc:file", p2, -1); p2 = pane_register(p2, 0, &menu_handle.c); /* Don't allow any shift - we size the menu to fit */ if (!p2) diff --git a/lib-menubar.c b/lib-menubar.c index 31dbf56c..69c6b508 100644 --- a/lib-menubar.c +++ b/lib-menubar.c @@ -225,8 +225,6 @@ static struct pane *menubar_find(struct pane *home safe, pane_add_notify(home, owner, "Notify:Close"); if (last_left) list_move(&d->siblings, &last_left->siblings); - else if (create == C_RIGHT) - list_move_tail(&d->siblings, &home->children); pane_damaged(home, DAMAGED_VIEW); return d; } @@ -288,7 +286,11 @@ DEF_CMD(menubar_done) if (mbi->child) pane_take_focus(mbi->child); - if (ci->str && ci->str[0]) + if (!ci->str || !ci->str[0]) + return 1; + if (ci->str[0] == ' ') + call(ci->str+1, pane_focus(home)); + else call("Keystroke-sequence", home, 0, NULL, ci->str); return 1; } @@ -345,6 +347,10 @@ DEF_CMD(menubar_press) if (p->x < cr.ret - 1) continue; /* clicked on 'p' */ + /* FIXME this should be pane_call, but emacs mode is + * a bit confusing. + */ + home_call(p->focus, "menu:refresh", p); mbi->menu = call_ret(pane, "attach-menu", p, 0, NULL, "DVF", 0, NULL, NULL, cih.x, mbi->bar->h); diff --git a/mode-emacs.c b/mode-emacs.c index ca958559..947e0542 100644 --- a/mode-emacs.c +++ b/mode-emacs.c @@ -3329,6 +3329,59 @@ DEF_CMD(emacs_quote) return 1; } +struct docs_helper { + struct command c; + int cnt; + struct pane *p safe; +}; + +DEF_CMD(emacs_doc_menu) +{ + const char *d = ksuffix(ci, "emacs:doc-menu:"); + struct pane *p = call_ret(pane, "docs:byname", ci->focus, + 0, NULL, d); + + if (p) { + struct pane *t = call_ret(pane, "ThisPane", ci->focus); + if (t) + home_call(p, "doc:attach-view", t, 1); + } + return 1; +} + +DEF_CB(emacs_menu_add_doc) +{ + struct docs_helper *dh = container_of(ci->comm, struct docs_helper, c); + char *name = pane_attr_get(ci->focus, "doc-name"); + + if (!name) + return Efallthrough; + if (dh->cnt >= 10) + return 1; + dh->cnt += 1; + call("menu:add", dh->p, 0, NULL, name, 0, NULL, + strconcat(ci->home, " emacs:doc-menu:", name)); + return Efallthrough; +} + +DEF_CMD(emacs_menu_refresh) +{ + struct pane *p = ci->focus; + char *n = pane_attr_get(p, "doc-name"); + struct docs_helper dh; + + if (!n || strcmp(n, "Documents") != 0) + return 1; + + call("menu:clear", p); + dh.c = emacs_menu_add_doc; + dh.cnt = 0; + dh.p = p; + call_comm("docs:byeach", p, &dh.c); + call("menu:add", p, 0, NULL, "List all", 0, NULL, ":C-X :C-B"); + return 1; +} + DEF_PFX_CMD(cx_cmd, ":CX"); DEF_PFX_CMD(cx4_cmd, ":CX4"); DEF_PFX_CMD(cx5_cmd, ":CX5"); @@ -3519,6 +3572,9 @@ static void emacs_init(void) key_add(m, "K:CX-e", &emacs_macro_run); key_add(m, "K-e", &emacs_macro_run); + key_add(m, "menu:refresh", &emacs_menu_refresh); + key_add_prefix(m, "emacs:doc-menu:", &emacs_doc_menu); + emacs_map = m; } @@ -3526,6 +3582,7 @@ DEF_LOOKUP_CMD(mode_emacs, emacs_map); static char *menus[][3] = { { "Help/Recent", ":F1 l", "R" }, + { "Documents/List all", ":C-X :C-B", "R"}, { "File/Open", ":C-X :C-F", "L"}, { "File/Save", ":C-X :C-S", "L"}, { "File/Exit", ":C-X :C-C", "L"}, -- 2.39.5