Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vim: Remap key to move to the next non-blank line (and vice versa)

Tags:

vim

viml

I'm looking for a way to remap a key to move the cursor down to the next line, skipping any lines that only contain \n and a way to do the same only going up to the next line.

Essentially, I want to do the opposite of the { and } motions.

like image 766
HaySwim Avatar asked Nov 08 '16 23:11

HaySwim


People also ask

How do I skip a line in Vim?

If we are in the vim editor, then simply do this, “Press the ENTER key, write the Line number, and press Shift+ g”: Again the output is the same.

What is the f command in Vim?

If you press "F", Vim will move the cursor backwards instead of forward. Given the previous sentence, if pressed "Fq", and the cursor was at the end of the line, it would move to the "q" in "quick".

How do I add a new line in Vim?

Starting in normal mode, you can press O to insert a blank line before the current line, or o to insert one after. O and o ("open") also switch to insert mode so you can start typing.


2 Answers

Here are alternatives to DJ's mappings that play well with hlsearch:

  • jump to next non-empty line

    nnoremap <key> :<C-u>call search('^.\+')<CR>
    
  • jump to previous non-empty line

    nnoremap <otherkey> :<C-u>call search('^.\+', 'b')<CR>
    
  • extend visual selection to next non-empty line

    xnoremap <key> :<C-u>k`\|call search('^.\+')\|normal! <C-r>=visualmode()<CR>``o<CR>
    
  • extend visual selection to previous non-empty line

    xnoremap <otherkey> :<C-u>k`\|call search('^.\+', 'b')\|normal! <C-r>=visualmode()<CR>``o<CR>
    
  • operate to next non-empty line

    omap <key> :<C-u>normal! v<key><CR>
    
  • operate to previous non-empty line

    omap <otherkey> :<C-u>normal! v<otherkey><CR>
    

Explanation…

With hlsearch enabled, /anything will highlight every match. Since we are not actively searching for non-empty lines but merely moving to them, the resulting highlighting is pointlessly noisy.

By using :help search(), we bypass hlsearchand thus make the mappings a lot less noisy.

<C-u> is used to remove any accidental range before calling our function.

The visual mode mappings work like this:

  1. we define the "previous mark" with :help :k,
  2. we perform the search,
  3. we run the following normal mode commands with :help :normal,
  4. we retrieve the previous visual mode with :help i_ctrl-r, :help "=, and :help visualmode(),
  5. we extend the visual selection to the location of the "previous mark" with :help '',
  6. and finally we move the cursor to the other end of the visual selection with :help v_o.

The operator pending mappings simply reuse the visual mode mappings.

like image 51
romainl Avatar answered Sep 28 '22 06:09

romainl


I'm not sure what you want to map these two, so I'll just use { and }. How about this?

nnoremap } /^\S<cr>
nnoremap { ?^\S<cr>

The explanation is pretty straightforward.

/           " Search forward
 ^          " For the start of a line
  \S        " Followed by a non-whitespace character
    <cr>    " Enter

The ? mapping is the same except for searching backwards instead of forwards.

Of course for completeness, you'll want to add

nnoremap } /^\S<cr>
xnoremap } /^\S<cr>
onoremap } /^\S<cr>
nnoremap { ?^\S<cr>
xnoremap { ?^\S<cr>
onoremap { ?^\S<cr>

This will make it work as an argument to an operator (e.g. d{) and in visual mode.

like image 40
DJMcMayhem Avatar answered Sep 28 '22 06:09

DJMcMayhem