Arreglando Dobles Dobles mientras escribo


23

Tengo un poco de meñique lento. A medida que mis otros dedos se vuelven cada vez más rápidos al escribir, mi meñique simplemente no puede seguir el ritmo. Esto frecuentemente me lleva a escribir oraciones cuya primera palabra comienza con dos letras mayúsculas. Aquí hay un pequeño ejemplo.

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

Por lo general, lo que hago es golpear M-b M-c(suponiendo que lo vea de inmediato), pero me estoy cansando un poco de eso.

¿Cómo puedo hacer que Emacs arregle esto automáticamente?

Es decir, me gustaría que Emacs detecte cuando escribo una palabra que comienza con dos letras mayúsculas seguidas de al menos una letra minúscula, y la corrige automáticamente.

Respuestas:


19

Aquí hay una función que convertirá DOuble CApitals a Single Capitals. Originalmente sugerí agregarlo post-self-insert-hook, pero a continuación hay una opción para un modo menor glorificado para que solo agregue a ese gancho cuando realmente lo desee:

(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)

Y la definición del modo menor:

(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)))

Para lo que vale, usando esta versión:

  • es simple: simplemente actívelo / desactívelo manualmente o en un modo de enlace;
  • no requiere cambios en las combinaciones de teclas, por lo que no está perdiendo ninguna otra funcionalidad.

Incluso cuando lo agrega post-self-insert-hook, la sobrecarga es casi inexistente, al menos de acuerdo con algunos puntos de referencia simples. En mi máquina, esto es lo que obtengo con 10,000 repeticiones, cada una de una forma ridículamente simple y la dcaps-to-scapsfunción:

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

Entonces, sí, es más lento que agregar 1 + 1, pero en términos absolutos nunca lo notarás.


Puede usar looking-at-p, lo que no establece los datos de coincidencia en absoluto (eso está bien ya que no lo necesita ni lo usa aquí).
YoungFrog

Unas cuantas más observaciones, en su mayoría poco importante (pero prefiero su respuesta, así que quiero contribuir; p): el uso de forward-wordno funcionarán bien con subword-mode, el uso (char-syntax (char-before))será (supongo) ignorar cualquier conjunto de clases de sintaxis con propiedades (solución alternativa: (syntax-after (1- (point))) , y (por último pero no menos importante) la expresión regular no encontrará letras acentuadas (por ejemplo, "ÉMincer", en francés)
YoungFrog

@YoungFrog: actualizado para tratar el forward-wordproblema, y ​​cambió la expresión regular para tratar con mayúsculas acentuadas.
Dan

¿Hay una razón para preferir andmás when, en particular, en primera instancia?
Clément

@ Clément: andestá en cortocircuito, por lo que la lógica funciona como whenaquí. No estoy seguro de si hay mejores prácticas sobre el uso de uno versus el otro, pero parece que sería una buena pregunta en este sitio (de todos modos, votaría de manera positiva).
Dan

8

Mi preferencia es simplemente crear una nueva función que haga lo que self-insert-commandharía habitualmente y más .

Aquí hay algunas razones:

  • Control más preciso sobre qué modos principales deberían tener esta capacidad de autocorrección. Para este caso de uso, podría ser modos de sólo texto gustaría org-mode, text-mode, etc.
  • Para el tipo de corrección solicitada en la pregunta, el usuario sería típicamente golpeado SPCo RETo .llave después de la palabra. Por lo tanto, usar algo como post-self-insert-hookpodría ser una exageración, y haríamos ese procesamiento adicional cada vez que presionamos cualquier tecla.

Entonces, la solución propuesta a continuación vincula esta función con solo la SPCclave org-mode-map(ignorando el caso de la esquina donde la palabra podría ser la última palabra en una línea). Si es necesario, el usuario puede vincular funciones de contenedor similares a más claves.

(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)

Este es un ejercicio interesante de elisp :)

Personalmente, no me gustaría vincular esto RETya que entonces perdería los enlaces predeterminados org-modey probablemente también en otros modos principales. Pero fue interesante aprender sobre elty 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))))

Ah, sí, restringirlo a modos derivados de texto es definitivamente una buena idea. :)
Malabarba

@Malabarba, ¿no quieres este comportamiento en cadenas para modos derivados del modo prog?
YoungFrog

@YoungFrog seguro, pero luego tendría que comprobar que realmente está dentro de una cadena, de lo contrario, solo se interpondría.
Malabarba

0

Tal vez esta respuesta no proporcione la solución que espera (corrección interactiva de palabras mientras escribe), me gustaría compartir mis formas de combatir tales problemas.

En primer lugar, no me gustan las cosas que cambian silenciosamente mi texto (mayúsculas, etc., y si quiere escribir la palabra IBuffer, creo que ese "corrector" es una forma incorrecta), por lo que le aconsejo dos cosas:

Primero, intente habilitar la función "Sticky Keys". Puede parecer extraño al principio, pero lo uso todo el tiempo. Esta característica está disponible en el entorno del sistema operativo / escritorio, no es material de Emacs. Cuando esto está habilitado, primero presiona ⇧ Shifty luego presiona otra tecla que desea capitalizar. De esta manera, su problema ni siquiera puede surgir, ¡solo una letra está en mayúscula en este enfoque secuencial! También reduce el trabajo que deben realizar sus manos sosteniendo la ⇧ Shifttecla. Creo que es más fácil escribir ahora.

En segundo lugar, ahora todavía puede usar la ⇧ Shifttecla normalmente (manteniéndola) cuando lo considere necesario, pero me gustaría proponerle un paquete de Emacs llamado Fix Word . Incluso si no le gustan las "Teclas adhesivas", puede corregir las palabras en sus formas apropiadas fácilmente, y puede corregir varias palabras seguidas sin movimientos inútiles del cursor. Pruébalo, lo uso todo el tiempo. (Todavía es difícil corregir las cosas si ingresó varias palabras y la palabra que necesita capitalizar está en algún lugar en el medio).

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.