branch: elpa/crux commit d2643ae98098fab91dec989057e2cf5a5dd27619 Author: Bozhidar Batsov <bozhi...@batsov.com> Commit: Bozhidar Batsov <bozhi...@batsov.com>
Add crux-ispell-word-then-abbrev Borrowed from @Malabarba. More info - http://endlessparentheses.com/ispell-and-abbrev-the-perfect-auto-correct.html. --- README.md | 8 ++++++++ crux.el | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/README.md b/README.md index e1274c7..a13b6b5 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ Command | Suggested Keybinding(s) | `crux-top-join-lines` | <kbd>Super-j</kbd> or <kbd>C-^</kbd> | Join lines `crux-kill-whole-line` | <kbd>Super-k</kbd> | Kill whole line `crux-kill-line-backwards` | <kbd>C-Backspace</kbd> | Kill line backwards +`crux-ispell-word-then-abbrev` | <kbd>C-c i</kbd> | Fix word using `ispell` and then save to `abbrev`. Here's how you'd bind some of the commands to keycombos: @@ -72,6 +73,13 @@ Here's how you'd bind some of the commands to keycombos: (global-set-key [remap kill-whole-line] #'crux-kill-whole-line) ``` +For `crux-ispell-word-then-abbrev` to be most effective you'll also need to add this to your config: + +```el +(setq save-abbrevs 'silently) +(setq-default abbrev-mode t) +``` + ## Using the bundled advices crux ships with some handy advises that can enhance the operation of existing commands. diff --git a/crux.el b/crux.el index 3de5450..08027f5 100644 --- a/crux.el +++ b/crux.el @@ -353,6 +353,39 @@ Doesn't mess with special buffers." (t (error "Unknown shell"))))) (find-file-other-window (expand-file-name shell-init-file (getenv "HOME"))))) +;; http://endlessparentheses.com/ispell-and-abbrev-the-perfect-auto-correct.html +(defun crux-ispell-word-then-abbrev (p) + "Call `ispell-word', then create an abbrev for it. +With prefix P, create local abbrev. Otherwise it will +be global. +If there's nothing wrong with the word at point, keep +looking for a typo until the beginning of buffer. You can +skip typos you don't want to fix with `SPC', and you can +abort completely with `C-g'." + (interactive "P") + (let (bef aft) + (save-excursion + (while (if (setq bef (thing-at-point 'word)) + ;; Word was corrected or used quit. + (if (ispell-word nil 'quiet) + nil ; End the loop. + ;; Also end if we reach `bob'. + (not (bobp))) + ;; If there's no word at point, keep looking + ;; until `bob'. + (not (bobp))) + (backward-word)) + (setq aft (thing-at-point 'word))) + (if (and aft bef (not (equal aft bef))) + (let ((aft (downcase aft)) + (bef (downcase bef))) + (define-abbrev + (if p local-abbrev-table global-abbrev-table) + bef aft) + (message "\"%s\" now expands to \"%s\" %sally" + bef aft (if p "loc" "glob"))) + (user-error "No typo at or before point")))) + (defmacro crux-with-region-or-buffer (func) "When called with no active region, call FUNC on current buffer.