Ace Jump Mode moves an Emacs cursor with three key presses
a quick cursor jump mode for emacs
At a glance
- What is it?
- ace-jump-mode is an Emacs minor mode that labels candidate positions on screen and jumps to the one you pick, across windows and frames, in three key presses. It is a single Elisp file with a Makefile that byte-compiles and tests it, GPL-3.0 licensed, and version 3.0 arrived on 2026-10-05.
- Who is it for?
- Adopt ace-jump-mode if you spend your day in Emacs and your cursor movement is the bottleneck, because the three key press promise holds across windows and frames and the whole package is one Elisp file you can read in a sitting. Skip it if your editing happens mostly in a modal or vi-like setup where a different plugin already covers the same ground, or if you need the labels to survive a terminal that redraws aggressively.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 14 days ago.
- What is it written in?
- Mainly Emacs Lisp, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Three key presses to any position on screen
Ace Jump Mode is a minor mode of Emacs that helps you move the cursor, and the headline capability is that you can move the cursor to any position, across windows and frames, using only three key presses. The mechanism is direct labelling. You trigger a jump, the mode paints a short label on every candidate position in the frame, and you type the label of the one you want. The screenshot in the README shows the word mode, where the words starting with a given letter are labelled a, b, c and so on. What makes the three press count work is that the first key narrows the set to the candidates matching what you typed, and the second key selects from what remains. The mode also handles the case of more candidates than available keys, so the first key narrows the choice and a second one jumps, and an upper case character searches case-sensitively. The whole thing is a minor mode, so it does not change how the rest of Emacs behaves, which is the design choice that makes it easy to try and easy to leave alone.
Word, character and line variants share one prefix
There are three ways in, and they differ in what they label. The default is word mode, bound to M-a, where you go to a word by entering its first character and then selecting the highlighted key to move to it, and pressing RET instead of a character goes to a line. Character mode is bound to C-u M-a and goes to a character by entering that character and then selecting the highlighted key. Line mode is C-u C-u M-a, where you select the highlighted key directly with no filtering step. The prefixes are cumulative and consistent, which is what makes the mode learnable in a few minutes rather than a day. There is a fourth binding that is not a jump at all: C-c M-a is ace-jump-mode-pop-mark, which jumps back to where the last jump started, and repeating it goes further back. That is the piece that makes a labelling scheme viable as a primary navigation method, because without an undo for the movement itself, a mis-typed label would leave you hunting for your place by hand. The README points to a video, Emacs Rocks! Episode 10, for a look at the mode in action.
Installing from MELPA with use-package
The package is on MELPA and on MELPA Stable, and the documented installation uses use-package.
(use-package ace-jump-mode
:ensure t
:bind (("M-a" . ace-jump-mode) ; instead of `backward-sentence'
("C-c M-a" . ace-jump-mode-pop-mark))
:config
(ace-jump-mode-enable-mark-sync))The example deliberately rebinds M-a, which the comment notes is instead of backward-sentence, so you can see the trade the mode asks you to make. In Emacs 30 or later, to follow the latest commit rather than the packaged release, you replace :ensure t with a version control entry.
:vc (:url "https://github.com/winterTTr/ace-jump-mode" :rev :newest)With straight.el the same effect is expressed as a :straight clause with the host and repository, and the documentation also notes that any other free key will do, giving C-c j as one example. The configuration line in the example is worth understanding rather than copying blindly. ace-jump-mode-enable-mark-sync keeps ace-jump-mode-pop-mark in sync with the Emacs mark rings, and the other way round, which is what makes the jump-back command consistent with the ordinary mark ring behaviour you already have. The README also covers evil and viper users, where the mode is bound to SPC in the relevant state maps, because those packages take over the space bar.
Customization covers scope, case sensitivity and faces
The customization group is the second thing to read, because the defaults are opinionated in a way that changes with your layout. Running M-x customize-group RET ace-jump RET lists the options, and among them are the move keys, the scope of a jump and case sensitivity. The scope default is all the windows of all the frames, with the alternative being the selected window only. That default is the one to think about. Labelling every candidate position in every frame on screen is the most useful setting when you are working across a wide multi-window layout, and it is visually noisy when you are working in a single frame with a large buffer, where the labels cover a good part of the text you are trying to read. The faces are also configurable, with the labels using the face ace-jump-face-foreground and the grayed text using ace-jump-face-background. If they do not suit your colour theme or terminal, you can change them with M-x customize-face, or you can leave the text as it is by setting ace-jump-mode-gray-background to nil. There is a FAQ in the wiki as well, linked from the customization section.
Terminal edge cases and the ghostel workaround
Two integrations get their own treatment in the README, and both are the kind of detail that decides whether the mode works in your setup. In a ghostel terminal, a jump has to leave the live input, because the next redraw takes point back to the terminal cursor. Leaving it may take point back as well, so the fix restores it afterwards, and the documentation supplies a hook that captures the target position, leaves the input and goes back to it.
(add-hook 'ace-jump-mode-end-hook
(lambda ()
(when (derived-mode-p 'ghostel-mode)
(let ((target (point)))
(ghostel-maybe-leave-input)
(goto-char target)))))The second case is a word-boundary problem rather than a cursor problem. ghostel makes / a word constituent so that a double click selects a path as a whole, and word mode then finds no word inside a path, because in /bin/emacs neither b nor e starts a word. The fix sets a local standard syntax table for word mode on the ghostel hook, so that word mode finds the word starts with the standard definitions instead of the path-aware ones. Both of these are the price of running a labelling scheme inside a terminal that has its own notion of where the cursor is, and both are solved in the documentation rather than left to discovery.
One Elisp file, a Makefile and a byte compiler as a gate
The repository is small in a way that says something about the project. The top level holds ace-jump-mode.el as the implementation, a Makefile, a README, a LICENSE, the images directory and a test/ directory, and the whole package is a single Elisp file. The Makefile is where the engineering discipline shows. The compile target runs the byte compiler with byte-compile-error-on-warn set to t, so any byte compiler warning fails the build, and the test target loads the newer of the .el and .elc files with load-prefer-newer so a stale compiled file never shadows the source. The lint target runs checkdoc on the file and treats any output as a failure, since checkdoc always exits with success, and then runs package-lint, which is cloned from git rather than installed from an archive, with an override for environments where GitHub is reachable over ssh only. The result is a package that is one file to read, byte-compiled without warnings, documented in the house style and covered by an ERT test suite. The version badge claims Emacs 24.4 and later, and the last push was on 2026-10-09 with the v3.0 release on 2026-10-05.
Editorial conclusion
Adopt ace-jump-mode if you spend your day in Emacs and your cursor movement is the bottleneck, because the three key press promise holds across windows and frames and the whole package is one Elisp file you can read in a sitting. Skip it if your editing happens mostly in a modal or vi-like setup where a different plugin already covers the same ground, or if you need the labels to survive a terminal that redraws aggressively. Before you enable it, read the customization group with M-x customize-group RET ace-jump RET, because the scope of a jump defaults to all windows of all frames and that default is worth checking against your layout.
Frequently asked questions
How do I install ace-jump-mode in Emacs?
Install it from MELPA, for instance with use-package and :ensure t. In Emacs 30 or later you can replace :ensure t with :vc (:url "https://github.com/winterTTr/ace-jump-mode" :rev :newest) to follow the latest commit, and a :straight (:host github :repo "winterTTr/ace-jump-mode") clause works with straight.el.
What are the different ace-jump-mode entry points?
M-a runs ace-jump-word-mode, C-u M-a runs ace-jump-char-mode, C-u C-u M-a runs ace-jump-line-mode, and C-c M-a runs ace-jump-mode-pop-mark to jump back to where the last jump started, repeating further back.
How do I change how ace-jump-mode labels look?
The labels use the face ace-jump-face-foreground and the grayed text uses ace-jump-face-background. You can change them with M-x customize-face, or set ace-jump-mode-gray-background to nil to leave the text as it is, and M-x customize-group RET ace-jump RET lists the move keys, the jump scope and case sensitivity.
Does ace-jump-mode work in a terminal with ghostel?
It does, with two documented adjustments. A jump has to leave the live input or the next redraw takes point back to the terminal cursor, so the documentation supplies an ace-jump-mode-end-hook that restores the target position, and because ghostel makes / a word constituent, word mode needs a local standard syntax table set on the ghostel-mode-hook to find word starts inside a path.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/winterttr-ace-jump-mode)Was this useful?