;;; cape-jinx-completion.el --- Completion At Point Extensions using Jinx spell checking -*- lexical-binding: t -*- ;; Copyright (C) 2023 Free Software Foundation, Inc. ;; Author: Adam Kruszewski ;; Maintainer: Adam Kruszewski ;; Created: 2023 ;; Version: 1.0 ;; Package-Requires: ((emacs "27.1") (compat "29.1.4.0") (cape "0.15") (jinx "0.5")) ;; Homepage: https://code.bsdgeek.org/adam/cape-jinx-completion ;; Keywords: completion, spell-check ;; This file is part of GNU Emacs. ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; Additional completion backend in the form of Capfs ;; (completion-at-point-functions), using underlying C module provided ;; by Jinx just-in-time spell-checking package ;; (see https://github.com/minad/jinx ). ;; ;; It doesn't need Jinx enabled, but it uses its configuration ;; and C module bridge to enchant library. ;; ;; Having jinx and cape configured you just need to add: ;; (add-to-list 'completion-at-point-functions #'cape-jinx) ;; cape-jinx-completion to your completions-at-point-functions. (require 'cape) (require 'jinx) ;; jinx.el version 0.5 is required (defun jinx-suggest-for-word (word) (when (not jinx--dicts) (when (not (fboundp #'jinx--mod-dict)) (jinx--load-module)) (jinx--load-dicts)) (let* ((result '())) (dolist (dict jinx--dicts) (dolist (el (jinx--mod-suggest dict word)) (when (string-prefix-p word el) (cl-pushnew el result)))) (delete-dups result))) ;; cape-jinx (based on cape-dict) (defgroup cape-jinx nil "Completion At Point extensions using Jinx spell checking." :prefix "cape-jinx" :group 'cape-jinx) (defcustom cape-jinx-case-replace 'case-replace "Preserve case of input. See `dabbrev-case-replace' for details." :type '(choice (const :tag "off" nil) (const :tag "use `case-replace'" case-replace) (other :tag "on" t))) (defcustom cape-jinx-case-fold 'case-fold-search "Case fold search during search. See `dabbrev-case-fold-search' for details." :type '(choice (const :tag "off" nil) (const :tag "use `case-fold-search'" case-fold-search) (other :tag "on" t))) (defvar cape--jinx-properties (list :annotation-function (lambda (_) " Jinx") :company-kind (lambda (_) 'text) :exclusive 'no) "Completion extra properties for `cape-jinx'.") (defun cape--jinx-list (input) "Return all words from Jinx spell checking mechanism matching INPUT." (unless (equal input "") (cape--case-replace-list cape-jinx-case-replace input (jinx-suggest-for-word input)))) ;;;###autoload (defun cape-jinx (&optional interactive) "Complete word from Jinx spell checking at point. If INTERACTIVE is nil the function acts like a Capf." (interactive (list t)) (if interactive (cape-interactive #'cape-jinx) (pcase-let ((`(,beg . ,end) (cape--bounds 'word))) `(,beg ,end ,(cape--table-with-properties (completion-table-case-fold (cape--cached-table beg end #'cape--jinx-list #'string-search) (not (cape--case-fold-p cape-jinx-case-fold))) :category 'cape-jinx) ,@cape--jinx-properties)))) ;;; cape-jinx-completion.el ends here (provide 'cape-jinx-completion)