Emacs command for quick substitution of previously-typed character. This is supposed to help input umlauts quicker by switching letters to their analogues and so on.

(defun krv/last-char-check (&optional pos)
  "Find previous non-whitespace character in current string.

Return in form of (position . character) cons nor nil"
    (let ((cur-pos (or (and pos (goto-char pos))
      (loop for prev-char = (preceding-char) then (preceding-char)
            for back-pos = 0 then (1- back-pos)
            when (bolp) return nil
            ; known whitespaces listed
            unless (member prev-char (list ?\ ?\xA0 ?\t)) return (cons back-pos prev-char)
            else do (backward-char)))))

(defun krv/unwrap-list-to-alist (list-form)
  "Helper function for setting character substitutions"
  (loop with first = (car list-form)
        for (s1 s2 . nil) on list-form
        if s2 collect (cons s1 s2)
        else collect (cons s1 first)))

(defvar cycle-symbols-alist nil
  "list of characters used for symbol cycling")

(defgroup cycle-symbols nil
  "Group for cycling symbols")

(defcustom cycle-symbols-lists-default
  (list (list ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?0) (list ?+ ?-) (list ?> ?< ?=))
  "Default lists for symbol cycling"
  :type 'sexp
  :set (lambda (s val)
         (set-default s val)
         (setq cycle-symbols-alist (mapcan #'unwrap-list-to-map val))))

(defun krv/cycle-symbols-command ()
  "Cycle previous non-whitespace if there is a known substitution"
  (let* ((check-pair (krv/last-char-check))
         (pos (car check-pair))
         (char (cdr check-pair))
         (rchar (assoc char cycle-symbols-alist)))
    (when (and check-pair rchar)
      (forward-char pos)
      (delete-backward-char 1)
      (insert-char (cdr rchar))
      (backward-char pos))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.