Need help with vim-seek?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

454 Stars 20 Forks MIT License 68 Commits 7 Opened issues


Seek makes navigating long lines effortless, acting like f but taking two characters.

Services available


Need anything else?

Contributors list

# 597,857
51 commits
# 132,845
6 commits
# 238,341
3 commits
# 350,399
Common ...
1 commit
# 35,989
1 commit
  • vim-seek

Seek is a Vim plugin with the simpleminded goal of making long-line navigation effortless, mostly acting like Vim's f but taking two characters instead.

** Introduction

This plugin introduces the /seek/ motion, summoned with =s= by default. Instead of one character like =f=, it expects two characters to be typed. This greatly reduces the possible matches within the line and mostly allows you to get anywhere in a line with just three keystrokes. Limiting movement to the current line, much like =f= does, is a usability consideration, making seek predictable, precise and solving a defined problem: it's a motion for within the line, not cross-line. If there's no match, your cursor doesn't go anywhere. Otherwise, the cursor is left off at the first character typed, so if you seek to "th" your cursor will now be at "t". The forward seek motion is complemented by =S=, which seeks backwards.

There are other unique features, notably leaps (see /Leaping motions/ section), but if you're looking for something more featureful, including extending movement across lines and even doing some of what EasyMotion does, you should look for /vim-sneak/, which fortunately picked up from my inactivity on vim-seek development, though also probably because vim-seek has been quite opinionated from the beginning.

** Motivation

The idea was borne out of frustration with getting at arbitrary points in longer lines, especially ones where navigating by word—on top of needing precise counts—gets mangled by symbols. It also filled a great need for faster navigation and editing of prose. The motion =f= often misfires by taking you to an earlier spot than where you aimed, and a full =/= search is too cumbersome, needing an extra == and leaving a highlight, and worst of all, might accidentally take you far away from the current line. Seek only works within the line (that's a feature.)

** What about substitute?

Vim, by default, maps the =s= key to substitute. That it is the perfect mnemonic to seek is a fortunate coincidence, but the choice was made because substitute (without a count) is an often inefficient command, being—ironically—easily substituted by others. Seek doesn't take a count by default, so whenever you supply a count to =s= it will map to the substitute command. However, if you don't use the substitute commmand at all, you can add =let g:seeksubstdisable = 1= to your =.vimrc= in order to allow counts for actual seeks.

The single character substitution can be accomplished with either =1s= or =cl=. And =S=, which is remapped to seek backwards, is completely substituted by =cc=.

However, if you don't want to give up substitute, you can scroll down to the /Customization/ section.

** I already use EasyMotion..

Seek solves a different problem, and both are powerful tools. EasyMotion is great for navigating across lines and around the file. But within the line, seek has more speed, for a very important reason: with seek you already know the keys you need to type before you even type =s=. Using EasyMotion there's a split second delay for it to generate the targets and another for your brain to process them. With seek you just type three quick keystrokes; you already know what to type.

** Advanced

Additional motions are provided as operator-pending only. That is, they only work when used after =d=, =c= or =y=, and not by themselves.

The motion =x= is to seek what =t= is to =f=. Standing for 'cut short [of the target]', it acts up to the first character typed, but doesn't include it. This is in contrast to =s= itself, which does include the first character typed—to keep it consistent with =f= behavior—but not the second character.

*** Leaping motions

My personal favorites, =r= (remote leap) and =p= (presential leap) act on the next word containing the characters typed. They're the equivalent of =iw=, but =r= snipes the target word from a distance, and =p= leaps to the target and stays there. So you can use =yrth= to yank the next word containing "th" without leaving your position (in reality Vim goes there and leaps back, fast enough that you don't see), and that's useful for pasting it to where you are. Or you can type =code= to leap to the next word with "de", deleting around it (aw) and leaving you in insert mode.

So whereas =r= and =p= use the inner word text object, the respective =u= and =o= are the equivalent outer word =aw=.

To enable the leaping mappings you need to add the following to your vimrc: =let g:seekenablejumps = 1=. They don't work in diff mode by default, because the mode uses =dp= and =do= for other purposes, but you can override this by also adding =let g:seekenablejumpsindiff = 1= to your vimrc.

As expected, all these advanced mappings are complemented by their capital letter versions, which operate backwards.

*** Customization

You can customize any of the keys that seek binds by adding lines such as the following to your vimrc. All the alternative keys shown below are just examples of customization, you can bind whichever keys you want.

Change s and S:

+begin_src VimL

let g:SeekKey = '' // note: doesn't work in terminal vim. let g:SeekBackKey = ''=


Change x and X:

+begin_src VimL

let g:SeekCutShortKey = '-' let g:SeekBackCutShortKey = '+'


Change p and P:

+begin_src VimL

let g:seekJumpPresentialInnerKey = 'p' let g:seekBackJumpPresentialInnerKey = 'P'


Change r and R:

+begin_src VimL

let g:seekJumpRemoteInnerKey = 'r' let g:seekBackJumpRemoteInnerKey = 'R'


Change o and O:

+begin_src VimL

let g:seekJumpPresentialAroundKey = 'o' let g:seekBackJumpPresentialAroundKey = 'O'


Change u and U

+begin_src VimL

let g:seekJumpRemoteAroundKey = 'u' let g:seekBackJumpPresentialInnerKey = 'U'


Or you can use a shorthand version to redefine all seek keys:

+begin_src VimL

let g:SeekKeys = ' - + p P' r R o O u U


Though it must always follow the order, you can simply use the defaults for keys you don't want to change, and you can truncate the string to leave the remaining unchanged:

+begin_src VimL

let g:SeekKeys = 's S - +' // will not change jump keys.


** Planned next

  • Create a doc file moving customization help out of this readme;
  • Repeat the last seek with =;= and =,= (same keys used for =f= and =t=);
  • (Optional) Respect user's =ignorecase= and =smartcase= settings, so that you can seek to a capital letter by typing the lowercase character;
  • Condensed jump mappings to allow you to use just one of =r= or =p= (or yet another key) for all jump motions, whereby you define which you want to be remote and which presential (e.g. =c= lends itself more to being presential, =y= to be remote, while =d= has good use of both).

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.