forked from redguardtoo/emacs.d
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinit-spelling.el
189 lines (169 loc) · 7.55 KB
/
init-spelling.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
;; {{ flyspell setup for web-mode
(defun web-mode-flyspell-verify ()
(let* ((f (get-text-property (- (point) 1) 'face))
rlt)
(cond
;; Check the words with these font faces, possibly.
;; This *blacklist* will be tweaked in next condition
((not (memq f '(web-mode-html-attr-value-face
web-mode-html-tag-face
web-mode-html-attr-name-face
web-mode-constant-face
web-mode-doctype-face
web-mode-keyword-face
web-mode-comment-face ;; focus on get html label right
web-mode-function-name-face
web-mode-variable-name-face
web-mode-css-property-name-face
web-mode-css-selector-face
web-mode-css-color-face
web-mode-type-face
web-mode-block-control-face)))
(setq rlt t))
;; check attribute value under certain conditions
((memq f '(web-mode-html-attr-value-face))
(save-excursion
(search-backward-regexp "=['\"]" (line-beginning-position) t)
(backward-char)
(setq rlt (string-match "^\\(value\\|class\\|ng[A-Za-z0-9-]*\\)$"
(thing-at-point 'symbol)))))
;; finalize the blacklist
(t
(setq rlt nil)))
rlt))
(put 'web-mode 'flyspell-mode-predicate 'web-mode-flyspell-verify)
;; }}
;; {{ flyspell setup for js2-mode
(local-require 'wucuo)
(put 'js2-mode 'flyspell-mode-predicate 'wucuo-generic-check-word-predicate)
(put 'rjsx-mode 'flyspell-mode-predicate 'wucuo-generic-check-word-predicate)
;; }}
(eval-after-load 'flyspell
'(progn
(require 'flyspell-lazy)
(flyspell-lazy-mode 1)))
;; better performance
(setq flyspell-issue-message-flag nil)
;; if (aspell installed) { use aspell}
;; else if (hunspell installed) { use hunspell }
;; whatever spell checker I use, I always use English dictionary
;; I prefer use aspell because:
;; 1. aspell is older
;; 2. looks Kevin Atkinson still get some road map for aspell:
;; @see http://lists.gnu.org/archive/html/aspell-announce/2011-09/msg00000.html
(defun flyspell-detect-ispell-args (&optional run-together)
"If RUN-TOGETHER is true, spell check the CamelCase words.
Please note RUN-TOGETHER will make aspell less capable. So it should only be used in prog-mode-hook."
(let (args)
(when ispell-program-name
(cond
((string-match "aspell$" ispell-program-name)
;; force the English dictionary, support Camel Case spelling check (tested with aspell 0.6)
(setq args (list "--sug-mode=ultra" "--lang=en_US"))
;; "--run-together-min" could not be 3, see `check` in "speller_impl.cpp" . The algorithm is
;; not precise .
;; Run `echo tasteTableConfig | aspell --lang=en_US -C --run-together-limit=16 --encoding=utf-8 -a` in shell.
(if run-together
(setq args (append args '("--run-together" "--run-together-limit=16")))))
((string-match "hunspell$" ispell-program-name)
(setq args nil))))
args))
;; Aspell Setup (recommended):
;; Skipped because it's easy.
;;
;; Hunspell Setup:
;; 1. Install hunspell from http://hunspell.sourceforge.net/
;; 2. Download openoffice dictionary extension from
;; http://extensions.openoffice.org/en/project/english-dictionaries-apache-openoffice
;; 3. That is download `dict-en.oxt'. Rename that to `dict-en.zip' and unzip
;; the contents to a temporary folder.
;; 4. Copy `en_US.dic' and `en_US.aff' files from there to a folder where you
;; save dictionary files; I saved it to `~/usr_local/share/hunspell/'
;; 5. Add that path to shell env variable `DICPATH':
;; setenv DICPATH $MYLOCAL/share/hunspell
;; 6. Restart emacs so that when hunspell is run by ispell/flyspell, that env
;; variable is effective.
;;
;; hunspell will search for a dictionary called `en_US' in the path specified by
;; `$DICPATH'
(defvar force-to-use-hunspell nil
"If t, force to use hunspell. Or else, search aspell at first and fall
back to hunspell if aspell is not found.")
(cond
;; use aspell
((and (not force-to-use-hunspell) (executable-find "aspell"))
(setq ispell-program-name "aspell"))
;; use hunspell
((executable-find "hunspell")
(setq ispell-program-name "hunspell")
(setq ispell-local-dictionary "en_US")
(setq ispell-local-dictionary-alist
'(("en_US" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_US") nil utf-8))))
(t (setq ispell-program-name nil)
(message "You need install either aspell or hunspell for ispell")))
;; `ispell-cmd-args' contains *extra* arguments appending to CLI process
;; when (ispell-send-string). Useless!
;; `ispell-extra-args' is *always* used when start CLI aspell process
(setq-default ispell-extra-args (flyspell-detect-ispell-args t))
;; (setq ispell-cmd-args (flyspell-detect-ispell-args))
(defadvice ispell-word (around my-ispell-word activate)
(let ((old-ispell-extra-args ispell-extra-args))
(ispell-kill-ispell t)
;; use emacs original arguments
(setq ispell-extra-args (flyspell-detect-ispell-args))
ad-do-it
;; restore our own ispell arguments
(setq ispell-extra-args old-ispell-extra-args)
(ispell-kill-ispell t)))
(defadvice flyspell-auto-correct-word (around my-flyspell-auto-correct-word activate)
(let* ((old-ispell-extra-args ispell-extra-args))
(ispell-kill-ispell t)
;; use emacs original arguments
(setq ispell-extra-args (flyspell-detect-ispell-args))
ad-do-it
;; restore our own ispell arguments
(setq ispell-extra-args old-ispell-extra-args)
(ispell-kill-ispell t)))
(defun text-mode-hook-setup ()
;; Turn off RUN-TOGETHER option when spell check text-mode
(setq-local ispell-extra-args (flyspell-detect-ispell-args)))
(add-hook 'text-mode-hook 'text-mode-hook-setup)
;; Add auto spell-checking in comments for all programming language modes
;; if and only if there is enough memory
;; You can use prog-mode-hook instead.
(defun can-enable-flyspell-mode ()
(and (not *no-memory*)
ispell-program-name
(executable-find ispell-program-name)))
(defun enable-flyspell-mode-conditionally ()
(if (can-enable-flyspell-mode)
(flyspell-mode 1)))
;; turn on flyspell-mode for programming languages
(if (can-enable-flyspell-mode)
(add-hook 'prog-mode-hook 'flyspell-prog-mode))
;; I don't use flyspell in text-mode because I often write Chinese.
;; I'd rather manually spell check the English text
;; you can also use "M-x ispell-word" or hotkey "M-$". It pop up a multiple choice
;; @see http://frequal.com/Perspectives/EmacsTip03-FlyspellAutoCorrectWord.html
(global-set-key (kbd "C-c s") 'flyspell-auto-correct-word)
;; {{ avoid spell-checking doublon (double word) in certain major modes
(defvar flyspell-check-doublon t
"Check doublon (double word) when calling `flyspell-highlight-incorrect-region'.")
(make-variable-buffer-local 'flyspell-check-doublon)
(defadvice flyspell-highlight-incorrect-region (around flyspell-highlight-incorrect-region-hack activate)
(if (or flyspell-check-doublon (not (eq 'doublon (ad-get-arg 2))))
ad-do-it))
;; }}
(defun my-clean-aspell-dict ()
"Clean ~/.aspell.pws (dictionary used by aspell)."
(interactive)
(let* ((dict (file-truename "~/.aspell.en.pws"))
(lines (read-lines dict))
;; sort words
(aspell-words (sort (cdr lines) 'string<)))
(with-temp-file dict
(insert (format "%s %d\n%s"
"personal_ws-1.1 en"
(length aspell-words)
(mapconcat 'identity aspell-words "\n"))))))
(provide 'init-spelling)