3

I often find I want to quickly select all the characters in an aligned column, something like this:

this.p           = obj.['propery'];
this.prop        = obj.['proper'];
this.proper      = obj.['prop'];
this.property    = obj.['p'];

Say I want to select the .s with visual block selection (CtrlV). If it's not immediately obvious how many rows there are (perhaps there are more), I typically use { or } once in visual block select mode to jump the appropriate distance. However, they go one line too far; if the following line is blank the cursor move to the first column, selecting far more than I want.

Is there an equivalent to { or } which jumps to the last line in the paragraph, while maintaining the current column?


My question is similar to How do I move by paragraphs, but end up *in* the paragraph? but the answer given there (mapping j or k after a { or }) won't work for me; the column will be lost.

  • 1
    I often have the same problem. I have found that setting 'relativenumber' can be a great help in getting it right the first time around. – filbranden Aug 1 at 1:12
  • @filbranden Do you find it gets in the way of using absolute line numbers to say, jump to lines mentioned in error messages? – gandalf3 Aug 1 at 1:13
  • 1
    Not really, since in that case I'll use a command (e.g. 346G) or the quickfix window. You can also use both 'relativenumber' and 'number' together, in which case it will show the absolute line for the current line, and relative around it. But yeah, I'd be curious to see if anyone has a better suggestion on how to handle this! – filbranden Aug 1 at 1:22
4
vnoremap <silent>x :<C-U>call cursor(line("'}")-1,col("'>"))<CR>`<1v``

Explanation:

  • vnoremap <silent>x --- remap something useless in visual mode (x is the same as d)
  • :<C-U> --- drop visual line range (also switches to normal mode)
  • call cursor(...)<CR> --- set cursor position
    • line("'}")-1 --- the last line of the current paragraph (except if it's the last paragraph in the whole file, but it's not that important, I think; use line("'}") - empty(getline(line("'}"))) if it is)
    • col("'>") --- the end column of the visual selection
  • `<1v --- restore visual mode
  • `` --- jump back to the latest jump, i.e. extend selection till that cursor() position
  • You can handle the last paragraph if you replace line("'}")-1 with line("'}") - (line("'}") == line("$") ? 0 : 1). – Jürgen Krämer Aug 1 at 6:12
  • @JürgenKrämer In fact, I wanted first to do line("'}") - (line("'}") != line("$")) (which is basically the same thing). But the problem is that the last line can be empty too. – Matt Aug 1 at 6:38
  • @JürgenKrämer So a "bullet-proof" version should be: line("'}") - empty(getline(line("'}"))) – Matt Aug 1 at 6:42
  • Sorry, but maybe I don't understand you first comment. If the last line is empty, the last line of the last paragraph is not the last line of the buffer and subtracting 1 will work. – Jürgen Krämer Aug 1 at 6:43
  • @JürgenKrämer If it's empty then line("'}") == line("$"), therefore your expression yields the number of the last (empty) line. – Matt Aug 1 at 6:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.