aboutsummaryrefslogtreecommitdiff
path: root/plugin/insert.vim
diff options
context:
space:
mode:
authorJosh Rahm <rahm@google.com>2022-09-16 06:30:48 +0000
committerJosh Rahm <rahm@google.com>2022-09-16 06:30:48 +0000
commitfaf9b29a25da337431e1ddaaf95d06c8783262cf (patch)
tree501ed6036558c4826f07177bbc03b3314f211678 /plugin/insert.vim
parent534f8ccabd777d419fc88aed28c7dc10a6637392 (diff)
downloadfieldmarshal.vim-wip.tar.gz
fieldmarshal.vim-wip.tar.bz2
fieldmarshal.vim-wip.zip
wipwip
Diffstat (limited to 'plugin/insert.vim')
-rw-r--r--plugin/insert.vim119
1 files changed, 101 insertions, 18 deletions
diff --git a/plugin/insert.vim b/plugin/insert.vim
index dea819a..722c0b5 100644
--- a/plugin/insert.vim
+++ b/plugin/insert.vim
@@ -57,6 +57,14 @@ 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"
@@ -113,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>
@@ -140,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.
@@ -151,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>
@@ -164,13 +225,18 @@ 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.
"
@@ -184,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
@@ -212,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