2013-08-15 12 views
6

Come è possibile alternare il caso di lettere (passare lettere maiuscole a minuscole e minuscole a maiuscole) del testo di una regione in Emacs?Come attivare casi di lettere in un'area in emacs

Ci sono i comandi elencati per la conversione ma nulla per la commutazione.

Esempio:

PLease Toggle mio caso LETTERA

dovrebbe diventare:

Si prega di attivare o disattivare la mia lettera CASO

+1

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

+1

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. –

risposta

2

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)))) 
+0

Sembra funzionare correttamente. –

1

Se intendi caso lettera, allora questa funzione funziona bene: http://ergoemacs.org/emacs/modernization_upcase-word.html

(defun toggle-letter-case() 
    "Toggle the letter case of current word or text selection. 
    Toggles between: “all lower”, “Init Caps”, “ALL CAPS”." 
    (interactive) 
    (let (p1 p2 (deactivate-mark nil) (case-fold-search nil)) 
    (if (region-active-p) 
     (setq p1 (region-beginning) p2 (region-end)) 
     (let ((bds (bounds-of-thing-at-point 'word))) 
     (setq p1 (car bds) p2 (cdr bds)))) 
    (when (not (eq last-command this-command)) 
     (save-excursion 
     (goto-char p1) 
     (cond 
     ((looking-at "[[:lower:]][[:lower:]]") (put this-command 'state "all lower")) 
     ((looking-at "[[:upper:]][[:upper:]]") (put this-command 'state "all caps")) 
     ((looking-at "[[:upper:]][[:lower:]]") (put this-command 'state "init caps")) 
     ((looking-at "[[:lower:]]") (put this-command 'state "all lower")) 
     ((looking-at "[[:upper:]]") (put this-command 'state "all caps")) 
     (t (put this-command 'state "all lower"))))) 
    (cond 
    ((string= "all lower" (get this-command 'state)) 
     (upcase-initials-region p1 p2) (put this-command 'state "init caps")) 
    ((string= "init caps" (get this-command 'state)) 
     (upcase-region p1 p2) (put this-command 'state "all caps")) 
    ((string= "all caps" (get this-command 'state)) 
     (downcase-region p1 p2) (put this-command 'state "all lower"))) 
    )) 
+0

Superiore a inferiore e inferiore a superiore per ogni lettera nella regione. –

1

I comandi upcase-region, downcase-region e capitalize-region non sono commutatori e sono forse i comandi di "conversione" a cui si fa riferimento. Ecco un comando che cicla tra loro.

(defvar cycle-region-capitalization-last 'upper) 
(defun cycle-region-capitalization (&optional msgp) 
    "Cycle the region text among uppercase, lowercase and capitalized (title case)." 
    (interactive "p") 
    (setq cycle-region-capitalization-last 
     (case cycle-region-capitalization-last 
      (upper (call-interactively #'downcase-region) 'lower) 
      (lower (call-interactively #'capitalize-region) 'title) 
      (title (call-interactively #'upcase-region)  'upper))) 
    (when msgp (message "Region is now %scase" cycle-region-capitalization-last))) 
0

Mi piaceva la tecnica di altra risposta del confronto this-command e last-command, così ho incorporato nella mia vecchia funzione. Ecco il risultato:

(defun upcase-word-toggle() 
    (interactive) 
    (let ((bounds (bounds-of-thing-at-point 'symbol)) 
     beg end 
     regionp) 
    (if (eq this-command last-command) 
     (setq regionp (get this-command 'regionp)) 
     (put this-command 'regionp nil)) 
    (cond 
     ((or (region-active-p) regionp) 
     (setq beg (region-beginning) 
      end (region-end)) 
     (put this-command 'regionp t)) 
     (bounds 
     (setq beg (car bounds) 
      end (cdr bounds))) 
     (t 
     (setq beg (point) 
      end (1+ beg)))) 
    (save-excursion 
     (goto-char (1- beg)) 
     (and (re-search-forward "[A-Za-z]" end t) 
      (funcall (if (char-upcasep (char-after)) 
         'downcase-region 
         'upcase-region) 
        beg end))))) 

(defun char-upcasep (letter) 
    (eq letter (upcase letter))) 

(global-set-key (kbd "C->") 'upcase-word-toggle) 
+0

Impossibile verificare il codice: la definizione della funzione del simbolo non è valida: char-upcasep –

7

È possibile farlo con una sostituzione regexp:

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

E 'a voi per associare una chiave di questo.

+0

C'è un extra paren alla fine nella sostituzione ma questo prende il premio –

+1

Sì, ho notato (e corretto) solo poco prima del tuo commento. – angus

Problemi correlati