(top)  (memo)  (rss)
howm の記事やメールなどが増えてきて探すのが面倒になってきたので全文検索 の導入を考えはじめました.まず Hyper Estraier がよさそうなので,評価も とりあえずなんとか検索できるような Emacs Lisp ででっちあげました.
この設定の部分でインチキ臭ささが酷いですね.なんと NTEmacs でも動かした い,かつ,ファイルの指定は find ... |grep のように指定したかったと いう個人的要望で,なんと .bat というバッチファイルを生成してシェルから 実行するという手抜きっぷりです.
M-x hyperestraier-make-index 種別を聞いてくるので、答えるとインデックスを作成する (:create で指定したコマンドラインを呼び出すだけ) M-x hyperestraier-update-index 種別を聞いてくるので、答えるとインデックスを作成する (:search で指定したコマンドラインを呼び出すだけ) M-x hyperestraier-search 種別、検索フレーズ、結果の表示方法を指定して検索する (:index で指定した場所のインデックスを検索する)
;;; HyperEstraier.el - Full Text Search Support for Emacs
;;;
;;; [設定]
;;;
;;; 1. HyperEstraier をインストールする (estcmd にパスが通っている事)
;;; 2. hyperestraier-config を設定する
;;; + :linux プラットフォーム
;;; + :howm 種別
;;; + :index インデックスのディレクトリへのパス
;;; + :create インデックス作成時のコマンド
;;; + :update インデックス更新時のコマンド
;;;
;;; [使い方]
;;;
;;; M-x hyperestraier-make-index
;;;
;;; 種別を聞いてくるので、答えるとインデックスを作成する (:create で指定したコマンドラインを呼び出すだけ)
;;;
;;; M-x hyperestraier-update-index
;;;
;;; 種別を聞いてくるので、答えるとインデックスを作成する (:search で指定したコマンドラインを呼び出すだけ)
;;;
;;; M-x hyperestraier-search
;;;
;;; 種別、検索フレーズ、結果の表示方法を指定して検索する (:index で指定した場所のインデックスを検索する)
;;;
;;; [ToDo]
;;;
;;; * 検索結果バッファ用のモードを用意する (考えてるのは↓のような簡易的なもの)
;;; p: 前の検索結果へ
;;; n: 次の検索結果へ
;;; v: 検索結果のファイルを開く
;;; * Mew との連係
;;;
(defvar hyperestraier-config nil)
(setq hyperestraier-config
'((:linux
(:howm
(:index "/home/lambda/nobackup/casket/howm")
(:create "estcmd create -attr @title seq -attr @author str -attr @cdate num /home/lambda/nobackup/casket/howm"
"find /home/lambda/howm -type f -name \"*.howm\" |estcmd gather -cl -il ja -fx .howm T@estxfilt -sd -cm /home/lambda/nobackup/casket/howm -"
"estcmd optimize /home/lambda/nobackup/casket/howm"))
(:mew
(:index "/home/lambda/nobackup/casket/mew")
(:create "estcmd create -attr @title seq -attr @author str -attr @cdate num /home/lambda/nobackup/casket/mew"
"find /home/lambda/Mail -type f -name \"[0-9][0-9]*\" |grep \"/[0-9][0-9]*$\" |grep -v draft |estcmd gather -pc CP932 -cl -il ja -fm -cm /home/lambda/nobackup/casket/mew -"
"estcmd optimize /home/lambda/nobackup/casket/mew")
(:update "find /home/lambda/Mail -type f -name \"[0-9][0-9]*\" |grep \"/[0-9][0-9]*$\" |grep -v draft |estcmd gather -cl -il ja -fm -cm /home/lambda/nobackup/casket/mew -")))
(:win32
(:howm
(:index "c:\\usr\\casket\\howm")
(:create "estcmd create -attr @title seq -attr @author str -attr @cdate num c:\\usr\\casket\\howm"
"c:\\cygwin\\bin\\find c:/home/lambda/howm -type f -name \"*.howm\" |estcmd gather -pc CP932 -cl -il ja -ic CP932 -fx .howm T@estxfilt -sd -cm c:\\usr\\casket\\howm -"
"estcmd optimize c:\\usr\\casket\\howm")
(:update "c:\\cygwin\\bin\\find c:/home/lambda/howm -type f -name \"*.howm\" |estcmd gather -pc CP932 -cl -il -ja -fx .howm T@estxfilt -sd -cm c:\\usr\\casket\\howm -")
(:optimize "estcmd optimize c:\\usr\\casket\\howm"))
(:mew
(:index "c:\\usr\\casket\\mew")
(:create "estcmd create -attr @title seq -attr @author str -attr @cdate num c:\\usr\\casket\\mew"
"c:\\cygwin\\bin\\find c:/home/lambda/Mail -type f -name \"[0-9][0-9]*\" |c:\\cygwin\\bin\\grep \"/[0-9][0-9]*$\" |c:\\cygwin\\bin\\grep -v draft |estcmd gather -pc CP932 -cl -il ja -fm -cm c:\\usr\\casket\\mew -"
"estcmd optimize c:\\usr\\casket\\mew")
(:update "c:\\cygwin\\bin\\find c:/home/lambda/Mail -type f -name \"[0-9][0-9]*\" |c:\\cygwin\\bin\\grep \"/[0-9][0-9]*$\" |c:\\cygwin\\bin\\grep -v draft |estcmd gather -pc CP932 -cl -il ja -fm -cm c:\\usr\\casket\\mew -")))))
(defvar hyperestraier-buffer-name " *Hyper Estraier Command*")
(defvar hyperestraier-serach-buffer-name "*Hyper Estraier Search*")
(defvar hyperestraier-process-name "Hyper Estraier Process")
(defvar hyperestraier-temporary-file nil)
(defun hyperestraier-search-words (index pharse &optional full-p)
(if (get-process hyperestraier-process-name)
(message "Another process is running ...")
(let ((buf (get-buffer-create hyperestraier-buffer-name)))
(set-buffer buf)
(erase-buffer)
(let ((cfg (case (hyperestraier-check-platform)
(:win32 '("CP932" shift_jis-dos))
(t '("EUC-JP" euc-jp)))))
(start-process hyperestraier-process-name buf "estcmd" "search" "-ic" (car cfg) (if full-p "-vf" "-vh") "-max" "100" index (encode-coding-string pharse 'shift_jis-dos))
(set-process-coding-system (get-process hyperestraier-process-name) 'utf-8-unix (cadr cfg)))
(set-process-sentinel (get-process hyperestraier-process-name) 'hyperestraier-search-sentinel))))
(defun hyperestraier-search-sentinel (process event)
(let ((buf (get-buffer-create hyperestraier-buffer-name)))
(switch-to-buffer buf)
(when (equal event "finished\n")
(goto-char (point-min)))))
(defun hyperestraier-check-platform ()
(let ((vstr (emacs-version)))
(cond ((string-match "nt5" vstr) :win32)
(t :linux))))
(defun hyperestraier-get-config (key)
(let ((platform (hyperestraier-check-platform)))
(assoc key (assoc platform hyperestraier-config))))
(defun hyperestraier-sentinel (process event)
(let ((buf (get-buffer-create hyperestraier-buffer-name)))
(switch-to-buffer buf)
(goto-char (point-max))
;; (insert (format "Process: %s (%s) Event: %s (%s)\n" process (type-of process) event (type-of event)))
;;; => Process: Hyper Estraier Process (process) Event: finished\n (string)
(when (and hyperestraier-temporary-file (equal event "finished\n"))
(let ((memo hyperestraier-temporary-file))
(delete-file hyperestraier-temporary-file)
(setq hyperestraier-temporary-file nil)
(insert (format "Delete Temporary File: %s\n" memo))))))
(defun hyperestraier-estcmd (prompt type)
(if (or (get-process hyperestraier-process-name) hyperestraier-temporary-file)
(message "Another process is running ...")
(let* ((buf (get-buffer-create hyperestraier-buffer-name))
(keystr (completing-read prompt (cdr (assoc (hyperestraier-check-platform) hyperestraier-config)) nil t))
(key (intern keystr))
(config (hyperestraier-get-config key))
(cmdlst (cdr (assoc type config)))
(file (concat (or (getenv "TEMP") "/tmp/") (make-temp-name "el-he-") ".bat")))
(when keystr
(setq hyperestraier-temporary-file file)
(with-temp-buffer
(when (eq (hyperestraier-check-platform) :win32)
(set-buffer-file-coding-system 'shift_jis-dos))
(dolist (cmd cmdlst)
(insert cmd)
(insert "\n"))
(write-region (point-min) (point-max) file))
(switch-to-buffer buf)
(erase-buffer)
(let ((shell (case (hyperestraier-check-platform)
(:win32
(set-buffer-file-coding-system 'utf-8-dos)
file)
(t "sh"))))
(start-process-shell-command hyperestraier-process-name hyperestraier-buffer-name shell file))
(set-process-sentinel (get-process hyperestraier-process-name) 'hyperestraier-sentinel)))))
;;; 標準 API
(defun hyperestraier-make-index ()
(interactive)
(hyperestraier-estcmd "Hyper Estraier Create Index: " :create))
(defun hyperestraier-update-index ()
(interactive)
(hyperestraier-estcmd "Hyper Estraier Update Index: " :update))
(defun hyperestraier-search ()
(interactive)
(let* ((config (cdr (assoc (hyperestraier-check-platform) hyperestraier-config)))
(keystr (if (> (length config) 0)
(completing-read "Index: " config nil t)
(symbol-name (caar config))))
(key (intern keystr))
(config (hyperestraier-get-config key))
(phrase (read-from-minibuffer "Search: " "" nil nil t nil))
(index (cadr (assoc :index config))))
(when (and (file-directory-p index) phrase)
(hyperestraier-search-words index phrase (yes-or-no-p "Full? ")))))
;;; サンプル
(defun he-howm-search (pharse)
(interactive "sSearch: ")
(let* ((config (hyperestraier-get-config :howm))
(index (cadr (assoc :index config))))
(hyperestraier-search-words index pharse nil)))
(defun he-mew-search (pharse)
(interactive "sSearch: ")
(let* ((config (hyperestraier-get-config :mew))
(index (cadr (assoc :index config))))
(hyperestraier-search-words index pharse nil)))
期待された方ごめんなさい.まだこれだけです.
しかし Hyper Estraier は速くて便利ですね.まとまった時間をとって Mew と の連携や検索画面のインターフェースなどと作りたいんですが,なかなか…. 探せばもうどっかにあるのかな?
posted: 2006/05/18 05:49 | permanent link to this entry | Tags: EMACS