diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2022-09-15 12:14:32 -0600 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2022-09-15 12:14:32 -0600 |
commit | e867ab7ec24ae61f437b2dc928aff095c2ac4022 (patch) | |
tree | 692eb718c0e00846d6f2424c4b8685f495b77d65 | |
parent | 1ce32ad32e0006fbc7fe3e5e82f400ee0f7d52fa (diff) | |
download | fieldmarshal.vim-e867ab7ec24ae61f437b2dc928aff095c2ac4022.tar.gz fieldmarshal.vim-e867ab7ec24ae61f437b2dc928aff095c2ac4022.tar.bz2 fieldmarshal.vim-e867ab7ec24ae61f437b2dc928aff095c2ac4022.zip |
command.vim: change g: semantics
instead of starting a command around a text object, repeat the last
ranged command around that text object.
So one can now do something like
vip:sort<cr>
to sort the current paragraph, and then that command can be repeated
on a different paragraph with g:ip, and then the command is
dot-repeatable.
-rw-r--r-- | plugin/command.vim | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/plugin/command.vim b/plugin/command.vim index db18cf3..4101307 100644 --- a/plugin/command.vim +++ b/plugin/command.vim @@ -1,14 +1,53 @@ -" g: is a command to run a vim command around a text object. +" g: last command operator. " -" For example, to do a substitution inside the current block, one can do: +" Runs the last command over the given text object. " -" g:iBs/foo/bar/g<cr> +" By "last command" I mean the last command run with a range. This avoids all those pesky :w and :e +" commands. +" +" so now to join all lines in a text object one could do something like: +" +" vap:join<cr> +" +" now this command can be repeated around a different text object using g:, for example g:ab +" +" what's more is after using g:, it is dot-repeatable. +" +" Note that while this is powerful, it wil only work on line-style selections as that it a +" limitation of ex commands. noremap <silent> g: :set operatorfunc=<SID>do_command_around<cr>g@ +noremap <silent> g:: :set operatorfunc=<SID>do_command_around<cr>g@_ + +function! s:find_cmd() abort + let match_mark = "\\('.\\)\\?[0-9\\-+^$.%]*" + + let i = -1 + while 1 + let ocmd = histget(':', i) + + " Strip the leading range + let ncmd = substitute(ocmd, printf('\(%s\)\(,\(%s\)\)\?', match_mark, match_mark), "", "") + + if ncmd != ocmd + " If this command had a range, use that one. + let cmd = ncmd + break + endif + + let i -= 1 + endwhile + + return cmd +endfunction function! s:do_command_around(str) abort - let [_, lnum0, _, _] = getpos("'[") - let [_, lnum1, _, _] = getpos("']") + call setpos("'<", getpos("'[")) + call setpos("'>", getpos("']")) + + let cmd = s:find_cmd() + - call feedkeys(printf(":silent! %d,%d ", lnum0, lnum1)) + echo printf("'<,'>%s", cmd) + exec printf("'<,'>%s", cmd) endfunction |