Как переключать регистры букв в регионе в emacs
Как я могу переключить регистр букв (переключить прописные буквы в нижний регистр и строчные буквы в верхний регистр) текста региона в Emacs?
есть перечисленные команды для преобразования, но ничего для переключения.
пример:
пожалуйста, переключите мой случай письма
должны стать:
пожалуйста, переключите мой случай письма
5 ответов
логика заключается в том, чтобы перебирать каждый символ в тексте. Если символ равен символу в downcase, добавьте его в возвращаемую строку в upcase. Если нет, добавьте его в downcase. В конце удалите region и вставьте возвращаемую строку.
он работает сразу на странице текста, хотя я был бы осторожен, чтобы использовать его на огромных текстах (должно быть хорошо еще.)
(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))))
вы можете сделать это с помощью подстановки regexp:
M-x replace-regexp RET
\([[:upper:]]+\)?\([[:lower:]]+\)? RET
\,(concat (downcase (or "")) (upcase (or ""))) RET
это до вас, чтобы привязать ключ к этому.
Если вы имеете в виду буквенный регистр, то эта функция работает хорошо: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")) )
) )
команды upcase-region
, downcase-region
иcapitalize-region
не являются переключателями и, возможно, являются командами "преобразование", о которых вы упомянули. Вот команда, которая вращается среди них.
(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)))
мне понравилась техника сравнения другого ответа this-command
и last-command
,
поэтому я включил его в свою старую функцию. Вот результат:
(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)