Top / すべてのバッファにoccur / grepを―color-moccur
https://bookshelf.jp/cgi-bin/goto.cgi?file=meadow&node=all%20buffer%20occur 要望やコメント、感想などがあればこのコメントにどうぞ. 最新の10件を表示しています。 コメントページを参照 目次
実装中ここの下に書いてあるのが,現在取り組んでいるものです.取り組んではいないけど,考えているものはアイデアメモのところにあります. dmoccurの改良により、ますますバッファが氾濫するようになってしまったのも何とかしたい。1ディレクトリあたりのファイルを制限するとかかな。 長い行を短く表示検索に一致した行が長いと少しみにくくなってしまいます.そこで,適当に短く表示する 機能を実装中. 現状はとりあえず作ってみましたというレベル.もっと表示すべき範囲とかをきちんと考 える必要がある. grepもどき環境によってはgrepやfindをインストールすることが面倒だったり、困難だったりすることがあります。これだけのために、Cygwinをインストールするのも面倒だしね。というわけで、color-moccurがあれば、そういった外部コマンドなんてなくてもgrepやgrep-findを行うことができます。 M-x moccur-grep と M-x moccur-grep-find を実装.その名の通り,ファイル を検索するための関数です.grep(-find) を Cygwin なしでも実行できます. moccur の検索関数を利用していますので,migemoによる検索も可能ですし, moccur-split-word や moccur-search-keyword-alist による検索も可能になってます. 検索部分は grep よりも柔軟にカスタマイズできます. Directory: d:/home/ で検索するディレクトリを指定し, Input Regexp and FileMask: で検索語とファイルマスクを正規表現で入力します.全ファイルを対象に 「meadow」という語で検索したければ. Input Regexp and FileMask: meadow . とします.一番最後の正規表現をファイルマスクと認識するので, Input Regexp and FileMask: meadow \.el$ とすれば,拡張子が el のファイルのみを検索できます.moccur のようなファ イルの内容表示はしていません. ただし,検索はgrepよりも遅いです.検索中に C-g で中断すれば,その時点 までの結果を出力してくれます. namazu + moccur-grepnamazuで検索するファイルを一覧させて,その後でgrepを行う方法. (defun namazu-grep (&optional page-num namazu-dir key) "namazu + moccur-grep" (interactive (list 0 (if (or (and (not namazu-always-query-index-directory) current-prefix-arg) (and namazu-always-query-index-directory (not current-prefix-arg))) (read-from-minibuffer "Namazu index directory: " nil namazu-minibuffer-map nil 'namazu-index-history) nil) (read-from-minibuffer "Enter Keyword: " nil namazu-minibuffer-field-map nil 'namazu-keyword-history))) (let* ((namazu-filename-list nil) (dir (or namazu-dir (progn (or namazu-default-dir (setq namazu-default-dir (namazu-get-default-index-dir))) (expand-file-name namazu-default-dir)))) (arg-list (list "-all" key))) (if (and dir (not (string= dir "")) (string-match "[^ \t]" dir)) (setq arg-list (append arg-list (namazu-split-dir (namazu-expand-dir-alias dir))))) (message "Namazu running ...") (let ((default-process-coding-system (cons namazu-cs-read namazu-cs-write)) (process-input-coding-system namazu-cs-read) (process-output-coding-system namazu-cs-write) (coding-system-for-read namazu-cs-read) (coding-system-for-write namazu-cs-write)) (with-temp-buffer (apply (function call-process) namazu-command nil t nil arg-list) (goto-char (point-min)) (setq namazu-filename-list (split-string (buffer-substring-no-properties (point-min) (point-max)) "\n")))) (message "done!") (setq namazu-filename-list (mapcar '(lambda (file) (if (string-match "^/\\([a-zA-Z]\\)|/\\(.+\\)$" file) (concat (match-string 1 file) ":/" (match-string 2 file)) file)) namazu-filename-list)) (if (> (length namazu-filename-list) namazu-search-num) (setq namazu-filename-list (reverse (nthcdr (- (length namazu-filename-list) namazu-search-num) (reverse namazu-filename-list))))) (moccur-setup) (setq moccur-last-command 'mgrep-namazu) (let ((moccur-split-word t) (regexp key)) (while (string-match " " regexp nil) (setq regexp (replace-match "\\\\|" nil nil regexp))) (moccur-search-files regexp nil namazu-filename-list) )))
利用の手引きとメモmoccur 利用の手引きmoccur の検索は moccur-search で行っています.これは,正規表現とバッファのリスト を必要とします.それさえ与えてやれば,自分の好きな時に,moccurを行うことができま す. moccur-search がするのは,正規表現を適当な形(migemoを利用する,スペースで分ける) にして,検索をします. サンプル(occur と同等のことをするもの) (defun my-occur (regexp arg) ;; moccur-regexp-read-from-minibuf は moccur で使っている ;; 文字を受け取る関数 (interactive (list (moccur-regexp-read-from-minibuf) current-prefix-arg)) ;; おまじない (moccur-setup) (let ((buffers (list (current-buffer)))) (moccur-search regexp t buffers) ;; 引数は正規表現 全バッファ バッファのリスト ;; 全バッファとは全バッファを検索するかどうかです ;; nil ならファイルバッファのみになります )) navi2chでmoccurスレッド一覧で*によりマークをつけて,m o でマークをつけたスレを一括検索.ただし,検索の度にスレの表示を行うので多少待つ必要がある. (defun navi2ch-bm-display-mark-moccur (regexp arg) (interactive (list (moccur-regexp-read-from-minibuf) current-prefix-arg)) (let ((navi2ch-article-max-buffers 10000) (buffers nil) (navi2ch-offline t)) (setq buffers (navi2ch-article-buffer-list)) (while buffers (if (buffer-live-p (car buffers)) (kill-buffer (car buffers))) (setq buffers (cdr buffers))) (navi2ch-bm-exec-subr 'navi2ch-bm-display-article) (setq buffers (navi2ch-article-buffer-list)) (moccur-setup) (moccur-search regexp t buffers) )) (add-hook 'navi2ch-article-load-hook (lambda () (define-key navi2ch-bm-mode-map "mo" 'navi2ch-bm-display-mark-moccur))) moccur を実行する時人によって多用するものは違いますが,今のところ主なものは以下の通りです. 私は dmoccur を多用してます(なので,これが一番テストをされてます).
アイデアメモハイライトの永続化現状はバッファを編集したりするとハイライトは消える。しかし、残しておきたい時もある。moccur バッファで明示的に q で終了しない限り色が消えないようにできると便利かも。 で、消すかどうかは適当な変数で設定できる。 moccurでのバッファの絞り込みdmoccurを連続した後などに、moccurをすると悲惨なことに。 moccurでもバッファのモードや拡張子などを元に検索するバッファを自動的に絞り込める設定が欲しい。もちろん、デフォルトではオフにしておくと。 eeでのUndoの不具合/ で undo.ただし,eeの画面で / を行うと,常に全作業が消え,最初の状態に戻ってしまう. 複数行検索定型的な書式を検索したいことがある。その場合、 @node isearch @section .+ @comm{.+} といった風に指定して検索したい。 曖昧検索simpleでsampleもsimploのようなスペルミスも検索したい。 levenshtein-distance.elを使えばできる。 ただし、その場合migemoを利用することはできない。 しかも使ってみると、、、遅い。うぅむ、これは常用するにはつらいなぁ。 not 検索ある単語を含まない行の検索。 バッファの選択検索に一致したバッファをリストにし,補完入力でさくっと切り替えられたら便利だ な. マウス対応右クリックで何かを.とか.だらだら使うにはいいかも 結果の表示アルファベット順でいいのか. スコアリングのようなことをして,当ってそうなファイルを上にできないか. バッファの関連大体同じディレクトリにあるバッファは関連性が大きい. 拡張子が同じでも関連性は大きいだろう.結果の順番も考えると面白いかも. 正規表現と単語(一部実装済み)r:で正規表現を指定するのは面倒.正規表現と単語を自動認識できないか. 単純には(regexp-quote "oo")== oo なんだよな.
後は,「hyou」で検索して,「正規表現」でも「表の作成」でもひっかかるのはあまり意味がない.isearchならいいけど,この場合,「表の作成」だけでもいいような... 後は,改行を含んでも検索して欲しい(これはまだ) dired と dmoccurdired で検索したら,dired-d:/home/memo/ という形で dmoccur に追加する. 複数のバッファの扱い (一部実装済)dmoccurは便利なんだが,多用するとバッファが氾濫する.
などが欲しい.
occur 関連私は完全にcolor-moccurをoccurとして,moccurとして使ってますが,世の中には同じような機能を持つ関数がいくつか存在します. 標準のoccurCVS先端では複数バッファのoccurにも対応.ただし,検索したいバッファをすべて選択しないといけない. joccuroccur の改良版.といっても使い勝手はそれほど変わらず.複数バッファも検索できるけど,やっぱり1個1個選択. 実装済みのもの上のものほど最近実装したものになってます. いい加減な undomoccurを何度か繰り返すと、前の状態に戻りたいということがありますよね。 これを実現する機能を実装してみました(ちと、手抜きですが) moccurバッファで u で前回の設定で検索を行います。 ただし、moccur-grep(-find)やdmoccurのたぐいはundo対象にはなりません。ファイルを開き直すのは手間だし。。。 コメントだけを検索(実装済み)Cなどではコメントを/* と */ で囲って表します.このコメントだけを検索しようと しても,その行にはコメントを表す文字がないので検索できません. そこで,「;; コメント」 のようにユーザが適当な文字を設定する.指定するのは, 文字とモード,判断する関数. そして,検索語の1単語目がその文字であれば,判断する関数にしたがって一致箇所 が条件に合うかどうかを確認する. 例えば,コメントならコメントのフェイスになっているかとか,書式があるのであれ ば前後に決まった文字があるかとかを判断させたい. ただ,モード毎に判断基準が異なってくるので,設定は複雑になりそう.需要はあま り無さそうだな. 個人的には欲しい. dmoccurで特定のファイルを除外 (実装済み)dmoccurは強力だが,除外したいファイルがあることもしばしば. 現状でも開くファイルを指定する正規表現を駆使すればいいかもしれないが,それは 面倒. そこで,除外するファイルの正規表現も個別に指定したい. ただ,問題が,,,これまでの設定との兼ね合いが取れなくなってしまうし,さらに 設定が面倒になってしまう... ディレクトリを再帰的に検索つっこみより
これに加えて,複数ディレクトリを指定できる設定も欲しい. (setq dmoccur-list '( ;;name directory mask option ("memo" (("~/memo/" t) ("~/2002/" nil)) ("\\.txt" "\\.memo$") nil) )) みたいな指定がしたい.で,ディレクトリの後にあるものがtなら,再帰的に検索する. となると,オプションが dir の場合,複数のディレクトリは指定できないんだから,それはエラーにする必要があると. CVSなど検索して欲しくないディレクトリはどうやって指定する?とりあえず,適当な変数で指定するようにするか.設定ごとに指定しようとすると, ("memo" (("~/memo/" t ("CVS" "secret") ("~/2002/" nil)) ("\\.txt" "\\.memo$") nil) となるのか. しかし,どんどん分かりにくくなっていくなぁと思いながら、この方針でひそかにいじってました。それなりに動いているみたいだし,丁度いいので公開します. #ref(): File not found: "color-moccur.el" at page "すべてのバッファにoccur/grepを―color-moccur"
(setq moccur-buffer-sort-method 'moccur-buffer-string<) としてください。 ディレクトリの指定方法設定は今までのままで使えます.そのままであれば動作は変わらないはずです. (setq dmoccur-recursive-search t) としておくと,どのお気に入りでも再帰的に検索するようになります.ただ,これでは時間がかかるだけであまりうれしくないので,お気に入りごとに指定した方が便利です. 以下が設定サンプル. (setq dmoccur-list '( ;; 従来の設定方法はそのまま使うことができる ("dir" default-directory (".*") dir) ;; 再帰的に検索する場合は、このように設定する ;; オプションがdirやsubなら1個しか指定できない ("dir-recursive" ((default-directory t)) (".*") dir nil "set") ("dir-test" (("~/test/" t)) (".*") nil nil "defun") ;; オプションが nil なら、何個でもディレクトリを指定できる ("test" (("~/test/test" t ("あああ" "sax/color")) ("~/mylisp/plisp/" t ("multi"))) (".*") nil) )) まず ("dir-recursive" ((default-directory t)) (".*") dir nil "set") ("dir-recursive" (("~/test" t)) (".*") dir nil "set") のようにすると,指定したディレクトリ以下を再帰的に検索できるようになります.このtをnilにすると,今までと同じで再帰的に検索しません. さらに ("test" (("~/test/test" t ("あああ" "sax/color")) ("~/mylisp/plisp/" t ("multi"))) (".*") nil) とすることで,複数のディレクトリを指定することもできます.指定項目は ディレクトリ 再帰検索するか(tならする) 検索しないファイルのリスト になっています.3番目はオプションなので無くても構いません.ただし、ディレクトリの中にファイルやディレクトリが多いようであれば,指定して絞った方が無難です.調子の乗って適当に追加していくと、大量のファイルが開かれてしまい、激重になります。 ただし,オプションに「dir」を指定している場合には,複数のディレクトリを指定するとエラーになるので注意. 1.51 版ここにあるのはテスト版です.かなり不安定なので,注意して使ってください.要望があれば,テスト版の中に書き込んでください.要望があれば,優先順位は上がります. ま,私のスキルでは実現できるかどうかはわかりませんけど. 変更点
これにより,従来のものに加え,以下のような設定も可能になります. (setq dmoccur-list '( ;;name directory mask option ("mlisp" default-directory ("\\.el$") dir (nil nil) "^;;; [^\\n]+ ---") ("test" default-directory (".*") dir nil "set") ("migemo" default-directory (".*") dir (t nil)) ("node" "~/www/soft/" ("\\.texi$") nil (nil nil) "\\(@cha\\|@sec\\)") ("old-node" "~/www/soft/" ("\\.texi$") nil (nil nil) meadowmemo-search-old-node-name) )) 5番目がmigemoなどを制御する部分.nilならデフォルトを使用. (t nil) とすると,そのお気に入りに限っては (setq moccur-use-migemo t) (setq moccur-split-word nil) と設定したのと同じことになる.これにより,あるディレクトリはmigemoを使わずに,常に正規表現で検索ということができる. 6番目はデフォルトの検索語.無くても構わないし,関数でもいい.ただし,検索語を返す関数である必要がある. これにより,古い日付けを検索するなど,動的な検索が可能になります. dmoccur-list の仕様以下の仕様は変えた方がいいかな. 何らかの方法で記録はしないと clean-dmoccur-buffers が動かなくなるんだが,それはあきらめた方がいいのかな.
初回
二回目以降
dmoccur-list 設定例こんな風にミニバッファから取るようなこともできる。 マスクも取ろうと思えば取れるんだなぁ,というサンプル.入力は何回かしないといけないので,かなりうっとうしい. デフォルトの入力があれば,再編集をなしにできるような設定が欲しい? (defun my-dmoccur-word () (message "d)ate w)ord m)ask") (let ((c (char-to-string (read-char))) (co)) (cond ((string-match "d" c) (format-time-string "%Y/%m/%d")) ((string-match "w" c) (read-from-minibuffer "Input word: ")) ((string-match "m" c) (setq dmoccur-mask-internal (cons (read-from-minibuffer "Input file-mask: ") nil)) (read-from-minibuffer "Input word: ")) (t (message "Illegal char") (sleep-for 1) ;; 再入力をうながす (my-dmoccur-word))))) (setq dmoccur-list '( ("test" default-directory (".*") dir nil my-dmoccur-word) )) 更新履歴
スペースを含む正規表現 (実装済み)平成15年11月10日(月)に実装済み 正しくない正規表現は (condition-case err (string-match "[-" "test") (error (message "invalid regexp"))) といった風に検索関数に渡すと,エラーになる.よって,それが正しいかどうかの判 断になる. 今はmoccur-split-wordがtなら何も考えずにスペースで分けているが,その前に正し いかどうかを判断し,正しくなければそこでは分けないという処理を追加する. これで,スペースを含むような正規表現でも検索できるのではないか デフォルトの検索語 (実装済み)moccurのデフォルトの検索語は
という順番で探している。しかし、たまたま数行がリージョンになっていると、大量に取り込まれてしまう。これは、50文字(日本語で25文字)ぐらいまでに制限したい。 50文字より長いとリージョン内に文字があっても無視されます. 検索結果で行/ファイルを削除(実装済)Lines matching setq Buffer: .abbrev.el とあって, 5 (setq save-abbrevs t) にカーソルがある時に,d とすると,その行を削除できる.カーソルが Buffer: の部分にある時に,d でこのバッファの結果全体を削除できる. M-d で,「カーソルを Buffer: の部分に移動し,d を押す」のと同じことができる.つまり,現在カーソルがある場所のバッファ(この例なら.abbrev.el)の結果を削除できる. ただし,これを実行すると,色は消える.これは,何度も色をつけ直していると遅いため. delete-region とか keep-lines / flush-lines も欲しいな. 結果画面で flush-lines/kepp-lines(実装済み)ができると便利かな. あとは余分なファイル項目の削除機能とか. 一行に複数の言葉がある行を検索できるようにしたい (実装済)(defun isearch-forward (&optional regexp-p no-recursive-edit) なら,「isearch regexp」で一致して欲しい 2003/06/11 実装してみた. (setq moccur-split-word t) で利用できる. 正規表現で検索したい (実装済)migemoを使っていると正規表現での検索はできない.しかし,正規表現での検索をしたい時がたまにある. 「r:正規表現」で正規表現を検索するようにはできる. しかし,上の設定があると,スペースを含む正規表現が切られてしまう.うぅむ...
ee と使いたい (実装済)これができれば、たくさんのバッファが一致しても見通しがよくなる。 手元では動いているみたい。。。 ということで,添付してみました. 設定を追加しなければ,eeを使いませんので,今までのものとほとんど変わりません. 1点だけ変わるのは,バッファの並び順です.これまでは,バッファリストそのままの並び順だったのですが,バッファ名で並び換えるようにしました. eeと一緒に使う場合は, (setq moccur-use-ee t) と設定しておきます.これで,結果画面が ee で表示されます.もちろんeeは必要です. 例えば,こんな風な画面 + Buffer: admini.texi 基本的な操作は同じで,以下が追加されています.
また,添付のmoccur-edit.elを使うと,今までと同じようにバッファの編集もできます.設定はそのままで,変更しなくても大丈夫です. おかしいところがあれば,コメントをよろしくお願いします デフォルトの扱い (実装済)
dmoccurのお気に入り (実装済)
(defun meadowmemo-search-old-node () (interactive) (let ((str) (day) buffers) (setq day (meadowmemo-old-day) ) (setq day (concat "\\(@subsection\\|@subsubsection\\|@section\\) .+ @emph{(" (meadowmemo-old-day) ;; 古いノードの日付けを作る関数 ")}$" )) (moccur-setup) (setq moccur-regexp-input day) (setq dmoccur-mask-internal '("\\.texi$")) (setq buffers (moccur-add-directory-to-search-list "~/www/soft/")) ;; sort ;;(setq buffers (sort buffers 'moccur-buffer-string<)) (let ((moccur-use-migemo nil) (moccur-split-word nil)) (moccur-search day t buffers) )))
(setq dmoccur-list '( ;;name directory mask option ("doc" "d:/home/soft/" (".texi") nil (nil nil) 'my-regexp-function) ("soft" "d:/home/elisp/" (".el") nil (nil nil) "^\\(defun\\|defc\\)") )) といったオプションを使えるといいのではないか.(nil nil)は (moccur-use-migemo nil) (moccur-split-word nil)ということ.最後のオプションは検索語あるいは検索語を作る関数. で,これで,dmoccurをすると,名前を指定するだけで,検索ができる.検索で定型化できるものはかなり便利になりそう.
dmoccur で余分なバッファをkill (実装済)dmoccurで新規に開いたファイルで編集中でないものを一括でkillしたい. 一致したバッファを削除するを使えば一応できるが,関係ないのが入ってないか確認するのが面倒.
お気に入りのディレクトリ (実装済)
あたりを何とかしたいなぁということで適当にいじってみた。 dmoccurを利用時に、dirオプション付きのものでディレクトリを辿ると、次回dmoccur使用時に dir-d:/home/memo が追加される。毎回辿らなくてもすむ。(これは dmoccur-use-project を t にしておけばいいかもしれんが) ただし,バッファをバッファリストなどで削除すると,そのバッファは開き直さないので注意.そのため,全部バッファを消してしまうと,常に一致は0になります.開き直した方がいいかなぁ. あとは、M-x clean-dmoccur-buffers でお気に入りを指定すると、そのバッファをすべて kill してくれます。 ただし、バグに注意。
XEmacs 対応 (実装済)
で動かなかった。 修正したつもり。 (emacs-version) "XEmacs 21.4 (patch 6) \"Common Lisp\" [Lucid] (i386-debian-linux, Mule) で確認。 質問分からないことなどは,どんどん書き込んでください 2個所にあるファイルマスクの設定の関係が分からない(setq dmoccur-mask '("\\.c$")) (setq dmoccur-list '(("dir" default-directory (".*") nil))) と、設定しているのに *.o まで検索されることがありました。 dmoccur-mask はグローバルな設定で、dmoccur-list はローカルな設定と 認識していたのですが、実際は dmoccur-list のファイルマスク設定によって dmoccur-mask は上書きされるのでしょうか?
お気に入り設定のディレクトリ指定について(setq dmoccur-list '(("memo" "~/memo/" ("\\.txt$") nil))) と、設定しました。そして C-u M-x dmoccur で実行して memo を選択すると、 設定通りに ~/memo が対象ディレクトリになりました。 そこで、オプションだけを dir に変えて (setq dmoccur-list '(("memo" "~/memo/" ("\\.txt$") dir)) とすると、~/memo をデフォルトの対象ディレクトリとして 入力待ちになると認識していました。 しかし、対象ディレクトリは ~/memo ではなく カレントディレクトリになりました。 つまり、オプション dir を指定している場合のデフォルト対象ディレクトリは "~/memo/" の部分が使われず、カレントディレクトリになる ということでしょうか?
要望~/memo/ と ~/memo の扱いを同じにして欲しいカレントディレクトリが ~/memo のときに M-x dmoccur で起動すると Directory: ~/memo/ と表示されて入力待ちになります。 そこでそのまま ~/memo 以下を検索したいので RET します。 すると予想に反してディレクトリがないという警告とともに再入力になってしまいます。 Emacsの標準的仕様だけを見てもディレクトリの最後の / の有無には寛容です。 ですので ~/memo/ のときでも ~/memo と同様の扱いにしていただけると助かります。
|