emacs
Up one levelEmacs + Mew + Fetchmail + Procmailなメール環境
Fetchmailとはその名のとおりメールサーバーからメールをダウンロードするプログラムであり、Procmailは入力されたメールをユーザー指定のフィルタによって配分するプログラムです。これまでは個人でメールを受信するにしても面倒なローカルサーバーをたてたりしていましたが、FetchmailとProcmailを組合せることにより、ローカルサーバーをたてることなしにMaildir形式でメールを取り込むことができるようになりました。最小の設定は以下のようになります。
~/.fetchmailrc:
defaults protocol pop3 keep # keep mails on the server no mimedecode mda "/usr/bin/procmail" poll pop.example.com username example passward example
~/.procmailrc:
MAILDIR=$HOME/.maildir
これで
% fetchmail
とすれば.maildirにメールを取り込むことができます。次にMewの設定をします。
~/.emacs:
(autoload 'mew "mew" nil t) (autoload 'mew-send "mew" nil t) (setq mew-name "example") (setq mew-user "example") (setq mew-mail-domain "example.com") (setq mew-smtp-server "smtp.example.com") (setq mew-mailbox-type 'mbox) (setq mew-mbox-command "incm") (setq mew-mbox-command-arg "-u -d /home/example/.maildir")
これで、EmacsからM-x mewでMaildirにあるメールを閲覧することができます。Maildirにメールを取り込むにはその都度fetchmailする必要がありますが、一々ターミナルに移動するのが面倒でしたら
~/.emacs:
(defun fetchmail () (interactive) (shell-command "fetchmail") )
を定義しておけばいいでしょう。shell-commandのあとにmewを呼び出すとbetterかもしれません。
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/matsuyama/emacs-mew-fetchmail-procmail306a30e130fc30eb74b05883/tbping
GNU screenを使って新着メール数を表示
http://dev.ariel-networks.com/Members/matsuyama/emacs-mew-fetchmail-procmail306a30e130fc30eb74b05883
メールを受信できるようになったのはいいのですが、新着があるかどうかもわからずにfetchmail -cしたりM-x mewするのはナンセンスというか面倒くさいのです。やはり理想はターミナルのどこかに新着メール数を表示してくれることです。幸いにも当方GNU screenのhardstatus alwayslastline(ターミナルの最終行にあらゆる情報を表示することができるステータス表示機能)を使っておりますので、ここに表示してしまうのが最も楽で見栄えもよいHackになるのです。ということで新着メール数を求める方法について検討したいと思います。まず一番はじめに思い浮かぶのが、.maildir/newのファイル数をそのまま新着メール数にしてしまうという方法。メリットはサーバー上にメールをkeepしなくてもよい。デメリットは実際に(バックグラウンドで)メールを受信しなければならない(あまりデメリットになっていない)。ほかの方法としてはサーバー上にメールをkeepしてしまってfetchmail -cの出力結果を解析して新着メール数を求める方法。メリットは実際にメールを受信するわけではないので計算時の負荷が小さい。デメリットはメールをサーバー上にkeepしなくてはならない(これは大きい)。現在のところ僕は後者の環境なのですので(近いうちに前者へ)、そちらを前提して説明します。
まずfetchmail -cで新着メール数を求める方法。これは何を使ってもいいのですが、fetchmail -cの出力結果が解析しづらい(というわけではないのですが)のと統一の問題を考慮して、Perlで書いてしまうのがいいと思います。
my ($total, $read) = `fetchmail -c` =~ /^(\d+).+?(\d+)/; my $unread = $total - $read; $unread = 0 if $unread < 0; # parse error ? print $unread, "\n";
次に上のPerlスクリプトによって得られた値をターミナル、すなわちscreenのhardstatus alwayslastlineに送ります。(いろいろ方法はあるらしいですが)値を送る方法としてはscreenの-Xオプション(指定されたscreenに指定されたコマンドを送信するオプション)を使ってその都度hardstatus alwayslastlineを上書きしてしまうのが一番わかりやすいでしょう。具体的には以下のようになります。
% screen -r -X hardstatus alwayslastline Mail(0)
これでhardstatus alwayslastlineにMail(0)と表示されますので、0の部分を先ほど求めた$unreadに置きかえてやればいいわけです。
screenstatus:
#!/usr/bin/perl my ($total, $read) = `fetchmail -c` =~ /^(\d+).+?(\d+)/; my $unread = $total - $read; $unread = 0 if $unread < 0; `screen -r -X hardstatus alwayslastline Mail($unread)`;
実際に新着メール数をチェックさせてhardstatus alwayslastlineを更新させるには、このスクリプトを起動します。
% ./screenstatus
さて、これで新着メール数をターミナルに表示することはできましたが、いちいちscreenstatusを起動するのは面倒すぎます。普通の人ならcrontabに登録して自動で新着メール数が更新される姿にうっとりしたいはずです。というわけでcrontabに登録しましょう。
% crontab -e */10 * * * * /home/example/bin/screenstatus
これで10分ごとに新着メール数が更新されるはず!とワクワクしながら待てど一向に更新される気配がありません。
% crontab -e */10 * * * * screen -r -X hardstatus alwayslastline test > /tmp/stdout 2> /tmp/stderr
として/tmp/stdoutを確かめてみると
No screen session found.
となってしまっています。どうやら同一セッション内からでしか-rオプション(既存screenをresumeするオプション)を使えないようです。いろいろ対策を探しては試してみましたが一つの方法を除いて全て失敗におわりました。唯一成功した方法では-Sオプション(PIDからscreenを指定するオプション)を使用するので無理矢理感が否めませんが、ほかに方法がないのでこの方法を使うようにscreenstatusスクリプトを修正します。
screenstatus:
#!/usr/bin/perl my ($pid) = `screen -ls` =~ /(\d+).+Attached/; # assume first number is PID my ($total, $read) = `fetchmail -c` =~ /^(\d+).+?(\d+)/; my $unread = $total - $read; $unread = 0 if $unread < 0; `screen -S $pid -X hardstatus alwayslastline Mail($unread)`;
これで無事10分ごとに新着メール数が更新されるようになりました。いやはやかっこいいですね。ぶっちゃけていうと、-Xオプションがサポートされているscreenでは新着メール数に限らずなんでも表示できてしまいます。screen最強です(screenに関するエントリも書く予定)。
なおrootで-Xオプションを使うにはコマンドが送られる側でaddacl or acladdコマンドが呼ばれている必要があります。
~.screenrc:
addacl root
あるいはC-a :でaddacl rootと逐次登録するのもありです。
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/matsuyama/gnu-screen30924f7f3063306665b0774030e130fc30eb657030928868793a/tbping
Re:GNU screenを使って新着メール数を表示
Re:GNU screenを使って新着メール数を表示
http://acapulco.dyndns.org/hiki/hiki.cgi?%28Gentoo%29Screen
fetchrss + emacs + mewでRSSを購読する
個人的にweb based RSS readerは嫌いなので仲間内でfetchmailっぽいinterfaceを提供するfetchrssを作ってみました。最初はC++で実装していたのですが、途中でparser書くのが面倒くさくなり結局Perlに逃げてしまった次第です(途中にrubyがあるけどrss libraryが使えないのでボツ)。動作概要としてはfetchmailみたくサイトからRSSフィードをfetchしparseしてentriesに落としたのちに、timestamp tableによる既読管理(~/.fetchrss)でチェックし、未読ならばコンフィグファイル(~/.fetchrssrc)のmdaフィールドにメール形式で投げるようになっています。例えばmdaをprocmailにしてmaildir形式にlocalに管理して購読することも可能ですし、RSS reader serverとして外部のメールアドレスに送信することも可能です。可能なのですがEmacsenにはprocmailに加えてemacs + mewな環境で購読することを薦めます。というよりそれを目的として作られているので。では早速使い方を説明します。
まず http://www.panicode.com/software/fetchrss/index.html にアクセスしてfetchrss-x.x.x.tar.gzをダウンロードします。fetchrssはただのPerlスクリプトですので簡単にインストールできます。またLWPとXML::Feedを使いますので別途インストールしておいてください。
% tar xzf fetchrss-x.x.x.tar.gz % cd fetchrss-x.x.x % su % make install
デフォルトでは/usr/local/binにインストールされます。場所を変えたい場合はMakefileをいじくってください。以上でインストールが完了しましたので、簡単なコンフィグファイルを書きましょう(sample-fetchrssrcが同封されています)。
~/.fetchrssrc:
defaults mda /usr/bin/procmail encoding ISO-2022-JP include site title uri body feed http://somewhere/RSS
mdaは必須フィールドです。/usr/bin/procmailの他に/usr/bin/sendmailも指定できます。その場合はtoフィールドやfromフィールドも適切に変更しましょう。
~/.fetchrssrc:
defaults mda /usr/sbin/sendmail ... to rss@somewhere from fetchrss@local ... ...
encodingにはmimeのencoding名を書きます。日本語メールはISO-2022-JPがほとんどなのでデフォルトのままで問題ありません。includeはメール本文に含む情報を指定します。siteはサイト名、titleはエントリのタイトル、uriはエントリのURI、bodyはエントリの本文となっています。またnohtmlを書いておくとhtmlをplainのままで埋め込みます。fetchmail同様、feed(fetchamilではpoll)ごとにも上記の設定を適用することができます。新しいfeedを追加したくなったら
% echo 'http://somewhere2/RSS' >> ~/.fetchrssrc
のようにしましょう。
これで
% /usr/bin/local/fetchrss
のようにすれば全feed取得できます。
さて次はmewで読めるようにしましょう。とはいってもprocmailを使えばmaildirにそのまま入れてくれるので基本設定だけでも購読はできます。ただfeedというのは日に日に増していくもので、それだけでmaildirがいっぱいいっぱいになってしまいます。なのでmewの自動整理機能を使ってfeedを整理できるようにしておきましょう。fetchrssはX-Mailerにfetchrss x.x.xという情報をいれるので、これを利用して+net/feedというフォルダに自動整理させるようにしましょう。
~/.mew.el:
(setq mew-refile-guess-alist '(("X-Mailer:" ("fetchrss" . "+net/feed"))))
これでSummery modeでM-oとすると整理対象を自動で検出してマークしてくれます。そのままxすれば自動整理完了です。ただ読むまえから整理しちゃうとメールがあちこちに飛んでいっちゃって、おまけにUマークも消えるので注意しましょう。
さて、feedを読んでいるとhtmlメールが多いことに気づくと思います。htmlタグを高速に脳内で変換できる人を除いて、ほとんどの人はそれを不愉快に思うでしょう。mewにはmew-w3mというemacs-w3mを利用したhtml rendererがあるのでこれを使います。
~/.mew.el:
(require 'mew-w3m)
これでSummery modeでhtmlメールにポイントし.すればw3m parserが動きだし適切にフォーマットしてくれます。これはこれで大変便利なのですが、いちいち.するのは非常に面倒です(人間の欲求は無限です)。それを知人に愚痴ったところ以下のようなコードを教えてくれました(多謝!)。
~/.mew.el:
(defadvice mew-summary-display (after mew-auto-analize-again activate) (mew-summary-analyze-again))))
これでnやpしたときに自動的にparserが動きだし.せずともhtmlメールを華麗に読むことができます。mewのUIはかなり特徴的で悪くいえばアクセシビリティのかけらもないのですが、ここまで環境を構築できればweb based rss readerさながらのUIを堪能することができます。nとpでどんどん読めますし、*でマークもできます。マークというのは非常に重要で、たとえばlivedoor readerがやっているようなpin機能はマークで実現できます。おまけにmewにはフォルダという概念がありますので、たとえば+net/feed/importantとかいうフォルダを作っておいてpinなマークをそのままmoxすることができます。またunder emacsですのでfeed内の文章をそのままキルヤンしたりもできます。その上検索もサポートされていますので、簡単に知識を抽出することができます(簡易knowledge base)。
また以下のように設定することによって簡単に外部ブラウザでそのエントリを確認することができます。ちなみに僕の外部ブラウザはemacs-w3m(すでに外部じゃない)です。
~/.emacs:
(global-set-key "\C-xM" 'browse-url-at-point)
~/.fetchrssrc:
feed http://somewhere/RSS include uri
include uriなfeedのメール本文にはエントリのURIが記述されますので、そこにポイントを合わせてC-xMしてください。
しばらく使ってみた感じでは大きな問題もなく、思っていたより使いやすいインターフェースで購読できてかなり満足しています。そして何よりmdaでprocmailに渡すところにesrの思想を感じます。thanks esr, but your thoughts about the configuration file is so crazy for foreigners.
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/matsuyama/fetchrss-emacs-mewrss30928cfc8aad3059308b/tbping
emacsでAntを使う
M-x compile RET ant RET でコンパイルできるといえばできるのですが、Ant特有のフォーマットが原因で正しくエラーメッセージをパースすることができないことがあります。antに-emacsオプションをつければ(標準の)emacsがパースできる形で表示してくれるらしいのですが、.antrcに自動判別コードを書けばもうすこしスマートにすることができるので紹介しときます。
.antrc:
# Detect (X)Emacs compile mode if [ "$EMACS" = "t" ] ; then ANT_ARGS="$ANT_ARGS -emacs" ANT_OPTS="$ANT_OPTS -Dbuild.compiler.emacs=true" fi
(詳しくはhttp://www.jajakarta.org/ant/ant-1.6.1/docs/ja/faq.html#emacs-mode)
ちなみに僕はマクロを使ってcompileの手間を省いています。 C-x ( compile RET C-a C-k cd /path/to/proj && ant RET C-o TAB C-) みたいな感じで登録しておいて、あとは C-x e でcompileを実行します。ある知人はC-c C-cをcompileに割りあてているらしいのですが、最近emacsのキーバインディングをいじるのが怖くなて、大体はマクロだとか関数だとかで解決しちゃっています。キーバインディングはできるだけデフォルトで一貫するのが一番かなと思っています。それなりに吟味されているわけですし。
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/matsuyama/emacs-ant/tbping
Emacsのページング機能
gccとかkernelなんかのソースを読んでいると ^L という謎の文字が出てきたりしてソースの整備がちゃんとなされているのか微妙に不安になったりするのですが、先日この文字の謎を偶然解明しました。どうやら ^L はEmacsのページング機能に使われるようです。適当な場所で C-q C-l として ^L を挿入しておくと、Emacsがそれをページの区切りとして扱ってくれて、他所から C-x [ や C-x ] でページをめくる感覚ですばやくページ間移動ができるようになるのです。C/C++なんかはどうしてもひとつのファイルがでかくなる傾向があるので、 ^L を適度に挿入してセクション移動を楽にしておくといいかもしれません。ただ正しくエスケープできないエディタで編集すると痛い目にあいそうなのでところかまわず使うのは問題がありそうです。
- Category(s)
- emacs
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/matsuyama/emacs-paging/tbping
Emacsからシェルを有効活用する
vim の ! には負けないぞ!
M-! の出力先が minibuffer なのがむかつくときは C-u M-! としましょう。出力先が current-buffer になります。例えば C-u M-! date RET とすれば現在時刻を current-buffer に書きこむことができます。
region を stdin にしたいときは M-| を使いましょう。例えば csv ファイルの一部を選択して M-| awk -F ',' '{ print $2 }' RET とすると2列目だけを抜きだしたテキストを minibuffer に出力してくれます。 C-u M-| とすれば vim の ! と同じ動作が得られます。つまりコマンドの出力が region に置きかわります。
eshell 使えという話に終始するネタなのですが、個人的に eshell が嫌い(設定がだるい)なのと、プリミティブなシェルが使いたいじゃんということで投下した次第であります。ちなみに eshell で vim を起動して ! するという変態な方法は大好きです。頭悪いうえに無駄が多くてすばらしいですね。
蛇足ですが僕はこの方法を知るまでは screen の copy-mode を使ったり、一度ファイルに保存してシェルで処理したのちに M-x revert-buffer RET するとかアホなことをしていました。シェルの活用はなかなか気付きにくいのが難点ですが、気付きさえすればハッカー気分を十分に味わえるのでなかなか興味深いですね。
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/matsuyama/emacs-shell-command/tbping
fetchrss 0.0.2 をリリースしました
おそらく僕以外誰も使っていないであろう fetchrss の 0.0.2 をリリースしました。 mew の summary-mode で読みやすくするために題名をフォーマットする設定を追加しました。
% svn co https://kserver.panicode.com/panicode/fetchrss/trunk fetchrss % cd fetchrss % make % sudo make install
~/.fetchrssrc
defaults mda /usr/bin/procmail encoding ISO-2022-JP include site title uri body # new option subject "$feed_title :: $entry_title"feed http://hoge/foo.rss
これで「フィード名 :: エントリ名」という題名でメールが送信されます。あとは
~/.mew.el
(setq mew-summary-form '(type (5 date) " " (15 from) " | " t (0 subj)))
って感じに書いておいて
% /usr/local/bin/fetchrss
すると
てな感じになります。
RSSリーダーがすこし使いやすくなったというお話。
PS: ECB の使い方わけわからん。
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/matsuyama/fetchrss-002/tbping
Mew でニュースを読む
以前より希望していた社内ニュースサーバーが動きだしたようなので Mew でニュースを読む方法を調べてみました(おそらく普通に検索しても見つからない)。
まず .mew.el に、
(setq mew-nntp-server "foo.bar")
を書いておき( foo.bar は NNTP サーバー名なので適宜変更してください)、
% emacs -f mew
で、 C-u 2 Z でニュースサーバーに接続し g で任意のニュースフォルダに移動します。たとえば hoge というフォルダなら g -hoge RET です。そして s all あるいは s update でニュースを受信します。あとは普通にメールを読んだり書いたりするように使えると思います( Mew の場合はそうはいかないかもしれませんが)。
非常に使いにくいのですが我慢して使います。
- Category(s)
- emacs
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/matsuyama/read-news-with-mew/tbping
Re:Mew でニュースを読む
ネットニュース2.0時代の始まりです。
Re:Emacs + Mew + Fetchmail + Procmailなメール環境
I have setup my system accordingly. I got a problem is that mew cannot read the mails fetched by fetchmail.
the mails are fetched and send by procmail to my maildir. I found that mew can read the mails after I changed the mail file name to pure figures, like from msg.ntLG to 15.
I have also try below:
(setq mew-mailbox-type 'maildir)
(setq mew-maildir-command "incm")
(setq mew-maildir-command-arg "-u -d /home/example/.maildir")
but it still don't work.
may I have done something wrong?
Best regards,
Bill