Neo(Vim) on Steroids: vim-sneak + easymotion = hop.nvim
Tags: neovim, vim, lua, tutorial
Published: 2022-03-17 01:55:11

If you've been using Vim for a while now, you probably stumbled upon some navigation plugins like easymotion and vim-sneak. Unless... you're still stuck inside vim without any idea of how to quit. (SHEESH!)

Kidding aside...

**easymotion** is used for navigating the buffer by pressing a keystroke and marking the text you can jump to. This is demonstrated below. [Github](https://github.com/easymotion/vim-easymotion)
![A GIF demonstrating easymotion motions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5dterjyp0mwnemavar6c.gif)

**vim-sneak**, on the other hand, is also used for navigating your buffer. But instead of relying on marking texts with a keystroke like easymotion, it takes 1-2 characters as an input and marks the text that contains those input characters. As seen below. [Github](https://github.com/justinmk/vim-sneak)
![A GIF demonstrating sneak motions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9d12uxkuaw06fo2gnbdo.gif)


**Okay, full disclosure, I lied.**


I didn't actually use easymotion and vim-sneak in the GIFs above. I used hop.nvim.

**hop.nvim** is a navigation plugin that was created in order to solve easymotion's tendency to temporarily manipulate the buffer in order to mark texts and combines vim-sneak motion as a bonus. [Github](https://github.com/phaazon/hop.nvim)

You can combine the best of both worlds with one plugin and here's my Neovim configuration for it.

```lua
-- hop.nvim
require'hop'.setup()

-- normal mode (easymotion-like)
vim.api.nvim_set_keymap("n", "<Leader><Leader>b", "<cmd>HopWordBC<CR>", {noremap=true})
vim.api.nvim_set_keymap("n", "<Leader><Leader>w", "<cmd>HopWordAC<CR>", {noremap=true})
vim.api.nvim_set_keymap("n", "<Leader><Leader>j", "<cmd>HopLineAC<CR>", {noremap=true})
vim.api.nvim_set_keymap("n", "<Leader><Leader>k", "<cmd>HopLineBC<CR>", {noremap=true})

-- visual mode (easymotion-like)
vim.api.nvim_set_keymap("v", "<Leader><Leader>w", "<cmd>HopWordAC<CR>", {noremap=true})
vim.api.nvim_set_keymap("v", "<Leader><Leader>b", "<cmd>HopWordBC<CR>", {noremap=true})
vim.api.nvim_set_keymap("v", "<Leader><Leader>j", "<cmd>HopLineAC<CR>", {noremap=true})
vim.api.nvim_set_keymap("v", "<Leader><Leader>k", "<cmd>HopLineBC<CR>", {noremap=true})


-- normal mode (sneak-like)
vim.api.nvim_set_keymap("n", "s", "<cmd>HopChar2AC<CR>", {noremap=false})
vim.api.nvim_set_keymap("n", "S", "<cmd>HopChar2BC<CR>", {noremap=false})

-- visual mode (sneak-like)
vim.api.nvim_set_keymap("v", "s", "<cmd>HopChar2AC<CR>", {noremap=false})
vim.api.nvim_set_keymap("v", "S", "<cmd>HopChar2BC<CR>", {noremap=false})

```

`vim.api.nvim_set_keymap()` is used to bind keystrokes to a command in your init.lua file.

For those using Vimscript / VimL
```lua
vim.api.nvim_set_keymap("n", "<Leader><Leader>b", "<cmd>HopWordBC<CR>", {noremap=true})

-- is equivalent to

nnoremap <Leader><Leader>b :HopWordBC<CR>
```

There are more options for hop.nvim that you can check with `:h hop` but these are the ones I use.
- HopWord<u>BC</u> looks for a word <u>B</u>efore <u>C</u>ursor
- HopWord<u>AC</u> looks for a word <u>A</u>fter <u>C</u>ursor
- HopLineBC and HopLineAC does the same before and after cursor respectively, but looks for lines instead of words.
- HopChar<u>2AC</u> takes <u>2</u> characters as an input and looks for texts that contain those 2 characters <u>A</u>fter <u>C</u>ursor
- HopChar2BC does the same as HopChar2AC, but before the cursor


That's it! It's my first time posting in Dev.to and I'm glad to be part of this community.

Cheers!