Quickly jump between next and previous NeoVim buffer, tab, file, quickfix, diagnostic, etc.
A lightweight plugin inspired by unimpaired.vim, but:
Use b (buffer) as an example:
]b/[b jump to next/previous buffer. Then just pressing <c-n><c-n><c-n><c-p><c-p>... to cycle
through buffers.]B/[B jump to last/first buffer.| Operator | Description |
|---|---|
| a, A | Tab |
| b, B | Buffer |
| d | Diagnostic |
| e | Edit (Change list) |
| f, F | File |
| l, L, C-l, M-l | Location list |
| q, Q, C-q, M-q | Quickfix |
| s | Spell |
| t, T, C-t | Tag |
| z | Fold |
| ' | Mark |
operators = {
["a"] = {
next = { rhs = "<cmd>tabnext<cr>", opts = { desc = "Next tab" } },
prev = { rhs = "<cmd>tabprevious<cr>", opts = { desc = "Prev tab" } },
},
["A"] = {
next = { rhs = "<cmd>tablast<cr>", opts = { desc = "Last tab" } },
prev = { rhs = "<cmd>tabfirst<cr>", opts = { desc = "First tab" } },
},
["b"] = {
next = { rhs = "<cmd>bnext<cr>", opts = { desc = "Next buffer" } },
prev = { rhs = "<cmd>bprevious<cr>", opts = { desc = "Prev buffer" } },
},
["B"] = {
next = { rhs = "<cmd>blast<cr>", opts = { desc = "Last buffer" } },
prev = { rhs = "<cmd>bfirst<cr>", opts = { desc = "First buffer" } },
},
["d"] = {
next = { rhs = vim.diagnostic.goto_next, opts = { desc = "Next diagnostic" } },
prev = { rhs = vim.diagnostic.goto_prev, opts = { desc = "Prev diagnostic" } },
mode = { "n", "v", "o" }
},
["e"] = {
next = { rhs = "g;", opts = { desc = "Older edit (change-list) item" } },
prev = { rhs = "g,", opts = { desc = "Newer edit (change-list) item" } }
},
["f"] = {
next = { rhs = M.next_file, opts = { desc = "Next file" } },
prev = { rhs = M.prev_file, opts = { desc = "Prev file" } },
},
["F"] = {
next = { rhs = M.last_file, opts = { desc = "Last file" } },
prev = { rhs = M.first_file, opts = { desc = "First file" } },
},
["l"] = {
next = { rhs = "<cmd>lnext<cr>", opts = { desc = "Next loclist item" } },
prev = { rhs = "<cmd>lprevious<cr>", opts = { desc = "Prev loclist item" } }
},
["L"] = {
next = { rhs = "<cmd>llast<cr>", opts = { desc = "Last loclist item" } },
prev = { rhs = "<cmd>lfirst<cr>", opts = { desc = "First loclist item" } }
},
["<C-l>"] = {
next = { rhs = "<cmd>lnfile<cr>", opts = { desc = "Next loclist item in different file" } },
prev = { rhs = "<cmd>lpfile<cr>", opts = { desc = "Prev loclist item in different file" } }
},
["<M-l>"] = {
next = { rhs = "<cmd>lnewer<cr>", opts = { desc = "Next loclist list" } },
prev = { rhs = "<cmd>lolder<cr>", opts = { desc = "Prev loclist list" } }
},
["q"] = {
next = { rhs = "<cmd>cnext<cr>", opts = { desc = "Next quickfix item" } },
prev = { rhs = "<cmd>cprevious<cr>", opts = { desc = "Prev quickfix item" } }
},
["Q"] = {
next = { rhs = "<cmd>clast<cr>", opts = { desc = "Last quickfix item" } },
prev = { rhs = "<cmd>cfirst<cr>", opts = { desc = "First quickfix item" } }
},
["<C-q>"] = {
next = { rhs = "<cmd>cnfile<cr>", opts = { desc = "Next quickfix item in different file" } },
prev = { rhs = "<cmd>cpfile<cr>", opts = { desc = "Prev quickfix item in different file" } }
},
["<M-q>"] = {
next = { rhs = "<cmd>cnewer<cr>", opts = { desc = "Next quickfix list" } },
prev = { rhs = "<cmd>colder<cr>", opts = { desc = "Prev quickfix list" } }
},
["s"] = {
next = { rhs = "]s", opts = { desc = "Next spell error" } },
prev = { rhs = "[s", opts = { desc = "Prev spell error" } },
mode = { "n", "v", "o" },
},
["t"] = {
next = { rhs = "<cmd>tnext<cr>", opts = { desc = "Next tag" } },
prev = { rhs = "<cmd>tprevious<cr>", opts = { desc = "Prev tag" } }
},
["T"] = {
next = { rhs = "<cmd>tlast<cr>", opts = { desc = "Last tag" } },
prev = { rhs = "<cmd>tfirst<cr>", opts = { desc = "First tag" } }
},
["<C-t>"] = {
next = { rhs = "<cmd>ptnext<cr>", opts = { desc = "Next tag in previous window" } },
prev = { rhs = "<cmd>ptprevious<cr>", opts = { desc = "Prev tag in previous window" } }
},
["z"] = {
next = { rhs = "zj", opts = { desc = "Next fold" } },
prev = { rhs = "zk", opts = { desc = "Prev fold" } },
mode = { "n", "v", "o" },
},
["'"] = {
next = { rhs = "]`", opts = { desc = "Next lowercase mark" } },
prev = { rhs = "[`", opts = { desc = "Prev lowercase mark" } }
},
You can add/override operators easily, for example:
require("nap").map("o", {
next = { rhs = "<cmd>AerialNext<cr>", opts = { desc = "Next outline symbol" } },
prev = { rhs = "<cmd>AerialPrev<cr>", opts = { desc = "Prev outline symbol" } },
mode = { "n", "v", "o" },
})
Under hood, this plugin calls vim.keymap.set to define two keybindings for you, see its doc about
rhs and opts.
Helper functions are provided for the following plugins to save your time:
-- The provided implementation falls back to ]c [c in diff mode.
require("nap").map('c', require("nap").gitsigns())
require("nap").map('o', require("nap").aerial())
require("nap").map('r', require("nap").illuminate())
You can also add/remove operators inside setup call if you prefer to put them in a central place, see next section.
Add liangxianzhe/nap-nvim to your plugin manager. Call require("nap").setup() to use defaults:
require("nap").setup({
next_prefix = "]",
prev_prefix = "[",
next_repeat = "<c-n>",
prev_repeat = "<c-p>",
-- to exclude some keys from the default
exclude_default_operators = {"a", "A"},
-- to add custom keys
operators = {
...
},
})
We need two pairs of keys: prefix keys to trigger the first jump, and repeat keys to repeat with
a single press.
The best config for you depends on many factors. Here are a few examples, feel free to try it out:
] and [ (":help ]" to check default mappings)<C-n> and <C-p><Enter> and <C-Enter> (Some terminal doesn't support C-Enter)<Enter> and \ (If you remap leader key, the original leader key is near Enter)<Space> and <C-Space>; and , (use flash.nvim, flit.nvim or similar plugins to free these two keys)> and < (":help >" to check default mappings)Alt prefixed keys (Need terminal supports)Technically you can set prefix and repeat to the same key (e.g. ]). It has one issue that when
pressing ] to repeat jump, vim will need to wait
timeoutlen to determine whether its is ]
or ]b.