(shtarkov)

Do not zap up to char

#emacs

2024-10-20

It struck me as odd that Emacs has zap-to-char and zap-up-to-char that advance point to a character and kill, but there is no command to just advance point. Hence iy-go-to-char.el and similar. I find myself using only to "up to" variant, so I put together this:

(defun cs-do-not-zap-up-to-char (arg char &optional interactive)
  "'zap-up-to-char', but push mark first (unless Transient Mark mode
is enabled and the mark is active) and do not kill. You can still kill
with 'C-w' afterwards."
  (interactive (list (prefix-numeric-value current-prefix-arg)
                     (read-char-from-minibuffer "Do not zap up to char: "
                                                nil 'read-char-history)
                     t))
  (let ((direction (if (>= arg 0) 1 -1))
        (case-fold-search (if (and interactive (char-uppercase-p char))
                              nil
                            case-fold-search)))
    (unless (region-active-p) (push-mark))
    (forward-char direction)
    (unwind-protect
        (search-forward (char-to-string char) nil nil arg)
      (backward-char direction))))

This is basically Isearch, but for one character only. You still have the option to kill afterwards with C-w, because the mark is saved where the search began (just like Isearch).