¿Cómo usar Flyspell para corregir eficientemente la palabra anterior?

18

Desde el momento en que comencé a usar Flyspell, siempre fue doloroso de usar. Raramente reviso todo el búfer en busca de palabras mal escritas, generalmente escribo y una vez que veo la palabra subrayada, quiero corregirla al instante y continuar escribiendo. Esto es simplemente porque temo olvidar olvidar corregir la palabra más tarde y porque cuando empiezo a realizar una comprobación exhaustiva del búfer, iSpell da demasiados falsos positivos. Entonces, casi siempre corrijo las palabras lo antes posible mientras escribo.

Aquí hay funciones integradas que conozco y razones por las que no son eficientes (para mí):

  • flyspell-correct-word- Esto está obligado a hacer clic con el mouse. Olvídalo, no voy a usar el mouse.

  • flyspell-correct-word-before-point- Lo usé por algún tiempo. Tiene dos desventajas:

    1. De manera predeterminada, muestra el menú GUI que es difícil de operar sin mouse y es realmente engorroso cuando tiene una lista de correcciones con más de 10 elementos.

    2. No funciona por palabra mucho antes del punto. Escribo rápido y cuando veo una palabra mal escrita, normalmente tengo una o dos palabras entre la palabra mal escrita y el punto. Necesito mover el punto, corregir la palabra, regresar. Oh.

  • flyspell-auto-correct-word - Vea el punto 2 ↑ y además no funciona bien cuando tiene una larga lista de finalizaciones (debido al ciclismo).

P: ¿Cómo puedo usar Flyspell de manera eficiente, con el teclado, pudiendo elegir de la lista de finalizaciones sin ciclar y con la capacidad de corregir palabras aún más o menos distantes?

Las respuestas aceptables incluyen paquetes que ayudan a navegar a palabras mal escritas anteriores, corregirlas y regresar o algo así, así como pequeños fragmentos, posiblemente de su propio archivo de configuración, ya que creo que otras personas descubrieron sus formas de interactuar eficientemente con Flyspell.

Mark Karpov
fuente

Respuestas:

14

El incorporado flyspell-auto-correct-previous-wordfunciona como un encanto para mí. Lo he vinculado F12y no he mirado atrás. Constantemente tiene palabras correctas para mí, no importa cuántas palabras haya devuelto la palabra incorrecta.

De la documentación de la función:

flyspell-auto-correct-previous-word is an interactive compiled Lisp
function in `flyspell.el'.

(flyspell-auto-correct-previous-word POSITION)

For more information check the manuals.

Auto correct the first misspelled word that occurs before point.
But don't look beyond what's visible on the screen.

Además, si la primera vez que la autocorrección no le dio la palabra correcta, siga presionando su tecla enlazada ( F12en mi caso) para recorrer todas las opciones.

[Mi configuración de revisión ortográfica]

Kaushal Modi
fuente
1
Veo que aún necesitas recorrer todas las correcciones posibles. Pruébelo, ttwopor ejemplo, aunque en mi menú veo 26 correcciones propuestas.
Mark Karpov
3
ttwocorregido automáticamente twoen el primer intento. Pero sé a qué te refieres. Según la experiencia práctica, en aproximadamente el 90% de los casos, el primer intento recibe la palabra correcta, probablemente el 9% restante requiere 2-3 intentos y ese último 1% es cuando el flyspell simplemente no lo resuelve y necesito ir a través de más de 5 intentos (o lo soluciono manualmente).
Kaushal Modi
Ya veo, su método tiene sus propios beneficios (simplicidad). Tal vez lo cambie después de todo.
Mark Karpov
2
Muy agradable: esto es lo que esperaba encontrar, y lo perdí porque estaba vinculando la clave predeterminada a otra cosa. De forma C-;predeterminada, esto se puede personalizar, y puede personalizarlo flyspell-auto-correct-bindingpara vincularlo a otra tecla en el mapa de flyspell. (O simplemente atarlo de la manera normal, por supuesto.)
glucas
6

Estoy bastante seguro de que otras personas encontrarán diferentes soluciones que serán útiles para futuros lectores. Sin embargo, así es como manejo actualmente esto.

Creo que flyspell-correct-word-before-pointes un buen lugar para comenzar, porque al menos se puede invocar presionando la tecla y muestra un menú de posibles correcciones. Para arreglar el menú, escribí el paquete Ace Popup Menu que usa Avy como backend. Esto reemplaza el menú emergente GUI que flyspell-correct-word-before-pointusa (se llama a la función x-popup-menu) con un menú emergente textual que presenta elementos de menú etiquetados: una o dos pulsaciones de teclas y ya está.

Para resolver el segundo problema (incapacidad para corregir las palabras "a distancia") he escrito este asistente:

(defun flyspell-correct-previous (&optional words)
  "Correct word before point, reach distant words.

WORDS words at maximum are traversed backward until misspelled
word is found.  If it's not found, give up.  If argument WORDS is
not specified, traverse 12 words by default.

Return T if misspelled word is found and NIL otherwise.  Never
move point."
  (interactive "P")
  (let* ((Δ (- (point-max) (point)))
         (counter (string-to-number (or words "12")))
         (result
          (catch 'result
            (while (>= counter 0)
              (when (cl-some #'flyspell-overlay-p
                             (overlays-at (point)))
                (flyspell-correct-word-before-point)
                (throw 'result t))
              (backward-word 1)
              (setq counter (1- counter))
              nil))))
    (goto-char (- (point-max) Δ))
    result))

Esto parece funcionar.

Mark Karpov
fuente
5

Con helm-flyspell puedes elegir de la lista de correcciones de manera eficiente. Utilizo el siguiente código para saltar a los errores y corregirlos con él, guarda la posición del punto en el mark-ringpara que pueda volver a la posición donde comenzó o corrigió las palabras anteriormente:

(defun flyspell-goto-previous-error (arg)
  "Go to arg previous spelling error."
  (interactive "p")
  (while (not (= 0 arg))
    (let ((pos (point))
          (min (point-min)))
      (if (and (eq (current-buffer) flyspell-old-buffer-error)
               (eq pos flyspell-old-pos-error))
          (progn
            (if (= flyspell-old-pos-error min)
                ;; goto beginning of buffer
                (progn
                  (message "Restarting from end of buffer")
                  (goto-char (point-max)))
              (backward-word 1))
            (setq pos (point))))
      ;; seek the next error
      (while (and (> pos min)
                  (let ((ovs (overlays-at pos))
                        (r '()))
                    (while (and (not r) (consp ovs))
                      (if (flyspell-overlay-p (car ovs))
                          (setq r t)
                        (setq ovs (cdr ovs))))
                    (not r)))
        (backward-word 1)
        (setq pos (point)))
      ;; save the current location for next invocation
      (setq arg (1- arg))
      (setq flyspell-old-pos-error pos)
      (setq flyspell-old-buffer-error (current-buffer))
      (goto-char pos)
      (if (= pos min)
          (progn
            (message "No more miss-spelled word!")
            (setq arg 0))))))


(defun check-previous-spelling-error ()
  "Jump to previous spelling error and correct it"
  (interactive)
  (push-mark-no-activate)
  (flyspell-goto-previous-error 1)
  (call-interactively 'helm-flyspell-correct))

(defun check-next-spelling-error ()
  "Jump to next spelling error and correct it"
  (interactive)
  (push-mark-no-activate)
  (flyspell-goto-next-error)
  (call-interactively 'helm-flyspell-correct))

(defun push-mark-no-activate ()
  "Pushes `point' to `mark-ring' and does not activate the region
 Equivalent to \\[set-mark-command] when \\[transient-mark-mode] is disabled"
  (interactive)
  (push-mark (point) t nil)
  (message "Pushed mark to ring"))
clemera
fuente