tpope / vim-rsi

rsi.vim: Readline style insertion
http://www.vim.org/scripts/script.php?script_id=4359
583 stars 35 forks source link

Have CLI <M-b> and <M-f> move over "words" instead of "WORDS" #20

Closed bruno- closed 10 years ago

bruno- commented 10 years ago

This is something that repeatedly pops up for me. While current implementation of <M-b> and <M-f> in command line is useful, I'd prefer to have it work just as in bash - that is, respecting "word".

I miss this the most when trying to manually edit the middle "piece" of the filename, example:

:e /path/need_to_edit_this_part/path/file.txt

If the feature is acceptable, I'd even be willing to try to implement this, but I'm worried no one would want to merge and later maintain the vimscript I write :/

tpope commented 10 years ago

Well without trying to cook up a fully working solution, what would your strategy be? I would definitely prefer that behavior, but without a built-in way to achieve it, I worry about a buggy, unmaintainable mess.

bruno- commented 10 years ago

Hi, I was first experimenting with something like this:

function! Cleft()
  let iskw = ExpandIsKeyword() " this function is 'juicy'
  let init_pos = getcmdpos()
  let line = getcmdline()
  let pos = init_pos - 1
  while match(iskw, line[pos-1]) > -1
    let pos -= 1
  endwhile
  return repeat("\<Left>", init_pos - pos)
endfunction

cmap <expr> <M-B> Cleft()

Basically, just iterating over the characters and comparing them with iskeyword. That "kinda" works - but not exactly. The function would need a lot of improvements and it would quickly degrade into mess.

Before declaring it impossible I decided to try regexes with word boundaries. I came up with this:

\(\<\S\|\>\S\|\s\zs\S\|^\S\)

From what I tested, the above regex seems to match 'next word' characters nicely. I tested by:

I even changed the 'iskeyword' setting with set iskeyword-=_, performed the search again, and new results were aligned with w.

So, if the above regex can correctly "detect" next word, I think coming up with an non-crappy implementation shouldn't be too hard. And just "reverse" the regex for the 'word backward'.

Now that I feel I'm onto something - I'll finalize this, even if it stays in my vimrc.