2009-07-16 (木)

Emacs講座 -第9回- C コーディングスタイル [Emacs講座]

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

cc-mode


Emacs では cc-mode というパッケージが C 系言語のコーディングスタイ
ルを統括しています。cc-mode はパッケージ名で、個々のメジャーモード
名は c-mode や c++-mode です。

cc-mode がサポートする言語を cc-mode.el から抜粋しておきます。

CC Mode supports K&R and ANSI C, ANSI C++, Objective-C, Java,
CORBA's IDL, Pike and AWK with a consistent indentation model
across all modes.


設定例


前述の言語の中で私が使うのは C 言語だけで、以下の設定をしていました。

(add-hook 'c-mode-common-hook
          (lambda ()
            (c-set-style "bsd")                            ;;; (a)
            (setq c-basic-offset 4)                        ;;; (b)
            ;; 演算式が複数行にまたがるときのオフセット
            (c-set-offset 'statement-cont 'c-lineup-math)  ;;; (c)
            ;; 行末のスペースやタブに色づけして警告する。
            (setq show-trailing-whitespace t)))            ;;; (d)


c-mode-common-hook は C と C++ 両方に影響する hook です。C だけに設
定したい場合は c-mode-hook を、C++ だけに設定したい場合は
c++-mode-hook を使います。

インデントは以下の手順で設定します。

1. 近いスタイルを選ぶ。
2. 気にいらないインデント部分を見つける。
3. Ctl-c Ctrl-s でインデントに効いてくる変数を見つける。
4. その変数の値をc-set-offset関数で変える。


1 が (a) です。加えて (b) も設定しています。私の場合は bsd スタイル
が一番しっくり来ました。

bsd 以外の他のスタイルは M-x c-set-style し、TAB キーを押すと確認で
きます。

2 は私の場合、以下のようなインデントでした。

ret = a +
    b +
    c;


このようにしたかったのです。

ret = a +
      b +
      c;



3 の見つけ方です。

まず "b +" の行で Ctrl-c Ctrl-s します。すると *Messages* バッファ
に以下のように表示されました。

Syntactic analysis: ((statement-cont 107))

この行のインデントは statement-cont によって設定されていることが分
かりました。

statement-cont とは何でしょうか。

cc-mode では c-basic-offset と c-offsets-alist がインデントに関係し
てきます。この c-offsets-alist を構成する値が statement-cont です。
c-offsets-alist の値を確認してみると以下のように設定されていました。

(statement-cont . +)


4 の方法です。が、ここで一点注意。

c-basic-offset は (b) のように setq() で設定すれば良いのですが、
c-offsets-alist は直接 setq() でいじってはいけません。
c-set-offset() で修正します。

(statement-cont . +) に相当する設定は以下になります。

(c-set-offset 'statement-cont '+)


'+ は c-basic-offset の値です。'++ にすると 2 倍になるそうです。

しかし、今回は意図した設定になりませんでした。どうやらこの設定を調
べていた当時、2ch で質問して c-lineup-math にしたようです。チャンチャン。
Emacs part8 の 891 レス目 - 2ch

(d) はコメントのとおり、不必要なスペースやタブに色付けして警告する
設定です。ソースによっては警告されまくりで、真っ赤になったりするの
であまりオススメはしません。

第9回終わり。

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

2009-07-10 (金)

Emacs講座 -第8回- タブ幅 [Emacs講座]

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

3つの変数


Emacs のタブ幅には、3つの変数が関係しています。

tab-width


タブコードを半角スペースいくつ分で表示するかを制御する変数です。
各バッファ毎に設定できます。デフォルトは 8 です。

default-tab-width


tab-width のデフォルト値です。全てのバッファに影響する変数です。
デフォルトは 8 です。

tab-stop-list


TAB キーを押した時に、カーソルが移動するカラムの位置です。デフォル
トは (8 16 24 32 40 48 56 64 72 80 88 96 104 112 120) です。

例えばタブ幅を 4 に変更したい場合は以下のようなコードを ~/.emacs に
記述します。

(setq-default tab-width 4)
(setq default-tab-width 4)
(setq tab-stop-list '(4 8 12 16 20 24 28 32 36 40 44 48 52 56 60
                      64 68 72 76 80 84 88 92 96 100 104 108 112 116 120))



関数化してみよう


tab-stop-list の設定が少し煩雑ですよね。以前は手計算で
tab-stop-list の中身を作っていたのですが、見事に計算間違いした経験
があります。そんな自分が嫌になったので、関数化しました。

「下記設定」と「前述の設定をタブ 8 に変えたもの」は同じ意味です。

(defun set-aurora-tab-width (num &optional local redraw)
  "タブ幅をセットします。タブ5とかタブ20も設定できたりします。
localが non-nilの場合は、カレントバッファでのみ有効になります。
redrawが non-nilの場合は、Windowを再描画します。"
  (interactive "nTab Width: ")
  (when local
    (make-local-variable 'tab-width)
    (make-local-variable 'tab-stop-list))
  (setq tab-width num)
  (setq tab-stop-list ())
  (while (<= num 256)
    (setq tab-stop-list `(,@tab-stop-list ,num))
    (setq num (+ num tab-width)))
  (when redraw (redraw-display)) tab-width)

(set-aurora-tab-width (setq default-tab-width (setq-default tab-width 8)))



動的なタブ幅の切り替え


開いたテキストが自分のタブ幅と異なるため、インデントがずれた経験は
ありませんか?

キー操作で動的に切り替えられるように、私は以下の設定をしています。
結構おすすめです。(ctl-q-map については、第5回を参照してください。)

(define-key ctl-q-map (kbd "2") (lambda () (interactive) (set-aurora-tab-width 2 t t)))
(define-key ctl-q-map (kbd "4") (lambda () (interactive) (set-aurora-tab-width 4 t t)))
(define-key ctl-q-map (kbd "8") (lambda () (interactive) (set-aurora-tab-width 8 t t)))


例えば "Ctrl-q 4" すると、カレントバッファのタブ幅が 4 になります。
他のバッファには影響を与えません。

ファイル単位でのタブ幅の切り替え


ファイルの先頭に以下を書いておくと、Emacs はそのファイルをタブ 4 で開きます。

-*- tab-width: 4 -*-


ファイルの最後に書くことも出来ます。

Local Variables:
tab-width: 4
End:


tab-width に特化された実装になっているわけではありません。
このような記述をすると、ファイル毎に変数値を設定できるのです。

英語ですが、Info にも詳しい説明が書いてあります。

1. M-x info [Enter]
2. 以下の行で Enter
  * Emacs: (emacs). The extensible self-documenting text editor.
3. g を押したあと、Specifying File Variables [Enter]


関連する関数


タブに関連する関数をご紹介します。それぞれ M-x で呼び出せます。

tabify


リージョン内の連続する空白をタブに変換します。変数 tab-width がこの
動きを制御します。

untabify


リージョン内のタブを複数のスペースに変換します。変数 tab-width がこ
の動きを制御します。

第8回終わり。

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

2009-07-09 (木)

Emacs講座 -第7回- 文字コード [Emacs講座]

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

さあ、文字コードです。

文字コードの設定


いきなり矛盾しますが、最近の Emacs(例:23.3) では文字コードの設定は
不要です。

Emacs はデフォルトの状態でも、文字コードを自動判別してファイルを開
くことが出来ます。新規作成ファイルの文字コードも locale の設定によっ
て自動決定されます。

もしあなたの ~/.emacs に下の設定が書いてあったら削除しましょう。
もはや廃れた設定です。参考情報: mule-ja-2009:09813

(set-language-environment "Japanese")
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(setq-default buffer-file-coding-system 'utf-8)



Mac OS X における文字コードの設定


Mac ではファイルシステムに HFS+ を使っているため、濁点や半濁点の扱
いが Windows と Linux と異なるそうです。これを回避するため、以下の
設定が必要とのこと。Emacs-23.2 以上で設定可能です。

(require 'ucs-normalize)
(set-file-name-coding-system 'utf-8-hfs)
(setq locale-coding-system 'utf-8-hfs)


紹介マニアどらふと版: Mac OS X におけるファイル名に関するメモ(NFC, NFD等)

文字コード関連の便利機能



Ctrl-x Ctrl-m c <文字コード> [Enter] Ctrl-x Ctrl-v [Enter]


文字コードを指定し直して、現在開いているファイルを開き直す方法です。
結構重宝します。<文字コード> は TAB で補完出来ます。

Ctrl-x Ctrl-m f <文字コード> [Enter]


現在開いているファイルの文字コードを変更する方法です。たくさんのファ
イルを変換する場合は nkf なんかを使うのでしょう。

第7回終わり。

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

追記(2011-02-08):
文字コードの設定は set-language-environment() と
prefer-coding-system() だけで良いようですので、他を削除しました。

追記(2011-08-06):
set-language-environment() と prefer-coding-system() さえも必要ない
ことがわかったので、全体的に書き換えました。

2009-07-05 (日)

Emacs講座 -第6回- load-path [Emacs講座]

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

本項は、ネット上から *.el をダウンロードして、いろいろ試したくなっ
てきたあたりで読むと良いと思います。load-path の仕組みを理解しましょう。

load-path とは何か?


UNIX や Windows 等に存在する「環境変数 PATH」の Emacs 版です。

例えば ls を実行すると、「環境変数 PATH」に登録された最初のディレク
トリから ls が検索され、最初にヒットした ls が使われますよね?
また、どのディレクトリにも ls が存在しなければ、

command not found: ls

などといったエラーが発生します。

Emacs では例えば ~/.emacs に以下のようなコードを書くと load-path が
参照されます。

(require 'hoge)


load-path は Emacs Lisp の変数です。どんな値が入っているのかは第3回
の方法で調べられます。

load-path には複数のディレクトリが登録されているはずです。

まず先頭のディレクトリについて、以下の順で検査が行われます。第2回
.emacs と同じですね。

1. hoge.elc が存在するか?
2. hoge.el が存在するか?
3. hoge が存在するか?


1, 2, 3 のどれにも当てはまらなければ、次のディレクトリが検査されます。
全てのディレクトリで当てはまらなければ、以下のエラーが発生します。

Cannot open load file: hoge


load-path を構成するディレクトリ


デフォルトの設定では、以下の順番に構成されているはずです。

1. <PREFIX>/share/emacs/<EMACS-VERSION>/site-lisp 以下全てのディレクトリ
2. <PREFIX>/share/emacs/site-lisp 以下全てのディレクトリ
3. <PREFIX>/share/emacs/<EMACS-VERSION>/lisp 以下全てのディレクトリ


Emacs-22.3 を /usr/local 以下にインストールした場合は、このようにな
ります。

1. /usr/local/share/emacs/22.3/site-lisp 以下全てのディレクトリ
2. /usr/local/share/emacs/site-lisp 以下全てのディレクトリ
3. /usr/local/share/emacs/22.3/lisp 以下全てのディレクトリ


1 は当該バージョンの Emacs だけに参照させたい *.el を置くディレクト
リです。デフォルトでは subdirs.el というファイルだけが置かれています。
(subdirs.el は後で説明するので、覚えておいて下さい。)

2 は全てのバージョンの Emacs から参照させたい *.el を置くディレクト
リです。ここにも、デフォルトでは subdirs.el というファイルだけが置
かれています。

3 は当該バージョンの Emacs に付属する、全ての *.el が置かれているデ
ィレクトリです。

load-path が構築される仕組み


<PREFIX>/share/emacs/site-lisp 以下に適当な名前のディレクトリを作っ
て、Emacs を再起動してみて下さい。追加したディレクトリが load-path
に追加されていますよね。なぜでしょう?

Emacs は起動時に以下の 3 つの subdirs.el を評価します。

1. <PREFIX>/share/emacs/<EMACS-VERSION>/site-lisp/subdirs.el
2. <PREFIX>/share/emacs/site-lisp/subdirs.el
3. <PREFIX>/share/emacs/<EMACS-VERSION>/lisp/subdirs.el


12 の subdirs.el の内容は同じで、以下のように記載されているはず
です。

(if (fboundp 'normal-top-level-add-subdirs-to-load-path)
    (normal-top-level-add-subdirs-to-load-path))


この Emacs Lisp 式の意味は
「normal-top-level-add-subdirs-to-load-path という関数が存在すれば、
normal-top-level-add-subdirs-to-load-path を実行する」になります。

normal-top-level-add-subdirs-to-load-path() はディレクトリを再帰的
に探索し、見つかったディレクトリを load-path に追加する関数です。た
だし、以下のディレクトリは load-path に追加しません。

"." で始まるディレクトリ
"RCS" "CVS" "rcs" "cvs" という名前のディレクトリ
".nosearch" というファイルが存在するディレクトリ


3 の subdirs.el には Emacs-22.3 の場合、以下のように記載されている
はずです。

(normal-top-level-add-to-load-path
 '("url" "textmodes" "progmodes" "play" "obsolete" "net" "mh-e" "mail" "language"
   "international" "gnus" "eshell" "erc" "emulation" "emacs-lisp" "calendar" "calc"))


まあ、だいたい意味は分かりますよね。(説明するのが面倒になってきまし
た..。^^;)

load-path にユーザ指定のディレクトリを追加する方法


root 権限を持っていない等の理由から、前述の site-lisp 以下に *.el
をコピーできない場合もあるでしょう。その場合は、load-path にディレ
クトリを追加します。

例えば、"~/share/elisp" を追加したい場合は以下を ~/.emacs に設定し
て下さい。

(add-to-list 'load-path "~/share/elisp")


この例では load-path の先頭に "~/share/elisp" が追加されます。

ユーザ指定のディレクトリ以下全てを load-path に追加する方法


上の方法だと、~/share/elisp 以下にディレクトリを追加するたびに
add-to-list() を追加する必要があり、少々面倒です。そこで前述の
normal-top-level-add-subdirs-to-load-path を利用します。

先にコードを晒します。

(defconst my-elisp-directory "~/share/elisp" "The directory for my elisp file.")

(dolist (dir (let ((dir (expand-file-name my-elisp-directory)))
               (list dir (format "%s%d" dir emacs-major-version))))
  (when (and (stringp dir) (file-directory-p dir))
    (let ((default-directory dir))
      (add-to-list 'load-path default-directory)
      (normal-top-level-add-subdirs-to-load-path))))


このコードを ~/.emacs に設定すると、load-path の先頭に以下の順番で
追加されます。

1. "~/share/elisp<emacs-major-version>" 以下全てのディレクトリ
2. "~/share/elisp" 以下全てのディレクトリ


使用している Emacs のバージョンが 22.3 の場合、
<emacs-major-version> は 22 になります。
変数 my-elisp-directory は適宜変更して下さい。

require 以外の *.el 読み込み方法


require は、ファイル中に (provide 'hoge) などと書かれている *.el を
読み込む関数です。そうすることで、require 済みかを以下の方法で判別
できます。

(if (featurep 'hoge)
    ...)


また、(require 'hoge) は何度実行しても、hoge.el は一度しか読み込ま
れません。

require と似たものに load があります。featurep() による検査は行えま
せん。load すると、安直に hoge.el が load されます。

(load "hoge")



少し特殊なものに autoload があります。この式が評価された時点では
hoge.el は読み込まれません。hogehoge という関数が実行された直後に
hoge.el が読み込まれ、その後 hogehoge() が実行されます。

(autoload 'hogehoge "hoge" nil t)



他、load-file という関数もあります。M-x load-file を実行し、読み込
みたいファイルを指定すると、そのファイルが load されます。つまり、
load-path とは直接関係ありません。

関連する関数


load-path に関連する関数をご紹介します。それぞれ M-x で呼び出せます。

locate-library
  指定した *.el の場所をフルパスで出力。

list-load-path-shadows
  *.el の名前が同じであるため、load されない *.el を表示。

第6回終わり。

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

2009-07-02 (木)

Emacs講座 -第5回- キーバインドの変更 [Emacs講座]

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

Emacs では数多くの関数がキーに割り当てられています。その中には押し
やすいものもあれば、押しづらいものもあります。また、全ての関数がキー
に割り当てられているわけではないため、頻繁に使う関数なのに

M-x hogehoge [Enter]

などと実行しなければならない場合もあります。

という状況ではありますが、Emacs のキーバインドはフルカスタマイズ可
能です。カスタマイズするしかないでしょう。:-)

ポリシー


私は以下のことを念頭に置いて、キーバインドを変更しています。

- デフォルトのキーバインドは、極力変更しない。
- 連打することがあるコマンドは1ストローク(例: Ctrl-t)。
- 連打する必要が少ない、もしくはやや危険なコマンドは2ストローク
 (例: Ctrl-q Ctrl-h)。
- 2ストロークにする時は、全て Ctrl-q Ctrl-h のような Ctrl を介したも
 のにする。例えば Ctrl-q h だと、Ctrl キーを一旦ニュートラルにする必
 要があるので、Ctrl-q Ctrl-h より確実に遅い。
- カーソルキーやファンクションキーは遠いので、極力使わない。


知っておくべきこと


例えば、Ctrl-n というキーを押すと next-line という関数が呼ばれます。
Ctrl-f は forward-char です。ただの a というキーにも
self-insert-command という関数が割り当てられています。

このように、全てのキーに関数が割り当てられています。

では、どうやって調べたらよいでしょうか?これを調べるヘルプコマンド
が、以下になります。ミニバッファに関数名が表示されます。

F1 c 調べたいキー操作


"F1 c" 自体も、もちろん関数呼び出しとなっています。上の方法で調べる
と、describe-key-briefly という関数だと分かります。

逆に、ある関数がどのキーに割り当てられているのかは、"F1 w" で分かり
ます。

以上を知っていれば、現在のキーバインドがどのように設定されているか
分かるはずです。

よく使うヘルプコマンド一覧を記載しておきますね。"F1 Ctrl-h" すると、
一覧から以下のヘルプを選択することも出来ます。

キー関数名説明
F1 cdescribe-key-briefly指定したキーに対応する関数名を、ミニバッファに表示
F1 kdescribe-key指定したキーに対応する、関数のヘルプを表示
F1 fdescribe-function指定した関数のヘルプを表示
F1 wwhere-is指定した関数に対応する、全てのキーを表示
F1 bdescribe-bindings現在のバッファのキーバインド一覧を出力
F1 mdescribe-mode現在のバッファのメジャーモードとマイナーモードの説明を出力
F1 aaproposキーワードにマッチする関数と変数を検索
F1 iinfoInfoを閲覧

基本となる設定方法



global-map


一例として。Ctrl-z すると、M-x shell を実行できるようにしてみます。

デフォルトで Ctrl-z に割り当てられている関数は、
iconify-or-deiconify-frame です。フレームが最小化されます。
これを置き換えます。

設定内容はこちらになります。~/.emacs に記載します。

(define-key global-map (kbd "C-z") 'shell)


define-key が関数名です。後ろの global-map, (kbd "C-z"), 'shell は
define-key への引数になります。

- global-map というのは全てのバッファに影響するキーマップです。
- (kbd "C-z") は Ctrl-z というキーのことだと思って下さい。
-- 他に (kbd "C-x C-p"), (kbd "M-p"), (kbd "C-M-p"), (kbd "C-,"),
  (kbd "<right>"), (kbd "<f8>") などが使えます。
-- (kbd "ほげ") の ほげ の部分は、"F1 c" した後、調べたいキーを
  押すと分かります。
- 'shell は関数名です。"'"(シングルクォート) を忘れないで下さい。


global-map 以外のキーマップ


有名なところでは、esc-map と ctl-x-map があります。global-map と同
じく、全てのバッファに影響するキーマップです。

以下は設定の一例です。M-j や Esc-j すると、goto-line を実行します。

(define-key esc-map (kbd "j") 'goto-line)


後述しますが、キーマップを自作することも出来ます。

他にも c-mode-base-map や dired-mode-map、isearch-mode-map などがあ
ります。apropos で調べられます。

Ctrl-u F1 a -map$ [Enter]

Emacs の Info や、elisp のソースを確認するのも良いと思います。

キーマップを自作する


デフォルトのキーバインドをできるだけ変更しないで、自分好みの設定を
しようとするとあることに気づくはずです。

「どのキーも埋まっているじゃん。。。」

使わなそうなキーなら良いのですが、実は使えるキーで、後で後悔するか
もしれません。

ここで、"Ctrl-なんとか"というキーを一つずつ調べてみました。結果、
Ctrl-q の使用頻度が少ないことに気がつきました。

Ctrl-q には quoted-insert という関数が割り当てられています。コント
ロールコード(ASCII コードの Ctrl-l や Ctrl-i 等)を挿入できます。

そこで、ctrl-q-map を作ってみることにしました。

そうすると、"Ctrl-q Ctrl-アルファベット" や "Ctrl-q 記号" などを自
由に使えるようになります。quoted-insert は "Ctrl-q Ctrl-q" に追いや
ることにします。

前置きが長くなりましたが、設定内容を下記に記載します。
「your-favorite-funca〜your-favorite-funcz」はもちろん、割り当てた
い関数名にしてください。

(defvar ctl-q-map (make-keymap))                 ;;; (★a)
(define-key global-map (kbd "C-q") ctl-q-map)    ;;; (★b)
(define-key ctl-q-map (kbd "C-a") 'your-favorite-funca)
(define-key ctl-q-map (kbd "C-b") 'your-favorite-funcb)
.
.
(define-key ctl-q-map (kbd "C-q") 'quoted-insert)
.
.
(define-key ctl-q-map (kbd "C-z") 'your-favorite-funcz)

;;; (★a) ctrl-q-map という変数を新たに定義しました。
;;;       新規作成したキーマップを代入しています。
;;;
;;; (★b) ctrl-q-map を Ctrl-q に割り当てています。


かなり自由に設定できるようになりましたね!

引数を指定したキーバインドの設定



-第4回- カーソル移動」の「スクロールアップ、スクロールダウン」の
Ctrl-u 1 Ctrl-v のような操作をキーに割り当てることもできます。

一例として1行スクロールアップする機能("Ctrl-u 1 Ctrl-v" に相当)を
"Ctrl-;" に割り当てることにします。

方法1


(1) 1行スクロールアップする関数 scroll-up1 を新規作成します。

(defun scroll-up1 ()
  (interactive)
  (scroll-up 1))


(2) scroll-up1 を "Ctrl-;" に割り当てます。

(define-key global-map (kbd "C-;") 'scroll-up1)



方法2


1行スクロールアップする無名関数を作って、直接 "Ctrl-;" に割り当て
ます。

(define-key global-map (kbd "C-;") (lambda () (interactive) (scroll-up 1)))



参考資料


今回は少しだけ「emacs 雑記」を参考にさせて頂きました。keybind のペー
ですね。

英語ですが、Info にも詳しい説明が書いてあります。

1. M-x info [Enter]
2. 以下の行で Enter
  * Emacs: (emacs). The extensible self-documenting text editor.
3. g を押したあと、Key Bindings [Enter]

最新の Info って誰か翻訳していないのかなあ。手元にあるのは 20.6 の
日本語マニュアル...。

第5回終わり。

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

2009-06-30 (火)

Emacs講座 -第4回- カーソル移動 [Emacs講座]

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

高速なカーソル移動は、エディタを使う上で重要なポイントになります。
上下左右以外の移動手段を無意識に使えるようになることが、高速化のコ
ツだと思います。

「emacs 雑記」の motion に触発されて書いてみましたが、かなりパク
リになってしまいました。

上下左右


- それぞれ、Ctrl-p, Ctrl-n, Ctrl-b, Ctrl-f に割り当てられています。
- 十字キーでも移動できますが、こちらの方がホームポジションからの距
  離が短いので効率が良いはずです。
- 前置き引数を付けると、「何文字だけ移動」とか「何行だけ移動」とか
  出来ます。

Ctrl-u Ctrl-f4 文字右に移動
Ctrl-u Ctrl-u Ctrl-n16 行下に移動
Ctrl-u 7 Ctrl-b7 文字左に移動

前の単語、次の単語


- それぞれ、Meta-b, Meta-f に割り当てられています。
- 英文だと正確に単語単位で移動しますが、日本語だと単語の区切りがお
  おざっぱです。ただ、通常の左右移動の高速版と考えると、かなり使えます。
- 私はそれぞれ、Ctrl-, と Ctrl-. に割り当て直しました。

行頭、行末


- 行頭は Ctrl-a と Home に、行末は Ctrl-e と End に割り当てられています。
- どちらもかかせません。

スクロールアップ、スクロールダウン


- スクロールアップは Ctrl-v と PageDown に、
  スクロールダウンは Meta-v と PageUp に割り当てられています。
- 一行だけスクロールしたい場合は、"Ctrl-u 1 Ctrl-v" や
  "Ctrl-u 1 Meta-v" のように前置き引数を付けます。もしくは、以下
  相当のものをキーに割り当てます。

(scroll-up 1)
(scroll-down 1)


- 私はそれぞれ Ctrl-;(一行スクロールアップ) と Ctrl-:(一行スクロー
  ルダウン) に割り当てました。

ウィンドウの上、中央、下


- ウィンドウの中央には Meta-r すると、移動できます。
- 前置き引数を付けると、ウィンドウの上や下にも移動できます。
  それぞれ、"Ctrl-u 0 Meta-r" と "Ctrl-u -1 Meta-r" です。もしくは、
  以下相当のものをキーに割り当てます。

(move-to-window-line 0)
(move-to-window-line -1)


- 私はそれぞれ、Ctrl-q Ctrl-p(上)、Ctrl-q Ctrl-l(中央)、
  Ctrl-q Ctrl-n(下) に割り当てました。

バッファの先頭、終端


- それぞれ、Meta-<, Meta-> に 割り当てられています。
- 実行するとマークセットしてしまうので、
  私は、以下相当のものをキーに割り当て直しました。

(goto-char (point-min))
(goto-char (point-max))



検索


- Emacs の検索はインクリメンタルサーチなので、移動手段としても重宝
  します。
- Ctrl-s で前方検索、Ctrl-r で後方検索が出来ます。それぞれ Ctrl-u
  を付けて実行すると、正規表現検索が出来ます。
- 検索中に Meta-e すると、非インクリメンタルな検索が出来ます。

migemo 検索


- ローマ字のまま日本語をインクリメンタル検索するためのツールです。
- 変換なしで日本語を検索出来るため、高速な移動手段となり得ます。

現在行の空白でない最初の文字まで移動


- Meta-m に割り当てられています。
- これは、行頭の空白を飛ばして最初に文字がくる部分に飛ぶ、という
  コマンドです。
- あらゆるプログラムではインデントして字下げをしますが、字下げされ
  たところに行きたいときに使用します。かなり必須です。

行番号を指定した移動


- キーには割り当てられていません。M-x goto-line を実行します。
- 目的の行番号が分かっている時は、この方法で移動します。

対括弧移動


- 対になっている括弧の一方から他方に飛ぶ移動です。
- "(" や "{" から、")" や "}" への移動は Ctrl-Meta-n 、その逆は Ctrl-Meta-p です。
- 文字列中の括弧を無視してくれる優れものです。
- 私はそれぞれ、Ctrl-q Ctrl-f と Ctrl-q Ctrl-b に割り当て直しました。

マークセットした場所に移動


- Ctrl-x Ctrl-x すると、Ctrl-space 等でマークセットした場所にカーソ
  ルを飛ばすことが出来ます。もう一度 Ctrl-x Ctrl-x すると、元の場所に
  戻ります。
- カーソル移動からは脱線しますが、M-x transient-mark-mode すると、
  リージョンに色が付きます。さらに Emacs22 の場合は Ctrl-space を
  2 回打つと、このモードになります。

前の関数、次の関数 (C or C++)


- 標準では用意されていないようですが、個人的に関数を自作し、
  "Ctrl-c Ctrl-[", "Ctrl-c Ctrl-]" に割り当てました。
- いつか紹介できるかもしれません。

grep 関連


- キーには割り当てられていません。M-x grep を実行します。
- ヒットした候補は、"Ctrl-x `" で順番にジャンプできます。
- もちろん、*grep* バッファ上で Enter してもジャンプできます。
  Emacs22 以降であれば、`n' や `p' で次の候補を別ウィンドウに開けます。
- 似た機能に以下のものがあります。

関数説明
M-x occur現在のバッファを検索します。
M-x grep-findfind と grep を使って検索します。

タグジャンプ


- ある程度の規模のソース群を探索する場合に便利です。
- キー操作は以下のとおりです。

キー関数説明
Meta-.M-x find-tagシンボルの定義部分に飛ぶ。
Meta-*M-x pop-tag-mark前の状態に飛ぶ。
なしM-x tags-searchシンボルを検索させる。
Meta-,M-x tags-loop-continue次の候補に飛ぶ。(検索状態で実行)
Ctrl-x 4 .M-x find-tag-other-window定義部分を別ウィンドウに表示。
Ctrl-x 5 .M-x find-tag-other-frame定義部分を別フレームに表示。
Meta-TABM-x complete-symbolシンボル名の補完(TAGS を読み込んだ状態で)
なしM-x visit-tags-tableタブテーブルを読み込み直す。

第4回終わり。

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

2009-06-28 (日)

Emacs講座 -第3回- *scratch* バッファ [Emacs講座]

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

本項は、いろいろな設定を .emacs にコピペし始めたあたりで読むと良い
と思います。コピペ房から脱却しましょう。

.emacs で多い設定の一つに

(setq message-log-max 256)


などといった setq 文があると思います。上記例では、message-log-max
という変数に 256 という値を代入しています。(message-log-max
は、*Messages* バッファに保存される最大行数を格納する変数です。)

では設定しないと、message-log-max にはどのような値が入っているので
しょう? *scratch* バッファを使うと簡単に調べられます。

message-log-max を *scratch* バッファにコピペし、message-log-max の
後ろで Ctrl-j してみてください。前述の設定をしないと 100 が、設定を
すると 256 が出力されると思います。

message-log-max
=>100


※ 変数のヘルプからも、現在の値を確認できます。

F1 v message-log-max [Enter]


実は上の方法は単に変数の値を調べているのではなく、変数を評価してい
ます。

もっと正確に言うと、message-log-max というシンボルを評価しています。
評価の結果(戻り値)が 100 というわけです。シンボルは S 式の最小単位
です。S 式が分からなければ、単に「式」と読み替えていただいて構いま
せん。

さて、もっとも典型的な S 式は前述のような (setq message-log-max 256)
です。これも *scratch* バッファで評価できます。

(setq message-log-max 256)
=>256


評価すると、変数 message-log-max には 256 が代入されます。Emacs
Lisp では S 式は必ず値を返すので、256 が出力されます。

では、なぜ *scratch* バッファでは、このようなことが出来ると思いますか?

それは *scratch* バッファのメジャーモードが lisp-interaction-mode
だからです。これは Emacs Lisp を対話的に実行できるモードです。モー
ドラインに以下のように表示されてもいると思います。

scratch

メジャーモードというのは、各バッファに1つだけ設定でき、且つ必ず設
定されているモードです。各バッファのメジャーモードは、変数
major-mode を評価すると分かります。

もうひとつ。emacs-version という変数があります。Emacs のバージョン
が文字列として格納されています。

emacs-version
=>"23.1.50.1"


実は emacs-version という関数もあります。関数は以下のように評価します。

(emacs-version)
=>"GNU Emacs 23.1.50.1 (i686-pc-linux-gnu, GTK+ Version 2.16.1)
 of 2009-06-26 on vergil"


まとめ。
- かっこがない時は変数を評価している。
- かっこがある時は関数を評価している。

以上を知っていれば、.emacs に設定を追加した後 Emacs を再起動するこ
とが少なくなるはずです。気軽に色々設定してみましょう!!

そうそう、*scratch* バッファでは簡単な計算も出来ます。`+' や `*' と
いう関数を使います。

(+ 1 2)          ;;; 1 + 2
=>3

(* (+ 1 2) 5)    ;;; (1 + 2) * 5
=>15



最後に *scratch* バッファ以外で評価する方法もご紹介します。

方法1
Meta-: した後、ミニバッファに評価したい S 式を書き、Enter する。

方法2
評価したい S 式の直後で Ctrl-x Ctrl-e する。評価結果がミニバッファ
に表示される。Ctrl-u Ctrl-x Ctrl-e すると、評価結果がカーソル下に挿
入される。

方法3
Ctrl-space でマークセットし評価の先頭地点とする。次に、評価したい最
終地点までカーソルを移動する。M-x eval-region すると、その範囲を評
価できる。

第3回終わり。

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

2009-06-27 (土)

Emacs講座 -第2回- .emacs (どっと いーまっくす) [Emacs講座]

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

何はなくとも .emacs (どっと いーまっくす) です。

Emacs は起動すると次の順番にユーザ設定ファイルを検索し、最初にヒッ
トしたものを読み込みます。これがいわゆる .emacs (どっと いーまっく
す) です。(最近の Emacs は ~/.emacs.d/init.el も使えます。)

1. ~/.emacs.elc
2. ~/.emacs.el
3. ~/.emacs


.emacs.elc は、.emacs.el や .emacs を以下のようにバイトコンパイルし
たものです(他の方法もあります)。

% emacs -Q -batch -f batch-byte-compile ~/.emacs


バイトコンパイルすると、起動時間や実行時間が少し短くなります。
ただ、.emacs を修正した後にバイトコンパイルし忘れると、前述の読み込
み順番のため、古い設定のまま Emacs が起動するという弊害もあります。

.emacs.el と .emacs は名前が違うだけです。

.emacs の他に site-start.el と default.el もあります。あまり意識す
ることはないかもしれませんが、管理者が全ユーザに設定させたい内容を
記載して使います。[2008-05-15-1] もご覧下さい。

-q オプションはよく使います。こうすると ~/.emacs を読み込みません。

% emacs -q


~/.emacs の代わりに別なファイルを読み込ませたい時は、このようにします。

% emacs -q -l /hoge/huga.el


第2回終わり。

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

2009-06-26 (金)

Emacs講座 -第1回- Emacs と私 [Emacs講座]

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

GNU Emacs に初めて出会ったのは、入社した時に使った Nemacs でした。
Solaris2.6 にインストールされていました。2000 年入社なので、使い始
めてもう 10 年です。

ちょうど良い区切りなので、初心者から脱却したい人向けに、まとまった
文章を書くことにしました。今回はそのイントロです。GNU Emacs は
Emacs と略します。XEmacs の話はしない予定です。

さて、入社当時の話に戻ります。

最初は訳が分からなかったため、Nemacs はすぐに使わなくなりました。
Windows に C ソースをコピーして秀丸で編集したり、rmail を使わずに
Becky! を使ったりしていました。しかし、Windows がない環境で仕事をす
ることになったため、腹を決めて Emacs と付き合っていくことにしました。

その環境には運良く Mule がインストールされていました。私は C ソース
を Mule で編集し、mh-e でメールを読み書きすることになりました。

そういえば、今も覚えていることがあります。当時はファイルを開くたび
に Mule を起動していましたが、職場の上司は Dired でディレクトリを開
いて、そこからファイルをいくつも開いていました。shell-mode も使って
いたかもしれません。ああ、こういう使い方をするエディタなんだと思っ
たことを覚えています。

当時はいろんな人の ~/.emacs を読み漁りました。職場の人のものや、ネッ
ト上に転がっているものです。

ネット上で特に参考になったのは、GANAWARE に置いてある .emacs です。
UNIX や Windows、Emacs の各バージョンの環境切り分け方法がきれいだっ
たので、今もその名残りが私の ~/.emacs に残っています。ほかに
blankspace も大変参考になりました。

そうこうしているうちに、Mule は過去のものだと知りました。当時の最新
は Emacs-20.7 でそろそろ Emacs21.1 が出る頃だったと思います。

Mule は時々 X まわりの不具合に遭遇したため、1 年と使わずに
Emacs-20.7 に移行しました。併せてメーラも mh-e から Mew に乗り換え
ました。Mew には今もお世話になっています。

ちなみに当時の開発環境は入社当時と異なり、オープンソースソフトウェ
アが日々バージョンアップされ、最新の技術に触れられる素晴らしい環境
でした。

そのころから ~/.emacs は会社で用意された共通設定ファイルを使わずに、
自分でスクラッチから書いたものを使うようになりました。スクラッチか
ら書くために Emacs Lisp の知識が必要になったため、広瀬さんの本を購
入し、多くを学ばせていただきました。



Emacs とは関係ありませんが、広瀬さんは最近「zshの本」という本を出さ
れたようです。私は zsh ユーザでもありますが、それについてはまたの機
会で。

話を Emacs に戻しますと、その後 Emacs21 と Emacs22 のバージョンアッ
プに追随しました。今は自宅の Emacs は CVS 先端の 23 を使っています。

2001 年頃から自宅で使い始めた Meadow の話もしましょう。

Meadow は Emacs の Windows 移植版です。Emacs を Windows でコンパイ
ルした NTEmacs というものもありますが、NTEmacs に比べて IME まわり
の親和性、フォントの設定、画像の取扱いが優れているそうです。ただ、
NTEmacs は触ったことないです。

自宅 PC には Windows しかインストールしていなかったため、Meadow +
Cygwin を使っていました。そういう意味で Meadow との付き合いも長いです。

Cygwin は Linux の Windows エミュレート環境ですが、エミュレートであ
るが故にハマル要素は多くありました。そのため、自宅 PC に RedHat
Linux をインストールし、Meadow はあまり使わなくなりました。ただ、こ
の 1〜2 年は会社の開発環境が Windows になったこともあり、またよく使
うようになりました。

Emacs にはさまざまな派生物があり、私は最初混乱しました。

Wikipedia - Emacs あたりが参考になるかもしれません。少し古い
ですが、Emacs の各バージョンは History of Emacs and MuleMule
History Drawing
としてまとめられています。

ネット上の情報が古かったのも、混乱させる要因の一つでした。そういう
経験が、この「Emacs講座」を書くきっかけの一つになりました。

第1回終わり。

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

追記(2011-10-03):
「やさしいEmacs‐Lisp講座」は改訂版が出ましたよ!!


この記事に言及しているこのブログ内の記事

2009-06-26 (金)

Emacs講座 -目次- [Emacs][Emacs講座]

-第1回- Emacs と私
-第2回- .emacs (どっと いーまっくす)
-第3回- *scratch* バッファ
-第4回- カーソル移動
-第5回- キーバインドの変更
-第6回- load-path
-第7回- 文字コード
-第8回- タブ幅
-第9回- C コーディングスタイル

Emacs のバージョンは 23.3 を想定しています。22 以下は考慮しないこと
にします。

Emacs の全てを説明することは出来ないので、私の書きたい内容を書きた
い順番で書いています。

以下は今後の予定。

-第10回- 私の .emacs (どっと いーまっくす)
-第11回- edebugger
-第12回- 次の関数、前の関数

最終更新時間: 2017-02-26 21:55

検索
最近の話題
- 2017-02-26
  git-hyper-blame のセットアップ方法と使い方
- 2017-02-25
  18 年 4 カ月使った au を解約して IIJmio に乗り換えた
- 2017-02-21
  第18回Elasticsearch勉強会に参加してきた #elasticsearchjp
- 2017-01-27
  同じ Ajax 処理を Vue.js と jQuery で書いてみた
- 2017-01-10
  完全に闇に落ちていた StartSSL に ¥3,603 課金してしまったお話
- 2017-01-03
  Software Design を 13 ヶ月分まとめ読みした
- 2016-12-19
  任意の Ruby オブジェクトを YAML として書く
  Ruby の $ERROR_INFO などの特殊変数は require 'English' が必要だったのか
最近追記された記事
- 2017-02-25-1 (0日前)
- 2017-02-21-1 (4日前)
- 2015-06-07-1 (10日前)
- 2016-10-19-1 (19日前)
- 2016-01-01-1 (31日前)
- 2015-01-04-1 (40日前)
- 2015-06-07-1 (60日前)
- 2016-12-10-1 (78日前)
- 2016-11-05-1 (86日前)
- 2015-01-04-1 (94日前)
カテゴリ
- Anthy (3)
- Apache (11)
- Apple (1)
- ATOK (4)
- au (3)
- AWS (15)
- Bazaar (1)
- Berkshelf (2)
- BigQuery (1)
- BitBar (3)
- Book (85)
- Boxen (2)
- Bugsnag (1)
- C (26)
- capistrano (3)
- chalow (56)
- ChatWork (1)
- Chef (17)
- Chrome (3)
- Chromecast (1)
- CircleCI (7)
- Comics (2)
- Cooking (10)
- cvs (15)
- cygwin (12)
- D3.js (1)
- Debian (55)
- Docker (1)
- E-mail (8)
- elasticsearch (4)
- Emacs (219)
- Emacs講座 (10)
- English (4)
- feedforce (7)
- fetchmail (3)
- Firefox (20)
- Fluentd (4)
- ftp (1)
- Game (19)
- Gem (5)
- Git (9)
- GitHub (15)
- Go (5)
- Google (1)
- gpg (4)
- GrowthForecast (7)
- Health (2)
- Heroku (9)
- Homebrew (10)
- HTML (6)
- iBook (1)
- iPhone (15)
- IRC (1)
- Jenkins (8)
- JS (1)
- Karabiner (1)
- KeySnail (3)
- Kibana (1)
- Kindle (1)
- Langrich (7)
- LDAP (6)
- Life (18)
- Linux (5)
- Mackerel (1)
- Mew (18)
- MongoDB (1)
- Mozilla (19)
- Music (1)
- MySQL (1)
- NAS (4)
- nginx (6)
- NHK (1)
- Node (1)
- ntp (4)
- OOP (1)
- OpenID (2)
- openssl (1)
- Opera (2)
- OSX (41)
- Perl (14)
- PHP (19)
- PostgreSQL (1)
- procmail (4)
- Programing (3)
- Puppet (1)
- Python (2)
- Rails (10)
- Rake (2)
- RaspberryPi (1)
- RedHat (29)
- Redmine (3)
- Rspec (1)
- Ruby (48)
- samba (3)
- screen (7)
- sed (5)
- serverspec (6)
- sh (8)
- Slack (2)
- Solaris9 (22)
- Spring (2)
- ssh (4)
- StatusNet (21)
- svn (12)
- Swift (1)
- Tablet (1)
- tdiary (3)
- Twitter (14)
- Twmode (6)
- Ubuntu (5)
- UNIX (102)
- vagrant (8)
- Video (21)
- vim (1)
- Wercker (9)
- Windows (29)
- Wine (3)
- XML (11)
- XP (1)
- zsh (25)
- インストールメモ (33)
- クイックシェイプ (12)
- ネタ (15)
- 勉強会 (14)
- 携帯 (6)
- 正規表現 (4)
過去ログ
2017 : 01 02 03 04 05 06 07 08 09 10 11 12
2016 : 01 02 03 04 05 06 07 08 09 10 11 12
2015 : 01 02 03 04 05 06 07 08 09 10 11 12
2014 : 01 02 03 04 05 06 07 08 09 10 11 12
2013 : 01 02 03 04 05 06 07 08 09 10 11 12
2012 : 01 02 03 04 05 06 07 08 09 10 11 12
2011 : 01 02 03 04 05 06 07 08 09 10 11 12
2010 : 01 02 03 04 05 06 07 08 09 10 11 12
2009 : 01 02 03 04 05 06 07 08 09 10 11 12
2008 : 01 02 03 04 05 06 07 08 09 10 11 12
2007 : 01 02 03 04 05 06 07 08 09 10 11 12
2006 : 01 02 03 04 05 06 07 08 09 10 11 12
2005 : 01 02 03 04 05 06 07 08 09 10 11 12
2004 : 01 02 03 04 05 06 07 08 09 10 11 12
2003 : 01 02 03 04 05 06 07 08 09 10 11 12
2002 : 01 02 03 04 05 06 07 08 09 10 11 12
2001 : 01 02 03 04 05 06 07 08 09 10 11 12
Google+