In vim I often use <S-x> to 'backspace' in normal mode (deleting the char behind the cursor). However if I position the cursor at the end of the line, the last character on the line is not removed (because of course in Vim the cursor cannot move past the last character on the line). I know I can just use x normally to do this, but I want to know if I can change the behaviour of <S-x> so it does the correct thing depending on the context.

  • 1
    Use set virtualedit=all (or maybe set ve=onemore)
    – Matt
    Oct 8 '19 at 12:26
  • Not sure if I'm misunderstanding your question, but, if your cursor is on the last character of the line, how can Vim know whether you want the normal "backspace" behaviour, or the special-case "delete last character" behaviour? It's easy to change the behaviour to always do the latter, but surely that just shifts the "character that cannot be deleted with <S-X>" problem to the previous character on the line?
    – Rich
    Oct 8 '19 at 12:39
  • @Rich Hi, sorry for any confusion, I wasn't exactly sure how else to describe what I meant. As far as edits for clarity go, what would you suggest?
    – myc3lium
    Oct 8 '19 at 12:45
  • @Rich ok, I'll change it to that, I think you're right that it would read more clearly. I was thinking more of how the cursor visually appears to be behind the characters.
    – myc3lium
    Oct 8 '19 at 13:02
  • @myc3lium That depends on how you have Vim/your terminal configured. I think (based on no evidence whatsoever!) that, in normal mode, most Vim configurations will display the cursor as a rectangle that entirely covers/surrounds the character it is on (rather than as a vertical bar that lies visually between characters).
    – Rich
    Oct 8 '19 at 13:15

As @Matt suggests, possibly the best solution for you is to:

:set virtualedit=onemore

This allows you to move the cursor one character further to the right so you can use Shift-X to delete the last character on the line.

If you don't like this setting, then you can change the behaviour of Shift-X to act like an unshifted x when it's at the end of a line with an expression mapping that checks the position of the cursor:

:nnoremap <expr> X len(getline('.')) == getcurpos()[2] ? 'x' : 'X'

...but I don't really understand how this is better than the default behaviour: now you can delete the last character on the line with Shift-X, but you can't delete the penultimate character any more.

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.