Reputation: 691
I Googled this but was unable to find any clear explanation.
A lot of people praise Vim for sort of being its own internally consistent language but I am failing to see the consistency.
Since hjkl
are left down up right:
dh
is like "delete left" and it deletes the character to the left of the cursor, makes sense so far.
dl
is like "delete right" but it deletes... the current character?
dj
is like "delete down" and I'd assume this just deletes the line below, but it actually deletes the current line as well!
'dk' is like "delete up" and similarly I'd expect it just clears the line above, but instead it clears the current line AND the one above it.
Can anyone explain what the logic is here? I am okay with the idea of delete + left and right handling characters on the same line, and delete + up and down handling lines, but why is the behavior so inconsistent? What's the logic I am missing here?
Or is it really more of a "there is no consistent logic here really, just memorize it" thing?
Upvotes: 5
Views: 1268
Reputation: 6016
This is consistent. Think about it as a textcursor, not as a block cursor so for example:
abc
^
You are here with the cursor. For the delete command it is actually like this:
a|bc
Vim always works with ranges. If you do not specify a range, only a target, the first point of the range is always the cursor position: So dh
is delete from here to h
, with h
being the following position:
|abc
So you tell vim to delete from a|bc
to |abc
hence everything between the cursor positions is deleted.
dl
goes to the other direction from a|bc
to ab|c
-> a|b|c
so only the b
will be deleted.
In j
and k
movements, it is line-based, but basically the same.
So if you press dk
on the following situation:
abc
abc
^
You tell vim to delete every line until you reach the following position:
abc
^
abc
This is consistent with all other commands in vim, and is a part of what makes vim so powerful.
Think about the search /
command for example:
abc
a|bc
abc
dfe
dfe
dfe
If you press d/dfe<CR>
it will not just delete dfe
, it will delete until dfe
. So you will have following two cursor positions:
abc
a|bc
abc
|dfe
dfe
dfe
Everything in between will be deleted, you will end up with:
abc
a
dfe
dfe
dfe
This is the case for every other movement.
Upvotes: 7
Reputation: 196456
You shouldn't "assume" or "expect" anything. The behavior of all those commands is explained precisely in Vim's online documentation.
hjkl
are motions and d
is an operator that works on the text covered by a motion.
dj
works on the text covered by the j
motion. Since j
is a linewise motion that moves the cursor to the line below, dj
is "cut this line and the one below".
dk
works on the text covered by the k
motion. Since k
is a linewise motion that moves the cursor to the line above, dk
is "cut this line and the one above".
For horizontal motions, you must understand that the terminal's cursor is actually between two characters:
sample text: lorem
the "current character": lorem
^
the "cursor": lo|rem
the text covered by "h": l|orem
←
the text covered by "l": lor|em
→
dh
works on the text covered by the h
motion so it cuts the character before the "cursor" which happens to also be the character before the "current character".
dl
works on the text covered by the l
motion so it cuts the character after the "cursor" which happens to be the "current character".
Upvotes: 1