vim-remotions : Allow to repeat motions or actions using the , and ; keys.
script karma |
Rating 0/0,
Downloaded by 30 |
Comments, bugs, improvements
|
Vim wiki
|
created by |
Vivian De Smedt |
|
script type |
utility |
|
description |
Remotions
Introduction
In standard Vim/Neovim the `;` and `,` keys repeats the `f`, `F`, `t` and `T` motions.
But for the other motions or actions (e.g. `}`, `]m`, <kbd>Ctrl+w</kbd>`>`) there are no builtin ways to repeat them.
The goal of this plugin is allow to repeat the other motions or actions using the `;` and `,` keys.
It is particularly useful for double characters motions likes next/previous method: `[m`/`]m`.
Count
It is also useful for motions with a count `10j` (10 lines down).
It is possible to configure some motions to be repeatable only if they are executed with a count above 1.
Repetition Direction
The repetition of the motions can be configured as to be done in the direction of:
- The initial motion (`;` repeat the motion, `,` undo the motion, the Vim/Neovim default) or of
- The document (`;` goes forward, `,` goes backward)
e.g. When the `[m` motion will be repeated:
If "direction of the document" has been selected then:
- The forward repetition `;` will do `]m` and
- The backward repetition `,` will do `[m`
If "direction of the initial motion" has been selected then:
- The forward repetition `;` will do `[m` and
- The backward repetition `,` will do `]m`
Advantages
The advantages of remotions on the other existing plugins identified are:
- It supports also plugin motions/operation defined both globally or at buffer level
- It supports repetition of motion including their count if different from 1 (optional)
Requirements
Tested on Vim >= 8.2 and Neovim >= 0.8.3
Installation
For [vim-plug](https://github.com/junegunn/vim-plug) users:
vim
Plug 'vds2212/vim-remotions'
For [lazy.vim]() users:
lua
local motions = {
para = { backward = "{", forward = "}" },
sentence = { backward = "(", forward = ")" },
change = { backward = "g,", forward = "g;" },
class = { backward = "[[", forward = "]]" },
classend = { backward = "[]", forward = "][" },
method = { backward = "[m", forward = "]m" },
methodend = { backward = "[M", forward = "]M" },
arg = { backward = "[a", forward = "]a" },
buffer = { backward = "[b", forward = "]b" },
location = { backward = "[l", forward = "]l" },
quickfix = { backward = "[q", forward = "]q" },
tag = { backward = "[t", forward = "]t" },
diagnostic = { backward = "[g", forward = "]g" },
}
return {
"vds2212/vim-remotions",
event = { "BufRead", "BufWinEnter", "BufNewFile" },
config = function()
vim.g.remotions_motions = motions
end,
}
Configuration
Motions
It is possible to configure the motions that should be considered:
For each motion three information have to be provided and some options can be set:
- The `name` of the motion (e.g. `para`)
- The `backward` motion key sequence (e.g. `{`)
- The `forward` motion key sequence (e.g. `}`)
- The `repeat_if_count` option for the motion.
If set the motion is repeatable only if it has been executed with a count above of 1.
- The `repeat_count` option for the motion.
If present overrides `g:remotions_repeat_count` of the motion.
Remark: Not all motions support count.
If the original motion does not support count the repetition will also not.
- The `direction` option for the motion.
If present overrides `g:remotions_direction` of the motion.
Here is the Remotions default:
vim
let g:remotions_motions = {
\ 'TtFf' : {},
\ 'para' : { 'backward' : '{', 'forward' : '}' },
\ 'change' : { 'backward' : 'g,', 'forward' : 'g;' },
\ 'class' : { 'backward' : '[[', 'forward' : ']]' },
\ 'classend' : { 'backward' : '[]', 'forward' : '][' },
\ 'method' : { 'backward' : '[m', 'forward' : ']m' },
\ 'methodend' : { 'backward' : '[M', 'forward' : ']M' },
\
\ 'buffer' : { 'backward' : '[b', 'forward' : ']b'},
\ 'location' : { 'backward' : '[l', 'forward' : ']l'},
\ 'quickfix' : { 'backward' : '[q', 'forward' : ']q'},
\ 'tag' : { 'backward' : '[t', 'forward' : ']t'},
\
\ 'diagnostic' : { 'backward' : '[g', 'forward' : ']g'},
\ }
Here is an more extensive list of motions:
vim
let g:remotions_motions = {
\ 'TtFf' : {},
\ 'para' : { 'backward' : '{', 'forward' : '}' },
\ 'sentence' : { 'backward' : '(', 'forward' : ')' },
\ 'change' : { 'backward' : 'g,', 'forward' : 'g;' },
\ 'class' : { 'backward' : '[[', 'forward' : ']]' },
\ 'classend' : { 'backward' : '[]', 'forward' : '][' },
\ 'method' : { 'backward' : '[m', 'forward' : ']m' },
\ 'methodend' : { 'backward' : '[M', 'forward' : ']M' },
\
\ 'line' : {
\ 'backward' : 'k',
\ 'forward' : 'j',
\ 'repeat_if_count' : 1,
\ 'repeat_count': 1
\ },
\ 'displayline' : {
\ 'backward' : 'gk',
\ 'forward' : 'gj',
\ },
\
\ 'char' : { 'backward' : 'h',
\ 'forward' : 'l',
\ 'repeat_if_count' : 1,
\ 'repeat_count': 1
\ },
\
\ 'word' : {
\ 'backward' : 'b',
\ 'forward' : 'w',
\ 'repeat_if_count' : 1,
\ 'repeat_count': 1
\ },
\ 'fullword' : { 'backward' : 'B',
\ 'forward' : 'W',
\ 'repeat_if_count' : 1,
\ 'repeat_count': 1
\ },
\ 'wordend' : { 'backward' : 'ge',
\ 'forward' : 'e',
\ 'repeat_if_count' : 1,
\ 'repeat_count': 1
\ },
\
\ 'pos' : { 'backward' : '<C-i>', 'forward' : '<C-o>' },
\
\ 'page' : { 'backward' : '<C-u>', 'forward' : '<C-d>' },
\ 'pagefull' : { 'backward' : '<C-b>', 'forward' : '<C-f>' },
\
\ 'undo' : { 'backward' : 'u', 'forward' : '<C-r>', 'direction' : 1 },
\
\ 'linescroll' : { 'backward' : '<C-e>', 'forward' : '<C-y>' },
\ 'columnscroll' : { 'backward' : 'zh', 'forward' : 'zl' },
\ 'columnsscroll' : { 'backward' : 'zH', 'forward' : 'zL' },
\
\ 'vsplit' : { 'backward' : '<C-w><', 'forward' : '<C-w>>' },
\ 'hsplit' : { 'backward' : '<C-w>-', 'forward' : '<C-w>+' },
\
\ 'arg' : { 'backward' : '[a', 'forward' : ']a'},
\ 'buffer' : { 'backward' : '[b', 'forward' : ']b'},
\ 'location' : { 'backward' : '[l', 'forward' : ']l'},
\ 'quickfix' : { 'backward' : '[q', 'forward' : ']q'},
\ 'tag' : { 'backward' : '[t', 'forward' : ']t'},
\
\ 'diagnostic' : { 'backward' : '[g', 'forward' : ']g'},
\ }
Remark: The `TtFf` motion corresponds to the `e`, `f` motions.
The entry can be used to specify the options for that motion (i.e.: `repeat_if_count`, `repeat_count`, `direction`).
Lua example
The following is an example of usage with [lazy.nvim](https://github.com/folke/lazy.nvim):
lua
local motions = {
para = { backward = "{", forward = "}" },
sentence = { backward = "(", forward = ")" },
change = { backward = "g,", forward = "g;" },
class = { backward = "[[", forward = "]]" },
classend = { backward = "[]", forward = "][" },
method = { backward = "[m", forward = "]m" },
methodend = { backward = "[M", forward = "]M" },
line = { backward = "k", forward = "j", repeat_if_count = 1, repeat_count = 1 },
char = { backward = "h", forward = "l", repeat_if_count = 1, repeat_count = 1 },
word = { backward = "b", forward = "w", repeat_if_count = 1, repeat_count = 1 },
fullword = { backward = "B", forward = "W", repeat_if_count = 1, repeat_count = 1 },
wordend = { backward = "ge", forward = "e", repeat_if_count = 1, repeat_count = 1 },
pos = { backward = "<C-i>", forward = "<C-o>" },
page = { backward = "<C-u>", forward = "<C-d>" },
pagefull = { backward = "<C-b>", forward = "<C-f>" },
undo = { backward = "u", forward = "<C-r>", direction = 1 },
linescroll = { backward = "<C-e>", forward = "<C-y>" },
charscroll = { backward = "zh", forward = "zl" },
vsplit = { backward = "<C-w><", forward = "<C-w>>" },
hsplit = { backward = "<C-w>-", forward = "<C-w>+" },
arg = { backward = "[a", forward = "]a" },
buffer = { backward = "[b", forward = "]b" },
location = { backward = "[l", forward = "]l" },
quickfix = { backward = "[q", forward = "]q" },
tag = { backward = "[t", forward = "]t" },
diagnostic = { backward = "[g", forward = "]g" },
}
local leap_motions = {
leap_fwd = {
backward = "<Plug>(leapbackward)",
forward = "<Plug>(leapforward)",
motion = "s",
motion_plug = "<Plug>(leap-forward-to)",
},
leap_bck = {
backward = "<Plug>(leapforward)",
forward = "<Plug>(leapbackward)",
motion = "S",
motion_plug = "<Plug>(leap-backward-to)",
},
}
return {
"vds2212/vim-remotions",
event = { "BufRead", "BufWinEnter", "BufNewFile" },
config = function()
if vim.g.loaded_leap then
vim.g.remotions_motions = vim.tbl_deep_extend("error", motions, leap_motions)
else
vim.g.remotions_motions = motions
end
end,
}
Note: If using leap.nvim, you'll need to manually set `vim.g.loaded_leap` until [this leap issue](https://github.com/ggandor/leap.nvim/issues/200) is resolved.
Direction
The direction of the repeated motion can be configured using the `g:remotions_direction`
vim
" Set the direction of the repetition to the direction of the initial move (the Vim default):
let g:remotions_direction = 0
vim
" Set the direction of the repetition to the direction of the document:
let g:remotions_direction = 1
Remark: This `g:remotions_direction` setting is overridden by the `direction` option of the motion if set.
Repeat Count
Some motions support `count` (e.g. `i`, `j`, `}`, etc.). E.g.: `2j` make the cursor go 2 lines below.
When a motion is repeated via `;` or `,` the original count is not take into consideration.
This is also the Vim default for the `f` and `t` motions.
If you want that the original count is taken in consideration:
vim
" Make the ; and , key also repeat the count when supported by the original move
let g:remotions_repeat_count = 1
Remark: This `g:remotions_repeat_count` is overridden by the `repeat_count` option of the motion if set.
Special Motion
Motion plugins are special because:
- They are triggered by a key or a key combination that is not the one used to repeat the action
- The hijacking of the trigger could requires some hint
Here are the configurations proposed for some of the popular ones:
- [vim-easymotion](https://github.com/easymotion/vim-easymotion)
- [leap.nvim](https://github.com/ggandor/leap.nvim)
- [vim-sneak](https://github.com/justinmk/vim-sneak)
EasyMotion
Here is a solution for repeating the [vim-easymotion](https://github.com/easymotion/vim-easymotion) motions:
vim
let g:remotions_motions = {
\ 'leap_fwd' : {
\ 'backward' : '<Plug>(easymotion-prev)',
\ 'forward' : '<Plug>(easymotion-next)',
\ 'motion': '<leader><leader>',
\ 'motion_plug' : '<Plug>(easymotion-prefix)'
\ },
\ }
Leap
Here is a solution for repeating the [leap.nvim](https://github.com/ggandor/leap.nvim) motions:
vim
lua require('leap').add_repeat_mappings('<Plug>(leapforward)', '<Plug>(leapbackward)')
let g:remotions_motions = {
\ 'leap_fwd' : {
\ 'backward' : '<Plug>(leapbackward)',
\ 'forward' : '<Plug>(leapforward)',
\ 'motion': 's',
\ 'motion_plug' : '<Plug>(leap-forward-to)'
\ },
\ 'leap_bck' : {
\ 'backward' : '<Plug>(leapbackward)',
\ 'forward' : '<Plug>(leapforward)',
\ 'motion': 's',
\ 'motion_plug' : '<Plug>(leap-backward-to)'
\ },
\ }
Sneak
Here is a solution for repeating the [vim-sneak](https://github.com/justinmk/vim-sneak) motions:
vim
let g:remotions_motions = {
\ 'sneak_fwd' : {
\ 'backward' : '<Plug>Sneak_,',
\ 'forward' : '<Plug>Sneak_;',
\ 'motion': 's',
\ 'motion_plug' : '<Plug>Sneak_s'
\ },
\ 'sneak_bckwd' : {
\ 'backward' : '<Plug>Sneak_,',
\ 'forward' : '<Plug>Sneak_;',
\ 'motion': 's',
\ 'motion_plug' : '<Plug>Sneak_S'
\ },
Similar Projects
Repmo
The [repmo.vim](https://www.vim.org/scripts/script.php?script_id=2174)
or its new [version](https://github.com/Houl/repmo-vim)
is mature plugin used by a number of people.
In my experience repmo works well for builtin commands.
But when the builtin command are overridden for a specific `filetype` (e.g. `]m` for the `python` `filetype`).
or when it is overridden by a `filetype` plugin (e.g. `]m` with [pythonsense](https://github.com/jeetsukumaran/vim-pythonsense))
I had difficulty to make it working (I failed).
I'm wondering also how repmo handle commands that are overridden by two different plugins for two different `filetype`.
These difficulty made me write [remotions](https://github.com/vds2212/vim-remotions).
If one of the previous statements about repmo is imprecise or wrong I'll more than happy to rectify the text.
Raise an issue and I will adapt the text of this readme file.
Repeatable-Motions
The [repeatable-motions.vim](https://www.vim.org/scripts/script.php?script_id=4914) is a mature plugin.
It introduces four keys to repeat the motions:
- <kbd>Ctrl j</kbd>, <kbd>Ctrl k</kbd> for the vertical motions.
- <kbd>Ctrl h</kbd>, <kbd>Ctrl l</kbd> for the horizontal motions.
In my experience repeatable-motions works well for builtin commands.
It supports a number of builtin motions.
But when the builtin command are overridden for a specific `filetype` (e.g. `]m` for the `python` `filetype`).
or when it is overridden by a `filetype` plugin (e.g. `]m` with [pythonsense](https://github.com/jeetsukumaran/vim-pythonsense))
I had difficulty to make it working (I failed).
If one of the previous statements about repeatable-motions is imprecise or wrong I'll more than happy to rectify the text.
Raise an issue and I will adapt the text of this readme file.
Repeat Motion
According to the documentation [repeat-motion](https://www.vim.org/scripts/script.php?script_id=3665)
only repeat a set of predefined builtin motions (i.e. `k`, `j`, `h`, `l`, `w`, `b`, `W`, `B`, `e`, `E`, `ge`, `gE`)
|
|
install details |
|
|
script versions (upload new version)
Click on the package to download.
ip used for rating: 13.58.157.160
|