0

I'm writing an IntelliJ-style "smart backspace" function which does the following:

  • If the whole of the line up to the point is whitespace
    • Join the line to the previous line, killing that whitespace
    • Indent the line
  • Otherwise, just delete a char as normal

I've got the smart backspace working, but the as normal part is proving difficult.

(defun smart-backspace ()
  (interactive)
  (if (beginning-of-line-text-p)
      (progn (join-line)
             (indent-according-to-mode))
      (delete-backward-char 1)))

The problem is most language modes provide their own version of delete-backward-char, so overriding backspace like this doesn't do handy (or crucial!) stuff such as paredit/smartparens' sp-backward-delete-char, which keeps the sexp tree intact when you backspace over a closing delimiter.

What I'm asking is: is there a way to call the "default" binding for a key or mode from inside a function such as mine?

0

The answer is "yes". As usual, I suspect that's not the answer you were looking for, tho.

How to do that depends on how you bind your backspace key to your smart-backspace command. One way to do it is to bind it as part of a minor mode:

(defvar smart-backspace-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "DEL") 'smart-backspace)
    map))

(define-minor-mode smart-backspace-mode
  "Be smart."
  :global t)

in which case you can call the "default" binding with something like:

(let ((smart-backspace-mode nil))
  (command-execute (key-binding (this-single-command-keys))))
1
  • Thank you, this worked! It needed a couple of tweaks - first it's command-execute not execute-command, and I needed to add a fallback to delete-backwards-char when key-binding doesn't return anything - but otherwise this works perfectly! – William Osborne Jan 31 '20 at 15:33
1

Stefan's solution is almost perfect, but it required the following modifications:

  • Use command-execute instead of execute-command
  • Provide a fallback to backspace when no key binding is defined, via or:
(defun smart-backspace ()
  (interactive)
  (if (beginning-of-line-text-p)
      (progn
        (join-line)
        (indent-according-to-mode))
      (let ((smart-backspace-mode nil))
        (command-execute (or
                          (key-binding (this-single-command-keys))
                          'evil-delete-backward-char-and-join)))))

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.