Emacs: Toggle Letter Case 🚀

By Xah Lee. Date: .

Solution: Toggle Letter Case

Here's a command that combines letter-case commands into one.

(see Emacs: Usability Problems of Letter-Case Changing Commands )

(defun xah-toggle-letter-case ()
  "Toggle the letter case of current word or selection.
Always cycle in this order: Init Caps, ALL CAPS, all lower.

URL `http://xahlee.info/emacs/emacs/emacs_toggle_letter_case.html'
Version: 2020-06-26 2023-11-14"
  (interactive)
  (let ( (deactivate-mark nil) xp1 xp2)
    (if (region-active-p)
        (setq xp1 (region-beginning) xp2 (region-end))
      (save-excursion
        (skip-chars-backward "[:alpha:]")
        (setq xp1 (point))
        (skip-chars-forward "[:alpha:]")
        (setq xp2 (point))))
    (when (not (eq last-command this-command))
      (put this-command 'state 0))
    (cond
     ((equal 0 (get this-command 'state))
      (upcase-initials-region xp1 xp2)
      (put this-command 'state 1))
     ((equal 1 (get this-command 'state))
      (upcase-region xp1 xp2)
      (put this-command 'state 2))
     ((equal 2 (get this-command 'state))
      (downcase-region xp1 xp2)
      (put this-command 'state 0)))))

Give it a easy key, such as Ctrl+9. [see Emacs Keys: Define Key]

Toggle Previous Letter Case

Another issue, not related to emacs, but related to efficiency of Shift key, is that the conventional way of typing capital letter using the Shift key is inefficient. You have to hold it, type a letter, then release it. (For detail about the Shift key problem, see Ban Shift Key.)

A better way to type capital letters, is to have a designated key, so that, when pressed, the previous letter is capitalized. (alternatively, press this key first, then next letter key pressed is capitalized. This is like a Compose key. [see Alt Graph Key, Compose Key, Dead Key] )

This is better because:

Here's the command.

(defun xah-toggle-previous-letter-case ()
  "Toggle the letter case of the letter to the left of cursor.

URL `http://xahlee.info/emacs/emacs/emacs_toggle_letter_case.html'
Version: 2015-12-22 2023-11-14"
  (interactive)
  (let ((case-fold-search nil))
    (left-char 1)
    (cond
     ((looking-at "[[:lower:]]") (upcase-region (point) (1+ (point))))
     ((looking-at "[[:upper:]]") (downcase-region (point) (1+ (point)))))
    (right-char)))

For this to work, you need to assign a easy key for this. For example, if you have a ergodox keyboard [see Best Keyboards for Emacs], set it to a thumb key.

If you have a normal PC keyboard, you could set the right Shift to something such as F20, then bind F20 to the command.

For how to remap keys in OS, see: Keyboard Tutorial: Layout, Keybinding, Key Macro ⌨.