From 56b2c9fb541d7d538cc955ae93409710bd325e0f Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Sun, 24 Apr 2022 15:00:11 -0500 Subject: Correct backward-kill-word behavior --- lisp/+emacs.el | 28 ++++++++++++++++++++++++++++ lisp/+paredit.el | 26 ++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 lisp/+paredit.el (limited to 'lisp') diff --git a/lisp/+emacs.el b/lisp/+emacs.el index b7e31e2..a0627cf 100644 --- a/lisp/+emacs.el +++ b/lisp/+emacs.el @@ -244,6 +244,34 @@ backward. It defaults to `backward-kill-word'." #'kill-region (or backward-kill-word-fn #'backward-kill-word)))) +(defun +backward-kill-word-wrapper (fn &optional arg) + "Kill backward using FN until the beginning of a word, smartly. +If point is on at the beginning of a line, kill the previous new +line. If the only thing before point on the current line is +whitespace, kill that whitespace. + +With argument ARG: if ARG is a number, just call FN +ARG times. Otherwise, just call FN." + ;; I want this to be a wrapper so that I can call other word-killing functions + ;; with it. It's *NOT* advice because those functions probably use + ;; `backward-kill-word' under the hood (looking at you, paredit), so advice + ;; will make things weird. + (if (null arg) + (cond + ((looking-back "^" 1) + (let ((delete-active-region nil)) + (delete-backward-char 1))) + ((looking-back "^[ ]*") + (delete-horizontal-space :backward-only)) + (t (call-interactively fn))) + (funcall fn (if (listp arg) 1 arg)))) + +(defun +backward-kill-word (&optional arg) + "Kill word backward using `backward-kill-word'. +ARG is passed to `backward-kill-word'." + (interactive "P") + (+backward-kill-word-wrapper #'backward-kill-word arg)) + ;; ... and advice ;; Indent the region after a yank. diff --git a/lisp/+paredit.el b/lisp/+paredit.el new file mode 100644 index 0000000..0c65328 --- /dev/null +++ b/lisp/+paredit.el @@ -0,0 +1,26 @@ +;;; +paredit.el --- bespoke paredit stuffs -*- lexical-binding: t; -*- + +;;; Commentary: + +;;; Code: + +(require '+emacs) ; `+backward-kill-word-wrapper' + +(defun +paredit--backward-kill-word (&optional n) + "Perform `paredit-backward-kill-word' N times." + (interactive "p") + (dotimes (_ (or n 1)) + (paredit-backward-kill-word))) + +(defun +paredit-backward-kill-word (&optional arg) + "Kill a word backward using `paredit-backward-kill-word'. +Wrapped in `+backward-kill-word-wrapper', which see. + +Prefix ARG means to just call `paredit-backward-kill-word'." + ;; Of course, `paredit-backward-kill-word' doesn't TAKE an argument ... :/// + ;; So I had to write the wrapper above. + (interactive) + (+backward-kill-word-wrapper #'+paredit--backward-kill-word arg)) + +(provide '+paredit) +;;; +paredit.el ends here -- cgit 1.4.1-21-gabe81