aboutsummaryrefslogtreecommitdiff
path: root/plugin/command.vim
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/command.vim')
-rw-r--r--plugin/command.vim51
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