Como usar o Flyspell para corrigir com eficiência a palavra anterior?

18

Desde o momento em que comecei a usar o Flyspell, sempre foi doloroso de usar. Eu raramente verifico o buffer inteiro em busca de palavras com erros ortográficos, geralmente digito e, quando vejo a palavra sublinhada, quero corrigi-lo instantaneamente e continuar digitando. Isso ocorre simplesmente porque tenho medo de esquecer de corrigir a palavra posteriormente e porque, quando inicio uma verificação abrangente do buffer, o iSpell fornece muitos falsos positivos. Portanto, quase sempre eu corrijo as palavras o mais rápido possível enquanto digito.

Aqui estão as funções internas que eu conheço e as razões pelas quais elas não são eficientes (para mim):

  • flyspell-correct-word- Isso está vinculado ao clique do mouse. Esqueça, eu não vou usar o mouse.

  • flyspell-correct-word-before-point- Eu usei por algum tempo. Tem duas desvantagens:

    1. Por padrão, mostra o menu da GUI difícil de operar sem o mouse e é realmente complicado quando você tem uma lista de correções com mais de 10 itens.

    2. Não funciona para palavras muito antes do ponto. Digito rápido e, quando vejo palavras com erros ortográficos, normalmente tenho uma ou duas palavras entre a palavra e o ponto com erros ortográficos. Preciso mudar de ponto, palavra correta, voltar. Oh.

  • flyspell-auto-correct-word - Veja o ponto 2 ↑, além de não funcionar bem quando você tem uma lista longa de conclusões (por causa do ciclismo).

P: Como posso usar o Flyspell de forma eficiente, com teclado, podendo escolher na lista de conclusões sem pedalar e com a capacidade de corrigir palavras ainda mais ou menos distantes?

As respostas aceitáveis ​​incluem pacotes que ajudam a navegar para a palavra incorreta anterior, corrigi-la e voltar ou algo assim, além de pequenos trechos, possivelmente do seu próprio arquivo de configuração, pois acredito que outras pessoas descobriram suas maneiras de interagir com o Flyspell de maneira eficiente.

Mark Karpov
fonte

Respostas:

14

O embutido flyspell-auto-correct-previous-wordfunciona como um encanto para mim. Eu o vinculei F12e não olhei para trás. Ele consistentemente tem palavras corretas para mim, não importa quantas palavras a palavra incorreta tenha.

Na documentação da função:

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.

Além disso, se a primeira correção automática não fornecer a palavra certa, continue pressionando a tecla vinculada ( F12no meu caso) para percorrer todas as opções.

[Minha configuração de verificação ortográfica]

Kaushal Modi
fonte
1
Vejo que você ainda precisa percorrer todas as correções possíveis. Experimente, ttwopor exemplo, embora meu menu veja 26 correções propostas!
Mark Karpov
3
ttwocorrigido automaticamente twona primeira tentativa. Mas eu sei o que você quer dizer. Por experiência prática, em cerca de 90% dos casos, a primeira tentativa obtém a palavra certa, provavelmente os 9% restantes requerem 2-3 tentativas e esse último 1% é quando o spell flyspell simplesmente não descobre e eu preciso ir através de mais de 5 tentativas (ou eu o corrigo manualmente).
Kaushal Modi
Entendo, seu método tem seus próprios benefícios (simplicidade). Talvez eu mude para isso depois de tudo.
Mark Karpov
2
Muito bom - era o que eu esperava encontrar e perdi porque estava vinculando a chave padrão a outra coisa. Isso está vinculado C-;por padrão e você pode personalizar flyspell-auto-correct-bindingpara vinculá-lo a outra chave no mapa do flyspell. (Ou simplesmente vinculá-lo da maneira normal, é claro.)
glucas
6

Tenho certeza de que outras pessoas encontrarão soluções diferentes que serão úteis para futuros leitores. No entanto, aqui está como eu manejo isso atualmente.

Eu acho que flyspell-correct-word-before-pointé um bom lugar para começar, porque pelo menos pode ser chamado com a tecla pressionada e exibe o menu de possíveis correções. Para consertar o menu que escrevi, o pacote Ace Popup Menu usa Avy como back-end. Isso substitui o menu pop-up da GUI que flyspell-correct-word-before-pointusa (a função é chamada x-popup-menu) pelo menu pop-up textual que apresenta itens de menu rotulados: um ou dois pressionamentos de tecla e pronto.

Para resolver o segundo problema (incapacidade de corrigir as palavras "à distância"), escrevi este ajudante:

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

Isso parece funcionar.

Mark Karpov
fonte
5

Com helm-flyspell, você pode escolher da lista de correções com eficiência. Eu uso o código a seguir para pular para os erros e corrigi-los com ele, ele salva a posição do ponto para mark-ringque você possa voltar à posição em que iniciou ou corrigiu as palavras 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
fonte