Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to toggle letter cases in a region in emacs

Tags:

emacs

elisp

How can I toggle the case of letters (switch uppercase letters to lowercase and lowercase letters to uppercase) of a region's text in Emacs?

There are listed commands for conversion but nothing for toggling.

Example:

PLease toggLE MY LETTER case

should become:

plEASE TOGGle my letter CASE

like image 850
Basel Shishani Avatar asked Aug 15 '13 16:08

Basel Shishani


2 Answers

You can do it with a regexp substitution:

M-x replace-regexp RET
\([[:upper:]]+\)?\([[:lower:]]+\)? RET
\,(concat (downcase (or \1 "")) (upcase (or \2 ""))) RET

It's up to you to bind a key to this.

like image 93
angus Avatar answered Sep 22 '22 18:09

angus


I wrote it for you; it did not have thorough testing, but it appears to do what you seek.

The logic behind it is to loop over every single character in the text. If the character is equal to the character in downcase, append it to the return string in upcase. If not, append it in downcase. At the end, delete region and insert the return string.

It works immediate on a page of text, though I'd be wary to use it on huge texts (should be fine still).

(defun toggle-case ()
  (interactive)
  (when (region-active-p)
    (let ((i 0)
      (return-string "")
      (input (buffer-substring-no-properties (region-beginning) (region-end))))
      (while (< i (- (region-end) (region-beginning)))
    (let ((current-char (substring input i (+ i 1))))
      (if (string= (substring input i (+ i 1)) (downcase (substring input i (+ i 1))))
          (setq return-string
            (concat return-string (upcase (substring input i (+ i 1)))))
        (setq return-string
          (concat return-string (downcase (substring input i (+ i 1)))))))
    (setq i (+ i 1)))
      (delete-region (region-beginning) (region-end))
      (insert return-string))))
like image 31
PascalVKooten Avatar answered Sep 23 '22 18:09

PascalVKooten