blog/content/post/2009/01/18/2009-01-18-00001111.md

508 lines
29 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Emacs Lispのイディオム
author: kazu634
date: 2009-01-18
wordtwit_post_info:
- 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:4483;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}'
categories:
- Emacs
- Lisp
---
<div class="section">
<p>
<a href="http://xahlee.org/emacs/elisp_idioms.html" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://xahlee.org/emacs/elisp_idioms.html', 'Emacs Lisp Idioms');" target="_blank">Emacs Lisp Idioms</a>を勉強をかねて訳しました。興味がある方はご覧ください。一部見出しレベルが異なりますが、はてなだとこれが限界みたいっす。。。
</p>
<p>
<a name="seemore"></a>
</p>
<h4>
Emacs lisp Idioms (by Xah Lee, 2008-06)
</h4>
<p>
このページではテキスト処理に関する基本的な Emacs-lisp プログラミングのイディオムを集めています。
</p>
<p>
このページは二部構成で Interactive セクションと、Batchセクションの二つのセクションに分かれています。Interactiveセクションでは実際にファイルを編集しているときに呼び出すコマンドを書く際のイディオムを扱います。例えば、カーソル位置の単語をGoogleで検索する、カレントリージョンの特定の単語を置換する、XMLテンプレートを挿入する、既存のプログラミングプロジェクトの関数名をリネームするなどです。Batchセクションでは、unixのシェルツールやPerlを用いて行うようなバッチスタイルのテキスト処理を扱います。例えば、与えられたファイルやディレクトリの中を検索して置換する、複数のファイルでXML正当性検査を行うディレクトリにあるtagファイルを探し、レポートを作成するです。
</p>
<p>
このページで紹介されているイディオムは、ビギナーの elisp プログラマーにとって適切な、基本的なタスクしか含まれておらず、頻繁に必要となるケースしか扱っていません。
</p>
<p>
このページに書いてあることを理解するためには、最初にカーソル位置を取得する、カーソルを移動する、テキスト検索をする、テキストを挿入・削除するといった基本的なemacsの機能を知っておく必要があります。
</p>
<h4>
Interactive関数のイディオム
</h4>
<p>
これがユーザー定義関数の典型的なひな形になります:
</p>
<pre class="syntax-highlight">
<span class="synSpecial">(</span><span class="synStatement">defun</span> my-function <span class="synSpecial">()</span>
<span class="synConstant">&#34;... do this returns that ...&#34;</span>
<span class="synSpecial">(</span>interactive<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">let</span> <span class="synSpecial">(</span>localVar1 localVar2 ...<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> localVar1 ...<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> localVar2 ...<span class="synSpecial">)</span>
...
<span class="synComment">;; do something ...</span>
<span class="synSpecial">)</span>
<span class="synSpecial">)</span>
</pre>
<h5>
テキストを取得する
</h5>
<h5>
与えられた初期位置・終了位置のテキストを取得する
</h5>
<pre class="syntax-highlight">
<span class="synComment">; get the string from buffer</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> myStr <span class="synSpecial">(</span>buffer-substring myStartPos myEndPos<span class="synSpecial">))</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> myStr <span class="synSpecial">(</span>buffer-substring-no-properties myStartPos myEndPos<span class="synSpecial">))</span>
</pre>
<p>
Emacsの文字列はシンタックス色づけ、active button、ハイパーテキストなどのためにプロパティーを持つことができます。buffer-substring-no-properties関数はこれらのプロパティーを持たないプレーンな文字列を返します。しかし、文字列を引数に取る多くの関数はプロパティー付きの文字列を引数に取ることもできます。
</p>
<h5>
カーソル位置の単語・カーソル行を取得する
</h5>
<p>
カーソル位置の単語・行・文・url・ファイルネームなどの取得は次のようになります:
</p>
<pre class="syntax-highlight">
<span class="synComment">;; grab a thing at point. The &#34;thing&#34; is a semantic unit. It can be a</span>
<span class="synComment">;; word, symbol, line, sentence, filename, url and others.</span>
<span class="synComment">;; grab the current word</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> myStr <span class="synSpecial">(</span>thing-at-point <span class="synSpecial">'</span><span class="synIdentifier">word</span><span class="synSpecial">))</span>
<span class="synComment">;; grab the current word with hyphens or underscore</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> myStr <span class="synSpecial">(</span>thing-at-point <span class="synSpecial">'</span><span class="synIdentifier">symbol</span><span class="synSpecial">))</span>
<span class="synComment">;; grab the current line</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> myStr <span class="synSpecial">(</span>thing-at-point <span class="synSpecial">'</span><span class="synIdentifier">line</span><span class="synSpecial">))</span>
<span class="synComment">;; grab the start and end positions of a word (or any other thing)</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> myBoundaries <span class="synSpecial">(</span>bounds-of-thing-at-point <span class="synSpecial">'</span><span class="synIdentifier">word</span><span class="synSpecial">))</span>
</pre>
<p>
取得したいものが「シンボル」の場合、「シンボル」がダッシュ(-)やアンダーバー(_)という文字を伴ったアルファベットの列を意味することに気をつけてください。例えば、phpリファレンス引きコマンドを作成していて、カーソルが&#8221;print_r($y);&#8221;のpの位置にあった場合、取得したいのはprintではなくprint_rです。「シンボル」の正確な意味はそのモードのシンタックス・テーブルに依存します。
</p>
<p>
以下に示すのが、アクティブなリージョンがない場合に「シンボル」を取得するphpリファレンス引きコマンドの例です:
</p>
<pre class="syntax-highlight">
<span class="synSpecial">(</span><span class="synStatement">defun</span> php-lookup <span class="synSpecial">()</span>
<span class="synConstant">&#34;Look up current word in PHP ref site in a browser.\n</span>
<span class="synConstant"> If a region is active (a phrase), lookup that phrase.&#34;</span>
<span class="synSpecial">(</span>interactive<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">let</span> <span class="synSpecial">(</span>myword myurl<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> myword
<span class="synSpecial">(</span><span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synStatement">and</span> transient-mark-mode mark-active<span class="synSpecial">)</span>
<span class="synSpecial">(</span>buffer-substring-no-properties <span class="synSpecial">(</span>region-beginning<span class="synSpecial">)</span> <span class="synSpecial">(</span>region-end<span class="synSpecial">))</span>
<span class="synSpecial">(</span>thing-at-point <span class="synSpecial">'</span><span class="synIdentifier">symbol</span><span class="synSpecial">)))</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> myurl
<span class="synSpecial">(</span>concat <span class="synConstant">&#34;http://us.php.net/&#34;</span> myword<span class="synSpecial">))</span>
<span class="synSpecial">(</span>browse-url myurl<span class="synSpecial">)))</span>
</pre>
<h5>
マッチしたペアーの間のテキストを取得する
</h5>
<p>
<>」、「()」、「&#8221;&#8221;」などで囲まれた範囲を取得します。
</p>
<p>
肝になるのはskip-chars-backwardとskip-chars-forward関数です。以下に示す例では、p1はカーソルの左側の「&#8221;」に設定され、p2はカーソル右側の「&#8221;」に設定されます。
</p>
<pre class="syntax-highlight">
<span class="synSpecial">(</span><span class="synStatement">defun</span> select-inside-quotes <span class="synSpecial">()</span>
<span class="synConstant">&#34;Select text between double straight quotes on each side of cursor.&#34;</span>
<span class="synSpecial">(</span>interactive<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">let</span> <span class="synSpecial">(</span>p1 p2<span class="synSpecial">)</span>
<span class="synSpecial">(</span>skip-chars-backward <span class="synConstant">&#34;^\&#34;&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> p1 <span class="synSpecial">(</span>point<span class="synSpecial">))</span>
<span class="synSpecial">(</span>skip-chars-forward <span class="synConstant">&#34;^\&#34;&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> p2 <span class="synSpecial">(</span>point<span class="synSpecial">))</span>
<span class="synSpecial">(</span>goto-char p1<span class="synSpecial">)</span>
<span class="synSpecial">(</span>push-mark p2<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> mark-active <span class="synStatement">t</span><span class="synSpecial">)</span>
<span class="synSpecial">)</span>
<span class="synSpecial">)</span>
</pre>
<p>
もし「()」で囲まれたテキストを取得したのであれば、「&#8221;^\&#8221;&#8221;」を「&#8221;^(&#8220;」と「&#8221;^)&#8221;」に変更してください。「<>」の場合も同様です。このコードはネストしたペアーを考慮していないことに気をつけてください。
</p>
<h4>
リージョンを処理する
</h4>
<p>
ここでは現在のリージョンのテキストを処理するためのイディオムを紹介します。
</p>
<p>
定義する関数に二つのパラメータお約束としては「start」・「end」としますを持たせます。そうして「(interactive &#8220;r&#8221;)」を用いると、現在のリージョンの開始と終了位置が二つのパラメータにセットされます。例えばこのようになります:
</p>
<pre class="syntax-highlight">
<span class="synSpecial">(</span><span class="synStatement">defun</span> remove-hard-wrap-region <span class="synSpecial">(</span>start end<span class="synSpecial">)</span>
<span class="synConstant">&#34;Replace newline chars in region by single spaces.&#34;</span>
<span class="synSpecial">(</span>interactive <span class="synConstant">&#34;r&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">let</span> <span class="synSpecial">((</span>fill-column <span class="synConstant">90002000</span><span class="synSpecial">))</span>
<span class="synSpecial">(</span>fill-region start end<span class="synSpecial">)))</span>
</pre>
<h5>
アクティブなリージョン、あるいはカーソル上の単語を処理する
</h5>
<p>
現在のリージョン、もしそれがなければ、カーソル上の単語を処理するイディオムは、以下のようになります:
</p>
<pre class="syntax-highlight">
<span class="synSpecial">(</span><span class="synStatement">defun</span> down-case-word-or-region <span class="synSpecial">()</span>
<span class="synConstant">&#34;Lower case the current word or text selection.&#34;</span>
<span class="synSpecial">(</span>interactive<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">let</span> <span class="synSpecial">(</span>pos1 pos2<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synStatement">and</span> transient-mark-mode mark-active<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> pos1 <span class="synSpecial">(</span>region-beginning<span class="synSpecial">)</span>
pos2 <span class="synSpecial">(</span>region-end<span class="synSpecial">))</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> pos1 <span class="synSpecial">(</span><span class="synStatement">car</span> <span class="synSpecial">(</span>bounds-of-thing-at-point <span class="synSpecial">'</span><span class="synIdentifier">word</span><span class="synSpecial">))</span>
pos2 <span class="synSpecial">(</span><span class="synStatement">cdr</span> <span class="synSpecial">(</span>bounds-of-thing-at-point <span class="synSpecial">'</span><span class="synIdentifier">word</span><span class="synSpecial">))))</span>
<span class="synSpecial">(</span>downcase-region pos1 pos2<span class="synSpecial">)</span>
<span class="synSpecial">)</span>
<span class="synSpecial">)</span>
</pre>
<h4>
ユーザーからの入力を促す
</h4>
<h5>
ユーザーからの入力を引数とする
</h5>
<p>
定義する関数の引数としてユーザーに入力を促すためのイディオムは次のようになります:
</p>
<pre class="syntax-highlight">
<span class="synSpecial">(</span><span class="synStatement">defun</span> query-friends-phone <span class="synSpecial">(</span>name<span class="synSpecial">)</span>
<span class="synConstant">&#34;...&#34;</span>
<span class="synSpecial">(</span>interactive <span class="synConstant">&#34;sEnter friend's name: &#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span>message <span class="synConstant">&#34;Name: %s&#34;</span> name<span class="synSpecial">)</span>
<span class="synSpecial">)</span>
</pre>
<p>
「(interactive &#8220;sEnter friend&#8217;s name:&#8221;)」が行っていることは、ユーザーに情報を入力するように促していることで、それは文字列として受け取られ、定義する関数のパラメータの値となります。
</p>
<p>
「(interactive)」は別な種類の入力も受け付けます。次にあげるのは「(interactive)」を用いたいくつかの基本的な例です:
</p>
<ul>
<li>
「(interactive)」は定義する関数を interactive に利用できるようにする。つまり execute-extended-command(M-x) を用いて使えるようにする。
</li>
<li>
「(interactive &#8220;s&#8221;)」はユーザーに入力を促す。入力された情報は文字列して受け取られ、定義する関数の引数となる。
</li>
<li>
「(interactive &#8220;n&#8221;)」はユーザーに入力を促す。入力された情報は数字として受け取られ、定義する関数の引数となる。
</li>
</ul>
<h5>
ユーザーに問い合わせを行う
</h5>
<p>
「(interactive &#8230;)」は定義する関数のパラメータに値をセットするには役立ちます。しかし、時には関数の途中でユーザーに入力を促す必要があります。例えば、「このファイルを編集しますか」です。この場合、「y-or-n-p」関数を用います。このようになります:
</p>
<pre class="syntax-highlight">
<span class="synSpecial">(</span><span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synStatement">y-or-n-p</span> <span class="synConstant">&#34;Do it?&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">progn</span>
<span class="synComment">;; code to do something here</span>
<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">progn</span>
<span class="synComment">;; code if user answered no.</span>
<span class="synSpecial">)</span>
<span class="synSpecial">)</span>
</pre>
<p>
「y-or-n-p」はユーザーに y か n の入力を求めます。また「yes-and-no-p」を用いて、 yes あるいは no のどちらかを答えてもらうこともできます。この「yes-and-no-p」は例えばファイルを削除するときの確認などで用います。
</p>
<p>
ユーザーからの入力を得るためのより一般的な方法が必要ならば、「read-from-minibuffer」があります。この関数は例えばキーワード補完や入力ヒストリーのような機能を用いたいときに役立ちます。
</p>
<h4>
文字列を処理する
</h4>
<p>
Perlのようなスクリプト言語では、文字列を処理する命令が数多くあります。elispでは、少数しかありません。というのも、elispはずっと強力なバッファーデータタイプを提供し、バッファー上のテキストを処理する関数を文字通り何千も持つからです。文字列やテキストがある時に、文字列の切り出しや、文字数のカウントをし、それを一時的なバッファーに挿入する以上のことを行う必要があります。次に例を載せます:
</p>
<pre class="syntax-highlight">
<span class="synComment">;; suppose mystr is a var whose value is a string</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> mystr <span class="synConstant">&#34;some string here you need to process&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> mystrNew
<span class="synSpecial">(</span>with-temp-buffer
<span class="synSpecial">(</span>insert mystr<span class="synSpecial">)</span>
<span class="synComment">;; manipulate the string here</span>
<span class="synSpecial">(</span>buffer-string<span class="synSpecial">)</span> <span class="synComment">; get result</span>
<span class="synSpecial">))</span>
</pre>
<h4>
テキストの検索と置換
</h4>
<p>
文字列の検索と置換はテキスト処理を特徴付けるものです。これらを行う方法を以下に示します:
</p>
<pre class="syntax-highlight">
<span class="synComment">;; idiom for string replacement in current buffer;</span>
<span class="synComment">;; use search-forward-regexp if you need regexp</span>
<span class="synSpecial">(</span>goto-char <span class="synSpecial">(</span>point-min<span class="synSpecial">))</span>
<span class="synSpecial">(</span>while <span class="synSpecial">(</span>search-forward <span class="synConstant">&#34;myStr1&#34;</span> <span class="synStatement">nil</span> <span class="synStatement">t</span><span class="synSpecial">)</span> <span class="synSpecial">(</span>replace-match <span class="synConstant">&#34;myReplaceStr1&#34;</span><span class="synSpecial">))</span>
<span class="synSpecial">(</span>goto-char <span class="synSpecial">(</span>point-min<span class="synSpecial">))</span>
<span class="synSpecial">(</span>while <span class="synSpecial">(</span>search-forward <span class="synConstant">&#34;myStr2&#34;</span> <span class="synStatement">nil</span> <span class="synStatement">t</span><span class="synSpecial">)</span> <span class="synSpecial">(</span>replace-match <span class="synConstant">&#34;myReplaceStr2&#34;</span><span class="synSpecial">))</span>
<span class="synComment">;; repeat for other string pairs</span>
</pre>
<h4>
dired でマークされたファイルに定義した関数を適応する
</h4>
<p>
dired でマークしたファイルに定義した関数を用いるには、「dired-get-marked-files」をこのようにして用います:
</p>
<pre class="syntax-highlight">
<span class="synComment">;; idiom for processing a list of files in dired's marked files</span>
<span class="synComment">;; suppose myProcessFile is your function that takes a file path</span>
<span class="synComment">;; and do some processing on the file</span>
<span class="synSpecial">(</span><span class="synStatement">defun</span> dired-myProcessFile <span class="synSpecial">()</span>
<span class="synConstant">&#34;apply myProcessFile function to marked files in dired.&#34;</span>
<span class="synSpecial">(</span>interactive<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">require</span> <span class="synSpecial">'</span><span class="synIdentifier">dired</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">mapc</span> <span class="synSpecial">'</span><span class="synIdentifier">myProcessFile</span> <span class="synSpecial">(</span>dired-get-marked-files<span class="synSpecial">))</span>
<span class="synSpecial">)</span>
</pre>
<h4>
Batch スタイルテキスト処理のイディオム
</h4>
<h4>
ファイルを開き、処理し、保存、もしくは閉じる
</h4>
<p>
ファイルを開き、処理し、保存、もしくは閉じる方法は次のようになります。
</p>
<pre class="syntax-highlight">
<span class="synComment">;; open a file, process it, save, close it</span>
<span class="synSpecial">(</span><span class="synStatement">defun</span> my-process-file <span class="synSpecial">(</span>fpath<span class="synSpecial">)</span>
<span class="synConstant">&#34;process the file at fullpath fpath ...&#34;</span>
<span class="synSpecial">(</span><span class="synStatement">let</span> <span class="synSpecial">(</span>mybuffer<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> mybuffer <span class="synSpecial">(</span>find-file fpath<span class="synSpecial">))</span>
<span class="synSpecial">(</span>goto-char <span class="synSpecial">(</span>point-min<span class="synSpecial">))</span> <span class="synComment">;; in case buffer already open</span>
<span class="synComment">;; do something</span>
<span class="synSpecial">(</span>save-buffer<span class="synSpecial">)</span>
<span class="synSpecial">(</span>kill-buffer mybuffer<span class="synSpecial">)))</span>
</pre>
<p>
何百ものファイルを処理するときは、emacsに元に戻るための情報や fontification を保持する必要はありません。この方が効率的になります:
</p>
<pre class="syntax-highlight">
<span class="synSpecial">(</span><span class="synStatement">defun</span> my-process-file <span class="synSpecial">(</span>fpath<span class="synSpecial">)</span>
<span class="synConstant">&#34;process the file at fullpath fpath ...&#34;</span>
<span class="synSpecial">(</span><span class="synStatement">let</span> <span class="synSpecial">()</span>
<span class="synComment">;; create temp buffer without undo record. first space is necessary</span>
<span class="synSpecial">(</span>set-buffer <span class="synSpecial">(</span>get-buffer-create <span class="synConstant">&#34; myTemp&#34;</span><span class="synSpecial">))</span>
<span class="synSpecial">(</span>insert-file-contents fpath <span class="synStatement">nil</span> <span class="synStatement">nil</span> <span class="synStatement">nil</span> <span class="synStatement">t</span><span class="synSpecial">)</span>
<span class="synComment">;; process it ...</span>
<span class="synSpecial">(</span>kill-buffer <span class="synConstant">&#34; myTemp&#34;</span><span class="synSpecial">)))</span>
</pre>
<h4>
シェルコマンドを呼び出す
</h4>
<pre class="syntax-highlight">
<span class="synComment">;; idiom for calling a shell command</span>
<span class="synSpecial">(</span>shell-command <span class="synConstant">&#34;cp /somepath/myfile.txt /somepath&#34;</span><span class="synSpecial">)</span>
<span class="synComment">;; idiom for calling a shell command and get its output</span>
<span class="synSpecial">(</span>shell-command-to-string <span class="synConstant">&#34;ls&#34;</span><span class="synSpecial">)</span>
</pre>
<p>
shell-command と shell-command-to-string のどちらも以降の処理を行う前にシェルプロセスが終了するのを待ちます。終了するのを待たない場合は、 start-process や start-process-shell-command を用いてください。
</p>
<h4>
ディレクトリを走査する
</h4>
<p>
次の例では、 my-process-file はフルパスつきのファイル名を入力として受け取ります。「find-lisp-find-files」関数は、正規表現で指定されたファイルのフルパスのリストを生成します。「mapc」はこの手続きをリストの要素全てに適応します。<span class="footnote"><a href="/sirocco634/#f1" name="fn1" title="Gauche での apply として用いているようだ。">*1</a></span>
</p>
<pre class="syntax-highlight">
<span class="synComment">;; idiom for traversing a directory</span>
<span class="synSpecial">(</span><span class="synStatement">require</span> <span class="synSpecial">'</span><span class="synIdentifier">find-lisp</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">mapc</span> <span class="synSpecial">'</span><span class="synIdentifier">my-process-file</span> <span class="synSpecial">(</span>find-lisp-find-files <span class="synConstant">&#34;~/web/emacs/&#34;</span> <span class="synConstant">&#34;\\.html$&#34;</span><span class="synSpecial">))</span>
</pre>
<h4>
バッチモードでelispを走らせる
</h4>
<p>
&#8211;script」オプションを用いれば、OSのコマンドラインインターフェースシェルで elisp プログラムを走らせることができます。例えば、
</p>
<pre class="syntax-highlight">
emacs --script process_log.el
</pre>
<p>
Emacsは他にいくつかオプションを持ち、elisp スクリプトをどのように走らせるかを制御できます。主要なオプションは次のようになります:
</p>
<table>
<tr>
<th>
フルオプション
</th>
<td>
*意味
</td>
</tr>
<tr>
<td>
&#8211;no-site-file
</td>
<td>
Do not load the site wide &#8220;site-start.el&#8221;
</td>
</tr>
<tr>
<td>
&#8211;no-init-file
</td>
<td>
Do not load your init files &#8220;~/.emacs&#8221; or &#8220;default.el&#8221;.
</td>
</tr>
<tr>
<td>
&#8211;batch
</td>
<td>
Run emacs in batch mode, use it together with &#8220;&#8211;load&#8221; to specify a lisp file.
</td>
</tr>
<tr>
<td>
&#8211;script <file path>
</td>
<td>
Run emacs like &#8220;&#8211;batch&#8221; with &#8220;&#8211;load&#8221; set to &#8220;<file path>&#8221;.
</td>
</tr>
<tr>
<td>
&#8211;load=&#8221;<elisp file path>&#8221;
</td>
<td>
Execute the elisp file at &#8220;<elisp file path>&#8221;.
</td>
</tr>
<tr>
<td>
&#8211;user=<user name>
</td>
<td>
Load user <user name>&#8217;s emacs init file (the &#8220;.emacs&#8221;).
</td>
</tr>
</table>
<p>
</p>
<p>
バッチモードで走らせる elisp スクリプトを書いているときは、それが独立しているようにしてください。つまり、作成するスクリプトが Emacs の初期化ファイル上の関数を呼び出していないこと、呼び出す場合はそのスクリプトが必要とするライブラリーを「require」や「load」を用いて読み込むこと、 Perl や Python スクリプトのようにスクリプト上で必要となるロードパスの設定を行っていること(つまり「(add-to-list &#8216;load-path <library path>)」)に注意してください。
</p>
<p>
適切にスクリプトを作成したら、「emacs &#8211;script <elisp file path>」を実行してください。
</p>
<p>
もし作成した elisp プログラムが Emacs の起動ファイル(.emacsで定義された関数を必要とする場合は、「(load <emacs init file path>)」を用いて明示的にその関数をロードすべきです。あるいは、その関数を読み込む起動オプションを追加すべきです。例えばこのように: 「&#8211;user=xah」必要となる関数をスクリプト内で定義するのが最善ではありますが
</p>
<p>
使っている Emacs が Mac 上の Carbon Emacs や Aquamacs であれば、 Emacs プログラムへのパスは単に「emacs」ではなく、このようになります: 「/Applications/Emacs.app/Contents/MacOS/Emacs」。次に示すのはこのような場合の起動コマンドの例です:
</p>
<pre class="syntax-highlight">
/Applications/Emacs.app/Contents/MacOS/Emacs --no-site-file --batch --load=process_log.el
</pre>
</div>
<div class="footnote">
<p class="footnote">
<a href="/sirocco634/#fn1" name="f1">*1</a>Gauche での apply として用いているようだ。
</p>
</div>