" Remap i{",',`} and a{",',`} to search for the next string. This is more like how objects like i( and i{ work. " " The behavior inside the quotes should remain unchanged. onoremap in" call find_next_quote('i', '"') onoremap an" call find_next_quote('a', '"') onoremap in' call find_next_quote('i', "'") onoremap an' call find_next_quote('a', "'") onoremap in` call find_next_quote('i', '`') onoremap an` call find_next_quote('a', '`') vnoremap in" call find_next_quote('i', '"') vnoremap an" call find_next_quote('a', '"') vnoremap in' call find_next_quote('i', "'") vnoremap an' call find_next_quote('a', "'") vnoremap in` call find_next_quote('i', '`') vnoremap an` call find_next_quote('a', '`') function! s:find_next_quote(ai, q) abort call search(a:q, '') call search(a:q, '') let l = getline(line('.')) let c = col('.') - 1 if l[c] == a:q && l[c - 1] == a:q exec "normal! i " elseif l[c] == a:q && l[c + 1] == a:q exec "normal! a l" endif exec "normal! v" . a:ai . a:q endfunction " Fix silly yank behavior. nnoremap Y y$ " . in visual mode will replay the last command on each line in the visual mode. vnoremap . call visual_repeat() function! s:visual_repeat() exec "normal! \" let [_, _, c, _] = getpos('.') let [b, l1_, _, p] = getpos("'<") let [_, l2_, _, _] = getpos("'>") let l1 = min([l1_, l2_]) let l2 = max([l1_, l2_]) let l = l1 while l <= l2 let newpos = [b, l, c, p] call setpos('.', newpos) if newpos == getpos('.') " Only execute if the new position was valid. normal! . endif let l += 1 endwhile endfunction