Skip to content

Commit

Permalink
feat(natural-langs): use jinx for spell checking instead of spell-fu
Browse files Browse the repository at this point in the history
  • Loading branch information
abougouffa committed Dec 25, 2023
1 parent 79aba80 commit b2b62bb
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 88 deletions.
89 changes: 2 additions & 87 deletions modules/extras/me-spell-fu.el
Original file line number Diff line number Diff line change
Expand Up @@ -10,93 +10,6 @@

(message "me-spell-fu is deprecated")

;; Adapted from Doom Emacs
(defun +spell-fu--correct (replace poss word orig-pt start end)
"Correct word with spell-fu."
(cond ((eq replace 'ignore)
(goto-char orig-pt)
nil)
((eq replace 'save)
(goto-char orig-pt)
(ispell-send-string (concat "*" word "\n"))
(ispell-send-string "#\n")
(setq ispell-pdict-modified-p '(t)))
((or (eq replace 'buffer) (eq replace 'session))
(ispell-send-string (concat "@" word "\n"))
(add-to-list 'ispell-buffer-session-localwords word)
(or ispell-buffer-local-name ; session localwords might conflict
(setq ispell-buffer-local-name (buffer-name)))
(when (null ispell-pdict-modified-p) (setq ispell-pdict-modified-p (list nil)))
(goto-char orig-pt)
(when (eq replace 'buffer) (ispell-add-per-file-word-list word)))
(replace
(let ((new-word (if (atom replace) replace (car replace)))
(orig-pt (+ (- (length word) (- end start)) orig-pt)))
(unless (equal new-word (car poss))
(delete-region start end)
(goto-char start)
(insert new-word))))
((goto-char orig-pt)
nil)))

;; Adapted from Doom Emacs
;;;###autoload
(defun +spell-fu-correct ()
"Correct spelling of word at point."
(interactive)
;; spell-fu fails to initialize correctly if it can't find aspell or a similar
;; program. We want to signal the error, not tell the user that every word is
;; spelled correctly.
(unless (or (and ispell-really-aspell ispell-program-name) (executable-find "aspell"))
(user-error "Aspell is required for spell checking"))

(ispell-set-spellchecker-params)
(save-current-buffer (ispell-accept-buffer-local-defs))
(if (not (featurep 'vertico))
(call-interactively #'ispell-word)
(cl-destructuring-bind (start . end)
(or (bounds-of-thing-at-point 'word) (user-error "No word at point"))
(let ((word (thing-at-point 'word t))
(orig-pt (point))
poss ispell-filter)
(ispell-send-string "%\n")
(ispell-send-string (concat "^" word "\n"))
(while (progn (accept-process-output ispell-process)
(not (string= "" (car ispell-filter)))))
(setq ispell-filter (cdr ispell-filter)) ; Remove leading empty element
;; ispell process should return something after word is sent. Tag word as valid (i.e., skip) otherwise
(unless ispell-filter (setq ispell-filter '(*)))
(when (consp ispell-filter) (setq poss (ispell-parse-output (car ispell-filter))))
(cond
((or (eq poss t) (stringp poss)) ; don't correct word
(message "%s is correct" (funcall ispell-format-word-function word))
t)
((null poss) ; ispell error
(error "Ispell: error in Ispell process"))
(t ; The word is incorrect, we have to propose a replacement
(setq res (completing-read (format "Corrections for %S: " word) (nth 2 poss)))
(unless res (setq res (cons 'break word)))
(cond
((stringp res)
(+spell-fu--correct res poss word orig-pt start end))
((let ((cmd (car res))
(wrd (cdr res)))
(unless (memq cmd '(skip break stop))
(+spell-fu--correct cmd poss wrd orig-pt start end)
(unless (string-equal wrd word)
(+spell-fu--correct wrd poss word orig-pt start end))))))
(ispell-pdict-save t)))))))

(defun +spell-fu--add-dictionary (lang)
"Add `LANG` to spell-fu multi-dict, with a personal dictionary."
;; Add the dictionary
(spell-fu-dictionary-add (spell-fu-get-ispell-dictionary lang))
(let ((personal-dict-file (expand-file-name (format "personal-aspell.%s.pws" lang) spell-fu-directory)))
;; Create an empty personal dictionary if it doesn't exists
(unless (file-exists-p personal-dict-file) (write-region "" nil personal-dict-file))
;; Add the personal dictionary
(spell-fu-dictionary-add (spell-fu-get-personal-dictionary (format "%s-personal" lang) personal-dict-file))))

;;;###autoload
(defmacro +spell-fu-register-dictionaries! (&rest langs)
"Register dictionaries for `LANGS` to spell-fu's multi-dict."
Expand All @@ -107,6 +20,8 @@
(setq closure (append closure `((+spell-fu--add-dictionary ,lang)))))
(append '(add-hook (quote spell-fu-mode-hook)) (list closure)))))

(make-obsolete '+spell-fu-register-dictionaries! 'jinx-mode "2023-12-25")


(provide 'me-spell-fu)

Expand Down
7 changes: 7 additions & 0 deletions modules/me-natural-langs.el
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@

;;; Code:

(use-package jinx
:straight t
:hook (text-mode . jinx-mode)
:init
(+map! "ts" #'jinx-mode)
(+nvmap! "z=" #'jinx-correct))

(use-package go-translate
:straight (:host github :repo "lorniu/go-translate")
:commands +gts-yank-translated-region +gts-translate-with
Expand Down
88 changes: 87 additions & 1 deletion modules/obsolete/me-spell-fu.el
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,93 @@
(defun +spell-fu--init-excluded-faces-h ()
"Set `spell-fu-faces-exclude' according to `+spell-excluded-faces-alist'."
(when-let (excluded (cdr (cl-find-if #'derived-mode-p +spell-excluded-faces-alist :key #'car)))
(setq-local spell-fu-faces-exclude excluded))))
(setq-local spell-fu-faces-exclude excluded)))

;; Adapted from Doom Emacs
(defun +spell-fu--correct (replace poss word orig-pt start end)
"Correct word with spell-fu."
(cond ((eq replace 'ignore)
(goto-char orig-pt)
nil)
((eq replace 'save)
(goto-char orig-pt)
(ispell-send-string (concat "*" word "\n"))
(ispell-send-string "#\n")
(setq ispell-pdict-modified-p '(t)))
((or (eq replace 'buffer) (eq replace 'session))
(ispell-send-string (concat "@" word "\n"))
(add-to-list 'ispell-buffer-session-localwords word)
(or ispell-buffer-local-name ; session localwords might conflict
(setq ispell-buffer-local-name (buffer-name)))
(when (null ispell-pdict-modified-p) (setq ispell-pdict-modified-p (list nil)))
(goto-char orig-pt)
(when (eq replace 'buffer) (ispell-add-per-file-word-list word)))
(replace
(let ((new-word (if (atom replace) replace (car replace)))
(orig-pt (+ (- (length word) (- end start)) orig-pt)))
(unless (equal new-word (car poss))
(delete-region start end)
(goto-char start)
(insert new-word))))
((goto-char orig-pt)
nil)))

;; Adapted from Doom Emacs
(defun +spell-fu-correct ()
"Correct spelling of word at point."
(interactive)
;; spell-fu fails to initialize correctly if it can't find aspell or a similar
;; program. We want to signal the error, not tell the user that every word is
;; spelled correctly.
(unless (or (and ispell-really-aspell ispell-program-name) (executable-find "aspell"))
(user-error "Aspell is required for spell checking"))

(ispell-set-spellchecker-params)
(save-current-buffer (ispell-accept-buffer-local-defs))
(if (not (featurep 'vertico))
(call-interactively #'ispell-word)
(cl-destructuring-bind (start . end)
(or (bounds-of-thing-at-point 'word) (user-error "No word at point"))
(let ((word (thing-at-point 'word t))
(orig-pt (point))
poss ispell-filter)
(ispell-send-string "%\n")
(ispell-send-string (concat "^" word "\n"))
(while (progn (accept-process-output ispell-process)
(not (string= "" (car ispell-filter)))))
(setq ispell-filter (cdr ispell-filter)) ; Remove leading empty element
;; ispell process should return something after word is sent. Tag word as valid (i.e., skip) otherwise
(unless ispell-filter (setq ispell-filter '(*)))
(when (consp ispell-filter) (setq poss (ispell-parse-output (car ispell-filter))))
(cond
((or (eq poss t) (stringp poss)) ; don't correct word
(message "%s is correct" (funcall ispell-format-word-function word))
t)
((null poss) ; ispell error
(error "Ispell: error in Ispell process"))
(t ; The word is incorrect, we have to propose a replacement
(setq res (completing-read (format "Corrections for %S: " word) (nth 2 poss)))
(unless res (setq res (cons 'break word)))
(cond
((stringp res)
(+spell-fu--correct res poss word orig-pt start end))
((let ((cmd (car res))
(wrd (cdr res)))
(unless (memq cmd '(skip break stop))
(+spell-fu--correct cmd poss wrd orig-pt start end)
(unless (string-equal wrd word)
(+spell-fu--correct wrd poss word orig-pt start end))))))
(ispell-pdict-save t)))))))

(defun +spell-fu--add-dictionary (lang)
"Add `LANG` to spell-fu multi-dict, with a personal dictionary."
;; Add the dictionary
(spell-fu-dictionary-add (spell-fu-get-ispell-dictionary lang))
(let ((personal-dict-file (expand-file-name (format "personal-aspell.%s.pws" lang) spell-fu-directory)))
;; Create an empty personal dictionary if it doesn't exists
(unless (file-exists-p personal-dict-file) (write-region "" nil personal-dict-file))
;; Add the personal dictionary
(spell-fu-dictionary-add (spell-fu-get-personal-dictionary (format "%s-personal" lang) personal-dict-file)))))


(provide 'obsolete/me-spell-fu)
Expand Down

0 comments on commit b2b62bb

Please sign in to comment.