aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2022-09-15 12:14:32 -0600
committerJosh Rahm <joshuarahm@gmail.com>2022-09-15 12:14:32 -0600
commite867ab7ec24ae61f437b2dc928aff095c2ac4022 (patch)
tree692eb718c0e00846d6f2424c4b8685f495b77d65
parent1ce32ad32e0006fbc7fe3e5e82f400ee0f7d52fa (diff)
downloadfieldmarshal.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.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