views:

314

answers:

4

ReSharper has a nice feature called "extend selection": by pressing CTRL+W (I think this is the default) repeatedly, you select more and more from your current caret location. First it's a word, then more and more words, a line, inner then outer block of lines (for example an if-block), then a function, etc...

Basically, by pressing the key combination repeatedly, you can end up selecting the entire file. I'm sure at least some of you will be familiar with it.

I have just started learning all the intricacies of vim and I don't have enough experience to see how something like this could be implemented in Vim (although I assume it's possible). So my question is meant for Vim gurus out there: can this be done and how?

Update: a bit of a background story. I've been talking to my ex-boss about all the benefits of Vim, and he thinks it's all great. His only question/problem was: does it have "extend selection"? My question so far has been no. So, if someone knows the answer, I'll finally win a discussion :P (and maybe create a new Vim convert:-))

+3  A: 

The answer is yes. Once in Visual mode you can use all the regular navigation methods as well as some extra ones.

Some of my favourites? First hit v while in normal mode to get to visual mode then hit:

  1. iw - to select the inner word. Great for selecting a word while excluding surrounding braces or quotes
  2. w - hit multiple times to keep selecting each subsequent word.
  3. b - select wordwise backwords
  4. ^ - select all from current position to beginning of text on line
  5. $ - select all from current position to end of line

I'm sure others here could add to this list as well. Oh and don't forget Visual Block mode C-v try it out in vim with the above commands it works in two dimensions :-)

Jeremy Wall
I am relatively familiar with the visual mode, but the key difference is that you have to move your fingers around and actually think what you want to select next (or, in other words, _where_ to extend your selection). The goal is to merge all those sequentially to a single key combination. [I hope I am clear enough, I'm not a native english speaker]
dr Hannibal Lecter
Well, that's doable in Vim, you'd just have to write a vim function that cycled through various selection levels, and map a keystroke to that function.
rampion
-1 for not reading the question properly.
Hassan Syed
+2  A: 

If you're talking about Vim (and you should be :-), you can start marking text with the v command, then you have all the standard cursor movement commands (and, as you know, there are a lot of them) which will extend the selection, as well as moving the cursor.

Then you just do whatever you want with the selected text.

See here for the gory details.

paxdiablo
The same comment as for Jeremy Wall :)
dr Hannibal Lecter
+2  A: 

One would need to write a function that would save the current selection, then try increasingly wide selections, until the new selection exceeds the saved one or selects all text. Some possible selections are:

  • viW - select word
  • vis - select sentence
  • vip - select paragraph
  • viB - select text within the innermost brackets
  • v2iB - select text within the next most innermost brackets
  • ggVG - select all text
Don Reba
This is exactly what I mean, only problem being I'm not familiar with the Vim scripting language. :(
dr Hannibal Lecter
+1  A: 

I had a quick go at this problem. It doesn't work as is. Feel Free to make edits and post on the vim wiki or as a plugin if you get it refined.

chances are you'd want to make a g:resharp_list for each language (eg. one for paranthesised languages, etc.)

All that is needed is a marker for the original cursor position :he markers and a timeout autocommand that resets the index.

"resharp emulator
"TODO this needs a marker
"also c-w is bad mapping as it has a lag with all the other-
"window mappings
"
let g:resharp_index = 0

let g:resharp_select =  ['iw', 'is', 'ip', 'ggVG']

func! ResharpSelect()
    if g:resharp_index >= len (g:resharp_select)
        let g:resharp_index = 0
    endif

    exe "norm \<esc>v" . g:resharp_select[g:resharp_index]
    let g:resharp_index = g:resharp_index + 1
endfun

nnoremap <c-w>  :call ResharpSelect()<cr>
vnoremap <c-w>  :call ResharpSelect()<cr>

"Something to reset on timeout. TODO this doesn't work
au CursorHold :let g:resharp_index = 0<cr>
michael
Just tried it, it's a good start! Hopefully I'll learn vim script one day and extend it.
dr Hannibal Lecter