align設定用例集
http://atnd.org/events/21982#comments:title=Emacs Advent Calender jp: 2011 の12日目です。
11日目は id:rubikitch さんの 集中力5倍!小よく大を制するミニマリストEmacs - (rubikitch loves (Emacs Ruby CUI Books)) でした。
昨年は org-modeでTODO管理 - handlename::blog というエントリで参加しました。
今年はalignのルール設定について、例を挙げながら説明してみます。
align
emacsにはalignという機能があります。この機能は拡張elispを追加することなく、デフォルトの状態で使用することができます。
たとえばこんなコードを、
<pre class="code lang-c" data-lang="c">int count = 0;
float degree = 0.2;
リージョン選択して、
<pre class="code">M-x align</pre>
とすると、こんな感じに整形してくれます。
<pre class="code lang-c" data-lang="c">int count = 0;
float degree = 0.2;
alignのルール
align-rules-listにルールを追加することで、整形する方法を自由に設定することができます。
<pre class="code lang-lisp" data-lang="lisp">(add-to-list 'align-rules-list
'(hoge-assignment ; ルールの名前
; オプションをここに書く
))</pre>
オプションの詳しい説明については、
<pre class="code">f| v align-rules-list</pre>
を参照。
例: 一番シンプルなルール
@を基準にしてalignする。
<pre class="code lang-lisp" data-lang="lisp">(add-to-list 'align-rules-list
'(atmark-assignment
(regexp . "\\( *\\)@") ; 基準を定義する<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%B5%B5%AC%C9%BD%B8%BD">正規表現</a>
(modes . '(text-mode)))) ; ルールを適用するモード</pre>
<pre class="code">foo@bar
hoge@huga 1@2
↓
<pre class="code">foo @bar
hoge @huga 1 @2
例: パターンの後ろを調整してそろえる
\\(\\s-*\\)をregexpの末尾においておくことによって、パターンの後ろにあるスペースを調整してalignすることができる。
<pre class="code lang-lisp" data-lang="lisp">(add-to-list 'align-rules-list
'(<a class="keyword" href="http://d.hatena.ne.jp/keyword/yaml">yaml</a>-assignment
(regexp . ":\\(\\s-*\\)") ; 末尾に \\(\\s-*\\)
(modes . '(<a class="keyword" href="http://d.hatena.ne.jp/keyword/yaml">yaml</a>-mode))))</pre>
<pre class="code lang-yaml" data-lang="yaml">Winter:
Decemberde: 12 January: 1 February: 2
↓
<pre class="code lang-yaml" data-lang="yaml">Winter:
Decemberde: 12 January: 1 February: 2
例: 1行に複数回ルールを適用する
repeatにnon-nilを指定すると、1行に複数回ルールを適用できる。
<pre class="code lang-lisp" data-lang="lisp">(add-to-list 'align-rules-list
'(camma-assignment
(regexp . ",\\( *\\)")
(repeat . t) ; 複数回適用を有効に
(modes . '(<a class="keyword" href="http://d.hatena.ne.jp/keyword/perl">perl</a>-mode))))</pre>
<pre class="code">my @primes = (
1,2,3,5,7,
11,13,17,19,23,
29,31,37,41,43,
);
↓
<pre class="code">my @primes = (
1, 2, 3, 5, 7,
11, 13, 17, 19, 23,
29, 31, 37, 41, 43,
);
例: タブ位置でそろえる
tab-stopにnon-nilを指定すると、tab-widthの整数倍の位置にそろえられる。
<pre class="code lang-lisp" data-lang="lisp">(add-to-list 'align-rules-list
'(tab-stop-assignment
(regexp . "\\(\\s-+\\)")
(tab-stop . t) ; タブ位置でそろえる
(modes . '(text-mode))))</pre>
tab-widthが4の場合
<pre class="code">0....5..8
yes はい no いいえ
↓
<pre class="code">0....5..8
yes はい no いいえ
例: 固定位置でそろえる
columnに列数を指定しておくと、その列でそろえられる。
<pre class="code lang-lisp" data-lang="lisp">(add-to-list 'align-rules-list
'(column-assignment
(regexp . "\\(\\s-+\\)")
(column . 10) ; そろえる列数
(modes . '(text-mode))))</pre>
<pre class="code">0....5....10
english 英語 japanese 日本語 french フランス語
↓
<pre class="code">0....5....10
english 英語 japanese 日本語 french フランス語
例: alignする段落の切れ目を指定する
separateに正規表現を指定すると、alignする段落の切れ目を変更することができる。
<pre class="code lang-lisp" data-lang="lisp">(add-to-list 'align-rules-list
'(custom-separete-assignment
(regexp . ",\\(\\s-*\\)")
(separate . "\\(===\\)") ; 段落の切れ目
(modes . '(text-mode))))</pre>
<pre class="code">January, 1
February, 2 March, 3 #
April, 4 May, 5 June, 6
↓
<pre class="code">January, 1
February, 2 March, 3 #
April, 4 May, 5 June, 6
ほかにも
align-rules-listのオプションには、
ほかにも
- group
- case-fold
- valid
- run-if
- spacing
- justify
というオプションがあります。詳しくはヘルプを読んでみてください。
# 正直なところ、groupが何をするのか、とか、よくわかってないです。教えてエラい人!
実用的なルール
このあたりの記事を参考にさせてもらってます。
余談
バージョン管理との関係
alignを使っていると、列揃えの変化(長い変数名が段落に追加された場合など)もファイルの変更としてリポジトリに記録されてしまい、本来の変更箇所が隠れてしまうので、若干使用をためらうこともありました。
が、
gitを使っているならdiffに-bオプションを付けると空白文字の増減は無視してくれるので、そのような気遣いをする必要がありません。
<pre class="code">$ git diff -b</pre>
align-regexp
ルールをその場で指定できるalign-regexpというコマンドもあります。
<pre class="code">; regexpだけを指定する場合
M-x align-regexp
; groupやrepeatなども指定する場合 C-u M-x align-regexp
そんなに大きくない、せいぜい数百行のアクセスログなどを整形するときに、cua-modeと組み合わせてよく使います。
もちろん、こういう処理を何度もする必要がある場合は、バッチを書くなりして自動化するのが賢明です。
おわり
明日は @uwabami さんです。