L'ho scritto per voi; non ha avuto test approfonditi, ma sembra fare ciò che cerchi.
La logica dietro è quella di ricoprire ogni singolo carattere nel testo. Se il personaggio è uguale al personaggio in downcase, aggiungilo alla stringa di ritorno in upcase. In caso contrario, aggiungilo in uno scomparto. Alla fine, elimina la regione e inserisci la stringa di restituzione.
Funziona immediatamente su una pagina di testo, anche se sarei prudente usarlo su testi enormi (dovrebbe andare bene ancora).
(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))))
Sembra che molte delle risposte tentate non riescano a visualizzare un caso d'uso per ciò che si sta effettivamente chiedendo, quindi risolvono invece un problema diverso. Puoi spiegare dove sarebbe utile, se non altro per il nostro divertimento? – tripleee
Questo potrebbe non essere troppo comune, ma ho cambiato caso per errore (terminali e non-terminali in un file di grammatica) e ho pensato che potesse esserci un comando per invertirli. Potrebbe accadere magari con markup e valori e casi simili. Sto pensando ora se ci fosse un tale comando, potrebbe essere usato sia per il downcase che per il downcase. –