Fast linewise motions and edits
Provides
- Extensions of
f
,F
,t
,T
,w
,W
,b
,B
and friends to navigate with one keystroke and minimal cognitive load- for example, instead of
fA;;;;
,3T
or5e
, you can press a single highlighted key to reach your target, avoiding prefix counting
- for example, instead of
- Fast ways to fix common typos on the same line, using swaps (
xp
), replacements (r
), and cuts (x
)
Read Motivation and FAQ for background.
Inspired by:
If you use a plugin manager this is as simple as
Plug 'yangmillstheory/vim-snipe'
The above example uses vim-plug; tweak accordingly for your plugin manager.
The plugin API is exposed via "named key sequences"; see this write-up on why this is a good idea. For more information, do :h snipe.txt
.
Use in Visual, Normal, or Operator-pending mode.
Example mappings:
map <leader><leader>F <Plug>(snipe-F)
map <leader><leader>f <Plug>(snipe-f)
map <leader><leader>T <Plug>(snipe-T)
map <leader><leader>t <Plug>(snipe-t)
Example usage: We want to jump to the last "o" in front of the cursor, but there are several other "o"'s in the way.
Use in Visual, Normal, or Operator-pending mode.
Example mappings:
map <leader><leader>w <Plug>(snipe-w)
map <leader><leader>W <Plug>(snipe-W)
map <leader><leader>e <Plug>(snipe-e)
map <leader><leader>E <Plug>(snipe-E)
map <leader><leader>b <Plug>(snipe-b)
map <leader><leader>B <Plug>(snipe-B)
map <leader><leader>ge <Plug>(snipe-ge)
map <leader><leader>gE <Plug>(snipe-gE)
Example usage: We want to jump to the end of "to".
Use in Normal mode.
Example mappings:
nmap <leader><leader>] <Plug>(snipe-f-xp)
nmap <leader><leader>[ <Plug>(snipe-f-xp)
Usage: Change the typo "smlal" to "small" by swapping a previous instance of "l".
Example mappings:
nmap <leader><leader>x <Plug>(snipe-f-x)
nmap <leader><leader>X <Plug>(snipe-F-x)
Example usage: Change the typo "smoall" to "small" by cutting an instance of "o".
nmap <leader><leader>r <Plug>(snipe-f-r)
nmap <leader><leader>R <Plug>(snipe-F-r)
Example usage: Change the typo "smbll" to "small" by replacing an instance of "b".
By default, the jump tokens are ordered starting with the home row 'asdfghjkl', then 'qwertyuiop', then 'zxcvbnm'. You can provide your own sequence by setting a global variable g:snipe_jump_tokens
. For Dvorak users, e.g.
let g:snipe_jump_tokens = 'aoeuidhtns'
You can also provide your own highlighting via
let g:snipe_highlight_gui_color = '#fabd2f'
let g:snipe_highlight_cterm256_color = '200'
let g:snipe_highlight_cterm_color = 7'
These are used to build the highlighting group in highlight.vim used when highlighting a jump.
1. Automate fixing typos on the same line.
I make mistakes often enough to make this worth automating - in fact, I made a few mistakes while writing this line.
2. No more ;
and ,
repetition when using linewise motions.
I almost always know exactly where I want to go, but I'm forced to navigate incrementally to that place, or manually count the prefix of the motion (i.e. 5e
). Other times, I want to jump somewhere far in one direction, and it's more efficient to see the possible jump markers, instead of manually exploring (wwwww
).
3. There aren't any plugins containing or focused on the same feature set.
The two plugins with the most overlap in functionality are
Stupid-Easymotion constrains motions to line('.')
, but it only provides mappings for f
, w
, and W
. It also hasn't seen any activity in a long time - 4+ years at the time of this writing.
vim-easymotion has a similarly incomplete API. It's also sprawling, and (IMHO) painful to extend.
However, I'd like to give credit to vim-easymotion, having borrowed some core functionality and logic:
- highlighting initialization
- clever algorithm for building the jump tree
Why did you constrain to
line('.')
?
There's no need to scan the whole buffer, given set relativenumber
. Thus, this approach is more performant and IMHO more natural.
But I've been getting by just fine without this!
Cool, then you shouldn't use it. I use it everyday, so it serves me well, and hopefully I'm not the only one.
Should I always use the mappings?
No, in some cases (i.e. a single hop to an adjacent word, or when the destination character is unique on the path to the cursor), it's probably faster to use f
, F
, t
, T
, etc. Pick the right tool for the right job, I'd say.
Pull requests are welcome; no special process is required.