[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
49.1.1 インクリメンタルサーチとは何か (2004/01/24) 49.1.2 正規表現によるインクリメンタルサーチ (2003/06/14) 49.1.3 非インクリメンタルサーチ (2003/06/14)
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
インクリメンタルサーチは, 現在のバッファ内から文字を検索する機能です. ただし, 普 通の検索とは異なり, 1 文字入力するとすぐに検索を開始し,最初に見つかった場所へカー ソルが移動します.さらに,もう一文字入力すると,またカーソルが移動します.
このようにリアルタイムで検索と入力を行うことができる検索をインクリメンタルサーチ といいます.
このインクリメンタルサーチには,下方向への検索と上方向への検索があり,それぞれ C-s,C-rで実行できます.
例えば C-s Eと入力すると, E という文字列を検索し, カーソルを最初に見つかっ た E の後に移動します. 続けて, m と入力すると最初に見つかった Em の後にカー ソルが移動します.
単語が見つかった時, 続けて C-sを入力すると, 次に見つかった文字へ移動できま す. 単語が見つからなければ, ミニバッファに Falling I-Search と表示されます. さら にC-sと入力すると, バッファの最初から検索します. C-r C-rでも同じです.
そして,途中で,単語を追加することもできます.そのためには,検索途中で,そのまま 文字を入力するだけです.そうすると,文字を追加して検索を続けることができます.
一つ前の状態へ戻りたい時には,BSを入力します.すると,一つ前の状態へ戻るこ とができます.つまり,何個か検索に一致したものがあれば,その場所へ順番に戻ること ができます.一致した箇所がなければ,検索語を 1 文字ずつ消すことができます.
このキー割り当ては
(define-key ekb-isearch-mode-map "\C-b" 'isearch-delete-char)
|
のようにすると,適当なキーに割り当てることができます.
そして,検索後,今度はC-s C-sと入力すると, 最後に検索した言葉で再度検索す ることができます. 検索をやめる時には RETを入力します. C-gでもやめる ことはできますが, カーソルが検索をはじめた位置へ戻ってしまいます.
改行を検索する時には C-j を用います. C-s C-jと入力すると改行を検索で きます. 改ページなどの制御文字を検索する時には C-s C-q C-l(^L を検索) のよ うに C-qを使用します.
\223 のようなコードも C-q 223 RETで入力できます.
This buffer is for notes you don't want to save, and for Lisp evaluation. If you want to create a file, visit that file with C-x C-f, then enter the text in that file's own buffer. |
今, 上のようなテキストがあり, カーソルは一番最初の T にあるとします. ここで, C-s bを入力すると, カーソルは最初の b へ移動します. ここで, C-wを入 力すると, 検索する文字は現在カーソルがあるところの文字列, つまり buffer になりま す. C-yを入力すると, 検索する文字は現在カーソルがあるところから改行までの 文字列, つまり buffer is for notes you don't want to save, and for Lisp evaluation. になります. 単語で検索する時にいちいち全部入力する必要はないわけです.
このインクリメンタルサーチでは日本語が使えません.一応,以下のように設定すると, 検索時に C-kを入力することで, IME による日本語入力や貼り付けも可能になりま す. ただし,インクリメンタルサーチではなく,通常の検索になります.
(define-key isearch-mode-map "\C-k" 'isearch-edit-string)
|
他には, isearch でM-nや,M-p(ヒストリを辿る) ,M-r(正規表現での 検索へ切り替える) ,M-y(貼り付け) が便利です.
最新の Meadow では isearch をすると,一致項目がすべてハイライトされます.しかし,古 い Meadow ではハイライトされません.その場合には, http://www.fan.gr.jp/~ring/Meadow/elisp/ishl.el.ishl.elをダウンロードし, ロードパスの通ったところへ置きます.
そして,以下を.emacs に追加します.
;;; isearch highlight (require 'ishl) (setq ishl-initial-delay 0.5) (setq ishl-delay 0.1) (add-hook 'isearch-mode-hook (function (lambda () (ishl-mode 1)))) |
これでは, migemo の一致項目はハイライトされないので, migemo を利用する時には以下も 追加します. しかしこれは普通のインクリメンタルサーチはハイライトしてくれるものの、 migemo による検索はハイライトしてくれません (日本語にハイライトしない?) 。それは嫌なので、無理矢理できるようにしてみました。.emacs に次のコードを追加しましょう*1 。
;; http://megadriver.ns.tc/~fumi/emacsce/cecmigemo/?date=19920101 ;; lazy に migemo の highlight をする (defadvice ishl-search (around migemo-lazy-highlight-search-ad activate) "adviced by migemo." (when migemo-isearch-enable-p (setq migemo-do-isearch t)) (unwind-protect ad-do-it (setq migemo-do-isearch nil))) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
C-u C-s(あるいはC-u C-r) と入力することにより, 正規表現による検索が 可能です.C-u C-s C-sとすると直前に行った条件で再度検索できます.
正規表現を使うことができる以外は,通常のインクリメンタルサーチと同じです.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
C-s RETと入力することで, 非インクリメンタルサーチができます. インクリメン タルサーチではありませんので, 当然すべての文字列を入力する必要があります. 日本語 も使えます.
この時, C-s RET C-w(あるいは C-r RET C-w) と入力すると単語の検索にな ります. 例えば word を検索すると, words は検索されず word のみを検索できます.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
49.2.1 インクリメンタル grep 検索 (2005/11/16)
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
isearchを実行した時に,その語に一致する行を別ウィンドウに表示してくれます.文字 入力の度に更新されるので,どこが一致しているのかがすぐに分かります.
Petit emacs lisp tips
インクリメンタルサーチはとても便利な機能です.しかし,これだけでは,他にどのよう な候補があるかを見ることができません.
上のように,インクリメンタルサーチを実行するだけで,該当箇所を一覧することができ ます.
設定していませんので,設定が必要になります.
以下を.emacsに追加します.最新の設定は Petit emacs lisp tips を確認ください.
(defvar my-igrep-buffer "*Incremental Grep*") ;; grep 結果を表示する window の名前 (defvar my-igrep-window-height 10) ;; grep 結果を表示する window の高さ (defvar my-igrep-window-offset 3) ;; grep 結果中の、現在行の表示位置 (defvar my-igrep-with-color t) ;; マッチした文字列に色をつけて表示 (defvar my-igrep-mark-str "=>") ;; mark (defvar my-igrep-min-length 3) ;; grep する最短文字数 (defvar my-igrep-delay 0) ;; grep し始めるまでの delay (defvar my-igrep-light-mode nil) ;; migemo (日本語検索)を grep に使うか (defvar my-igrep-enable-p t) ;; igrep オン・オフのの初期設定 (defface my-igface '((t (:background "paleturquoise"))) nil) ;; 色 (defvar my-igrep-match 0) (defvar my-igrep-overlay nil) (defvar my-igrep-window-configuration nil) (defadvice isearch-mode (before my-igrep activate) (when my-igrep-enable-p (get-buffer-create my-igrep-buffer) (with-current-buffer my-igrep-buffer (make-local-variable 'window-min-height) (setq window-min-height 2 truncate-lines t)))) ; *1 (add-hook 'isearch-mode-end-hook (lambda () (my-igrep-window-cleanup) (when my-igrep-enable-p (kill-buffer my-igrep-buffer)))) (defadvice isearch-update (after my-igrep activate) (if (and my-igrep-enable-p (>= (length isearch-string) my-igrep-min-length)) (my-igrep-display) (my-igrep-window-cleanup))) (defun my-igrep-toggle-grep-enable () (interactive) (message (if (setq my-igrep-enable-p (not my-igrep-enable-p)) "t" "nil"))) (defun my-igrep-search (&optional end) (if (and my-igrep-light-mode (featurep 'migemo) migemo-isearch-enable-p) (re-search-forward (migemo-get-pattern isearch-string) end t) (search-forward isearch-string end t))) (defun my-igrep-colorize (str beg end pos) (put-text-property (- (match-beginning 0) beg) pos 'face 'my-igface str) (if (my-igrep-search end) (my-igrep-colorize str beg end (- (point) beg)) str)) (defun my-igrep-window-setup () ;; 検索 window の setup (set-window-buffer (cond ((>= (- (window-height) my-igrep-window-height) window-min-height) (setq my-igrep-window-configuration (current-window-configuration)) (split-window (selected-window) ; 分割可能な window なら分割して表示 (- (window-height) (1+ my-igrep-window-height)))) (t (next-window))) (get-buffer my-igrep-buffer))) (defun my-igrep-window-cleanup () ;; 検索 window の cleanup (when (window-configuration-p my-igrep-window-configuration) (set-window-configuration my-igrep-window-configuration) (setq my-igrep-window-configuration nil))) (defun my-igrep-display () (let ((clinen (count-lines (point-min) (point)))) (when (sit-for my-igrep-delay) ;; (or (= my-igrep-delay 0) (save-excursion (goto-char (point-min)) (unless (memq this-command ; 検索文字列が変更されたときのみ再検索 (list 'isearch-repeat-forward 'isearch-repeat-backward)) (setq my-igrep-match 0) (with-current-buffer my-igrep-buffer (erase-buffer)) (let ((linen 1) (ppos (point))) (while (my-igrep-search) ; マッチした行だけ処理 (setq linen (+ linen (1- (count-lines ppos (setq ppos (point)))))) (let* ((beg (save-excursion (progn (beginning-of-line) (point)))) (end (save-excursion (progn (end-of-line) (point)))) (str (buffer-substring beg end))) ;-no-properties (setq my-igrep-match (1+ my-igrep-match)) (when my-igrep-with-color (setq str (my-igrep-colorize str beg end (- (point) beg)))) (with-current-buffer my-igrep-buffer (insert (concat (format "%7d: " linen)) str "\n")))))) (cond ((= my-igrep-match 0) (my-igrep-window-cleanup)) ((not (window-configuration-p my-igrep-window-configuration)) (my-igrep-window-setup))) (when (and (> my-igrep-match 0) my-igrep-window-configuration) (save-selected-window (select-window (get-buffer-window my-igrep-buffer)) (with-current-buffer my-igrep-buffer (goto-char (point-max)) (let* ((alen (length my-igrep-mark-str)) (beg (re-search-backward (format "^ +%d:" clinen) nil t)) (end (save-excursion (end-of-line) (point))) (alinen (count-lines (point-min) (point)))) (when (and beg (> my-igrep-match 0)) (setq beg (1+ beg)) ; *2 (if my-igrep-overlay (move-overlay my-igrep-overlay beg (+ beg alen)) (setq my-igrep-overlay (make-overlay beg (+ beg alen)))) (overlay-put my-igrep-overlay 'invisible t) ; *3 (overlay-put my-igrep-overlay 'before-string my-igrep-mark-str) (when my-igrep-window-configuration ;; リサイズ (enlarge-window (1+ (- (if (> my-igrep-match (window-height)) (min my-igrep-window-height my-igrep-match) (max window-min-height my-igrep-match)) (window-height))))) (when (> my-igrep-match (window-height)) (recenter (- my-igrep-window-offset 1))) (setq mode-line-buffer-identification `("%b" ,(format " - %d:%d matches" alinen my-igrep-match)))) (force-mode-line-update))))))))) |
普通にインクリメンタルサーチを実行するだけです.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
追加すると便利になる関数の紹介です.
49.3.1 isearch で C-w のように文字を 1 文字ずつ追加 (2003/06/14) 49.3.2 isearch の検索語を 1 文字ずつ消す (2003/06/28) 49.3.3 isearch の終了時のカーソル位置 (2003/04/03) 49.3.4 isearch で検索中の単語で occur (2004/02/03)
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
C-s C-wとすると, isearch でカーソル付近の単語が追加されます.しかし,日本 語では非常に長い部分が追加されてしまい,不便です.
そこで,以下のような設定を追加します.すると,C-s C-dとすると,カーソル付 近の文字を 1 文字ずつ追加してくれます.
(defun isearch-yank-char () "Pull next character from buffer into search string." (interactive) (isearch-yank-string (save-excursion (and (not isearch-forward) isearch-other-end (goto-char isearch-other-end)) (buffer-substring (point) (1+ (point)))))) (define-key isearch-mode-map "\C-d" 'isearch-yank-char) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
isearch で C-w を利用すると,カーソル付近の単語をそのまま検索することがで きます.しかし,日本語の場合,思ったよりもたくさん含まれてしまいます.しかも,そ こで,BS とすると,単語全体が消えてしまうので,結局一文字ずつ追加していく 必要があります.
BSのように単語全体ではなく,一文字ずつ消していくことができます.
以下の設定を.emacs に追加します.
(defun isearch-real-delete-char () (interactive) (setq isearch-string (if (= (length isearch-string) 1) isearch-string (substring isearch-string 0 (- (length isearch-string) 1))) isearch-message isearch-string isearch-yank-flag t) (isearch-search-and-update)) (define-key isearch-mode-map "\C-o" 'isearch-real-delete-char) |
単語をC-wで追加した後,C-oとすると一文字ずつ消していくことができます.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
ネタ元:ELF-ml
C-sで文字を検索して,RETで終了するとカーソル位置は検索後の後ろになり ます.一方,C-rでは,検索語の前になります.
これを,常に後ろのする設定が以下です.ついでに,M-mで終わると,カーソル位 置を検索語の前へ持っていってくれます.
(define-key isearch-mode-map "\M-m" 'isearch-exit) (add-hook 'isearch-mode-end-hook (lambda () (cond ((eq last-input-char ?\C-m) (goto-char (match-end 0))) ((eq last-input-char ?\M-m) (goto-char (match-beginning 0)))))) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
isearch で検索している単語で occur をすることができます.
isearch は手軽に使えて非常に便利ですが,一覧ができません.
isearch で検索中の単語で occur を行うことができます.
以下を.emacs に追加します.
(defun isearch-occur () "Invoke `occur' from within isearch." (interactive) (let ((case-fold-search isearch-case-fold-search)) (occur (if isearch-regexp isearch-string (regexp-quote isearch-string))))) (define-key isearch-mode-map (kbd "C-o") 'isearch-occur) |
同じことは color-moccur の moccur でもできます.最新の color-moccur であれば,M-o で実行できます.
isearch 中にC-oで occur を起動できます.
migemo は使っていないので,日本語には一致しません.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
日本語をローマ字入力のままインクリメンタルサーチできる migemo というものがありま す. これを使うと, 「 kenn 」と入力すると, 「検索」や「検出」などを検索することが できます. もちろん, 「 kenn 」という英数字にも一致しますし, 全角の英数字にも一致 します.
うれしすぎます.一度使うと,これがないとやってられなくなります.
インストールはちょっと面倒です.
まず, Ruby/Romkan, Ruby/Bsearchをダウンロートしま す. 解凍すると, それぞれ romkan.rb, bsearch.rb というファイルが含まれてますので, これを C:/cygwin/usr/local/lib/ruby/site_ruby (インストール条件によって変わりま す) へコピーします.
次にMigemoをダウンロードし, 解凍します. 解凍後, bash でそのディレクトリへ移動し, configure/make/make install を行います. 実行例 を示します.
cd tmp/migemo-0.32 ./configure --with-emacs=meadow make make install
これだと migemo.el は変なディレクトリに行ってしまいます. 正しく./configure をす ればいいんですが, 私は手で migemo.el をロードパスの通ったディレクトリへ移動しま した (C:/unix/Meadow/1.99/site-lisp/migemo へ移動) .
さらに, C:/cygwin/usr/local/bin に migemo がコピーされますが, 先頭行がうまく設定 されていないようです. #! /usr/local/bin/ruby に変更します. ruby.exe のパスが違う 場合は適当に換えてください.
以下を.emacs に追加します. 順番が大事です. 必ずこの順番で設定します.
(setq migemo-directory "e:/cygwin/usr/local/share/migemo") (load-library "migemo") |
単にC-sとした後でローマ字を打ち込むだけで, 日本語を検索できます.日本語変 換は必要ありません.
ただし,以下のような文の前で,C-s kanzitohiragana としてもヒットしません. このような連文節は「 kanziTohiragana 」という風に,先頭の文字を大文字にする必要 があります.
漢字とひらがなが混ざった文の検索
「混ざった」を検索したいなら,「 maZatta 」とします.
基本的には普通の isearch と同じです.M-mのみが異なっており, migemo のオン/オ フになっています.
SKK と併用している場合は,
(setq skk-isearch-start-mode 'latin) |
として, インクリメンタルサーチ時には SKK を抑制するようにすると便利です. こうす ると, 普通に検索すると migemo ,C-sの後で SKK を起動すると, SKK による日本 語検索と使い分けることができます. 最新の SKK では, isearch 時に SKK をオフにする ことも可能ですが, 個人的にはこちらの方が便利です.
専門用語などの登録はユーザ辞書を作成すれば可能です.サンプルが `C:/cygwin/usr/local/share/migemo/user-dict.sample' にありますので,これを 参考に作成して `C:/cygwin/usr/local/share/migemo/user-dict' として保存すれ ば,登録した文字も検索できるようになります.
ただ, migemo は通常のインクリメンタルサーチよりは遅いです. migemo の初期化を行 うため,特に初回は遅いです.
上記の設定に続けて
(migemo-init) |
と書いておくと初期化を起動時に行うことができるので,検索時のいらいらは減ります. 起動時の待ちは増えますけど...
単純に検索するのではなく,途中に変換処理を行っているわけですから,当然普通の isearch よりも遅いです.
しかし, migemo にはキャッシュという機能があります.これは,一度入力した検索語を記 憶しておく機能です.
これにより,頻繁に検索する語は素早く検索することができます.
利用するためには,以下を.emacs に追加します.
(setq migemo-use-pattern-alist t) (setq migemo-use-frequent-pattern-alist t) (setq migemo-pattern-alist-length 1024) |
英数字の検索だけなら遅い migemo を使うよりも, C-u C-sで正規表現による検索 を利用した方がいいでしょう.
ネタ元:http://ko.meadowy.net/~shirai/diary/20030724.html#p02
Emacs が落ちた場合は以下の設定が有効かもしれません.
私のところでは落ちないので,有効性は確認できてません...
(cond ((fboundp 'replace-in-string) (defalias 'my-replace-in-string 'replace-in-string)) (t (defun my-replace-in-string (str regex replace) (when (stringp str) (let ((start 0) (len (length replace))) (save-match-data (while (setq start (string-match regex str start)) (setq str (concat (substring str 0 (match-beginning 0)) replace (substring str (match-end 0)))) (setq start (+ start len)))))) str))) (setq migemo-after-conv-function 'migemo-add-zenkaku-pattern) (defun migemo-add-zenkaku-pattern (word pattern) (let ((zenup (japanese-zenkaku (upcase word))) (zendown (japanese-zenkaku (downcase word))) (len (length word)) (i 0) (zenkaku "") upchar downchar) (while (< i len) (setq upchar (aref zenup i)) (setq downchar (aref zendown i)) (if (eq upchar downchar) (setq zenkaku (format "%s\a%c" zenkaku upchar)) (setq zenkaku (format "%s\a[%c%c]" zenkaku downchar upchar))) (setq i (1+ i))) (if (= len 1) (setq pattern (format "%s\\|%s" pattern (substring zenkaku 1))) (setq pattern (format "\\(%s\\)\\|\\(%s\\)" pattern (substring zenkaku 1)))) (my-replace-in-string pattern "\a" migemo-white-space-regexp))) |
49.4.1 migemo の出力をキャッシュして高速化 (2003/06/14) 49.4.2 C/migemo を使いたい (2003/11/05) 49.4.3 migemo でも C-w を使いたい (2003/06/28) 49.4.4 日本語の時だけ migemo で検索 (2006/02/07) 49.4.5 自動連文節検索 (2006/02/07)
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
最新版ではすでに取り込まれていますので,これは不要です.
このサイトはメモですので,残しておきます.
ネタ元:migemo ML
白井さんにより migemo の出力をキャッシュして高速化するという変更が http://migemo.namazu.org/ml/msg00153.htmlで提案されています.
パッチは上のメールからコピーして使うか,パッチを適用済みの https://bookshelf.jp/elc/migemo.el で古い migemo.el を上書きします. migemo.elc があれば,削除しておきます.
そして,.emacs に以下を追加します.これで, migemo の結果を 1000 個保存してくれ ます.
(setq migemo-pattern-alist-length 1000) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
ネタ元:2 ちゃんねる
Ruby 版を高速化し,他のソフトでも取り込めるようにするために C により実装された C/migemo が KaoriYa にて公開されています.
Ruby が不要ですので,導入の手間が少なくて済みます.
まず,KaoriYaより,最新の C/migemo をダウ ンロードします.
次に QKCより QKC の UNIX 版をダ ウンロードして, make しておきます. Cygwin があれば「 make CC=gcc 」でできます. そして, qkc.exe をパスの通ったところへコピーしておきます.
後は, MSVC なら,
nmake msvc nmake msvc-dict
で make できます.
Cygwin なら
make cyg make cyg-dict
でできます.
できた辞書は適当なフォルダへ,実行ファイル (migemo.exe と migemo.dll) はパスの通っ たところへ置いておきます.
これで,
cmigemo -d /usr/local/share/cmigemo/migemo-dict
として,適当な文字を入力すると,日本語が表示されるはずです.
うまくいかないようなら,以下のように, main.c の該当行に「 fflush (stdout);」を追加 するといいかもしれません.
ans = migemo_query (p, buf); if (ans) printf (quiet ? "%s\n" : "PATTERN: %s\n", ans); + fflush (stdout); migemo_release (p, ans); } return 0; |
https://bookshelf.jp/elc/cmigemo-1.1.013.lzh にコンパイル済みのバイナ リを用意してあります.
解凍すると, cmigemo.exe と migemo.dll がありますので,パスの通ったところへ移動しま す.
さらに migemo.el はロードパスの通ったところへ, dict フォルダの中身は適当なフォルダ へ移動します.
以下を参考に,.emacs に追加します.
;; 基本設定 (setq migemo-command "cmigemo") (setq migemo-options '("-q" "--emacs")) ;; migemo-dict のパスを指定 (setq migemo-dictionary "e:/cygwin/usr/local/share/cmigemo/migemo-dict") (setq migemo-user-dictionary nil) (setq migemo-regex-dictionary nil) ;; キャッシュ機能を利用する (setq migemo-use-pattern-alist t) (setq migemo-use-frequent-pattern-alist t) (setq migemo-pattern-alist-length 1024) ;; 辞書の文字コードを指定. ;; バイナリを利用するなら,このままで構いません (setq migemo-coding-system 'euc-jp-unix) (load-library "migemo") ;; 起動時に初期化も行う (migemo-init) |
これで,C-sとするだけで, migemo を利用した検索が可能になります.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
migemo ML より
最新の migemo には取り込まれていますので,この設定は不要になりました.
isearch ではC-wを入力すると,カーソル以降の単語を検索文字として追加してく れます.しかし, migemo を使っていると,ローマ字と日本語が混在してしまい,思うよ うに動いてくれません.
そこで,以下の設定が便利です.これを入れておくと,C-wで単語を追加する際に, ローマ字を消して,日本語だけにしてくれます.
つまり,「 ben 」で「便利」を検索していた時にC-wとすると,通常は「 ben 利」 となってしまいますが,これを入れておくと,「便利」にしてくれます.
(define-key isearch-mode-map "\C-d" 'isearch-yank-char) (define-key isearch-mode-map "\C-w" 'isearch-yank-word) (defun isearch-yank-char () "Pull next character from buffer into search string with migemo." (interactive) (when (and (boundp 'migemo-isearch-enable-p) migemo-isearch-enable-p (not isearch-regexp) isearch-other-end) (setq isearch-string (buffer-substring-no-properties isearch-other-end (point))) (setq isearch-message isearch-string)) (isearch-yank-string (save-excursion (and (not isearch-forward) isearch-other-end (goto-char isearch-other-end)) (buffer-substring-no-properties (point) (progn (forward-char 1) (point)))))) (defun isearch-yank-word () "Pull next character from buffer into search string with migemo." (interactive) (when (and (boundp 'migemo-isearch-enable-p) migemo-isearch-enable-p (not isearch-regexp) isearch-other-end) (setq isearch-string (buffer-substring-no-properties isearch-other-end (point))) (setq isearch-message isearch-string)) (isearch-yank-string (save-excursion (and (not isearch-forward) isearch-other-end (goto-char isearch-other-end)) (buffer-substring-no-properties (point) (progn (forward-word 1) (point)))))) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
日本語があると思われるファイルの時だけ migemo で検索することにより,余計な語への ヒット,動作の重さが低くなります.
Petit emacs lisp tips
ASCIIのファイルを開いていても,migemoをインストールしてある状態で C-s で検 索すると migemoを使って検索してしまいます.
ファイルの文字コードに応じて migemo を使うかどうかを自動判別してくれます.
設定していません.
以下を .emacs に追加します.
;; buffer-file-coding-system から言語判別 ;; unicode も入れた方がいいのかも。 (defun my-language-check (lang) (let ((coding (coding-system-base buffer-file-coding-system))) (memq coding (cdr (assoc 'coding-system (assoc lang language-info-alist)))))) ;; 日本語じゃないときは migemo を使わない (eval-after-load "migemo" '(progn (defadvice isearch-mode (before my-migemo-off activate) (unless (my-language-check "Japanese") (make-local-variable 'migemo-isearch-enable-p) (setq migemo-isearch-enable-p nil))) (add-hook 'isearch-mode-end-hook (lambda () (unless (my-language-check "Japanese") (setq migemo-isearch-enable-p t)))))) |
普通に C-s で検索するだけで,日本語を含まないと思われる文字コードであれば, migemo を利用しないようになります
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
migemo では通常,「KennsakuMoji」(検索文字)のように区切りを大文字にすることで連 文を検索するが,これを自動的に行う.
Petit emacs lisp tips
migemo で複数語から成る語を検索しようとすると,その区切りを大文字で入力する必要 があり面倒です.
一致する語が無かった時に,一致しなかった点を大文字にすることで,自動での連文検索 を可能にしています.
設定していません.
以下を.emacsに追加します
(defun my-ren-cap (str) ; 次単語の先頭を大文字化 (string-match ".*[aiueo]\\(?:nn\\)*\\(.+\\)" str) ; 最後の母音 OR nn 直後 (let ((start (match-beginning 1))) (cond ((string-match "n\\([^aiueon]\\)" str start); n の後の子音 (replace-match (upcase (match-string 1 str)) nil nil str 1)) ((string-match "[ ,.]*\\(.\\)" str start); 母音 OR nn の直後 (replace-match (upcase (match-string 1 str)) nil nil str 1)) (t str)))) (defadvice isearch-update (after my-migemo-auto-cap activate) (when (and (featurep 'migemo) migemo-isearch-enable-p ; migemo が on で, (not isearch-success) ; isearch に失敗し, ;; 検索文字列が二文字以上で母音終わり, (string-match ".[aiueo]$" isearch-string) (eq this-command 'isearch-printing-char) ; 検索文字列を伸ばした (save-excursion ;; 残りのバッファを検索しても検索文字列がない場合 (goto-char (point-min)) (not (funcall (if isearch-forward 're-search-forward 're-search-backward) (migemo-get-pattern isearch-string) nil t)))) ;; migemo で isearch に失敗したらそこから次単語とする (dolist (var (list 'isearch-string 'isearch-message)) (let ((str (symbol-value var))) (set var (my-ren-cap str))));; (length str))))) ;; 再検索 -- isearch-barrier からでいいのかな? (goto-char isearch-opoint) (isearch-search))) |
普通に migemo を使って検索するだけです.
うまくいかない時もあるようですが,なかなかに面白いので,今後のアップデートが楽し みです.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
C-d などでバッファから isearch の検索語として文字を取ったときには migemo をオ フにできます.
Wiki のリクエスト で書いたもの.短いものですが,思った以上に便利でした.
isearch ではC-wやC-dでバッファの文字を検索語に追加できます.この時に も migemo がオンであるため,「 off 」を追加した時には「オフ」にも一致します.
しかし,バッファから検索語を追加する場合,その文字自体を検索したい時がほとんどで, migemo はオフの方が便利です.
バッファから検索語を追加した時には migemo がオフになります.
以下を.emacs に追加します.
;; 文字をバッファからコピーするときには ;; migemo をオフにする (defadvice isearch-yank-string (before migemo-off activate) (setq migemo-isearch-enable-p nil)) ;; isearch で検索する時には ;; migemo をオンにする (defadvice isearch-mode (before migemo-on activate) (setq migemo-isearch-enable-p t)) |
普通に isearch で検索します.C-dなどでバッファから文字を追加すると migemo がオ フになります.
アドバイスで強制的に isearch をオン/オフしています.M-x migemo-toggle-isearch-enable などでオフにしても, isearch を実行すると migemo が オンになりますので,ご注意を.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
Windows の IME を使うために,.emacs に
(setq default-input-method "MW32-IME")
|
と書いている場合には ekb-isearch というものを使うことができます.これは, Windows の IME を使ってインクリメンタルサーチを行う Elisp です.
使い方は簡単で,http://www.mdcnet.co.jp/~keiichi/meadow-tips-ja.shtml よりダウンロードし,ロードパスの通ったところへ置き,
(require 'ekb-isearch) |
を .emacs に追加します.
これで普通に isearch をすると, IME を利用できます.これにより, IME の変換を決 定した時点ですぐに検索が始まりますし,途中で文字を追加することもできます.
ただし, ekb-isearch を使うと ekb-isearch-mode-map という変数でキーバインドを設定 しています.そのため, isearch のキーバインドを変える時には,
(define-key isearch-mode-map "\C-k" 'isearch-edit-string) (require 'ekb-isearch) |
という風に, ekb-isearch よりも前に書く必要があります.
また, ekb-isearch を使うと, IME の確定前の文字がバッファに表示されます.ミニバッファ へ目が行っているのに,バッファに表示されるのは不便です.
そこで, isearch-fep とい うものがあります.まず, isearch-fep.elを ダウンロードします.そして,ロードパスの通ったところへ置き,以下を.emacs に追加し ます.
(require 'isearch-fep) |
これで,確定前の文字もミニバッファに表示されるようになります.入れても変わらない ようであれば, ekb-isearch との順番を変えてみてください.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
ネタ元: Petit emacs lisp tips
isearch で検索してもコメントがあると,意図していないところまで検索してしまい,結 局目的のところへ辿り着くまでに時間がかかってしまいます.
コメント部分のみ,あるいはコメント以外のみを対象に isearch ができます.
以下を.emacs に追加します.
最新のものは Petit emacs lisp tips にありますので,そちらを参照してください.
;; comment 行を skip する search-forward (defadvice search-forward (around my-comment-skip disable) (let (match) (while (and (integerp (setq match ad-do-it)) (not (string= (ad-get-arg 0) "")) (nth 4 (parse-partial-sexp (point-min) match)))) match)) ;; comment 行以外を skip する search-forward (defadvice search-forward (around my-comment-only disable) (let (match) (while (and (integerp (setq match ad-do-it)) (not (string= (ad-get-arg 0) "")) (not (nth 4 (parse-partial-sexp (point-min) match))))) match)) ;; comment 行を skip する re-search-forward (defadvice re-search-forward (around my-comment-skip disable) (let (match) (while (and (integerp (setq match ad-do-it)) (not (string= (ad-get-arg 0) "")) (nth 4 (parse-partial-sexp (point-min) match)))) match)) ;; comment 行以外を skip する re-search-forward (defadvice re-search-forward (around my-comment-only disable) (let (match) (while (and (integerp (setq match ad-do-it)) (not (string= (ad-get-arg 0) "")) (not (nth 4 (parse-partial-sexp (point-min) match))))) match)) (fset 'isearch-forward-comment-only 'isearch-forward) (fset 'isearch-forward-comment-skip 'isearch-forward) ;; isearch-forward が内部で使っている search-forward を ;; isearch-forward (migemo) が ;; 内部で使っている re-search-forward を ;; isearch-forward-comment-skip では ;; コメント行を無視するように ;; isearch-forward-comment-only では ;; コメント行以外を無視するように変更 (defadvice isearch-forward-comment-skip (before my-ad-activate activate) (ad-enable-advice 'search-forward 'around 'my-comment-skip) (ad-activate 'search-forward) (ad-enable-advice 're-search-forward 'around 'my-comment-skip) (ad-activate 're-search-forward)) (defadvice isearch-forward-comment-only (before my-ad-activate activate) (ad-enable-advice 'search-forward 'around 'my-comment-only) (ad-activate 'search-forward) (ad-enable-advice 're-search-forward 'around 'my-comment-only) (ad-activate 're-search-forward)) (add-hook 'isearch-mode-end-hook (lambda () (ad-deactivate 'search-forward) (ad-disable-advice 'search-forward 'around 'my-comment-skip) (ad-disable-advice 'search-forward 'around 'my-comment-only) (ad-activate 'search-forward) (ad-deactivate 're-search-forward) (ad-disable-advice 're-search-forward 'around 'my-comment-skip) (ad-disable-advice 're-search-forward 'around 'my-comment-only) (ad-activate 're-search-forward))) |
普通にC-sで通常の isearch になり,M-x isearch-forward-comment-onlyでコ メントのみ,M-x isearch-forward-comment-skipでコメント以外のみを対象に isearch ができます.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
通常の isearch はカレントバッファのみに isearch を行います.しかし,複数のバッファ を検索したい時もあります.そんな時には,バッファを切り替える必要があり少し面倒で す.
すべてのバッファを対象の isearch ができます.
isearch-all.elをダウン ロードし,ロードパスの通ったところへ置きます.
以下を.emacs に追加します.
(load "isearch-all") |
普通に isearch で検索すると,普通の isearch になります.
そして,途中で次のページへ行きたいなと思ったら,C-nやC-pとします.す ると,次のバッファや前のバッファへ移動することができます.その後,C-sとす ると,次々とバッファを検索していけますし,C-nで次のバッファへ行くこともで きます.
また,バッファの検索中に,C-uとすると,C-sだけで,すべてのバッファを 次々と検索できるようになります.
また,上の設定に,以下を追加すると現在のバッファを検索し終わった後で,自動的に次 のバッファへ移動するようになります.
(setq isearch-all-buffer t) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
hyper を押しながら文字を入力することで isearch のような検索ができる.
hyper を入力しながら文字を入力すると,文字を検索できます. hyper を離すと検索が終了 するので,すぐに編集に入れます.
super キーで逆方向に検索できます.
スペースや改行の検索もできるので,段落を移動して,すぐに編集などは簡単にできるか も...
qsearch.elをダウンロードしてロー ドパスの通ったところへ置きます.
以下を.emacs に追加します.
(require 'qsearch) |
hyper や super キーを入力しながら文字を入力すると,検索できます.
Windows では super や hyper キーは一般的ではないため,キーボードにないかもしれません. その場合は
(w32-set-modifier-key "noconvert" 'hyper) (w32-set-modifier-key "convert" 'super) |
のように変換キーと無変換キーなどに割り当てて試してください.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
テキストファイル内の文字を置換する機能です.
M-%を入力すると, ミニバッファへカーソルが移動し,
Query replace:
と表示されますので, そこで検索したい文字を入力し, RETを入力します.
すると,
Query replace: てすと with:
と表示されますので, 置換後も文字を入力して, RETを入力します.
すると, 今カーソルのある場所よりも下にある文章内から, 最初に入力した文字を検索し ます. 指定した文字があれば, そこに移動し, ミニバッファに Query replace help with からはじまる文字が表示されます. ここで, SPCを押すとその文字は置換され, nを押すとその文字は置換されません. そして, また検索を続けます. 途中で検索 をやめたい時は, Query replace help with からはじまる文字が表示された時に, qを押すとそこで終了します. !で検索に一致したすべての文字をユーザに尋 ねずに置換できます.
M-%は query-replace という関数が実行されています. 同様の関数は他に replace-string というものがあります. これも, query-replace と同じように使えます が, 置換するかどうかは尋ねず, すべて置換します.
改行を置換する時には C-q C-j を用います. 改ページなどの制御文字を検索する 時には C-q C-l(^L を検索) のように C-qを使用します.
置換を開始して途中で置換する文字を変えたくなる時があります.そんな時には M-% で置換している時に e を入力します.すると,カーソルがミニバッファ に移動し置換する文字を編集することができます.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
49.10.1 基本的な置換機能 (2004/03/25)と使い方はまったく同じです. ただし, 検索するものを正規表現 (48. 正規表現とは (2007/12/06)) で指定する必要があります.
例を上げて説明すると
1:インクリメンタルサーチ 2:grep 3:namazu
を
(1) → [インクリメンタルサーチ] (2) → [grep] (3) → [namazu]
のように置換したいとします.
この場合は,M-x query-replace-regexp で,\([0-9]\):\(.+\) を (\1) → [\2] に置換するように指定します.
こんな風に \(\) で囲うとそこは 1 つのグループとなり,前から 1 , 2 グループとなります.そして,それは \1 や \2 で呼び出すことができます.一致項目全体は \& で指定できます.
こんな風に正規表現を用いると,置換の自由度は大きく向上します.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
M-%で置換中にC-rとすると,置換を中断してテキストを編集できます. C-M-cで置換を再開します.
M-%でテキストの置換を行うことができます.しかし,置換していくと,一部のテ キストを編集したくなることがあります.
しかし,かといって一度置換を終了して,編集を行い,再度置換をするというのは,かな り面倒です.
置換を中断して,テキストを編集し,また置換を再開することができます.
標準機能ですので,作業は不要です.設定もいりません.
普通にM-%で置換を行い,編集したいところまできたら,C-rとします.
そうすると,モードラインの一部が
(Texi Win MMM Fill) → [(Texi Win MMM Fill)]
のように,「 [] 」で括られます.これで「再帰編集」に入りました.
後は普通に編集を行います.そして,編集が終わったら,「再帰編集」から抜けるために C-M-c(ESC を押し,離してから, C-c を押す,あるいは Alt と Ctrl と c を同時に押す) とします.
これで,「再帰編集」を抜け,置換が再開します.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
isearch で検索している単語ですぐに置換することができる.
isearch で長い正規表現を作って検索した後で,その文字を置換したくなる時があります. しかし,そのためにまた正規表現を作るのも面倒なものです.
isearch で検索後,置換に入ることができます.
ireplace を か ireplace.el からダウンロードし て,ロードパスの通ったところへ置きます.
以下を.emacs に追加します.
(require 'ireplace) |
isearch で検索中に,C-RETで置換に移ることができます.M-%でも可能です. このような普通の置換だけではなく,もう少し高度なこともできます.
C-u C-s で「 def.+ire 」を検索したとします.そうすると,例えば以下が一致しま す.
(defconst ireplace-version "0.1" (defvar ireplace-match-count 10) (defvar ireplace-regexp nil) (defvar ireplace-from nil)
ここで,C-M-%かM-returnを押します.すると,それぞれを別々の単語に置 換することができます.
つまり,「 defconst ire 」は「 defvar ire 」へ,「 defvar ire 」は「 defcustom ire 」へ とかが可能なのです.ただし,「 defvar ire 」で始まる行は 3 つありますが,これらを別々 の文字に置換することはできません.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
if などを用いて,一致した文字に応じて置換する文字を変化させることができる.
M-%やM-x query-replace-regexp は確かに便利です.しかし,こ れらの置換方法は「 setq 」を「 defvar 」へ,「 setq 」を「 (setq) 」へ といった風な置換しかできません.
そのため,一致した文字がある文字の時には「 A 」にして,それ以外の時に は「 B 」に置換するといったことは不可能です.
置換対象に簡単な関数を指定することで,極めて自由度の高い置換が可能にな ります.
Meadow ではそのままで利用できます.
M-x query-replace-regexp-eval とします.そうすると,ミニバッファ に
Query replace regexp:
と表示されますので,正規表現を入力します (ここまでは,M-x query-replace-regexp と同じです) .
入力すると,
Query replace regexp \(e.+s\) with eval:
のように表示されます (「\(e.+s\) 」の部分は入力した文字になります) .
ここで,
(if (string= "emacs" \1) "Meadow" "Emacs")
といった具合に簡単な Elisp を入力できます (この例だと「 emacs 」に一致 した文字だけが「 Meadow 」に置換されます) .
また,「\([0-9]+\) 」で数字に一致させておき,
(+ (string-to-int \1) 10)
として,適当な数を加えるといったことも可能です.
簡単な Elisp が書ける必要がありますが,使いこなすことができると,かな り強力な武器になると思います.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
現在開いているファイルを対象に置換を実行できます.
xyzzy の紹介ページ でgresregを知って,Meadow向けに実装してみたものです.
M-% による置換では現在のバッファしか置換できません.複数バッファ の置換では,1個1個移動して置換していく必要があります.
すべてのファイル関連のバッファを対象に置換を実行できます.
gresreg.el をダウンロー ドして,ロードパスの通ったところに置きます.
以下を.emacsに追加します.
(require 'gresreg) |
M-x gresreg とします.すると,M-% による置換と同様に置換す る語を入力します.すると,
Replace in gresreg.el ? (? for help)
のように,そのバッファで置換を実行するかどうか確認されます.yか SPC で置換を実行,n でそのバッファはキャンセル,q で 終了,! ですべてのバッファを確認なしで置換を実行できます.
思いつきで適当に作ったものです.問題があればコメントください.
[ << ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |