aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugin/insert.vim61
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