-
Notifications
You must be signed in to change notification settings - Fork 138
Advanced Hop
You have made it so far. It is time for you to learn how to use more advanced features of Hop by calling the various Lua API functions.
Note: if you need more information on the various Lua API functions, you can always use the embedded documentation with
:h hop-lua-api
.
Every Hop command is actually implemented as a Lua call to the associated Lua API function. Here is a mapping between Hop commands and the associated Lua function:
Hop command | Lua API function |
---|---|
HopAnywhere |
require'hop'.hint_anywhere() |
HopChar1 |
require'hop'.hint_char1() |
HopChar2 |
require'hop'.hint_char2() |
HopLine |
require'hop'.hint_lines() |
HopLineStart |
require'hop'.hint_lines_skip_whitespace() |
HopVertical |
require'hop'.hint_vertical() |
HopPattern |
require'hop'.hint_patterns() |
HopWord |
require'hop'.hint_words() |
You will need those Lua functions to build more sophisticated motions. All those commands take a single, optional
argument, called opts
. That argument is the same as the one passed to require'hop'.setup
. However, the one passed to
those functions takes precedence on the one passed to the setup
function, so it’s the right place to override and
customize a single call invocation. It allows you to test a specific kind of option while calling the function. For
instance, if you want to see what it looks like to run hint_words
with keys
changed to something else, you can still
run a command like this, using the : Neovim command line:
:lua require'hop'.hint_words({ keys = 'abcd' })
From now on, it is highly recommended that you first test your commands using this UX, as it is much faster to run Lua code in the command line rather than binding them to a key and restarting Neovim.
Before providing you some useful examples, we need to talk about command variations.
As you might have read in the Commands page, most of Hop commands have variations. There is no black
magic here and you should already start to understand how they are made. A clue: they are just regular Lua API calls
with some opts
options overridden, as seen above.
Here is a table showing how variations are made:
Hop command variation | Lua API function |
---|---|
Hop*BC |
require'hop'.*({ direction = require'hop.hint'.HintDirection.BEFORE_CURSOR }) |
Hop*AC |
require'hop'.*({ direction = require'hop.hint'.HintDirection.AFTER_CURSOR }) |
Hop*CurrentLine |
require'hop'.*({ current_line_only = true }) |
Hop*MW |
require'hop'.*({ multi_windows = true }) |
It’s as simple as that.
By leveraging everything you now know about Hop commands, variations and the Lua API, you can already make very powerful and acute motions. Let’s see a couple of them.
The f
and F
Neovim motions are very important kind of motions, as they are built-ins allowing to quickly move on
the current line. f
goes after the cursor, and F
goes backwards, before the cursor. You might already see how
you could reimplement those motions, right?
Let’s do f
(put everything on the same line; we break it on multiple lines for readability):
:lua require'hop'.hint_char1({
direction = require'hop.hint'.HintDirection.AFTER_CURSOR,
current_line_only = true
})
And let’s do F
:
:lua require'hop'.hint_char1({
direction = require'hop.hint'.HintDirection.BEFORE_CURSOR,
current_line_only = true
})
The t
and T
Neovim motions are very useful. They are very similar to f
and F
but instead of moving on the
actual target, they move one character before. If you have read the Configuration page and the
previous section, you already know how to reimplement both motions.
For t
:
:lua require'hop'.hint_char1({
direction = require'hop.hint'.HintDirection.AFTER_CURSOR,
current_line_only = true,
hint_offset = -1
})
And T
:
:lua require'hop'.hint_char1({
direction = require'hop.hint'.HintDirection.BEFORE_CURSOR,
current_line_only = true,
hint_offset = -1
})
It’s so simple.
:lua require'hop'.hint_word({
direction = require'hop.hint'.HintDirection.BEFORE_CURSOR,
current_line_only = true,
})
:lua require'hop'.hint_char1({
direction = require'hop.hint'.HintDirection.AFTER_CURSOR,
current_line_only = true,
hint_offset = 1
})
:lua require'hop'.hint_char1({
direction = require'hop.hint'.HintDirection.BEFORE_CURSOR,
current_line_only = true,
hint_offset = 1
})