Creating a dynamic menu for Emacs
Posted August 20, 2014 at 08:26 PM | categories: emacs | tags:
I have an application where I want a dynamic menu in Emacs, e.g. the menu auto-updates as things change on your computer. Here is a prototype example. We will make a menu that shows entries for each file in the current directory, and opens that entry.
We start by creating a menu that is initially empty like this. This menu will be called "My Files" in the menu.
(easy-menu-define jrk-menu global-map "MyMenu" '("My Files"))
Next, we create this function which will create a submenu with a vector entry for each file in this directory.
(defun get-menu () (easy-menu-create-menu "Files" (mapcar (lambda (x) (vector (file-name-nondirectory x) `(lambda () (interactive) (find-file ,x) t))) (f-glob "*"))))
get-menu
Next, we add the submenu. This is a one-time addition, which reflects the files in the directory at the time I ran this block.
(easy-menu-add-item jrk-menu '() (get-menu))
After you do that, the menu looks like this:
This menu is not yet dynamic. We need to create a function that can update the menu, and then add the function to a hook that runs each time the menu opens. Here is the code. The easy-menu-add-item function will replace the contents of an item by the same name, which we use here to update the menu.
(defun update-my-file-menu () (easy-menu-add-item jrk-menu '() (get-menu))) (add-hook 'menu-bar-update-hook 'update-my-file-menu)
update-my-file-menu | undo-tree-update-menu-bar | menu-bar-update-buffers |
Now, if we run this block to create a file:
touch newfile
Then, after saving this buffer the menu looks like this:
Now, every time a new file appears in this directory, a new menu item will appear every time you check the menu. That is really dynamic.
Copyright (C) 2014 by John Kitchin. See the License for information about copying.
Org-mode version = 8.2.7c