Skip to content

Instantly share code, notes, and snippets.

@EgZvor
Created November 8, 2021 18:22
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EgZvor/e804cdd8259455a41eaa9f6ed0cdde53 to your computer and use it in GitHub Desktop.
Save EgZvor/e804cdd8259455a41eaa9f6ed0cdde53 to your computer and use it in GitHub Desktop.
Vim mappings to jump through jumplist by files
if exists('g:loaded_jumpfile')
finish
endif
let g:loaded_jumpfile = 1
function! JumpFileComputePrevious()
let [jump_list, pos] = getjumplist()
let previous_list = jump_list
\ ->map({idx, val -> [idx, val]})[:pos]
\ ->reverse()
\ ->filter({idx, pos_b -> pos_b[1].bufnr != bufnr()})
if previous_list != []
return pos - previous_list[0][0]
else
return 0
endif
endfunction
function! JumpFileComputeNext()
let [jump_list, pos] = getjumplist()
let next_list = jump_list
\ ->map({idx, val -> [idx, val]})[pos:]
\ ->filter({idx, pos_b -> pos_b[1].bufnr != bufnr()})
if next_list != []
return next_list[0][0] - pos
else
return 0
endif
endfunction
nnoremap <plug>(JumpPrevFile) <cmd>execute 'normal ' . JumpFileComputePrevious() . "\<c-o>"<cr>
nnoremap <plug>(JumpNextFile) <cmd>execute 'normal ' . JumpFileComputeNext() . "\<c-i>"<cr>
@EgZvor
Copy link
Author

EgZvor commented Jan 7, 2022

A little explainer, since the code is pretty dense.

We're calling a getjumplist function which returns both the list of entries and our current position in that list.

Say, this is a jump list (each letter signifies a different file).

             V
[a1, a2, b1, b2, c1, c2, c3]
             ^
pos == 3

The provided functions return the distance between the desired and current position in the jump list, which is the closest position (in each direction) that is contained in a different file.

Let's trace through JumpFileComputePrevious.

First we use map to create a new list to preserve indexes:

                                V
[[0, a1], [1, a2], [2, b1], [3, b2], [4, c1], [5, c2], [6, c3]]
                                ^

Cut off the "newer" entries, since we only care about "older" (previous) ones.

[[0, a1], [1, a2], [2, b1], [3, b2]]

Reverse the list

[[3, b2], [2, b1], [1, a2], [0, a1]]

Filter out all the entries matching the current file

[[1, a2], [0, a1]]

Compute the difference between the current position and the desired one (the first of the resulting list)

pos - 1 = 3 - 1 = 2

The count to jump is 2.

If it happens that all entries belong to the current buffer, return 0, which will mean "don't move".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment