Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mawkler/demicolon.nvim
Overloaded ; and , keys in Neovim
https://github.com/mawkler/demicolon.nvim
neovim neovim-plugin plugin treesitter
Last synced: about 4 hours ago
JSON representation
Overloaded ; and , keys in Neovim
- Host: GitHub
- URL: https://github.com/mawkler/demicolon.nvim
- Owner: mawkler
- License: mit
- Created: 2024-08-06T20:41:10.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2024-10-26T20:40:42.000Z (24 days ago)
- Last Synced: 2024-10-26T22:35:10.631Z (24 days ago)
- Topics: neovim, neovim-plugin, plugin, treesitter
- Language: Lua
- Homepage:
- Size: 47.9 KB
- Stars: 73
- Watchers: 2
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# demicolon.nvim
In addition to repeating `t`/`T`/`f`/`F` motions, this plugin lets you repeat diagnostic jumps (e.g. `]d`/`[d`) and [nvim-treesitter-textobjects](https://github.com/nvim-treesitter/nvim-treesitter-textobjects?tab=readme-ov-file#text-objects-move) jumps (e.g. `]f`/`[f`) with the `;`/`,` keys.
This plugin also integrates with [gitsigns.nvim](https://github.com/lewis6991/gitsigns.nvim).
https://github.com/user-attachments/assets/e847cf39-40bd-49cb-9989-34e921b3393a
## Installation
With [lazy.nvim](https://github.com/folke/lazy.nvim):
```lua
{
'mawkler/demicolon.nvim',
-- keys = { ';', ',', 't', 'f', 'T', 'F', ']', '[', ']d', '[d' }, -- Uncomment this to lazy load
dependencies = {
'nvim-treesitter/nvim-treesitter',
'nvim-treesitter/nvim-treesitter-textobjects',
},
opts = {}
}
```## Usage
After pressing any of the keymaps below, demicolon.nvim lets you repeat them with `;` and `,`.
### Vertical motions (`t`/`T`/`f`/`F`)
See [`:help t`](https://neovim.io/doc/user/motion.html#t), [`:help T`](https://neovim.io/doc/user/motion.html#T), [`:help f`](https://neovim.io/doc/user/motion.html#f), and [`:help F`](https://neovim.io/doc/user/motion.html#F) respectively.
### Diagnostic motions
By default, demicolon.nvim will create the diagnostic motion keymaps below. See [Configuration](#Configuration) for info on how to disable default keymaps.
| Motion | Description |
| --------- | --------------------------------------- |
| `]d`/`[d` | Next/previous diagnostic (any severity) |
| `]e`/`[e` | Next/previous error |
| `]w`/`[w` | Next/previous warning |
| `]i`/`[i` | Next/previous information |
| `]h`/`[h` | Next/previous hint |### Treesitter text-object motions
demicolon.nvim lets you repeat any [nvim-treesitter-textobjects](https://github.com/nvim-treesitter/nvim-treesitter-textobjects?tab=readme-ov-file#text-objects-move) motion. For example: `]f` to "jump to next function", `]c` to "jump to next class", etc.
> [!NOTE]
> To use treesitter text-objects you need to [configure `textobjects.move` in nvim-treesitter-textobjects](https://github.com/nvim-treesitter/nvim-treesitter-textobjects?tab=readme-ov-file#text-objects-move).### Native Neovim motions
| Motion | Jumps to next/pevious... | Help page with more information |
| ----------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `]q`/`[q` | item in quickfix list | [`:help ]q`](https://neovim.io/doc/user/quickfix.html#%5Dq)/[`:help [q`](https://neovim.io/doc/user/quickfix.html#%5Bq) |
| `]l`/`[l` | item in location list | [`:help ]l`](https://neovim.io/doc/user/quickfix.html#%5Dl)/[`:help [l`](https://neovim.io/doc/user/quickfix.html#%5Bl) |
| `]`/`[` | file in quickfix list | [`:help ]CTRL-Q`](https://neovim.io/doc/user/quickfix.html#%5DCTRL-Q)/[`:help [CTRL-Q`](https://neovim.io/doc/user/quickfix.html#%5BCTRL-Q) |
| `]`/`[` | file in location list | [`:help ]CTRL-L`](https://neovim.io/doc/user/quickfix.html#%5DCTRL-L)/[`:help [CTRL-L`](https://neovim.io/doc/user/quickfix.html#%5BCTRL-L) |
| `]z`/`[z` | fold | [`:help zj`](https://neovim.io/doc/user/fold.html#zj)/[`:help zk`](https://neovim.io/doc/user/fold.html#zk) |
| `]s`/`[z` | spelling mistake | [`:help ]s`](https://neovim.io/doc/user/spell.html#%5Ds)/[`:help [s`](https://neovim.io/doc/user/spell.html#%5Bs) |## Configuration
Default options:
```lua
opts = {
diagnostic = {
-- See `:help vim.diagnostic.Opts.Float`
float = {}
},
-- Create default keymaps
keymaps = {
-- Create t/T/f/F key mappings
horizontal_motions = true,
-- Create ]d/[d, etc. key mappings to jump to diganostics. See demicolon.keymaps.create_default_diagnostic_keymaps
diagnostic_motions = true,
-- Create ; and , key mappings
repeat_motions = true,
-- Create ]q/[q/]/[ and ]l/[l/]/[ quickfix and location list mappings
list_motions = true,
-- Create `]s`/`[s` key mappings for jumping to spelling mistakes
spell_motions = true,
-- Create `]z`/`[z` key mappings for jumping to folds
fold_motions = true,
},
integrations = {
-- Integration with https://github.com/lewis6991/gitsigns.nvim
gitsigns = {
enabled = true,
keymaps = {
next = ']c',
prev = '[c',
},
},
},
}
```### Custom jumps
You can create your own custom repeatable jumps using `repeatably_do()` in [`demicolon.jump`](./lua/demicolon/jump.lua). `repeatably_do()` takes a funcion as its first argument and options to be passed to that function as its second argument. Make sure that the options include a boolean `forward` field to determine whether the action should be forward or backward. Take a look at how I've implemented the [gitsigns.nvim integration](./lua/demicolon/integrations/gitsigns.lua) for inspiration.
### eyeliner.nvim integration
[eyeliner.nvim](https://github.com/jinh0/eyeliner.nvim) can highlight unique letters in words when you press `t`/`T`/`f`/`F`. Below is my recommended configuration for using eyeliner.nvim together with demicolon.nvim.
**NOTE:** make sure to set `keymaps.horizontal_motions = false` in your demicolon setup if you want to use this config.
```lua
return {
'jinh0/eyeliner.nvim',
-- keys = { 't', 'f', 'T', 'F' }, -- Uncomment this to lazy load eyeliner.nvim
config = function()
require('eyeliner').setup({
highlight_on_key = true,
default_keymaps = false,
dim = true, -- Optional
})local function eyeliner_jump(key)
local forward = vim.list_contains({ 't', 'f' }, key)
return function()
require('eyeliner').highlight({ forward = forward })
return require('demicolon.jump').horizontal_jump(key)()
end
endlocal nxo = { 'n', 'x', 'o' }
local opts = { expr = true }vim.keymap.set(nxo, 'f', eyeliner_jump('f'), opts)
vim.keymap.set(nxo, 'F', eyeliner_jump('F'), opts)
vim.keymap.set(nxo, 't', eyeliner_jump('t'), opts)
vim.keymap.set(nxo, 'T', eyeliner_jump('T'), opts)
end
}
```### Full recommended config
Here is a full configuration, including [nvim-treesitter-textobjects](https://github.com/nvim-treesitter/nvim-treesitter-textobjects) and [eyeliner.nvim](https://github.com/jinh0/eyeliner.nvim):
Click here to see the code
```lua
require('lazy').setup({
{
'nvim-treesitter/nvim-treesitter-textobjects',
dependencies = 'nvim-treesitter/nvim-treesitter',
build = ':TSUpdate',
config = function()
require('nvim-treesitter.configs').setup({
ensure_installed = 'all',
textobjects = {
move = {
enable = true,
goto_next_start = {
["]f"] = "@function.outer",
["]a"] = "@argument.outer",
["]m"] = "@method.outer",
-- ...
},
goto_previous_start = {
["[f"] = "@function.outer",
["[a"] = "@argument.outer",
["[m"] = "@method.outer",
-- ...
},
},
},
})
end,
},
{
'jinh0/eyeliner.nvim',
keys = { 't', 'f', 'T', 'F' },
opts = {
highlight_on_key = true,
dim = true,
default_keymaps = false,
}
},
{
'mawkler/demicolon.nvim',
dependencies = {
'jinh0/eyeliner.nvim',
'nvim-treesitter/nvim-treesitter',
'nvim-treesitter/nvim-treesitter-textobjects'
},
keys = { ';', ',', 't', 'f', 'T', 'F', ']', '[', ']d', '[d' },
config = function()
require('demicolon').setup({
keymaps = {
horizontal_motions = false,
},
})local function eyeliner_jump(key)
local forward = vim.list_contains({ 't', 'f' }, key)
return function()
require('eyeliner').highlight({ forward = forward })
return require('demicolon.jump').horizontal_jump(key)()
end
endlocal nxo = { 'n', 'x', 'o' }
local opts = { expr = true }vim.keymap.set(nxo, 'f', eyeliner_jump('f'), opts)
vim.keymap.set(nxo, 'F', eyeliner_jump('F'), opts)
vim.keymap.set(nxo, 't', eyeliner_jump('t'), opts)
vim.keymap.set(nxo, 'T', eyeliner_jump('T'), opts)
end
}
})
```[Here's](https://github.com/nvim-treesitter/nvim-treesitter-textobjects?tab=readme-ov-file#built-in-textobjects) the full list of available treesitter textobjects.
### "I want `;`/`,` to remember the direction of the original jump"
Neovim's default behaviour is for `;`/`,` to remember the direction of the jump that they repeat. That means that if you for instance repeat a `T` motion (as opposed to `t`) with `;` it will move you to the _left_. A lot of people prefer if `;` always moves you to the right and `,` always to the left, which is how demicolon works by default.
If you prefer Neovim's default behaviour you can disable demicolon's default `;`/`,` keymaps and remap them manually like this:
Click here to see the code
```lua
require('demicolon').setup({
keymaps = {
repeat_motions = false,
},
})local ts_repeatable_move = require('nvim-treesitter.textobjects.repeatable_move')
local nxo = { 'n', 'x', 'o' }vim.keymap.set(nxo, ';', ts_repeatable_move.repeat_last_move)
vim.keymap.set(nxo, ',', ts_repeatable_move.repeat_last_move_opposite)
```## Credit
The treesitter portion of this plugin is just a wrapper over [nvim-treesitter-textobjects](https://github.com/nvim-treesitter/nvim-treesitter-textobjects). Credit to them for making an awesome plugin!