diff --git a/init.el b/init.el index 20c57ed..c7d0751 100644 --- a/init.el +++ b/init.el @@ -315,6 +315,36 @@ Apply OLDFUN with to ARGS." . conf-mode)) (add-to-list 'auto-mode-alist `(,(rx (or bos "/") "README" eos) . markdown-mode)) +(defun my/delete-backward-char-or-tab (n &optional killflag) + "Delete N characters, or that many characters worth of tabs, before point. +If there is only whitespace between point and the beginning of the current line, +delete N characters worth of tabs, rounding up. For example, if N is 2 and +`tab-width' is 4, delete one tab. If `indent-tabs-mode' is nil, instead delete +`tab-width' spaces. In this case, deletion stops at the beginning of the +current line. + +If point is anywhere else on the line, delete N characters. + +If KILLFLAG is non-nil, save the deleted text to the kill ring." + (interactive "p\nP") + (unless (natnump n) + (signal 'wrong-type-argument (list 'natnump n))) + (cl-flet ((only-indentation-p () + (let ((start (point))) + (save-excursion + (beginning-of-line) + (skip-syntax-forward " " start) + ;; `back-to-indentation' does this, so I do too + (backward-prefix-chars) + (>= (point) start)))) + (count-chars-for-delete-tab () + (min (* (ceiling n tab-width) (if indent-tabs-mode 1 tab-width)) + (- (point) (pos-bol))))) + (if (not (only-indentation-p)) + (delete-char (- n) killflag) + (delete-char (- (count-chars-for-delete-tab)) killflag)))) +(keymap-set prog-mode-map "DEL" #'my/delete-backward-char-or-tab) + ;; Show the fill column ;; (global-display-fill-column-indicator-mode -1) ;; (setopt display-fill-column-indicator-warning t)