Background
I'm attempting to remap the arrow keys to move by word while staying within the current line. I.e. I'm looking for a behavior similar to w
and b
, but that acts like h
and l
in the sense that it doesn't move to a line above or below. For moving right, I have the current solution:
nnoremap <expr> <Right> getline('.')[col('.')-1:] =~# '\s\S' ? 'w' : '$'
It gets most of the way there, but since \s\S
is only looking to see if there are more whitespaces, the behavior breaks down at the end of a line. For instance, it misses instrs
in the following example line:`
'>'::xs -> parse_chars xs ((Next 1)::instrs)
Question
How do I get the behavior I'm looking for? Is there any way to regex match a "vim word" to get the desired behavior?
Edit
I'm aware that this is technically possible by a short script using norm
, like below:
function! CustomRight()
let last = line('.')
norm w
if line('.') != last
norm b$
endif
endfunction
But this isn't ideal, since norm
brings you into normal mode. So it wouldn't work in visual mode.
nnoremap <expr> <Right> getline('.')[col('.')-1:] =~# '\<' ? 'w' : '$'
so check if there is a word-boundary atom anywhere on the right\<
must be a vim-regex dialect for something other than what vim considers to be words (in w and b)? It doesn't seem to work correctly near the end of some lines. For instance, If I try it on the solution you posted it will skip from the first apostrophe in... w' : '$'
to the end of the line.:h /\<
.