est-mode.el

最近Javaを使っていて、APIの検索にHyperEstraierをうまく使いたいなぁと思っていろいろ作ってましたが、結局emacsでそれなりのものができたかなぁと思ったので公開してみます。いろいろ不具合はあると思いますので、ご意見などいただけたらそれなりに反映するかもしれません。

機能としては、

  • 複数DBから一つを選択して検索できる (M-x est-search あるいは "C-x :")
  • gatherも可能 (M-x est-gather)
  • それぞれのDBに対してsearch/gatherするときのoptionも設定可能

というあたりでしょうか。

使い方は、基本的にest-config-alistのest-config-alist の内容をsearch/gatherしたい対象にあわせて書き換える、

  • "estdb": estraierのdbを保持している場所
  • "dir" : 検索対象の文書が置かれているディレクト
  • "gatherarg" : estcmd gather 時に使われる引数 (なければdefaultの引数が使われる)
  • "searchrarg" : estcmd search 時に使われる引数 (なければdefaultの引数が使われる)

だけでいいはずです。

なお、先人たるDekさん(http://august.oor.jp/logs/boo/index.php?itemid=58)からは一部を拝借しておりまして、大変感謝しています。

;-*- Emacs-Lisp -*- 
;; est-mode.el
;;   search for the hyper estraier.
;;    Hyper Estraier
;;      http://hyperestraier.sourceforge.net/index.ja.html
;;   
;;   Thanks to Dek-san
;;      http://august.oor.jp/logs/boo/index.php?itemid=58 
;; 
;;   License: New BSD Licence (except Dek-san part)

;;;; config part
;; Please add or change as you like.
(setq est-config-alist
      '(
;;	("example"
;;	 ("estdb"     . "/Full/path/to/estdb/casket")
;;	 ("dir"       . "/Full/path/to/target/gether/documents")
;;	 ("gatherarg" . "-il ja -ft -cl")    ;; optional
;;	 ("searcharg" . "-sf -vh -ic UTF-8") ;; optional
;;	 )
;;
        ("rubydoc"
	 ("estdb"  . "~/Docs/estdbs/rubydoc")
	 ("dir"    . "~/Docs/ruby-man-ja-html-20051029")
	 )
;;
        ("javadoc"
	 ("estdb"  . "~/Docs/estdbs/javadoc")
	 ("dir"    . "~/Docs/jdk-6-doc")
	 )
;;
        ("phpdoc"
	 ("estdb"  . "~/Docs/estdbs/phpdoc")
	 ("dir"    . "~/Docs/phpdoc")
	 )
;;
        ("mail"
	 ("estdb"  . "~/Mail/casket")
	 ("dir"    . "~/Mail")
         ("gatherarg" . "-il ja -fm -cl -xl -sd")
         ("searcharg" . "-sf -vh -ic UTF-8 -ord \"@cdate NUMD\" ")
	 )
;;
	("howm"
	 ("estdb"     . "~/Works/estdbs/estHowm")
	 ("dir"       . "~/howm")
	 ("gatherarg" . "-il ja -ft -cl")
	 )
;;
))

;; default est-search key is "C-x :"
(define-key ctl-x-map ":" 'est-search)

(setq est-estcmd-path "/usr/bin/env estcmd")
(setq est-gather-default-arg "-il ja -fh -cl")
(setq est-search-default-arg "-sf -vh -ic UTF-8")

(setq est-search-show-locale 'utf-8)


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

(setq est-result-buffer "*estresult*")
(setq est-config-hist (mapcar (function car) est-config-alist))

(require 'w3m) ;; We can not do w3m-find-file until the w3m is loaded.

(defun est-search ()
  "*search hyperestraier"
  (interactive)
  (est-minibuf-key-map)

  (setq confname (est-get-confname))

  ;; getting search argment
  (setq est-arg (est-get-config-value confname '"searcharg"))
  (unless est-arg
    (setq est-arg est-search-default-arg)
    )

  (setq phrase (read-string "phrase?: "))

  ;; asynchronous start process using the shell
  ;;;; the charactor will be changed if coding-system is not set.
  (let ((coding-system-for-read est-search-show-locale))
    (let ((coding-system-for-write est-search-show-locale))
      (start-process-shell-command 
       "est-search" est-result-buffer
       (format "%s %s %s %s %s" 
	       est-estcmd-path  "search" 
	       est-arg (est-get-config-value confname '"estdb")
	       phrase)
       )))

  (switch-to-buffer est-result-buffer)
  (est-mode)
  (toggle-read-only)
  (beginning-of-buffer)
)

(defun est-gather ()
  "*gather from dir"
  (interactive)
  (est-minibuf-key-map)

  (setq confname (est-get-confname))

  ;; getting gather argment
  (setq est-arg (est-get-config-value confname '"gatherarg"))
  (unless est-arg
    (setq est-arg est-gather-default-arg)
    )

  ;; asynchronous start process using the shell
  (start-process-shell-command 
   "est-gather" est-result-buffer
   (format "%s %s %s %s %s" 
	   est-estcmd-path "gather" 
	   est-arg
	   (est-get-config-value confname '"estdb")
	   (est-get-config-value confname '"dir")))
  
  (message (format "starting estcmd gather at %s" est-result-buffer))
;;  (switch-to-buffer est-result-buffer)
)

;;;;;;
;; sub-functions

(defun est-get-config-value (confname key)
  (cdr (assoc key (cdr (assoc confname est-config-alist))))
)

(defun est-get-confname ()
  (let (conf) 
    (completing-read (format 
		      "estdb (default \"%s\"): "
		      (car est-config-hist))
		     (mapcar (function car) est-config-alist)
		     nil t nil
		     'est-config-hist
		     )

    (if (eq (length conf) 0) ;; set last confname if empty string
	(car est-config-hist)
      (conf))
  )
)

(defun est-minibuf-key-map ()
  "Add history related keybindings."

  ;; for estdb input
  (define-key minibuffer-local-completion-map "\C-n" 
    'next-history-element)
  (define-key minibuffer-local-completion-map "\C-p" 
    'previous-history-element)
  (define-key minibuffer-local-completion-map "\C-r" 
    'next-matching-history-element)
  (define-key minibuffer-local-completion-map "\C-s" 
    'previous-matching-history-element)

  ;; for phrase input. it does not need completion.
  (define-key minibuffer-local-map "\C-n" 
    'next-history-element)
  (define-key minibuffer-local-map "\C-p" 
    'previous-history-element)
  (define-key minibuffer-local-map "\C-r" 
    'next-matching-history-element)
  (define-key minibuffer-local-map "\C-s" 
    'previous-matching-history-element)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Dek-san part
;; Thanks to Dek-san
;;    http://august.oor.jp/logs/boo/index.php?itemid=58 

(defun est-mode ()
  "Major mode for Hyper Estraier Mode"
  (interactive)
  (setq major-mode 'est-mode
	mode-name "est")
  (setq est-local-map (make-keymap))
  (define-key est-local-map "n" 'est-next-url)
  (define-key est-local-map "p" 'est-prev-url)
  (define-key est-local-map "q" 'est-mode-quit)
  (define-key est-local-map "\r" 'est-open-html)
  (use-local-map est-local-map)
)

(defun est-next-url ()
  (interactive)
  (next-line)
  (re-search-forward "^URI:\sfile://")
  (recenter 0))

(defun est-prev-url ()
  (interactive)
  (previous-line)
  (re-search-backward "^URI:\sfile://")
  (recenter 0))

(defun est-mode-quit ()
  (interactive)
  (kill-buffer est-result-buffer))

(defun est-open-html ()
  (interactive)
  (beginning-of-line)
  (re-search-forward "^URI:\sfile://")
  (w3m-find-file
   (buffer-substring (point) (progn (end-of-line) (point)))))