aboutsummaryrefslogtreecommitdiff
path: root/plugin/insert.vim
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/insert.vim')
-rw-r--r--plugin/insert.vim126
1 files changed, 106 insertions, 20 deletions
diff --git a/plugin/insert.vim b/plugin/insert.vim
index 3caca81..722c0b5 100644
--- a/plugin/insert.vim
+++ b/plugin/insert.vim
@@ -57,6 +57,17 @@ if g:field_marshal_insert_include_bindings
"
noremap Zi <Plug>(insert-before-motion)
noremap Za <Plug>(append-after-motion)
+ noremap Zo <Plug>(open-after-motion)
+ noremap ZO <Plug>(OPEN-after-motion)
+
+ noremap Z[ <Plug>(to-object-start)
+ noremap Z] <Plug>(to-object-end)
+
+ " Zgi -- start another insert using the same parameters from the last Z[ia]
+ noremap Zgi c<Plug>(insert-about-obj)
+
+ vnoremap <expr> Zi "\<esc>'<" . (visualmode() == "V" ? "0" : "") . "i"
+ vnoremap <expr> Za "\<esc>'>" . (visualmode() == "V" ? "$" : "") . "a"
endif
noremap <Plug>(insert-after-comment) <cmd>call <sid>insert_comment_count(v:count1)<cr>1c<Plug><sid>(insert-comment-obj-nog)
@@ -110,12 +121,62 @@ function! s:insert_comment_obj(g, ...) abort
endif
endfunction
-noremap <silent> <Plug>(insert-before-motion) <cmd>call <sid>save_state('i')
- \<bar>call <sid>start_recording()
- \<bar>set operatorfunc=<sid>recordop<cr>g@
-noremap <silent> <Plug>(append-after-motion) <cmd>call <sid>save_state('a')
- \<bar>call <sid>start_recording()
- \<bar>set operatorfunc=<sid>recordop<cr>g@
+noremap <silent> <Plug>(insert-before-motion)
+ \ <cmd>call <sid>prepare_operation('i', "c\<Plug>(insert-about-obj)")
+ \<bar>call <sid>start_recording()
+ \<bar>set operatorfunc=<sid>recordop<cr>g@
+
+noremap <silent> <Plug>(append-after-motion)
+ \ <cmd>call <sid>prepare_operation('a', "c\<Plug>(insert-about-obj)")
+ \<bar>call <sid>start_recording()
+ \<bar>set operatorfunc=<sid>recordop<cr>g@
+
+noremap <silent> <Plug>(open-after-motion)
+ \ <cmd>call <sid>prepare_operation('o', "c\<Plug>(insert-about-obj)")
+ \<bar>call <sid>start_recording()
+ \<bar>set operatorfunc=<sid>recordop<cr>g@
+
+noremap <silent> <Plug>(OPEN-after-motion)
+ \ <cmd>call <sid>prepare_operation('O', "c\<Plug>(insert-about-obj)")
+ \<bar>call <sid>start_recording()
+ \<bar>set operatorfunc=<sid>recordop<cr>g@
+
+nnoremap <silent> <Plug>(to-object-start)
+ \ <cmd>call <sid>prepare_operation('[', "\<Plug>(to-object-pos-post)")
+ \<bar>call <sid>start_recording()
+ \<bar>set operatorfunc=<sid>recordop<cr>g@
+nnoremap <silent> <Plug>(to-object-end)
+ \ <cmd>call <sid>prepare_operation(']', "\<Plug>(to-object-pos-post)")
+ \<bar>call <sid>start_recording()
+ \<bar>set operatorfunc=<sid>recordop<cr>g@
+
+" The Z[ and Z] commands as text motions. These are done in a similar hacky way as other plugin
+" mappings in this file
+"
+" What they do, is:
+"
+" 1. prepare the operation, and prepare to send <operator>\<plug>(to-object-pos-post)
+" 2. escape operator-pending mode. This mapping is not the actual mapping we want to use for the
+" operation, we just use this as a dummy to set up all the variables needed for the actual
+" operation.
+" 3. start the recording macro.
+" 4. enter operating-pending mode again. This will record the macro. Once the user has entered the
+" operator, it will then call the <operator>\<plug>(to-object-pos-post). This is the command
+" that we really want to be able repeat with the dot (.) operator.
+onoremap <silent> <Plug>(to-object-start)
+ \ <cmd>call <sid>prepare_operation('[', printf("%s\<Plug>(to-object-pos-post)", v:operator))<cr>
+ \<esc>
+ \<cmd>call <sid>start_recording()
+ \<bar>set operatorfunc=<sid>recordop<cr>g@
+onoremap <silent> <Plug>(to-object-end)
+ \ <cmd>call <sid>prepare_operation(']', printf("%s\<Plug>(to-object-pos-post)", v:operator))<cr>
+ \<esc>
+ \<cmd>call <sid>start_recording()
+ \<bar>set operatorfunc=<sid>recordop<cr>g@
+
+onoremap <silent> <Plug>(to-object-pos-post) <cmd>call <sid>to_object_start()<cr>
+nnoremap <silent> <Plug>(to-object-pos-post) <cmd>call <sid>to_object_start()<cr>
+
onoremap <silent> <Plug>(insert-about-obj) <cmd>call <sid>insert_before_recorded()<cr>
nnoremap <silent> <Plug>(insert-about-obj) <cmd>call <sid>insert_before_recorded()<cr>
@@ -137,7 +198,9 @@ function! s:start_recording()
exec "normal! q" . s:reg_to_clobber
endfunction
-function! s:save_state(instype)
+let s:operate_keys=''
+function! s:prepare_operation(instype, operate_keys)
+ echom "operate_keys: " . a:operate_keys
" Unfortunately macros kinda break this feature. While I think I might be able
" to patch together a fix to make them work, I figure that I'll see if there's
" any real need to implement it.
@@ -148,6 +211,7 @@ function! s:save_state(instype)
let s:savereg = [getreg(s:reg_to_clobber, 1, 1), getregtype(s:reg_to_clobber)]
let s:savepos = getpos('.')
let s:instype = a:instype
+ let s:operate_keys = a:operate_keys
endfunction
noremap <plug>(ñóþ) <nop>
@@ -161,18 +225,23 @@ function s:save_object(t) abort
\ }
endfunction
-function! s:insert_before_recorded() abort
- " A limitation of normal! is that it can't start with a space, so use a NOP
- " instead.
- if s:recorded =~ '^\s'
- let s:recorded = "\<plug>(ñóþ)" . s:recorded
- endif
+function! s:to_object_start() abort
+ set operatorfunc=s:save_object
+ exec "normal g@" . s:recorded
+
+ let pos = s:instype == '[' ? s:object.start : s:object.end
+
+ echom printf("Jump To [%s] (%s) (%s)", string(pos), s:recorded, v:operator)
+ call setpos('.', pos)
+endfunction
+function! s:insert_before_recorded() abort
+ let l:instype = s:instype
" Something of a hack. If the motion starts with i or a, it is probably a
" text object.
"
- " I think there's probably a better way to handle this, butth
- if s:recorded =~ '^[ia]'
+ " I think there's probably a better way to handle this, but
+ if s:recorded =~ '^[ia]' || s:recorded =~ 'g[nN]' || s:recorded =~ '[_]'
" Without Rahm's patched Neovim, custom text objects will not work. This is
" because while the redo buffer is saved and restored when calling a user
" function, repeat_cmdline is not, and thus the g@ command clobbers the
@@ -181,25 +250,37 @@ function! s:insert_before_recorded() abort
set operatorfunc=s:save_object
exec "normal g@" . s:recorded
- if s:instype == 'a'
+ if l:instype == 'a'
call setpos(".", s:object.end)
if s:object.type == 'line'
normal! $
endif
- else
+ elseif l:instype == 'i'
call setpos(".", s:object.start)
if s:object.type == 'line'
normal! 0
endif
+ if s:object.start[2] > col(".")
+ " Trying to insert at the $. Needs to be append.
+ let l:instype = 'a'
+ endif
+ elseif l:instype == 'o'
+ call setpos(".", s:object.end)
+ elseif l:instype == 'O'
+ call setpos(".", s:object.start)
endif
else
exec "normal " . s:recorded
endif
- if s:instype == 'a'
+ if l:instype == 'a'
exec "normal! \<esc>a \<esc>v"
- else
+ elseif l:instype == 'i'
exec "normal! \<esc>i \<esc>v"
+ elseif l:instype == 'o'
+ exec "normal! \<esc>o \<esc>v"
+ elseif l:instype == 'O'
+ exec "normal! \<esc>O \<esc>v"
endif
endfunction
@@ -209,12 +290,17 @@ function! s:recordop(...) abort
normal! q
" Save the recorded amount
let s:recorded=getreg(s:reg_to_clobber)
+ " A limitation of normal! is that it can't start with a space, so use a NOP
+ " instead.
+ if s:recorded =~ '^\s'
+ let s:recorded = "\<plug>(ñóþ)" . s:recorded
+ endif
" Restore the register
call setreg(s:reg_to_clobber, s:savereg[0], s:savereg[1])
" Restore the position
call setpos('.', s:savepos)
" Called <Plug>(insert-about-obj). This is the part that can be repeated.
- call feedkeys("c\<Plug>(insert-about-obj)")
+ call feedkeys(s:operate_keys)
endfunction