Last major edit (later minor edits)
Changed:
< My current strategy is to learn a few tools such as smartparens to aid the otherwise painful process.
to
> My current strategy is to learn a few tools such as [https://github.com/Fuco1/smartparens smartparens] to aid the otherwise painful process.
OneKey to rule them all, OneKey to find them, OneKey to bring them all and in the darkness bind them.
One Key provides a single keystroke that when pressed presents you with a menu of commands which can be executed with a further keystroke. The menu is presented as a buffer either within the current frame or within its own frame (see screenshot below).
It provides a convenient way to quickly find commands, or other objects such as Yasnippets or bookmarks, and to learn keybindings (which are displayed in the menu).
By default the menu items are highlighted according to usage to help you identify commonly used items, and you can apply your own colour scheme to make them more readable.
Different types of menus for accessing different types of objects are defined by one-key plugin libraries (see plugins below). You can also easily create your own menus on the fly, or edit existing ones, and save them. By default menus for common prefix keys and commands, as well as major-mode keybindings, are defined.
Several different menus can be stored together as a menu set, and you can switch between these menus using the left/right arrow keys. Different menu sets can be associated with different major-modes or buffers, and OneKey will open the appropriate menu set when the top key is pressed (see menusets below).
‘one-key-read’, ‘one-key-read-tree’, ‘one-key-read-list’ and ‘one-key-read-logical-formula’ (require 'one-key)
(global-set-key (kbd "<menu>") 'one-key-open-associated-menu-set)
‘max-lisp-eval-depth’ and ‘max-specpdl-size’ from their defaults to prevent the probability of an error occurring.Press the top key (e.g. “<menu>”) and the One-Key buffer will popup. Read on for further details…
Pressing the top key or running the command ‘one-key-open-default-menu-set’ or ‘one-key-open-menu-set’ opens the One-Key buffer. Within the One-Key buffer you will see a list of command descriptions each with a corresponding key in square brackets to its left. Pressing one of these keys executes the corresponding command. Press q to quit.
Along the top of the buffer in the header line you will see a list of menu names. One of these names will be highlighted and indicates the current menu. You can navigate between the different menus by pressing the left/right arrow keys.
You can scroll the menus up & down using the up/down arrow keys and scroll up/down keys, and you can toggle the visibility and size of the One-Key window by repeatedly pressing the top key. This is useful if there are a large number of items in the menu, or when you need to see part of the buffer that is obscured by the One-Key window.
By default the One-Key window will close after pressing a key corresponding to one of the menu items. If you want to keep the window open after pressing an item key you should toggle the menu persistence by pressing the appropriate special key (C-menu by default, see “Special keybindings” below). To quit one-key and close the One-Key window press q. If you want to quit but keep the window open (e.g. to see the keybindings for a major mode), press C-q.
For each different type of menu certain “special” keybindings are defined which activate menu specific commands, such as sorting or editing the menu items, adding new menus, etc. These special keybindings are specific to each menu type, though many of them will be the same for all menu types. For example the arrow keys are defined as special keybindings for navigating around menus.
Pressing the f1 key displays a help message listing all the special keybindings for the current menu.
By default, when a menu is created one-key will ensure that the keys corresponding to menu items do not clash with the special keybindings for that menu type. However, if for some reason there is a clash then the menu item gets priority over the special keybinding unless the help window is displayed (by pressing f1), in which case the special keybinding gets priority.
You can alter or add new special keybindings by customizing ‘one-key-special-keybindings’, and ‘one-key-default-special-keybindings’. Extension libraries (such as ‘one-key-dir’ or ‘one-key-regs’) may also define customizable special keys specific to the menu type defined in the library.
By default the following special keybindings are defined:
| q | Quit and close menu window | C-q | Quit, but keep menu window open | C-menu | Toggle menu persistence |
| menu | Toggle menu display | left | Change to next menu | right | Change to previous menu |
| up | Scroll/move up one line | down | Scroll/move down one line | Page Up | Scroll menu down one page |
| Page Down | Scroll menu up one page | C-h | Show help for next item chosen | C-s | Save current state of menu |
| f1 | Toggle this help buffer | f2 | Toggle column/row ordering of items | f3 | Sort items by next method |
| C-f3 | Sort items by previous method | f4 | Reverse order of items | / | Limit items to those matching regexp |
| C-/ | Highlight items matching regexp | f5 | Edit a menu item | f6 | Delete a menu item |
| f7 | Copy/kill coloured items | C-f7 | Yank copied items | f8 | Swap menu item keys |
| f9 | Add a menu item | C-f9 | Add a menu | C-S-f9 | Remove this menu |
| f10 | Reposition item (with arrow keys) | f11 | Donate to support further development | C-f11 | Report a bug |
Persistent menus are stored in the file ‘one-key-menus-save-file’ (customizable), but you should never need to edit this file. Instead you can create and edit menus from within the One-Key buffer. If you press the special key corresponding to “Add a menu” you will be prompted for the type of menu to add. By default the following menu types are defined, but more may be added with extension libraries, or by creating them yourself (see ‘one-key-types-of-menu’):
‘one-key-toplevel-alist’, which by default contains menus for common commands and prefix keys to help new users learn emacs If ‘one-key-autosave-menus’ is non-nil then any new menus or menus that have been changed will be saved on Emacs exit, unless they are listed in ‘one-key-exclude-from-save’ Alternatively you may save individual menus by pressing the special key for “Save the current state of menu” (C-s by default).
A menu set is a collection of menu names. When you open the One-Key buffer with ‘one-key-open-associated-menu-set’ it opens a collection of menus associated with the current major-mode or buffer. By default this is the set of menus in ‘one-key-default-menu-set’. You can define other menu sets by customizing ‘one-key-sets-of-menus-alist’, and associate them with different major-modes or buffers by customizing ‘one-key-associations-for-menu-sets’. Each menu set consists of a name for the menu set, and a list of menu names. one-key reconstructs a menu from its name by searching ‘one-key-types-of-menu’ for a matching entry, and applying the associated function to create the menu. With the “menu-sets” menu you can see what menu sets are currently defined, switch menu sets, and save the current menus as a menu set (C-s). See “Creating menus” above for info on how to add the “menu-sets” menu to the One-Key buffer.
Item help: to get help on a particular menu item press C-h followed by the key for the item. The help page for the associated command will be displayed. If part of the Help buffer is obscured by the One-Key buffer, you can hide the One-Key buffer by pressing the top key to toggle the window visibility.
Item brightening: By default the background colour of a menu item is increased relative to the brightness of other items each time the item is executed. This means you can easily see the most frequently used items. To turn this feature off set ‘one-key-auto-brighten-used-keys’ to nil.
Sorting items: you can sort the items in a menu by pressing the appropriate special key, and add new sort methods by customizing ‘one-key-default-sort-method-alist’. The current sort method is displayed in the mode-line. You can also toggle between row/column ordering of items, and reverse the order of items. By trying out different sort and ordering combinations you can find a configuration which is most readable, or fits most items on screen. The order of menu items is persistent between sessions if the menus are saved (see “Saving menus”).
Filtering and colouring items: you can filter the items displayed to match a regular expression, or specify the background colour of items that match a given regular expression (press f1 to see which key to press). This can make the menus more readable. The background colours will be saved with the menu.
Editing menus: you can add, delete and edit menu items, and also copy, kill (i.e. cut) and yank (i.e. paste) items from one menu to another. To copy or kill a bunch of items first make sure they are all highlighted with the same background colour (doesn’t matter if they have different brightness levels), and then press the appropriate special key (press f1 for help). You will be prompted for an item in the group, and whether or not you want to also kill the items from the current menu. The items will be saved in ‘one-key-copied-items’ and can be then be yanked into another menu. Any further copy/kills will overwrite the value of ‘one-key-copied-items’. You cannot retrieve previous kills so take care. You can also reposition items in a menu:
All the options below can be customized by M-x customize-group RET one-key RET
| one-key-default-menu-keys | A list of chars which may be used as the default keys in automatically generated one-key menus. |
| one-key-min-keymap-submenu-size | The minimum number of elements allowed in a submenu when creating menus from keymaps. |
| one-key-popup-window | Whether to popup window when one-key-menu is run for the first time. |
| one-key-buffer-name | The buffer name of the popup menu window. |
| one-key-column-major-order | If true then menu items are displayed in column major order, otherwise row major order. |
| one-key-force-multi-column-keymap-menus | If non-nil then one-key menus created from keymaps will have command descriptions shortened to fit two columns. |
| one-key-menu-window-max-height | The max height of popup menu window. |
| one-key-menus-save-file | The file where one-key menus are saved. |
| one-key-autosave-menus | If non-nil then one-key menus will automatically be saved when created or changed. |
| one-key-exclude-from-save | List of regular expressions matching names of menus which should not be autosaved. |
| one-key-include-menubar-items | Whether or not to include menu items with no keybinding when creating one-key menus from keymaps. |
| one-key-item-foreground-colour | Foreground colour of highlighted items in one-key menus. |
| one-key-auto-brighten-used-keys | If non-nil then set brightness of menu items colours according to how often the keys are pressed. |
| one-key-submenus-replace-parents | If non-nil then when a submenu of a one-key menu is opened it will replace the parent menu. |
| one-key-major-mode-remap-alist | A list of cons cells mapping major modes to one-key-menus. |
| one-key-toplevel-alist | The one-key top-level alist. |
| one-key-sets-of-menus-alist | Saved menu sets (sets of menus). |
| one-key-default-menu-set | The default menu set. It’s value should be the car of one of the items in one-key-sets-of-menus-alist’ |
| one-key-default-sort-method-alist | An alist of sorting methods to use on the one-key menu items. |
| one-key-special-keybindings | An list of special keys; labels, keybindings, descriptions and associated functions. |
| one-key-default-special-keybindings | List of special keys to be used if no other set of special keys is defined for a given one-key menu type. |
| one-key-menu-sets-special-keybindings | List of special keys to be used for menu-sets menus (see one-key-default-special-keybindings for more info). |
| one-key-disallowed-keymap-menu-keys | List of keys that should be excluded from one-key menus created from keymaps. |
| one-key-types-of-menu | A list of names of different types of one-key menu, and associated functions. |
| one-key-persistent-menu-number | If non-nil then when the default menu set is opened it will start with the same menu as when previously opened. |
| one-key-mode-line-message | Form that when evaluated should produce a string for the mode-line in the One-Key buffer. |
The following plugin libraries are available:
Note: the following functions are not yet complete, but should be finished soon.
You can use the following functions in your own code to offer the user a simple way to select different types of items:
| one-key-read | OneKey replacement for the built-in ‘completing-read’ function |
| one-key-read-tree | Read a tree (recursive list) of items using OneKey menus |
| one-key-read-list | OneKey replacement for the ‘completing-read-multiple’ function |
| one-key-read-logical-formula | Read a logical/boolean formula (e.g. for filtering items) using OneKey menus. The result is an elisp form which can be evaluated. |
If you want to help develop OneKey have a look at the github repo: https://github.com/vapniks/one-key The code there is currently broken as I am in the midst of a major refactoring (but the code here on the wiki should work).
The OneKey “top-level” menu. The two menu items “mode specific bindings” and “outline commands” are highlighted which indicates that they have been used more often than the others.
Notice that “top-level” is highlighted in yellow in the header line, and other menu types are listed to the left and right of this. The user can navigate to the other menus by pressing the left/right arrow keys. Notice also that the mode line indicates the current sort method.
I have a problem when assigning, for example, ‘mark-paragraph’ function to a key, the paragraph is not marked. While using ‘M-x mark-paragraph’ works! Any idea what is wrong?
I found Lisp:one-key-default.el a bit annoying: after loading it, I can’t bind key to ‘C-x j’,‘C-x p’ etc any longer (as ‘C-x’ is no longer a prefix key), and I can’t use ‘C-x C-h’ to query the keybindings list either. Thus it is only useful for learning Emacs default keys.
I wrote a new routine to bind e.g. ‘ESC C-x’ to the one-key-menu. ‘C-x’ is still a prefix key. You can add keybindings to ‘C-x j’, you can use ‘C-x C-h’ to query keybindings list and you can use ‘one-key-refresh-menu’ to refresh the menu (after adding ‘C-x j’, ‘C-x p’ etc).
(defun one-key-bind-keymap (key keymap-prefix)
"Generate an one-key menu for keys starting with `keymap-prefix', and bind it to `key'.
It also bind `keymap-prefix'-? to the same one-key menu, if not in use.
For example, when called with ('ESC <f1>', '<f1>'), it would
generate one-key menu 'one-key-menu-<f1>', and bind 'ESC <f1>'
and '<f1> ?' to one-key-menu-<f1>.
"
(if (keymapp (key-binding (read-kbd-macro keymap-prefix)))
(let ( (one-key-menu-sym (intern (format "one-key-menu-%s"
(replace-regexp-in-string " " "-" keymap-prefix)))) )
(let ( (prefixed-?-key (read-kbd-macro (concat keymap-prefix " ?"))) )
(unless (key-binding prefixed-?-key)
(global-set-key prefixed-?-key one-key-menu-sym)))
(with-temp-buffer
(one-key-insert-template keymap-prefix keymap-prefix)
(eval-buffer))
(global-set-key (read-kbd-macro key) one-key-menu-sym))
(message "'%s' is not a keymap-prefix" keymap-prefix)))
;; use it this way in your ~/.emacs
(one-key-bind-keymap "ESC C-x" "C-x")
(defun one-key-refresh-menu (fkey)
(interactive "sfkey: ")
(one-key-bind-keymap (concat "ESC " fkey) fkey))
;;use `M-x one-key-refresh-menu' at anytime to refresh the menu
The above code won’t work with the new version of one-key and is not recommended. Also `one-key-default.el’ is now redundant.
The new version has a “top-level” menu containing all the common prefix keys. This is much safer than the above method since the old keybindings are not lost. It is also just as fast since you only need press a single key to open the top-level one-key menu, followed by the key for the required prefix key.
I found that when I have (one-key-default-setup-keys) in my .emacs, I do not get the eshell prompt.
That command is now redundant. Just use the “top-level” menu instead.
Could you please update the git repository (and keep it up-to-date) – JonasBernoulli
OK, just pushed the “no-structs” branch to github, which is the version here on the emacswiki. The no-structs branch should work (at least on linux with graphical windows).
The master branch on github is not usable. Really sorry about this, but I want to make it more flexible and extensible allowing multiple One-Key windows for example. This requires a large refactoring which is taking some time. My current strategy is to learn a few tools such as smartparens to aid the otherwise painful process.