redguardtoo / wucuo

Fastest solution to spell check camel case code or plain text
122 stars 4 forks source link

[[https://github.com/redguardtoo/wucuo/actions/workflows/test.yml][https://github.com/redguardtoo/wucuo/actions/workflows/test.yml/badge.svg]] [[http://melpa.org/#/wucuo][file:http://melpa.org/packages/wucuo-badge.svg]] [[http://stable.melpa.org/#/wucuo][file:http://stable.melpa.org/packages/wucuo-badge.svg]]

Fastest solution to spell check camel case code or plain text

Screenshot:

[[file:demo.png]]

[[file:huge-file-demo-nq8.png]]

If using [[https://guix.gnu.org/][GNU Guix]], Wucuo and its dependencies can be installed via =guix install emacs-guix=.

This program does not mess up your Flyspell configuration. It assumes Flyspell is already configured properly.

But if you get some problem on Flyspell configuration, check sample configuration in "Tips" section.

The spell checking starts when current buffer is saved.

See =wucuo-check-nil-font-face= on how to check plain text (text without font).

Please note Wucuo is a complete solution. You should turn off =flyspell-prog-mode= and =flyspell-mode= before using this program.

Wucuo uses Flyspell API. So the good news is your configuration for flyspell still works.

Flyspell provides two minor modes, =flyspell-prog-mode= and =flyspell-mode=. They also use Flyspell API.

This program replaces these two minor modes.

Even you don't use this program, you still need configure flyspell.

If your existing Flyspell configuration already works, you don't need read this section.

This section is to help users who have problem to setup flyspell.

You could read my article [[https://blog.binchen.org/posts/what-s-the-best-spell-check-set-up-in-emacs.html][What's the best spell check setup in emacs]] and [[https://emacs.stackexchange.com/questions/21378/spell-check-with-multiple-dictionaries/22240#22240][my stackexchange answers on flyspell]] to learn the Flyspell knowledge.

*** Aspell configuration sample Please install command line program Aspell and insert below code into =~/.emacs=,

+begin_src elisp

(setq ispell-program-name "aspell") ;; You could add extra option "--camel-case" for camel case code spell checking if Aspell 0.60.8+ is installed ;; @see https://github.com/redguardtoo/emacs.d/issues/796 (setq ispell-extra-args '("--sug-mode=ultra" "--lang=en_US" "--run-together" "--run-together-limit=16"))

+end_src

*** hunspell configuration sample Please install command line program hunspell and insert below code into =~/.emacs=,

+begin_src elisp

(setq ispell-program-name "hunspell") ;; reset the hunspell so it STOPS querying locale! ;; "en_US" is the key to lookup in ispell-local-dictionary-alist (setq ispell-local-dictionary "en_US") ;; two dictionaries "en_US" and "zh_CN" are used. Feel free to remove "zh_CN" ;; If ispell-local-dictionary-alist' is nil,ispell-local-dictionary' is passed ;; to hunpsell cli program as dictionary. (setq ispell-local-dictionary-alist '(("en_US" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_US" "zh_CN") nil utf-8))) ;; new variable `ispell-hunspell-dictionary-alist' is defined in Emacs ;; If it's nil, Emacs tries to automatically set up the dictionaries. (when (boundp 'ispell-hunspell-dictionary-alist) (setq ispell-hunspell-dictionary-alist ispell-local-dictionary-alist))

+end_src

** Spell check file and directory The function =wucuo-spell-check-file= will spell check one file and report typos. The function =wucuo-spell-check-directory= will spell check files under one directory and report typos.

Above functions could be used through Emacs CLI.

Example to use aspell to syntax check all files under current directory,

+begin_src elisp

emacs -batch -Q -L ~/projs/wucuo -l ~/projs/wucuo/wucuo.el --eval '(let ((ispell-program-name "aspell") (ispell-extra-args (wucuo-aspell-cli-args t))) (wucuo-spell-check-directory "."))'

+end_src

Example to use hunspell to syntax check one file,

+begin_src elisp

emacs -batch -Q -L ~/projs/wucuo -l ~/projs/wucuo/wucuo.el --eval '(let ((ispell-program-name "hunspell") (ispell-local-dictionary "en_US")) (wucuo-spell-check-file "README.org"))'

+end_src

** Start mode The default value of =wucuo-flyspell-start-mode= is "fast".

If =wucuo-flyspell-start-mode= is "fast", =wucuo-start= calls =flyspell-region= to check visible region in current window periodically.

If =wucuo-flyspell-start-mode= is "normal", =wucuo-start= calls =flyspell-buffer= periodically.

The interval of buffer checking or region checking is controlled by =wucuo-update-interval=.

Wucuo only checks typo in current buffer or the visible region. So it's much faster than =flyspell-mode=. ** Skip spell checking under certain circumstances

You can define a function in =wucuo-spell-check-buffer-predicate=. If the function returns t, the spell checking of current buffer will continue. If it returns nil, the spell checking is skipped.

Here is sample to skip checking in specified major modes,

+begin_src elisp

(setq wucuo-spell-check-buffer-predicate (lambda () (not (memq major-mode '(dired-mode log-edit-mode compilation-mode help-mode profiler-report-mode speedbar-mode gud-mode calc-mode Info-mode)))))

+end_src

Change dictionaries See =wucuo-aspell-language-to-use= and =wucuo-hunspell-dictionary-base-name= Spell check words with specific font faces By default, =wucuo-font-faces-to-check= has already set up the font faces to spell check. You can adjust this variable to add or remove font faces.

If you only need add some extra font faces to check, it's recommended to set up =wucuo-personal-font-faces-to-check=,

+begin_src elisp

(setq wucuo-personal-font-faces-to-check '(font-lock-comment-face))

+end_src

** Flyspell wrongly mark some word as typo There are two solutions. *** Solution 1, set up Emacs with below code,

+begin_src elisp

(defun my-checker (word) "If WORD is typo, return t." ;; add your own setup code here t) (setq wucuo-extra-predicate #'my-checker)

+end_src

*** Solution 2, create a personal dictionary If you use Aspell, run =M-x wucuo-create-aspell-personal-dictionary= to create a plain text dictionary =~/.aspell.en.pws=. The "en" in ".aspell.en.pws" means the personal dictionary is an English dictionary. It's actually [[https://en.wikipedia.org/wiki/ISO_639-1][language code]] assigned to the English. Aspell's option =--lang= uses same language code ("en" is default value).

If you use Hunspell, run =M-x wucuo-create-hunspell-personal-dictionary= to create a plain text dictionary =~/.hunspell_en_US=. "en_US" is the language code used by Hunspell's option =-d=.

Here is my [[file:.aspell.en.pws]].

Hunspell's personal dictionary is in the same format as Aspell.

Please note it's reported that [[https://github.com/redguardtoo/emacs.d/issues/947][the dictionary file should be utf-8 encoded]]. ** Speed up checking if aspell is used

+begin_src elisp

(setq ispell-extra-args "--run-together")

+end_src

** Ignore major mode's own flyspell predicate Or if you need replace the default configuration of multiple major modes, you can use below code,

+begin_src elisp

(setq wucuo-modes-whose-predicate-ignored '("typescript-mode"))

+end_src

Detect font face at point Use =wucuo-current-font-face= to detect font face at point. Skip spell checking when buffer or visible region is too big In =wucuo-flyspell-start-mode= is "normal", =wucuo-spell-check-buffer-max= specifies the maximum size of buffer to check.

In =wucuo-flyspell-start-mode= is "fast", =wucuo-spell-check-region-max= specifies the maximum size of visible region to check.