Emacs - smartrep.elでrepeatを活性化せよ

くどいプレフィクスキー

Emacsにはプレフィクスキーという概念がありますね。

そのおかげで1ストロークではおさまりきれいないほどの
数のコマンドをキーに割り当てることができます。

それはいいことなんですが、プレフィクスキー
付きのコマンドを何度も実行すると、いい加減
プレフィクスキーがくどいと感じてきませんか?


たとえば、
C-x 3でウィンドウを左右分割してください。

その後C-x {を何回か実行して
ウィンドウを縮めてください。

C-x { C-x { C-x { …と何度もC-x {を
実行するハメになってしまいますね。

repeatはいいけど

これを回避する方法としてrepeatを使う方法があります。

C-x zを使えばC-x { C-x z z …のようにできますが、
やはりC-xがくどいのではないでしょうか?

(global-set-key (kbd "C-,") 'repeat)

とC-,にrepeatを割り当てれば
C-x { C-, C-, …のように操作できます。

それでも同じ操作を繰り返すのにC-,に操作を切り替える
のはしっくりこないと感じるのではないでしょうか?

C-fならば、それを繰り返せばどんどん
カーソルを前に持っていけますね。

それと同じように C-x { { { …と
操作できた方が使いやすいはずです。

逆にウィンドウを広げる C-x } も使えば、
C-x { { } { …のようにキーボードだけ
で微調整ができるようになります。

ウィンドウの大きさを調節するのに
わざわざマウスを使う必要はありません。

smartrep登場

それを実現するのが2年以上前に
登場したsmartrep.elです。

M-x package-refresh-contents
M-x package-install smartrep

にてインストールしてください。

そして以下のコードを評価すると、
C-xの後に{と}でウィンドウの横幅を
調節できるようになります。

(require 'smartrep)
(smartrep-define-key global-map "C-x"
  '(("{" . shrink-window-horizontally)
    ("}" . enlarge-window-horizontally)))

続きはメルマガで

他にもsmartrep的なコマンドを紹介したり、
smartrepを使ってウィンドウ制御をする設定を
明日のメルマガでお話します。お楽しみに!


http://www.mag2.com/m/0001373131.html

Software Design誌でEmacs入門の連載を始めました

お久しぶりです。

気付けば1年以上ブログを放置していましたが、なんとか生きています。

この度、技術評論社Software Design誌5月号からEmacs入門の連載をやらせていただくことになりました。
これからEmacsを始めようとしている人でもEmacsの魅力を存分に味わっていただけるようなコンセプトになっています。
本当に初歩の初歩から始まり、徐々に魅力的なコマンド・外部elispプログラムの数々を紹介します。
その中で根底にある考え方にも触れていきます。

敷居が高くて新参者にとってみれば変態エディタとも言えるEmacsですが、そこには楽しい世界があります。
Emacsはあなたが考えているほど難しくはありません。
今だからこそEmacsに入門する意味があります。

P.S.

Emacsについてもっと深く学びたいならば僕が運営するEmacsネット塾に入ってみてはいかがでしょうか?

http://www.mag2.com/m/0001373131.html

週1のメルマガに加え、読者に対して僕がアドバイザーとなり無制限メールサポートを行っています。
メールサポート込の月々527円ですが、初月無料なのでお試しに登録してみてはいかがでしょうか。

P.P.S.
増税の影響で月々512円から値上りしてしまったことをお詫びします。
512円(2の9乗)に戻す手続き中です。

all-ext.el:対象行を絞り込んでからまとめて編集するM-x allを超強化!occurと融合&anything・helmと連携

お久しぶりです。

みなさん、M-x allって知ってますか?

M-x package-install all

でインストールできるのですが、これはM-x occurのように正規表現にマッチする行を表示します。

occurとの違いは表示結果を書き換えれば、該当部分が自動的に書き変わることです。

ユースケースとしては、編集対象行を絞り込んでから、置換やrectangle系コマンドで一気に編集するって感じです。

便利なので以前から重宝しています。

ただ、occurより劣る点としては、対象行の行番号が出ていない点と、M-g M-n (next-error)とM-g M-p (previous-error)で移動できない点です。

(union all occur)

occurで絞り込んだはいいけれど、その結果をやっぱり編集したいという場合に改めてM-x allを実行するのは面倒ですね。

そこで、拙作all-ext.elの出番です。

MELPAに登録してあるので

M-x package-refresh-contents
M-x package-install all-ext

でインストールしてください。

packageについては以下の設定が必要です。

(add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/"))
(add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t)


all.elがインストールされていないならば同時にインストールされます。

(require 'all-ext)

のみで使えます。


ついでにauto-install.elなどもMELPA経由でインストールできるようにしました。


all-ext.elをインストール後、いつも通りM-x allを実行してください。

M-x occur同様行番号がついていることがわかります。

そしてM-g M-nやM-g M-pを実行してください。
該当行にジャンプできるようになっています。

 *All*バッファからもC-c C-cで該当行にジャンプできます。

これでだいたいM-x occurの置き換えはできたことでしょう。

この時点で書き換え可能なoccurとなりました。

anythingやhelmから使う

今のemacsで検索といえば、anythingやその後継となるhelmを使ってる人も多いでしょう。

M-x anything-occur、M-x anything-c-moccur-occur-by-moccur、M-x helm-occurでMigemoつきでガンガン絞り込めるのは爽快としか言いようがありません。

これらで特定の行を絞り込んだら、その結果を編集したいときもあります。

そのとき、anything-resumeなどで次々と見ていくのは面倒で非効率的です。

ならばいっそのことanythingやhelmで表示されている内容を*All*に放り込めないかと思いました。

M-x anything-occurやM-x helm-occurで絞り込んだ後にC-c C-aを押すと、表示内容による*All*バッファが作成されます。

あとは*All*バッファを編集して元のバッファに反映させてください。

occurだけでなく、行番号とその行の内容を表示しているanything・helmコマンドならばなんでも使えます。

http://www.rubyist.net/~rubikitch/archive/all-ext-1.png

http://www.rubyist.net/~rubikitch/archive/all-ext-2.png

ert-expectations: 新世代ユニットテストフレームワーク in Emacs Lisp

お久しぶりです。

世の中はすっかりEmacs24になってきたようですね。

本日、el-expectations.elの後継となるert-expectations.elをリリースしたのでお知らせします。

el-expectations.elは現役で使っているのですが、テストが失敗したときのレポート機能が弱くて不便に思っていました。
Emacs24ではユニットテストフレームワークのERTが標準添付になったことにより、ERTを内部で呼び出すことでその問題を克服しました。

基本的な使い方はel-expectationsと変わりません。
ERTについて学んでなくても今すぐ使えます。

M-x install-elisp-from-emacswiki ert-expectations.el
M-x install-elisp-from-emacswiki el-mock.el
あるいは
M-x auto-install-batch el-expectations
でインストールしてください。

※auto-install-batch-list.elはert-expectations.elを読むように更新しました。

http://www.emacswiki.org/emacs/download/ert-expectations.el
http://www.emacswiki.org/emacs/download/el-mock.el

たとえば、成功するテスト2つと失敗するテスト2つを実行させましょう。

el-expectationsと同じようにS式にてC-M-xを押します。

(expectations
  (desc "success")
  (expect 10
    (+ 4 6))
  (expect 5
    (length "abcde"))
  (desc "fail")
  (expect 11
    (+ 4 6))
  (expect 6
    (length "abcde")))

すると、*ert*バッファに次のように出力されます。

テスト失敗時のレポートがより詳しく出力されるのです。

Selector: t
Passed: 2
Failed: 2 (2 unexpected)
Total:  4/4

Started at:   2012-10-09 15:37:17+0900
Finished.
Finished at:  2012-10-09 15:37:17+0900

..FF

F erte-test-00003
    (ert-test-failed
     ((should
       (equal 11
              (mock-protect
               (lambda nil
                 (+ 4 6)))))
      :form
      (equal 11 10)
      :value nil :explanation
      (different-atoms
       (11 "#xb" "?^K")
       (10 "#xa" "?\n"))))

F erte-test-00004
    (ert-test-failed
     ((should
       (equal 6
              (mock-protect
               (lambda nil
                 (length "abcde")))))
      :form
      (equal 6 5)
      :value nil :explanation
      (different-atoms
       (6 "#x6" "?^F")
       (5 "#x5" "?^E"))))

また、desc式を置いていれば、テスト名(erte-test-00003など)のリンクを辿ればジャンプできます。

その他はel-expectations.elの説明を参照してください。
http://d.hatena.ne.jp/rubikitch/20080409/elexpectations

P.S.

Emacsのネット塾を運営しています。
最新の技術を数分で自分のものにすることができます。
ここで一気にライバルに差をつけてしまいましょう。
週1のメルマガに加え、僕がアドバイザーとなり無制限サポートを行っています。

anything-grep.elで最初からマッチ行をハイライトするようにした

anything.elの後継としてhelm.elが開発されていますが、anything.elはまだ死んでいません。

anything.elの現行ユーザのために、バグ修正をメインにメンテナンスし続けます。

ものすごい久し振りですがanything-grep.elを修正しました。

grepの結果をanything.elで絞り込む anything-grep.el をリリース - http://rubikitch.com/に移転しました

変更点はたった1点で、何も設定しなくてもpersistent-actionでマッチした行をハイライトできるようにしました。

(require 'anything-grep) のみでおkです。

M-x install-elisp-from-emacswiki anything-grep.el

Gitリポジトリではcontribに入っているので注意。

Emacs24のelispは速いぞ!ベンチマークを測定してみた

Emacs24「ねんがんのlexical-bindingをてにいれたぞ!」

10年にわたって開発してきたlexical-bindingがついにEmacs24に取り込まれました。

これはEmacs界の大大大ニュースです!

lexical-bindingが有効になると、letがlexical-letに化けます。

lexical-bindingは速いということらしいのですが、現時点でベンチマークをみかけないので測定してみました。

lexical-bindingは変数lexical-bindingをtにすると有効になります。
この変数は、バッファローカル変数なのでsetqで設定しても他のバッファに影響はありません。

M-x ielmで実験してみましょう。

ELISP> (setq lexical-binding t)
t
ELISP> (defun f1 (n) (let ((i 1) (s 0)) (while (<= i n) (setq s (+ s i)) (setq i (1+ i))) s))
f1
ELISP> (f1 10)
55
ELISP> (byte-compile 'f1)
nil
ELISP> (symbol-function 'f1)
(closure
 (t)
 (n)
 (let
     ((i 1)
      (s 0))
   (while
       (<= i n)
     (setq s
           (+ s i))
     (setq i
           (1+ i)))
   s))

ぬ、lexical-bindingを設定したらielmではバイトコンパイルできないぞ??

とりあえず、適当なファイルを開いて以下の内容にして、C-u M-x byte-compile-file。

lexical-bindingをファイル内で有効にするには、こんなふうに一行目に -*- lexical-binding: t -*- を入れること。

;; -*- lexical-binding: t -*-
(defun f1 (n) (let ((i 1) (s 0)) (while (<= i n) (setq s (+ s i)) (setq i (1+ i))) s))


そこでM-x rename-uniquelyでバッファ名を変えて、再びM-x ielm。
こっちはlexical-bindingを使わない方。

ELISP> (defun f2 (n) (let ((i 1) (s 0)) (while (<= i n) (setq s (+ s i)) (setq i (1+ i))) s))
f2
ELISP> (byte-compile 'f2)
#[(n)
  略(バイトコード)
  [s i n 1 0]
  3]

さっそく測定。

ELISP> (benchmark-run 1 (f1 100000))
(0.016059 0 0.0)
ELISP> (benchmark-run 1 (f2 100000))
(0.022624 0 0.0)

lexical-bindingによって3割ほど高速化しました。

P.S.

Emacsのネット塾を運営しています。
最新の技術を数分で自分のものにすることができます。
ここで一気にライバルに差をつけてしまいましょう。

Emacs Lispテクニックバイブル正誤


明けまして、おめでとうございます。

今年もよろしくお願いします。

昨年発行したEmacs Lispテクニックバイブルは好評です。

絶賛の声をたくさんいただきました。

本当にありがとうございます。

万全を期していたのですが、残念
ながら誤植がみつかってしまいました。

読者の皆様には大変御迷惑をおかけしました。

================================================================
p132 4-3-2
注1が行方不明

注1 筆者は4分割以上はしていません。
================================================================


================================================================
p142 5-1-2

書式 (round &optional 整数)

書式 (random &optional 整数)
================================================================

================================================================
p161 6-3-2

書式 (make-hash-table :key 'equal)

書式 (make-hash-table :test 'equal)
================================================================

================================================================
p184 6-9-7

gensymは展開式の「外側」で使います。、

gensymは展開式の「外側」で使います。
================================================================

================================================================
p195 7-2-3

;;; defmacroにはリスト分解機能がある

;;; defmacro*にはリスト分解機能がある
================================================================

================================================================
p200 7-4-2

(f1 (lambda () v))) ; => externa

(f1 (lambda () v))) ; => external
================================================================

================================================================
p205 7-6-1

分岐節にい「型名」を指定するところが異なります。

分岐節に「型名」を指定するところが異なります。
================================================================

================================================================
p248 9-3-3 表9.1

window-configuration-change-hook ウィンドウ構成構成変更後

window-configuration-change-hook ウィンドウ構成変更後
================================================================

P.S.
Emacsメールマガジン発行しています。

完全メールサポートつきで初月無料
でなので安心してご登録ください。