[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X. Maintaining Programs

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=Maintaining"
"texi/emacs21/X.MaintainingPrograms"へのコメント(無し)

This chapter describes Emacs features for maintaining programs. The version control features (see 節 N.7 VC(版管理、バージョンコントロール)) are also particularly useful for this purpose.



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.1 変更記録

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=Change%20Log"
"texi/emacs21/X.1変更記録"へのコメント(無し)

コマンドC-x 4 aは、編集中のファイルに対する 新たな項目を変更記録ファイルに追加します (add-change-log-entry-other-window)。

変更記録ファイルは、プログラムを変更した日付やその理由を 時間順に記録したもので、個々の変更を記述した項目の並びから成ります。 通常は、編集しているファイルと同じディレクトリ、あるいは、 その親ディレクトリに置いた`ChangeLog'と呼ばれる ファイルに保存されています。 1つの`ChangeLog'ファイルで、このファイルを置いたディレクトリや そのサブディレクトリに置いた全ファイルの変更を記録できます。

変更記録項目は、名前、(user-mail-addressから得られた) 電子メイルアドレス、現在の日付と時刻から成るヘッダ行で始まります。 変更記録内の各行はヘッダ行を除いて、つねに空白かタブで始まります。 1つの項目は小項目から構成され、 各小項目は空白と星印で始まる行で始まります。 以下は、1993年5月付けの2つの項目で、 それぞれに2つの小項目があります。

 
1993-05-25  Richard Stallman  

        * man.el: Rename symbols `man-*' to `Man-*'.
        (manual-entry): Make prompt string clearer.

        * simple.el (blink-matching-paren-distance):
        Change default to 12,000.

1993-05-24  Richard Stallman  

        * vc.el (minor-mode-map-alist): Don't use it if it's void.
        (vc-cancel-version): Doc fix.

(Emacsの以前の版では、日付の形式が異なる。)

1つの項目で複数の変更を記述できます。 各変更について、それぞれの小項目を用意しなくてはいけません。 通常、小項目のあいだには空行がなくてはいけません。 小項目が関連している(場所は異なるが同じ変更の一部分の)場合には、 それらのあいだには空行を入れずに一塊にしておきます。 上記の2番目の項目には、このようにしてまとめた2つの小項目が含まれています。

C-x 4 aは、変更記録ファイルを訪問して、 最新の項目が今日の日付で当人の名前のものでなければ、 新たに項目を作成します。 また、現在のファイルに対する新たな小項目も作成します。 多くの言語に対して、変更された関数名やその他のオブジェクトを 推測することもできます。

変更記録ファイルは、変更記録(change-log)モードで訪問します。 このメジャーモードでは、(空行で区切らない)ひとまとまりの小項目群を 段落として扱い、各項目をページとして扱います。 これにより項目の編集が容易になります。 C-jや自動詰め込みにより、 新たな行は直前の行と同様に字下げされます。 これは項目内容を入力するのに便利です。

プログラムの変更を掌握し、変更記録を維持する他の手段としては、 版管理(バージョンコントロール)システムがあります。 See 節 N.7.3.3 記録項目用バッファの機能



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.2 タグテーブル

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=Tags"
"texi/emacs21/X.2タグテーブル"へのコメント(無し)

タグテーブルとは、複数のファイルで構成されるプログラムが、 どのように各ファイルに分割されているのか記述したものです。 これは、プログラムを構成するファイル名、 そのファイルに入っている関数の名前(または、名前の付いた別の単位)や ファイル内の位置の一覧です。 こうして関連するファイルをまとめておけば、 全ファイルを対象とした探索や置換をコマンド1つで行えます。 また、関数名とその位置を記録してあるので、 関数がどのファイルに入っているか調べて関数定義をみつけだす M-.のようなコマンドを実現できます。

タグテーブルは、タグテーブルファイルと呼ばれるファイルに格納されます。 このファイルの慣習的な名前は`TAGS'です。

タグテーブルの各項目は、タグ名、タグが(暗黙に)定義されているファイルの名前、 そして、ファイル中でタグが定義されている位置を記録しています。

もとのプログラムファイルから、どんな名前がタグテーブルに記録されるかは、 プログラム言語によって異なります。 一般的には、すべての関数やサブルーチンを含み、 大域変数、データ型、あると便利なその他の情報などを含むこともあります。 記録された個々の名前をタグと呼びます。

X.2.1 ソースファイルのタグ構文    Tag syntax for various types of code and text files.
X.2.2 タグテーブルの作成    Creating a tags table with etags.
X.2.3 タグテーブルの選択    How to visit a tags table.
X.2.4 タグの探索    Commands to find the definition of a specific tag.
X.2.5 タグテーブルを用いた探索と置換    Using a tags table for searching and replacing.
X.2.6 タグテーブルの照会    Listing and finding tags defined in a file.



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.2.1 ソースファイルのタグ構文

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=Tag%20Syntax"
"texi/emacs21/X.2.1ソースファイルのタグ構文"へのコメント(無し)

ここでは、広く一般に使われている言語に対するタグ構文の定義を紹介します。

他にも以下の言語で使えます。

正規表現に基づいてタグを生成する方法 (see 節 X.2.2 タグテーブルの作成)もあるので、 上記以外の形式や言語を扱うこともできます。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.2.2 タグテーブルの作成

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=Create%20Tags%20Table"
"texi/emacs21/X.2.2タグテーブルの作成"へのコメント(無し)

タグテーブルファイルを作成するには、etagsプログラムを使います。 etagsは、数種類の言語について、 構文を解析しタグを取り出すことができます。 X.2.1 ソースファイルのタグ構文。 つぎのように実行します。

 
etags inputfiles...

etagsは指定されたファイルを読み、 カレント作業ディレクトリの`TAGS'という名前のファイルに タグテーブルを書き出します。 etagsは、ファイル名とその内容から自動的に使用言語を識別します。 後述の`--language=name'オプションで、 言語を明示することもできます。

ファイルを変更するなどしてタグテーブルの内容が古くなった場合、 テーブルを更新するには、最初にタグテーブルを作成した手順を 繰り返します。 頻繁に更新する必要はありません。

タグテーブルに記録できなかったり、誤ったファイルを記録してしまった場合、 Emacsはタグの定義をみつけることはできません。 しかし、(タグの定義を含んだファイルを多少編集するなどしたために) タグテーブルに記録された位置が多少ズレている程度ならば、 タグをみつけるのに通常より少し時間がかかるだけです。 記録された位置が大幅に狂っていたとしても、 Emacsはタグをみつけることができますが、 そのためにファイル全体を調べなくてはなりません。

ですから、新しいタグを定義したとき、タグの定義を別のファイルに移動したとき、 ファイルを相当変更したときには、タグテーブルの更新が必要です。 しかし、ファイルを編集するつどタグテーブルを更新する必要はありませんし、 毎日更新する必要すらないでしょう。

タグテーブルに別のタグテーブルを取り込むこともできます。 取り込むタグファイル名をオプション`--include=file'で 指定してタグファイルを作成します。 このように作成したタグファイルには、 指定したソースファイルに加えて、 取り込んだタグファイルに記録されていたファイルも含まれます。

etagsを実行するときに相対ファイル名でソースファイルを指定すると、 タグファイルには、タグファイルを書き出したときのディレクトリを 基準にしたファイル名が記録されます。 こうした場合、 タグファイルとソースファイルを含んだディレクトリ木構造全体を 移動することができ、しかも、タグファイルはソースファイルを正しく指し続けます。

etagsの引数として絶対ファイル名を指定すると、 タグファイルには絶対ファイル名が記録されます。 こうした場合、ソースファイルが同じ場所にある限り、 タグファイルを移動してもタグファイルは同じファイルを指し続けます。 絶対ファイル名は、`/'、あるいは、 MS-DOSとMS-Windowsでは`device:/'で始まります。

非常に多数のファイルからタグテーブルを作成する場合、 コマンド行の長さを制限しているシステムもあるので、 ファイル名をコマンドラインで指定するときに問題が起こる可能性があります。 この制限を回避するもっとも単純な方法は、 つぎのように、ファイル名を指定する位置にダッシュを打って、 etagsに標準入力からファイル名を読み込ませることです。

 
find . -name "*.[chCH]" -print | etags -

オプション`--language=name'を使えば、 言語を明示的に指定できます。 このオプションはファイル名と混ぜていくつでも使用できます。 それぞれ、あとに続くファイル名に適用されます。 `--language=auto'を指定すると、 etagsはファイル名とその内容からふたたび使用言語を推測します。 `--language=none'を指定すれば、 言語に依存した処理をいっさい行わないようになります。 すると、etagsは正規表現による一致だけに 基づいてタグを認識します。 etagsが知っている言語と、言語を推測するファイル名規則を表示するには、 `etags --help'を指定します。

`--regex'オプションは、 正規表現による一致に基づいてタグを認識させる一般的な方法です。 このオプションとファイル名を自由に混ぜて使用できます。 各`--regex'オプションは、それ以前に指定した正規表現に追加され、 オプションのあとにあるファイルに適用されます。 オプションの構文はつぎのとおりです。

 
--regex=/tagregexp[/nameregexp]/

ここで、tagregexpは、行に一致させてタグを取り出すために使われます。 これはつねに位置が固定されています。 つまり、`^'が前置されているかのように扱われます。 字下げ分を考慮したければ、正規表現を`[ \t]*'で始めて、 行頭の任意個の空白に一致するようにします。 正規表現においては、`\'は直後の文字をクォートし、 `\t'はタブ文字を表します。 etagsでは、これら以外にはCで使われるエスケープシーケンスを 扱えないことに注意してください。

etagsの正規表現の構文は、Emacsのものと同じで、 反復回数演算子(interval operator)が拡張されています。 この演算子は、grepedで使えるものと同じ動作をします。 反復回数演算子の構文は`\{m,n\}'であり、 直前の正規表現のm回以上n回以下の繰り返しに一致します。

tagregexpがタグとして認識したい部分よりも長く一致するようには しないでください。 tagregexpに一致する部分が必要以上に長くなるのが避けられないならば、 タグの範囲を狭めるためにnameregexpを追加するとよいかもしれません。 正規表現を利用した例をいくつか紹介しましょう。

`-R'オプションは、それまでに`--regex'オプションで定義した すべての正規表現を削除します。 つぎの使用例からもわかるように、 オプションのあとに続くファイルに適用されます。

 
etags --regex=/reg1/ voo.doo --regex=/reg2/ \
    bar.ber -R --lang=lisp los.er

この例では、etagsは、 `voo.doo'と`bar.ber'に対しては、その内容から使用言語を推定します。 さらに、`voo.doo'から余分にタグを認識するためにreg1を使い、 `bar.ber'から余分にタグを認識するためには reg1reg2の両方を使います。 `los.er'からタグを認識するには、 Lispのタグ構文規則だけを使い、正規表現による一致はいっさい使いません。

別の例を示しましょう。 ここでは、シェルが解釈しないように正規表現をクォートします。

他のオプション一覧を表示するには、 etags --helpを実行してください。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.2.3 タグテーブルの選択

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=Select%20Tags%20Table"
"texi/emacs21/X.2.3タグテーブルの選択"へのコメント(無し)

Emacsでは、いつでも1つの選択されたタグテーブルがあり、 タグテーブルを使って動作するコマンドは選択されたタグテーブルを使用します。 タグテーブルを選択するには、M-x visit-tags-tableと打ちます。 すると、タグテーブルファイル名を聞いてきます。 デフォルトのファイル名は、デフォルトディレクトリの`TAGS'です。

このコマンドは、ファイル名を変数tags-file-nameに格納するだけです。 タグテーブルを使おうとしない限り、 Emacsは実際にはタグテーブルの内容を読み込みません。 visit-tags-tableを使わずに、 自分自身でこの変数にファイル名を設定してもかまいません。 この変数の初期値はnilです。 これは、タグテーブルを使うすべてのコマンドに、 使用するタグテーブルファイルを尋ねさせることになります。

すでにタグテーブルを読み込んであるときにvisit-tags-tableを使うと、 2つの選択肢があります。 現在のタグテーブルリストに新たにタグテーブルを追加するか、 タグテーブルリストを新規に始めるかです。 タグコマンドは、現在のリストにあるすべてのタグテーブルを使用します。 新たなタグテーブルリストを始めると、他のタグテーブルのかわりに 新たなタグテーブルが使われます。 現在のリストに新たなタグテーブルを追加すると、 他のタグテーブルとともに新たなものも使われます。 タグコマンドがタグテーブルリストを走査するときには、 つねにリストの先頭から始めるわけではありません。 現在のファイルを記録しているタグテーブルがあれば、 まずそれから始めてリストの末尾まで進みます。 そして、リストの先頭からリストに含まれる すべてのタグテーブルを調べ終るまで走査を続けます。

変数tags-table-listに文字列のリストを設定すれば、 タグテーブルの正確なリストをあらかじめ指定できます。 たとえば、つぎのようにします。

 
(setq tags-table-list
      '("~/emacs" "/usr/local/lib/emacs/src"))

この設定例では、タグコマンドは、 個人の`~/emacs'ディレクトリと `/usr/local/lib/emacs/src'ディレクトリの (2つの)`TAGS'ファイルを見にいきます。 上で述べたように、タグファイルを使う順番は、 対象としているファイルやそのファイルを記述しているタグテーブルに依存します。

tags-file-nametags-table-listの両方に 値を設定してはいけません。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.2.4 タグの探索

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=Find%20Tag"
"texi/emacs21/X.2.4タグの探索"へのコメント(無し)

タグテーブルで実現されるもっとも重要な機能は、 指定したタグの定義を探し出すことです。

M-. tag RET
タグtagの最初の定義を探す(find-tag)。
C-u M-.
最後に指定したタグのつぎの定義を探す。
C-u - M-.
まえにみつかったタグに戻る。
C-M-. pattern RET
名前がpatternに一致するタグを探す(find-tag-regexp)。
C-u C-M-.
最後に使用したパターンに一致するつぎのタグを探する。
C-x 4 . tag RET
タグtagの最初の定義を探し、 別のウィンドウに表示する(find-tag-other-window)。
C-x 5 . tag RET
タグtagの最初の定義を探し、 バッファを選択するための新たなフレームを作る。 (find-tag-other-frame)。
M-*
まえにM-.を起動した場所へ戻る。

M-.find-tag)は、指定したタグの定義を探すコマンドです。 まず、タグテーブルの中で文字列としてタグ名を探し、 タグテーブルの情報を用いて、 定義されているファイルの名前とファイル内でのおおよその文字位置を求めます。 続いて、find-tagはそのソースファイルを訪れて、 ポイントをおおよその文字位置に移動してから、 範囲を広げながらタグの定義を探します。

(単にRETと打って)引数を指定しないと、 ポイントの直前または周辺にあるS式をtag引数として使います。 S式に関しては、See 節 V.2 リストとS式

コマンドM-.にタグの名前を完全に与える必要はありません。 その一部分で十分です。 というのは、M-.は、部分文字列としてtagを含む タグをタグテーブルで探すからです。 もちろん、部分一致よりも全一致のほうが望ましいです。 同じ部分文字列に一致する別のタグを探すには、 C-u M-.のようにfind-tagに数引数を指定します。 こうするとタグ名を聞いてきませんが、 最後に使ったものと同じ部分文字列を含む別のタグを タグテーブルから探します。 もし本物のMETAキーが使えるのであれば、 C-u M-.のかわりにM-0 M-.と打つほうが簡単でしょう。

バッファの切り替えを伴う他のコマンドと同様に、 find-tagにも新たなバッファを別のウィンドウに表示したり、 新規作成したフレームに表示する変種があります。 前者はC-x 4 .であり、コマンドfind-tag-other-windowを起動します。 後者はC-x 5 .であり、find-tag-other-frameを起動します。

最近にみつけたタグ位置に戻るには、C-u - M-.を使います。 より一般的には、M-.に負の数引数を指定します。 このコマンドは、別のバッファへも移動します。 C-x 4 .に負の数引数を指定すると、 別のウィンドウでまえのタグ位置に戻ります。

最近にみつけたタグ位置に戻るだけでなく、 タグを探したときの場所へ戻ることもできます。 それには、コマンドpop-tag-markを起動するM-*を使います。 典型的な使い方では、M-.で何かの定義を調べてから、 M-*でもとの場所に戻ります。

C-u - M-.M-*のどちらも、 変数find-tag-marker-ring-lengthで指定される深さまで、 辿った経路を引き返せます。

コマンドC-M-.find-tag-regexp)は、 指定した正規表現に一致するタグを訪れます。 部分文字列ではなく正規表現に一致するものであることを除けば、 M-.と同じです。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.2.5 タグテーブルを用いた探索と置換

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=Tags%20Search"
"texi/emacs21/X.2.5タグテーブルを用いた探索と置換"へのコメント(無し)

ここで紹介するコマンドは、選択されたタグテーブルに記録されている すべてのファイルを1つ1つ訪れては探索を行います。 これらのコマンドに対しては、タグテーブルは探索対象となる 一連のファイルを指定するだけです。

M-x tags-search RET regexp RET
選択されたタグテーブル内の各ファイルから 指定された正規表現を探索する。
M-x tags-query-replace RET regexp RET replacement RET
選択されたタグテーブル内の各ファイルに対して、 query-replace-regexpを実行する。
M-,
ポイント位置から上記のコマンドのいずれかを再実行する (tags-loop-continue)。

M-x tags-searchは、ミニバッファで正規表現を読み取り、 選択されたタグテーブル内のすべてのファイル1つ1つについて、 正規表現に一致する部分を探します。 このコマンドは探索しているファイル名を表示するので、 進行状況がわかります。 正規表現に一致する部分がみつかると、tags-searchはすぐに戻ります。

一致する部分をみつけたあとに、残りも探したくなるでしょう。 つぎの一致を探すには、 M-,tags-loop-continue)と打って、 tags-searchを再開します。 これは、カレントバッファの残りを探索してから、 タグテーブルの残りのファイルについても探索します。

M-x tags-query-replaceは、タグテーブル内のすべてのファイルを対象に、 query-replace-regexpを実行します。 このコマンドは、通常のM-x query-replace-regexp (問い合わせ型置換)と同じく、 探索すべき正規表現と置換文字列を読み取ります。 そして、M-x tags-searchのように探索を行い、 利用者の入力に応じて一致部分を処理することを繰り返します。 問い合わせ型置換について詳しくは、See 節 K.8 置換コマンド (2004/03/27)

M-x tags-query-replaceを一度起動するだけで、 タグテーブル内の全ファイルの置換を行うことができます。 しかし、一時的に置換作業から抜け出して、 問い合わせ型置換とは関係ないことを行えると便利です。 M-,と打てば、問い合わせ型置換を再開できます。 このコマンドは、最後に行ったタグの探索コマンドか置換コマンドを 再開します。

ここで紹介したコマンドは、find-tag系列のコマンドよりも、 幅広い探索を実行します。 find-tagコマンドは、指定した部分文字列や正規表現に一致する タグの定義だけをみつけます。 コマンドtags-searchtags-query-replaceは、 通常の探索コマンドや置換コマンドがカレントバッファで行うように、 正規表現に一致するあらゆる部分を探し出します。

これらのコマンドは、(Emacsバッファにまだ訪れていないものに対しては) 探索すべきファイル用に一時的なバッファを作成します。 一致部分がみつからなければバッファはただちに消されますが、 みつかれば存続します。

tags-searchは、grepプログラムにたいへんよく似ていると 思われたかもしれません。 Emacsの下位プロセスとしてgrepを実行して、 Emacsに一致した行を1つずつ表示させることもできます。 これは、コンパイルを実行するのと同じように動作します。 grepが一致を検出したソース箇所を探すことは、 コンパイルエラーを探すのと同様に動作します。 See 節 W.1 Emacs下でのコンパイラの実行 (2004/08/16)



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.2.6 タグテーブルの照会

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=List%20Tags"
"texi/emacs21/X.2.6タグテーブルの照会"へのコメント(無し)

M-x list-tags RET file RET
プログラムファイルfileで定義されているタグの一覧を表示する。
M-x tags-apropos RET regexp RET
regexpに一致するすべてのタグを表示する。

M-x list-tagsは、選択されたタグテーブルに記載されている ファイルのどれか1つのファイル名を読み取り、 そのファイルで定義されているすべてのタグを表示します。 引数の『ファイル名』は、タグテーブルに記録されたファイル名と 単純に文字列として比較されます。 ファイル名というよりは、文字列として読まれます。 したがって、補完やデフォルトはありませんし、 タグテーブルに格納されているとおりに正確にファイル名を入力する必要があります。 タグテーブル内のファイル名にディレクトリが含まれない限り、 ファイル名にもディレクトリを含めてはいけません。

M-x tags-approposは、タグに対するaproposにあたります (see 節 G.4 アプロポス)。 このコマンドは、正規表現を読み取り、 選択されたタグテーブルの中から正規表現に一致する項目のタグを すべてみつけだし、そのタグ名を表示します。

現在のタグテーブルに含まれるタグ名を名前空間として、 バッファ内で補完を行うこともできます。 See 節 V.9 シンボル名の補完



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.3 emergeを用いたファイルの併合

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=Emerge"
"texi/emacs21/X.3emergeを用いたファイルの併合"へのコメント(無し)

ちょっとしたミスで、1つのプログラムから2つの別の版を 作ってしまうこともあります。 この混乱した状態を収拾するには、それらを併合する必要があります。 emergeを使うと、併合作業が容易になります。 手動で比較するコマンドについては、N.9 ファイルの比較と The Ediff Manualを参照してください。

X.3.1 emergeの概要    How to start Emerge. Basic concepts.
X.3.2 emergeのサブモード    Fast mode vs. Edit mode. Skip Prefers mode and Auto Advance mode.
X.3.3 相違箇所の状態    You do the merge by specifying state A or B for each difference.
X.3.4 併合コマンド    Commands for selecting a difference, changing states of differences, etc.
X.3.5 emergeの終了    What to do when you've finished the merge.
X.3.6 2つの版の混合    How to keep both alternatives for a difference.
X.3.7 細かな注意点    Misc.



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.3.1 emergeの概要

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=Overview%20of%20Emerge"
"texi/emacs21/X.3.1emergeの概要"へのコメント(無し)

以下の4つのコマンドのいずれかでemergeを実行します。

M-x emerge-files
指定した2つのファイルを併合する。

M-x emerge-files-with-ancestor
共通の祖先を参照しながら、指定した2つのファイルを併合する。

M-x emerge-buffers
2つのバッファを併合する。

M-x emerge-buffers-with-ancestor
3番目のバッファに入っている共通の祖先を参照しながら、2つのバッファを併合する。

emergeコマンドは、2つのファイル、あるいは、2つのバッファを比較して、 比較結果を3つのバッファ、つまり、 各入力テキストに1つずつ(AバッファBバッファ)と、 併合を実施するバッファ(併合バッファ)に表示します。 併合バッファには、比較によって得られる差分だけでなく、 併合したテキスト全体が表示されます。 2つの入力テキストが相違している箇所については、 どちらのテキストを併合バッファに含めるか選択できます。

既存のバッファを入力源とするemergeコマンドでは、 入力バッファがナロイングされていると、 バッファの参照可能な部分だけを使います(see 節 AD.20 ナロイング (2005/05/07))。

併合したい2つのテキストのもとである共通の祖先にあたる版を利用できるときには、 emergeはそれを使ってどちらの選択肢が正しいのか推測します。 一方の入力と祖先との一致部分がどこかにあれば、 もう一方の入力には併合結果に残すべき意図的な変更がなされていると推測します。 共通の祖先のテキストを指定するには、 名前に`with-ancestor'の付いたコマンドを使ってください。 これらのコマンドは、A版、B版、共通の祖先に対応する 3つのファイル名かバッファ名を読み取ります。

入力を比較してバッファの準備を終えると、つぎは対話的な併合作業が始まります。 併合バッファで特別な併合コマンドを打って併合作業を制御します。 併合バッファには、単なる差分ではなく併合したテキスト全体が表示されます。 入力テキストの各相違箇所に対して、どちら側を残すか選択したり、 両者をもとにして編集できます。

併合バッファでは、emergeモードと呼ばれる特別なメジャーモードが使われ、 これらを選択するコマンドがあります。 もちろん、通常のEmacsコマンドでバッファを編集することもできます。

emergeの注意は、いつでも注目相違箇所と呼ばれる 相違箇所に向けられています。 3つのバッファ内では、注目相違点はつぎのように印が付けられます。

 
vvvvvvvvvvvvvvvvvvvv
text that differs
^^^^^^^^^^^^^^^^^^^^

emergeはすべての相違箇所に順に番号をふります。 さらに、モード行にはつねに注目相違箇所の番号が表示されます。

通常、併合バッファはA版の内容で始まります。 しかし、A版の内容が共通の祖先の内容と一致するときには、 併合バッファはB版の内容で始まります。

emergeを終えると、併合バッファにはその時点の併合済みテキストが残ります。 emerge終了時には、C-x C-wでファイルに保存できます。 emerge-filesemerge-files-with-ancestorに 数引数を指定すると、ミニバッファで出力ファイル名を読み取ります。 (どちらの場合でも、これがいちばん最後に聞かれるファイル名。) すると、emerge終了時には、併合済みのテキストがその出力ファイルに保存されます。

emergeを終えると、通常、emergeコマンドが併合バッファをファイルに保存します。 emergeをC-]でアボートするとemergeコマンドは併合バッファを保存しませんが、 必要ならばユーザー自身で保存できます。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.3.2 emergeのサブモード

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=Submodes%20of%20Emerge"
"texi/emacs21/X.3.2emergeのサブモード"へのコメント(無し)

併合コマンドを指示するためのモードが2つ、つまり、 高速モード(Fast mode)と編集モード(Edit mode)があり、どちらかを選べます。 高速モードでは、基本的な併合コマンドは1文字で表され、 通常のEmacsコマンドは禁止されています。 併合コマンドだけを使用するのであれば、高速モードが便利です。 編集モードでは、すべての併合コマンドはプレフィックスC-c C-cで始まり、 通常のEmacsコマンドも使えます。 このモードでは、併合バッファを編集できますが、emergeの処理は遅くなります。

編集モードに切り替えるにはeを使い、 高速モードに切り替えるにはC-c C-c fを使います。 モード行には、編集モードは`E'、高速モードは`F'と表示されます。

emergeには、特定の併合コマンドの動作に影響を与えるサブモードが さらに2つあります。 自動前進(auto-advance)モードと 優先箇所スキップ(skip-prefers)モードです。

自動前進モードがオンであると、コマンドabは、 自動的につぎの相違箇所にポイントを進めます。 このモードでは、どちらかの入力だけを選ぶ状況である限り、高速に併合を行えます。 モード行には`A'と表示され、自動前進モードであるを示します。

優先箇所スキップモードがオンであると、 コマンドnpは、 A優先/B優先の状態にある相違箇所をスキップします (see 節 X.3.3 相違箇所の状態)。 つまり、どちらの版も『正しい』と推定されない相違箇所だけを調べことになります。 モード行には`S'と表示され、優先箇所スキップモードであることを示します。

自動前進モードをオン/オフするには、 コマンドs aemerge-auto-advance-mode)を使います。 優先箇所スキップモードをオン/オフするには、 コマンドs semerge-skip-prefers-mode)を使います。 どちらのコマンドも、正の数引数を指定するとオンにし、 負あるいは0の数引数を指定するとオフにし、 引数を指定しないとトグル(切り替え)します。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.3.3 相違箇所の状態

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=State%20of%20Difference"
"texi/emacs21/X.3.3相違箇所の状態"へのコメント(無し)

併合バッファ内では、相違箇所は`v'と`^'の文字だけの行に 挟まれて示されます。 各相違箇所は、つぎの7つのいずれかの状態になっています。

状態A
この相違箇所はA版の内容である。 aコマンドは必ずこの状態にする。 モード行には`A'と表示される。

状態B
この相違箇所はB版の内容である。 bコマンドは必ずこの状態にする。 モード行には`B'と表示される。

デフォルトA
デフォルトB
まだ決心していないので、『デフォルト』で、 相違箇所は状態A(A版の内容)か状態B(B版の内容)である。 どちらかの選択肢が『優先される』(下記参照)場合を除いて、 相違箇所はすべてデフォルトAで始まる (つまり、併合バッファの内容はAバッファのコピー)。

相違箇所を選択すると、その状態は、デフォルトAやデフォルトBから 状態Aや状態Bに遷移する。 つまり、一度でも選択した相違箇所は、 デフォルトAやデフォルトBの状態であることはなく、 これらの状態はけっしてモード行には表示されない。

デフォルトの状態として、 コマンドd aはデフォルトAを選び、 d bデフォルトBを選ぶ。 これらのコマンドで選んだデフォルトの状態は、 一度も選択してなく、かつ、どちらの版も優先されない相違箇所に適用される。 併合作業を先頭から順に行っている場合、 最後に選択した相違箇所に続く相違箇所群が一度も選択されていないものである。 したがって、先頭から順に進めるのであれば、 d ad bを使い分けて、 併合バッファのある部分ではA版をデフォルトとし、 別の部分ではB版をデフォルトとすることができる。

優先A
優先B
どちらかが優先されているので、 相違箇所は状態A(A版の内容)か状態B(B版の内容)である。 つまり、明示的にはまだ選択していないが、当該箇所では、 一方の版が共通の祖先に一致するため、 他方の版のほうが正しく思われるのである。 したがって、Aバッファが共通の祖先と一致する箇所では、 実際に変更されたほうが正しいものである可能性があるので、 B版が優先される。

これらの2つの状態は、モード行では`A*'や`B*'と表示される。

混合状態
x cx Cコマンドの結果、 相違箇所は、状態A(A版の内容)と状態B(B版の内容)の混合状態になっている。

相違箇所がいったんこの状態になると、 コマンドabに数引数を指定しない限り、何もしない。

この状態は、モード行では`comb'と表示される。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.3.4 併合コマンド

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=Merge%20Commands"
"texi/emacs21/X.3.4併合コマンド"へのコメント(無し)

ここでは、高速モードの併合操作コマンドを示します。 編集モードでは、これらのコマンドのまえにC-c C-cを付けます。

p
まえの相違箇所を選択する。

n
つぎの相違箇所を選択する。

a
この相違箇所をA版にする(状態A)。

b
この相違箇所をB版にする(状態B)。

C-u n j
番号nの相違箇所を選択する。

.
ポイントを含む相違箇所を選択する。 このコマンドは、併合バッファ、Aバッファ、Bバッファのいずれでも使える。

q
終了する。 併合作業を完了。

C-]
アボートする。 併合作業をやめ、併合結果も保存しない。

f
高速モードに移行する。 (編集モードでは、実際にはC-c C-c fコマンド。)

e
編集モードに移行する。

l
3つのウィンドウすべてを(C-lのように)再表示する。

-
数引数の一部を指定する。

digit
これも、数引数の一部を指定する。

d a
併合バッファのこれ以降では、A版を選ぶ(デフォルトA)。

d b
併合バッファのこれ以降では、B版を選ぶ(デフォルトB)。

c a
この相違箇所のA版のテキストをキルリングにコピーする。

c b
この相違箇所のB版のテキストをキルリングにコピーする。

i a
この相違箇所のA版のテキストをポイント位置に挿入する。

i b
この相違箇所のB版のテキストをポイント位置に挿入する。

m
相違箇所の周りにポイントとマークを設定する。

^
3つのウィンドウすべてを(M-vのように)下にスクロールする。

v
3つのウィンドウすべてを(C-vのように)上にスクロールする。

<
3つのウィンドウすべてを(C-x <のように)左にスクロールする。

>
3つのウィンドウすべてを(C-x >のように)右にスクロールする。

|
3つのウィンドウすべてで、水平方向のスクロール分をリセットする。

x 1
併合バッファを表示しているウィンドウの高さを1行に縮小する。 (フルサイズに戻すにはC-u lを使う。)

x c
この相違箇所の2つの版を混合する(see 節 X.3.6 2つの版の混合)。

x f
emergeで作業しているファイル/バッファの名前を、 ヘルプ用ウィンドウに表示する。 (ウィンドウをもとの状態に戻すにはC-u lを使う。)

x j
この相違箇所を、つぎの相違箇所と結合する。 (C-u x jでは、まえの相違箇所と結合する。)

x s
この相違箇所を2つに分割する。 このコマンドを使うまえに、3つのバッファそれぞれで、 相違箇所を分割したい位置にポイントを移動しておく。

x t
相違箇所の先頭や末尾にある同じ行を取り去る。 このような行が現れるのは、 A版とB版は一致しているが、共通の祖先とは一致しない場合。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.3.5 emergeの終了

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=Exiting%20Emerge"
"texi/emacs21/X.3.5emergeの終了"へのコメント(無し)

qコマンド(emerge-quit)は、併合を終了し、 出力ファイルを指定してあれば、そこに結果を保存します。 AバッファとBバッファは正しい内容に復元されますが、 emergeがAバッファとBバッファを作成して、かつ、編集されていなければ、 それらをキルします。 さらに、併合バッファでのemergeコマンドを使用禁止にします。 というのは、これ以降に併合コマンドを実行すると さまざまなバッファが悪影響を受ける可能性があるからです。

C-]は、併合作業をアボートします。 つまり、出力ファイルに書き出さずに終ります。 出力ファイルを指定していなければ、併合作業をアボートしようが終了しようが、 何の違いもありません。

他のLispプログラムからemergeコマンドが呼び出された場合、 正しく終了するとt、アボートしたときはnilが返されます。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.3.6 2つの版の混合

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=Combining%20in%20Emerge"
"texi/emacs21/X.3.62つの版の混合"へのコメント(無し)

相違箇所によっては、両方の版を残したいこともあるでしょう。 そのような場合には、x cを使います。 すると、併合バッファはつぎのようになります。

 
#ifdef NEW
version from A buffer
#else /* not NEW */
version from B buffer
#endif /* not NEW */

この例では、2つの版をCのプリプロセッサの条件節で分けていますが、 変数emerge-combine-versions-templateに好みの文字列を設定すれば、 このコマンドで使用する文字列を指定できます。 この文字列内では、A版のテキストを置く箇所には`%a'を、 B版のを置く箇所には`%b'を指定します。 上に示した結果を生じるデフォルトの設定はつぎのとおりです。

 
"#ifdef NEW\n%a#else /* not NEW */\n%b#endif /* not NEW */\n"



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

X.3.7 細かな注意点

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs21&node=Fine%20Points%20of%20Emerge"
"texi/emacs21/X.3.7細かな注意点"へのコメント(無し)

併合作業中には、AバッファやBバッファを勝手に編集してはいけません。 emergeは一時的にこれらのバッファの内容を変更しますが、 最終的にはもとの状態に戻します。

複数の併合処理を同時に進めることもできますが、 別の併合処理の入力に同じバッファを使用してはいけません。 というのは、一時的にせよ、互いに異なる複数の変更が 1つのバッファに加えられてしまうからです。

入力ファイル全体を比較する必要があるため、 emergeの開始にはしばらく時間がかかる場合もあります。 また、diffコマンドが完了するまで、emergeは何もできません。 たぶん、そのうち誰かがemergeを変更して、 入力ファイルが大きいときにはバックグラウンドで比較を行うようにするでしょう。 そうすれば、emergeがコマンドを受け付けるようになるまで、 Emacsで他の作業を続けられます。

フックemerge-startup-hook(see 節 AE.2.3 フック)が、併合処理の設定の最後 に実行されます。


[ << ] [ >> ]           [表紙] [目次] [索引] [検索] [上端 / 下端] [?]