LoginSignup
4
6

More than 3 years have passed since last update.

ivyインターフェイスを用いたispell/aspellに基づく英単語補完

Last updated at Posted at 2020-02-17

かなり前の記事に、ispell / aspell による英単語補完をhelmインターフェイスを使って実装した話があった。

今回はそれをhelmでなくivyで実装したわけである。英語アルファベット3文字以上を入力して、M-x ivy-ispell とすれば補完が走る。適当なキーバインドをアサインするのも一興だろう。ちなみにバイナリはispell/aspell/hunspellのどれかを用意しておく必要がある (cf. ispell-program-name)。

(require 'ispell)
(require 'ivy)
(require 'thingatpt)

(defvar ivy-ispell--word-at-point nil)

(defun ivy-ispell--case-function (input)
  (let ((case-fold-search nil))
    (cond ((string-match-p "\\`[A-Z]\\{2\\}" input) 'upcase)
          ((string-match-p "\\`[A-Z]\\{1\\}" input) 'capitalize)
          (t 'identity))))

(defun ivy-ispell--compare-length (a b)
  (< (length a) (length b)))

(defun ivy-ispell--make-candidate ()
  (let ((input (downcase ivy-ispell--word-at-point))
        (case-func (ivy-ispell--case-function
                    ivy-ispell--word-at-point)))
    (when (string-match-p "\\`[a-z]+\\'" input)
      (mapcar case-func
              (sort (ispell-lookup-words (concat input "*")
                                         ispell-complete-word-dict)
                    'ivy-ispell--compare-length)))))

(defun ivy-ispell ()
  (interactive)
  (setq ivy-ispell--word-at-point (thing-at-point 'word))
  (if (not ivy-ispell--word-at-point)
      (message "Nothing to complete.")
    (let ((candidate (ivy-read "Completion: "
                               (funcall 'ivy-ispell--make-candidate)
                               :initial-input ivy-ispell--word-at-point))
          (curpoint (point)))
      (backward-word 1)
      (delete-region (point) curpoint)
      (insert candidate))))

動作例
"nece"と入力し、ivyインターフェイスで絞り込みを行って"necessarily"を入力している様子。
ezgif-2-a058b0cde611.gif

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6