Виправлення DOUble CApitals під час введення


23

У мене трохи повільний рожевий. Оскільки інші мої пальці стають все швидшими та швидшими при наборі тексту, мій рожевий просто не може йти в ногу. Це часто приводить мене до введення речень, перше слово яких починається з двох великих літер. Ось короткий приклад.

THere's nothing in there. DEfinitely not a body.

Зазвичай те, що я роблю, - це враження M-b M-c(якщо припустити, що це негайно помітити), але я трохи втомлююся від цього.

Як я можу зробити Emacs це автоматично виправити для мене?

Тобто, я хотів би, щоб Emacs виявив, коли я набираю слово, яке починається з двох великих літер, а потім хоча б одну малу літеру, і виправляти це автоматично.

Відповіді:


19

Ось функція, яка перетворить DOuble CApitals в Одиничні столиці. Спочатку я запропонував би його додати post-self-insert-hook, але нижче є варіант для прославленого другорядного режиму, щоб ви додавали його до цього гака лише тоді, коли цього дуже хочете:

(defun dcaps-to-scaps ()
  "Convert word in DOuble CApitals to Single Capitals."
  (interactive)
  (and (= ?w (char-syntax (char-before)))
       (save-excursion
         (and (if (called-interactively-p)
                  (skip-syntax-backward "w")
                (= -3 (skip-syntax-backward "w")))
              (let (case-fold-search)
                (looking-at "\\b[[:upper:]]\\{2\\}[[:lower:]]"))
              (capitalize-word 1)))))

(add-hook 'post-self-insert-hook #'dcaps-to-scaps nil 'local)

І другорядне визначення режиму:

(define-minor-mode dubcaps-mode
  "Toggle `dubcaps-mode'.  Converts words in DOuble CApitals to
Single Capitals as you type."
  :init-value nil
  :lighter (" DC")
  (if dubcaps-mode
      (add-hook 'post-self-insert-hook #'dcaps-to-scaps nil 'local)
    (remove-hook 'post-self-insert-hook #'dcaps-to-scaps 'local)))

Для чого це варто, використовуючи цю версію:

  • просто: просто вмикайте / вимикайте його вручну або в режимі гачка;
  • не потребує змін у ключових прив’язках, тому ви не втрачаєте жодної іншої функціональності.

Навіть коли ви додаєте його post-self-insert-hook, накладні витрати майже не існують, принаймні згідно з простим бенчмаркінг. На моїй машині ось що я отримую з 10 000 повторень, кожен із смішно простої форми та dcaps-to-scapsфункції:

(benchmark-run-compiled 10000 (+ 1 1))          ; => .001 to .003 -ish
(benchmark-run-compiled 10000 (dcaps-to-scaps)) ; => .003 to .006 -ish

Так, так, це повільніше, ніж додавання 1 + 1, але в абсолютному виразі ви ніколи не помітите.


Ви можете використовувати looking-at-p, яка взагалі не встановлює дані відповідності (це нормально, оскільки вам тут не потрібно або використовувати їх).
YoungFrog

Ще кілька зауважень, здебільшого неважливих (але я віддаю перевагу вашій відповіді, тому я хочу внести свій внесок; p): використання forward-wordне буде добре працювати subword-mode, використовуючи (char-syntax (char-before))буде (я думаю) ігнорувати будь-який набір класів синтаксису з властивостями (альтернативне рішення (syntax-after (1- (point)):) , і (останнє, але не менш важливо), в регулярному вираженні не знайдеться наголошених літер (наприклад, "ÉMincer", французькою мовою)
YoungFrog

@YoungFrog: оновлено, щоб вирішити цю forward-wordпроблему, і змінив регулярний параметр, щоб мати справу з великими столицями.
День

Чи є причина віддавати перевагу andнад when, зокрема, в першу чергу?
Clément

@ Clément: andкоротке замикання, тому логіка працює як whenтут. Я не впевнений, чи є найкращі практики використання одного проти іншого, але, схоже, це було б гарним питанням на цьому сайті (я б хотів подати заявку).
День

8

Моя перевага - просто створити нову функцію, яка робить те, що звичайне робило self-insert-commandб і більше .

Ось кілька причин:

  • Чіткіший контроль, у яких основних режимах має бути ця можливість автоматичного виправлення. Для цього випадку використання, це може бути тільки текстові режими подобається org-mode, text-modeі т.д.
  • Для типу корекції запитаний в питанні, користувач, як правило , удар SPCабо RETабо .клавішу після слова. Тож використання чогось подібного post-self-insert-hookможе бути зайвим, і ми робимо цю додаткову обробку кожного разу, коли натискаємо будь-який ключ.

Отже, запропоноване нижче рішення пов'язує цю функцію лише SPCклавішею org-mode-map(ігноруючи кутовий випадок, коли це слово може бути останнім словом у рядку). Якщо потрібно, користувач може прив’язати подібні функції обгортки до кількох клавіш.

(defun space-plus-more ()
  (interactive)
  (save-excursion
    (backward-word 1)
    (let ((case-fold-search))
      (when (looking-at-p "[A-Z]\\{2\\}.*?[a-z]+.*?\\b")
        (capitalize-word 1))))
  (self-insert-command 1))

(define-key org-mode-map (kbd "<SPC>") #'space-plus-more)

Це цікава вправа Elisp :)

Я особисто не хотів би це пов'язувати, RETоскільки тоді я втратив би прив'язки за замовчуванням org-modeі, ймовірно, інші основні режими теж. Але цікаво було дізнатися eltі про this-command-keys-vector.

(defun my/fix-double-caps ()
  (interactive)
  (save-excursion
    (backward-word 1)
    (let ((case-fold-search))
      (when (looking-at-p "[A-Z]\\{2\\}.*?[a-z]+.*?\\b")
        (capitalize-word 1))))
  (if (eq 13 (elt (this-command-keys-vector) 0)) ; detect RET
      (newline)
    (self-insert-command 1)))

(let ((maps-list (list org-mode-map
                       text-mode-map))
      (keys-list (list "<SPC>" "<RET>" ".")))
  (dolist (map maps-list)
    (dolist (key keys-list)
      (define-key map (kbd key) #'my/fix-double-caps))))

О так, обмеження його текстовими режимами, безумовно, є хорошою ідеєю. :)
Малабарба

@Malabarba Ви не хочете, щоб ця поведінка в рядках для режимів, похідних від прог-режиму?
YoungFrog

@YoungFrog впевнений, але тоді доведеться перевірити, що він насправді всередині рядка, інакше він просто заважатиме.
Малабарба

0

Можливо, ця відповідь не забезпечує рішення, якого ви очікуєте (інтерактивна корекція слів під час введення), я хотів би поділитися своїми способами боротьби з такими проблемами.

Перш за все, мені не подобаються речі, які мовчки змінюють мій текст (з великої літери тощо), що, якщо ви хочете ввести слово IBuffer, я вважаю, що такий "коректор" - це неправильний шлях), тому я раджу дві речі:

Спочатку спробуйте включити функцію "Клейкі ключі". Спочатку це може здатися дивним, але я його постійно використовую. Ця функція доступна на рівні ОС / робочого столу, це не матеріали Emacs. Коли ця річ увімкнена, спочатку натискаєте, ⇧ Shiftа потім натискаєте іншу клавішу, яку ви хочете використовувати з великої літери. Таким чином, ваша проблема навіть не може виникнути, в цьому послідовному підході використовується велика літера з великої літери! Це також зменшує роботу, яку потрібно робити вашим рукам, тримаючи ⇧ Shiftключ. Я думаю, що зараз простіше набрати текст.

По-друге, тепер ти все ще можеш ⇧ Shiftнормально використовувати ключ (утримуючи його), коли вважаєш за потрібне, але я хотів би запропонувати вам пакет Emacs під назвою Fix Word . Навіть якщо вам не подобаються «Клейкі ключі», ви можете легко виправити слова у їхніх правильних формах, і ви можете виправити кілька слів підряд без марних рухів курсору. Спробуйте, я його використовую постійно. (Виправити речі все ще важко, якщо ви ввели кілька слів, а слово, яке потрібно з великої літери, знаходиться десь посередині.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.