From 367f5ff28cc83cbd34555d777b8ed9862694ea88 Mon Sep 17 00:00:00 2001 From: Kalle Lindqvist Date: Thu, 13 Sep 2018 22:13:33 +0200 Subject: [PATCH] spell-checking: add words to dictionary functionality When writing documents in latex or any markup language there is soon or later going to be unrecognized words that get falsely flagged as incorrect. These functions and key-bindings allows the user to add unrecognized words to the dictionary so they are recognized as correctly spelled words by ispell/flyspell. This seem's like a must have feature for any application that does any kind of spell checking. Added key bindings: SPC S a b for Add word to dict (buffer) SPC S a g for Add word to dict (global) SPC S a s for Add word to dict (session) Spell Checking Transient State: SPC S . B for Add word to dict (buffer) SPC S . G for Add word to dict (global) SPC S . S for Add word to dict (session) --- CHANGELOG.develop | 8 ++++ layers/+checkers/spell-checking/README.org | 18 ++++--- layers/+checkers/spell-checking/funcs.el | 53 +++++++++++++++++++++ layers/+checkers/spell-checking/packages.el | 20 +++++--- 4 files changed, 86 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.develop b/CHANGELOG.develop index 4beacd71a..6f4651cea 100644 --- a/CHANGELOG.develop +++ b/CHANGELOG.develop @@ -2220,6 +2220,14 @@ Other: - Added spell checking transient state (thanks to Francesc Elies Henar) - Update to flyspell-correct v0.5 (thanks to Boris Buliga) - Update spell checking ts to flyspell-correct v0.5 (thanks to Bruno Tavares) +- Added key bindings (thanks to Kalle Lindqvist): + - ~SPC S a b~ Add word to dict (buffer) + - ~SPC S a g~ Add word to dict (global) + - ~SPC S a s~ Add word to dict (session) + Transient State: + - ~SPC S . B~ Add word to dict (buffer) + - ~SPC S . G~ Add word to dict (global) + - ~SPC S . S~ Add word to dict (session) **** Syntax-checking - Key bindings: - ~SPC e e~ is now for triggering a syntax check, the old action diff --git a/layers/+checkers/spell-checking/README.org b/layers/+checkers/spell-checking/README.org index b7eae63eb..fc13dc99e 100644 --- a/layers/+checkers/spell-checking/README.org +++ b/layers/+checkers/spell-checking/README.org @@ -124,12 +124,15 @@ set the layer variable =enable-flyspell-auto-completion= to t: | Key binding | Description | |-----------------+----------------------------------------| -| ~SPC S b~ | flyspell whole buffer | -| ~SPC S c~ | flyspell correct | -| ~SPC u SPC S c~ | flyspell correct all errors one by one | -| ~SPC S d~ | change dictionary | -| ~SPC S n~ | flyspell goto next error | -| ~SPC t S~ | toggle flyspell | +| ~SPC S a b~ | Add word to dict (buffer) | +| ~SPC S a g~ | Add word to dict (global) | +| ~SPC S a s~ | Add word to dict (session) | +| ~SPC S b~ | Flyspell whole buffer | +| ~SPC S c~ | Flyspell correct | +| ~SPC u SPC S c~ | Flyspell correct all errors one by one | +| ~SPC S d~ | Change dictionary | +| ~SPC S n~ | Flyspell goto next error | +| ~SPC t S~ | Toggle flyspell | ** Spell Checking Transient-state @@ -142,6 +145,9 @@ set the layer variable =enable-flyspell-auto-completion= to t: | ~SPC S . t~ | Toggle spell check | | ~SPC S . q~ | Quit transient state | | ~SPC S . Q~ | Quit transient state and disable =flyspell-mode= | +| ~SPC S . B~ | Add word to dict (buffer) | +| ~SPC S . G~ | Add word to dict (global) | +| ~SPC S . S~ | Add word to dict (session) | * Known issues Vim-empty-lines layer seems incompatible with spell-checking inside org-mode. If diff --git a/layers/+checkers/spell-checking/funcs.el b/layers/+checkers/spell-checking/funcs.el index 112c94cd8..af9d6cb11 100644 --- a/layers/+checkers/spell-checking/funcs.el +++ b/layers/+checkers/spell-checking/funcs.el @@ -22,3 +22,56 @@ auto-dictionary is not used, use the adict version otherwise." (if (fboundp 'adict-change-dictionary) (adict-change-dictionary) (call-interactively 'ispell-change-dictionary))) + +(defun spacemacs/add-word-to-dict-buffer () + "Save word at point as correct in current buffer." + (interactive) + (spacemacs//add-word-to-dict 'buffer)) + +(defun spacemacs/add-word-to-dict-global () + "Save word at point as a correct word globally." + (interactive) + (spacemacs//add-word-to-dict 'save)) + +(defun spacemacs/add-word-to-dict-session () + "Save word at point as correct in current session." + (interactive) + (spacemacs//add-word-to-dict 'session)) + +(defun spacemacs//add-word-to-dict (scope) + "Save word at point as a correct word. +SCOPE can be: +`save' to save globally, +`session' to save in current session or +`buffer' for buffer local." + (let ((current-location (point)) + (word (flyspell-get-word))) + (when (consp word) + (if (spacemacs//word-in-dict-p (car word)) + (error "%s is already in dictionary" (car word)) + (progn + (flyspell-do-correct scope nil (car word) current-location + (cadr word) (caddr word) current-location) + (ispell-pdict-save t)))))) + +(defun spacemacs//word-in-dict-p (word) + "Check if WORD is defined in any of the active dictionaries." + ;; use the correct dictionary + (flyspell-accept-buffer-local-defs) + (let (poss ispell-filter) + ;; now check spelling of word. + (ispell-send-string "%\n") ;put in verbose mode + (ispell-send-string (concat "^" word "\n")) + ;; wait until ispell has processed word + (while (progn + (accept-process-output ispell-process) + (not (string= "" (car ispell-filter))))) + ;; Remove leading empty element + (setq ispell-filter (cdr ispell-filter)) + ;; ispell process should return something after word is sent. + ;; Tag word as valid (i.e., skip) otherwise + (or ispell-filter + (setq ispell-filter '(*))) + (if (consp ispell-filter) + (setq poss (ispell-parse-output (car ispell-filter)))) + (or (eq poss t) (stringp poss)))) diff --git a/layers/+checkers/spell-checking/packages.el b/layers/+checkers/spell-checking/packages.el index 3b4a0cace..6b3eb64ce 100644 --- a/layers/+checkers/spell-checking/packages.el +++ b/layers/+checkers/spell-checking/packages.el @@ -48,21 +48,23 @@ (spacemacs|define-transient-state spell-checking :title "Spell Checking Transient State" :doc " -Spell Commands^^ Other ---------------^^ ----- -[_b_] check whole buffer [_t_] toggle spell check -[_d_] change dictionary [_q_] exit -[_n_] next spell error [_Q_] exit and disable spell check -[_c_] correct word -" +Spell Commands^^ Add To Dictionary^^ Other +--------------^^-------- -----------------^^------------- -----^^--------------------------- +[_b_] check whole buffer [_B_] add word to dict (buffer) [_t_] toggle spell check +[_d_] change dictionary [_G_] add word to dict (global) [_q_] exit +[_n_] next spell error [_S_] add word to dict (session) [_Q_] exit and disable spell check +[_c_] correct word" :on-enter (flyspell-mode) :bindings + ("B" spacemacs/add-word-to-dict-buffer) ("b" flyspell-buffer) ("d" spell-checking/change-dictionary) + ("G" spacemacs/add-word-to-dict-global) ("n" flyspell-goto-next-error) ("c" flyspell-correct-wrapper) ("Q" flyspell-mode :exit t) ("q" nil :exit t) + ("S" spacemacs/add-word-to-dict-session) ("t" spacemacs/toggle-spelling-checking)) (spacemacs/set-leader-keys "S." 'spacemacs/spell-checking-transient-state/body) @@ -83,7 +85,11 @@ Spell Commands^^ Other :evil-leader "tS") (spacemacs/declare-prefix "S" "spelling") + (spacemacs/declare-prefix "Sa" "add word to dict") (spacemacs/set-leader-keys + "Sab" 'spacemacs/add-word-to-dict-buffer + "Sag" 'spacemacs/add-word-to-dict-global + "Sas" 'spacemacs/add-word-to-dict-session "Sb" 'flyspell-buffer "Sd" 'spell-checking/change-dictionary "Sn" 'flyspell-goto-next-error))