(rubikitch loves (Emacs Ruby CUI Books)) このページをアンテナに追加 RSSフィード

2011-02-26

[]savekill.elリリース - Emacsの突然死に備えて

savekill.elをリリースしました

動機

最近、なぜかよくわかりませんが、Emacsが突然死することありますよね?

あまり使いこんでない人はあまり経験がないかもしれませんが、ヘビーユーザーにとっては日常茶飯事です。

不安定すぎて落ちまくるほどではないですが、僕のところでは数日に1回のペースで落ちてしまいます。

Emacs以外を使っていると、ソフトウェアの突然死の恐怖はよくわかると思います。

「保存してなくて、今までの作業がパーになった!」

誰もが一度はそんな経験があるでしょう。

もちろん、そこは我等がEmacs、ちゃんと防衛線は張っています。

Emacsには自動セーブ機能があり、一定時間以上保存していないと、一時ファイルに保存する仕組みになっています。

そのため、Emacsが落ちたとしても、当該ファイルに対し M-x recover-file を実行すれば、ほとんどの作業を取り戻すことができます。

あるいは、 auto-save-buffers.el を使うことで、手で保存をする必要をなくすことすらできます。

しかし、これでも障害対策は不十分だと僕は思っています。

大量のテキストをC-wでカットすると、当然バッファ(ファイル)からは、大量のテキストが失われます。

カットしたテキストはキルリングに格納されています。

もし、C-yで貼り付けする前にEmacsがお亡くなりになったら…

当然目もあてられません。

そこで、キルリングにも防衛線を張っておくのが、このsavekill.elです。

概要

savekill.elは、キルリングディスクに保存・復元する小さなEmacs Lispです。

実質10行に満たないサイズです。

C-wやM-w等、テキストをキルリングに入れる動作をしたときに、自動的に保存されます。

そして、Emacs起動時にキルリングの内容は復元されます。

これならば、万一の時も安心ですね!

インストールと設定

拙作auto-install.el(導入記事)を導入すると、

M-x install-elisp-from-emacswiki savekill.el

ダウンロード、保存、バイトコンパイル、ロードまでできます!

ブラウザで見るには↓へどうぞ。

http://www.emacswiki.org/cgi-bin/wiki/download/savekill.el

そして、以下の設定を.emacsに加えてください。



(require 'savekill)



使い方

特になし!通常通りEmacsを操作してください。空気のようなEmacs Lispです。

参考リンク

http://d.hatena.ne.jp/tomoya/20110217/1297928222 では、recentfのリスト一定時間後に自動保存することで、突然死に備えています。

Emacsの突然死を憎むのは勝手です。

しかし、そもそもバグのないソフトウェア存在しません。

突然死は起こるものとして防衛線を張っておくことこそが、我々ユーザにできる現実的な行動だと考えています。

返信


rilさん

きちんとキルリングは保存されるのですが、起動時に、*Compile-Log*バッファWarning: ad-Orig-kill-new called with 3 arguments, but accepts only 1-2と表示されるようになって しまいました。


こちらでは再現しませんね。他のパッケージがkill-newをアドバイスしてたりしませんか?

id:tkf41 さん

anything.elのadaptive-historyのバグの可能性があります。

使っているならば、Emacs起動時に

rm ~/.emacs.d/anything-c-adaptive-history

で削除してください。

最新のanything.elでも起きますか?

rilril 2011/02/28 21:20 便利なEmacs Lispをありがとうございます。
きちんとキルリングは保存されるのですが、起動時に、*Compile-Log*バッファにWarning: ad-Orig-kill-new called with 3 arguments, but accepts only 1-2と表示されるようになってしまいました。これは仕様なのでしょうか。

rilril 2011/03/05 15:40 .emacsの中で、(require 'auto-install)を(require 'savekill)の前においていたことが問題だったようです。順序を逆にしたら表示されなくなりました。ありがとうございました。

tkf41tkf41 2011/12/23 07:38 とても便利に使わせてもらっていますが,時々、"mapcar: Wrong type argument: stringp, \.\.\."というエラーでkillできなくなります。 kill-ring の末尾を見ると \.\.\. という記号(""で囲まれていない)が入っていて、それが原因のようですが、なぜこんな要素が入っているのかは謎です。

*Backtrace* の中身は以下のような感じです。

Debugger entered--Lisp error: (wrong-type-argument stringp \.\.\.)
substring-no-properties(\.\.\.)
mapcar(substring-no-properties (#("text" 0 4 (fontified t face font-lock-comment-face)) <略> "outline-next-visible-heading" "lambda ()" \.\.\.))
save-kill-internal()
kill-new(#("text" 0 4 (fontified t face font-lock-comment-face)))
ad-Orig-copy-region-as-kill(159 163)
copy-region-as-kill(159 163)
kill-ring-save(159 163)
call-interactively(kill-ring-save nil nil)

tkf41tkf41 2012/01/04 07:11 rubikitchさん、ありがとうございます。 ~/.emacs.d/anything-c-adaptive-history はありませんでした。最新の anything.el に変えて様子を見てみます。

yibeyibe 2012/02/03 20:44 (require 'savekill) しているファイルを Emacs 23.3.1 でバイトコンパイルした際に
ril さんと同様の警告が出たので、最小限のコードで再現を試みたところ、23.3.1 では
コンパイル中に `kill-new' へのアドバイスを活性化させるだけでこれが発生してしまう
ようです。(詳しく追ってないので不明ですが本体のバグかも。23.1.1 では発生せず)
次の内容のファイルを emacs -Q -batch -f batch-byte-compile した場合に発生します:

(eval-and-compile
(defadvice kill-new (after savekill activate)))

savekill.el のほうで activate フラグを `defadvice' するのと同時に指定せず、
定義後に `ad-activate' の第2引数に負数を指定して実行することで動作に影響なく
回避できるようです。

(defadvice kill-new (after savekill) ... )
(ad-activate 'kill-new -1)


それと id:tkf41 さんの症状は anything 以外の原因でも何かのはずみで
`print-length' が nil 以外になってしまっている場合に起こり得ることなので、
`prin1-to-string' を走らせる時に確実に `print-length' を nil に、
`print-level' も nil または 1 などに固定しておいたほうがいいと思います。

(let (print-length print-level)
(prin1-to-string '("abc" "def" "ghi")))
;=> "(\"abc\" \"def\" \"ghi\")"

(let ((print-length 2) (print-level 1))
(prin1-to-string '("abc" "def" "ghi")))
;=> "(\"abc\" \"def\" ...)"

(let ((print-length nil) (print-level 0))
(prin1-to-string '("abc" "def" "ghi")))
;=> "..."

tkf41tkf41 2012/03/30 02:34 save-kill-file-name で指定したファイル無い時に Emacs を起動するとエラーが出ます。 NOERROR を渡してみてはどうですか:

(add-hook 'after-init-hook (lambda () (load save-kill-file-name t)))

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/rubikitch/20110226/savekill