refeとかriをanythingで

(defvar ri-program "fri")
;;friを使わないなら
;;(setq ri-program "ri")
(defvar refe-program "~/bin/refe.sh")

(defvar ruby-all-methods nil)
(defvar my-ruby-reference-last-word "")

(defun read-ruby-document (document com)
  "Open each ruby's ruby-document on other window"
  (let ((buf "*ruby document*"))
    (if (equal com "")
	(shell-command (concat document " -l") buf)
      (shell-command (concat document " " com) buf))
    (save-excursion
      (set-buffer buf)
      (ansi-color-apply-on-region (point-min) (point-max)))))

(defun get-ruby-method-reference ()
  (let ((buf "*ruby document*"))
    (progn (read-ruby-document ri-program "")
	   (setq ruby-all-methods
		 (buffer->alist buf '( "(\"" "\" \"" "\")")))
	     (kill-buffer buf)))
  ruby-all-methods)

(defun buffer->alist (src-buffer &optional padding)
  ;;"a\nb\nc" => (a b c)
  (let* ((padding (if padding padding '( "(" " " ")")))
	 (beg-paren (car padding))
	 (joiner (cadr padding))
	 (end-paren (caddr padding)))
    (save-excursion
      (set-buffer src-buffer)
      (goto-char (point-min))
      (insert beg-paren)
      (while (search-forward "\n" nil t)
      (replace-match joiner nil t))
    (goto-char (point-max))
    (insert end-paren)
    (goto-char (point-min))
    (read (current-buffer)))))

(defun my-ruby-reference (method &optional prog chr)
  (let  ((chr (if chr chr "."))
	 (prog (if prog prog ri-program)))
    (let ((method (replace-regexp-in-string "#" chr method)))
      (setq my-ruby-reference-last-word method)
      (read-ruby-document prog method))))
  
(setq anything-c-source-ruby-method-reference
      '((name . "Ruby Mehtod")
	(candidates . ruby-all-methods)
	(action . (("RI" . (lambda (c) (my-ruby-reference c)))
		   ("Refe". (lambda (c) (my-ruby-reference c refe-program " ")))))
	))

(defun anything-ruby-method-reference () (interactive)
  (unless ruby-all-methods (get-ruby-method-reference))
  (let ((anything-sources (list anything-c-source-ruby-method-reference))
	(anything-initial-input my-ruby-reference-last-word))
    (anything)))

M-x anything-ruby-method-referenceでanything候補を選択しながらriとかが使える。
でも、rcodetoolsをインストールした方が便利だと思います><*1

*1:今回作ったようなリファレンス用の機能も入っているし、テストの補助とか補完とか他にも色々便利な機能がはいってます>rocdetools

最近やっとanythingの設定の仕方が分かってきた

他の人にもanythingを使ってほしいので、anythingの解説もしてみます><。
(特にemacsをつかったことがないひととかに使ってほしいです)

agenda

  • anythingって?
  • emacselispって?
  • anythingのインストール
  • anythingを実行する
  • anythingが見るもの(sources)
  • anything-sourcesを弄る
  • anything-c-*について

anythingって

好きなsourcesを設定して、その中でインクリメンタルサーチができるようになるelispです。
google-desktop-searchとかspotlightのようなものをemacsから使えるような感じです。
おおげさにいえば、「anythingがあなたのPCの検索エンジンに…」みたいなかんじです。

emacselispって?

elispemacsの機能を拡張するプログラムのことです。
firefoxのaddonみたいな感じです。
表にするとこんなかんじです。

用途 名前 拡張の方法 拡張子
テキストエディタ emacs elisp el, elc*1
ブラウザ firefox addon xpi

emacsは昔からあるらしいです。
でも、emacselispにより成長するので、古い時代遅れのエディタとはいえないかもしれません。
古いけど新しいというようなわけのわからないエディタです。*2
一部のユーザのemacsへの信仰は、自分のペットに対する愛情に近いものがもとになっているのかもしれません。

anythingのインストール

以下のurl*3から"anything.el"と"anything-config.el"をダウンロードしてください。

load-pathに含まれているところに二つのファイルをいれます。(新しく自分ようのディレクトリを追加するのもいいかもしれません)

補足

  • load-pathの調べ方
    • C-h*4 v load-path
    • M-x*5 describe-variable*6 load-path*7
  • 指定したディレクトリをload-pathにする方法
;例 home-directoryのboxをload-pathに追加
(add-to-list 'load-path "~/box")
;(add-to-list 'load-path "/home/<user名>/box")でもいい

load-pathに含まれているところにanything.el、anything-config.elの2つのファイルをいれたら.emacsに以下の記述を追加

(require 'anything-config)

C-x C-s で.emacsの変更を保存しましょう。
ちなみにこういう設定にしている人が多いみたいです。http://yamashita.dyndns.org/blog/anythingel/
後は、設定を有効にすればanythingが使えるようになります。

補足

  • .emacsの設定を有効にする方法にもいくつか方法があります。
    • それぞれのかっこの")"の部分でC-x C-e
    • emacsを一度終了して再起動(面倒)
    • .emacs上でM-x eval-current-buffer

anythingを実行する

M-x anything ESC + x; minibufferでanythingと入力して改行
(anything) ")"にカーソルをあててC-x C-e

ふつうは何かのkeyにanythingを割り当てて使います。(上で紹介したひとは"C-;"でした)
例)C-c C-dにbind*10

(global-set-key "\C-c\C-d" 'anything)

anythingが見るもの(sources)

anythingは呼ばれるとanything-sourcesという変数を読みます。

補足

  • 詳しい説明が読みたければ、C-h v anything-sourcesとかしてみて下さい
  • 実際に格納している値が知りたいのなら以下のように打ってからC-x C-eで実行してみてください
    • (print anything-sources #'insert)

anythingはanything-sourcesを見ているので、anything-sourcesを変更すれば別のものも検索の対象に含めることができそうです。

anything-sourcesを弄る

emacsだとsetqで変数の値を変更することができます。(上で紹介したひともsetqで変更してました)
ただ、setqで変更すると前に格納していた情報が失なわれてしまいます。
色んなものをanythingを使って検索したいときに一つのsourceしか指定できないのは不便ですね。
letを使うと変数の値を変更したかのように見せかけることができます。*11

anything-c-*について

anything-sourcesは(list anything-c-* anything-c-* ...)という形でできてます。
このanything-c-*がanythingの見るsourceです。
一番かんたんなかたちはこんな感じです。*12

'((name . "name of source")
  (candidates . '("a" "bb" "cc" "dddd"))
  (action . (("insert" . insert)))
  )
  • nameは見出しのようなものです。
  • candidatesは選択できる候補のことです
  • actionは候補を選択するときに呼び出される関数です
    • actionの中身は複数の要素をとれます
    • 選択するときにtabを押すことで呼び出す関数を変えることができます。

これと上で紹介したletをつかって他のanythingとsourcesを共有しないanythingを作ることができます.

(setq anything-c-my-sources '((name . "name of source")
			      (candidates . '("a" "bb" "cc" "dddd"))
			      (action . (("insert" . insert) ("message" . message))))
  )

;;(interactive)をつけた関数はM-xで呼べます
(defun my-anything () (interactive)
  (let ((anything-sources (list anything-c-my-sources)))
    (anything)))

M-x my-anythingで実行したあとa, bb, cc, ddddの選択肢が表示されて選択した値がカーソルの右側に出力されたはずです。
これをつかって色んな言語のリファレンスがつくれそうな感じです。
実際の記述の仕方を学ぶには、anything-c-lisp-complete-symbol.elのコードを読むのがおすすめです。

*1:byte-compileしたelファイルのことです。byte-compileすると起動が早くなります.

*2:firefoxのaddonを知ったときは、新鮮な印象を覚えたのですが、昔から似たような機能をもつプログラムは存在していたみたいです。もしかしたら、今すごいといわれているものの多くも新しい技術というわけではないのかもしれません。

*3:emacswikiにはanythingの他にもいろいろ便利なelispが存在します

*4:"C-h" はCtrlキーを押しながら"h"を押すという意味です

*5:"M-x" はESCキーを押してから"x"を押すという意味です

*6:打っている途中にtabキーで補完ができます。補完をすると、全部の単語を入力しないですむので便利です。

*7:ここでもtabで補完ができます。

*8:.emacsemacsの設定を記述するファイルです。C-x C-f で下に表示されるminibufferの内容が"Find file: ~/.emacs"となるように文字を打ってenterを押して改行すれば開けます。

*9:一番上に書くことをおすすめします。そうじゃないとファイルがみつかりませんという感じのエラーが表示されるかもしれません

*10:cdに近いので覚えやすいかも?

*11:正確な表現じゃないです><

*12:詳しいことはanything.elのファイル自体に書いてあります