diff options
author | Teddy Wing | 2019-12-10 00:12:29 +0100 |
---|---|---|
committer | Teddy Wing | 2019-12-13 20:50:49 +0100 |
commit | c34de5c3663e2b07e021a6b22abc3f0382c72d4a (patch) | |
tree | 0b8c24588edae4c4c2f89425983f597de96f830a | |
parent | 648f8e788c6a49c32e6b1cf9c04c8b6665709d8d (diff) | |
download | dotvim-c34de5c3663e2b07e021a6b22abc3f0382c72d4a.tar.bz2 |
case-star: Get `c#` mapping working in the middle of a word
After trying a few different approaches, finally settled on a mapping
implementation for `c#` that seems to work both at the start and in the
middle of a word.
Previously, as the TODO on line 1 indicates, if the cursor was on the
start of the word, we'd move to the previous match using `c#`. However,
if the cursor was in the middle of the word, `c#` would move to the
start of the word, when it should instead move to the previous match.
First tried to solve the movement problem using `search()`. Managed to
find a formula that did what I wanted, but search highlighting isn't
applied when searching within functions. This function (in particular
the 'z' flag) allows us to move to the previous match even when starting
in the middle of the word:
call search('\C' . expand('<cword>'), 'bz')<CR>
I then tried an <expr> mapping against a function that would call:
call search('\<', 'bc')
first to move to the start of the word (even when already on the start
of the word), then return the `?...` command to run the search for the
previous match. This, however, didn't work because the above mentioned
`search()` call wasn't part of the <expr> mapping, and it's likely the
search was undone, similar to what I encountered next.
I then tried to run an `execute 'normal! ?...'` command to run the
search, preceded still by the aforementioned `search()` call to move to
the beginning of the word. This did not work because it turns out that
searches in a function are undone when that function returns:
:h function-search-undo
This behaviour is also the likely reason why my `search()` + <expr>
function didn't work.
Finally, tried an <expr> mapping containing both the `search()` call to
move to the beginning of the word and the `?...` command to search for
the previous match (all returned in the <expr> string). Once I got the
syntax right, this seems to do exactly what I want.
Left the in-between code states for reference. I'll be cleaning those up
later.
-rw-r--r-- | bundle/case_star/plugin/case_star.vim | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/bundle/case_star/plugin/case_star.vim b/bundle/case_star/plugin/case_star.vim index 62deac7..cc9d530 100644 --- a/bundle/case_star/plugin/case_star.vim +++ b/bundle/case_star/plugin/case_star.vim @@ -1,5 +1,31 @@ " TODO: if not on start of word, ensure we move to previous match -nnoremap <silent> c# ?\C<C-r>=expand('<cword>')<CR><CR> +" nnoremap <silent> c# :call search('\C' . expand('<cword>'), 'bz')<CR> +" nnoremap <expr> c# <SID>SearchBackward() +" nnoremap c# :call <SID>SearchBackward()<CR> +nnoremap <expr> c# <SID>SearchBackward() +" nnoremap <silent> c* :call search('\C' . expand('<cword>'), 'z')<CR> nnoremap <silent> c* /\C<C-r>=expand('<cword>')<CR><CR> +" call search('\C' . expand('<cword>'), 'bz') +" call search('\C' . expand('<cword>'), 'z') + " TODO: Currently behaves like g* g#. Need * # versions. + + +" function! s:SearchBackward() +" call search('\<', 'bc') +" " return "?\\C\<C-r>=expand('<cword>')\<CR>\<CR>" +" " execute 'normal! ?\C' . expand('<cword>') . '<CR>' +" execute 'normal! ?\C' . expand('<cword>') . "\<CR>" +" endfunction + +function! s:SearchBackward() + let expr = '' + + let expr .= ":call search('\<', 'bc')\<CR>" + " let expr .= "?\\C\<C-r>=expand('<cword>')\<CR>\<CR>" + let cword = expand('<cword>') + let expr .= '?\C' . cword ."\<CR>" + + return expr +endfunction |