13

Is there a command for deleting line (or n lines) above current one? Above = current not included.

I.e., is there an alternative to dk which doesn't delete current line? Similar to how o/O and p/P work, but with deletion.

Currently, I'm doing kdd, which moves cursor one line up and deletes it. I could do nnoremap <Leader>d kdd and nnoremap <Leader>D jdd-, but having an alternative which doesn't move the cursor seems like a better option. Is there such?

7
  • If your problem is that your mappings move the cursor why don't you do nnoremap <Leader>d kddj and nnoremap <Leader>D jddk?
    – statox
    Aug 4, 2015 at 12:00
  • Using either kddj or jddk, column position is not preserved. I'm not saying it's a big problem, but it's annoying. For the record, kddj moves cursor 1 line below original position. And jdd- seems like a better alternative to jddk because at least I'm returning to first non white space character. If line below the one I want deleted is empty, I'm left at the beginning of the line. Aug 4, 2015 at 12:04
  • How about using makdd`a for your map? Sets a mark and returns to it afterwards... you might want to change it to a lesser used character though. Aug 4, 2015 at 12:17
  • @PhilippFrank Or I can use `` to get the cursor back and not occupy a register (not that I use any :) ). Aug 5, 2015 at 8:46
  • No that doesn't work, k is not a jump, so you cannot go back using ``. Aug 5, 2015 at 9:15

6 Answers 6

39
:-d

cuts the line above the current line.


:-5d

cuts the 5th line above the current line (but moves the cursor).


:-5,-d

cuts the 5 lines above the current line.


:+,+5d

cuts the 5 lines below the current line.

3
  • 5
    That still moves the cursor, though. Aug 5, 2015 at 6:27
  • 1
    You can't avoid moving the cursor. The best you can do is move the cursor and move it back.
    – romainl
    Aug 5, 2015 at 7:51
  • Thank you! This kind of "vim way" is what I was looking for. I'm going to use this in combination with `` to get the cursor back where it was. Aug 5, 2015 at 8:44
7

If we use the small delete register "-, we can restore the cursor position after deleting above n lines.

For example, d0dgk"-P deletes above 1 line and restores the cursor back where it was.

  1. d0 deletes characters from the cursor to the first character of the line. Since 0 is an exclusive motion, the character under the cursor is not deleted. And the deleted characters are put into the small delete regsiter "-.

  2. dgk deletes above 1 line. This will leave the current line, because gk is not linewise and exclusive.

  3. "-P puts the text from the small delete register "-.

It is a sort of hack. But if you are looking for non-ex commands, consider using it.

2
  • Nice solution! Although I think you want "-P not "-p. The latter messes up the text a little bit.
    – DJMcMayhem
    Jun 21, 2016 at 20:07
  • @DJMcMayhem You're right. I corrected the answer. Thank you for pointing out it.
    – MS.Kim
    Jun 23, 2016 at 5:48
5

EDIT I didn't know the built-in features suggested by @Romainl in his answer: of course the -d and +d method should be prefered as it is way simpler than adding functions to your .vimrc

Maybe adding something like that to your .vimrc could be what you want:

function! DeleteOver()
   let save_cursor = getpos(".")
   normal k
   normal dd
   call setpos(".", save_cursor)
   normal k
endfunction

function! DeleteUnder()
   let save_cursor = getpos(".")
   normal j
   normal dd
   call setpos(".", save_cursor)
endfunction

These functions delete the line under or the line over the current one and go back to the position before the deletion.

For the function DeleteOver() we need to go up one line with normal k after the deletion because the deletion change the number of the original line which doesn't happend with DeleteUnder()

You can also add this to your .vimrc

nnoremap <Leader>d :call DeleteOver()<CR>
nnoremap <Leader>D :call DeleteUnder()<CR>

To create the mappings calling the functions.

1
  • An alternative to saving/restoring the cursor position is to unset/restore the nostartofline option.
    – Rich
    Mar 23, 2018 at 15:07
3

Perhaps you'll improve your workflow if don't fear to ... jump :)

Example:

This is where cursor initially is: _.

[Some other stuff you want to keep/skip ...]

I want to delete these lines.
I want to delete these lines.
I want to delete these lines.
I want to delete these lines.
I want to delete these lines.

Your actions (normal mode, cursor is on _): /I want Enter 5dd Ctrl-o. That's it.

Of course, romainl answer is the best if all you want to delete whole lines, and you can count their offset easily (using relative linenumbers for example). The above is a more generic way to "act": go there, using something that counts as a jump: this means you can always jump back, after you modify the text.

For example, if you use absolute line numbers, you can replace the /I want Enter with something like 78gg or 78G to jump directly at that line number.

0

Based on ms-kim solution I have developed a slightly different variation that saves col postion.

function! DeleteLineAbove()
    if line('.') == 1
        echom "You are at the first line!"
        return
    endif
    let l:colsave = col(".")
    exec  "normal! kdd"
    call cursor(line("."), l:colsave)
endfunction
nnoremap <Leader>k :call DeleteLineAbove()<CR>

OBS: I have also used this post as reference.

1
  • Do you mean @statox rather than @MS.Kim?
    – Rich
    Mar 23, 2018 at 15:11
-1

If you want to delete duplicate lines throughout the whole file, just do the following:

:g/any part of the string/d

Example:

In command mode

:g/I want to delete/d

If you just want a list of the string(s) initially:

:g/I want to delete/p
1
  • 3
    I'm not really sure how this answers the asked question? Feb 23, 2017 at 16:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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