[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

31. テキスト

本章では、バッファ内のテキストを扱う関数について述べます。 それらのほとんどは、カレントバッファ内のテキストを 調べたり挿入したり削除しますが、しばしばポイント付近で行います。 多くは対話的に使えます。 テキストを変更するすべての関数は、変更を取り消せます(see section 31.9 アンドゥ)。

テキスト関連の多くの関数は、startendという名前の引数で渡された 2つのバッファ内位置で定義されるテキストの領域に作用します。 これらの引数は、マーカ(see section 30. マーカ)であるか 文字の位置を表す数値(see section 29. バッファ内の位置)である必要があります。 これらの引数の順番は関係なく、startが領域の終了位置で endが開始位置であってもまったく問題ありません。 たとえば、(delete-region 1 10)(delete-region 10 1)は同値です。 startendがバッファの参照可能部分の外側にあると エラーargs-out-of-rangeを通知します。 対話的な呼び出しでは、ポイントとマークをこれらの引数として使います。

本章では、バッファ内の文字を(関係あるときには) それらのテキスト属性を含めて『テキスト』と呼びます。

31.1 ポイント付近のテキストを調べる  Examining text in the vicinity of point.
31.2 バッファの内容を調べる  Examining text in a general fashion.
31.3 テキストの比較  Comparing substrings of buffers.
31.4 テキストの挿入  Adding new text to a buffer.
31.5 ユーザーレベルの挿入コマンド  User-level commands to insert text.
31.6 テキストの削除  Removing text from a buffer.
31.7 ユーザーレベルの削除コマンド  User-level commands to delete text.
31.8 キルリング  Where removed text sometimes is saved for later use.
31.9 アンドゥ  Undoing changes to the text of a buffer.
31.10 アンドゥリストの管理  How to enable and disable undo information. How to control how much information is kept.
31.11 詰め込み  Functions for explicit filling.
31.12 詰め込みのための余白  How to specify margins for filling commands.
31.13 適応型詰め込み(adaptive-fill)モード  Adaptive Fill mode chooses a fill prefix from context.
31.14 自動詰め込み(auto-filling)モード  How auto-fill mode is implemented to break lines.
31.15 テキストのソート  Functions for sorting parts of the buffer.
31.16 コラムを数える  Computing horizontal positions, and using them.
31.17 字下げ  Functions to insert or adjust indentation.
31.18 大文字小文字の変更  Case conversion of parts of the buffer.
31.19 テキスト属性  Assigning Lisp property lists to text characters.
31.20 文字コードの置換  Replacing a given character wherever it appears.
31.22 テキストの転置  Swapping two portions of a buffer.
31.21 レジスタ  How registers are implemented. Accessing the text or position stored in a register.
31.23 変更フック  Supplying functions to be run when text is changed.


31.1 ポイント付近のテキストを調べる

多くの関数は、ポイント付近の文字を調べるためのものです。 ここでは、数個の単純な関数について述べます。 33.3 正規表現の探索looking-atも参照してください。

Function: char-after &optional position
この関数は、カレントバッファ内の位置positionにある (つまり直後の)文字を返す。 positionがバッファの先頭のまえや末尾のうしろにあるなどして この目的に適した範囲の外側にあると、値はnilである。 positionのデフォルトはポイントである。

つぎの例では、バッファの最初の文字は`@'であると仮定する。

 
(char-to-string (char-after 1))
     => "@"

Function: char-before &optional position
この関数は、カレントバッファ内の位置positionのまえにある文字を返す。 positionがバッファの先頭のまえや末尾のうしろにあるなどして この目的に適した範囲の外側にあると、値はnilである。 positionのデフォルトはポイントである。

Function: following-char
この関数は、カレントバッファのポイントのうしろにある文字を返す。 これは(char-after (point))と同様である。 しかし、ポイントがバッファの末尾にあると、 following-charは0を返す。

ポイントはつねに文字のあいだにあり、 端末のカーソルはポイントの直後の文字に重ねて表示されることに注意してほしい。 したがって、following-charが返す文字は、 カーソルが重なっている文字である。

つぎの例では、ポイントは`a'と`c'のあいだにある。

 
---------- Buffer: foo ----------
Gentlemen may cry ``Pea-!-ce! Peace!,''
but there is no peace.
---------- Buffer: foo ----------

(char-to-string (preceding-char))
     => "a"
(char-to-string (following-char))
     => "c"

Function: preceding-char
この関数は、カレントバッファのポイントのまえの文字を返す。 例については上記のfollowing-charを参照。 ポイントがバッファの先頭にあると、preceding-charは0を返す。

Function: bobp
この関数は、ポイントがバッファの先頭にあるとtを返す。 ナロイングしていると、これはバッファの参照可能部分の先頭を意味する。 29.1 ポイントpoint-minも参照。

Function: eobp
この関数は、ポイントがバッファの末尾にあるとtを返す。 ナロイングしていると、これはバッファの参照可能部分の末尾を意味する。 29.1 ポイントpoint-maxも参照。

Function: bolp
この関数は、ポイントが行頭にあるとtを返す。 see section 29.2.4 テキスト行単位の移動。 バッファ(あるいはその参照可能部分)の先頭は、 つねに行頭とみなす。

Function: eolp
この関数は、ポイントが行末にあるとtを返す。 see section 29.2.4 テキスト行単位の移動。 バッファ(あるいはその参照可能部分)の末尾は、 つねに行末とみなす。


31.2 バッファの内容を調べる

本節では、Lispプログラムでバッファ内の任意の部分のテキストを文字列に変換する ための2つの関数について述べます。

Function: buffer-substring start end
この関数は、カレントバッファのstartendの位置で定義される 領域のテキストのコピーを含んだ文字列を返す。 引数がバッファの参照可能部分の内側の位置でないと、 buffer-substringはエラーargs-out-of-rangeを通知する。

startendより小さい必要はなく、引数の順番はどちらでもよい。 しかし、ほとんどの場合、小さい引数を先に書く。

コピーされるテキストにテキスト属性がある場合、 テキスト属性もそれが属する文字とともに文字列へコピーされる。 see section 31.19 テキスト属性。 しかし、バッファのオーバレイ(see section 38.8 オーバレイ)とそれらの属性は 無視されコピーされない。

 
---------- Buffer: foo ----------
This is the contents of buffer foo

---------- Buffer: foo ----------

(buffer-substring 1 10)
=> "This is t"
(buffer-substring (point-max) 10)
=> "he contents of buffer foo
"

Function: buffer-substring-no-properties start end
この関数はbuffer-substringと同様であるが、 テキスト属性をコピーせずに文字だけをコピーする点が異なる。 see section 31.19 テキスト属性

Function: buffer-string
この関数は、カレントバッファの参照可能部分全体の内容を文字列として返す。 これは、つぎと等価である。

 
(buffer-substring (point-min) (point-max))

 
---------- Buffer: foo ----------
This is the contents of buffer foo

---------- Buffer: foo ----------

(buffer-string)
     => "This is the contents of buffer foo
"

Function: thing-at-point thing
ポイントの周りやそのうしろにあるthingを文字列として返す。

引数thingは、構文上の要素の種類を指定するシンボルである。 可能な値は、symbollistsexpdefunfilenameurlwordsentencewhitespacelinepageなどである。

 
---------- Buffer: foo ----------
Gentlemen may cry ``Pea-!-ce! Peace!,''
but there is no peace.
---------- Buffer: foo ----------

(thing-at-point 'word)
     => "Peace"
(thing-at-point 'line)
     => "Gentlemen may cry ``Peace! Peace!,''\n"
(thing-at-point 'whitespace)
     => nil


31.3 テキストの比較

この関数により、バッファ内のテキストの部分同士を 文字列にコピーせずに比較できます。

Function: compare-buffer-substrings buffer1 start1 end1 buffer2 start2 end2
この関数は、同一バッファ内の2つの部分文字列、あるいは、 異なる2つのバッファの部分文字列を比較する。 始めの3つの引数は、バッファとそのバッファ内の2つの位置を与え、 1つの部分文字列を指定する。 残りの3つの引数も同様にして別の部分文字列を指定する。 カレントバッファを表すために、 buffer1buffer2のいずれか、あるいは、 両方にnilを指定できる。

始めの文字列のほうが小さければ値は負であり、 始めのほうが大きければ値は正であり、等しければ0である。 結果の絶対値は、部分文字列の中で最初に異なる文字の添字足す1である。

この関数は、case-fold-searchnil以外であると、 文字の比較では大文字小文字を区別しない。 テキスト属性はつねに無視する。

カレントバッファにはテキスト`foobarbar haha!rara!'があるとする。 すると、この例の2つの部分文字列は`rbar 'と`rara!'である。 2番目の文字で最初の文字列のほうが大きいので、結果は2である。

 
(compare-buffer-substring nil 6 11 nil 16 21)
     => 2


31.4 テキストの挿入

挿入(insertion)とは、バッファに新たなテキストを追加することです。 挿入されたテキストはポイント位置に、つまり、 ポイントのまえの文字とポイントのあとの文字のあいだに入ります。 挿入されたテキストのまえにポイントを留める関数もあれば、 そのうしろに留める関数もあります。 前者をポイントのうしろへ挿入と呼び、 後者をポイントのまえへ挿入と呼びます。

挿入により、挿入箇所よりうしろの位置を指すマーカは再配置されて 同じ周りの文字に留まります(see section 30. マーカ)。 マーカが挿入箇所を指している場合には、 マーカの挿入型(see section 30.5 マーカの挿入型)に依存して、 挿入するとマーカが再配置されたりされなかったりします。 insert-before-markersなどの特定の特殊な関数は、 マーカの挿入型に関わらず、 挿入されたテキストのうしろを指すように そのようなすべてのマーカを再配置します。

カレントバッファが読み出し専用であると、挿入関数はエラーを通知します。

これらの関数は、テキストの文字群をそれらの属性とともに 文字列からバッファへコピーします。 挿入された文字群は、コピーされるまえとまったく同じ属性を持ちます。 対照的に、文字列やバッファの一部ではない孤立した引数として 指定された文字群は、周りのテキストからテキスト属性を継承します。

挿入関数は、文字列由来やバッファ由来のテキストの場合には、 マルチバイトバッファへ挿入するために ユニバイトからマルチバイトへテキストを変換し、逆向きの変換も行います。 しかし、カレントバッファがたとえマルチバイトバッファであっても、 128から255のユニバイト文字コードはマルチバイト文字には変換しません。 See section 32.2 テキスト表現の変換

Function: insert &rest args
この関数は、文字列や文字群argsをカレントバッファのポイント位置に挿入し、 ポイントを先へ進める。 いいかえれば、ポイントのまえにテキストを挿入する。 argsが文字列でも文字でもないと、エラーを通知する。 値はnilである。

Function: insert-before-markers &rest args
この関数は、文字列や文字群argsをカレントバッファのポイント位置に挿入し、 ポイントを先へ進める。 argsが文字列でも文字でもないと、エラーを通知する。 値はnilである。

挿入箇所を指していたマーカを挿入されたテキストのうしろを指すように再配置 する点で、この関数は他の挿入関数と異なる。 挿入箇所でオーバレイが始まるときには、 挿入されたテキストはオーバレイの範囲外に出る。 空でないオーバレイが挿入箇所で終るときには、 挿入されたテキストはオーバレイの範囲内に入る。

Function: insert-char character &optional count inherit
この関数は、カレントバッファのポイントのまえに 文字charactercount個挿入する。 引数countは数(nilは1を意味する)であり、 characterは文字であること。 値はnilである。

この関数は、カレントバッファがたとえマルチバイトバッファであっても、 128から255のユニバイト文字コードはマルチバイト文字には変換しない。 see section 32.2 テキスト表現の変換

inheritnil以外であると、挿入された文字は、 挿入箇所の前後の2つの文字からスティッキテキスト属性を継承する。

Function: insert-buffer-substring from-buffer-or-name &optional start end
この関数は、バッファfrom-buffer-or-name(既存であること)の部分を カレントバッファのポイントのまえへ挿入する。 挿入されるテキストはstartからendまでの領域である。 (これらの引数のデフォルトは、当該バッファの参照可能部分の先頭と末尾である。) この関数はnilを返す。

この例では、バッファ`bar'をカレントバッファとしてフォームを実行する。 バッファ`bar'は最初は空であると仮定する。

 
---------- Buffer: foo ----------
We hold these truths to be self-evident, that all
---------- Buffer: foo ----------

(insert-buffer-substring "foo" 1 20)
     => nil

---------- Buffer: bar ----------
We hold these truth-!-
---------- Buffer: bar ----------

挿入に加えて周りのテキストからテキスト属性を継承する他の関数については、 See section 31.19.6 テキスト属性のスティッキ性。 字下げ関数が挿入した白文字もテキスト属性を継承します。


31.5 ユーザーレベルの挿入コマンド

本節では、テキストを挿入する上位レベルのコマンドについて述べます。 これらはLispプログラムでも有用ですが主にユーザー向けのコマンドです。

コマンド: insert-buffer from-buffer-or-name
このコマンドは、from-buffer-or-name(既存であること)の全内容を カレントバッファのポイントのうしろに挿入する。 挿入されたテキストのうしろにマークを置く。 値はnilである。

コマンド: self-insert-command count
このコマンドは、最後に打たれた文字を挿入する。 ポイントのまえにcount回挿入してnilを返す。 ほとんどの印字文字はこのコマンドにバインドされている。 普通の状況では、self-insert-commandは Emacsにおいてもっとも頻繁に呼び出される関数であるが、 プログラムではキーマップに登録する以外にはほとんど使わない。

対話的に呼ばれると、countは数値前置引数である。

このコマンドは、挿入した文字が空白や改行であると、 auto-fill-functionnil以外であると auto-fill-functionを呼び出す (see section 31.14 自動詰め込み(auto-filling)モード)。

このコマンドは、略語(abbrev)モードがオンであり、かつ、 挿入した文字が単語構成構文でないと、略語展開を行う。 (35. 略語と略語の展開とsee section 34.2.1 構文クラス一覧。)

挿入した文字が閉じ括弧構文であるときに blink-paren-functionを呼び出す責任も持つ (see section 38.11 括弧を点滅する)。

コマンド: newline &optional number-of-newlines
このコマンドは、カレントバッファのポイントのまえに改行を挿入する。 number-of-newlinesを指定すると、その個数だけ改行文字を挿入する。

この関数は、現在のコラム番号がfill-columnの値よりも大きく number-of-newlinesnilであると auto-fill-functionを呼び出す。 auto-fill-functionの典型的な仕事は改行を挿入することである。 ここでの全体としての効果は、改行を2つの異なる位置、つまり、 ポイント位置と行のまえの箇所に挿入することである。 newlineは、number-of-newlinesnil以外であると 自動詰め込みを行わない。

このコマンドは、左端の余白が0以外であるとその分だけ字下げする。 see section 31.12 詰め込みのための余白

戻り値はnilである。 対話的に呼ばれると、countは数値前置引数である。

コマンド: split-line
このコマンドは、行のポイントのうしろの部分を垂直に降ろして 変更前の真下に行を移動することで現在行を分割する。 関数indent-toを用いて、降ろした行の先頭に必要に応じて白文字を挿入する。

プログラムではまったくこの関数を使わない。

Variable: overwrite-mode
この変数は、上書き(overwrite)モードがオンかどうかを制御する。 この値は、overwrite-mode-textualoverwrite-mode-binarynilのいずれかであること。 overwrite-mode-textualは、テキストの上書きモード (改行とタブを特別に扱う)を指定し、 overwrite-mode-binaryは、バイナリの上書きモード (改行やタブも他の文字と同様に扱う)を指定する。


31.6 テキストの削除

削除とは、バッファ内のテキストのある部分をキルリング (see section 31.8 キルリング)に保存せずに取りさることです。 削除したテキストはヤンクはできませんが、 アンドゥ機構(see section 31.9 アンドゥ)を使って再度挿入できます。 特別な場合にはキルリングにテキストを保存する削除関数もあります。

すべての削除関数はカレントバッファに作用し、nilの値を返します。

コマンド: erase-buffer
この関数は、カレントバッファから全テキストを削除して空にする。 バッファが読み出し専用であると、エラーbuffer-read-onlyを通知する。 さもなければ、いっさい確認を取らずにテキストを削除する。 nilを返す。

バッファから多量のテキストを削除すると、通常、 『バッファが縮小した』としてそのバッファの自動保存を禁止する。 しかし、erase-bufferはこうしない。 これまでのテキストと将来のテキストには関連がなく、 これまでのテキストのサイズと比較すべきでないと考えるからである。

コマンド: delete-region start end
このコマンドは、startendで定義されるカレントバッファの テキストを削除する。 戻り値はnilである。 削除された領域の内側にポイントがあると、 その値は削除後にはstartになる。 さもなければ、マーカと同様にポイントは 周りのテキストに留まるように再配置される。

コマンド: delete-char count &optional killp
このコマンドは、ポイントの直後の、あるいは、 countが負であるとポイントの直前のcount個の文字を削除する。 killpnil以外であると、 削除した文字をキルリングに保存する。

対話的に呼ばれると、countは数値前置引数であり、 killpは未処理の前置引数である。 つまり、前置引数を指定すると、テキストをキルリングに保存する。 前置引数を指定しないと1文字だけを削除するが、 キルリングには保存しない。

戻り値はつねにnilである。

コマンド: delete-backward-char count &optional killp
このコマンドは、ポイントの直前の、あるいは、 countが負であるとポイントの直後のcount個の文字を削除する。 killpnil以外であると、 削除した文字をキルリングに保存する。

対話的に呼ばれると、countは数値前置引数であり、 killpは未処理の前置引数である。 つまり、前置引数を指定すると、テキストをキルリングに保存する。 前置引数を指定しないと1文字だけを削除するが、 キルリングには保存しない。

戻り値はつねにnilである。

コマンド: backward-delete-char-untabify count &optional killp
このコマンドは、タブを空白にかえながら後向きにcount個の文字を削除する。 つぎに削除する文字がタブであると、まずタブを配置を保つだけの等価な個数の 空白に置換してから、タブのかわりにそれらの空白を削除する。 killpnil以外であると、このコマンドは 削除した文字をキルリングに保存する。

countが正である場合に限って、タブを空白に変換する。 countが負であると、ポイントのうしろのちょうど -count個の文字を削除する。

対話的に呼ばれると、countは数値前置引数であり、 killpは未処理の前置引数である。 つまり、前置引数を指定すると、テキストをキルリングに保存する。 前置引数を指定しないと1文字だけを削除するが、 キルリングには保存しない。

戻り値はつねにnilである。

User Option: backward-delete-char-untabify-method
このオプションは、backward-delete-char-untabifyでの 白文字の扱い方を指定する。 可能な値は、タブを空白に変換してから空白を削除することを意味する デフォルトのuntabify、 1回の呼び出しでポイントのまえにある白文字をすべて削除することを意味する hungry、 白文字に対して特別なことをしないことを意味するnilである。


31.7 ユーザーレベルの削除コマンド

本節では、テキストを削除する上位レベルのコマンドについて述べます。 これらはLispプログラムでも有用ですが主にユーザー向けのコマンドです。

コマンド: delete-horizontal-space
この関数は、ポイントの周りの空白やタブをすべて削除する。 nilを返す。

つぎの例では、毎回ポイントを2番目と3番目の文字のあいだに置いて、 各行につき1回ずつdelete-horizontal-spaceを計4回呼び出す。

 
---------- Buffer: foo ----------
I -!-thought
I -!-     thought
We-!- thought
Yo-!-u thought
---------- Buffer: foo ----------

(delete-horizontal-space)   ; Four times.
     => nil

---------- Buffer: foo ----------
Ithought
Ithought
Wethought
You thought
---------- Buffer: foo ----------

コマンド: delete-indentation &optional join-following-p
この関数は、ポイントがある行をそのまえの行に連結する。 連結箇所の白文字は削除し、場合によっては空白1個に置き換える。 join-following-pnil以外であると、 delete-indentationは、この行を後続の行に連結する。 関数はnilを返す。

詰め込み接頭辞があり、かつ、連結対象の2番目の行が その接頭辞で始まっている場合には、 delete-indentationは連結するまえに詰め込み接頭辞を削除する。 see section 31.12 詰め込みのための余白

以下の例では、ポイントは`events'で始まる行にあり、 そのまえの行の行末に空白があっても違いはない。

 
---------- Buffer: foo ----------
When in the course of human
-!-    events, it becomes necessary
---------- Buffer: foo ----------

(delete-indentation)
     => nil

---------- Buffer: foo ----------
When in the course of human-!- events, it becomes necessary
---------- Buffer: foo ----------

行を連結したあと、 関数fixup-whitespaceには、 連結箇所に空白を置くかどうかを決定する責任がある。

Function: fixup-whitespace
この関数は、文脈に応じて、 ポイントを囲む白文字すべてを1つの空白に置換するかまったくなくす。 nilを返す。

行の先頭や末尾では、空白の適切な量は0である。 閉じ括弧構文の文字のまえや、 開き括弧構文や式前置子構文の文字のうしろでも空白はないほうが適している。 それ以外では、空白1個が適している。 see section 34.2.1 構文クラス一覧

以下の例では、最初の行の単語`spaces'のまえにポイントがあるときに 最初にfixup-whitespaceが呼ばれる。 2度目に呼ばれるときには、ポイントは`('の直後にある。

 
---------- Buffer: foo ----------
This has too many     -!-spaces
This has too many spaces at the start of (-!-   this list)
---------- Buffer: foo ----------

(fixup-whitespace)
     => nil
(fixup-whitespace)
     => nil

---------- Buffer: foo ----------
This has too many spaces
This has too many spaces at the start of (this list)
---------- Buffer: foo ----------

コマンド: just-one-space
このコマンドは、ポイントの周りのすべての空白やタブを1個の空白に置き換える。 nilを返す。

コマンド: delete-blank-lines
この関数は、ポイントを囲む空行を削除する。 前後に複数の空行がある空行にポイントがある場合、 1つの空行を残してそれ以外はすべて削除する。 孤立した1つの空行にポイントがある場合には、その行を削除する。 空行でない行にポイントがある場合には、 その行のうしろにある空行をすべて削除する。

空行とは、タブや空白のみから成る行と定義する。

delete-blank-linesnilを返す。


31.8 キルリング

キル関数は削除関数のようにテキストを削除しますが、 ユーザーがヤンク(yank)で再度挿入できるように保存します。 これらの関数の多くは、その名前に`kill-'があります。 対照的に、`delete-'で始まる名前の関数は、 ヤンクできるようにテキストを保存しません(アンドゥはできる)。 それらは『削除』関数です。

キルコマンドの多くは主に対話的に使うものであり、 ここではそれらについては述べません。 ここで述べるのは、そのようなコマンドを書くために使う関数についてです。 これらの関数は読者がテキストをキルするコマンドを書くために使えます。 Lisp関数において内部目的のためにテキストを削除する必要があるときには、 キルリングの内容を乱さないように普通は削除関数を用いるべきです。 See section 31.6 テキストの削除

キルしたテキストはあとでヤンクできるように キルリング(kill ring)に保存されます。 これは、最後にキルしたテキストだけでなく、 最近キルしたものを多数保持するリストです。 これを『リング』と呼ぶのは、 要素が循環しているようにヤンクが扱うからです。 このリストは変数kill-ringに保持されていて、 リスト向けの通常の関数で操作できますが、 本節で述べるように、それをリングとして扱う特別な関数もあります。

単語『キル』の使い方が不適当だと考える人々がいます。 『キル』したものを特に破壊しない操作を表すために使っているからです。 日常生活に照らしてみると、死は恒久的であり『キル』したものが 生き返ることはありません。 したがって、別の隠喩も提案されています。 たとえば、原稿を鋏で切り貼りすることに慣れていた前計算機世代の人々には 『カットリング』のほうが意味が通じるでしょう。 しかし、いまさら用語を変更するのは困難です。

31.8.1 キルリングの概念  What text looks like in the kill ring.
31.8.2 キル向けの関数  Functions that kill text.
31.8.3 ヤンク向けの関数  Commands that access the kill ring.
31.8.4 下位レベルのキルリング  Functions and variables for kill ring access.
31.8.5 キルリングの内部  Variables that hold kill-ring data.


31.8.1 キルリングの概念

キルリングは、もっとも最近にキルされたものを先頭にして、 キルされたテキストを文字列としてリストに記録します。 たとえば、短いキルリングはつぎのようになります。

 
("some text" "a different piece of text" "even older text")

リストの長さがkill-ring-maxに達すると、 新たな項目を追加すると自動的に最後の項目を削除します。

キルコマンドが他のコマンドと混在する場合、 各キルコマンドはキルリングに新たな項目を追加します。 連続した複数のキルコマンドは、キルリングに1つの項目を作りあげ、 それを1個としてヤンクできます。 2番目以降の連続したキルコマンドは、最初のキルコマンドが作った 項目にテキストを追加していきます。

ヤンクでは、キルリングの1つの項目をリングの『先頭』として区別します。 リングの別の項目を『先頭』と指定することでリングを『回転』する コマンドもあります。


31.8.2 キル向けの関数

kill-regionは、テキストをキルするための普通のサブルーティンです。 この関数を呼び出す任意のコマンドは『キルコマンド』です (その名前には`kill'があるはず)。 kill-regionは、新たにキルされたテキストを キルリングの先頭に新たな項目として追加したり、 もっとも最近の項目に加えます。 まえのコマンドがキルコマンドであるかどうかを (last-commandを使って)自動的に判定し、 もしそうならば、キルされたテキストをもっとも最近の項目に加えます。

コマンド: kill-region start end
この関数は、startendで定義される領域のテキストをキルする。 テキストは削除されるが、テキスト属性とともにキルリングに保存される。 値はつねにnilである。

対話的に呼ばれると、startendはポイントとマークである。

バッファが読み出し専用であると、 kill-regionはキルリングを同様に変更するが、 バッファを変更せずにエラーを通知する。 読み出し専用バッファからキルリングへテキストをコピーするために、 ユーザーはすべてのキルコマンドを使えるのでこれは便利である。

User Option: kill-read-only-ok
このオプションがnil以外であると、 kill-regionは、バッファが読み出し専用であってもエラーとしない。 そのかわりに、キルリングを更新しバッファは変更せずに戻る。

コマンド: copy-region-as-kill start end
このコマンドは、startendで定義される領域を (テキスト属性とともに)キルリングに保存するが、 バッファからテキストを削除しない。 nilを返す。 また、カーソルを一時的に移動してコピーしたテキストの範囲を示すか、 あるいは、エコー領域にメッセージを表示する。

このコマンドはthis-commandkill-regionを設定しないので、 これ以降のキルコマンドはキルリングの同じ項目には加えない。

Emacs 18版でも使うつもりがない限り、 Lispプログラムからはcopy-region-as-killを呼ばないこと。 Emacsの新しい版では、そのかわりにkill-newkill-appendを 使うほうがよい。 see section 31.8.4 下位レベルのキルリング


31.8.3 ヤンク向けの関数

ヤンク(yank)とは、キルリングからまえにキルされたテキストの項目を 再度挿入することです。

コマンド: yank &optional arg
このコマンドは、キルリングの先頭項目のテキストを ポイントのまえに挿入する。 そのテキストの先頭にマークを末尾にポイントを置く。

argがリスト(対話的な呼び出しではユーザーが数字文字なしに C-uを打ったとき)であると、yankは上に述べたように テキストを挿入するが、ヤンクしたテキストの先頭にポイントを 末尾にマークを置く。

argが数であると、yankarg番目のもっとも最近に キルされたテキスト、つまり、キルリングリストのarg番目の項目を 挿入する。

yankはキルリングの内容を変更したり回転しない。 nilを返す。

コマンド: yank-pop arg
このコマンドは、キルリングからヤンクした項目を キルリングの別の項目で置き換える。

これはyankや別のyank-popの直後でのみ許される。 そのような場合、リージョンにはヤンクしたばかりのテキストが含まれる。 yank-popはそのテキストを削除し、 その位置にキルされた別のテキストを挿入する。 削除したテキストはすでにキルリングのどこかにあるので、 キルリングには追加しない。

argnilであると、キルリングの古い項目で置き換える。 argが数であると、arg番古いキルで置き換える。 argが負であると、より最近のキルで置き換える。

キルリング内でのキルの順番は、 最古のもののつぎに最新のものがあり、 最新のもののまえに最古のものがあるように折り返されている。

戻り値はつねにnilである。


31.8.4 下位レベルのキルリング

これらの関数と変数は、下位レベルでキルリングを参照するためのものですが、 Lispプログラムで使っても便利です。 これらはウィンドウシステムのセレクション(see section 28.18 ウィンドウシステムのセレクション) との相互作用の面倒をみてくれるからです。

Function: current-kill n &optional do-not-move
関数current-killは、キルリングの『先頭』として区別する ヤンクポインタを(新しいキルから古いキルへ向けて)n個分回転し、 リングのその位置のテキストを返す。

省略可能な第2引数do-not-movenil以外であると、 current-killは、ヤンクポインタは変更せずに、 現在のヤンクポインタから数えてn番目のキルを返す。

nが0であると、もっとも最近のキルを要求することを表し、 current-killは、キルリングを調べるまえに (以下に述べる)interprogram-paste-functionの値を呼び出す。

Function: kill-new string
この関数は、テキストstringを新たな項目として キルリングの先頭に置く。 必要ならば最古の項目を破棄する。 interprogram-cut-function(下記参照)の値も起動する。

Function: kill-append string before-p
この関数は、キルリングの先頭項目にテキストstringを追加する。 通常、stringはその項目の末尾に加わるが、 before-pnil以外であるとその項目の先頭に加わる。 この関数は、interprogram-cut-function(下記参照)の値も起動する。

Variable: interprogram-paste-function
この変数は、ウィンドウシステムを使っているときに 別のプログラムからキルされたテキストを転送する方法を提供する。 その値は、nilであるか、引数なしの関数であること。

値が関数であると、 『もっとも最近のキル』を得るためにcurrent-killが呼び出す。 関数がnil以外の値を返すと、 その値は『もっとも最近のキル』として使われる。 nilを返せば、kill-ringの先頭項目が使われる。

このフックの普通の用途は、 セレクションが別のアプリケーションに属する場合であっても、 ウィンドウシステムの一次セレクションを もっとも最近のキルとして得ることである。 see section 28.18 ウィンドウシステムのセレクション

Variable: interprogram-cut-function
この変数は、ウィンドウシステムを使っているときに キルされたテキストを別のプログラムへ転送する方法を提供する。 その値は、nilであるか、引数なしの関数であること。

値が関数であると、kill-newkill-appendが キルリングの新たな先頭項目を引数として呼び出す。

このフックの普通の用途は、 新たにキルされたテキストを ウィンドウシステムの一次セレクションにすることである。 see section 28.18 ウィンドウシステムのセレクション


31.8.5 キルリングの内部

変数kill-ringは、文字列のリストの形でキルリングの内容を保持します。 もっとも最近のキルがつねにリストの先頭にあります。

変数kill-ring-yank-pointerは、 CARがつぎにヤンクすべきテキストであるような キルリングリストの項目を指しています。 この変数がリングの『先頭』を識別するといいます。 kill-ring-yank-pointerを別の項目へ動かすことを キルリングを回転すると呼びます。 ヤンクポインタを動かす関数は、 リストの末尾からリストの先頭へ折り返しその逆も行うので、 キルリングを『リング』と呼ぶのです。 リングの回転は仮想的なものであり、 kill-ringの値は変更しません。

kill-ringkill-ring-yank-pointerもLisp変数であり、 それらの値は普通のリストです。 kill-ring-yank-pointerの名前の単語『ポインタ』は、 つぎのヤンクコマンドで使うリストの項目を識別することが 変数の目的であることを表します。

kill-ring-yank-pointerの値は、キルリングリストの 1つの項目とつねにeqです。 これが識別する項目は、その項目のCARです。 キルリングを変更するキルコマンドも、 kill-ringの値をこの変数の値とします。 その効果は、新たにキルされたテキストが先頭にくるように リングを回転することです。

キルリング("some text" "a different piece of text" "yet older text")の 第2項目を変数kill-ring-yank-pointerが指しているようすをつぎに示します。

 
kill-ring                  ---- kill-ring-yank-pointer
  |                       |
  |                       v
  |     --- ---          --- ---      --- ---
   --> |   |   |------> |   |   |--> |   |   |--> nil
        --- ---          --- ---      --- ---
         |                |            |            
         |                |            |            
         |                |             -->"yet older text" 
         |                |
         |                 --> "a different piece of text" 
         |
          --> "some text"

C-yyank)の直後にM-yyank-pop)を使うと この状態になります。

Variable: kill-ring
この変数は、もっとも最近にキルされたものを最初にして キルされたテキストを順に並べたリストを保持する。

Variable: kill-ring-yank-pointer
この変数の値は、キルリングのどの要素が ヤンクするためのリングの『先頭』であるかを表す。 より正確には、その値はkill-ringのリストの一部であり、 そのCARはC-yがヤンクするキルされた文字列である。

User Option: kill-ring-max
この変数の値は、末尾の要素が破棄されるまでに キルリングが増大できる最大の長さである。 kill-ring-maxのデフォルト値は30である。


31.9 アンドゥ

ほとんどのバッファには、バッファのテキストに対する変更をアンドゥ(もとに戻す) できるようにすべての変更を記録する アンドゥリスト(undo list)があります。 (アンドゥリストのないバッファは、 Emacsがアンドゥは有用ではないと仮定する特殊目的のバッファである。) バッファのテキストを変更するすべての基本関数は、 変数buffer-undo-listに収めたアンドゥリストの先頭に 自動的に要素を追加します。

Variable: buffer-undo-list
この変数の値は、カレントバッファのアンドゥリストである。 値tはアンドゥ情報の記録を禁止する。

アンドゥリストの要素として可能なものをつぎに示します。

position
この種の要素は、まえのポイント値を記録する。 この要素をアンドゥするとポイントをpositionへ移動する。 通常のカーソル移動では、いかなる種類のアンドゥ記録も作らないが、 削除操作ではコマンド実行前のポイント位置を記録するためにこの項目を作る。

(beg . end)
この種の要素は、挿入されたテキストを削除する方法を表す。 挿入されたテキストはバッファのbegからendまでの範囲を占める。

(text . position)
この種の要素は、削除されたテキストを再度挿入する方法を表す。 削除されたテキストそのものは文字列textである。 再度挿入する位置は(abs position)である。

(t high . low)
この種の要素は、未変更のバッファが変更されたことを表す。 highlowは2つの整数であり、それぞれ、 まえに訪問したときや保存したときの訪問しているファイルの更新時刻の 16ビットを記録している。 primitive-undoはこれらの値を用いて、 バッファを再度未変更と印を付けるかどうか判定する。 ファイルの更新時刻がこれに一致するときにのみ再度未変更とする。

(nil property value beg . end)
この種の要素は、テキスト属性の変更を記録する。 変更をアンドゥするにはつぎのようにする。

 
(put-text-property beg end property value)

(marker . adjustment)
この種の要素は、周りのテキストが削除されたために マーカmarkerを再配置し adjustment文字分位置を移動したことを記録する。 この要素をアンドゥすると、 marker - adjustment文字に移動する。

nil
この要素は境界である。 2つの境界のあいだの要素群を変更グループ(change group)と呼ぶ。 通常、各変更グループは1つのキーボードコマンドに対応し、 アンドゥコマンドはグループ全体を1個としてアンドゥする。

Function: undo-boundary
この関数は、アンドゥリストに境界要素を置く。 アンドゥコマンドはそのような境界で停止し、 連続したアンドゥコマンドはよりまえの境界までアンドゥする。 この関数はnilを返す。

エディタコマンドループは、 各キー列を実行するまえにアンドゥの境界を自動的に作る。 したがって、各アンドゥは、1つのコマンドの効果を普通は取り消す。 自己挿入の入力文字は例外である。 コマンドループはそのような最初の文字に境界を作り、 つぎの19個の連続する自己挿入の入力文字では境界を作らず、 20番目で境界を作るということを自己挿入の入力文字が続く限り行う。

別のバッファでアンドゥ可能な変更を行うたびに バッファのすべての変更で境界を追加する。 これは、各コマンドが変更した箇所で各バッファに境界を作ることを 保証するためである。

1つのコマンドの効果を複数に分けるためにこの関数を直接呼ぶことは有用である。 たとえば、query-replaceは各置換のあとでundo-boundaryを呼び出し、 ユーザーが個々の置換を1つ1つアンドゥできるようにする。

Function: primitive-undo count list
これは、アンドゥリストの要素をアンドゥする基本的な関数である。 listの先頭のcount個の要素をアンドゥし、listの残りを返す。 この関数をLispで書くこともできるが、Cで書いたほうが便利である。

primitive-undoは、バッファを変更すると バッファのアンドゥリストに要素を追加する。 アンドゥコマンドは一連のアンドゥ操作を始めるときに アンドゥリストを保存して混乱を避ける。 アンドゥ操作では、保存しておいた値を使い更新する。 アンドゥによって追加される新たな要素はこの保存された値の一部ではないので、 それらはアンドゥを続行しても干渉しない。


31.10 アンドゥリストの管理

本節では、指定されたバッファでアンドゥ情報の記録をオン/オフする 方法について述べます。 また、アンドゥリストが大きくなりすぎないように 自動的に切り詰める方法についても説明します。

新たに作成されたバッファのアンドゥ情報の記録は普通は始めオンですが、 バッファ名が空白で始まる場合は最初からオフです。 つぎの2つの関数を使うか、読者自身がbuffer-undo-listに設定すれば、 アンドゥ記録を明示的にオン/オフできます。

コマンド: buffer-enable-undo &optional buffer-or-name
このコマンドは、バッファbuffer-or-nameでのアンドゥ記録をオンにし、 以降の変更を取り消せるようにする。 引数を指定しないと、カレントバッファを使う。 当該バッファでアンドゥ記録がすでにオンであると、 この関数はなにもしない。 nilを返す。

対話的に呼ばれると、buffer-or-nameはカレントバッファである。 他のバッファを指定できない。

コマンド: buffer-disable-undo &optional buffer
コマンド: buffer-flush-undo &optional buffer
この関数はバッファbufferのアンドゥリストを破棄し、 以降のアンドゥ情報の記録をオフにする。 その結果、これ以前の変更も以降の変更も取り消すことはできない。 bufferのアンドゥリストがすでにオフであると、 この関数にはなんの効果もない。

この関数はnilを返す。

名前buffer-flush-undoは廃れているとはみなさないが、 好ましい名前はbuffer-disable-undoである。

編集を続けるにしたがってアンドゥリストはどんどん長くなります。 これらがメモリを使い尽くさないように、 読者が設定した上限サイズにガベッジコレクションが切り詰めます。 (この目的においてアンドゥリストの『サイズ』は、 リストを構成するコンスセルの個数と削除された文字列の和である。) 2つの変数undo-limitundo-strong-limitは、 許容できるサイズの範囲を制御します。

Variable: undo-limit
これはアンドゥリストの許容できるサイズの緩い制限である。 このサイズを越える位置にある変更グループは保持される最古のものである。

Variable: undo-strong-limit
これはアンドゥリストの許容できるサイズの上限である。 このサイズを越える位置にある変更グループは (これより古いものも含めて)削除される。 例外が1つあり、最新の変更グループは それがどれほど大きくてもけっして破棄しない。


31.11 詰め込み

詰め込み(fill)とは、指定されている最大幅 (を越えず)にほぼ収まるように(行分け位置を移動して) 行の長さを調整することです。 さらに、行を幅揃え(justify)することもできます。 つまり、左右の両端や片側の余白をきちんと揃えるため 空白を挿入することです。 幅は変数fill-columnで制御します。 読みやすいように、行は70コラム程度に収めるべきです。

テキストを挿入するにつれて自動的にテキストを詰め込むには、 自動詰め込み(auto-fill)モード(see section 31.14 自動詰め込み(auto-filling)モード)を使いますが、 既存のテキストを変更しても正しくない詰め込み状態のまま放置されます。 したがって、そのようなテキストは明示的に詰め込む必要があります。

本節のほとんどの関数が返す値には意味はありません。 詰め込みを行うすべての関数は、現在の左端余白、現在の右端余白、 現在の幅揃えスタイルに注意をはらいます(see section 31.12 詰め込みのための余白)。 現在の幅揃えスタイルがnoneであると、 詰め込み関数は実際にはなにもしません。

詰め込み関数には引数justifyを取るものもあります。 それがnil以外であると、幅揃えの種類を指示します。 特定の幅揃えスタイルを指示するものは、 leftrightfullcenterです。 それがtであると、 テキストの当該部分には現在の幅揃えスタイルを用いることを意味します (下記のcurrent-justificationを参照)。 これ以外の値はfullとして扱います。

対話的に詰め込み関数を呼ぶときに前置引数を使うと、 justifyとして値fullを暗に指示します。

コマンド: fill-paragraph justify
このコマンドは、ポイントがある段落、あるいは、ポイントのあとの段落を詰め込む。 justifynil以外であると、各行の幅揃えも行う。 段落の境界を探すために普通の段落移動コマンドを用いる。 see section `段落' in GNU Emacs マニュアル

コマンド: fill-region start end &optional justify nosqueeze to-eop
このコマンドは、startからendの領域内の各段落を詰め込む。 justifynil以外であれば、幅揃えも行う。

nosqueezenil以外であると、 行分け以外の白文字にはふれないことを意味する。 to-eopnil以外であると、 段落の末尾まで、あるいは、 use-hard-newlinesがオンならばつぎのハード改行(下記参照)までを 詰め込むことを意味する。

変数paragraph-separateは、段落の区別方法を制御する。 see section 33.8 編集に用いられる標準的な正規表現

コマンド: fill-individual-paragraphs start end &optional justify mail-flag
このコマンドは、領域内の各段落を各段落の詰め込み接頭辞に従って詰め込む。 したがって、段落の行が空白で字下げされていると、 詰め込んだあとの段落も同じように字下げされる。

最初の2つの引数startendは、 詰め込むべき範囲の先頭と末尾である。 3番目と4番目の引数、justifymail-flagは省略できる。 justifynil以外であると、 段落の詰め込みに加えて幅揃えも行う。 mail-flagnil以外であると、 メイルメッセージなのでヘッダ行を詰め込まないことを意味する。

通常、fill-individual-paragraphsは、 字下げが変わると新しい段落の開始とみなす。 fill-individual-varying-indentnil以外であると、 区切り行のみが段落を区切るとみなす。 これは段落の先頭行と後続の行で字下げが異なる段落を処理できる。

User Option: fill-individual-varying-indent
この変数は、上に述べたように fill-individual-paragraphsの動作を変える。

コマンド: fill-region-as-paragraph start end &optional justify nosqueeze squeeze-after
このコマンドは、テキストの領域を1つの段落とみなして詰め込む。 領域に複数の段落があると、段落のあいだの空行は取りさる。 justifynil以外であると幅揃えも行う。

対話的な呼び出しでは、前置引数で幅揃えを指示する。

nosqueezenil以外であると、 行分け以外の白文字にはふれないことを意味する。 squeeze-afternil以外であると、 それは領域内の位置を表し、 その位置よりまえにある空白を変更しないように指示する。

適応型詰め込み(adaptive-fill)モードでは、 デフォルトの詰め込み接頭辞を選ぶために このコマンドはfill-context-prefixを呼び出す。 see section 31.13 適応型詰め込み(adaptive-fill)モード

コマンド: justify-current-line how eop nosqueeze
このコマンドは、現在行の単語のあいだに空白を挿入し、 ちょうどfill-columnコラムで行が終るようにする。 nilを返す。

引数hownil以外であると、 幅揃えスタイルを指定する。 可能な値は、leftrightfullcenter、または、noneである。 tであると、指定されている幅揃えスタイルに従うことを意味する (下記のcurrent-justificationを参照)。 nilは、幅揃えしないことを意味する。

eopnil以外であると、 current-justificationが両端揃えを指定しているときには 左端揃えを行うことを意味する。 これは段落の最後の行に適用される。 段落全体として両端揃えであっても、最後の行はそうすべきではない。

nosqueezenil以外であると、 内側の白文字を変更しないことを意味する。

User Option: default-justification
この変数の値は、テキスト属性で幅揃えスタイルを指定していない テキストに対して用いる幅揃えスタイルを指定する。 可能な値は、leftrightfullcenternoneである。 デフォルト値はleftである。

Function: current-justification
この関数は、ポイントの周りのテキストを詰め込むときに使う 正しい幅揃えスタイルを返す。

User Option: sentence-end-double-space
この変数がnil以外であると、 直後に1つの空白を従えたピリオドを文末とみなさず、 詰め込み関数はそのような箇所で行分けしない。

Variable: fill-paragraph-function
この変数は、段落の詰め込みに優先する方法をメジャーモードに与える。 値がnil以外であると、 fill-paragraphは詰め込み処理のためにこの関数を呼び出す。 関数がnil以外の値を返すと、 fill-paragraphは処理が完了したとみなして戻り値をただちに返す。

この機能の普通の用途は、 プログラム言語向けのモードでコメントを詰め込むためである。 この関数で普通の方法で詰め込む必要がある場合には、つぎのようにする。

 
(let ((fill-paragraph-function nil))
  (fill-paragraph arg))

Variable: use-hard-newlines
この変数がnil以外であると、 詰め込み関数は、テキスト属性hardを持つ改行を削除しない。 これらの『ハード改行』は段落の区切りとして働く。


31.12 詰め込みのための余白

User Option: fill-prefix
このバッファローカルな変数は、普通のテキスト行の先頭に現れ、 詰め込み時には無視すべきテキストの文字列(詰め込み接頭辞)を指定する。 詰め込み接頭辞で始まらない行は段落の開始行とみなすため、 詰め込み接頭辞のあとに余分に白文字があるとそれらも段落の開始行とみなす。 詰め込み接頭辞で始まりそのあとに余分な白文字がない行は、 いっしょに詰め込める普通のテキスト行である。

左端余白がある場合には、左端余白のあとに詰め込み接頭辞が続く。

User Option: fill-column
このバッファローカルな変数は、詰め込んだ行の最大幅を指定する。 この値は整数であり、コラム数であること。 自動詰め込み(auto-fill)モード(see section 31.14 自動詰め込み(auto-filling)モード)を含めて すべての詰め込み/幅揃え/中央揃えを行うコマンドは、 この変数に影響される。

特に他人のために書いているテキストでは、 fill-columnを70未満にするべきである。 さもないと、人によっては快適に読むには行が長すぎて、 テキストが不恰好に見える。

Variable: default-fill-column
この変数の値は、バッファでfill-columnの値を設定していない場合の fill-columnのデフォルト値である。 これは(default-value 'fill-column)と同じである。

default-fill-columnのデフォルト値は70である。

コマンド: set-left-margin from to margin
fromからtoまでのテキストの 属性left-marginを値marginにする。 自動詰め込み(auto-fill)モードがオンであると、 このコマンドは、当該領域を再詰め込みして新たな余白に適合するようにする。

コマンド: set-right-margin from to margin
fromからtoまでのテキストの 属性right-marginを値marginにする。 自動詰め込み(auto-fill)モードがオンであると、 このコマンドは、当該領域を再詰め込みして新たな余白に適合するようにする。

Function: current-left-margin
この関数は、ポイントの周りのテキストを詰め込むときに使う 正しい左端余白の値を返す。 その値は、現在行の最初の文字の属性left-marginの値(なければ0) と変数left-marginの値の和である。

Function: current-fill-column
この関数は、ポイントの周りのテキストを詰め込むときに使う 正しい詰め込み幅を返す。 その値は、変数fill-columnの値から ポイント直後の文字の属性right-marginの値を引いたものである。

コマンド: move-to-left-margin &optional n force
この関数は、ポイントを現在行の左端余白へ移動する。 移動先のコラム位置は関数current-left-marginを呼び出して決定する。 引数nnil以外であると、 move-to-left-marginn-1先の行へまず移動する。

forcenil以外であると、 行の字下げが左端余白の値に一致しないときには、 字下げを修正することを指示する。

Function: delete-to-left-margin from to
この関数は、fromからtoまでのテキストから 左端余白分の字下げを取りさる。 削除する字下げ量は、current-left-marginを呼び出して決定する。 この関数が白文字以外を削除することは絶対にない。

Function: indent-to-left-margin
これは、基本(fundamental)モード、テキスト(text)モードなどが使う デフォルトのindent-line-functionである。 その効果は、変数left-marginの値で指定した位置から 現在行が始まるように字下げを調整することである。 それには白文字の挿入や削除が伴う。

Variable: left-margin
この変数は、左端余白コラムの起点を指定する。 基本(fundamental)モードでは、C-jがこのコラム位置に字下げする。 この変数に設定すると自動的にバッファローカルになる。

Variable: fill-nobreak-predicate
この変数は、特定の箇所では行分けしない方法をメジャーモードに提供する。 その値は関数であること。 この関数は、引数なしで行分け予定箇所にポイントを置いて呼び出される。 この関数がnil以外を返すと、当該箇所では行分けしない。


31.13 適応型詰め込み(adaptive-fill)モード

適応型詰め込みモード(adaptive-fill)では、 詰め込むべき各段落のテキストから自動的に詰め込み接頭辞を選びます。

User Option: adaptive-fill-mode
この変数がnil以外であると、 適応型詰め込みモード(adaptive-fill)がオンである。 デフォルトではtである。

Function: fill-context-prefix from to
この関数は適応型詰め込みモード(adaptive-fill)の中核を実装するものであり、 fromからtoのあいだのテキストに基づいて詰め込み接頭辞を選ぶ。 以下に述べる変数に基づいて、段落の最初の2行を調べてこれを行う。

User Option: adaptive-fill-regexp
この変数は、適応型詰め込みモード(adaptive-fill)を制御する 正規表現を保持する。 適応型詰め込みモード(adaptive-fill)では、 行の(あれば)左端余白の白文字のうしろから始まるテキストに対して この正規表現の一致を試みる。 一致した文字群が当該行の詰め込み接頭辞の候補になる。

User Option: adaptive-fill-first-line-regexp
1行だけの段落において、詰め込み接頭辞の候補がこの正規表現に一致するか、 comment-start-skipに一致すると、その候補を使う。 さもなければ、同じ幅に相当する白文字をかわりに使う。

1行だけの段落から選んだ詰め込み接頭辞が後続の行の段落の始まりである場合には、 1行だけの段落からはけっして詰め込み接頭辞を選ばない。

User Option: adaptive-fill-function
この変数に関数を指定することで、 詰め込み接頭辞のより複雑な自動選択方法を指定できる。 この関数は、adaptive-fill-regexpの一致に失敗したときに、 行の左端余白のうしろにポイントを置いて呼び出され、 当該行に基づいて適切な詰め込み接頭辞を返すこと。 それがnilを返すと、当該行には詰め込み接頭辞がないことを意味する。


31.14 自動詰め込み(auto-filling)モード

自動詰め込み(auto-filling)モードは、テキストを挿入するにつれて 自動的に行を詰め込むマイナモードです。 本節では、自動詰め込み(auto-filling)モードが使うフックについて述べます。 既存のテキストを詰め込んだり幅揃えするために 明示的に呼び出す関数については、31.11 詰め込みを参照してください。

自動詰め込み(auto-filling)モードでは、 テキストの一部を再詰め込む際の 余白や幅揃えスタイルを変更するための関数も使えるようにします。 See section 31.12 詰め込みのための余白

Variable: auto-fill-function
この変数の値は、 自己挿入される空白や改行のあとで呼び出されるべき (引数なしの)関数であること。 これがnilであると、そのような場合に特別なことを行わない。

自動詰め込み(auto-filling)モードがオンであると、 auto-fill-functionの値はdo-auto-fillである。 この関数の目的は、行分けの通常の方針を実装することである。

Emacsの古い版では、この変数をauto-fill-hookと命名していたが、 フックの標準的な慣習に従って呼ばれないため 19版でauto-fill-functionと改名した。

Variable: normal-auto-fill-function
この変数は、自動詰め込み(auto-filling)モードがオンになったとき/であるときに auto-fill-functionとして用いる関数を指定する。 メジャーモードでは、この変数のバッファローカルな値に設定することで 自動詰め込み(auto-filling)モードのふるまいを変更できる。


31.15 テキストのソート

本節で述べるソート関数すべては、バッファ内のテキストを並べ替えます。 これは、リスト内の要素の順番を並べ替える関数sort (see section 5.6.3 リストの順序を変更する関数)と対照的です。 これらの関数が返す値には意味はありません。

Function: sort-subr reverse nextrecfun endrecfun &optional startkeyfun endkeyfun
この関数は、バッファ内のテキストをレコードに分割してソートする 汎用のテキストソートルーティンである。 本節のコマンドのほとんどは、この関数を用いる。

sort-subrの動作方法を理解するためは、 バッファの参照可能部分全体が ソートレコード(sort record)と呼ばれる 重なり合いのない断片に分割されていると考える。 レコードは連続しているかもしれないし、そうでないかもしれないが、 けっして重なり合わない。 各ソートレコードの一部分(あるいは全体)をソートキーとして区別する。 ソートでは、ソートキーの順に並ぶようにレコードを並び替える。

通常、レコードをソートキーの昇順に並べ替える。 関数sort-subrの第1引数reversenil以外であると、 ソートキーの降順にレコードを並べ替える。

sort-subrのつぎの4つの引数は、 ソートレコードをまたいでポイントを移動するために呼ばれる関数である。 それらは、sort-subrで多数回呼び出される。

  1. nextrecfunは、レコードの末尾にポイントを置いて呼び出される。 この関数は、つぎのレコードの先頭にポイントを移動する。 最初のレコードの先頭は、 sort-subrを呼び出したときのポイント位置であると仮定する。 したがって、sort-subrを呼び出すまえには、普通、 バッファの先頭にポイントを移動しておくこと。

    この関数は、バッファの末尾にポイントを置いておくことで、 ソートレコードがなくなったことを表せる。

  2. endrecfunは、レコード内にポイントを置いて呼び出される。 レコードの末尾にポイントを移動する。

  3. startkeyfunは、レコードの先頭からソートキーの先頭へ ポイントを移動するために呼び出される。 この引数は省略可能であり、省略するとレコード全体をソートキーとする。 指定した場合、その関数は、ソートキーとして用いるnil以外の値を返すか、 バッファのポイント位置からソートキーが始まることを表すnilを返すこと。 後者の場合、ソートキーの末尾を探すためにendkeyfunが呼ばれる。

  4. endkeyfunは、ソートキーの先頭からソートキーの末尾に ポイントを移動するために呼び出される。 この引数は省略可能である。 startkeyfunnilを返しこの引数が省略されている (あるいはnilである)と、ソートキーはレコードの末尾までである。 startkeyfunnil以外の値を返すのであれば、 endkeyfunは必要ない。

sort-subrの例として、 sort-linesの完全な関数定義を示す。

 
;; 説明文字列の始めの2行は、ユーザーが見るときには
;; 実質的には1行であることに注意
(defun sort-lines (reverse beg end)
  "Sort lines in region alphabetically;\
 argument means descending order.
Called from a program, there are three arguments:
REVERSE (non-nil means reverse order),\
 BEG and END (region to sort).
The variable `sort-fold-case' determines\
 whether alphabetic case affects
the sort order.
  (interactive "P\nr")
  (save-excursion
    (save-restriction
      (narrow-to-region beg end)
      (goto-char (point-min))
      (sort-subr reverse 'forward-line 'end-of-line))))

ここで、forward-lineはつぎのレコードの先頭にポイントを移動し、 end-of-lineはレコードの末尾にポイントを移動する。 レコード全体をソートキーとして用いるため、 引数startkeyfunendkeyfunは指定しない。

関数sort-paragraphsもほぼ同様であるが、 つぎのようにsort-subrを呼び出す点が異なる。

 
(sort-subr reverse
           (function
             (lambda ()
               (while (and (not (eobp))
                      (looking-at paragraph-separate))
                 (forward-line 1))))
           'forward-paragraph)

sort-subrから戻ったあとでは、 ソートレコードを指しているマーカは意味のある位置を指していない。

User Option: sort-fold-case
この変数がnil以外であると、 sort-subrや他のバッファソート関数は、 文字列の比較において大文字小文字を区別しない。

コマンド: sort-regexp-fields reverse record-regexp key-regexp start end
このコマンドは、startendのあいだの領域を record-regexpkey-regexpの指定に従って アルファベット順にソートする。 reverseが負の整数であると、逆順にソートする。

アルファベット順のソートとは、 最初の文字同士、2番目の文字同士といった具合に 2つのソートキーを比較することである。 不一致がみつかると、ソートキーが等しくないことを意味し、 最初の不一致箇所の文字が小さいほうのソートキーが小さい。 個々の文字は、Emacsの文字集合における文字コードの数値に従って比較する。

引数record-regexpの値は、バッファをソートレコードに 分割する方法を指定する。 各レコードの末尾において、この正規表現を探索し それに一致したテキストをつぎのレコードとする。 たとえば、正規表現`^.+$'は、 少なくとも1つの文字のあとに改行があるような行に一致し、 そのような行をソートレコードとする。 正規表現の構文と意味については、see section 33.2 正規表現

引数key-regexpの値は、 レコードのどの部分がソートキーであるかを指定する。 key-regexpは、レコード全体かその一部分に一致する。 後者の場合、レコードの残りの部分は、レコードの並び替え順序には影響しないが、 レコードをその新たな位置に移動するときにいっしょに移動される。

引数key-regexprecord-regexpの部分式に一致したテキストを参照してもよいし、 独立した正規表現でもよい。

key-regexpにはつぎの可能性がある。

`\digit'
record-regexpdigit番目の 括弧によるグループ化`\(...\)'に一致したテキストがソートキーである。

`\&'
レコード全体がソートキーである。

正規表現
sort-regexp-fieldsはレコード内でこの正規表現に一致するものを探す。 一致がみつかれば、それがソートキーになる。 レコード内でkey-regexpに対する一致がみつからなければ、 レコードを無視する。 つまり、バッファ内での当該レコードの位置を変更しない。 (別のレコードが周りに移動してくるかもしれない。)

たとえば、領域内のすべての行を各行の`f'で始まる最初の単語で ソートするには、record-regexpに`^.*$'、 key-regexpに`\<f\w*\>'を指定する。 つまり、つぎのような式になる。

 
(sort-regexp-fields nil "^.*$" "\\<f\\w*\\>"
                    (region-beginning)
                    (region-end))

sort-regexp-fieldsを対話的に呼び出すと、 ミニバッファでrecord-regexpkey-regexpを問い合わせる。

コマンド: sort-lines reverse start end
このコマンドは、startendのあいだの領域の行を アルファベット順にソートする。 reversenil以外であると、逆順にソートする。

コマンド: sort-paragraphs reverse start end
このコマンドは、startendのあいだの領域の段落を アルファベット順にソートする。 reversenil以外であると、逆順にソートする。

コマンド: sort-pages reverse start end
このコマンドは、startendのあいだの領域のページを アルファベット順にソートする。 reversenil以外であると、逆順にソートする。

コマンド: sort-fields field start end
このコマンドは、startendのあいだの領域の行を 各行のfield番目のフィールド同士をアルファベット順に比較してソートする。 フィールドは白文字で区切られ、1から数える。 fieldが負であると、 行末から-field番目のフィールドでソートする。 このコマンドは、表をソートするのに有用である。

コマンド: sort-numeric-fields field start end
このコマンドは、startendのあいだの領域の行を 各行のfield番目のフィールド同士を数値として比較してソートする。 領域内の各行の指定したフィールドには数があること。 フィールドは白文字で区切られ、1から数える。 fieldが負であると、 行末から-field番目のフィールドでソートする。 このコマンドは、表をソートするのに有用である。

コマンド: sort-columns reverse &optional beg end
このコマンドは、startendのあいだの領域の行を 特定範囲のコラムをアルファベット順に比較してソートする。 begendのコラム位置は、ソート対象のコラムの範囲を区切る。

reversenil以外であると、逆順にソートする。

このコマンドの普通でない点は、 位置begを含む行全体と位置endを含む行全体も ソート対象の領域に含まれることである。

sort-columnsは、ユーティリティプログラムsortを使うため、 タブ文字を含むテキストを正しく扱えない。 ソートするまえにM-x untabifyを使ってタブを空白に変換すること。


31.16 コラムを数える

コラム関数は、(バッファの先頭から文字を数えた)文字位置を (スクリーンの行頭から文字を数えた)コラム位置に変換します。

これらの関数は、各文字をそれがスクリーン上で占めるコラム数を基に数える。 つまり、ctl-arrowの値に依存してコントロール文字は、 2コラムか4コラム占めると数え、 タブ文字は、タブの開始コラムとtab-widthの値に依存する コラム数を占めると数えることを意味します。 See section 38.13 通常の画面表示慣習

コラム番号の計算では、ウィンドウの幅や水平スクロール量を無視します。 その結果、コラム値は任意の大きさになりえます。 最初の(スクリーン左端の)コラムの番号は0です。

Function: current-column
この関数は、左端を0としてコラム数で数えたポイントの水平位置を返す。 コラム位置は、現在行の先頭からポイント位置までの文字すべての 表示上の表記の幅の総和である。

current-columnの使用例については、 29.2.4 テキスト行単位の移動count-linesを参照。

Function: move-to-column column &optional force
この関数は、ポイントを現在行のcolumnへ移動する。 columnの計算では、現在行の先頭からポイント位置までの 文字すべての表示上の表記の幅を考慮する。

コラムcolumnが行末を越える場合、ポイントを行末へ移動する。 columnが負であると、ポイントを行頭へ移動する。

コラムcolumnがタブなどの複数コラムを占める文字の中ほどにあるために そこへ移動できない場合には、 ポイントを当該文字の末尾へ移動する。 しかし、forcenil以外であり columnがタブの中ほどであると、 コラムcolumnに正確に移動できるようにタブを空白に変換する。 複数コラムを占めるその他の文字では、それらを分割する方法がないため、 forceを指定しても変則的になる。

コラムcolumnに到達できるほど行が長くない場合にも 引数forceには効果がある。 そのような場合、指定コラムに達するように行末に白文字を追加する。

columnが整数でないと、エラーを通知する。

戻り値は、実際の移動先のコラム番号である。


31.17 字下げ

字下げ関数は、行頭の空白を調べたり、そこへ移動したり、 変更するために使います。 行の他の白文字を変更するものもあります。 コラム関数と字下げ関数は左端を0と数えます。

31.17.1 字下げ基本関数  Functions used to count and insert indentation.
31.17.2 メジャーモードの制御による字下げ  Customize indentation for different modes.
31.17.3 領域全体の字下げ  Indent all the lines in a region.
31.17.4 先行行相対の字下げ  Indent the current line based on previous lines.
31.17.5 調整可能な『タブストップ』  Adjustable, typewriter-like tab stops.
31.17.6 字下げに基づく移動コマンド  Move to first non-blank character.


31.17.1 字下げ基本関数

本節では、字下げを数えたり挿入するために使われる基本関数について述べます。 後続の節の関数群は、これらの基本関数を使っています。 関連する関数については、See section 38.9 表示幅

Function: current-indentation
この関数は、現在行の字下げを返す。 これは最初の白文字以外の文字の水平位置である。 行全体が白文字や空である場合には、行末の水平位置を返す。

コマンド: indent-to column &optional minimum
この関数は、ポイント位置からcolumnに達するまでタブや空白で字下げする。 minimumを指定しnil以外であると、 columnを越える場合であっても最低minimum個の空白を挿入する。 さもなければ、ポイントがcolumnを越えている場合には、 この関数はなにもしない。 戻り値は、挿入した字下げが終る箇所のコラムである。

挿入された白文字は周りの文字(普通は、まえの文字)からテキスト属性を継承する。 see section 31.19.6 テキスト属性のスティッキ性

User Option: indent-tabs-mode
この変数がnil以外であると、 字下げ関数は空白に加えてタブも挿入する。 さもなければ、空白のみを挿入する。 この変数に設定すると、カレントバッファでバッファローカルになる。


31.17.2 メジャーモードの制御による字下げ

各メジャーモードの重要な機能は、 キーTABを編集対象の言語に適した字下げにカスタマイズすることです。 本節では、キーTABの機構とそれを制御する方法について述べます。 本節の関数は、予測できない値を返します。

Variable: indent-line-function
この変数の値は、現在行を字下げするために TAB(やさまざまなコマンド)が使う関数である。 コマンドindent-according-to-modeは、 この関数を呼ぶこと以上のことはしない。

lispモードでは値はシンボルlisp-indent-line、 Cモードではc-indent-line、 fortranモードではfortran-indent-lineである。 標準的な字下げがない基本(fundamental)モード、 テキスト(text)モード、他の多くのモードでは、 値はindent-to-left-margin(デフォルト値)である

コマンド: indent-according-to-mode
このコマンドは、現在のメジャーモードに適した方法で現在行を字下げするために indent-line-functionで指定される関数を呼び出す。

コマンド: indent-for-tab-command
このコマンドは、現在行を字下げするために indent-line-functionで指定される関数を呼び出すが、 その関数がindent-to-left-marginであると、 かわりにinsert-tabを呼び出す。 (これはタブ文字を挿入する単純なコマンドである。)

コマンド: newline-and-indent
この関数は、改行を挿入してから、 (改行を挿入したばかりの行に続く)新たな行を メジャーモードに基づいて字下げする。

現在のindent-line-functionを呼び出して字下げを行う。 プログラム言語向けのモードでは、これはTABが行うことと同じであるが、 TABがタブを挿入するテキスト向けのモードの一部では、 newline-and-indentleft-marginで指定されたコラムに字下げする。

コマンド: reindent-then-newline-and-indent
このコマンドは、現在行を字下げし直し、ポイント位置に改行を挿入し、 (改行を挿入したばかりの行に続く)新たな行を字下げする。

このコマンドは、indent-line-functionの現在の値を呼び出すことで、 どちらの行も現在のメジャーモードに基づいて字下げする。 プログラム言語向けのモードでは、これはTABが行うことと同じであるが、 TABがタブを挿入するテキスト向けのモードの一部では、 reindent-then-newline-and-indentは、 left-marginで指定されるコラムに字下げする。


31.17.3 領域全体の字下げ

本節では、領域内のすべての行を字下げするコマンドについて述べます。 これらは予測できない値を返します。

コマンド: indent-region start end to-column
このコマンドは、start(を含めて)と end(を含めない)のあいだで始まる空でない各行を字下げする。 to-columnnilであると、 indent-regionは、現在のモードの字下げ関数、 つまり、indent-line-functionの値を呼び出して、 空でない各行を字下げする。

to-columnnil以外であると、 それは字下げ先のコラム番号を指定する整数であること。 すると、この関数は、白文字を追加するか削除して、 各行を指定どおりに字下げする。

詰め込み接頭辞がある場合、 indent-regionは詰め込み接頭辞で行を始めることで各行を字下げする。

Variable: indent-region-function
この変数の値は、indent-regionの短縮版として利用可能な関数である。 領域の開始位置と終了位置の2つの引数をとる。 領域の行を1つ1つ字下げする場合と同じ結果を生じるが、 より速く動作することを意図してこの関数を設計するべきである。

値がnilであると短縮版はなく、 indent-regionが実際に1行ずつ処理する。

短縮版関数はCモードやlispモードのようなモードで有用である。 そのようなモードでは、indent-line-functionで関数定義の始まりを 走査する必要があり、これを各行に適用すると自乗の時間がかかる。 短縮版では、字下げし終えた関数定義を通過するたびに 走査情報を更新でき、これには線形時間かかるだけである。 個々の行を高速に字下げできるモードでは、短縮版は必要ない。

引数to-columnnil以外を指定したindent-regionには 別の意味があり、この変数を使わない。

コマンド: indent-rigidly start end count
このコマンドは、start(を含めて)と end(を含めない)のあいだで始まる行すべてを コラム数countだけ字下げする。 これは、領域を1つの塊として動かしてその領域の『形を保つ』。 このコマンドは、字下げしていないテキストの領域だけでなく、 整形済みの領域を字下げするためにも有用である。

たとえば、countが3であると、 このコマンドは指定した領域内の各行の行頭に3コラムの字下げを追加する。

メイル(mail)モードでは、C-c C-ymail-yank-original)が 返信対象のメッセージからコピーしたテキストを字下げするために indent-rigidlyを使っている。

Function: indent-code-rigidly start end columns &optional nochange-regexp
この関数はindent-rigidlyと同様であるが、 文字列やコメントで始まる行を変更しない点が異なる。

さらに、(nochange-regexpnil以外のとき) 行の先頭がnochange-regexpに一致する場合にも行を変更しない。


31.17.4 先行行相対の字下げ

本節では、先行する行の内容に基づいて現在行を字下げする2つの コマンドについて述べます。

コマンド: indent-relative &optional unindented-ok
このコマンドは、空白でないまえの行のつぎの字下げ位置のコラムに 達するまで、ポイント位置に白文字を挿入する。 字下げ位置とは、白文字に続く白文字以外の文字である。 つぎの字下げ位置とは、現在行のポイントのコラム位置より大きな 最初の字下げ位置のことである。 たとえば、テキスト行の白文字以外の最初の文字より左側で、 その下の行にポイントがあると、 白文字を挿入してそのコラム位置にポイントを移動する。

空白でないまえの行に、つぎの字下げ位置(つまり、ポイント位置より 大きなコラム)がないと、indent-relativeは、 (unindented-oknil以外であれば)なにもしないか、 tab-to-tab-stopを呼び出す。 したがって、まえのテキスト行が短くてその行末より右側で、 その下の行にポイントがあると、このコマンドは、通常どおり、 白文字を挿入してつぎのタブ位置へポイントを移動する。

indent-relativeの戻り値は予測できない。

つぎの例では、ポイントは2行目の行頭にある。

 
            This line is indented twelve spaces.
-!-The quick brown fox jumped.

(indent-relative nil)を評価すると、つぎのようになる。

 
            This line is indented twelve spaces.
            -!-The quick brown fox jumped.

つぎの例では、ポイントは`jumped'の`m'と`p'のあいだにある。

 
            This line is indented twelve spaces.
The quick brown fox jum-!-ped.

(indent-relative nil)を評価すると、つぎのようになる。

 
            This line is indented twelve spaces.
The quick brown fox jum  -!-ped.

コマンド: indent-relative-maybe
このコマンドは、引数unindented-oktを指定して indent-relativeを呼び出すことで、 まえの行と同様に字下げする。 戻り値は予測できない。

空行でないまえの行に現在のコラム位置を越える字下げ位置がなければ、 このコマンドはなにもしない。


31.17.5 調整可能な『タブストップ』

本節では、ユーザー指定の『タブストップ』の機構と、 それを使ったり設定するための機構について説明します。 『タブストップ』という名前を使うのは、 この機構がタイプライタのタブストップに似た機能だからです。 この機能は、適切な個数の空白とタブ文字を挿入して つぎのタブストップのコラムへ到達しますが、 バッファ内のタブ文字の表示に影響することはありません (see section 38.13 通常の画面表示慣習)。 テキスト(text)モードなどの少数のメジャーモードでのみ、 入力としての文字TABがこのタブストップ機能を使います。

コマンド: tab-to-tab-stop
このコマンドは、tab-stop-listで定義されたつぎのタブストップコラムまで、 ポイントのまえに空白やタブを挿入する。 このリストで現在のコラム番号より大きな要素を探し、 その要素を字下げ位置のコラムとして使う。 そのような要素がなければ、このコマンドはないもしない。

User Option: tab-stop-list
この変数は、tab-to-tab-stopsが使うタブストップコラムのリストである。 それらの要素は、昇順の整数であること。 タブストップコラムの間隔は、等間隔である必要はない。

タブストップを対話的に編集するにはM-x edit-tab-stopsを使う。


31.17.6 字下げに基づく移動コマンド

これらのコマンドは、主に対話的に使うもので、 テキストの字下げに基づいて動作します。

コマンド: back-to-indentation
このコマンドは、現在行(ポイントが位置する行)の 白文字でない最初の文字へポイントを移動する。 nilを返す。

コマンド: backward-to-indentation arg
このコマンドは、arg行だけポイントを後方へ移動してから、 当該行の白文字でない最初の文字へポイントを移動する。 nilを返す。

コマンド: forward-to-indentation arg
このコマンドは、arg行だけポイントを前方へ移動してから、 当該行の白文字でない最初の文字へポイントを移動する。 nilを返す。


31.18 大文字小文字の変更

ここに述べる大文字小文字の変更コマンドは、 カレントバッファのテキストに作用します。 文字列や文字の大文字小文字を変換する関数については、 See section 4.8 Lispの大文字小文字変換。 どの文字が大文字でどの文字が小文字であり、それらをどのように変換するかを カスタマイズする方法については、See section 4.9 大文字小文字テーブル

コマンド: capitalize-region start end
この関数は、startendで定義される領域内の すべての単語をキャピタライズ(大文字で始まるように)する。 つまり、各単語の最初の文字を大文字に、残りの文字を小文字に変換する。 この関数はnilを返す。

領域の端が単語の途中にあると、 その単語の領域内の部分を1つの単語とみなす。

capitalize-regionを対話的に呼び出すと、 startendはポイントとマークであり、小さいほうがさきにくる。

 
---------- Buffer: foo ----------
This is the contents of the 5th foo.
---------- Buffer: foo ----------

(capitalize-region 1 44)
=> nil

---------- Buffer: foo ----------
This Is The Contents Of The 5th Foo.
---------- Buffer: foo ----------

コマンド: downcase-region start end
この関数は、startendで定義される領域内の すべての文字を小文字に変換する。 この関数はnilを返す。

downcase-regionを対話的に呼び出すと、 startendはポイントとマークであり、小さいほうが先にくる。

コマンド: upcase-region start end
この関数は、startendで定義される領域内の すべての文字を大文字に変換する。 この関数はnilを返す。

upcase-regionを対話的に呼び出すと、 startendはポイントとマークであり、小さいほうが先にくる。

コマンド: capitalize-word count
この関数は、ポイントのうしろのcount個の単語を キャピタライズ(大文字で始まるように)し、ポイントをそれらの末尾に移動する。 つまり、各単語の最初の文字を大文字に、残りの文字を小文字に変換する。 countが負であると、まえの-count個の単語を 大文字で始まるようにするが、ポイントは移動しない。 値はnilである。

ポイントが単語の途中にあると、単語を前方へ移動するときには ポイントよりまえにある単語の部分を無視する。 単語の残りの部分を1つの単語として扱う。

capitalize-wordを対話的に呼び出すと、 countは数値前置引数である。

コマンド: downcase-word count
この関数は、ポイントのうしろのcount個の単語を すべて小文字に替え、ポイントをそれらの末尾に移動する。 countが負であると、まえの-count個の単語を 変換するが、ポイントは移動しない。 値はnilである。

downcase-wordを対話的に呼び出すと、 countは数値前置引数である。

コマンド: upcase-word count
この関数は、ポイントのうしろのcount個の単語を すべて大文字に替え、ポイントをそれらの末尾に移動する。 countが負であると、まえの-count個の単語を 変換するが、ポイントは移動しない。 値はnilである。

upcase-wordを対話的に呼び出すと、 countは数値前置引数である。


31.19 テキスト属性

シンボルの属性リスト(see section 7.4 属性リスト)のように、 バッファや文字列の各文字にはテキスト属性リスト (text property list)を持てます。 この属性は、(本節の原文のタイトルの)文字`T'や `foo'の最初の`o'のような特定の箇所の特定の文字に属します。 同じ文字が異なる箇所に現れるとき、 一般にはそれぞれに異なる属性を持てます。

各属性には、名前と値があります。 どちらも任意のLispオブジェクトでかまいませんが、 名前は普通はシンボルです。 属性リストを参照する普通の方法では、 名前を指定してそれに対応する値を問い合わせます。

文字に属性categoryがあるとき、 それを文字のカテゴリ(category)といいます。 それはシンボルであるべきです。 そのシンボルの属性が、文字の属性のデフォルトとして働きます。

文字列とバッファのあいだでテキストをコピーすると、 文字とともにその属性も保たれます。 substringinsertbuffer-substringなどの さまざまな関数がそうします。

31.19.1 テキスト属性を調べる  Looking at the properties of one character.
31.19.2 テキスト属性の変更  Setting the properties of a range of text.
31.19.3 テキスト属性を探す関数  Searching for where a property changes value.
31.19.4 特別な意味を持つ属性  Particular properties with special meanings.
31.19.5 整形済みテキストの属性  Properties for representing formatting of text.
31.19.6 テキスト属性のスティッキ性  How inserted text gets properties from neighboring text.
31.19.7 テキスト属性をファイルへ保存する  Saving text properties in files, and reading them back.
31.19.8 テキスト属性の遅延計算  Computing text properties in a lazy fashion only when text is examined.
31.19.9 クリック可能なテキストを定義する  Using text properties to make regions of text do something when you click on them.
31.19.10 テキスト属性が範囲でない理由  Why text properties do not use Lisp-visible text intervals.


31.19.1 テキスト属性を調べる

テキスト属性を調べるもっとも簡単な方法は、 特定の文字の特定の属性の値を問い合わせることです。 それには、get-text-propertyを使います。 文字の属性リスト全体を取得するにはtext-properties-atを使います。 複数の文字の属性を一度に調べるための関数については、 See section 31.19.3 テキスト属性を探す関数

これらの関数は、文字列とバッファの両方を扱えます。 文字列内の位置は0から始まり、 バッファ内の位置は1から始まることに注意してください。

Function: get-text-property pos prop &optional object
この関数は、object(バッファか文字列)内の位置posの うしろの1文字の属性propの値を返す。 引数objectは省略でき、 デフォルトはカレントバッファである。

その文字に属性propがなくてもシンボルであるカテゴリがあれば、 get-text-propertyは当該シンボルの属性propを返す。

Function: get-char-property pos prop &optional object
この関数はget-text-propertyに似ているが、 まずオーバレイを調べてからテキスト属性を調べる。 see section 38.8 オーバレイ

引数objectは、文字列、バッファ、ウィンドウのいずれかである。 ウィンドウであると、そのウィンドウに表示しているバッファの テキスト属性とオーバレイを対象にするが、 対象となるオーバレイはそのウィンドウに対して活性なものだけである。 objectがバッファであると、テキスト属性に加えて そのバッファのすべてのオーバレイを対象にする。 objectが文字列であると、 文字列にはオーバレイはないので、テキスト属性のみを対象にする。

Function: text-properties-at position &optional object
この関数は、文字列やバッファであるobject内の 位置positionにある1文字の属性リスト全体を返す。 objectnilであると、デフォルトはカレントバッファである。

Variable: default-text-properties
この変数は、テキスト属性のデフォルト値を与える属性リストを保持する。 直接的にもカテゴリシンボルを介して間接的にも 文字に属性の値が指定されていないと、 このリストに収めた値をかわりに使う。 つぎに例を示す。

 
(setq default-text-properties '(foo 69))
;; 位置1の文字に属性がないことを保証する
(set-text-properties 1 2 nil)
;; 問い合わせたときに見えるのはデフォルト値である
(get-text-property 1 'foo)
     => 69


31.19.2 テキスト属性の変更

属性を変更する基本関数は、バッファや文字列の指定した範囲に作用します。 関数set-text-properties(本節の最後)は、 その範囲のテキストの属性リスト全体を設定します。 これは、名前で指定した特定の属性のみを追加/変更/削除するのに しばしば有用です。

テキスト属性はバッファ(や文字列)の一部分であるとみなされ、 スクリーン上でのバッファの見た目に影響するので、 バッファのテキスト属性を変更すると、 バッファには変更済みの印を付けます。 バッファのテキスト属性の変更もアンドゥ(see section 31.9 アンドゥ)できます。

Function: put-text-property start end prop value &optional object
この関数は、文字列やバッファであるobject内の startendのあいだのテキストの属性propの値を valueとする。 objectnilであると、デフォルトはカレントバッファである。

Function: add-text-properties start end props &optional object
この関数は、文字列やバッファであるobject内の startendのあいだのテキストの テキスト属性に追加/上書きする。 objectnilであると、デフォルトはカレントバッファである。

引数propsで追加する属性を指定する。 これは属性リスト(see section 7.4 属性リスト)の形であること。 つまり、属性名とその値を交互に並べたリストであること。

この関数が属性の値をどれか実際に変更したならば、戻り値はtである。 さもなければ(propsnilだったり、 テキスト内の値と同じ値であると)nilである。

たとえば、テキストのある範囲の属性commentfaceを 設定するにはつぎのようにする。

 
(add-text-properties start end
                     '(comment t face highlight))

Function: remove-text-properties start end props &optional object
この関数は、文字列やバッファであるobject内の startendのあいだのテキストから 指定したテキスト属性を削除する。 objectnilであると、デフォルトはカレントバッファである。

引数propsで削除する属性を指定する。 これは属性リスト(see section 7.4 属性リスト)の形であること。 つまり、属性名とその値を交互に並べたリストであること。 ただし、意味があるのは名前のみであり、その値は無視する。 たとえば、属性faceを削除するにはつぎのようにする。

 
(remove-text-properties start end '(face nil))

この関数が属性の値をどれか実際に変更したならば、戻り値はtである。 さもなければ(propsnilだったり、 指定したテキスト内の文字にそれらのいずれの属性もなければ) nilである。

特定のテキストからすべてのテキスト属性を削除するには、 新たな属性リストとしてnilを指定して set-text-propertiesを使う。

Function: set-text-properties start end props &optional object
この関数は、文字列やバッファであるobject内の startendのあいだのテキストのテキスト属性を完全に置き換える。 objectnilであると、 デフォルトはカレントバッファである。

引数propsは新たな属性リストである。 これは、属性名とその値を交互に並べたリストであること。

set-text-propertiesから戻ると、 指定した範囲のすべての文字は同一の属性を持つことになる。

propsnilであると、 テキストの指定した範囲からすべての属性を削除する効果がある。 たとえば、つぎのようにする。

 
(set-text-properties start end nil)

バッファからテキストをコピーするがその属性はコピーしない 関数buffer-substring-no-properties(see section 31.2 バッファの内容を調べる)も 参照してください。


31.19.3 テキスト属性を探す関数

テキスト属性の典型的な用途では、 ほとんどの場合多くの連続した文字の1つの属性には同じ値があります。 1つずつ文字を調べるようにプログラムするよりは、 同じ属性値を持つテキストの塊を処理するほうがとても速いです。

このために使える関数をここで説明します。 これらは属性値の比較にeqを使います。 objectのデフォルトは、すべての場合でカレントバッファです。

高い効率のためには、これらの関数に引数limitを使うことが重要であり、 1つの属性を探す関数には特にあてはまります。 さもないと、読者が望む属性が変更されないような場合、 それらの関数はバッファの末尾まで走査して長い時間を費すことになります。

これらの関数はポイントを移動しませんが、そのかわりに 位置(あるいはnil)を返します。 位置はつねに2つの文字のあいだにあることに注意してください。 これらの関数が返す位置は、異なる属性を持つ2つの文字のあいだです。

Function: next-property-change pos &optional object limit
この関数は、文字列やバッファであるobject内の位置posから テキスト属性のいずれかが異なるまでテキストを走査し、その変化する位置を返す。 いいかえれば、posの直後の文字のテキスト属性とは異なる 属性を持つposのあとにある最初の文字の位置を返す。

limitnil以外であると、limitの位置で走査を終える。 その箇所まで異なる属性がないと、 next-property-changelimitを返す。

limitnilでありobjectの末尾まで属性に変化がないと、 値はnilである。 値がnil以外であると、それはposより大きいか等しい位置である。 値がposに等しいのは、limitposに等しい場合のみである。

バッファからすべての属性が同じであるテキストの塊を 走査する方法の例をつぎに示す。

 
(while (not (eobp))
  (let ((plist (text-properties-at (point)))
        (next-change
         (or (next-property-change (point) (current-buffer))
             (point-max))))
    ポイントからnext-changeまでのテキストを処理する...
    (goto-char next-change)))

Function: next-single-property-change pos prop &optional object limit
この関数は、文字列やバッファであるobject内の位置posから 属性propが異なるまでテキストを走査し、その変化する位置を返す。 いいかえれば、posの直後の文字の属性propとは異なる 属性propをもつposのあとにある最初の文字の位置を返す。

limitnil以外であると、limitの位置で走査を終える。 その箇所まで異なる属性がないと、 next-single-property-changelimitを返す。

limitnilでありobjectの末尾まで属性に変化がないと、 値はnilである。 値がnil以外であると、それはposより大きいか等しい位置である。 値がposに等しいのは、limitposに等しい場合のみである。

Function: previous-property-change pos &optional object limit
これはnext-property-changeと同様であるが、 前方へではなくposから後方へ走査する。 値がnil以外であると、それはposより小さいか等しい位置である。 値がposに等しいのは、limitposに等しい場合のみである。

Function: previous-single-property-change pos prop &optional object limit
これはnext-single-property-changeと同様であるが、 前方へではなくposから後方へ走査する。 値がnil以外であると、それはposより小さいか等しい位置である。 値がposに等しいのは、limitposに等しい場合のみである。

Function: next-char-property-change position &optional limit
これはnext-property-changeと同様であるが、 テキスト属性に加えてオーバレイも対象にする。 この関数はカレントバッファにのみ作用するため、 objectを表す引数はない。 どちらかの属性が異なるつぎの位置を返す。

Function: previous-char-property-change position &optional limit
これはnext-char-property-changeと同様であるが、 前方へではなくposから後方へ走査する。

Function: text-property-any start end prop value &optional object
startendのあいだに属性propの値がvalueである 文字が1つでもあれば、この関数はnil以外を返す。 より正確には、そのような最初の文字の位置を返す。 さもなければnilを返す。

省略可能な5番目の引数objectは、走査すべき文字列やバッファを指定する。 位置はobjectに相対である。 objectのデフォルトはカレントバッファである。

Function: text-property-not-all start end prop value &optional object
startendのあいだに属性propの値がvalueでない 文字が1つでもあれば、この関数はnil以外を返す。 より正確には、そのような最初の文字の位置を返す。 さもなければnilを返す。

省略可能な5番目の引数objectは、走査すべき文字列やバッファを指定する。 位置はobjectに相対である。 objectのデフォルトはカレントバッファである。


31.19.4 特別な意味を持つ属性

特別な組み込みの意味を持つテキスト属性名の一覧を以下に示します。 以降の節では、詰め込みや属性の継承を制御する特別な属性名も示します。 それ以外の名前には標準的な意味はないので、 読者はそれらを好きなように使ってかまいません。

category
文字に属性categoryがあるとき、 これを文字のカテゴリ(category)と呼ぶ。 これはシンボルであること。 そのシンボルの属性が、文字の属性のデフォルトとして働く。

face
テキストのフォントと表示色を制御するために属性faceを使う。 その値はフェイス名かフェイス名のリストである。 詳しくは、see section 38.10 フェイス

属性値がリストであると、その要素は、 (foreground-color . color-name)(background-color . color-name)の形でもよい。 これらの要素は、前景色だけや背景色だけを指定する。 したがって、使用する各色を表すフェイスを作成する必要はない。

テキストの内容に基づいて属性faceを自動的に更新する方法に関しては、 see section 22.5 フォントロック(font-lock)モード

mouse-face
マウスが文字の上やその近くにあると、属性faceのかわりに 属性mouse-faceが使われる。 この目的において『近く』とは、 文字とマウスの位置のあいだの 属性mouse-faceの値が同じであるすべてのテキストである。

local-map
属性local-mapを用いることで、 バッファ内のテキストの一部分に対して別のキーマップを指定できる。 ポイントのうしろの文字のこの属性の値がnil以外であると、 バッファのローカルマップのかわりにその値をキー探索に使う。 属性値がシンボルであると、シンボルの関数定義をキーマップとして使う。 see section 21.6 活性なキーマップ

syntax-table
属性syntax-tableは、構文テーブルがこの文字に指定するものに優先する。 see section 34.4 構文属性

read-only
文字に属性read-onlyがあると、その文字を変更できない。 変更するどのようなコマンドもエラーになる。

挿入されるテキストがスティッキ性のために属性read-onlyを 継承する場合には、読み出し専用文字のつぎにテキストを挿入するとエラーになる。 したがって、スティッキ性を制御することで、 読み出し専用テキストのつぎへのテキスト挿入を許すかどうかを制御できる。 see section 31.19.6 テキスト属性のスティッキ性

属性を変更するとバッファを変更したとみなすため、 特別なトリックを知らない限り、属性をread-onlyを削除できない。 つまり、inhibit-read-onlynil以外の値を束縛して、 属性を削除する。 see section 26.7 読み出し専用バッファ

invisible
属性invisiblenil以外であると、 その文字はスクリーンに表示されない。 詳しくは、see section 38.4 不可視なテキスト

intangible
連続する文字に属性intangiblenilでない同じ値があると、 それらのあいだにポイントを置けなくなる。 前方に向けてこれらの文字の中にポイントを移動しようとすると、 ポイントは実際にはそれらの末尾へ移動する。 後方に向けてこれらの文字の中にポイントを移動しようとすると、 ポイントは実際にはそれらの先頭へ移動する。

変数inhibit-point-motion-hooksnil以外であると、 属性intangibleは無視される。

modification-hooks
文字に属性modification-hooksがある場合、それは関数のリストであること。 その文字の変更にはそれらの関数すべてが呼び出される。 各関数は2つの引数、つまり、バッファの変更対象部分の先頭と末尾を受け取る。 1つの操作で変更される一連の文字に同じ変更フック関数が現れる場合、 関数が実際に何回呼ばれるか予測できないことに注意してほしい。

insert-in-front-hooks
insert-behind-hooks
バッファにテキストを挿入する操作でも、 挿入箇所のうしろの文字の属性insert-in-front-hooksと まえの文字の属性insert-behind-hooksに指定されている 関数群を呼び出す。 これらの関数は2つの引数、つまり、挿入されたテキストの先頭と末尾を受け取る。 これらの関数が呼ばれるのは、実際の挿入操作を終えてからである。

バッファ内のテキストを変更するときに呼び出される他のフックについては、 31.23 変更フックも参照。

point-entered
point-left
特別な属性point-enteredpoint-leftは、 ポイント移動を報告するフック関数を保持する。 ポイントが動くたびに、Emacsはこれらの2つの属性値、つまり、

を比較する。 これら2つの値が異なれば、 ポイントの古い値と新しい値の2つの引数で(nilでなければ) それぞれを呼び出す。

同じことを移動前後のポイントのまえの文字についても行う。 その結果、(同じかもしれない)point-leftの関数を2回、かつ/あるいは、 (同じかもしれない)point-enteredの関数を2回実行する。 いずれにしても、point-leftの関数が最初に呼ばれ、 そのあとでpoint-enteredの関数が呼ばれる。

これらの関数では、char-afterを使って ポイントを移動せずにさまざまな箇所の文字を調べられる。 ポイントの値が実際に変わったときにのみ、これらのフック関数が実行される。

Variable: inhibit-point-motion-hooks
この変数がnil以外であると、 point-leftpoint-enteredのフック関数は実行されなくなり、 属性intangibleの効果もなくなる。 この変数はグローバルに設定せずに、letで束縛すること。


31.19.5 整形済みテキストの属性

これらのテキスト属性は、詰め込みコマンドのふるまいに影響します。 これらは整形済みのテキストを表現するために使われます。 31.11 詰め込みとSee section 31.12 詰め込みのための余白

hard
改行文字にこの属性があると、『ハード』改行である。 詰め込みコマンドは『ハード』改行を変更せず、 それらをまたがって単語を移動しない。 しかし、この属性はuse-hard-newlinesnil以外の場合にのみ効果を持つ。

right-margin
テキストのこの部分を詰め込むための余分な右端余白を指定する。

left-margin
テキストのこの部分を詰め込むための余分な左端余白を指定する。

justification
テキストのこの部分を詰め込むための幅揃えスタイルを指定する。


31.19.6 テキスト属性のスティッキ性

自己挿入文字は、通常、先行する文字と同じ属性を持ちます。 これを属性の継承(inheritance)と呼びます。

Lispプログラムでは、挿入基本関数を選べば、 継承して挿入したり継承せずに挿入できます。 insertなどの普通のテキスト挿入関数は、 いかなる属性も継承しません。 これらは、挿入する文字列の属性をそのまま持ったテキストを挿入し、 それ以外の属性はありません。 キルリングなどのある文脈から別の文脈へテキストをコピーするプログラムには、 これは正しい動作です。 継承して挿入するには、本節で述べる特別な基本関数を使います。 自己挿入文字はこれらの基本関数を使っているので、属性を継承します。

継承して挿入するとき、どの属性を継承するかは、 2つの特別な属性front-stickyrear-nonstickyに依存します。

文字のうしろに挿入すると、その文字の後続スティッキ(rear-sticky) である属性を継承します。 文字のまえに挿入すると、その文字の先行スティッキ(front-sticky) である属性を継承します。 デフォルトでは、テキスト属性は先行スティッキではなく後続スティッキです。 したがって、デフォルトでは、まえの文字のすべての属性を継承して、 うしろの文字からはなにも継承しません。 特定の属性のスティッキ性を指定することで、異なるふるまいを指定できます。

文字の属性front-stickytであると、 その文字のすべての属性は先行スティッキです。 属性front-stickyがリストであると、 リストに現れる名前のその文字の属性は先行スティッキです。 たとえば、文字の属性front-stickyの値が(face read-only)であると、 この文字のまえに挿入するとこの文字の属性faceread-onlyを 継承しますが、それ以外には継承しません。

rear-nonstickyは反対の働きをします。 すべての属性はデフォルトでは後続スティッキですから、 属性rear-nonstickyはどの属性が 後続スティッキでないかを指定します。 文字の属性rear-nonstickytであると、 その文字には後続スティッキである属性はありません。 属性rear-nonstickyがリストであると、 リストに名前が現れない限り、 属性は後続スティッキです。

継承するようにテキストを挿入すると、 まえの文字からは後続スティッキであるすべての属性を継承し、 うしろの文字からは先行スティッキであるすべての属性を継承します。 両側の文字に異なるスティッキ性の同じ属性がある場合には、 まえの文字の属性が優先します。

属性を継承してテキストを挿入する関数はつぎのとおりです。

Function: insert-and-inherit &rest strings
関数insertと同様に文字列stringsを挿入するが、 前後のテキストから任意のスティッキ性の属性を継承する。

Function: insert-before-markers-and-inherit &rest strings
関数insert-before-markersと同様に文字列stringsを挿入するが、 前後のテキストから任意のスティッキ性の属性を継承する。

継承しない普通の挿入関数については、See section 31.4 テキストの挿入


31.19.7 テキスト属性をファイルへ保存する

つぎの2つのフックを使って、 テキスト属性を(テキストそのものとともに)ファイルに保存しておき、 ファイルを訪問したり挿入するときに同じテキスト属性を復元できます。

Variable: write-region-annotate-functions
この変数の値は、ファイルへ書き込むテキストに対する注記の形で テキスト属性を符号化するためにwrite-regionが呼び出す関数の リストである。 see section 24.4 ファイルへの書き出し

リスト内の各関数は2つの引数、つまり、 書き込む領域の先頭と末尾で呼び出される。 これらの関数はバッファの内容を変更しないこと。 そのかわりに、バッファのテキストに加えてファイルに書き込むべき 注記を表すリストを返すべきである。

各関数は、(position . string)の形の要素から成る リストを返すべきである。 ここで、positionは書き込まれるテキスト内の相対位置を指定する整数、 stringはそこへ追加する注記である。

これらの関数が返す各リストは、positionの昇順になっている必要がある。 複数の関数があると、write-regionは リストを破壊的に併合して1つのソートしたリストにする。

write-regionがバッファからファイルにテキストを実際に書くときに、 指定された注記を対応する位置に混在させる。 バッファを変更せずにこれらすべてを行う。

Variable: after-insert-file-functions
この変数は、insert-file-contentsがファイルの内容を挿入してから 呼び出す関数のリストを保持する。 これらの関数は挿入されたテキストで注記を走査し、 それらが表すテキスト属性にそれらを変換する。

各関数は1つの引数、つまり、挿入されたテキストの長さで呼ばれ、 ポイントは挿入されたテキストの先頭を表す。 関数は当該テキストで注記を走査して注記を削除し、 注記が指定するテキスト属性を作成する。 関数は、変更を反映した挿入されたテキストの更新された長さを返すこと。 関数が返した値がつぎの関数の引数になる。

これらの関数は、挿入されたテキストの先頭にポイントをつねに戻すこと。

after-insert-file-functionsの意図された用途は、 テキスト表現の注記を実際のテキスト属性に変換することである。 しかし、別の使い方も可能である。

これらのフックを使ってファイルにテキスト属性を保存したり復元する Lispプログラムを書いて、さまざまなデータ書式を試して よいものをみつけるようにお願いします。 最終的には、Emacsに取り込める良質で汎用の拡張を ユーザーが作り出すことを願っています。

テキスト属性の名前や値として任意のLispオブジェクトを 処理しないように忠告しておきます。 そのような汎用のプログラムは書くのが難しく動作が遅くなりがちです。 そのかわりに、適当に柔軟性があり符号化が難しくないデータ型の集合を選びます。

関連する機能については、See section 24.12 ファイル書式変換


31.19.8 テキスト属性の遅延計算

バッファ内のすべてのテキストのテキスト属性を計算するかわりに、 必要になった時点でテキストの一部分のテキスト属性を計算するようにできます。

バッファからテキスト属性とともにテキストを取り出す基本関数は、 buffer-substringです。 属性を調べるまえに、この関数はアブノーマルフック buffer-access-fontify-functionsを実行します。

Variable: buffer-access-fontify-functions
この変数は、テキスト属性を計算する関数のリストを保持する。 buffer-substringがバッファの一部分からテキストとテキスト属性を コピーするまえに、この関数はこのリスト内の関数すべてを呼び出す。 各関数は、バッファの参照される範囲を指定する2つの引数を受け取る。 (バッファはつねにカレントバッファである。)

関数buffer-substring-no-propertiesは テキスト属性を無視するので、これらの関数を呼び出しません。

バッファの同じ部分に対してフック関数が複数回呼び出されるのを防ぐには、 変数buffer-access-fontified-propertyを使います。

Variable: buffer-access-fontified-property
この変数の値がnil以外であると、 それはテキスト属性の名前として使われるシンボルである。 そのテキスト属性に対するnil以外の値は、 『この文字の他のテキスト属性はすでに計算済みである』ことを意味する。

buffer-substringに指定された範囲のすべての文字において、 この属性に対してnil以外の値があると、 buffer-substringbuffer-access-fontify-functionsの関数を呼び出さない。 それらの文字にはすでに正しいテキスト属性があるとみなし、 それらにすでにある属性をコピーする。

この機能を使う普通の方法は、 buffer-access-fontify-functionsの関数が 他の属性ととともにこの属性をそれらが操作した文字に追加する。 そうすれば、同じテキストに対して何回も呼び出されるのを防ぐことができる。


31.19.9 クリック可能なテキストを定義する

バッファ内にクリック可能なテキスト(clickable text)を設定するには 2つの方法があります。 これは典型的には2つの部分から成ります。 つまり、マウスが重なるとテキストを強調表示し、 テキストのその部分をクリックすると マウスボタンがなんらかの処理を行うようにします。

強調表示はテキスト属性mouse-faceで行います。 diredでの方法を例として示します。

 
(condition-case nil
    (if (dired-move-to-filename)
        (put-text-property (point)
                           (save-excursion
                             (dired-move-to-end-of-filename)
                             (point))
                           'mouse-face 'highlight))
  (error nil))

put-text-propertyの最初の2つの引数は、 テキストの先頭と末尾を指定します。

このテキストをクリックしたときにマウスになにかをさせるようにする 普通の方法は、メジャーモードのキーマップでmouse-2を定義することです。 クリック可能なテキストをクリックしたかどうかの検査は、 コマンド定義で行われます。 diredではつぎのようにしています。

 
(defun dired-mouse-find-file-other-window (event)
  "In dired, visit the file or directory name you click on."
  (interactive "e")
  (let (file)
    (save-excursion
      (set-buffer (window-buffer (posn-window (event-end event))))
      (save-excursion
        (goto-char (posn-point (event-end event)))
        (setq file (dired-get-filename))))
    (select-window (posn-window (event-end event)))
    (find-file-other-window (file-name-sans-versions file t))))

外側のsave-excursionは、カレントバッファが変わることを防ぎます。 内側のは、クリックしたバッファのポイントを恒久的に変更することを防ぎます。 この例では、diredは関数dired-get-filenameを用いて、 イベントの位置に基づいて訪問すべきファイルを決定します。

メジャーモードのマウスコマンドを定義するかわりに、 テキスト属性local-mapを使って、 クリック可能なテキストそのものにキーバインディングを定義することもできます。

 
(let ((map (make-sparse-keymap)))
  (define-key-binding map [mouse-2] 'operate-this-button)
  (put-text-property (point)
                     (save-excursion
                       (dired-move-to-end-of-filename)
                       (point))
                     'local-map map))

この方法では、テキストのさまざまなクリック可能な部分に 異なるコマンドを定義できます。 さらに、バッファの残りの部分に対しては、 メジャーモードの定義(やグローバルな定義)がそのまま有効です。


31.19.10 テキスト属性が範囲でない理由

バッファ内のテキストに属性を付加できるエディタのなかには、 ユーザーにテキスト内の『範囲』を指定させ、 その範囲に属性を付加するものがあります。 このようなエディタでは、ユーザーやプログラマが 個々の範囲の先頭と末尾を決定できます。 テキスト変更に伴うある種の矛盾するようなふるまいを避けるために、 熟考の結果Emacs Lispでは別の種類のインターフェイスを提供することにしました。

複数の範囲に細分することが意味を持つならば、 ある属性の1つの範囲があるだけのバッファと、 その同じテキストをその同じ属性の2つの範囲にしてあるバッファとを 区別できるはずです。

1つの範囲だけを持つバッファにおいて、そのテキストの一部をキルしたとします。 バッファに残っているテキストは1つの範囲であり、 キルリング(とアンドゥリスト)内のコピーは1つの別の範囲になります。 そしてキルされたテキストをヤンクして戻すと、 同じ属性を持つ2つの範囲ができます。 つまり、編集すると、1つの範囲と2つの範囲の区別を保存できなくなります。

テキストを挿入すると2つの範囲を融合することで この問題を『修正』したとします。 バッファにもともと1つの範囲しかなければ、うまくいきます。 しかし、同じ属性の範囲が連続して2つある場合に、 一方の範囲をキルしてからヤンクして戻したとします。 別の場面では救いになる同じ属性の範囲を融合する機能が、 ここではトラブルを引き起こします。 つまり、ヤンクすると1つの範囲になってしまいます。 ここでも、編集すると、1つの範囲と2つの範囲の区別を保存できなくなります。

2つの範囲の境界にテキストを挿入する場合でも、 満足できる解決方法がない問題を提起します。

しかし、『この文字の属性はなにか』といった形の問いに対して 一貫したふるまいをするような編集にするのは簡単です。 そのために、これらが唯一の意味ある問いかけであると判断したのです。 範囲の先頭と末尾を問うようなものは実装してありません。

実用上は、明示的な範囲の境界のかわりに、 テキスト属性を探索する関数を普通は使えます。 それらの関数は、可能な場合にはつねに範囲は融合されると仮定して 範囲の境界を探すと考えることができます。 See section 31.19.3 テキスト属性を探す関数

Emacsには表示機能として明示的な範囲もあります。 38.8 オーバレイを参照してください。


31.20 文字コードの置換

つぎの関数は、指定した領域内の文字をそれらの文字コードに基づいて置き換えます。

Function: subst-char-in-region start end old-char new-char &optional noundo
この関数は、カレントバッファのstartendで定義される領域の すべての文字old-charを文字new-charに置き換える。

noundonil以外であると、 subst-char-in-regionはアンドゥ用の変更を記録せず、 バッファに変更済みの印も付けない。 この機能は、選択表示(see section 38.5 選択表示)の制御に使われている。

subst-char-in-regionはポイントを移動せず、 nilを返す。

 
---------- Buffer: foo ----------
This is the contents of the buffer before.
---------- Buffer: foo ----------

(subst-char-in-region 1 20 ?i ?X)
     => nil

---------- Buffer: foo ----------
ThXs Xs the contents of the buffer before.
---------- Buffer: foo ----------

Function: translate-region start end table
この関数は、バッファのstartendのあいだの文字に変換表を適用する。

変換表tableは文字列であり、 (aref table ochar)は、 ocharに対応する変換した文字を与える。 tableの長さが256未満であると、 tableの長さより大きなコードの文字は変換によっては変更されない。

translate-regionの戻り値は、 変換によって実際に変更した文字の個数を返す。 これには、変換表で自分自身に変換された文字は数えない。


31.21 レジスタ

レジスタは、Emacsの編集においてさまざまな種類の値を保持できる変数の一種です。 各レジスタには1文字の名前が付いています。 すべてのASCII文字とそれらのメタ変種(ただしC-gを除く)を レジスタの名前に使えます。 したがって、255個のレジスタを使えます。 Emacs Lispでは、レジスタ名でレジスタを区別します。

Variable: register-alist
この変数は、(name . contents)の形の要素の連想リストである。 通常、使用中のEmacsの各レジスタに対して1つの要素がある。

オブジェクトnameは、レジスタを識別する文字(整数)である。

レジスタの内容(contents)に可能な型はいくつかあります。

数そのものを表す。 insert-registerがレジスタ内で数をみつけると10進数に変換する。

マーカ
マーカはジャンプ先のバッファ内位置を表す。

文字列
文字列はレジスタに保存されたテキストである。

矩形領域
矩形領域は文字列のリストで表現される。

(window-configuration position)
これは、1つのフレームに復元するウィンドウ構成と カレントバッファでのポイントの移動先を表す。

(frame-configuration position)
これは、復元するフレーム構成とカレントバッファでのポイントの移動先を表す。

(file filename)
訪問すべきファイルを表す。 この値にジャンプするとファイルfilenameを訪問する。

(file-query filename position)
これは、訪問すべきファイルとその中での位置を表す。 この値にジャンプするとファイルfilenameを訪問し バッファ内位置positionへ移動する。 この種の位置を復元すると、まずユーザーに確認を取る。

本節の関数は、明記してない場合には予測できない値を返します。

Function: get-register reg
この関数は、レジスタregの内容、 あるいは、内容がなければnilを返す。

Function: set-register reg value
この関数は、レジスタregの内容をvalueとする。 レジスタには任意の値を設定できるが、他のレジスタ関数は 特定のデータ型を期待する。 戻り値はvalueである。

コマンド: view-register reg
このコマンドは、レジスタregになにが入っているかを表示する。

コマンド: insert-register reg &optional beforep
このコマンドはレジスタregの内容をカレントバッファに挿入する。

通常、このコマンドは挿入したテキストのまえにポイントを置き、 そのあとにマークを置く。 しかし、省略可能な2番目の引数beforepnil以外であると、 まえにマークを置きあとにポイントを置く。 この関数を対話的に呼び出すときに前置引数を指定すれば、 2番目の引数beforepnil以外を渡せる。

レジスタに矩形領域が含まれる場合、 ポイント位置に矩形領域の左上隅がくるように挿入される。 つまり、テキストは現在行とそのしたの連続する行に挿入される。

保存したテキスト(文字列)や矩形領域(リスト)以外がレジスタに入っていると、 現状では有用なことは起こらない。 将来これは変更されるであろう。


31.22 テキストの転置

つぎのサブルーティンは転置コマンドで使われます。

Function: transpose-regions start1 end1 start2 end2 &optional leave-markers
この関数は、バッファの重なり合わない2つの部分を入れ換える。 引数start1end1で一方の部分の境界を指定し、 引数start2end2で他方の部分の境界を指定する。

通常、transpose-regionsは転置したテキスト内のマーカを再配置する。 つまり、2つの転置部分の一方の内側を指していたマーカは その部分とともに移動して、新しい位置で同じ2つの文字のあいだに留まる。 しかし、leave-markersnil以外であると、 transpose-regionsはこれを行わず、 すべてのマーカは再配置されない。


31.23 変更フック

これらのフックにより、すべてのバッファ (それらをバッファローカルにしておけば特定のバッファ)における すべての変更を知るようにできます。 テキストの特定部分の変更を検出する方法については、 31.19.4 特別な意味を持つ属性も参照してください。

これらのフックに使う関数において正規表現を使う場合には、 マッチデータを保存し復元する必要があります。 さもないと、それらを呼び出す編集操作と奇妙な干渉を引き起こします。

Variable: before-change-functions
この変数は、バッファを変更するまえに呼び出すべき関数のリストを保持する。 各関数は2つの引数、つまり、整数で表した変更対象の領域の先頭と末尾を受け取る。 変更対象のバッファはつねにカレントバッファである。

Variable: after-change-functions
この変数は、バッファを変更したあとに呼び出すべき関数のリストを保持する。 各関数は3つの引数、つまり、変更されたばかりの領域の先頭と末尾、 変更前に存在していたテキストの長さを受け取る。 3つの引数はすべて整数である。 変更対象のバッファはつねにカレントバッファである。

古いテキストの長さは、変更前のそのテキストの先頭と末尾の バッファ内位置の差である。 変更済みのテキストの長さは、単純に始めの2つの引数の差である。

Macro: combine-after-change-calls body...
このマクロは通常どおりbodyを実行するが、 一連の変更に対して安全と思えるときには、 after-change-functionsの関数を一度だけ呼び出す。

プログラムからバッファの同じ部分でテキスト変更を複数回行う場合、 プログラムの当該部分の周りでマクロcombine-after-change-callsを使うと、 フックafter-change-functionsを使用してるときには 動作がかなり速くなりうる。 最終的にフックafter-change-functionsが呼ばれると、 combine-after-change-callsの本体で行った変更すべてを含むような バッファ部分が引数に指定される。

警告: フォームcombine-after-change-callsの本体の内側では after-change-functionsafter-change-functionの値を 変更しないこと。

注意: 変更がバッファの広く分散した部分に行われるときにもこれは動作するが、 推奨できない。 非効率なふるまいをするようなフック関数があるからである。

Variable: before-change-function
この廃れた変数は、任意のバッファの変更を行うまえに 呼ばれる1つの関数を保持する (nilならばそのような関数はなし)。 before-change-functionsの関数と同様に呼ばれる。

Variable: after-change-function
この廃れた変数は、任意のバッファの変更を行ったあとに 呼ばれる1つの関数を保持する (nilならばそのような関数はなし)。 after-change-functionsの関数と同様に呼ばれる。

上の4つの変数は、これらの関数が実行中には一時的にnilに束縛されます。 つまり、これらの関数の1つがバッファを変更しても、 その変更ではこれらの関数を呼び出しません。 フック関数においてこれらの関数を実行するような変更を行いたい場合には、 フック関数でこれらの変数をそれらの通常の値に束縛し直します。

この保護的な機構の1つの不便な帰結は、 after-change-functionsbefore-change-functionsには、 その変数の値を変更する関数を持てないことです。 しかし、これは本当の制限ではありません。 それらの関数で実行すべき関数のリストを変更したければ、 単純に1つの定まった関数をフックに追加し、 その関数では呼び出すべき別の関数を指定する別の変数を調べます。 つぎのようにします。

 
(setq my-own-after-change-functions nil)
(defun indirect-after-change-function (beg end len)
  (let ((list my-own-after-change-functions))
    (while list
      (funcall (car list) beg end len)
      (setq list (cdr list)))))

(add-hooks 'after-change-functions
           'indirect-after-change-function)

Variable: first-change-hook
この変数は、未変更状態のバッファを変更するたびに実行される ノーマルフックである。

[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Akihiro Sagawa on January, 21 2003 using texi2html