@kyanny's blog

My thoughts, my life. Views/opinions are my own.

anything-slime.el で補完する (+α でインデントも)

anything-slime.el を使うと anything のインターフェースで補完ができる。

anything.el とともに SLIME を使うのに便利な設定を集めた anything-slime.el をようやく EmacsWiki にアップロードしました - hchbaw記

おなじみの anything なバッファで補完候補を選べる。実は anything-complete 的なものを使ったのはこれが初めて。見やすいし候補選択が楽でいい。ただ、これを TAB (C-i) に割り当てるとちょっと困ったことがあって、インデントができない。インデントと補完を一緒にやりたいので、どうにかならないか少し調べた。

anything-slime.el にはインデントをするような関数はなかったので、 M-x apropos slime indent とかで調べると slime-fuzzy-indent-and-complete-symbol というのが見つかった。これがなかなか優秀で、まずインデントをしてカーソルが移動してなかったら補完する、というものらしい。しかも fuzzy (あいまい) なので先頭一致じゃなくても補完候補を選んでくれるみたい。これは SLIME に同梱の slime-fuzzy.el で定義されてる。

slime-fuzzy-indent-and-complete-symbol をみてみると補完の部分は slime-fuzzy-complete-symbol を呼んでるようなので、そこを anything-slime-complete に変えた関数を自前で定義して C-i に割り当てたらいけるんじゃないかな?と思ってやってみたらうまくいった。以下、 SLIME と anything-slime あたりの設定。 my-indent-and-anything-slime-complete ってのがコピペして一部書き換えただけの関数。 anything-slime-complete もちゃんと fuzzy complete な補完ソースを提示してくれる。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; slime
(add-to-list 'load-path "/opt/local/share/emacs/site-lisp/slime")
(require 'slime-autoloads)
(setq slime-lisp-implementations
      `((clisp ("/opt/local/bin/clisp"))
        (sbcl ("/opt/local/bin/sbcl"))
        (abcl ("/opt/local/bin/abcl"))
        ))
(add-hook 'lisp-mode-hook
           (lambda ()
             (cond ((not (featurep 'slime))
                    (require 'slime)
                    (normal-mode)))))

(eval-after-load "slime"
   '(slime-setup '(slime-fancy slime-banner anything-slime)))

;; key
(add-hook 'slime-mode-hook
          (lambda ()
            (define-key global-map (kbd "C-M-;") 'slime-selector)
            ;(define-key slime-mode-map (kbd "C-i") 'slime-fuzzy-indent-and-complete-symbol)
            ))

;; anything-slime
(defun my-indent-and-anything-slime-complete ()
  "Indent and completion with anything interface."
  (interactive)
  (let ((pos (point)))
    (unless (get-text-property (line-beginning-position) 'slime-repl-prompt)
      (lisp-indent-line))
    (when (= pos (point))
      (cond ((save-excursion (re-search-backward "[^() \n\t\r]+\\=" nil t))
             (anything-slime-complete))
            ((memq (char-before) '(?\t ?\ ))
             (slime-echo-arglist))))))

(require 'anything-kyr-config)
(add-hook
 'anything-slime-init-hook
 (lambda ()
   (add-to-list 'anything-kyr-commands-by-condition
                '(slime-net-processes
                  anything-slime-list-connections))
   (define-key slime-mode-map (kbd "C-i") 'my-indent-and-anything-slime-complete)
   (define-key slime-repl-mode-map (kbd "C-i") 'my-indent-and-anything-slime-complete)
   (define-key slime-repl-mode-map "\M-r" 'anything-slime-repl-history)
   ))

(setq anything-slime-complete-sources
  '(anything-slime-fuzzy-complete-source
    anything-slime-simple-complete-source
    anything-slime-compound-complete-source))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;