How to Treat j and k as Jumps in Vim?
The aim is to explore how we can enhance Vim’s navigation by treating j
and k
motions (preceded by counts) as jumps.
TL;DR > Paste the following into your .vimrc...
nnoremap <expr> k (v:count > 1 ? "m'" . v:count : '') . 'gk'
nnoremap <expr> j (v:count > 1 ? "m'" . v:count : '') . 'gj'
Why?
First, because:
When you make a jump to a position with the “G” command, Vim remembers the position from before this jump. This position is called a mark. To go back where you came from, use this command: `` … But not the character searches with “fx” and “tx” or the word movements “w” and “e”. Also, “j” and “k” are not considered to be a jump, even when you use a count to make them move the cursor quite a long way away.
— https://vimhelp.org/usr_03.txt.html#03.10
Second, because:
…utilize relative numbers to race from one line to another. This method relies on using a count + directional key. So, 4j will move me down four lines from where I currently am within Vim. This seems well enough, but actually has a hidden weakness.
— Understanding Vim’s Jump List. One of the great joys of Vim is its… | by Kade Killary | Medium
This is powerful in combination with relative line numbering. For a definite treatment of that subject, see https://jeffkreeftmeijer.com/vim-number/.
We’ll achieve treating <count>j
and <count>k
as jumps through custom mappings.
Jump Lists:
- Vim maintains a jump list to keep track of cursor movements within a file.
- Each time you move your cursor to a different location, Vim records these jumps.
- The jump list is essential for efficient navigation through your editing history.
What Qualifies as a Jump?:
- Not all cursor motions are considered jumps.
- However,
j
(downward) andk
(upward) are not natively treated as jumps by Vim.
The Problem with j
and k
:
- Suppose you use
4j
to move down four lines. - Vim doesn’t consider this a jump, so you can’t easily return to the previous position using the `` (backtick) command.
Custom Mappings to the Rescue:
- We’ll create custom mappings in our
.vimrc
configuration file. - These mappings will make
j
andk
behave like jumps, ensuring they're recorded in the jump list.
The Configuration Change:
- Open your
.vimrc
(or create one if it doesn't exist). - Add the following lines:
nnoremap <expr> k (v:count > 1 ? "m'" . v:count : '') . 'gk'
nnoremap <expr> j (v:count > 1 ? "m'" . v:count : '') . 'gj'
Let’s break down what these mappings do:
nnoremap
: Non-recursive mapping for normal mode.<expr>
: Indicates that the right-hand side of the mapping is an expression.k
andj
: Our target keys.(v:count > 1 ? "m'" . v:count : '')
: This part checks if a count is provided (e.g.,4k
).- If a count exists, it sets a mark (
m'
) at the current position. - The
v:count
variable holds the count value. 'gk'
and'gj'
: These are the actual motions (upward and downward).
Example Usage:
- Suppose you move down 4 lines with
4j
. - Pressing
CTRL-o
will take you back to the previous position.