I've published a Vim plugin that nudges visually selected lines up or down, which for the most part seems to function as designed. However, I believe there are likely ways that this plugin could be improved.
Questions
- How do I register a movement that takes an optional amount?
In other words how can this plugin differentiate between Shift^J and 3Shift^J?
Have I made any critical mistakes?
Are there any features that should be added?
Requirements
This plugin is tested on Linux based operating systems, but suggestions on how to make it OS agnostic are certainly welcomed; regardless Vim should be installed prior to using this plugin, eg...
sudo apt-get install vim
Setup
Source code is maintained on GitHub, as are the documentation files and README.md
. Included within this question are the TLDR and source .vim
script code files.
mkdir -vp ~/git/hub/vim-utilities
cd ~/git/hub/vim-utilities
git clone [email protected]:vim-utilities/nudge-lines.git
If not utilizing some form of Vim plugin manager, then the linked-install.sh
script may be run on most 'nix devices...
./linked-install.sh
... which will symbolically link plugin scripts and documentation, and update Vim documentation tags.
Usage
After visually selecting a line, or range of lines, use the following keyboard shortcuts:
Ctrl^k Nudge visual selection up
Shift^K Nudge visual selection up and reformat tabs
Ctrl^j Nudge visual selection down
Shift^J Nudge visual selection down and reformat tabs
Source Code
#!/usr/bin/env vim
vnoremap <S-K> :call Nudge_Selection__Laterally(-1, 'reformat')<CR>
vnoremap <C-K> :call Nudge_Selection__Laterally(-1)<CR>
vnoremap <S-J> :call Nudge_Selection__Laterally(1, 'reformat')<CR>
vnoremap <C-J> :call Nudge_Selection__Laterally(1)<CR>
""
" Nudges visually selected lines up or down
" @param {number} a:amount - Signed integer of lines to nudge selection by
" @param {string[]} a:0 - Optionally reformat tabs
" @example
" :'<,'> call Nudge_Selection__Laterally(-1, 'reformat')
" @author S0AndS0
" @license AGPL-3.0
function! Nudge_Selection__Laterally(amount, ...) abort range
let l:not_visual_mode = visualmode() != 'V'
let l:at_limits__lower = a:lastline == line('$')
let l:at_limits__upper = a:firstline == 1
if l:not_visual_mode
\ || (a:amount > 0 && l:at_limits__lower)
\ || (a:amount < 0 && l:at_limits__upper)
normal! gv
return
endif
if a:amount > 0
let l:move_command = "'>+" . a:amount
elseif a:amount < 0
let l:move_command = "'<-" . (1 - a:amount)
else
throw 'amount must be greater or less than 0'
endif
execute "'<,'>move " . l:move_command
if a:0 == 0
normal! gv
else
normal! gv=gv
endif
silent! foldopen!
endfunction
Side note, I'm not sure what's going on with syntax highlighting here, but as of latest revisions this plugin seem to function without error.
y
shortcut). You usualy press y And then an up or down arrow, optionally some numbers between to denote number of lines. Yours could behave similary. Visualy select lines, press Shift+j, nothing happens yet, press arrow up, all moves one line up, press 6 and arrow down, all moves 6 lines down... Its more flexible IMHO And you have saved Shift+k for a different feature... \$\endgroup\$