1

I'm using the following commands to move a line of text up and down in the file.

:move +1<CR>
:move -2<CR>

However, these commands don't work on the edges of the file. If I try to move the first line up or the last line down I get an error that says E14: Invalid Address. Is there a way to avoid this error? I'd prefer if attempting to move past the edges of the file became a no-op instead.

I'm wondering if there is another way to specify the target address instead of +1 and -2, which would tell Vim that I don't want to go outside the bounds of the file.

0
3

Use

:silent! move +1<CR>
:silent! move -2<CR>

:silent suppresses normal messages, while :silent! also suppresses error messages.

See :h :silent.

Disadvantage: This suppresses all kinds of error messages.

If you want a mapping for this, you could check the line before executing:

:nnoremap <silent> <C-Up> :if line('.')!=1 \| exe "move -2" \| endif<cr>
:nnoremap <silent> <C-Down> :if line('.')!=line('$') \| exe "move +1" \| endif<cr>

Here <silent> just prevents echoing the command. See :h :map-silent.


Update because of comment:

In visual mode try the following:

:vnoremap <expr> <C-Up> line("'<")!=1 ? ":'<,'>move '<-2<cr>" : ''
:vnoremap <expr> <C-Down> line("'>")!=line('$') ? ":'<,'>move '>+1<cr>" : ''

A map-expression (:h :map-expression) returns the keys to execute. Here it is combined with a conditional.

For UP check if the first selected line is not line 1. If yes -> move, else do nothing.

For DOWN check if the last selected line is the last line of the file. If yes -> move, else do nothing.

3
  • Thanks! I do want to put those commands in a mapping, in which case those if statements are exactly what I want. Is there a way to make them also work for a visual mode mapping? If I start the visualmode mapping with :if if errors with "E481: No range allowed".
    – hugomg
    Jun 7 '20 at 13:50
  • That's because the range is in front of the if. Also it is not that easy. If you mark 3 lines a :move +1 will result in an error (E134: Cannot move a range of lines into itself). In that case you would need :move +3. If you also want to cover that, I guess you need a function that handles those cases. Will answer later.
    – Ralf
    Jun 7 '20 at 14:10
  • I am currently using :move `>+1 and :move `>-2 as my mapping for visual mode. They do the right thing if a range of lines is selected but they also break near the edges of the file.
    – hugomg
    Jun 7 '20 at 15:58

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.