Mew Builtin Search ～ Emacs だけで Mew のサーチを済ます

# Mew の サーチ を Emacs だけで済ませます

Mew はサーチに grep 等外部コマンドを使いますが、それなしで Emacs のみできるようにする拡張です。

外部ツールの仕様に依存せずテキストに適合した日本語の検索ができるようになります。

現在殆どのメールがユニコードを使っていて base64 等でエンコードされたもののため、grep に素通ししただけでは検索できなくなってしまっています。そこを解消するものでもあります。
主に自分のような Mew なしではメールができない人向けです。

自分のメールストック数では、起動したてのノンキャッシュ状態の PC でメール全文検索に 5分くらいかかりました。そのあとならキャッシュされているので相当早く済みます。

ファイルサーチされるたび実行される `multipart-decode.el` 
はバイトコンパイルしておいたほうがよいかもしれません。

# インストール

必要なファイルは次のふたつです。
[本体](https://gist.github.com/s-fubuki/4e4d5c6a6a7a4af0b08afaabf2514fb5) と [デコードパート](https://gist.github.com/s-fubuki/ee7ce186e99a77171085c011283e02fa) を DL し `load-path` の通った処に置き、適宜バイトコンパイル等して `.mew.el` か `init.el` に以下の1行を追加します

```emacs-lisp:sample
(requare 'mew-builtin-search)
```

それぞれの環境により Mew が検索エンジンのデフォルトを決定するので、Mew 起動後に `M-: mew-search-method[RET]`  等の方法などで `mew-search-method` の値を調べ `builtin` になっていなければ、`.mew.el` か `init.el` 等で

```emacs-lisp:sample
(setq mew-search-method 'builtin) 
```

と設定を追加しておいてください。
この設定が優先されるようになります。

# これにより置き換えされる機能

インストール前と使い方に変わりはありませんが、列挙しておきます。

## `?` 今いるフォルダでサーチしてマークする
マークは解除しない限り残っているので、その仕様に合わせ前の検索ワードのハイライトも残るようにしてあります。

クリアするときは `U*` して全マーククリアするとハイライトもクリアされます。

Mew が持っている `M-n`  `M-p` も生きていて使えます(但し生バッファでは効かないようです)。

`SPACE` や正規表現で使うことのある `?` が補完キーになっているので、変更して `SPACE` や `?` を入力できるようにしてあります。
補完を利用する場合は `TAB(C-i)` が使えます。

## `/` 今いるフォルダでサーチしてセレクションを作る
`?` で検索してから `m/` してもこれと同じ状態を作れます

## `k?` 今いるフォルダでサーチしてマークする
`?` とまったく同じになります。但しこちらはリージョン指定が効きません。
本来なら `?` と同じ機能を grep に換えて全文検索する方の検索エンジンで実行するコマンドですが、この場合 `?` とほぼ同じになります。

## `k/` 全フォルダからサーチしてセレクションを作る

保存されたメールすべてを対象にするいわゆる全文検索です。
その都度走査するのでデータベース作成等のコマンドはありません.

`=` で元々どこに在るメールなのか判ります。

`C-c C-q` または `Q` で Mew を完全終了しない限り、このバッファは残っているので再度収集しないでも選択すればいつでも見ることができます。
但し前回マッチしたハイライトは検索直後に該当箇所が発見しやすいよう消しています。
全文検索のときは蓄積せず実行の度に更新する仕様です。

`Prefix` 付で実行するとカンマで切って検索するフォルダを複数指定できます。
`Mail` のルートフォルダ以外にそういうケースがあるのかは判りませんが、指定したフォルダの中に更にメールフォルダがあれば再帰的に検索します。

# 除外したいフォルダー

全文検索から除外したいフォルダは変数 `mbs-ignore-directory-list` に正規表現のリストで設定します。
デフォルトでは `trash, draft, backup` が検索対象から除外されます。
デフォルトを変更したい場合は `.mew.el` 等で変数を新たに設定しなおすことで除外してください。

```emacs-lisp:sample
(setq mbs-ignore-directory-list '("trash" "draft" "backup" "queue"))
```


`Prefix` を付けて  `k/` を実行したときはこの変数が無効になり、ここで指定されているフォルダも対象にすることができます。

# 検索時の大文字小文字の区別

変数 `mbs-case-fold-search` に真偽値をセットして既定値の設定ができます。
非NIL なら大文字小文字は区別しません。
デフォルトは buffer local 変数 `case-fold-search` の値です。
特に何も設定をしていなければ `t`(大文字小文字の区別をしない)になっていると思います。

この値はキーワード入力のとき `M-c` でトグルすることができます。

# 検索入力の凡例

### "中西" または "綿谷" "速水" 等を含むメールを抽出

```emacs-lisp:sample
中西\|綿谷\|速水
```


正規表現は elisp の [info](https://www.gnu.org/software/emacs/manual/html_node/elisp/Syntax-of-Regexps.html#Syntax-of-Regexps) 通りに書けば大丈夫です。
`"\\|"` 等のように Backslash を2重にエスケープする必要はありません。

### "From:" が "nakamura@foo.jp" さんと "koga@foo.jp" さんのメールを抽出

```emacs-lisp:sample
^From: .*\(nakamura\|koga\)@foo\.jp
```


但しメール全体を見るので本文の中に同じパターンがあってもマッチしてしまいます。

### 2016年 7月のメールを抽出

```emacs-lisp:sample
^Date:.+jul.+2016
```


上記と同様です。

### 画像や PDF の同梱されたメールを抽出

```emacs-lisp:画像
^Content.+\.\(jpg\|png\|gif\)
```

```emacs-lisp:PDF
^Content.+\.pdf
```


### mew で書かれたメールを抽出

```emacs-lisp:sample
^x-mail.+mew
```


# その他諸々の情報

## `mewl` との併用はできません。

はじめは `grep` のみ置き換えて `mewl` はそのまま通る仕様だったのですが、それだとキーワードによってはそのまま渡されず
`foo\|bar` 等の正規表現が `mewl` に渡すために 複数のワードに分解されて渡されることに気がついたので、バイパスして入力したままの文字列を得るようにしたため対応していません。

フォルダサーチで `mewl` 等デフォルトを利用したい場合は、変数 `mbs-builtin` を `nil` にしてください。

## 拡張子有りのメッセージファイルでしかテストされていません

一応 `.mew` 拡張子は Mew の変数で付け足すような形で実装していますが、拡張子ありの環境でのテストしかしていません。
拡張子が無いメッセージファイルで Mew を運用している場合うまく動くかどうかは不明です。

## マッチハイライトは Emacs を終了すると消えます

マークは1度 Emacs を終了して再起動したあとに起動した Mew でも残っていますが、マッチ箇所のハイライトは消えます。
変数として保持しているだけなので Mew だけの終了/再起動後なら残っています。

## 拾われたのにマッチ箇所がない?

メールヘッダからも丸ごと検索することを目的としている為、文字通りの全文を検索をするのでヘッダのどこかにマッチしている場合もあります。

また HTML レンダリング等されたいわゆる調理モード( `.` で表示される画面)のときはマッチ箇所が現れない場合があります。
`,` を押すとデコードされたメールソースの表示のモード(人がソースを読むのに都合の良い半生モード)になり、調理モードでは隠されていた部分が可視できるようになる場合があります。

あるいは Mew は "To:"行等が長すぎる場合 ... と省略表示するので、その中にあるかもしれません。

それでも見当たらなければ `C-c TAB(C-c C-i)` で現在見ているメールのメールソース(生メール)がロードできるのでそれで確認するなどしてください。
そこで `multipart-decode` を実行して探す等すると見つかるかもしれません。
バッファが破壊されるのでそのまま保存して上書きしないよう気をつけてください。
バッファをコピーして実行するのが安全です。


## 対応しているフォーマット

base64 等で固められたメールを人の読める形にきめ細かく展開するルーチンは Mew が当然持っていますが、Mew は万能故に巨大すぎて該当する関数を実装に合わせて呼び出す方法を解析するのも骨なので、横着をして稚作ながら自前で簡易な展開をしています。(base64等のデコード自体は Emacs のものです)

展開するのはヘッダの Subject:, From:, To:, Cc: の箇所と本文です。
本文はシングルパートまたはマルチパートのプレーンテキストまたは html テキストが以下のエンコードになったものです。ヘッダも同様です。message/rfc822 の入れ子になったメールからも探します。

- base64 
- quoted-printable 
- プレーンテキストのまま

デコードに失敗した場合そのファイル名が `*Messages*` バッファに残ります。

jpeg, zip 等のバイナリ箇所は、英単語をサーチするとエンコードされた無意味な羅列に偶然一致してしまうことがあり、検索の邪魔にしかならないので、ファイル名等を含むヘッダだけ残して実体であるバイナリ部分は削除した状態を検索します。

`quoted-printable` のとき "Malformed quoted-printable text" という警告メッセージが出ることがありますが、デコードは完了するが不正があるときに出るようです。
(つまりこのメールからのサーチは行なわれる)

不正といえば Emacs に対応していないキャラクタセットが指定されているときは、近似であると思われるキャラクタセット名に適当に置き換えしてデコードします。
この手のメールは Spam 等でしか出くわしたことがないので、検索から除外しても問題がないので通常はそこまでする必要はないと思いますが、必要な場合は変数 `mpd-regular-alist` に
`((元のコード . 置換するコード) ...)= の形式の連想リストで設定をしてください。

## Mew は pop 利用前提です

ローカルに落としたメールでの想定及び試験しかしていません。
Mew の imap は利用したことがなく、実装法も知らないのでうまく動くのかどうなるのかはまったく判りません。

# 更新情報

## Wed Oct 31 09:57:04 2018 - 1.3

[multipart-decode.el](https://gist.github.com/s-fubuki/ee7ce186e99a77171085c011283e02fa) の前回の修正で正規化(キャラクタセット名の適宜置換)を忘れていたので直しました。

あとパッチをあてても版がよく判らなく不親切なので Source の上の方に rcsid を入れました。この版だと 1.3 になります。

## Sat Oct 27 11:16:29 2018 - 1.2

[multipart-decode.el](https://gist.github.com/s-fubuki/ee7ce186e99a77171085c011283e02fa)  にバグが見つかったので修正しました。登録したばかりなのにもうしわけありません。

# 作成とテストに使った Emacs と Mew のバージョン

> Emacs - "GNU Emacs 26.1 (build 1, i686-w64-mingw32) of 2018-05-31"
> Mew - "Mew version 6.8"

以上です。
それでは楽しんでください!