Upping my Emacs navigation game
Posted September 27, 2015 at 09:21 PM | categories: hydra, emacs | tags:
I have been trying to up my navigation game in Emacs, by which I mean I want to get my cursor where I want it with a minimal number of keystrokes, and preferrably no mouse actions. There are lots of little and big navigations I do a lot:
- forward/backward by a character
- forward/backward by a word/subword
- forward/backward by a sentence
- forward/backward by a line
- to the beginning and end of a line
- to the beginning and end of a sentence
- to the beginning and end of a paragraph
- to the beginning and end of a page
- to the beginning and end of a buffer
- scrolling up/down
- into another window
- back and forth to buffers
Occasionally, I want to save a location so I can easily get back to it. Not all of these are strictly speaking navigation in the usual sense, but they are things I do often enough. There are Emacs commands for all these, and keyboard shortcuts for many of them, but I don't use them often, and as a result I don't remember them either.
Here I develop a hydra that will provide these features. Hydra is a super amazing, menu prompting system that provides hints to remind you of what can be done, and to access it from a character. It is possible to pass numeric and universal arguments to the commands by typing -, a number, or C-u before pressing the character.
I want some commands to be repeatable, which we get with a "red" hydra, and some commands to exit on running, which we get with a "blue" head. So, here is an over-the-top hydra for navigation.
(defhydra hydra-navigate (:color red :hint nil) " _f_: forward-char _w_: forward-word _n_: next-line _b_: backward-char _W_: backward-word _p_: previous-line ^ ^ _o_: subword-right _,_: beginning-of-line ^ ^ _O_: subword-left _._: end-of-line _s_: forward sentence _a_: forward paragraph _g_: forward page _S_: backward sentence _A_: backward paragraph _G_: backward page _h_: helm mini _B_: buffer list _i_: window _<left>_: previous buffer _<right>_: next buffer _<up>_: scroll-up _<down>_: scroll-down _[_: backward-sexp _]_: forward-sexp _<_ beginning of buffer _>_ end of buffer _m_: set mark _/_: jump to mark " ("f" forward-char) ("b" backward-char) ("w" forward-word) ("W" backward-word) ("n" next-line) ("p" previous-line) ("o" subword-right) ("O" subword-left) ("s" forward-sentence) ("S" backward-sentence) ("a" forward-paragraph) ("A" backward-paragraph) ("g" forward-page) ("G" backward-page) ("<right>" next-buffer) ("<left>" previous-buffer) ("h" helm-mini :color blue) ("i" ace-window :color blue) ("m" org-mark-ring-push) ("/" org-mark-ring-goto :color blue) ("B" helm-buffers-list) ("<up>" scroll-up) ("<down>" scroll-down) ("<" beginning-of-buffer) (">" end-of-buffer) ("." end-of-line) ("[" backward-sexp) ("]" forward-sexp) ("," beginning-of-line) ("q" nil "quit" :color blue)) (global-set-key (kbd "s-n") 'hydra-navigate/body)
hydra-navigate/body
I basically like it. The menu is a little on the large side, but it makes for easy modal navigation in a buffer, to other windows, and other buffers. On the whole for moderate cursor movements, this results in basically equal keystrokes. For example, to move 3 characters forward, we have C-f C-f C-f or C-u 3 C-f, or s-n 3 f. The advantage (I think) is a single interface to all these navigation commands with hints on what to do.
There is still another level of navigation, which is related to navigation by searching. That is a whole different level of navigation I will work on another day!
Copyright (C) 2015 by John Kitchin. See the License for information about copying.
Org-mode version = 8.2.10