All these codes are copied from http://blog.binchen.org/posts/what-s-the-best-spell-check-set-up-in-emacs.html
(setq flyspell-issue-welcome-flag nil)
(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"
(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"))
(if RUN-TOGETHER
(setq args (append args '("--run-together" "--run-together-limit=16" "--run-together-min=2")))))
((string-match "hunspell$" ispell-program-name)
(setq args nil))))
args))
(cond
((executable-find "aspell")
(setq ispell-program-name "aspell"))
((executable-find "hunspell")
(setq ispell-program-name "hunspell")
;; just reset dictionary to the safe one "en_US" for hunspell. if we need
;; use different dictionary, we specify it in command line arguments
(setq ispell-local-dictionary "en_US")
(setq ispell-local-dictionary-alist
'(("en_US" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil nil nil utf-8))))
(t (setq ispell-program-name nil)))
;; ispell-cmd-args is useless, it's the list of *extra* command line arguments
;; we will append to the ispell process when ispell-send-string()
;; ispell-extra-args is the command arguments which will *always* be used when
;; start ispell process
(with-eval-after-load 'flyspell
(add-hook 'flyspell-mode-hook
(lambda ()
(setq ispell-extra-args (flyspell-detect-ispell-args t)))))
;; (setq ispell-cmd-args (flyspell-detect-ispell-args))
;; personal dictionary
(if dropbox-root
(setq ispell-personal-dictionary
(concat dropbox-root "/dict/aspell.en.pws"))
(setq ispell-personal-dictionary
(concat starter-kit-dir "dict/aspell.en.pws")))
(defadvice ispell-word (around my-ispell-word activate)
(let ((old-ispell-extra-args ispell-extra-args))
(ispell-kill-ispell t)
(setq ispell-extra-args (flyspell-detect-ispell-args))
ad-do-it
(setq ispell-extra-args old-ispell-extra-args)
(ispell-kill-ispell t)))
(defadvice ispell-region (around my-ispell-region activate)
(let ((old-ispell-extra-args ispell-extra-args))
(ispell-kill-ispell t)
(setq ispell-extra-args (flyspell-detect-ispell-args))
ad-do-it
(setq ispell-extra-args old-ispell-extra-args)
(ispell-kill-ispell t)))
;; NO spell check for embedded snippets
(defadvice org-mode-flyspell-verify (after org-mode-flyspell-verify-hack activate)
(let ((rlt ad-return-value)
(begin-regexp "^[ \t]*\\(#\\+begin_\\(src\\|html\\|latex\\)\\|\\\\begin{\\)")
(end-regexp "^[ \t]*\\(#\\+end_\\(src\\|html\\|latex\\)\\|\\\\end{\\)")
old-flag
b e)
(when ad-return-value
(save-excursion
(setq old-flag case-fold-search)
(setq case-fold-search t)
(setq b (re-search-backward begin-regexp nil t))
(if b (setq e (re-search-forward end-regexp nil t)))
(setq case-fold-search old-flag))
(if (and b e (< (point) e)) (setq rlt nil)))
(setq ad-return-value rlt)))
(defadvice flyspell-correct-word-before-point (around my-fcwbp activate)
(let ((old-ispell-extra-args ispell-extra-args))
(ispell-kill-ispell t)
(setq ispell-extra-args (flyspell-detect-ispell-args))
ad-do-it
(setq ispell-extra-args old-ispell-extra-args)
(ispell-kill-ispell t)))
(defun flyspell-emacs-popup-textual (event poss word)
"A textual flyspell popup menu."
(require 'popup)
(let* ((corrects (if flyspell-sort-corrections
(sort (car (cdr (cdr poss))) 'string<)
(car (cdr (cdr poss)))))
(cor-menu (if (consp corrects)
(mapcar (lambda (correct)
(list correct correct))
corrects)
'()))
(affix (car (cdr (cdr (cdr poss)))))
show-affix-info
(base-menu (let ((save (if (and (consp affix) show-affix-info)
(list
(list (concat "Save affix: " (car affix))
'save)
'("Accept (session)" session)
'("Accept (buffer)" buffer))
'(("Save word" save)
("Accept (session)" session)
("Accept (buffer)" buffer)))))
(if (consp cor-menu)
(append cor-menu (cons "" save))
save)))
(menu (mapcar
(lambda (arg) (if (consp arg) (car arg) arg))
base-menu)))
(cadr (assoc (popup-menu* menu :scroll-bar t) base-menu))))
(eval-after-load "flyspell"
'(progn
(fset 'flyspell-emacs-popup 'flyspell-emacs-popup-textual)))