]> git.neil.brown.name Git - edlib.git/commitdiff
Add Documents menu to the menubar
authorNeilBrown <neil@brown.name>
Fri, 29 Sep 2023 23:57:02 +0000 (09:57 +1000)
committerNeilBrown <neil@brown.name>
Fri, 29 Sep 2023 23:57:02 +0000 (09:57 +1000)
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 <neil@brown.name>
DOC/TODO.md
doc-list.c
lib-menu.c
lib-menubar.c
mode-emacs.c

index f81ef9abc1cba6b2050d685b84a9a4b4a61aaa88..fdb26f7fd14adb044cfac9d251fa3d35f82c489b 100644 (file)
@@ -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
 
index 61c28196ebeab85d16b0ee6e13cd8ece10de50bf..13fe48a1ea6221e4b1d8eb68fa6f739fbac5ead7 100644 (file)
@@ -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;
index ff8ed21bac6d5817a2f3c309bb8409de38bbee4f..33bc6e1839ca5d9b0a01ff15cbce42bd0416cf31 100644 (file)
@@ -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)
index 31dbf56cb475631fdb869764eeaeefb7e6dae395..69c6b508f84eb75e8198bbffd89065f105ed6f9d 100644 (file)
@@ -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);
index ca9585594ced68507ad5c11f697efbb199b09d7d..947e05426993d692d67c067f0035284a55e0c0b6 100644 (file)
@@ -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"},