diff options
author | Josh Rahm <rahm@google.com> | 2022-09-12 16:29:49 -0600 |
---|---|---|
committer | Josh Rahm <rahm@google.com> | 2022-09-12 16:29:49 -0600 |
commit | e3716c7ae015a5ea960c47d2aa4e975e93d66151 (patch) | |
tree | a7a087197a35d7fc81a67c46aef808ed06362ec9 | |
parent | c055c2f90c7ed43ea61775f08d890a5de34a242e (diff) | |
download | fieldmarshal.vim-e3716c7ae015a5ea960c47d2aa4e975e93d66151.tar.gz fieldmarshal.vim-e3716c7ae015a5ea960c47d2aa4e975e93d66151.tar.bz2 fieldmarshal.vim-e3716c7ae015a5ea960c47d2aa4e975e93d66151.zip |
insert.vim: add cI and cgI commands.
c[g]I - starts insert after the v:count1'th WORD. If the g is not
supplied, whitespace is skipped and insert starts right before th
e (v:count1+1)'th WORD.
-rw-r--r-- | plugin/insert.vim | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/plugin/insert.vim b/plugin/insert.vim new file mode 100644 index 0000000..c6de7a2 --- /dev/null +++ b/plugin/insert.vim @@ -0,0 +1,61 @@ +" Other operators for entering insert mode. + +" Like 'I', but skip past the first v:count1 WORDs. Useful for when one wants +" the 'I' behavior to respect comments. +" +" If there are fewer than v:count1 WORDs in the line, then append to the end of +" the line. +" +" Have to cheese this a little bit to get the redo (.) operator to work with it. +" This is done by making a "sort-of" 0-width text object that exists where the +" change should happen. +" +" If the 'g' is present, that acts similar to gI -- it does not skip +" whitespace and starts insertion directly after the v:count1'th word. +noremap cI <cmd>call <sid>insert_comment_count(v:count1)<cr>1c<Plug><sid>(insert-comment-obj-nog) +noremap cgI <cmd>call <sid>insert_comment_count(v:count1)<cr>1c<Plug><sid>(insert-comment-obj-g) +onoremap <Plug><sid>(insert-comment-obj-nog) <cmd>call <sid>insert_comment_obj(0)<cr> +onoremap <Plug><sid>(insert-comment-obj-g) <cmd>call <sid>insert_comment_obj(1)<cr> + +function! s:insert_comment_count(count) abort + let s:count = a:count +endfunction + +function! s:insert_comment_obj(g, ...) abort + if v:operator == 'c' + let end = 0 + normal! 0 + let i = 0 + call search('^\s*\zs\S', '', line('.')) + while i < s:count + if col('.') == col('$') - 1 + let end = 1 + break + endif + + if a:g + let pattern = '\S*\zs\ze\s\+' + else + let pattern = '\S*\s\+\zs' + endif + + if ! search(pattern, '', line('.')) + let end = 1 + break + endif + + let i += 1 + endwhile + + " Cheese because 0-width visual selections aren't a thing, I don't think, so + " instead insert an ephemeral space and VIsual highlight that space, the c + " command will then remove that ephemeral space, all with the user being + " none-the-wiser. + if end + exec "normal! A \<esc>v" + else + exec "normal! i \<esc>v" + endif + else + endif +endfunction |