This is the GNU Emacs Lisp Reference Manual corresponding to Emacs version 25.1.
Copyright © 1990–1996, 1998–2016 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with the Invariant Sections being “GNU General Public License,” with the Front-Cover Texts being “A GNU Manual,” and with the Back-Cover Texts as in (a) below. A copy of the license is included in the section entitled “GNU Free Documentation License.”
(a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify this GNU manual. Buying copies from the FSF supports it in developing GNU and promoting software freedom.”
Published by the Free Software Foundation
51 Franklin St, Fifth Floor
Boston, MA 02110-1301
USA
ISBN 1-882114-74-4
Cover art by Etienne Suvasa.
[ < ] | [ > ] | [Contents] | [Index] | [ ? ] |
This is the GNU Emacs Lisp Reference Manual corresponding to Emacs version 25.1.
Copyright © 1990–1996, 1998–2016 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with the Invariant Sections being “GNU General Public License,” with the Front-Cover Texts being “A GNU Manual,” and with the Back-Cover Texts as in (a) below. A copy of the license is included in the section entitled “GNU Free Documentation License.”
(a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify this GNU manual. Buying copies from the FSF supports it in developing GNU and promoting software freedom.”
1 イントロダクション | イントロダクションと使用される慣習。 | |
2 Lispのデータ型 | Emacs Lispでのオブジェクトのデータタイプ。 | |
3 数値 | 数値と算術関数。 | |
4 文字列と文字 | 文字列とそれらを処理する関数。 | |
5 リスト | リスト、コンスセルと関連する関数。 | |
6 シーケンス、配列、ベクター | リスト、文字列、ベクターはシーケンスと呼ばれる。特定の関数は任意の種類のシーケンスに機能する。ここではベクターの説明も行う。 | |
7 ハッシュテーブル | 非常に高速な照会テーブル。 | |
8 シンボル | 名前を一意に表すシンボル。 | |
9 評価 | Lisp式が評価される方法。 | |
10 制御構造 | 条件文、ループ、非ローカル脱出。 | |
11 変数 | プログラムで値を表すためにシンボルを使用する。 | |
12 関数 | 関数とは別の関数から呼び出せるLispプログラムである。 | |
13 マクロ | マクロとはLisp言語を拡張する手段である。 | |
14 カスタマイゼーション設定 | 変数やフェイスをカスタマイズ可能にする。 | |
15 ロード | LispコードのファイルをLispに読み込む。 | |
16 バイトコンパイル | プログラム実行を高速にするコンパイル。 | |
17 Lispプログラムのデバッグ | Lispプログラムのデバッグのためのツールとヒント。 | |
18 Lispオブジェクトの読み取りとプリント | Lispオブジェクトからテキストへの変換と逆変換。 | |
19 ミニバッファー | 入力を読み取るためにミニバッファーを使用する。 | |
20 コマンドループ | エディターコマンドループが機能する方法と、そのサブルーチンを呼び出す方法。 | |
21 キーマップ | キーをコマンドにバインドするための定義。 | |
22 メジャーモードとマイナーモード | メジャーモードとマイナーモードの定義。 | |
23 ドキュメント | ドキュメント文字列の記述と使用。 | |
24 ファイル | ファイルへのアクセス。 | |
25 バックアップと自動保存 | バックアップファイルト自動保存ファイルの作成方法の制御。 | |
26 バッファー | バッファーオブジェクトの作成と使用。 | |
27 ウィンドウ | ウィンドウの操作とバッファーの表示。 | |
28 フレーム | システムレベルウィンドウを複数作成する。 | |
29 ポジション | バッファー位置と移動関数。 | |
30 マーカー | マーカーは位置を表し、テキスト変更時に自動的に更新される。 | |
31 テキスト | バッファー内のテキストの調査と変更。 | |
32 非ASCII文字 | バッファーと文字列内の非ASCIIテキスト。 | |
33 検索とマッチング | バッファー内の文字列や正規表現の検索。 | |
34 構文テーブル | 単語やリストの解析を制御する構文テーブル。 | |
35 abbrevとabbrev展開 | Abbrevモードが機能する方法と、そのデータ構造。 | |
36 プロセス | サブプロセスの実行と対話。 | |
37 Emacsのディスプレー表示 | スクリーン表示を制御するための機能。 | |
38 オペレーティングシステムのインターフェース | ユーザーID、システムタイプ、環境変数、その他類似項目の取得。 | |
39 配布用 Lispコードの準備 | 配布用にLispコードを準備する。 | |
Appendices | ||
Appendix A Emacs 24 Antinews | Info for users downgrading to Emacs 24. | |
Appendix B GNU Free Documentation License | このドキュメントのライセンス。 | |
Appendix C GNU General Public License | GNU Emacsの複製と変更を行うための条件。 | |
Appendix D ヒントと規約 | Emacs Lispのコーディング規約にたいするアドバイス。 | |
Appendix E GNU Emacsの内部 | Emacsのビルドとダンプ、内部的な構造。 | |
Appendix F 標準的なエラー | いくつかの標準的なエラーシンボルのリスト。 | |
Appendix G 標準的なキーマップ | いくつかの標準的なキーマップのリスト。 | |
Appendix H 標準的なフック | いくつかの標準的なフック変数のリスト。 | |
Index | 概念、関数、変数、その他用語のインデックス。 | |
— 詳細ノードリスト — ——————————— 以下はすでにリストしたもののサブノードであるようなノードのリストです。1ステップで移動できるようにここに記します: Introduction | ||
1.1 注意事項 | 不備な点と、助けを求める方法。 | |
1.2 Lispの歴史 | Emacs LispはMaclispの子孫です。 | |
1.3 表記について | このマニュアルのフォーマット方法。 | |
1.4 バージョンの情報 | 実行中のEmacsのバージョンは? | |
1.5 謝辞 | このマニュアルの著者、編集者、スポンサー。 | |
Conventions | ||
1.3.1 用語について | このマニュアルで使用する用語の説明。 | |
1.3.2 nil とt | シンボルnil とt の使用方法。
| |
1.3.3 評価の表記 | 評価の例で使用するフォーマット。 | |
1.3.4 プリントの表記 | テキストのプリント例で使用するフォーマット。 | |
1.3.5 エラーメッセージ | エラー例で使用するフォーマット。 | |
1.3.6 バッファーテキストの表記 | 例のバッファー内容で使用するフォーマット。 | |
1.3.7 説明のフォーマット | 関数や変数などの説明にたいする表記。 | |
Format of Descriptions | ||
1.3.7.1 関数の説明例 | 架空の関数foo にたいする記述例。
| |
1.3.7.2 変数の説明例 | 架空の変数electric-future-map にたいする記述例。
| |
Lisp Data Types | ||
2.1 プリント表現と読み取り構文 | Lispオブジェクトがテキストとして表現される方法。 | |
2.2 コメント | コメントとコメント書式の慣例。 | |
2.3 プログラミングの型 | すべてのLispシステムに存在する型。 | |
2.4 編集用の型 | Emacs固有の型。 | |
2.5 循環オブジェクトの読み取り構文 | 循環構造にたいする入力構文。 | |
2.6 型のための述語 | 型に関連するテスト。 | |
2.7 同等性のための述語 | 2つのオブジェクトが等しいかのテスト。 | |
Programming Types | ||
2.3.1 整数型 | 小数部のない数字。 | |
2.3.2 浮動小数点数型 | 広い範囲をもつ、小数部をもつ数字。 | |
2.3.3 文字型 | 文字、数字、コントロール文字にたいする表現。 | |
2.3.4 シンボル型 | 関数、変数、プロパティーリストを参照する、一意に識別される多目的オブジェクト。 | |
2.3.5 シーケンス型 | リストと配列はどちらもシーケンスに分類される。 | |
2.3.6 コンスセルとリスト型 | コンスセル、および(コンスセルにより作られる)リスト。 | |
2.3.7 配列型 | 配列には文字列とベクターが含まれる。 | |
2.3.8 文字列型 | (効率的な)文字の配列。 | |
2.3.9 ベクター型 | 1次元の配列。 | |
2.3.10 文字テーブル型 | 文字によりインデックスされる1次元の疎な配列。 | |
2.3.11 ブールベクター型 | t とnil からなる、1次元の配列。
| |
2.3.12 ハッシュテーブル型 | とても高速な参照用のテーブル。 | |
2.3.13 関数型 | 他の場所から呼び出せる実行可能なコードの断片。 | |
2.3.14 マクロ型 | より基本的だが少し見栄えの悪い、式を他の式に展開する手法。 | |
2.3.15 プリミティブ関数型 | Lispから呼び出せる、Cで記述された関数。 | |
2.3.16 バイトコード関数型 | Lispで記述されてからコンパイルされた関数。 | |
2.3.17 autoload型 | 頻繁に使用されない関数を自動的にロードするために使用される型。 | |
2.3.18 Finalizer Type | Runs code when no longer reachable. | |
Character Type | ||
2.3.3.1 基本的な文字構文 | 標準的な文字の構文。 | |
2.3.3.2 一般的なエスケープ構文 | 文字をコードにより指定する方法。 | |
2.3.3.3 コントロール文字構文 | コントロール文字の構文。 | |
2.3.3.4 メタ文字構文 | メタ文字の構文。 | |
2.3.3.5 その他の文字修飾ビット | ハイパー、スーパー、アルト文字の構文。 | |
Cons Cell and List Types | ||
2.3.6.1 ボックスダイアグラムとしてのリストの描写 | リストを絵で書いたら。 | |
2.3.6.2 ドットペア表記 | コンスセルの一般的な構文。 | |
2.3.6.3 連想リスト型 | コンスセルの一般的な構文。 | |
String Type | ||
2.3.8.1 文字列の構文 | Lisp文字列を指定する方法。 | |
2.3.8.2 文字列内の非ASCII文字 | 文字列内の国際化文字。 | |
2.3.8.3 文字列内の非プリント文字 | 文字列内の印刷不可能なリテラル文字。 | |
2.3.8.4 文字列内のテキストプロパティ | テキストプロパティーをともなう文字列。 | |
Editing Types | ||
2.4.1 バッファー型 | 編集のための基本オブジェクト。 | |
2.4.2 マーカー型 | バッファー内の位置。 | |
2.4.3 ウィンドウ型 | バッファーはウィンドウ内に表示する。 | |
2.4.4 フレーム型 | ウィンドウはフレームを細分化する。 | |
2.4.5 端末型 | フレームを表示する端末デバイス。 | |
2.4.6 ウィンドウ構成型 | フレームが細分化された方法を記録する。 | |
2.4.7 フレーム構成型 | すべてのフレームの状態を記録する。 | |
2.4.8 プロセス型 | 背後のOS上で実行されるEmacsのサブプロセス。 | |
2.4.9 ストリーム型 | 文字の受信と送信。 | |
2.4.10 キーマップ型 | キーストロークがどの関数を呼び出すか。 | |
2.4.11 オーバーレイ型 | オーバーレイが表示される方法。 | |
2.4.12 フォント型 | テキストを表示するフォント。 | |
Numbers | ||
3.1 整数の基礎 | 整数の表現と範囲。 | |
3.2 浮動小数点数の基礎 | 浮動少数の表現と範囲。 | |
3.3 数値のための述語 | 数にたいするテスト。 | |
3.4 数値の比較 | 同一性と非同一性の述語。 | |
3.5 数値の変換 | 浮動小数点数から整数、またはその逆の変換。 | |
3.6 算術演算 | 加減乗除の方法。 | |
3.7 丸め処理 | 浮動小数点数の明示的な丸め。 | |
3.8 ビット演算 on Integers | 論理的なand、or、not、shift。 | |
3.9 標準的な数学関数 | 三角関数、指数、対数関数。 | |
3.10 乱数 | 予測可能または不可能な乱数の取得。 | |
Strings and Characters | ||
4.1 文字列と文字の基礎 | 文字列と文字の基本的なプロパティー。 | |
4.2 文字列のための述語 | オブジェクトが文字列か文字かをテストする。 | |
4.3 文字列の作成 | 新しい文字列を割り当てる関数。 | |
4.4 文字列の変更 | 既存の文字列の内容を変更する。 | |
4.5 文字および文字列の比較 | 文字または文字列を比較する。 | |
4.6 文字および文字列の変換 | 文字から文字列、文字から文字列への変換。 | |
4.7 文字列のフォーマット | format :
printf ’のEmacsバージョン。
| |
4.8 Lispでの大文字小文字変換 | case変換関数。 | |
4.9 caseテーブル | case変換のカスタマイズ。 | |
Lists | ||
5.1 リストとコンスセル | コンスセルからリストが作られる方法。 | |
5.2 リストのための述語 | このオブジェクトはリストか? 2つのリストを比較する。 | |
5.3 リスト要素へのアクセス | リストの一部を抽出する。 | |
5.4 コンスセルおよびリストの構築 | リスト構造の作成。 | |
5.5 リスト変数の変更 | 変数に保存されたリストにたいする変更。 | |
5.6 既存のリスト構造の変更 | 既存のリストに新しい要素を保存する。 | |
5.7 集合としてのリストの使用 | リストは有限な数学集合を表現できる。 | |
5.8 連想リスト | リストは有限な関係またはマッピングを表現できます。 | |
5.9 プロパティリスト | 要素ペアのリスト。 | |
Modifying Existing List Structure | ||
5.6.1 setcar によるリスト要素の変更 | リスト内の要素の置き換え。 | |
5.6.2 リストのCDRの変更 | リストの根幹部分の置き換え。これは要素の追加や削除に使用される。 | |
5.6.3 リストを再配置する関数 | リスト内の要素の再配置、リストの合成。 | |
Property Lists | ||
5.9.1 プロパティリストと連想リスト | プロパティーリストと連想リストの利点の比較。 | |
5.9.2 プロパティリストと外部シンボル | 他の場所に保管されたプロパティーリストへのアクセス。 | |
Sequences, Arrays, and Vectors | ||
6.1 シーケンス | 任意の種類のシーケンスを許す関数。 | |
6.2 配列 | Emacs Lispの配列の特徴。 | |
6.3 配列を操作する関数 | Emacs Lispの配列の特徴。 | |
6.4 ベクター | Emacs Lispベクターの特質。 | |
6.5 ベクターのための関数 | ベクターのための特別な関数。 | |
6.6 文字テーブル | 文字テーブルを扱う方法。 | |
6.7 ブールベクター | ブールベクターを扱う方法。 | |
6.8 オブジェクト用固定長リングの管理 | オブジェクトの固定サイズのリングを管理する。 | |
Hash Tables | ||
7.1 ハッシュテーブルの作成 | ハッシュテーブルを作成する関数。 | |
7.2 ハッシュテーブルへのアクセス | ハッシュテーブルの内容の読み書き。 | |
7.3 ハッシュの比較の定義 | 新たな比較方法の定義。 | |
7.4 ハッシュテーブルのためのその他関数 | その他。 | |
Symbols | ||
8.1 シンボルの構成要素 | シンボルは名前、値、関数定義、プロパティーリストをもつ。 | |
8.2 シンボルの定義 | 定義は、シンボルが使用される方法を示す。 | |
8.3 シンボルの作成とintern | シンボルが一意に保たれる方法。 | |
8.4 シンボルのプロパティ | さまざまな情報を記録するために、各シンボルはプロパティーリストをもつ。 | |
Symbol Properties | ||
8.4.1 シンボルのプロパティへのアクセス | シンボルプロパティーへのアクセス。 | |
8.4.2 シンボルの標準的なプロパティ | シンボルプロパティーの標準的な意味。 | |
Evaluation | ||
9.1 評価の概要 | 事の在り方における評価。 | |
9.2 フォームの種類 | さまざまなオブジェクト類が評価される方法。 | |
9.3 クォート | (プログラム内に定数を配すための)評価の回避。 | |
9.4 バッククォート | リスト構造の、より簡単な構築。 | |
9.5 eval | Lispインタープリターを明示的に呼び出す方法。 | |
Kinds of Forms | ||
9.2.1 自己評価を行うフォーム | 自分自身を評価するフォーム。 | |
9.2.2 シンボルのフォーム | 変数として評価されるシンボル。 | |
9.2.3 リストフォームの分類 | さまざまな種類のリストフォームを区別する方法。 | |
9.2.4 シンボル関数インダイレクション | シンボルがリストのcarにある場合、そのシンボルを通じて実際の関数を見つける。 | |
9.2.5 関数フォームの評価 | 関数を呼び出すフォーム。 | |
9.2.6 Lispマクロの評価 | マクロを呼び出すフォーム。 | |
9.2.7 スペシャルフォーム | Special forms are idiosyncratic primitives, most of them extremelyimportant. | |
9.2.8 自動ロード | 実際の定義を含むファイルのロードをセットアップする関数。 | |
Control Structures | ||
10.1 順序 | テキスト順の評価。 | |
10.2 条件 | if 、cond 、when 、unless 。
| |
10.3 条件の組み合わせ | and 、or 、not 。
| |
10.4 繰り返し | while ループ。
| |
10.5 Generators | Generic sequences and coroutines. | |
10.6 非ローカル脱出 | シーケンスの外へジャンプ。 | |
Conditionals | ||
10.2.1 パターンマッチングによるcase文 | How to use pcase .
| |
Nonlocal Exits | ||
10.6.1 明示的な非ローカル脱出: catch とthrow | プログラム自身の目的による非ローカル脱出。 | |
10.6.2 catch とthrown の例 | このような非ローカル脱出が記述される方法。 | |
10.6.3 エラー | エラーがシグナル・処理される方法。 | |
10.6.4 非ローカル脱出のクリーンアップ | エラーが発生した場合のクリーンアップフォーム実行のアレンジ。 | |
Errors | ||
10.6.3.1 エラーをシグナルする方法 | エラーを報告する方法。 | |
10.6.3.2 Emacsがエラーを処理する方法 | エラーを報告するときEmacsが何を行なうか。 | |
10.6.3.3 エラーを処理するコードの記述 | エラーをトラップして実行を継続する方法。 | |
10.6.3.4 エラーシンボルとエラー条件 | エラートラッピングのために、エラーをクラス分けする方法。 | |
Variables | ||
11.1 グローバル変数 | どの場所でも永続的に存在する変数の値。 | |
11.2 Variables that Never Change | Variables that never change. | |
11.3 ローカル変数 | 一時的にのみ存在する存在する変数の値。 | |
11.4 変数がvoidのとき | 値を持たないシンボル。 | |
11.5 グローバル変数の定義 | シンボルが変数として使用されていることを宣言する定義。 | |
11.6 堅牢な変数定義のためのヒント | 変数を定義するときに考慮すべき事項。 | |
11.7 変数の値へのアクセス | 実行時に判明する名前をもつ変数の値を確認する。 | |
11.8 変数の値のセット | 変数に新しい値を格納する。 | |
11.9 変数のバインディングのスコーピングルール | Lispがローカル値とグローバル値を選択する方法。 | |
11.10 バッファーローカル変数 | 1つのバッファーないだけで効果をもつ変数の値。 | |
11.11 ファイルローカル変数 | ファイル内にリストされたローカル変数の処理。 | |
11.12 ディレクトリーローカル変数 | ディレクトリー内のすべてのファイルで共通のローカル変数。 | |
11.13 変数のエイリアス | 他の変数のエイリアスとなる変数。 | |
11.14 値を制限された変数 | 任意のLispオブジェクトを値とすることができない、定数ではない変数。 | |
11.15 ジェネリック変数 | 変数の概念の拡張。 | |
Scoping Rules for Variable Bindings | ||
11.9.1 ダイナミックバインディング | Emacs内でのローカル変数にたいするデフォルトのバインディング。 | |
11.9.2 ダイナミックバインディングの正しい使用 | ダイナミックバインディングによる問題を回避する。 | |
11.9.3 レキシカルバインディング | ローカル変数にたいする他の種類のバインディング。 | |
11.9.4 レキシカルバインディングの使用 | レキシカルバインディングを有効にする方法。 | |
Buffer-Local Variables | ||
11.10.1 バッファーローカル変数の概要 | イントロダクションと概念。 | |
11.10.2 バッファーローカルなバインディングの作成と削除 | ||
11.10.3 バッファーローカル変数のデフォルト値 | 自身ではバッファーローカルな値をもたないバッファーで参照されるデフォルト値。 | |
Generalized Variables | ||
11.15.1 setf マクロ | ||
11.15.2 新たなsetf フォーム | 新たなsetf フォームの定義。
| |
Functions | ||
12.1 関数とは? | Lisp関数 vs. プリミティブ。専門用語。 | |
12.2 ラムダ式 | 関数がLispオブジェクトとして表現される方法。 | |
12.3 関数の命名 | シンボルは関数を名づける役割を果たすことができる。 | |
12.4 関数の定義 | 関数定義のためのLisp式。 | |
12.5 関数の呼び出し | 既存の関数を使う方法。 | |
12.6 関数のマッピング | リストの各要素などに関数を適用する。 | |
12.7 無名関数 | ラムダ式、それは無名の関数。 | |
12.8 Generic Functions | Polymorphism, Emacs-style. | |
12.9 関数セルの内容へのアクセス | シンボルの関数定義へのアクセスとセット。 | |
12.10 クロージャー | レキシカル環境に囲まれた関数。 | |
12.11 Emacs Lisp関数にたいするアドバイス | Adding to the definition of a function. | |
12.12 関数を陳腐と宣言する | ||
12.13 インライン関数Inline Functions | コンパイラーによりインライン展開される関数。 | |
12.14 declare フォーム | 関数についての補足的な情報の追加。 | |
12.15 コンパイラーへの定義済み関数の指示 | 関数が定義されていることをコンパイラーに知らせる。 | |
12.16 安全に関数を呼び出せるかどうかの判断 | 呼び出しても安全な関数なのか判断する。 | |
12.17 関数に関するその他トピック | 関数が動作する方法において特別な意味をもつ、特定のLispプリミティブのクロスリファレンス。 | |
Lambda Expressions | ||
12.2.1 ラムダ式の構成要素 | ラムダ式のパーツ。 | |
12.2.2 単純なラムダ式の例 | シンプルな例。 | |
12.2.3 引数リストのその他機能 | 引数リストの詳細と特別な機能。 | |
12.2.4 関数のドキュメント文字列 | 関数内にドキュメントを記述する方法。 | |
Advising Emacs Lisp Functions | ||
12.11.1 アドバイスを操作するためのプリミティブ | Primitives to manipulate advice. | |
12.11.2 名前つき関数にたいするアドバイス | Advising named functions. | |
12.11.3 アドバイスの構築方法 | Ways to compose advice. | |
12.11.4 古いdefadviceを使用するコードの改良 | Adapting code using the old defadvice. | |
Macros | ||
13.1 単純なマクロの例 | 基本的な例。 | |
13.2 マクロ呼び出しの展開 | いつ、なぜ、どのようにしてマクロが展開されるか。 | |
13.3 マクロとバイトコンパイル | コンパイラーによりマクロが展開される方法。 | |
13.4 マクロの定義 | マクロ定義を記述する方法。 | |
13.5 マクロ使用に関する一般的な問題 | マクロ引数を何回も評価しないこと。ユーザーの変数を隠さないこと。 | |
13.6 マクロのインデント | マクロ呼び出しのインデント方法の指定。 | |
Common Problems Using Macros | ||
13.5.1 タイミング間違い | マクロ内ではなく展開形で作業を行う。 | |
13.5.2 マクロ引数の多重評価 | 展開形は各マクロ引数を一度評価すること。 | |
13.5.3 マクロ展開でのローカル変数 | 展開形でのローカル変数バインディングには特に注意を要する。 | |
13.5.4 展開におけるマクロ引数の評価 | 評価せずに展開形の中に配置すること。 | |
13.5.5 マクロが展開される回数は? | 展開が行われる回数への依存を避ける。 | |
Customization Settings | ||
14.1 一般的なキーワードアイテム | すべての種類のカスタマイズ宣言に共通なキーワード引数。 | |
14.2 カスタマイゼーショングループの定義 | カスタマイズグループ定義の記述。 | |
14.3 カスタマイゼーション変数の定義 | ユーザーオプションの宣言。 | |
14.4 カスタマイゼーション型 | ユーザーオプションの型指定。 | |
14.5 カスタマイゼーションの適用 | カスタマイズセッティングを適用する関数。 | |
14.6 Customテーマ | カスタムテーマの記述。 | |
Customization Types | ||
14.4.1 単純型 | シンプルなカスタマイズ型(sexp、integerなど)。 | |
14.4.2 複合型 | 他の型やデータから新しい型を構築する。 | |
14.4.3 リストへのスプライス | :inline で要素をリストに結合する。
| |
14.4.4 型キーワード | カスタマイズ型でのキーワード/引数ペアー | |
14.4.5 新たな型の定義 | 型に名前をつける。 | |
Loading | ||
15.1 プログラムがロードを行う方法 | load ’関数、その他。
| |
15.2 ロードでの拡張子 | load ’が試みられるサフィックスについての詳細。
| |
15.3 ライブラリー検索 | ロードするライブラリーの検索。 | |
15.4 非ASCII文字のロード | Emacs Lispファイル内の非ASCII文字。 | |
15.5 autoload | オートロードのための関数のセットアップ。 | |
15.6 多重ロード | ファイルを2度ロードする場合の配慮。 | |
15.7 名前つき機能 | まだロードされていないライブラリーのロード。 | |
15.8 どのファイルで特定のシンボルが定義されているか | 特定のシンボルがどのファイルで定義されているかの検索。 | |
15.9 アンロード | ロードされたライブラリーをunloadする方法。 | |
15.10 ロードのためのフック | 特定のライブラリーがロードされたとき実行されるコードの提供。 | |
15.11 Emacs Dynamic Modules | Modules provide additional Lisp primitives. | |
Byte Compilation | ||
16.1 バイトコンパイル済みコードのパフォーマンス | バイトコンパイルによるスピードアップ例。 | |
16.2 バイトコンパイル関数 | ||
16.3 ドキュメント文字列とコンパイル | ドキュメント文字列のダイナミックロード。 | |
16.4 個別関数のダイナミックロード | 個々の関数のダイナミックロード。 | |
16.5 コンパイル中の評価 | コンパイル時に評価されるコード。 | |
16.6 コンパイラーのエラー | コンパイラーのエラーメッセージの扱い。 | |
16.7 バイトコード関数オブジェクト | バイトコンパイル済み関数に使用されるデータ型。 | |
16.8 逆アセンブルされたバイトコード | バイトコードの逆アセンブル。バイトコードの読み方。 | |
Debugging Lisp Programs | ||
17.1 Lispデバッガ | Emacs Lisp評価機能にたいするデバッガ。 | |
17.2 Edebug | Emacs Lispソースレベルデバッガ。 | |
17.3 無効なLisp構文のデバッグ | シンタックスエラーを見つける方法。 | |
17.4 カバレッジテスト | プログラムのすべての分岐を確実にテストする。 | |
17.5 プロファイリング | あなたのコードが使用するリソースの計測。 | |
The Lisp Debugger | ||
17.1.1 エラーによるデバッガへのエンター | エラー発生時にデバッガにエンターする。 | |
17.1.2 無限ループのデバッグ | exitしないプログラムの停止デバッグ。 | |
17.1.3 関数呼び出しによるデバッガへのエンター | 特定の関数が呼び出されたときにデバッガにエンターする。 | |
17.1.4 明示的なデバッガへのエントリー | プログラム内の特定箇所でデバッガにエンターする。 | |
17.1.5 デバッガの使用 | デバッガが行なうこと: そこで何を目にするか。 | |
17.1.6 デバッガのコマンド | デバッガで使用するコマンド。 | |
17.1.7 デバッガの呼び出し | 関数debug の呼び出し方。
| |
17.1.8 デバッガの内部 | デバッガのサブルーチン、およびグローバル変数。 | |
Edebug | ||
17.2.1 Edebugの使用 | Edebug使用のための手引き。 | |
17.2.2 Edebugのためのインストルメント | Edebugでデバッグするために、コードをインストルメント(計装)しなければならないe | |
17.2.3 Edebugの実行モード | 多かれ少なかれ、ストップする実行モード。 | |
17.2.4 ジャンプ | 特定の位置にジャンプするコマンド。 | |
17.2.5 その他のEdebugコマンド | さまざまなコマンド。 | |
17.2.6 ブレーク | プログラムをストップさせるbreakpointのセット。 | |
17.2.7 エラーのトラップ | Edebugでのエラーのトラップ。 | |
17.2.8 Edebugのビュー | Edebugの内側と外側のビュー。 | |
17.2.9 評価 | Edebugでの式の評価。 | |
17.2.10 評価 List Buffer | Edebugにエンターするたびに値が表示される式。 | |
17.2.11 Edebugでのプリント | プリントのカスタマイズ。 | |
17.2.12 トレースバッファー | バッファー内で採れを生成する方法。 | |
17.2.13 カバレッジテスト | 評価をカバレッジテストする方法。 | |
17.2.14 コンテキスト外部 | Edebugが保存およびリストアするデータ。 | |
17.2.15 Edebugとマクロ | マクロ呼び出しをハンドルする方法の指定。 | |
17.2.16 Edebugのオプション | Edebugをカスタマイズするオプション変数。 | |
Breaks | ||
17.2.6.1 Edebugのブレークポイント | ストップポイントのbreakpoint。 | |
17.2.6.2 グローバルなブレーク条件 | イベントによるbreak。 | |
17.2.6.3 ソースブレークポイント | ソースコードに埋め込まれたbreakpoint。 | |
The Outside Context | ||
17.2.14.1 停止するかどうかのチェック | 何を行うかをEdebugが決定するタイミング。 | |
17.2.14.2 Edebugの表示の更新 | Edebugがディスプレイを更新するタイミング。 | |
17.2.14.3 Edebugの再帰編集 | Edebugが実行をストップするタイミング。 | |
Edebug and Macros | ||
17.2.15.1 マクロ呼び出しのインストルメント | 基本的な問題点。 | |
17.2.15.2 仕様リスト | 式の複雑なパターンを指定する方法。 | |
17.2.15.3 仕様でのバックトレース | マッチに失敗したときEdebugが行なうこと。 | |
17.2.15.4 仕様の例 | Edebug仕様を理解するために。 | |
Debugging Invalid Lisp Syntax | ||
17.3.1 過剰な開カッコ | 誤った開カッコと閉カッコを探す方法。 | |
17.3.2 過剰な閉カッコ | 誤った閉カッコと開カッコを探す方法。 | |
Reading and Printing Lisp Objects | ||
18.1 読み取りとプリントの概念 | ストリーム、読み取り、プリントの概観。 | |
18.2 入力ストリーム | 入力ストリームとして使用できる、さまざまなデータ型。 | |
18.3 入力関数 | テキストからLispオブジェクトを読み取る関数。 | |
18.4 出力ストリーム | 出力ストリームとして使用できる、さまざまなデータ型。 | |
18.5 出力関数 | テキストとしてLispオブジェクトをプリントする関数。 | |
18.6 出力に影響する変数 | プリント関数が何を行うか制御する変数。 | |
Minibuffers | ||
19.1 ミニバッファーの概念 | ミニバッファーに関する基本的な情報。 | |
19.2 ミニバッファーでのテキスト文字列の読み取り | そのままのテキスト文字列を読み取る方法。 | |
19.3 ミニバッファーでのLispオブジェクトの読み取り | Lispオブジェクトや式を読み取る方法。 | |
19.4 ミニバッファーのヒストリー | ユーザーが再利用できるように以前のミニバッファー入力は記録される。 | |
19.5 入力の初期値 | ミニバッファーにたいして初期内容を指定する。 | |
19.6 補完 | 補完の呼び出しとカスタマイズ方法。 | |
19.7 Yes-or-Noによる問い合わせ | 問いにたいし単純な答えを求める。 | |
19.8 複数のY-or-Nの問い合わせ | 一連の似たような問いに答える。 | |
19.9 パスワードの読み取り | 端末からパスワードを読み取る。 | |
19.10 ミニバッファーのコマンド | ミニバッファー内でキーバインドとして使用されるコマンド。 | |
19.11 ミニバッファーのウィンドウ | 特殊なミニバッファーウィンドウを処理する。 | |
19.12 ミニバッファーのコンテンツ | どのようなコマンドがミニバッファーのテキストにアクセスするか。 | |
19.13 再帰的なミニバッファー | ミニバッファーへの再帰的なエントリーが許容されるかどうか。 | |
19.14 ミニバッファー、その他の事項 | カスタマイズ用のさまざまなフックや変数。 | |
Completion | ||
19.6.1 基本的な補完関数 | 文字列を補完する低レベル関数。 | |
19.6.2 補完とミニバッファー | 補完つきでミニバッファーを呼び出す。 | |
19.6.3 補完を行うミニバッファーコマンド | ||
19.6.4 高レベルの補完関数 | 特別なケースに有用な補完(バッファー名や変数名などの読み取り)。 | |
19.6.5 ファイル名の読み取り | ファイル名やシェルコマンドの読み取りに補完を使用する。 | |
19.6.6 補完変数 | 補完の挙動を制御する変数。 | |
19.6.7 プログラムされた補完 | 独自の補完関数を記述する。 | |
19.6.8 通常バッファーでの補完 | 通常バッファー内でのテキスト補完。 | |
Command Loop | ||
20.1 コマンドループの概要 | コマンドループがコマンドを読み取る方法。 | |
20.2 コマンドの定義 | 関数が引数を読み取る方法を指定する。 | |
20.3 interactiveな呼び出し | 引数を読み取るようにコマンドを呼び出す。 | |
20.4 interactiveな呼び出しの区別 | インタラクティブな呼び出しとコマンドを区別する。 | |
20.5 コマンドループからの情報 | 検証用にコマンドループによりセットされる変数。 | |
20.6 コマンド後のポイントの調整 | コマンドの後にポイント位置を調整する。 | |
20.7 入力イベント | 入力を読み取るとき、入力がどのように見えるか。 | |
20.8 入力の読み取り | キーボードやマウスからの入力イベントを読み取る方法。 | |
20.9 スペシャルイベント | 即座かつ個別に処理されるイベント。 | |
20.10 時間の経過や入力の待機 | ユーザー入力または経過時間の待機。 | |
20.11 quit | C-g’が機能する方法。quitをcatchまたは延期する方法。 | |
20.12 プレフィクスコマンド引数 | コマンドがプレフィクス引数が機能するようにセットするための方法。 | |
20.13 再帰編集 | 再帰編集へのエンター、なぜ通常は再帰編集を行うべきでないのか。 | |
20.14 コマンドの無効化 | コマンドループが無効なコマンドを扱う方法。 | |
20.15 コマンドのヒストリー | コマンドヒストリーがセットアップされる方法と、どのようにアクセスされるか。 | |
20.16 キーボードマクロ | キーボードマクロが実装される方法。 | |
Defining Commands | ||
20.2.1 interactive の使用 | interactive ’にたいする一般的なルール。
| |
20.2.2 interactive にたいするコード文字 | さまざまな方法で引数を読み取る標準的な文字のコード。 | |
20.2.3 interactive の使用例 | インタラクティブ引数を読み取る方法の例。 | |
20.2.4 コマンド候補からの選択 | ||
Input Events | ||
20.7.1 キーボードイベント | Ordinary characters – keys with symbols on them. | |
20.7.2 ファンクションキー | Function keys – keys with names, not symbols. | |
20.7.3 マウスイベント | マウスイベントの概観。 | |
20.7.4 クリックイベント | マウスボタンのプッシュとリリース。 | |
20.7.5 ドラッグイベント | ボタンをリリースする前のマウス移動。 | |
20.7.6 ボタンダウンイベント | ボタンがプッシュされて、まだリリースされていない状態。 | |
20.7.7 リピートイベント | ダブル、トリプルのクリック(またはドラッグ、ダウン) | |
20.7.8 モーションイベント | ボタンを押さずに、マウスだけを移動する。 | |
20.7.9 フォーカスイベント | フレーム間のマウス移動。 | |
20.7.10 その他のシステムイベント | システムが生成可能なその他のイベント。 | |
20.7.11 イベントの例 | マウスイベントの例。 | |
20.7.12 イベントの分類 | イベントシンボル内の修飾キーを見つける。イベント型。 | |
20.7.13 マウスイベントへのアクセス | マウスイベントから情報抽出する関数。 | |
20.7.14 スクロールバーイベントへのアクセス | スクロールバーイベントから情報取得する関数。 | |
20.7.15 文字列内へのキーボードイベントの配置 | 文字列内にキーボード文字イベントを配すための特別な配慮。 | |
Reading Input | ||
20.8.1 キーシーケンス入力 | キーシーケンスを読み取る方法。 | |
20.8.2 単一イベントの読み取り | イベントを1つだけ読み取る方法。 | |
20.8.3 入力イベントの変更と変換 | Emacsが読み取られたイベントを変更する方法。 | |
20.8.4 入力メソッドの呼び出し | 入力メソッドを使用するイベントを読み取る方法。 | |
20.8.5 クォートされた文字の入力 | 文字の指定をユーザーに問い合わせる。 | |
20.8.6 その他のイベント入力の機能 | 入力イベントの最読み取りや破棄の方法。 | |
Keymaps | ||
21.1 キーシーケンス | Lispオブジェクトとしてのキーシーケンス。 | |
21.2 キーマップの基礎 | キーマップの基本概念。 | |
21.3 キーマップのフォーマット | キーマップはLispオブジェクトとしてどのように見えるか。 | |
21.4 キーマップの作成 | キーマップを作成、コピーする関数。 | |
21.5 継承とキーマップ | キーマップが他のキーマップのバインディングを継承する方法。 | |
21.6 プレフィクスキー | キーマップの定義としてキーを定義する。 | |
21.7 アクティブなキーマップ | Emacsがアクティブなキーマップでキーバインディングを探す方法。 | |
21.8 アクティブなキーマップの検索 | アクティブなマップ検索のLisp処理概要。 | |
21.9 アクティブなキーマップの制御 | 各バッファーは標準(グローバル)のバインディングをオーバーライドするためのキーマップをもつ。マイナーモードもそれらをオーバーライドできる。 | |
21.10 キーの照合 | 1つのキーマップから、あるキーのバインディングを探す。 | |
21.11 キー照合のための関数 | キールックアップを要求する方法。 | |
21.12 キーバインディングの変更 | キーマップ内でのキーの再定義。 | |
21.13 コマンドのリマップ | キーマップはあるコマンドを他のコマンドに変換できる。 | |
21.14 イベントシーケンス変換のためのキーマップ | イベントシーケンスを変換するキーマップ。 | |
21.15 キーのバインドのためのコマンド | キーの再定義にたいするインタラクティブなインターフェイス。 | |
21.16 キーマップのスキャン | ヘルプをプリントするためにすべてのキーマップを走査する。 | |
21.17 メニューキーアップ | キーマップとしてキーマップを定義する。 | |
Menu Keymaps | ||
21.17.1 メニューの定義 | メニューを定義するキーマップを作成する方法。 | |
21.17.2 メニューとマウス | ユーザーがマウスでメニューを操作する方法。 | |
21.17.3 メニューとキーボード | ユーザーがキーボードでメニューを操作する方法。 | |
21.17.4 メニューの例 | シンプルなメニューの作成。 | |
21.17.5 メニューバー Bar | メニューバーのカスタマイズ方法。 | |
21.17.6 ツールバー | イメージ行のツールバー。 | |
21.17.7 メニューの変更 | メニューへ新たなアイテムを追加する方法。 | |
21.17.8 easy-menu | メニュー作成のための便利なマクロ。 | |
Defining Menus | ||
21.17.1.1 単純なメニューアイテム | 単純なメニューのキーバインディング。 | |
21.17.1.2 拡張メニューアイテム | 複雑なメニューアイテムの定義。 | |
21.17.1.3 メニューセパレーター | メニューに水平ラインを描画する。 | |
21.17.1.4 メニューアイテムのエイリアス | メニューアイテムにコマンドエイリアスを使用する。 | |
Major and Minor Modes | ||
22.1 フック | フックの使い方と、フックを提供するコードの記述方法。 | |
22.2 メジャーモード | メジャーモードの定義。 | |
22.3 マイナーモード | マイナーモードの定義。 | |
22.4 モードラインのフォーマット | モードラインに表示されるテキストのカスタマイズ。 | |
22.5 Imenu | バッファーで作成された定義のメニューを提供する。 | |
22.6 Font Lockモード | モードが構文に応じてテキストをハイライトする方法。 | |
22.7 コードの自動インデント | メジャーモードにたいするインデントをEmacsに伝える方法。 | |
22.8 Desktop Saveモード | Emacsセッション間でモードがバッファー状態を保存する方法。 | |
Hooks | ||
22.1.1 フックの実行 | フックの実行方法。 | |
22.1.2 フックのセットSetting Hooks | 関数をフックに登録、削除する方法。 | |
Major Modes | ||
22.2.1 メジャーモードの慣習 | キーマップなどにたいするコーディング規約。 | |
22.2.2 Emacsがメジャーモードを選択する方法 | Emacsが自動的にメジャーモードを選択する方法。 | |
22.2.3 メジャーモードでのヘルプ入手 | モードの使用方法の探し方。 | |
22.2.4 派生モードの定義 | 他のメジャーモードにもとづき新たなメジャーモードを定義する。 | |
22.2.5 基本的なメジャーモード | 他のモードからよく派生元とされるモード。 | |
22.2.6 モードフック | メジャーモード関数の最後に実行されるフック。 | |
22.2.7 Tabulated Listモード | 表形式データを含むバッファーにたいする親モード。 | |
22.2.8 ジェネリックモード | コメント構文とFont | |
22.2.9 メジャーモードの例 | TextモードとLispモード。 | |
Minor Modes | ||
22.3.1 マイナーモード記述の規約 | マイナーモードを記述するためのTips。 | |
22.3.2 キーマップとマイナーモード | マイナーモードが自身のキーマップをもつための方法。 | |
22.3.3 マイナーモードの定義 | マイナーモードを定義するための便利な機能。 | |
Mode Line Format | ||
22.4.1 モードラインの基礎 | モードライン制御の基本概念。 | |
22.4.2 モードラインのデータ構造 | モードラインを制御するデータ構造。 | |
22.4.3 モードライン制御のトップレベル | トップレベル変数、mode-line-format。 | |
22.4.4 モードラインで使用される変数 | そのデータ構造で使用される変数。 | |
22.4.5 モードラインでの% 構造 | モードラインへの情報の配置。 | |
22.4.6 モードラインでのプロパティ | モードライン内でのテキストプロパティの使用。 | |
22.4.7 ウィンドウのヘッダーライン | モードラインに類似した最上部のライン。 | |
22.4.8 モードラインのフォーマットのエミュレート | モードラインのようにテキストをフォーマットする。 | |
Font Lock Mode | ||
22.6.1 Font Lockの基礎 | Font Lockカスタマイズの概要。 | |
22.6.2 検索ベースのフォント化 | 正規表現にもとづくフォント表示。 | |
22.6.3 検索ベースのフォント化のカスタマイズ | 検索ベースフォント表示のカスタマイズ。 | |
22.6.4 Font Lockのその他の変数 | 追加のカスタマイズ機能。 | |
22.6.5 Font Lockのレベル | 多なりとも少ユーザーが選択できるように、それぞれのモードは代替レベルを定義できる。 | |
22.6.6 事前計算されたフォント化 | バッファーコンテンツを生成するLispプログラムが、どのようにしてそれをフォント表示する方法も指定できるか。 | |
22.6.7 Font Lockのためのフェイス | Font Lockにたいする具体的な特殊フェイス。 | |
22.6.8 構文的なFont Lock | 構文テーブルにもとづくフォント表示。 | |
22.6.9 複数行のFont Lock構造 | Font Lockに複数行構成の正しいハイライトを強制する方法。 | |
Multiline Font Lock Constructs | ||
22.6.9.1 複数行のFont Lock | テキストプロパティで複数行塊をマークする。 | |
22.6.9.2 バッファー変更後のリージョンのフォント化 | バッファー変更後にどのリージョンを再フォント表示するかを制御する。 | |
Automatic Indentation of code | ||
22.7.1 SMIE: 無邪気なインデントエンジン | SMIE: Simple Minded Indentation Engine(純真なインデントエンジン)。 | |
Simple Minded Indentation Engine | ||
22.7.1.1 SMIEのセットアップと機能 | ||
22.7.1.2 演算子順位文法 | 非常にシンプルなパース技術。 | |
22.7.1.3 言語の文法の定義 | 言語の文法を定義する。 | |
22.7.1.4 トークンの定義 | ||
22.7.1.5 非力なパーサーの使用 | パーサー制限の回避策。 | |
22.7.1.6 インデントルールの指定 | ||
22.7.1.7 インデントルールにたいするヘルパー関数 | ||
22.7.1.8 インデントルールの例 | ||
22.7.1.9 インデントのカスタマイズ | ||
Documentation | ||
23.1 ドキュメントの基礎 | ドキュメント文字列が定義、格納される場所。 | |
23.2 ドキュメント文字列へのアクセス | Lispプログラムがドキュメント文字列にアクセスする方法。 | |
23.3 ドキュメント内でのキーバインディングの置き換え | カレントキーバインディングの置き換え。 | |
23.4 ヘルプメッセージの文字記述 | 非プリント文字やキーシーケンスをプリント可能な記述にする。 | |
23.5 ヘルプ関数 | Emacsヘルプ機能により使用されるサブルーチン。 | |
Files | ||
24.1 ファイルのvisit | 編集のためにEmacsバッファーにファイルを読み込む。 | |
24.2 バッファーの保存 | 変更されたバッファーをファイルに書き戻す。 | |
24.3 ファイルの読み込み | ファイルをvisitせずにバッファーに読み込む。 | |
24.4 ファイルの書き込み | バッファーの一部から新たなファイルに書き込む。 | |
24.5 ファイルのロック | 複数名による同時編集を防ぐためにファイルをlockまたはunlockする。 | |
24.6 ファイルの情報 | ファイルの存在、アクセス権、サイズのテスト。 | |
24.7 ファイルの名前と属性の変更 | ファイル名のリネームやパーミッションの変更など。 | |
24.8 ファイルの名前 | ファイル名の分解と展開。 | |
24.9 ディレクトリーのコンテンツ | ディレクトリーないのファイルリストの取得。 | |
24.10 ディレクトリーの作成・コピー・削除 | ディレクトリーの作成と削除。 | |
24.11 特定のファイル名の“Magic”の作成 | 特定のファイル名にたいする特別な処理。 | |
24.12 ファイルのフォーマット変換 | さまざまなファイルフォーマットへ/からの変換。 | |
Visiting Files | ||
24.1.1 ファイルをvisitする関数 | visit用の通常のインターフェイス関数。 | |
24.1.2 visitのためのサブルーチン | 通常のvisit関数が使用する低レベルのサブルーチン。 | |
Information about Files | ||
24.6.1 アクセシビリティのテスト | そのファイルは読み取り可能か?書き込み可能か? | |
24.6.2 ファイル種別の区別 | それはディレクトリー?それともシンボリックリンク? | |
24.6.3 本当の名前 | シンボリックリンクが行き着くファイル名。 | |
24.6.4 ファイルの属性 | ファイルのサイズ?更新日時など。 | |
24.6.5 拡張されたファイル属性 | アクセス制御にたいするファイル属性の拡張。 | |
24.6.6 標準的な場所へのファイルの配置 | 標準的な場所でファイルを見つける方法。 | |
File Names | ||
24.8.1 ファイル名の構成要素 | ファイル名のディレクトリー部分と、それ以外。 | |
24.8.2 絶対ファイル名と相対ファイル名 | カレントディレクトリーにたいして相対的なファイル名。 | |
24.8.3 ディレクトリーの名前 | ディレクトリーとしてのディレクトリー名と、ファイルとしてのファイル名の違い。 | |
24.8.4 ファイル名を展開する関数 | 相対ファイル名から絶対ファイル名への変換。 | |
24.8.5 一意なファイル名の生成 | 一時ファイル用の名前の生成。 | |
24.8.6 ファイル名の補完 | 与えられたファイル名にたいする補完を探す。 | |
24.8.7 標準的なファイル名 | パッケージが固定されたファイル名を使用する際に、種々のオペレーティングシステムをシンプルに処理する方法。 | |
File Format Conversion | ||
24.12.1 概要 | insert-file-contents とwrite-region 。
| |
24.12.2 ラウンドトリップ仕様 | format-alist の使用。
| |
24.12.3 漸次仕様 | 非ペアー変換の指定。 | |
Backups and Auto-Saving | ||
25.1 ファイルのバックアップ | バックアップファイルの作成と名前選択の方法。 | |
25.2 自動保存 | auto-saveファイルの作成と名前選択の方法。 | |
25.3 リバート | revert-buffer とその動作のカスタマイズ方法。
| |
Backup Files | ||
25.1.1 バックアップファイルの作成 | Emacsがバックアップファイルを作成する方法とタイミング。 | |
25.1.2 リネームかコピーのどちらでバックアップするか? | 2つの選択肢: 古いファイルのリネームとコピー。 | |
25.1.3 番号つきバックアップファイルの作成と削除 | ソースファイルごとに複数のバックアップを保持する。 | |
25.1.4 バックアップファイルの命名 | バックアップファイル名の計算方法とカスタマイズ。 | |
Buffers | ||
26.1 バッファーの基礎 | バッファーとは? | |
26.2 カレントバッファー | バッファーをカレントに指定することにより、プリミティブはバッファーのコンテンツにアクセスする。 | |
26.3 バッファーの名前 | バッファー名にたいするアクセスと変更。 | |
26.4 バッファーのファイル名 | バッファーファイル名は、どのファイルをvisitしているかを示す。 | |
26.5 バッファーの変更 | 保存が必要なら、バッファーは“変更されている(modified)”。 | |
26.6 バッファーの変更 Time | Determining whether the visited file was changed behind Emacs’s back. | |
26.7 読み取り専用のバッファー | 読み取り専用バッファーでのテキスト変更は許されない。 | |
26.8 バッファーリスト | すべての既存バッファーを閲覧する方法。 | |
26.9 バッファーの作成 | バッファーを作成する関数。 | |
26.10 バッファーのkill | 明示的にkillされるまで、バッファーは存在する。 | |
26.11 インダイレクトバッファー | インダイレクトバッファーは、他のバッファーとテキストを共有する。 | |
26.12 2つのバッファー間でのテキストの交換 | ||
26.13 バッファーのギャップ | バッファー内のギャップ。 | |
Windows | ||
27.1 Emacsウィンドウの基本概念 | ウィンドウ使用についての基本情報。 | |
27.2 ウィンドウとフレーム | ウィンドウとそれらが表示されるフレームとの関連。 | |
27.3 ウィンドウのサイズ | ウィンドウのサイズへのアクセス。 | |
27.4 ウィンドウのリサイズ | ウィンドウのサイズの変更。 | |
27.5 Preserving Window Sizes | Preserving the size of windows. | |
27.6 ウィンドウの分割 | 新たなウィンドウの作成。 | |
27.7 ウィンドウの削除 | フレームからのウィンドウの削除。 | |
27.8 ウィンドウの再結合 | ウィンドウの分割や削除時のフレームレイアウトの保存。 | |
27.9 ウィンドウの選択 | 選択されたウィンドウとは、編集を行っているウィンドウである。 | |
27.10 ウィンドウのサイクル順 | 既存のウィンドウ間の移動。 | |
27.11 バッファーとウィンドウ | それぞれのウィンドウは、バッファーのコンテンツを表示する。 | |
27.12 ウィンドウ内のバッファーへの切り替え | バッファー切り替えのための、より高レベルな関数。 | |
27.13 表示するウィンドウの選択 | バッファーを表示するウィンドウの選択方法。 | |
27.14 display-buffer にたいするアクション関数 | display-buffer 用のサブルーチン。
| |
27.15 バッファー表示の追加オプション | バッファー表示方法に影響する拡張オプション。 | |
27.16 ウィンドウのヒストリー | それぞれのウィンドウは、表示されていたバッファーを記憶する。 | |
27.17 専用のウィンドウ | 特定のウィンドウ内で他のバッファーの表示を無効にする。 | |
27.18 ウィンドウのquit | 以前に表示していたバッファーの状態をリストアする方法。 | |
27.19 ウィンドウとポイント | それぞれのウィンドウは、自身の位置とポイントをもつ。 | |
27.20 ウィンドウの開始位置と終了位置 | ウィンドウ内でスクリーン表示されるテキストを表すバッファー位置。 | |
27.21 テキスト的なスクロール | ウィンドウを通じたテキストの上下移動。 | |
27.22 割り合いによる垂直スクロール | ウィンドウ上のコンテンツの上下移動。 | |
27.23 水平スクロール | ウィンドウ上のコンテンツの横移動。 | |
27.24 座標とウィンドウ | 座標からウィンドウへの変換。 | |
27.25 ウィンドウの構成 | スクリーンの情報の保存とリストア。 | |
27.26 ウィンドウのパラメーター | ウィンドウへの追加情報の割り当て。 | |
27.27 ウィンドウのスクロールと変更のためのフック | スクロール、ウィンドウのサイズ変更、ある特定のしきい値を超えたときに行われる再表示、ウィンドウ設定の変更にたいするフック。 | |
Frames | ||
28.1 フレームの作成 | 追加のフレームの作成。 | |
28.2 複数の端末 | 異なる複数デバイス上での表示。 | |
28.3 Frame Geometry | Geometric properties of frames. | |
28.4 フレームのパラメーター | フレームのサイズ、位置、フォント等の制御。 | |
28.5 端末のパラメーター | 端末上のすべてのフレームにたいして一般的なパラメーター。 | |
28.6 フレームのタイトル | フレームタイトルの自動的な更新。 | |
28.7 フレームの削除 | 明示的に削除されるまでフレームは存続する。 | |
28.8 すべてのフレームを探す | すべての既存フレームを調べる方法。 | |
28.9 ミニバッファーとフレーム | フレームが使用するミニバッファーを見つける方法。 | |
28.10 入力のフォーカス | 選択されたフレームの指定。 | |
28.11 フレームの可視性 | フレームは可視、不可視、またはアイコン化されているかもしれない。 | |
28.12 フレームを前面や背面に移動する | フレームを前面に移動して他のウィンドウを隠し、背面に移動して他のウィンドウがフレームを隠す。 | |
28.13 フレーム構成 | すべてのフレームの状態の保存。 | |
28.14 マウスの追跡 | マウス移動時のイベントの取得。 | |
28.15 マウスの位置 | マウスの場所や移動を問い合わせる。 | |
28.16 ポップアップメニュー | ユーザーに選択させるためのメニューの表示。 | |
28.17 ダイアログボックス | yes/noを問い合わせるためのボックスの表示。 | |
28.18 ポインターの形状 | マウスポインターのシェイプの指定。 | |
28.19 ウィンドウシステムによる選択 | 他のXクライアントとのテキストの転送。 | |
28.20 ドラッグアンドドロップ | ドラッグアンドドロップの実装の内部。 | |
28.21 カラー名 | カラー名定義の取得。 | |
28.22 テキスト端末のカラー | テキスト端末のカラーの定義。 | |
28.23 Xリソース | サーバーからのリソース値の取得。 | |
28.24 ディスプレー機能のテスト | 端末の機能の判定。 | |
Frame Geometry | ||
28.3.1 Frame Layout | Basic layout of frames. | |
28.3.2 Frame Font | The default font of a frame and how to set it. | |
28.3.3 Size and Position | フレームのサイズと位置の変更。 | |
28.3.4 Implied Frame Resizing | Implied resizing of frames and how to prevent it. | |
Frame Parameters | ||
28.4.1 フレームパラメーターへのアクセス | フレームのパラメーターの変更方法。 | |
28.4.2 フレームの初期パラメーター | フレーム作成時に指定するフレームパラメーター。 | |
28.4.3 ウィンドウフレームパラメーター | ウィンドウシステムにたいするフレームパラメーターのリスト。 | |
28.4.4 ジオメトリー | ジオメトリー仕様の解析。 | |
Window Frame Parameters | ||
28.4.3.1 基本パラメーター | 基本的なパラメーター。 | |
28.4.3.2 位置のパラメーター | スクリーン上のフレームの位置。 | |
28.4.3.3 サイズのパラメーター | フレームのサイズ。 | |
28.4.3.4 レイアウトのパラメーター | フレームのパーツのサイズと、一部パーツの有効化と無効化。 | |
28.4.3.5 バッファーのパラメーター | 表示済みまたは表示されるべきバッファーはどれか。 | |
28.4.3.6 ウィンドウ管理のパラメーター | ウィンドウマネージャーとの対話。 | |
28.4.3.7 カーソルのパラメーター | カーソルの外見の制御。 | |
28.4.3.8 フォントとカラーのパラメーター | フレームテキストにたいするフォントとカラー。 | |
Positions | ||
29.1 ポイント | 編集タスクが行われる特別な位置。 | |
29.2 モーション | ポイントの変更。 | |
29.3 エクスカーション | 一時的な移動とバッファーの変更。 | |
29.4 ナローイング | バッファーの一部に編集を限定する。 | |
Motion | ||
29.2.1 文字単位の移動 | 文字単位での移動。 | |
29.2.2 単語単位の移動 | 単語単位での移動。 | |
29.2.3 バッファー終端への移動 | バッファー先頭または終端への移動。 | |
29.2.4 テキスト行単位の移動 | テキスト行単位での移動。 | |
29.2.5 スクリーン行単位の移動 | 表示される行単位での移動。 | |
29.2.6 バランスのとれたカッコを越えた移動 | リストやS式の解析による移動。 | |
29.2.7 文字のスキップ | 特定の集合に属す文字のスキップ。 | |
Markers | ||
30.1 マーカーの概要 | マーカー構成要素と再配置方法。 | |
30.2 マーカーのための述語 | オブジェクトがマーカーか否かのテスト。 | |
30.3 マーカーを作成する関数 | 空マーカーや特定箇所のマーカーの作成。 | |
30.4 マーカーからの情報 | マーカーのバッファーや文字位置を探す。 | |
30.5 Marker 挿入タイプ | マーカーが指す位置への挿入時にマーカーを再配置する2つの方法。 | |
30.6 マーカー位置の移動 | 新たなバッファーや位置にマーカーを移動する。 | |
30.7 マーク | How the mark is implemented with a marker. | |
30.8 リージョン | How to access the region. | |
Text | ||
31.1 ポイント周辺のテキストを調べる | ポイント付近のテキストを調べる。 | |
31.2 バッファーのコンテンツを調べる | 一般的な方法によってテキストを調べる。 | |
31.3 テキストの比較 | バッファーの部分文字列を比較する。 | |
31.4 テキストの挿入 | バッファーへの新たなテキストの追加。 | |
31.5 ユーザーレベルの挿入コマンド | テキスト挿入のためのユーザーレベルコマンド。 | |
31.6 テキストの削除 | バッファーからテキストを削除する。 | |
31.7 ユーザーレベルの削除コマンド | テキスト削除のためのユーザーレベルコマンド。 | |
31.8 killリング | テキスト削除時にユーザーのためにそれを保存する場所。 | |
31.9 アンドゥ | バッファーのテキストにたいする変更の取り消し。 | |
31.10 アンドゥリストの保守 | undo情報の有効と無効。情報をどれだけ保持するか制御する方法。 | |
31.11 fill | 明示的にフィルを行う関数。 | |
31.12 fillのマージン | フィルコマンドにたいしてマージンを指定する方法。 | |
31.13 Adaptive Fillモード | コンテキストからフィルプレフィクスを選択するAdaptive | |
31.14 オートfill | 行ブレークにたいするauto-fillの実装方法。 | |
31.15 テキストのソート | バッファーの一部をソートする関数。 | |
31.16 列を数える | 水平位置の計算とその使用方法。 | |
31.17 インデント | インデントの挿入や調整のための関数。 | |
31.18 大文字小文字の変更 | バッファーの一部にたいするcase変換。 | |
31.19 テキストのプロパティ | テキスト文字にたいするLispプロパティリストの追加。 | |
31.20 文字コードの置き換え | 与ええられた文字の出現箇所を置換する。 | |
31.21 レジスター | レジスターの実装方法。レジスターに格納されたテキストや位置にアクセスする。 | |
31.22 テキストの交換 | バッファーの2つの部分を交換する。 | |
31.23 圧縮されたデータの処理 | 圧縮データの扱い。 | |
31.24 Base 64エンコーディング | Base64エンコーディングとの変換。 | |
31.25 チェックサムとハッシュ | 暗号ハッシュの計算。 | |
31.26 HTMLとXMLの解析 | HTMLおよびXMLの解析。 | |
31.27 グループのアトミックな変更 | Installing several buffer changes atomically. | |
31.28 フックの変更 | テキスト変更時に実行する関数の指定。 | |
The Kill Ring | ||
31.8.1 killリングの概念 | killリング内のテキストがどのように見えるか。 | |
31.8.2 killリングのための関数 | テキストをkillする関数。 | |
31.8.3 yank | yankが行われる方法。 | |
31.8.4 yankのための関数 | killリングにアクセスするコマンド。 | |
31.8.5 低レベルのkillリング | killリングアクセス用の関数および変数。 | |
31.8.6 killリングの内部 | killリングのデータを保持する変数。 | |
Indentation | ||
31.17.1 インデント用のプリミティブ | インデントのカウントと挿入に使用される関数。 | |
31.17.2 メジャーモードが制御するインデント | 異なるモード用にインデントをカスタマイズする。 | |
31.17.3 リージョン全体のインデント | リージョン内すべての行のインデント。 | |
31.17.4 前行に相対的なインデント | 前の行にもとづきカレント行をインデントする。 | |
31.17.5 Adjustable Tab Stops | 調整可能なタイプライター形式のタブストップ。 | |
31.17.6 インデントにもとづくモーションコマンド | 最初の非ブランク文字への移動。 | |
Text Properties | ||
31.19.1 テキストプロパティを調べる | 単一の文字のプロパティを調べる。 | |
31.19.2 テキストプロパティの変更 | テキスト範囲のプロパティをセットする。 | |
31.19.3 テキストプロパティの検索関数 | プロパティが値を変更する場所の検索。 | |
31.19.4 特殊な意味をもつプロパティ | 特別な意味をもつ特定のプロパティ。 | |
31.19.5 Formatted Text Properties | テキストのフォーマットを表すプロパティ。 | |
31.19.6 テキストプロパティの粘着性 | 挿入されたテキストが隣接するテキストからプロパティを取得する方法。 | |
31.19.7 テキストプロパティのlazyな計算 | テキストが調べられる際のみ、ものぐさな方法でテキストプロパティを計算する。 | |
31.19.8 クリック可能なテキストの定義 | テキストプロパティを使用して、テキストリージョンがクリック時に何か行うようにする。 | |
31.19.9 フィールドの定義と使用 | バッファー内にフィールドを定義するfield プロパティ。
| |
31.19.10 なぜテキストプロパティはインターバルではないのか | テキストプロパティがLispから可視なテキスト間隔をもたない理由。 | |
Parsing HTML and XML | ||
31.26.1 Document Object Model | Access, manipulate and search the DOM. | |
Non-ASCII Characters | ||
32.1 テキストの表現方法 | Emacsがテキストを表す方法。 | |
32.2 マルチバイト文字の無効化 | マルチバイト使用を制御する。 | |
32.3 テキスト表現の変換 | ユニバイトとマルチバイトの相互変換。 | |
32.4 表現の選択 | バイトシーケンスをユニバイトやマルチバイトとして扱う。 | |
32.5 文字コード | ユニバイトやマルチバイトが個々の文字のコードと関わる方法。 | |
32.6 文字のプロパティ | 文字の挙動と処理を定義する文字属性。 | |
32.7 文字セット | 利用可能な文字コード空間はさまざまな文字セットに分割される。 | |
32.8 文字セットのスキャン | バッファーで使用されている文字セットは? | |
32.9 文字の変換 | 変換に使用される変換テーブル。 | |
32.10 コーディングシステム | コーディングシステムはファイル保存のための変換である。 | |
32.11 入力メソッド | 入力メソッドによりユーザーは特別なキーボードなしで非ASCII文字を入力できる。 | |
32.12 locale | POSIX localeとの対話。 | |
Coding Systems | ||
32.10.1 コーディングシステムの基本概念 | 基本的な概念。 | |
32.10.2 エンコーディングとI/O | ファイル入出力関数がコーディングシステムを扱う方法。 | |
32.10.3 Lispでのコーディングシステム | コーディングシステム名を処理する関数。 | |
32.10.4 ユーザー選択のコーディングシステム | ユーザーにコーディングシステムの選択を求める。 | |
32.10.5 デフォルトのコーディングシステム | デフォルトの選択の制御。 | |
32.10.6 単一の操作にたいするコーディングシステムの指定 | 単一ファイル処理にたいして特定のコーディングシステムを要求する。 | |
32.10.7 明示的なエンコードとデコード | 入出力を伴わないテキストのエンコードおよびデコード。 | |
32.10.8 端末I/Oのエンコーディング | 端末入出力にたいするエンコーディングの使用。 | |
Searching and Matching | ||
33.1 文字列の検索 | 正確なマッチの検索。 | |
33.2 検索と大文字小文字 | case-independentまたはcase-significantな検索。 | |
33.3 正規表現 | 文字列クラスの記述。 | |
33.4 正規表現の検索 | regexpにたいするマッチの検索。 | |
33.5 POSIX正規表現の検索 | 最長マッチにたいするPOSIXスタイルのマッチ。 | |
33.6 マッチデータ | 文字列またはregexp検索後に、テキストがマッチした部分を見つける。 | |
33.7 検索と置換 | 検索と置換を繰り返すコマンド。 | |
33.8 編集で使用される標準的な正規表現 | センテンスやページ等を探すために有用なregexp。 | |
Regular Expressions | ||
33.3.1 正規表現の構文 | 正規表現の記述ルール。 | |
33.3.2 正規表現の複雑な例 | 正規表現構文の説明。 | |
33.3.3 正規表現の関数 | 正規表現を操作する関数。 | |
Syntax of Regular Expressions | ||
33.3.1.1 正規表現内の特殊文字 | 正規表現内のスペシャル文字。 | |
33.3.1.2 文字クラス | 正規表現内で使用される文字クラス。 | |
33.3.1.3 正規表現内のバッククラッシュ構造 | 正規表現内のバックスラッシュシーケンス。 | |
The Match Data | ||
33.6.1 マッチしたテキストの置換 | マッチされた部分文字列の置換。 | |
33.6.2 単純なマッチデータへのアクセス | 特定の部分式開始箇所のような、マッチデータの単一アイテムへのアクセス。 | |
33.6.3 マッチデータ全体へのアクセス | リストとしてマッチデータ全体に一度にアクセスする。 | |
33.6.4 マッチデータの保存とリストア | ||
Syntax Tables | ||
34.1 構文テーブルの概念 | 構文テーブルの基本的概念。 | |
34.2 構文記述子 | 文字がクラス分けされる方法。 | |
34.3 構文テーブルの関数 | 構文テーブルを作成、調査、変更する方法。 | |
34.4 構文プロパティ | テキストプロパティによる構文テーブルのオーバーライド。 | |
34.5 モーションと構文 | 特定の構文による文字間の移動。 | |
34.6 式のパース | 構文テーブル使用によるバランスのとれた式の解析。 | |
34.7 構文テーブルの内部 | 構文テーブルの情報が格納される方法。 | |
34.8 カテゴリー | 文字構文をクラス分けする別の手段。 | |
Syntax Descriptors | ||
34.2.1 構文クラスのテーブル | ||
34.2.2 構文フラグ | 各文字が所有できる追加のフラグ。 | |
Parsing Expressions | ||
34.6.1 パースにもとづくモーションコマンド | パースにより機能する移動関数。 | |
34.6.2 ある位置のパース状態を調べる | ある位置の構文状態を判断する。 | |
34.6.3 パーサー状態 | Emacsが構文状態を表す方法。 | |
34.6.4 低レベルのパース | 指定されたリージョンを横断するパース。 | |
34.6.5 パースを制御するためのパラメーター | パースに影響するパラメーター。 | |
Abbrevs and Abbrev Expansion | ||
35.1 abbrevテーブル | abbrevテーブルの作成と操作。 | |
35.2 abbrevの定義 | 略語の指定とそれらの展開。 | |
35.3 ファイルへのabbrevの保存 | ||
35.4 略語の照会と展開 | 展開の制御と展開サブルーチン。 | |
35.5 標準的なabbrevテーブル | 種々メジャーモードに使用されるabbrevテーブル。 | |
35.6 abbrevプロパティー | abbrevプロパティの読み取りとセットを行う方法。どのプロパティが何の効果をもつか。 | |
35.7 abbrevテーブルのプロパティー | abbrevテーブルプロパティの読み取りとセットを行う方法。どのプロパティが効果をもつか。 | |
Processes | ||
36.1 サブプロセスを作成する関数 | サブプロセスを開始する関数。 | |
36.2 shell引数 | shellに渡すために引数をクォートする。 | |
36.3 同期プロセスの作成 | 同期サブプロセス使用の詳細。 | |
36.4 非同期プロセスの作成 | 非同期サブプロセスの起動。 | |
36.5 プロセスの削除 | 非同期サブプロセスの削除。 | |
36.6 プロセスの情報 | 実行状態および他の属性へのアクセス。 | |
36.7 プロセスへの入力の送信 | 非同期サブプロセスへの入力の送信。 | |
36.8 プロセスへのシグナルの送信 | 非同期サブプロセスの停止、継続、割り込み。 | |
36.9 プロセスからの出力の受信 | 非同期サブプロセスからの出力の収集。 | |
36.10 センチネル: プロセス状態の変更の検知 | プロセスの実行状態変更時に実行されるセンチネル。 | |
36.11 exit前の問い合わせ | exitによりプロセスがkillされる場合に問い合わせるかどうか。 | |
36.12 別のプセスへのアクセス | そのシステム上で実行中の別プロセスへのアクセス。 | |
36.13 トランザクションキュー | サブプロセスとのトランザクションベースのコミュニケション。 | |
36.14 ネットワーク接続 | ネットワーク接続のopen。 | |
36.15 ネットワークサーバー | Emacsによるネット接続のacceptを可能にするネットワークサーバー。 | |
36.16 データグラム | UDPネットワーク接続。 | |
36.17 低レベルのネットワークアクセス | 接続およびサーバーを作成するための、より低レベルだがより汎用的な関数。 | |
36.18 その他のネットワーク機能 | ネット接続用の追加の関連関数。 | |
36.19 シリアルポートとの対話 | シリアルポートでのやり取り。 | |
36.20 バイト配列のpackとunpack | bindatを使用したバイナリーデータのpackとunpack。 | |
Receiving Output from Processes | ||
36.9.1 プロセスのバッファー | デフォルトでは、出力はバッファーに送信される。 | |
36.9.2 プロセスのフィルター関数 | フィルター関数はプロセスからの出力を受け取る。 | |
36.9.3 プロセス出力のデコード | フィルターはユニバイトおよびマルチバイトの文字列を取得できる。 | |
36.9.4 プロセスからの出力を受け入れる | プロセスの出力到着まで待機する方法。 | |
Low-Level Network Access | ||
36.17.1 make-network-process | make-network-process ’の使用。
| |
36.17.2 ネットワークのオプション | 更なるネットワーク接続の制御。 | |
36.17.3 ネットワーク機能の可用性のテスト | 使用中マシン上で動作するネットワーク機能を判断する。 | |
Packing and Unpacking Byte Arrays | ||
36.20.1 データレイアウトの記述 | ||
36.20.2 バイトのunpackとpackのための関数 | unpack化とpack化を行う。 | |
36.20.3 バイトのunpackとpackの例 | bindat.elが行えることのサンプル。 | |
Emacs Display | ||
37.1 スクリーンのリフレッシュ | スクリーン上にあるすべてのもののクリアーと再描画。 | |
37.2 強制的な再表示 | 再描画の強制。 | |
37.3 切り詰め | 長いテキストの折り畳みと折り返し。 | |
37.4 エコーエリア | スクリーン最下部へのメッセージ表示。 | |
37.5 警告のレポート | ユーザーへの警告メッセージの表示。 | |
37.6 不可視のテキスト | バッファーのテキストの一部を隠す。 | |
37.7 選択的な表示 | バッファーのテキストの一部を隠す(旧来の方式)。 | |
37.8 一時的な表示 | 自動的に消える表示。 | |
37.9 オーバーレイ | オーバーレイを使用したバッファーの一部のハイライト。 | |
37.10 表示されるテキストのサイズ | 表示されたテキストの大きさ。 | |
37.11 行の高さ | 行の高さの制御。 | |
37.12 フェイス | テキスト文字のグラフィカルスタイル(フォント、カラー等)を定義するフェイス。 | |
37.13 フリンジ | ウィンドウフリンジの制御。 | |
37.14 スクロールバー | Controlling scroll bars. | |
37.15 ウィンドウディバイダー | ウィンドウを視覚的に区別する。 | |
37.16 display プロパティ | 特別な表示機能の有効化。 | |
37.17 イメージ | Emacsバッファー内でのイメージ表示。 | |
37.19 ボタン | Emacsバッファー内へのイメージ表示クリック可能ボタン追加。 | |
37.20 抽象的なディスプレー | オブジェクトコレクション用のEmacsウィジェット。 | |
37.21 カッコの点滅 | Emacsがマッチする開カッコを表示する方法。 | |
37.22 文字の表示 | Emacsがマッチする個々の文字を表示する方法。 | |
37.23 ビープ | ユーザーへの可聴シグナル。 | |
37.24 ウィンドウシステム | どのウィンドウシステムが使用されているか。 | |
37.25 Tooltips | Tooltip display in Emacs. | |
37.26 双方向テキストの表示 | アラビア語やペルシア語のような、双方向スクリプトの表示。 | |
The Echo Area | ||
37.4.1 エコーエリアへのメッセージの表示 | エコーエリア内に明示的にテキストを表示する。 | |
37.4.2 処理の進捗レポート | 長時間の処理の進行状況をユーザーに知らせる。 | |
37.4.3 *Messages*へのメッセージのロギング | ユーザー用にログされるエコーエリアメッセージ。 | |
37.4.4 エコーエリアのカスタマイズ | エコーエリアの制御。 | |
Reporting Warnings | ||
37.5.1 警告の基礎 | 警告の概念と、それらを報告するための関数。 | |
37.5.2 警告のための変数 | プログラムが警告をカスタマイズするためにバインドする変数。 | |
37.5.3 警告のためのオプション | ユーザーが警告の表示を制御するためにセットする変数。 | |
37.5.4 遅延された警告 | コマンド終了まで警告を延期する。 | |
Overlays | ||
37.9.1 オーバーレイの管理 | オーバーレイの作成と変更。 | |
37.9.2 オーバーレイのプロパティ | プロパティ読み取りおよびセットの方法。どのプロパティがスクリーン表示に何を行うか。 | |
37.9.3 オーバーレイにたいする検索 | ||
Faces | ||
37.12.1 フェイスの属性 | フェイスとは? | |
37.12.2 フェイスの定義 | フェイスを定義する方法。 | |
37.12.3 フェイス属性のための関数 | フェイス属性の確認およびセットを行う関数。 | |
37.12.4 フェイスの表示 | ある文字にたいして指定されたフェイスをEmacsが組み合わせる方法。 | |
37.12.5 フェイスのリマップ | フェイスを別の定義にリマップする。 | |
37.12.6 フェイスを処理するための関数 | フェイスの定義、および確認する方法。 | |
37.12.7 フェイスの自動割り当て | 自動的にフェイスを割り当てるフック。 | |
37.12.8 基本的なフェイス | デフォルトで定義されるフェイス。 | |
37.12.9 フォントの選択 | あるフェイスに最適なフォントを見つける。 | |
37.12.10 フォントの照会 | 利用可能なフォント名とそれらの情報の照会。 | |
37.12.11 フォントセット | フォントセット、それは文字セットの範囲を処理するフォントコレクションである。 | |
37.12.12 低レベルのフォント表現 | 文字表示フォントのLisp表現。 | |
Fringes | ||
37.13.1 フリンジのサイズと位置 | ウィンドウフリンジを置く場所を指定する。 | |
37.13.2 フリンジのインジケーター | ウィンドウフリンジ内にインジケーターアイコンを表示する。 | |
37.13.3 フリンジのカーソルFringe Cursors | 右フリンジ内にカーソルを表示する。 | |
37.13.4 フリンジのビットマップ | フリンジインジケーターにたいしてビットマップを指定する。 | |
37.13.5 フリンジビットマップのカスタマイズ | フリンジ内で使用する独自ビットマップの指定。 | |
37.13.6 オーバーレイ矢印 | 位置を示す矢印の表示。 | |
The | ||
37.16.1 テキストを置換するディスプレー仕様 | テキストを置換するディスプレイspec。 | |
37.16.2 スペースの指定 | 指定された幅に1つのスペースを表示する。 | |
37.16.3 スペースにたいするピクセル指定 | ピクセル単位でスペースの幅または高さを指定する。 | |
37.16.4 その他のディスプレー仕様 | イメージの表示。高さ、スペーシング、その他のテキストプロパティの調整。 | |
37.16.5 マージン内への表示 | メインテキスト側面へのテキストまたはイメージの表示。 | |
Images | ||
37.17.1 イメージのフォーマット | サポートされるイメージフォーマット。 | |
37.17.2 イメージのディスクリプタ | :display 内で使用されるイメージの指定方法。
| |
37.17.3 XBMイメージ | XBMフォーマット用の特別な機能。 | |
37.17.4 XPMイメージ | XPMフォーマット用の特別な機能。 | |
37.17.5 PostScriptイメージ | PostScriptフォーマット用の特別な機能。 | |
37.17.6 ImageMagickイメージ | ImageMagickを通じて利用できる特別な機能。 | |
37.17.7 その他のイメージタイプ | サポートされるその他さまざまなフォーマット。 | |
37.17.8 イメージの定義 | 後で使用するためにイメージを定義する便利な方法。 | |
37.17.9 イメージの表示 | 一度定義されたイメージを表示するための便利な方法。 | |
37.17.10 マルチフレームのイメージ | 1つ以上のフレームを含むイメージ。 | |
37.17.11 イメージキャッシュ | イメージ表示の内部的メカニズム。 | |
Buttons | ||
37.19.1 ボタンのプロパティ | 特別な意味をもつボタンプロパティ。 | |
37.19.2 ボタンのタイプ | ボタンのクラスにたいして一般的なプロパティを定義する。 | |
37.19.3 ボタンの作成 | Emacsバッファーへのボタンの追加。 | |
37.19.4 ボタンの操作 | ボタンプロパティの取得とセット。 | |
37.19.5 ボタンのためのバッファーコマンド | ボタンにたいするバッファー規模のコマンドとバインディング。 | |
Abstract Display | ||
37.20.1 抽象ディスプレーの関数 | Ewocパッケージ内の関数。 | |
37.20.2 抽象ディスプレーの例 | Ewocの使用例。 | |
Character Display | ||
37.22.1 通常の表示の慣習 | 文字の表示にたいする通常の慣習。 | |
37.22.2 ディスプレーテーブル | ディスプレイテーブルの構成要素。 | |
37.22.3 アクティブなディスプレーテーブル | 使用するディスプレイテーブルをEmacsが選択する方法。 | |
37.22.4 グリフ | グリフの定義方法とグリフの意味。 | |
37.22.5 グリフ文字の表示 | グリフなしの文字の描画方法。 | |
Operating System Interface | ||
38.1 Emacsのスタートアップ | Customizing Emacs startup processing. | |
38.2 Emacsからの脱出 | (永久または一時的に)exitが機能する方法。 | |
38.3 オペレーティングシステムの環境 | システム名と種類の区別。 | |
38.4 ユーザーの識別 | そのユーザーの名前とユーザーIDを調べる。 | |
38.5 時刻 | カレント時刻の取得。 | |
38.7 時刻の変換 | 時刻の数値形式からカレンダーデータへの変換と逆変換。 | |
38.8 時刻のパースとフォーマット | 時刻の数値形式からテキストへの変換と逆変換。 | |
38.9 プロセッサーの実行時間 | Emacsによる実行時間の取得。 | |
38.10 時間の計算 | 時間の加減算、その他。 | |
38.11 遅延実行のためのタイマー | 特定時刻に関数を呼び出すためにターマーをセットする。 | |
38.12 アイドルタイマー | Emacsが特定の時間の間アイドル時に関数を呼び出すためにタイマーをセットする。 | |
38.13 端末の入力 | 端末入力へのアクセスと記録。 | |
38.14 端末の出力 | 端末出力の制御と記録。 | |
38.15 サウンドの出力 | コンピューターのスピーカーでのサウンド再生。 | |
38.16 X11キーシンボルの処理 | Xウィンドウにたいするキーシンボルの操作。 | |
38.17 batchモード | 端末との対話なしでEmacsを実行する。 | |
38.18 セッションマネージャー | Xセッション管理の保存とリストア。 | |
38.19 デスクトップ通知 | ||
38.20 ファイル変更による通知 | ファイル通知。 | |
38.21 動的にロードされるライブラリー | サポートライブラリーのオンデマンドロード。 | |
38.22 Security Considerations | Running Emacs in an unfriendly environment. | |
Emacsのスタートアップ | ||
38.1.1 要約: スタートアップ時のアクション順序 | スタートアップ時にEmacsが行うアクションの順序。 | |
38.1.2 initファイル | initファイル読み込みの詳細。 | |
38.1.3 端末固有の初期化 | 端末固有のLispファイルの読み込み方法。 | |
38.1.4 コマンドライン引数 | コマンドライン引数の処理とカスタマイズの方法。 | |
Getting Out of Emacs | ||
38.2.1 Emacsのkill | Emacsからの不可逆的なexit。 | |
38.2.2 Emacsのサスペンド | Emacsからの可逆的なexit。 | |
Terminal Input | ||
38.13.1 入力のモード | 入力の処理方法にたいするオプション。 | |
38.13.2 入力の記録 | 直近またはすべての入力イベントのヒストリーの保存。 | |
Preparing Lisp code for distribution | ||
39.1 パッケージ化の基礎 | Emacs Lispパッケージの基本的概念。 | |
39.2 単純なパッケージ | 単一.elファイルをパッケージする方法。 | |
39.3 複数ファイルのパッケージ | 複数ファイルをパッケージする方法。 | |
39.4 パッケージアーカイブの作成と保守 | パッケージアーカイブの保守。 | |
Tips and Conventions | ||
D.1 Emacs Lispコーディングの慣習 | 明快で堅牢なプログラムにたいする慣習。 | |
D.2 キーバインディングの慣習 | どのキーをどのプログラムにバインドすべきか。 | |
D.3 Emacsプログラミングのヒント | Emacsコードを円滑にEmacsに適合させる。 | |
D.4 コンパイル済みコードを高速化ためのヒント | コンパイル済みコードの実行を高速にする。 | |
D.5 コンパイラー警告を回避するためのヒント | コンパイラー警告をオフにする。 | |
D.6 ドキュメント文字列のヒント | 読みやすいドキュメント文字列の記述。 | |
D.7 コメント記述のヒント | コメント記述の慣習。 | |
D.8 Emacsライブラリーのヘッダーの慣習 | ライブラリーパッケージにたいする標準的なヘッダー。 | |
GNU Emacs Internals | ||
E.1 Emacsのビルド | ダンプ済みEmacsの作成方法。 | |
E.2 純粋ストレージ | その場かぎりの事前ロードされたLisp関数を共有する。 | |
E.3 ガーベージコレクション | Lispオブジェクトの使用されないスペースの回収。 | |
E.4 Stack-allocated Objects | Temporary conses and strings on C stack. | |
E.5 メモリー使用量 | これまでに作成されたLispオブジェクトの総サイズの情報。 | |
E.6 C方言 | What C variant Emacs is written in. | |
E.7 Emacsプリミティブの記述 | Emacs用にCコードを記述する。 | |
E.8 オブジェクトの内部 | バッファー、ウィンドウ、プロセスのデーラフォーマット。 | |
E.9 Cの整数型 | How C integer types are used inside Emacs. | |
Object Internals | ||
E.8.1 バッファーの内部 | バッファー構造体の構成子。 | |
E.8.2 ウィンドウの内部 | ウィンドウ構造体の構成子。 | |
E.8.3 プロセスの内部 | プロセス構造体の構成子。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU Emacsテキストエディターのほとんどの部分は、Emacs Lispと呼ばれるプログラミング言語で記述されています。新しいコードをEmacs Lispで記述して、このエディターの拡張としてインストールできます。しかしEmacs Lispは、単なる拡張言語を越える言語であり、それ自体で完全なコンピュータープログラミング言語です。他のプログラミング言語で行なうすべてのことに、この言語を使用できます。
Emacs Lispはエディターの中で使用するようにデザインされているので、テキストのスキャンやパースのための特別な機能をもち、同様にファイル、バッファー、ディスプレー、サブプロセスを処理する機能をもちます。Emacs Lispは編集機能と密に統合されています。つまり編集コマンドはLispプログラムから簡単に呼び出せる関数で、カスタマイズのためのパラメーターは普通のLisp変数です。
このマニュアルはEmacs Lispの完全な記述を試みます。初心者のためのEmacs Lispのイントロダクションは、Free Software Foundationからも出版されている、Bob ChassellのAn Introduction to Emacs Lisp Programmingを参照してください。このマニュアルは、Emacsを使用した編集に熟知していることを前提としています。これの基本的な情報については、The GNU Emacs Manualを参照してください。
おおまかに言うと、前の方のチャプターでは多くのプログラミング言語の機能にたいして、Emacs Lispでの対応する機能を説明し、後の方のチャプターではEmacs Lispに特異な機能や、編集に特化した関連する機能を説明します。
これは Emacs 25.1に対応したGNU Emacs Lisp Reference Manualです。
1.1 注意事項 | 不備な点と、助けを求める方法。 | |
1.2 Lispの歴史 | Maclispを後継するEmacs Lisp。 | |
1.3 表記について | このマニュアルのフォーマット方法。 | |
1.4 バージョンの情報 | 実行中のEmacsのバージョンは? | |
1.5 謝辞 | このマニュアルの著者、編集者、スポンサー。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このマニュアルは幾多のドラフトを経てきました。ほとんど完璧ではありますが、不備がないとも言えません。(ほとんどの特定のモードのように)それらが副次的であるとか、まだ記述されていないという理由により、カバーされていないトピックもあります。わたしたちがそれらを完璧に扱うことはできないので、いくつかの部分は意図的に省略しました。
このマニュアルは、それがカバーしている事柄については完全に正しくあるべきあり、故に特定の説明テキスト、チャプターやセクションの順番にたいしての批判にオープンであるべきです。判りにくかったり、このマニュアルでカバーされていない何かを学ぶためにソースを見たり実地から学ぶ必要があるなら、このマニュアルはおそらく訂正されるべきなのかもしれません。どうかわたしたちにそれを教えてください。
このマニュアルを使用するときは、間違いを見つけたらすぐに訂正を送ってください。関数または関数グループの単純な現実例を考えたときは、ぜひそれを記述して送ってください。それが妥当ならコメントでノード名と関数名や変数名を参照してください。あなたが訂正を求めるエディションのバージョンも示してください。
M-x report-emacs-bugを使用して、コメントや訂正を送ってください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lisp(LISt Processing language: リスト処理言語)は、MIT(Massachusetts Institute of Technology: マサチューセッツ工科大学)で、AI(artificial intelligence: 人工知能)の研究のために、1950年代末に最初に開発されました。Lisp言語の強力なパワーは、編集コマンドの記述のような、他の目的にも適っています。
長年の間に何ダースものLisp実装が構築されてきて、それらのそれぞれに特異な点があります。これらの多くは、1960年代にMITのProject MACで記述された、Maclispに影響を受けています。最終的に、Maclisp後裔の実装者は共同して、Common Lispと呼ばれる標準のLispシステムを開発しました。その間にMITのGerry SussmanとGuy Steeleにより、簡潔ながらとても強力なLisp方言の、Schemeが開発されました。
GNU Emacs LispはMaclispから多く、Common Lispから少し影響を受けています。Common Lispを知っている場合、多くの類似点に気づくでしょう。しかしCommon Lispの多くの機能は、GNU Emacsが要求するメモリー量を削減するために、省略または単純化されています。ときには劇的に単純化されているために、Common Lispユーザーは混乱するかもしれません。わたしたちは時折GNU Emacs LispがCommon Lispと異なるか示すでしょう。Common Lispを知らない場合、それについて心配する必要はありません。このマニュアルは、それ自体で自己完結しています。
cl-libライブラリーを通じて、Common Lispをかなりエミュレートできます。Overview in Common Lisp Extensionsを参照してください。
Emacs LispはSchemeの影響は受けていません。しかしGNUプロジェクトにはGuileと呼ばれるScheme実装があります。拡張が必要な新しいGNUソフトウェアーでは、Guileを使用します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは、このマニュアルで使用する表記規約を説明します。あなたはこのセクションをスキップして、後から参照したいと思うかもしれません。
1.3.1 用語について | このマニュアルで使用する用語の説明。 | |
1.3.2 nil とt | シンボルnil とt の使用方法。
| |
1.3.3 評価の表記 | 評価の例で使用するフォーマット。 | |
1.3.4 プリントの表記 | テキストのプリント例で使用するフォーマット。 | |
1.3.5 エラーメッセージ | エラー例で使用するフォーマット。 | |
1.3.6 バッファーテキストの表記 | 例のバッファー内容で使用するフォーマット。 | |
1.3.7 説明のフォーマット | 関数や変数などの説明にたいする表記。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このマニュアルでは、“Lispリーダー”および“Lispプリンター”という用語で、Lispのテキスト表現を実際のLispオブジェクトに変換したり、その逆を行なうLispルーチンを参照します。詳細については、プリント表現と読み取り構文を参照してください。あなた、つまりこのマニュアルを読んでいる人のことはプログラマーと考えて“あなた”と呼びます。“ユーザー”とは、あなたの記述したものも含めて、Lispプログラムを使用する人を指します。
Lispコードの例は、(list 1 2 3)
のようなフォーマットです。メタ構文変数(metasyntactic
variables)を表す名前や、説明されている関数の引数名前は、first-numberのようにフォーマットされています。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
nil
とt
Emacs
Lispでは、シンボルnil
には3つの異なる意味があります。1つ目は‘nil’という名前のシンボル、2つ目は論理値のfalse、3つ目は空リスト
— つまり要素が0のリストです。変数として使用した場合、nil
は常に値nil
をもちます。
Lispリーダーに関する限り、‘()’と‘nil’は同一です。これらは同じオブジェクト、つまりシンボルnil
を意味します。このシンボルを異なる方法で記述するのは、完全に人間の読み手を意図したものです。Lispリーダーが‘()’か‘nil’のどちらかを読み取った後は、プログラマーが実際にどちらの表現で記述したかを判断する方法はありません。
このマニュアルでは、空リストを意味することを強調したいときは()
と記述し、論理値のfalseを意味することを強調したいときはnil
と記述します。この慣習はLispプログラムで使用してもよいでしょう。
(cons 'foo ()) ; 空リストを強調 (setq foo-flag nil) ; 論理値のfalseを強調
論理値が期待されているコンテキストでは、非nil
はtrueと判断されます。しかし論理値のtrueを表す好ましい方法はt
です。trueを表す値を選択する必要があり、他に選択の根拠がない場合はt
を使用してください。シンボルt
は、常に値t
をもちます。
Emacs
Lispでのnil
とt
は、常に自分自身を評価する特別なシンボルです。そのためプログラムでこれらを定数として使用する場合、クォートする必要はありません。これらの値の変更を試みると、結果はsetting-constant
エラーとなります。Variables that Never Changeを参照してください。
objectが2つの正規のブーリーン値(t
かnil
)のいずれかなら、非nil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
評価できるLisp式のことをフォーム(form)と呼びます。フォームの評価により、これは結果として常にLispオブジェクトを生成します。このマニュアルの例では、これを‘⇒’で表します:
(car '(1 2)) ⇒ 1
これは“(car '(1 2))
を評価すると、1になる”と読むことができます。
フォームがマクロ呼び出しの場合、それは評価されるための新たなLispフォームに展開されます。展開された結果は‘→’で表します。わたしたちは展開されたフォームの評価し結果を示すこともあれば、示さない場合もあります。
(third '(a b c)) → (car (cdr (cdr '(a b c)))) ⇒ c
1つのフォームを説明するために、同じ結果を生成する別のフォームを示すこともあります。完全に等価な2つのフォームは、‘≡’で表します。
(make-sparse-keymap) ≡ (list 'keymap)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このマニュアルの例の多くは、それらが評価されるときにテキストをプリントします。(*scratch*バッファーのような)Lisp
Interactionバッファーでコード例を実行する場合、プリントされるテキストはそのバッファーに挿入されます。(関数eval-region
での評価のように)他の方法でコード例を実行する場合、プリントされるテキストはエコーエリアに表示されます。
このマニュアルの例はプリントされるテキストがどこに出力されるかに関わらず、それを‘-|’で表します。フォームを評価することにより戻される値は、‘⇒’とともに後続の行で示します。
(progn (prin1 'foo) (princ "\n") (prin1 'bar)) -| foo -| bar ⇒ bar
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
エラーをシグナルする例もあります。これは通常、エコーエリアにエラーメッセージを表示します。エラーメッセージの行は‘error→’で始まります。‘error→’自体は、エコーエリアに表示されないことに注意してください。
(+ 23 'x) error→ Wrong type argument: number-or-marker-p, x
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファー内容の変更を説明する例もあます。それらの例では、そのテキストのbefore(以前)とafter(以後)のバージョンを示します。それらの例では、バッファー内容の該当する部分を、ダッシュを用いた2行の破線(バッファー名を含む)で示します。さらに、‘∗’はポイントの位置を表します(もちろんポイントのシンボルはバッファーのテキストの一部ではなく、ポイントが現在配されている2つの文字の間の位置を表す)。
---------- Buffer: foo ---------- This is the ∗contents of foo. ---------- Buffer: foo ---------- (insert "changed ") ⇒ nil ---------- Buffer: foo ---------- This is the changed ∗contents of foo. ---------- Buffer: foo ----------
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このマニュアルでは関数(function)、変数(variable)、コマンド(command)、ユーザーオプション(user option)、スペシャルフォーム(special form)を、統一されたフォーマットで記述します。記述の最初の行には、そのアイテムの名前と、もしあれば引数(argument)が続きます。 そのアイテムの属するカテゴリー(function、variableなど)は、行の先頭に表示します。 それ以降の行は説明行で、例を含む場合もあります。
1.3.7.1 関数の説明例 | 架空の関数foo にたいする記述例。
| |
1.3.7.2 変数の説明例 | 架空の変数electric-future-map にたいする記述例。
|
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
関数の記述では、関数の名前が最初に記述されます。同じ行に引数の名前のリストが続きます。引数の値を参照するために、引数の名前は記述の本文にも使用されます。
引数リストの中にキーワード&optional
がある場合、その後の引数が省略可能であることを示します(省略された引数のデフォルトはnil
)。その関数を呼び出すときは、&optional
を記述しないでください。
キーワード&rest
(これの後には1つの引数名を続けなければならない)は、その後に任意の引数を続けることができることを表します。&rest
の後に記述された引数名の値には、その関数に渡された残りのすべての引数がリストとしてセットされます。この関数を呼び出すときは、&rest
を記述しないでください。
以下はfoo
という架空の関数(function)の説明です:
関数foo
はinteger2からinteger1を減じてから、その結果に残りすべての引数を加える。integer2が与えられなかった場合、デフォルトして数値19が使用される。
(foo 1 5 3 9) ⇒ 16 (foo 5) ⇒ 14
より一般的には、
(foo w x y…) ≡ (+ (- x w) y…)
慣例として引数の名前には、(たとえばinteger、integer1、bufferのような)期待されるタイプ名が含まれます。(buffersのような)複数形のタイプは、しばしばその型のオブジェクトのリストを意味します。objectのような引き数名は、それが任意の型であることを表します(EmacsオブジェクトタイプのリストはLispのデータ型を参照)。他の名前をもつ引数(たとえばnew-file)はその関数に固有の引数で、関数がドキュメント文字列をもつ場合、引数のタイプはその中で説明されるべきです(ドキュメントを参照)。
&optional
や&rest
により修飾される引数のより完全な説明は、ラムダ式を参照してください。
コマンド(command)、マクロ(macro)、スペシャルフォーム(special form)の説明も同じフォーマットですが、‘Function’が‘Command’、‘Macro’、‘Special Form’に置き換えられます。コマンドはとは単に、インタラクティブ(interactive: 対話的)に呼び出すことができる関数です。マクロは関数とは違う方法(引数は評価されない)で引数を処理しますが、同じ方法で記述します。
マクロとスペシャルフォームにたいする説明には、特定のオプション引数や繰り替えされる引数のために、より複雑な表記が使用されます。なぜなら引数リストが、より複雑な方法で別の引数に分離されるからです。‘[optional-arg]’はoptional-argがオプションであることを意味し、‘repeated-args…’は0個以上の引数を表します。カッコ(parentheses)は、複数の引数をリスト構造の追加レベルにグループ化するのに使用されます。以下は例です:
この架空のスペシャルフォームは、 bodyフォームを実行してから変数varをインクリメントするループを実装します。最初の繰り返しでは変数は値fromをもちます。以降の繰り返しでは、変数は1(incが与えられた場合はinc)増分されます。varがtoに等しい場合、bodyを実行する前にループをexitします。以下は例です:
(count-loop (i 0 10) (prin1 i) (princ " ") (prin1 (aref vector i)) (terpri))
fromとtoが省略された場合、ループを実行する前にvarにnil
がバインドされ、繰り返しの先頭においてvarが非nil
の場合は、ループをexitします。以下は例です:
(count-loop (done) (if (pending) (fixit) (setq done t)))
このスペシャルフォームでは、引数fromとtoはオプションですが、両方を指定するか未指定にするかのいずれかでなければなりません。これらの引数が与えられた場合には、オプションでincも同様に指定することができます。これらの引数は、フォームのすべての残りの要素を含むbodyと区別するために、引数varとともにリストにグループ化されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
変数(variable)とは、オブジェクトにバインド(bind)される名前です(セット(set)とも言う)。変数がバインドされたオブジェクトのことを値(value)と呼びます。このような場合には、その変数が値をもつという言い方もします。ほとんどすべての変数はユーザーがセットすることができますが、特にユーザーが変更できる特定の変数も存在し、これらはユーザーオプション(user options)と呼ばれます。通常の変数およびユーザーオプションは、関数と同様のフォーマットを使用して説明されますが、それらには引数がありません。
以下は架空の変数electric-future-map
の説明です。
この変数の値はElectric Command Futureモードで使用される完全なキーマップである。このマップ内の関数により、まだ実行を考えていないコマンドの編集が可能になる。
ユーザーオプションも同じフォーマットをもちますが、‘Variable’が‘User Option’に置き換えられます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の機能は、使用しているEmacsに関する情報を提供します。
この関数は実行しているEmacsのバージョンを説明する文字列をreturnすす。これはバグレポートにこの文字列を含めるときに有用である。
(emacs-version) ⇒ "GNU Emacs 24.5.1 (x86_64-unknown-linux-gnu, GTK+ Version 3.16) of 2015-06-01"
hereが非nil
ならテキストをバッファーのポイントの前に挿入して、nil
をリターンする。この関数がインタラクティブに呼び出すと、同じ情報をエコーエリアに出力する。プレフィクス引数を与えると、hereが非nil
になる。
この変数の値はEmacsがビルドされた日時を示す。値はcurrent-time
と同様の、4つの整数からなるリストである(時刻を参照)。
emacs-build-time ⇒ (20614 63694 515336 438000)
この変数の値は実行中のEmacsのバージョンであり、"23.1.1"
のような文字列。この文字列の最後の数字は、実際にはEmacsリリースのバージョン番号の一部ではなく、任意のディレクトリーにおいてEmacsがビルドされる度に増分される。"22.0.91.1"
のように4つの数字から構成される値は、それがリリースではないテストバージョンであることを示す。
Emacsのメジャーバージョン番号を示す整数。Emacs 23.1では値は23。
Emacsのマイナーバージョン番号を示す整数。Emacs 23.1では値は1。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このマニュアルは当初、Robert Krawitz、Bil Lewis、Dan LaLiberte、Richard M. Stallman、Chris Welty、およびGNUマニュアルグループのボランティアにより、数年を費やして記述されました。Robert J. Chassellはこのマニュアルのレビューと編集をDefense Advanced Research Projects Agency、ARPA Order 6082のサポートのもとに手助けしてくれ、Computational Logic, IncのWarren A. Hunt, Jr.によりアレンジされました。それ以降も追加のセクションがMiles Bader、Lars Brinkhoff、Chong Yidong、Kenichi Handa、Lute Kamstra、Juri Linkov、Glenn Morris、Thien-Thi Nguyen、Dan Nicolaescu、Martin Rudalics、Kim F. Storm、Luc Teirlinck、Eli Zaretskii、およびその他の人たちにより記述されました。
Drew Adams、Juanma Barranquero、Karl Berry、Jim Blandy、Bard Bloom、Stephane Boucher、David Boyes、Alan Carroll、Richard Davis、Lawrence R. Dodd、Peter Doornbosch、David A. Duff、Chris Eich、Beverly Erlebacher、David Eckelkamp、Ralf Fassel、Eirik Fuller、Stephen Gildea、Bob Glickstein、Eric Hanchrow、Jesper Harder、George Hartzell、Nathan Hess、Masayuki Ida、Dan Jacobson、Jak Kirman、Bob Knighten、Frederick M. Korz、Joe Lammens、Glenn M. Lewis、K. Richard Magill、Brian Marick、Roland McGrath、Stefan Monnier、Skip Montanaro、John Gardiner Myers、Thomas A. Peterson、Francesco Potortì、Friedrich Pukelsheim、Arnold D. Robbins、Raul Rockwell、Jason Rumney、Per Starbäck、Shinichirou Sugou、Kimmo Suominen、Edward Tharp、Bill Trost、Rickard Westman、Jean White、Eduard Wiebe、Matthew Wilding、Carl Witty、Dale Worley、Rusty Wright、David D. Zuhnにより訂正が提供されました。
より完全な貢献者のリストは、Emacsソースリポジトリーの関連する変更ログエントリーを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispのオブジェクト(object)とは、Lispプログラムから操作されるデータです。型(type)やデータ型(data type)とは、可能なオブジェクトの集合を意味します。
すべてのオブジェクトは少なくとも1つの型に属します。同じ型のオブジェクトは同様な構造をもち、通常は同じコンテキストで使用されます。型を重複してもつことができ、オブジェクトは複数の型に属することができます。その結果として、あるオブジェクトが特定の型に属するかどうかを尋ねることはできますが、オブジェクトがその型だけに属するかどうかは決定できません。
Emacsにはいくつかの基本オブジェクト型が組み込まれています。これらの型は他のすべての型を構成するもとであり、プリミティブ型(primitive types: 基本型)と呼ばれます。すべてのオブジェクトはただ1つのプリミティブ型に属します。これらの型には整数(integer)、浮動小数点数(float)、コンス(cons)、シンボル(symbol)、文字列(string)、ベクター(vector)、ハッシュテーブル(hash-table)、サブルーチン(subr)、バイトコード関数(byte-code function)、およびbufferのような編集に関連した特別な型が含まれます(編集用の型を参照)。
プリミティブ型にはそれぞれ、オブジェクトがその型のメンバーかどうかのチェックを行なうために、それぞれ対応するLisp関数があります。
他の多くの言語とは異なり、Lispのオブジェクトは自己記述(self-typing)的です。オブジェクトのプリミティブ型は、オブジェクト自体に暗に含まれます。たとえばオブジェクトがベクターなら、それを数字として扱うことはできません。Lispはベクターが数字でないことを知っているのです。
多くの言語では、プログラマーは各変数にたいしてデータ型を宣言しなければならず、コンパイラーは型を知っていますが、データの中に型はありません。Emacs Lispには、このような型宣言はありません。Lisp変数は任意の型の値をもつことができ、変数に保存した値と型を記憶します(実際には特定の型の値だけをもつことができる少数のEmacs Lisp変数がある。値を制限された変数を参照されたい)。
このチャプターでは、GNU Emacs Lispの各標準型の意味、プリント表現(printed representation)、入力構文(read syntax)を説明します。これらのデータ型を使用する方法についての詳細は、以降のチャプターを参照してください。
2.1 プリント表現と読み取り構文 | Lispオブジェクトがテキストとして表現される方法。 | |
2.2 コメント | コメントとコメント書式の慣例。 | |
2.3 プログラミングの型 | すべてのLispシステムに存在する型。 | |
2.4 編集用の型 | Emacs固有の型。 | |
2.5 循環オブジェクトの読み取り構文 | 循環構造にたいする入力構文。 | |
2.6 型のための述語 | 型に関連するテスト。 | |
2.7 同等性のための述語 | 2つのオブジェクトが等しいかのテスト。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
オブジェクトのプリント表現(printed
representation)とは、オブジェクトにたいしてLispプリンター(関数prin1
)が生成する出力のフォーマットです。すべてのデータ型は一意なプリント表現をもちます。オブジェクトの入力構文(read
syntax)とは、オブジェクトにたいしてLispリーダー(関数read
)が受け取る入力のフォーマットです。これは一意である必要はありません。多くの種類のオブジェクトが複数の構文をもちます。Lispオブジェクトの読み取りとプリントを参照してください。
ほとんどの場合、オブジェクトのプリント表現が、入力構文としても使用されます。しかしLispプログラム内の定数とすることに意味が無いいくつかの型には、入力構文がありません。これらのオブジェクトはハッシュ表記(hash notation)でプリントされ、‘#<’、説明的な文字列(典型的には型名にオブジェクトの名前を続けたもの)、‘>’で構成される文字列です。たとえば:
(current-buffer) ⇒ #<buffer objects.texi>
ハッシュ表記は読み取ることができないので、Lispリーダーは‘#<’に遭遇すると常にエラーinvalid-read-syntax
をシグナルします。
他の言語では式はテキストであり、これ以外の形式はありません。Lispでは式は第一にまずLispオブジェクトであって、オブジェクトの入力構文であるテキストは副次的なものに過ぎません。たいていこの違いを強調する必要はありませんが、このことを心に留めておかないとたまに混乱することがあるでしょう。
インタラクティブに式を評価するとき、Lispインタープリターは最初にそれのテキスト表現を読み取り、Lispオブジェクトを生成してからそのオブジェクトを評価します(評価を参照)。しかし評価と読み取りは別の処理です。読み取りによりテキストにより表現されたLispオブジェクトを読み取り、Lispオブジェクトがリターンされます。後でオブジェクトは評価されるかもしれないし、評価されないかもしれません。オブジェクトを読み取るための基本的な関数read
の説明は、入力関数を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コメント(comment)はプログラム中に記述されたテキストであり、そのプログラムを読む人間ためだけに存在するもので、プログラムの意味には何の影響ももちません。Lispではそれが文字列や文字定数にある場合をのぞき、セミコロン(‘;’)でコメントが開始されます。行の終端までがコメントになります。Lispリーダーはコメントを破棄します。コメントはLispシステム内でプログラムを表すLispオブジェクトの一部にはなりません。
‘#@count’構成は、次のcount個の文字をスキップします。これはプログラムにより生成されたバイナリーデータを含むコメントにたいして有用です。Emacs Lispバイトコンパイラーは出力ファイルにこれを使用します(バイトコンパイルを参照)。しかしソースファイル用ではありません。
コメントのフォーマットにたいする慣例は、コメント記述のヒントを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispには2種類の一般的な型があります。1つはLispプログラミングに関わるもので、もう1つは編集に関わるものです。前者はさまざまな形で多くのLisp実装に存在します。後者はEmacs Lispに固有です。
2.3.1 整数型 | 小数部のない数字。 | |
2.3.2 浮動小数点数型 | 広い範囲をもつ、小数部をもつ数字。 | |
2.3.3 文字型 | 文字、数字、コントロール文字にたいする表現。 | |
2.3.4 シンボル型 | 関数、変数、プロパティーリストを参照する、一意に識別される多目的オブジェクト。 | |
2.3.5 シーケンス型 | リストと配列はどちらもシーケンスに分類される。 | |
2.3.6 コンスセルとリスト型 | コンスセル、および(コンスセルにより作られる)リスト。 | |
2.3.7 配列型 | 配列には文字列とベクターが含まれる。 | |
2.3.8 文字列型 | (効率的な)文字の配列。 | |
2.3.9 ベクター型 | 1次元の配列。 | |
2.3.10 文字テーブル型 | 文字によりインデックスされる1次元の疎な配列。 | |
2.3.11 ブールベクター型 | t とnil からなる1次元の配列。
| |
2.3.12 ハッシュテーブル型 | 非常に高速な参照用のテーブル。 | |
2.3.13 関数型 | 他の場所から呼び出せる実行可能なコード断片。 | |
2.3.14 マクロ型 | より基本的だが少し見栄えの悪い、式を他の式に展開する手法。 | |
2.3.15 プリミティブ関数型 | Lispから呼び出せるCで記述された関数。 | |
2.3.16 バイトコード関数型 | Lispで記述されてコンパイルされた関数。 | |
2.3.17 autoload型 | 頻繁に使用されない関数を自動的にロードするために使用される型。 | |
2.3.18 Finalizer Type | オブジェクトが到達不能になった際に実行するコード。 | |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
整数の値の範囲はマシンに依存します、最小のレンジは-536,870,912から536,870,911(30ビットでは
-2**29
から
2**29 - 1)
ですが、多くのマシンはこれより広い範囲を提供します。Emacs
Lispの数学関数は整数のオーバーフローをチェックしません。したがってEmacsのh整数が30ビットの場合、(1+
536870911)
は-536,870,912になります。
整数にたいする入力構文は、(10を基数とする)数字のシーケンスで、オプションで先頭に符号、最後にピリオドがつきます。Lispインタープリターにより生成されるプリント表現には、先頭の ‘+’や最後の‘.’はありません。
-1 ; 整数の-1 1 ; 整数の1 1. ; これも整数の1 +1 ; これも整数の1
特別な例外として、数字シーケンスが有効なオブジェクトとしては大きすたり小さすぎる整数を指定する場合、Lispリーダーはそれを浮動小数点数(浮動小数点数型を参照)として読み取ります。たとえば、Emacsの整数が30ビットの場合、536870912
は浮動小数点数の536870912.0
として読み取られます。
詳細は数値を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
浮動小数点数は、コンピューターにおける科学表記に相当するものです。浮動小数点数を10の指数をともなう有理数として考えることができます。正確な有効桁数と可能な指数はマシン固有です。Emacsは値の保存にCデータ型のdouble
を使用し、内部的には10の指数ではなく、2の指数として記録します。
浮動小数点数のプリント表現には、(後に最低1つの数字をともなう)小数点と、指数のどちらか一方、または両方が必要です。たとえば‘1500.0’、‘+15e2’、‘15.0e+2’、‘+1500000e-3’、‘.15e4’は、いずれも浮動小数点数の1500を記述し、これらはすべて等価です。
詳細は数値を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispでの文字(character)は、整数以外の何者でもありません。言い換えると、文字は文字コードで表現されます。たとえば文字Aは、整数の65として表現されます。
プログラムで文字を個別に使用するのは稀であり、文字のシーケンスとして構成される文字列(strings)として扱われるのがより一般的です。文字列型を参照してください。
文字列やバッファーの中の文字は、現在のところ0から4194303の範囲 — つまり22ビットに制限されています(文字コードを参照)。0から127のコードはASCIIコードで、残りは非ASCIIです(非ASCII文字を参照)。キーボード入力を表す文字はコントロール(Control)、メタ(Meta)、シフト(Shift)などの修飾キーをエンコードするために、より広い範囲をもちます。
文字から可読なテキスト記述を生成する、メッセージ用の特別な関数が存在します。ヘルプメッセージの文字記述を参照してください。
2.3.3.1 基本的な文字構文 | 標準的な文字の構文。 | |
2.3.3.2 一般的なエスケープ構文 | 文字をコードにより指定する方法。 | |
2.3.3.3 コントロール文字構文 | コントロール文字の構文。 | |
2.3.3.4 メタ文字構文 | メタ文字の構文。 | |
2.3.3.5 その他の文字修飾ビット | ハイパー、スーパー、アルト文字の構文。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
文字は実際には整数なので、文字のプリント表現は10進数です。文字にたいする入力構文も利用可能ですが、Lispプログラムでこの方法により文字を記述するのは、明解なプログラミングではありません。文字にたいしては、Emacs Lispが提供する、特別な入力構文を常に使用するべきです。これらの構文フォーマットはクエスチョンマークで開始されます。
英数字にたいする通常の入力構文は、クエスチョンマークと、その後にその文字を記述します。したがって文字Aは‘?A’、文字Bは‘?B’、文字aは‘?a’となります。
たとえば:
?Q ⇒ 81 ?q ⇒ 113
区切り文字(punctuation characters)にも同じ構文を使用できますが、Lispコードを編集するためのEmacsコマンドが混乱しないように、‘\’を追加するのがよい場合がしばしばあります。たとえば開カッコを記述するために‘?\(’と記述します。その文字が‘\’の場合、それをクォートするために、‘?\\’のように2つ目の‘\’を使用しなければなりません。
Ctrl+g(control-g)、バックスペース(backspace)、タブ(tab)、改行(newline)、垂直タブ(vertical tab)、フォームフィード(formfeed)、スペース(space)、キャリッジリターン(return)、デリート(del)、エスケープ(escape)はそれぞれ‘?\a’、‘?\b’、‘?\t’、‘?\n’、‘?\v’、‘?\f’、‘?\s’、‘?\r’、‘?\d’、‘?\e’と表すことができます(後にダッシュのついた‘?\s’は違う意味をもつ — これは後続の文字にたいしてスーパーによる修飾を適用する)。したがって、
?\a ⇒ 7 ; control-g、C-g ?\b ⇒ 8 ; バックスペース、BS、C-h ?\t ⇒ 9 ; タブ、TAB、C-i ?\n ⇒ 10 ; 改行、C-j ?\v ⇒ 11 ; 垂直タブ、C-k ?\f ⇒ 12 ; フォームフィード文字、C-l ?\r ⇒ 13 ; キャリッジリターン、RET、C-m ?\e ⇒ 27 ; エスケープ文字、ESC、C-[ ?\s ⇒ 32 ; スペース文字、SPC ?\\ ⇒ 92 ; バックスラッシュ文字、\ ?\d ⇒ 127 ; デリート文字、DEL
バックスラッシュがエスケープ文字の役割を果たすので、これらのバックスラッシュで始まるシーケンスはエスケープシーケンス(escape sequences)とも呼ばれます。この用語法は文字ESCとは関係ありません。‘\s’は文字定数としての使用を意図しており、文字定数の内部では単にスペースを記述します。
エスケープという特別な意味を与えずに、任意の文字の前にバックスラッシュの使用することは許されており、害もありません。したがって‘?\+’は‘?+’と等価です。ほとんどの文字の前にバックスラッシュを追加することに理由はありません。しかしLispコードを編集するEmacsコマンドが混乱するのを避けるために、文字‘()\|;'`"#.,’の前にはバックスラッシュを追加するべきです。スペース、タブ、改行、フォームフィードのような空白文字の前にもバックスラッシュを追加できます。しかしタブやスペースspaceのような実際の空白文字のかわりに、‘\t’や‘\s’のような可読性のあるエスケープシーケンスを使用するほうが明解です(スペースを後にともなうバックスラッシュを記述する場合、後続のテキストと区別するために、文字定数の後に余分なスペースを記述すること)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
特に重要なコントロール文字にたいする特別なエスケープシーケンスに加えて、Emacsは非ASCIIテキスト文字の指定に使用できる、何種類かのエスケープ構文を提供します。
最初に、文字をUnicodeの値で指定することができます。?\unnnn
はUnicodeのコードポイント‘U+nnnn’の文字を表します。ここでnnnnは、(慣例により)正確に4桁の16進数です。バックスラッシュは、後続の文字がエスケープシーケンスを形成することを示し、‘u’はUnicodeエスケープシーケンスを指定します。
U+ffff
より大きなコードポイントをもつUnicode文字を指定するために、若干異なる構文が存在します。?\U00nnnnnn
はコードポイント‘U+nnnnnn’の文字を表します。ここでnnnnnnは6桁の16進数です。Unicode標準は‘U+10ffff’までのコードポイントだけを定義するので、これより大きいコードポイントを指定するとEmacsはエラーをシグナルします。
次に文字を16進の文字コードで指定できます。16進エスケープシーケンスはバックスラッシュ、‘x’、および16進の文字コードにより構成されます。したがって‘?\x41’は文字A、‘?\x1’は文字C-a、?\xe0
は文字à(グレイブアクセントつきのa)になります。任意の16進数を使用できるので、この方法で任意の文字を表すことができます。
最後に、8進の文字コードにより文字を指定できます。8進エスケープシーケンスは、3桁までの8進数字をともなうバックスラッシュにより形成されます。したがって‘?\101’は文字A、‘?\001’は文字C-a、?\002
は文字C-bを表します。この方法で指定できるのは、8進コード777までの文字だけです。
これらのエスケープシーケンスは文字列内でも使用されます。文字列内の非ASCII文字を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
他の入力構文を使用してコントロール文字を表すことができます。これは後にバックスラッシュ、カレット、対応する非コントロール文字(大文字か小文字)をともなうクエスチョンマークから構成されます。たとえば‘?\^I’と‘?\^i’はどちらも、値が9である文字C-iの有効な入力構文です。
‘^’のかわりに‘C-’を使用することもできます。したがって‘?\C-i’は‘?\^I’や‘?\^i’と等価です。
?\^I ⇒ 9 ?\C-I ⇒ 9
文字列やバッファーの中ではASCIIのコントロール文字だけが許されますが、キーボード入力にたいしては‘C-’により任意の文字をコントロール文字にすることができます。これらの非ASCIIのコントロール文字にたいするコントロール文字には 非コントロール文字にたいするコードと同様に、2**26 ビットが含まれます。通常のテキスト端末には非ASCIIコントロール文字を生成する方法がありませんが、Xやその他のウィンドウシステムを使用すれば簡単に生成することができます。
歴史的な理由により、EmacsはDEL文字を?のコントロール文字として扱います:
?\^? ⇒ 127 ?\C-? ⇒ 127
結果として、Xでは有意な入力文字であるControl-?文字を、‘\C-’を使用して表現することは今のところできません。さまざまなLispファイルがこの方法でDELを参照するので、これを変更するのは簡単ではないのです。
コントロール文字の表現はファイルや文字列内で見ることができますが、わたしたちは‘^’構文を推奨します。キーボード入力にたいするコントロール文字に好ましいのは、‘C-’構文です。どちらを使用するかはプログラムの意味に影響しませんが、プログラムを読む人の理解を助けるでしょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
メタ文字(meta character)とは、META修飾キーとともにタイプされた文字です。そのような文字を表す整数には 2**27 のビットがセットされています。基本的な文字コードの広い範囲を利用可能にするために、メタやその他の修飾にたいしては上位ビットを使用します。
文字列では、メタ文字を示すASCII文字に、 2**7 ビットが付加されます。したがって文字列に含めることができるメタ文字のコードは1から255の範囲となり、メタ文字は通常のASCII文字のメタ修飾されたバージョンとなります。文字列内でのMETA処理の詳細については、文字列内へのキーボードイベントの配置を参照してください。
メタ文字の入力構文には‘\M-’を使用します。たとえば‘?\M-A’はM-Aを意味します。8進文字コード(以下参照)や、‘\C-’、その他の文字にたいする他の構文とともに‘\M-’を使用できます。したがって、M-Aは‘?\M-A’や‘?\M-\101’と記述できます。同様にC-M-bは‘?\M-\C-b’、‘?\C-\M-b’、‘?\M-\002’と記述することができます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
グラフィック文字(graphic character)のcaseは文字コードで示されます。たとえばASCIIでは、文字‘a’と文字‘A’は区別されます。しかしASCIIにはコントロール文字が大文字なのか小文字なのかを表現する方法がありません。コントロール文字がタイプされたときシフトキーが使用されたかを示すために、Emacsは 2**25 のビットを使用します。この区別はX端末や、その他の特別な端末を使用しているときだけ可能です。通常のテキスト端末は、これらの違いを報告しません。シフトをあらわすビットのためのLisp構文は‘\S-’です。したがって‘?\C-\S-o’や‘?\C-\S-O’は、Shift+Ctrl+o文字を表します。
Xウィンドウシステムは文字にセットするために、他にも3つ修飾ビット — ハイパー(hyper)、スーパー(super)、アルト(alt)を定義します。これらのビットにたいする構文は、‘\H-’、‘\s-’、‘\A-’です(これらのプレフィクスでは、caseは意味がある)。したがって‘?\H-\M-\A-x’はAlt-Hyper-Meta-xを表します(‘-’が後にない‘\s’はスペース文字を表すことに注意)。 数値としてはビット値2**22はアルト、2**23はスーパー、2**24はハイパーです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU Emacs Lispでのシンボル(symbol)とは、名前をもつオブジェクトです。シンボル名は、そのシンボルのプリント表現としての役割があります。Lispの通常の使用では、1つのobarray(シンボルの作成とinternを参照)により、シンボル名は一意です — 2つのシンボルが同じ名前をもつことはありません。
シンボルは変数や関数名としての役割、プロパティーリストを保持する役割をもつことができます。データ構造内にそのようなシンボルが存在することが確実に認識できるように、他のすべてのLispオブジェクトから区別するためだけの役割をもつ場合もあります。与えられたコンテキストにおいて、通常はこれらのうちの1つの使用だけが意図されます。しかし3つすべての方法で、1つのシンボルを独立して使用することもできます。
名前がコロン(‘:’)で始まるシンボルはキーワードシンボル(keyword symbol)と呼ばれます。これらのシンボルは自動的に定数として振る舞い、通常は未知のシンボルといくつかの特定の候補を比較することだけに使用されます。Variables that Never Changeを参照してください。
シンボル名にはどんな文字でも含めることができます。ほとんどのシンボル名は英字、数字、‘-+=*/’などの区切り文字で記述されます。このような名前には特別な区切り文字は必要ありません。名前が数字のように見えない限り、名前にはどのような文字も使用できます(名前が数字のように見える場合は、名前の先頭に‘\’を記述して強制的にシンボルとして解釈させる)。文字‘_~!@$%^&:<>{}?’はあまり使用されませんが、これらも特別な句読点文字を必要としません。他の文字も、バックスラッシュでエスケープすることにより、シンボル名に含めることができます。しかし文字列内でのバックスラッシュの使用とは対照的に、シンボル名でのバックスラッシュは、バックスラッシュの後の1文字をエスケープするだけです。たとえば文字列内では、‘\t’はタブ文字を表します。しかしシンボル名の中では、‘\t’は英字‘t’をクォートするに過ぎません。名前にタブ文字をもつシンボルを記述するには、(バックスラッシュを前置した)実際のタブを使用しなければなりません。しかし、そのようなことを行なうことは稀です。
Common Lispに関する注意:Common Lispでは明示的にエスケープされない限り、小文字は常に大文字に“フォールド(folded)”される。Emacs Lispでは大文字と小文字は区別される。
以下はシンボル名の例です。4つ目の例の中の‘+’は、シンボルが数字として読み取られるのを防ぐためにエスケープされていることに注意してください。6つ目の例では、名前の残りの部分により数字としては不正なのでエスケープの必要はありません。
foo ; ‘foo’という名前のシンボル FOO ; ‘foo’とは別の、‘FOO’という名前のシンボル
1+ ; ‘1+’という名前のシンボル ; (整数の‘+1’ではない)
\+1 ; ‘+1’という名前のシンボル ; (判読しにくい名前)
\(*\ 1\ 2\) ; ‘(* 1 2)’という名前のシンボル(悪い名前) +-*/_~!@$%^&=:<>{} ; ‘+-*/_~!@$%^&=:<>{}’という名前のシンボル ; これらの文字のエスケープは不要
シンボル名がプリント表現としての役割をもつというルールの例外として、‘##’があります。これは、名前が空文字列のinternされたシンボルのプリント表現です。さらに‘#:foo’は、internされていないfooという名前のシンボルにたいするプリント表現です(通常、Lispリーダーはすべてのシンボルをinternする。シンボルの作成とinternを参照されたい)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
シーケンス(sequence)とは、要素の順序セットを表現するLispオブジェクトです。Emacs Lispには2種類のシーケンス — リスト(lists)と配列(arrays)があります。
リストはもっとも一般的に使用されるシーケンスです。リストは任意の型の要素を保持でき、要素の追加と削除により簡単に長さを変更できます。リストについては、次のサブセクションを参照してください。
配列は固定長のシーケンスです。配列はさらに文字列(strings)、ベクター(vectors)、文字テーブル(char-tables)、ブールベクター(bool-vectors)に細分されます。ベクターは任意の型の要素を保持できますが、文字列の要素は文字でなければならず、ブールベクターの要素はt
かnil
でなければなりません。文字テーブルはベクターと似ていますが、有効な文字によりインデックスづけされる点が異なります。文字列内の文字は、バッファー内の文字のようにテキストプロパティーをもつことができます(テキストのプロパティを参照)。しかしベクターはその要素が文字のときでも、テキストプロパティーをサポートしません。
リスト、文字列、およびその他の配列型も、重要な類似点を共有します。たとえば、それらはすべて長さlをもち、要素は0からl-1でインデックスづけされます。いくつかの関数はシーケンス関数と呼ばれ、これらは任意の種類のシーケンスを許容します。たとえば、関数length
は、任意の種類のシーケンスの長さを報告します。シーケンス、配列、ベクターを参照してください。
シーケンスは読み取りにより常に新たに作成されるやめ、同じシーケンスを2回読み取るのは一般的に不可能です。シーケンスにたいする入力構文を2回読み取った場合には、内容が等しい2つのシーケンスを得ます。これには1つ例外があります。空リスト()
は、常に同じオブジェクトnil
を表します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コンスセル(cons cell)はCARスロット、CDRスロットと呼ばれる2つのスロットから構成されるオブジェクトです。それぞれのスロットはには、任意のLispオブジェクトを保持できます。そのときCARスロットに保持されるオブジェクトが何であれ、わたしたちは“このコンスセルのCAR”のような言い方をします。これはCDRの場合も同様です。
リスト(list)はコンスセルの連続するシリーズで、各コンスセルのCDRスロットは次のコンスセル、または空リストを保持します。空リストは実際にはシンボルnil
です。詳細については、リストを参照してください。ほとんどのコンスセルはリストの一部として使用されるので、わたしたちはコンスセルにより構成される任意の構造を、リスト構造(list
structure)という用語で参照します。
Cプログラマーにたいする注意: Lispのリストはコンスセルにより構築されるリンクリスト(linked list)として機能する。Lispではポインターは暗黙的なので、コンスセルのスロットが値を“保持(hold)”するのか、それとも値を“指す(point)”のかは区別しない。
コンスセルはLispの中核なので、コンスセルではないオブジェクトにたいする用語もあります。これらのオブジェクトはアトム(atoms)と呼ばれます。
リストにたいする入力構文とプリント表現は同じで左カッコ、任意の数の要素、右カコから構成されます。以下はリストの例です:
(A 2 "A") ; 3要素のリスト () ; 要素がないリスト(空リスト) nil ; 要素がないリスト(空リスト) ("A ()") ; 1要素のリスト: 文字列"A ()"
(A ()) ; 2要素のリスト:A
と空リスト (A nil) ; 同上 ((A B C)) ; 1要素のリスト ; (この要素は、3要素のリスト)
読み取りではカッコの内側はリストの要素になります。つまりコンスセルは各要素から作成されます。コンスセルのCARスロットは要素を保持し、CDRスロットはリスト内の次のコンスセル(このコンスセルはリスト内の次の要素をする)を参照します。最後のコンスセルのCDRスロットはnil
を保持するようにセットされます。
CARやCDRという名称はLispの歴史に由来します。オリジナルのLisp実装はIBM 704コンピューターで実行されていました。ワードを2つの部分、つまり“address”と呼ばれる部分と、“decrement”と呼ばれる部分に分割していて、その際CARはaddress部から内容を取り出す命令で、CDRはdecrement部から内容を取り出す命令でした。これとは対照的に“cons
cells”は、これらを作成する関数cons
から命名されました。この関数は関数の目的、すなわちセルを作る(construction of
cells)という目的から命名されました。
2.3.6.1 ボックスダイアグラムとしてのリストの描写 | リストの図解。 | |
2.3.6.2 ドットペア表記 | コンスセルの一般的な構文。 | |
2.3.6.3 連想リスト型 | 特別に構築されるリスト。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コンスセルを表現するドミノのような1対のボックスによる図で、リストを説明することができます(Lispリーダーがこのような図を読み取ることはできない。人間とコンピューターが理解できるテキスト表記と異なり、ボックス図は人間だけが理解できる)。この図は3要素のリスト(rose
violet buttercup)
を表したものです:
--- --- --- --- --- --- | | |--> | | |--> | | |--> nil --- --- --- --- --- --- | | | | | | --> rose --> violet --> buttercup
この図では、ボックスは任意のLispオブジェクトへの参照を保持できるスロットを表します。ボックスのペアーはコンスセルを表します。矢印はLispオブジェクト(アトム、または他のコンスセル)への参照を表します。
この例では、1番目のボックスは1番目のコンスセルで、それのCARはrose
(シンボル)を参照または保持します。2番目のボックスは1番目のコンスセルのCDRを保持し、次のボックスペアすなわち2番目のコンスセルを参照します。2番目のコンスセルのCARはviolet
で、CDRは3番目のコンスセルです。(最後の)3番目のコンスセルのCDRはnil
です。
同じリスト(rose violet buttercup)
を、違うやり方で描いた別の図で表してみましょう:
--------------- ---------------- ------------------- | car | cdr | | car | cdr | | car | cdr | | rose | o-------->| violet | o-------->| buttercup | nil | | | | | | | | | | --------------- ---------------- -------------------
要素がないリストは空リスト(empty
list)で、これはシンボルnil
と同じです。言い換えるとnil
はシンボルであり、かつリストでもあります。
以下はリスト(A ())
、または等価な(A nil)
をボックスと矢印で描いたものです:
--- --- --- --- | | |--> | | |--> nil --- --- --- --- | | | | --> A --> nil
以下はもっと複雑な例です。これは1番目の要素が2要素のリストであるような、3要素のリスト((pine needles) oak
maple)
を表します:
--- --- --- --- --- --- | | |--> | | |--> | | |--> nil --- --- --- --- --- --- | | | | | | | --> oak --> maple | | --- --- --- --- --> | | |--> | | |--> nil --- --- --- --- | | | | --> pine --> needles
同じリストを2番目のボックス表記で表すと、以下のようになります:
-------------- -------------- -------------- | car | cdr | | car | cdr | | car | cdr | | o | o------->| oak | o------->| maple | nil | | | | | | | | | | | -- | --------- -------------- -------------- | | | -------------- ---------------- | | car | cdr | | car | cdr | ------>| pine | o------->| needles | nil | | | | | | | -------------- ----------------
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ドットペア表記(dotted pair
notation)は、CARとCDRが明示的に表されたコンスセルの一般的な構文です。この構文では(a
.
b)
がCARがオブジェクトa、CDRがオブジェクトbという意味になります。CDRがリストである必要がないので、ドットペア表記はより一般的なリスト構文です。しかしリスト構文が機能するような場合には、より扱いにくくなります。ドットペア表記では、リスト‘(1
2 3)’は‘(1 . (2 . (3
.
nil)))’と記述されます。nil
で終端されたリストにたいしては、どちらの表記法も使用できますが、リスト表記の方が通常は明解で便利です。リストをプリントする場合には、コンスセルのCDRがリストでないときだけドットペア表記が使用されます。
以下はボックスを使用してドットペア表記を表した例です。これはペア(rose . violet)
を表します:
--- --- | | |--> violet --- --- | | --> rose
最後のCDRが非nil
のコンスセルのチェーンを表すので、ドットペア表記とリスト表記を組み合わせることができます。リストの最後の要素の後にドットを記述して、その後に最後のコンスセルのCDRを記述します。たとえば(rose
violet . buttercup)
は、(rose . (violet
. buttercup))
と等価です。オブジェクトは以下のようになります:
--- --- --- --- | | |--> | | |--> buttercup --- --- --- --- | | | | --> rose --> violet
構文(rose . violet .
buttercup)
は無効です。なぜならこれは何も意味していないからです。何か意味があるとしても、violet
のためにCDRがすでに使用されているコンスセルのCDRに、buttercup
を置くということになります。
リスト(rose violet)
は(rose . (violet))
と等価であり、以下のようになります:
--- --- --- --- | | |--> | | |--> nil --- --- --- --- | | | | --> rose --> violet
同様に3要素のリスト(rose violet buttercup)
は、(rose . (violet
. (buttercup)))
と等価です。
これは以下のようになります:
--- --- --- --- --- --- | | |--> | | |--> | | |--> nil --- --- --- --- --- --- | | | | | | --> rose --> violet --> buttercup
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
連想リスト(association list)またはalistは、要素がコンスセルであるように特別に構成されたリストです。各要素においては、CARがキー(key)で、CDRが連想値(associated value)であると考えます(連想値がCDRのCARに保存される場合もある)。リストの先頭への連想値の追加と削除は簡単なので、連想リストはスタック(stack)にしばしば使用されます。
たとえば、
(setq alist-of-colors '((rose . red) (lily . white) (buttercup . yellow)))
これは変数alist-of-colors
に3要素のalistをセットします。最初の要素では、rose
がキーでred
が値になります。
alistとalist関数についての詳細な説明は連想リストを参照してください。(多くのキーの操作をより高速に行なう)テーブルを照合する他の手段についてはハッシュテーブルを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
配列(array)は、他のLispオブジェクトを保持または参照する任意の数のスロットから構成され、メモリーの連続ブロックに配列されます。配列の任意の要素へのアクセス時間は大体同じです。対照的にリストの要素にたいするアクセスは、リスト内でのその要素の位置に比例した時間を要します(リストの最後の要素にアクセスするにはリストの最初の要素にアクセスするより長い時間が必要)。
Emacsは文字列(strings)、ベクター(vectors)、ブールベクター(bool-vectors)、文字テーブル(char-tables)という4種の配列を定義します。
文字列は文字の配列であり、ベクターは任意のオブジェクトの配列です。ブールベクターはt
かnil
だけを保持できます。この種の配列は、もっとも大きい整数までの任意の長さをもつことができます。文字テーブルは、任意の有効な文字コードによりインデックスづけされる疎な配列であり、任意のオブジェクトを保持することができます。
配列の最初の要素はインデックス0、2番目の要素はインデックス1、...となります。これは0基準(zero-origin)のインデックスづけと呼ばれます。たとえば、4要素の配列はインデックス0、1、2、3をもちます。利用できる最大のインデックス値は、配列の長さより1つ小さくなります。▼一度配列が作成されると、長さは固定されます。
Emacs Lispのすべての配列は、1次元です(他のほとんどのプログラミング言語は多次元配列をサポートするが、これらは必須ではない。ネストされた1次元配列により同じ効果を得ることが可能)。各種の配列は独自の入力構文をもちます。詳細は以降のセクションを参照してください。
配列型はシーケンス型のサブセットであり文字列型、ベクター型、ブールベクター型、文字テーブル型が含まれます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
文字列(string)とは文字の配列です。Emacsがテキストエディターであることから予想できるように、文字列はたとえばLispシンボルの名前、ユーザーへのメッセージ、バッファーから抽出されたテキストの表現など多くの目的のために使用されます。Lispの文字列は定数です。文字列を評価すると、それと同じ文字列がリターンされます。
文字列を操作する関数については文字列と文字を参照してください。
2.3.8.1 文字列の構文 | Lisp文字列を指定する方法。 | |
2.3.8.2 文字列内の非ASCII文字 | 文字列内の国際化文字。 | |
2.3.8.3 文字列内の非プリント文字 | 文字列内の印刷不可能なリテラル文字。 | |
2.3.8.4 文字列内のテキストプロパティ | テキストプロパティーをもつ文字列。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
文字列にたいする入力構文は"like
this"
のようにダブルクォート、任意個数の文字、もう1つのダブルクォートから構成されます。文字列内にダブルクォートを含める場合は、それの前にバックスラッシュを記述します。したがって"\""
は1つのダブルクォート文字だけを含む文字列です。同様にバックスラッシュを含める場合は、"this
\\ is a single embedded backslash"
のように、それの前にもう1つのバックスラッシュを記述します。
文字列にたいする入力構文では、改行(newline)は特別ではありません。ダブルクォートの間に改行を記述すれば、その改行は文字列内の文字となります。しかしエスケープされた改行 — 前に‘\’をともなう改行 — は文字列の一部とはなりません。同様にエスケープされたスペース‘\ ’も無視されます。
"It is useful to include newlines in documentation strings, but the newline is \ ignored if escaped." ⇒ "It is useful to include newlines in documentation strings, but the newline is ignored if escaped."
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacdの文字列内の非ASCII文字にたいしては2つのテキスト表現 — マルチバイト(multibyte)とユニバイト(unibyte)があります(テキストの表現方法を参照)。大まかに言うとユニバイト文字列にはraw(生)バイトが保存され、マルチバイト文字列には人間が読めるテキストが保存されます。ユニバイト文字列内の各文字はバイトであり、値は0から255となります。対照的にマルチバイト文字列内の各文字は、0から4194303の値をもつかもしれません(文字型を参照)。いずれも127より上の文字は非ASCIIです。
文字をリテラルとして記述することにより、文字列に非ASCII文字を含めることができます。マルチバイトのバッファーや文字列、あるいはマルチバイトとしてvisitされたファイル等、マルチバイトのソースから文字列定数を読み込む場合、Emacsは非ASCII文字をマルチバイト文字として読み取り、その文字列を自動的にマルチバイト文字列にします。ユニバイトのソースから文字列定数を読み込む場合、Emacsは非ASCII文字をユニバイト文字として読み取り、その文字列をユニバイト文字列にします。
マルチバイト文字列内にリテラルとして文字を記述するかわりに、エスケープシーケンスを使用して文字コードとして記述できます。エスケープシーケンスについての詳細は、一般的なエスケープ構文を参照してください。
文字列定数内でUnicodeスタイルのエスケープシーケンス‘\uNNNN’または‘\U00NNNNNN’を使用する場合、(たとえASCII文字であっても)Emacsは自動的に文字列をマルチバイトとみなします。
文字列定数内で16進エスケープシーケンス(‘\xn’)と8進エスケープシーケンス(‘\n’)を使用することもできます。しかし注意してください: 文字列定数が16進または8進のエスケープシーケンスを含み、それらのエスケープシーケンスすべてがユニバイト文字(256より小)を指定していて、その文字列内に他にリテラルの非ASCII文字またはUnicodeスタイルのエスケープシーケンスが存在しない場合、Emacsは自動的に文字列をユニバイト文字列とみなします。つまり文字列内のすべての非ASCII文字は8ビットのrawバイトとみなされます。
16進および8進のエスケープシーケンスでは、エスケープされた文字コードに可変個の数字が含まれるかもしれないので、それに続く文字で16進および8進として有効ではない最初の文字は、そのエスケープシーケンスを終了させます。文字列内の次の文字が16進または8進として解釈できる文字の場合は、‘\ ’(バックスラッシュとスペース)を記述して、エスケープシーケンスを終了できます。たとえば‘\xe0\ ’はgrave accentつきの‘a’という1文字を表します。文字列内の‘\ ’はバックスラッシュ改行と同様です。これは文字列内の文字とはなりませんが、先行する16進エスケープを終了します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
リテラル文字と同様に、文字列定数内でバックスラッシュによるエスケープシーケンスを使用できます(ただし文字定数を開始するクエスチョンマークは使用しない)。たとえば非プリント文字のタブとC-aを含む文字列は、"\t,
\C-a"
のように、それらの間にカンマとスペースを記述します。文字にたいする入力構文については文字型を参照してください。
しかしバックスラッシュによるエスケープシーケンスとともに記述できるすべての文字が、文字列内で有効というわけではありません。文字列が保持できるコントロール文字はASCIIコントロール文字だけです。ASCIIコントロール文字では、文字列のcaseは区別されません。
正確に言うと、文字列はメタ文字を保持できません。しかし文字列がキーシーケンスとして使用される場合には、文字列内でメタ修飾されたASCII文字を表現するための方法を提供する特別な慣習があります。文字列定数内でメタ文字を示すために‘\M-’構文を使用した場合、これは文字列内の文字の
2**7
のビットをセットします。その文字列がdefine-key
またはlookup-key
で使用される場合、この数字コードは等価なメタ文字に変換されます。文字型を参照してください。
文字列はハイパー(hyper)、スーパー(super)、アルト(alt)で修飾された文字を保持できません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
文字列にはその文字自身に加えて、文字のプロパティーも保持することができます。これにより特別なことをしなくても、文字列とバッファーとの間でテキストをコピーするプログラムが、テキストプロパティーをコピーすることが可能になります。テキストプロパティーが何を意味するかについてはテキストのプロパティを参照してください。テキストプロパティーをもつ文字列は、特別な入力構文とプリント構文を使用します。
#("characters" property-data...)
ここでproperty-dataは,3個でグループ化された0個以上の要素から構成されます:
beg end plist
要素begおよびendは整数で、文字列内のインデックスの範囲を指定します。plistはその範囲にたいするプロパティーリストです。たとえば、
#("foo bar" 0 3 (face bold) 3 4 nil 4 7 (face italic))
これはテキスト内容が‘foo
bar’で、最初の3文字はface
プロパティーに値bold
をもち、最後の3文字はface
プロパティーに値italic
をもつことを表します(4番目の文字にはテキストプロパティーはないので、プロパティーリストはnil
。実際には範囲の中の指定されていない文字はデフォルトではプロパティーをもたないので、範囲のプロパティーリストをnil
と指定する必要ない)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ベクター(vector)は任意の型の要素からなる1次元の配列です。ベクター内の任意の要素へのアクセスに要す時間は一定です(リストの場合では要素へのアクセスに要す時間は、リストの先頭からその要素までの距離に比例する)。
ベクターのプリント表現は左角カッコ(left square bracket)、要素、右角カッコ(right square bracket)から構成されます。これは入力構文でもあります。数字や文字列と同様にベクターは評価において定数と判断されます。
[1 "two" (three)] ; 3要素のベクター
⇒ [1 "two" (three)]
ベクターに作用する関数についてはベクターを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
文字テーブル(char-table)は任意の型の要素をもつ1次元の配列であり、文字コードによりインデックスづけされます。文字テーブルは、文字コードに情報を割り当てることを必要とする多くの処理を簡単にするための、特別な追加の機能をもちます — たとえば文字テーブルは継承する親、デフォルト値、特別な目的のために使用する余分なスロットをいくつかもつことができます。文字テーブルは文字セット全体にたいして1つの値を指定することもできます。
文字テーブルのプリント表現はベクターと似ていますが、最初に余分な‘#^’があります1。
文字テーブルを操作する特別な関数については文字テーブルを参照してください。文字テーブルの使用には以下が含まれます:
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ブールベクター(bool-vector)は、要素がt
かnil
のいずれかでなければならない1次元の配列です。
ブールベクターのプリント表現は文字列と似ていますが、後に長さを記述した‘#&’で始まります。これに続く文字列定数は、ビットマップとして実際に内容を指定するブールベクターです
—
文字列定数内のそれぞれの“文字”は8ビットを含み、これはブールベクターの次の8要素を指定します(1はt
、0はnil
です)。文字の最下位ビットブールベクターの最下位のインデックスに対応します。
(make-bool-vector 3 t) ⇒ #&3"^G" (make-bool-vector 3 nil) ⇒ #&3"^@"
‘C-g’の2進コードは111、‘C-@’はコード0の文字なのでこの結果は理にかなっています。
長さが8の倍数でなければプリント表現には余分な要素が表示されますが、これらの余分な要素に意味はありません。たとえば以下の例では、最初の3ビットだけが使用されるので2つのブールベクターは等価です:
(equal #&3"\377" #&3"\007") ⇒ t
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ハッシュテーブルは非常に高速な照合テーブルの一種で、キーを対応する値にマップするalistと似ていますがより高速です。ハッシュテーブルのプリント表現では、以下のようにハッシュテーブルのプロパティーと内容を指定します:
(make-hash-table) ⇒ #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8 data ())
ハッシュテーブルについての詳細はハッシュテーブルを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
他のプログラミング言語の関数と同様、Lisp関数は実行可能なコードです。他の言語と異なり、Lispの関数はLispオブジェクトでもあります。Lispのコンパイルされていない関数はラムダ式
— つまり1番目の要素がシンボルlambda
であるリストです(ラムダ式を参照)。
ほとんどのプログラミング言語では名前のない関数はありません。Lispでは関数に本質的な名前はありません。名前がなくてもラムダ式を関数として呼び出すことができます。これを強調するために、わたしたちはこれを無名関数(anonymous function)とも呼びます(無名関数を参照)。Lispの名前つき関数は関数セルに有効な関数がセットされた単なるシンボルです(関数の定義を参照)。
ほとんどの場合、関数はLispプログラム内のLisp式の名前が記述されたところで呼び出されます。しかし実行時に関数オブジェクトを構築または取得してから、プリミティブ関数funcall
およびapply
により呼び出すことができます。関数の呼び出しを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispマクロ(Lisp
macro)はLisp言語を拡張するユーザー定義の構成です。これはオブジェクトとしてではなく関数のように表現されますが、引数の渡し方の意味が異なります。Lispマクロの形式はリストです。これは最初の要素がmacro
で、CDRがLisp関数オブジェクト(lambda
シンボルを含む)であるようなリストです。
Lispマクロオブジェクトは通常、ビルトインのdefmacro
関数で定義されますが、macro
で始まる任意のリストもEmacsにとってはマクロです。マクロを記述する方法の説明はマクロを参照してください。
警告: Lispマクロとキーボードマクロ(キーボードマクロを参照)は完全に別の物である。修飾なしで“マクロ”という単語を使用したときは、キーボードマクロではなくLispマクロのことを指す。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プリミティブ関数(primitive function)とは、Cプログラミング言語で記述されたLispから呼び出せる関数です。プリミティブ関数はsubrsやビルトイン関数(built-in functions)とも呼ばれます(単語“subr”は“サブルーチン(subroutine)”が由来)。ほとんどのプリミティブ関数ハ、呼び出されたときニすべての引数を評価します。すべての引数を評価しないプリミティブ関数はスペシャルフォーム(special form)と呼ばれます(スペシャルフォームを参照)。
呼び出す側からすれば、その関数がプリミティブ関数かどうかは問題になりません。しかしプリミティブ関数をLispで記述された関数で再定義した場合に問題になります。理由はそのプリミティブ関数がCコードから直接呼び出されているかもしれないからです。Lispから再定義した関数を呼び出すと新しい定義を使用するでしょうが、Cコードから呼び出すとビルトインの定義が使用されるでしょう。したがって、プリミティブ関数の再定義はしないでください。
関数(function)という用語で、LispやCで記述されたすべてのEmacs関数を参照します。Lispで記述された関数についての情報は関数型を参照してください。
プリミティブ関数に入力構文はなく、サブルーチン名とともにハッシュ表記でプリントします。
(symbol-function 'car) ; そのシンボルの関数セルに ; アクセスする ⇒ #<subr car> (subrp (symbol-function 'car)) ; これはプリミティブ関数? ⇒ t ; そのとおり
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バイトコード関数オブジェクト(byte-code function objects)は、Lispコードをバイトコンパイルすることにより生成されます(バイトコンパイルを参照)。バイトコード関数オブジェクトは、内部的にはベクターによく似ています。しかしバイトコード関数オブジェクトが関数呼び出しのように見える場合、評価プロセスによりこのデータ型は特別に処理されます。バイトコード関数オブジェクトを参照してください。
バイトコード関数オブジェクトのプリント表現と入力構文はベクターのものと似ていますが、開き角カッコ‘[’の前に‘#’があります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
autoloadオブジェクト(autoload
object)は、最初の要素がシンボルautoload
のリストです。これはシンボルの関数定義として保存され、実際の定義にたいする代替としての役割をもちます。autoloadオブジェクトは、必要な時にロードされるLispコードファイルの中で実際の定義を見つけることができることを宣言します。これにはファイル名と、それに加えて実際の定義についての他のいくつかの情報が含まれます。
ファイルのロード後、そのシンボルはautoloadオブジェクトではない新しい関数定義をもつはずです。新しい定義は、最初からそこにあったかのように呼び出されます。ユーザーの観点からは関数呼び出しは期待された動作、つまりロードされたファイル内の関数定義を使用します。
autoloadオブジェクトは通常、シンボルの関数セルにオブジェクトを保存する関数autoload
により作成されます。詳細はautoloadを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ファイナライザーオブジェクト(finalizer object)は、オブジェクトがもはや必要なくなった後のLispコードのクリーンアップを助けます。ファイナライザーは、Lisp関数オブジェクトを保持します。ガーベージコレクションのオアス後にファイナライザーオブジェクトが到達不能になったとき、Emacsはそのファイナライザーに関連付けられた関数オブジェクトを呼び出します。ファイナライザーの到達可否の判定時、もしかしてファイナライザーオブジェクト自身が参照を離さないのではないかと心配することなくファイナライザーを使用できるように、Emacsはファイナラーオブジェト自身からの参照は勘定しません。
ファイナラーザー内でのエラーは*Messages*
にプリントされます。その関数が失敗しても、Emacsは与えられたファイナライザーオブジェクトに関連付けられた関数を正確に1回実行します。
functionを実行するファイナライザーを作成する。functionはガーベージコレクション後、リターンされたファイナライザーオブジェクトが到達不能になったときに実行される。そのファイナライザーオブジェクトがファイナライザーオブジェクトからの参照を通じてのみ到達可能なら、functionの実行是非の判断時の目的にたいして、それは到達可能とみなされない。functionはファイナライザーオブジェクトごとに1回実行される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
前セクションの型は一般的なプログラミング目的のために使用され、これらの型のほとんどはLisp方言のほとんどで一般的です。Emacs Lispは編集に関する目的のために、いくつかの追加のデータ型を提供します。
2.4.1 バッファー型 | 編集のための基本オブジェクト。 | |
2.4.2 マーカー型 | バッファー内の位置。 | |
2.4.3 ウィンドウ型 | バッファーはウィンドウ内に表示される。 | |
2.4.4 フレーム型 | ウィンドウはフレームを細分化する。 | |
2.4.5 端末型 | フレームを表示する端末デバイス。 | |
2.4.6 ウィンドウ構成型 | フレームが細分化された方法を記録する。 | |
2.4.7 フレーム構成型 | すべてのフレームの状態を記録する。 | |
2.4.8 プロセス型 | 背後のOS上で実行されるEmacsのサブプロセス。 | |
2.4.9 ストリーム型 | 文字の受信と送信。 | |
2.4.10 キーマップ型 | どのキーストロークがどの関数を呼び出すか。 | |
2.4.11 オーバーレイ型 | オーバーレイが表示される方法。 | |
2.4.12 フォント型 | テキストを表示するフォント。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファー(buffer)とは、編集されるテキストを保持するオブジェクトです(バッファーを参照)。ほとんどのバッファーはディスクファイル(ファイルを参照)の内容を保持するので編集できますが、他の目的のために使用されるものもいくつかあります。ほとんどのバッファーはユーザーにより閲覧されることも意図しているので、いつかはウィンドウ内(ウィンドウを参照)に表示されます。しかしバッファーはウィンドウに表示される必要はありません。バッファーはそれぞれ、ポイント(point)と呼ばれる位置指定をもちます(ポジションを参照)。ほとんどの編集コマンドは、カレントバッファー内のポイントに隣接する内容を処理します。常に1つのバッファーがカレントバッファー(current buffer)です。
バッファーの内容は文字列によく似ていますが、バッファーはEmacs Lispの文字列と同じようには使用されず、利用可能な操作は異なります。文字列にテキストを挿入するためには部分文字列の結合が必要で、結果は完全に新しい文字列オブジェクトなのるのにたいして、バッファーでは既存のバッファーに効率的にテキストを挿入してバッファーの内容を変更できます。
標準的なEmacs関数の多くは、カレントバッファー内の文字を操作したりテストするためのものです。このマニュアルはこれらの関数の説明のために、1つのチャプターを設けています(テキストを参照)。
他のデータ構造のいくつかは、各バッファーに関連付けられています:
ローカルキーマップと変数リストは、グローバルなバインディングや値を個別にオーバーライドするためのエントリーを含みます。これらは実際にプログラムを変更することなく、異なるバッファーでプログラムの振る舞いをカスタマイズするために使用されます。
バッファーはインダイレクト(indirect: 間接) — つまり他のバッファーとテキストを共有するがそれぞれ別に表示する — かもしれません。インダイレクトバッファーを参照してください。
バッファーに入力構文はありません。バッファーはバッファー名を含むハッシュ表記でプリントされます。
(current-buffer) ⇒ #<buffer objects.texi>
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マーカー(marker)は特定のバッファー内の位置を表します。したがってマーカーには2つの内容 — 1つはバッファー、もう1つは位置 — をもちます。バッファーのテキストの変更では、マーカーが常にバッファー内の同じ2つの文字の間に位置することを確実にするために、必要に応じて自動的に位置の値が再配置されます。
マーカーは入力構文をもちません。マーカーはカレントの文字位置とそのバッファー名を与える、ハッシュ表記でプリントされます。
(point-marker) ⇒ #<marker at 10779 in objects.texi>
マーカーのテスト、作成、コピー、移動の方法についての情報はマーカーを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウ(window)はEmacsがバッファーを表示するために使用する端末スクリーンの部分を記述します。すべてのウィンドウは関連付けられた1つのバッファーをもち、バッファーの内容はそのウィンドウに表示されます。それとは対照的に、あるバッファーは1つのウィンドウに表示されるか表示されないか、それとも複数のウィンドウに表示されるかもしれません。
同時に複数のウィンドウが存在するかもしれませんが、常に1つのウィンドウが選択されたウィンドウ(selected window)になります。Emacsがコマンドにたいして準備できているときは、(通常は)カーソルが表示されるウィンドウが選択されたウィンドウです。選択されたウィンドウは、通常はカレントバッファー(カレントバッファーを参照)を表示しますがこれは必須ではありません。
スクリーン上でウィンドウはフレームにグループ化されます。ウィンドウはそれぞれ、ただ1つのフレームだけに属します。フレーム型を参照してください。
ウィンドウは入力構文をもちません。ウィンドウはウィンドウ番号と表示されているバッファー名を与える、ハッシュ表記でプリントされます。与えられたウィンドウに表示されるバッファーは頻繁に変更されるかもしれないので、一意にウィンドウを識別するためにウィンドウ番号が存在します。
(selected-window) ⇒ #<window 1 on objects.texi>
ウィンドウに作用する関数の説明はウィンドウを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレーム(frame)とは1つ以上のEmacsウィンドウを含むスクリーン領域です。スクリーン領域を参照するためにEmacsが使用するLispオブジェクトを指す場合にも“フレーム”という用語を使用します。
フレームは入力構文をもちません。フレームはフレームのタイトルとメモリー内のアドレス(フレームを一意に識別するのに有用)を与えるハッシュ表記でプリントされます。
(selected-frame) ⇒ #<frame emacs@psilocin.gnu.org 0xdac80>
フレームに作用する関数の説明はフレームを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
端末(terminal)は1つ以上のEmacsフレーム(フレーム型を参照)を表示する能力があるデバイスです。
端末は入力構文をもちません。端末はその端末の順序番号とTTYデバイスファイル名を与える、ハッシュ表記でプリントされます。
(get-device-terminal nil) ⇒ #<terminal 1 on /dev/tty>
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウ構成(window configuration)はフレーム内のウィンドウの位置とサイズ、内容についての情報を保持します。これにより後で同じウィンドウ配置を再作成できます。
ウィンドウ構成は入力構文をもちません。ウィンドウ構成のプリント表現は‘#<window-configuration>’のようになります。ウィンドウ構成に関連するいくつかの関数の説明はウィンドウの構成を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレーム構成(frame
configuration)はすべてのフレーム内のウィンドウの位置とサイズ、内容についての情報を保持します。これは基本型ではありません —
実際のところ、これはCARがframe-configuration
でCDRがalistであるようなリストです。それぞれのalist要素は、その要素のCARに示される1つのフレームを記述します。
フレーム構成に関連するいくつかの関数の説明はフレーム構成を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プロセス(process)という単語は、通常は実行中のプログラムを意味します。Emacs自身はこの種のプロセス内で実行されます。しかしEmacs Lispでは、プロセスとはEmacsプロセスにより作成されたサブプロセスを表すLispオブジェクトです。シェル、GDB、ftp、コンパイラーなどのプログラムは、Emacsのサブプロセスとして実行されEmacsの能力を拡張します。さらに操作を行なうために、EmacsサブプロセスはEmacsからテキスト入力を受け取り、テキスト出力をEmacsにリターンします。Emacsがサブプロセスにシグナルを送ることもできます。
プロセスオブジェクトは入力構文をもちません。プロセスオブジェクトはプロセス名を与えるハッシュ表記でプリントされます。
(process-list) ⇒ (#<process shell>)
プロセスの作成、削除、プロセスに関する情報のリターン、入力やシグナルの送信、出力の受信を行なう関数についての情報はプロセスを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ストリーム(stream)とは、文字のソースまたはシンクとして — つまり入力として文字を供給したり、出力として文字を受け入れるために使用できるオブジェクトです。多くの異なるタイプ — マーカー、バッファー、文字列、関数をこの方法で使用できます。ほとんどの場合、入力ストリーム(文字列ソース)はキーボード、バッファー、ファイルから文字を受け取り、出力ストリーム(文字シンク)は文字を*Help*バッファーのようなバッファーやエコーエリアに文字を送ります。
オブジェクトnil
は、他の意味に加えてストリームとして使用されることがあります。nil
は変数standard-input
やstandard-output
の値を表します。オブジェクトt
も入力としてミニバッファー(ミニバッファーを参照)、出力としてエコーエリア(エコーエリアを参照)の使用を指定するストリームになります。
ストリームは特別なプリント表現や入力構文をもたず、それが何であれそれらの基本型としてプリントされます。
パース関数およびプリント関数を含む、ストリームに関連した関数の説明はLispオブジェクトの読み取りとプリントを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
キーマップ(keymap)はユーザーがタイプした文字をコマンドにマップします。このマップはユーザーのコマンド入力が実行される方法を制御します。キーマップは、実際にはCARがシンボルkeymap
であるようなリストです。
キーマップの作成、プレフィクスキーの処理、ローカルキーマップやグローバルキーマップ、キーバインドの変更についての情報はキーマップを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
オーバーレイ(overlay)はバッファーの一部に適用するプロパティーを指定します。それぞれのオーバーレイはバッファーの指定された範囲に適用され、プロパティーリスト(プロパティー名と値が交互に記述された要素のリスト)を含みます。オーバーレイプロパティーは、バッファーの指定された一部を、一時的に異なるスタイルで表示するために使用されます。オーバーレイは入力構文をもたず、バッファー名と範囲の位置を与えるハッシュ表記でプリントされます。
オーバーレイを作成したり使用する方法についての情報はオーバーレイを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
fontはグラフィカルな端末上のテキストを表示する方法を指定します。実際には異なる3つのフォント型 — フォントオブジェクト(font objects)、フォントスペック(font specs)、フォントエンティティー(font entities) — が存在します。これらは入力構文をもちません。これらのプリント構文は‘#<font-object>’、‘#<font-spec>’、‘#<font-entity>’のようになります。これらのLispオブジェクトの説明は低レベルのフォント表現を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
複雑なLispオブジェクトでの共有された構造や循環する構造を表すために、リーダー構成‘#n=’と‘#n#’を使用することができます。
後でオブジェクトを参照するには、オブジェクトの前で#n=
を使用します。その後で、他の場所にある同じオブジェクトを参照するために、#n#
を使用することができます。ここでnは任意の整数です。たとえば以下は、1番目の要素が3番目の要素にも繰り替えされるリストを作成する方法です:
(#1=(a) b #1#)
これは、以下のような通常の構文とは異なります
((a) b (a))
これは1番目の要素と3番目の要素がそっくりなリストですが、これらは同じLispオブジェクトではありません。以下で違いを見ることができます:
(prog1 nil (setq x '(#1=(a) b #1#))) (eq (nth 0 x) (nth 2 x)) ⇒ t (setq x '((a) b (a))) (eq (nth 0 x) (nth 2 x)) ⇒ nil
“要素”として自身を含むような循環する構造を作成するために、同じ構文を使用できます。以下は例です:
#1=(a #1#)
これは2番目の要素がそのリスト自身であるリストを作成します。これが実際にうまくいくのか、以下で確認できます:
(prog1 nil (setq x '#1=(a #1#))) (eq x (cadr x)) ⇒ t
変数print-circle
を非nil
値にバインドした場合、Lispプリンターは、循環および共有されるLispオブジェクトを記録するこの構文を生成することができます。出力に影響する変数を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
関数が呼び出されたとき、Emacs Lispインタープリター自身はその関数に渡された実際の引数の型チェックは行ないません。それが行なえないのは、Lispにおける関数の引数は他のプログラミング言語のようなデータ型宣言をもたないからです。したがって実際の引数が、その関数が使用できる型に属するかどうかをテストするのは、それぞれの関数に任されています。
すべてのビルトイン関数は適切なときに実際の引数の型チェックを行い、引数の型が違う場合はwrong-type-argument
エラーをシグナルします。たとえば以下は、+
の引数に+
が扱うことができない引数を渡したとき何が起こるかの例です:
(+ 2 'a) error→ Wrong type argument: number-or-marker-p, a
異なる型にたいして異なる処理をプログラムに行なわせる場合は、明示的に型チェックを行なわなければなりません。オブジェクトの型をチェックするもっとも一般的な方法は型述語(type predicate)関数の呼び出しです。Emacsはそれぞれの型にたいする型述語をもち、組み合わされた型にたいする述語もあります。
型述語関数は1つの引数をとり、その引数が適切な型であればt
、そうでなければnil
をリターンします。述語関数にたいする一般的なLisp慣習にしたがい、ほとんどの型述語の名前は‘p’で終わります。
以下はリストにたいしてチェックを行なう述語listp
と、シンボルにたいしてチェックを行なう述語symbolp
の例です。
(defun add-on (x) (cond ((symbolp x) ;; XがシンボルならLISTにputする (setq list (cons x list))) ((listp x) ;; Xがリストならその要素をLISTに追加 (setq list (append x list))) (t ;; シンボルとリストだけを処理する (error "Invalid argument %s in add-on" x))))
以下のテーブルは事前定義された型述語(アルファベット順)と、さらに情報を得るためのリファレンスです。
atom
atomを参照のこと。
arrayp
arraypを参照のこと。
bool-vector-p
bool-vector-pを参照のこと。
bufferp
bufferpを参照のこと。
byte-code-function-p
byte-code-function-pを参照のこと。
case-table-p
case-table-pを参照のこと。
char-or-string-p
char-or-string-pを参照のこと。
char-table-p
char-table-pを参照のこと。
commandp
commandpを参照のこと。
consp
conspを参照のこと。
custom-variable-p
custom-variable-pを参照のこと。
floatp
floatpを参照のこと。
fontp
低レベルのフォント表現を参照のこと。
frame-configuration-p
frame-configuration-pを参照のこと。
frame-live-p
frame-live-pを参照のこと。
framep
framepを参照のこと。
functionp
functionpを参照のこと。
hash-table-p
hash-table-pを参照のこと。
integer-or-marker-p
integer-or-marker-pを参照のこと。
integerp
integerpを参照のこと。
keymapp
keymappを参照のこと。
keywordp
Variables that Never Changeを参照のこと。
listp
listpを参照のこと。
markerp
markerpを参照のこと。
wholenump
wholenumpを参照のこと。
nlistp
nlistpを参照のこと。
numberp
numberpを参照のこと。
number-or-marker-p
number-or-marker-pを参照のこと。
overlayp
overlaypを参照のこと。
processp
processpを参照のこと。
sequencep
sequencepを参照のこと。
stringp
stringpを参照のこと。
subrp
subrpを参照のこと。
symbolp
symbolpを参照のこと。
syntax-table-p
syntax-table-pを参照のこと。
vectorp
vectorpを参照のこと。
window-configuration-p
window-configuration-pを参照のこと。
window-live-p
window-live-pを参照のこと。
windowp
windowpを参照のこと。
booleanp
booleanpを参照のこと。
string-or-null-p
string-or-null-pを参照のこと。
あるオブジェクトがどの型かチェックするもっとも一般的な方法は、関数type-of
の呼び出しです。オブジェクトは、ただ1つだけの基本型に属することを思い出してください。type-of
は、それがどの型かを告げます(Lispのデータ型を参照)。しかしtype-of
は基本型以外の型については何も知りません。ほとんどの場合では、type-of
より型述語を使用するほうが便利でしょう。
この関数はobjectの基本型を名前とするシンボルをリターンする。リターン値はシンボルbool-vector
、buffer
、char-table
、compiled-function
、cons
、finalizer
、float
、font-entity
、font-object
、font-spec
、frame
、hash-table
、integer
、marker
、overlay
、process
、string
、subr
、symbol
、vector
、window
、window-configuration
のいずれか。
(type-of 1) ⇒ integer
(type-of 'nil)
⇒ symbol
(type-of '()) ; ()
はnil
です。
⇒ symbol
(type-of '(x))
⇒ cons
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ここでは2つのオブジェクトの同一性をテストする関数を説明します。(たとえば文字列などの)特定の型のオブジェクト同士で内容の同一性をテストするのは、別の関数を使用します。これらの述語にたいしては、そのデータ型を説明する適切なチャプターを参照してください。
この関数はobject1とobject2が同じオブジェクトならt
、それ以外はnil
をリターンする。
object1とobject2が同じ値をもつ整数なら、これらは同じオブジェクトと判断される(eq
はt
をリターンする)。object1とobject2が同じ名前のシンボルなら、通常は同じオブジェクトであるが例外もある。シンボルの作成とinternを参照のこと。(リストやベクター、文字列などの)他の型にたいしては、同じ内容(または要素)の2つの引数が両者eq
である必要はない。これらが同じオブジェクトの場合だけeq
であり、その場合は一方の内容を変更するともう一方の内容にも同じ変更が反映される。
(eq 'foo 'foo) ⇒ t
(eq 456 456) ⇒ t
(eq "asdf" "asdf") ⇒ nil
(eq "" "") ⇒ t ;; この例外は省スペースのためにEmacs Lispが ;; マルチバイトの空文字列を1つだけ作成するため
(eq '(1 (2 (3))) '(1 (2 (3)))) ⇒ nil
(setq foo '(1 (2 (3)))) ⇒ (1 (2 (3))) (eq foo foo) ⇒ t (eq foo '(1 (2 (3)))) ⇒ nil
(eq [(1 2) 3] [(1 2) 3]) ⇒ nil
(eq (point-marker) (point-marker)) ⇒ nil
make-symbol
関数はinternされていないシンボルをリターンする。これはLisp式内でその名前を記述したシンボルとは区別される。同じ名前の異なるシンボルはeq
ではない。シンボルの作成とinternを参照のこと。
(eq (make-symbol "foo") 'foo) ⇒ nil
この関数はobject1とobject2が同じ構成要素をもつならt
、それ以外はnil
をリターンする。eq
が引数が同じオブジェクトなのかテストするのにたいして、equal
は同一でない引数の内部を調べて、それらの要素または内容が同一化をテストする。したがって2つのオブジェクトがeq
ならばそれらはequal
だが、その逆は常に真ではない。
(equal 'foo 'foo) ⇒ t
(equal 456 456) ⇒ t
(equal "asdf" "asdf") ⇒ t
(eq "asdf" "asdf") ⇒ nil
(equal '(1 (2 (3))) '(1 (2 (3)))) ⇒ t
(eq '(1 (2 (3))) '(1 (2 (3)))) ⇒ nil
(equal [(1 2) 3] [(1 2) 3]) ⇒ t
(eq [(1 2) 3] [(1 2) 3]) ⇒ nil
(equal (point-marker) (point-marker)) ⇒ t
(eq (point-marker) (point-marker)) ⇒ nil
文字列の比較はcaseを区別するがテキストプロパティーは考慮しない — これは文字列内の文字だけを比較する。テキストのプロパティを参照のこと。テキストプロパティーも比較する場合には、equal-including-properties
を使用すること。技術的な理由によりユニバイト文字列とマルチバイト文字列は、それらが同じ文字シーケンスを含みすべてのコードが0から127(ASCII)、または160から255(8ビットグラフィック
)の場合に限りequal
となる(テキストの表現方法を参照)。
(equal "asdf" "ASDF") ⇒ nil
しかし2つの別のバッファーは、それらのテキスト内容が同じでもequal
と判断されることはない。
equal
のテストは再帰的に実装されています。たとえば2つのコンスセルxとyを与えると、(equal
x y)
は、以下の式の両方がt
をリターンする場合だけt
をリターンします:
(equal (car x) (car y)) (equal (cdr x) (cdr y))
これは再帰処理なので循環するリストがあると無限再帰となる(エラーとなる)。
この関数はすべてのケースにおいてequal
と同様に振る舞うが、2つの文字列がequal
になるためには、それらが同じテキストプロパティーをもつ必要がある。
(equal "asdf" (propertize "asdf" 'asdf t)) ⇒ t
(equal-including-properties "asdf" (propertize "asdf" 'asdf t)) ⇒ nil
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU Emacsは2つの数値データ型 — 整数(integers)と浮動小数点数(floating-point numbers)をサポートします。整数は-3、0、7、13、511などの整数です。浮動小数点数は-4.5、0.0、2.71828などの小数部をもちます。これらは指数記数法でも表現できます — ‘1.5e2’は‘150.0’と同じです。ここで‘e2’は10の2乗を表し、それに1.5を乗じるという意味です。整数計算はオーバーフローするときもありますが正確です。浮動小数点数の計算にでは、数値は固定された精度をもつので、しばしば丸め誤差(rounding errors)が発生します。
3.1 整数の基礎 | 整数の表現と範囲。 | |
3.2 浮動小数点数の基礎 | 浮動少数の表現と範囲。 | |
3.3 数値のための述語 | 数にたいするテスト。 | |
3.4 数値の比較 | 同一性と非同一性の述語。 | |
3.5 数値の変換 | 浮動小数点数から整数の変換と逆変換。 | |
3.6 算術演算 | 加減乗除の方法。 | |
3.7 丸め処理 | 浮動小数点数の明示的な丸め。 | |
3.8 ビット演算 on Integers | 論理的なand、or、not、shift。 | |
3.9 標準的な数学関数 | 三角関数、指数、対数関数。 | |
3.10 乱数 | 予測可能または不可能な乱数の取得。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
整数の値の範囲はマシンに依存します。最小の範囲は-536,870,912から536,870,911(30ビット長の -2**29 から 2**29 - 1) ですが、多くのマシンはこれより広い範囲を提供します。このチャプターの例の多くは、最小の整数が30ビット長であると仮定します。
Lispリーダーは、数字のシーケンス(オプションで最初の符号記号と最後のピリオドをともなう)として整数を読み取ります。Emacsの範囲を超える整数は浮動小数点数として扱われます。
1 ; 整数1 1. ; 整数1 +1 ; これも整数1 -1 ; 整数-1 9000000000000000000 ; 浮動小数点数9e18 0 ; 整数0 -0 ; 整数0
基数が10以外の整数の構文では‘#’の後に基数を指定する文字 — 2進は‘b’、8進は‘o’、16進は‘x’、‘radixr’は基数radix — を記述します。基数を指定する文字のcaseは区別されません。したがって‘#binteger’はintegerを2進として読み取り、‘#radixrinteger’はintegerを基数radixとして読み取ります。radixに指定できる値は2から36です。たとえば:
#b101100 ⇒ 44 #o54 ⇒ 44 #x2c ⇒ 44 #24r1k ⇒ 44
整数にたいして処理を行なうさまざまな関数、特にビット演算(ビット演算 on Integersを参照)を理解するためには、数を2進形式で見ることが助けになることがよくあります。
30ビットの2進では10進数の整数5は以下のようになります:
0000...000101 (全部で30ビット)
(‘...’は30ビットのワードを満たすのに充分なビットを意味しており、この場合の‘...’は12個の0ビットを意味する。以下の例でも2進の整数を読みやすくするために、‘...’の表記を使用している。)
整数の-1は以下のようになります:
1111...111111 (全部で30ビット)
-1から4を減じることで負の整数-5が得られます。10進の整数4は2進では100です。したがって-5は以下のようになります:
1111...111011 (全部で30ビット)
この実装では、0ビットの2進の最大は10進の536,870,911です。これは2進では以下のようになります:
0111...111111 (全部で30ビット)
算術関数は整数が範囲外かどうかをチェックしないので、536,870,911に1を加えるとその値は負の整数-536,870,912になります:
(+ 1 536870911) ⇒ -536870912 ⇒ 1000...000000 (全部で30ビット)
このチャプターで説明する多くの関数は、数字の位置として引数にマーカー(マーカーを参照)を受け取ります。そのような関数にたいする実際の引数は数字かマーカーなので、わたしたちはこれらの引数にnumber-or-markerという名前を与えることがあります。引数の値がマーカーならマーカーの位置が使用され、マーカーのバッファーは無視されます。
この変数の値はEmacs Lispが扱える整数の最大値。典型的な値は32ビットでは 2**29 - 1 、64ビットでは 2**61 - 1 。
この変数の値はEmacs Lispが扱える最小の整数。これは負の整数になる。典型的な値は32ビットでは -2**29 、64ビットでは -2**61、 。
Emacs
Lispでは、テキスト文字は整数により表現されます。0から(max-char)
までの整数は、有効な文字として判断されます。文字コードを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
浮動小数点数は整数ではない数を表現するのに有用です。浮動小数点数の範囲は、使用しているマシンでのCデータ型のdouble
と同じ範囲です。Emacsで現在サポートされているすべてのコンピューターでは、これは倍精度のIEEE浮動小数点数です。
浮動小数点数にたいする入力構文は、小数点と指数のどちらか1つ、または両方が必要とします。オプションの符号(‘+’か‘-’)は、その数字と指数の前に記述します。たとえば‘1500.0’、‘+15e2’、‘15.0e+2’、‘+1500000e-3’、‘.15e4’は値が1500の浮動小数点数を記述する5つの方法です。これらはすべて等価です。Common Lispと同様、Emacs Lispは浮動小数点数の小数点の後に少なくとも1つの数字を必要とします。‘1500.’は整数であって浮動小数点数ではありません。
Emacs
Lispはequal
と=
に関して、-0.0
を通常の0と数学的に同じものとして扱います。これは、(他の処理がこれらを区別にしても-0.0
と0.0
は数学的に等しいとする)IEEE浮動小数点数規格にしたがっています。
IEEE浮動小数点数規格は浮動小数点数として、正の無限大と負の無限大をサポートします。この規格はNaNまたは“not a
number(数字ではない)”と呼ばれる値クラスも提供します。正しい答えが存在しないような場合に、数学関数はこのような値をリターンします。たとえば(/
0.0 0.0)
はNaNをリターンします。実用に際し、たとえNaN値に符号がついていたとしても、Emacs
Lispでは異なるNaN値に有意な差はありません。
以下は、これらの特別な浮動小数点数にたいする入力構文です:
‘1.0e+INF’と‘-1.0e+INF’
‘0.0e+NaN’と‘-0.0e+NaN’
以下の関数は浮動小数点数を扱うために特化したものです:
この述語は浮動小数引数がNaNならt
、それ以外はnil
をリターンする。
この関数はコンスセル(s
.
e)
をリターンする。ここでsとeは、浮動小数点数の仮数(浮動小数点数を2の指数表現したときの仮数)と指数である。
xが有限ならsは0.5以上1.0未満の浮動小数点数、eは整数で、 x = s * 2**eとなる。 xが0または無限ならsはxと等しくなる。xがNaNならsもNaN。xが0ならeは0。
数値の仮数sと整数の指数eを与えられると、この関数は浮動小数点数 s * 2**eをリターンする。
この関数はx2の符号をx1の値にコピーして結果をリターンする。x1とx2は浮動小数でなければならない。
この関数はxの2進指数をリターンする。より正確には、これは|x|の2を底とする対数を整数に切り下げた値。
(logb 10) ⇒ 3 (logb 10.0e20) ⇒ 69
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションの関数は数値や、特定の数値型にたいしてテストを行ないます。関数integerp
とfloatp
は、引数として任意のLispオブジェクト型をとることができます(でなければ、あまり使用する機会ない)。しかし述語zerop
は引数として数値を要求します。マーカーのための述語のinteger-or-marker-p
、number-or-marker-p
も参照してください。
この述語は引数が浮動小数かどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。
この述語は引数が整数かどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。
この述語は引数が数(整数か浮動小数)かどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。
この述語は引数が正の整数かどうかをテストしてもしそうならt
、それ以外はnil
をリターンする(名前は“natural
numberl: 自然数”が由来)。0は整数と判断される。
wholenump
はnatnump
のシノニム。
この述語は引数が0かどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。引数は数でなければならない。
(zerop x)
は(= x 0)
と等価。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
数が数値的に等しいかのテストには、eq
ではなく通常は=
を使用するべきです。同じ数値をもつ多くの浮動小数オブジェクトが存在するかもしれません。これらを比較するのにeq
を使用する場合、これは2つの値が同じオブジェクトかどうかをテストすることになります。対照的に=
はオブジェクトの数値的な値だけを比較します。
Emacs
Lispでは、それぞれの整数は一意なLispオブジェクトです。したがって整数に関してはeq
は=
と同じです。未知の整数の値の比較に、eq
を使用する方が便利な場合があります。なぜなら未知の値が数でない場合でもeq
はエラーを報告しないからです。対照的に引数が数でもマーカーでもない場合、=
はエラーをシグナルします。しかし整数の比較においてさえ、使用できる場合は=
を使用するのがよいプログラミング習慣です。
数の比較において、2つの数が同じデータ型(どちらも整数か浮動小数)では、同じ値の場合は等しい数として扱うequal
のほうが便利なときもあります。対照的に=
は整数と浮動小数点数を等しい数と扱うことができます。同等性のための述語を参照してください。
他の欠点もあります。浮動小数演算は正確ではないので、浮動小数値を比較するのが悪いアイデアとなるときがよくあります。通常は近似的に等しいことをテストするほうがよいでしょう。以下はこれを行なう関数です:
(defvar fuzz-factor 1.0e-6) (defun approx-equal (x y) (or (= x y) (< (/ (abs (- x y)) (max (abs x) (abs y))) fuzz-factor)))
Common Lispに関する注意: Common Lispは複数ワード整数を実装していて、2つの別の整数オブジェクトが同じ数値的な値をもつことができるので、Common Lispでの数の比較はには常に
=
が要求されます。Emacs Lispの整数は範囲が制限されているため、与えられた値に対応する整数オブジェクトは1つだけです。
この関数はすべての引数が数値的に等しいかどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。
この関数はeq
と同様に振る舞うが引数が両方とも数のときを除く。これは数を型と数値的な値により比較するので、(eql 1.0
1)
はnil
をリターンするが、(eql 1.0 1.0)
と(eql 1
1)
はt
をリターンする。
この関数は引数が数値的に等しいかどうかをテストして、もし異なる場合はt
、等しい場合はnil
をリターンする。
この関数は、各引数それぞれを後の引数より小さいかどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。
この関数は、各引数それぞれが後の引数以下かどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。
この関数は、各引数それぞれが後の引数より大きいかどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。
この関数は、各引数それぞれが後の引数以上かどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。
この関数は引数の最大をリターンする。引数のどれかが浮動小数なら、たとえ最大が整数であっても浮動小数として値がリターンする。
(max 20) ⇒ 20 (max 1 2.5) ⇒ 2.5 (max 1 3 2.5) ⇒ 3.0
この関数は引数の最小をリターンする。引数のどれかが浮動小数なら、たとえ最小が整数であっても浮動小数として値がリターンする。
(min -4 1) ⇒ -4
この関数はnumberの絶対値をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
整数を浮動少数の変換には関数float
を使用します。
これは浮動小数点数に変換されたnumberをリターンする。すでにnumberが浮動小数点数ならfloat
はそれを変更せずにリターンする。
浮動小数点数を整数に変換する関数が4つあります。これらは浮動小数点数を丸める方法が異なります。これらはすべて引数number、およびオプション引数としてdivisorを受け取ります。引数は両方とも整数か浮動小数点数です。divisorがnil
のこともあります。divisorがnil
または省略された場合、これらの関数はnumberを整数に変換するか、それが既に整数の場合は変更せずにリターンします。divisorが非nil
なら、これらの関数はnumberをdivisorで除して結果を整数に変換します。divisorが(整数か浮動小数かに関わらず)0の場合、Emacsはarith-error
エラーをシグナルします。
これは0に向かって丸めることにより整数に変換したnumberをリターンする。
(truncate 1.2) ⇒ 1 (truncate 1.7) ⇒ 1 (truncate -1.2) ⇒ -1 (truncate -1.7) ⇒ -1
これは下方(負の無限大に向かって)に丸めることにより整数に変換したnumberをリターンする。
divisorが指定された場合には、mod
に相当する種類の除算演算を使用して下方に丸めを行う。
(floor 1.2) ⇒ 1 (floor 1.7) ⇒ 1 (floor -1.2) ⇒ -2 (floor -1.7) ⇒ -2 (floor 5.99 3) ⇒ 1
これは上方(正の無限大に向かって)に丸めることにより整数に変換したnumberをリターンする。
(ceiling 1.2) ⇒ 2 (ceiling 1.7) ⇒ 2 (ceiling -1.2) ⇒ -1 (ceiling -1.7) ⇒ -1
これはもっとも近い整数に向かって丸めることにより、整数に変換したnumberをリターンする。2つの整数から等距離にある値の丸めでは、偶数の整数をリターンする。
(round 1.2) ⇒ 1 (round 1.7) ⇒ 2 (round -1.2) ⇒ -1 (round -1.7) ⇒ -2
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs
Lispは伝統的な4つの算術演算(加減乗除)、同様に剰余とmodulusの関数、および1の加算と減算を行う関数を提供します。%
を除き、これらの各関数は引き数として整数か浮動小数を受け取り、浮動小数の引数がある場合は浮動小数点数をリターンします。
Emacs Lispの算術関数は整数のオーバーフローをチェックしません。したがって(1+
536870911)
は-536870912に評価されるかもしれず、それはハードウェアーに依存します。
この関数はnumber-or-marker + 1をリターンする。例えば、
(setq foo 4) ⇒ 4 (1+ foo) ⇒ 5
この関数はCの演算子++
とは異なり、変数をインクリメントしない。この関数は和を計算するだけである。したがって以下を続けて評価すると、
foo ⇒ 4
変数をインクリメントしたい場合は、以下のようにsetq
を使用しなければならない:
(setq foo (1+ foo)) ⇒ 5
この関数はnumber-or-marker - 1をリターンする。
この関数は引数すべてを加算する。引数を与えないと+
は0をリターンする。
(+) ⇒ 0 (+ 1) ⇒ 1 (+ 1 2 3 4) ⇒ 10
-
関数は2つの目的 — 符号反転と減算 —
をもつ。-
に1つの引数を与えると、値は引数の符号を反転したものになる。複数の引数の場合は、number-or-markerからmore-numbers-or-markersまでの各値を蓄積的に減算する。引数がなければ結果は0。
(- 10 1 2 3 4) ⇒ 0 (- 10) ⇒ -10 (-) ⇒ 0
この関数はすべての引数を乗じて積をリターンする。引数がなかれば*
は1をリターンする。
(*) ⇒ 1 (* 1) ⇒ 1 (* 1 2 3 4) ⇒ 24
divisorsが1つ以上ならこの関数はdivisors内の除数で順にnumberを除して、その商をリターンする。divisorsがなければ、この関数は1/number、つまりnumberの逆数をリターンする。各引数には数かマーカーを指定できる。
すべての引数が整数なら、結果は各除算の後に商を0へ向かって丸めることにより得られる整数となる。
(/ 6 2) ⇒ 3
(/ 5 2) ⇒ 2
(/ 5.0 2) ⇒ 2.5
(/ 5 2.0) ⇒ 2.5
(/ 5.0 2.0) ⇒ 2.5
(/ 4.0) ⇒ 0.25
(/ 4) ⇒ 0
(/ 25 3 2) ⇒ 4
(/ -17 6) ⇒ -2
整数を整数0で除するとEmacsはarith-error
エラー(エラーを参照)をシグナルする。浮動小数点数の除算では、非0の数を0で除することで正の無限大または負の無限大を得る(浮動小数点数の基礎を参照)。
この関数はdividendをdivisorで除した後、その剰余を整数でリターンする。引数は整数かマーカーでなければならない。
任意の2つの整数dividendとdivisorにたいして、
(+ (% dividend divisor) (* (/ dividend divisor) divisor))
は、divisorが非0なら常にdividendと等しくなる。
(% 9 4) ⇒ 1 (% -9 4) ⇒ -1 (% 9 -4) ⇒ 1 (% -9 -4) ⇒ -1
この関数はdividendのdivisorにたいするmodulo、言い換えるとdividendをdivisorで除した後の剰余(ただし符号はdivisorと同じ)をリターンする。引数は数かマーカーでなければならない。
%
とは異なりmod
は浮動小数の引数を許す。これは商を整数に下方(負の無限大に向かって)へ丸めて剰余を計算するのにこの商を使用する。
mod
はdivisorが0のとき、両方の引数が整数ならarith-error
エラーをシグナルし、それ以外はNaNをリターンする。
(mod 9 4) ⇒ 1
(mod -9 4) ⇒ 3
(mod 9 -4) ⇒ -3
(mod -9 -4) ⇒ -1
(mod 5.5 2.5) ⇒ .5
任意の2つの数dividendとdivisorにたいして、
(+ (mod dividend divisor) (* (floor dividend divisor) divisor))
は常にdividendになる(ただし引数のどちらかが浮動小数なら、丸め誤差の範囲内で等しく、かつdividendが整数でdivisorが0ならarith-error
となる)。floor
については、数値の変換を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
関数ffloor
、fceiling
、fround
、ftruncate
は浮動小数の引数をとり、値が近くの整数であるような浮動少数をリターンします。ffloor
は一番近い下方の整数、fceiling
は一番近い上方の整数、ftruncate
は0に向かう方向で一番近い整数、fround
は一番近い整数をリターンします。
この関数はfloatを次に小さい整数値に丸めて、その値を浮動小数点数としてリターンする。
この関数はfloatを次に大きい整数値に丸めて、その値を浮動小数点数としてリターンする。
この関数はfloatを0方向の整数値に丸めて、その値を浮動小数点数としてリターンする。
この関数はfloatを一番近い整数値に丸めて、その値を浮動小数点数としてリターンする。2つの整数値との距離が等しい値にたいする丸めでは、偶数の整数をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コンピューターの中では、整数はビット(bit: 0か1の数字)のシーケンスである2進数で表されます。ビット演算は、そのようなシーケンスの中の個々のビットに作用します。たとえばシフト(shifting)はシーケンス全体を1つ以上左または右に移動して、移動されたのと同じパターンを再現します。
Emacs Lispのビット演算は整数だけに適用されます。
lsh
はlogical
shiftの略で、integer1のビットを左にcount個シフトする。countが負なら右にシフトし、シフトにより空きになったビットには0がセットされる。countが負ならlsh
は左端(最上位)に0をシフトするので、integer1が負の場合でも正の結果が生成される。これと対照的なのが以下で説明するash
である。
以下はlsh
でビットパターンの位置を1つ左にシフトする例である。ここでは下位8ビットの2進パターンだけを表示しており、残りのビットはすべて0である。
(lsh 5 1) ⇒ 10 ;; 10進の5が10進の10になる 00000101 ⇒ 00001010 (lsh 7 1) ⇒ 14 ;; 10進の7は10進の14になる 00000111 ⇒ 00001110
この例が示すように、ビットパターンを左に1シフトすると、生成される数は元の数の2倍になる。
ビットパターンを左に2シフトすると、以下の結果が生成される(8ビット2進数):
(lsh 3 2)
⇒ 12
;; 10進の3が10進の12になる
00000011 ⇒ 00001100
一方、右に1シフトすると以下のようになる:
(lsh 6 -1)
⇒ 3
;; 10進の6は10進の3になる
00000110 ⇒ 00000011
(lsh 5 -1)
⇒ 2
;; 10進の5は10進の2になる
00000101 ⇒ 00000010
例で明らかなように右に1シフトすることにより、正の整数の値が2で除され下方に丸められる。
関数lsh
は他のEmacs
Lisp算術関数と同様、オーバーフローをチェックしないので、左にシフトすることにより上位ビットが捨てられ、その数の符号が変化するかもしれない。たとえば30ビットの実装では、536,870,911を左にシフトすると-2が生成されます。
(lsh 536870911 1) ; 左シフト
⇒ -2
2進ではこの引数は以下のようになる:
;; 10進の536,870,911
0111...111111 (全部で30ビット)
これを左にシフトすると以下のようになる:
;; 10進の-2
1111...111110 (全部で30ビット)
ash
(算術シフト(arithmetic
shift))は、integer1の中のビット位置を左にcountシフトする。countが負なら右にシフトする。
ash
はlsh
と同じ結果を与えるが、例外はinteger1とcountがいずれも負の場合である。この場合、lsh
は左にできる空きビットに0、ash
は1を置く。
したがってash
でビットパターンの位置を右に1シフトすると以下のようになる:
(ash -6 -1) ⇒ -3
;; 10進の-6は10進の-3になる
1111...111010 (30 bits total)
⇒
1111...111101 (30 bits total)
対照的に、lsh
でビットパターンの位置を1右にシフトすると以下のようになる:
(lsh -6 -1) ⇒ 536870909
;; 10進の-6は10進の536,870,909になる
1111...111010 (30 bits total)
⇒
0111...111101 (30 bits total)
他にも例を示す:
; 30ビットの2進数 (lsh 5 2) ; 5 = 0000...000101 ⇒ 20 ; = 0000...010100
(ash 5 2) ⇒ 20 (lsh -5 2) ; -5 = 1111...111011 ⇒ -20 ; = 1111...101100 (ash -5 2) ⇒ -20
(lsh 5 -2) ; 5 = 0000...000101 ⇒ 1 ; = 0000...000001
(ash 5 -2) ⇒ 1
(lsh -5 -2) ; -5 = 1111...111011 ⇒ 268435454 ; = 0011...111110
(ash -5 -2) ; -5 = 1111...111011 ⇒ -2 ; = 1111...111110
この関数は引数のビットのANDをリターンする。すべての引数のn番目のビットが1の場合に限り、結果のn番目のビットが1となる。
たとえば13と12では、4ビット2進数を使用すると1101と1100のビットANDは1100を生成する。この2進数ではいずれも左の2ビットがセット(つまり1)されているので、リターンされる値の左2ビットがセットされる。しかし右の2ビットにたいしては少なくとも1つの引数でそのビットが0なので、リターンされる値の右2ビットは0になる。
したがって、
(logand 13 12) ⇒ 12
logand
に何も引数も渡さなければ、値-1がリターンされる。-1を2進数で表すとすべてのビットが1なので、-1はlogand
にたいする単位元(identity
element)である。
; 30ビット2進数 (logand 14 13) ; 14 = 0000...001110 ; 13 = 0000...001101 ⇒ 12 ; 12 = 0000...001100
(logand 14 13 4) ; 14 = 0000...001110 ; 13 = 0000...001101 ; 4 = 0000...000100 ⇒ 4 ; 4 = 0000...000100
(logand)
⇒ -1 ; -1 = 1111...111111
この関数は、引数のビット単位の包含的ORをリターンする。少なくとも1つの引数でn番目のビットが1なら、結果のn番目のビットが1になる。引数を与えなければ、結果はこの処理にたいする単位元である0となる。logior
に渡す引数が1つだけならその引数がリターンされる。
; 30ビット2進数 (logior 12 5) ; 12 = 0000...001100 ; 5 = 0000...000101 ⇒ 13 ; 13 = 0000...001101
(logior 12 5 7) ; 12 = 0000...001100 ; 5 = 0000...000101 ; 7 = 0000...000111 ⇒ 15 ; 15 = 0000...001111
この関数は、引数のビット単位の排他的ORをリターンする。n番目のビットが1であるような引数の数が奇数個の場合のみ、結果のn番目のビットが1となる。引数を与えなければ、結果はこの処理の単位元である0となる。logxor
に渡す引数が1つだけならその引数がリターンされる。
; 30ビット2進数 (logxor 12 5) ; 12 = 0000...001100 ; 5 = 0000...000101 ⇒ 9 ; 9 = 0000...001001
(logxor 12 5 7) ; 12 = 0000...001100 ; 5 = 0000...000101 ; 7 = 0000...000111 ⇒ 14 ; 14 = 0000...001110
この関数は引数のビット単位の補数(bitwise complement)をリターンする。integerのn番目のビットが0の場合に限り、結果のn番目のビットが1になり、その逆も成り立つ。
(lognot 5) ⇒ -6 ;; 5 = 0000...000101 (全部で30ビット) ;; becomes ;; -6 = 1111...111010 (全部で30ビット)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の数学的関数は、引数として整数と同様に浮動小数点数も受け入れます。
これらは三角関数であり、引数argはラジアン単位。
(asin arg)
の値は、sinの値がargとなるような
-pi/2
から
pi/2
(両端を含む)の数である。argが範囲外([-1, 1]の外)なら、asin
はNaNをリターンする。
(acos arg)
の値は、cosの値がargとなるような、0から
pi
(両端を含む)の数である。argが範囲外([-1, 1]の外)ならacos
はNaNをリターンする。
(atan y)
の値は、tanの値がyとなるような、
-pi/2
から
pi/2
(両端を含まず)の数である。オプションの第2引数xが与えられると、(atan y
x)
の値はベクトル[x, y]
とX
軸が成す角度のラジアン値となる。
これは指数関数である。この関数はeの指数argをリターンする。
この関数は底をbaseとするargの対数をリターンする。baseを指定しなければ、自然底(natural
base)eが使用される。argかbaseが負なら、log
はNaNをリターンする。
この関数はxにyを乗じてリターンする。引数が両方とも整数でyが正なら結果は整数になる。この場合オーバーフローによる切り捨てが発生するので注意しされたい。xが有限の負数でyが有限の非整数なら、expt
はNaNをリターンする。
これはargの平方根をリターンする。argが有限で0より小さければ、sqrt
はNaNをリターンする。
加えて、Emacsは以下の数学的な定数を定義します:
自然対数e(2.71828…)
円周率pi(3.14159…)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
決定論的なコンピュータープログラムでは真の乱数を生成することはできません。しかしほとんどの目的には、疑似乱数(pseudo-random numbers)で充分です。一連の疑似乱数は決定論的な手法により生成されます。真の乱数ではありませんが、それらにはランダム列を模する特別な性質があります。たとえば疑似ランダム系では、すべての可能な値は均等に発生します。
疑似乱数はシード値(seed
value)から生成されます。与えられた任意のシードから開始することにより、random
関数は常に同じ数列を生成します。デフォルトでは、Emacsは開始時に乱数シードを初期化することにより、それぞれのEmacsの実行において、random
の値シーケンスは(ほとんど確実に)異なります。
再現可能な乱数シーケンスが欲しい場合もあります。たとえば乱数シーケンスに依存するプログラムをデバッグする場合、プログラムの各実行において同じ挙動を得ることが助けになります。再現可能なシーケンスを作成するには、(random
"")
を実行します。これは特定のEmacsの実行可能ファイルにたいして、シードに定数値をセットします(しかしこの実行可能ファイルは、その他のEmacsビルドと異なるものになるであろう)。シード値として、他のさまざまな文字列を使用することができます。
この関数は疑似乱数の整数をリターンする。繰り返し呼び出すと一連の疑似乱数の整数をリターンする。
limitが正なら、値は負ではないlimit未満の値から選択される。それ以外なら値はmost-negative-fixnum
からmost-positive-fixnum
の間の、Lispで表現可能な任意の整数(整数の基礎を参照)となるだろう。
limitがt
なら、あたかもEmacsが再起動されたかのように、通常はシステムのエントロピーから新たなシードが選択されることを意味する。エントロピープールを欠くシステムでは、カレント時刻のような若干揮発性が低い乱数からシードが選択される。
limitが文字列なら、その文字列定数にもとづいた新しいシードを選択することを意味する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispの文字列は、文字列の順序列(ordered sequence)を含む配列です。文字列はシンボル、バッファー、ファイルの名前に使用されます。その他にもユーザーにたいしてメッセージを送ったりバッファー間でコピーする文字列を保持したり等、多くの目的に使用されます。文字列は特に重要なので、Emacs Lispは特別には文字列を操作するために多くの関数があります。Emacs Lispプログラムでは個々の文字より文字列を多用します。
キーボードの文字イベントの文字列にたいする特別な考慮は、文字列内へのキーボードイベントの配置を参照してください。
4.1 文字列と文字の基礎 | 文字列と文字の基本的なプロパティー。 | |
4.2 文字列のための述語 | オブジェクトが文字列か文字かをテストする。 | |
4.3 文字列の作成 | 新しい文字列を割り当てる関数。 | |
4.4 文字列の変更 | 既存の文字列の内容を変更する。 | |
4.5 文字および文字列の比較 | 文字または文字列を比較する。 | |
4.6 文字および文字列の変換 | 文字から文字列への変換と逆変換。 | |
4.7 文字列のフォーマット | format : printf のEmacs版。
| |
4.8 Lispでの大文字小文字変換 | 大文字小文字の変換関数。 | |
4.9 caseテーブル | case変換のカスタマイズ。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
文字(character)とは、テキスト内の1つの文字を表すLispオブジェクトです。Emacs Lispでは文字は単なる整数です。ある整数が文字か文字でないかを区別するのは、それが使用される方法だけです。Emacsでの文字表現についての詳細は文字コードを参照してください。
文字列(string)とは固定された文字シーケンスです。これは配列(array)と呼ばれるシーケンス型であり、配列長が固定で一度作成したら変更できないことを意味します(シーケンス、配列、ベクターを参照)。Cとは異なり、Emacs Lispの文字列は文字コードを判断することにより終端されません。
文字列は配列であるということは同様にシーケンスでもあるので、シーケンス、配列、ベクターにドキュメントされている一般的な配列関数やシーケンス関数で文字列を処理できます。たとえば文字列内の特定の文字にアクセスしたり変更することができます。しかし表示された文字列の幅を計算するために、length
を使用するべきではないことに注意してください。かわりにstring-width
を使用してください(表示されるテキストのサイズを参照)。
Emacs文字列での非ASCIIにたいすテキスト表現は2つ — ユニバイト(unibyte)とマルチバイト(multibyte)があります。ほとんどのLispプログラミングでは、これら2つの表現を気にする必要はありません。詳細はテキストの表現方法を参照してください。
キーシーケンスがユニバイト文字列で表されることがあります。ユニバイト文字列がキーシーケンスの場合、範囲128から255までの文字列要素は範囲128から255の文字コードではなく、メタ文字(これは非常に大きな整数である)を表します。文字列はハイパー(hyper)、スーパー(super)、アルト(alt)で修飾された文字を保持できません。文字列はASCIIコントロール文字を保持できますが、それは他のコントロール文字です。文字列はASCIIコントロール文字のcaseを区別できません。そのような文字をシーケンスに保存したい場合は、文字列ではなくベクターを使用しなければなりません。キーボード入力文字についての情報は文字型を参照してください。
文字列は正規表現を保持するために便利です。string-match
(正規表現の検索を参照)を使用して、文字列にたいして正規表現をマッチすることもできます。関数match-string
(単純なマッチデータへのアクセスを参照)とreplace-match
(マッチしたテキストの置換を参照)は、文字列にたいして正規表現をマッチした後に、文字列を分解・変更するのに便利です。
バッファーのように、文字列は文字列内の文字自身とその文字にたいするテキストプロパティーを含みます。テキストのプロパティを参照してください。文字列からバッファーや他の文字列にテキストをコピーする、すべてのLispプリミティブ(Lisp primitives)はコピーされる文字のプロパティーもコピーします。
文字列の表示やバッファーにコピーする関数についての情報はテキストを参照してください。文字または文字列の構文についての情報は、文字型と文字列型を参照してください。異なるテキスト表現間で変換したり、文字コードをエンコード、デコードする関数については非ASCII文字を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
一般的なシーケンスや配列にたいする述語についての情報は、シーケンス、配列、ベクターと配列を参照してください。
この関数はobjectが文字列ならt
、それ以外はnil
をリターンする。
この関数はobjectが文字列かnil
ならt
、それ以外はnil
をリターンする。
この関数はobjectが文字列か文字(たとえば整数)ならt
、それ以外はnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数は新たに文字列を作成したり、文字列同士の結合による文字列の作成や、文字列の一部から文字列を作成する関数です。
この関数はcharacterをcount回繰り返すことにより作成された文字列をリターンする。countが負ならエラーをシグナルする。
(make-string 5 ?x) ⇒ "xxxxx" (make-string 0 ?x) ⇒ ""
この関数に対応する他の関数にはmake-vector
(ベクターを参照)やmake-list
(コンスセルおよびリストの構築を参照)が含まれる。
この関数は文字charactersを含む文字列をリターンする。
(string ?a ?b ?c) ⇒ "abc"
この関数はstringから、インデックスstartの文字(その文字を含む)とendの文字(その文字は含まない)の間の範囲の文字で構成される、新しい文字列をリターンする。文字列の最初の文字はインデックス0。引数が1つなら、この関数は単にstringをコピーする。
(substring "abcdefg" 0 3) ⇒ "abc"
上記の例では‘a’のインデックスは0、‘b’のインデックスは1、‘c’のインデックスは2となる。インデックス3 —
この文字列の4番目の文字 —
は、コピーされる部分文字列の文字位置までをマークする。したがって文字列"abcdefg"
から‘abc’がコピーされる。
負の数は文字列の最後から数えることを意味するので、-1は文字列の最後の文字のインデックスである。たとえば:
(substring "abcdefg" -3 -1) ⇒ "ef"
この例では‘e’のインデックスは-3、‘f’のインデックスは-2、‘g’のインデックスは-1。つまり‘e’と‘f’が含まれ、‘g’は含まれない。
endにnil
を使用した場合、それは文字列の長さを意味する。したがって、
(substring "abcdefg" -3 nil) ⇒ "efg"
引数endを省略した場合、それはnil
を指定したのと同じである。(substring string
0)
はstringのすべてをコピーしてリターンする。
(substring "abcdefg" 0) ⇒ "abcdefg"
しかしこの目的のためにはcopy-sequence
を推奨する(シーケンスを参照)。
stringからコピーされた文字がテキストプロパティーをもつなら、そのプロパティーは新しい文字列へもコピーされる。テキストのプロパティを参照のこと。
substring
の最初の引数にはベクターも指定できる。たとえば:
(substring [a b (c) "d"] 1 3) ⇒ [b (c)]
startが整数でない、またはendが整数でもnil
でもななければ、wrong-type-argument
エラーがシグナルされる。startがendの後の文字を指す、またはstringにたいして範囲外の整数をいずれかに指定すると、args-out-of-range
エラーがシグナルされる。
この関数に対応するのはbuffer-substring
(バッファーのコンテンツを調べるを参照)で、これはカレントバッファー内のテキストの一部を含む文字列をリターンする。文字列の先頭はインデックス0だが、バッファーの先頭はインデックス1である。
これはsubstring
と同じように機能するが、値のすべてのテキストプロパティーを破棄する。startを省略したりnil
を指定することができ、その場合は0と等価だる。したがって(substring-no-properties string)
は、すべてのテキストプロパティーが削除されたstringのコピーをリターンする。
この関数は渡された引数内の文字からなる、新しい文字列をリターンする(もしあればテキストプロパティーも)。引数には文字列、数のリスト、数のベクターを指定できる。引数は変更されない。concat
に引数を指定しなければ空文字列をリターンする。
(concat "abc" "-def")
⇒ "abc-def"
(concat "abc" (list 120 121) [122])
⇒ "abcxyz"
;; nil
hあ空のシーケンス。
(concat "abc" nil "-def")
⇒ "abc-def"
(concat "The " "quick brown " "fox.")
⇒ "The quick brown fox."
(concat)
⇒ ""
この関数は常に、任意の既存文字列にたいしてeq
ではない、新しい文字列を構築するが、結果が空文字列の時を除く(スペース省略のためにEmacsは空のマルチバイト文字列を1つだけ作成する)。
他の結合関数(concatenation functions)についての情報は関数のマッピングのmapconcat
、ベクターのための関数のvconcat
、コンスセルおよびリストの構築のappend
を参照のこと。シェルコマンドで使用される文字列の中に、個々のコマンドライン引数を結合するには、combine-and-quote-stringsを参照されたい。
この関数は正規表現separators(正規表現を参照)にもとづいて、stringを部分文字列に分解する。separatorsにたいする各マッチは分割位置を定義する。分割位置の間にある部分文字列をリストにまとめてリターンする。
omit-nullsがnil
(または省略)なら、連続する2つのseparatorsへのマッチか、stringの最初か最後にマッチしたときの空文字列が結果に含まれる。omit-nullsがt
なら、これらの空文字列は結果から除外される。
separatorsがnil
(または省略)なら、デフォルトはsplit-string-default-separators
の値となる。
特別なケースとしてseparatorsがnil
(または省略)なら、常に結果から空文字列が除外される。したがって:
(split-string " two words ") ⇒ ("two" "words")
有用性はほとんどないであろう("" "two" "words"
"")
という結果とはならない。このような結果が必要ならseparatorsに明示的な値を使用すること
(split-string " two words " split-string-default-separators) ⇒ ("" "two" "words" "")
他にも例を示す:
(split-string "Soup is good food" "o") ⇒ ("S" "up is g" "" "d f" "" "d") (split-string "Soup is good food" "o" t) ⇒ ("S" "up is g" "d f" "d") (split-string "Soup is good food" "o+") ⇒ ("S" "up is g" "d f" "d")
空のマッチはカウントされます。例外は、空でないマッチを使用することにより、すでに文字列の最後に到達しているとき、またはstringが空の時で、この場合split-string
は最後の空マッチを探しません。
(split-string "aooob" "o*") ⇒ ("" "a" "" "b" "") (split-string "ooaboo" "o*") ⇒ ("" "" "a" "b" "") (split-string "" "") ⇒ ("")
しかしseparatorsが空文字列にマッチできるとき、通常はomit-nullsをt
にすれば、前の3つの例の不明瞭さはほとんど発生しない:
(split-string "Soup is good food" "o*" t) ⇒ ("S" "u" "p" " " "i" "s" " " "g" "d" " " "f" "d") (split-string "Nice doggy!" "" t) ⇒ ("N" "i" "c" "e" " " "d" "o" "g" "g" "y" "!") (split-string "" "" t) ⇒ nil
空でないマッチより空のマッチを優先するような、一部の“非貪欲(non-greedy)”な値をseparatorsに指定することにより、幾分奇妙(ではあるが予見可能)な振る舞いが発生することがある。繰り返しになるが、そのような値は実際には稀である:
(split-string "ooo" "o*" t) ⇒ nil (split-string "ooo" "\\|o+" t) ⇒ ("o" "o" "o")
オプションの引数trimが非nil
なら、その値は各部分文字列の最初と最後からトリム(trim:
除去)するテキストにマッチする正規表現を指定する。トリムによりその部分文字列が空になるようなら、それは空文字列として扱われる。
文字列を分割してcall-process
やstart-process
に適するような、個々のコマンドライン引数のリストにする必要がある場合は、split-string-and-unquoteを参照されたい。
split-string
のseparatorsにたいするデフォルト値。通常の値は"[ \f\t\n\r\v]+"
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
既存の文字列の内容を変更するもっとも基本的な方法は、aset
(配列を操作する関数を参照)を使用する方法です。(aset string idx
char)
は、stringのインデックスidxに、charを格納します。それぞれの文字は1文字以上を占有しますが、すでにインデックスの場所にある文字のバイト数がcharが要するバイト数と異なる場合、aset
はエラーをシグナルします。
より強力な関数はstore-substring
です:
この関数はインデックスidxで開始される位置にobjを格納することにより、文字列stringの内容の一部を変更する。objは文字、または(stringより小さい)文字列です。
既存の文字列の長さを変更するのは不可能なので、stringの実際の長さにobjが収まらない、またはstringのその位置に現在ある文字のバイト数が新しい文字に必要なバイト数と異なる場合はエラーになる。
パスワードを含む文字列をクリアーするときにはclear-string
を使用します:
これはstringをユニバイト文字列にして、内容を0にクリアーする。これによりstringの長さも変更されるだろう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数は引数が同じ文字を表すならt
、それ以外はnil
をリターンする。case-fold-search
が非nil
なら、この関数はcaseの違いを無視する。
(char-equal ?x ?x) ⇒ t (let ((case-fold-search nil)) (char-equal ?x ?X)) ⇒ nil
この関数は、2つの文字列の文字が正確にマッチすればt
をリターンする。引数にはシンボルも指定でき、この場合はそのシンボル名が使用される。case-fold-search
とは無関係にcaseは常に意味をもつ。
この関数は、equal
で2つの文字列を比較するのと等価である(同等性のための述語を参照)。特に、2つの文字列のテキストプロパティーは無視されます。テキストプロパティーだけが異なる文字列を区別する必要があるならequal-including-properties
を使用すること。しかしequal
とは異なり、いずれかの引数が文字列でもシンボルでもなければ、string=
はエラーをシグナルする。
(string= "abc" "abc") ⇒ t (string= "abc" "ABC") ⇒ nil (string= "ab" "ABC") ⇒ nil
技術的な理由によりユニバイト文字列とマルチバイト文字列がequal
になるのは、それらが同じ文字コードのシーケンスを含み、それらすべてのコードが0から127(ASCII)、または160から255(eight-bit-graphic
)のときだけである。しかしユニバイト文字列をマルチバイト文字列に変更する際、コードが160から255の範囲にあるすべての文字はより高いコードに変換され、ASCII文字は変換されないまま残る。したがってユニバイト文字列とそれを変換したマルチバイト文字列は、その文字列のすべてがASCIIのときだけequal
となる。もしマルチバイト文字列中で文字コード160から255の文字があったとしても、それは完全に正しいとは言えない。結果として、すべてがASCIIではないユニバイト文字列とマルチバイト文字列がequal
という状況は、もしかしたらEmacs
Lispプロプラマーが直面するかもしれない、とても稀で記述的に不可解な状況だといえよう。テキストの表現方法を参照されたい。
string-equal
はstring=
の別名である。
この関数は照合ルール(collation
rules)にもとづいてstring1とstring2が等しければt
をリターンする。照合ルールはstring1とstring2に含まれる文字の辞書順だけではなく、それらの文字間の関係に関する他のルールにより判断される。これは通常は、Emacs実行中のlocale環境により決定される。
たとえば異なるコーディングポイントでも、Unicodeのグレイブアクセント文字のように同じ意味なら等しいとみなされる。
(string-collate-equalp (string ?\uFF40) (string ?\u1FEF)) ⇒ t
オプション引数locale(文字列)は、照合用のカレントlocale識別子(current locale
identifier)をオーバーライドする。値はシステムに依存する。たとえばPOSIXシステムでは"en_US.UTF-8"
、MS-Windowsシステムでは"enu_USA.1252"
のlocaleが適用できるだろう。
ignore-caseが非nil
なら、それらは比較前に小文字に変換される。
MS-WindowsシステムでUnicode互換の照合をエミュレートする場合、MS-Windowsではlocaleのコードセット部分を"UTF-8"
にできないので、w32-collate-ignore-punctuation
に非nil
値をバインドすること。
あるlocale環境をシステムがサポートしなれければ、この関数はstring-equal
と同様に振る舞う。
一般的にファイルシステムは照合ルールが実装するような文字列の言語学的な等価性を尊重しないので、この関数をファイル名の等価性の比較に使用しないこと。
この関数はstring1がstring2のプレフィクス(たとえばstring2がstring1で始まる)なら、非nil
をリターンする。オプションの引数ignore-caseが非nil
ばら、比較においてcaseの違いは無視される。
この関数はsuffixがstringのサフィックス(たとえばstringがsuffixで終わる)なら、非nil
をリターンする。オプションの引数ignore-caseが非nil
なら、比較においてcaseの違いは無視される。
この関数は2つの文字列を1文字ずつ比較する。この関数は同時に2つの文字列をスキャンして、対応する文字同士がマッチしない最初のペアを探す。2つの文字列内で小さいほうの文字がstring1の文字ならstring1が小さいことになり、この関数はt
をリターンする。小さいほうの文字がstring2の文字ならstring1が大きいことになり、この関数はnil
をリターンする。2つの文字列が完全にマッチしたら値はnil
になる。
文字のペアーは文字コードで比較されル。ASCII文字セットでは英小文字は英大文字より高い数値をもつことに留意されたい。数字と区切り文字の多くは英大文字より低い数値をもつ。ASCII文字は任意の非ASCII文字より小さくなる。ユニバイトの非ASCII文字は、任意のマルチバイト非ASCII文字より常に小さくなります(テキストの表現方法を参照)。
(string< "abc" "abd") ⇒ t (string< "abd" "abc") ⇒ nil (string< "123" "abc") ⇒ t
文字列の長さが異なり、string1の長さまでマッチする場合、結果はt
になる。string2の長さまでマッチする場合、結果はnil
になる。文字を含まない文字列は、他の任意の文字列より小さくなる。
(string< "" "abc") ⇒ t (string< "ab" "abc") ⇒ t (string< "abc" "") ⇒ nil (string< "abc" "ab") ⇒ nil (string< "" "") ⇒ nil
引数としてシンボルを指定することもでき、この場合はシンボルのプリント名が比較される。
string-lessp
はstring<
の別名である。
この関数は逆順でstring1とstring2を比較した結果をリタンーする。つまりこれは(string-lessp
string2 string1)
を呼び出すのと等価である。
この関数は照合順でstring1がstring2より小さければt
をリターンする。照合順はstring1とstring2に含まれる文字の辞書順だけではなく、それらの文字間の関係に関するルールによっても判断される。これは通常はEmacs実行中のlocale環境により決定される。
たとえばソートでは区切り文字と空白文字は無視されるだろう(シーケンスを参照)。
(sort '("11" "12" "1 1" "1 2" "1.1" "1.2") 'string-collate-lessp) ⇒ ("11" "1 1" "1.1" "12" "1 2" "1.2")
Cygwinではlocaleと無関係に区切り文字と空白文字が無視されることが決してないように、この振る舞いはシステム依存である。
オプション引数locale(文字列)は、照合用のカレントlocale識別子(current locale
identifier)をオーバーライドする。値はシステムに依存する。たとえばPOSIXシステムでは"en_US.UTF-8"
、MS-Windowsシステムでは"enu_USA.1252"
のlocaleが適用できるだろう。localeの値を"POSIX"
か"C"
にすると、string-collate-lessp
はstring-lessp
と同様に振る舞う。
(sort '("11" "12" "1 1" "1 2" "1.1" "1.2") (lambda (s1 s2) (string-collate-lessp s1 s2 "POSIX"))) ⇒ ("1 1" "1 2" "1.1" "1.2" "11" "12")
ignore-caseが非nil
なら、それらは比較前に小文字に変換される。
MS-WindowsシステムでUnicode互換の照合をエミュレートする場合、MS-Windowsではlocaleのコードセット部分を"UTF-8"
にできないので、w32-collate-ignore-punctuation
に非nil
値をバインドすること。
locale環境をサポートしないシステムでは、この関数はstring-lessp
と同様に振る舞う。
この関数はstring1がstring2のプレフィクス(たとえばstring2がstring1で始まる)なら、非nil
をリターンする。オプションの引数ignore-caseが非nil
ばら、比較においてcaseの違いは無視される。
この関数はsuffixがstringのサフィックス(たとえばstringがsuffixで終わる)なら、非nil
をリターンする。オプションの引数ignore-caseが非nil
なら、比較においてcaseの違いは無視される。
この関数はstring1の指定部分をとstring2指定部分を比較する。string1の指定部分とは、インデックスstart1(その文字を含む)から、インデックスend1(その文字を含まない)まで。start1にnil
を指定すると文字列の最初という意味になり、end1にnil
を指定すると文字列の長さを意味する。同様にstring2の指定部分とはインデックスstart2からインデックスend2まで。
文字列は文字列内の文字の数値により比較される。たとえばstr1とstr2は、最初に異なる文字でstr1の文字の数値が小さければ小さいと判断される。ignore-caseが非nil
なら比較を行なう前に大文字に変換される。比較用にユニバイト文字列はマルチバイト文字列に変換されるので(テキストの表現方法を参照)、ユニバイト文字列とそれを変換したマルチバイト文字列は常に等しくなる。
2つの文字列の指定部分がマッチした場合、値はt
になる。それ以外なら値は整数で、何文字が一致してどちらの文字が小さいかを示す。この値の絶対値は、2つの文字列の先頭から一致した文字数に1加えた値になる。string1(または指定部分)のほうが小さければ符号は負になる。
この関数はassoc
と同様に機能するが、keyは文字列かシンボルでなければならず、比較はcompare-strings
を使用して行なわれる。テストする前にシンボルは文字列に変換される。case-foldが非nil
なら、keyとalistの要素は比較前に大文字に変換される。assoc
とは異なり、この関数はコンスではない文字列またはシンボルのalist要素もマッチできる。特にalistは実際のalistではなく、文字列またはリストでも可。連想リストを参照のこと。
バッファー内のテキストを比較する方法として、テキストの比較の関数compare-buffer-substrings
も参照してください。文字列にたいして正規表現のマッチを行なう関数string-match
も、ある種の文字列比較に使用することができます。正規表現の検索を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは文字、文字列、整数の間で変換を行なう関数を説明します。format
(文字列のフォーマットを参照)とprin1-to-string
(出力関数を参照)もLispオブジェクトを文字列に変換できます。read-from-string
(入力関数を参照)は、Lispオブジェクトの文字列表現をオブジェクトに“変換”できます。関数string-to-multibyte
とstring-to-unibyte
は、テキスト表現を文字列に変換します(テキスト表現の変換を参照)。
テキスト文字と一般的なインプットイベントにたいするテキスト記述を生成する関数(single-key-description
とtext-char-description
)については、ドキュメントを参照してください。これらの関数は主にヘルプメッセージを作成するために使用されます。
この関数はnumberの10進プリント表現からなる文字列をリターンする。引数が負ならリターン値はマイナス記号から開始される。
(number-to-string 256) ⇒ "256"
(number-to-string -23) ⇒ "-23"
(number-to-string -23.5) ⇒ "-23.5"
int-to-string
はこの関数にたいする半ば廃れたエイリアスである。
文字列のフォーマットの関数format
も参照されたい。
この関数はstring内の文字の数値的な値をリターンする。baseが非nil
なら値は2以上16以下でなければならず、整数はその基数に変換される。baseがnil
なら基数に10が使用される。浮動少数点数の変換は基数が10のときだけ機能する。わたしたちは浮動小数点数にたいして他の基数を実装しない。なぜならこれには多くの作業を要し、その割にその機能が有用には思えないからだ。stringが整数のように見えるが、その値がLispの整数に収まらないほど大きな値なら、string-to-number
は浮動小数点数の結果をリターンする。
パースではstringの先頭にあるスペースとタブはスキップして、与えられた基数で数字として解釈できるところまでstringを読み取る(スペースとタブだけではなく先頭にある他の空白文字を無視するシステムもある)。stringを数字として解釈できなければこの関数は0をリターンする。
(string-to-number "256") ⇒ 256 (string-to-number "25 is a perfect square.") ⇒ 25 (string-to-number "X256") ⇒ 0 (string-to-number "-4.5") ⇒ -4.5 (string-to-number "1e5") ⇒ 100000.0
string-to-int
はこの関数にたいする半ば廃れたエイリアスである。
この関数は1つの文字characterを含む新しい文字列をリターンする。関数string
のほうがより一般的であり、この関数は半ば廃れている。文字列の作成を参照のこと。
この関数はstringの最初の文字をリターンする。これはほとんど(aref string
0)
と同じで、例外は文字列が空のときに0をリターンすること(文字列の最初の文字がASCIIコード0のヌル文字のときも0をリターンする)。この関数は残すのに充分なほど有用と思えないければ、将来削除されるかもしれない。
以下は文字列へ/からの変換に使用できるその他の関数です:
concat
この関数はベクターまたはリストから文字列に変換する。文字列の作成を参照のこと。
vconcat
この関数は文字列をベクターに変換する。ベクターのための関数を参照のこと。
append
この関数は文字列をリストに変換する。コンスセルおよびリストの構築を参照のこと。
byte-to-string
この関数は文字データのバイトをユニバイト文字列に変換する。テキスト表現の変換を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フォーマット(formatting)とは、定数文字列内のなまざまな場所を計算された値で置き換えることにより、文字列を構築することを意味します。この定数文字列は他の値がプリントされる方法、同様にどこに表示するかを制御します。これはフォーマット文字列(format string)と呼ばれます。
表示されるメッセージを計算するためにフォーマットが便利なことがしばしばあります。実際に関数message
とerror
は、ここで説明する機能と同じフォーマットを提供します。これらの関数とformat-message
の違いはフォーマットされた結果を使用する方法だけです。
この関数はstringをコピーしてから、対応するobjectsをエンコードする、そのコピー内の任意のフォーマット仕様(format specification)を置換して作成される、新しい文字列をリターンする。引数objectsはフォーマットされる計算された値。
(もしあれば)string内のフォーマット仕様以外の文字は、テキストプロパティーを含めて出力に直接コピーされる。
この関数はformat
と同様に機能するが、text-quoting-style
の各値に応じてstring内のすべてのcurved
single quotes文字も変換して、グレイブアクセント(`)とアポストロフィー(')があたかもcurved single
quotes文字であるかのように扱う点が異なる。
グレイブアクセントとアポストロフィーでクォートされたフォーマット`like this'は、通常はcurved quotesされた‘like
this’を生成する。対照的にアポストロフィーだけでクォートされた'like this'は、通常の英文スタイルであるは2つのclosing
curved quotesでクォートされた’like
this’を生成する。変数text-quoting-style
が生成されるクォートに影響を与える方法については、ドキュメント内でのキーバインディングの置き換えを参照のこと。
フォーマット仕様(format
specification)は‘%’で始まる文字シーケンスです。したがってstring内に‘%d’がるとformat
はそれを、フォーマットされる値の1つ(引数objectsのうちの1つ)にたいするプリント表現で置き換えます。たとえば:
(format "The value of fill-column is %d." fill-column) ⇒ "The value of fill-column is 72."
format
は文字‘%’をフォーマット仕様と解釈するので、決して最初の引数に不定な文字列(arbitrary
string)を渡すべきではありません。これは特に何らかのLispコードga生成siた文字列の場合に当てはまります。その文字列が決して文字‘%’を含まないと確信できないならば、以下で説明するように最初の引数に"%s"
を渡して、不定な文字列を2番目の引数として渡します:
(format "%s" arbitrary-string)
stringに複数のフォーマット仕様が含まれる場合、フォーマット仕様はobjectsから連続して値を引き当てます。つまり、string内の1番目のフォーマット仕様は1番目の値、2番目のフォーマット仕様は2番目の値、...を使用します。余分なフォーマット仕様(対応する値がない場合)にはエラーとなります。フォーマットされる値が余分にある場合は無視されます。
ある種のフォーマット仕様は特定の型の値を要求します。その要求に適合しない値を与えた場合にはエラーがシグナルされます。
以下は有効なフォーマット仕様のテーブルです:
フォーマット仕様を、クォートなしのオブジェクトのプリント表現で置き換える(つまりprin1
ではなくprinc
を使用して置き換える。出力関数を参照されたい)。したがって文字列は‘"’文字なしの文字列内容だけが表示され、シンボルは‘\’文字なしで表される。
オブジェクトが文字列なら文字列のプロパティーは出力にコピーされる。‘%s’のテキストプロパティー自身もコピーされるが、オブジェクトのテキストプロパティーが優先される。
フォーマット仕様を、クォートありのオブジェクトのプリント表現で置き換える(つまりprin1
を使用して変換する。出力関数を参照されたい)。したがって文字列は‘"’文字で囲まれ、必要となる特別文字の前に‘\’文字が表示される。
フォーマット仕様を8進表現の整数で置き換える。
フォーマット仕様を10進表現の整数で置き換える。
フォーマット仕様を16進表現の整数で置き換える。‘%x’なら小文字、‘%X’なら大文字が使用される。
フォーマット仕様を与えられた値の文字で置き換える。
フォーマット仕様を浮動小数点数の指数表現で置き換える。
フォーマット仕様を浮動小数点数にたいする10進少数表記で置き換える。
フォーマット仕様を指数か10進少数のいずれか短いほうの表記を使用した浮動小数点数で置き換える。
フォーマット仕様を1つの‘%’で置き換える。このフォーマット仕様は値を使用しない。たとえば(format "%% %d"
30)
は"% 30"
をリターンする。
他のフォーマット文字は‘Invalid format operation’エラーとなります。
以下は典型的なtext-quoting-style
のセッティングを想定した場合の例です:
(format "The octal value of %d is %o, and the hex value is %x." 18 18 18) ⇒ "The octal value of 18 is 22, and the hex value is 12." (format-message "The name of this buffer is ‘%s’." (buffer-name)) ⇒ "The name of this buffer is ‘strings.texi’." (format-message "The buffer object prints as `%s'." (current-buffer)) ⇒ "The buffer object prints as ‘strings.texi’."
フォーマット仕様はフィールド幅(width)をもつことができます。これは‘%’とフォーマット仕様文字(specification
character)の間の10進の数字です。そのオブジェクトのプリント表現がこのフィールド幅より少ない文字で構成される場合、format
はパディングによりフィールド幅に拡張します。フォーマット仕様‘%%’ではフィールド幅の指定は無視されます。フィールド幅指定子により行なわれるパディングは、通常は左側にスペースを挿入します。
(format "%5d is padded on the left with spaces" 123) ⇒ " 123 is padded on the left with spaces"
フィールド幅が小さすぎる場合でもformat
はオブジェクトのプリント表現を切り詰めません。したがって情報を失う危険を犯すことなく、フィールドの最小幅を指定することができます。以下の2つの例では‘%7s’は最小幅に7を指定します。1番目の例では‘%7s’に挿入される文字列は3文字だけなので、4つのブランクスペースによりパディングされます。2番目の例では文字列"specification"
は13文字ですが切り詰めはされません。
(format "The word '%7s' has %d letters in it." "foo" (length "foo")) ⇒ "The word ' foo' has 3 letters in it." (format "The word '%7s' has %d letters in it." "specification" (length "specification")) ⇒ "The word 'specification' has 13 letters in it."
‘%’の直後、オプションのフィールド幅指定子の前にフラグ文字(flag characters)を置くこともできます。
フラグ‘+’は正の数の前にプラス符号を挿入するので、数には常に符号がつきます。フラグとしてスペースを指定すると、正数の前に1つのスペースが挿入されます(それ以外は、正数は最初の数字から開始される)。これらのフラグは、確実に正数と負数が同じ列数を使用させるために有用です。これらは‘%d’、‘%e’、‘%f’、‘%g’以外では無視され、両方が指定された場合は‘+’が優先されます。
フラグ‘#’は代替形式(alternate form)を指定します。これは使用するフォーマットに依存します。‘%o’にたいしては結果を‘0’で開始させます。‘%x’と‘%X’にたいしては結果のプレフィクスは‘0x’または‘0X’になります。‘%e’、‘%f’、‘%g’にたいしての‘#’フラグは、少数部が0のときにも小数点が含まれることを意味します。
フラグ‘0’はスペースの代わりに文字‘0’でパディングします。このフラグは‘%s’、‘%S’、‘%c’のような非数値のフォーマット仕様文字では無視されます。これらのフォーマット仕様文字で‘0’フラグを指定できますが、それでもスペースでパディングされます。
フラグ‘-’はフィールド幅指定子により挿入されるパディングに作用し、もしパディングがあるなら左側ではなく右側にパディングされます。‘-’と‘0’の両方が指定されると‘0’フラグは無視されます。
(format "%06d is padded on the left with zeros" 123) ⇒ "000123 is padded on the left with zeros" (format "'%-6d' is padded on the right" 123) ⇒ "'123 ' is padded on the right" (format "The word '%-7s' actually has %d letters in it." "foo" (length "foo")) ⇒ "The word 'foo ' actually has 3 letters in it."
すべてのフォーマット仕様文字には、その文字の前(フィールド幅がある場合はその後)に、オプションで精度(precision)を指定できます。精度は小数点‘.’と、その後に桁文字列(digit-string)を指定します。浮動少数点数のフォーマット仕様(‘%e’、‘%f’、‘%g’)では、精度は表示する小数点以下の桁数を指定します。0の場合は小数点も省略されます。‘%s’と‘%S’にたいしては、文字列を精度で指定された幅に切り詰めます。したがって‘%.3s’では、objectにたいするプリント表現の最初の3文字だけが表示されます。他のフォーマット仕様文字にたいしては、精度の効果はローカルライブラリーのprintf
関数ファミリーが生成する効果となります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
case変換関数(character case functions)は、1つの文字または文字列中の大文字小文字を変換します。関数は通常、アルファベット文字(英字‘A’から‘Z’と‘a’から‘z’、同様に非ASCIIの英字)だけを変換し、それ以外の文字は変換しません。caseテーブル(case table。caseテーブルを参照されたい)で指定することにより、caseの変換に異なるマッピングを指定できます。
これらの関数は引数として渡された文字列は変更しません。
以下の例では文字‘X’と‘x’を使用します。これらのASCIIコードは88と120です。
この関数はstring-or-char(文字か文字列)を小文字に変換する。
string-or-charが文字列なら、この関数は引数の大文字を小文字に変換した新しい文字列をリターンする。string-or-charが文字なら、この関数は対応する小文字(整数)をリターンする。元の文字が小文字か非英字ならリターン値は元の文字と同じ。
(downcase "The cat in the hat") ⇒ "the cat in the hat" (downcase ?X) ⇒ 120
この関数はstring-or-char(文字か文字列)を大文字に変換する。
string-or-charが文字列なら、この関数は引数の小文字を大文字に変換した新しい文字列をリターンする。string-or-charが文字なら、この関数は対応する大文字(整数)をリターンする。元の文字が大文字か非英字ならリターン値は元の文字と同じ。
(upcase "The cat in the hat") ⇒ "THE CAT IN THE HAT" (upcase ?x) ⇒ 88
この関数は文字列や文字をキャピタライズ(capitalize: 先頭が大文字で残りは小文字)する。この関数はstring-or-charが文字列ならstring-or-charの各単語をキャピタライズした新たなコピーをリターンする。これは各単語の最初の文字が大文字に変換され、残りは小文字に変換されることを意味する。
単語の定義はカレント構文テーブル(current syntax table)の単語構成構文クラス(word constituent syntax class)に割り当てられた、連続する文字の任意シーケンスである(構文クラスのテーブルを参照)。
string-or-charが文字ならこの関数はupcase
と同じことを行なう。
(capitalize "The cat in the hat") ⇒ "The Cat In The Hat"
(capitalize "THE 77TH-HATTED CAT") ⇒ "The 77th-Hatted Cat"
(capitalize ?x) ⇒ 88
この関数はstring-or-charが文字列なら、string-or-charの中の単語の頭文字をキャピタライズして、頭文字以外の文字は変更しない。この関数はstring-or-charの各単語の頭文字が大文字に変換された新しいコピーをリターンする。
単語の定義はカレント構文テーブル(current syntax table)の単語構成構文クラス(word constituent syntax class)に割り当てられた、連続する文字の任意シーケンスである(構文クラスのテーブルを参照)。
upcase-initials
の引数が文字なら、upcase-initials
の結果はupcase
と同じ。
(upcase-initials "The CAT in the hAt") ⇒ "The CAT In The HAt"
文字列を比較する関数(caseの違いを無視するものや、オプションでcaseの違いを無視できるもの)については、文字および文字列の比較を参照されたい。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
特別なcaseテーブル(case table)をインストールすることにより、caseの変換をカスタマイズできます。caseテーブルは大文字と小文字の間のマッピングを指定します。caseテーブルはLispオブジェクトにたいするcase変換関数(前のセクションを参照)と、バッファー内のテキストに適用される関数の両方に影響します。それぞれのバッファーにはcaseテーブルがあります。新しいバッファーのcaseテーブルを初期化するために使用される、標準のcaseテーブル(standard case table)もあります。
caseテーブルは、サブタイプがcase-table
の文字テーブル(char-table。文字テーブルを参照)です。この文字テーブルはそれぞれの文字を対応する小文字にマップします。caseテーブルは、関連するテーブルを保持する3つの余分なスロットをもちます:
upcase(大文字)テーブルはそれぞれの文字を対応する大文字にマップする。
canonicalize(正準化)テーブルは、caseに関連する文字セットのすべてを、その文字セットの特別なメンバーにマップする。
equivalence(同値)テーブルは、大の字小文字に関連した文字セットのそれぞれを、そのセットの次の文字にマップする。
単純な例では、小文字へのマッピングを指定することだけが必要です。3つの関連するテーブルは、このマッピングから自動的に計算されます。
大文字と小文字が1対1で対応しない言語もいくつかあります。これらの言語では、2つの異なる小文字が同じ大文字にマップされます。このような場合、大文字と小文字の両方にたいするマップを指定する必要があります。
追加のcanonicalizeテーブルは、それぞれの文字を正準化された等価文字にマップします。caseに関連する任意の2文字は、同じ正準等価文字(canonical equivalent character)をもちます。たとえば‘a’と‘A’はcase変換に関係があるので、これらの文字は同じ正準等価文字(両方の文字が‘a’、または両方の文字が‘A’)をもつべきです。
追加のequivalencesテーブルは、等価クラスの文字(同じ正準等価文字をもつ文字)それぞれを循環的にマップします(通常のASCIIでは、これは‘a’を‘A’に‘A’を‘a’にマップし、他の等価文字セットにたいしても同様にマップする)。
caseテーブルを構築する際は、canonicalizeにnil
を指定できます。この場合、Emacsは大文字と小文字のマッピングでこのスロットを充填します。equivalencesにたいしてnil
を指定することもできます。この場合、Emacsはcanonicalizeからこのスロットを充填します。実際に使用されるcaseテーブルでは、これらのコンポーネントは非nil
です。canonicalizeを指定せずにequivalencesを指定しないでください。
以下はcaseテーブルに作用する関数です:
この述語は、objectが有効なcaseテーブルなら非nil
をリターンする。
この関数はtableを標準caseテーブルにして、これ以降に作成される任意のバッファーにたいしてこのテーブルが使用されるようにする。
これは標準caseテーブル(standard case table)をリターンする。
この関数はカレントバッファーのcaseテーブルをリターンする。
これはカレントバッファーのcaseテーブルをtableにセットする。
with-case-table
マクロはカレントcaseテーブルを保存してから、tableをカレントcaseテーブルにセットし、その後にbodyフォームを評価してから、最後にcaseテーブルをリストアします。リターン値は、bodyの最後のフォームの値です。throw
かエラー(非ローカル脱出を参照)により異常終了した場合でも、caseテーブルはリストアされます。
ASCII文字のcase変換を変更する言語環境(language
environment)がいくつかあります。たとえばトルコ語の言語環境では、ASCIIの大文字‘I’にたいする小文字は、トルコ語のドットがないi(‘ı’)です。これは(ASCIIベースのネットワークプロトコル実装のような)ASCIIの通常のcase変換を要求するコードに干渉する可能性があります。このような場合には、変数ascii-case-tableにたいしてwith-case-table
マクロを使用してください。これにより変更されていないASCII文字セットのcaseテーブルが保存されます。
ASCII文字セットにたいするcaseテーブル。すべての言語環境セッティングにおいて、これを変更するべきではない。
以下の3つの関数は、非ASCII文字セットを定義するパッケージにたいして便利なサブルーチンです。これらはcase-tableに指定されたcaseテーブルを変更します。これは標準構文テーブルも変更します。構文テーブルを参照してください。通常これらの関数は、標準caseテーブルを変更するために使用されます。
この関数は対応する文字のペアー(一方は大文字でもう一方は小文字)を指定する。
この関数は文字lとrを、case不変区切り(case-invariant delimiter)のマッチングペアーとする。
この関数はcharを構文syntaxのcase不変(case-invariant)とする。
このコマンドはカレントバッファーのcaseテーブルの内容にたいする説明を表示する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
リスト(list)は0個以上の要素(任意のLispオブジェクト)のシーケンスを表します。リストとベクターの重要な違いは、2つ以上のリストが構造の一部を共有できることです。加えて、リスト全体をコピーすることなく要素の挿入と削除ができます。
5.1 リストとコンスセル | コンスセルからリストが作られる方法。 | |
5.2 リストのための述語 | このオブジェクトはリストか? 2つのリストを比較する。 | |
5.3 リスト要素へのアクセス | リストの一部を抽出する。 | |
5.4 コンスセルおよびリストの構築 | リスト構造の作成。 | |
5.5 リスト変数の変更 | 変数に保存されたリストにたいする変更。 | |
5.6 既存のリスト構造の変更 | 既存のリストに新しい要素を保存する。 | |
5.7 集合としてのリストの使用 | リストは有限な数学集合を表現できる。 | |
5.8 連想リスト | リストは有限な関係またはマッピングを表現できる。 | |
5.9 プロパティリスト | 要素ペアのリスト。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispでのリストは基本データ型ではありません。リストはコンスセル(cons cells)から構築されます(コンスセルとリスト型を参照)。コンスセルは順序つきペアを表現するデータオブジェクトです。つまりコンスセルは2つのスロットをもち、それぞれのスロットはLispオブジェクトを保持(holds)または参照(refers to)します。1つのスロットはCAR、もう1つはCDRです(これらの名前は歴史的なものである。コンスセルとリスト型を参照されたい)。CDRは“could-er(クダー)”と発音します。
わたしたちは、コンスセルのCARスロットに現在保持されているオブジェクトが何であれ、“このコンスセルのCARは、...”のような言い方をします。これはCDRの場合でも同様です。
リストとは互いに連なる(chained together)一連のコンスセルであり、各セルは次のセルを参照します。リストの各要素にたいして1つのコンスセルがあります。慣例によりコンスセルのCARはリストの要素を保持し、CDRはリストをチェーンするのに使用されます(CARとCDRの間の非対称性は完全に慣例的なものである。コンスセルのレベルではCARスロットとCDRスロットは同じようなプロパティーをもつ)。したがって、リスト内の各コンスセルのCDRスロットは次のコンスセルを参照します。
これも慣例的なものですが、リスト内の最後のコンスセルのCDRはnil
です。わたしたちはこのようなnil
で終端された構造を、真リスト(true
list)と呼びます。Emacs
Lispではシンボルnil
はシンボルであり、かつ要素なしのリストでもあります。便宜上、シンボルnil
はそのCDR(とCAR)にnil
をもつと考えます。
したがって真リストのCDRは、常に真リストです。空でない真リストのCDRは、1番目の要素以外を含む真リストです。
リストの最後のコンスセルのCDRがnil
以外の何らかの値の場合、このリストのプリント表現はドットペア表記(dotted pair
notation。ドットペア表記を参照のこと)を使用するので、わたしたちはこの構造をドットリスト(dotted
list)と呼びます。他の可能性もあります。あるコンスセルのCDRが、そのリストのそれより前にある要素を指すかもしれません。わたしたちは、この構造を循環リスト(circular
list)と呼びます。
ある目的においてはそのリストが真リストか、循環リストなのか、ドットリストなのかが問題にならない場合もあります。そのプログラムがリストを充分に辿って最後のコンスセルのCDRを確認しようとしないなら、これは問題になりません。しかしリストを処理する関数のいくつかは真リストを要求し、ドットリストの場合はエラーをシグナルします。リストの最後を探そうと試みる関数のほとんどは、循環リストを与えると無限ループに突入します。
ほとんどのコンスセルはリストの一部として使用されるので、わたしたちはコンスセルで構成される任意の構造をリスト構造(list structure)と呼びます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の述語はあるLispオブジェクトがアトムか、コンスセルか、リストなのか、またはオブジェクトがnil
かどうかテストします(これらの述語の多くは他の述語で定義することもできるが、多用されるので個別に定義する価値がある)。
この関数はobjectがコンスセルならt
、それ以外はnil
をリターンする。たとえnil
がリストであっても、コンスセルではない。
この関数はobjectがアトムならt
、それ以外はnil
をリターンする。シンボルnil
はアトムであり、かつリストでもある。そのようなLispオブジェクトはnil
だけである。
(atom object) ≡ (not (consp object))
この関数はobjectがコンスセルかnil
ならt
、それ以外はnil
をリターンする。
(listp '(1)) ⇒ t
(listp '()) ⇒ t
この関数はlistp
の反対である。objectがリストでなければt
、それ以外はnil
をリターンする。
(listp object) ≡ (not (nlistp object))
この関数はobjectがnil
ならt
、それ以外はnil
をリターンする。この関数はnot
と等価だが、明解にするためにobjectをリストだと考えるときはnull
、真偽値だと考えるときはnot
を使用すること(条件の組み合わせのnot
を参照)。
(null '(1)) ⇒ nil
(null '()) ⇒ t
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はコンスセルcons-cellの1番目のスロットが参照する値をリターンする。言い換えるとこの関数はcons-cellのCARをリターンする。
特別なケースとしてcons-cellがnil
の場合、この関数はnil
をリターンする。したがってリストはすべて引数として有効である。引数がコンスセルでもnil
でもなければエラーがシグナルされる。
(car '(a b c)) ⇒ a
(car '()) ⇒ nil
この関数はコンスセルcons-cellの2番目のスロットにより参照される値をリターンする。言い換えるとこの関数はcons-cellのCDRをリターンする。
特別なケースとしてcons-cellがnil
の場合、この関数はnil
をリターンする。したがってリストはすべて引数として有効である。引数がコンスセルでもnil
でもければエラーがシグナルされる。
(cdr '(a b c)) ⇒ (b c)
(cdr '()) ⇒ nil
この関数により他のデータ型によるエラーを起こさずに、コンスセルのCARを取得できり。この関数はobjectがコンスセルならobjectのCAR、それ以外はnil
をリターンする。この関数は、objectがリストでなければエラーをシグナルするcar
とは対象的である。
(car-safe object) ≡ (let ((x object)) (if (consp x) (car x) nil))
この関数により他のデータ型によるエラーを起こさずに、コンスセルのCDRを取得できる。この関数はobjectがコンスセルならobjectのCDR、それ以外はnil
をリターンする。この関数は、objectがリストでないときはエラーをシグナルするcdr
とは対象的である。
(cdr-safe object) ≡ (let ((x object)) (if (consp x) (cdr x) nil))
このマクロはリストのCARを調べて、それをリストから取り去るのを一度に行なう便利な方法を提供する。この関数はlistnameに格納されたリストにたいして処理を行なう。この関数はリストから1番目の要素を削除して、CDRをlistnameに保存し、その後で削除した要素をリターンする。
もっとも単純なケースは、リストに名前をつけるためのクォートされていないシンボルの場合である。この場合、このマクロは(prog1 (car listname) (setq listname (cdr listname)))
と等価である。
x ⇒ (a b c) (pop x) ⇒ a x ⇒ (b c)
より一般的なのはlistnameが汎変数(generalized
variable)の場合である。この場合、このマクロはsetf
を使用してlistnameに保存する。ジェネリック変数を参照のこと。
リストに要素を追加するpush
マクロについてはリスト変数の変更を参照のこと。
この関数はlistのn番目の要素をリターンする。要素は0から数えられるのでlistのCARは要素0になる。listの長さがn以下なら値はnil
。
(nth 2 '(1 2 3 4)) ⇒ 3
(nth 10 '(1 2 3 4)) ⇒ nil (nth n x) ≡ (car (nthcdr n x))
これは関数elt
も類似しているが、任意の種類のシーケンスに適用される。歴史的な理由によりこの関数は逆の順序で引数を受け取る。シーケンスを参照のこと。
この関数はlistのn番目のCDRをリターンする。言い換えると、この関数はlistの最初のn個のリンクをスキップしてから、それ以降をリターンする。
nが0ならnthcdr
はlist全体をリターンする。listの長さがn以下ならnthcdr
はnil
をリターンする。
(nthcdr 1 '(1 2 3 4)) ⇒ (2 3 4)
(nthcdr 10 '(1 2 3 4)) ⇒ nil
(nthcdr 0 '(1 2 3 4)) ⇒ (1 2 3 4)
この関数はlistの最後のリンクをリターンする。このリンクのcar
はこのリストの最後の要素。listがnullならnil
がリターンされる。nが非nil
ならn番目から最後までのリンクがリターンされる。nがlistの長さより大きければlist全体がリターンされる。
この関数はエラーや無限ループの危険なしで、listの長さをリターンする。この関数は一般的に、リスト内のコンスセルの個数をリターンする。しかし循環リストでは単に上限値が値となるため、非常に大きくなる場合があります。
listがnil
]とコンスセルのいずれでもなければsafe-length
は0をリターンする。
循環リストを考慮しなくてもよい場合にリストの長さを計算するもっとも一般的な方法は、length
を使う方法です。シーケンスを参照してください。
これは(car (car cons-cell))
と同じ。
これは(car (cdr cons-cell))
か(nth 1 cons-cell)
と同じ。
これは(cdr (car cons-cell))
と同じ。
これは(cdr (cdr cons-cell))
か(nthcdr 2 cons-cell)
と同じ。
この関数はリストxから、最後の要素か最後のn個の要素を削除してリターンする。nが0より大きければこの関数はリストのコピーを作成するので、元のリストに影響はない。一般的に(append
(butlast x n) (last x n))
は、xと等しいリストをリターンする。
この関数はリストのコピーを作成するのではなく、cdr
を適切な要素に変更することにより破壊的に機能するバージョンのbutlast
である。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
リストはLispの中核にあたる機能なので、リストを構築するために多くの関数があります。cons
はリストを構築する基本的な関数です。しかしEmacsのソースコードでは、cons
よりlist
のほうが多く使用されているのは興味深いことです。
この関数は新しいリスト構造を構築するための、もっとも基本的な関数である。この関数はobject1をCAR、object2をCDRとする新しいコンスセルを作成して、それから新しいコンスセルをリターンする。引数object1とobject2には任意のLispオブジェクトを指定できるが、ほとんどの場合object2はリストである。
(cons 1 '(2)) ⇒ (1 2)
(cons 1 '()) ⇒ (1)
(cons 1 2) ⇒ (1 . 2)
リストの先頭に1つの要素を追加するために、cons
がよく使用される。これをリストに要素をコンスすると言います。2たとえば:
(setq list (cons newelt list))
この例で使用されているlist
という名前の変数と、以下で説明するlist
という名前の関数は競合しないことに注意されたい。すべてのシンボルが、変数ト関数の両方の役割を果たすことができる。
この関数はobjectsを要素とするリストを作成する。結果となるリストは常にnil
終端される。objectsを指定しないと空リストがリターンされる。
(list 1 2 3 4 5) ⇒ (1 2 3 4 5)
(list 1 2 '(3 4 5) 'foo) ⇒ (1 2 (3 4 5) foo)
(list) ⇒ nil
この関数は各要素がobjectであるような、length個の要素からなるリストを作成する。make-list
とmake-string
(文字列の作成を参照)を比較してみよ。
(make-list 3 'pigs) ⇒ (pigs pigs pigs)
(make-list 0 'pigs) ⇒ nil
(setq l (make-list 3 '(a b))) ⇒ ((a b) (a b) (a b)) (eq (car l) (cadr l)) ⇒ t
この関数はsequencesのすべての要素を含むリストをreturnします。sequencesにはリスト、ベクター、ブールベクター、文字列も指定できるが、通常は最後にリストを指定すること。最後の引数を除くすべての引数はコピーされるので、変更される引数はない(コピーを行なわずにリストを結合する方法についてはリストを再配置する関数のnconc
を参照のこと)。
より一般的にはappend
にたいする最後の引数は、任意のLispオブジェクトを指定できる。最後の引数はコピーや変換はされない。最後の引数は、新しいリストの最後のコンスセルのCDRとなる。最後の引数もリストならば、このリストの要素は実質的には結果リストの要素になる。最後の要素がリストでなければ、最後のCDRが(真リストで要求される)nil
ではないので、結果はドットリストになる。
以下はappend
を使用した例です:
(setq trees '(pine oak)) ⇒ (pine oak) (setq more-trees (append '(maple birch) trees)) ⇒ (maple birch pine oak)
trees ⇒ (pine oak) more-trees ⇒ (maple birch pine oak)
(eq trees (cdr (cdr more-trees))) ⇒ t
append
がどのように機能するか、ボックスダイアグラムで確認できます。変数trees
はリスト(pine
oak)
にセットされ、それから変数more-trees
にリスト(maple birch pine
oak)
がセットされます。しかし変数trees
は継続して元のリストを参照します:
more-trees trees | | | --- --- --- --- -> --- --- --- --- --> | | |--> | | |--> | | |--> | | |--> nil --- --- --- --- --- --- --- --- | | | | | | | | --> maple -->birch --> pine --> oak
空のシーケンスはappend
によりリターンされる値に寄与しません。この結果、最後の引数にnil
を指定すると、それより前の引数のコピーを強制することになります。
trees ⇒ (pine oak)
(setq wood (append trees nil)) ⇒ (pine oak)
wood ⇒ (pine oak)
(eq wood trees) ⇒ nil
関数copy-sequence
が導入される以前は,これがリストをコピーする通常の方法でした。シーケンス、配列、ベクターを参照してください。
以下はappend
の引数としてベクターと文字列を使用する例です:
(append [a b] "cd" nil) ⇒ (a b 99 100)
apply
(関数の呼び出しを参照)の助けを借りることにより、リストのリストの中のすべてのリストをappendできます。
(apply 'append '((a b c) nil (x y z) nil)) ⇒ (a b c x y z)
sequencesが与えられなければnil
がリターンされます:
(append) ⇒ nil
以下は最後の引数がリストでない場合の例です:
(append '(x y) 'z) ⇒ (x y . z) (append '(x y) [z]) ⇒ (x y . [z])
2番目の例は最後の引数はリストではないシーケンスの場合で、このシーケンスの要素は、結果リストの要素にはなりません。かわりに最後の引数がリストでないときと同様、シーケンスが最後のCDRになります。
この関数はツリーtree
のコピーをリターンする。treeがコンスセルなら、同じCARとCDRをもつ新しいコンスセルを作成してから、同じ方法によりCARとCDRを再帰的にコピーする。
treeがコンスセル以外の場合、通常はcopy-tree
は単にtreeをリターンする。しかしvecpが非nil
なら、この関数はベクターでもコピーします(そしてベクターの要素を再帰的に処理する)。
これはfromからseparationづつインクリメントして、toの直前で終わる、数字のリストをリターンする。separationには正か負の数を指定でき、デフォルトは1。toがnil
、または数値的にfromと等しければ、値は1要素のリスト(from)
になる。separationが正でtoがfromより小さい、またはseparationが負でtoがfromより大きければ、これらの引数は空のシーケンスを指示することになるので、値はnil
になります。
separationが0で、toがnil
でもなく、数値的にfromとも等しくまければ、これらの引数は無限シーケンスを指示することになるので、エラーがシグナルされる。
引数はすべて数字である。浮動少数点数の計算は正確ではないので、浮動少数点数の引数には注意する必要がある。たとえばマシンへの依存により、(number-sequence
0.4 0.8 0.2)
が3要素のリストをリターンして、(number-sequence 0.4 0.6
0.2)
が1要素のリスト(0.4)
をリターンnすることがよく起こる。リストのn番目の要素は、厳密に(+
from (* n
separation))
という式により計算される。リストに確実にtoが含まれるようにするために、この式に適切な型のtoを渡すことができる。別の方法としてtoを少しだけ大きな値(separationが負なら少しだけ小さな値)に置き換えることもできる。
例をいくつか示す:
(number-sequence 4 9) ⇒ (4 5 6 7 8 9) (number-sequence 9 4 -1) ⇒ (9 8 7 6 5 4) (number-sequence 9 4 -2) ⇒ (9 7 5) (number-sequence 8) ⇒ (8) (number-sequence 8 5) ⇒ nil (number-sequence 5 8 -1) ⇒ nil (number-sequence 1.5 6 2) ⇒ (1.5 3.5 5.5)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数と1つのマクロは、変数に格納されたリストを変更する便利な方法を提供します。
このマクロはCARがelementで、CDRがlistnameのリストであるような新しいリストを作成して、そのリストをlistnameに保存する。listnameがリストに名前をつけるクォートされていないシンボルのときは単純で、この場合マクロは(setq listname (cons element listname))
と等価になる。
(setq l '(a b)) ⇒ (a b) (push 'c l) ⇒ (c a b) l ⇒ (c a b)
より一般的なのはlistname
が汎変数の場合である。この場合、このマクロは(setf listname (cons element listname))
と等価になる。ジェネリック変数を参照のこと。
リストから1番目の要素を取り出すpop
マクロについては、リスト要素へのアクセスを参照されたい。
以下の2つの関数は、変数の値であるリストを変更します。
この関数はelementがsymbolの値のメンバーでなければ、symbolにelementをコンスすることにより、変数symbolをセットする。この関数はリストが更新されているか否かに関わらず、結果のリストをリターンする。symbolの値は呼び出し前にすでにリストであることが望ましい。elementがリストの既存メンバーか比較するために、add-to-list
はcompare-fnを使用する。compare-fnがnil
ならequal
を使用する。
elementが追加される場合は、通常はsymbolの前に追加されるが、オプションの引数appendが非nil
なら最後に追加される。
引数symbolは暗黙にクォートされない。setq
とは異なりadd-to-list
はset
のような通常の関数である。クォートしたい場合には自分で引数をクォートすること。
以下にadd-to-list
を使用する方法をシナリオで示します:
(setq foo '(a b)) ⇒ (a b) (add-to-list 'foo 'c) ;;c
を追加 ⇒ (c a b) (add-to-list 'foo 'b) ;; 効果なし ⇒ (c a b) foo ;;foo
が変更された ⇒ (c a b)
以下は(add-to-list 'var value)
と等価な式です:
(or (member value var) (setq var (cons value var)))
この関数は古い値のorder
(リストであること)で指定された位置に、elementを挿入して変数symbolをセットする。elementがすでにこのリストのメンバなら、リスト内の要素の位置はorderにしたがって調整される。メンバーか否かはeq
を使用してテストされる。この関数は更新されているかどうかに関わらず、結果のリストをリターンする。
orderは通常は数字(整数か浮動小数点数)で、リストの要素はその数字の昇順で並べられる。
orderは省略またはnil
を指定できる。これによりリストにelementがすでに存在するなら、elementの数字順序は変更されない。それ以外ならelementは数字順序をもたない。リストの数字順序をもたない要素はリストの最後に配置され、特別な順序はつかない。
orderに他の値を指定すると、elementがすでに数字順序をもつときは数字順序が削除される。それ以外はならnil
と同じ。
引数symbolは暗黙にクォートされない。add-to-ordered-list
はsetq
などとは異なり、set
のような通常の関数である。必要なら引数を自分でクォートすること。
順序の情報はsymbolのlist-order
プロパティーにハッシュテーブルで保存される。
以下にadd-to-ordered-list
を使用する方法をシナリオで示します:
(setq foo '()) ⇒ nil (add-to-ordered-list 'foo 'a 1) ;;a
を追加 ⇒ (a) (add-to-ordered-list 'foo 'c 3) ;;c
を追加 ⇒ (a c) (add-to-ordered-list 'foo 'b 2) ;;b
を追加 ⇒ (a b c) (add-to-ordered-list 'foo 'b 4) ;;b
を移動 ⇒ (a c b) (add-to-ordered-list 'foo 'd) ;;d
を後に追加 ⇒ (a c b d) (add-to-ordered-list 'foo 'e) ;;e
を追加 ⇒ (a c b e d) foo ;;foo
が変更された ⇒ (a c b e d)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プリミティブ関数setcar
とsetcdr
により、コンスセルのCARおよびCDRの内容を変更できます。わたしたちは、これらは既存のリスト構造を変更するので、これらを破壊的処理です。
Common Lispに関する注意: Common Lispはリスト構造の変更に
rplaca
とrplacd
を使用する。これらはsetcar
やsetcdr
と同じ方法でリスト構造を変更するが、setcar
とsetcdr
は新しいCARやCDRをリターンするのにたいして、Common Lispの関数はコンスセルをリターンする。
5.6.1 setcar によるリスト要素の変更 | リスト内の要素の置き換え。 | |
5.6.2 リストのCDRの変更 | リストの根幹部分の置き換え。これは要素の追加や削除に使用される。 | |
5.6.3 リストを再配置する関数 | リスト内の要素の再配置、リストの合成。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
setcar
によるリスト要素の変更コンスセルのCARの変更はsetcar
で行ないます。リストにたいして使用するとsetcar
はリストの1つの要素を別の要素に置き換えます。
この関数は以前のCARを置き換えて、consの新しいCARにobjectを格納する。言い換えると、この関数はconsのCARスロットをobjectを参照するように変更する。この関数は値objectをリターンする。たとえば:
(setq x '(1 2)) ⇒ (1 2)
(setcar x 4) ⇒ 4
x ⇒ (4 2)
コンスセルが複数のリストを共有する構造の一部なら、コンスに新しいCARを格納することにより、これら共有されたリストの各1つの要素を変更します。以下は例です:
;; 部分的に共有された2つのリストを作成
(setq x1 '(a b c))
⇒ (a b c)
(setq x2 (cons 'z (cdr x1)))
⇒ (z b c)
;; 共有されたリンクのCARを置き換え (setcar (cdr x1) 'foo) ⇒ foo x1 ; 両方のリストが変更された ⇒ (a foo c) x2 ⇒ (z foo c)
;; 共有されていないリンクのCARを置き換え (setcar x1 'baz) ⇒ baz x1 ; 1つのリストだけが変更された ⇒ (baz foo c) x2 ⇒ (z foo c)
なぜb
を置き換えると両方が変更されるのかを説明するために、変数x1
とx2
の2つのリストによる共有構造を視覚化してみましょう:
--- --- --- --- --- --- x1---> | | |----> | | |--> | | |--> nil --- --- --- --- --- --- | --> | | | | | | --> a | --> b --> c | --- --- | x2--> | | |-- --- --- | | --> z
同じ関係を別のボックス図で示すと、以下のようになります:
x1: -------------- -------------- -------------- | car | cdr | | car | cdr | | car | cdr | | a | o------->| b | o------->| c | nil | | | | -->| | | | | | -------------- | -------------- -------------- | x2: | -------------- | | car | cdr | | | z | o---- | | | --------------
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
CDRを変更するもっとも低レベルのプリミティブ関数はsetcdr
です:
この関数は前のCDRを置き換えて、consの新しいCDRにobjectを格納する。言い換えると、この関数はconsのCDRがobjectを参照するように変更する。この関数は値objectをリターンする。
以下はリストのCDRを、他のリストに置き換える例です。1番目の要素以外のすべての要素は、別のシーケンスまたは要素のために取り除かれます。1番目の要素はリストのCARなので変更されず、CDRを通じて到達することもできないからです。
(setq x '(1 2 3)) ⇒ (1 2 3)
(setcdr x '(4)) ⇒ (4)
x ⇒ (1 4)
リスト内のコンスセルのCDRを変更することにより、リストの途中から要素を削除できます。たとえば以下では、1番目のコンスセルのCDRを変更することにより、2番目の要素b
をリスト(a
b c)
から削除します。
(setq x1 '(a b c)) ⇒ (a b c) (setcdr x1 (cdr (cdr x1))) ⇒ (c) x1 ⇒ (a c)
以下に結果をボックス表記で示します:
-------------------- | | -------------- | -------------- | -------------- | car | cdr | | | car | cdr | -->| car | cdr | | a | o----- | b | o-------->| c | nil | | | | | | | | | | -------------- -------------- --------------
以前は要素b
を保持していた2番目のコンスセルは依然として存在し、そのCARもb
のままですが、すでにこのリストの一部を形成していません。
CDRを変更して新しい要素を挿入するのも同じくらい簡単です:
(setq x1 '(a b c)) ⇒ (a b c) (setcdr x1 (cons 'd (cdr x1))) ⇒ (d b c) x1 ⇒ (a d b c)
以下に結果をボックス表記で示します:
-------------- ------------- ------------- | car | cdr | | car | cdr | | car | cdr | | a | o | -->| b | o------->| c | nil | | | | | | | | | | | | --------- | -- | ------------- ------------- | | ----- -------- | | | --------------- | | | car | cdr | | -->| d | o------ | | | ---------------
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下ではリストの構成要素であるコンスセルのCDRを変更することにより、リストを破壊的に再配置する関数をいくつか示します。これらの関数が破壊的だという理由は、これらの関数が引数として渡された元のリストを処理してリターン値となる新しいリストを形成するために、リストのコンスセルを再リンクするからです。
コンスセルを変更する他の関数については、集合としてのリストの使用のdelq
を参照してください。
この関数はlistsの要素すべてを含むリストをリターンする。append
(コンスセルおよびリストの構築を参照)とは異なり、listsはコピーされない。かわりにlistsの各リストの最後のCDRが次のリストを参照するように変更される。listsの最後のリストは変更されない。たとえば:
(setq x '(1 2 3)) ⇒ (1 2 3)
(nconc x '(4 5)) ⇒ (1 2 3 4 5)
x ⇒ (1 2 3 4 5)
nconc
の最後の引数は変更されないので、上記の例のように'(4
5)
のような定数リストを使用するのが合理的である。また同じ理由により最後の引数がリストである必要はない。
(setq x '(1 2 3)) ⇒ (1 2 3)
(nconc x 'z) ⇒ (1 2 3 . z)
x ⇒ (1 2 3 . z)
しかし他の(最後を除くすべての)引数はリストでなければなければならない。
一般的な落とし穴としては、nconc
にたいしてクォートされたリスト定数を最後以外の引数として使用した場合である。これを行なうと、実行するごとにプログラムはリスト定数を変更するだろう!
何が起こるのかを以下に示す:
(defun add-foo (x) ; この関数ではfoo
(nconc '(foo) x)) ; を引数の前に追加したい
(symbol-function 'add-foo) ⇒ (lambda (x) (nconc (quote (foo)) x))
(setq xx (add-foo '(1 2))) ; 動いているように見える
⇒ (foo 1 2)
(setq xy (add-foo '(3 4))) ; 何が起きているのか?
⇒ (foo 1 2 3 4)
(eq xx xy) ⇒ t
(symbol-function 'add-foo) ⇒ (lambda (x) (nconc (quote (foo 1 2 3 4) x)))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
リストは順序なしの数学的集合 — リスト内に要素があれば集合の要素の値としてリスト内の順序は無視される —
を表すことができます。2つの集合を結合(union)するには、(重複する要素を気にしなければ)append
を使用します。equal
である重複を取り除くにはdelete-dups
を使用します。集合にたいする他の有用な関数にはmemq
やdelq
や、それらのequal
バージョンであるmember
とdelete
が含まれます。
Common Lispに関する注意: 集合を処理するためにCommon Lispには(要素の重複がない)関数
union
がある。これらの関数は標準のGNU Emacs Lispには存在しないが、cl-libがこれらを提供する。Lists as Sets in Common Lisp Extensionsを参照されたい。
この関数はobjectがlistのメンバーかどうかをテストする。メンバーならmemq
は、objectで最初に見つかった要素から開始されるリストをリターンする。メンバーでなければnil
をリターンする。memq
の文字‘q’は、この関数がobjectとリスト内の要素の比較にeq
を使用することを示す。たとえば:
(memq 'b '(a b c b a)) ⇒ (b c b a)
(memq '(2) '((1) (2))) ; (2)
と(2)
はeq
ではない。
⇒ nil
この関数はlistからobjectとeq
であるような、すべての要素を破壊的に取り除いて結果のリストをリターンする。delq
の文字‘q’は、この関数がobjectとリスト内の要素の比較にeq
を使用することを示す(memq
やremq
と同様)。
delq
を呼び出すときは、通常は元のリストを保持していた変数にリターン値を割り当てて使用する必要がある(理由は以下参照)。
delq
関数がリストの先頭にある要素を削除する場合は、単にリストを読み進めてこの要素の後から開始される部分リストをリターンします。つまり:
(delq 'a '(a b c)) ≡ (cdr '(a b c))
リストの途中にある要素を削除するときは、必要なCDR (リストのCDRの変更を参照)を変更することで削除を行います。
(setq sample-list '(a b c (4))) ⇒ (a b c (4))
(delq 'a sample-list) ⇒ (b c (4))
sample-list ⇒ (a b c (4))
(delq 'c sample-list) ⇒ (a b (4))
sample-list ⇒ (a b (4))
(delq 'a sample-list)
は何も取り除きませんが(単に短いリストをリターンする)、(delq 'c
sample-list)
は3番目の要素を取り除いてsample-list
を変更することに注意してください。引数listを保持するように形成された変数が、実行後にもっと少ない要素になるとか、元のリストを保持すると仮定しないでください!
かわりにdelq
の結果を保存して、それを使用してください。元のリストを保持していた変数に結果を書き戻すことはよく行なわれます。
(setq flowers (delq 'rose flowers))
以下の例では、delq
が比較しようとしている(4)
と、sample-list
内の(4)
はeq
ではありません:
(delq '(4) sample-list) ⇒ (a c (4))
与えられた値とequal
な要素を削除したい場合には、delete
(以下参照)を使用してください。
この関数はobjectとeq
なすべての要素が除かれた、listのコピーをリターンする。remq
の文字‘q’は、この関数がobjectとリスト内の要素の比較にeq
を使用することを示す。
(setq sample-list '(a b c a b c)) ⇒ (a b c a b c)
(remq 'a sample-list) ⇒ (b c b c)
sample-list ⇒ (a b c a b c)
関数memql
はeql
(浮動少数点数の要素は値で比較される)を使用してメンバーとeql
を比較することにより、objectがlistのメンバーかどうかをテストする。objectがメンバーなら、memql
はlist内で最初に見つかった要素から始まるリスト、それ以外ならnil
をリターンする。
memq
と比較してみよう:
(memql 1.2 '(1.1 1.2 1.3)) ; 1.2
と1.2
はeql
。
⇒ (1.2 1.3)
(memq 1.2 '(1.1 1.2 1.3)) ; 1.2
と1.2
はeq
ではない。
⇒ nil
以下の3つの関数はmemq
、delq
、remq
と似ていますが、要素の比較にeq
ではなくequal
を使用します。同等性のための述語を参照してください。
関数member
は、メンバーとobjectをequal
を使用して比較して、objectがlistのメンバーかどうかをテストする。objectがメンバーなら、member
はlistで最初に見つかったところから開始されるリスト、それ以外ならnil
をリターンする。
memq
と比較してみよう:
(member '(2) '((1) (2))) ; (2)
and (2)
are equal
.
⇒ ((2))
(memq '(2) '((1) (2))) ; (2)
と(2)
はeq
ではない。
⇒ nil
;; 同じ内容の2つの文字列はequal
(member "foo" '("foo" "bar"))
⇒ ("foo" "bar")
この関数はsequenceからobjectとequal
な要素を取り除いて、結果のシーケンスをリターンする。
sequenceがリストなら、delete
がdelq
に対応するように、member
はmemq
に対応する。つまりこの関数はmember
と同様、要素とobjectの比較にequal
を使用する。マッチする要素が見つかったら、delq
が行なうようにその要素を取り除く。delq
と同様、通常は元のリストを保持していた変数にリターン値を割り当てて使用する。
sequence
がベクターか文字列なら、delete
はobject
とequal
なすべての要素を取り除いたsequence
のコピーをリターンする。
たとえば:
(setq l '((2) (1) (2))) (delete '(2) l) ⇒ ((1)) l ⇒ ((2) (1)) ;;l
の変更に信頼性を要するときは ;;(setq l (delete '(2) l))
と記述する。
(setq l '((2) (1) (2)))
(delete '(1) l)
⇒ ((2) (2))
l
⇒ ((2) (2))
;; このケースではl
のセットの有無に違い
;; はないが他のケースに倣ってセットするべき
(delete '(2) [(2) (1) (2)]) ⇒ [(1)]
この関数はdelete
に対応する非破壊的な関数である。この関数はobject
とequal
な要素を取り除いた、sequence
(リスト、ベクター、文字列)のコピーをリターンする。たとえば:
(remove '(2) '((2) (1) (2))) ⇒ ((1))
(remove '(2) [(2) (1) (2)]) ⇒ [(1)]
Common Lispに関する注意: GNU Emacs Lispの関数
member
、delete
、remove
はCommon Lispではなく、Maclispを継承する。Common Lispでは比較にequal
を使用しない。
この関数はmember
と同様だが、objectが文字列でcaseとテキスト表現の違いを無視する。文字の大文字と小文字は等しいものとして扱われ、比較に先立ちユニバイト文字列はマルチバイト文字列に変換される。
この関数はlistからすべてのequal
な重複を破壊的に取り除いて、結果をlistに保管してそれをリターンする。list内の要素にequal
な要素がいくつかあるなら、delete-dups
は最初の要素を残す。
変数に格納されたリストへの要素の追加や、それを集合として使用する方法については、リスト変数の変更の関数add-to-list
も参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
連想配列(association list、短くはalist)は、キーと値のマッピングを記録します。これは連想(associations)と呼ばれるコンスセルのリストです。各コンスセルにおいてCARはキー(key)で、CDRは連想値(associated value)となります。3
以下はalistの例です。キーpine
は値cones
、キーoak
はacorns
、キーmaple
はseeds
に関連付けられます。
((pine . cones) (oak . acorns) (maple . seeds))
alist内の値とキーには、任意のLispオブジェクトを指定できます。たとえば以下のalist0では、シンボルa
は数字1
、文字列"b"
はリスト(2
3)
(alist要素のCDR)に関連付けられます。
((a . 1) ("b" 2 3))
要素のCDRのCARに連想値を格納するようにalistデザインするほうがよい場合があります。以下はそのようなalistです。
((rose red) (lily white) (buttercup yellow))
この例では、red
がrose
に関連付けられる値だと考えます。この種のalistの利点は、CDRのCDRの中に他の関連する情報
— 他のアイテムのリストでさえも —
を格納することができることです。不利な点は、与えられた値を含む要素を見つけるためにrassq
(以下参照)を使用できないことです。これらを検討することが重要でない場合には、すべての与えられたalistにたいして一貫している限り、選択は好みの問題といえます。
上記で示したのと同じalistは、要素のCDRに連想値をもつと考えることができます。この場合、rose
に関連付けられる値はリスト(red)
になるでしょう。
連想リストは新しい連想値を簡単にリストの先頭に追加できるので、スタックに保持したいような情報を記録するのによく使用されます。連想リストから与えられたキーにたいして連想値を検索する場合、それが複数ある場合は、最初に見つかったものがreturnされます。
Emacs Lispでは、連想リストがコンスセルでなくても、それはエラーではありません。alist検索関数は、単にそのような要素を無視します。多くの他のバージョンのLispでは、このような場合はエラーをシグナルします。
いくつかの観点において、プロパティーリストは連想リストと似ていることに注意してください。それぞれのキーが一度だけ出現するような場合、プロパティーリストは連想リストと同様に振る舞います。プロパティーリストと連想リストの比較については、プロパティリストを参照してください。
この関数は、alist要素にたいしてkeyを比較するのにequal
を使用して、alist内からkeyをもつ最初の連想をリターンする。CARがkeyとequal
であるような連想値がalistになければ、この関数はnil
をリターンする。たとえば:
(setq trees '((pine . cones) (oak . acorns) (maple . seeds))) ⇒ ((pine . cones) (oak . acorns) (maple . seeds)) (assoc 'oak trees) ⇒ (oak . acorns) (cdr (assoc 'oak trees)) ⇒ acorns (assoc 'birch trees) ⇒ nil
以下はキーと値がシンボルでない場合の例である:
(setq needles-per-cluster '((2 "Austrian Pine" "Red Pine") (3 "Pitch Pine") (5 "White Pine"))) (cdr (assoc 3 needles-per-cluster)) ⇒ ("Pitch Pine") (cdr (assoc 2 needles-per-cluster)) ⇒ ("Austrian Pine" "Red Pine")
関数assoc-string
はassoc
と似ていますが、文字列間の特定の違いを無視する点が異なります。文字および文字列の比較を参照してください。
この関数はalistの中から値valueをもつ最初の連想をリターンする。CDRがvalueとequal
であるような連想値がalistになければ、この関数はnil
をリターンする。
rassoc
はassoc
と似てイルが、CARではなくalistの連想値のCDRを比較する。この関数は与えられた値に対応するキーを探す、assoc
の逆バージョンと考えることができよう。
この関数は、alistからkeyをもつ最初の連想値をリターンする点はassoc
と同様だが、比較にequal
ではなくeq
を使用する点が異なる。CARがkeyとeq
であるような連想値がalist内に存在しなければ、assq
はnil
をリターンする。eq
はequal
より早く、ほとんどのalistはキーにシンボルを使用するので、この関数はassoc
より多用される。同等性のための述語を参照のこと。
(setq trees '((pine . cones) (oak . acorns) (maple . seeds))) ⇒ ((pine . cones) (oak . acorns) (maple . seeds)) (assq 'pine trees) ⇒ (pine . cones)
逆にキーがシンボルではないalistでは、通常はassq
は有用ではない:
(setq leaves '(("simple leaves" . oak) ("compound leaves" . horsechestnut))) (assq "simple leaves" leaves) ⇒ nil (assoc "simple leaves" leaves) ⇒ ("simple leaves" . oak)
この関数はassq
と似ているが、keyにたいする連想値全体(key
.
value)
ではなく、valueだけをリターンする点が異なる。keyがalist内で見つからなければdefaultをリターンする。
これはsetf
での値の変更に使用できる汎変数である(ジェネリック変数を参照)。値の値へのセットにこれを使用する際、オプション引数removeが非nilの場合は、新たな値がdefaultとeql
なら、alistからkeyを削除することを意味する。
この関数は、alist内から値valueをもつ最初の連想値をリターンする。alist内にCDRがvalueとeq
であるような連想値が存在しないならnil
をリターンする。
rassq
はassq
と似ていますが、CARではなくalistの各連想のCDRを比較します。この関数を、与えられた値に対応するキーを探すassq
の逆バージョンと考えることができます。
たとえば:
(setq trees '((pine . cones) (oak . acorns) (maple . seeds))) (rassq 'acorns trees) ⇒ (oak . acorns) (rassq 'spores trees) ⇒ nil
rassq
は要素のCDRのCARに保管された値の検索はできません:
(setq colors '((rose red) (lily white) (buttercup yellow))) (rassq 'white colors) ⇒ nil
この場合、連想(lily
white)
のCDRはwhite
ではなくリスト(white)
です。これは連想をドットペア表記で記述すると明確になります:
(lily white) ≡ (lily . (white))
この関数は、keyにたいするマッチをalistから検索する。alistの各要素にたいして、この関数はkeyと要素(アトムの場合)、または要素のCAR(コンスの場合)を比較する。比較はtestに2つの引数
— 要素(か要素のCAR)とkey —
を与えて呼び出すことにより行なわれる。引数はこの順番で渡されるので、正規表現(正規表現の検索を参照)を含むalistでは、string-match
を使用することにより有益な結果を得ることができる。testが省略またはnil
なら比較にequal
が使用される。
alistの要素がこの条件によりkeyとマッチすると、assoc-default
はその要素の値をリターンする。要素がコンスなら値は要素のCDR、それ以外ならリターン値はdefaultとなる。
keyにマッチする要素がalistに存在しないければ、assoc-default
はnil
をリターンする。
この関数は深さのレベルが2のalistのコピーをリターンする。この関数は各連想の新しいコピーを作成するので、元のalistを変更せずに新しいalistを変更できる。
(setq needles-per-cluster '((2 . ("Austrian Pine" "Red Pine")) (3 . ("Pitch Pine"))
(5 . ("White Pine")))) ⇒ ((2 "Austrian Pine" "Red Pine") (3 "Pitch Pine") (5 "White Pine")) (setq copy (copy-alist needles-per-cluster)) ⇒ ((2 "Austrian Pine" "Red Pine") (3 "Pitch Pine") (5 "White Pine")) (eq needles-per-cluster copy) ⇒ nil (equal needles-per-cluster copy) ⇒ t (eq (car needles-per-cluster) (car copy)) ⇒ nil (cdr (car (cdr needles-per-cluster))) ⇒ ("Pitch Pine")
(eq (cdr (car (cdr needles-per-cluster))) (cdr (car (cdr copy)))) ⇒ t
以下の例は、どのようにしてcopy-alist
が他に影響を与えずにコピーの連想を変更可能なのかを示す:
(setcdr (assq 3 copy) '("Martian Vacuum Pine")) (cdr (assq 3 needles-per-cluster)) ⇒ ("Pitch Pine")
この関数は、delq
を使用してマッチする要素を1つずつ削除するときのように、CARがkeyとeq
であるようなすべての要素をalistから削除する。この関数は短くなったalistをリターンし、alistの元のリスト構造を変更することもよくある。正しい結果を得るために、alistに保存された値ではなくassq-delete-all
のリターン値を使用すること。
(setq alist '((foo 1) (bar 2) (foo 3) (lose 4))) ⇒ ((foo 1) (bar 2) (foo 3) (lose 4)) (assq-delete-all 'foo alist) ⇒ ((bar 2) (lose 4)) alist ⇒ ((foo 1) (bar 2) (lose 4))
この関数は、alistからCDRがvalueとeq
であるようなすべての要素を削除する。この関数は短くなったリストをリターンし、alistの元のリスト構造を変更することもよくある。rassq-delete-all
はassq-delete-all
と似ているが、CARではなくalistの各連想のCDRを比較する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プロパティーリスト(property list、短くはplist)は、ペアになった要素のリストです。各ペアはプロパティー名(通常はシンボル)とプロパティー値を対応づけます。以下はプロパティーリストの例です:
(pine cones numbers (1 2 3) color "blue")
このプロパティーリストはpine
をcones
、numbers
を(1 2
3)
、color
を"blue"
に関連づけます。プロパティー名とプロパティー値には任意のLispオブジェクトを指定できますが、通常プロパティー名は(この例のように)シンボルです。
いくつかのコンテキストでプロパティーリストが使用されます。たとえば関数put-text-property
はプロパティーリストを引数にとり、文字列やバッファー内のテキストにたいして、テキストプロパティーとテキストに適用するプロパティー値を指定します。テキストのプロパティを参照してください。
プロパティーリストが頻繁に使用される他の例は、シンボルプロパティーの保管です。すべてのシンボルはシンボルに関する様々な情報を記録するために、プロパティーのリストを処理します。これらのプロパティーはプロパティーリストの形式で保管されます。シンボルのプロパティを参照してください。
5.9.1 プロパティリストと連想リスト | プロパティーリストと連想リストの利点の比較。 | |
5.9.2 プロパティリストと外部シンボル | 他の場所に保管されたプロパティーリストへのアクセス。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
連想リスト(連想リストを参照)は、プロパティーリストとよく似ています。連想リストとは対照的にプロパティー名は一意でなければならないので、プロパティーリスト内でペアの順序に意味はありません。
様々なLisp関数や変数に情報を付加するためには、連想リストよりプロパティーリストの方が適しています。プログラムでこのような情報すべてを1つの連想リストに保持する場合は、特定のLisp関数や変数にたいする連想をチェックする度にリスト全体を検索する必要が生じ、それにより遅くなる可能性があります。対照的に関数名や変数自体のプロパティーリストに同じ情報を保持すれば、検索ごとにそのプロパティーリストの長さだけを検索するようになり、通常はこちらの方が短時間で済みます。変数のドキュメントがvariable-documentation
という名前のプロパティーに記録されているのはこれが理由です。同様にバイトコンパイラーも、特別に扱う必要がある関数を記録するためにプロパティーを使用します。
とはいえ連想リストにも独自の利点があります。アプリケーションに依存しますが、プロパティーを更新するより連想リストの先頭に連想を追加する方が高速でしょう。シンボルにたいするすべてのプロパティーは同じプロパティーリストに保管されるので、プロパティー名を異なる用途のために使用すると衝突の可能性があります(この理由により、そのプログラムで通常の変数や関数の名前につけるプレフィクスをプロパティー名の先頭につけて、一意と思われるプロパティー名を選ぶのはよいアイデアだと言える)。連想リストは、連想をリストの先頭にpushして、その後にある連想は無視されるので、スタックと同様に使用できます。これはプロパティーリストでは不可能です。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はプロパティーリストを操作するために使用されます。これらの関数はすべて、プロパティー名の比較にeq
を使用します。
この関数はプロパティーリストplistに保管された、プロパティーpropertyの値をリターンする。この関数には不正な形式(malformed)のplist引数を指定できる。plistでpropertyが見つからないと、この関数はnil
をリターンする。たとえば、
(plist-get '(foo 4) 'foo) ⇒ 4 (plist-get '(foo 4 bad) 'foo) ⇒ 4 (plist-get '(foo 4 bad) 'bad) ⇒ nil (plist-get '(foo 4 bad) 'bar) ⇒ nil
この関数はプロパティーリストplistに、プロパティーpropertyの値としてvalueを保管する。この関数はplistを破壊的に変更するかもしれず、元のリスト構造を変更せずに新しいリストを構築することもある。この関数は変更されたプロパティーリストをリターンするので、plistを取得した場所に書き戻すことができる。たとえば、
(setq my-plist '(bar t foo 4)) ⇒ (bar t foo 4) (setq my-plist (plist-put my-plist 'foo 69)) ⇒ (bar t foo 69) (setq my-plist (plist-put my-plist 'quux '(a))) ⇒ (bar t foo 69 quux (a))
plist-get
と同様だがプロパティーの比較にeq
ではなくequal
を使用する。
plist-put
と同様だがプロパティーの比較にeq
ではなくequal
を使用する。
この関数は与えられたpropertyがplistに含まれるなら非nil
をリターンする。plist-get
とは異なりこの関数は存在しないプロパティーと、値がnil
のプロパティーを区別できる。実際にリターンされる値は、car
がpropertyで始まるplistの末尾部分である。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
シーケンス(sequence)型は2つの異なるLisp型 — リストと配列 — を結合した型です。言い換えると任意のリストはシーケンスであり任意の配列はシーケンスです。すべてのシーケンスがもつ共通な属性は、それぞれが順序づけされた要素のコレクションであることです。
配列(array)はスロットがその要素であるような、固定長のオブジェクトです。すべての要素に一定時間でアクセスできます。配列の4つの型として文字列、ベクター、文字テーブル、ブールベクターがあります。
リストは要素のシーケンスですが、要素は単一の基本オブジェクトではありません。リストはコンスセルにより作られ、要素ごとに1つのセルをもちます。n番目の要素を探すにはn個のコンスセルを走査する必要があるので、先頭から離れた要素ほどアクセスに時間を要します。しかしリストは要素の追加や削除が可能です。
以下の図はこれらの型の関連を表しています:
_____________________________________________ | | | Sequence | | ______ ________________________________ | | | | | | | | | List | | Array | | | | | | ________ ________ | | | |______| | | | | | | | | | | Vector | | String | | | | | |________| |________| | | | | ____________ _____________ | | | | | | | | | | | | | Char-table | | Bool-vector | | | | | |____________| |_____________| | | | |________________________________| | |_____________________________________________|
6.1 シーケンス | 任意の種類のシーケンスを許す関数。 | |
6.2 配列 | Emacs Lispの配列の特徴。 | |
6.3 配列を操作する関数 | 配列に特化した関数。 | |
6.4 ベクター | Emacs Lispベクターの特質。 | |
6.5 ベクターのための関数 | ベクターのための特別な関数。 | |
6.6 文字テーブル | 文字テーブルを扱う方法。 | |
6.7 ブールベクター | ブールベクターを扱う方法。 | |
6.8 オブジェクト用固定長リングの管理 | オブジェクトの固定サイズのリングを管理する。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは任意の種類のシーケンスを許す関数を説明します。
この関数はobjectがリスト、ベクター、文字列、ブールベクター、文字テーブルならt
、それ以外はnil
をリターンする。
この関数はsequence内の要素の数をリターンする。sequenceがドットリストならwrong-type-argument
エラーがシグナルされる。循環リストは無限ループを引き起こす。文字テーブルではEmacsの最大文字コードより1大きい値が常にリターンされる。
関連する関数safe-length
についてはDefinition of safe-lengthを参照のこと。
(length '(1 2 3)) ⇒ 3
(length ()) ⇒ 0
(length "foobar") ⇒ 6
(length [1 2 3]) ⇒ 3
(length (make-bool-vector 5 nil)) ⇒ 5
テキストの表現方法のstring-bytes
も参照されたい。
ディスプレー上での文字列の幅を計算する必要があるなら、文字数だけを数えて各文字のディスプレー幅を計算しないlength
ではなく、string-width
(表示されるテキストのサイズを参照)を使用すること。
この関数はindexによりインデックスづけされた、sequenceの要素をリターンする。indexの値として妥当なのは、0からsequenceの長さより1小さい数までの範囲の整数。sequenceがリストなら範囲外の値はnth
と同じように振る舞う。Definition of nthを参照のこと。それ以外なら範囲外の値はargs-out-of-range
エラーを引き起こす。
(elt [1 2 3 4] 2) ⇒ 3
(elt '(1 2 3 4) 2) ⇒ 3
;; elt
がどの文字をreturnするか明確にするためにstring
を使用
(string (elt "1234" 2))
⇒ "3"
(elt [1 2 3 4] 4) error→ Args out of range: [1 2 3 4], 4
(elt [1 2 3 4] -1) error→ Args out of range: [1 2 3 4], -1
この関数はaref
(配列を操作する関数を参照)とnth
(Definition of nthを参照)を一般化したものである。
この関数はsequenceのコピーをリターンする。コピーは元のシーケンスと同じ型、同じ要素、同じ順番となる。
コピーに新しい要素を格納するのは、元のsequenceに影響を与えずその逆も真である。しかし新しいシーケンス内の要素がコピーされたものでなければ、元のシーケンスの要素と同一(eq
)になる。したがって、コピーされたシーケンスを介して見つかった要素を変更すると、この変更は元のシーケンスでも見ることができる。
シーケンスがテキストプロパティーをもつ文字列なら、コピー内のプロパティーリスト自身もコピーとなり、元のシーケンスのプロパティーリストと共有はされない。しかしプロパティーリストの実際の値は共有される。テキストのプロパティを参照のこと。
この関数はドットリストでは機能しない。循環リストのコピーは無限ループを起こすだろう。
シーケンスをコピーする別の方法についてはコンスセルおよびリストの構築のappend
、文字列の作成のconcat
、ベクターのための関数のvconcat
も参照されたい。
(setq bar '(1 2)) ⇒ (1 2)
(setq x (vector 'foo bar)) ⇒ [foo (1 2)]
(setq y (copy-sequence x)) ⇒ [foo (1 2)]
(eq x y) ⇒ nil
(equal x y) ⇒ t
(eq (elt x 1) (elt y 1)) ⇒ t
;; 一方のシーケンスの要素を置き換え
(aset x 0 'quux)
x ⇒ [quux (1 2)]
y ⇒ [foo (1 2)]
;; 共有された要素の内部を変更
(setcar (aref x 1) 69)
x ⇒ [quux (69 2)]
y ⇒ [foo (69 2)]
この関数はsequenceの要素を反転した要素をもつ新たなシーケンスを作成する。元となる引数sequenceは変更されない。文字テーブルは反転できないことに注意。
(setq x '(1 2 3 4)) ⇒ (1 2 3 4)
(reverse x) ⇒ (4 3 2 1) x ⇒ (1 2 3 4)
(setq x [1 2 3 4]) ⇒ [1 2 3 4]
(reverse x) ⇒ [4 3 2 1] x ⇒ [1 2 3 4]
(setq x "xyzzy") ⇒ "xyzzy"
(reverse x) ⇒ "yzzyx" x ⇒ "xyzzy"
この関数はsequenceの要素を反転する。reverse
とは異なり、元となるsequenceは変更されるかもしれない。
たとえば:
(setq x '(a b c)) ⇒ (a b c)
x ⇒ (a b c) (nreverse x) ⇒ (c b a)
;; 先頭にあったコンスセルが末尾となった
x
⇒ (a)
混乱しないように、通常は元となるリストを保持する同じ変数に、nreverse
の結果を書き戻す:
(setq x (nreverse x))
お馴染の例(a b c)
のnreverse
を以下に図示する:
Original list head: Reversed list: ------------- ------------- ------------ | car | cdr | | car | cdr | | car | cdr | | a | nil |<-- | b | o |<-- | c | o | | | | | | | | | | | | | | ------------- | --------- | - | -------- | - | | | | ------------- ------------
setqが不要なのでベクターはより単純になる:
(setq x [1 2 3 4]) ⇒ [1 2 3 4] (nreverse x) ⇒ [4 3 2 1] x ⇒ [4 3 2 1]
reverse
とは異なり、この関数は文字列では機能しない。aset
を使用して文字列データを変更できても、文字列は不変として扱うことを強く推奨する。
この関数はsequenceを安定ソートする。この関数はすべてのシーケンスにたいしては機能せず、リストとベクターにたいしてのみ使用できることに注意されたい。sequenceがリストなら破壊的に変更される。この関数はソートされたsequenceをリターンして、要素の比較にはpredicateを使用する。安定ソートでは、ソートキーが等しい要素の相対順序がソートの前後で保たれる。この安定性は異なる条件により要素を並べ替えるために、連続してソートを行う場合に重要となる。
引数predicateは2つの引数を受け取る関数でなければならない。これはsequenceの2つの要素で呼び出される。昇順でソートするなら、1つ目の要素が2つ目の要素より“小”なら非nil
、それ以外ならnil
をリターンすること。
比較関数predicateは、少なくともsort
の単一の呼び出しにおいて、与えられた任意の引数ペアにたいして信頼できる結果をリターンしなければならない。これは非対照的(antisymmetric)、すなわちaがbより小なら、bがaより小であってはならず、推移律(transitive)、すなわちaがbより小、かつbがcより小なら、aはcより小でなければならない。これらの要件に合致しない比較関数を使用すると、sort
の結果は予想できない。
sort
のリストにたいする破壊的側面は、CDRを変更することによりsequenceを形成するコンスセルを再配置することにある。非破壊ソート関数は、それらのソート順に要素を格納するために、新たなコンスセルを作成するだろう。オリジナルを破壊せずにソートしたコピーを望むなら、まずcopy-sequence
でコピーしてからソートすること。
ソートによりsequenceのコンスセルのCARは変化しない。元々sequence内で要素a
を含むコンスセルは、ソート後もそのCARにa
を保持する。しかしCDRの変更により、ソート後には異なる位置に出現する。たとえば:
(setq nums '(1 3 2 6 5 4 0)) ⇒ (1 3 2 6 5 4 0)
(sort nums '<) ⇒ (0 1 2 3 4 5 6)
nums ⇒ (1 2 3 4 5 6)
警告
nums
内のリストが0を含まないことに注意。これはソート前と同じコンスセルだがもはやリストの先頭ではない。ソート前に引数を保持していた変数がソート済みリスト全体を保持すると仮定してはならない!
かわりにsort
の結果を保存して、それを使うこと。ほとんどの場合、わたしたちは元のリストを保持していた変数に結果を書き戻すようにしている。
(setq nums (sort nums '<))
安定ソートの何たるかをより理解するには、以下のベクターのサンプルを考えてみよ。ソート後、car
が8であるようなすべてのアイテムはvector
の先頭にグループ化されるが、それらの相対的な順序は保たれる。car
が9であるようなすべてのアイテムはvector
の末尾にグループ化されるが、それらの相対的な順序も保たれる。
(setq vector (vector '(8 . "xxx") '(9 . "aaa") '(8 . "bbb") '(9 . "zzz") '(9 . "ppp") '(8 . "ttt") '(8 . "eee") '(9 . "fff"))) ⇒ [(8 . "xxx") (9 . "aaa") (8 . "bbb") (9 . "zzz") (9 . "ppp") (8 . "ttt") (8 . "eee") (9 . "fff")]
(sort vector (lambda (x y) (< (car x) (car y)))) ⇒ [(8 . "xxx") (8 . "bbb") (8 . "ttt") (8 . "eee") (9 . "aaa") (9 . "zzz") (9 . "ppp") (9 . "fff")]
ソートを行う他の関数についてはテキストのソートを参照のこと。sort
の有用な例は、ドキュメント文字列へのアクセスのdocumentation
を参照されたい。
seq.elライブラリーは、以下のようなプレフィクスseq-
がついたシーケンス操作用の追加のマクロと関数を提供します。それらを使用するには、最初にseqライブラリーをロードしなければなりません。
このライブラリー内で定義されたすべての関数は、副作用をもちません。これらは引数として渡されたすべてのシーケンス(リスト、ベクター、文字列)を変更しません。特に明記しなければ、結果は入力と同じ型のシーケンスです。述語を受け取る関数では、それらは単一の関数である必要があります。
seq.elライブラリーは、シーケンシャルなデータ構造の追加型で機能するように拡張可能です。そのためにすべての関数はcl-defgeneric
を使用して定義されています。cl-defgeneric
を使用した拡張の追加に関する詳細は、Generic Functionsを参照してください。
この関数はindex(有効な範囲は0からsequenceの長さより1少ない整数)で指定されたsequenceの要素をリターンする。ビルトインのシーケンス型にたいする範囲外(out-of-range)の値にたいして、seq-elt
はelt
と同様に振る舞う。詳細はDefinition of eltを参照のこと。
(seq-elt [1 2 3 4] 2) ⇒ 3
seq-elt
はsetf
を使用してセット可能なplaceをリターンする(setf
マクロを参照)。
(setq vec [1 2 3 4]) (setf (seq-elt vec 2) 5) vec ⇒ [1 2 5 4]
この関数はsequence内の要素の個数をリターンする。ビルトインのシーケンス型にたいしてseq-length
はlength
と同様に振る舞う。Definition of lengthを参照のこと。
この関数はsequenceがシーケンス(リストか配列)、またはseq.elのジェネリック関数を通じて定義されたすべての追加シーケンス型なら非nil
をリターンする。
(seqp [1 2]) ⇒ t
(seqp 2) ⇒ nil
この関数はsequenceの最初のn個(整数)を除く、すべての要素をリターンする.nが0以下なら結果はsequence。
(seq-drop [1 2 3 4 5 6] 3) ⇒ [4 5 6]
(seq-drop "hello world" -4) ⇒ "hello world"
この関数はsequenceの最初のn個(整数)の要素をリターンする。nが0以下なら結果はnil
。
(seq-take '(1 2 3 4) 3) ⇒ (1 2 3)
(seq-take [1 2 3 4] 0) ⇒ []
この関数はsequenceのメンバーを順にリターンし、predicateが最初にnil
をリターンした要素の前で停止する。
(seq-take-while (lambda (elt) (> elt 0)) '(1 2 3 -1 -2)) ⇒ (1 2 3)
(seq-take-while (lambda (elt) (> elt 0)) [-1 4 6]) ⇒ []
この関数はpredicateが最初にnil
をリターンした要素から、sequenceのメンバーを順にリターンする。
(seq-drop-while (lambda (elt) (> elt 0)) '(1 2 3 -1 -2)) ⇒ (-1 -2)
(seq-drop-while (lambda (elt) (< elt 0)) [1 4 6]) ⇒ [1 4 6]
この関数はsequenceの各要素にたいして、(恐らくは副作用を得るために)順番にfunctionを適用して、sequenceをリターンする。
この関数はsequenceの各要素にfunctionを適用した結果をリターンする。リターン値はリスト。
(seq-map #'1+ '(2 4 6)) ⇒ (3 5 7)
(seq-map #'symbol-name [foo bar]) ⇒ ("foo" "bar")
この関数はsequencesの各要素にfunctionを適用した結果をリターンする。 functionのarity (関数が受け取れる引数の個数。sub-arityを参照)はシーケンスの個数にマッチしなければならない。マッピングは最短のシーケンス終端で停止する。リターン値はリスト。
(seq-mapn #'+ '(2 4 6) '(20 40 60)) ⇒ (22 44 66)
(seq-mapn #'concat '("moskito" "bite") ["bee" "sting"]) ⇒ ("moskitobee" "bitesting")
この関数はpredicateが非nil
をリターンしたsequence内のすべての要素のリストをリターンする。
(seq-filter (lambda (elt) (> elt 0)) [1 -1 3 -3 5]) ⇒ (1 3 5)
(seq-filter (lambda (elt) (> elt 0)) '(-1 -3 -5)) ⇒ nil
この関数はpredicateがnil
をリターンしたsequence内のすべての要素のリストをリターンする。
(seq-remove (lambda (elt) (> elt 0)) [1 -1 3 -3 5]) ⇒ (-1 -3)
(seq-remove (lambda (elt) (< elt 0)) '(-1 -3 -5)) ⇒ nil
この関数はinitial-valueとsequenceの1つ目の要素でfunctionを呼び出し、次にその結果とsequenceの2つ目の要素でfunctionを呼び出し、その次にその結果とsequenceの3つ目の要素で、...と呼び出した結果をリターンする。functionは引数が2つの関数であること。sequenceが空なら、これはfunctionを呼び出さずにinitial-valueをリターンする。
(seq-reduce #'+ [1 2 3 4] 0) ⇒ 10
(seq-reduce #'+ '(1 2 3 4) 5) ⇒ 15
(seq-reduce #'+ '() 3) ⇒ 3
この関数はsequenceの各要素に順にpredicateを適用してリターンされた、最初の非nil
値をリターンする。
(seq-some #'numberp ["abc" 1 nil]) ⇒ t
(seq-some #'numberp ["abc" "def"]) ⇒ nil
(seq-some #'null ["abc" 1 nil]) ⇒ t
(seq-some #'1+ [2 4 6]) ⇒ 3
この関数はpredicateが非nil
をリターンした、sequence内の最初の要素をリターンする。predicateにマッチする要素がなければ、この関数はdefaultをリターンする。
この関数は見つかった要素がdefaultと等しい場合、要素が見つかったかどうかを知る術がないので曖昧さをもつことに注意。
(seq-find #'numberp ["abc" 1 nil]) ⇒ 1
(seq-find #'numberp ["abc" "def"]) ⇒ nil
この関数はsequenceの各要素にpredicateを適用して、すべてが非nil
をリターンしたら非nil
をリターンする。
(seq-every-p #'numberp [2 4 6]) ⇒ t
(seq-some #'numberp [2 4 "6"]) ⇒ nil
この関数はsequenceが空ならnil
をリターンする。
(seq-empty-p "not empty") ⇒ nil
(seq-empty-p "") ⇒ t
この関数はsequence内でpredicateが非nil
をリターンした要素の個数をリターンする。
(seq-count (lambda (elt) (> elt 0)) [-1 2 0 3 -2]) ⇒ 2
この関数はfunctionに応じてソートされたsequenceのコピーをリターンする。functionは2つの引数を受け取り、1つ目の引数が2つ目より前にソートされるべきなら非nil
をリターンする。
この関数はsequence内のeltとequal
であるような最初の要素をリターンする。オプション引数functionが非nil
なら、それはデフォルトのequal
のかわりに使用する2つの引数を受け取る関数であること。
(seq-contains '(symbol1 symbol2) 'symbol1) ⇒ symbol1
(seq-contains '(symbol1 symbol2) 'symbol3) ⇒ nil
この関数はeltとequal
であるようなsequence内の最初の要素のインデックスをリターンする。オプション引数functionが非nil
なら、それはデフォルトのequal
のかわりに使用する2つの引数を受け取る関数であること。
(seq-position '(a b c) 'b) ⇒ 1
(seq-position '(a b c) 'd) ⇒ nil
この関数は重複を削除したsequenceの要素のリストをリターンする。オプション引数functionが非nil
なら、それはデフォルトのequal
のかわりに使用する2つの引数を受け取る関数であること。
(seq-uniq '(1 2 2 1 3)) ⇒ (1 2 3)
(seq-uniq '(1 2 2.0 1.0) #'=) ⇒ [3 4]
この関数はsequenceのstartからend(いずれも整数)までのサブセットをリターンする(endのデフォルトは最後の要素)。startかendが負ならsequenceの最後から数える。
(seq-subseq '(1 2 3 4 5) 1) ⇒ (2 3 4 5)
(seq-subseq '[1 2 3 4 5] 1 3) ⇒ [2 3]
(seq-subseq '[1 2 3 4 5] -3 -1) ⇒ [3 4]
この関数はsequencesを結合して作成されたtype型のシーケンスをリターンする。typeはvector
、list
、string
のいずれか。
(seq-concatenate 'list '(1 2) '(3 4) [5 6]) ⇒ (1 2 3 5 6)
(seq-concatenate 'string "Hello " "world") ⇒ "Hello world"
この関数はsequenceの各要素にfunctionを適用した結果に、seq-concatenate
を適用した結果をリターンする。結果はtype型のシーケンス、またはtypeがnil
ならリストである。
(seq-mapcat #'seq-reverse '((3 2 1) (6 5 4))) ⇒ (1 2 3 4 5 6)
この関数は長さnのサブシーケンスへグループ化したsequenceの要素のリストをリターンする。最後のシーケンスに含まれる要素はnより少ないかもしれない。nは整数であること。nが0以下の整数ならリターン値はnil
。
(seq-partition '(0 1 2 3 4 5 6 7) 3) ⇒ ((0 1 2) (3 4 5) (6 7))
この関数はsequence1とsequence2の両方に出現する要素のリストをリターンする。オプション引数functionが非nil
なら、それはデフォルトのequal
のかわりに比較に使用する2つの引数を受け取る関数であること。
(seq-intersection [2 3 4 5] [1 3 5 6 7]) ⇒ (3 5)
この関数はsequence1に出現するがsequence2に出現しない要素のリストをリターンする。オプション引数functionが非nil
なら、それはデフォルトのequal
のかわりに比較に使用する2つの引数を受け取る関数であること。
(seq-difference '(2 3 4 5) [1 3 5 6 7]) ⇒ (2 4)
この関数はsequenceの各要素にfunctionを適用して、その結果をキーとしてsequenceをalistに分割する。キーの比較にはequal
を使用する。
(seq-group-by #'integerp '(1 2.1 3 2 3.2)) ⇒ ((t 1 3 2) (nil 2.1 3.2))
(seq-group-by #'car '((a 1) (b 2) (a 3) (c 4))) ⇒ ((b (b 2)) (a (a 1) (a 3)) (c (c 4)))
この関数はシーケンスsequenceをtype型のシーケンスに変換する。typeはvector
、string
、list
のいずれかであること。
(seq-into [1 2 3] 'list) ⇒ (1 2 3)
(seq-into nil 'vector) ⇒ []
(seq-into "hello" 'vector) ⇒ [104 101 108 108 111]
この関数はsequenceの最小の要素をリターンする。sequenceの要素は数字かマーカー(マーカーを参照)でなければならない。
(seq-min [3 1 2]) ⇒ 1
(seq-min "Hello") ⇒ 72
この関数はsequenceの最大の要素をリターンする。sequenceの要素は数字かマーカーでなければならない。
(seq-max [1 3 2]) ⇒ 3
(seq-max "Hello") ⇒ 111
このマクロはdolist
(dolistを参照)と同様だが、sequenceにリスト、ベクター、文字列のいずれかを指定できる点が異なる。これ主な利点は副作用である。
このマクロはarguments内で定義される変数にsequenceの要素をバインドする。argumentsはネストされた非構造化を許容することにより、自身にシーケンスを含むことができる。
argumentsシーケンスには、sequence
の残りにバインドされる変数名が後続するような、&rest
マーカーを含めることもできる。
(seq-let [first second] [1 2 3 4] (list first second)) ⇒ (1 2)
(seq-let (_ a _ b) '(1 2 3 4) (list a b)) ⇒ (2 4)
(seq-let [a [b [c]]] [1 [2 [3]]] (list a b c)) ⇒ (1 2 3)
(seq-let [a b &rest others] [1 2 3 4] others)
⇒ [3 4]
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
配列(array)オブジェクトは、いくつかのLispオブジェクトを保持するスロットをもち、これらのオブジェクトは配列の要素と呼ばれます。配列内の任意の要素は一定時間でアクセスされます。対照的にリスト内の要素のアクセスに要する時間は、その要素がリスト内のどの位置にあるかに比例します。
Emacsは4つの配列型 —文字列(strings、文字列型を参照)、ベクター(vectors、ベクター型を参照)、ブールベクター(bool-vectors、ブールベクター型を参照)、文字テーブル(char-tables、文字テーブル型を参照) —
を定義しており、これらはすべて1次元です。ベクターと文字テーブルは任意の型の要素を保持できますが、文字列は文字だけ、ブールベクターはt
かnil
しか保持できません。
4種のすべての配列はこれらの特性を共有します:
aref
で参照したり、関数aset
で変更できる(配列を操作する関数を参照)。
配列を作成したとき、文字テーブル以外では長さを指定しなければなりません。文字テーブルの長さは文字コードの範囲により決定されるので長さを指定できません。
原則として、テキスト文字の配列が欲しい場合は、文字列とベクターのどちらかを使用できます。実際のところ4つの理由により,そのような用途にたいしては、わたしたちは常に文字列を選択します:
対照的に、(キーシーケンスのような)キーボード入力文字の配列では、多くのキーボード入力文字は文字列に収まる範囲の外にあるので、ベクターが必要になるでしょう。キーシーケンス入力を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではすべての型の配列に適用される関数を説明します。
この関数はobjectが配列(ベクター、文字列、ブールベクター、文字テーブル)ならt
をリターンする。
(arrayp [a])
⇒ t
(arrayp "asdf")
⇒ t
(arrayp (syntax-table)) ;; 文字テーブル
⇒ t
この関数は arrayのindex番目の要素をリターンする。1番目の要素のインデクスは0。
(setq primes [2 3 5 7 11 13]) ⇒ [2 3 5 7 11 13] (aref primes 4) ⇒ 11
(aref "abcdefg" 1)
⇒ 98 ; ‘b’のASCIIコードは98
シーケンスの関数elt
も参照されたい。
この関数はarrayのindex番目の要素をobjectにセットする。この関数はobjectをリターンする。
(setq w [foo bar baz]) ⇒ [foo bar baz] (aset w 0 'fu) ⇒ fu w ⇒ [fu bar baz]
(setq x "asdfasfd") ⇒ "asdfasfd" (aset x 3 ?Z) ⇒ 90 x ⇒ "asdZasfd"
arrayが文字列でobjectが文字でなければ、結果はwrong-type-argument
エラーとなる。この関数は文字列の挿入で必要なら、ユニバイト文字列をマルチバイト文字列に変換する。
この関数は配列arrayをobjectで充填するので、arrayのすべての要素はobjectになる。この関数はarrayをリターンする。
(setq a [a b c d e f g]) ⇒ [a b c d e f g] (fillarray a 0) ⇒ [0 0 0 0 0 0 0] a ⇒ [0 0 0 0 0 0 0]
(setq s "When in the course") ⇒ "When in the course" (fillarray s ?-) ⇒ "------------------"
arrayが文字列でobjectが文字でなければ、結果はwrong-type-argument
エラーとなる。
配列と判っているオブジェクトにたいしては、一般的なシーケンス関数copy-sequence
とlength
が有用なときがよくあります。シーケンスを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ベクター(vector)とは任意のLispオブジェクトを要素にもつことができる、一般用途のための配列です(対照的に文字列の要素は文字のみ。文字列と文字を参照)。Emacsではベクターはキーシーケンス(キーシーケンスを参照)、シンボル検索用のテーブル(シンボルの作成とinternを参照)、バイトコンパイルされた関数表現の一部(バイトコンパイルを参照)などの多くの目的で使用されます。
他の配列と同様、ベクターは0基準のインデックスづけを使用し、1番目の要素はインデックス0になります。
ベクターは角カッコ(square
brackets)で囲まれた要素としてプリントされます。したがってシンボルa
、b
、a
を要素にもつベクターは、[a
b a]
とプリントされます。Lisp入力として同じ方法でベクターを記述できます。
文字列や数値と同様にベクターは定数として評価され、評価された結果は同じベクターになります。ベクターの要素は評価も確認もされません。自己評価を行うフォームを参照してください。
以下はこれらの原理を表す例です:
(setq avector [1 two '(three) "four" [five]]) ⇒ [1 two (quote (three)) "four" [five]] (eval avector) ⇒ [1 two (quote (three)) "four" [five]] (eq avector (eval avector)) ⇒ t
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ベクターに関連した関数をいくつか示します:
この関数はobjectがベクターならt
をリターンする。
(vectorp [a]) ⇒ t (vectorp "asdf") ⇒ nil
この関数は引数objectsを要素にもつベクターを作成してリターンする。
(vector 'foo 23 [bar baz] "rats") ⇒ [foo 23 [bar baz] "rats"] (vector) ⇒ []
この関数は各要素がobjectに初期化された、length個の要素からなる新しいベクターをリターンする。
(setq sleepy (make-vector 9 'Z)) ⇒ [Z Z Z Z Z Z Z Z Z]
この関数はsequencesのすべての要素を含む新しいベクターをリターンする。引数sequencesは真リスト、ベクター、文字列、ブールベクター。sequencesが与えられければ空のベクターがリターンされる。
値は空のベクター、またはすべての既存ベクターとeq
ではないような空ではない新しいベクターのいずれか。
(setq a (vconcat '(A B C) '(D E F))) ⇒ [A B C D E F] (eq a (vconcat a)) ⇒ nil
(vconcat) ⇒ [] (vconcat [A B C] "aa" '(foo (6 7))) ⇒ [A B C 97 97 foo (6 7)]
vconcat
関数は、引数としてバイトコード関数オブジェクトも受け取ることができる。これはバイトコード関数オブジェクトの内容全体にアクセスするのを容易にするための特別な機能である。バイトコード関数オブジェクトを参照のこと。
結合を行なう他の関数については関数のマッピングのmapconcat
、文字列の作成のconcat
、コンスセルおよびリストの構築のappend
を参照されたい。
append
関数はベクターを同じ要素をもつリストに変換する方法も提供します:
(setq avector [1 two (quote (three)) "four" [five]]) ⇒ [1 two (quote (three)) "four" [five]] (append avector nil) ⇒ (1 two (quote (three)) "four" [five])
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
文字テーブル(char-table)はベクターとよく似ていますが、文字テーブルは文字コードによりインデックスづけされます。文字テーブルのインデックスには、修飾キーをともなわない任意の有効な文字コードを使用できます。他の配列と同様に、aref
とaset
で文字テーブルの要素にアクセスできます。加えて、文字テーブルは追加のデータを保持するために、特定の文字コードに関連づけられていないエキストラスロット(extra
slots)をもつことができます。ベクターと同様、文字テーブルは定数として評価され、任意の型の要素を保持できます。
文字テーブルはそれぞれサブタイプ(subtype)をもち、これは2つの目的をもつシンボルです:
display-table
の文字テーブルであり、構文テーブル(syntax
tables)はサブタイプがsyntax-table
の文字テーブル。以下で説明するように関数char-table-subtype
を使用してサブタイプの問い合わせが可能。
char-table-extra-slots
シンボルプロパティー(シンボルのプロパティを参照)により指定され、値は0から10の整数。サブタイプにそのようなシンボルプロパティーがなければ、その文字テーブルはエキストラスロットをもたない。
文字テーブルは親(parent)をもつことができ、これは他の文字テーブルです。文字テーブルが親をもつ場合、その文字テーブルで特定の文字cにたいしてnil
が指定されていたら、親と指定された文字テーブルで指定された値を継承します。言い方を変えると、文字テーブルchar-tableでcにnil
が指定されていたら、(aref
char-table c)
はchar-tableの親の値をリターンします。
文字テーブルはデフォルト値(default
value)をもつこともできます。デフォルト値をもつとき、文字テーブルchar-tableがcにたいしてnil
値を指定すると、(aref
char-table c)
はデフォルト値をリターンします。
サブタイプsubtype(シンボル)をもつ、新たに作成された文字テーブルをリターンする。各要素はinitに初期化され、デフォルトはnil
。文字テーブルが作成された後で、文字テーブルのサブタイプを変更することはできない。
すべての文字テーブルは、インデックスとなる任意の有効な文字テーブルのための空間をもつので、文字テーブルの長さを指定する引数はない。
subtypeがシンボルプロパティーchar-table-extra-slots
をもつなら、それはその文字列テーブル内のエキストラスロットの数を指定する。値には0から10の整数を指定し、これ以外ならmake-char-table
はエラーとなる。subtypeがシンボルプロパティーchar-table-extra-slots
(プロパティリストを参照)をもたなければ、その文字テーブルはエキストラスロットをもたない。
この関数はobjectが文字テーブルならt
、それ以外はnil
をリターンする。
この関数はchar-tableのサブタイプのシンボルをリターンする。
文字テーブルのデフォルト値にアクセスするための特別な関数は存在しません。これを行なうにはchar-table-range
を使用します(以下参照)。
この関数はchar-tableの親をリターンする。親は常にnil
か他の文字テーブルである。
この関数はchar-tableの親をnew-parentにセットする。
この関数はchar-tableのエキストラスロットn (0基準)の内容をリターンする。文字テーブルのエキストラスロットの数は文字テーブルのサブタイプにより決定される。
この関数はchar-tableのエキストラスロットn (0基準)にvalueを格納する。
文字テーブルは1つの文字コードにたいして1つの要素値(element value)を指定できます。文字テーブルは文字セット全体にたいして値を指定することもできます。
この関数は文字範囲rangeにたいしてchar-tableで指定された値をリターンする。可能なrangeは以下のとおり:
nil
デフォルト値への参照。
文字charにたいする要素への参照(charは有効な文字コードであると仮定)。
(from . to)
包括的な範囲‘[from..to]’内のすべての文字を参照するコンスセル。
この関数はchar-table内の文字範囲rangeにたいして値をセットする。可能なrangeは以下のとおり:
nil
デフォルト値への参照。
t
文字コード範囲の全体を参照。
文字charにたいする要素への参照(charは有効な文字コードであると仮定)。
(from . to)
包括的な範囲‘[from..to]’内のすべての文字を参照するコンスセル。
この関数はchar-tableの非nil
値ではない各要素にたいして引数functionを呼び出す。functionの呼び出しでは2つの引数(keyとvalue)が指定される。keyはchar-table-range
にたいする可能なrange
(有効な文字か、同じ値を共有する文字範囲を指定するコンスセル(from
. to)
)。valueは(char-table-range char-table
key)
がリターンする値。
全体として、functionに渡されるkey-valueのペアはchar-tableに格納されたすべての値を表す。
リターン値は常にnil
である。map-char-table
呼び出しを有用にするためにfunctionは副作用をもつこと。たとえば以下は構文テーブルを調べる方法:
(let (accumulator) (map-char-table #'(lambda (key value) (setq accumulator (cons (list (if (consp key) (list (car key) (cdr key)) key) value) accumulator))) (syntax-table)) accumulator) ⇒ (((2597602 4194303) (2)) ((2597523 2597601) (3)) ... (65379 (5 . 65378)) (65378 (4 . 65379)) (65377 (1)) ... (12 (0)) (11 (3)) (10 (12)) (9 (0)) ((0 8) (3)))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ブールベクター(bool-vector)はベクターとよく似ていますが、値にt
とnil
しか格納できません。ブールベクターの要素に非nil
値の格納を試みたると、そこにはt
が格納されます。すべての配列と同様、ブールベクターのインデックスは0から開始され、一度ブールベクターが作成されたら長さを変更することはできません。ブールベクターは定数として評価されます。
ブールベクターを処理する特別な関数がいくつかあります。その関数以外にも、他の種類の配列に使用されるのと同じ関数でブールベクターを操作できます。
initialに初期化されたlength要素の新しいブールベクターをリターンする。
この関数は引数objectsを要素にもつブールベクターを作成してリターンする。
この関数はobjectがブールベクターであればt
、それ以外はnil
をリターンする。
以下で説明するように、ブールベクターのセット処理を行なう関数がいくつかあります:
ブールベクターaとbのビットごとの排他的論理和(bitwise exclusive or)をリターンする。オプション引数cが与えられたら、この処理の結果はcに格納される。引数にはすべて同じ長さのブールベクターを指定すること。
ブールベクターaとbのビットごとの論理和(bitwise or)をリターンする。オプション引数cが与えられたら、この処理の結果はcに格納される。引数にはすべて同じ長さのブールベクターを指定すること。
ブールベクターaとbのビットごとの論理積(bitwise and)をリターンする。オプション引数cが与えられたら、この処理の結果はcに格納される。引数にはすべて同じ長さのブールベクターを指定すること。
ブールベクターaとbの差集合(set difference)をリターンする。オプション引数cが与えられたら、この処理の結果はcに格納される。引数にはすべて同じ長さのブールベクターを指定すること。
ブールベクターaの補集合(set complement)をリターンする。オプション引数bが与えられたら、この処理の結果はbに格納される。引数にはすべて同じ長さのブールベクターを指定すること。
a内のすべてのt
値が、bでもt
値ならt
、それ以外はnil
をリターンする。引数にはすべて同じ長さのブールベクターを指定すること。
iから始まるaの、bと等しい連続する要素の数をリターンする。a
はブールベクターで、bはt
かnil
、iはa
のインデックス。
ブールベクターaからt
であるような要素の数をリターンする。
長さ8以下のブール値のプリント表記は1文字で表されます。
(bool-vector t nil t nil) ⇒ #&4"^E" (bool-vector) ⇒ #&0""
他のベクター同様、vconcat
を使用してブールベクターをプリントできます:
(vconcat (bool-vector nil t nil t)) ⇒ [nil t nil t]
以下はブールベクターを作成、確認、更新する別の例です:
(setq bv (make-bool-vector 5 t)) ⇒ #&5"^_" (aref bv 1) ⇒ t (aset bv 3 nil) ⇒ nil bv ⇒ #&5"^W"
control-_の2進コードは11111、control-Wは10111なので、この結果は理にかなっています。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
リング(ring)は挿入、削除、ローテーション、剰余(modulo)でインデックスづけされた、参照と走査(traversal)をサポートする固定長のデータ構造です。ring
パッケージにより効率的なリングデータ構造が実装されています。このパッケージは、このセクションにリストした関数を提供します。
Emacsにあるkillリングやマークリングのようないくつかのリングは、実際には単なるリストとして実装されていることに注意してください。したがってこれらのリングにたいしては、以下の関数は機能しないでしょう。
この関数はsizeオブジェクトを保持できる、新しいリングをリターンする。sizeは整数。
この関数はobjectがリングならt
、それ以外はnil
をリターンする。
この関数はringの最大の要素数をリターンする。
この関数はringに現在含まれるオブジェクトの数をリターンする。値がring-size
のリターンする値を超えることはない。
この関数はring内のオブジェクトのリストをリターンする。リストの順序は新しいオブジェクトが先頭になる。
この関数は新しいリングとしてringのコピーをリターンする。新しいリングはringと同じ(eq
な)オブジェクトを含む。
この関数はringが空ならt
、それ以外はnil
をリターンする。
リング内の1番新しい要素は常にインデックス0をもちます。より大きいインデックスは、より古い要素に対応します。インデックスはリング長のmoduloにより計算されます。インデックス-1は1番古い要素、-2は次に古い要素、...となります。
この関数はインデックスindexにあるring内のオブジェクトをリターンする。indexには負やリング長より大きい数を指定できる。ringが空ならring-ref
はエラーをシグナルする。
この関数は1番新しい要素としてobjectをringに挿入してobjectをリターンする。
リングが満杯なら新しい要素用の空きを作るために、挿入により1番古い要素が削除される。
ringからオブジェクトを削除してそのオブジェクトをリターンする。引数indexはどのアイテムを削除するかを指定する。これがnil
なら、それは1番古いアイテムを削除することを意味する。ringが空ならring-remove
はエラーをシグナルする。
この関数は1番古い要素としてobjectをringに挿入する。リターン値に意味はない。
リングが満杯なら、この関数は挿入される要素のための空きを作るために1番新しい要素を削除する。
リングサイズを超過しないよう注意すれば、そのリングをFIFO(first-in-first-out: 先入れ先出し)のキューとして使用することができます。たとえば:
(let ((fifo (make-ring 5))) (mapc (lambda (obj) (ring-insert fifo obj)) '(0 one "two")) (list (ring-remove fifo) t (ring-remove fifo) t (ring-remove fifo))) ⇒ (0 t one t "two")
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ハッシュテーブル(hash table)は非常に高速なルックアップテーブルの一種で、キーに対応する値をマップするという点ではalist(連想リストを参照)に似ています。ハッシュテーブルは以下の点でalistと異なります:
Emacs Lispは一般的な用途のハッシュテーブルデータ型とともに、それらを処理する一連の関数を提供します。ハッシュテーブルは‘#s’、その後にハッシュテーブルのプロパティーと内容を指定するリストが続く、特別なプリント表現をもちます。ハッシュテーブルの作成を参照してください(ハッシュ表記の最初に使用される‘#’文字は、読み取り表現をもたないオブジェクトのプリント表現であり、これはハッシュテーブルに何も行わない。プリント表現と読み取り構文を参照のこと)。
obarray(オブジェクト配列)もハッシュテーブルの一種ですが、これらは異なる型のオブジェクトであり、intern(インターン)されたシンボルを記録するためだけに使用されます(シンボルの作成とinternを参照)。
7.1 ハッシュテーブルの作成 | ハッシュテーブルを作成する関数。 | |
7.2 ハッシュテーブルへのアクセス | ハッシュテーブルの内容の読み書き。 | |
7.3 ハッシュの比較の定義 | 新たな比較方法の定義。 | |
7.4 ハッシュテーブルのためのその他関数 | その他。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ハッシュテーブルを作成する基本的な関数はmake-hash-table
です。
この関数は指定された引数に対応する新しいハッシュテーブルを作成する。引数はキーワード(特別に認識される独自のシンボル)と、それに対応する値を交互に指定することで構成される。
make-hash-table
ではいくつかのキーワードが意味をもつが、実際に知る必要があるのは:test
と:weakness
の2つだけである。
:test test
これはそのハッシュテーブルにたいしてキーを照合する方法を指定する。デフォルトはeql
であり他の代替としてはeq
やequal
がある:
eql
キーが数字ならそれらがequal
、つまりそれらの値が等しくどちらも整数か浮動少数点数なら同一。それ以外なら別の2つのオブジェクトは決して同一とならない。
eq
別の2つのLispオブジェクトはすべて別のキーになる。
equal
別の2つのLispオブジェクトで、それらがequal
なら同一のキーである。
testにたいして追加の選択肢を定義するために、define-hash-table-test
(ハッシュの比較の定義を参照)を使用することができる。
:weakness weak
ハッシュテーブルのweakness(強度)は、ハッシュテーブル内に存在するキーと値をガーベージコレクションから保護するかどうかを指定する。
値weakにはnil
、key
、value
、key-or-value
、key-and-value
、またはt
(key-and-value
のエイリアス)のいずれかを指定しなければならない。weakがkey
ならそのハッシュテーブルは、(キーが他の場所で参照されていなければ)ハッシュテーブルのキーがガーベージコレクトされるのを妨げられない。ある特定のキーがガーベージコレクトされると、それに対応する連想はハッシュテーブルから削除される。
weakがvalue
ならそのハッシュテーブルは、(値が他の場所で参照されていなければ)ハッシュテーブルの値がガベージコレクトされるのを妨げませんられない。ある特定の値がガーベージコレクトされると、それに対応する連想はハッシュテーブルから削除される。
weakがkey-and-value
(かt
)なら、その連想を保護するためにはキーと値の両方が生きていなければならない。したがってそのハッシュテーブルは、キーと値の一方だけをガーベージコレクトから守ることはしない。キーか値のどちらか一方がガーベージコレクトされたら、その連想は削除される。
weakがkey-or-value
nara、キーか値のどちらか一方で、その連想を保護することができる。したがってキーと値の両方がガベージコレクトされたときだけ(それがハッシュテーブル自体にたいする参照でなければ)、ハッシュテーブルからその連想が削除される。
weakのデフォルトはnil
なので、ハッシュテーブルから参照されているキーと値はすべてガーベージコレクションから保護される。
:size size
これはそのハッシュテーブルに保管しようとしている、連想の数にたいするヒントを指定する。数が概算で判っていれば、この方法でそれを指定して処理を若干効率的にすることができる。小さすぎるサイズを指定すると、そのハッシュテーブルは必要に応じて自動的に拡張されるが、これを行なうために時間が余計にかかる。
デフォルトのサイズは65。
:rehash-size rehash-size
ハッシュテーブルに連想を追加するとき、そのテーブルが満杯ならテーブルを自動的に拡張する。この値はその際にどれだけハッシュテーブルを拡張するかを指定する。
rehash-sizeが整数(正であること)なら、通常のサイズにrehash-sizeを加えてハッシュテーブルを拡張する。rehash-sizeが浮動小数点数(1より大きい方がよい)なら、古いサイズにその数を乗じてハッシュテーブルを拡張する。
デフォルト値は1.5。
:rehash-threshold threshold
これはハッシュテーブルが満杯(なのでもっと大きく拡張する必要がある)と判断される基準を指定する。thresholdの値は、1以下の正の浮動小数点数であること。実際のエントリー数が、通常のサイズにたいする指定割合を超えると、そのハッシュテーブルは満杯となる。thresholdのデフォルトは0.8。
ハッシュテーブルのプリント表現を使用して、新しいハッシュテーブルを作成することもできます。指定されたハッシュテーブル内の各要素が、有効な入力構文(プリント表現と読み取り構文を参照)をもっていれば、Lispリーダーはこのプリント表現を読み取ることができます。たとえば以下は値val1
(シンボル)と300
(数字)に関連づけられた、キーkey1
とkey2
(両方ともシンボル)を、新しいハッシュテーブルに指定します。
#s(hash-table size 30 data (key1 val1 key2 300))
ハッシュテーブルのプリント表現は‘#s’と、その後の‘hash-table’で始まるリストにより構成されます。このリストの残りの部分はそのハッシュテーブルのプロパティーと初期内容を指定する、0個以上のプロパティーと値からなるペアで構成されるべきです。プロパティーと値はそのまま読み取られます。有効なプロパティー名はsize
、test
、weakness
、rehash-size
、rehash-threshold
、data
です。data
プロパティーは、初期内容にたいするキーと値のペアのリストであるべきです。他のプロパティーは、上記で説明したmake-hash-table
のキーワード(:size
、:test
など)と同じ意味をもちます。
バッファーやフレームのような、入力構文をもたないオブジェクトを含んだ初期内容をもつハッシュテーブルを指定できないことに注意してください。そのようなオブジェクトは、ハッシュテーブルを作成した後に追加します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではハッシュテーブルにアクセスしたり、連想を保管する関数を説明します。比較方法による制限がない限り、一般的には任意のLispオブジェクトをハッシュキーとして使用できます。
この関数はtableのkeyを照合してそれに関連づけられたvalue、table内にkeyをもつ連想が存在しなければdefaultをリターンする。
この関数はtable内に値valueをもつkeyの連想を挿入します。tableがすでにkeyの連想をもつなら、valueで古い連想値を置き換える。
この関数はtableにkeyの連想があればそれを削除する。keyが連想をもたなければremhash
は何も行なわない。
Common Lispに関する注意: Common
Lispではremhash
が実際に連想を削除したときは非nil
、それ以外はnil
をリターンする。Emacs
Lispではremhash
は常にnil
をリターンする。
この関数はハッシュテーブルtableからすべての連想を削除するので、そのハッシュテーブルは空になる。これはハッシュテーブルのクリーニング(clearing)とも呼ばれる。
Common Lispに関する注意: Common
Lispではclrhash
は空のtableをリターンする。Emacs Lispではnil
をリターンする。
この関数はtable内の各連想にたいして一度ずつfunctionを呼び出す。関数functionは2つの引数 —
tableにリストされたkeyと、それに関連づけられたvalue —
を受け取ること。maphash
はnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
define-hash-table-test
でキーを照合する新しい方法を定義できます。この機能を使用するにはハッシュテーブルの動作方法と、ハッシュコード(hash
code)の意味を理解する必要があります。
概念的にはハッシュテーブルを1つの連想を保持できるスロットがたくさんある巨大な配列として考えることができます。キーを照合するにはまず、gethash
がキーから整数のハッシュコードを計算します。配列内のインデックスを生成するために、gethash
は配列の長さからこの整数のmoduloを得ます。それからキーが見つかったかどうか確認するためにそのスロット、もし必要なら近くのスロットを探します。
したがってキー照合の新しい方法を定義するためには、キーからハッシュコードを計算する関数と、2つのキーを直接比較する関数の両方が必要です。
この関数はnameという名前の新たなハッシュテーブルテストを定義します。
この方法でnameを定義した後は、make-hash-table
の引数testにこれを使用することができる。これを行なう際は、そのハッシュテーブルのキー値の比較にtest-fn、キー値からハッシュコードを計算するためにhash-fnを使用することになる。
関数test-fnは2つの引数(2つのキー)をとり、それらが同一と判断されたときは非nil
をリターンする。
関数hash-fnは1つの引数(キー)を受け取り、そのキーのハッシュコード(整数)をリターンすること。よい結果を得るために、その関数は負の整数を含む整数の全範囲をハッシュコードに使用するべきある。
指定された関数は、プロパティーhash-table-test
の配下の、nameというプロパティーリストに格納される。そのプロパティーの値形式は(test-fn
hash-fn)
。
この関数はLispオブジェクトobjのハッシュコードをリターンする。リターン値はobjと、それが指す別のLispオブジェクトの内容を表す整数。
2つのオブジェクトobj1とobj2がequalなら、(sxhash
obj1)
と(sxhash obj2)
は同じ整数になる。
2つのオブジェクトがequalでなければ、通常はsxhash
がリターンする値は異なるが、常に異なるとは限らない。稀(運次第)にだがsxhash
が同じ結果を与えるような、2つの異なった外見のオブジェクトに遭遇するかもしれない。
以下はlcaseを区別しない文字列のキーをもつハッシュテーブルを作成する例です。
(defun case-fold-string= (a b) (eq t (compare-strings a nil nil b nil nil t))) (defun case-fold-string-hash (a) (sxhash (upcase a))) (define-hash-table-test 'case-fold 'case-fold-string= 'case-fold-string-hash) (make-hash-table :test 'case-fold)
以下は事前に定義されたテスト値equal
と等価なテストを行なうハッシュテーブルを定義できるという例です。キーは任意のLispオブジェクトで、equalに見えるオブジェクトは同じキーと判断されます。
(define-hash-table-test 'contents-hash 'equal 'sxhash) (make-hash-table :test 'contents-hash)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はハッシュテーブルに作用する他の関数です。
この関数はtableがハッシュテーブルオブジェクトなら非nil
をリターンする。
この関数はtableのコピーを作成してリターンする。そのテーブル自体がコピーされたものである場合のみ、キーと値が共有される。
この関数はtable内の実際のエントリー数をリターンする。
この関数はハッシュを行なう方法と、キーを比較する方法を指定するために、table作成時に与えられたtestの値をリターンする。ハッシュテーブルの作成のmake-hash-table
を参照されたい。
この関数はハッシュテーブルtableに指定されたweakの値をリターンする。
この関数はtableのrehash-sizeをリターンする。
この関数はtableのrehash-thresholdをリターンする。
この関数はtableの現在の定義されたサイズをリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
シンボル(symbol)は一意な名前をもつオブジェクトです。このチャプターではシンボル、シンボルの構成要素とプロパティーリスト、およびシンボルの作成とインターンする方法を説明します。別のチャプターではシンボルを変数として使用したり、関数名として使用する方法が説明されています。変数と関数を参照してください。シンボルの正確な入力構文については、シンボル型を参照してください。
symbolp
を使用して、任意のLispオブジェクトがシンボルかどうかをテストできます:
この関数はobjectがシンボルならt
、それ以外はnil
をリターンする。
8.1 シンボルの構成要素 | シンボルは名前、値、関数定義、プロパティーリストをもつ。 | |
8.2 シンボルの定義 | 定義はシンボルが使用される方法を示す。 | |
8.3 シンボルの作成とintern | シンボルが一意に保たれる方法。 | |
8.4 シンボルのプロパティ | さまざまな情報を記録するために各シンボルはプロパティーリストをもつ。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
各シンボルは4つの構成要素(もしくは“セル”)をもち、構成要素はそれぞれ別のオブジェクトを参照します:
そのシンボルの名前。
変数としてのそのシンボルの現在値。
そのシンボルの関数定義。シンボル、キーマップ、キーボードマクロも保持できる。
そのシンボルのプロパティーリスト。
プリント名のセルは常に文字列を保持し、それを変更することはできません。他の3つのセルには、任意のLispオブジェクトをセットすることができます。
プリント名のセルはシンボルの名前となる文字列を保持します。シンボルはシンボル名によりテキストとして表されるので、2つのシンボルが同じ名前をもたないことが重要です。Lispリーダーはシンボルを読み取るごとに、それを新規作成する前に、指定されたシンボルがすでに存在するかを調べます。シンボルの名前を得るには関数symbol-name
(シンボルの作成とinternを参照)を使用します。
値セルは変数としてのシンボルの値(そのシンボル自身がLisp式として評価されたときに得る値)を保持します。ローカルバインディング(local
binding)やスコーピングルール(scoping
rules)等のような複雑なものを含めて、変数のセットや取得方法については変数を参照してください。ほとんどのシンボルは値として任意のLispオブジェクトをもつことができますが、一部の特別なシンボルは変更できない値をもちます。これらにはnil
、t
、および名前が‘:’で始まるすべてのシンボル(キーワード(keyword)と呼ばれる)が含まれます。Variables that Never Changeを参照してください。
関数セルはシンボルの関数定義を保持します。実際はにはfoo
の関数セルの中に保管されている関数を意味するときに、“関数foo
”といってそれを参照することがよくあります。わたしたちは必要なときだけ、これを明確に区別することにします。関数セルは通常は関数(関数を参照)か、マクロ(マクロを参照)を保持するために使用されます。しかし関数セルはシンボル(シンボル関数インダイレクションを参照)、キーボードマクロ(キーボードマクロを参照)、キーマップ(キーマップを参照)、またはオートロードオブジェクト(自動ロードを参照)を保持するためにも使用できます。シンボルの関数セルの内容を得るには、関数symbol-function
(関数セルの内容へのアクセスを参照)を使用します。
プロパティーリストのセルは、通常は正しくフォーマットされたプロパティーリストを保持するべきです。シンボルのプロパティーリストを得るには関数symbol-plist
を使用します。シンボルのプロパティを参照してください。
マクロセルと値セルがvoid(空)のときもあります。voidとはそのセルがどのオブジェクトも参照していないことを意味します(これはシンボルvoid
を保持するのともシンボルnil
を保持するのとも異なる)。voidの関数セルまたは値セルを調べようとすると結果は‘Symbol's
value as variable is void’のようなエラーとなります。
各シンボルは値セルと関数セルを別個にもつので、変数名と関数名が衝突することはありません。たとえばシンボルbuffer-file-name
が値(カレントバッファーでvisitされているファイルの名前)をもつと同様に、関数定義(ファイルの名前をリターンするプリミティブ関数)をもつことができます:
buffer-file-name ⇒ "/gnu/elisp/symbols.texi" (symbol-function 'buffer-file-name) ⇒ #<subr buffer-file-name>
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
定義(definition)とは、特別な方法での使用の意図を宣言する特別な種類のLisp式です。定義とは通常はシンボルにたいする値を指定するか、シンボルにたいする1つの種類の使用についての意味とその方法で使用する際のシンボルの意味のドキュメントを指定します。したがってシンボルを変数として定義すると、その変数の初期値に加えてその変数のドキュメントを提供できます。
defvar
とdefconst
はグローバル変数(global variable) —
Lispプログラムの任意の箇所からアクセスできる変数 —
として定義するためのスペシャルフォームです。変数についての詳細は変数を参照してください。カスタマイズ可能な変数を定義するにはdefcustom
(サブルーチンとしてdefvar
も呼び出す)を使用します(カスタマイゼーション設定を参照)。
最初にシンボルが変数として定義されていなくても、原則としてsetq
で任意のシンボルに値を割り当てることができます。しかし使用したいグローバル変数それぞれにたいして変数定義を記述するべきです。さもないとレキシカルスコープ(変数のバインディングのスコーピングルールを参照)が有効なときに変数が評価されたると、あなたのLispプログラムが正しく動作しないかもしれません。
defun
はラムダ式(lambda
expression)を生成して、そのシンボルの関数セルに格納することにより、そのシンボルを関数として定義します。したがってこのシンボルの関数定義は、そのラムダ式になります(関数セルの内容を意味する用語“関数定義(function
definition)”は、defun
がシンボルに関数としての定義を与えるというアイデアに由来する)。関数を参照してください。
defmacro
はシンボルをマクロとして定義します。これはマクロオブジェクトを作成してシンボルの関数セルにそれを格納します。シンボルにはマクロと関数を与えることができますが、マクロと関数定義はどちらも関数セルに保持されるのにたいし、関数セルに保持できるのは常にただ1つのLispオブジェクトなので、一度に両方を行なうことはできないことに注意してください。マクロを参照してください。
前に注記したようにEmacs
Lispではシンボルを(たとえばdefvar
で)変数として定義して、同じシンボルを(たとえばdefun
で)関数やマクロとして両方定義することができます。このような定義は衝突しません。
これらの定義はプログラミングツールのガイドを果たすこともできます。たとえばC-h fとC-h vコマンドは関連する変数、関数、マクロ定義へのリンクを含むヘルプバッファーを作成します。Name Help in The GNU Emacs Manualを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU Emacs Lispでシンボルが作成される方法を理解するには、Lispがシンボルを読み取る方法を理解しなければなりません。Lispは、同じ文字綴りを読み取ったら、毎回同じシンボルを見つけることを保証しなければなりません。これに失敗すると、完全な混乱を招くでしょう。
Lispリーダーがシンボルに出会うと、Lispリーダーは名前のすべての文字を読み取ります。その後Lispリーダーはobarray(オブジェクト配列)と呼ばれるテーブル内のインデックスを決めるために、これらの文字をハッシュ(hash)します。ハッシュ化(hashing)は何かを照合するのに効果的な方法です。たとえばJan Jonesを見つけるときは、電話帳を表紙から1頁ずつ探すのではなくJの頁から探し始めます。これはハッシュ化の簡単なバージョンです。obarrayの各要素は与えられたハッシュコードとともに、すべてのシンボルを保持するバケット(bucket)です。与えられた名前を探すためには、バケットの中からハッシュコードがその名前であるような、すべてのシンボルを探すのが効果的です(同じアイデアは一般的なEmacsのハッシュテーブルでも使用されていがこれらはデータ型が異なる。ハッシュテーブルを参照されたい)。
探している名前のシンボルが見つかったら、リーダーはそのシンボルを使用します。obarrayにその名前のシンボルが含まれなければ、リーダーは新しいシンボルを作成してそれをobarrayに追加します。特定の名前のシンボルを探して追加することをインターン(intern)と言い、これが行なわれた後はそのシンボルはインターンされたシンボル(interned symbol)と呼ばれます。
インターンすることによりある特定の名前のシンボルは、各obarrayに1つだけであることが保証されます。同じ名前のシンボルが他に存在するかもしれませんが、同じobarrayには存在しません。したがってリーダーは、(同じobarrayを読みつづける限り)同じ名前にたいして同じシンボルを取得します。
インターンは通常はリーダー内で自動的に発生しますが、他のプログラムがこれを行なう必要がある場合もあります。たとえばM-xコマンドはその後にミニバッファーを使用してコマンド名を文字列として取得して、その文字列をインターンしてからインターンされたその名前のシンボルを得ます。
すべてのシンボルを含むobarrayはありません。実際にどのobarrayにも含まれないシンボルがいくつかあります。これらはインターンされていないシンボル(uninterned symbols)と呼ばれます。インターンされていないシンボルも、他のシンボルと同じく4つのセルをもちます。しかしインターンされていないシンボルへのアクセスを得る唯一の方法は、他の何らかのオブジェクトとして探すか、変数の値として探す方法だけです。
インターンされていないシンボルの作成は、Lispコードを生成するとき有用です。なぜなら作成されたコード内で変数として使用されているインターンされていないシンボルは、他のLispプログラムで使用されている任意の変数と競合することはありえないからです。
Emacs
Lispではobarrayはベクターです。ベクター内の各要素がバケットになります。要素の値は、名前がそのバケットにハッシュされるようなインターンされたシンボル、またはバケットが空のときは0です。インターンされたシンボルは、そのバケット内の次のシンボルへの内部リンク(ユーザーからは見えない)をもちます。これらのリンクは不可視なので、mapatoms
(以下参照)を使用する方法をのぞき、obarray内のすべてのシンボルを探す方法はありません。バケット内のシンボルの順番に意味はありません。
空のobarrayではすべての要素が0なので、(make-vector length
0)
でobarrayを作成することができます。obarrayを作成する有効な方法はこれだけです。長さに素数を指定するとよいハッシュ化がされる傾向があります。2の累乗から1減じた長さもよい結果を生む傾向があります。
自分でobarrayにシンボルを置かないでください。これはうまくいきません —
obarrayに正しくシンボルを入力できるのはintern
だけです。
Common Lispに関する注意: Common Lispとは異なりEmacs Lispは1つのシンボルを複数のobarrayにインターンする方法を提供しない。
以下の関数のほとんどは、引数に名前とobarrayをとります。名前が文字列以外、またはobarrayがベクター以外ならwrong-type-argument
エラーがシグナルされます。
この関数はsymbolの名前を文字列としてリターンする。たとえば:
(symbol-name 'foo) ⇒ "foo"
警告: 文字の置き換えにより文字列を変更すると、それはシンボルの名前を変更しますが、obarrayの更新には失敗するので行なわないこと!
この関数は新たに割り当てられた、名前がname(文字列でなかればならない)であるような、インターンされていないシンボルをリターンする。このシンボルの値と関数はvoidで、プロパティーリストはnil
。以下の例ではsym
の値はfoo
とeq
ではない。なぜならこれは名前が‘foo’という、インターンされていないシンボルだからである。
(setq sym (make-symbol "foo")) ⇒ foo (eq sym 'foo) ⇒ nil
この関数は名前がnameであるような、インターンされたシンボルをリターンする。オブジェクト配列obarrayの中にそのようなシンボルが存在しなければ、intern
は新たにシンボルを作成してobarrayに追加してそれをリターンする。obarrayが省略されると、グローバル変数obarray
の値が使用される。
(setq sym (intern "foo")) ⇒ foo (eq sym 'foo) ⇒ t (setq sym1 (intern "foo" other-obarray)) ⇒ foo (eq sym1 'foo) ⇒ nil
Common Lispに関する注意: Common Lispでは既存のシンボルをobarrayにインターンできる。Emacs Lispでは
intern
の引数はシンボルではなく文字列なのでこれを行なうことはできない。
この関数はobarray内の名前がnameのシンボル、obarrayにその名前のシンボルが存在しなければnil
をリターンする。したがって与えられた名前のシンボルがすでにインターンされているかテストするために、intern-soft
を使用することができる。obarrayが省略されるとグローバル変数obarray
の値が使用される。
引数nameにはシンボルも使用できる。この場合、指定されたobarrayにnameがインターンされていればname、それ以外ならnil
をリターンする。
(intern-soft "frazzle") ; そのようなシンボルは存在しない ⇒ nil (make-symbol "frazzle") ; インターンされていないシンボルを作成する ⇒ frazzle
(intern-soft "frazzle") ; そのようなシンボルは見つからない
⇒ nil
(setq sym (intern "frazzle")) ; インターンされたシンボルを作成する
⇒ frazzle
(intern-soft "frazzle") ; シンボルが見つかった!
⇒ frazzle
(eq sym 'frazzle) ; そしてそれは同じシンボル
⇒ t
この変数はintern
とread
が使用する標準のobarrayである。
この関数はオブジェクト配列obarrayの中の各シンボルにたいして、functionを一度呼び出しその後nil
をリターンする。obarrayが省略されると、通常のシンボルにたいする標準のオブジェクト配列obarray
の値がデフォルトになる。
(setq count 0) ⇒ 0 (defun count-syms (s) (setq count (1+ count))) ⇒ count-syms (mapatoms 'count-syms) ⇒ nil count ⇒ 1871
mapatoms
を使用する他の例については、ドキュメント文字列へのアクセスのdocumentation
を参照のこと。
この関数はオブジェクト配列obarrayからsymbolを削除する。obarrayの中にsymbol
が存在ければ、unintern
は何も行なわない。obarrayがnil
なら現在のobarrayが使用される。
symbolにシンボルではなく文字列を与えると、それはシンボルの名前を意味する。この場合、unintern
は(もしあれば)obarrayからその名前のシンボルを削除する。そのようなシンボルが存在するならunintern
は何も行なわない。
unintern
がシンボルを削除したらt
、それ以外はnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
シンボルはそのシンボルについての様々な情報を記録するために使用される、任意の数のシンボルプロパティー(symbol
properties)をもつことができます。たとえばシンボルのrisky-local-variable
プロパティーがnil
なら、その変数の名前が危険なファイルローカル変数(ファイルローカル変数を参照)であることを意味します。
シンボルのプロパティーとプロパティー値はそれぞれ、シンボルのプロパティーリストセル(シンボルの構成要素を参照)に、プロパティーリスト形式(プロパティリストを参照)で格納されます。
8.4.1 シンボルのプロパティへのアクセス | シンボルプロパティーへのアクセス。 | |
8.4.2 シンボルの標準的なプロパティ | シンボルプロパティーの標準的な意味。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数を使用してシンボルプロパティーにアクセスできます。
この関数はsymbolのプロパティーリスト内の、名前がpropertyというプロパティーの値をリターンする。そのようなプロパティーが存在しなければnil
をリターンする。したがって値がnil
のときとプロパティーが存在しないときの違いはない。
名前propertyはeq
を使用して既存のプロパティーと比較されるので、すべてのオブジェクトがプロパティーとして適正である。
put
の例を参照のこと。
この関数はsymbolのプロパティーリストの、プロパティー名propertyにvalueをputして、前のプロパティー値を置き換える。put
関数はvalueをリターンする。
(put 'fly 'verb 'transitive) ⇒'transitive (put 'fly 'noun '(a buzzing little bug)) ⇒ (a buzzing little bug) (get 'fly 'verb) ⇒ transitive (symbol-plist 'fly) ⇒ (verb transitive noun (a buzzing little bug))
この関数はsymbolのプロパティーリストをリターンする。
この関数はsymbolのプロパティーリストをplistにセットする。plistは通常は適正なプロパティーリストであるべきだが、これは強制ではない。リターン値はplistです。
(setplist 'foo '(a 1 b (2 3) c nil)) ⇒ (a 1 b (2 3) c nil) (symbol-plist 'foo) ⇒ (a 1 b (2 3) c nil)
通常の用途には使用されない特別なobarray内のシンボルでは、非標準的な方法でプロパティーリストセルを使用することに意味があるかもしれない。実際にabbrev(abbrevとabbrev展開を参照)のメカニズムでこれを行なっている。
以下のようにsetplist
とplist-put
でput
を定義できる:
(defun put (symbol prop value) (setplist symbol (plist-put (symbol-plist symbol) prop value)))
この関数はget
と等価だがsymbolが関数のエイリアス名なら。実際の関数を命名するシンボルのプロパティリストを照合する点が異なる。関数の定義を参照のこと。オプション引数autoloadが非nil
で、symbolが自動ロードされていれば、その自動ロードによりsymbolのpropertyがセットされるかもしれないので、この関数はそれの自動ロードを試みるだろう。autoloadがシンボルmacro
なら、symbolが自動ロードされたマクロのときだけ自動ロードを試みる。
この関数はfunctionのpropertyにvalueをセットする。functionはシンボルであること。関数のプロパティのセットには、put
よりこの関数を呼び出すほうがよい。この関数を使用すれば、いつか古いプロパティから新しいプロパティへのリマップを実装することができるからである。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsで特別な目的のために使用されるシンボルプロパティーを以下に一覧します。以下のテーブルで、“命名される関数(the named function)”と言うときは、関数名がそのシンボルであるような関数を意味します。“命名される変数(the named variable)”等の場合も同様です。
:advertised-binding
このプロパティーリストは、命名される関数のドキュメントを表示する際に優先されるキーバインディングを指定する。ドキュメント内でのキーバインディングの置き換えを参照のこと。
char-table-extra-slots
値が非nil
なら、それは命名される文字テーブル型の追加スロットの数を指定する。文字テーブルを参照のこと。
customized-face
face-defface-spec
saved-face
theme-face
これらのプロパティーはフェイスの標準のフェイス仕様(face
specs)と、フォント仕様のsaved-fase、customized-face、themed-faceを記録するために使用される。これらのプロパティーを直接セットしないこと。これらのプロパティーはdefface
と関連する関数により管理される。フェイスの定義を参照のこと。
customized-value
saved-value
standard-value
theme-value
これらのプロパティーは、カスタマイズ可能な変数のstandard-value、saved-value、customized-value(しかし保存はされない)、themed-valueを記録するために使用される。これらのプロパティーを直接セットしないこと。これらはdefcustom
と関連する関数により管理される。カスタマイゼーション変数の定義を参照のこと。
disabled
値が非nil
なら命名される関数はコマンドとして無効になる。コマンドの無効化を参照のこと。
face-documentation
値には命名されるフェイスのドキュメント文字列が格納される。これはdefface
により自動的にセットされる。フェイスの定義を参照のこと。
history-length
値が非nil
なら、命名されるヒストリーリスト変数のミニバッファーヒストリーの最大長を指定する。ミニバッファーのヒストリーを参照のこと。
interactive-form
この値は命名される関数のインタラクティブ形式である。通常はこれを直接セットするべきではない。かわりにスペシャルフォームinteractive
を使用すること。interactiveな呼び出しを参照されたい。
menu-enable
この値は命名されるメニューアイテムが、メニュー内で有効であるべきか否かを決定するための式である。単純なメニューアイテムを参照のこと。
mode-class
値がspecial
なら命名されるメジャーモードはspecial(特別)である。メジャーモードの慣習を参照のこと。
permanent-local
値が非nil
なら命名される変数はバッファーローカル変数となり、メジャーモードの変更によって変数の値はリセットされない。バッファーローカルなバインディングの作成と削除を参照のこと。
permanent-local-hook
値が非nil
なら、命名される関数はメジャーモード変更時にフック変数のローカル値から削除されない。フックのセットSetting Hooksを参照のこと。
pure
値が非nil
なら、命名される関数は副作用の影響を受けないとみなされる。定数であるような引数で呼び出される場合には、コンパイル時に評価が可能。これは実行時のエラーをコンパイル時へとシフトする。
risky-local-variable
値が非nil
なら、命名される変数はファイルローカル変数としては危険だとみなされる。ファイルローカル変数を参照のこと。
safe-function
値が非nil
なら、命名される関数は評価において一般的に安全だとみなされます。安全に関数を呼び出せるかどうかの判断を参照のこと。
safe-local-eval-function
値が非nil
なら、命名される関数はファイルローカルの評価フォーム内で安全に呼び出すことができる。ファイルローカル変数を参照のこと。
safe-local-variable
値は命名される変数の、安全なファイルローカル値を決定する関数を指定する。ファイルローカル変数を参照のこと。
side-effect-free
非nil
値は関数の安全性(安全に関数を呼び出せるかどうかの判断を参照)、およびバイトコンパイラーの最適化を決定するために、命名される関数に副作用がないことを示す。これをセットしないこと。
variable-documentation
非nil
なら、それは命名される変数のドキュメント文字列を指定する。ドキュメント文字列はdefvar
と関連する関数により自動的にセットされる。フェイスの定義を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispでの式の評価(evaluation)は、Lispインタープリター —
入力としてLispオブジェクトを受け取り、それの式としての値(value as an expression)を計算する —
により処理されます。評価を行なう方法はそのオブジェクトのデータ型に依存していて、それはこのチャプターで説明するルールにより行なわれます。インタープリターはプログラムの一部を評価するために自動的に実行されますが、Lispプリミティブ関数のeval
を通じて明示的に呼び出すこともできます。
9.1 評価の概要 | 事の在り方における評価。 | |
9.2 フォームの種類 | さまざまなオブジェクト類が評価される方法。 | |
9.3 クォート | (プログラム内に定数を配すことによる)評価の回避。 | |
9.4 バッククォート | リスト構文より簡単な構築。 | |
9.5 eval | Lispインタープリターを明示的に呼び出す方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispインタープリター(またはLispエバリュエーター)はEmacsの一部であり、与えられた式の値を計算します。Lispで記述された関数が呼び出されると、エバリュエーターはその関数のbody(本文)の中の式を評価してその関数の値を計算します。したがってLispプログラムを実行するとは、実際にはLispインタープリターを実行することを意味します。
評価を意図したLispオブジェクトはフォーム(form)、または式(expression)と呼ばれます4。フォームはデータオブジェクトであって単なるテキストではないという事実は、Lisp風の言語と通常のプログラミング言語との間にある基本的な相違点の1つです。任意のオブジェクトを評価できますが、実際に評価される事が非常に多いのは数字、シンボル、リスト、文字列です。
以降のセクションでは、各種フォームにたいしてそれを評価することが何を意味するかの詳細を説明します。
Lispフォームを読み取ってそのフォームを評価するのは、非常に一般的なアクティビティーですが、読み取りと評価は別のアクティビティーであって、どちらか一方を単独で処理することができます。読み取っただけでは何も評価されません。読み取りはLispオブジェクトのプリント表現をそのオブジェクト自体に変換します。そのオブジェクトが評価されるべきフォームなのか、そのれともまったく違う目的をもつかを指定するのは、read
の呼び出し元の役目です。入力関数を参照してください。
評価とは再帰的な処理であり、あるフォームを評価するとそのフォームの一部が評価されるといったことがよくあります。たとえば(car
x)
のような関数呼び出し(function
call)のフォームを評価する場合、Emacsは最初にその引数(サブフォームx
)を評価します。引数を評価した後、Emacsはその関数(car
)を実行(executes)します。その関数がLispで記述されていれば、関数のbody(本文)を評価することによって実行が行なわれます(しかしこの例で使用しているcar
はLisp関数ではなくCで実装されたプリミティブ関数である)。関数と関数呼び出しについての情報は関数を参照してください。
評価は環境(environment)と呼ばれるコンテキストの内部で行なわれます。環境はすべてのLisp変数(変数を参照)のカレント値とバインディングにより構成されます。5フォームが新たなバインディングを作成せずに変数を参照する際、その変数はカレントの環境から与えられる値へと評価されます。フォームの評価は、変数のバインディングによって一時的にその環境を変更することもあります(ローカル変数を参照)。
フォームの評価が永続する変更を行なうこともあります。これらの変更は副作用(side
effects)と呼ばれます。副作用を生成するフォームの例は(setq foo 1)
です。
コマンドキー解釈での評価と混同しないでください。エディターのコマンドループはアクティブなキーマップを使用して、キーボード入力をコマンド(インタラクティブに呼び出すことができる関数)に変換してからそのコマンドを実行するために、call-interactively
を使用します。そのコマンドがLispで記述されていれば、そのコマンドの実行には通常は評価を伴います。しかしこのステップはコマンドキー解釈の一部とは考えません。コマンドループを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
評価される事を意図したLispオブジェクトはフォーム(form)、または式(expression))と呼ばれます。Emacsがフォームを評価する方法はフォームのデータ型に依存します。Emacsは3種の異なるフォーム — シンボル、リスト、およびその他すべての型 — をもち、それらが評価される方法は異なります。このセクションではまず最初に自己評価フォームのその他の型から開始して、3つの種類をすべて1つずつ説明します。
9.2.1 自己評価を行うフォーム | 自分自身を評価するフォーム。 | |
9.2.2 シンボルのフォーム | 変数として評価されるシンボル。 | |
9.2.3 リストフォームの分類 | さまざまな種類のリストフォームを区別する方法。 | |
9.2.4 シンボル関数インダイレクション | シンボルがリストのcarにあればそのシンボルを通じて実際の関数を見つける。 | |
9.2.5 関数フォームの評価 | 関数を呼び出すフォーム。 | |
9.2.6 Lispマクロの評価 | マクロを呼び出すフォーム。 | |
9.2.7 スペシャルフォーム | スペシャルフォームは特異なプリミティブであり、それらのほとんどがとても重要である。 | |
9.2.8 自動ロード | 実際の定義を含むファイルのロードをセットアップする関数。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
自己評価フォーム(self-evaluating
form)はリストやシンボルではないすべてのフォームです。自己評価フォームはそのフォーム自身を評価します。評価の結果は評価されたオブジェクトと同じです。したがって数字の25は25、文字列"foo"
は文字列"foo"
に評価されます。同様にベクターの評価では、ベクターの要素の評価は発生しません
— 内容が変更されずに同じベクターがリターンされます。
'123 ; 評価されずに表示される数字
⇒ 123
123 ; 通常どおり評価され、同じものがreturnされる
⇒ 123
(eval '123) ; 手動での評価 — 同じものがreturnされる
⇒ 123
(eval (eval '123)) ; 2度評価しても何も変わらない。
⇒ 123
自己評価されるという事実による利点から数字、文字、文字列、そしてベクターでさえLispコード内で記述されるのが一般的です。しかし入力構文がない型にたいしてこれを行なうのは極めて異例です。なぜなら、これらをテキスト的に記述する方法がないからです。Lispプログラムを使用してこれらの型を含むLisp式を構築することは可能です。以下は例です:
;; バッファーオブジェクトを含む式を構築する。
(setq print-exp (list 'print (current-buffer)))
⇒ (print #<buffer eval.texi>)
;; それを評価する。
(eval print-exp)
-| #<buffer eval.texi>
⇒ #<buffer eval.texi>
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
シンボルが評価されるときは変数として扱われます。それが値をもつなら結果はその変数の値になります。そのシンボルが変数としての値をもたなければ、Lispインタープリターはエラーをシグナルします。変数の使用法についての情報は変数を参照してください。
以降の例ではsetq
でシンボルに値をセットしています。その後シンボルを評価してからをsetq
に戻します。
(setq a 123) ⇒ 123
(eval 'a) ⇒ 123
a ⇒ 123
シンボルnil
とt
は特別に扱われるので、nil
の値は常にnil
、t
の値は常にt
になります。これらに他の値をセットしたり、他の値にバインドすることはできません。したがってこの2つのシンボルは、(たとえeval
がそれらを他の任意のシンボルと同様に扱うとはいえ)自己評価フォームと同じように振る舞います。名前が‘:’で始まるシンボルも同じ方法で自己評価されます。そして、(通常は)値を変更できない点も同じです。Variables that Never Changeを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
空ではないリストフォームは関数呼び出し、マクロ呼び出し、スペシャルフォームのいずれかで、それは1番目の引数にしたがいます。これら3種のフォームは、以下で説明するように異なる方法で評価されます。残りの要素は関数、マクロ、またはスペシャルフォームにたいする引数(arguments)を構成します。
空ではないリストを評価する最初のステップは、1番目の要素の確認です。この要素は単独でそのリストがどの種類のフォームなのかと、残りの引数をどのように処理するがを決定します。SchemeのようなLisp方言とは異なり、1番目の要素は評価されません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
リストの最初の要素がシンボルなら、評価はそのシンボルの関数セルを調べて、元のシンボルの代わりに関数セルの内容を使用します。その内容が他のシンボルなら、シンボルではないものが得られるまでこのプロセスが繰り返されます。このプロセスのことをシンボル関数インダイレクション(symbol function indirection: indirectionは間接の意)と呼びます。シンボル関数インダイレクションについての情報は関数の命名を参照してください。
このプロセスの結果、シンボルの関数セルが同じシンボルを参照する場合には、無限ループを起こす可能性があります。それ以外なら最終的には非シンボルにたどりつき、それは関数か他の適切なオブジェクトである必要があります。
適切なオブジェクトとは、より正確にはLisp関数(ラムダ式)、バイトコード関数、プリミティブ関数、Lispマクロ、スペシャルフォーム、またはオートロードオブジェクトです。これらそれぞれの型については以降のセクションで説明します。これらの型以外のオブジェクトならEmacsはinvalid-function
エラーをシグナルします。
以下の例はシンボルインダイレクションのプロセスを説明するものです。わたしたちはシンボルの関数セルへの関数のセットにfset
、関数セルの内容(関数セルの内容へのアクセスを参照)の取得にsymbol-function
を使用します。具体的にはfirst
の関数セルにシンボルcar
を格納して、シンボルfirst
をerste
の関数セルに格納します。
;; この関数セルのリンクを構築する:
;; ------------- ----- ------- -------
;; | #<subr car> | <-- | car | <-- | first | <-- | erste |
;; ------------- ----- ------- -------
(symbol-function 'car) ⇒ #<subr car>
(fset 'first 'car) ⇒ car
(fset 'erste 'first) ⇒ first
(erste '(1 2 3)) ; erste
により参照される関数を呼び出す
⇒ 1
対照的に、以下の例ではシンボル関数インダイレクションを使用せずに関数を呼び出しています。なぜなら1番目の要素はシンボルではなく、無名Lisp関数(anonymous Lisp function)だからです。
((lambda (arg) (erste arg)) '(1 2 3)) ⇒ 1
関数自身を実行するとその関数のbodyを評価します。ここではerste
を呼び出すとき、シンボル関数インダイレクションが行なわれています。
このフォームが使用されるのは稀であり、現在では推奨されていません。かわりに以下のように記述するべきです:
(funcall (lambda (arg) (erste arg)) '(1 2 3))
または単に
(let ((arg '(1 2 3))) (erste arg))
ビルトイン関数のindirect-function
は、明示的にシンボル関数インダイレクションを処理するための簡単な方法を提供します。
この関数はfunctionが意味するものを関数としてリターンする。functionがシンボルならfunctionの関数定義を探して、その値で最初からやり直す。functionがシンボルでなければfunction自身をリターンする。
この関数は最終的なシンボルがバインドされていなければnil
をリターンする。特定のシンボル内にループがれば、この関数はcyclic-function-indirection
エラーをシグナルする。
オペション引数noerrorは廃れており、後方互換のためだけのもので効果はない。
以下はLispでindirect-function
を定義する例である:
(defun indirect-function (function) (if (symbolp function) (indirect-function (symbol-function function)) function))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
リストの1番目の要素がLispの関数オブジェクト、バイトコードオブジェクト、プリミティブ関数オブジェクトのいずれかと評価されると、そのリストは関数呼び出し(function
call)になります。たとえば、以下は関数+
を呼び出します:
(+ 1 x)
関数呼び出しを評価する最初のステップでは、そのリストの残りの要素を左から右に評価します。結果は引数の実際の値で、リストの各要素にたいして1つの値となります。次のステップでは関数apply
(関数の呼び出しを参照)を使用して、引数のリストでその関数を呼び出します。関数がLispで記述されていたら引数はその関数の引数変数にバインドするために使用されます。その後に関数body内のフォームが順番に評価されて、リストのbodyフォームの値が関数呼び出しの値になります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
リストの最初の要素がマクロオブジェクトと評価されると、そのリストはマクロ呼び出し(macro call)になります。マクロ呼び出しが評価されるとき、リストの残りの要素は最初は評価されません。そのかわりこれらの要素自体がマクロの引数に使用されます。そのマクロ定義は、元のフォームが評価される場所で置換フォームを計算します。これをマクロの展開(expansion)と言います。展開した結果は、任意の種類のフォーム — 自己評価定数、シンボル、リストになります。展開した結果自体がマクロ呼び出しなら、結果が他の種類のフォームになるまで、繰り返し展開処理が行なわれます。
通常のマクロ展開は、その展開結果を評価することにより終了します。しかし他のプログラムもマクロ呼び出しを展開し、それらが展開結果を評価するか、あるいは評価しないかもしれないので、そのマクロ展開が即時または最終的に評価される必要がない場合があります。
引数式は通常はマクロ展開の計算の一部としては評価されませんが、展開の部分として出現するので、展開結果が評価されるときに計算されます。
たとえば以下のようなマクロ定義が与えられたとします:
(defmacro cadr (x) (list 'car (list 'cdr x)))
(cadr (assq 'handler list))
のような式はマクロ呼び出しであり、展開結果は以下のようになります:
(car (cdr (assq 'handler list)))
引数(assq 'handler list)
が展開結果に含まれることに注意してください。
Emacs Lispマクロの完全な説明はマクロを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
スペシャルフォーム(special form)とは、特別だとマークされたプリミティブ関数であり、その引数のすべては評価されません。もっとも特別なフォームは制御構文の定義や変数バインディングの処理等、関数ではできないことを行ないます。
スペシャルフォームはそれぞれ、どの引数を評価して、どの引数を評価しないかについて独自のルールをもちます。特定の引数が評価されるかどうかは、他の引数を評価した結果に依存します。
式の最初のシンボルがスペシャルフォームなら、式はそのスペシャルフォームのルールにしたがう必要があります。それ以外ならEmacsの挙動は(たとえクラッシュしなくいとしても)未定義です。たとえば((lambda
(x) x . 3)
4)
はlambda
で始まるサブ式を含みますが、これは適正なlambda
式ではないので、Emacsはエラーをシグナルするかもしれないし、3や4やnil
をリターンしたり、もしかしたら他の挙動を示すかもしれません。
この述語は引数がスペシャルフォームかをテストして、スペシャルフォームならt
、それ以外ならnil
をリターンする。
以下にEmacs Lispのスペシャルフォームすべてと、それらがどこで説明されているかのリファレンスをアルファベット順でリストします。
and
条件の組み合わせを参照のこと。
catch
明示的な非ローカル脱出: catch
とthrow
を参照のこと。
cond
条件を参照のこと。
condition-case
エラーを処理するコードの記述を参照のこと。
defconst
グローバル変数の定義を参照のこと。
defvar
グローバル変数の定義を参照のこと。
function
無名関数を参照のこと。
if
条件を参照のこと。
interactive
interactiveな呼び出しを参照のこと。
lambda
ラムダ式を参照のこと。
let
let*
ローカル変数を参照のこと。
or
条件の組み合わせを参照のこと。
prog1
prog2
progn
順序を参照のこと。
quote
クォートを参照のこと。
save-current-buffer
カレントバッファーを参照のこと。
save-excursion
エクスカーションを参照のこと。
save-restriction
ナローイングを参照のこと。
setq
変数の値のセットを参照のこと。
setq-default
バッファーローカルなバインディングの作成と削除を参照のこと。
track-mouse
マウスの追跡を参照のこと。
unwind-protect
非ローカル脱出を参照のこと。
while
繰り返しを参照のこと。
Common Lispに関する注意: GNU EmacsとCommon Lispのスペシャルフォームを比較する。
setq
、if
、catch
はEmacs LispとCommon Lispの両方でスペシャルフォームである。save-excursion
はEmacs Lispではスペシャルフォームだが、Common Lispには存在しない。throw
はCommon Lispではスペシャルフォーム(なぜなら複数の値をthrowできなければならない)だが、Emacs Lispでは(複数の値をもたない)関数である。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
オートロード(autoload)機能により、まだ関数定義がEmacsにロードされていない関数(またはマクロ)を呼び出すことができます。オートロードは定義がどのファイルに含まれるかを指定します。オートロードオブジェクトがシンボルの関数定義にある場合は、関数としてそのシンボルを呼び出すことにより、自動的に指定されたファイルがロードされます。その後にファイルからロードされた実際の定義を呼び出します。シンボル内の関数定義としてオートロードオブジェクトをアレンジする方法はautoloadで説明します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
スペシャルフォームquote
は、単一の引数を記述されたままに評価せずにリターンします。これはプログラムに自己評価オブジェクトではない、定数シンボルや定数リストを含める方法を提供します(数字、文字列、ベクターのような自己評価オブジェクトをクォートする必要はない)。
このスペシャルフォームは評価せずにobjectをリターンする。
quote
はプログラム中で頻繁に使用されるので、Lispはそれにたいする便利な入力構文を提供します。アポストロフィー文字(‘'’)に続けてLispオブジェクト(の入力構文)を記述すると、それは1番目の要素がquote
、2番目の要素がそのオブジェクトであるようなリストに展開されます。つまり入力構文'x
は(quote
x)
の略記になります。
以下にquote
を使用した式の例をいくつか示します:
(quote (+ 1 2)) ⇒ (+ 1 2)
(quote foo) ⇒ foo
'foo ⇒ foo
''foo ⇒ (quote foo)
'(quote foo) ⇒ (quote foo)
['foo] ⇒ [(quote foo)]
他のクォート構文としては、コンパイル用にLispで記述された無名のラムダ式の元となるfunction
(無名関数を参照)、リストを計算して置き換える際にリストの一部だけをクォートするために使用される‘`’(バッククォートを参照)があります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッククォート構文(backquote
constructs)を使用することにより、リストをクォートしてそのリストのある要素を選択的に評価することができます。もっとも簡単な使い方ではスペシャルフォームquote
と同じです
(前のセクションで説明済み。クォートを参照)。
たとえば以下の2つのフォームは同じ結果を生みます:
`(a list of (+ 2 3) elements) ⇒ (a list of (+ 2 3) elements)
'(a list of (+ 2 3) elements) ⇒ (a list of (+ 2 3) elements)
バッククォートする引数の内側でスペシャルマーカー‘,’を使用すると、それは値が定数でないことを示します。Emacs Lispエバリュエーターは‘,’がついた引数を放置して、リスト構文内にその値を配置します:
`(a list of ,(+ 2 3) elements) ⇒ (a list of 5 elements)
‘,’による置き換えを、リスト構文のより深いレベルでも使用できます。たとえば:
`(1 2 (3 ,(+ 4 5))) ⇒ (1 2 (3 9))
スペシャルマーカー‘,@’を使用すれば、評価された値を結果リストに継ぎ足す(splice)こともできます。継ぎ足されたリストの要素は、結果リスト内の他の要素と同じレベルになります。‘`’を使用しない等価なコードは読むのが困難なことがよくあります。以下にいくつかの例を示します:
(setq some-list '(2 3)) ⇒ (2 3)
(cons 1 (append some-list '(4) some-list)) ⇒ (1 2 3 4 2 3)
`(1 ,@some-list 4 ,@some-list) ⇒ (1 2 3 4 2 3)
(setq list '(hack foo bar)) ⇒ (hack foo bar)
(cons 'use (cons 'the (cons 'words (append (cdr list) '(as elements))))) ⇒ (use the words foo bar as elements)
`(use the words ,@(cdr list) as elements) ⇒ (use the words foo bar as elements)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フォームはほとんどの場合、実行されるプログラム内に出現することにより自動的に評価されます。ごく稀に実行時 —
たとえば編集されているテキストやプロパティーリストから取得したフォームを読み取った後 —
に計算されるようにフォームを評価するコードを記述する必要があるかもしれません。このようなときはeval
関数を使用します。eval
が不必要だったり、かわりに他の何かを使用すべきときがよくあります。たとえば変数から値を取得するにはeval
も機能しますが、symbol-value
のほうが適しています。eval
で評価するためにプロパティーリストに式を格納するかわりに、funcall
に渡すように関数を格納した方がよいでしょう。
このセクションで説明する関数と変数はフォームの評価、評価処理の制限の指定、最後にリターンされた値の記録を行なうものです。ファイルのロードでも評価が行なわれます(ロードを参照)。
データ構造に式を格納して評価するより、データ構造に関数を格納してfuncall
やapply
で呼び出すほうが、より明解で柔軟です。関数を使用することにより、引数に情報を渡す能力が提供されます。
これは式を評価する基本的な関数である。この関数はカレント環境内でformを評価して、その結果をリターンする。formオブジェクトの型はそれが評価される方法を決定します。フォームの種類を参照のこと。
引数lexicalは、ローカル変数にたいするスコープ規則(変数のバインディングのスコーピングルールを参照)を指定する。これが省略またはnil
ならデフォルトのダイナミックスコープ規則を使用してformを評価することを意味する。t
ならレキシカルスコープ規則が使用されることを意味する。lexicalの値にはレキシカルバインディングでの特定のレキシカル環境(lexical
environment)を指定する空ではないalistも指定できる。しかしこの機能はEmacs
Lispデバッガーのような、特別な用途にたいしてのみ有用。レキシカルバインディングを参照のこと。
eval
は関数なのでeval
呼び出しに現れる引数式は2回 —
eval
が呼び出される前の準備で一度、eval
関数自身によりもう一度 — 評価される。以下に例を示す:
(setq foo 'bar) ⇒ bar
(setq bar 'baz) ⇒ baz ;;eval
が引数foo
を受け取る (eval 'foo) ⇒ bar ;;eval
が、foo
の値である、引数bar
を受け取る (eval foo) ⇒ baz
eval
で現在アクティブな呼び出しの数はmax-lisp-eval-depth
に制限される(以下参照)。
この関数はカレントバッファー内の、位置startとendで定義されるリージョン内のフォームを評価する。この関数はリージョンからフォームを読み取ってeval
を呼び出す。これはリージョンの最後に達するか、処理されないエラーがシグナルされるまで行なわれる。
デフォルトではeval-region
は出力を何も生成しない。しかしstreamが非nil
なら出力関数(出力関数を参照)で生成された任意の出力、同様にリージョン内の式を評価した結果の値が、streamを使用してプリントされる。出力ストリームを参照のこと。
read-functionが非nil
なら、read
のかわりに1つずつ式を読み取るために使用する関数を指定すること。これは入力を読み取るストリームを指定する、1つの引数で呼び出される関数である。この関数を指定するために変数load-read-function
(How Programs Do
Loadingを参照)も使用できるが、引数read-functionを使用するほうが堅実である。
eval-region
はポイントを移動しない。常にnil
をリターンする。
この関数はeval-region
と似ているが、引数は異なるオプション機能を提供する。eval-buffer
はバッファーbuffer-or-nameのアクセス可能な部分(Narrowing in The GNU Emacs
Manualを参照)の全体を処理する。buffer-or-nameにはバッファー名(文字列)を指定でき、nil
(または省略)のときはカレントバッファーを意味する。streamが非nil
、またはprintがnil
なら、eval-region
のようにstreamが使用される。この場合には式の評価結果の値は依然として破棄されるが、出力関数による出力はエコーエリアにプリントされる。filenameはload-history
(アンロードを参照)に使用されるファイル名であり、デフォルトはbuffer-file-name
(バッファーのファイル名を参照)。unibyteが非nil
ならread
可能な限りは文字列をユニコードに変換する。
eval-current-buffer
はこのコマンドのエイリアスである。
この変数はエラー(エラーメッセージは"Lisp nesting exceeds
max-lisp-eval-depth"
)がシグナルされる前にeval
、apply
、funcall
の呼び出しで許容される最大の深さを定義する。
制限を超過時のエラーを付随するこの制限は、誤って定義された関数による無限再帰をEmacs
Lispが回避する方法の1つである。max-lisp-eval-depth
の値を過大に増加させると、そのようなコードはかわりにスタックオーバーフローを起こすだろう。オーバーフローを処理できるシステムがいくつかある。この場合には通常のLisp評価は割り込まれて、制御はトップレベルのコマンドループ(top-level
)に戻される。この状況ではEmacs
Lispデバッガにエンターする手段は存在しないことに注意されたい。エラーによるデバッガへのエンターを参照のこと。
Lisp式に記述された関数の呼び出し、関数呼び出しの引数と関数bodyフォームにたいする再帰評価、Lispコード内での明示的な呼び出し等では内部的にeval
、apply
、funcall
を使用して深さ制限を計数する。
この変数のデフォルト値は400。この値を100未満にセットして値が与えられた値に達すると、Lispはそれを100にリセットする。デバッガ自身を実行するために空きが必要になるので、Lispデバッガに入ったとき空きが少なければこの値が増加されます。
max-specpdl-size
はネストの他の制限を提供する。Local Variablesを参照のこと。
この変数の値は読み取り、評価、プリントを行なった標準的なEmacsコマンドにより、バッファー(ミニバッファーを含む)からリターンされる値のリストである(これには*ielm*バッファーでの評価や、lisp-interaction-mode
でのC-jやC-x
C-e、類似の評価コマンドを使用した評価は含まれないことに注意)。要素の順番はもっとも最近のものが最初になる。
(setq x 1) ⇒ 1
(list 'A (1+ 2) auto-save-default) ⇒ (A 3 t)
values ⇒ ((A 3 t) 1 …)
この変数は最近評価されたフォームの値を後で参照するのに有用。values
自体の値のプリントは、値がおそらく非常に長くなるので通常は悪いアイデアである。かわりに以下のように特定の要素を調べること:
;; もっとも最近評価された結果を参照する
(nth 0 values)
⇒ (A 3 t)
;; これは新たな要素をputするので ;; すべての要素が1つ後に移動する (nth 1 values) ⇒ (A 3 t)
;; これは次に新しい、この例の前の次に新しい要素を取得する
(nth 3 values)
⇒ 1
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispプログラムは一連の式、あるいはフォーム (フォームの種類を参照)により形成されます。これらのフォームの実行順は制御構造(control structures)で囲むことによって制御します。制御構造とはその制御構造が含むフォームをいつ、どのような条件で、何回実行するかを制御するスペシャルフォームです。
もっとも単純な実行順は1番目はa、2番目はb、...というシーケンシャル実行(sequential execution: 順番に実行)です。これは関数のbody内の連続する複数のフォームや、Lispコードのファイル内のトップレベルを記述したときに発生します — つまりフォームは記述した順に実行されます。わたしたちはこれをテキスト順(textual order)と呼びます。たとえば関数のbodyが2つのフォームaとbから構成される場合、関数の評価は最初にa、次にbを評価します。bを評価した結果がその関数の値となります。
明示的に制御構造を使用することにより、非シーケンシャルな順番での実行が可能になります。
Emacs Lispは他の様々な順序づけ、条件、繰り返し、(制御された)ジャンプを含む複数の種類の制御構造を提供しており、以下ではそれらのすべてを記述します。ビルトインの制御構造は制御構造のサブフォームが評価される必要がなかったり、順番に評価される必要がないのでスペシャルフォームです。独自の制御構造を構築するためにマクロを使用することができます(マクロを参照)。
10.1 順序 | テキスト順の評価。 | |
10.2 条件 | if 、cond 、when 、unless 。
| |
10.3 条件の組み合わせ | and 、or 、not 。
| |
10.4 繰り返し | while ループ。
| |
10.5 Generators | 汎用のシーケンスとコルーチン。 | |
10.6 非ローカル脱出 | シーケンスの外へのジャンプ。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フォームを出現順に評価するのは、あるフォームから別のフォームに制御を渡すもっとも一般的な制御です。関数のbodyのようなコンテキストにおいては自動的にこれが行なわれます。他の場所ではこれを行なうために制御構造を使用しなければなりません。Lispで一単純な制御構造はprogn
です。
スペシャルフォームprogn
は以下のようなものです:
(progn a b c …)
これは順番にa、b、c、...を実行するよう指定します。これらはprogn
フォームのbodyと呼ばれます。body内の最後のフォームの値がprogn
全体の値になります。(progn)
はnil
をリターンします。
初期のLispではprogn
は、連続で複数のフォームを実行して最後のフォームの値を使用する唯一の方法でした。しかしプログラマーは関数のbodyの、(その時点では)1つのフォームだけが許される場所でprogn
を使用する必要が多いことに気づきました。そのため関数のbodyを暗黙のprogn
にして、progn
のbodyのように複数のフォームを記述できるようにしました。他の多くの制御構造も暗黙のprogn
を同様に含みます。結果として昔ほどprogn
は多用されなくなりました。現在ではprogn
が必要になるのはunwind-protect
、and
、or
、またはif
のthenパートの中であることがほとんどです。
このスペシャルフォームはformsのすべてをテキスト順に評価してフォームの結果をリターンする。
(progn (print "The first form") (print "The second form") (print "The third form")) -| "The first form" -| "The second form" -| "The third form" ⇒ "The third form"
他の2つの構文は一連のフォームを同様に評価しますが、異なる値をリターンします:
このスペシャルフォームはform1とformsのすべてをテキスト順に評価してform1の結果をリターンする。
(prog1 (print "The first form") (print "The second form") (print "The third form")) -| "The first form" -| "The second form" -| "The third form" ⇒ "The first form"
以下の例は変数x
のリストから1番目の要素を削除して、削除した1番目の要素の値をリターンする:
(prog1 (car x) (setq x (cdr x)))
このスペシャルフォームはform1、form2、その後のformsのすべてをテキスト順で評価してform2の結果をリターンする。
(prog2 (print "The first form") (print "The second form") (print "The third form")) -| "The first form" -| "The second form" -| "The third form" ⇒ "The second form"
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
条件による制御構造は選択肢の中から選択を行ないます。Emacs
Lispには4つの条件フォームをもちます。if
は他の言語のものとほとんど同じです。when
とunless
はif
の変種です。cond
は一般化されたcase命令です。
if
はconditionの値にもとづきthen-formとelse-formsを選択する。評価されたconditionが非nil
ならthen-formが評価されて結果がリターンされる。それ以外ならelse-formsがテキスト順に評価されて最後のフォームの値がリターンされる(if
のelseパートは暗黙のprogn
の例である。順序を参照)。
conditionの値がnil
でelse-formsが与えられなければ、if
はnil
をリターンする。
選択されなかったブランチは決して評価されない — 無視される —
ので、if
はスペシャルフォームである。したがって以下の例ではprint
が呼び出されることはないのでtrue
はプリントされない。
(if nil (print 'true) 'very-false) ⇒ very-false
これはelse-formsがなく、複数のthen-formsが可能なif
の変種である。特に、
(when condition a b c)
は以下と完全に等価である
(if condition (progn a b c) nil)
これはthen-formがないif
の変種です:
(unless condition a b c)
は以下と完全に等価である
(if condition nil a b c)
cond
は任意個数の選択肢から選択を行なう。cond
内の各clauseはリストでなければならない。このリストのCARはconditionで、(もしあれば)残りの要素はbody-formsとなる。したがってclauseは以下のようになる:
(condition body-forms…)
cond
は各clauseのconditionを評価することにより、テキスト順でclauseを試みる。conditionの値が非nil
ならそのclauseは成り立つ。その後にcond
はそのclauseのbody-formsを評価して、body-formsの最後の値をリターンする。残りのclauseは無視される。
conditionの値がnil
ならそのclauseは失敗して、cond
は次のclauseに移動してそれのconditionを試みる。
clauseは以下のようにも見えるかもしれない:
(condition)
conditionがテストされたときに非nil
なら、cond
フォームはconditionの値をリターンする。
すべてのconditionがnil
に評価された場合 —
つまりすべてのclauseが不成立なら、cond
はnil
をリターンする。
以下の例はx
の値が数字、文字列、バッファー、シンボルなのかをテストする4つのclauseをもつ:
(cond ((numberp x) x) ((stringp x) x) ((bufferp x) (setq temporary-hack x) ; 1つのclauseに (buffer-name x)) ; 複数bodyフォーム ((symbolp x) (symbol-value x)))
前のclauseが不成立のとき最後の条項を実行したいときがよくある。これを行なうには(t
body-forms)
のように、conditionの最後のclauseにt
を使用する。フォームt
はt
に評価され決してnil
にならないので、このclauseが不成立になることはなく最終的にcond
はこのclauseに到達する。たとえば:
(setq a 5) (cond ((eq a 'hack) 'foo) (t "default")) ⇒ "default"
このcond
式はa
の値がhack
ならfoo
、それ以外は文字列"default"
をリターンする。
すべての条件構文はcond
かif
のいずれかで表すことができます。したがってどちらを選択するかはスタイルの問題になります。たとえば:
(if a b c) ≡ (cond (a b) (t c))
10.2.1 パターンマッチングによるcase文 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
cond
フォームにより、あらかじめ記述された既知の特定の値と式の値を比較する述語条件を使用して選択肢を選択できます。しかし広範な値クラス間を区別する、より一般的な条件にもとづいて選択肢を選択するのが有用なこともあります。pcase
マクロにより、一連のパターンにたいする式の値のマッチングにもとづいて選択肢を選択できます。パターンにはリテラル値(cond
で使用した比較用のリテラル値)や、予想される式の値のより一般的な構造記述を使用できます。
expressionを評価して、任意個数の選択肢の中からexpressionの値にもとづいた選択を行う。可能な選択肢はclausesで指定され、それぞれが(pattern
body-forms…)
という形式のリストでなければならない。pcase
はexpressionの値と各clauseのpatternのマッチを試みる。値がマッチしたらそのclauseが成功となり、pcase
はそれのbody-formsを評価して、body-formsの最後の値をリターンする。残りのclausesはすべて無視される。
patternパートはバッククォートでクォートされたQPatternと、クォートされていないUPatternのいずれかで指定できる。UPatternsのほうが単純なのでそれから説明する。
注意:
以下のパターンの記述ではpcase
の1つ目の引数となるexpressionの値を参照するために、“マッチされる値”という言葉を使用している。
UPatternには以下の形式を指定できる:
'val
マッチされる値がvalとequal
ならマッチ。
atom
任意のatom
(キーワード、数字、文字列)にマッチする(これらは自己クォートされるのでこの種のUPatternは実際には'atom
の略記である)。文字列(浮動小数点数)は同じ内容(値)の任意の文字列(浮動小数点数)とマッチすることに注意。
_
任意の値にマッチする。これはdon’t careやwildcardとして知られる。
symbol
任意の値にマッチする。さらにマッチした値をsymbolにletバインドするので、body-formsや後続のパターンからそれを参照することができる。
(pred predfun)
マッチされる値を引数として述語関数predfunを呼び出して、非nil
をリターンしたらマッチ。predfunは後述するフォームのいずれかを指定できる。
(guard boolean-expression)
boolean-expressionが非nil
に評価されたらマッチ。これにより以前のUPatternで、値(マッチされる値を含む)にバインドされたシンボルを参照するブール条件をUPatternに含めることができる。典型的にはUPattern
and
内で使用される(以下参照)。たとえば(and x (guard (< x 10)))
は10より小さい任意の数にマッチして、その数を変数x
にletバインドする。
(let upattern expression)
指定されたexpressionが指定されたupatternにマッチしたらマッチ。これによりpcase
の1つ目の引数だけでなく、任意の式の値にパターンをマッチできる(upatternはUPattern
symbolを使用してシンボルを値にバインドできるのでlet
と呼ばれる。たとえば((or `(key . ,val) (let val 5)) val)
)。
(app function upattern)
マッチされる値にfunctionを適用してupatternにマッチする値がリターンされたらマッチ。これはUPattern
pred
と似ているが、これはブールの真値ではなくUPatternにたいして結果をテストする点が異なる。function呼び出しは後述のフォームのいずれかを使用できる。
(or upattern1 upattern2…)
引数のUPatternのいずれかがマッチしたらマッチ。マッチする最初のUPatternが見つかったら残りはテストされない。この理由により、マッチされる値にシンボルをletバインドするすべてのUPatternは同じシンボルをバインドすること。
(and upattern1 upattern2…)
引数のUPatternすべてがマッチしたらマッチ。
pred
とapp
のUPatternで使用される関数呼び出しは、以下のいずれかのフォームをもつことができる:
integerp
のような関数シンボルこの場合には、その名前つき関数がマッチされる値に適用される。
(lambda (arg) body)
この場合には、そのラムダ関数がマッチされる値を単一の引数として呼び出される。
(func args…)
これは指定されたn個の引数で呼び出される関数である。関数はこれらn個の引数と、マッチされる値であるn+1番目の引数を追加して呼び出される。
以下はUPatternを使用した説明用の例です:
(pcase (get-return-code x) ('success (message "Done!")) ('would-block (message "Sorry, can't do it now")) ('read-only (message "The shmliblick is read-only")) ('access-denied (message "You do not have the needed rights")) (code (message "Unknown return code %S" code)))
加えてより強力なバッククォートされたパターンを使用できます。これらを使用すればpcase
の1つ目の引数の式の値を、その構造(structure)の仕様とマッチさせることができます。たとえば1つ目の要素が特定の文字列で、2つ目の要素が`("first"
,second-elem)
のようなバッククォートされた任意の値であるような2要素のリストを、値として強制指定することができます。
バッククォートされたパターンは`qpattern
という形式をもち、qpatternは以下の形式をもつことができます:
(qpattern1 . qpattern2)
マッチされる値が、car
がqpattern1、cdr
がqpattern2にマッチするようなコンスセルならマッチ。これは(qpattern1 qpattern2 …)
のように、容易にバッククォートされたリストに一般化できる。
[qpattern1 qpattern2 … qpatternm]
マッチされる値が、長さmで0
から(m-1)
番目の要素がそれぞれqpattern1、qpattern2、…、qpatternmにマッチするようなベクターならマッチ。
atom
マッチされる値の対応する要素が指定されたatomとequal
ならマッチ。
,upattern
マッチされる値の対応する要素が指定されたupatternとマッチすればマッチ。
QPatternは後述のpcase-defmacro
を使用してUPatternのトップレベルで実装されているので、QPatternの使用はUPatternを使用することでのみ表現可能なことに注意。とはいえQPatternの使用により、多くの場合コードの可読性は向上するだろう。
以下はpcase
を使用して、小さな式言語用のシンプルなインタープリターを実装する例です(この例にはレキシカルバインディングが必要なことに注意。)レキシカルバインディングを参照のこと):
(defun evaluate (exp env) (pcase exp (`(add ,x ,y) (+ (evaluate x env) (evaluate y env))) (`(call ,fun ,arg) (funcall (evaluate fun env) (evaluate arg env))) (`(fn ,arg ,body) (lambda (val) (evaluate body (cons (cons arg val) env)))) ((pred numberp) exp) ((pred symbolp) (cdr (assq exp env))) (_ (error "Unknown expression %S" exp))))
ここで`(add ,x
,y)
は、exp
がリテラルシンボルadd
で始まる3要素のリストであることをチェックしてから、2つ目と3つ目の要素を抽出して変数x
とy
にバインドするパターンです。それからx
とy
を評価して結果を加算します。同様にcall
とfn
のパターンは、関数呼び出しに相当するものを2つ実装します。(pred
numberp)
はexp
が数であるかをチェックして、もしそうならそれを評価します。(pred
symbolp)
はシンボルにマッチして、その連想をリターンします。最後に_
はすべてにマッチするcatch-allパターンなので、構文エラーの報告に適しています。
以下は評価した結果を含む、この小さな言語のサンプルプログラムの例です:
(evaluate '(add 1 2) nil) ;=> 3 (evaluate '(add x y) '((x . 1) (y . 2))) ;=> 3 (evaluate '(call (fn x (add 1 x)) 2) nil) ;=> 3 (evaluate '(sub 1 2) nil) ;=> error
pcase-defmacro
を使用することにより追加のUPatternを定義できます。
pcase
にたいして新たな種類のUPatternを定義する。新たなUPatternは(name
actual-args)
のように呼び出されるだろう。bodyには、UPattern
nameを他の何らかのUPatternに書き換える方法を記述すること。argsがactual-argsにバインドされる環境でbodyを評価した結果がこの書き換えとなる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは複雑な条件を表現するためにif
やcond
とともによく使用される3つの構文を説明します。and
とor
の構文は、ある種の複数条件の構文として個別に使用することもできます。
この関数はconditionが偽であることをテストする。この関数はconditionがnil
ならt
、それ以外はnil
をリターンする。関数not
はnull
と等価であり、空のリストをテストする場合はnull
の使用を推奨する。
スペシャルフォームand
は、すべてのconditionsが真かどうかをテストする。この関数はconditionsを記述順に1つずつ評価することにより機能する。
あるconditionsがnil
に評価されると、残りのconditionsに関係なく、and
はnil
をリターンしなければならない。この場合and
は即座にnil
をリターンして、残りのconditionsは無視される。
すべてのconditionsが非nil
なら、それらの最後の値がand
フォームの値になる。conditionsがない単独の(and)
はt
をリターンする。なぜならすべてのconditionsが非nil
となるので、これは適切である(考えてみてみよ、非nil
でないconditionsはどれか?)。
以下に例を示す。1番目の条件は整数1をリターンし、これはnil
ではまい。同様に2番目の条件は整数2をリターンし、これもnil
ではない。3番目の条件はnil
なので、のこりの条件が評価されることは決してない。
(and (print 1) (print 2) nil (print 3)) -| 1 -| 2 ⇒ nil
以下はand
を使用した、より現実的な例である:
(if (and (consp foo) (eq (car foo) 'x)) (message "foo is a list starting with x"))
(consp foo)
がnil
をリターンすると、(car
foo)
は実行されないのでエラーにならないことに注意。
if
かcond
のいずれかを使用して、and
式を記述することもできる。以下にその方法を示す:
(and arg1 arg2 arg3) ≡ (if arg1 (if arg2 arg3)) ≡ (cond (arg1 (cond (arg2 arg3))))
スペシャルフォームor
は、少なくとも1つのconditionsが真かどうかをテストする。この関数はすべてのconditionsを1つずつ、記述された順に評価することにより機能する。
あるconditionsが非nil
値に評価されたら、or
の結果は非nil
でなければならない。この場合or
は即座にリターンし、残りのconditionsは無視される。この関数がリターンする値は、非nil
値に評価された条件の値そのものである。
すべてのconditionsがnil
なら、or
式はnil
をリターンします。conditionsのない単独の(or)
はnil
をリターンする。なぜならすべてのconditionsがnil
になるのでこれは適切である(考えてみよ、nil
でないconditionsはどれか?)。
たとえば以下の式は、x
がnil
か整数0かどうかをテストする:
(or (eq x nil) (eq x 0))
and
構文と同様に、or
をcond
に置き換えて記述することができる。たとえば:
(or arg1 arg2 arg3) ≡ (cond (arg1) (arg2) (arg3))
ほとんどの場合は、or
をif
に置き換えて記述できるが完全ではない:
(if arg1 arg1 (if arg2 arg2 arg3))
これは完全に同一ではない。なぜならarg1かarg2を2回評価するかもしれないからである。対照的に(or
arg1 arg2 arg3)
が2回以上引数を評価することは決してない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
繰り返し(iteration)とは、プログラムの一部を繰り返し実行することを意味します。たとえばリストの各要素、または0からnの整数にたいして、繰り返し一度ずつ何らかの計算を行いたいとしましょう。Emacs
Lispではスペシャルフォームwhile
でこれを行なうことができます:
while
は最初にconditionを評価する。結果が非nil
ならformsをテキスト順に評価する。その後にconditionを再評価して結果が非nil
なら、再度formsを評価する。この処理はconditionがnil
に評価されるまで繰り返される。
繰り返し回数に制限はない。このループはconditionがnil
に評価されるか、エラーになるか、またはthrow
で抜け出す(非ローカル脱出を参照)まで継続される。
while
フォームの値は常にnil
である。
(setq num 0) ⇒ 0
(while (< num 4) (princ (format "Iteration %d." num)) (setq num (1+ num))) -| Iteration 0. -| Iteration 1. -| Iteration 2. -| Iteration 3. ⇒ nil
各繰り返しごとに何かを実行して、その後も終了テストを行なうrepeat-untilループを記述するには、以下のようにwhile
の1番目の引数としてbodyの後に終了テストを記述して、それをprogn
の中に配置する:
(while (progn (forward-line 1) (not (looking-at "^$"))))
これは1行前方に移動して、空行に達するまで行単位の移動を継続する。独特な点はwhile
がbodyをもたず、終了テスト(これはポイント移動という実処理も行なう)だけを行うことである。
マクロdolist
およびdotimes
は、2つの一般的な種類のループを記述する、便利な方法を提供します。
この構文はlistの各要素に一度bodyを実行して、カレント要素をローカルに保持するように、変数varにバインドする。その後にresultを評価した値、resultが省略された場合はnil
をリターンする。たとえば以下はreverse
関数を定義するためにdolist
を使用する方法の例である:
(defun reverse (list) (let (value) (dolist (elt list value) (setq value (cons elt value)))))
この構文は0以上count未満の各整数にたいして、一度bodyを実行してから、繰り返しのカレント回数となる整数を変数varにバインドする。その後にresultの値、resultが省略された場合はnil
をリターンする。以下はdotimes
を使用して、何らかの処理を100回行なう例である:
(dotimes (i 100) (insert "I will not obey absurd orders\n"))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ジェネレーター(generator)とは、潜在的に無限な値ストリームを生成する関数です。毎回その関数が値を生成するごとに、呼び出し側が次の値を要求するまで、自身をサスペンドします。
iter-defun
はジェネレーター関数を定義する。ジェネレーター関数は通常の関数と同様のsignatureをもつが、異なるように機能する。ジェネレーター関数は呼び出し時にbodyを実行するのではなく、かわりにiteratorオブジェクトをリターンする。このiteratorは値を生成するためにbodyを実行、値を発行するとiter-yield
かiter-yield-from
が出現するまで一時停止する。bodyが正常にリターンした際に、iter-next
がコンディションデータとなるbodyの結果とともに、iter-end-of-sequence
をシグナルする。
body内部では任意の種類のLispコードが有効だが、iter-yield
とiter-yield-from
はunwind-protect
フォームの内部にあってはならない。
iter-lambda
はiter-defun
で生成されたジェネレーター関数と同様な、無名のジェネレーター関数を生成する。
iter-yield
がジェネレーター関数内部で出現した際には、カレントiteratorが一時停止してiter-next
からvalueをリターンすることを示す。iter-yield
は、次回iter-next
呼び出しのvalue
パラメーターへと評価される。
iter-yield-from
はiteratorが生成するすべての値を生成して、そのiteratorのジェネレーター関数が通常リターンする値へと評価される。これが制御を得ている間、iteratorはiter-next
を使用して送信された値を受け取る。
ジェネレーター関数を使用するには、まずそれを普通に呼び出してiteratorオブジェクトを生成します。iteratorはジェネレーターの固有のインスタンスです。その後でこのiteratorから値を取得するためにiter-next
を使用します。iteratorから取得する値がなくなると、iter-next
はそのiteratorの最終値とともにiter-end-of-sequence
のコンディションをraisesします。
ジェネレーター関数のbodyは、iter-next
の呼び出しの内側でのみ実行されることに注意することが重要です。iter-defun
で定義された関数の呼び出しはiteratorを生成します。何か興味があることが発生したら、iter-next
でこのiteratorを制御しなければなりません。ジェネレーター関数の個々の呼び出しは、それぞれが独自に状態をもつ別個のiteratorを生成します。
iteratorから次の値を取得する。(iteratorのジェネレーター関数がリターンしていて)生成される値が存在しない場合、iter-next
はコンディションiter-end-of-sequence
をシグナルする。このコンディションに関連付けられるデータ値は、iteratorのジェネレーター関数がリターンした値である。
valueはiteratorに送信されて、iter-yield
を評価した値になる。iteratorのジェネレーター関数の開始時には、ジェネレーター関数はiter-yield
フォームを何も評価していないので、与えられたiteratorにたいする最初のiter-next
呼び出しではvalueは無視される。
iteratorがunwind-protect
のbodyform
フォーム内でサスペンドされていたら、ガーベージコレクション処理後にEmacsが最終的にunwindハンドラーを実行する(unwind-protect
のunwindforms
内部ではiter-yield
は不当であることに注意)。その前に確実にこれらのハンドラーを実行するには、iter-close
を使用すること。
iteratorを簡単に連携できるように、便利な関数がいくつか提供されています:
iteratorが生成する各値をvarにバインドしつつbodyを実行する。
Common Lispのループ機能にもiteratorと連携する機能が含まれます。Loop Facility in Common Lisp Extensionsを参照してください。
以下のコード片はiteratorとの連携における重要な原則を示すものです。
(iter-defun my-iter (x) (iter-yield (1+ (iter-yield (1+ x)))) ;; 普通にリターンする -1) (let* ((iter (my-iter 5)) (iter2 (my-iter 0))) ;; 6をプリント (print (iter-next iter)) ;; 9をプリント (print (iter-next iter 8)) ;; 1をプリント ;; iterとiterは異なる状態をもつ (print (iter-next iter2 nil)) ;; ここでiterシーケンスの終了を待機 (condition-case x (iter-next iter) (iter-end-of-sequence ;; my-iterが通常の方法でリターンした-1をプリント (print (cdr x)))))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
非ローカル脱出(nonlocal exit)とは、プログラム内のある位置から別の離れた位置へ制御を移します。Emacs Lispではエラーの結果として非ローカル脱出が発生することがあります。明示的な制御の下で非ローカル脱出を使用することもできます。非ローカル脱出は脱出しようとしている構文により作成された、すべての変数バインディングのバインドを解消します。
10.6.1 明示的な非ローカル脱出: catch とthrow | プログラム自身の目的による非ローカル脱出。 | |
10.6.2 catch とthrown の例 | このような非ローカル脱出が記述される方法。 | |
10.6.3 エラー | エラーのシグナルと処理される方法。 | |
10.6.4 非ローカル脱出のクリーンアップ | エラーが発生した場合のクリーンアップフォーム実行のアレンジ。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
catch
とthrow
ほとんどの制御構造は、その構文自身の内部の制御フローだけに影響します。関数throw
は、この通常のプログラム実行でのルールの例外です。これはリクエストにより非ローカル脱出を行ないます(他にも例外はあるがそれらはエラー処理用のものだけ)。throw
はcatch
の内部で使用され、catch
に制御を戻します。たとえば:
(defun foo-outer () (catch 'foo (foo-inner))) (defun foo-inner () … (if x (throw 'foo t)) …)
throw
フォームが実行されると、対応するcatch
に制御を移して、catch
は即座にリターンします。throw
の後のコードは実行されません。throw
の2番目の引数はcatch
のリターン値として使用されます。
関数throw
は1番目の引数にもとづいて、それにマッチするcatch
を探します。throw
は1番目の引数が、throw
で指定されたものとeq
であるようなcatch
を検索します。複数の該当するcatch
がある場合には、最内のものが優先されます。したがって上記の例ではthrow
がfoo
を指定していて、foo-outer
内のcatch
が同じシンボルを指定しているので、(この間に他のマッチするcatch
は存在しないと仮定するなら)そのcatch
が該当します。
throw
の実行により、マッチするcatch
までのすべてのLisp構文(関数呼び出しを含む)を脱出します。この方法によりlet
や関数呼び出しのようなバインディング構文を脱出する場合には、これらの構文を正常にexitしたときのように、そのバインディングは解消されます(ローカル変数を参照)。同様にthrow
はsave-excursion
(エクスカーションを参照)によって保存されたバッファーと位置を復元します。throw
がスペシャルフォームunwind-protect
を脱出した場合には、unwind-protect
により設定されたいくつかのクリーンアップも実行されます。
ジャンプ先となるcatch
内にレキシカル(局所的)である必要はありません。throw
はcatch
内で呼び出された別の関数から、同じようにに呼び出すことができます。throw
が行なわれたのが、時系列的にcatch
に入った後で、かつexitする前である限り、そのthrow
はcatch
にアクセスできます。エディターのコマンドループから戻るexit-recursive-edit
のようなコマンドで、throw
が使用されるのはこれが理由です。
Common Lispに関する注意: Common Lispを含む、他のほとんどのバージョンのLispは非シーケンシャルに制御を移すいくつかの方法 — たとえば
return
、return-from
、go
— をもつ。Emacs Lispはthrow
のみ。cl-libライブラリーはこれらのうちいくつかを提供する。Blocks and Exits in Common Lisp Extensionsを参照のこと。
catch
はthrow
関数にたいするリターン位置を確立する。リターン位置はtagにより、この種の他のリターン位置と区別される。tagはnil
以外の任意のLispオブジェクト。リターン位置が確立される前に、引数tagは通常どおり評価される。
リターン位置が効果をもつことにより、catch
はbodyのフォームをテキスト順に評価する。フォームが(エラーや非ローカル脱出なしで)通常に実行されたなら、bodyの最後のフォームの値がcatch
からリターンされる。
bodyの実行の間にthrow
が実行された場合、tagと同じ値を指定するとcatch
フォームは即座にexitする。リターンされる値は、それが何であれthrow
の2番目の引数に指定された値である。
throw
の目的は、以前にcatch
により確立されたリターン位置に戻ることである。引数tagは、既存のさまざまなリターン位置からリターン位置を選択するために使用される。複数のリターン位置がtagにマッチしたら、最内のものが使用される。
引数valueはcatch
からリターンされる値として使用される。
タグtagのリターン位置が存在しなければ、データ(tag
value)
とともにno-catch
エラーがシグナルされます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
catch
とthrown
の例2重にネストされたループから脱出する1つの方法は、catch
とthrow
を使うことです(これはほとんどの言語ではgoto
により行なわれるだろう)。ここではiとjを0から9に変化させて、(foo
i j)
を計算します:
(defun search-foo () (catch 'loop (let ((i 0)) (while (< i 10) (let ((j 0)) (while (< j 10) (if (foo i j) (throw 'loop (list i j))) (setq j (1+ j)))) (setq i (1+ i))))))
foo
が非nil
をリターンしたら即座に処理を中止して、iとjのリストをリターンしています。foo
が常にnil
をリターンする場合には、catch
は通常どおりリターンして、その値はwhile
の結果であるnil
となります。
以下では2つのリターン位置を一度に表す、微妙に異なるトリッキーな例を2つ示します。まず同じタグhack
にたいして2つのリターン位置があります:
(defun catch2 (tag) (catch tag (throw 'hack 'yes))) ⇒ catch2
(catch 'hack (print (catch2 'hack)) 'no) -| yes ⇒ no
どちらのリターン位置もthrow
にマッチするタグをもつので内側のもの、つまりcatch2
で確立されたcatchへgotoします。したがってcatch2
は通常どおり値yes
をリターンして、その値がプリントされます。最後に外側のcatch
の2番目のbody、つまり'no
が評価されて外側のcatch
からそれがリターンされます。
ここでcatch2
に与える引数を変更してみましょう:
(catch 'hack (print (catch2 'quux)) 'no) ⇒ yes
この場合も2つのリターン位置がありますが、今回は外側だけがタグhack
で、内側はかわりにタグquux
をもちます。したがってthrow
により、外側のcatch
が値yes
をリターンします。関数print
が呼び出されることはなくbodyのフォーム'no
も決して評価されません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispが何らかの理由で評価できないようなフォームの評価を試みると、エラー(error)がシグナル(signal)されます。
エラーがシグナルされるとエラーメッセージを表示して、カレントコマンドの実行を終了するのがEmacsデフォルトの反応です。たとえばバッファーの最後でC-fとタイプしたときのように、ほとんどの場合にはこれは正しい反応になります。
複雑なプログラムでは単なる終了が望ましくない場合もあるでしょう。たとえばそのプログラムがータ構造に一時的に変更を行なっていたり、プログラム終了前に削除する必要がある一時バッファーを作成しているかもしれません。このような場合には、エラー時に評価されるクリーンアップ式(cleanup
expressions)を設定するために、unwind-protect
を使用するでしょう(非ローカル脱出のクリーンアップを参照)。サブルーチン内のエラーにもかかわらずに、プログラムの実行を継続したいときがあるかもしれません。このような場合には、エラー時のリカバリーを制御するエラーハンドラー(error
handlers)を設定するためにcondition-case
を使用するでしょう。
エラーハンドラーを使用せずにプログラムの一部から別の部分へ制御を移すためには、catch
とthrow
を使用します。明示的な非ローカル脱出: catch
とthrow
を参照してください。
10.6.3.1 エラーをシグナルする方法 | エラーを報告する方法。 | |
10.6.3.2 Emacsがエラーを処理する方法 | エラーを報告するときEmacsが何を行なうか。 | |
10.6.3.3 エラーを処理するコードの記述 | エラーをトラップして実行を継続する方法。 | |
10.6.3.4 エラーシンボルとエラー条件 | エラートラプのためにエラーをクラス分けする方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
エラーのシグナリング(signaling)とは、エラーの処理を開始することを意味します。エラー処理は通常は実行中のプログラムのすべて、または一部をアボート(abort)してエラーをハンドルするためにセットアップされた位置にリターンします。ここではエラーをシグナルする方法を記述します。
ほとんどのエラーは、たとえば整数にたいしてCARの取得を試みたり、バッファーの最後で1文字前方に移動したときなどのように、他の目的のために呼び出したLispプリミティブ関数の中で自動的にシグナルされます。関数error
とsignal
で明示的にエラーをシグナルすることもできます。
ユーザーがC-gをタイプしたときに発生するquitはエラーとは判断されませんが、ほとんどはエラーと同様に扱われます。quitを参照してください。
すべてのエラーメッセージはそれぞれ、何らかのエラーメッセージを指定します。そのメッセージは何が悪いのか(“File does not exist”)、物事がどうしてそうあるべきではない(“File must exist”)かを示すべきです。Emacs Lispの慣習ではエラーメッセージは大文字で開始され、区切り文字で終わるべきではありません。
この関数はformat-stringとargsにたいして、format-message
(文字列のフォーマットを参照)を適用して構築されたエラーメッセージとともに、エラーをシグナルする。
以下はerror
を使用する典型的な例である:
(error "That is an error -- try something else") error→ That is an error -- try something else
(error "Invalid name `%s'" "A%%B") error→ Invalid name ‘A%%B’
2つの引数 — エラーシンボルerror
とformat-message
がリターンするる文字列を含むリスト —
でsignal
を呼び出すことによりerror
は機能する。
text-quoting-style
変数は何のクォートを生成するかを制御する。ドキュメント内でのキーバインディングの置き換えを参照のこと。グレイブアクセントやアポストロフィーを含む"Missing
`%s'"のようなフォーマットを使用した呼び出しでは、通常は\"Missing ‘foo’\"のようにマッチするcurved
quotesをもつメッセージが生成される。対照的に"Missing
'%s'"のようにアポストロフィーだけのフォーマットを使用した場合には、通常は"Missing ’foo’"のように、closing
curved quotesだけをもつ英語では普通使用されないスタイルのメッセージが生成される。
警告: エラーメッセージとして固定の文字列を使用したい場合、単に(error
string)
とは記述しないこと。もしstringが‘%’、‘`’、‘'’を含んでいると、再フォーマットされて望む結果は得られないだろう。かわりに、(error
"%s" string)
を使用すること。
この関数はerror-symbolで命名されるエラーをシグナルする。引数dataはエラー状況に関連する追加のLispオブジェクトのリスト。
引数error-symbolはエラーシンボル(error symbol) —
define-error
で定義されたシンボル — でなければならない。これはEmacs
Lispが異なる種類のエラーをクラス分けする方法である。エラーシンボル(error symbol)、エラーコンディション(error
condition)、コンディション名(condition name)の説明についてはエラーシンボルとエラー条件を参照のこと。
エラーが処理されない場合には、エラーメッセージをプリントするために2つの引数が使用される。このエラーメッセージは通常、error-symbolのerror-message
プロパティーにより提供される。dataが非nil
なら、その後にコロンとdataの未評価の要素をカンマで区切ったリストが続く。error
にたいするエラーメッセージはdataのCARである(文字列であること)。サブカテゴリーfile-error
は特別に処理される。
data内のオブジェクトの数と意味はerror-symbolに依存する。たとえばwrong-type-argument
エラーではリスト内に2つのオブジェクト
— 期待する型を記述する述語とその型への適合に失敗したオブジェクト — であること。
エラーを処理する任意のエラーハンドラーにたいしてerror-symbolとdataの両方を利用できる。condition-case
はローカル変数を(error-symbol
. data)
というフォームでバインドする(エラーを処理するコードの記述を参照)。
関数signal
は決してリターンしない。
(signal 'wrong-number-of-arguments '(x y)) error→ Wrong number of arguments: x, y
(signal 'no-such-error '("My unknown error condition")) error→ peculiar error: "My unknown error condition"
この関数は、error
とまったく同じように振る舞うが、error
ではなくエラーシンボルuser-error
を使用する。名前が示唆するように、このエラーはコード自身のエラーではなく、ユーザー側のエラーの報告を意図している。たとえばInfoの閲覧履歴の開始を超えて履歴を遡るためにコマンドInfo-history-back
(l)を使用した場合、Emacsはuser-error
をシグナルする。このようなエラーでは、たとえdebug-on-error
が非nil
であっても、デバッガーへのエントリーは発生しない。エラーによるデバッガへのエンターを参照のこと。
Common Lispに関する注意: Emacs LispにはCommon Lispのような継続可能なエラーのような概念は存在しない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
エラーがシグナルされたとき、signal
はそのエラーにたいするアクティブなハンドラー(handler)を検索します。ハンドラーとは、Lispプログラムの一部でエラーが発生したときに実行するよう意図されたLisp式のシーケンスです。そのエラーが適切なハンドラーをもっていればそのハンドラーが実行され、そのハンドラーの後から実行が再開されます。ハンドラーはそのハンドラーが設定されたcondition-case
の環境内で実行されます。condition-case
内のすべての関数呼び出しはすでに終了しているので、ハンドラーがそれらにリターンすることはありません。
そのエラーにたいする適切なハンドラーが存在しなければ、カレントコマンドを終了してエディターのコマンドループに制御をリターンします(コマンドループにはすべての種類のエラーにたいする暗黙のハンドラーがある)。コマンドループのハンドラーは、エラーメッセージをプリントするためにエラーシンボルと、それに関連付けられたデータを使用します。変数command-error-function
を使用して、これが行なわれる方法を制御できます:
この変数が非nil
なら、それはEmacsのコマンドループに制御をリターンしたエラーの処理に使用する関数を指定する。この関数は3つの引数を受け取る。1つ目のdataは、condition-case
が自身の変数にバインドするのと同じフォーム。2つ目のcontextはエラーが発生した状況を記述する文字列か、(大抵は)nil
。3つ目のcallerはエラーをシグナルしたプリミティブ関数を呼び出したLisp関数。
明示的なハンドラーがないエラーは、Lispデバッガーを呼び出すかもしれません。変数debug-on-error
(エラーによるデバッガへのエンターを参照)が非nil
ならデバッガーが有効です。エラーハンドラーと異なり、デバッガーはそのエラーの環境内で実行されるので、エラー時の変数の値を正確に調べることができます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
エラーをシグナルすることによる通常の効果は、実行されていたコマンドを終了してEmacsエディターのコマンドループに即座にリターンすることです。スペシャルフォームcondition-case
を使用してエラーハンドラーを設定することにより、プログラム内の一部で発生するエラーのをトラップを調整することができます。以下は単純な例です:
(condition-case nil (delete-file filename) (error nil))
これはfilenameという名前のファイルを削除して、任意のエラーをcatch、エラーが発生した場合はnil
をリターンします(このような単純なケースではマクロignore-errors
を使用することもできる。以下を参照のこと)。
condition-case
構文は、insert-file-contents
呼び出しによるファイルオープンの失敗のような、予想できるエラーをトラップするために多用されます。condition-case
構文はユーザーから読み取った式を評価するプログラムのような、完全には予測できないエラーのトラップにも使用されます。
condition-case
の2番目の引数は保護されたフォーム(protected
form)と呼ばれます(上記の例では保護されたフォームはdelete-file
の呼び出し)。このフォームの実行が開始されるとエラーハンドラーが効果をもち、このフォームがリターンすると不活性になります。その間のすべてにおいてエラーハンドラーは効果をもちます。特にこのフォームで呼び出された関数とそのサブルーチン等を実行する間、エラーハンドラーは効果をもちます。厳密にいうと保護されたフォーム自身ではなく、保護されたフォームから呼び出されたLispプリミティブ関数(signal
とerror
を含む)だけがシグナルされるというのは、よいことと言えます。
保護されたフォームの後の引数はハンドラーです。各ハンドラーはそれぞれ、どのエラーを処理するかを指定する1つ以上のコンディション名(シンボル)をリストします。エラーがシグナルされたとき、エラーシンボルはコンディション名のリストも定義します。エラーが共通のコンディション名をもつ場合、そのハンドラーがそのエラーに適用されます。上記の例では1つのハンドラーがあり、それはすべてのエラーをカバーするコンディション名error
を指定しています。
適切なハンドラーの検索は、もっとも最近に設定されたハンドラーから始まり、設定されたすべてのハンドラーをチェックします。したがってネストされたcondition-case
フォームに同じエラー処理がある場合には、内側のハンドラーがそれを処理します。
何らかのcondition-case
によりエラーが処理されると、debug-on-error
でエラーによりデバッガーが呼び出されるようにしていても、通常はデバッガーの実行が抑制されます。
condition-case
で補足されるようなエラーをデバッグできるようにしたいなら、変数debug-on-signal
に非nil
値をセットします。以下のようにコンディション内にdebug
を記述することにより、最初にデバッガーを実行するような特定のハンドラーを指定することもできます:
(condition-case nil (delete-file filename) ((debug error) nil))
ここでのdebug
の効果は、デバッガー呼び出しを抑制するcondition-case
を防ぐことだけです。debug-on-error
とその他のフィルタリングメカニズムがデバッガーを呼び出すように指定されているときだけ、エラーによりデバッガーが呼び出されます。エラーによるデバッガへのエンターを参照してください。
マクロcondition-case-unless-debug
は、そのようなフォームのデバッギングを処理する、別の方法を提供する。このマクロは変数debug-on-error
がnil
、つまり任意のエラーを処理しないようなケース以外は、condition-case
とまったく同様に振る舞う。
特定のハンドラーがそのエラーを処理するとEmacsが判断すると、Emacsは制御をそのハンドラーにreturnします。これを行うために、Emacsはそのとき脱出しつつあるバインディング構成により作成されたすべての変数のバインドを解き、そのとき脱出しつつあるすべてのunwind-protect
フォームを実行します。制御がそのハンドラーに達すると、そのハンドラーのbodyが通常どおり実行されます。
そのハンドラーのbodyを実行した後、condition-case
フォームから実行がreturnされます。保護されたフォームは、そのハンドラーの実行の前に完全にexitしているので、そのハンドラーはそのエラーの位置から実行を再開することはできず、その保護されたフォーム内で作られた変数のバインディングを調べることもできません。ハンドラーが行なえることは、クリーンアップと、処理を進行させることだけです。
エラーのシグナルとハンドルにはthrow
とcatch
(明示的な非ローカル脱出: catch
とthrow
を参照)に類似する点がいくつかありますが、これらは完全に別の機能です。エラーはcatch
でキャッチできず、throw
をエラーハンドラーで処理することはできません(しかし対応するcatch
が存在しないときにthrow
を使用することによりシグナルされるエラーは処理できる)。
このスペシャルフォームはprotected-formの実行を囲い込むエラーハンドラーhandlersを確立する。エラーなしでprotected-formが実行されると、リターンされる値はcondition-case
フォームの値になる。この場合、condition-case
は効果をもたない。protected-formの間にエラーが発生すると、condition-case
フォームは違いを生じる。
handlersはそれぞれ、(conditions
body…)
というフォームのリストである。ここでconditionsはハンドルされるエラーコンディション名、またはそのハンドラーの前にデバッガーを実行するためのコンディション名(debug
を含む)。bodyはこのハンドラーがエラーを処理するときに実行される1つ以上のLisp式。
(error nil) (arith-error (message "Division by zero")) ((arith-error file-error) (message "Either division by zero or failure to open a file"))
発生するエラーはそれぞれ、それが何の種類のエラーかを記述するエラーシンボル(error
symbol)をもち、これはコンディション名のリストも記述する(エラーシンボルとエラー条件を参照)。Emacsは1つ以上のコンディション名を指定するハンドラーにたいして、すべてのアクティブなcondition-case
フォームを検索する。condition-case
の最内のマッチがそのエラーを処理する。condition-case
内では、最初に適合したハンドラーがそのエラーを処理する。
ハンドラーのbodyを実行した後、condition-case
は通常どおりリターンして、ハンドラーのbodyの最後の値をハンドラー全体の値として使用する。
引数varは変数である。protected-formを実行するとき、condition-case
はこの変数をバインドせず、エラーを処理するときだけバインドする。その場合には、varをエラー記述(error
description)にバインドする。これはエラーの詳細を与えるリストである。このエラー記述は(error-symbol
.
data)
というフォームをもつ。ハンドラーは何を行なうか決定するために、このリストを参照することができる。たとえばファイルオープンの失敗にたいするエラーなら、ファイル名がdata(エラー記述の3番目の要素)の2番目の要素になる。
varがnil
なら、それはバインドされた変数がないことを意味する。この場合、エラーシンボルおよび関連するデータは、そのハンドラーでは利用できない。
より外側のレベルのハンドラーにcatchさせるために、condition-case
によりcatchされたシグナルを再度throwする必要がある場合もある。以下はこれを行なう方法である:
(signal (car err) (cdr err))
ここでerr
はエラー記述変数(error description
variable)で、condition-case
の1番目の引数は、再throwしたいエラーコンディション。Definition of signalを参照のこと。
この関数は与えられたエラー記述子(error descriptor)にたいするエラーメッセージ文字列をリターンする。これはそのエラーにたいする通常のエラーメッセージをプリントすることにより、エラーを処理したい場合に有用。Definition of signalを参照のこと。
以下は0除算の結果によるエラーを処理するために、condition-case
を使用する例です。このハンドラーは、(beepなしで)エラーメッセージを表示して、非常に大きい数をリターンします。
(defun safe-divide (dividend divisor)
(condition-case err
;; 保護されたフォーム
(/ dividend divisor)
;; ハンドラー (arith-error ; コンディション ;; このエラーにたいする、通常のメッセージを表示する (message "%s" (error-message-string err)) 1000000))) ⇒ safe-divide
(safe-divide 5 0) -| Arithmetic error: (arith-error) ⇒ 1000000
このハンドラーはコンディション名arith-error
を指定するので、division-by-zero(0除算)エラーだけを処理します。他の種類のエラーは(このcondition-case
によっては)、処理されません。したがって:
(safe-divide nil 3) error→ Wrong type argument: number-or-marker-p, nil
以下はerror
によるエラーを含む、すべての種類のエラーをcatchするcondition-case
です:
(setq baz 34) ⇒ 34
(condition-case err
(if (eq baz 35)
t
;; 関数error
の呼び出し
(error "Rats! The variable %s was %s, not 35" 'baz baz))
;; フォームではないハンドラー
(error (princ (format "The error was: %s" err))
2))
-| The error was: (error "Rats! The variable baz was 34, not 35")
⇒ 2
この構文は、それの実行中に発生する任意のエラーを無視してbodyを実行する。その実行中にエラーがなければ、ignore-errors
はbody内の最後のフォームの値を、それ以外はnil
をリターンする。
以下はこのセクションの最初の例をignore-errors
を使用して記述する例である:
(ignore-errors (delete-file filename))
このマクロはいわばignore-errors
の穏やかなバージョンである。これはエラーを完全に抑止するのではなく、エラーをメッセージに変換する。これはメッセージのフォーマットに、文字列formatを使用する。formatは"Error:
%S"
のように、単一の‘%’シーケンスを含むこと。エラーをシグナルするとは予測されないが、もし発生した場合は堅牢であるべきようなコードの周囲にwith-demoted-errors
を使用する。このマクロはcondition-case
ではなく、condition-case-unless-debug
を使用することに注意。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
エラーをシグナルするとき、想定するエラーの種類を指定するためにエラーシンボル(error symbol)を指定します。エラーはそれぞれ、それをカテゴリー分けするために単一のエラーシンボルをもちます。これはEmacs Lisp言語で定義されるエラーを分類する、もっともよい方法です。
これらの狭義の分類はエラー条件(error
conditions)と呼ばれる、より広義のクラス階層にグループ化され、それらはコンディション名(condition
names)により識別されます。そのようなもっとも狭義なクラスは、エラーシンボル自体に属します。つまり各エラーシンボルは、コンディション名でもあるのです。すべての種類のエラー(quit
を除く)を引き受けるコンディション名error
に至る、より広義のクラスにたいするコンディション名も存在します。したがって各エラーは1つ以上のコンディション名をもちます。つまりerror
、error
とは区別されるエラーシンボル、もしかしたらその中間に分類されるものかもしれません。
シンボルをエラーシンボルとするために、シンボルは親コンディションを受け取るdefine-error
で定義されなければならない。この親はその種のエラーが属するコンディションを定義する。親の推移的な集合は、常にそのエラーシンボルとシンボルerror
を含む。quitはエラーと判断されないので、quit
の親の集合は単なる(quit)
である。
親のコンディションに加えてエラーシンボルはメッセージ(message)をもち、これは処理されないエラーがシグナルされたときプリントされる文字列です。そのメッセージが有効でなければ、エラーメッセージ‘peculiar error’が使用されます。Definition of signalを参照してください。
内部的には親の集合はエラーシンボルのerror-conditions
プロパティーに格納され、メッセージはエラーシンボルのerror-message
プロパティーに格納されます。
以下は新しいエラーシンボルnew-error
を定義する例です:
(define-error 'new-error "A new error" 'my-own-errors)
このエラーは複数のコンディション名 —
もっとも狭義の分類new-error
、より広義の分類を想定するmy-own-errors
、およびmy-own-errors
のコンディションすべてを含むerror
であり、これはすべての中でもっとも広義なものです。
エラー文字列は大文字で開始されるべきですが、ピリオドで終了すべきではありません。これはEmacsの他の部分との整合性のためです。
もちろんEmacs自身がnew-error
をシグナルすることはありません。あなたのコード内で明示的にsignal
(Definition of signalを参照)を呼び出すことにより、これを行なうことができます。
(signal 'new-error '(x y)) error→ A new error: x, y
このエラーは、エラーの任意のコンディション名により処理することができます。以下の例はnew-error
とクラスmy-own-errors
内の他の任意のエラーを処理します:
(condition-case foo (bar nil t) (my-own-errors nil))
エラーが分類される有効な方法はコンディション名による方法で、その名前はハンドラーのエラーのマッチに使用されます。エラーシンボルは意図されたエラーメッセージと、コンディション名のリストを指定する便利な方法であるという役割をもつだけです。1つのエラーシンボルではなく、コンディション名のリストをsignal
に与えるのは面倒でしょう。
対照的にコンディション名を伴わずにエラーシンボルだけを使用すると、それはcondition-case
の効果を著しく減少させるでしょう。コンディション名はエラーハンドラーを記述するとき、一般性のさまざまなレベルにおいて、エラーをカテゴリー分けすることを可能にします。エラーシンボルを単独で使用することは、もっとも狭義なレベルの分類を除くすべてを捨ててしまうことです。
主要なエラーシンボルとそれらのコンディションについては、標準的なエラーを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
unwind-protect
構文は、データ構造を一時的に不整合な状態に置くときに重要です。これはエラーやthrouのイベントにより、再びデータを整合された状態にすることができます(バッファー内容の変更だけに使用される他のクリーンアップ構成はアトミックな変更グループである。グループのアトミックな変更を参照)。
unwind-protect
は制御がbody-formを離れる場合に、cleanup-formsが評価されるという保証の下において、何が起こったかに関わらずbody-formを実行する。body-formは通常どおり完了するかもしれず、unwind-protect
の外側でthrow
の実行やエラーが発生するかもしれないが、cleanup-formsは評価される。
body-formが正常に終了したら、unwind-protect
はcleanup-formsを評価した後に、body-formの値をリターンする。body-formが終了しなかったら、unwind-protect
は通常の意味におけるような値はリターンしない。
unwind-protect
で保護されるのはbody-formだけである。cleanup-forms自体の任意のフォームが、(throw
またはエラーにより)非ローカルにexitすると、unwind-protect
は残りのフォームが評価されることを保証しない。cleanup-formsの中の1つが失敗することが問題となるようなら、そのフォームの周囲に他のunwind-protect
を配置して保護すること。
現在アクティブなunwind-protect
フォーム数とローカルの変数バインディング数の和は、max-specpdl-size
(Local Variablesを参照)により制限される。
たとえば以下は一時的な使用のために不可視のバッファーを作成して、終了する前に確実にそのバッファーをkillする例です:
(let ((buffer (get-buffer-create " *temp*"))) (with-current-buffer buffer (unwind-protect body-form (kill-buffer buffer))))
(kill-buffer
(current-buffer))
のように記述して、変数buffer
を使用せずに同様のことを行えると思うかもしれません。しかし上の例は、別のバッファーにスイッチしたときにbody-formでエラーが発生した場合、より安全なのです(一時的なバッファーをkillするとき、そのバッファーがカレントとなることを確実にするために、かわりにbody-formの周囲にsave-current-buffer
を記述することもできる)。
Emacsには上のコードとおおよそ等しいコードに展開される、with-temp-buffer
という標準マクロが含まれます(Current
Bufferを参照)。このマニュアル中で定義されるいくつかのマクロは、この方法でunwind-protect
を使用します。
以下はFTPパッケージ由来の実例です。これはリモートマシンへの接続の確立を試みるために、プロセス(プロセスを参照)を作成しています。関数ftp-login
は関数のライター(writer)が予想できないことによる多くの問題から非常に影響を受けるので、失敗イベントでプロセスの削除を保証するフォームで保護されています。そうしないとEmacsは無用なサブプロセスで一杯になってしまうでしょう。
(let ((win nil)) (unwind-protect (progn (setq process (ftp-setup-buffer host file)) (if (setq win (ftp-login process host user password)) (message "Logged in") (error "Ftp login failed"))) (or win (and process (delete-process process)))))
この例には小さなバグがあります。ユーザーがquitするためにC-gとタイプすると、関数ftp-setup-buffer
のリターン後に即座にquitが発生しますが、それは変数process
がセットされる前なので、そのプロセスはkillされないでしょう。このバグを簡単に訂正する方法はありませんが、少なくともこれは非常に稀なことだと言えます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
変数(variable)とはプログラム内で値を表すために使用される名前です。Lispでは変数はそれぞれLispシンボルとして表されます(シンボルを参照)。変数名は単にそのシンボルの名前であり、変数の値はそのシンボルの値セル(value cell)に格納されます6。シンボルの構成要素を参照してください。Emacs Lispではシンボルを変数として使用することは、同じシンボルを関数名として使用することと関係ありません。
このマニュアルで前述したとおり、Lispプログラムはまず第1にLispオブジェクトとして表され、副次的にテキストとして表現されます。Lispプログラムのテキスト的な形式は、そのプログラムを構成するLispオブジェクトの入力構文により与えられます。したがってLispプログラム内の変数のテキスト的な形式は、その変数を表すシンボルの入力構文を使用して記述されます。
11.1 グローバル変数 | どの場所でも永続的に存在する変数の値。 | |
11.2 Variables that Never Change | Variables that never change. | |
11.3 ローカル変数 | 一時的にのみ存在する存在する変数の値。 | |
11.4 変数がvoidのとき | 値を持たないシンボル。 | |
11.5 グローバル変数の定義 | シンボルが変数として使用されていることを宣言する定義。 | |
11.6 堅牢な変数定義のためのヒント | 変数を定義するときに考慮すべき事項。 | |
11.7 変数の値へのアクセス | 実行時に判明する名前をもつ変数の値を確認する。 | |
11.8 変数の値のセット | 変数に新しい値を格納する。 | |
11.9 変数のバインディングのスコーピングルール | Lispがローカル値とグローバル値を選択する方法。 | |
11.10 バッファーローカル変数 | 1つのバッファーないだけで効果をもつ変数の値。 | |
11.11 ファイルローカル変数 | ファイル内にリストされたローカル変数の処理。 | |
11.12 ディレクトリーローカル変数 | ディレクトリー内のすべてのファイルで共通のローカル変数。 | |
11.13 変数のエイリアス | 他の変数のエイリアスとなる変数。 | |
11.14 値を制限された変数 | 任意のLispオブジェクトを値とすることができない、定数ではない変数。 | |
11.15 ジェネリック変数 | 変数の概念の拡張。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
変数を使用するための一番シンプルな方法は、グローバル(globally)を使用する方法です。これはある時点でその変数はただ1つの値をもち、その値が(少なくともその時点では)Lispシステム全体で効果をもつことを意味します。あらたな値を指定するまでその値が効果をもちます。新しい値で古い値を置き換えるとき、古い値を追跡する情報は変数内に残りません。
シンボルの値はsetq
で指定します。たとえば、
(setq x '(a b))
これは変数x
に値(a
b)
を与えます。setq
はスペシャルフォームであることに注意してください。これは1番目の引数(変数の名前)は評価しませんが、2番目の引数(新しい値)は評価します。
変数が一度値をもつと、そのシンボル自身を式として使用することによって参照することができます。したがって、
x ⇒ (a b)
これは上記のsetq
フォームが実行された場合です。
同じ変数を再びセットすると、古い値は新しい値で置き換えられます:
x ⇒ (a b)
(setq x 4) ⇒ 4
x ⇒ 4
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs
Lispでは特定のシンボルは、通常は自分自身に評価されます。これらのシンボルにはnil
とt
、同様に名前が‘:’で始まる任意のシンボル(これらはキーワードと呼ばれる)が含まれます。これらのシンボルはリバインドや、値の変更はできません。nil
やt
へのセットやリバインドは、setting-constant
エラーをシグナルします。これはキーワード(名前が‘:’で始まるシンボル)についても当てはまります。ただしキーワードが標準のobarrayにinternされていれば、そのようなシンボルを自分自身にセットしてもエラーになりません。
nil ≡ 'nil ⇒ nil
(setq nil 500) error→ Attempt to set constant symbol: nil
この関数はobjectが‘:’で始まる名前のシンボルであり、標準のobarrayにinternされていればt
、それ以外はnil
をリターンする。
これらの定数はスペシャルフォームdefconst
(グローバル変数の定義を参照)を使用して定義された定数(constant)とは根本的に異なります。defconst
フォームは、人間の読み手に値の変更を意図しない変数であることを知らせる役目は果たしますが、実際にそれを変更してもEmacsはエラーを起こしません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
グローバル変数は新しい値で明示的に置き換えるまで値が持続します。変数にローカル値(local value) — Lispプログラム内の特定の部分で効果をもつ — を与えると便利なときがあります。変数がローカル値をもつとき、わたしたちは変数がその値にローカルにバインド(locally bound)されていると言い、その変数をローカル変数(local variable)と呼びます。
たとえば関数が呼び出されるとき、関数の引数となる変数はローカル値(その関数の呼び出しにおいて実際の引数に与えられた値)を受け取ります。これらのローカルバインディングは、その関数のbody内で効果をもちます。他にもたとえばスペシャルフォームlet
は特定の変数にたいして明示的にローカルなバインディングを確立し、これはlet
フォームのbody内で効果を持ちます。
これにたいしてグローバルなバインディング(global binding)とは、(概念的には)グローバルな値が保持される場所です。
ローカルバインディングを確立すると、その変数の以前の値は他の場所に保存されます(または失われる)。わたしたちはこれを、以前の値がシャドー(shadowed)されたと言います。シャドーはグローバル変数とローカル変数の両方で発生し得ます。ローカルバインディングが効果を持つときには、ローカル変数にsetq
を使用することにより、指定した値をローカルバインディングに格納します。ローカルバインディングが効果を持たなくなったとき、以前にシャドーされた値が復元されます(または失われる)。
変数は同時に複数のローカルバインディングを持つことができます(たとえばその変数をバインドするネストされたlet
)。カレントバインディング(current
binding)とは、実際に効果を持つローカルバインディングのことです。カレントバインディングは、その変数の評価によりリターンされる値を決定し、setq
により影響を受けるバインディングです。
ほとんどの用途において、最内(innermost)のローカルバインディングとローカルバインディングをもたないグローバルバインディングを、カレントバインディングと考えることができます。より正確に言うと、スコープルール(scoping rule)と呼ばれるルールは、プログラム内でローカルバインディングが効果を持つ任意の与えられた場所を決定します。Emacs Lispのスコープルールはダイナミックスコープ(dynamic scoping)と呼ばれ、これは単に実行中のプログラム内の与えられた位置でのカレントバインディングを示しており、その変数がまだ存在すれば、その変数にたいしてもっとも最近作成されたバインディングです。ダイナミックスコープについての詳細、およびその代替であるレキシカルスコープ(lexical scoping)と呼ばれるスコープルールについては、変数のバインディングのスコーピングルールを参照してください。
スペシャルフォームlet
とlet*
は、ローカルバインディングを作成するために存在します:
このスペシャルフォームは、bindingsにより指定される特定の変数セットにたいするローカルバインディングをセットアップしてから、formsのすべてをテキスト順に評価する。これはforms内の最後のフォームの値をリターンする。
bindingsの各バインディングは2つの形式のいずれかである。(i)
シンボルなら、そのシンボルはnil
にローカルにバインドされる。(ii) フォーム(symbol
value-form)
のリストなら、symbolはvalue-formを評価した結果へローカルにバインドされる。value-formが省略されたらnil
が使用される。
bindings内のすべてのvalue-formは、シンボルがそれらにバインドされる前に、記述された順番に評価される。以下の例ではz
はy
の新しい値(つまり1)にではなく、古い値(つまり2)にバインドされる。
(setq y 2) ⇒ 2
(let ((y 1) (z y)) (list y z)) ⇒ (1 2)
このスペシャルフォームはlet
と似ているが、次の変数値にたいするローカル値を計算する前に、ローカル値を計算してそれを変数にバインドする。したがてbindings内の式は、このlet*
フォーム内の前のシンボルのバインドを参照できる。以下の例を上記let
の例と比較されたい。
(setq y 2) ⇒ 2
(let* ((y 1)
(z y)) ; y
の値に今計算されたばかりの値を使用する
(list y z))
⇒ (1 1)
以下はローカルバインディングを作成する他の機能のリストです:
変数はバッファーローカルなバインディングを持つこともできます(バッファーローカル変数を参照)。数は多くありませんが、端末ローカル(terminal-local)なバインディングをもつ変数もあります(複数の端末を参照)。この種のバインディングは、通常のローカルバインディングのように機能することもありますが、これらはEmacs内のどこにいるかに依存してローカルになります。
この変数はローカルな変数バインディングと、unwind-protect
にゆるクリーンアップ(Cleaning Up from Nonlocal
Exitsを参照)の総数にたいする制限を定義し、この変数を越えるとEmacsは(データ"Variable binding depth
exceeds max-specpdl-size"
とともに)エラーをシグナルする。
このリミットは、もし超過したときにエラーが関連付けられていれば、誤って定義された関数による無限再起を避けるための1つの手段になる。ネストの深さにたいする他の制限としては、max-lisp-eval-depth
がある。Evalを参照のこと。
デフォルト値は1300。Lispデバッガーのエントリーしたとき、もし残りが少なければ、デバッガーを実行するための空きを作るために値が増加される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
シンボルの値セル(シンボルの構成要素を参照)に値が割り当てられていない場合、その変数はvoid(空)であると言います。
Emacs Lispのデフォルトであるダイナミックスコープルール(変数のバインディングのスコーピングルールを参照)の下では、値セルはその変数のカレント値(ローカルまたはグローバル)を保持します。値が割り当てられていない値セルは、値セルにnil
をもつのとは異なることに注意してください。シンボルnil
はLispオブジェクトであり、他のオブジェクトと同様に変数の値となることができます。nil
は値なのです。変数がvoidの場合にその変数の評価を試みると、値をリターンするかわりに、void-variable
エラーがシグナルされます。
オプションであるレキシカルスコープルール(lexical scoping rule)の下では、値セル保持できるのはその変数のグローバル値 — 任意のレキシカルバインディング構造の外側の値だけです。変数がレキシカルにバインドされている場合、ローカル値はそのレキシカル環境により決定されます。したがってこれらのシンボルの値セルに値が割り当てられていなくても、変数はローカル値を持つことができます。
この関数はsymbolの値セルを空にして、その変数をvoidにする。この関数はsymbolをリターンする。
symbolがダイナミックなローカルバインディングをもつなら、makunbound
はカレントのバインディングをvoidにして、そのローカルバインディングが効果を持つ限りvoidにする。その後で以前にシャドーされたローカル値(またはグローバル値)が再び有効になって、再び有効になった値がvoidでなければ、その変数はvoidではなくなる。
いくつか例を示す(ダイナミックバインディングが有効だとする):
(setq x 1) ; グローバルバインディングに値をセットする ⇒ 1 (let ((x 2)) ; それをローカルにバインドする (makunbound 'x) ; ローカルバインディングをvoidにする x) error→ Symbol's value as variable is void: x
x ; グローバルバインディングは変更されない ⇒ 1 (let ((x 2)) ; ローカルにバインドする (let ((x 3)) ; もう一度 (makunbound 'x) ; 最内のローカルバインディングをvoidにする x)) ; それを参照すると、void error→ Symbol's value as variable is void: x
(let ((x 2))
(let ((x 3))
(makunbound 'x)) ; 内側のバインディングをvoidにしてから取り除く
x) ; 外側のlet
バインディングが有効になる
⇒ 2
この関数はvariable(シンボル)がvoidでなければt
、voidならnil
をリターンする。
いくつか例を示す(ダイナミックバインディングが有効だとする):
(boundp 'abracadabra) ; 最初はvoid
⇒ nil
(let ((abracadabra 5)) ; ローカルにバインドする
(boundp 'abracadabra))
⇒ t
(boundp 'abracadabra) ; グローバルではまだvoid
⇒ nil
(setq abracadabra 5) ; グローバルで非voidにする
⇒ 5
(boundp 'abracadabra) ⇒ t
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
変数定義(variable
definition)とは、そのシンボルをグローバル変数として使用する意図を表明する構文です。これには以下で説明するスペシャルフォームdefvar
やdefconst
が使用されます。
変数宣言は3つの目的をもちます。1番目はコードを読む人にたいして、そのシンボルが特定の方法(変数として)使用されることを意図したものだと知らせることです。2番目はLispシステムにたいしてオプションで初期値とドキュメント文字列を与えて、これを知らせることです。3番目はetags
のようなプログラミングツールにたいして、その変数が定義されている場所を見つけられるように情報を提供することです。
defconst
とdefvar
の主な違いは、人間の読み手に値が変更されるかどうかを知らせることにあります。Emacs
Lispは実際に、defconst
で定義された変数の値の変更を妨げません。この2つのフォームの特筆すべき違いは、defconst
は無条件で変数を初期化して、defvar
は変数が元々voidのときだけ初期化することです。
カスタマイズ可能な変数を定義する場合は、defcustom
を使用するべきです(これはサブルーチンとしてdefvar
を呼び出す)。カスタマイゼーション変数の定義を参照してください。
このスペシャルフォームは変数としてsymbolを定義する。symbolが評価されないことに注意。シンボルはdefvar
フォーム内に明示的に表記して定義される必要がある。この変数は特別だとマークされて、これは常に変数がダイナミックにバインドされることを意味する(変数のバインディングのスコーピングルールを参照)。
valueが指定されていてsymbolがvoid(たとえばこのシンボルがダイナミックにバインドされた値を持たないとき。変数がvoidのときを参照)ならvalueが評価されて、その結果がsymbolにセットされる。しかしsymbolがvoidでなければ、valueは評価されずsymbolの値は変更されない。valueが省略された場合は、いかなる場合もsymbolの値は変更されない。
symbolがカレントバッファー内でバッファーローカルなバインディングをもつ場合、defvar
はデフォルト値に作用する。デフォルト値はバッファーローカルなバインディングではなく、バッファーにたいして独立である。デフォルト値がvoidのときはデフォルト値をセットする。バッファーローカル変数を参照のこと。
すでにsymbolがレキシカルにバインドされている場合(たとえばレキシカルバインドが有効な状態でlet
フォーム内にdefvar
があるような場合)、defvar
はダイナミックな値をセットする。バインディング構文を抜けるまで、レキシカルバインディングは効果をもつ。変数のバインディングのスコーピングルールを参照のこと。
Emacs LispモードでC-M-x
(eval-defun
)でトップレベルのdefvar
を評価するとき、eval-defun
の特別な機能はその値がvoidであるかテストすることなく、その変数を無条件にセットする。
引数doc-stringが与えられたら、それは変数にたいするドキュメント文字列を指定する(そのシンボルのvariable-documentation
プロパティーに格納される)。ドキュメントを参照のこと。
以下にいくつか例を示す。これはfoo
を定義するが初期化は行わない:
(defvar foo) ⇒ foo
以下の例はbar
の値を23
に初期化してドキュメント文字列を与える:
(defvar bar 23 "The normal weight of a bar.") ⇒ bar
defvar
フォームはsymbolをリターンするが、これは通常は値が問題にならないファイル内のトップレベルで使用される。
このスペシャルフォームはある値でsymbolを定義して、それを初期化する。これはコードを読む人に、symbolがここで設定される標準的なグローバル値をもち、ユーザーや他のプログラムがそれを変更すべきではないことを知らせる。symbolが評価されないことに注意。定義されるシンボルはdefconst
内に明示的に記されなければならない。
defvar
と同様、defconst
は変数を特別 —
この変数が常にダイナミックにバインドされているという意味 — であるとマークする(変数のバインディングのスコーピングルールを参照)。加えてこれはその変数を危険であるとマークする(ファイルローカル変数を参照)。
defconst
は常にvalueを評価して、その結果をsymbolの値にセットする。カレントバッファー内でsymbolがバッファーローカルなバインディングをもつなら、defconst
はデフォルト値ではなくバッファーローカルな値をセットする(しかしdefconst
で定義されたシンボルにたいしてバッファーローカルなバインディングを作らないこと)。
defconst
の使い方の例は、Emacsのfloat-pi
—
(たとえインディアナ州議会が何を試みようと)何者かにより変更されるべきではない数学定数piにたいする定義である。しかし2番目のdefconst
の例のように、これは単にアドバイス的なものである。
(defconst float-pi 3.141592653589793 "The value of Pi.") ⇒ float-pi
(setq float-pi 3) ⇒ float-pi
float-pi ⇒ 3
警告:
変数がローカルバインディングをもつとき(let
により作成された、または関数の引数の場合)に、スペシャルフォームdefconst
またはdefvar
を使用すると、これらのフォームはグローバルバインディングではなく、ローカルバインディングをセットします。これは通常は、あなたが望むことではないはずです。これを防ぐには、これらのスペシャルフォームをファイル内のトップレベルで使用します。この場所は通常、何のローカルバインディングも効果をもたないので、その変数にたいするローカルバインディングが作成される前にファイルがロードされることが確実だからです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
値が関数(または関数のリスト)であるような変数を定義するときには、変数の名前の最後に‘-function’(または‘-functions’)を使用します。
他にも変数名に関する慣習があります。以下はその完全なリストです:
変数はノーマルフック(フックを参照)。
値は関数。
値は関数のリスト。
値はフォーム(式)。
値はフォーム(式)のリスト。
値は述語(predicate) — 1つの引数をとる関数 — であり成功なら非nil
、失敗ならnil
をリターンする。
nil
か否かだけが意味をもつような値。結局そのような変数は、やがては多くの値をもつことが多いので、この慣習を強く推奨はしない。
値はプログラム名。
値は完全なシェルコマンド。
値はコマンドにたいして指定するオプション。
変数を定義するときは、その変数を安全(safe)とマークすべきか、それとも危険(risky)とマークすべきかを常に考慮してください。ファイルローカル変数を参照してください。
複雑な値を保持する変数(バインディングをもつkeymapなど)の定義や初期化を行う場合は、以下のように値の計算をすべてdefvar
の中に配置するのが最良です:
(defvar my-mode-map (let ((map (make-sparse-keymap))) (define-key map "\C-c\C-a" 'my-command) … map) docstring)
この方法にはいくつかの利点があります。1つ目はファールをロード中にユーザーが中断した場合、変数はまだ初期化されていないか、初期化されているかのどちらかであり、その中間ということはありません。まだ初期化されていなければ、ファイルをリロードすれば正しく初期化されます。2つ目は一度初期化された変数は、ファイルをリロードしても変更されないことです。コンテンツの一部を変更(たとえばキーのリバインド)するフックをユーザーが実行した場合などに、これは重要です。3つ目はC-M-xでdefvar
を評価すると、そのマップは完全に再初期化されることです。
defvar
フォーム内に多すぎるコードを配置することが不利な点が1つあります。ドキュメント文字列が変数の名前から離れた場所に配置されることです。これを避ける安全な方法は以下の方法です:
(defvar my-mode-map nil docstring) (unless my-mode-map (let ((map (make-sparse-keymap))) (define-key map "\C-c\C-a" 'my-command) … (setq my-mode-map map)))
これは初期化をdefvar
の内側に配置した場合とまったく同じ利点をもちますが、変数を再度初期化したい場合は、各フォームにたいして1回ずつ、C-M-xを2回タイプしなければならない点が異なります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
変数を参照する通常の方法は、それに名前をつけるシンボルを記述する方法です。シンボルのフォームを参照してください。
実行時にのみ決定される変数を参照したいときがあるかもしれません。そのような場合、プログラム中のテキストで変数名を指定することはできません。そのような値を抽出するためにsymbol-value
を使うことができます。
この関数はsymbolの値セルに格納された値をリターンする。これはその変数の(ダイナミックな)カレント値が格納された場所である。その変数がローカルバインディングをもたなければ単にその変数のグローバル値になる。変数がvoidならvoid-variable
はエラーをシグナルする。
その変数がレキシカルにバインドされていれば、symbol-value
が報告する値は、その変数のレキシカル値と同じである必要はない。レキシカル値はそのシンボルの値セルではなく、レキシカル環境により決定される。変数のバインディングのスコーピングルールを参照のこと。
(setq abracadabra 5) ⇒ 5
(setq foo 9) ⇒ 9
;; ここでシンボルabracadabra
;; は値がテストされるシンボル
(let ((abracadabra 'foo))
(symbol-value 'abracadabra))
⇒ foo
;; ここではabracadabra
の値、 ;; つまりfoo
が値を ;; テストされるシンボル (let ((abracadabra 'foo)) (symbol-value abracadabra)) ⇒ 9
(symbol-value 'abracadabra) ⇒ 5
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ある変数の値を変更する通常の方法は、スペシャルフォームsetq
を使用する方法です。実行時に変数選択を計算する必要がある場合には関数set
を使用します。
このスペシャルフォームは、変数の値を変更するためのもっとも一般的な方法である。symbolにはそれぞれ、新しい値(対応するformが評価された結果)が与えられる。そのシンボルのカレントバインディングは変更される。
setq
はsymbolを評価せずに、記述されたシンボルをセットする。この引数のことを自動的にクォートされた(automatically
quoted)と呼ぶ。setq
の‘q’は“quoted(クォートされた)”が由来。
setq
フォームの値は最後のformの値となる。
(setq x (1+ 2)) ⇒ 3
x ; ここでx
はグローバル値をもつ
⇒ 3
(let ((x 5))
(setq x 6) ; x
のローカルバインディングをセット
x)
⇒ 6
x ; グローバル値は変更されない
⇒ 3
1番目のformが評価されてから1番目のsymbolがセット、次に2番目のformが評価されてからsymbolが評価されて、...となることに注意:
(setq x 10 ; ここで、x
がセットされるのは y (1+ x)) ;y
の計算前であることに注目 ⇒ 11
この関数はsymbolの値セルにvalueを配置する。これはスペシャルフォームではなく関数なので、シンボルにセットするためにsymbolに記述された式は評価される。リターン値はvalue。
ダイナミックな変数バインドが有効(デフォルト)なら、set
は自身の引数symbolを評価するが、setq
は評価しないという点を除き、set
はsetq
と同じ効果をもつ。しかし変数がレキシカルバインドなら、set
は変数のダイナミックな値に、setq
は変数のカレント値(レキシカル値)に影響する。変数のバインディングのスコーピングルールを参照のこと。
(set one 1) error→ Symbol's value as variable is void: one
(set 'one 1) ⇒ 1
(set 'two 'one) ⇒ one
(set two 2) ; two
はシンボルone
に評価される
⇒ 2
one ; したがってone
がセットされる ⇒ 2 (let ((one 1)) ;one
のこのバインディングがセットされる (set 'one 3) ; のであってグローバル値はセットされない one) ⇒ 3
one ⇒ 2
symbolが実際のシンボルでなければwrong-type-argument
エラーがシグナルされる。
(set '(x y) 'z) error→ Wrong type argument: symbolp, (x y)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ある変数にたいするローカルバインディングを作成するとき、そのバインディングはプログラムの限られた一部だけに効果をもちます(ローカル変数を参照)。このセクションでは、これが正確には何を意味するかについて説明します。
ローカルバインディングはそれぞれ、個別にスコープ(scope: 範囲という意味)とエクステント(extent: これも範囲を意味する)をもちます。スコープはそのバインディングにアクセスできるのが、テキストのソースコードのどこ(where)であるかを示します。エクステントはプログラムの実行中に、そのバインディングが存在するのがいつ(when)であるかを示します。
デフォルトではEmacsが作成したローカルバインディングは、ダイナミックバインディング(dynamic
binding)です。このようなバインディングはダイナミックスコープ(dynamic
scope)をもち、それはプログラムの任意の範囲が、その変数バインディングにアクセスするかもしれないことを意味します。これはダイナミックエクステント(dynamic
extent)ももっています。これはそのバインディング構造(let
フォームのbodyなど)が実行される間だけ、そのバインディングが存続することを意味します。
Emacsはオプションでレキシカルバインディング(lexical binding)を作成することができます。レキシカルバインディングはレキシカルスコープ(lexical scope)をもち、これはその変数にたいするすべての参照が、バインディング構文内にテキスト的に配置されなければならないことを意味します7。レキシカルバインディングは不定エクステント(indefinite extent)ももっています。これはある状況下において、クロージャー(closures)と呼ばれるスペシャルオブジェクトにより、バインディング構造が実行を終えた後でさえも、存続し続けることを意味します。
以降のサブセクションでは、ダイナミックバインディングとレキシカルバインディング、およびEmacs Lispプログラムでレキシカルバインディングを有効にする方法についてより詳細に説明します。
11.9.1 ダイナミックバインディング | Emacs内でのローカル変数にたいするデフォルトのバインディング。 | |
11.9.2 ダイナミックバインディングの正しい使用 | ダイナミックバインディングによる問題を回避する。 | |
11.9.3 レキシカルバインディング | ローカル変数にたいする他の種類のバインディング。 | |
11.9.4 レキシカルバインディングの使用 | レキシカルバインディングを有効にする方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
デフォルトでは、Emacsにより作成されるローカル変数のバインディングはダイナミックバインディングです。ある変数がダイナミックにバインドされていると、Lispプログラムの実行における任意のポイントでのカレントバインディングは、単にそのシンボルにたいしてもっとも最近作成されたダイナミックなローカルバインディング、またはそのようなローカルバインディングが存在しなければグローバルバインディングになります。
以下の例のように、ダイナミックバインディングはダイナミックスコープとダイナミックエクステントをもちます:
(defvar x -99) ;x
は初期値として-99を受け取る (defun getx () x) ; この関数内ではx
は自由に使用される (let ((x 1)) ;x
はダイナミックにバインドされている (getx)) ⇒ 1 ;;let
フォームが終了した後に ;;x
は前の値-99にリバートされる (getx) ⇒ -99
関数getx
はx
を参照します。defun
構文自体の中にx
にたいするバインディングが存在しないという意味において、これはフリーな参照です。x
が(ダイナミックに)バインドされているlet
フォーム内からgetx
を呼び出すと、ローカル値(つまり1)が取得されます。しかしその後let
フォームの外側からgetx
を呼び出すと、グローバル値(つまり-99)が取得されます。
以下はsetq
を使用してダイナミックに変数をバインドする例です:
(defvar x -99) ;x
は初期値として-99を受け取る (defun addx () (setq x (1+ x))) ;x
に1加算して新しい値をリターンする (let ((x 1)) (addx) (addx)) ⇒ 3 ;addx
を2回呼び出すとx
に2回加算される ;;let
フォームが終了した後に ;;x
は前の値-99にリバートされる (addx) ⇒ -98
Emacs Lispでのダイナミックバインディングは、シンプルな方法で実装されています。シンボルはそれぞれ、シンボルのカレントのダイナミック値(または値の不在)を指定する値セルをもちます。シンボルの構成要素を参照してください。あるシンボルがダイナミックなローカル値を与えられたとき、Emacsは値セルの内容(または値の不在)をスタックに記録して、新しいローカル値を値セルに格納します。バインディング構文が実行を終えたとき、Emacsはスタックから古い値をpopして値セルにそれを配置します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ダイナミックバインディングは、プログラムにたいしてテキスト的なローカルスコープ内で定義されていない変数を参照することを許容する、強力な機能です。しかし無制限に使用した場合には、プログラムの理解を困難にしてしまうこともあります。このテクニックを使用するために2つの明解な方法があります:
let
フォームのbodyなどの場所)だけでそれを使用する。プログラムでこの慣習に一貫してしたがえば、プログラム内の他の場所で同じ変数シンボルを任意に使用しても、その変数の値に影響を与えたり、影響を受けることがなくなる。
defvar
、defconst
、defcustom
で変数を定義する。グローバル変数の定義を参照のこと。この定義は通常はEmacs
Lispファイル内のトップレベルにあること。この定義には変数の意味と目的を説明するドキュメント文字列を可能な限り含めるべきである。また名前の衝突を避けるように変数を命名すること(Emacs Lispコーディングの慣習を参照)。
そうすればプログラム内のどこか別の場所で、それが何に影響するか確信をもって変数をバインドすることができます。その変数にどこで出会っても、(たとえば変数の定義がEmacsにロードされていればC-h vコマンドを通じて)定義を参照するのが簡単になります。Name Help in The GNU Emacs Manualを参照してください。
たとえばcase-fold-search
のようなカスタマイズ可能な変数にたいしてローカルバインディングを使用するのは一般的です:
(defun search-for-abc () "Search for the string \"abc\", ignoring case differences." (let ((case-fold-search nil)) (re-search-forward "abc")))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsのバージョン24.1からオプションの機能としてレキシカルバインディングが導入されました。わたしたちはこの機能の重要性が、将来増加することを期待しています。レキシカルバインディングは最適化の機会をより広げるので、この機能を使用するプログラムはおそらくEmacsの将来のバージョンで高速に実行されるようになるでしょう。レキシカルバインディングは、わたしたちがEmacsに将来追加したいと考える並列性(concurrency)とも互換性があります。
レキシカルにバインドされた変数はレキシカルスコープ(lexical scope)をもちます。これはその変数にたいする参照が、そのバインディング構文内にテキスト的に配置されなければならないことを意味しています。以下は例です (実際にレキシカルバインディングを有功にする方法は、レキシカルバインディングの使用を参照のこと):
(let ((x 1)) ;x
はレキシカルにバインドされる (+ x 3)) ⇒ 4 (defun getx () x) ; この関数内ではx
は自由に使用される (let ((x 1)) ;x
はレキシカルにバインドされる (getx)) error→ Symbol's value as variable is void: x
ここではx
はグローバル値をもちません。let
フォーム内でレキシカルにバインドされたとき、この変数はlet
のテキスト境界内で使用できます。しかしこのlet
内から呼び出されるgetx
関数からは、getx
の関数定義がlet
フォームの外側なので使用することができません。
レキシカルバインディングが機能する方法を説明します。バインディング構文はぞれぞれ、その構文内でローカル値にバインドする変数を指定する、レキシカル環境(lexical environment)を定義します。Lispの評価機能(Lisp evaluator)が、ある変数のカレント値を得たいときは、最初にレキシカル環境内を探します。そこで変数が指定されていなければ、ダイナミック値が格納されるシンボルの値セルを探します。
(内部的にはレキシカル環境はシンボルと値がペアになったalistでり、alistの最後の要素はコンスセルではなくシンボルt
である。そのようなalistはフォームを評価するためのレキシカル環境を指定するために、eval
関数の2番目の引数として渡すことができる。evalを参照のこと。しかしほとんどのEmacs
Lispプログラムは、この方法で直接レキシカル環境を使用するべきではない。デバッガーのような特化されたプログラムだけが使用すること。)
レキシカルバインディングは不定エクステント(indefinite extent)をもちます。バインディング構造が終了した後でも、そのレキシカル環境はクロージャー(closures)と呼ばれるLispオブジェクト内に“保持”されるかもしれ、あせん。クロージャーはレキシカルバインディングが有効な、名前つきまたは無名(anonymous)の関数が作成されたときに作成されます。詳細はクロージャーを参照してください。
クロージャーが関数として呼び出されたとき、その関数の定義内のレキシカル変数にたいする任意の参照は、維持されたレキシカル環境を使用します。以下は例です:
(defvar my-ticker nil) ; クロージャーを格納するために ; この変数を使用する (let ((x 0)) ;x
はレキシカルにバインドされる (setq my-ticker (lambda () (setq x (1+ x))))) ⇒ (closure ((x . 0) t) () (setq x (1+ x))) (funcall my-ticker) ⇒ 1 (funcall my-ticker) ⇒ 2 (funcall my-ticker) ⇒ 3 x ;x
はグローバル値をもたないことに注意 error→ Symbol's value as variable is void: x
let
バインディングは、内部に変数x
をもつレキシカル環境を定義して、変数は0にローカルにバインドされます。このバインディング構文内でx
を1増加して、増加された値をリターンするクロージャーを定義しています。このラムダ式は自動的にクロージャーとなり、たとえlet
構文を抜けた後でも、その内部ではレキシカル環境が存続します。クロージャーを評価するときは、毎回レキシカル環境内のx
のバインディングが使用されて、x
が加算されます。
シンボルオブジェクト自体に束縛されるダイナミック変数と異なり、レキシカル変数とシンボルの関係はインタープリター(かコンパイラー)内にのみ存在します。したがって(symbol-value
、boundp
、set
のような)シンボル引数を受け取る関数ができるのは、変数のダイナミックなバインディング(そのシンボルの値セルの内容)の取得と変更だけです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs
LispファイルのロードやLispバッファーを評価するとき、バッファーローカルな変数lexical-binding
が非nil
なら、レキシカルバインディングが有効になります:
このバッファーローカルな変数が非nil
なら、Emacs
Lispファイルとバッファーはダイナミックバインディングではなくレキシカルバインディングを使用して評価される(しかし特別な変数はダイナミックにバインドされたまま。以下を照)。nil
ならすべてのローカル変数にたいしてダイナミックバインディングが使用される。この変数は、通常はファイルローカル変数として、Emacs
Lispファイル全体にたいしてセットされる(ファイルローカル変数を参照)。他のファイルローカル変数などとは異なり、ファイルの最初の行でセットされなければならないことに注意。
eval
呼び出しを使用してEmacs
Lispコードを直接評価するとき、eval
のlexical引数が非nil
なら、レキシカルバインディングが有効になります。evalを参照してください。
レキシカルバインディングが有効な場合でも、特定の変数はダイナミックにバインドされたままです。これらはスペシャル変数(special
variable)と呼ばれます。defvar
、defcustom
、defconst
で定義されたすべての変数はスペシャル変数です(グローバル変数の定義を参照)。その他のすべての変数はレキシカルバインディングの対象になります。
この関数はsymbolがスペシャル変数(つまり変数がdefvar
、defcustom
、defconst
による定義をもつ)なら非nil
をリターンする。、それ以外ならリターン値はnil
。
関数内での通常の引数としてのスペシャル変数の使用は、推奨されません。レキシカルバインディングモードが有効なときにこれを行うと、(あるときはレキシカルバインディング、またあるときはダイナミックバインディングのような)不定な動作が起こります。
Emacs Lispプログラムをレキシカルバインディングに変換するのは簡単です。最初にEmacs
Lispソースファイルのヘッダー行でlexical-binding
をt
にして、ファイルローカル変数を追加します(ファイルローカル変数を参照)。次に意図せずレキシカルにバインドしてしまわないように、ダイナミックなバインドをもつ必要がある変数が変数定義をもつことを各変数ごとにチェックします。
どの変数が変数定義をもつ必要があるか見つけるシンプルな方法は、ソースファイルをバイトコンパイルすることです。バイトコンパイルを参照してください。let
フォームの外側で非スペシャル変数が使用されていれば、バイトコンパイラーはフリーな変数にたいする参照や割り当てについて警告するでしょう。非スペシャル変数がバインドされているがlet
フォーム内で使用されていなければ、バイトコンパイラーは使用されないレキシカル変数に関して警告するでしょう。バイトコンパイラーは、スペシャル変数を関数の引数として使用している場合も問題を警告します。
(使用されていない変数についての警告を抑制するためには、単に変数名をアンダースコアーで開始すればよい。そうすればバイトコンパイラーはその変数が使用されないことを示すと解釈する。)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
グローバルおよびローカルな変数バインディングは、いずれかの形式をほとんどのプログラミング言語で見つけることができます。しかしEmacsは1つのバッファーだけに適用されるバッファーローカル(buffer-local)なバインディング用に、普通には存在しない類の変数バインディングもサポートしています。ある変数にたいして異なるバッファーごとに別の値をもつのは、カスタマイズでの重要な手法です(変数は端末ごとにローカルなバインディングをもつこともできる。複数の端末を参照)。
11.10.1 バッファーローカル変数の概要 | イントロダクションと概念。 | |
11.10.2 バッファーローカルなバインディングの作成と削除 | ||
11.10.3 バッファーローカル変数のデフォルト値 | 自身ではバッファーローカルな値をもたないバッファーで参照されるデフォルト値。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファーローカル変数は特定のバッファーに関連づけられた、バッファーローカルなバインディングをもちます。このバインディングはそのバッファーがカレントのときに効果をもち、カレントでないときには効果がありません。バッファーローカルなバインディングが効力をもつときにその変数をセットすると、そのバインディングは新しい値をもちますが他のバインディングは変更されません。これはバッファーローカルなバインディングを作成したバッファーだけで変更が見えることを意味します。
その変数にたいする特定のバッファーに関連しない通常のバインディングは、デフォルトバインディング(default binding)と呼ばれます。これはほとんどの場合はグローバルバインディングです。
変数はあるバッファーではバッファーローカルなバインディングをもつことができ、他のバッファーではもたないことができます。デフォルトバインディングは、その変数にたいして自身のバインディングをもたないすべてのバッファーで共有されます(これには新たに作成されたバッファーが含まれる)。ある変数にたいして、その変数のバッファーローカルなバインディングをもたないバッファーでその変数をセットすると、それによりデフォルトバインディングがセットされるので、デフォルトバインディングを参照するすべてのバッファーで新しい値を見ることになります。
バッファーローカルなバインディングのもっとも一般的な使用は、メジャーモードがコマンドの動作を制御するために変数を変更する場合です。たとえばCモードやLispモードは、空行だけがパラグラフの区切りになるように変数paragraph-start
をセットします。これらのモードは、CモードやLispモードになるようなバッファー内でこの変数をバッファーローカルにすることでこれを行って、その後そのモードにたいする新しい値をセットします。メジャーモードを参照してください。
バッファーローカルなバインディングを作成する通常の方法は、make-local-variable
による方法で、これは通常はメジャーモードが使用します。これはカレントバッファーだけに効果があります。その他すべてのバッファー(まだ作成されていないバッファーを含む)は、それらのバッファー自身が明示的にバッファーローカルなバインディングを与えるまでデフォルト値を共有し続けます。
変数を自動的にバッファーローカルになるようにマークする、より強力な操作はmake-variable-buffer-local
を呼び出すことにより行われます。これはたとえその変数がまだ作成されていなくても、変数をすべてのバッファーにたいしてローカルにすると考えることができます。より正確には変数を自動的にセットすることにより、その変数がカレントバッファーにたいしてローカルでなくても、変数をローカルにする効果があります。すべてのバッファーは最初は通常のようにデフォルト値を共有しますが、変数をセットすることでカレントバッファーにたいしてバッファーローカルなバインディングを作成します。新たな値はバッファーローカルなバインディングに格納され、デフォルトバインディングは変更されずに残ります。これは任意のバッファーでsetq
によりデフォルト値を変更できないことを意味します。変更する唯一の方法はsetq-default
だけです。
警告:
ある変数が1つ以上のバッファーでバッファーローカルなバインディングをもつ際に、let
はそのとき効力がある変数のバインディングをリバインドします。たとえばカレントバッファーがバッファーローカルな値をもつなら、let
は一時的にそれをリバインドします。効力があるバッファーローカルなバインディングが存在しなければlet
はデフォルト値をリバインドします。let
の内部で、別のバインディングが効力をもつ別のバッファーをカレントバッファーにすると、それ以上let
バインディングを参照できなくなります。他のバッファーにいる間にlet
を抜けると、(たとえそれが正しくても)バインディングの解消を見ることはできません。以下にこれを示します:
(setq foo 'g) (set-buffer "a") (make-local-variable 'foo)
(setq foo 'a) (let ((foo 'temp)) ;; foo ⇒ 'temp ; バッファー‘a’内でのletバインディング (set-buffer "b") ;; foo ⇒ 'g ; fooは‘b’にたいしてローカルではないためグローバル値 body…)
foo ⇒ 'g ; exitによりバッファー‘a’のローカル値が復元されるが ; バッファー‘b’では見ることができない
(set-buffer "a") ; ローカル値が復元されたことを確認
foo ⇒ 'a
body内のfoo
にたいする参照は、バッファー‘b’のバッファーローカルなバインディングにアクセスすることに注意してください。
あるファイルがローカル変数の値をセットする場合、これらの変数はファイルをvisitするときバッファーローカルな値になります。File Variables in The GNU Emacs Manualを参照してください。
バッファーローカル変数を端末ローカル(terminal-local)にすることはできません(複数の端末を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はカレントバッファー内で、variable(シンボル)にたいするバッファーローカルなバインディングを作成する。他のバッファーは影響を受けない。リターンされる値はvariable。
variableのバッファーローカルな値は、最初は以前にvariableがもっていた値と同じ値をもつ。variableがvoidのときはvoidのまま。
;; バッファー‘b1’で行う: (setq foo 5) ; すべてのバッファーに影響する。 ⇒ 5
(make-local-variable 'foo) ; ‘b1’内でローカルになった
⇒ foo
foo ; 値は変更されない
⇒ 5
(setq foo 6) ; ‘b1’内で値を変更
⇒ 6
foo ⇒ 6
;; バッファー‘b2’では、値は変更されていない
(with-current-buffer "b2"
foo)
⇒ 5
変数をlet
バインディングでバッファーローカルにしても、let
への出入り時の両方でこれを行うバッファーがカレントでなければ信頼性はない。これはlet
がバインディングの種類を区別しないからである。let
に解るのはバインディングが作成される変数だけである。
変数が端末ローカル(複数の端末を参照)なら、この関数はエラーをシグナルする。そのような変数はバッファーローカルなバインディングをもつことができない。
警告:
フック変数にたいしてmake-local-variable
を使用しないこと。フック変数はadd-hook
かremove-hook
のlocal引数を使用すると、必要に応じて自動でバッファーローカルになる。
このマクロはカレントバッファー内でvariableにたいするバッファーローカルなバインディングを作成して、それにバッファーローカルな値valueを与える。このマクロはmake-local-variable
に続けてsetq
を呼び出すのと同じ。variableはクォートされていないシンボル。
このコマンドはvariable(シンボル)が自動的にバッファーローカルになるようにマークするので、それ以降にその変数へのセットを試みると、その時点でカレントのバッファーにローカルになる。しばしば混乱を招くmake-local-variable
とは異なり、これが取り消されることはなく、すべてのバッファー内での変数の挙動に影響する。
この機能特有の欠点は、(let
やその他のバインディング構文による)変数のバインディングが、その変数にたいするバッファーローカルなバインディングを作成しないことである。(set
やsetq
による)変数のセットだけは、その変数がカレントバッファーで作成されたlet
スタイルのバインディングをもたないので、ローカルなバインディングを作成する。
variableがデフォルト値をもたない場合、このコマンドの呼び出しはnil
のデフォルト値を与える。variableがすでにデフォルト値をもつなら、その値は変更されずに残る。それ以降にvariableにたいしてmakunbound
を呼び出すと、バッファーローカル値をvoidにして、デフォルト値は影響を受けずに残る。
▼リターン値はvariable。
警告:
ユーザーオプション変数では、ユーザーは異なるバッファーにたいして異なるカスタマイズを望むかもしれないので、make-variable-buffer-local
を使うべきだと決め込むべきではない。ユーザーは望むなら任意の変数をローカルにできる。その選択の余地を残すほうがよい。
make-variable-buffer-local
を使用すべきなのは、複数のバッファーが同じバインディングを共有しないことが自明な場合である。たとえばバッファーごとに個別な値をもつことに依存するLispプログラム内の内部プロセスにたいして変数が使用されるときは、make-variable-buffer-local
の使用が最善の解決策になるかもしれない。
このマクロはvariableを初期値valueとdocstringの変数として定義して、それを自動的にバッファーローカルとマークする。これはdefvar
の後につづけてmake-variable-buffer-local
を呼び出すのと同じ。variableはクォートされていないシンボル。
これはvariableがバッファーbuffer(デフォルトはカレントバッファー)内でバッファーローカルならt
、それ以外はnil
をリターンする。
これはvariableがバッファーbuffer内でバッファーローカル値をもつ、または自動的にバッファーローカルになるならt
、それ以外はnil
をリターンする。bufferが省略またはnil
の場合のデフォルトはカレントバッファー。
この関数はバッファーbuffer内の、variable(シンボル)のバッファーローカルなバインディングをリターンする。variableがバッファーbuffer内でバッファーローカルなバインディングをもたなければ、かわりにvariableのデフォルト値(バッファーローカル変数のデフォルト値を参照)をリターンする。
この関数はバッファーbuffer内のバッファーローカル変数を表すリストをリターンする(bufferが省略された場合はカレントバッファーが使用される)。リストの各要素は通常は(sym . val)
という形式をもつ。ここでsymはバッファーローカル変数(シンボル)、valはバッファーローカル値。しかしbuffer内のある変数のバッファーローカルなバインディングがvoidなら、その変数に対応するリスト要素は単にsymとなる。
(make-local-variable 'foobar) (makunbound 'foobar) (make-local-variable 'bind-me) (setq bind-me 69)
(setq lcl (buffer-local-variables))
;; 最初はすべてのバッファー内でローカルなビルトイン変数:
⇒ ((mark-active . nil)
(buffer-undo-list . nil)
(mode-name . "Fundamental")
…
;; 次にビルトインでないバッファーローカル変数 ;; This one is buffer-local and void: foobar ;; これはバッファーローカルでvoidではない: (bind-me . 69))
このリスト内のコンスセルのCDRに新たな値を格納しても、その変数のバッファーローカル値は変化しないことに注意。
この関数はカレントバッファー内のvariable(シンボル)にたいするバッファーローカルなバインディング(もしあれば)を削除する。その結果として、このバッファー内でvariableのデフォルトバインディングが可視になる。これは通常はvariableの値を変更する。デフォルト値は削除されたバッファーローカル値とは異なるのが普通だからである。
セットしたとき自動的にバッファーローカルになる変数のバッファーローカルなバインディングをkillすると、これによりカレントバッファー内でデフォルト値が可視になる。しかし変数を再度セットすると、その変数にたいするバッファーローカルなバインディングが再作成される。
kill-local-variable
はvariableをreturnします。
この関数はコマンドである。なぜならバッファーローカル変数のインタラクティブな作成が有用な場合があるように、あるバッファーローカル変数のインタラクティブなkillが有用な場合があるからである。
この関数はpermanent(永続的)とマークされた変数とpermanent-local-hook
プロパティーに非nil
をもつローカルフック関数(フックのセットSetting Hooksを参照)を除き、カレントバッファーのすべてのバッファーローカルなバインディングを解消する。結果として、そのバッファーのほとんどの変数がデフォルト値を参照するようになる。
この関数はそのバッファーに関連する他の特定の情報もリセットする。これはローカルキーマップをnil
、構文テーブルを(standard-syntax-table)
の値、caseテーブルを(standard-case-table)
、abbrevテーブルをfundamental-mode-abbrev-table
の値にセットする。
この関数が1番最初に行うのはノーマルフックchange-major-mode-hook
(以下参照)の実行である。
すべてのメジャーモードコマンドは、Fundamentalモードにスイッチする効果をもち、以前のメジャーモードのほとんどの効果を消去する、この関数を呼び出すことによって開始されます。この関数が処理を行うのを確実にするために、メジャーモードがセットする変数はpermanentとマークすべきではない。
kill-all-local-variables
returns nil
.
関数kill-all-local-variables
は、何か他のことを行う前にまずこのノーマルフックを実行する。この関数はメジャーモードにたいして、ユーザーが他のメジャーモードにスイッチした場合に行われる何か特別なことを準備する方法を与える。この関数はユーザーがメジャーモードを変更した場合に忘れられるべき、バッファー固有のマイナーモードにたいしても有用。
最善の結果を得るために、この変数をバッファーローカルにすれば、処理が終了したときに消えるので、以降のメジャーモードに干渉しなくなる。フックを参照のこと。
変数名(シンボル)が非nil
のpermanent-local
プロパティーをもつなら、そのバッファーローカル変数はpermanent(永続的)です。そのような変数はkill-all-local-variables
の影響を受けず、したがってメジャーモードの変更によりそれらのローカルバインディングは作成されません。permanentなローカル変数はファイルの内容を編集する方法ではなく、どこから読み込んだファイルか、あるいはどのように保存するかといったことに関連するデータに適しています。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファーローカルなバインディングをもつ変数のグローバル値もデフォルト値(default)値と呼ばれます。なぜならその変数にたいしてカレントバッファーや選択されたフレームもバインディングをもたなければ、その値が常に効果をもつからです。
関数default-value
とsetq-default
は、カレントバッファーがバッファーローカルなバインディングをもつかどうかに関わらず、その変数のデフォルト値にアクセスまたは変更します。たとえばほとんどのバッファーにたいして、paragraph-start
のデフォルトのセッティングを変更するために、setq-default
を使用できます。そしてこの変数にたいするバッファーローカルな値をもつCモードやLispモードにいるときでさえ、これは機能します。
スペシャルフォームdefvar
とdefconst
もバッファーローカルな値ではなく、(もし変数にセットする場合は)デフォルト値をセットします。
この関数はsymbolのデフォルト値をリターンする。これはこの変数にたいして独自の値をもたないバッファーやフレームから参照される値である。symbolがバッファーローカルでなければ、これはsymbol-value
(変数の値へのアクセスを参照)と同じ。
関数default-boundp
はsymbolのデフォルト値がvoidでないか報告する。(default-boundp
'foo)
がnil
をリターンした場合には(default-value 'foo)
はエラーになる。
default-boundp
はdefault-value
、boundp
はsymbol-value
にたいする述語である。
このスペシャルフォームは各symbolに新たなデフォルト値として、対応するformを評価した結果を与える。これはsymbolを評価しないがformは評価する。setq-default
フォームの値は最後のformの値。
カレントバッファーにたいしてsymbolがバッファーローカルでなく、自動的にバッファーローカルにマークされていなければ、setq-default
はsetq
と同じ効果をもつ。カレントバッファーにたいしてsymbolがバッファーローカルなら、(バッファーローカルな値をもたない)他のバッファーから参照できる値を変更するが、それはカレントバッファーが参照する値ではない。
;; バッファー‘foo’で行う:
(make-local-variable 'buffer-local)
⇒ buffer-local
(setq buffer-local 'value-in-foo) ⇒ value-in-foo
(setq-default buffer-local 'new-default) ⇒ new-default
buffer-local ⇒ value-in-foo
(default-value 'buffer-local) ⇒ new-default
;; (新しい)バッファー‘bar’で行う:
buffer-local
⇒ new-default
(default-value 'buffer-local) ⇒ new-default
(setq buffer-local 'another-default) ⇒ another-default
(default-value 'buffer-local) ⇒ another-default
;; バッファー‘foo’に戻って行う:
buffer-local
⇒ value-in-foo
(default-value 'buffer-local)
⇒ another-default
この関数はsetq-default
と似ているが、symbolは通常の引数として評価される。
(set-default (car '(a b c)) 23) ⇒ 23
(default-value 'a) ⇒ 23
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ファイルにローカル変数の値を指定できます。そのファイルをvisitしているバッファー内で、これらの変数にたいしてバッファーローカルなバインディングを作成するために、Emacsはこれらを使用します。ファイルローカル変数の基本的な情報については、Local Variables in Files in The GNU Emacs Manualを参照してください。このセクションではファイルローカル変数が処理される方法に影響する関数と変数を説明します。
ファイルローカル変数が勝手に関数や、後で呼び出されるLisp式を指定できたら、ファイルのvisitによってEmacsが乗っ取られてしまうかもしれません。Emacsは既知のファイルローカル変数だけにたいして、指定された値が安全だと自動的にセットすることにより、この危険から保護します。これ以外のファイルローカル変数は、ユーザーが同意した場合のみセットされます。
追加の安全策としてEmacsがファイルローカル変数を読み込むとき、一時的にread-circle
をnil
にバインドします(入力関数を参照)。これは循環認識と共有されたLisp構造からLispリーダーを保護します(循環オブジェクトの読み取り構文を参照)。
この変数はファイルローカル変数を処理するかどうかを制御する。以下の値が利用できる:
t
(デフォルト)安全な変数をセット、安全でない変数は問い合わせる(1回)。
:safe
安全な変数だけをセット、問い合わせはしない。
:all
問い合わせをせずに、すべての変数をセット。
nil
変数をセットしない。
すべての変数にたいして問い合わせる(1回)。
これは正規表現のリストである。ファイルがこのリストの要素にマッチする名前をもつなら、すべてのファイルローカル変数のフォームはスキャンされない。どんなときにこれを使いたいかの例は、Emacsがメジャーモードを選択する方法を参照のこと。
この関数はカレントバッファーの内容により指定された任意のローカル変数にたいしてパースを行い、適切にバインドと評価を行う。変数enable-local-variables
はここでも効果をもつ。しかしこの関数は‘-*-’行の、‘mode:’ローカル変数を探さない。set-auto-mode
はこれを行ってenable-local-variables
も考慮する(Emacsがメジャーモードを選択する方法を参照)。
この関数はfile-local-variables-alist
内に格納されたalistを調べて、各ローカル変数を順に適用することにより機能する。この関数は変数に適用する前(か後)に、before-hack-local-variables-hook
(かhack-local-variables-hook
)を呼び出す。alistが非nil
の場合のみ、事前のフック(before-hook)を呼び出し、その他のフックは常に呼び出す。この関数はそのバッファーがすでにもつメジャーモードと同じメジャーモードが指定された場合は‘mode’要素を無視する。
オプションの引数mode-onlyが非nil
なら、メジャーモードを指定するシンボルをリターンするのがこの関数が行うのすべてであり、‘-*-’行かローカル変数リストがメジャーモードを指定していればそのモード、それ以外はnil
をリターンする。この関数はモードや他のファイルローカル変数をセットしない。
このバッファーローカルな変数は、ファイルローカル変数のセッティングのalistを保持する。alistの各要素は(var . value)
という形式で、varはローカル変数のシンボル、valueはその値である。Emacsがファイルをvisitするとき、最初にすべてのファイルローカル変数をこのalistに収集して、その後で変数に1つずつ関数hack-local-variables
を適用する。
Emacsはfile-local-variables-alist
に格納されたファイルローカル変数を適用する直前にこのフックを呼び出す。
Emacsはfile-local-variables-alist
に格納されたファイルローカル変数を適用し終えた直後にこのフックを呼び出す。
ある変数にたいしてsafe-local-variable
プロパティーによって安全な値を指定できます。このプロパティーは引数を1つとる関数です。与えられた値にたいして、その関数が非nil
をリターンしたらその値は安全です。一般的に目にするファイル変数の多くは、safe-local-variable
プロパティーをもちます。これらのファイル変数にはfill-column
、fill-prefix
、indent-tabs-mode
が含まれます。ブーリーン値の変数にたいしては、プロパティーの値にbooleanp
を使用します。
defcustom
を使用してユーザーオプションを定義する際、defcustom
に引数:safe
function
を追加することにより、safe-local-variable
プロパティーをセットできます(カスタマイゼーション変数の定義を参照)。
この変数はある変数の値が安全であることをマークする、別の方法を提供する。これはコンスセル(var
. val)
のリストでありvarは変数名、valはその変数にたいして安全な値である。
Emacsが一連のファイルローカル変数にしたがうかどうかユーザーに尋ねるとき、ユーザーはそれらの変数が安全だとマークすることができる。安全とマークするとsafe-local-variable-values
にこれらのvariable/valueペアーが追加されて、ユーザーのカスタムファイルに保存する。
この関数は上記の条件に基づき、symに値valを与えても安全ななら非nil
をリターンする。
いくつかの変数は危険(risky)だと判断されます。ある変数が危険なら、その変数がsafe-local-variable-values
に自動的に追加されることはありません。ユーザーがsafe-local-variable-values
を直接カスタマイズすることで明示的に値を許さない限り、危険な変数をセットする前にEmacsは常に確認を求めます。
名前が非nil
のrisky-local-variable
プロパティーをもつすべての変数は危険だと判断されます。defcustom
を使用してユーザーオプションを定義するとき、defcustom
に引数:risky
value
を追加することにより、ユーザーオプションにrisky-local-variable
プロパティーをセットできます。それに加えて名前が‘-command’、‘-frame-alist’、‘-function’、‘-functions’、‘-hook’、‘-hooks’、‘-form’、‘-forms’、‘-map’、‘-map-alist’、‘-mode-alist’、‘-program’、‘-predicate’で終わるすべての変数は自動的に危険だと判断されます。後に数字をともなう変数‘font-lock-keywords’と‘font-lock-keywords’、さらには‘font-lock-syntactic-keywords’も危険だと判断されます。
この関数はsymが上記の条件にもとづき危険な変数なら非nil
をリターンする。
この変数はファイルによりローカル値を与えらるべきではない変数のリストを保持する。これらの変数に指定された任意の値は、完全に無視される。
“変数”‘Eval:’も抜け道になる可能性があるので、Emacsは通常はそれを処理する前に確認を求めます。
この変数は‘-*-’の行中、またはvisitされるファイル内のローカル変数リストにたいする、‘Eval:’の処理を制御する。値t
は無条件に実行し、nil
はそれらを無視することを意味します。それ以外なら各ファイルにたいして何を行うか、ユーザーに確認を求めることを意味する。デフォルト値はmaybe
。
この変数はファイルローカル変数リスト内で‘Eval:’“変数”が見つかった際に評価しても安全な式のリストを保持する。
式が関数呼び出しであり、その関数がsafe-local-eval-function
プロパティーをもつなら、その式の評価が安全かどうかはそのプロパティー値が決定します。プロパティー値はその式をテストするための述語(predicate)、そのような述語のリスト(成功した述語があれば安全)、またはt
(引数が定数である限り常に安全)を指定できます。
テキストプロパティーには、それらの値に関数呼び出しを含めることができるので抜け道になる可能性があります。したがってEmacsはファイルローカル変数にたいして指定された文字列値から、テキストプロパティーを取り除きます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ディレクトリーは、そのディレクトリー内のすべてのファイルに共通なローカル変数値を指定することができます。Emacsはそのディレクトリー内の任意のファイルをvisitしているバッファー内で、それらの変数にたいするバッファーローカルなバインディングを作成するためにこれを使用します。これはそのディレクトリー内のファイルが何らかのプロジェクトに属していて、同じローカル変数を共有するときなどに有用です。
ディレクトリーローカル変数を指定するために2つの異なる方法があります: 1つは特別なファイルにそれを記述する方法、もう1つはそのディレクトリーにプロジェクトクラス(project class)を定義する方法です。
この定数はEmacsがディレクトリーローカル変数が見つけることができると期待するファイルの名前である。ファイル名は.dir-locals.el8。ディレクトリー内でその名前をもつファイルにより、Emacsはディレクトリー内の任意のファイル、または任意のサブディレクトリー(オプションでサブディレクトリーを除外できる。以下参照)にセッティングを適用する。独自に.dir-locals.elをもつサブディレクトリーがあるなら、Emacsはサブディレクトリーで見つかった1番深いファイルのディレクトリーからディレクトリーツリーを上方に移動しつつ、1番深いファイルのセッティングを使用する。このファイルはローカル変数をフォーマットされたリストとして指定する。詳細はPer-directory Local Variables in The GNU Emacs Manualを参照のこと。
この関数は.dir-locals.el
ファイルを読み込み、そのディレクトリー内の任意のファイルをvisitしているバッファーにローカルなfile-local-variables-alist
内に、それらを適用することなくディレクトリーローカル変数を格納する。この関数はディレクトリーローカルなセッティングもdir-locals-class-alist
(.dir-locals.elファイルが見つかったディレクトリーにたいする特別なクラスを定義する)内に格納する。この関数は以下で説明するように、dir-locals-set-class-variables
とdir-locals-set-directory-class
を呼び出すことにより機能する。
この関数はディレクトリーローカル変数を探して、即座にそれらをカレントバッファーに適用する。これはDiredバッファーのような、非ファイルバッファーをディレクトリーローカル変数のセッティングにしたがわせるために、モードコマンド呼び出しの中から呼び出されることを意図したものである。非ファイルバッファーにたいしては、Emacsはdefault-directory
とその親ディレクトリーの中から、ディレクトリーローカル変数を探す。
この関数はclassという名前がつけられたシンボルにたいして、一連の変数セッティングを定義する。ユーザーは後からこのクラスを1つ以上のディレクトリーに割り当てることができる。そしてEmacsはこれらの変数セッティングを、それらのディレクトリー内のすべてのファイルに適用するだろう。variables内のリストは2つの形式
— (major-mode . alist)
か(directory
. list)
—
のいずれかをもつことができる。1番目の形式ではそのファイルのバッファーがmajor-modeを継承するモードに切り替わるときに、連想リストalist内のすべての変数が適用される。alistは(name
.
value)
という形式。major-modeにたいする特別な値nil
は、そのセッティングが任意のモードに適用できることを意味する。alist内では特別なnameとして、subdirs
を使用することができる。連想値がnil
なら、alistは関連するディレクトリー内のファイルだけに適用され、それらのサブディレクトリーには適用されない。
variablesの2番目の形式では、directoryがそのファイルのディレクトリーの最初のサブディレクトリーなら、上記のルールにしたがいlistが再帰的に適用される。listはこの関数のvariablesで指定できる2つの形式のうち1つを指定する。
この関数はdirectory
とサブディレクトリー内のすべてのファイルにclassを割り当てる。その後、classにたいして指定されたすべての変数セッティングは、directoryとその子ディレクトリー内でvisitされたすべてのファイルに適用される。classは事前にdir-locals-set-class-variables
で定義されていなければならない。
Emacsが.dir-locals.el
ファイルからディレクトリー変数をロードする際、内部的にこの関数を使用する。その場合、オプションの引数mtimeはファイルの修正日時(modification
time。file-attributes
によりリターンされる)を保持する。Emacsは記憶されたローカル変数がまだ有効化チェックするために、この日時を使用する。ファイルを介さず直接クラスを割り当てる場合、この引数はnil
になる。
このalistはクラスシンボル(class
symbol)とそれに関連づけられる変数のセッティングを保持する。これはdir-locals-set-class-variables
により更新される。
このalistはディレクトリー名、それらに割り当てられたクラス名、およびこのエントリーに関連するディレクトリーローカル変数ファイルの修正日時を保持する。関数dir-locals-set-directory-class
はこのlistを更新する。
nil
ならディレクトリーローカル変数は無視される。この変数はファイルローカル変数(ファイルローカル変数を参照)にはしたがうが、ディレクトリーローカル変数は無視したいモードにたいして有用かもしれない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
シノニムとして2つの変数を作成できれば便利なときがあります。2つの変数は常に同じ値をもち、どちらか一方を変更すると、もう一方も変更されます。変数の名前を変更
— 古い名前はよく考慮して選択されたものではなかったとか、変数の意味が部分的に変更された等の理由で —
するとき、互換性のために新しい名前のエイリアス(alias)として古い名前を維持できれば便利なときがあるかもしれません。defvaralias
によってこれを行うことができます。
この関数はシンボルbase-variableのエイリアスとして、シンボルnew-aliasを定義する。これはnew-aliasから値を取得するとbase-variableの値がリターンされ、new-aliasの値を変更するとbase-variableの値が変更されることを意味する。エイリアスされた2つの変数名は、常に同じ値と同じバインディングを共有する。
docstring引数が非nil
なら、それはnew-aliasのドキュメント文字列を指定する。それ以外なら、エイリアスは(もしあれば)base-variableと同じドキュメント文字列となる。ただしそれはbase-variable自体がエイリアスではない場合で、エイリアスならnew-aliasはエイリアスチェーンの最後の変数のドキュメント文字列になる。
この関数はbase-variableをリターンする。
変数のエイリアスは、変数にたいする古い名前を新しい名前に置き換える便利な方法です。make-obsolete-variable
は古い名前を陳腐化(obsolete)していると宣言して。それが将来のある時点で削除されるかもしれないことを宣言します。
この関数はバイトコンパイラーに変数obsolete-nameが陳腐化していると警告させる。current-nameがシンボルなら、それはこの変数の新たな名前である。警告メッセージはその後、obsolete-nameのかわりにcurrent-nameを使用するよう告げるようになる。current-nameが文字列なら、それはメッセージであり、置き換えられる変数はない。whenはその変数が最初に陳腐化するのがいつかを示す文字列(通常はバージョン番号文字列)。
オプションの引数access-typeが非nil
なら、それは陳腐化の警告を引き起こすアクセスの種類を指定すること。get
かset
を指定できる。
2つの変数シノニムを作成してマクロdefine-obsolete-variable-alias
を使用することにより、1つが陳腐化していると同時に宣言できます。
このマクロは変数obsolete-nameが陳腐化しているとマークして、それを変数current-nameにたいするエイリアスにする。これは以下と等価である:
(defvaralias obsolete-name current-name docstring) (make-obsolete-variable obsolete-name current-name when)
この関数はvariableのエイリアスチェーンの最後の変数をリターンする。variableがシンボルでない、またはvariableがエイリアスとして定義されていなければ、この関数はvariableをリターンする。
この関数はシンボルのチェーンがループしていたら、cyclic-variable-indirection
エラーをシグナルする。
(defvaralias 'foo 'bar) (indirect-variable 'foo) ⇒ bar (indirect-variable 'bar) ⇒ bar (setq bar 2) bar ⇒ 2
foo ⇒ 2
(setq foo 0) bar ⇒ 0 foo ⇒ 0
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
通常のLisp変数には、有効なLispオブジェクトである任意の値を割り当てることができます。しかしLispではなくCで定義されたLisp変数もあります。これらの変数のほとんどは、DEFVAR_LISP
を使用してCコードで定義されています。Lispで定義された変数と同様、これらは任意の値をとることができます。しかしいくつかの変数はDEFVAR_INT
やDEFVAR_BOOL
を使用して定義されています。C実装の概要的な議論は、Writing Emacs
Primitives、特にsyms_of_filename
型の関数の説明を参照してください。
DEFVAR_BOOL
型の変数は、値にnil
かt
しかとることができません。他の値の割り当てを試みるとt
がセットされます:
(let ((display-hourglass 5)) display-hourglass) ⇒ t
この変数はDEFVAR_BOOL
型のすべての変数のリストを保持する。
DEFVAR_INT
型の変数は、整数値だけをとることができます。他の値の割り当てを試みると結果はエラーになります:
(setq undo-limit 1000.0) error→ Wrong type argument: integerp, 1000.0
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ジェネリック変数(generalized variable: 汎変数)またはplaceフォーム(place form)は、値が格納されるLispメモリー内の多くの場所のうちの1つです。1番シンプルなplaceフォームは通常のLisp変数です。しかしリストのCARとCDR、配列の要素、シンボルのプロパティー、その他多くのロケーション(location)もLisp値が格納される場所です。
ジェネリック変数は、C言語のlvalues(左辺値)と類似しています。C言語のlvalueでは‘x =
a[i]’で配列から要素を取得し、同じ表記を使用して‘a[i] =
x’で要素を格納します。Cではa[i]
のような特定のフォームがlvalueになれるように、Lispでジェネリック変数になることができる一連のフォームが存在します。
11.15.1 setf マクロ | ||
11.15.2 新たなsetf フォーム | 新たなsetf フォームの定義。
|
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
setf
マクロsetf
マクロはジェネリック変数を操作する、もっとも基本的な方法です。setf
フォームはsetq
と似ていますが、シンボルだけでなく左辺の任意のplaceフォームを受け入れます。たとえば(setf
(car a) b)
はa
のcarをb
にセットして、(setcar a
b)
と同じ操作を行いますが、すべてのplace型へのセットとアクセスを行うために2つの別個の関数を覚える必要はありません。
このマクロはformを評価して、それをplaceに格納する。placeは有効なジェネリック変数フォームでなければならない。複数のplace/formペアーがある場合、割り当てはsetq
の場合と同様。setf
は最後のformの値をリターンする。
以下のLispフォームはジェネリック変数として機能するので、setf
のplace引数にすることができます:
(setf x y)
は完全に(setq x
y)
と等しく、厳密に言うとsetq
自体はsetf
が存在するので冗長である。これは純粋にスタイルと歴史的な理由によるが、多くのプログラマーは依然として単純な変数へのセットにsetq
を好む。実際にはマクロ(setf
x y)
は(setq x y)
に展開されるので、コンパイルされたコードでこれを使用することにパフォーマンス的な不利はない。
aref cddr symbol-function car elt symbol-plist caar get symbol-value cadr gethash cdr nth cdar nthcdr
alist-get process-get frame-parameter process-sentinel terminal-parameter window-buffer keymap-parent window-display-table match-data window-dedicated-p overlay-get window-hscroll overlay-start window-parameter overlay-end window-point process-buffer window-start process-filter default-value
どのように処理すれば良いか未知なplaceフォームを渡すと、setf
はエラーをシグナルします。
nthcdr
の場合、関数のリスト引数はそれ自体が有効なplaceフォームでなければならないことに注意してください。たとえば(setf
(nthcdr 0 foo) 7)
は、foo
自体に7をセットするでしょう。
マクロpush
(リスト変数の変更を参照)とpop
(リスト要素へのアクセスを参照)は、リストだけでなくジェネリック変数を操作できます。(pop
place)
はplace内に格納されたリストの最初の要素を削除してリターンします。これは(prog1 (car
place) (setf place (cdr
place)))
と似ていますが、すべてのサブフォームを一度だけ評価します。(push x
place)
はplace内に格納されたリストの1番前にxを挿入します。これは(setf
place (cons x
place))
と似ていますが、サブフォームの評価が異なります。nthcdr
placeへのpush
とpop
は、リスト内の任意の位置での挿入ち削除に使用できることに注意してください。
cl-libライブラリーでは追加のsetf
placeを含む、ジェネリック変数にたいするさまざまな拡張が定義されています。Generalized Variables in Common Lisp Extensionsを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
setf
フォームこのセクションでは、setf
が操作できる新たなフォームの定義方法を説明します。
このマクロは単純なケースでsetf
メソッドを簡単に定義することを可能にする。nameは関数、マクロ、スペシャルフォームの名前。nameがそれを更新するための対応するsetter関数をもつなら、このマクロを使用できる(たとえば(gv-define-simple-setter
car setcar)
)。
このマクロは以下のフォームの呼び出しを
(setf (name args…) value)
以下のように変換する。
(setter args… value)
このようなsetf
の呼び出しはvalueをリターンするとドキュメントされている。これはcar
とsetcar
では問題はない。setcar
はそれがセットする値をリターンするからである。setter関数がvalueをリターンしない場合には、gv-define-simple-setter
のfix-return引数に、非nil
値を使用すること。これは以下のようなものに展開される
(let ((temp value)) (setter args… temp) temp)
これで正しい結果がリターンされることが保証される。
このマクロは上述のフォームより複雑なsetf
展開を可能にする。たとえば呼び出すべきシンプルなsetter関数が存在しないときや、もしそれが存在してもplaceフォームとは異なる引数を要求するなら、このフォームを使う必要があるかもしれない。
このマクロは最初にsetf
引数フォーム(value
args…)
をarglistにバインドして、その後bodyを実行することによって、フォーム(setf
(name args…)
value)
を展開する。bodyは割り当てを行うLispフォームをリターンして、最終的にはセットされた値をリターンすること。以下はこのマクロの使用例である:
(gv-define-setter caar (val x) `(setcar (car ,x) ,val))
展開をさらに制御するならマクロgv-define-expander
を参照してください。マクロgv-letplace
はsetf
のような処理を行うマクロを定義するのに有用です。詳細はgv.elのソースファイルを参照してください。
Common Lispに関する注意: Common Lispは関数としての
setf
、すなわち関数名がシンボルではなくリスト(setf name)
であるようなsetf
関数の挙動を指定するために別の方法を定義する。たとえば(defun (setf foo) …)
は、setf
がfoo
に適用されるときに使用される関数を定義する。Emacsはこれをサポートしない。適切な展開が定義されていないフォームにsetf
を使用するとコンパイル時エラーとなる。Common Lispでは後で関数(setf func)
が定義されるのでエラーにならない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispプログラムは主にLisp関数で構成されます。このチャプターはで関数とは何か、引数を受け取る方法、そして関数を定義する方法を説明します。
12.1 関数とは? | Lisp関数 vs. プリミティブ。専門用語。 | |
12.2 ラムダ式 | 関数がLispオブジェクトとして表現される方法。 | |
12.3 関数の命名 | シンボルは関数を命名できる。 | |
12.4 関数の定義 | 関数定義のためのLisp式。 | |
12.5 関数の呼び出し | 既存の関数を使う方法。 | |
12.6 関数のマッピング | リストの各要素などに関数を適用する。 | |
12.7 無名関数 | ラムダ式、それは無名の関数。 | |
12.8 Generic Functions | Polymorphism, Emacs-style. | |
12.9 関数セルの内容へのアクセス | シンボルの関数定義へのアクセスとセット。 | |
12.10 クロージャー | レキシカル環境に囲まれた関数。 | |
12.11 Emacs Lisp関数にたいするアドバイス | 関数の定義への追加。 | |
12.12 関数を陳腐と宣言する | ||
12.13 インライン関数Inline Functions | コンパイラーによりインライン展開される関数。 | |
12.14 declare フォーム | 関数についての補足的な情報の追加。 | |
12.15 コンパイラーへの定義済み関数の指示 | 関数が定義されていることをコンパイラーに知らせる。 | |
12.16 安全に関数を呼び出せるかどうかの判断 | 呼び出しても安全な関数なのか判断する。 | |
12.17 関数に関するその他トピック | 関数が動作する方法において特別な意味をもつ、特定のLispプリミティブのクロスリファレンス。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
一般的な意味において関数とは、引数(arguments)と呼ばれる与えられた入力値の計算を担うルールです。計算の結果はその関数の値(value)、またはリターン値(return value)と呼ばれます。計算では変数の値やデータ構造の内容を変更する等の副作用をもつこともできます。
ほとんどのコンピューター言語では、関数はそれぞれ名前をもちます。しかしLispでは厳密な意味において関数は名前をもちません。関数はオブジェクトであり、関数の名前の役割を果たすシンボルに関連づけることができますが(たとえばcar
)、それはオプションです。関数の命名を参照してください。関数が名前を与えられたとき、通常はそのシンボルを“関数”として参照します(たとえば関数car
のように参照する)。このマニュアルでは、関数名と関数オブジェクト自身との間の区別は通常は重要ではありませんが、それが意味をもつような場合には注記します。
スペシャルフォーム(special form)、マクロ(macro)と呼ばれる関数likeなオブジェクトがいくつかあり、それらも引数を受け取って計算を行います。しかし以下で説明するようにEmacs Lispではこれらは関数とはみなされません。
以下は関数と関数likeなオブジェクトにたいする重要な条件です:
Lispで記述された関数(厳密には関数オブジェクト)。これらについては以降のセクションで説明します。 ラムダ式を参照のこと。
Lispから呼び出すことができるが実際にはCで記述されている。プリミティブはビルトイン関数(built-in
functions)とかサブルーチン(subr)のようにも呼ばれる。それらの例には関数likeなcar
やappend
が含まれる。加えてすべてのスペシャルフォーム(以下参照)もプリミティブとみなされる。
関数はLispの基礎となる部分(たとえばcar
)であり、オペレーティングシステムのサービスにたいして低レベルのインターフェースを与え、高速に実行される必要があるために、通常はプリミティブとして実装されている。Lispで定義された関数と異なり、プリミティブの修正や追加には、Cソースの変更とEmacsのリコンパイルが必要となる。Emacsプリミティブの記述を参照のこと。
プリミティブは関数と似ているが、すべての引数が通常の方法で評価されない。いくつかの引数だけが評価されるかもしれず、通常ではない順序で評価されるか、複数回評価されるかもしれない。プリミティブの例にはif
、and
、while
が含まれる。スペシャルフォームを参照のこと。
あるLisp式をオリジナルの式のかわりに評価される別の式に変換する、関数とは別のLispで定義された構文。マクロはスペシャルフォームが行う一連のことを、Lispプログラマーが行うのを可能にする。マクロを参照のこと。
プリミティブcommand-execute
を通じて呼び出すことができるオブジェクトで、通常はそのコマンドにバインドされたキーシーケンスをユーザーがタイプすることにより呼び出される。interactiveな呼び出しを参照のこと。コマンドは通常は関数である。その関数がLispで記述されていれば、関数の定義内のinteractive
フォームによってコマンドとなる(コマンドの定義を参照)。関数であるコマンドは他の関数と同様、Lisp式から呼び出すこともできる。
キーボードマクロ(文字列かベクター)は関数ではないが、これらもコマンドである。キーボードマクロを参照のこと。シンボルの関数セルにコマンドが含まれてれば、わたしたちはそのシンボルをコマンドと言う(シンボルの構成要素を参照)。そのような名前つきコマンド(named command)はM-xで呼び出すことができる。
ラムダ式とよく似た関数オブジェクトだが、クロージャーはレキシカル変数バインディングの環境にも囲われている。クロージャーを参照のこと。
バイトコンパイラーによりコンパイル済みの関数。バイトコード関数型を参照のこと。
実際の関数のプレースホルダー。autoloadオブジェクトが呼び出されると、Emacsは実際の関数の定義を含むファイルをロードした後に実際の関数を呼び出す。autoloadを参照のこと。
関数functionp
を使用して、あるオブジェクトが関数かどうかテストできます:
この関数はobjectが任意の種類の関数(funcall
に渡すことができる)ならt
をリターンする。functionp
は関数を名づけるシンボルにたいしてはt
、スペシャルフォームにたいしてはnil
をリターンすることに注意。
functionp
と異なり、以下の3つの関数はシンボルをそれの関数定義としては扱いません。
この関数はobjectがビルトイン関数(たとえばLispプリミティブ)ならt
をリターンする。
(subrp 'message) ; message
はシンボルであり、
⇒ nil ; subrオブジェクトではない
(subrp (symbol-function 'message)) ⇒ t
この関数はobjectがバイトコード関数ならt
をリターンする。たとえば:
(byte-code-function-p (symbol-function 'next-line)) ⇒ t
この関数はプリミティブsubrの引数リストに関する情報を提供する。リターン値は(min
.
max)
というペアである。minは引数の最小数、maxは最大数、または引数&rest
を伴う関数ではシンボルmany
、subrがスペシャルフォームならシンボルunevalled
となる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ラムダ式(lambda expression)はLispで記述された関数オブジェクトです。以下は例です:
(lambda (x) "Xの双曲線コサインをreturnする" (* 0.5 (+ (exp x) (exp (- x)))))
Emacs Lispではこのようなリストは、関数オブジェクトに評価される有効な式です。
ラムダ式自身は名前をもたない無名関数(anonymous function)です。ラムダ式をこの方法で使用できますが(無名関数を参照)、名前付き関数(named functions)を作成するためにシンボルに関連付けられる方が一般的です(関数の命名を参照)。これらの詳細に触れる前に以下のサブセクションではラムダ式の構成要素と、それらが行うことについて説明します。
12.2.1 ラムダ式の構成要素 | ラムダ式のパーツ。 | |
12.2.2 単純なラムダ式の例 | シンプルな例。 | |
12.2.3 引数リストのその他機能 | 引数リストの詳細と特別な機能。 | |
12.2.4 関数のドキュメント文字列 | 関数内にドキュメントを記述する方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ラムダ式は以下のようなリストです:
(lambda (arg-variables…) [documentation-string] [interactive-declaration] body-forms…)
ラムダ式の1番目の要素は常にシンボルlambda
です。これはそのリストが関数を表すことを示します。lambda
で関数定義を開始する理由は、別の目的での使用が意図された他のリストが、意図せずに関数として評価されないようにするためです。
2番目の要素はシンボル — 引数変数名のリストです。これはラムダリスト(lambda list)と呼ばれます。Lisp関数が呼び出されたとき、引数値はラムダリスト内の変数と対応付けされます。ラムダリストには、与えられた値にたいするローカルバインディングが付与されます。ローカル変数を参照してください。
ドキュメント文字列(documentation string)はEmacs Lispのヘルプ機能にたいして、その関数を説明する関数定義に配されたLispの文字列オブジェクトです。関数のドキュメント文字列を参照してください。
インタラクティブ宣言(interactive declaration)は、(interactive
code-string)
という形式のリストです。これはこの関数が対話的に使用された場合に引数を提供する方法を宣言します。この宣言をもつ関数は、コマンド(command)と呼ばれます。コマンドはM-xを使用したり、キーにバインドして呼び出すことができます。この方法で呼び出されることを意図しない関数は、インタラクティブ宣言を持つべきではありません。インタラクティブ定義を記述する方法は、コマンドの定義を参照してください。
残りの要素はその関数のbody(本体) — その関数が処理を行うためのLispコード(Lispプログラマーは“評価されるLispフォームのリスト”と言うだろう)です。この関数からリターンされる値は、bodyの最後の要素によりリターンされる値です。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の例を考えてみてください:
(lambda (a b c) (+ a b c))
以下のようにfuncall
に渡すことにより、この関数を呼び出すことができます:
(funcall (lambda (a b c) (+ a b c)) 1 2 3)
この呼び出しは変数a
に1、b
に2、c
に3をバインドして、ラムダ式のbodyを評価します。bodyの評価によってこれら3つの数が加算されて、6が結果として生成されます。したがってこの関数呼び出しにより6がリターンされます。
以下のように引数は他の関数の結果であってもよいことに注意してください:
(funcall (lambda (a b c) (+ a b c)) 1 (* 2 3) (- 5 4))
これは引数1
、(* 2 3)
、(- 5
4)
を左から右に評価します。その後ラムダ式に引数1、6、1を適用して値8が生成されます。
これらの例が示すように、ローカル変数を作成してそれらに値を与えるフォームとして、CARがラムダ式であるようなフォームを使用することができます。古い時代のLispでは、この方法がローカル変数をバインドして初期化する唯一の方法でした。しかし現在ではこの目的にはフォームlet
を使用するほうが明解です(ローカル変数を参照)。ラムダ式は主に他の関数の引数として渡される無名関数(無名関数を参照)として、あるいは名前つき関数(関数の命名を参照)を生成するためにシンボルの関数定義に格納するために使用されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
シンプルなサンプル関数(lambda (a b c) (+ a b
c))
は3つの引数変数を指定しているので、3つの引数で呼び出されなければなりません。引数を2つしか指定しなかったり4つ指定した場合は、wrong-number-of-arguments
エラーとなります。
特定の引数を省略できる関数を記述できると便利なこともあります。たとえば関数substring
は3つの引数 —
文字列、開始インデックス、終了インデックス —
を受け取りますが、3つ目の引数を省略すると、デフォルトでその文字列のlengthとなります。関数list
や+
が行うように、特定の関数にたいして不定個の引数を指定できると便利なときもあります。
関数が呼び出されるとき省略されるかもしれないオプションの引数を指定するには、オプションの引数の前にキーワード&optional
を含めるだけです。0個以上の追加引数のリストを指定するには、最後の引数の前にキーワード&rest
を含めます。
したがって引数リストの完全な構文は以下のようになります:
(required-vars… [&optional optional-vars…] [&rest rest-var])
角カッコ(square bracket)は&optional
と&rest
、およびそれらに続く変数が省略できることを示します。
この関数の呼び出しではrequired-varsのそれぞれにたいして、実際の引数が要求されます。0個以上のoptional-varsにたいして実際の引数があるかもしれませんが、ラムダ式が&rest
を使用していなければ、その個数を超えて実際の引数を記述することはできません。&rest
が記述されていれば、追加で任意の個数の実際の引数があるかもしれません。
optionaやrest変数にたいして実際の引数が省略されると、それらのデフォルトは常にnil
になります。関数にたいして引数に明示的にnil
が使用されたのか、引数が省略されたのかを区別することはできません。しかし関数のbodyが、nil
を他の有意な値が省略されたと判断することは自由です。substring
はこれを行います。substring
の3つ目の引数がnil
なら、それは文字列の長さを使用することを意味します。
Common Lispに関する注意: Common Lispではオプションの引数が省略されたときに使用するデフォルト値を指定できる。Emacs Lispでは、引数が明示的に渡されたかを調べる
supplied-p
変数はサポートされない。
例えば引数リストは以下のようになります:
(a b &optional c d &rest e)
a
とb
は最初の2つの実引数となり、これらは必須です。さらに1つまたは2つの引数が指定された場合、それらは順番にc
とd
にバインドされます。1つ目から4つ目の引数の後の引数は、リストにまとめられてe
にそのリストがバインドされます。2つしか引数が指定されなかったら、c
はnil
になります。2つか3つの引数なら、d
はnil
です。引数が4つ以下なら、e
はnil
になります。
オプションの引数の後ろに必須の引数を指定する方法はありません —
これは意味を成さないからです。なぜそうなるかは、この例でc
がオプションでd
が必須な場合を考えてみてください。実際に3つの引数が与えられたとします。3番めの引数は何を指定したのでしょうか?
この引数はcなのでしょうか、それともdに使用されるのでしょうか?
両方の場合が考えられます。同様に&rest
引数の後に、さらに引数(必須またはオプション)をもつことも意味を成しません。
以下に引数リストと、それを正しく呼び出す例をいくつか示します:
(funcall (lambda (n) (1+ n)) ; 1つの必須: 1) ; これは正確に1つの引数を要求する ⇒ 2 (funcall (lambda (n &optional n1) ; 1つは必須で、1つはオプション: (if n1 (+ n n1) (1+ n))) ; 1つまたは2つの引数 1 2) ⇒ 3 (funcall (lambda (n &rest ns) ; 1つは必須で、後は残り: (+ n (apply '+ ns))) ; 1つ以上の引数 1 2 3 4 5) ⇒ 15
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ラムダ式はラムダリストの直後に、オプションでドキュメント文字列(documentation string)をもつことができます。この文字列は、その関数の実行に影響を与えません。これはコメントの一種ですがLisp機構に内在するシステム化されたコメントであり。Emacsのヘルプ機能で使用できます。ドキュメント文字列にアクセスする方法は、ドキュメントを参照してください。
たとえその関数があなたのプログラム内だけで呼び出される関数だとしても、すべての関数にドキュメント文字列を与えるのはよいアイデアです。ドキュメント文字列はコメントと似ていますが、コメントより簡単にアクセスできます。
ドキュメント文字列の1行目は、関数自体にもとづくものであるべきです。なぜならapropos
は、最初の1行目だけを表示するからです。ドキュメント文字列の1行目は、その関数の目的を要約する1つか2つの完全なセンテンスで構成されるべきです。
ドキュメント文字列の開始は通常、ソースファイル内ではインデントされていますが、ドキュメント文字列の開始のダブルクォート文字の前にインデントのスペースがあるので、インデントはドキュメント文字列の一部にはなりません。ドキュメント文字列の残りの行がプログラムソース内で揃うようにインデントする人がいます。これは間違いです。後続の行のインデントは文字列の内部にあります。これはソースコード内での見栄えはよくなりますが、ヘルプコマンドで表示したとき見栄えが悪くなります。
ドキュメント文字列がなぜオプションになるのか不思議に思うかもしれません。なぜならドキュメント文字列の後には必須となる関数の構成要素であるbodyが続くからです。文字列を評価するとその文字列自身がリターンされるので、それがbody内の最後のフォームでない限りなんの効果もありません。したがって実際はbodyの1行目とドキュメント文字列で混乱が生じることはありません。bodyの唯一のフォームが文字列なら、それはリターン値とドキュメントの両方の役目を果たします。
ドキュメント文字列の最後の行には、実際の関数引数とは異なる呼び出し規約を指定できます。これは以下のようなテキストを記述します
\(fn arglist)
そのテキストの後に空行を配置して、テキスト自身は行頭から記述、ドキュメント文字列内でこのテキストの後に改行が続かないように記述します(‘\’はEmacsの移動コマンドが混乱するのを避けるために使用する)。この方法で指定された呼び出し規約は、ヘルプメッセージ内で関数の実引数から生成される呼び出し例と同じ場所に表示されます。
マクロ定義内に記述された引数は、ユーザーがマクロ呼び出しの一部だと考える方法とは合致しない場合がしばしばあるので、この機能はマクロ定義で特に有用です。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
シンボルは関数の名前となることができます。これはそのシンボルの関数セル(function cell: シンボルの構成要素を参照)が、関数オブジェクト(たとえばラムダ式)を含むときに起こります。するとそのシンボル自身が呼び出し可能な有効な関数、つまりそのシンボルの関数セルの関数と等価になります。
関数セルの内容はそのシンボルの関数定義(function definition)と呼ぶこともできます。そのシンボルのかわりにシンボルの関数定義を使う手続きのことをシンボル関数インダイレクション(symbol function indirection)と呼びます。シンボル関数インダイレクションを参照。与えられたシンボルに関数定義がなければシンボルの関数セルはvoidと呼ばれ、それを関数として使用することはできません。
実際のところほとんどすべての関数は名前をもち、その名前により参照されます。ラムダ式を定義することで名前つきのLisp関数を作成、それを関数セル(関数セルの内容へのアクセスを参照)に置くことができます。しかしより一般的なのはdefun
スペシャルフォーム(次のセクションで説明)を使う方法です。
関数の定義を参照してください。
わたしたちが関数に名前を与えるのは、Lisp式内で関数を名前で参照するのが便利だからです。また名前つきの関数は簡単に自分自身を — 再帰的(recursive)に参照することができます。さらにプリミティブはテキスト的な名前だけで参照することができます。なぜならプリミティブ関数は入力構文(read syntax)をもたないオブジェクトだからです(プリミティブ関数型を参照)。
関数が一意な名前をもつ必要はありません。与えられた関数オブジェクトは通常は1つのシンボルの関数セルだけに存在しますが、これは単に慣習的なものです。fset
を使用すれば関数を複数のシンボルに格納するのは簡単です。それらのシンボルはそれぞれ、同じ関数にたいする有効な名前となります。
関数として使用しているシンボルを、変数としても利用できることに注意してください。シンボルのこれら2つの利用法は独立しており、競合はしません(これはSchemaのような他のいくつかのLisp方言には当てはまらない)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
わたしたちは通常は関数を最初に作成したときに名前を与えます。これは関数の定義(defining a
function)と呼ばれ、defun
マクロにより行われます。
defun
は新たなLisp関数を定義する通常の方法である。これは引数リストargs、およびbodyにより与えられるbodyフォームとともに、シンボルnameを関数として定義する。nameとargsをクォートする必要はない。
docが与えられたら、それはその関数のドキュメント文字列を指定する文字列であること(関数のドキュメント文字列を参照)。declareが与えられたら、それは関数のメタデータを指定するdeclare
フォームであること(declare
フォームを参照)。interactiveが与えられたら、それは関数が対話的に呼び出される方法を指定するinteractive
フォームであるこ(interactiveな呼び出しを参照)。
defun
のリターン値は定義されていません。
以下にいくつか例を示す:
(defun foo () 5) (foo) ⇒ 5
(defun bar (a &optional b &rest c) (list a b c)) (bar 1 2 3 4 5) ⇒ (1 2 (3 4 5))
(bar 1) ⇒ (1 nil nil)
(bar) error→ Wrong number of arguments.
(defun capitalize-backwards () "Upcase the last letter of the word at point." (interactive) (backward-word 1) (forward-word 1) (backward-char 1) (capitalize-word 1))
意図せず既存の関数を再定義しないように注意されたい。defun
はcar
のようなプリミティブ関数でさえ、問い合わせせずに躊躇なく再定義する。Emacsがこれを妨げることはない。なぜなら関数の再定義は故意に行われることがあり、そのような意図した再定義を、意図しない再定義と見分ける方法はがないからである。
この関数は定義definition(任意の有効なLisp関数)とともに、シンボルnameを関数として定義する。この関数のリターン値は未定義。
docが非nil
なら、それは関数nameのドキュメントとなる。それ以外ならdefinitionにより提供されるドキュメントが使用される。
内部的にはdefalias
は、通常は定義のセットにfset
を使用する。しかしnameがdefalias-fset-function
プロパティーをもつなら、fset
を呼び出すかわりにそれに割り当てられた値を使用する。
defalias
を使う正しい場所は、特定の関数名が正に定義される場所 —
特にソースファイルがロードされるとき明示的にその名前が出現する場所である。これはdefalias
がdefun
と同じように、どれが関数を定義するファイルなのか記録するからである(アンロードを参照)。
それとは対象的に他の目的のために関数を操作するプログラムでは、そのような記録を保持しないfset
を使用するほうがよいだろう。関数セルの内容へのアクセスを参照のこと。
defun
やdefalias
で新たなプリミティブ関数を作成することはできませんが、任意の関数定義を変更するのに使用することができ、通常の定義がプリミティブであるcar
やx-popup-menu
のような関数でさえ変更することができます。しかしこれは危険なことです。たとえばLispの完全性を損なうことなく、car
を再定義するのはほとんど不可能だからです。それほど有名ではないx-popup-menu
のような関数の再定義では、危険は減少しますが、それでも期待したとおりに機能しないかもしれません。Cコードにそのプリミティブの呼び出しがあれば、それは直接そのプリミティブのC定義を呼び出すので、シンボル定義を変更してもそれらに影響はありません。
defsubst
も参照してください。これはdefun
のように関数を定義して、それのインライン展開を処理するようLispコンパイラーに指示します。インライン関数Inline Functionsを参照してください。
かわりにコンパイラーマクロとしてインライン展開されるコードを記述することにより関数を定義できます。以下のマクロがこれを可能にします。
自身をインライン化するコードを提供することにより、コンパイラーマクロとして関数nameを定義する。この関数は引数リストargsを受け取り、指定されたbodyをもつ。
docが与えられたなら、それは関数のドキュメント文字列であること(関数のドキュメント文字列を参照)。declareが与えられたなら、それは関数のメタデータを指定するdeclare
フォームであること(declare
フォームを参照)。
define-inline
で定義された関数は、defsubst
やdefmacro
で定義されたマクロにたいして複数の利点をもちます。
mapcar
に渡すことができる(関数のマッピングを参照)。
cl-defsubst
より予測可能な方法で振る舞う(Argument Lists in Common Lisp
Extensions for GNU Emacs Lispを参照)。
defmacro
と同様に、define-inline
でインライン化された関数は、呼び出し側からダイナミックかレキシカルいずれかのスコーピングルールを継承します。変数のバインディングのスコーピングルールを参照してください。
以下のマクロはdefine-inline
で定義された関数のbody内で使用する必要があります。
define-inline
にたいしてexpressionをクォートする。これはバッククォート(バッククォートを参照)と似ているが、コードをクォートして,
だけを受け入れ、,@
は受け入れない。
これはlet
(ローカル変数を参照)と似ているが、bindingsで指定されたようにローカル変数をセットアップして、そのバインディングの効力の下でbodyを評価する。bindingsのそれぞれの要素はシンボルか(var expr)
という形式のリストのいずれかであること。後者ならexprを評価した結果がvarにバインドされる。bindingsの末尾にはnil
、または引数のリストを保持するシンボルを指定できる。後者の場合は各引数が評価されて、そのシンボルに結果リストがバインドされる。
expressionの値が既知なら非nil
をリターンする。
expressionの値をリターンする。
formatに応じてargsをフォーマットしてエラーをシグナルする。
以下はdefine-inline
を使用した例です:
(define-inline myaccessor (obj) (inline-letevals (obj) (inline-quote (if (foo-p ,obj) (aref (cdr ,obj) 3) (aref ,obj 2)))))
これは以下と等価です
(defsubst myaccessor (obj) (if (foo-p obj) (aref (cdr obj) 3) (aref obj 2)))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
関数を定義しただけでは半分しか終わっていません。関数はそれを呼び出す(call) — たとえば実行(run)するまでは何も行いません。関数のcallはinvocationとしても知られています。
関数を呼び出すもっとも一般的な方法は、リストの評価によるものです。たとえばリスト(concat "a"
"b")
を評価することにより、関数concat
が引数"a"
と"b"
で呼び出されます。評価については評価を参照してください。
プログラム内で式としてリストを記述するときは、プログラム内にテキストでどの関数を呼び出すか、いくつの引数を与えるかを指定します。通常はこれが行いたいことです。どの関数を呼び出すかを実行時に計算する必要がある場合もあります。これを行うには関数funcall
を使用します。実行時にいくつの引数を渡すか決定する必要があるときはapply
を使用します。
funcall
は関数functionを引数argumentsで呼び出して、functionがリターンした値をリターンする。
funcall
は関数なので、functionを含むすべての引数はfuncall
の呼び出し前に評価される。これは呼び出される関数を得るために任意の式を使用できることを意味している。またfuncall
がargumentsに記述した式ではなく、その値だけを見ることを意味している。これらの値はfunction呼び出し中では、2回目は評価されない。funcall
の処理は関数の通常の呼び出し手続きと似ており、すでに評価された引数は評価されない。
引数functionはLisp関数かプリミティブ関数でなければならない。つまりスペシャルフォームやマクロは、未評価の引数式を与えられたときだけ意味があるので、指定することはできない。上述したように最初の場所でfuncall
がそれらを知らないので、funcall
がそれらを提供することはできない。
コマンドの呼び出しにfuncall
を使用して、それがインタラクティブに呼び出されたように振る舞うようにする必要があるなら、funcall-interactively
を使用すること(interactiveな呼び出しを参照)。
(setq f 'list) ⇒ list
(funcall f 'x 'y 'z) ⇒ (x y z)
(funcall f 'x 'y '(z)) ⇒ (x y (z))
(funcall 'and t nil) error→ Invalid function: #<subr and>
これらの例をapply
の例と比較されたい。
apply
は関数functionを引数argumentsで呼び出す。これはfuncall
と同様だが1つ違いがある。argumentsの最後はオブジェクトのリストである。これは1つのリストではなく、個別の引数としてfunctionに渡される。わたしたちはこれを、apply
がこのリストを展開(spread)(個々の要素が引数となるので)すると言う。
apply
はfunctionを呼び出した結果をリターンする。funcall
と同様、functionはLisp関数かプリミティブ関数でなければならない。つまりスペシャルフォームやマクロはapply
では意味をもたない。
(setq f 'list) ⇒ list
(apply f 'x 'y 'z) error→ Wrong type argument: listp, z
(apply '+ 1 2 '(3 4)) ⇒ 10
(apply '+ '(1 2 3 4)) ⇒ 10
(apply 'append '((a b c) nil (x y z) nil)) ⇒ (a b c x y z)
apply
を使用した興味深い例はDefinition of mapcarを参照のこと。
ある関数にたいして、その関数のある引数を特定の値に固定して、他の引数は実際に呼びだされたときの値にできれば便利なことがあります。関数のいくつかの引数を固定することは、その関数の部分適用(partial application)と呼ばれます9。これの結果は残りの引数をとる新たな関数で、すべての引数を合わせて元の関数を呼び出します。
Emacs Lispで部分適用を行う方法を示します:
この関数は新たな関数をリターンする。この新しい関数は呼びだされたときにargs、および呼び出し時に指定された追加の引数から成る引数リストでfuncを呼び出す関数である。funcにn個の引数を指定できる場合、m < n
個の引数でapply-partially
を呼び出すと、n - m
個の新たな関数を生成する。
以下はビルトイン関数1+
が存在しないものとして、apply-partially
と他のビルトイン関数+
を使用して1+
を定義する例である:
(defalias '1+ (apply-partially '+ 1) "Increment argument by one.")
(1+ 10) ⇒ 11
引数として関数を受け取ったり、データ構造(特にフック変数やプロパティーリスト)から関数を探す関数はLispでは一般的で、それらはfuncall
やapply
を使用してそれらの関数を呼び出します。引数として関数をとる関数は、ファンクショナル(functional)と呼ばれるときもあります。
ファンクショナルを呼び出すとき、引数としてno-op関数(何も行わない関数)を指定できると便利なときがあります。以下に2つの異なるno-op関数を示します:
この関数はargをリターンする。副作用はない。
この関数はすべての引数を無視してnil
をリターンする。
関数のいくつかはユーザーに可視なコマンドで、これらは(通常はキーシーケンスを介して)対話的に呼び出すことができます。そのようなコマンドは、call-interactively
関数を使用することにより、対話的に呼びだされたときと同様に呼び出すことができます。interactiveな呼び出しを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マップ関数(mapping
function)は与えられた関数(スペシャルフォームやマクロではない)を、リストや他のコレクションの各要素に適用します。Emacs
Lispにはそのような関数がいくつかあります。このセクションではリストにたいしてマッピングを行うmapcar
、mapc
、mapconcat
を説明します。obarray内のシンボルにたいしてマッピングを行う関数mapatoms
は、Definition of mapatomsを参照してください。ハッシュテーブル内のkey/value関係にたいしてマッピングを行う関数maphash
は、Definition of maphashを参照してください。
これらのマップ関数は文字テーブル(char-table)には適用されません。なぜなら文字テーブルは非常に広い範囲の疎な配列だからです。疎な配列であるという性質に適う方法で文字テーブルにマッピングするには、関数map-char-table
を使用します(文字テーブルを参照)。
mapcar
は関数functionをsequenceの各要素にたいして順番に適用して、その結果をリストでリターンする。
引数sequenceには、文字テーブルを除く任意の種類のシーケンス — つまりリスト、ベクター、ブールベクター、文字列を指定できる。結果は常にリストになる。結果の長さはsequenceの長さと同じ。たとえば:
(mapcar 'car '((a b) (c d) (e f))) ⇒ (a c e) (mapcar '1+ [1 2 3]) ⇒ (2 3 4) (mapcar 'string "abc") ⇒ ("a" "b" "c")
;; my-hooks
内の各関数を呼び出す
(mapcar 'funcall my-hooks)
(defun mapcar* (function &rest args) "Apply FUNCTION to successive cars of all ARGS. Return the list of results." ;; リストが消費されていなければ (if (not (memq nil args)) ;; CARに関数を適用する (cons (apply function (mapcar 'car args)) (apply 'mapcar* function ;; 残りの要素のための再帰 (mapcar 'cdr args)))))
(mapcar* 'cons '(a b c) '(1 2 3 4)) ⇒ ((a . 1) (b . 2) (c . 3))
mapc
はmapcar
と似ているが、functionは副作用のためだけに使用される —
つまりfunctionがリターンする値は無視されてリストに収集されない。mapc
は常にsequenceをリターンする。
mapconcat
はsequenceのそれぞれの要素にfunctionを適用する。結果は文字のシーケンス(文字列、ベクター、リスト)でなければならず、単一の文字列に結合されてリターン値となる。mapconcat
は結果シーケーンスの各ペアの間にseparatorの文字を挿入する。これも文字列、または文字のベクターかリストでなければならない。シーケンス、配列、ベクターを参照のこと。
引数functionは1つの引数を受け取り文字のシーケンス、すなわち文字列、ベクター、リストのいずれかをリターンする。引数sequenceは文字テーブル以外の任意の種類のシーケンス、すなわちリスト、ベクター、ブールベクター、または文字列を指定できる。
(mapconcat 'symbol-name '(The cat in the hat) " ") ⇒ "The cat in the hat"
(mapconcat (function (lambda (x) (format "%c" (1+ x)))) "HAL-8000" "") ⇒ "IBM.9111"
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
関数は通常はdefun
により定義されて、同時に名前が与えられますが、明示的にラムダ式を使う — 無名関数(anonymous
function)のほうが便利なときもあります。無名関数は名前つき関数が有効な場所ならどこでも有効です。無名関数は変数や関数の引数に割り当てられることがよくあります。たとえばある関数をリストの各要素に適用するmapcar
のfunction引数に渡すかもしれません(関数のマッピングを参照)。現実的な例はdescribe-symbols exampleを参照してください。
無名関数として使用するためのラムダ式を定義するとき、原則的にはリストを構築する任意の手法を使用できます。しかし通常はマクロlambda
、スペシャルフォームfunction
、または入力構文#'
を使用するべきです。
このマクロは引数リストargs、(もしあれば)ドキュメント文字列doc、(もしあれば)インタラクティブ指定interactive、およびbodyで与えられるbodyフォームをもつ無名関数をリターンする。
実際にはこのマクロはlambda
フォームを自己クォート(self-quoting)する。つまりCARがlambda
であるようなフォームはそのフォーム自身を取得する。
(lambda (x) (* x x)) ⇒ (lambda (x) (* x x))
lambda
フォームは別の1つの効果をもつ。このマクロはfunction
(以下参照)をサブルーチンとして使用することにより、Emacs評価機能(Emacs
evaluator)とバイトコンパイラーに、その引数が関数であることを告げる。
このスペシャルフォームは評価を行わずにfunction-objectをリターンする。この点ではquote
(クォートを参照)と似ている。しかしquote
とは異なり、Emacs評価機能とバイトコンパイラーに、これを関数として使用する意図を告げる役割をもつ。function-objectが有効なラムダ式と仮定すると、これは2つの効果をもつ:
入力構文#'
はfunction
の使用の略記です。以下のフォームは等価です:
(lambda (x) (* x x)) (function (lambda (x) (* x x))) #'(lambda (x) (* x x))
以下の例では3つ目の引数に関数をとるchange-property
関数を定義して、その後のchange-property
で無名関数を渡してこれを使用しています:
(defun change-property (symbol prop function) (let ((value (get symbol prop))) (put symbol prop (funcall function value))))
(defun double-property (symbol prop) (change-property symbol prop (lambda (x) (* 2 x))))
lambda
フォームをクォートしていないことに注意してください。
上記のコードをコンパイルすると無名関数もコンパイルされます。リストをクォートすることにより無名関数を構築した場合にはコンパイルはされません。
(defun double-property (symbol prop) (change-property symbol prop '(lambda (x) (* 2 x))))
この場合、無名関数はコンパイルされたコード内のラムダ式に保持されます。バイトコンパイラーはchange-property
が関数としての使用を意図していることを知ることができないので、たとえこの関数が関数のように見えるとしても、このリストが関数であると決め込むことができません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
defun
を使用して定義された関数は、その引数の型と期待する値に関して、ハードコードされた一連の仮定をもちます。たとえば数字か数字のリストを引数値として処理するようにデザインされた関数は、ベクターや文字列のような他の型の値で呼び出されると失敗したりエラーをシグナルするでしょう。これはその関数実装が、デザイン時に想定した以外の型に対応しないために発生します。
対照的に多相型関数(polymorphic functions)を使用したオブジェクト指向プログラムでは、同一の名前をもつ一連の特化した関数のそれぞれが、特定の引数型セットにたいして記述されます。どの関数が実際に呼び出されるかは、実際の引数の型にもとづいて実行時に決定されます。
Emacsはポリモーフィズム(polymorphism)にたいするサポートを提供します。他のLisp環境、特にCommon LispとCommon Lispオブジェクトシステム(CLOS)と同じように、このサポートはジェネリック関数(generic functions)を基礎としています。Emacsのジェネリック関数は同一名の使用を含むCLOSに密接にしたがっているので、CLOSの経験があればこのセクションの残りの部分は非常に身近に感じるでしょう。
ジェネリック関数は、その名前と引数のリストを指定して、(通常は)実装されていない抽象操作(abstract
operation)を指定します。引数のいくつかの固有クラスにたいする実際の実装はメソッド(methods)により提供され、これは個別に定義されるべきです。ジェネリック関数を実装するそれぞれのメソッドはジェネリック関数としてとして同じ名前をもちますが、そのジェネリック関数で定義された引数のスペシャライジング(specializing)により、メソッドの定義はどの種類の引数を処理可能かを示します。これらの引数スペシャライザー(argument
specializers)は多少の差はあれ特化したものにできます。たとえばstring
型はsequence
のようなより一般的な型より特化した型です。
C++やSimulaのようなメッセージベースのOO言語と異なり、ジェネリック関数を実装するメソッドはクラスに属さずに、それらが実装するジェネリック関数に属することに注意してください。
ジェネリック関数が呼び出されると、呼び出し側に渡された実際の引数と各メソッドの引数スペシャライザーを比較することにより、適用可能なメソッドを呼び出します。その呼び出しの実際の引数がメソッドのスペシャライザーと互換性があれば、そのメソッドが適用可能です。複数のメソッドが適用可能ならば、それらは以下で説明する特定のルールにより合成されて、その組み合わせが呼び出しを処理します。
このマクロは指定したnameとargumentsでジェネリック関数を定義する。bodyが与えられたなら、それは実装のデフォルトを与える。(常に与えられるべきであるが)documentationが与えられたなら、それは(:documentation
docstring)
の形式でそのジェネリック関数のドキュメント文字列を指定する。オプションのoptions-and-methodsは以下のフォームのいずれかを指定できる:
(declare declarations)
declare
フォームで説明するようなdeclareフォーム。
(:argument-precedence-order &rest args)
このフォームは適用可能なメソッド合成にたいするソート順に影響を与える。合成において2つのメソッドを比較する際、メソッドの引数は通常は左から右に試験されて、引数スペシャライザーがより特化した最初のメソッドが他のメソッドより前になる。このフォームで定義された順序はそれをオーバーライドして、左から右ではなくこのフォームの順に応じて試験される。
(:method [qualifiers…] args &rest body)
このメソッドはcl-defmethod
が行うようなメソッドを定義する。
このマクロはnameと呼ばれるジェネリック関数の、特定の実装を定義する。実装コードはbodyで与えられる。もし与えられたらdocstringはそのメソッドのドキュメント文字列である。リストargumentsはジェネリック関数を実装するすべてのメソッドで等しく、その関数の引数リストとマッチしなければならず、(arg
spec)
という形式の引数スペシャライザーを提供する。ここでargはcl-defgeneric
呼び出しで指定された引数名、specは以下のスペシャライザーフォームのいずれかであること:
type
このスペシャライザーは、引数がtypeのいずれかであることを要求する。typeは以下で説明する型ヒエラルキーのいずれかの型である。
(eql object)
このスペシャライザーは、引数がobjectとeql
であることを要求する。
(head object)
引数はcar
がobjectとeql
であるようなコンスセルでなければならない。
struct-tag
引数はcl-defstruct
で定義されるstruct-tagという名前のクラス(Structures in Common Lisp Extensions for GNU Emacs
Lispを参照)、またはその親クラスのいずれかののインスタンスでなければならない。
かわりに引数スペシャライザーは&context (expr
spec)
という形式でもよく、この場合はexprの値はspecが提供するスペシャライザーと互換性がなければならない。specには以下で説明する任意のフォームを指定できる。言い換えると、このスペシャライザーのフォームはメソッドが適用可能かどうかの判定にたいして、引数のかわりにexprの値を使用する。たとえば&context
(overwrite-mode (eql t))
はoverwrite-mode
がオンのときだけ互換性のあるメソッドを作成する。
型スペシャライザー(arg type)
は以下のリストのシステム型(system
types)のいずれかを指定できる。親の型が指定されたときは、型がより特化した子型、孫型、曾孫型、...のいずれかであるような任意の引数も互換となるだろう。
integer
親型: number
。
number
null
親型: symbol
。
symbol
string
親型: array
。
array
親型: sequence
。
cons
親型: list
。
list
親型: sequence
。
marker
overlay
float
親型: number
。
window-configuration
process
window
subr
compiled-function
buffer
char-table
親型: array
。
bool-vector
親型: array
。
vector
親型: array
。
frame
hash-table
font-spec
font-entity
font-object
オプションのqualifierは複数の適用可能なメソッドの合成を許容する。与えられなければ定義されるメソッドはprimary(主)メソッドとなり、スペシャライズされた引数にたいする主要な実装の提供に責任を有する。qualifierとして以下の値のいずれかを使用してauxiliary(副)メソッドも定義できる:
:before
このauxiliaryメソッドはprimaryメソッドの前に実行される。より正確にはすべての:before
メソッドは、より特化したメソッドが最初になる順で、primaryメソッドの前に実行される。
:after
このauxiliaryメソッドはprimaryメソッドの後に実行される。より正確にはすべてのこの類のメソッドは、より特化したメソッドが最後になる順で、primaryメソッドの後に実行される。
:around
このauxiliaryメソッドはprimaryメソッドの代替えとして実行される。この類のメソッドでもっとも特化したものが他のメソッドより前に実行される。このようなメソッドは他のauxiliaryメソッドやprimaryメソッドを呼び出すために、通常は以下で説明するcl-call-next-method
を使用する。
:extra string
これにより同一のspecializerとqualifierにたいして、stringで区別されるメソッドを追加できる。
ジェネリック関数が呼び出されると、毎回その関数にたいして定義された適用可能なメソッドを合成することによってその呼び出しを処理するeffectiveメソッド(effective method)を構築します。適用可能なメソッドを探してeffectiveメソッドを生成するプロセスはdispatchと呼ばれます。その呼び出しの実際の引数と互換性があるスペシャライザーをもつすべてのメソッドが、互換性のあるメソッドです。すべての引数がスペシャライザーと互換でなければならないので、それらはすべてメソッドが適用可能かどうか判定します。複数の引数に明示的に特化したメソッドをmultiple-dispatchメソッド(multiple-dispatch methods)と呼びます。
適用可能なメソッドはそれらが合成される順にソートされます。最左の引数スペシャライザーがもっとも特化したものであるようなメソッドが、順序の最初になります(上述したようにcl-defmethod
の一部として:argument-precedence-order
を指定することによりこれをオーバーライドできる)。そのメソッドのbodyがcl-call-next-method
を呼び出すと、もっとも特化した次のメソッドが実行されます。適用可能な:around
メソッドがあれば、それらのうちもっとも特化したメソッドが実行されます。そのメソッドはより特化していない任意の:around
メソッドを実行するために、cl-call-next-method
を呼び出すべきです。次に:before
メソッドがその特化した順に、その後にspecificityメソッドが実行されます。そして後に:after
メソッドがその特化した順と逆順で実行されます。
primaryメソッドか:around
auxiliaryメソッド内のレキシカルbody内で呼び出されると、同じジェネリック関数にたいして適用可能な次のメソッドを呼び出す。通常これは引数なしで呼び出され、これは次の適用可能なメソッドを呼び出すメソッドが、呼び出されたときと同じ引数で次のメソッドを呼び出すことを意味する。それ以外ならかわりに指定された引数が使用される。
primaryメソッドか:around
auxiliaryメソッドのレキシカルbody内からこの関数を呼び出したときは、呼び出す次のメソッドが存在すれば非nil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
シンボルの関数定義(function definition)とは、そのシンボルの関数セルに格納されたオブジェクトのことです。ここではシンボルの関数セルへのアクセスやテスト、それをセットする関数を説明します。
Definition of indirect-functionの関数indirect-function
も参照してください。
これはsymbolの関数セル内のオブジェクトをリターンする。これはリターンされたオブジェクトが本物のの関数であるかチェックしない。
関数セルがvoidならリターン値はnil
。関数セルがvoidのときとnil
がセットされているときを区別するにはfboundp
(以下参照)を使用する。
(defun bar (n) (+ n 2)) (symbol-function 'bar) ⇒ (lambda (n) (+ n 2))
(fset 'baz 'bar) ⇒ bar
(symbol-function 'baz) ⇒ bar
シンボルに何の関数定義も与えていなければ、そのシンボルの関数セルはvoidだと言います。言い換えると、その関数セルはどんなLispオブジェクトも保持しません。そのシンボルを関数として呼びだそうとすると、Emacsはvoid-function
エラーをシグナルします。
voidはnil
やシンボルvoid
とは異なることに注意してください。シンボルnil
とvoid
はLispオブジェクトであり、他のオブジェクトと同じように関数セルに格納することができます(これらのシンボルはdefun
を使用して有効な関数になることができる)。voidであるような関数セルは、どのようなオブジェクトも含んでいません。
fboundp
を使用して任意のシンボルの関数定義がvoidかどうかテストすることができます。シンボルに関数定義を与えた後は、fmakunbound
を使用して再びvoidにすることができます。
この関数はそのシンボルが関数セルにオブジェクトをもっていればt
、それ以外はnil
をリターンする。これはそのオブジェクトが本物の関数であるかチェックしない。
この関数はsymbolの関数セルをvoidにする。そのためこれ以降に関数セルへのアクセスを試みると、void-function
エラーが発生する。これはsymbolをリターンします(変数がvoidのときのmakunbound
も参照)。
(defun foo (x) x) (foo 1) ⇒1
(fmakunbound 'foo) ⇒ foo
(foo 1) error→ Symbol's function definition is void: foo
この関数はsymbolの関数セルにdefinitionを格納する。結果はdefinition。definitionは通常は関数か関数の名前であるべきだが、これはチェックされない。引数symbolは通常のどおり評価される引数である。
この関数は主に関数を定義したり変更して構築を行う、defun
やadvice-add
のようなものからサブルーチンとして使用される。たとえばキーボードマクロ(キーボードマクロを参照)のような、関数ではない関数定義をシンボルに与えるためにも使用することができる:
;; 名前つきのキーボードマクロを定義する。
(fset 'kill-two-lines "\^u2\^k")
⇒ "\^u2\^k"
関数にたいして別の名前を作成するためにfset
を使いたいなら、かわりにdefalias
の使用を考慮すること。Definition of defaliasを参照。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
変数のバインディングのスコーピングルールで説明したように、Emacsはオプションで変数のレキシカルバインディングを有効にできます。レキシカルバインディングが有効な場合は、(たとえばdefun
などで)作成したすべての名前つき関数、同様にlambda
マクロやfunction
スペシャルフォーム、#'
構文を使用して作成したすべての無名関数(無名関数を参照)が、自動的にクロージャー(closure)に変換されます。
クロージャーとはその関数が定義されたどときに存在したレキシカル環境の記録をあわせもつ関数です。クロージャーが呼び出されたとき、定義内のレキシカル変数の参照には、その保持されたレキシカル環境が使用されます。他のすべての点では、クロージャーは通常の関数と同様に振る舞います。特にクロージャーは通常の関数と同じ方法で呼び出すことができます。
クロージャー使用する例はレキシカルバインディングを参照してください。
現在のところEmacs
Lispのクロージャーオブジェクトは、1つ目の要素にシンボルclosure
をもつリストとして表現されます。そのリストは2つ目の要素としてレキシカル環境、残りの要素で引数リストとbodyフォームを表します:
;; レキシカルバインディングが有効
(lambda (x) (* x x))
⇒ (closure (t) (x) (* x x))
しかし実際にはクロージャーの内部構造は、内部的な実装の詳細と判断される残りのLisp界を晒け出すものだと言えます。この理由により、クロージャーオブジェクトの構造を直接調べたり変更することは推奨しません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
他のライブラリーの関数定義を変更する必要があるとき、およびfoo-function
oのようなフックやプロセスフィルター(process
filter)や、関数を値としてもつ任意の変数やオブジェクトを変更する必要があるときには、名前つきの関数にはfset
かdefun
、フック変数にはsetq
、プロセスフィルターにはset-process-filter
のように、適切なセッター関数(setter
function)を使用することができます。しかしこれらが以前の値を完全に破棄してしまうのが好ましくない場合もあります。
アドバイス(advice)機能によって関数にアドバイスすることにより、既存の関数定義に機能を追加できます。これは関数全体を再定義するより明解な手法です。
Emacsのアドバイスシステムは2つのプリミティブセットを提供します。コアとなるセットは変数やオブジェクトのフィールドに保持された関数値にたいするものです(対応するプリミティブはadd-function
とremove-function
)。もう1つのセットは名前つき関数の最上位のレイヤーとなるものです(主要なプリミティブはadvice-add
とadvice-remove
)。
たとえばプロセスprocのプロセスフィルターの呼び出しをトレースするために以下を使用できます:
(defun my-tracing-function (proc string) (message "Proc %S received %S" proc string)) (add-function :before (process-filter proc) #'my-tracing-function)
これによりそのプロセスの出力は元のプロセスフィルターに渡される前に、my-tracing-function
に渡されるようになります。my-tracing-function
は元の関数と同じ引数を受け取ります。これを行えば以下のようにしてトレースを行う前の振る舞いにリバートすることができます。
(remove-function (process-filter proc) #'my-tracing-function)
同様にdisplay-buffer
という名前つきの関数の実行をトレースしたいなら以下を使用できます:
(defun his-tracing-function (orig-fun &rest args) (message "display-buffer called with args %S" args) (let ((res (apply orig-fun args))) (message "display-buffer returned %S" res) res)) (advice-add 'display-buffer :around #'his-tracing-function)
ここでhis-tracing-function
は元の関数のかわりに呼び出されて、元の関数(に加えてその関数の引数)を引数として受け取るので、必要な場合はそれを呼び出すことができます。出力を確認し終えたら、以下のようにしてトレースを行う前の振る舞いにリバートできます:
(advice-remove 'display-buffer #'his-tracing-function)
上記の例で使用されている引数:before
と:around
は、2つの関数が構成される方法を指定します(これを行う多くの方法があるから)。追加された関数もアドバイス(advice)と呼ばれます。
12.11.1 アドバイスを操作するためのプリミティブ | アドバイスを扱うプリミティブ。 | |
12.11.2 名前つき関数にたいするアドバイス | 名前つき関数のアドバイス。 | |
12.11.3 アドバイスの構築方法 | アドバイスを構成する方法。 | |
12.11.4 古いdefadviceを使用するコードの改良 | 古いdefadviceを使用したコードの改良。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このマクロはplace(ジェネリック変数を参照)に格納された関数に、アドバイスfunctionを追加する手軽な方法である。
whereは既存の関数のどこ — たとえば元の関数の前や後 — にfunctionが構成されるかを決定する。2つの関数を構成するために利用可能な方法のリストは、アドバイスの構築方法を参照のこと。
(通常は名前が-function
で終わる)変数を変更するときには、functionがグローバルに使用されるか、あるいはカレントバッファーだけに使用されるか選ぶことができる。placeが単にシンボルならfunctionはplaceのグローバル値に追加される。placeが(local
symbol)
というフォームなら、symbolはその変数の名前をリターンする式なので、functionはカレントバッファーだけに追加される。最後にレキシカル変数を変更したければ、(var
variable)
を使用する必要があるだろう。
add-function
で追加されたすべての関数は、自動的にプロパティーpropsの連想リストに加えることができる。現在のところ特別な意味をもつのは以下の2つのプロパティーのみ:
name
これはアドバイスの名前を与える。この名前はremove-function
が取り除く関数を識別するのに使用できます。これは通常はfunctionが無名関数のときに使用されます。
depth
これは複数のアドバイスが与えられたときに、どのようにアドバイスを順番づけるべきかを指定する。depthのデフォルト0。depthが100なら、そのアドバイスは可能な限りの深さを保持すべきことを、-100なら最外のアドバイスに留めることを意味する。同じdepthで2つのアドバイスが指定されたら、もっとも最近に追加されたアドバイスが最外となる。
:before
アドバイスにたいしては、最外(outermost)になるということは、このアドバイスが他のすべてのアドバイスの前、つまり1番目に実行されることを意味し、最内(innermost)とは元の関数が実行される直前、すなわちこのアドバイスと元の関数の間に実行されるアドバイスは存在しないことを意味する。同様に:after
アドバイスにたいしては、最内とは元の関数の直後、つまりこの元の関数とアドバイスの間に実行される他のアドバイスは存在せず、最外とは他のすべてのアドバイスが実行された直後にこのアドバイスが実行されることを意味する。:override
の最内アドバイスは、元の関数だけをオーバーライドし、他のアドバイスはそれに適用されるが、:override
の最外アドバイスは元の関数だけではなく、その他すべての適用済みのアドバイスをも同様にオーバーライドする。
functionがインタラクティブでなければ合成された関数は、(もしあれば)元の関数のインタラクティブ仕様(interactive
spec)を継承します。それ以外なら合成された関数はインタラクティブとなりfunctionのインタラクティブ仕様を使用します。1つ例外があります。functionのインタラクティブ仕様が(式や文字列ではない)関数なら、元の関数のインタラクティブ仕様を唯一の引数としてその関数を呼び出して、それが合成された関数のインタラクティブ指定になります。引数として受け取ったインタラクティブ仕様を解釈するためにはadvice-eval-interactive-spec
を使用します。
注意:
functionのインタラクティブ仕様は合成された関数に適用され、functionではなく結合された関数の呼び出し規約に従うこと。多くの場合これらは等しいので差異は生じないが、functionの:around
、:filter-args
、filter-return
では重要になる。
このマクロはplaceに格納された関数からfunctionを取り除く。これはadd-function
を使用してfunctionがplaceに追加されたときだけ機能する。
functionはplaceに追加された関数にたいして、ラムダ式にたいしても機能するようにequal
を使用して比較を試みる。これは追加でplaceに追加された関数のname
プロパティーも比較する。これはequal
を使用してラムダ式を比較するより信頼性がある。
adviceがすでにfunction-def内にあれば非nil
をリターンする。上記のremove-function
と同様、実際の関数adviceのかわりにアドバイスのname
も使用できる。
function-defに追加されたすべてのアドバイスにたいして、関数fを呼び出す。fは2つの引数 — アドバイス関数とそれのプロパティーで呼びだされる。
そのようなインタラクティブ仕様で関数がインタラクティブに呼び出されたようにspecを評価して、構築された引数のリストに対応するリストをリターンする。たとえば(advice-eval-interactive-spec
"r\nP")
はリージョンの境界、カレントプレフィクス引数を含む、3つの要素からなるリストをリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
アドバイスは名前つき関数やマクロにたいして使用するのが一般的な使い方です。これは単にadd-function
を使用して以下のように行うことができます:
(add-function :around (symbol-function 'fun) #'his-tracing-function)
しかしかわりにadvice-add
とadvice-remove
を使うべきです。この異なる関数セットは名前つき関数に適用されるアドバイスを操作するためのもので、add-function
と比較して以下の追加機能があります。まずこれらはマクロとオートロードされた関数を扱う方法を知っています。次にdescribe-function
にたいして追加されたアドバイスと同様に、元のドキュメント文字列を維持します。さらに関数が定義される前でも、アドバイスの追加と削除ができます。
既存の関数全体を再定義せずに既存の呼び出しを変更するために、advice-add
が有用になります。しかしその関数の既存の呼び出し元は古い振る舞いを前提としているかもしれず、アドバイスによりその振る舞いが変更されたときに正しく機能しないかもしれないので、これはソー内スのバグにもなり得ます。アドバイスはデバッグを難しくする可能性もあります。デバッグを行う人はその関数がアドバイスにより変更されたことに気づかなかったり、失念しているかもしれません。
これらの理由により、他の方法で関数の振る舞いを変更できない場合に備えるために、アドバイスの使用は控えるべきです。フックを通じて同じことが行えるならフック(フックを参照)の使用が望ましい方法です。特定のキーが行う何かを変更したいだけなら、新しいコマンドを記述して、古いコマンドのキーバインドを新しいコマンドにリマップ(コマンドのリマップを参照)するのが、おそらくより良い方法です。特にEmacs自身のソースファイルは、Emacs内の関数をアドバイスするべきではありません(現在のところこの慣習にはいくつかの例外があるが、わたしたちはこれを改善しようと思っている)。
スペシャルフォーム(スペシャルフォームを参照)はアドバイスできませんが、マクロは関数と同じ方法でアドバイスできます。もちろんこれはすでにマクロ展開されたコードには影響しないため、マクロ展開前にアドバイスが確実にインストールされる必要があります。
プリミティブ(関数とは?を参照)にアドバイスするのは可能ですが、2つの理由により通常は行うべきではありません。1つ目の理由はいくつかのプリミティブがアドバイスのメカニズム内で使用されているため、それらにたいしてアドバイスを行うと無限再帰が発生するからです。2つ目の理由は多くのプリミティブがCから直接呼び出されていて、そのような呼び出しはアドバイスを無視するからです。したがってプリミティブにたいしてアドバイスの使用を控えることにより、ある呼び出しはアドバイスにしたがい(Lispコードから呼びだされたため)、他の呼び出しではアドバイスにしたがわない(Cコードから呼び出されたため)という混乱した状況を解決できます。
このマクロはアドバイスを定義して、それをsymbolという名前の関数に追加する。nameがnilかsymbol@name
という名前の関数なら、そのアドバイスは無名関数である。他の引数の説明はadvice-add
を参照のこと。
名前つき関数symbolにアドバイスfunctionを追加する。whereとpropsはadd-function
(アドバイスを操作するためのプリミティブを参照)のときと同じ意味をもつ。
名前つき関数symbolからアドバイスfunctionを取り除く。functionにアドバイスのname
を指定することもできる。
名前つき関数symbol内にすでにアドバイスfunctionがあれば非nil
をリターンする。functionにアドバイスのname
を指定することもできる。
名前つき関数symbolにすでに追加されたすべての関数にたいしてfunctionを呼び出す。functionはアドバイス関数とそのプロパティーという2つの引数で呼び出される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はadd-function
とadvice-add
のwhere引数に可能な値であり、そのアドバイスfunctionと元の関数が構成される方法を指定します。
:before
古い関数の前にfunctionを呼び出す。関数は両方とも同じ引数を受け取り、2つの関数の結合のリターン値は古い関数のリターン値である。より正確に言うと2つの関数の結合は以下のように振る舞う:
(lambda (&rest r) (apply function r) (apply oldfun r))
(add-function :before funvar
function)
はノーマルフックにたいする(add-hook 'hookvar
function)
のような1関数のフックと同等。
:after
古い関数の後にfunctionを呼び出す。関数は両方とも同じ引数を受け取り、2つの関数の結合のリターン値は古い関数のリターン値である。より正確に言うと2つの関数の結合は以下のように振る舞う:
(lambda (&rest r) (prog1 (apply oldfun r) (apply function r)))
(add-function :after funvar
function)
はノーマルフックにたいする(add-hook 'hookvar function
'append)
のような1関数のフックと同等。
:override
これは古い関数を新しい関数に完全に置き換える。もちろんremove-function
を呼び出した後に古い関数が復元される。
:around
古い関数のかわりにfunctionを呼び出すが、古い関数はfunctionの追加の引数になる。これはもっとも柔軟な結合である。たとえば古い関数を異なる引数で呼び出したり、複数回呼び出したり、letバインディングで呼び出したり、あるときは古い関数に処理を委譲し、またあるときは完全にオーバーライドすることが可能になる。より正確に言うと2つの関数の結合は以下のように振る舞う:
(lambda (&rest r) (apply function oldfun r))
:before-while
古い関数の前にfunctionを呼び出し、functionがnil
をリターンしたら古い関数を呼び出さない。関数は両方とも同じ引数を受け取り、2つの関数の結合のリターン値は古い関数のリターン値である。より正確に言うと2つの関数の結合は以下のように振る舞う:
(lambda (&rest r) (and (apply function r) (apply oldfun r)))
(add-function :before-while funvar
function)
はrun-hook-with-args-until-failure
を通じてhookvarが実行されたときの(add-hook
'hookvar function)
のような1関数のフックと同等。
:before-until
古い関数の前にfunctionを呼び出し、functionがnil
をリターンした場合だけ古い関数を呼び出す。より正確に言うと2つの関数の結合は以下のように振る舞う:
(lambda (&rest r) (or (apply function r) (apply oldfun r)))
(add-function :before-until funvar
function)
はrun-hook-with-args-until-success
を通じてhookvarが実行されたときの(add-hook
'hookvar function)
のような1関数のフックと同等。
:after-while
古い関数が非nil
をリターンした場合だけ、古い関数の後にfunctionを呼び出す。関数は両方とも同じ引数を受け取り、2つの関数の結合のリターン値はfunctionのリターン値である。より正確に言うと2つの関数の結合は以下のように振る舞う:
(lambda (&rest r) (and (apply oldfun r) (apply function r)))
(add-function :after-while funvar
function)
はrun-hook-with-args-until-failure
を通じてhookvarが実行されたときの(add-hook
'hookvar function 'append)
のような1関数のフックと同等。
:after-until
古い関数がnil
をリターンした場合だけ、古い関数の後にfunctionを呼び出す。より正確に言うと2つの関数の結合は以下のように振る舞う:
(lambda (&rest r) (or (apply oldfun r) (apply function r)))
(add-function :after-until funvar
function)
はrun-hook-with-args-until-success
を通じてhookvarが実行されたときの(add-hook
'hookvar function 'append)
のような1関数のフックと同等。
:filter-args
最初にfunctionを呼び出し、その結果(リスト)を新たな引数として古い関数に渡す。より正確に言うと2つの関数の結合は以下のように振る舞う:
(lambda (&rest r) (apply oldfun (funcall function r)))
:filter-return
最初に古い関数を呼び出し、その結果をfunctionに渡す。より正確に言うと2つの関数の結合は以下のように振る舞う:
(lambda (&rest r) (funcall function (apply oldfun r)))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
多くのコードは古いdefadvice
メカニズムを使用しており、これらの大半はadvice-add
によって陳腐化しました。advice-add
の実装とセマンティックは非常にシンプルです。
古いアドバイスは以下のようなものです:
(defadvice previous-line (before next-line-at-end (&optional arg try-vscroll)) "Insert an empty line when moving up from the top line." (if (and next-line-add-newlines (= arg 1) (save-excursion (beginning-of-line) (bobp))) (progn (beginning-of-line) (newline))))
新しいアドバイスメカニズムを使用すれば、これを通常の関数に変換できます:
(defun previous-line--next-line-at-end (&optional arg try-vscroll) "Insert an empty line when moving up from the top line." (if (and next-line-add-newlines (= arg 1) (save-excursion (beginning-of-line) (bobp))) (progn (beginning-of-line) (newline))))
これが実際のprevious-line
を変更しないことは明確です。古いアドバイスには以下が必要です:
(ad-activate 'previous-line)
一方、新しいアドバイスメカニズムでは以下が必要です:
(advice-add 'previous-line :before #'previous-line--next-line-at-end)
ad-activate
はグローバルな効果をもつことに注意してください。これは指定された関数にたいして、アドバイスのすべてを有効にします。特定のアドバイスだけをアクティブ、または非アクティブにしたいなら、ad-enable-advice
かad-disable-advice
でアドバイスを有効か無効にする必要があります。新しいメカニズムではこの区別はなくなりました。
以下のようなaroundのアドバイスがあるとします:
(defadvice foo (around foo-around) "Ignore case in `foo'." (let ((case-fold-search t)) ad-do-it)) (ad-activate 'foo)
これは以下のように変換できます:
(defun foo--foo-around (orig-fun &rest args) "Ignore case in `foo'." (let ((case-fold-search t)) (apply orig-fun args))) (advice-add 'foo :around #'foo--foo-around)
アドバイスのクラスについて、新たな:before
は古いbefore
は完全に等価ではないことに注意してください。なぜなら古いアドバイス内では、(たとえばad-set-arg
を使って)その関数の引数を変更でき、それは元の関数が参照する引数値に影響します。しかし新しい:before
は、setq
を通じてアドバイス内の引数を変更して、その変更は元の関数からの参照に影響しません。この振る舞いにもとづいてbefore
アドバイスを移行するときは、代わりにそれを新たなアドバイス:around
か:filter-args
に変更する必要があるでしょう。
同様に古いafter
アドバイスは、ad-return-value
を変更することによりリターン値を変更できますが、新しい:after
は変更できないので、そのようなafter
を移行するときは、かわりにそれらを新しいアドバイス:around
か:filter-return
に変更する必要があるでしょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
名前つき関数を陳腐化している(obsolete)とマークすることができます。これはその関数が将来のある時点で削除されるかもしれないことを意味します。陳腐化しているとマークされた関数を含むコードをバイトコンパイルしたとき、Emacsは警告を発します。またその関数のヘルプドキュメントは表示されなくなります。他の点では陳腐化した関数は他の任意の関数と同様に振る舞います。
関数を陳腐化しているとマークするもっとも簡単な方法は、その関数のdefun
定義に(declare (obsolete
…))
を配置することです。declare
フォームを参照してください。かわりに以下で説明しているmake-obsolete
関数を使うこともできます。
make-obsolete
を使用してマクロ(マクロを参照)を陳腐化しているとマークすることもできます。これは関数のときと同じ効果をもちます。関数やマクロにたいするエイリアスも、陳腐化しているとマークできます。これはエイリアス自身をマークするのであって、名前解決される関数やマクロにたいしてではありません。
この関数はobsolete-nameを陳腐化しているとマークする。obsolete-nameには関数かマクロを命名するシンボル、または関数やマクロにたいするエイリアスを指定する。
current-nameがシンボルならobsolete-nameのかわりにcurrent-nameの使用を促す警告メッセージになる。current-nameがobsolete-nameのエイリアスである必要はない。似たような機能をもつ別の関数かもしれない。current-nameには警告メッセージとなる文字列も指定できる。メッセージは小文字で始まりピリオドで終わること。nil
も指定でき、この場合には警告メッセージに追加の詳細は提供されない。
whenが与えられたら、それは最初にその関数が陳腐化する時期を示す文字列 — たとえば日付やリリース番号を指定する。
この便利なマクロは関数obsolete-nameを陳腐化しているとマークして、それを関数current-nameのエイリアスにする。これは以下と等価:
(defalias obsolete-name current-name doc) (make-obsolete obsolete-name current-name when)
加えて陳腐化した関数にたいする特定の呼び出し規約をマークできます。
この関数はfunctionを呼び出す正しい方法として、引数リストsignatureを指定する。これによりEmacs Lispプログラムが他の方法でfunctionを呼び出していたら、Emacsのバイトコンパイラーが警告を発する(それでもコードはバイトコンパイルされる)。whenにはその変数が最初に陳腐化するときを示す文字列(通常はバージョン番号)を指定する。
たとえば古いバージョンのEmacsでは、sit-for
には以下のように3つの引数を指定していた
(sit-for seconds milliseconds nodisp)
しかしこの方法によるsit-for
の呼び出しは陳腐化していると判断される(時間の経過や入力の待機を参照)。以下のように古い呼び出し規約は推奨されない:
(set-advertised-calling-convention 'sit-for '(seconds &optional nodisp) "22.1")
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
インライン関数(inline
function)は関数と同様に機能しますが、1つ例外があります。その関数の呼び出しがバイトコンパイルされると(バイトコンパイルを参照)、その関数の定義が呼び出し側に展開されます。インライン関数を定義するには、defun
のかわりにdefsubst
を使用します。
このマクロはインライン関数を定義する。マクロの構文はdefun
とまったく同じ(関数の定義を参照)。
関数をインラインにすることにより、その関数の呼び出しが高速になる場合があります、が欠点もありその1つは柔軟性の減少です。その関数の定義を変更すると、すでにインライン化された呼び出しは、リコンパイルを行うまで古い定義を使用することになります。
もう1つの欠点は、大きな関数をインライン化することにより、コンパイルされたコードのファイル上およびメモリー上のサイズが増大することです。スピード面でのインライン化の有利性は小さい関数で顕著なので、一般的に大きな関数をインライン化するべきではありません。
インライン関数はデバッグ、トレース、アドバイス(Emacs Lisp関数にたいするアドバイスを参照)に際してうまく機能しません。デバッグの容易さと関数の再定義の柔軟さはEmacsの重要な機能なので、スピードがとても重要であってdefun
の使用が実際に性能の面で問題となるのか検証するためにすでにコードをチューニングしたのでなければ、たとえその関数が小さくてもインライン化するべきではありません。
インライン関数を定義した後そのインライン展開はマクロ同様、同じファイル内の後の部分で処理されます。
defsubst
を使用してインライン関数が実行するのと同じコードに展開されるマクロ(マクロを参照)を定義することは可能です。しかし式内でのマクロの直接の使用には制限があります
—
apply
、mapcar
などでマクロを呼び出すことはできません。通常の関数からマクロへの変換には、そのための余分な作業が必要になります。通常の関数をインライン関数に変換するのは簡単です。defun
をdefsubst
に置き換えるだけです。インライン関数の引数はそれぞれ正確に1回評価されるので、マクロのときのようにbodyで引数を何回使用するか心配する必要はありません。
defsubst
の代替えとして、完全なコンパイラーマクロを通じて関数を定義するdefine-inline
を使用できます、define-inlineを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
declare
フォームdeclare
(宣言)は特別なマクロで、関数やマクロにメタプロパティーを追加するために使用できます。たとえば陳腐化しているとマークしたり、Emacs
Lispモード内の特別なTABインデント規約を与えることができます。
このマクロは引数を無視してnil
として評価されるので、実行時の効果はない。しかしdefun
やdefsubst
(関数の定義を参照)、またはdefmacro
マクロ(マクロの定義を参照)の定義のdeclare引数にdeclare
フォームがある場合は、specsで指定されたプロパティーを関数またはマクロに追加します。これはdefun
、defsubst
、defmacro
により特別に処理される。
specs内の各要素は(property
args…)
というフォームをもつこと。またそれあをクォートしないこと。これらは以下の効果をもつ:
(advertised-calling-convention signature when)
これはset-advertised-calling-convention
(関数を陳腐と宣言するを参照)の呼び出しと同じように振る舞う。signatureにはその関数(またはマクロ)にたいする正しい引数リスト、whenには古い引数リストが最初に陳腐化する時期を示す文字列を指定する。
(debug edebug-form-spec)
これはマクロだけに有効である。Edebugでそのマクロ入ったときに、edebug-form-specを使用する。マクロ呼び出しのインストルメントを参照のこと。
(doc-string n)
自身が関数やマクロ、変数のようなエンティティーを定義するために使用されるような関数やマクロを定義するときにこれが使用される。これはn番目の引数というこを示し、もしそれがあれば、それはドキュメント文字列とみなされる。
(indent indent-spec)
この関数(かマクロ)にたいするインデント呼び出しは、indent-specにしたがう。これは関数でも機能するが、通常はマクロで使用される。マクロのインデントを参照のこと。
(interactive-only value)
その関数のinteractive-only
プロパティにvalueをセットする。The interactive-only propertyを参照のこと。
(obsolete current-name when)
make-obsolete
(関数を陳腐と宣言するを参照)と同様に、関数(かマクロ)が陳腐化しているとマークする。current-nameにはシンボル(かわりにこのシンボルを使うことを促す警告メッセージになる)、文字列(警告メッセージを指定)、またはnil
(警告メッセージには追加の詳細が含まれない)を指定すること。whenにはその関数(かマクロ)が最初に陳腐化する時期を示す文字列を指定すること。
(compiler-macro expander)
これは関数だけに使用でき、最適化関数(optimization
function)としてexpanderを使用するようコンパイラーに告げる。(function
args…)
のようなその関数への呼び出しフォームに出会うと、マクロ展開機能(macro
expander)はargs…と同様のフォームでexpanderを呼び出す。expanderはその関数呼び出しのかわりに使用するための新しい式、または変更されていないフォーム(その関数呼び出しを変更しないことを示す)のどちらかをリターンすることができる。expanderにはシンボルかフォーム(lambda
(arg)
body)
を指定できる。フォームならargは元の関数呼び出し式を保持して、その関数の形式に適う引数を使用することにより、その関数にたいする(評価されていない)引数にアクセスができる。
(gv-expander expander)
expanderがgv-define-expander
と同様、ジェネリック変数としてマクロ(か関数)にたいする呼び出しを処理する関数であることを宣言する。expanderはシンボルかフォーム(lambda
(arg) body)
を指定できる。フォームなら、その関数は追加でそのマクロ(か関数)の引数にアクセスできる。
(gv-setter setter)
setterがジェネリック変数としてマクロ(か関数)にたいする呼び出しを処理する関数であることを宣言する。setterはシンボルかフォームを指定できる。シンボルなら、そのシンボルはgv-define-simple-setter
に渡される。フォームなら(lambda
(arg)
body)
という形式で、その関数は追加でマクロ(か関数)の引数にアクセスでき、それはgv-define-setter
に渡される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
あるファイルをバイトコンパイルするとき、コンパイラーが知らない関数について警告が生成されるときがあります(コンパイラーのエラーを参照)。実際に問題がある場合もありますが、問題となっている関数がそのコードの実行時にロードされる他のファイルで定義されている場合が通常です。たとえば以前はfortran.elをバイトコンパイルすると、以下のような警告が出ていました:
In end of data: fortran.el:2152:1:Warning: the function ‘gud-find-c-expr’ is not known to be defined.
実際のところgud-find-c-expr
はFortranモードが使用するgud-find-expr-function
のローカル値(GUDからのコールバック)の中だけで使用されていて、呼び出されるとGUD関数がロードされます。そのような警告が実際には問題を示さないことを知っているときには、警告を抑制したほうがよいでしょう。そうすれば実際に問題があることを示す新しい警告の識別性が良くなります。declare-function
を使用してこれを行うことができます。
必要なのは問題となっている関数を最初に使用する前にdeclare-function
命令を追加するだけです:
(declare-function gud-find-c-expr "gud.el" nil)
これはgud-find-c-expr
がgud.el(‘.el’は省略可)の中で定義されていることを告げます。コンパイラーは関数がそのファイルでそれが実際に定義されているとみなして、チェックを行いません。
3つ目の引数はオプションでgud-find-c-expr
の引数リストを指定します。この例では引数はありません(nil
と値が未指定なのは異なる)。それ以外なら(file
&optional
overwrite)
のようになります。引数リストを指定する必要はありませんが、指定すればコンパイラーはその呼び出しが宣言と合致するかチェックできます。
バイトコンパイラーにたいして引数arglistを受け取るfunctionが定義されていて、その定義はfileにあるとみなすように告げる。fileonlyが非nil
なら、fileが存在することだけをチェックして実際のfunctionの定義はチェックしないことを意味する。
これらの関数がdeclare-function
が告げる場所で実際に宣言されているかどうかを検証するには、check-declare-file
を使用して1つのソースファイル中のすべてのdeclare-function
呼び出しをチェックするか、check-declare-directory
を使用して特定のディレクトリー配下のすべてのファイルをチェックする。
これらのコマンドは、locate-library
で使用する関数の定義を含むはずのファイルを探す。ファイルが見つからなければ、これらのコマンドはdeclare-function
の呼び出しを含むファイルがあるディレクトリーからの相対ファイル名に、定義ファイル名を展開する。
‘.c’や‘.m’で終わるファイル名を指定することにより、プリミティブ関数を指定することもできる。これが有用なのは特定のシステムだけで定義されるプリミティブを呼び出す場合だけである。ほとんどのプリミティブは常に定義されているので、それらについて警告を受け取ることはありえないはずである。
あるファイルがオプションとして外部のパッケージの関数を使う場合もある。declare-function
命令内のファイル名のプレフィクスを‘ext:’にすると、そのファイルが見つかった場合はチェックして、見つからない場合はエラーとせずにスキップする。
‘check-declare’が理解しない関数定義もいくつか存在する(たとえばdefstruct
やその他いくつかのマクロ)。そのような場合はdeclare-function
のfileonly引数に非nil
を渡すことができる。これはファイルの存在だけをチェックして、その関数の実際の定義はチェックしないことを意味する。これを行うなら引数リストを指定する必要はないが、arglist引数にはt
をセットする必要があることに注意(なぜならnil
は引数リストが指定されなかったという意味ではなく空の引数リストを意味するため)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SESのようないくつかのメジャーモードは、ユーザーファイル内に格納された関数を呼び出します(SESの詳細はSee (ses)Topを参照)。 ユーザーファイルは素性があやふやな場合があります — 初対面の人から受け取ったスプレッドシートかもしれず、会ったことのない誰かから受け取ったeメールかもしれません。そのためユーザーファイルに格納されたソースコードの関数を呼び出すのは、それが安全だと決定されるすまでは危険です。
formが安全(safe)なLisp式ならnil
、危険ならなぜその式が危険かもしれないのか説明するリストをリターンする。引数unsafep-varsは、この時点で一時的なバインドだと判っているシンボルのリスト。これは主に内部的な再帰呼び出しで使用される。カレントバッファーは暗黙の引数になり、これはバッファーローカルなバインディングのリストを提供する。
高速かつシンプルにするために、unsafep
は非常に軽量な分析を行うので、実際には安全な多くのLisp式を拒絶します。安全ではない式にたいしてunsafep
がnil
をリターンするケースは確認されていません。しかし安全なLisp式はdisplay
プロパティーと一緒に文字列をリターンでき、これはその文字列がバッファーに挿入された後に実行される、割り当てられたLisp式を含むことができます。割り当てられた式はウィルスかもしれません。安全であるためにはバッファーへ挿入する前に、ユーザーコードで計算されたすべての文字列からプロパティーを削除しなければなりません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のテーブルは関数呼び出しと関数定義に関連したことを行ういくつかの関数です。これらは別の場所で説明されているので、ここではクロスリファレンスを提供します。
apply
関数の呼び出しを参照のこと。
autoload
autoloadを参照のこと。
call-interactively
interactiveな呼び出しを参照のこと。
called-interactively-p
interactiveな呼び出しの区別を参照のこと。
commandp
interactiveな呼び出しを参照のこと。
documentation
ドキュメント文字列へのアクセスを参照のこと。
eval
evalを参照のこと。
funcall
関数の呼び出しを参照のこと。
function
無名関数を参照のこと。
ignore
関数の呼び出しを参照のこと。
indirect-function
シンボル関数インダイレクションを参照のこと。
interactive
interactive
の使用を参照のこと。
interactive-p
interactiveな呼び出しの区別を参照のこと。
mapatoms
シンボルの作成とinternを参照のこと。
mapcar
関数のマッピングを参照のこと。
map-char-table
文字テーブルを参照のこと。
mapconcat
関数のマッピングを参照のこと。
undefined
キー照合のための関数を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マクロ(macros)により新たな制御構造や、他の言語機能の定義を可能にします。マクロは関数のように定義されますが、値の計算方法を指定するかわりに、値を計算する別のLisp式を計算する方法を指示します。わたしたちはこの式のことをマクロの展開(expansion)と呼んでいます。
マクロは関数が行うように引数の値を処理するのではなく、引数にたいする未評価の式を処理することによって、これを行うことができます。したがってマクロは、これらの引数式かその一部を含む式を構築することができます。
て通常の関数が行えることをマクロを使用して行う場合、単にそれが速度面の理由ならばかわりにインライン関数の使用を考慮してください。インライン関数Inline Functionsを参照してください。
13.1 単純なマクロの例 | 基本的な例。 | |
13.2 マクロ呼び出しの展開 | いつ、なぜ、どのようにマクロが展開されるか。 | |
13.3 マクロとバイトコンパイル | コンパイラーによりマクロが展開される方法。 | |
13.4 マクロの定義 | マクロ定義を記述する方法。 | |
13.5 マクロ使用に関する一般的な問題 | マクロ引数を何回も評価しないこと。ユーザーの変数を隠さないこと。 | |
13.6 マクロのインデント | マクロ呼び出しのインデント方法の指定。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Cの++
演算子のように、変数の値をインクリメントするためのLisp構造を定義したいとしましょう。(inc
x)
のように記述すれば、(setq x (1+ x))
という効果を得たいとします。以下はこれを行うマクロ定義です:
(defmacro inc (var) (list 'setq var (list '1+ var)))
これを(inc x)
のように呼び出すと、引数varはシンボルx
になります —
関数のときのようにx
の値ではありません。このマクロのbodyはこれを展開の構築に使用して、展開形は(setq x
(1+ x))
になります。マクロが一度この展開形をリターンするとLispはそれを評価するので、x
がインクリメントされます。
この述語はその引数がマクロかどうかテストして、もしマクロならt
、それ以外はnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マクロ呼び出しは関数の呼び出しと同じ外観をもち、マクロの名前で始まるリストで表されます。そのリストの残りの要素はマクロの引数になります。
マクロ呼び出しの評価は1つの重大な違いを除いて、関数の評価と同じように開始されます。重要な違いとはそのマクロの引数はマクロ呼び出し内で実際の式として現れます。これらの引数はマクロ定義に与えられる前には評価されません。対象的に関数の引数はその関数の呼び出しリストの要素を評価した結果です。
こうして得た引数を使用して、Lispは関数呼び出しのようにマクロ定義を呼び出します。マクロの引数変数はマクロ呼び出しの引数値にバインドされるか、a
&rest
引数の場合は引数地のリストになります。そしてそのマクロのbodyが実行されて、関数bodyが行うようにマクロbodyの値をリターンします。
マクロと関数の2つ目の重要な違いは、マクロのbodyからリターンされる値が代替となるLisp式であることで、これはマクロの展開(expansion)としても知られています。Lispインタープリターはマクロから展開形が戻されると、すぐにその展開形の評価を行います。
展開形は通常の方法で評価されるので、もしかしたらその展開形は他のマクロの呼び出しを含むかもしれません。一般的ではありませんが、もしかすると同じマクロを呼び出すかもしれません。
EmacsはコンパイルされていないLispファイルをロードするときに、マクロの展開を試みることに注意してください。これは常に利用可能ではありませんが、もし可能ならそれ以降の実行の速度を改善します。プログラムがロードを行う方法を参照してください。
macroexpand
を呼び出すことにより、与えられたマクロ呼び出しにたいする展開形を確認することができます。
この関数はそれがマクロ呼び出しならformを展開する。結果が他のマクロ呼び出しなら、結果がマクロ呼び出しでなくなるまで順番に展開を行う。これがmacroexpand
からリターンされる値になる。formがマクロ呼び出しで開始されなければ、与えられたformをそのままリターンする。
macroexpand
は、(たとえいくつかのマクロ定義がそれを行っているとしても)formの部分式(subexpression)を調べないことに注意。たとえ部分式自身がマクロ呼び出しでも、macroexpand
はそれらを展開しない。
関数macroexpand
はインライン関数の呼び出しを展開しない。なぜならインライン関数の呼び出しは、通常の関数呼び出しと比較して理解が難しい訳ではないので、通常はそれを行う必要がないからである。
environmentが与えられたら、それはそのとき定義されているマクロをシャドーするマクロのalistを指定する。バイトコンパイルではこの機能を使用している。
(defmacro inc (var) (list 'setq var (list '1+ var)))
(macroexpand '(inc r)) ⇒ (setq r (1+ r))
(defmacro inc2 (var1 var2) (list 'progn (list 'inc var1) (list 'inc var2)))
(macroexpand '(inc2 r s))
⇒ (progn (inc r) (inc s)) ; ここではinc
は展開されない
macroexpand-all
はmacroexpand
と同様にマクロを展開するが、ドップレベルだけではなくform内のすべてのマクロを探して展開する。展開されたマクロがなければリターン値はformとeq
になる。
上記macroexpand
で使用した例をmacroexpand-all
に用いると、macroexpand-all
がinc
に埋め込まれた呼び出しの展開を行うことを確認できる
(macroexpand-all '(inc2 r s)) ⇒ (progn (setq r (1+ r)) (setq s (1+ s)))
この関数はmacroexpand
のようにマクロを展開するが、展開の1ステップだけを行う。結果が別のマクロ呼び出しならmacroexpand-1
はそれを展開しない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
なぜわざわざマクロにたいする展開形を計算して、その後に展開形を評価する手間をかけるのか、不思議に思うかもしれません。なぜマクロbodyは直接望ましい結果を生成しないのでしょうか? それはコンパイルする必要があるからです。
コンパイルされるLispプログラム内にマクロ呼び出しがあるとき、Lispコンパイラーはインタープリターが行うようにマクロ定義を呼び出して展開形を受け取ります。しかし展開形を評価するかわりに、コンパイラーは展開形が直接プログラム内にあるかのようにコンパイルを行います。結果としてコンパイルされたコードはそのマクロにたいする値と副作用を生成しますが、実行速度は完全にコンパイルされたときと同じになります。もしマクロbody自身が値と副作用を計算したら、このようには機能しません — コンパイル時に計算されることになり、それは有用ではありません。
マクロ呼び出しのコンパイルが機能するためには、マクロを呼び出すコードがコンパイルされるとき、そのマクロがLisp内ですでに定義されていなければなりません。コンパイラーにはこれを行うのを助ける特別な機能があります。コンパイルされるファイルがdefmacro
フォームを含むなら、そのファイルの残りの部分をコンパイルするためにそのマクロが一時的に定義されます。
ファイルをバイトコンパイルすると、ファイル内のトップレベルにあるすべてのrequire
呼び出しも実行されるので、それらを定義しているファイルをrequireすることにより、コンパイルの間に必要なマクロ定義が利用できることが確実になります(名前つき機能を参照)。誰かがコンパイルされたプログラムを実行するときに、マクロ定義ファイルのロードをしないようにするには、require
呼び出しの周囲にeval-when-compile
を記述します(コンパイル中の評価を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispのマクロオブジェクトは、CARがmacro
でCDRが関数であるようなリストです。マクロの展開形はマクロ呼び出しから、評価されていない引数のリストに、(apply
を使って)関数を適用することにより機能します。
無名関数のように無名Lispマクロを使用することも可能ですが、無名マクロをmapcar
のような関数に渡すことに意味がないので、これが行われることはありません。実際のところすべてのLispマクロは名前をもち、ほとんど常にdefmacro
マクロで定義されます。
defmacro
はシンボルname(クォートはしない)を、以下のようなマクロとして定義する:
(macro lambda args . body)
(このリストのCDRはラムダ式であることに注意。)
このマクロオブジェクトはnameの関数セルに格納される。argsの意味は関数の場合と同じで、キーワード&rest
や&optional
が使用されることもある(引数リストのその他機能を参照)。nameとargsはどちらもクォートされるべきではない。defmacro
のリターン値は未定義。
docが与えられたら、それはマクロのドキュメント文字列を指定する文字列であること。declareが与えられたら、それはマクロのメタデータを指定するdeclare
フォームであること(declare
フォームを参照)。マクロを対話的に呼び出すことはできないので、インタラクティブ宣言をもつことはできないことに注意。
マクロが定数部と非定数部の混合体から構築される巨大なリスト構造を必要とする場合があります。これを簡単に行うためには‘`’構文(バッククォートを参照)を使用します。たとえば:
(defmacro t-becomes-nil (variable) `(if (eq ,variable t) (setq ,variable nil)))
(t-becomes-nil foo) ≡ (if (eq foo t) (setq foo nil))
マクロ定義のbodyには、そのマクロに関する追加のプロパティーを指定するdeclare
フォームを含めることができます。declare
フォームを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マクロ展開が直感に反する結果となることがあり得ます。このセクションでは問題になりやすい重要な結果と、問題を避けるためにしたがうべきルールをいくつか説明します。
13.5.1 タイミング間違い | マクロ内ではなく展開形で作業を行う。 | |
13.5.2 マクロ引数の多重評価 | 展開形は各マクロ引数を一度評価すること。 | |
13.5.3 マクロ展開でのローカル変数 | 展開形でのローカル変数バインディングには特に注意を要する。 | |
13.5.4 展開におけるマクロ引数の評価 | 評価せずに展開形の中に配置すること。 | |
13.5.5 マクロが展開される回数は? | 展開が行われる回数への依存を避ける。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マクロを記述する際のもっとも一般的な問題として、展開形の中ではなくマクロ展開中に早まって実際に何らかの作業を行ってしまうことがあります。たとえば実際のパッケージが以下のマクロ定義をもつとします:
(defmacro my-set-buffer-multibyte (arg) (if (fboundp 'set-buffer-multibyte) (set-buffer-multibyte arg)))
この誤ったマクロ定義は解釈(interpret)されるときは正常に機能しますがコンパイル時に失敗します。このマクロ定義はコンパイル時にset-buffer-multibyte
を呼び出してしまいますが、それは間違っています。その後でコンパイルされたパッケージを実行しても何も行いません。プログラマーが実際に望むのは以下の定義です:
(defmacro my-set-buffer-multibyte (arg) (if (fboundp 'set-buffer-multibyte) `(set-buffer-multibyte ,arg)))
このマクロは、もし適切ならset-buffer-multibyte
の呼び出しに展開され、それはコンパイルされたプログラム実行時に実行されるでしょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マクロを定義する場合、展開形が実行されるときに引数が何回評価されるか注意を払わなければなりません。以下の(繰り返し処理を用意にする)マクロで、この問題を示してみましょう。このマクロでfor-loop構文を記述できます。
(defmacro for (var from init to final do &rest body) "Execute a simple \"for\" loop. For example, (for i from 1 to 10 do (print i))." (list 'let (list (list var init)) (cons 'while (cons (list '<= var final) (append body (list (list 'inc var)))))))
(for i from 1 to 3 do (setq square (* i i)) (princ (format "\n%d %d" i square))) →
(let ((i 1)) (while (<= i 3) (setq square (* i i)) (princ (format "\n%d %d" i square)) (inc i)))
-|1 1 -|2 4 -|3 9 ⇒ nil
マクロ内の引数from
、to
、do
は構文糖(syntactic
sugar)であり完全に無視されます。このアイデアはマクロ呼び出し中で(from
、to
、do
のような)余計な単語をこれらの位置に記述できるようにするというものです。
以下はバッククォートの使用により、より単純化された等価の定義です:
(defmacro for (var from init to final do &rest body) "Execute a simple \"for\" loop. For example, (for i from 1 to 10 do (print i))." `(let ((,var ,init)) (while (<= ,var ,final) ,@body (inc ,var))))
この定義のフォームは両方(バッククォートのあるものとないもの)とも、各繰り返しにおいて毎回finalが評価されるという欠点をもちます。finalが定数のときは問題がありません。しかしこれがより複雑な、たとえば(long-complex-calculation
x)
のようなフォームならば、実行速度は顕著に低下し得ます。finalが副作用をもつなら、複数回実行するとおそらく誤りになります。
うまく設計されたマクロ定義は、繰り返し評価することがそのマクロの意図された目的でない限り、引数を正確に1回評価を行う展開形を生成することで、この問題を避けるためのステップを費やします。以下はfor
マクロの正しい展開形です:
(let ((i 1) (max 3)) (while (<= i max) (setq square (* i i)) (princ (format "%d %d" i square)) (inc i)))
以下はこの展開形を生成するためのマクロ定義です:
(defmacro for (var from init to final do &rest body) "Execute a simple for loop: (for i from 1 to 10 do (print i))." `(let ((,var ,init) (max ,final)) (while (<= ,var max) ,@body (inc ,var))))
残念なことにこの訂正により以下のセクションで説明する、別の問題が発生します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
前のセクションではfor
の定義を、展開形がマクロ引数を正しい回数評価するように訂正しました:
(defmacro for (var from init to final do &rest body) "Execute a simple for loop: (for i from 1 to 10 do (print i))."
`(let ((,var ,init) (max ,final)) (while (<= ,var max) ,@body (inc ,var))))
for
の新しい定義には新たな問題があります。この定義はユーザーが意識していない、max
という名前のローカル変数を導入しています。これは以下の例で示すようなトラブルを招きます:
(let ((max 0)) (for x from 0 to 10 do (let ((this (frob x))) (if (< max this) (setq max this)))))
for
のbody内部のmax
への参照は、max
のユーサーバインディングの参照を意図したものですが、実際にはfor
により作られたバインディングにアクセスします。
これを修正する方法は、max
のかわりにinternされていない(uninterned)シンボルを使用することです(シンボルの作成とinternを参照)。internされていないシンボルは他のシンボルと同じようにバインドして参照することができますが、for
により作成されるので、わたしたちはすでにユーザーのプログラムに存在するはずがないことを知ることができます。これはinternされていないので、プログラムの後続の部分でそれを配置する方法はありません。これはfor
により配置された場所をのぞき、他の場所で配置されることがないのです。以下はこの方法で機能するfor
の定義です:
(defmacro for (var from init to final do &rest body) "Execute a simple for loop: (for i from 1 to 10 do (print i))." (let ((tempvar (make-symbol "max"))) `(let ((,var ,init) (,tempvar ,final)) (while (<= ,var ,tempvar) ,@body (inc ,var)))))
作成されたinternされていないシンボルの名前はmax
で、これを通常のinternされたシンボルmax
のかわりに、式内のその位置に記述します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マクロ定義自体がeval
(evalを参照)の呼び出しなどによりマクロ引数式を評価した場合には別の問題が発生します。その引数がユーザーの変数を参照する場合、ユーザーがマクロ引数と同じ名前で変数を使用しようとした場合に問題となるでしょう。マクロのbody内では、マクロ引数のバインディングはその変数のもっともローカルなバインディングなので、そのフォーム内部の任意の参照はそれを参照するように評価されます。以下は例です:
(defmacro foo (a) (list 'setq (eval a) t))
(setq x 'b) (foo x) → (setq b t) ⇒ t ;b
がセットされる ;; but (setq a 'c) (foo a) → (setq a t) ⇒ t ; しかしc
ではなくa
がセットされる
ユーザーの変数の名前がa
かx
かということで違いが生じています。これはa
がマクロの引数変数a
と競合しているからです。
マクロ定義内でのeval
の呼び出しにまつわる別の問題は、それがおそらくコンパイル時にあなたが意図したことを行わないだろうということです。バイトコンパイラーは、そのプログラム自身の(あなたがeval
でアクセスしたいと望む)計算が発生しない、ローカル変数バインディングも存在しないプログラムのコンパイル時にマクロ定義を実行します。
この問題を避けるためには、マクロ展開形の計算では引数式を評価しないでください。かわりにその式をマクロ展開形の中に置き換えれば、その値は展開形の実行の一部として計算されます。これは、このチャプターの他の例が機能する方法です。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
逐次解釈される関数で毎回マクロ呼び出しが展開されるが、コンパイルされた関数では(コンパイル時の)1回だけしか展開されないという事実にもとづく問題が時折発生します。そのマクロ定義が副作用をもつなら、そのマクロが何回展開されたかによって、それらのマクロは異なる動作をとるでしょう。
したがってあなたが何をしているか本当に判っていないのであれば、マクロ展開形の計算での副作用は避けるべきです。
避けることのできない特殊な副作用が1つあります。それはLispオブジェクトの構築です。ほとんどすべてのマクロ展開形にはリストの構築が含まれます。リスト構築はほとんどのマクロの核心部分です。これは通常は安全です。用心しなければならないケースが1つだけあります。それは構築するオブジェクトがマクロ展開形の中でクォートされた定数の一部となるときです。
そのマクロが1回だけ — コンパイル時 — しか展開されないなら、そのオブジェクトの構築もコンパイル時の1回です。しかし逐次実行では、そのマクロはマクロ呼び出しが実行されるたびに展開され、これは毎回新たなオブジェクトが構築されることを意味します。
クリーンなLispコードのほとんどでは、この違いは問題になりません。しかしマクロ定義によるオブジェクト構築の副作用を処理する場合には、問題になるかもしれません。したがって問題を避けるために、マクロ定義によるオブジェクト構築の副作用を避けてください。以下は副作用により問題が起こる例です:
(defmacro empty-object () (list 'quote (cons nil nil)))
(defun initialize (condition) (let ((object (empty-object))) (if condition (setcar object condition)) object))
initialize
が解釈されると、initialize
が呼び出されるたびに新しいリスト(nil)
が構築されます。したがって各呼び出しの間において副作用は存続しません。しかしinitialize
がコンパイルされると、マクロempty-object
はコンパイル時に展開され、これは1つの定数(nil)
を生成し、この定数はinitialize
の呼び出しの各回で再利用、変更されます。
このような異常な状態を避ける1つの方法は、empty-object
をメモリー割り当て構造ではなく一種の奇妙な変数と考えることです。'(nil)
のような定数にたいしてsetcar
を使うことはないでしょうから、当然(empty-object)
にも使うことはないでしょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マクロ定義ではマクロ呼び出しをTABがどのようにインデントすべきか指定するために、declare
フォーム(マクロの定義を参照)を使うことができます。インデント指定は以下のように記述します:
(declare (indent indent-spec))
このlisp-indent-function
プロパティ内の結果はマクロの名前にセットされます。
以下は利用できるindent-specです:
nil
これはプロパティーを指定しない場合と同じ — 標準的なインデントパターンを使用する。
defun
この関数を‘def’構文 — 2番目の行がbodyの開始 — と同様に扱う。
関数の最初のnumber個の引数は区別され、残りは式のbodyと判断される。その式の中の行は、最初の引数が区別されているかどうかにしたがってインデントされる。引数がbodyの一部なら、その行はこの式の先頭の開カッコ(open-parenthesis)よりもlisp-body-indent
だけ多い列にインデントされる。引数が区別されていて1つ目か2つ目の引数なら、2倍余分にインデントされる。引数が区別されていて1つ目か2つ目以外の引数なら、その行は標準パターンによってインデントされる。
symbolは関数名。この関数はこの式のインデントを計算するために呼び出される関数。この関数は2つの引数をとる:
その行のインデントが開始される位置。
その行の開始まで解析したとき、parse-partial-sexp
(インデントとネスト深さの計算のためのLispプリミティブ)によりリターンされる値。
これは数(その行のインデントの列数)、またはそのような数がcarであるようなリストをリターンすること。数とリストの違いは、数の場合は同じネスト深さの後続のすべての行はこの数と同じインデントとなる。リストなら、後続の行は異なるインデントを呼び出すかもしれない。これはC-M-qによりインデントが計算されるときに違いが生じる。値が数ならC-M-qはリストの終わりまでの後続の行のインデントを再計算する必要はない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
EmacsのユーザーはCustomizeインターフェースにより、Lispコードを記述することなく変数とフェースをカスタマイズできます。Easy Customization in The GNU Emacs Manualを参照してください。このチャプターではCustomizeインターフェースを通じて、ユーザーとやりとりするためのカスタマイズアイテム(customization items)を定義する方法を説明します。
カスタマイズアイテムにはdefcustom
マクロ
で定義されるカスタマイズ可能変数
defface
(フェイスの定義で個別に説明)で定義されるカスタマイズ可能フェイス、およびdefgroup
で定義される
カスタマイゼーショングループ(customization
groups)が含まれ、これは関連するカスタマイゼーションアイテムのコンテナとして振る舞います。
14.1 一般的なキーワードアイテム | すべての種類のカスタマイゼーション宣言に共通なキーワード引数。 | |
14.2 カスタマイゼーショングループの定義 | カスタマイゼーショングループ定義の記述。 | |
14.3 カスタマイゼーション変数の定義 | ユーザーオプションの宣言。 | |
14.4 カスタマイゼーション型 | ユーザーオプションの型指定。 | |
14.5 カスタマイゼーションの適用 | カスタマイゼーションセッティングを適用する関数。 | |
14.6 Customテーマ | Customテーマの記述。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以降のセクションで説明するカスタマイゼーション宣言(customization declaration) —
defcustom
、defgroup
などはすべてさまざまな情報を指定するためのキーワード引数(Variables that Never Changeを参照)を受け取ります。このセクションではカスタマイゼーション宣言のすべての種類に適用されるキーワードを説明します。
:tag
以外のすべてのキーワードは、与えられたアイテムにたいして複数回使用できます。キーワードの使用はそれぞれ独立した効果をもちます。例外は:tag
で、これはすべての与えられたアイテムは1つの名前だけを表示できるからです。
:tag label
labelを使用すると、カスタマイゼーションメニュー(customization menu)とカスタマイゼーションバッファー(customization buffer)のアイテムのラベルづけに、そのアイテムの名前のかわりに指定された文字列を使用します。混乱を招くのでそのアイテムの実際の名前と大きく異なる名前は使用しないでください。
:group group
このカスタマイゼーションアイテムをグループgroupにputする。カスタマイゼーションアイテムからこのキーワードが欠落していると、アイテムは最後に定義された同じグループ内に配置されるだろう。
defgroup
内で:group
を使用すると、そのアイテムは新しいグループ(:group
のサブグループ)になる。
このキーワードを複数回使用すると、1つのアイテムを複数のグループに配置することができる。それらのグループのいずれかを表示すると、このアイテムが表示される。煩雑になるので多用しないこと。
:link link-data
このアイテムのドキュメント文字列の後に外部リンクを含める。これは他のドキュメントを参照するセンテンスを含んだボタンである。
link-dataに使用できる複数の選択肢がある:
(custom-manual info-node)
infoノードへのリンク。info-nodeは"(emacs)Top"
のような、ノード名を示す文字列である。このリンクはカスタマイゼーションバッファーの‘[Manual]’に表示され、info-nodeにたいしてビルトインのinfoリーダーを起動する。
(info-link info-node)
custom-manual
と同様だが、カスタマイゼーションバッファーにはそのinfoノード名が表示される。
(url-link url)
ウェブページヘのリンク。urlはURLを指定する文字列である。カスタマイゼーションバッファーに表示されるリンクはbrowse-url-browser-function
で指定されたWWWブラウザーを呼び出す。
(emacs-commentary-link library)
ライブラリーのコメントセクション(commentary section)へのリンク。libraryはライブラリー名を指定する文字列である。Emacsライブラリーのヘッダーの慣習を参照のこと。
(emacs-library-link library)
Emacs Lispライブラリーファイルへのリンク。libraryはライブラリー名を指定する文字列である。
(file-link file)
ファイルへのリンク。fileはユーザーがこのリンクを呼び出したときにfind-file
でvisitするファイルの名前を指定する文字列である。
(function-link function)
関数のドキュメントへのリンク。functionはユーザーがこのリンクを呼び出したときにdescribe-function
で説明を表示する関数の名前を指定する文字列である。
(variable-link variable)
変数のドキュメントへのリンク。variableはユーザーがこのリンクを呼び出したときにdescribe-variable
で説明を表示する変数の名前を指定する文字列である。
(custom-group-link group)
他のカスタマイゼーショングループへのリンク。このリンクを呼び出すことによりgroupにたいする新たなカスタマイゼーションバッファーが作成される。
link-dataの1つ目の要素の後に:tag
name
を追加することにより、カスタマイゼーションバッファーで使用するテキストを指定できます。たとえば(info-link
:tag "foo" "(emacs)Top")
は、そのバッファーで‘foo’と表示されるEmacs manualへのリンクを作成します。
複数のリンクを追加するために、このキーワードを複数回使用することができます。
:load file
そのカスタマイゼーションアイテムを表示する前にファイルfileをロードする(ロードを参照)。ロードはload
により行われ、そのファイルがまだロードされていないときだけロードを行う。
:require feature
保存したカスタマイゼーションがこのアイテム値をセットするとき、(require
'feature)
が実行される。featureはシンボル。
:require
を使用するもっとも一般的な理由は、ある変数がマイナーモードのような機能を有効にするとき、そのモードを実装するコードがロードされていなければ、変数のセットだけでは効果がないからである。
:version version
このキーワードはそのアイテムが最初に導入されたEmacsバージョンversionか、そのアイテムのデフォルト値がそのバージョンで変更されたことを指定する。値versionは文字列でなければならない。
:package-version '(package . version)
このキーワードはそのアイテムが最初に導入されたpackageのバージョンversionか、アイテムの意味(またはデフォルト値)が変更されたバージョンを指定する。このキーワードは:version
より優先される。
packageにはそのパッケージの公式名をシンボルとして指定すること(たとえばMH-E
)。versionには文字列であること。パッケージpackageがEmacsの一部としてリリースされたなら、packageとversionの値はcustomize-package-emacs-version-alist
の値に表示されるはずである。
Emacsの一部として配布された:package-version
キーワードを使用するパッケージは、customize-package-emacs-version-alist
変数も更新しなければなりません。
これは:package-version
キーワード内でリストされたパッケージのバージョンに関連付けられたEmacsのバージョンにたいして、マッピングを提供するalistである。このalistの要素は:
(package (pversion . eversion)…)
それぞれのpackage(シンボル)にたいして、パッケージバージョンpversionを含む1つ以上の要素と、それに関連付けられるEmacsバージョンeversionが存在する。これらのバージョンは文字列である。たとえばMH-Eパッケージは以下によりalistを更新する:
(add-to-list 'customize-package-emacs-version-alist '(MH-E ("6.0" . "22.1") ("6.1" . "22.1") ("7.0" . "22.1") ("7.1" . "22.1") ("7.2" . "22.1") ("7.3" . "22.1") ("7.4" . "22.1") ("8.0" . "22.1")))
packageの値は一意である必要があり、:package-version
キーワード内に現れるpackageの値とマッチする必要がある。おそらくユーザーはエラーメッセージからこの値を確認するので、MH-EやGnusのようなパッケージの公式名を選択するのがよいだろう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispパッケージはそれぞれ、1つのメインのカスタマイゼーショングループ(main customization group)をもち、それにはすべてのオプションとフェイス、そのパッケージ内の他のグループが含まれるべきです。そのパッケージに少数のオプションとフェイスしかなければ、1つのグループだけを使用してその中にすべてを配置します。20以上のオプションやフェイスがあるなら、それらをサブグループ内に構造化して、そのサブグループをメインのカスタマイゼーショングループの下に配置します。そのパッケージ内の任意のオプションやフェイスを、サブグループと並行してメイングループに配置しても問題はありません。
そのパッケージのメイングループ(または唯一のグループ)は、1つ以上の標準カスタマイゼーショングループ(standard customization
group)のメンバーであるべきです(これらの完全なリストを表示するにはM-x
customizeを使用する)。それらの内から1つ以上(多すぎないこと)を選択して、:group
を使用してあなたのグループをそれらに追加します。
新しいカスタマイゼーショングループはdefgroup
で宣言します。
membersを含むカスタマイゼーショングループとしてgroupを宣言する。シンボルgroupはクォートしない。引数docはそのグループにたいするドキュメント文字列を指定する。
引数membersはそのグループのメンバーとなるカスタマイゼーションアイテムの初期セットを指定するリストである。しかしほとんどの場合はmembersをnil
にして、メンバーを定義するときに:group
キーワードを使用することによってそのグループのメンバーを指定する。
membersを通じてグループのメンバーを指定したければ、要素はそれぞれ(name
widget)
という形式で指定すること。ここでnameはシンボル、widgetはそのシンボルを編集するウィジェット型(widget
type)である。変数にはcustom-variable
、フェイスにはるcustom-face
、グループにはcustom-group
が有用なウィジェットである。
Emacsに新しいグループを導入するときはdefgroup
内で:version
キーワードを使用する。そうすればグループの個別のメンバーにたいしてそれを使用する必要がなくなる。
一般的なキーワード(一般的なキーワードアイテムを参照)に加えて、defgroup
内では以下のキーワードも使用できる:
:prefix prefix
グループ内のアイテムの名前がprefixで始まり、カスタマイズ変数custom-unlispify-remove-prefixes
が非nil
なら、そのアイテムのタグからprefixが省略される。グループは任意の数のプレフィクスをもつことができる。
この変数が非nil
ならグループの:prefix
キーワードで指定されたプレフィクスは、ユーザーがグループをカスタマイズするときは常にタグ名から省略される。
デフォルト値はnil
、つまりプレフィクス省略(prefix-discarding)の機能は無効となる。これはオプションやフェイスの名前にたいするプレフィクスの省略が混乱を招くことがあるからである。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
カスタマイズ可能変数(customizable variable)はユーザーオプション(user
option)とも呼ばれ、これはCustomizeインターフェースを通じてセットできるグローバルなLisp変数です。defvar
(グローバル変数の定義を参照)デ定義される他のグローバル変数と異なり、カスタマイズ可能変数はdefcustom
マクロを使用して定義されます。サブルーチンとしてdefvar
を呼び出すことに加えテ、defcustom
はCustomizeインターフェースでその変数が表示される方法や、その変数がとることができる値などを明示します。
このマクロはユーザーオプション(かカスタマイズ可能変数)としてoptionを宣言する。optionはクォートしないこと。
引数standardはoptionの標準値を指定する式である。defcustom
フォームの評価によりstandardが評価されるが、その値にそのオプションをバインドする必要はない。optionがすでにデフォルト値をもつなら、それは変更されずに残る。ユーザーがすでにoptionにたいするカスタマイゼーションを保存していれば、ユーザーによりカスタマイズされた値がデフォルト値としてインストールされる。それ以外ならstandardを評価した結果がデフォルト値としてインストールされる。
defvar
と同様、このマクロはoption
をスペシャル変数 — 常にダイナミックにバインドされることを意味する —
としてマークする。optionがすでにレキシカルバインドをもつなら、そのレキシカルバインドはバインディング構文を抜けるまで効果をもつ。変数のバインディングのスコーピングルールを参照のこと。
式standardは別の様々な機会 — カスタマイゼーション機能がoptionの標準値を知る必要があるときは常に — にも評価される可能性がある。そのため任意回数の評価を行ても安全な式を使用するように留意されたい。
引数docはその変数にたいするドキュメント文字列を指定する。
defcustom
が何も:group
を指定しなければ、同じファイル内でdefgroup
によって最後に定義されたグループが使用される。この方法ではほとんどのdefcustom
は明示的な:group
が不必要になる。
Emacs
LispモードでC-M-x(eval-defun
)でdefcustom
フォームを評価するとき、eval-defun
の特別な機能は変数の値がvoidかどうかテストせずに、無条件に変数をセットするよう段取りする(同じ機能はdefvar
にも適用される。グローバル変数の定義を参照)。すでに定義されたdefcustomでeval-defun
を使用することにより、(もしあれば):set
関数(以下参照)が呼び出される。
事前ロード(pre-loaded)されたEmacs Lispファイル(Emacsのビルドを参照)にdefcustom
を配置すると、ダンプ時にインストールされた標準値は正しくない —
たとえば依存している他の変数がまだ正しい値を割り当てられていない
— かもしれない。この場合はEmacs起動後に標準値を再評価するために、以下で説明するcustom-reevaluate-setting
を使用する。
一般的なキーワードアイテムにリストされたキーワードに加えて、このマクロには以下のキーワードを指定できる
:type type
このオプションのデータ型としてtypeを使用する。これはどんな値が適正なのか、その値をどのように表示するかを指定する(カスタマイゼーション型を参照)。defcustom
はそれぞれこのキーワードにたいする値を指定すること。
:options value-list
このオプションに使用する適正な値のリストを指定する。ユーザーが使用できる値はこれらの値に限定されないが、これらは便利な値の選択肢を提示する。
これは特定の型にたいしてのみ意味をもち現在のところhook
、plist
、alist
が含まれる。:options
を使用する方法は個別の型の定義を参照のこと。
:set setfunction
Customizeインターフェースを使用してこのオプションの値を変更する方法としてsetfunctionを指定する。関数setfunctionは2つの引数
— シンボル(オプション名)と新しい値 —
を受け取り、このオプションにたいして正しく値を更新するために必要なことは何であれ行うこと(これはおそらくLisp変数として単にオプションをセットすることを意味しない)。この関数は引数の値を破壊的に変更しないことが望ましい。setfunctionのデフォルトはset-default
。
このキーワードを指定すると、その変数のドキュメント文字列には手入力のLispコードで同じことを行う方法が記載されること。
:get getfunction
このオプションの値を抽出する方法としてgetfunctionを指定する。関数getfunctionは1つの引数(シンボル)を受け取り、カスタマイズがそのシンボル(シンボルのLisp値である必要はない)にたいするカレント値としてそれを使うべきかどうかをリターンすること。デフォルトはdefault-value
。
:get
を正しく使用するためには、Customの機能を真に理解する必要がある。これは変数としてCustom内で扱われる値のためのものだが、実際にはLisp変数には格納されない。実際にLisp変数に格納されている値にgetfunctionを指定するのは、ほとんどの場合は誤りである。
:initialize function
functionはdefcustom
が評価されるときに変数を初期化するために使用される関数であること。これは2つの引数 —
オプション名(シンボル)と値を受け取る。この方法での使用のために事前定義された関数がいくつかある:
custom-initialize-set
変数の初期化にその変数の:set
関数を使用するが、値がすでに非voidなら再初期化を行わない。
custom-initialize-default
custom-initialize-set
と同様だが、その変数の:set
のかわりに関数set-default
を使用して変数をセットする。これは変数の:set
関数がマイナーモードを有効または無効にする場合の通常の選択である。この選択により変数の定義ではマイナーモード関数を呼び出しは行わないが、変数をカスタマイズしたときはマイナーモード関数を呼び出すだろう。
custom-initialize-reset
変数の初期化に常に:set
関数を使用する。変数がすでに非voidなら、(:get
メソッドでリターンされる)カレント値を使用して:set
関数を呼び出して変数をリセットする。これはデフォルトの:initialize
関数である。
custom-initialize-changed
変数がすでにセットされている、またはカスタマイズされているなら、変数の初期化のために:set
関数を使用して、それ以外なら単にset-default
を使用する。
custom-initialize-safe-set
custom-initialize-safe-default
これらのn関数はcustom-initialize-set
、custom-initialize-default
と同様に振る舞うがエラーをcatchする。初期化中にエラーが発生したら、set-default
を使用して変数をnil
にセットして、エラーのシグナルはしない。
これらの関数は事前ロードされたファイルで定義されたオプションのためのものである(requireされた変数や関数がまだ定義されていないため、standard式はエラーをシグナルするかもしれない)。その値は通常はstartup.elで更新され、defcustom
により計算された値は無視される。startup後にその値をunsetしてdefcustom
を再評価すれば、エラーなしでstandardは評価される。
:risky value
その変数のrisky-local-variable
プロパティーをvalueにセットする(ファイルローカル変数を参照)。
:safe function
その変数のsafe-local-variable
プロパティーをfunctionにセットします(ファイルローカル変数を参照)。
:set-after variables
保存されたカスタマイゼーションに合わせて変数をセッティングするときは、その前に変数variables確実にセット —
つまりこれら他のものが処理される後までセッティングを遅延 —
すること。これら他の変数が意図された値をもっていない場合に、この変数のセッティングが正しく機能しなければ:set-after
を使用すること。
特定の機能をオンに切り替えるオプションにたいしては、:require
キーワードを指定すると便利です。これはその機能がまだロードされていないときは、そのオプションがセットされるとEmacsがその機能をロードするようにします。一般的なキーワードアイテムを参照してください。以下はライブラリーsaveplace.elの例です:
(defcustom save-place nil "Non-nil means automatically save place in each file..." :type 'boolean :require 'saveplace :group 'save-place)
あるカスタマイゼーションアイテムが:options
がサポートするhook
やalist
のような型をもつなら、custom-add-frequent-value
を呼び出すことによってdefcustom
宣言の外部から別途値を追加できます。たとえばemacs-lisp-mode-hook
から呼び出されることを意図した関数my-lisp-mode-initialization
を定義する場合は、emacs-lisp-mode-hook
にたいする正当な値として、その定義を編集することなくその関数をリストに追加したいと思うかもしれません。これは以下のようにして行うことができます:
(custom-add-frequent-value 'emacs-lisp-mode-hook 'my-lisp-mode-initialization)
カスタマイズオプションsymbolにたいして正当な値のリストにvalueを追加する。
追加による正確な効果はsymbolのカスタマイズ型に依存する。
defcustom
は内部的に、標準値にたいする式の記録にシンボルプロパティstandard-value
、カスタマイゼーションバッファーでユーザーが保存した値の記録にsaved-value
、カスタマイゼーションバッファーでユーザーがセットして未保存の値の記録にcustomized-value
を使用します。シンボルのプロパティを参照してください。これらのプロパティは、carがその値を評価する式であるようなリストです。
この関数はdefcustom
を通じて宣言されたユーザーオプションsymbolの標準値を再評価する。変数がカスタマイズされたなら、この関数はかわりに保存された値を再評価する。それからこの関数はその値に、(もし定義されていればそのオプションの:set
プロパティーを使用して)ユーザーオプションをセットする。
これは値が正しく計算される前に定義されたカスタマイズ可能オプションにたいして有用である。たとえばstartupの間、Emacsは事前ロードされたEmacs Lispファイルで定義されたユーザーオプションにたいしてこの関数を呼び出すが、これらの初期値は実行時だけ利用可能な情報に依存する。
この関数はargがカスタマイズ可能変数なら非nil
をリターンする。カスタマイズ可能変数とは、standard-value
かcustom-autoload
プロパティーをもつ(通常はdefcustom
で宣言されたことを意味する)変数、または別のカスタマイズ可能変数にたいするエイリアスのことである。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
defcustom
でユーザーオプションを定義するときは、ユーザーオプションのカスタマイゼーション型(customization
type)を指定しなければなりません。これは(1)どの値が適正か、および(2)編集のためにカスタマイゼーションバッファーで値を表示する方法を記述するLispオブジェクトです。
カスタマイゼーション型はdefcustom
内の:type
キーワードで指定します。:type
の引数は評価されますが、defcustom
が実行されるときに1回だけ評価されるので、さまざまな値をとる場合には有用でありません。通常はクォートされた定数を使用します。たとえば:
(defcustom diff-command "diff" "The command to use to run diff." :type '(string) :group 'diff)
一般的にカスタマイゼーション型は最初の要素が以降のセクションで定義されるカスタマイゼーション型の1つであるようなリストです。このシンボルの後にいくつかの引数があり、それはそのシンボルに依存します。型シンボルと引数の間にはオプションでkeyword-valueペアー(型キーワードを参照)を記述できます。
いくつかの型シンボルは引数を使用しません。これらはシンプル型(simple
types)と呼ばれます。シンプル型ではkeyword-valueペアーを使用しないなら、型シンボルの周囲のカッコ(parentheses)を省略できます。たとえばカスタマイゼーション型として単にstring
と記述すると、それは(string)
と等価です。
すべてのカスタマイゼーション型はウィジェットとして実装されます。詳細は、Introduction in The Emacs Widget Libraryを参照してください。
14.4.1 単純型 | シンプルなカスタマイゼーション型(sexp、integerなど)。 | |
14.4.2 複合型 | 他の型やデータから新しい型を構築する。 | |
14.4.3 リストへのスプライス | :inline で要素をリストに結合する。
| |
14.4.4 型キーワード | カスタマイゼーション型でのキーワード/引数ペアー | |
14.4.5 新たな型の定義 | 型に名前をつける。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではすべてのシンプルデータ型を説明します。これらのカスタマイゼーション型のうちのいくつかにたいして、カスタマイゼーションウィジェットはC-M-iかM-TABによるインライン補完を提供します。
sexp
値はプリントと読み込みができる任意のLispオブジェクト。より特化した型を使用するために時間をとりたくなければ、すべてのオプションにたいするフォールバックとしてsexp
を使用することができる。
integer
値は整数でなければならない。
number
値は数(浮動小数点数か整数)でなければならない。
float
値は浮動小数点数でなければならない。
string
値は文字列でなければならない。カスタマイゼーションバッファーはその文字列を区切り文字‘"’文字と‘\’クォートなしで表示する。
regexp
string
文字と同様だがその文字列は有効な正規表現でなければならない。
character
値は文字コードでなければならない。文字コードは実際には整数だが、この型は数字を表示せずにバッファー内にその文字を挿入することにより値を表示する。
file
値はファイル名でなければならない。ウィジェットは補完を提供する。
(file :must-match t)
値は既存のファイル名でなければならない。ウィジェットは補完を提供する。
directory
値はディレクトリー名でなければならない。ウィジェットは補完を提供する。
hook
値は関数のリストでなければならない。このカスタマイゼーション型はフック変数にたいして使用される。フック内で使用を推奨される関数のリストを指定するために、フック変数のdefcustom
内で:options
キーワードを使用できる。カスタマイゼーション変数の定義を参照のこと。
symbol
値はシンボルでなければならない。これはカスタマイゼーションバッファー内でシンボル名として表示される。ウィジェットは補完を提供する。
function
値はラムダ式か関数名でなければならない。ウィジェットは関数名にたいする補完を提供する。
variable
値は変数名でなければならない。ウィジェットは補完を提供する。
face
値はフェイス名のシンボルでなければならない。ウィジェットは補完を提供する。
boolean
値は真偽値 —
nil
かt
である。choice
とconst
を合わせて使用することにより(次のセクションを参照)、値はnil
かt
でなければならないが、それら選択肢に固有の意味に適合する方法でそれぞれの値を説明するテキストを指定することもできる。
key-sequence
値はキーシーケンス。カスタマイゼーションバッファーはkbd関数と同じ構文を使用してキーシーケンスを表示する。キーシーケンスを参照のこと。
coding-system
値はコーディングシステム名でなければならず、M-TABで補完することができる。
color
値は有効なカラー名でなければならない。ウィジェットはカラー名にたいする補完と、同様に*Colors*バッファーに表示されるカラーサンプルとカラー名のリストからカラー名を選択するボタンを提供する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
適切なシンプル型がなければ複合型(composite types)を使用することができます。複合型は特定のデータにより、他の型から新しい型を構築します。指定された型やデータは、その複合型の引数(argument)と呼ばれます。複合型は通常は以下のようなものです:
(constructor arguments…)
しかし以下のように引数の前にkeyword-valueペアーを追加することもできます。
(constructor {keyword value}… arguments…)
以下のテーブルに、コンストラクター(constructor)と複合型を記述するためにそれらを使用する方法を示します:
(cons car-type cdr-type)
値はコンスセルでなければならずCARはcar-type、CDRはcdr-typeに適合していなければならない。たとえば(cons
string symbol)
は、("foo" . foo)
のような値にマッチするデータ型となる。
カスタマイゼーションバッファーでは、CARとCDRはそれぞれ特定のデータ型に応じて個別に表示と編集が行われる。
(list element-types…)
値はelement-typesで与えられる要素と数が正確に一致するリストでなければならず、リストの各要素はそれぞれ対応するelement-typeに適合しなければならない。
たとえば(list integer string
function)
は3つの要素のリストを示し、1つ目の要素は整数、2つ目の要素は文字列、3つ目の要素は関数である。
カスタマイゼーションバッファーでは、各要素はそれぞれ特定のデータ型に応じて個別に表示と編集が行われる。
(group element-types…)
これはlist
と似ているが、Customバッファー内でのテキストのフォーマットが異なる。list
は各要素の値をそのタグでラベルづけするが、group
はそれを行わない。
(vector element-types…)
これはlist
と似ているが、リストではなくベクターでなければならない。各要素はlist
の場合と同様に機能する。
(alist :key-type key-type :value-type value-type)
値はコンスセルのリストでなければならず、各セルのCARはカスタマイゼーション型key-typeのキーを表し、同じセルのCDRはカスタマイゼーション型value-typeの値を表す。ユーザーはkey/valueペアーの追加や削除ができ、各ペアのキーと値の両方を編集することができる。
省略された場合のkey-typeとvalue-typeのデフォルトはsexp
。
ユーザーは指定されたkey-typeにマッチする任意のキーを追加できるが、:options
(カスタマイゼーション変数の定義を参照)で指定することにより、あるキーを優先的に扱うことができる。指定されたキーは、(適切な値とともに)常にカスタマイゼーションバッファーに表示される。またalistにkey/valueを含めるか、除外するか、それとも無効にするかを指定するチェックボックスも一緒に表示される。ユーザーは:options
キーワード引数で指定された値を変更できない。
:options
キーワードにたいする引数は、alist内の適切なキーにたいする仕様のリストであること。これらは通常は単純なアトムであり、それらは自身を意味します。たとえば:
:options '("foo" "bar" "baz")
これは名前が"foo"
、"bar"
、"baz"
であるような3つの既知のキーがあることを指定し、それらは常に最初に表示される。
たとえば"bar"
キーに対応する値を整数だけにするというように、特定のキーに対して値の型を制限したいときがあるかもしれない。これはリスト内でアトムのかわりにリストを使用することにより指定することができる。前述のように1つ目の要素はそのキー、2つ目の要素は値の型を指定する。たとえば:
:options '("foo" ("bar" integer) "baz")
最後にキーが表示される方法を変更したいときもあるだろう。デフォルトでは:options
キーワードで指定された特別なキーはユーザーが変更できないので、キーは単にconst
として表示される。しかしたとえばそれが関数バインディングをもつシンボルであることが既知なら、function-item
のようにあるキーの表示のためにより特化した型を使用したいと思うかもしれない。これはキーにたいしてシンボルを使うかわりに、カスタマイゼーション型指定を使用することにより行うことができる。
:options '("foo" ((function-item some-function) integer) "baz")
多くのalistはコンスセルのかわりに2要素のリストを使用する。たとえば、
(defcustom cons-alist '(("foo" . 1) ("bar" . 2) ("baz" . 3)) "Each element is a cons-cell (KEY . VALUE).")
のかわりに以下を使用する
(defcustom list-alist '(("foo" 1) ("bar" 2) ("baz" 3)) "Each element is a list of the form (KEY VALUE).")
リストはコンスセルの最上位に実装されているため、上記のlist-alist
をコンスセルのalist(値の型が実際の値を含む1要素のリスト)として扱うことができる。
(defcustom list-alist '(("foo" 1) ("bar" 2) ("baz" 3)) "Each element is a list of the form (KEY VALUE)." :type '(alist :value-type (group integer)))
list
のかわりにgroup
を使用するのは、それが目的に適したフォーマットだという理由だけである。
同様に以下のようなトリックの類を用いることにより、より多くの値が各キー連づけられたalistを得ることができる:
(defcustom person-data '(("brian" 50 t) ("dorith" 55 nil) ("ken" 52 t)) "Alist of basic info about people. Each element has the form (NAME AGE MALE-FLAG)." :type '(alist :value-type (group integer boolean)))
(plist :key-type key-type :value-type value-type)
このカスタマイゼーション型はalist
(上記参照)と似ているが、(1)情報がプロパティーリスト(プロパティリストを参照)に格納されていて、(2)key-typeが省略された場合のデフォルトはsexp
ではなくsymbol
になる。
(choice alternative-types…)
値はalternative-typesのうちのいずれかに適合しなければならない。たとえば(choice integer
string)
では整数か文字列が許容される。
カスタマイゼーションバッファーでは、ユーザーはメニューを使用して候補を選択して、それらの候補にたいして通常の方法で値を編集できる。
通常はこの選択からメニューの文字列が自動的に決定される。しかし候補の中に:tag
キーワードを含めることにより、メニューにたいして異なる文字列を指定できる。たとえば空白の数を意味する整数と、その通りに使用したいテキストにたいする文字列なら、以下のような方法でカスタマイゼーション型を記述したいと思うかもしれない
(choice (integer :tag "Number of spaces") (string :tag "Literal text"))
この場合のメニューは‘Number of spaces’と‘Literal text’を提示する。
const
以外のnil
が有効な値ではない選択肢には、:value
キーワードを使用して有効なデフォルト値を指定すること。型キーワードを参照のこと。
複数の候補によりいくつかの値が提供されるなら、カスタマイズは適合する値をもつ最初の候補を選択する。これは常にもっとも特有な型が最初で、もっとも一般的な型が最後にリストされるべきことを意味する。以下は適切な使い方の例である
(choice (const :tag "Off" nil) symbol (sexp :tag "Other"))
この使い方では特別な値nil
はその他のシンボルとは別に扱われ、シンボルは他のLisp式とは別に扱われる。
(radio element-types…)
これはchoice
と似ているが、選択はメニューではなくラジオボタンで表示される。これは該当する選択にたいしてドキュメントを表示できる利点があるので、関数定数(function-item
カスタマイゼーション型)の選択に適している場合がある。
(const value)
値はvalueでなければならず他は許容されない。
const
は主にchoice
の中で使用される。たとえば(choice integer (const
nil))
では整数かnil
が選択できる。
choice
の中では:tag
とともにconst
が使用される場合がある。たとえば、
(choice (const :tag "Yes" t) (const :tag "No" nil) (const :tag "Ask" foo))
これはt
がyes、nil
がno、foo
が“ask”を意味することを示す。
(other value)
この選択肢は任意のLisp値にマッチできるが、ユーザーがこの選択肢を選択したら値valueが選択される。
other
は主にchoice
の最後の要素に使用される。たとえば、
(choice (const :tag "Yes" t) (const :tag "No" nil) (other :tag "Ask" foo))
これはt
がyes、nil
がno、それ以外は“ask”を意味することを示す。ユーザーが選択肢メニューから‘Ask’を選択したら、値foo
が指定される。しかしその他の値(t
、nil
、foo
を除く)ならfoo
と同様に‘Ask’が表示される。
(function-item function)
const
と同様だが値が関数のときに使用される。これはドキュメント文字列も関数名と同じように表示する。ドキュメント文字列は:doc
で指定した文字列かfunction自身のドキュメント文字列。
(variable-item variable)
const
と同様だが値が変数名のときに使用される。これはドキュメント文字列も変数名と同じように表示する。ドキュメント文字列は:doc
で指定した文字列かvariable自身のドキュメント文字列。
(set types…)
値はリストでなければならず指定されたtypesのいずれかにマッチしなければならない。
これはカスタマイゼーションバッファーではチェックリストとして表示されるので、typesはそれぞれ対応する要素を1つ、あるいは要素をもたない。同じ1つのtypesにマッチするような、異なる2つの要素を指定することはできない。たとえば(set
integer
symbol)
はリスト内で1つの整数、および/または1つのシンボルが許容されて、複数の整数や複数のシンボルは許容されない。結果としてset
内でinteger
のような特化していない型を使用するのは稀である。
以下のようにconst
型はset
内のtypesでよく使用される:
(set (const :bold) (const :italic))
alist内で利用できる要素を示すために使用されることもある:
(set (cons :tag "Height" (const height) integer) (cons :tag "Width" (const width) integer))
これによりユーザーにオプションでheightとwidthの値を指定させることができる。
(repeat element-type)
値はリストでなければならず、リストの各要素は型element-typeに適合しなければならない。カスタマイゼーションバッファーでは要素のリストとして表示され、‘[INS]’と‘[DEL]’ボタンで要素の追加や削除が行われる。
(restricted-sexp :match-alternatives criteria)
これはもっとも汎用的な複合型の構築方法である。値はcriteriaを満足する任意のLispオブジェクト。criteriaはリストで、リストの各要素は以下のうちのいずれかを満たす必要がある:
nil
か非nil
のどちらかをリターンする関数。リスト内での述語の使用によりその述語が非nil
をリターンするようなオブジェクトが許されることを意味する。
'object
。リスト内でこの要素はobject自身が許容される値であることを示す。
たとえば、
(restricted-sexp :match-alternatives (integerp 't 'nil))
これは整数、t
、nil
を正当な値として受け入れる。
カスタマイゼーションバッファーは適切な値をそれらの入力構文de表示して、ユーザーはこれらをテキストとして編集できる。
以下は複合型でキーワード/値ペアーとして使用できるキーワードのテーブルです:
:tag tag
tagはユーザーとのコミュニケーションのために、その候補の名前として使用される。choice
内に出現する型にたいして有用。
:match-alternatives criteria
criteriaは可能な値とのマッチに使用される。restricted-sexp
内でのみ有用。
:args argument-list
型構築の引数としてargument-listの要素を使用する。たとえば(const :args
(foo))
は(const
foo)
と等価である。明示的に:args
と記述する必要があるのは稀である。なぜなら最後のキーワード/値ペアーの後に続くものは何であれ、引数として認識されるからである。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
:inline
機能により可変個の要素を、カスタマイゼーション型のlist
やvector
の途中にスプライス(splice:
継ぎ足す)することができます。list
やvector
記述を含む型にたいして:inline
t
を追加することによってこれを使用します。
list
やvector
型の仕様は、通常は単一の要素型を表します。しかしエントリーが:inline
t
を含むなら、マッチする値は含まれるシーケンスに直接マージされます。たとえばエントリーが3要素のリストにマッチするなら、全体が3要素のシーケンスになります。これはバッククォート構文(バッククォートを参照)の‘,@’に類似しています。
たとえば最初の要素がbaz
で、残りの引数は0個以上のfoo
かbar
でなければならないようなリストを指定するには、以下のカスタマイゼーション型を使用します:
(list (const baz) (set :inline t (const foo) (const bar)))
これは(baz)
、(baz foo)
、(baz bar)
、(baz foo
bar)
のような値にマッチします。
要素の型がchoice
なら、choice
自身の中で:inline
を使用せずに、choice
の選択肢(の一部)の中で使用します。たとえば最初がファイル名で始まり、その後にシンボルt
か2つの文字列を続けなければならないようなリストにマッチさせるには、以下のカスタマイゼーション型を使用します:
(list file (choice (const t) (list :inline t string string)))
選択においてユーザーが選択肢の1つ目を選んだ場合はリスト全体が2つの要素をもち、2つ目の要素はt
になります。ユーザーが2つ目の候補を選んだ場合にはリスト全体が3つの要素をもち、2つ目と3つ目の要素は文字列でなければなりません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
カスタマイゼーション型内の型名シンボルの後にキーワード/引数ペアーを指定できます。以下は使用できるキーワードとそれらの意味です:
:value default
デフォルト値を提供する。
その候補にたいしてnil
が有効な値でなければ、:value
に有効なデフォルトを指定することが必須となる。
choice
の内部の選択肢として出現する型にたいしてこれを使用するなら、ユーザーがカスタマイゼーションバッファー内のメニューでその選択肢を選択したときに使用するデフォルト値を最初に指定する。
もちろんオプションの実際の値がこの選択肢に適合するなら、defaultではなく実際の値が表示される。
:format format-string
この文字列はその型に対応する値を記述するために、バッファーに挿入される。format-string内では以下の‘%’エスケープが利用できる:
ボタンとしてマークされたテキストbuttonを表示する。:action
属性はユーザーがそれを呼び出したときに、そのボタンが何を行うか指定する。この属性の値は2つの引数
— ボタンが表示されるウィジェットとイベント — を受け取る関数である。
異なるアクションを行う2つの異なるボタンを指定する方法はない。
:sample-face
により指定されたスペシャルフェイス内のsampleを表示する。
そのアイテムの値を代替えする。その値がどのように表示されるかはアイテムの種類と、(カスタマイゼーション型にたいしては)カスタマイゼーション型にに依存する。
そのアイテムのドキュメント文字列を代替えする。
‘%d’と同様だが、ドキュメント文字列が複数行なら、ドキュメント文字列全体か最初の行だけかを制御するボタンを追加する。
その位置でタグに置き換える。:tag
キーワードでタグを指定する。
リテラル‘%’を表示する。
:action action
ユーザーがボタンをクリックしたらactionを実行する。
:button-face face
‘%[…%]’で表示されたボタンテキストにたいして、フェイスface(フェイス名、またはフェイス名のリスト)を使用する。
:button-prefix prefix
:button-suffix suffix
これらはボタンの前か後に表示されるテキストを指定する。以下が指定できる:
nil
テキストは挿入されない。
その文字列がリテラルに挿入される。
そのシンボルの値が使用される。
:tag tag
この型に対応する値(または値の一部)にたいするタグとしてtag(文字列)を使用する。
:doc doc
この型に対応する値(か値の一部)にたいするドキュメント文字列としてdocを使用する。これが機能するためには:format
にたいする値を指定して、その値にたいして‘%d’か‘%h’を使用しなければならない。
ある型にたいしてドキュメント文字列を指定するのは、:choice
内の選択肢の型や、他の複合型の一部について情報を提供するのが通常の理由である。
:help-echo motion-doc
widget-forward
やwidget-backward
でこのアイテムに移動したときに、エコーエリアに文字列motion-docを表示する。さらにマウスのhelp-echo
文字列としてmotion-docが使用され、これには実際には」ヘルプ文字列を生成するために評価される関数かフォームを指定できる。もし関数ならそれは1つの引数(そのウィジェット)で呼び出される。
:match function
値がその型にマッチするか判断する方法を指定する。対応する値functionは2つの引数(ウィジェットと値)を受け取る関数であり、値が適切なら非nil
をリターンすること。
:validate function
入力にたいして検証を行う関数を指定する。functionは引数としてウィジェットを受け取り、そのウィジェットのカレント値がウィジェットにたいして有効ならnil
をリターンすること。それ以外なら無効なデータを含むウィジェットをリターンして、そのウィジェットの:error
プロパティに、そのエラーを記述する文字列をセットすること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
前のセクションでは、defcustom
にたいして型の詳細な仕様を作成する方法を説明しました。そのような型仕様に名前を与えたい場合があるかもしれません。理解しやすいケースとしては、多くのユーザーオプションに同じ型を使用する場合などです。各オプションにたいして仕様を繰り返すよりその型に名前を与えて、defcustom
それぞれにその名前を使用することができます。他にもユーザーオプションの値が再帰的なデータ構造のケースがあります。あるデータ型がそれ自身を参照できるようにするためには、それが名前をもつ必要があります。
カスタマイゼーション型はウィジェットとして実装されているめ、新しいカスタマイゼーション型を定義するには、新たにウィジェット型を定義します。ここではウィジェットインターフェイスの詳細は説明しません。Introduction in The Emacs Widget Libraryを参照してください。かわりにシンプルな例を用いて、カスタマイゼーション型を新たに定義するために必要な最小限の機能について説明します。
(define-widget 'binary-tree-of-string 'lazy "A binary tree made of cons-cells and strings." :offset 4 :tag "Node" :type '(choice (string :tag "Leaf" :value "") (cons :tag "Interior" :value ("" . "") binary-tree-of-string binary-tree-of-string))) (defcustom foo-bar "" "Sample variable holding a binary tree of strings." :type 'binary-tree-of-string)
新しいウィジェットを定義するための関数はdefine-widget
と呼ばれます。1つ目の引数は新たなウィジェット型にしたいシンボルです。2つ目の引数は既存のウィジェットを表すシンボルで、新しいウィジェットではこの既存のウィジェットと異なる部分を定義することになります。新たなカスタマイゼーション型を定義する目的にたいしてはlazy
ウィジェットが最適です。なぜならこれはdefcustom
にたいするキーワード引数と同じ構文と名前でキーワード引数:type
を受け取るからです。3つ目の引数は新しいウィジェットにたいするドキュメント文字列です。この文字列はM-x
widget-browse RET binary-tree-of-string RETコマンドで参照することができます。
これらの必須の引数の後にキーワード引数が続きます。もっとも重要なのは:type
で、これはこのウィジェットにマッチさせたいデータ型を表します。上記の例ではbinary-tree-of-string
は文字列、またはcarとcdrがbinary-tree-of-string
であるようなコンスセルです。この定義中でのウィジェット型への参照に注意してください。:tag
属性はユーザーインターフェイスでウィジェット名となる文字列、:offset
引数はカスタマイゼーションバッファーでのツリー構造の外観で,子ノードと関連する親ノードの間に4つのスペースを確保します。
defcustom
は通常のカスタマイゼーション型に使用される方法で新しいウィジェットを表示します。
lazy
という名前の由来は、他のウィジェットではそれらがバッファーでインスタンス化されるとき、他の合成されたウィジェットが下位のウィジェットを内部形式に変換するからです。この変換は再帰的なので、下位のウィジェットはそれら自身の下位ウィジェットへと変換されます。データ構造自体が再帰的なら、その変換は無限再帰(infinite
recursion)となります。lazy
ウィジェットは、:type
引数を必要なときだけ変換することによってこの再帰を防ぎます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数には変数とフェイスにたいして、そのユーザーのカスタマイゼーション設定をインストールする役目をもちます。それらの関数はユーザーがCustomizeインターフェイスで‘Save
for future
sessions’を呼び出したとき、次回のEmacs起動時に評価されるようにcustom-set-variables
フォーム、および/またはcustom-set-faces
フォームがカスタムファイルに書き込まれることによって効果をもちます。
この関数はargsにより指定された変数のカスタマイゼーションをインストールする。args内の引数はそれぞれ、以下のようなフォームであること
(var expression [now [request [comment]]])
varは変数名(シンボル)、expressionはカスタマイズされた値に評価される式である。
このcustom-set-variables
呼び出しより前にvarにたいしてdefcustom
フォームが評価されたら即座にexpressionが評価されて、その変数の値にその結果がセットされる。それ以外ならその変数のsaved-value
プロパティにexpressionが格納されて、これに関係するdefcustom
が呼び出されたとき(通常はその変数を定義するライブラリーがEmacsにロードされたとき)に評価される。
now、request、commentエントリーは内部的な使用に限られており、省略されるかもしれない。nowがもし非nil
なら、たとえその変数のdefcustom
フォームが評価されていなくても、その変数の値がそのときセットされる。requestは即座にロードされる機能のリストである(名前つき機能を参照)。commentはそのカスタマイゼーションを説明する文字列。
この関数はargsにより指定されたフェイスのカスタマイゼーションをインストールする。args内の引数はそれぞれ以下のようなフォームであること
(face spec [now [comment]])
faceはフェイス名(シンボル)、specはそのフェイスにたいするカスタマイズされたフェイス仕様(フェイスの定義を参照)。
now、request、commentエントリーは内部的な使用に限られており、省略されるかもしれない。nowがもし非nil
なら、たとえdefface
フォームが評価されていなくても、そのフェイス仕様がそのときセットされる。commentはそのカスタマイズを説明する文字列。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Customテーマ(Custom themes)とはユニットとして有効や無効にできるセッティングのコレクションです。Custom Themes in The GNU Emacs Manualを参照してください。CustomテーマはそれぞれEmacs Lispソースファイルにより定義され、それらはこのセクションで説明する慣習にしたがう必要があります(Customテーマを手作業で記述するかわりに、Customize風のインターフェイスを使用して作成することもできる。Creating Custom Themes in The GNU Emacs Manualを参照)。
Customテーマファイルはfoo-theme.elのように命名すること。ここでfooはテーマの名前。このファイルでの最初のLispフォームはdeftheme
の呼び出しで、最後のフォームはprovide-theme
にすること。
このマクロはCustomテーマの名前としてtheme(シンボル)を宣言する。オプション引数docは、そのテーマを説明する文字列であること。この文字列はユーザーがdescribe-theme
コマンドを呼び出したり、‘*Custom
Themes*’バッファーで?をタイプしたときに表示される。
2つの特別なテーマ名は禁止されている(使用するとエラーになる)。user
はそのユーザーの直接的なカスタマイズ設定を格納するためのダミーのテーマである。そしchanged
はCustomizeシステムの外部で行われた変更を格納するためのダミーのテーマである。
このマクロは完全に仕様が定められたテーマ名themeを宣言する。
deftheme
とprovide-theme
の違いは、そのテーマセッティングを規定するLispフォームです(通常はcustom-theme-set-variables
の呼び出し、および/またはcustom-theme-set-faces
の呼び出し)。
この関数はCustomテーマthemeの変数のセッティングを規定する。themeはシンボル。args内の各引数はフォームのリスト。
(var expression [now [request [comment]]])
ここでリストエントリーはcustom-set-variables
のときと同じ意味をもつ。カスタマイゼーションの適用を参照のこと。
この関数はCustomテーマthemeのフェイスのセッティングを規定する。themeはシンボル。args内の各引数はフォームのリスト。
(face spec [now [comment]])
ここでリストエントリーはcustom-set-faces
のときと同じ意味をもつ。カスタマイゼーションの適用を参照のこと。
原則的にテーマファイルは他のLispフォームを含むこともでき、それらはそのテーマがロードされるときに評価されるでしょうが、これは悪いフォームです。悪意のあるコードを含むテーマのロードを防ぐために、最初に非ビルトインテーマをロードする前にEmacsはソースファイルを表示して、ユーザーにたいして確認を求めます。
以下の関数は、テーマをプログラム的に有効または無効にするのに有用です:
この関数はtheme(シンボル)がCustomテーマの名前(たとえばそのテーマが有効かどうかにかかわらず、CustomテーマがEmacsにロードされている)なら非nil
をリターンする。それ以外はnil
をリターンする。
この変数の値はEmacsにロードされたテーマのリストである。テーマはそれぞれLispシンボル(テーマ名)により表される。この変数のデフォルト値は2つのダミーテーマ(user
changed)
を含む。changed
テーマにはCustomテーマが適用される前に行われたセッティング(たとえばCustomの外部での変数のセット)が格納されている。user
テーマにはそのユーザーがカスタマイズして保存したセッティングが格納されている。deftheme
マクロで宣言されたすべての追加テーマは、このリストの先頭に追加される。
この関数はthemeという名前のCustomテーマを、変数custom-theme-load-path
で指定されたディレクトリーから探して、ソースファイルからロードする。Custom
Themes in The GNU Emacs
Manualを参照のこと。またそのテーマの変数とフェイスのセッティングが効果を及ぼすようにテーマをenablesにする(オプション引数no-enableがnil
の場合)。さらにオプション引数no-confirmがnil
なら、そのテーマをロードする前にユーザーに確認を求める。
この関数はthemeという名前のCustomテーマを有効にする。そのようなテーマがロードされていなければ、エラーをシグナルする。
この関数はthemeという名前のCustomテーマを無効にする。テーマはロードされたまま残るので、続けてenable-theme
を呼び出せばテーマは再び有効になる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispコードのファイルをロードすることは、その内容をLispオブジェクト形式でLisp環境に取り込むことを意味します。Emacsはファイルを探してオープンして、テキストを読み込んで各フォームを評価してから、そのファイルをクローズします。そのようなファイルはLispライブラリー(Lisp library)とも呼ばれます。
eval-buffer
関数がバッファー内のすべての式を評価するのと同様に、load関数はファイル内のすべての式を評価します。異なるのはEmacsバッファー内のテキストではなく、load関数はディスク上で見つかったファイル内のテキストを読み込んで評価することです。
ロードされたファイルは、ソースコードかバイトコンパイルされたコードとしてLisp式を含んでいなければなりません。このファイル内の各フォームはトップレベルフォーム(top-level form)と呼ばれます。ロード可能なファイル内のフォームにたいする特別なフォーマットはありません。ファイル内のフォームはどれも同じように直接バッファーにタイプされて、そこで評価されるでしょう(実際ほとんどのコードはこの方法でテストされる)。多くの場合はそのフォームは関数定義と変数定義です。
Emacsはコンパイルされたダイナミックモジュールも同様にロードできます。これはEmacs Lispプログラム内で、Emacs Lispで記述されたパッケージと同様に使用するための、追加機能を提供する共有ライブラリーです。ダイナミックモジュールのロード時に、Emacsはそのモジュールが実装する必要がある特殊な名前の初期化関数を呼び出して、Emacs Lispプログラムに追加の関数と変数を公開します。
特定のEmacsプリミティブで必要となるとあらかじめ判明している外部ライブラリーのオンデマンドローディングについては、動的にロードされるライブラリーを参照してください。
15.1 プログラムがロードを行う方法 | load 関数、その他。
| |
15.2 ロードでの拡張子 | load が試みられるサフィックスについての詳細。
| |
15.3 ライブラリー検索 | ロードするライブラリーの検索。 | |
15.4 非ASCII文字のロード | Emacs Lispファイル内の非ASCII文字。 | |
15.5 autoload | オートロードのための関数のセットアップ。 | |
15.6 多重ロード | ファイルを2度ロードする場合の配慮。 | |
15.7 名前つき機能 | まだロードされていないライブラリーのロード。 | |
15.8 どのファイルで特定のシンボルが定義されているか | 特定のシンボルがどのファイルで定義されているかの検索。 | |
15.9 アンロード | ロードされたライブラリーをunloadする方法。 | |
15.10 ロードのためのフック | 特定のライブラリーがロードされたとき実行されるコードの提供。 | |
15.11 Emacs Dynamic Modules | 追加のLispプリミティブを提供するモジュール。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs
Lispにはロードのためのインターフェイスがいくつかあります。たとえばautoload
はファイル内で定義された関数にたいしてプレースホルダーとなるオブジェクトを作成します。この関数はオートロードされる関数を呼び出すために、ファイルからその関数の実際の定義の取得を試みます(autoloadを参照)。require
はファイルがまだロードされていない場合にファイルをロードします(名前つき機能を参照)。これらすべての関数は処理を行うために最終的にload
を呼び出します。
この関数はLispコードのファイルを見つけてオープンして、その中のすべてのフォームを評価してそのファイルをクローズする。
load
はまずファイルを見つけるために、filename.elcという名前、つまりfilenameに拡張子‘.elc’を足した名前のファイルを探す。このようなファイルが存在したらそれをロードする。Emacsがダイナミックモジュール(Emacs Dynamic Modulesを参照)のサポートつきでコンパイルされていれば、、次にload
はfilename.extという名前のファイルを探す。ここでextは共有ライブラリーのシステム依存のファイル名拡張子である。その名前のファイルが存在しなければ、load
はfilename.elという名前のファイルを探す。このファイルが存在したらそれをロードする。最後に、もしこれらの名前がいずれも見つからなければ、load
は何も付け足さないfilenameという名前のファイルを探してそれが存在したらロードする(load
関数にfilenameを認識する賢さはない。foo.el.elのような正しくない名前のファイルでも、(load
"foo.el")
を評価してそれを見つけてしまうだろう)。
Auto
Compressionモードが有効(残念ながらデフォルトでは有効)なら、load
は他のファイル名を試みる前に圧縮されたバージョンのファイル名を探すのでファイルを見つけることができない。圧縮されたファイルが存在したら、それを解凍してロードする。load
はファイル名にjka-compr-load-suffixes
内の各サフィックスを足して圧縮されたバージョンを探す。この変数の値は文字列のリストでなければならない。標準的な値は(".gz")
。
オプション引数nosuffixが非nil
なら、load
はサフィックス‘.elc’と‘.el’のロードを試みない。この場合はロードしたいファイルの正確な名前を指定しなければならない。ただしAuto
Compressionモードが有効ならload
は圧縮されたバージョンを探すために、jka-compr-load-suffixes
を使用する。正確なファイル名を指定して、nosuffixにt
を使用することにより、foo.el.elのような名前のファイルにたいするロードの試みを抑止できる。
オプション引数must-suffixが非nil
の場合、ロードに使用されるファイルの名前に明示的にディレクトリー名が含まれていなければ、load
はファイル名が‘.el’か‘.elc’、または共有ライブラリーの拡張子で終わること(もしかしたら圧縮による拡張子が付加されているかもしれない)を要求する。
オプションload-prefer-newer
が非nil
なら、load
はサフィックスを検索するとき、どんなファイル(‘.elc’、‘.el’等)であっても、もっとも最近変更されたファイルのバージョンを選択する。
filenameがfooやbaz/foo.barのような相対ファイル名なら、load
は変数load-path
を使用してそのファイルを探す。これはload-path
内にリストされた各ディレクトリーにfilenameを追加して、最初に見つかった名前のマッチするファイルをロードする。デフォルトディレクトリーを意味するnil
がload-path
で措定されたときだけ、カレントデフォルトディレクトリーを試みる。load
はload-path
内の最初のディレクトリーで利用可能な3つのサフィックスすべてを試行してから、2つ目のディレクトリーで3つのサフィックスすべてを試行する、...というようにファイルを探す。ライブラリー検索を参照のこと。
最終的に見つかったファイル、およびEmacsがそのファイルを見つけたディレクトリーが何であれ、Emacsはそのファイル名を変数load-file-name
の値にセットする。
foo.elcがfoo.elより古いと警告されたら、それはfoo.elのリコンパイルを考慮すべきことを意味する。バイトコンパイルを参照のこと。
(コンパイルされていない)ソースファイルをロードしたとき、Emacsがファイルをvisitしたときと同じようにload
は文字セットの変換を行う。コーディングシステムを参照のこと。
コンパイルされていないファイルをロードするとき、Emacsはそのファイルに含まれるすべてのマクロ(マクロを参照)を展開する。わたしたちはこれをeagerマクロ展開(eager macro expansion)と呼んでいる。(関連するコードを実行するまで展開を延期しないで)これを行うことにより、コンパイルされていないコードの実行スピードが明らかに向上する。循環参照によりこのマクロ展開を行うことができないときもある。これの一番簡単な例は、ロードしようとしているファイルが他のファイルで定義されているマクロを参照しているが、そのファイルはロードしようとしているファイルを必要としている場合である。これは一般的には無害である。Emacsは問題の詳細を与えるために警告(‘Eager macro-expansion skipped due to cycle…’)をプリントするが、単にその時点ではマクロを展開せずにそのファイルをロードする。あなたはこの問題が発生しないようにコードをリストラクチャーしたいと思うかもしれない。コンパイル済みファイルではマクロ展開はコンパイル時に行われるので、ロード時のマクロ展開は行われない。マクロとバイトコンパイルを参照のこと。
nomessageが非nil
でなければ、エコーエリアに‘Loading foo...’や‘Loading
foo...done’のようなメッセージがロードの間に表示される。
ファイルをロードする間のハンドルされないエラーはロードを終了させる。autoload
のためのロードの場合、ロードの間に定義された任意の関数定義は元に戻される。
load
がロードするファイルを見つけられいと、通常は(‘Cannot open load file
filename’メッセージとともに)エラーfile-error
がシグナルされる。しかしmissing-okが非nil
なら、load
は単にnil
をリターンする。
式の読み取りにたいしてload
がread
のかわりに使用する関数を指定するために、変数load-read-function
を使用できる。以下を参照されたい。
ファイルが正常にロードされたら、load
はt
をリターンする。
このコマンドはファイルfilenameをロードする。filenameが相対ファイル名のなら、それはカレントデフォルトディレクトリーを指定したとみなされる。このコマンドはload-path
を使用せず、サフィックスの追加もしない。しかし(Auto
Compressionモードが有効なら)圧縮されたバージョンの検索を行う。ロードするファイル名を正確に指定したければ、このコマンドを使用すること。
このコマンドはlibraryという名前のライブラリーをロードする。このコマンドは引数を読み取る方法がインタラクティブであることを除きload
と同じ。Lisp
Libraries in The GNU Emacs Manualを参照のこと。
この変数はEmacsがファイルをロード中なら非nil
、それ以外はnil
である。
このセクションの最初に説明した検索でEmacsがファイルを見つけて、そのファイルをロード中のとき、この変数の値はそのファイルの名前である。
この変数はload
とeval-region
が式を読み取るために、read
のかわりに使用する関数を指定する。指定する関数はread
と同様、引数が1つの関数であること。
デフォルトではこの変数の値はread
。入力関数を参照のこと。
この変数を使用するかわりに別の新たな方法を使用するほうが明確である。それはeval-region
のread-function引数にその関数を渡す方法である。Evalを参照のこと。
Emacsのビルドでload
がどのように使用されているかについての情報は、Emacsのビルドを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ここではload
が試行するサフィックスについて、技術的な詳細を説明します。
これは(ソースまたはコンパイル済みの)Emacs
Lispファイルを示すサフィックスのリストである。空の文字列が含まないこと。load
は指定されたファイル名にLispファイルのサフィックスを追加するときに、これらのサフィックスを使用する。標準的な値は(".elc"
".el")
で、これは前のセクションで説明した振る舞いとなる。
これは同じファイルにたいして異なる表現を示すサフィックスのリストである。このリストは空の文字列から開始されること。load
はファイルを検索するときは、他のファイルを検索する前にこのリストのサフィックスを順番にファイル名に追加する。
Auto
Compressionモードを有効にすることによりjka-compr-load-suffixes
のサフィックスがこのリストに追加され、無効にすると再びリストから取り除かれる。load-file-rep-suffixes
の標準的な値は、Auto
Compressionモードが無効なら("")
。jka-compr-load-suffixes
の標準的な値が(".gz")
であることを考慮すると、Auto
Compressionモードが有効な場合のload-file-rep-suffixes
の標準的な値は(""
".gz")
である。
この関数はmust-suffix引数が非nil
のときは、load
が試みるべきすべてのサフィックスを順番にしたがったリストでリターンする。この関数はload-suffixes
とload-file-rep-suffixes
の両方を考慮する。load-suffixes
、jka-compr-load-suffixes
、load-file-rep-suffixes
がすべて標準的な値の場合、この関数はAuto
Compressionモードが有効なら(".elc" ".elc.gz" ".el"
".el.gz")
、無効なら(".elc" ".el")
をリターンする。
まとめると、load
は通常まず(get-load-suffixes)
の値のサフィックスを試み、次にload-file-rep-suffixes
を試みる。nosuffixが非nil
なら前者がスキップされ、must-suffixが非nil
なら後者がスキップされる。
このオプションが非nil
なら、ファイルが見つかった最初のサフィックスで停止せずに、load
はすべてのサフィックスをテストして、一番新しいファイルを使用する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
EmacsがLispライブラリーをロードするときは、変数load-path
により指定されるディレクトリー内のライブラリーを検索します。
この変数の値はload
でファイルをロードするときに検索するディレクトリーのリストである。リストの各要素は文字列(ディレクトリー名でなければなりません)、またはnil
(カレントワーキングディレクトリーを意味する)である。
Emacsは起動時にいくつかのステップによりload-path
の値をセットアップする。最初にEmacsがコンパイルされたときのデフォルトロケーションセット(default
locations set)を使用して、load-path
を初期化する。通常これは以下のようなディレクトリーである
"/usr/local/share/emacs/version/lisp"
(以降の例ではあなたがインストールしたEmacsのインストールプレフィクスに合うように/usr/localを置き換えること。) これらのディレクトリーには、Emacsとともにインストールされた標準的なLispファイルが含まれる。Emacsがこれらを見つけられなければ正常に起動しないだろう。
Emacsをビルドしたディレクトリーから起動した場合 −−− つまり正式にインストールされた実行形式ではないEmacsを起動した場合
— 、Emacsはビルドされたディレクトリーのソースのlispディレクトリーを使用してload-path
を初期化する。ソースとは別のディレクトリーでEmacsをビルドした場合は、ビルドしたディレクトリーのlispディレクトリーも追加する(いずれも要素は絶対ファイル名になる)。
--no-site-lispオプションでEmacsを起動した場合を除き、load-path
の先頭にさらに2つのsite-lispを追加する。これらはローカルにインストールされたLispファイルで、通常は:
"/usr/local/share/emacs/version/site-lisp"
および
"/usr/local/share/emacs/site-lisp"
の形式である。1つ目は特定のバージョンのEmacsにたいしてローカルにインストールされたものである。2つ目はインストールされたすべてのバージョンのEmacsが使用することを意図してローカルにインストールされたものである(インストールされたものでないEmacsが実行されると、もし存在すればソースディレクトリーとビルドディレクトリーのsite-lispディレクトリーも追加される。これらのディレクトリーは通常はsite-lispディレクトリーを含まない)。
環境変数EMACSLOADPATH
がセットされていたら、上述の初期化プロセスが変更される。Emacsはこの環境変数の値にもとづいてload-path
を初期化する。
EMACSLOADPATH
の構文は、PATH
で使用される構文と同様である。ディレクトリー名は‘:’(オペレーティングシステムによっては‘;’)で区切られる。
以下は(sh
スタイルのシェルから)EMACSLOADPATH
変数をセットする例である:
export EMACSLOADPATH=/home/foo/.emacs.d/lisp:
環境変数の値内の空の要素は、(上記例のような)末尾、先頭、中間のいずれにあるかに関わらず、標準の初期化処理により決定されるload-path
のデフォルト値に置き換えられる。そのような空要素が存在しなければEMACSLOADPATH
によりload-path
全体が指定される。空要素、または標準のLispファイルを含むディレクトリーへの明示的なパスのいずれかを含めなければならない。さもないとEmacsが関数を見つけられなくなる(load-path
を変更する他の方法は、Emacs起動時にコマンドラインオプション-Lを使用する方法である。以下参照)。
load-path
内の各ディレクトリーにたいして、Emacsはそのディレクトリーがファイルsubdirs.elを含むか確認して、もしあればそれをロードする。subdirs.elファイルは、load-path
のディレクトリーにたいして任意のサブディレクトリーを追加するためのコードが含まれており、Emacsがビルド/インストールされたときに作成される。サブディレクトリーと複数階層下のレベルのサブディレクトリーの両方が直接追加される。ただし名前の最初が英数字でないディレクトリー、名前がRCSまたはCVSのディレクトリー、名前が.nosearchというファイルを含むディレクトリーは除外される。
次にEmacsはコマンドラインオプション-L(Action Arguments in The GNU Emacs Manualを参照)で指定したロードディレクトリーを追加する。もしあればオプションパッケージ(パッケージ化の基礎を参照)がインストールされた場所も追加する。
initファイル(initファイルを参照)でload-path
に1つ以上のディレクトリーを追加するコードを記述するのは一般的に行なわれている。たとえば:
(push "~/.emacs.d/lisp" load-path)
Emacsのダンプにはload-path
の特別な値を使用する。ダンプされたEmacsをカスタマイズするためにsite-load.elかsite-init.elを使用する場合、これらのファイルが行ったload-path
にたいする変更はすべてダンプ後に失われる。
このコマンドはライブラリーlibraryの正確なファイル名を探す。load
と同じ方法でライブラリーを検索を行い、引数nosuffixもload
の場合と同じ意味をもつ。libraryに指定する名前にはサフィックス‘.elc’または‘.el’を追加しないこと。
pathが非nil
ならload-path
のかわりにそのディレクトリーのリストが使用される。
locate-library
がプログラムから呼び出されたときはファイル名を文字列としてリターンする。ユーザーがインタラクティブにlocate-library
を実行したときは、引数interactive-callがt
となり、これはlocate-library
にたいしてファイル名をエコーエリアに表示するよう指示する。
このコマンドはシャドー(shadowed)されたEmacs
Lispファイルを表示する。シャドーされたファイルとは、load-path
のディレクトリーに存在するにも関わらず、load-path
のディレクトリーリスト内で前の位置にある他のディレクトリーに同じ名前のファイルが存在するため、通常はロードされないファイルのことである。
たとえば以下のようにload-path
がセットされていたとする
("/opt/emacs/site-lisp" "/usr/share/emacs/23.3/lisp")
そして両方のディレクトリーにfoo.elという名前のファイルがあるとする。この場合、(require
'foo)
は決して2つ目のディレクトリーのファイルをロードしない。このような状況はEmacsがインストールされた方法に問題があることを示唆する。
Lispから呼び出されたると、この関数はシャドーされたファイルリストをバッファー内に表示するかわりに、それのメッセージをプリントする。オプション引数stringp
が非nil
なら、かわりにシャドーされたファイルを文字列としてリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispプログラムが非ASCII文字の文字列定数を含むとき、Emacsはそれらをユニバイト文字列かマルチバイト文字列のいずれかで表現する場合があります。どちらの表現が使用されるかは、そのファイルがどのようにEmacsに読み込まれたかに依存します。マルチバイト表現へのデコーディングとともに読み込まれた場合、Lispプログラム内のテキストはマルチバイトのテキストとなり、ファイル内の文字列定数はマルチバイト文字列になります。(たとえば)Latin-1文字を含むファイルをデコーディングなしで読み込むと、そのプログラムのテキストはユニバイトのテキストとなり、ファイル内の文字列定数はユニバイト文字列になります。コーディングシステムを参照してください。
マルチバイト文字列がユニバイトバッファーに挿入されるときは自動的にユニバイトに変換されるため、大部分のEmacs
Lispプログラムにおいて、マルチバイト文字列が非ASCII文字列であるという事実を意識させないようにするべきです。しかしこれが行われことにより違いが生じる場合には、ローカル変数セクションに‘coding:
raw-text’と記述することにより、特定のLispファイルを強制的にユニバイトとして解釈させることができます。この識別子により、そのファイルは無条件でユニバイトとして解釈されます。これは?vliteral
で記述された非ASCII文字にキーバインドするとき重要になります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
オートロード(autoload: 自動ロード)の機能により、定義されているファイルをロードすることなく関数やマクロの存在を登録できます。関数の最初の呼び出しで、実際の定義とその他の関連するコードをインストールするために適切なライブラリーを自動的にロードして、すべてがすでにロードされていたかのように実際の定義を実行します。関数やマクロのドキュメントを参照することによってもオートロードが発生します(ドキュメントの基礎を参照)。
オートロードされた関数をセットアップするには2つの方法があります。それはautoload
を呼び出す方法と、ソースの実際の定義の前に、“マジック”コメントを記述する方法です。autoload
はオートロードのための低レベルのプリミティブです。任意のLispプログラムが、任意のタイミングでautoload
を呼び出すことができます。Emacsとともにインストールされるパッケージにとって、マジックコメントは関数をオートロードできるようににするための一番便利な方法です。そのコメント自身は何も行いませんが、コマンドupdate-file-autoloads
にたいするガイドの役目を果たします。このコマンドはautoload
の呼び出しを構築して、Emacsビルド時に実行されるようにアレンジします。
この関数はfilenameから自動的にロードされるように、functionという名前の関数(かマクロ)を定義する。文字列filenameにはfunctionの実際の定義を取得するファイルを指定する。
filenameがディレクトリー名、またはサフィックス.el
と.elc
のいずれも含まなければ、この関数はこれらのサフィックスのいずれかを強制的に追加して、サフィックスがないただのfilenameという名前のファイルはロードしない(変数load-suffixes
により要求される正確なサフィックスが指定される)。
引数docstringはその関数のドキュメント文字列である。autoload
の呼び出しでドキュメント文字列を指定することにより、その関数の実際の定義をロードせずにドキュメントを見ることが可能になる。この引数の値は通常は関数定義のドキュメント文字列と等しいこと。もし等しくなければ、その関数定義のドキュメント文字列がロード時に有効になる。
interactiveが非nil
なら、その関数はインタラクティブに呼び出すことが可能になる。これによりfunctionの実際の定義をロードせずに、M-xによる補完が機能するようになる。ここでは完全なインタラクティブ仕様は与えられない。完全な仕様はユーザーが実際にfunctionを呼び出すまで必要ない。ユーザーが実際に呼び出したときに、実際の定義がロードされる。
普通の関数と同様、マクロとキーマップをオートロードできる。functionが実際にはマクロならtypeにmacro
、キーマップのならtypeにkeymap
を指定する。Emacsのさまざまな部分では、実際の定義をロードせずにこれらの情報を知ることが必要とされる。
オートロードされたキーマップは、あるプレフィクスキーがシンボルfunctionにバインドされているとき、キーを探す間に自動的にロードされる。そのキーマップにたいする他の類のアクセスではオートロードは発生しない。特にLispプログラムが変数の値からそのキーマップを取得してdefine-key
を呼び出した場合には、たとえその変数の名前がシンボルfunctionと同じであってもオートロードは発生しない。
functionが非voidのオートロードされたオブジェクトではない関数定義をもつなら、その関数は何も行わずにnil
をリターンする。それ以外ならオートロードされたオブジェクト(autoload型を参照)を作成して、それをfunctionにたいする関数定義として格納する。オートロードされたオブジェクトは以下の形式をもつ:
(autoload filename docstring interactive type)
たとえば、
(symbol-function 'run-prolog) ⇒ (autoload "prolog" 169681 t nil)
このような場合、"prolog"
はロードするファイルの名前、169681はemacs/etc/DOCファイル(ドキュメントの基礎を参照)内のドキュメント文字列への参照で、t
はその関数がインタラクティブであること、nil
はそれがマクロやキーマップでないことを意味する。
この関数はobjectがオートロードされたオブジェクトなら非nil
をリターンする。たとえばrun-prolog
がオートロードされたオブジェクトかチェックするには以下を評価する
(autoloadp (symbol-function 'run-prolog))
オートロードされたファイルは、通常は他の定義を含み1つ以上の機能を必要としたり、あるいは提供するかもしれません。(内容の評価でのエラーにより)そのファイルが完全にロードされていなければ、そのロードの間に行われた関数定義やprovide
の呼び出しはアンドゥされます。これはそのファイルからオートロードされる関数にたいして再度呼び出しを試みたときに、そのファイルを確実に再ロードさせるためです。こうしないと、そのファイル内のいくつかの関数はアボートしたロードにより定義されていて、それらはロードされない修正後のファイルで提供される正しいサブルーチンを欠くため、正しく機能しないからです。
オートロードされたファイルが意図したLisp関数またはマクロの定義に失敗すると、データ"Autoloading failed to
define function function-name"
とともにエラーがシグナルされます。
オートロードのマジックコメント(autoload
cookieとも呼ばれる)は、オートロード可能なソースファイル内の実際の定義の直前にある、‘;;;###autoload’だけの行から構成されます。コマンドM-x
update-file-autoloadsは、対応するautoload
呼び出しをloaddefs.el内に書き込みます(autoload
cookieとなる文字列とupdate-file-autoloads
で生成されるファイルの名前は上述のデフォルトから変更可能です。以下参照)。Emacsのビルドではloaddefs.elをロードするためにautoload
を呼び出します。M-x
update-directory-autoloadsはより強力です。このコマンドはカレントディレクトリー内のすべてのファイルにたいするオートロードを更新します。
このマジックコメントは任意の種類のフォームをloaddefs.el内にコピーできます。このマジックコメントに続くフォームはそのままコピーされます。しかしオートロード機能が特別に処理するフォームの場合は除外されます(たとえばautoload
内への変換)。以下はそのままコピーされないフォームです:
defun
とdefmacro
。cl-defun
とcl-defmacro
(Argument
Lists in Common Lisp
Extensionsを参照)、およびdefine-overloadable-function
(mode-local.el内のコメントを参照)も該当する。
define-minor-mode
、define-globalized-minor-mode
、define-generic-mode
、define-derived-mode
、easy-mmode-define-minor-mode
、easy-mmode-define-global-mode
、define-compilation-mode
、define-global-minor-mode
。
defcustom
、defgroup
、defclass
(EIEIO in EIEIOを参照)、およびdefine-skeleton
(skeleton.el内のコメントを参照)。
ビルド時にそのファイル自身をロードするときにフォームを実行しないようにするためにマジックコメントを使用することもできます。これを行なうにはマジックコメントと同じ行にフォームを記述します。これはコメントなのでソースファイルをロードするときには何も行いません。ただしM-x update-file-autoloadsでは、Emacsビルド時に実行されたものはM-x update-file-autoloadsにコピーします。
以下はマジックコメントによるオートロードのためにdoctor
を準備する例です:
;;;###autoload (defun doctor () "Switch to *doctor* buffer and start giving psychotherapy." (interactive) (switch-to-buffer "*doctor*") (doctor-mode))
これにより以下がloaddefs.el内に書き込まれます:
(autoload (quote doctor) "doctor" "\ Switch to *doctor* buffer and start giving psychotherapy. \(fn)" t nil)
ダブルクォートの直後のバックスラッシュと改行は、loaddefs.elのようなプリロードされた未コンパイルのLispファイルだけに使用される慣習です。これはmake-docfile
にたいして、ドキュメント文字列をetc/DOCファイルに配置するよう指示します。Emacsのビルドを参照してください。またlib-src/make-docfile.c内のコメントも参照してください。ドキュメント文字列の使い方(usage
part)の中の‘(fn)’は、種々のヘルプ関数(ヘルプ関数を参照)が表示するときに、その関数の名前に置き換えられます。
関数定義手法として既知ではなく、認められてもいないような、通常とは異なるマクロにより関数定義を記述した場合、通常のオートロードのマジックコメントの使用によって定義全体がloaddefs.el
内にコピーされるでしょう。これは期待した動作ではありません。かわりに以下を記述することにより、意図したautoload
呼び出しをloaddefs.el
内に配置することができます。
;;;###autoload (autoload 'foo "myfile") (mydefunmacro foo ...)
autoload cookieとしてデフォルト以外の文字列を使用して、デフォルトのloaddefs.elとは異なるファイル内に対応するオートロード呼び出しを記述できます。これを制御するためにEmacsは2つの変数を提供します:
この変数の値はLispコメントの文法に準じた文字列である。M-x
update-file-autoloadsはそのcookieの後のLispフォームを、cookieが生成したオートロードファイル内にコピーします。この変数のデフォルト値は";;;###autoload"
。
この変数の値は、オートロード呼び出しが書き込まれるEmacs Lispファイルを命名する。デフォルト値はloaddefs.elだが、(たとえば.elファイル内のセクションLocal Variables))をオーバーライドできる。オートロードファイルは、フォームフィード文字で開始される終端を含んでいると仮定される。
以下の関数はオートロードオブジェクトにより指定されたライブラリーを明示的にロードするために使用されるかもしれません:
この関数はオートロードオブジェクトautoloadにより指定されたロードを処理する。オプション引数nameに非nil
を指定するなら、関数値がautoloadとなるシンボルを指定すること。この場合、この関数のリターン値がそのシンボルの新しい関数値になる。オプション引数macro-onlyの値がmacro
なら、この関数は関数ではなくマクロのロードだけを有効にする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
1つのEmacsセッション内でファイルを複数回ロードできます。たとえばバッファーで関数定義を編集して再インストールした後に元のバージョンに戻したいときがあるかもしれません。これは元のファイルをリロードすることにより行なうことができます。
ファイルのロードやリロードを行う際、load
とload-library
関数は未コンパイルのファイルではなく、バイトコンパイルされた同名のファイルを自動的にロードすることに留意してください。ファイルを再記述して保存後に再インストールする場合には、新しいバージョンをバイトコンパイルする必要があります。さもないとEmacsは新しいソースではなく、古いバイトコンパイルされたファイルをロードしてしまうでしょう!
この場合にはファイルロード時に表示されるメッセージに、そのファイルのリコンパイルを促す‘(compiled; note, source is
newer)’というメッセージが含まれます。
Lispライブラリーファイル内にフォームを記述するときは、そのファイルが複数回ロードされるかもしれないことに留意してください。たとえば、そのライブラリーをリロードするときには、各変数が再初期化されるべきかどうか考慮してください。。変数がすでに初期化されていれば、defvar
はその変数の値を変更しません(グローバル変数の定義を参照)。
alistに要素を追加するもっともシンプルな方法は、以下のようなものでしょう:
(push '(leif-mode " Leif") minor-mode-alist)
しかしこれはそのライブラリーがリロードされると、複数の要素を追加してしまうでしょう。この問題を避けるにはadd-to-list
(リスト変数の変更を参照)を使用します:
(add-to-list 'minor-mode-alist '(leif-mode " Leif"))
時にはライブラリーが既にロード済みか、明示的にテストしたいときがあるでしょう。そのライブラリーがprovide
を使用して名前付きフィーチャ(named
feature)を提供していれば、featurep
を使用して以前にprovide
が実行されているかテストすることができます。かわりに以下のようにすることもできます:
(defvar foo-was-loaded nil) (unless foo-was-loaded execute-first-time-only (setq foo-was-loaded t))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
provide
とrequire
は、autoload
にかわってファイルを自動的にロードする関数です。これらは名前付きのフィーチャ(feature:
機能)という面で機能します。オートロードは特定の関数の呼び出しをトリガーにしますが、フィーチャは最初は他のプログラムが名前により問い合わせたときにロードされます。
フィーチャ名とは関数や変数などのコレクションを表すシンボルです。これらを定義するファイルは、そのフィーチャをプロバイド(provide: 提供)するべきです。これらのフィーチャを使用する他のプログラムは、その機能をリクワイア(require: 要求)することによって、それらが定義されているか確認できるでしょう。これは定義がまだロードされていなければ、定義ファイルをロードします。
フィーチャをリクワイアするには、フィーチャ名を引数としてrequire
を呼び出します。require
は意図する機能がすでにプロバイドされているか確認するために、グローバル変数features
を調べます。もしプロバイドされていなければ、適切なファイルからそのフィーチャをロードします。このファイルはそのフィーチャをfeatures
に追加するために、トップレベルでprovide
を呼び出すべきです。これに失敗するとrequire
はエラーをシグナルします。
たとえばidlwave.el内のidlwave-complete-filename
にたいする定義には以下のコードが含まれます:
(defun idlwave-complete-filename () "Use the comint stuff to complete a file name." (require 'comint) (let* ((comint-file-name-chars "~/A-Za-z0-9+@:_.$#%={}\\-") (comint-completion-addsuffix nil) ...) (comint-dynamic-complete-filename)))
式(require
'comint)
はcomint.elがまだロードされていなければ、comint-dynamic-complete-filename
が確実に定義されるようにそのファイルをロードします。フィーチャは通常はそれらを提供するファイルにしたがって命名されるため、require
にファイル名を与える必要はありません(require
命令文がlet
のbodyの外側にあるのが重要なことに注意。変数がletバインドされているライブラリーをロードすることにより、意図せぬ結果、つまりletをexitした後にその変数がアンバインドされる)。
comint.elには以下のトップレベル式が含まれます:
(provide 'comint)
これはcomint
をグローバルなリストfeatures
に追加するので、(require
'comint)
は今後何も行う必要がないことを知ることができます。
ファイルのトップレベルでrequire
が使用されたときは、それをロードしたときと同様、そのファイルをバイトコンパイル(バイトコンパイルを参照)するときにも効果が表れます。これはリクワイアされたパッケージがマクロを含んでいて、バイトコンパイラーがそれを知らなければならない場合です。これはrequire
によりロードされるファイルで定義される関数と変数にへのバイトコンパイラーの警告も無効にします。
バイトコンパイルの間にトップレベルのrequire
が評価されるとしても、provide
呼び出しは評価されません。したがって以下の例のようにprovide
の後に同じ機能にたいするrequire
を含めることにより、バイトコンパイル前に定義しているファイルを確実にロードできます。
(provide 'my-feature) ; バイトコンパイラーには無視され
; load
には評価される
(require 'my-feature) ; バイトコンパイラーにより評価される。
コンパイラーはprovide
を無視して、その後に対象のファイルをロードすることによりrequire
が処理されます。ファイルのロードはprovide
呼び出しを実行するので、後続のrequire
はファイルがロードされていれば何も行いません。
この関数はカレントEmacsセッションにfeatureがロードされたこと、あるいはロードされつつあることをアナウンスする。これはfeatureに関連する機能が他のLispプログラムから利用可能できる、あるいは利用可能になることを意味する。
provide
呼び出にによる直接的な効果は、リストfeature内にまだ追加されていなければfeatureの先頭にそれを追加して、それを必要としているeval-after-load
コードを呼び出すことである(ロードのためのフックを参照)。引数featureはシンボルでなければならない。provide
はfeatureをリターンする。
subfeaturesが与えられたら、それはfeatureの当該バージョンによりプロバイドされる特定のサブフィーチャのセットを示すシンボルのリストであること。featurep
を使用して、サブフィーチャの存在をテストできる。そのパッケージがロードされるかどうか、あるいは与えられるバージョンで存在するかどうか不明であるようなあるパッケージ(1つのfeature)において、パッケージの種々の部分やパッケージ機能に命名することでそのパッケージを使いやすくするのが困難なほど複雑なときに使用するというのがサブフィーチャのアイデアである。ネットワーク機能の可用性のテストの例を参照されたい。
features ⇒ (bar bish) (provide 'foo) ⇒ foo features ⇒ (foo bar bish)
オートロードによりあるファイルがロードされて、その内容の評価エラーによりストップしたときは、そのロードの間に発生した関数定義やprovide
呼び出しはアンドゥされる。autoloadを参照のこと。
この関数はカレントEmacsセッションにおいて、featureが存在するかどうかを((featurep
feature)
を使用する。以下参照)をチェックする。引数featureはシンボルでなければならない。
そのフィーチャが存在しなければ、require
はload
によってfilenameをロードする。filenameが与えられなければ、シンボルfeatureの名前がロードするファイル名のベースとして使用される。しかしこの場合、require
はfeatureを探すためにサフィックス‘.el’と‘.elc’の追加を強制する(圧縮ファイルのサフィックスに拡張されるかもしれない)。名前がただのfeatureというファイルは使用されない(変数load-suffixes
は要求されるLispサフィックスを正確に指定する)。
noerrorが非nil
なら、ファイルの実際のロードにおけるエラーを抑止する。この場合はそのファイルのロードが失敗するとrequire
はnil
をリターンする。通常ではrequire
はfeatureをリターンする。
ファイルのロードは成功したがfeatureをプロバイドしていなければ、require
は‘Required
feature feature was not provided’のようにエラーをシグナルする。
この関数はカレントEmacsセッションでfeatureがプロバイドされていれば(たとえばfeatureがfeatures
のメンバーなら)t
をリターンする。subfeatureが非nil
なら、この関数はサブフィーチャも同様にプロバイドされているとき(たとえばsubfeatureがシンボルfeatureのプロパティsubfeature
のメンバーのとき)だけt
をリターンする。
この変数の値はシンボルのリストであり、そのシンボルはカレントEmacsセッションにロードされたフィーチャである。シンボルはそれぞれprovide
を呼び出すことにより、このリストにputされたものである。リストfeatures
内の要素の順番に意味はない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はsymbolを定義しているファイルの名前をリターンする。typeがnil
なら、どのようなタイプの定義も受け入れる。typeがdefun
なら関数定義、defvar
は変数定義、defface
はフェイス定義だけを指定する。
値は通常は絶対ファイル名である。定義がどのファイルにも関係しなければnil
になることもある。symbolがオートロード関数を指定するなら、値が拡張子なしの相対ファイル名になることもある。
symbol-file
は変数load-history
の値にもとづく。
この変数の値はロードされたライブラリーファイルの名前を、それらが定義する関数と変数の名前、およびそれらがプロバイドまたはリクワイアするフィーチャに関連付けるalistである。
このalist内の各要素は、1つのロード済みライブラリー(スタートアップ時にプリロードされたライブラリーを含む)を記述する。要素はCARがライブラリーの絶対ファイル名(文字列)であるようなリストである。残りのリスト要素は以下の形式をもつ:
var
シンボルvarが変数として定義された。
(defun . fun)
関数funが定義された。
(t . fun)
関数funはそのライブラリーが関数として再定義する前はオートロードとして定義されていた。後続の要素は常に(defun
. fun)
であり、これはfunを関数として定義する。
(autoload . fun)
関数funはオートロードとして定義された。
(defface . face)
フェイスfaceが定義された。
(require . feature)
フィーチャfeatureがリクワイアされた。
(provide . feature)
フィーチャfeatureがプロバイドされた。
(cl-defmethod method specializers)
cl-defmethod
を使用してスペシャライザーspecializersとともにmethodという名前が定義された。
(define-type . type)
型typeが定義された。
load-history
の値には、CARがnil
であるような要素が1つ含まれるかもしれない。この要素はファイルをvisitしていないバッファーでeval-buffer
により作成された定義を記述する。
コマンドeval-region
はload-history
を更新しますが、要素を置き換えずに、visitされているファイルの要素にたいして定義されたシンボルを追加します。evalを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
他のLispオブジェクト用にメモリーを回収するために、ライブラリーによりロードされた関数や変数を破棄することができます。これを行うには関数unload-feature
を使用します:
このコマンドはフィーチャfeatureをプロバイドしていたライブラリーをアンロードする。そのライブラリー内のdefun
、defalias
、defsubst
、defmacro
、defconst
、defvar
、defcustom
によって定義されたすべての関数、マクロ、変数は未定義になる。その後に、それらのシンボルにたいして事前に関連付けられていたオートロードをリストアする(ロードはシンボルのautoload
プロパティにこれらを保存している)。
以前の定義をリストアする前に、特定のフックからそのライブラリー内の関数を取り除くために、unload-feature
はremove-hook
を実行する。これらのフックには名前が‘-hook’(または廃止されたサフィックス‘-hooks’)で終わる変数、加えてunload-feature-special-hooks
、同様にauto-mode-alist
にリストされた変数も含まれる。これは重要なフックがすでに定義されていない関数を参照をすることにより、Emacsの機能が停止することを防ぐためである。
標準的なアンロードアクティビティでは、そのライブラリー内の関数のELPプロファイリング、そのライブラリーによりプロバイドされたフィーチャ、そのライブラリーで定義された変数に保持されたタイマーを取り消す。
これらの基準が機能不全を防ぐのに十分でなければ、ライブラリーはfeature-unload-function
という名前の明示的なアンローダーを定義できる。そのシンボルが関数として定義されていたら、unload-feature
は何かを行う前にまず引数なしでそれを呼び出す。これはライブラリーのアンロードのために適切なすべてのことを行うことができる。これがnil
をリターンしたら、unload-feature
は通常のアンロードアクションを処理する。それ以外ならアンロード処理は完了したとみなす。
unload-feature
は通常は他のライブラリーが依存するライブラリーのアンロードを拒絶する(ライブラリーbにたいするrequire
がライブラリーaに含まれるなら、aはbに依存している)。オプション引数forceが非nil
なら依存関係は無視されて、どのようなライブラリーもアンロードできる。
unload-feature
関数はLispで記述されており、その動作は変数load-history
にもとづきます。
この変数はライブラリー内で定義された関数を取り除くために、ライブラリーをアンロードする前にスキャンするフックのリストを保持する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
変数after-load-functions
を使用することにより、Emacsがライブラリーをロードするたびにコードを実行させることができます:
このアブノーマルフック(abnormal hook)は、ファイルをロードした後に実行される。フック内の各関数は1つの引数(ロードされたファイルの絶対ファイル名)で呼び出される。
特定のライブラリーのロード後にコードを実行したければ、マクロwith-eval-after-load
を使用します:
このマクロはlibraryがロードされるたびに、ファイルlibraryのロードの最後でbodyが評価されるよう準備する。libraryがすでにロード済みなら即座にbodyを評価する。
ファイル名libraryにディレクトリーや拡張子を与える必要はない。通常は以下のようにファイル名だけを与える:
(with-eval-after-load "edebug" (def-edebug-spec c-point t))
どのファイルが評価をトリガーするか制限するには、ディレクトリーか拡張子、またはその両方をlibraryに含める。実際のファイル名(シンボリックリンク名はすべて除外される)が、与えられた名前すべてにマッチするファイルだけがマッチとなる。以下の例ではどこかのディレクトリー..../foo/bar
にあるmy_inst.elcやmy_inst.elc.gzは評価をトリガーするが、my_inst.elは異なる。:
(with-eval-after-load "foo/bar/my_inst.elc" …)
libraryはフィーチャ(たとえばシンボル)でもよく、その場合には(provide
library)
を呼び出す任意のファイルの最後にbodyが評価される。
body内でのエラーはロードをアンドゥしないが、bodyの残りの実行を防げる。
上手く設計されたLispプログラムは、通常はwith-eval-after-load
を使用するべきではありません。(外部からの使用を意図した)他のライブラリーで定義された変数を調べたりセットする必要があるなら、それは即座に行うことができます
−−−
そのライブラリーがロードされるのを待つ必要はありまん。そのライブラリーで定義された関数を呼び出す必要があるならそのライブラリーをロードすべきであって、それにはrequire
(名前つき機能を参照)が適しています。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ダイナミックEmacsミジュール(dynamic Emacs module)とは、Emacs Lispで記述されたパッケージのように、Emacs Lispプログラムで使用するための追加機能を提供する共有ライブラリーです。
Emacs Lispパッケージをロードする関数は、ダイナミックモジュールのロードもできます。これらの関数はファイル名の拡張子、いわゆる“サフィックス”を調べることによってダイナミックモジュールを認識します。
この変数はモジュールファイルのファイル名拡張子の、システム依存な値を保持する。Posixホストでは.so、MS-Windowsでは.dll。
すべてのダイナミックモジュールはCから呼び出し可能なemacs_module_init
という名前の関数をエクスポートする必要があります。load
かrequire
でそのモジュールをロードする一部として、Emacsはその関数を呼び出します。モジュールのコードがGPLまたはGPL互換のライセンスの下にリリースされたことを示す、plugin_is_GPL_compatible
という名前のシンボルもエクスポートしてください。Emacsはこのようなシンボルをエクスポートしないモジュールのロードを拒絶するでしょう。
モジュールがEmacs関数を呼び出す必要があるなら、Emacsディストリビューションに含まれるヘッダーファイルemacs-module.hで定義およびドキュメントされているAPIを通じてこれを行ってください。
モジュールは、そのモジールで定義されたC構造体にたいする埋め込みポインターであるuser-ptr
Lispオブジェクトを作成できます。これはモジュールで作成されてそのモジュールの関数に渡される複雑なデータ構造を保持するために有用です。user-ptrオブジェクトはそれに関連付けられるファイナライザー(finalizers)をもつこともできます。ファイナライザーとはオブジェクトがガーベージコレクションされたときに実行される関数のことです。
この関数は引数がuser-ptr
オブジェクトならt
をリターンする。
Emacsのロード可能モジュールは、configure時にオプション--with-modulesを使用することにより有効になります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs LispにはLispで記述された関数をより効率的に実行できる、バイトコード(byte-code)と呼ばれる特別な表現に翻訳するコンパイラー(compiler)があります。コンパイラーはLispの関数定義をバイトコードに置き換えます。バイトコード関数が呼び出されたとき、その定義はバイトコードインタープリター(byte-code interpreter)により評価されます。
バイトコンパイルされたコードは、(本当のコンパイル済みコードのように)そのマシンのハードウェアによって直接実行されるのではなく、バイトコンパイラーによって評価されるため、バイトコードはリコンパイルしなくてもマシン間での完全な可搬性を有します。しかし本当にコンパイルされたコードほど高速ではありません。
一般的に任意のバージョンのEmacsはそれ以前のバージョンのEmacsにより生成されたバイトコンパイル済みコードを実行できますが、その逆は成り立ちません。
あるLispファイルを常にコンパイルせずに実行したい場合は、以下のようにno-byte-compile
をバインドするファイルローカル変数を配置します:
;; -*-no-byte-compile: t; -*-
16.1 バイトコンパイル済みコードのパフォーマンス | バイトコンパイルによるスピードアップ例。 | |
16.2 バイトコンパイル関数 | ||
16.3 ドキュメント文字列とコンパイル | ドキュメント文字列のダイナミックロード。 | |
16.4 個別関数のダイナミックロード | 個々の関数のダイナミックロード。 | |
16.5 コンパイル中の評価 | コンパイル時に評価されるコード。 | |
16.6 コンパイラーのエラー | コンパイラーのエラーメッセージの扱い。 | |
16.7 バイトコード関数オブジェクト | バイトコンパイル済み関数に使用されるデータ型。 | |
16.8 逆アセンブルされたバイトコード | バイトコードの逆アセンブル; バイトコードの読み方。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バイトコンパイルされた関数はCで記述されたプリミティブ関数ほど効率的ではありませんが、Lispで記述されたバージョンよりは高速に実行されます。以下は例です:
(defun silly-loop (n) "Return the time, in seconds, to run N iterations of a loop." (let ((t1 (float-time))) (while (> (setq n (1- n)) 0)) (- (float-time) t1))) ⇒ silly-loop
(silly-loop 50000000) ⇒ 10.235304117202759
(byte-compile 'silly-loop)
⇒ [コンパイルされたコードは表示されない]
(silly-loop 50000000) ⇒ 3.705854892730713
この例ではインタープリターによる実行には10秒を要しますが、バイトコンパイルされたコードは4秒未満です。これは典型的な結果例ですが、実際の結果はさまざまでしょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
byte-compile
により、関数やマクロを個別にバイトコンパイルできます。byte-compile-file
でファイル全体、byte-recompile-directory
またはbatch-byte-compile
で複数ファイルをコンパイルできます。
バイトコンパイラーが警告、および/またはエラーメッセージを生成することもあります(詳細はコンパイラーのエラーを参照)。これらのメッセージはCompilationモードが使用する*Compile-Log*と呼ばれるバッファーに記録されます。Compilation Mode in The GNU Emacs Manualを参照してください。
バイトコンパイルを意図したファイル内にマクロ呼び出しを記述する際には注意が必要です。マクロ呼び出しはコンパイル時に展開されるので、そのマクロはEmacsにロードされる必要があります(さもないとバイトコンパイラーが正しく処理しないだろう)。これを処理する通常の方法は、必要なマクロ定義を含むファイルをrequire
フォームで指定することです。バイトコンパイラーは通常はコンパイルするコードを評価しませんが、require
フォームは指定されたライブラリーをロードすることにより特別に扱われます。誰かがコンパイルされたプログラムを実行する際にマクロ定義ファイルのロードを回避するためには、require
呼び出しの周囲にeval-when-compile
を記述します(コンパイル中の評価を参照)。詳細はマクロとバイトコンパイルを参照してください。
インライン関数(defsubst
)はこれほど面倒ではありません。定義が判明する前にそのような関数呼び出しをコンパイルした場合でも、その呼び出しは低速になるだけで正しく機能するでしょう。
この関数はsymbolの関数定義をバイトコンパイルして、以前の定義をコンパイルされた定義に置き換える。symbolの関数定義は、その関数にたいする実際のコードでなければならない。byte-compile
はインダイレクト関数を処理しない。リターン値は、symbolのコンパイルされた定義であるようなバイトコード関数ブジェクト(バイトコード関数オブジェクトを参照)。
(defun factorial (integer) "INTEGERの階乗を計算する。" (if (= 1 integer) 1 (* integer (factorial (1- integer))))) ⇒ factorial
(byte-compile 'factorial) ⇒ #[(integer) "^H\301U\203^H^@\301\207\302^H\303^HS!\"\207" [integer 1 * factorial] 4 "Compute factorial of INTEGER."]
symbolの定義がバイトコード関数オブジェクトなら、byte-compile
は何も行わずnil
をリターンする。そのシンボルの関数セル内の(コンパイルされていない)オリジナルのコードはすでにバイトコンパイルされたコードに置き換えられているので、シンボルの定義の再コンパイルはしない。
byte-compile
の引数としてlambda
式も指定できる。この場合、関数は対応するコンパイル済みコードをリターンするが、それはどこにも格納されない。
このコマンドはポイントを含むdefunを読み取りそれをコンパイルして、結果を評価します。実際に関数定義であるようなdefunでこれを使用した場合は、その関数のコンパイル済みバージョンをインストールする効果があります。
compile-defun
は通常は評価した結果をエコーエリアに表示するが、argが非nil
なら、そのフォームをコンパイルした後にカレントバッファーに結果を挿入する。
この関数はfilenameという名前のLispコードファイルを、バイトコードのファイルにコンパイルする。出力となるファイルの名前は、サフィックス‘.el’を‘.elc’に変更することにより作成される。filenameが‘.el’で終了しない場合には、‘.elc’をfilenameの最後に付け足す。
コンパイルは入力ファイルから1つのフォームを逐次読み取ることにより機能する。フォームが関数かマクロなら、コンパイル済みの関数かマクロが書き込まれる。それ以外のフォームはまとめられて、まとめられたものごとにコンパイルされて、そのファイルが読まれたとき実行されるようにコンパイルされたコードが書き込まれる。入力ファイルを読み取る際には、すべてのコメントは無視される。
このコマンドはエラーがなければt
、それ以外はnil
をリターンする。インタラクティブに呼び出されたときは、ファイル名の入力をもとめる。
loadが非nil
なら、このコマンドはコンパイルした後にコンパイルしたファイルをロードする。インタラクティブに呼び出された場合、loadはプレフィクス引数である。
$ ls -l push* -rw-r--r-- 1 lewis lewis 791 Oct 5 20:31 push.el
(byte-compile-file "~/emacs/push.el") ⇒ t
$ ls -l push* -rw-r--r-- 1 lewis lewis 791 Oct 5 20:31 push.el -rw-rw-rw- 1 lewis lewis 638 Oct 8 20:25 push.elc
このコマンドはdirectory(またはそのサブディレクトリー)内の、リコンパイルを要するすべての‘.el’ファイルをリコンパイルする。‘.elc’ファイルが存在して、それが‘.el’より古いファイルは、リコンパイルが必要となる。
‘.el’ファイルに対応する‘.elc’ファイルが存在しない場合に何を行うかをflagで指定する。nil
なら、このコマンドはこれらのファイルを無視する。flagが0なら、それらをコンパイルする。nil
と0以外なら、それらのファイルをコンパイルするかユーザーに尋ねて、同様にそれぞれのサブディレクトリーについても尋ねる。
インタラクティブに呼び出されると、byte-recompile-directory
はdirectoryの入力を求めて、flagはプレフィクス引数となる。
forceが非nil
なら、このコマンドは‘.elc’ファイルが存在するすべての‘.el’ファイルをリコンパイルする。
リターン値は不定。
この関数はコマンドラインで指定されたファイルにたいしてbyte-compile-file
を実行する。この関数は処理が完了するとEmacsをkillするので、Emacsのバッチ実行でのみ使用しなければならない。1つのファイルでエラーが発生しても、それによって後続のファイルにたいする処理が妨げられることはないが、そのファイルにたいする出力ファイルは生成されず、Emacsプロセスは0以外のステータスコードで終了する。
noforceが非nil
なら、この関数は最新の‘.elc’ファイルがあるファイルをリコンパイルしない。
$ emacs -batch -f batch-byte-compile *.el
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsがバイトコンパイルされたファイルから関数や変数をロードする際、通常はメモリー内にそれらのドキュメント文字列をロードしません。それぞれのドキュメント文字列は、必要なときだけバイトコンパイルされたファイルからダイナミック(dynamic: 動的)にロードされます。ドキュメント文字列の処理をスキップすることにより、メモリーが節約されてロードが高速になります。
この機能には欠点があります。コンパイル済みのファイルを削除や移動、または(新しいバージョンのコンパイル等で)変更した場合、Emacsは以前にロードした関数や変数のドキュメント文字列にアクセスできなくなるでしょう。このような問題は通常なら、あなた自身がEmacsをビルドしたときに、そのLispファイルを編集および/またはリコンパイルしたときだけ発生します。この問題は、リコンパイル後にそれぞれのファイルをリロードするだけで解決します。
バイトコンパイルされたファイルからのドキュメント文字列のダイナミックロードは、バイトコンパイルされたファイルごとにコンパイル時に解決されます。これはオプションbyte-compile-dynamic-docstrings
で無効にできます。
これが非nil
なら、バイトコンパイラーはドキュメント文字列をダイナミックロードするようにセットアップしたコンパイル済みファイルを生成する。
特定のファイルでダイナミックロード機能を無効にするには、以下のようにヘッダー行でこのオプションにnil
をセットする(Local Variables in Files in The GNU Emacs Manualを参照)。
-*-byte-compile-dynamic-docstrings: nil;-*-
これは主として、あるファイルを変更しようとしていて、そのファイルをすでにロード済みのEmacsセッションがファイルを変更した際にも正しく機能し続けることを望む場合に有用である。
内部的にはドキュメント文字列のダイナミックロードは、特殊なLispリーダー構文‘#@count’とともにコンパイル済みファイルに書き込むことによって達成される。この構文は次のcount文字をスキップする。さらに‘#$’構文も使用され、これはこのファイルの名前(文字列)を意味する。これらの構文をLispソースファイル内で使用しないこと。これらは人間がファイルを読む際に明確であるようにデザインされていない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ファイルをコンパイルするとき、オプションでダイナミック関数ロード(dynamic function loading)機能(laxyロード(lazy loading)とも呼ばれる)を有効にできます。ダイナミック関数ロードでは、ファイルのロードでファイル内の関数定義は完全には読み込まれません。かわりに各関数定義にはそのファイルを参照するプレースホルダーが含まれます。それぞれ関数が最初に呼び出されるときにそのプレースホルダーを置き換えるために、ファイルから完全な定義が読み込まれます。
ダイナミック関数ロードの利点は、ファイルのロードがより高速になることです。ユーザーが呼び出せる関数を多く含むファイルにとって、それらの関数のうち1つを使用したら多分残りの関数も使用するというのでなければ、これは利点になります。多くのキーボードコマンドを提供する特化したモードは、このパターンの使い方をする場合があります。ユーザーはそのモードを呼び出すかもしれませんが、使用するのはそのモードが提供するコマンドのわずか一部です。
ダイナミックロード機能には不利な点がいくつかあります:
このような問題は通常の状況でインストールされたEmacsファイルでは決して発生しません。しかしあなたが変更したLispファイルでは発生し得ます。それぞれのファイルをリコンパイルしたらすぐに新たなコンパイル済みファイルをリロードするのが、これらの問題を回避する一番簡単な方法です。
コンパイル時に変数byte-compile-dynamic
が非nil
なら、バイトコンパイラーはダイナミック関数ロード機能を使用します。ダイナミックロードが望ましいのは特定のファイルにたいしてだけなので、この変数をグローバルにセットしないでください。そのかわりに、特定のソースファイルのファイルローカル変数でこの機能を有効にしてください。たとえばソースファイルの最初の行に以下のテキストを記述することにより、これを行うことができます:
-*-byte-compile-dynamic: t;-*-
これが非nil
なら、バイトコンパイラーはダイナミック関数ロード用にセットアップされたコンパイル済みファイルを生成する。
functionがバイトコード関数オブジェクトなら、それがまだ完全にロードされていなければ、バイトコンパイル済みのファイルからのfunctionのバイトコードのロードを完了させる。それ以外なら何も行わない。この関数は常にfunctionをリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
これらの機能によりプログラムのコンパイル中に評価されるコードを記述できます。
このフォームはそれを含むコードがコンパイルされるとき、および(コンパイルされているかいないかに関わらず)実行されるときの両方でbodyが評価されるようにマークする。
bodyを別のファイルに配置して、そのファイルをrequire
で参照すれば同様の結果が得られる。これはbodyが大きいときに望ましい方法である。事実上、require
は自動的にeval-and-compile
されて、そのパッケージはコンパイル時と実行時の両方でロードされる。
autoload
も実際はeval-and-compile
される。これはコンパイル時に認識されるので、そのような関数の使用により警告“not
known to be defined”は生成されない。
ほとんどのeval-and-compile
の使用は、完全に妥当であると言えよう。
あるマクロがマクロの結果を構築するためのヘルパー関数をもち、そのマクロがそのパッケージにたいしてローカルと外部の両方で使用される場合には、コンパイル時と後の実行時にそのヘルパー関数を取得するためにeval-and-compile
を使用すること。
これは関数がプログラム的に(fset
で)定義されている場合には、コンパイル時と実行時にプログラム的な定義を行わせてそれらの関数の呼び出しをチェックするためにも使用できる(“not
known to be defined”の警告は抑制される)。
このフォームはbodyがコンパイル時に評価され、コンパイルされたプログラムがロードされるときは評価されないようにマークする。コンパイラーによる評価の結果はコンパイル済みのプログラム内の定数となる。ソースファイルをコンパイルではなくロードすると、bodyは通常どおり評価される。
生成するために何らかの計算が必要な定数があるなら、eval-when-compile
はコンパイル時にそれを行なうことができる。たとえば、
(defvar my-regexp (eval-when-compile (regexp-opt '("aaa" "aba" "abb"))))
他のパッケージを使用しているが、そのパッケージのマクロ(バイトコンパイラーはそれらを展開します)だけが必要なら、それらを実行せずにコンパイル用にロードさせるためにeval-when-compile
を使用できる。たとえば、
(eval-when-compile (require 'my-macro-package))
これらの事項は、マクロとdefsubst
関数がローカルに定義されていて、そのファイル内だけで使用されることを要求する。これらはそのファイルのコンパイルに必要だが、コンパイル済みファイルの実行には、ほとんどの場合必要ない。たとえば、
(eval-when-compile (unless (fboundp 'some-new-thing) (defmacro 'some-new-thing () (compatibility code))))
これは大抵は他のバージョンのEmacsとの互換性の保証のためのコードにたいしてのみ有用である。
Common Lispに関する注意: トップレベルでは、eval-when-compile
はCommon
Lispのイディオム(eval-when (compile eval) …)
に類似する。トップレベル以外では、Common
Lispのリーダーマクロ‘#.’(ただし解釈時を除く)が、eval-when-compile
と近いことを行う。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バイトコンパイルのエラーメッセージと警告メッセージは、*Compile-Log*という名前のバッファーにプリントされます。これらのメッセージには、問題となる箇所を示すファイル名と行番号が含まれます。これらのメッセージにたいして、コンパイラー出力を操作する通常のEmacsコマンドが使用できます。
あるエラーがプログラムのシンタックスに由来する場合、バイトコンパイラーはエラーの正確な位置の取得に際して混乱するかもしれません。バッファー *Compiler Input*.にスイッチするのは、これを調べ1つの方法です(このバッファー名はスペースで始まるので、Buffer Menuに表示されない)。このバッファーにはコンパイルされたプログラムと、バイトコンパイラーが読み取った箇所からポイントがどれほど離れているかが含まれ、エラーの原因はその近傍の可能性があります。シンタックスエラーを見つけるヒントについては、無効なLisp構文のデバッグを参照してください。
定義されていない関数や変数の使用は、バイトコンパイラーにより報告される警告のタイプとしては一般的です。そのような警告では、定義されていない関数や変数を使用した位置ではなく、そのファイルの最後の行の行番号が報告されるので、それを見つけるには手作業で検索しなければなりません。
定義のない関数や変数の警告が間違いだと確信できる場合には、警告を抑制する方法がいくつかあります:
fboundp
でテストすることで抑制できる:
(if (fboundp 'func) ...(func ...)...)
funcへの呼び出しはif
文のthen-form内になければならず、funcはfboundp
呼び出し内でクォートされていなければならない(この機能はcond
でも同様に機能する)。
boundp
テストで抑制できる:
(if (boundp 'variable) ...variable...)
variableへの参照はif
文のthen-form内になければならず、variableはboundp
呼び出し内でクォートされていなければならない。
declare-function
を使用して定義されていると告げることができる。コンパイラーへの定義済み関数の指示を参照のこと。
defvar
を使用して定義されているとコンパイラーに告げることができる(これはその変数を特別な変数としてマークすることに注意。グローバル変数の定義を参照)。
with-no-warnings
構文を使用して特定の式にたいするコンパイラーの任意の警告をすべて抑制することもできます:
これは実行時には(progn
body...)
と等価だが、コンパイラーはbodyの中で起こるいかなる事項にたいしても警告を発しない。
わたしたちは、あなたが抑制したいと意図する警告以外の警告を失わないようにするために、可能な限り小さいコード断片にたいしてこの構文を使用することを推奨する。
変数byte-compile-warnings
をセットすることにより、コンパイラーの警告をより詳細に制御できます。詳細は変数のドキュメント文字列を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バイトコンパイルされた関数は、バイトコード関数オブジェクト(byte-code function objects)という特別なデータ型をもちます。関数呼び出しとしてそのようなオブジェクトが出現したとき、Emacsはそのバイトコードを実行するために、常にバイトコードインタープリターを使用します。
内部的にはバイトコード関数オブジェクトはベクターとよく似ています。バイトコード関数オブジェクトの要素にはaref
を通じてアクセスできます。バイトコード関数オブジェクトのプリント表現(printed
representation)はベクターと似ていて、開き‘[’の前に‘#’が追加されます。バイト関数オブジェクトは少なくとも4つの要素をもたねばならず、その要素数に上限はありません。しかし通常使用されるのは最初の6要素です。これらは:
引数の記述子(descriptor)。これは引数リストのその他機能で説明されるような引数のリスト、または要求される引数の個数をエンコードする整数のいずれかである。後者の場合、その記述子の値は0ビットから6ビットで引数の最小個数、8ビットから14ビットで引数の最大個数を指定する。引数リストが&rest
を使用するなら7ビットがセットされて、それい以外ならクリアーされる。
argdescがリストなら、そのバイトコード実行前に引数はダイナミックにバインドされる。argdescが整数なら、引数リストはそのバイトコード実行前にバイトコーピンタープリンターのスタックにpushされる。
バイトコード命令を含む文字列。
バイトコードにより参照されるLispオブジェクトのベクター。関数名と変数名に使用されるシンボルが含まれる。
この関数が要するスタックの最大サイズ。
(もしあれば)ドキュメント文字列。それ以外はnil
。ドキュメント文字列がファイルに格納されている場合、値は数字かリストかもしれない。本当のドキュメント文字列の取得には、関数documentation
を使用する(ドキュメント文字列へのアクセスを参照)。
(もしあれば)インタラクティブ仕様。文字列かLisp式。インタラクティブでない関数ではnil
。
以下はバイトコード関数オブジェクトのプリント表現の例です。これはコマンドbackward-sexp
の定義です。
#[256 "\211\204^G^@\300\262^A\301^A[!\207" [1 forward-sexp] 3 1793299 "^p"]
バイトコードオブジェクトを作成するプリミティブな方法はmake-byte-code
です:
この関数はelementsを要素とするバイトコードオブジェクトを構築してリターンする。
あなた自身で要素を収集してバイトコード関数を構築しないでください。それらが矛盾する場合、その関数の呼び出しによりEmacsがクラッシュするかもしれません。これらのオブジェクトの作成は常にバイトコンパイラーにまかせてください。(願わくば)バイトコンパイラーは要素を矛盾なく構築します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
人はバイトコードを記述しません。それはバイトコンパイラーの仕事です。しかし好奇心を満たすために、わたしたちはディスアセンブラを提供しています。ディスアセンブラはバイトコードを人間が読めるフォームに変換します。
バイトコードインタープリターは、シンプルなスタックマシンとして実装されています。これは値を自身のスタックにpushして、計算で使用するためにそれらをpopして取り出し、その結果を再びそのスタックにpushして戻します。バイトコード関数がリターンするときは、スタックから値をpopして取り出し、その関数の値としてリターンします。
それに加えてスタックとバイトコード関数は、値を変数とスタック間で転送することにより、普通のLisp変数を使用したり、バインドやセットを行うことができます。
このコマンドはobjectにたいするディスアセンブルされたコードを表示する。インタラクティブに使用した場合、またはbuffer-or-nameがnil
か省略された場合は、*Disassemble*という名前のバッファーに出力します。buffer-or-nameが非nil
なら、それはバッファーもしくは既存のバッファーの名前でなければならない。その場合は、そのバッファーのポイント位置に出力され、ポイントは出力の前に残りされる。
引数objectには関数名、ラムダ式(ラムダ式を参照)、またはバイトコードオブジェクト(バイトコード関数オブジェクトを参照)を指定できる。ラムダ式ならdisassemble
はそれをコンパイルしてから、そのコンパイル済みコードをディスアセンブルする。
以下にdisassemble
関数を使用した例を2つ示します。バイトコードとLispソースを関連付ける助けとなるように、説明的なコメントを追加してあります。これらのコメントはdisassemble
の出力にはありません。
(defun factorial (integer) "Compute factorial of an integer." (if (= 1 integer) 1 (* integer (factorial (1- integer))))) ⇒ factorial
(factorial 4) ⇒ 24
(disassemble 'factorial) -| byte-code for factorial: doc: Compute factorial of an integer. args: (integer)
0 varref integer ; integer
の値を取得して
; それをスタック上にpushする
1 constant 1 ; スタック上に1をpushする
2 eqlsign ; 2つの値をスタックからpopして取り出し、 ; それらを比較して結果をスタック上にpushする
3 goto-if-nil 1 ; スタックのトップをpopしてテストする
; nil
なら1へ、それ以外はcontinue
6 constant 1 ; スタックのトップに1をpushする
7 return ; スタックのトップの要素をリターンする
8:1 varref integer ;integer
の値をスタック上にpushする 9 constant factorial ;factorial
をスタック上にpushする 10 varref integer ;integer
の値をスタック上にpushする 11 sub1 ;integer
をpopして値をデクリメントする ; スタック上に新しい値をpushする 12 call 1 ; スタックの最初(トップ)の要素を引数として ; 関数factorial
を呼び出す ; リターン値をスタック上にpushする
13 mult ; スタックのトップ2要素をpopして取り出し乗じ ; 結果をスタック上にpushする 14 return ; スタックのトップ要素をリターンする
silly-loop
は幾分複雑です:
(defun silly-loop (n) "Return time before and after N iterations of a loop." (let ((t1 (current-time-string))) (while (> (setq n (1- n)) 0)) (list t1 (current-time-string)))) ⇒ silly-loop
(disassemble 'silly-loop) -| byte-code for silly-loop: doc: Return time before and after N iterations of a loop. args: (n)
0 constant current-time-string ; current-time-string
を
; スタック上のトップにpushする
1 call 0 ; 引数なしでcurrent-time-string
を呼び出し
; 結果をスタック上にpushする
2 varbind t1 ; スタックをpopしてt1
にpopされた値をバインドする
3:1 varref n ; 環境からn
の値を取得して
; その値をスタック上にpushする
4 sub1 ; スタックのトップから1を減ずる
5 dup ; スタックのトップを複製する ; たとえばスタックのトップをコピーしてスタック上にpushする 6 varset n ; スタックのトップをpopして ;n
をその値にバインドする ;; (要はシーケンスdup varset
はpopせずに ;; スタックのトップをn
の値にコピーする)
7 constant 0 ; スタック上に0をpushする 8 gtr ; スタックのトップ2値をpopして取り出し ; nが0より大かテストし ; 結果をスタック上にpushする
9 goto-if-not-nil 1 ; n
> 0なら1へ
; (これはwhile-loopを継続する)
; それ以外はcontinue
12 varref t1 ;t1
の値をスタック上にpushする 13 constant current-time-string ;current-time-string
を ; スタックのトップにpushする 14 call 0 ; 再度current-time-string
を呼び出す
15 unbind 1 ; ローカル環境のt1
をアンバインドする
16 list2 ; スタックのトップ2要素をpopして取り出し
; それらのリストを作りスタック上にpushする
17 return ; スタックのトップの値をリターンする
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispプログラム内の問題を見つけて詳細に調べる方法がいくつかあります。
入出力の問題をデバックする便利なその他のツールとして、ドリブルファイル(dribble file: 端末の入力を参照)と、open-termscript
関数(端末の出力)があります。
17.1 Lispデバッガ | Emacs Lisp評価機能にたいするデバッガ。 | |
17.2 Edebug | Emacs Lispソースレベルデバッガ。 | |
17.3 無効なLisp構文のデバッグ | シンタックスエラーを見つける方法。 | |
17.4 カバレッジテスト | プログラムのすべての分岐を確実にテストする。 | |
17.5 プロファイリング | あなたのコードが使用するリソースの計測。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
普通のLispデバッガは、フォーム評価のサスペンド機能を提供します。評価がサスペンド(一般的にはbreakの状態として知られる)されている間、実行時スタックを調べたり、ローカル変数やグローバル変数の値を調べたり変更することができます。breakは再帰編集(recursive edit)なので、Emacsの通常の編集機能が利用可能です。デバッガにエンターするようにプログラムを実行することさえ可能です。再帰編集を参照してください。
17.1.1 エラーによるデバッガへのエンター | エラー発生時にデバッガにエンターする。 | |
17.1.2 無限ループのデバッグ | exitしないプログラムの停止デバッグ。 | |
17.1.3 関数呼び出しによるデバッガへのエンター | 特定の関数が呼び出されたときにデバッガにエンターする。 | |
17.1.4 明示的なデバッガへのエントリー | プログラム内の特定箇所でデバッガにエンターする。 | |
17.1.5 デバッガの使用 | デバッガが行なうこと: そこで何を目にするか。 | |
17.1.6 デバッガのコマンド | デバッガで使用するコマンド。 | |
17.1.7 デバッガの呼び出し | 関数debug の呼び出し方。
| |
17.1.8 デバッガの内部 | デバッガのサブルーチンとグローバル変数。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
デバッガに入るタイミングとして一番重要なのは、Lispエラーが発生したときです。デバッガではエラーの直接原因を調査できます。
しかしデバッガへのエンターは、エラーによる通常の結末ではありません。多くのコマンドは不適切に呼び出されたときにLispエラーをシグナルするので、通常の編集の間にこれが発生するたびデバッガにエンターするのは、とても不便でしょう。したがってエラーの際にデバッガにエンターしたいなら、変数debug-on-error
に非nil
をセットします(コマンドtoggle-debug-on-error
はこれを簡単に行う方法を提供する)。
この変数はエラーがシグナルされて、それがハンドルされていないときにデバッガを呼び出すかどうかを決定する。debug-on-error
がt
なら、debug-ignored-errors
(以下参照)にリストされているエラー以外の、すべての種類のエラーがデバッガを呼び出す。nil
ならデバッガを呼び出さない。
値にはエラー条件(エラーをシグナルする方法を参照)のリストも指定できる。その場合はこのリスト内のエラー条件だけによってデバッガが呼び出される(debug-ignored-errors
にもリストされているエラー条件は除外される)。たとえばdebug-on-error
をリスト(void-variable)
にセットすると、値をもたない変数に関するエラーにたいしてのみデバッガが呼び出される。
eval-expression-debug-on-error
がこの変数をオーバーライドするケースがいくつかあることに注意(以下参照)。
この変数が非nil
のとき、Emacsはプロセスフィルター関数と番兵(sentinel)の周囲にエラーハンドラーを作成しない。したがってこれらの関数内でのエラーは、デバッガを呼び出す。プロセスを参照のこと。
この変数はdebug-on-error
の値に関わらず、デバッガにエンターすべきでないエラーを指定する。変数の値はエラー条件のシンボルおよび/または正規表現のリスト。エラーがこれら条件シンボルのいずれか、またはエラーメッセージが正規表現のいずれかにマッチすれば、そのエラーはデバッガにエンターしない。
この変数の通常の値にはuser-error
、および編集中に頻繁に発生するがLispプログラムのバグに起因することは稀であるような、いくつかのエラーが含まれる。しかし“稀である”ことは“絶対ない”ということではない。あなたのプログラムがこのリストにマッチするエラーによって機能しないなら、そのエラーをデバッグするためにこのリストの変更を試みるのもよいだろう。通常はdebug-ignored-errors
をnil
にセットしておくのが、もっとも簡単な方法である。
この変数が非nil
値(デフォルト)なら、コマンドeval-expression
の実行によって一時的にdebug-on-error
がt
がバインドされる。Evaluating Emacs-Lisp Expressions in The GNU Emacs
Manualを参照のこと。
eval-expression-debug-on-error
がnil
なら、eval-expression
の間もdebug-on-error
の値は変更されない。
condition-case
でキャッチされたエラー、は通常は決してデバッガを呼び出さない。condition-case
はデバッガがそのエラーをハンドルする前にエラーをハンドルする機会を得る。
debug-on-signal
を非nil
値に変更すると、condition-case
の存在如何に関わらずすべてのエラーにおいてデバッガが最初に機会を得る(デバッガを呼び出すためには依然としてそのエラーがdebug-on-error
とdebug-ignored-errors
で指定された条件を満たさなければならない)。
警告:
この変数を非nil
にセットすると、芳しくない効果があるかもしれない。Emacsのさまざまな部分で処理の通常の過程としてエラーがキャッチされており、そのエラーが発生したことに気づかないことさえあるかもしれない。condition-case
でラップされたコードをデバッグする必要があるなら、condition-case-unless-debug
(see section エラーを処理するコードの記述を参照)の使用を考慮されたい。
debug-on-event
をスペシャルイベント(スペシャルイベントを参照)にセットすると、Emacsはspecial-event-map
をバイパスしてこのイベントを受け取ると即座にデバッガへのエンターを試みる。現在のところサポートされる値は、シグナルSIGUSR1
とSIGUSR2
に対応する値のみ(これがデフォルト)。これはinhibit-quit
がセットされていて、それ以外はEmacsが応答しない場合に有用かもしれない。
debug-on-message
に正規表現をセットした場合は、それにマッチするメッセージがエコーエリアに表示されると、Emacsはデバッガにエンターする。たとえばこれは特定のメッセージの原因を探すのに有用かもしれない。
initファイルロード中に発生したエラーをデバッグするには、オプション‘--debug-init’を使用する。これはinitファイルロードの間にdebug-on-error
をt
にバインドして、通常はinitファイル内のエラーをキャッチするcondition-case
をバイパスする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プログラムが無限にループしてリターンできないとき、最初の問題はそのループをいかに停止するかです。ほとんどのオペレーティングシステムでは、(quitさせる)C-gでこれを行うことができます。quitを参照してください。
普通のquitでは、なぜそのプログラムがループしたかについての情報は与えられません。変数debug-on-quit
に非nil
をセットすることにより、より多くの情報を得ることができます。無限ループの途中でデバッガを実行すれば、デバッガからステップコマンドで先へ進むことができます。ループ全体をステップで追えば、問題を解決するために十分な情報が得られるでしょう。
C-gによるquitはエラーとは判断されないので、C-gのハンドルにdebug-on-error
は効果がありません。同じようにdebug-on-quit
はエラーにたいして効果がありません。
この変数はquit
がシグナルされて、それがハンドルされていないときにデバッガを呼び出すかどうかを決定する。debug-on-quit
が非nil
なら、quit(つまりC-gをタイプ)したときは常にデバッガが呼び出される。debug-on-quit
がnil
(デフォルト)なら、quitしてもデバッガは呼び出されない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プログラムの途中で発生する問題を調べるための有用なテクニックの1つは、特定の関数が呼び出されたときデバッガにエンターする方法です。問題が発生した関数にこれを行ってその関数をステップで追ったり、問題箇所の少し手前の関数呼び出しでこれを行って、その関数をステップオーバーしてその後をステップで追うことができます。
この関数はfunction-nameが呼び出されるたびにデバッガの呼び出しを要求する。
Lispコードで定義された任意の関数とマクロは、インタープリターに解釈されたコードかコンパイル済みのコードかに関わらず、エントリーにbreakをセットできる。その関数がコマンドならLispから呼び出されたときと、インタラクティブに呼び出されたときにデバッガにエンターする。(たとえばCで記述された)プリミティブ関数にもこの方法でdebug-on-entry
をセットできるが、そのプリミティブがLispコードから呼び出されたときだけ効果がある。debug-on-entry
はスペシャルフォームにはセットできない。
debug-on-entry
がインタラクティブに呼び出されたときは、ミニバッファーでfunction-nameの入力を求める。その関数がすでにエントリーでデバッガを呼び出すようにセットアップされていたら、debug-on-entry
は何も行わない。debug-on-entry
は常にfunction-nameをリターンする。
以下はこの関数の使い方を説明するための例である:
(defun fact (n) (if (zerop n) 1 (* n (fact (1- n))))) ⇒ fact
(debug-on-entry 'fact) ⇒ fact
(fact 3)
------ Buffer: *Backtrace* ------ Debugger entered--entering a function: * fact(3) eval((fact 3)) eval-last-sexp-1(nil) eval-last-sexp(nil) call-interactively(eval-last-sexp) ------ Buffer: *Backtrace* ------
この関数はfunction-nameにたいするdebug-on-entry
の効果をアンドゥする。インタラクティブに呼び出されたときは、ミニバッファーでfunction-nameの入力を求める。function-nameが省略またはnil
なら、すべての関数にたいするbreak-on-entryをキャンセルする。エントリー時にbreakするようセットアップされていない関数にcancel-debug-on-entry
を呼び出したときは何も行わない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プログラム内の特定箇所に式(debug)
を記述することによって、その箇所でデバッガが呼び出されるようにできます。これを行うにはソースファイルをvisitして、適切な箇所にテキスト‘(debug)’を挿入し、C-M-x(Lispモードでのeval-defun
にたいするキーバインド)をタイプします。警告:
一時的なデバッグ目的のためにこれを行なう場合には、ファイルを保存する前に確実にアンドゥしてください!
‘(debug)’を挿入する箇所は追加フォームが評価されることができ、かつその値を無視することができる箇所でなければなりません(‘(debug)’の値を無視しないとプログラムの実行が変更されてしまうだろう!)。一般的にもっとも適した箇所は、progn
または暗黙的なprogn
(順序を参照)の内部です。
デバッグ命令を配置したいソースコード中の正確な箇所がわからないが、特定のメッセージが表示されたときにバックトレースを表示したい場合には、意図するメッセージにマッチする正規表現をdebug-on-message
にセットできます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
デバッガにエンターすると、その前に選択されていたウィンドウを1つのウィンドウに表示して、他のウィンドウに*Backtrace*という名前のバッファーを表示します。backtraceバッファーには、現在実行されているLisp関数の各レベルが1行ずつ含まれます。このバッファーの先頭は、デバッガが呼び出された理由を説明するメッセージ(デバッガがエラーにより呼び出された場合はエラーメッセージや関連するデータなど)です。
backtraceバッファーは読み取り専用で、文字キーにデバッガコマンドが定義されたDebuggerモードという特別なメジャーモードを使用します。通常のEmacs編集コマンドが利用できます。したがってエラー時に編集されていたバッファーを調べるためにウィンドウを切り替えたり、バッファーの切り替えやファイルのvisit、その他一連の編集処理を行なうことができます。しかしデバッガは再帰編集レベル(再帰編集を参照)にあり、編集が終わったらそれはbacktraceバッファーに戻って、(qコマンドで)デバッガをexitできます。デバッガをexitすることによって再帰編集を抜け出し、backtraceバッファーはバリー(bury:
覆い隠す)されます(変数debugger-bury-or-killw
をセットすることによってbacktraceバッファーでqコマンドが何を行うかをカスタマイズできる。たとえばバッファーをバリーせずにkillしたいなら、この変数をkill
にセットする。他の値については変数のドキュメントを調べてほしい)。
デバッガにエンターしたとき、eval-expression-debug-on-error
に一致するように変数debug-on-error
が一時的にセットされます。変数eval-expression-debug-on-error
が非nil
なら、debug-on-error
は一時的にt
にセットされます。これはデバッグセッション行っている間にさらにエラーが発生すると、(デフォルトでは)他のbacktraceがトリガーされることを意味します。これが望ましくなければ、debugger-mode-hook
内でeval-expression-debug-on-error
をnil
にセットするか、debug-on-error
をnil
にセットすることができます。
backtraceバッファーは実行されている関数と、その関数の引数の値を示します。そのフレームを示す行にポイントを移動して、スタックフレームを指定することもできます(スタックフレームとは、Lispインタープリターがある関数への特定の呼び出しを記録する場所のこと)。行ポイントがオンのフレームが、カレントフレーム(current frame)となります。デバッガコマンドのいくつかは、カレントフレームを処理します。ある行がスター(star)で始まる場合は、そのフレームをexitすることによって再びデバッガが呼び出されることを意味します。これは関数のリターン値を調べるとき有用です。
関数名にアンダーラインが引かれている場合は、デバッガがその関数のソースコードの位置を知っていることを意味します。その名前をマウスでクリックするか、そこに移動してRETをタイプすれば、ソースコードをvisitできます。
デバッガはデバッガ自身のスタックフレーム数を想定するため、バイトコンパイルされて実行されなければなりません。デバッガがインタープリターに解釈されて実行されているときは、これらの想定は正しくなくなります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
(Debuggerモードの)debuggerバッファーでは、通常のEmacsコマンドに加えて特別なコマンドが提供されます。デバッガでもっとも重要な使い方をするのは、制御フローを見ることができるコードをステップ実行するコマンドです。デバッガはインタープリターによって解釈された制御構造のステップ実行はできますが、バイトコンパイル済みの関数ではできません。バイトコンパイル済み関数をステップ実行したいなら、同じ関数の解釈された定義に置き換えてください(これを行なうにはその関数のソースをvisitして、関数の定義でC-M-xとタイプする)。プリミティブ関数のステップ実行にLispデバッガは使用できません。
以下はDebuggerモードのコマンドのリストです:
デバッガをexitして実行を継続する。これはあたかもデバッガにエンターしなかったかのようにプログラムの実行を再開する(デバッガ内で行った変数値やデータ構造の変更などの副作用は除外)。
実行を継続するが、次にLisp関数が何か呼び出されたときはデバッガにエンターする。これによりある式の下位の式をステップ実行して、下位の式が計算する値や行うことを確認できる。
デバッガにエンターした関数呼び出しにたいして、この方法で作成されたスタックフレームには自動的にフラグがつくため、そのフレームをexitすると再びデバッガが呼び出される。このフラグはuコマンドを使用してキャンセルできる。
カレントフレームにフラグをつけるので、そのフレームをexitするときデバッガにエンターする。この方法でフラグがつけられたフレームは、backtraceバッファーでスターのマークがつく。
カレントフレームをexitしたときデバッガにエンターしない。これはそのフレームのbコマンドをキャンセルする。目に見える効果としてはbacktraceバッファーの行からスターが削除される。
bと同じようにカレントフレームにフラグをつける。その後にcのように実行を継続するが、debug-on-entry
によりセットアップされたすべての関数にたいするbreak-on-entryを一時的に無効にする。
ミニバッファーのLisp式を読み取り、(関連するlexical環境が適切なら)それを評価してエコーエリアに値をプリントする。デバッガは特定の重要な変数とバッファーを処理の一部として変更する。eは一時的にデバッガの外部からそれらの値をリストアするので、それらを調べて変更できる。これによりデバッガはより透過的になる。対照的にデバッガ内でM-:は特別なことを行わず、デバッガ内での変数の値を表示する。
eと同様だがバッファー*Debugger-record*内の評価結果も保存する。
デバッグされているプログラムを終了して、Emacsコマンド実行のトップレベルにリターンする。
C-gによりデバッガにエンターしたが、実際はデバッグではなくquitしたいときはqコマンドを使用する。
デバッガから値をリターンする。ミニバッファーで式を読み取ってそれを評価することにより値が計算される。
dコマンドは、(bによるリクエストやdによるそのフレームへのエンターによる)Lisp呼び出しフレームからのexitでデバッガが呼び出されたときに有用である。rコマンドで指定された値は、そのフレームの値として使用される。これはdebug
を呼び出して、そのリターン値を使用するときにも有用。それ以外はrはcと同じ効果をもち、指定されたリターン値は問題とはならない。
エラーによりデバッガにエンターしたときはrコマンドは使用できない。
呼び出されたときにデバッガを呼び出す関数をリストする。これはdebug-on-entry
によりエントリー時にbreakするようセットされた関数のリストである。
カレントスタックフレームのローカル変数の表示を切り替える。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下ではデバッガを呼び出すために使用される関数debug
の完全な詳細を説明します。
この関数はデバッガにエンターする。この関数は*Backtrace*(デバッガへの2回目以降の再帰エントリーでは*Backtrace*<2>、...)という名前のバッファーにバッファーを切り替えて、Lisp関数呼び出しについての情報を書き込む。それから再帰編集にエンターして、Debuggerモードでbacktraceバッファーを表示する。
Debuggerモードのコマンドc、d、j、rは再帰編集をexitする。その後、debug
は以前のバッファーに戻って、debug
を呼び出したものが何であれそこにリターンする。これは関数debug
が呼び出し元にリターンできる唯一の方法である。
debugger-argsを使用すると、debug
は*Backtrace*の最上部に残りの引数を表示するしてユーザーがそれらを確認できる。以下で説明する場合を除いて、これはこれらの引数を使用する唯一の方法である。
しかしdebug
への1つ目の引数にたいする値は、特別な意味をもつ(これらの値は通常はdebug
を呼び出すプログラマーではなく、Emacs内部でのみ使用される)。以下はこれら特別な値のテーブルである:
lambda
1つ目の引数がlambda
のなら、それはdebug-on-next-call
が非nil
のときに関数にエントリーしたことによってdebug
が呼び出されたことを意味する。デバッガはバッファーのトップのテキスト行に‘Debugger
entered--entering a function:’と表示する。
debug
1つ目の引数がdebug
なら、それはエントリー時にデバッグされるようにセットされた関数にエントリーしたことにってdebug
が呼び出されたことを意味する。デバッガはlambda
のときと同様、‘Debugger
entered--entering a
function:’を表示する。これはその関数のスタックフレームもマークするので、exit時にデバッガが呼び出される。
t
1つ目の引数がt
なら、それはdebug-on-next-call
が非nil
のときに関数呼び出しの評価によってdebug
が呼び出されたことを示す。デバッガはバッファーのトップの行に‘Debugger
entered--beginning evaluation of function call form:’と表示する。
exit
1つ目の引数がexit
のときは、exit時にデバッガを呼び出すよう以前にマークされたスタックフレームをexitしたことを示す。この場合はdebug
に与えられた2つ目の引数がそのフレームからリターンされた値になる。デバッガはバッファーのトップの行に‘Debugger
entered--returning value:’とリターンされた値を表示する。
error
1つ目の引数がerror
のときは、ハンドルされていないエラーまたはquit
がシグナルされてデバッガにエンターした場合であり、デバッガは‘Debugger
entered--Lisp error:’とその後にシグナルされたエラーとsignal
への引数を表示してそれを示す。たとえば、
(let ((debug-on-error t)) (/ 1 0))
------ Buffer: *Backtrace* ------ Debugger entered--Lisp error: (arith-error) /(1 0) ... ------ Buffer: *Backtrace* ------
エラーがシグナルされた場合はおそらく変数debug-on-error
は非nil
で、quit
がシグナルされた場合はおそらく変数debug-on-quit
は非nil
である。
nil
明示的にデバッガにエンターしたいときは、debugger-argsの1つ目の引数にnil
を使用する。残りのdebugger-argsはバッファーのトップの行にプリントされる。メッセージ
— たとえばdebug
が呼び出された条件を思い出すためのリマインダーとして — の表示にこの機能を使用できる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではデバッガ内部で使用される関数と変数について説明します。
この関数の値はデバッガを呼び出す関数呼び出しである。値には任意個数の引数をとる関数、より具体的には関数の名前でなければならない。この関数は何らかのデバッガを呼び出すこと。この変数のデフォルト値はdebug
。
関数にたいしてLispが渡す1つ目の引数は、その関数がなぜ呼び出されたかを示す。引数の慣習についてはdebug
(デバッガの呼び出し)に詳解がある。
この関数は現在アクティブなLisp関数呼び出しのトレースをプリントする。この関数はdebug
が*Backtrace*バッファーに書き込む内容を得るために使用される。どの関数呼び出しがアクティブか判断するためにスタックにアクセスしなければならないので、この関数はCで記述されている。リターン値は常にnil
。
以下の例ではLisp式で明示的にbacktrace
を呼び出している。これはストリームstandard-output
(この場合はバッファー‘backtrace-output’)にbacktraceをプリントする。
backtraceの各行は、1つの関数呼び出しを表す。関数の引数が既知なら行に値が表示され、まだ計算中の場合は行にその旨が示される。スペシャルフォームの引数は無視される。
(with-output-to-temp-buffer "backtrace-output" (let ((var 1)) (save-excursion (setq var (eval '(progn (1+ var) (list 'testing (backtrace)))))))) ⇒ (testing nil)
----------- Buffer: backtrace-output ------------ backtrace() (list ...computing arguments...)
(progn ...) eval((progn (1+ var) (list (quote testing) (backtrace)))) (setq ...) (save-excursion ...) (let ...) (with-output-to-temp-buffer ...) eval((with-output-to-temp-buffer ...)) eval-last-sexp-1(nil)
eval-last-sexp(nil) call-interactively(eval-last-sexp) ----------- Buffer: backtrace-output ------------
この変数が非nil
なら、それは次のeval
、apply
、funcall
の前にデバッガを呼び出すよう指定する。デバッガへのエンターによってdebug-on-next-call
はnil
にセットされる。
デバッガのdコマンドは、この変数をセットすることにより機能します。
この関数はそのスタックフレームのlevel下位のスタックフレームのdebug-on-exitフラグにflagに応じた値をセットする。flagが非nil
なら、後でそのフレームをexitするときデバッガにエンターする。そのフレームを通じた非ローカルexitでも、デバッガにエンターする。
この関数はデバッガだけに使用される。
この変数はカレントのインタラクティブコマンドのデバッグ状態を記録する。コマンドがインタラクティブに呼び出されるたびに、この変数はnil
にバインドされる。デバッガは同じコマンドが呼び出されたときのデバッガ呼び出しに情報を残すために、この変数をセットできる。
普通のグローバル変数ではなくこの変数を使用する利点は、そのデータが後続のコマンド呼び出しに決して引き継がれないことである。
関数backtrace-frame
はLispデバッガ内での使用を意図している。これはframe-numberレベル下位のスタックフレームで、何の評価が行われているかに関する情報をリターンする。
そのフレームがまだ引数を評価していない、またはそのフレームがスペシャルフォームの場合、値は(nil function
arg-forms…)
。
そのフレームが引数を評価して関数をすでに呼び出していたら、リターン値は(t function
arg-values…)
。
リターン値のfunctionは何であれ評価されたリストのCARとして提供される。マクロ呼び出しの場合はlambda
式になる。その関数に&rest
引数があればリストarg-valuesの末尾に示される。
frame-numberが範囲外ならbacktrace-frame
はnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
EdebugはEmacs Lispプログラムにたいするソースレベルデバッガです。これにより以下のことができます:
以下の初めの3つのセクションは、Edebugの使用を開始するために十分な説明を行います。
17.2.1 Edebugの使用 | Edebug使用のための手引き。 | |
17.2.2 Edebugのためのインストルメント | Edebugでデバッグするために、コードをインストルメント(計装)しなければならないe | |
17.2.3 Edebugの実行モード | 多かれ少なかれ、ストップする実行モード。 | |
17.2.4 ジャンプ | 特定の位置にジャンプするコマンド。 | |
17.2.5 その他のEdebugコマンド | さまざまなコマンド。 | |
17.2.6 ブレーク | プログラムをストップさせるbreakpointのセット。 | |
17.2.7 エラーのトラップ | Edebugでのエラーのトラップ。 | |
17.2.8 Edebugのビュー | Edebugの内側と外側のビュー。 | |
17.2.9 評価 | Edebugでの式の評価。 | |
17.2.10 評価 List Buffer | Edebugにエンターするたびに値が表示される式。 | |
17.2.11 Edebugでのプリント | プリントのカスタマイズ。 | |
17.2.12 トレースバッファー | バッファー内で採れを生成する方法。 | |
17.2.13 カバレッジテスト | 評価をカバレッジテストする方法。 | |
17.2.14 コンテキスト外部 | Edebugが保存およびリストアするデータ。 | |
17.2.15 Edebugとマクロ | マクロ呼び出しをハンドルする方法の指定。 | |
17.2.16 Edebugのオプション | Edebugをカスタマイズするオプション変数。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
EdebugでLispプログラムをデバッグするには、最初にデバッグしたいLispコードをインストルメント(instrument:
計装)しなければなりません。これを行なうもっともシンプルな方法は、関数またはマクロの定義に移動してC-u
C-M-x(プレフィクス引数を指定したeval-defun
)を行います。コードをインストルメントする他の手段については、Edebugのためのインストルメントを参照してください。
一度関数をインストルメントすると、その関数にたいする任意の呼び出しによってEdebugがアクティブになります。Edebugがアクティブになると、どのEdebug実行モードを選択したかに依存して、その関数をステップ実行できるように実行がストップされるか、ディスプレイを更新してデバッグコマンドにたいするチェックの間、実行が継続されます。デフォルトの実行モードstepで、これは実行をストップします。Edebugの実行モードを参照してください。
Edebugでは通常は、デバッグしているLispコードをEmacsバッファーで閲覧します。これをソースコードバッファー(source code buffer)と呼び、バッファーは一時的に読み取り専用になります。
左フリンジの矢印は、その関数で実行されている行を示します。ポイントは最初はその関数の実行されている行にありますが、ポイントを移動するとこれは真ではなくなります。
以下はfac
の定義(以下を参照)をインストルメントして(fac
3)
を実行した場合に通常目にするものです。ポイントはif
の前の開きカッコにあります。
(defun fac (n) =>∗(if (< 0 n) (* n (fac (1- n))) 1))
関数内でEdebugが実行をストップできる位置のことを、ストップポイント(stop
points)と呼びます。ストップポイントはリストであるような部分式の前後、および変数参照の後でも発生します。以下は関数fac
内のストップポイントをピリオドで示したものです:
(defun fac (n) .(if .(< 0 n.). .(* n. .(fac .(1- n.).).). 1).)
Emacs
Lispモードのコマンドに加えて、ソースコードバッファーではEdebugのスペシャルコマンドが利用できます。たとえばEdebugコマンドSPCで次のストップポイントまで実行することができます。fac
にエントリーした後に一度SPCとタイプした場合は、以下のように表示されるでしょう:
(defun fac (n) =>(if ∗(< 0 n) (* n (fac (1- n))) 1))
式の後でEdebugが実行をストップしたときは、エコーエリアにその式の値が表示されます。
他にも頻繁に使用されるコマンドとして、ストップポイントにbreakpointをセットするb、breakpointに達するまで実行するg、Edebugをexitしてトップレベルのコマンドループにリターンするqがあります。また?とタイプするとすべてのEdebugコマンドがリストされます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
LispコードのデバッグにEdebugを使用するためには、最初にそのコードをインストルメント(instrument: 計装)しなければなりません。コードをインストルメントすると、適切な位置でEdebugを呼び出すために追加コードが挿入されます。
関数定義でプレフィクス引数とともにコマンドC-M-x
(eval-defun
)を呼び出すと、それを評価する前にその定義をインストルメントします(ソースコード自体は変更しない)。変数edebug-all-defs
が非nil
ならプレフィクス引数の意味を反転します。この場合は、C-M-xはプレフィクス引数がなければその定義をインストルメントします。edebug-all-defs
のデフォルト値はnil
です。コマンドM-x
edebug-all-defsは変数edebug-all-defs
の値を切り替えます。
edebug-all-defs
が非nil
ならeval-region
、eval-current-buffer
、eval-buffer
もそれらが評価する定義をインストルメントします。同様にedebug-all-forms
は、eval-region
が(非定義フォームさえ含むあらゆるフォームをインストルメントするべきかを制御します。これはミニバッファー内でのロードや評価には適用されません。コマンドM-x
edebug-all-formsはこのオプションを切り替えます。
他にもコマンドM-x
edebug-eval-top-level-formが利用でき、これはedebug-all-defs
やedebug-all-forms
の値に関わらずトップレベルのすべてのフォームをインストルメントします。edebug-defun
はedebug-eval-top-level-form
のエイリアスです。
Edebugがアクティブのの間、コマンドI(edebug-instrument-callee
)はポイント後のリストフォームに呼び出される関数およびマクロ定義がまだインストルメントされていなければ、それらをインストルメントします。これはそのファイルのソースの場所をEdebugが知っている場合だけ可能です。この理由によりEdebugロード後は、たとえ評価する定義をインストルメントしない場合でも、eval-region
は評価するすべての定義の位置を記録します。インストルメント済み関数呼び出しにステップインするiコマンドも参照してください(ジャンプを参照)。
Edebugはすべての標準スペシャルフォーム、式引数をもつinteractive
フォーム、無名ラムダ式、およびその他の定義フォームのインストルメント方法を知っています。しかしEdebugはユーザー定義マクロが引数にたいして何を行うかを判断できないので、Edebug仕様を使用してその情報を与えなければなりません。詳細はEdebugとマクロを参照してください。
Edebugがセッション内で最初にコードをインストルメントしようとするときは、フックedebug-setup-hook
を実行してからそれにnil
をセットします。使おうとしているパッケージに結びつけてEdebug仕様をロードするためにこれを使用できますが、それはEdebugを使用するときだけ機能します。
定義からインストルメントを削除するには、単にインストルメントを行わない方法でその定義を再評価するだけです。フォームを絶対にインストルメントせずに評価するには2つの方法があります。それはファイルからのload
による評価と、ミニバッファーからのeval-expression
(M-:)による評価です。
Edebugがインストルメント中にシンタックスエラー(syntax error:
構文エラー)を検知した場合は、間違ったコードの箇所にポイントを残してinvalid-read-syntax
エラーをシグナルします。
Edebug内で利用可能な他の評価関数については、評価を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Edebugはデバッグするプログラムの実行にたいして、いくつかの実行モードをサポートします。これらの実行モードをEdebug実行モード(Edebug execution modes)と呼びます。これらをメジャーモードやマイナーモードと混同しないでください。カレントのEdebug実行モードは、プログラムをストップする前にEdebugがどれだけ実行を継続するか — たとえばストップポイントごとにストップ、あるいは次のbreakpointまで継続など — 、およびストップする前にEdebugがどれだけ進捗を表示するかを決定します。
Edebug実行モードは、通常はある特定のモードでプログラムを継続させるコマンドをタイプすることによって指定します。以下はそれらのコマンドのテーブルです。S以外のコマンドはプログラムの実行を再開して、少なくともある長さの間だけは実行を継続します。
Stop(ストップ): これ以上プログラムを実行しないでEdebugのコマンドを待つ(edebug-stop
)。
Step(ステップ): 次のストップポイントでストップする(edebug-step-mode
)。
Next(次へ):
式の後にある次のストップポイントでストップする(edebug-next-mode
)。ジャンプのedebug-forward-sexp
も参照のこと。
Trace(トレース): Edebugのストップポイントごとにpause(通常は1秒)する(edebug-trace-mode
)。
Rapid
trace(高速でトレース):ストップポイントごとに表示を更新するが、実際にpauseはしない(edebug-Trace-fast-mode
)。
Go(進む): 次のbreakpointまで実行する(edebug-go-mode
)。Edebugのブレークポイントを参照のこと。
Continue(継続): breakpointごとにpauseしてから継続する(edebug-continue-mode
)。
Rapid continue(高速で継続):
ポイントを各breakpointへ移動するがpauseしない(edebug-Continue-fast-mode
)。
Go non-stop(ストップせず進む):
breakpointを無視する(edebug-Go-nonstop-mode
)。まだSやその他の編集コマンドでプログラムをストップするのは可能。
一般的に上記リストの最初のほうにある実行モードは後のほうの実行モードに比べて、プログラムをより低速に実行するか、すぐにストップさせます。
新たなEdebugレベルにエンターしたとき、Edebugは通常は最初に遭遇したインストルメント済みの関数でストップするでしょう。breakpointでのみストップするか、(たとえばカバレッジデータ収集時など)ストップさせないようにするには、edebug-initial-mode
の値をデフォルトのstep
からgo
かGo-nonstop
、あるいはその他の値に変更してください(Edebugのオプションを参照)。C-x C-a C-m
(edebug-set-initial-mode
)でこれを容易に行うことができます:
C-x C-a
C-mにバインドされるこのコマンドはedebug-initial-mode
をセットする。これはモードを示すキーの入力を求める。対応するモードをセットする上述8つのキーのいずれかを入力すること。
たとえば1つのコマンドからインストルメント済みの関数が複数回呼び出されたら、同じEdebugレベルに再エンターするかもしれないことに注意してください。
実行中とトレース中は、任意のEdebugコマンドをタイプすることによって実行をインタラプト(interrupt: 中断、割り込み)できます。Edebugは次のストップポイントでプログラムをストップしてからタイプされたコマンドを実行します。たとえば実行中にtをタイプすると、次のストップポイントでトレースモードに切り替えます。Sを使用すれば他に何も行わずに実行をストップできます。
関数でたまたま読み取り入力が発生した場合には、実行のインタラプトを意図してタイプされた文字は、かわりにその関数により読み取られます。そのプログラムが入力を欲するタイミングに注意を払うことで、そのような意図せぬ結果を避けることができます。
このセクションのコマンドを含むキーボードマクロは、完全には機能しません。プログラムを再開するためにEdebugからexitすると、キーボードマクロの追跡記録は失われます。これに対処するのは簡単ではありません。またEdebug外部でキーボードマクロを定義または実行しても、Edebug内部のコマンドに影響しません。通常これは利点です。Edebugのオプション内のedebug-continue-kbd-macro
オプションも参照してください。
このオプションはtraceモードとcontinueモードで実行ステップの間を何秒待つか指定する。デフォルトは1秒。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションで説明するコマンドは、指定された場所に達するまで実行を続けます。iを除くすべてのコマンドは、ストップ場所を確立するために一時的なbreakpointを作成してからgoモードにスイッチします。意図されたストップポイントの前にある他のストップポイントに達した場合にも実行はストップします。breakpointの詳細は、Edebugのブレークポイントを参照してください。
以下のコマンドでは、非ローカルexitはプログラムのストップを望む一時的なbreakpointをバイパスできるので、期待どおり機能しないかもしれません。
ポイントがある場所の近くのストップポイントへ実行を進める(edebug-goto-here
)。
プログラムの式を1つ実行する(edebug-forward-sexp
)。
sexpを含む終端までプログラムを実行する(edebug-step-out
)。
ポイントの後のフォームから呼び出された関数かマクロにステップインする(edebug-step-in
)。
hコマンドは一時的なbreakpointを使用してポイントのカレント位置、またはその後のストップポイントまで処理を進めます。
fコマンドは式を1つ飛び越してプログラムを実行します。より正確にはforward-sexp
により到達できる位置に一時的なbreakpointをセットしてからgoモードで実行するので、プログラムはそのbreakpointでストップすることになります。
プレフィクス引数nとともに使用すると、ポイントからn個のsexp(s-expression: S式)を超えた場所に一時的なbreakpointをセットします。ポイントを含むリストがnより少ない要素で終わるような場合には、ストップ箇所はポイントが含まれる式の後になります。
forward-sexp
が見つける位置が、プログラムを実際にストップさせたい位置なのかチェックしなければなりません。たとえばcond
内ではこれは正しくないかもしれません。
fコマンドは柔軟性を与えるために、forward-sexp
をストップポイントではなくポイント位置から開始します。カレントのストップポイントから1つの式を実行したい場合には、まずそこにポイントを移動するためにw(edebug-where
)をタイプして、それからfをタイプしてください。
oコマンドは、式の外側で実行を継続します。これはポイントを含む式の最後に一時的なbreakpointを配置します。ポイントを含むsexpが関数定義ならoはその定義内の最後のsexpの直前まで実行を継続します。もし定義内の最後のsexpの直前にポイントがある場合は、その関数からリターンしてからストップします。言い換えるとこのコマンドは最後のsexpの後にポイントがなければ、カレントで実行中の関数からexitしません。
iコマンドは、ポイントの後のリストフォームに呼び出された関数やマクロにステップインします。そのフォームは評価されようとしているものの1つである必要はないことに注意してください。しかしそのフォームが評価されようとしている関数呼び出しなら、引数が何も評価されないうちにこのコマンドを使用しないと、遅すぎることを覚えておいてください。
iコマンドはステップインしようとしている関数やマクロがまだインストルメントされていなければ、それらをインストルメントします。これは便利かもしれませんが、それらを明示的に非インストルメントしなければ、その関数やマクロはインストルメントされたままになることを覚えておいてください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ここではその他のEdebugコマンドを説明します。
Edebugのヘルプメッセージを表示する(edebug-help
)。
1レベルを中断して以前のコマンドレベルへ戻る(abort-recursive-edit
)。
エディターのトップレベルのコマンドループにリターンする(top-level
)。これはすべてのレベルのEdebugアクティビティを含むすべての再帰編集レベルをexitする。しかしフォームunwind-protect
かcondition-case
で保護されたインストルメント済みのコードはデバッグを再開するかもしれない。
qと同様だが、保護されたコードでもストップしない(edebug-top-level-nonstop
)。
エコーエリアにもっとも最近の既知のコマンドを再表示する(edebug-previous-result
)。
backtraceを表示するが、明確であるようにEdebug自身の関数は除外される(edebug-backtrace
)。
Edebugのbacktraceバッファーでは、標準デバッガ内のようにバッガコマンドは使用できない。
実行を継続したときにbacktraceバッファーは自動的にkillされる。
Edebugから再帰的にEdebugをアクティブにするコマンドを呼び出すことができます。Edebugがアクティブなときは常にqによトップレベルの終了、またはC-]による再帰編集1レベルの中断ができます。dによってすべての未解決な評価のbacktraceを表示できます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Edebugのstepモードは、次のストップポイントに達したときに実行をストップします。一度開始されたEdebugの実行をストップするには、他に3つの方法があります。それはbreakpoint、グローバルbreak条件、およびソースbreakpointです。
17.2.6.1 Edebugのブレークポイント | ストップポイントのbreakpoint。 | |
17.2.6.2 グローバルなブレーク条件 | イベントによるbreak。 | |
17.2.6.3 ソースブレークポイント | ソースコードに埋め込まれたbreakpoint。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Edebugを使用しているときは、テスト中のプログラム内にbreakpointを指定できます。breakpointとは実行がストップされる場所のことです。Edebugの使用で定義されている任意のストップポイントにbreakpointをセットできます。breakpointのセットと解除で影響を受けるストップポイントは、ソースコードバッファー内でポイント位置、またはポイント位置の後の最初のストップポイントです。以下はEdebugのbreakpoint用のコマンドです:
ポイント位置、またはポイント位置の後のストップポイントにbreakpointをセットする(edebug-set-breakpoint
)。プレフィクス引数を使用すると、それは一時的なbreakpointとなり、プログラムが最初にそこで停止したときに解除される。
(もしあれば)ポイント位置、またはポイント位置の後のストップポイントにあるbreakpointを解除(unset)する(edebug-unset-breakpoint
)。
conditionを評価して非nil
値になる場合だけプログラムをストップする条件付きbreakpointをセットする(edebug-set-conditional-breakpoint
)。プレフィクス引数を指定すると一時的なbreakpointになる。
カレント定義内の次のbreakpointにポイントを移動する(edebug-next-breakpoint
)。
Edebug内ではbでbreakpointをセットして、uでそれを解除できます。最初に望ましいストップポイントにポイントを移動してから、そこにbreakpointをセットまたは解除するためにbまたはuをタイプします。breakpointがない場所でbreakpointを解除しても影響はありません。
ある定義の再評価や再インストルメントを行うと、以前のbreakpointはすべて削除されます。
条件付きbreakpoint(conditional
breakpoint)は、プログラムがそこに達するたびに条件をテストします。条件を評価した結果エラーが発生した場合、エラーは無視されて結果はnil
になります。条件付きbreakpointをセットするにはxを使用して、ミニバッファーで条件式を指定します。以前にセットされた条件付きbreakpointがあるストップポイントに条件付きbreakpointをセットすると、以前の条件式がミニバッファーに配置されるのでそれを編集できます。
プレフィクス引数を指定してbreakpointをセットするコマンドを使用することによって、一時的な条件付きbreakpoint、および無条件のbreakpointを作成できます。一時的なbreakpointによりプログラムがストップしたとき、そのbreakpointは自動的に解除されます。
Go-nonstopモードを除き、Edebugは常にbreakpointでストップ、またはpauseします。Go-nonstopモードではbreakpointは完全に無視されます。
breakpointがどこにあるか探すにはBコマンドを使用します。このコマンドは同じ関数内からポイント以降にある次のbreakpoint(ポイント以降にbreakpointが存在しなければ最初のbreakpoint)にポイントを移動します。このコマンドは実行を継続せずに、単にバッファー内のポイントを移動します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
グローバルbreak条件(global break
condition)は指定された条件が満たされたとき、それがどこで発生したかによらず、実行をストップします。Edebugは、すべてのストップポイントでグローバルbreak条件を評価します。これが非nil
値に評価された場合は、あたかもそのストップポイントにbreakpointがあったかのように、実行をストップまたはpauseします(実行モードによる)。条件の評価でエラーを取得した場合は、実行をストップしません。
条件式はedebug-global-break-condition
に格納されます。EdebugがアクティブなときにソースバッファーからXコマンドを使用するか、Edebugがロードされている間は任意のバッファーから任意のタイミングでC-x
X X(edebug-set-global-break-condition
)を使用して新たな式を指定できます。
グローバルbreak条件は、コード内のどこでイベントが発生したかを見つけるもっともシンプルな方法ですが、コードの実行は遅くなります。そのため使用しないときは条件をnil
にリセットするべきです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
定義内のすべてのbreakpointは、それをインストルメントするたびに失われます。breakpointが失われないようにしたければソースコード内で単に関数edebug
を呼び出すソースbreakpoint(source
breakpoint)を記述できます。もちろんそのような呼び出しを条件付きすることにもできます。たとえばfac
関数内に以下のような行を1行目に挿入して、引数が0になったときストップさせることができます:
(defun fac (n) (if (= n 0) (edebug)) (if (< 0 n) (* n (fac (1- n))) 1))
fac
の定義がインストルメントされて呼び出されたとき、edebug
呼び出しはbreakpointとして振る舞います。実行モードに応じてEdebugはそこでストップまたはpauseします。
edebug
が呼び出されたときにインストルメント済みのコードが実行されていなければ、この関数はdebug
を呼び出します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
エラーがシグナルされて、それがcondition-case
でハンドルされていないとき、Emacsは通常はエラーメッセージを表示します。Edebugがアクティブでインストルメント済みコードの実行中は、ハンドルされていないエラーには通常はEdebugが対応します。オプションedebug-on-error
とedebug-on-quit
でこれをカスタマイズできます。Edebugのオプションを参照してください。
Edebugがエラーに対応するときは、エラー発生箇所の前にある最後のストップポイントを表示します。この場所はインストルメントされていない関数の呼び出しであったり、その関数内で実際にエラーが発生したのかもしれません。バインドされていない変数に関するエラーの場合は、最後の既知のストップポイントは、その不正な変数参照から遠く離れた場所にあるかもしれません。そのような場合には完全なbacktraceを表示したいと思うでしょう(その他のEdebugコマンドを参照)。
Edebugがアクティブの間にdebug-on-error
かdebug-on-quit
を変更すると、それらの変更はEdebugが非アクティブになったとき失われます。さらにEdebugの再帰編集の間、これらの変数はEdebugの外部でもっていた値にバインドされます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
これらのEdebugコマンドは、Edebugにエントリーする前のバッファーの外観とウィンドウの状態を調べるコマンドです。外部のウィンドウ構成はウィンドウのコレクションとその内容であり、それらは実際にはEdebugの外部にあります。
外部のウィンドウ構成ビューに切り替える(edebug-view-outside
)。EdebugにリターンするにはC-x X
wをタイプする。
一時的に外部のカレントバッファーを表示して、ポイントもその外部の位置になる(edebug-bounce-point
)。Edebugにリターンする前に1秒
pauseする。プレフィクス引数nを指定すると、かわりにn秒 pauseする。
ソースコードバッファー内のカレントストップポイントにポイントを戻す(edebug-where
)。
このコマンドを同じバッファーを表示する異なるウィンドウで使用すると、そのウィンドウは将来カレント定義を表示するために代用される。
Edebugが外部のウィンドウ構成の保存とリストアを行うかどうかを切り替える(edebug-toggle-save-windows
)。
プレフィクス引数を指定すると、W
は選択されたウィンドウの保存とリストアだけを切り替える。ソースコードバッファーを表示していないウィンドウを指定するには、グローバルキーマップからC-x
X Wを使用しなければならない。
v、または単にpでカレントバッファーにポイントを反跳させれば、たとえ通常は表示されないウィンドウでも外部のウィンドウ構成を調べることができます。
ポイントを移動した後にストップポイントに戻りたいときがあるかもしれません。これはソースコードバッファーからwで行うことができます。どのバッファーにいてもC-x X wを使用すれば、ソースコードバッファー内のストップポイントに戻ることができます。
保存をオフにするためにWを使用するたびに、Edebugは外部のウィンドウ構成を忘れます。そのためたとえ保存をオンに戻しても、(プログラムを実行することによって)次にEdebugをexitしたとき、カレントウィンドウ構成は変更されないまま残ります。しかし十分な数のウィンドウをオープンしていない場合には、*edebug*と*edebug-trace*の再表示があなたが見たいバッファーと競合するかもしれません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Edebug内では、まるでEdebugが実行されていないかのように式を評価できます。式の評価とプリントに際して、Edebugは不可視になるよう試みます。副作用をもつ式の評価は、Edebugが明示的に保存とリストアを行うデータへの変更を除いて期待したとおり機能するでしょう。このプロセスの詳細は、コンテキスト外部を参照してください。
Edebugのコンテキスト外で式expを評価する(edebug-eval-expression
)。つまり、Edebugはその式への干渉を最小限にしようと努める。
Edebug自身のコンテキスト内で式expを評価する(eval-expression
)。
Edebugのコンテキスト外でポイントの前の式を評価する(edebug-eval-last-sexp
)。
Edebugはcl.el内の構文(lexical-let
、macrolet
、symbol-macrolet
)によって作成された、レキシカル(lexical)にバインドされたシンボルへの参照を含む式の評価をサポートします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
式をインタラクティブに評価するために、*edebug*と呼ばれる評価リストバッファー(evaluation list buffer)を使用できます。Edebugがディスプレイを更新するたびに自動的に評価される、式の評価リスト(evaluation list)もセットアップできます。
評価リストバッファー*edebug*に切り替える(edebug-visit-eval-list
)。
*edebug*バッファーでは、以下の特別なコマンドと同様にLisp Interactionモード(Lisp Interaction in The GNU Emacs Manualを参照)のコマンドも使用できます。
ポイントの前の式をコンテキスト外で評価して、その値をバッファーに挿入する(edebug-eval-print-last-sexp
)。
Edebugのコンテキスト外でポイントの前の式を評価する(edebug-eval-last-sexp
)。
バッファー内のコンテンツから新たに評価リストを構築する(edebug-update-eval-list
)。
ポイントのある評価リストグループを削除する(edebug-delete-eval-item
)。
ソースコードバッファーに切り替えてカレントストップポイントに戻る(edebug-where
)。
評価リストウィンドウ内では、*scratch*にいるときと同様にC-jやC-x C-eで式を評価できますが、それらはEdebugのコンテキスト外で評価されます。
インタラクティブに入力した式(と結果)は、実行を継続すると失われます。しかし実行がストップされるたびに評価されるように、式から構成される評価リストをセットアップできます。
これを行なうには、評価リストバッファー内で1つ以上の評価リストグループ(evaluation list group)を記述します。評価リストグループは1つ以上のLisp式から構成されます。グループはコメント行で区切られます。
コマンドC-c
C-u(edebug-update-eval-list
)はバッファーをスキャンして、各グループの最初の式を使用して評価リストを再構築します(これはグループの2つ目の式は以前に計算、表示されている値だという発想からである)。
Edebugにエントリーするたびに、評価リストの各式(および式の後に式のカレント値)をバッファーに挿入して再表示します。これはコメント行も挿入するので、各式はそのグループの一員となります。したがってバッファーのテキストを変更せずにC-c C-uとタイプすると、評価リストは実際には変更されません。
評価リストからの評価の間にエラーが発生すると、それが式の結果であるかのようにエラーメッセージが文字列で表示されます。したがってカレントで無効な変数を使用する式によって、デバッグが中断されることはありません。
以下はいくつかの式を評価リストウィンドウに追加したとき、どのように見えるかの例です:
(current-buffer) #<buffer *scratch*> ;--------------------------------------------------------------- (selected-window) #<window 16 on *scratch*> ;--------------------------------------------------------------- (point) 196 ;--------------------------------------------------------------- bad-var "Symbol's value as variable is void: bad-var" ;--------------------------------------------------------------- (recursion-depth) 0 ;--------------------------------------------------------------- this-command eval-last-sexp ;---------------------------------------------------------------
グループを削除するにはグループ内にポイントを移動してC-c C-dをタイプするか、単にグループのテキストを削除してC-c C-uで評価リストを更新します。評価リストに新たな式を追加するには、適切な箇所にその式を挿入して新たなコメント行を挿入してからC-c C-uをタイプします。コメント行にダッシュを挿入する必要はありません — 内容は関係ないのです。
*edebug*を選択した後にC-c C-wでソースコードバッファーにリターンできます。*edebug*は実行を継続したときにkillされて、次回必要となったときに再作成されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プログラム内の式が循環リスト構造(circular list structure)を含む値を生成する場合は、Edebugがそれをプリントしようとしたときエラーとなるかもしれません。
循環構造への対処の1つとして、print-length
とprint-level
にプリントの切り詰めをセットする方法があります。Edebugは変数edebug-print-length
とedebug-print-level
の値(非nil
値なら)を、これらの変数にバインドします。出力に影響する変数を参照してください。
非nil
なら結果をプリントするときEdebugはprint-length
をこの値にバインドする。デフォルト値は50
。
非nil
なら結果をプリントするときEdebugはprint-level
をこの値にバインドする。デフォルト値は50
。
print-circle
を非nil
値にバインドして、循環構造や要素を共有する構造にたいして、より参考になる情報をプリントするよういにすることもできます。
以下は循環構造を作成するコードの例です:
(setq a '(x y)) (setcar a a)
カスタムプリントはこれを‘Result: #1=(#1# y)’のようにプリントします。‘#1=’という表記はその後の構造をラベル‘1’とラベル付けして、‘#1#’表記はその前にラベル付けされた構造を参照しています。この表記はリストとベクターの任意の共有要素に使用されます。
非nil
なら結果をプリントするときEdebugはprint-circle
をこの値にバインドする。デフォルト値はt
。
他のプログラムもカスタムプリントを使用できます。詳細はcust-print.elを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Edebugは実行トレースを*edebug-trace*という名前のバッファーに格納して記録できます。実行トレースとは関数呼び出しとリターンのログのことで関数名と引数、および値を確認できます。トレースレコードを有効にするには、edebug-trace
を非nil
値にセットしてください。
トレースバッファーの作成は実行モードのトレースの使用(Edebugの実行モードを参照)と同じではありません。
トレースレコードが有効なときは、関数へのエントリーとexitのたびにトレースバッファーに行が追加されます。関数エントリーレコードは‘::::{’、および関数名と引数の値によって構成されます。関数のexitレコードは‘::::}’、および関数名と関数の結果によって構成されます。
‘:’の数は関数エントリーの再帰レベルを表します。トレースバッファーでは関数呼び出しの開始と終了の検索に‘{’と‘}’を使用できます。
関数edebug-print-trace-before
とedebug-print-trace-after
を再定義することによって、関数エントリーと関数exitのトレースレコードをカスタマイズできます。
このマクロはbodyフォームの実行活動にたいして追加のトレース情報をリクエストする。引数stringはトレースバッファーに配置する‘{’と‘}’の後のテキストを指定する。すべての引数は評価されて、edebug-tracing
はbody内の最後のフォームの値をリターンする。
この関数はトレースバッファーにテキストを挿入する。テキストは(apply 'format format-string
format-args)
によって計算される。エントリー間の区切りとして改行も付け加える。
edebug-tracing
とedebug-trace
は、たとえEdebugが非アクティブでも、呼び出されたときは常にトレースバッファーに行を挿入します。トレースバッファーへのテキストの追加により、挿入された最後の行が見えるようにウィンドウもスクロールします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Edebugは基本的なカバレッジテスト(coverage test)と実行頻度(execution frequency)の表示を提供します。
カバレッジテストは、すべての式の結果と以前の結果を比較することによって機能します。プログラム内の各フォームがカレントEmacsセッション内でカバレッジテストを開始して以降に、2つの異なる値をリターンしたら、それらのフォームはカバーされたと判断されます。したがってプログラムにカバレッジテストを行なうには、そのプログラムをさまざまなコンディション下で実行して、プログラムが正しく振る舞うかに注目します。異なるコンディション下で十分にテストして、すべてのフォームが異なる2つの値をリターンしたとき、Edebugはそのことを告げるでしょう。
カバレッジテストにより実行速度が低下するので、edebug-test-coverage
が非nil
のときだけカバレッジテストが行なわれます。頻度計数(frequency
count)はたとえ実行モードがGo-nonstopでも、カバレッジテストが有効か無効かに関わらずすべての式にたいして行われます。
定義にたいするカバレッジ情報と頻度数の両方を表示するにはC-x X =
(edebug-display-freq-count
)を使用します。単に=
(edebug-temp-display-freq-count
)とすると、他のキーをタイプするまでの間だけ一時的に同様の情報を表示します。
このコマンドはカレント定義の各行の頻度数を表示する。
このコマンドはコードの各行の下にコメント行として頻度数を挿入する。1回のundo
コマンドですべての挿入をアンドゥできる。頻度数は式の前の‘(’か式の後の‘)’、または変数の最後の文字の下に表示される。表示をシンプルにするために同一行にたいして式の以前頻度数と頻度数が同じ場合は表示しない。
ある式にたいする頻度数の後に文字‘=’がある場合は、その式が評価されるたびに同じ値を毎回リターンしていることを表す。言い換えるとカバレッジテストの目的からは、その式はまだカバーされていないということである。
ある定義にたいして頻度数とカバレッジデータを明確にするには、単にeval-defun
で再インストルメントすればよい。
たとえばソースのbreakpointで(fac
5)
を評価した後にedebug-test-coverage
をt
にセットすると、breakpointに達したときの頻度データは以下のようになります:
(defun fac (n) (if (= n 0) (edebug)) ;#6 1 = =5 (if (< 0 n) ;#5 = (* n (fac (1- n))) ;# 5 0 1)) ;# 0
コメント行はfac
が6回呼び出されたことを表しています。最初のif
命令は毎回同じ結果を5回リターンしています。同じ結果という意味では2つ目のif
の条件にも当てはまります。fac
の再帰呼び出しは結局リターンしません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Edebugはデバッグ中のプログラムにたいして透過的であろうと努めますが完全には達成されません。Edebugはeや評価リストバッファーで式を評価するときにも、一時的に外部のコンテキストをリストアして透明化を試みます。このセクションではEdebugがリストアするコンテキストと、Edebugが完全に透過的になるのに失敗する理由を正確に説明します。
17.2.14.1 停止するかどうかのチェック | 何を行うかをEdebugが決定するタイミング。 | |
17.2.14.2 Edebugの表示の更新 | Edebugがディスプレイを更新するタイミング。 | |
17.2.14.3 Edebugの再帰編集 | Edebugが実行をストップするタイミング。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Edebugにエンターするときは常に特定のデータの保存とリストアを行なう必要があり、それはトレース情報を作成するか、あるいはプログラムを停止するかを決定する前に行なう必要があります。
max-lisp-eval-depth
とmax-specpdl-size
は、Edebugがスタックに与える影響の低減効果を高める。しかしそれでもEdebug使用時にスタック空間を使い切ってしまうことがあり得る。
edebug-continue-kbd-macro
がnil
ならexecuting-kbd-macro
がnil
にバインドされる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
(たとえばtraceモードなどで)Edebugが何かを表示する必要があるときは、Edebugの外部からカレントウィンドウ構成(ウィンドウの構成を参照)を保存します。Edebugをexitするときに、以前のウィンドウ構成がリストアされます。
Emacsはpause時だけ再表示を行います。通常は実行を継続すると、そのプログラムはbreakpointかステップ実行後にEdebugに再エンターして、その間にpauseや入力の読み取りはありません。そのような場合、Emacsが外部の構成を再表示する機会は決してありません。結果としてユーザーが目にするウィンドウ構成は、前回Edebugが中断なしでアクティブだったときのウィンドウ構成と同じになります。
何かを表示するためにEdebugにエントリーすることにより、(たとえこれらのうちのいくつかは、エラーやquitがシグナルされたときは故意にリストアしないデータだとしても)以下のデータも保存とリストアが行われます。
edebug-save-windows
が非nil
なら、外部のウィンドウ構成の保存とリストアが行われる(Edebugのオプションを参照)。
エラーやquitではウィンドウ構成はリストアされないが、save-excursion
がアクティブなら、たとえエラーやquitのときでも外部の選択されたウィンドウが再選択される。edebug-save-windows
の値がリストなら、それにリストされたウィンドウだけが保存およびリストアされる。
ただしソースコードバッファーのウィンドウの開始位置と水平スクロールはリストアされないので、表示はEdebug内で整合性が保たれたままとなる。
edebug-save-displayed-buffer-points
が非nil
なら、表示されているそれぞれのバッファー内のポイント値は保存およびリストアされる。
overlay-arrow-position
とoverlay-arrow-string
は保存とリストアが行われるので、同じバッファー内の他の場所の再帰編集から安全にEdebugを呼び出せる。
cursor-in-echo-area
はnil
にローカルにバインドされるのでカーソルはそのウィンドウ内に現れる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Edebugにエンターしてユーザーのコマンドが実際に読み取られるとき、Edebugは以下の追加データを保存(および後でリストア)します:
last-command
、this-command
、last-command-event
、last-input-event
、last-event-frame
、last-nonmenu-event
、track-mouse
。Edebug内のコマンドはEdebug外部のこれらの変数に影響をあたえない。
Edebug内でのコマンド実行はthis-command-keys
によりリターンされるキーシーケンスを変更でき、Lispからそのキーシーケンスをリセットする方法はない。
Edebugはunread-command-events
の値の保存とリストアができない。この変数が重要な値をもつときにEdebugにエンターすると、デバッグ中のプログラムの実行に干渉する可能性がある。
command-history
に追加される。これは稀に実行に影響を与える。
standard-output
とstandard-input
は、recursive-edit
によってnil
にバインドされるがEdebugは評価の間それらを一時的にリストアする。
defining-kbd-macro
はedebug-continue-kbd-macro
にバインドされる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Edebugが正しくマクロを呼び出す式をインストルメントするには、いくつかの特定な配慮が必要になります。このサブセクションでは、その詳細を説明します。
17.2.15.1 マクロ呼び出しのインストルメント | 基本的な問題点。 | |
17.2.15.2 仕様リスト | 式の複雑なパターンを指定する方法。 | |
17.2.15.3 仕様でのバックトレース | マッチに失敗したときEdebugが行なうこと。 | |
17.2.15.4 仕様の例 | Edebug仕様を理解するために。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
EdebugがLispマクロを呼び出す式をインストルメントするときは、正しくインストルメントを行なうために、そのマクロに関して追加の情報が必要になります。これはマクロ呼び出しのどの部分式(subexpression)が評価されるフォームなのか推測する方法がないからです(評価はマクロのbodyで明示的に発生するかもしれないし、展開結果が評価されるとき、または任意のタイミングで行われるかもしれない)。
したがってEdebugが処理するかもしれないすべてのマクロにたいして、そのマクロの呼び出しフォーマットを説明するためのEdebug仕様(Edebug
specification)を定義しなければなりません。これを行なうにはマクロ定義にdebug
宣言を追加します。以下はマクロ例for
(マクロ引数の多重評価を参照)にたいする簡単な仕様の例です。
(defmacro for (var from init to final do &rest body) "Execute a simple \"for\" loop. For example, (for i from 1 to 10 do (print i))." (declare (debug (symbolp "from" form "to" form "do" &rest form))) ...)
このEdebug仕様はマクロ呼び出しのどの部分が評価されるフォームなのかを示しています。単純なマクロにたいするEdebug仕様は、そのマクロ定義の正式な引数リストに酷似している場合がありますが、Edebug仕様はマクロ引数に比べてより汎的です。declare
フォームの詳細はマクロの定義を参照してください。
コードをインストルメントするときには、Edebugに仕様が確実に解るように注意してください。マクロ定義を含む他のファイルを要求するためにeval-when-compile
を使用するファイルから関数をインストルメントする場合には、そのファイルを明示的にロードする必要があるかもしれません。
def-edebug-spec
によりマクロ定義から個々のマクロにたいしてEdebug仕様を定義することもできます。Lispで記述されたマクロ定義にたいしてはdebug
宣言を追加するほうが好ましく便利でもありますが、def-edebug-spec
ではCで実装されたスペシャルフォームにたいしてEdebug仕様を定義することが可能になります。
マクロmacro呼び出しのどの式が評価される式かを指定する。specificationはEdebug仕様である。どちらの引数も評価されない。
引数macroには単なるマクロ名ではない、任意の実シンボルを指定できる。
以下はspecificationに指定できるシンボルと、引数を処理する方法のテーブルです。
t
すべての引数は評価のためにインストルメントされる。
0
引数はインストルメントされない。
そのシンボルはかわりに使用されるEdebug仕様をもたなければならない。このインダイレクションは他の種類の仕様が見つかるまで繰り返される。これによって他のマクロの仕様を継承できる。
リストの要素はフォーム呼び出しの引数の型を記述する。仕様リストに指定できる要素については以降のセクションを参照のこと。
マクロがEdebug仕様をもたなければ、debug
宣言およびdef-edebug-spec
呼び出しのどちらを介しても、変数edebug-eval-macro-args
が効果を発揮します。
これはEdebugが明示的なEdebug仕様をもたないマクロ引数を扱う方法を制御する。nil
(デフォルト)なら引数は評価のためにインストルメントされない。それ以外ばらすべての引数がインストルメントされる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
あるマクロ呼び出しにおいて、いくつかの引数は評価されても、それ以外の引数は評価されないような場合には、Edebug仕様のために仕様リスト(specification
list)が必要となります。仕様リスト内のいくつかの要素は1つ以上の引数にマッチしますが、それ以外の要素は以降に続くすべての引数の処理を変更します。後者は仕様キーワード(specification
keywords)と呼ばれ、(&optional
のように)‘&’で始まるシンボルです。
仕様リストはそれ自身がリストであるような引数にマッチする部分リスト(sublist)、あるいはグループ化に使用されるベクターを含むかもしれません。したがって部分式とグループは仕様リストをレベル階層に細分化します。仕様キーワードは部分式やグループを含むものの残りに適用されます。
仕様リストに選択肢や繰り返しが含まれる場合は、実際のマクロの呼び出しのマッチでバックトラックが要求されるかもしれません。詳細は仕様でのバックトレースを参照してください。
Edebug仕様はバランスのとれたカッコで括られた部分式へのマッチ、フォームの再帰処理、インダイレクト仕様を通じた再帰等の、正規表現によるマッチングとコンテキストに依存しない文法構成を提供します。
以下は仕様リストに使用できる要素と、その意味についてのテーブルです(使用例は仕様の例を参照):
sexp
評価されない単一のLispオブジェクト。インストルメントされない。
form
評価される単一のLispオブジェクト。インストルメントされる。
place
汎変数(generalized variable)。ジェネリック変数を参照のこと。
body
&rest form
の省略形。以下の&rest
を参照のこと。
function-form
関数フォーム。クォートされた関数シンボル、クォートされたラムダ式、または(関数シンボルかラムダ式に評価される)フォームのいずれか。これはラムダ式のbodyをいずれかの方法でインストルメントするので、function
よりもquote
でクォートされたラムダ式の引数にたいして有用。
lambda-expr
クォートされないラムダ式。
&optional
仕様リスト内の後続の要素はオプション。マッチしない要素が出現するとEdebugはこのレベルのマッチングを停止する。
後続が非オプションの要素であるような数個の要素をオプションにするだけなら、[&optional
specs…]
を使用する。複数の要素すべてのマッチや非マッチを指定するには、&optional
[specs…]
を使用する。defun
の例を参照のこと。
&rest
仕様リスト内の後続のすべての要素は0回以上繰り返される。しかし最後の繰り返しでは、仕様リスト内のすべての要素にたいするマッチングの前に式が終了しても問題はない。
数個の要素を繰り返すには[&rest
specs…]
を使用する。各繰り返しにおいてすべてマッチしなければならない複数要素を指定するには、&rest
[specs…]
を使用する。
&or
仕様リスト内の後続の各要素は選択肢である。選択肢の1つがマッチしなければならず、マッチしなければ&or
仕様は失敗する。
&or
に続く各リスト要素は単一の選択肢である。複数のリスト要素を単一の選択肢にグループ化するには、それらを[…]
で括る。
¬
後続の各要素は&or
が使用されたときのように選択肢にマッチするが、要素がマッチしたら失敗となる。マッチする要素がなければ何もマッチされないが¬
仕様は成功となる。
&define
フォーム定義にたいする仕様であることを示す。フォーム定義自体はインストルメントされない(つまりEdebugはフォーム定義の前後でストップしない)が、フォーム内部は通常はインストルメントされるであろう。&define
キーワードはリスト仕様の最初の要素であること。
nil
カレント引数レベルでマッチさせる引数が存在しなければ成功し、それ以外は失敗する。部分リスト仕様とバッククォートの例を参照のこと。
gate
引数はマッチされないがgateを通じたバックトラックは、このレベルの仕様の残りをマッチングする間は無効にされる。これは主に特定の構文エラーメッセージを一般化するために使用される。詳細は仕様でのバックトレース、およびlet
の例も参照のこと。
other-symbol
仕様リスト内のその他の要素は、述語(predicate)かインダイレクト仕様(indirect specification)である。
シンボルがEdebug仕様をもつなら、インダイレクト仕様(indirect
specification)はシンボル位置に使用されるリスト仕様か、引数を処理するための関数のいずれかである。この仕様はマクロにたいするdef-edebug-spec
のように定義される。defun
の例を参照のこと。
それ以外ならシンボルは述語(predicate)である。述語は引数とともに呼び出されてnil
をリターンしたら、その仕様は失敗して引数はインストルメントされない。
適切な述語としてはsymbolp
、integerp
、stringp
、vectorp
、atom
が含まれる。
[elements…]
要素のベクターは要素を単一のグループ仕様(group specification)にグループ化する。このグループ仕様はベクター自体には何も行わない。
"string"
引数はstringという名前のシンボルである。この仕様はsymbolの名前がstringであるようなクォートされたシンボル'symbol
と等価だが、文字列形式のほうが好ましい。
(vector elements…)
引数は要素が仕様内のelementsにマッチするようなベクターである。バッククォートの例を参照のこと。
(elements…)
他のリストは部分リスト仕様(sublist specification)であり、引数は要素が仕様のelementsにマッチするリストでなければならない。
部分リスト仕様はドットリスト(dotted
list)かもしれず、その場合対応するリスト引数はドットリストである。かわりにドットリスト仕様の最後のCDRが、(グループ化やインダイレクト仕様による)他の部分リスト仕様かもしれない(たとえば要素が非ドットリストにマッチする(spec
. [(more
specs…)])
))。これはバッククォートの例のような再帰仕様に有用。このような再帰を終了させるには上述のnil
仕様も参照のこと。
(specs . nil)
のように記述された部分リスト仕様は(specs)
、(specs .
(sublist-elements…))
は(specs
sublist-elements…)
と等価であることに注意。
以下は&define
の後だけに出現する追加仕様のリストです。defun
の例を参照してください。
name
引数(シンボル)は定義フォームの名前。
定義フォームは名前フィールドをもつ必要はなく、複数の名前フィールドをもつかもしれない。
:name
この構文は引数に実際のマッチは行わない。:name
の後の要素はシンボルであり、その定義の追加の名前要素として使用される。定義名に一意で静的な要素を加えるためにこれを使用できる。複数回使用できる。
arg
引数(シンボル)は定義フォームの引数の名前である。しかしlambda-listキーワード(‘&’で始まるシンボル)は許されない。
lambda-list
これはラムダリスト(ラムダ式の引数リスト)にマッチする。
def-body
引数は定義内のコードのbodyである。これは上述のbody
と似ているが、定義のbodyはその定義に関連する情報を照会する別のEdebug呼び出しでインストルメントされていなければならない。定義内のより高位レベルのフォームリストにはdef-body
を使用する。
def-form
引数は定義内のもっとも高位レベルの単一フォームである。これはdef-body
と似ているが、フォームリストではなく単一フォームのマッチに使用される。特別なケースとしてdef-form
はフォームが実行されるときトレース情報を出力しないことも意味する。interactive
の例を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
あるポイント位置で仕様がマッチに失敗しても、構文エラーがシグナルされるとは限りません。そのかわりバックトラッッキング(backtracking)が開始されます。バックトラックはすべての選択肢をマッチングするまで行なわれます。最終的に引数リストのすべての要素は仕様内の要素のいずれかとマッチしなければならず、仕様内の必須要素は引数のいずれかとマッチしなければなりません。
構文エラーが検出されてもその時点では報告されず、より高位レベルの選択肢のマッチングが終わった後、実際のエラー箇所から離れたポイント位置でエラーが報告されるかもしれません。しかしエラー発生時にバックトラックが無効ならエラーは即座に報告されるでしょう。ある状況ではバックトラックも自動的に再有効化されることに注意してください。&optional
、&rest
、&or
により新たな選択肢が設定されたとき、または部分リスト、グループ、インダイレクト仕様が開始されたときはバックトラックが自動的に有効になります。バックトラックを有効、または無効にした場合の影響は、現在処理中のレベルの残り要素と低位レベルに限定されます。
何らかのフォーム仕様(すなわちform
、body
、def-form
、def-body
)をマッチングする間、バックトラックは無効になっています。これらの仕様は任意のフォームにマッチするので、何らかのエラーが発生するとしたらそれは高位レベルではなく、そのフォーム自体の内部でなければなりません。
バックトラックはクォートされたシンボルや文字列仕様とのマッチに成功した後にも無効になります。なぜなら通常これは構文成が認識されたことを示すからです。しかし同じシンボルで始まる一連の選択肢構文がある場合には、たとえば["foo"
&or [first case] [second case]
...]
のように、通常は選択肢の外部にそのシンボルをファクタリングすることによりこの制約に対処できます。
ほとんどのニーズは、バックトラックを自動的に無効にする、これら2つの方法で満足させることができますが、gate
仕様を使用して明示的にバックトラックを無効にするほうが便利なときもあります。これは高位に適用可能な選択肢が存在しないことが分かっている場合に有用です。let
仕様の例を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下で提供する例から学ぶことにより、Edebug仕様の理解が容易になるでしょう。
スペシャルフォームlet
は、バインディングとbodyのシーケンスをもちます。各バインディングはそシンボル、またはシンボルとオプションの部分リストです。以下の仕様では部分リストを見つけたらバックトラックを抑止するために、部分リスト内のgate
があることに注目してください。
(def-edebug-spec let ((&rest &or symbolp (gate symbolp &optional form)) body))
Edebugはdefun
および関連する引数リスト、interactive
仕様にたいして以下の仕様を使用します。式の引数はその関数bodyの外部で実際に評価されるので、interactiveフォームは特別に処理する必要があります。(defmacro
にたいする仕様はdefun
にたいする仕様と酷似するがdeclare
命令文が許される)
(def-edebug-spec defun
(&define name lambda-list
[&optional stringp] ; ドキュメント文字列が与えられた場合はマッチする。
[&optional ("interactive" interactive)]
def-body))
(def-edebug-spec lambda-list
(([&rest arg]
[&optional ["&optional" arg &rest arg]]
&optional ["&rest" arg]
)))
(def-edebug-spec interactive
(&optional &or stringp def-form)) ; def-form
に注目
以下のバッククォートにたいする仕様はドットリストにマッチさせる方法と、nil
を使用して再帰を終了させる方法を説明するための例です。またベクターのコンポーネントをマッチさせる方法も示しています(Edebugにより定義される実際の仕様は少し異なり、失敗するかもしれない非常に深い再帰を引き起こすためドットリストについてはサポートしない)。
(def-edebug-spec \` (backquote-form)) ; 単なる明確化用エイリアス
(def-edebug-spec backquote-form
(&or ([&or "," ",@"] &or ("quote" backquote-form) form)
(backquote-form . [&or nil backquote-form])
(vector &rest backquote-form)
sexp))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のオプションはEdebugの動作に影響を与えます:
Edebugが使用される前に呼び出される関数。この関数は毎回新たな値をセットする。Edebugはこれらの関数を一度呼び出したら、その後にedebug-setup-hook
をnil
にリセットする。使用するパッケージに関係するEdebug仕様をロードするために使用でdきるがそれはEdebugを使用するときだけである。Edebugのためのインストルメントを参照のこと。
これが非nil
の場合にdefun
やdefmacro
のような定義フォームの普通に評価すると、Edebug用にインストルメントされる。これはeval-defun
、eval-region
、eval-buffer
、and
eval-current-buffer
に適用される。
このオプションの切り替えにはコマンドM-x edebug-all-defsを使用する。Edebugのためのインストルメントを参照のこと。
これが非nil
の場合にはeval-defun
、eval-region
、eval-buffer
、eval-current-buffer
はたとえフォームが何も定義していなくても、すべてのフォームをインストルメントする。これはロードとミニバッファー内の評価には適用されない。
このオプションの切り替えにはコマンドM-x edebug-all-formsを使用する。Edebugのためのインストルメントを参照のこと。
これが非nil
なら、Edebugはウィンドウ構成の保存とリストアを行なう。これにはある程度の時間を要するので、ウィンドウ構成に何が起こってもプログラムに関係なければ、この変数をnil
にセットしたほうがよい。
値がリストならリストされたウィンドウだけが保存およびリストアされる。
Edebug内ではこの変数をインタラクティブに変更するためにWコマンドを使用できる。Edebugの表示の更新を参照のこと。
これが非nil
ならEdebugは表示されているすべてのバッファー内のポイントを保存およびリストアする。
選択されていないウィンドウ内に表示されているバッファーのポイントを変更するコードをデバッグしている場合は、他のバッファーのポイントを保存およびリストアする必要がある。その後にEdebugまたはユーザーがそのウィンドウを選択した場合は、そのバッファー内のポイントはそのウィンドウのポイント値に移動される。
すべてのバッファー内のポイントの保存とリストアは、それぞれのウィンドウを2回選択する必要があり高価な処理なので、必要なときだけ有効にする。Edebugの表示の更新を参照のこと。
この変数が非nil
なら、Edebugが最初にアクティブになったときのEdebugの最初の実行モードを指定する。指定できる値はstep
、next
、go
、Go-nonstop
、trace
、Trace-fast
、continue
、Continue-fast
。
デフォルト値はstep
。この変数はC-x C-a C-mでインタラクティブにセットできる。Edebugの実行モードを参照のこと。
これが非nil
なら各関数のエントリーとexitをトレースする。トレース出力は関数のエントリーとexitを行ごとに、再帰レベルにしたがって*edebug-trace*という名前のバッファーに表示される。
トレースバッファーのedebug-tracing
も参照されたい。
非nil
ならEdebugはデバッグされるすべての式のカバレッジをテストする。カバレッジテストを参照のこと。
非nil
ならEdebug外部で実行されている任意のキーボードマクロの定義または実行を継続する。これはデバッグされないので慎重に使用すること。Edebugの実行モードを参照されたい。
非nil
ならEdebugは式の結果を表示するときに、その式自体のインストルメント結果の削除を試みる。マクロをデバッグするときは、式の結果自体がインストルメントされた式になるということに関連するオプションである。実際的な例ではないが、サンプル例の関数fac
がインストルメントされたとき、そのフォームのマクロを考えてみるとよい。
(defmacro test () "Edebug example." (if (symbol-function 'fac) …))
test
マクロをインストルメントしてステップ実行すると、デフォルトではsymbol-function
呼び出しは多数のedebug-after
フォームとedebug-before
フォームをもつことになり、それにより実際の結果の確認が難しくなり得る。edebug-unwrap-results
が非nil
ならEdebugは結果からこれらのフォームの削除を試みる。
debug-on-error
が以前nil
だったら、Edebugはdebug-on-error
をこの値にバインドする。エラーのトラップを参照のこと。
debug-on-quit
の以前の値がnil
なら、Edebugはdebug-on-quit
にこの値をバインドする。エラーのトラップを参照のこと。
Edebugがアクティブな間にedebug-on-error
かedebug-on-quit
の値を変更したら、次回に新たなコマンドを通じてEdebugが呼び出されるまでこれらの値は使用されない。
非nil
なら、値はすべてのステップポイントでテストされる式である。式の結果がnil
ならbreakする。エラーは無視される。グローバルなブレーク条件を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispリーダーは無効な構文(invalid syntax)について報告はしますが実際の問題箇所は報告しません。たとえばある式を評価中のエラー‘End of file during parsing’は、開カッコまたは開角カッコ(open parenthese or open square bracket)が多いことを示しています。Lispリーダーはこの不一致をファイル終端で検出しましたが、本来閉カッコがあるべき箇所を解決することはできません。同様に‘Invalid read syntax: \")\"’は開カッコの欠落を示していますが、欠落しているカッコが属すべき場所は告げません。ならばどうやって変更すべき箇所を探せばよいのでしょうか?
問題が単なるカッコの不一致でない場合の便利なテクニックは、各defunの先頭でC-M-eとタイプして、そのdefunの最後と思われる箇所に移動するか確認する方法です。もし移動しなければ、問題はそのdefunの内部にあります。
マッチしないカッコがLispにおいてもっとも一般的な構文エラーなので、これらのケースにたいしてさらにアドバイスすることができます(Show Parenモードを有効にしてコードにポイントを移動するだけでカッコの不一致を探しやすくなるだろう)。
17.3.1 過剰な開カッコ | 誤った開カッコと閉カッコの欠落を探す方法。 | |
17.3.2 過剰な閉カッコ | 誤った閉カッコと開カッコの欠落を探す方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
カッコがマッチしないdefunを探すことが最初のステップです。過剰な開カッコが存在する場合は、ファイルの終端に移動してC-u C-M-uとタイプします。これによってカッコがマッチしない最初のdefunの先頭に移動するでしょう。
何が間違っているのか正確に判断するのが次のステップです。これを確実に行なうには、そのプログラムを詳しく調べる以外に方法はありませんが、カッコがあるべき箇所を探すのに既存のインデントが手掛かりになることが多々あります。C-M-qで再インデントして何が移動されるか確認するのが、この手掛かりを使用するもっとも簡単な方法です。しかし、行うのはちょっと待ってください! まず続きを読んでからにしましょう。
これを行なう前にdefunに十分な閉カッコがあるか確認します。十分な閉カッコがなければC-M-qがエラーとなるか、そのdefunからファイル終端までの残りすべてが再インデントされます。その場合はdefunの最後に移動して、そこに閉カッコを挿入します。そのdefunのカッコの釣り合いがとれるまでは、defunの最後に移動するのにC-M-eは失敗するでしょうから使用できません。
これでdefunの先頭に移動してC-M-qとタイプすることができます。通常は一定のポイントからその関数の最後までのすべての行が、右へとシフトされるでしょう。これはおそらくそのポイント付近で閉カッコが欠落しているか不要な開カッコがあります(しかしこれを真実と決め付けずコードを詳しく調べてること)。不一致箇所を見つけたら、元のインデントはおそらく意図されたカッコに適しているはずなので、C-_でC-M-qをアンドゥしてください。
問題をfixできたと思った後に、再度C-M-qを使用します。実際に元のインデントが意図したカッコのネストに適合していて、足りないカッコを追加していたら、C-M-qは何も変更しないはずです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
過剰な閉カッコへの対処は、まずファイルの先頭に移動してから、カッコのマッチしないdefunを探すためにC-u -1 C-M-uをタイプします。
それからそのdefunの先頭でC-M-fをタイプして、実際にマッチする閉カッコを探します。これによりそのdefunの終端より幾分手前の箇所に移動するはずです。その付近に間違った閉カッコが見つかるでしょう。
そのポイントに問題が見つからなければ、そのdefunの先頭でC-M-qをタイプするのが次のステップです。ある行範囲はおそらく左へシフトするでしょう。その場合には欠落している開カッコまたは間違った閉カッコは、おそらくそれらの行の1行目付近にあるでしょう (しかしこれを真実と決め付けずコードを詳しく調べること)。不一致箇所を見つけたら、元のインデントはおそらく意図されたカッコに適しているはずなので、C-_でC-M-qをアンドゥしてください。
問題をfixできたと思った後に再度C-M-qを使用します。実際に元のインデントが意図したカッコのネストに適合していて、足りないカッコを追加していたら、C-M-qは何も変更しないはずです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
testcover
ライブラリーをロードしてコマンドM-x testcover-start RET
file
RETでコードをインストルメントすることにより、Lispコードのファイルにたいしてカバレッジテストを行なうことができます。コードを1回以上呼び出すことによってテストが行なわれます。コマンドM-x
testcover-mark-allを使用すれば、カバレッジが不十分な箇所が色付きでハイライト表示されます。コマンドM-x
testcover-next-markは次のハイライトされた箇所へポイントを前方に移動します。
赤くハイライトされた箇所は通常はそのフォームが完全に評価されたことが一度もないことを示し、茶色でハイライトされた箇所は常に同じ値に評価された(その結果にたいして少ししかテストされていない)ことを意味します。しかしerror
のように完全に評価するのが不可能なフォームにたいしては、赤いハイライトはスキップされます。(setq
x 14)
のように常に同じ値に評価されることが期待されるフォームにたいしては、茶色のハイライトはスキップされます。
難しいケースではテストカバレッジツールにアドバイスを与えるために、コードにdo-nothingマクロを追加することができます。
formを評価してその値をリターンするが、テストカバレッジにたいしてformが常に同じ値だという情報を与える。
formを評価してformが決してリターンしないという情報をカバレッジテストに与える。もしリターンしたらrun-timeエラーとなる。
Edebugにもカバレッジテスト機能があります(カバレッジテストを参照)。これらの機能は部分的に重複しており、組み合わせることで明確になるでしょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プログラムは正常に機能しているものの、より高速または効率的に実行させたい場合にまず行うべきは、そのプログラムがリソースをどのように使用するか知るためにコードをプロファイル(profile)することです。ある特定の関数の実行が、実行時間のうち無視できない割り合いを占めるようなら、その部分を最適化する方法を探すことを開始できます。
このためにEmacsにはビルトインのサポートがあります。プロファイリングを開始するにはM-x profiler-startをタイプします。プロファイルはプロセッサー使用(processor usage)とメモリー使用(memory usage)、またはその両方を選択できます。何らかの処理を行った後にM-x profiler-reportとタイプすると、プロファイルに選択した各リソースがsummaryバッファーに表示されます。reportバッファーの名前にはそのレポートが生成された時刻が含まれるので、前の結果を消去せずに後で他のレポートを生成できます。プロファイリングが終了したらM-x profiler-stopとタイプしてください(プロファイリングに関連する多少のオーバーヘッドがあるため)。
profiler reportバッファーでは各行に呼び出された関数と、その後にプロファイリングが開始されてから使用したリソース(プロセッサーまたはメモリー)の絶対時間とパーセンテージ時間が表示されます。左側にシンボル‘+’のある行ではRETをタイプして行を展開して、高位レベルの関数に呼び出された関数を確認できます。もう一度RETをタイプすると、元の状態へと行が折り畳まれます。
jかmouse-2を押下すると関数の定義にジャンプします。dを押下すると関数のドキュメントを閲覧できます。C-x C-wを使用してプロファイルをファイルに保存できます。=を使用すれば2つのプロファイルを比較することができます。
elpライブラリーは別のアプローチを提案します。使い方はelp.elを参照してください。
benchmarkライブラリーを使用してEmacs
Lispフォームのスピードを個別にチェックできます。benchmark.el内の関数benchmark-run
とbenchmark-run-compiled
を参照してください。
configure
のオプションに--enable-profilingを使用してビルドすることにより、EmacsをCコードのレベルでプロファイルすることができます。こうしてビルドされたEmacsは、Emacsをexitするときにgprof
ユーティリティを使用して検証できるファイルgmon.outを生成します。この機能は主にEmacsのデバッグに有用です。このEmacsは実行状態から上述のM-x
profiler-…コマンドによりLispレベルで実際にストップします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プリント(print)と読み取り(read)はLispオブジェクトからテキスト形式への変換、またはその逆の変換を行なう操作です。これらはLispのデータ型で説明したプリント表現(printed representation)と入力構文(read syntax)を使用します。
このチャプターでは読み取りとプリントのためのLisp関数について説明します。このチャプターではさらにストリーム(stream)についても説明します。ストリームとは、(読み取りでは)テキストがどこから取得されるか、(プリントでは)テキストをどこに出力するかを指定します。
18.1 読み取りとプリントの概念 | ストリーム、読み取り、プリントの概観。 | |
18.2 入力ストリーム | 入力ストリームとして使用できる、さまざまなデータ型。 | |
18.3 入力関数 | テキストからLispオブジェクトを読み取る関数。 | |
18.4 出力ストリーム | 出力ストリームとして使用できる、さまざまなデータ型。 | |
18.5 出力関数 | テキストとしてLispオブジェクトをプリントする関数。 | |
18.6 出力に影響する変数 | プリント関数が何を行うか制御する変数。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispオブジェクトの読み取りとは、テキスト形式のLisp式をパース(parse:
解析)して、対応するLispオブジェクトを生成することを意味します。これはLLispプログラムがLispコードファイルからLispに取得される方法でもあります。わたしたちはそのテキストのことを、そのオブジェクトの入力構文(read
syntax)と呼んでいます。たとえばテキスト‘(a .
5)’は、CARがa
でCDRが数字の5であるようなコンスセルにたいする入力構文です。
Lispオブジェクトのプリントとは、あるオブジェクトをそのオブジェクトのプリント表現(printed representation)に変換することによって、そのオブジェクトを表すテキストを生成することを意味します(プリント表現と読み取り構文を参照)。上述のコンスセルをプリントするとテキスト‘(a . 5)’が生成されます。
読み取りとプリントは概ね逆の処理といえます。あるテキスト断片を読み取った結果として生成されたオブジェクトをプリントすると、多くの場合は同じテキストが生成され、あるオブジェクトをプリントした結果のテキストを読み取ると、通常は同じようなオブジェクトが生成されます。たとえばシンボルfoo
をプリントするとテキスト‘foo’が生成されて、そのテキストを読み取るとシンボルfoo
がリターンされます。要素がa
とb
のリストをプリントするとテキスト‘(a
b)’が生成されて、そのテキストを読み取ると、(同じリストではないが)要素がa
とb
のリストが生成されます。
しかし、これら2つの処理は互いにまったく逆の処理というわけではありません。3つの例外があります:
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
テキストを読み取るLisp関数の大部分は、引数として入力ストリーム(input stream)を受け取ります。入力ストリームは読み取られるテキストの文字をどこから、どのように取得するかを指定します。以下は利用できる入力ストリーム型です:
入力文字はbufferのポイントの後の文字から直接読み取られる。文字の読み取りとともにポイントが進む。
入力文字はmarkerがあるバッファーの、マーカーの後の文字から直接読み取られる。文字の読み取りとともにマーカーが進む。ストリームがマーカーならバッファー内のポイント値に影響はない。
入力文字はstringの最初の文字から必要な文字数分が取得される。
入力文字はfunctionから生成され、その関数は2種類の呼び出しをサポートしなければならない:
t
t
はその入力がミニバッファーから読み取られるストリームであることを意味する。実際にはミニバッファーが1回呼び出されて、ユーザーから与えられたテキストが、その後に入力ストリームとして使用される文字列となる。Emacsがbatchモードで実行されている場合には、ミニバッファーのかわりに標準入力が使用される。たとえば、
(message "%s" (read t))
このような場合には標準入力からLisp式が読み取られて、結果は標準出力にプリントされるだろう。
nil
入力ストリームとしてnil
が与えられた場合は、かわりにstandard-input
の値が使用されることを意味する。この値はデフォルトの入力ストリーム(default
input stream)であり、非nil
の入力ストリームでなければならない。
入力ストリームとしてのシンボルは、(もしあれば)そのシンボルの関数定義と等価である。
以下の例ではバッファーストリームから読み込んで、読み取りの前後におけるポイント位置を示しています:
---------- Buffer: foo ---------- This∗ is the contents of foo. ---------- Buffer: foo ----------
(read (get-buffer "foo")) ⇒ is
(read (get-buffer "foo")) ⇒ the
---------- Buffer: foo ---------- This is the∗ contents of foo. ---------- Buffer: foo ----------
最初の読み取りではスペースがスキップされていることに注意してください。読み取りでは意味のあるテキストに先行する、任意のサイズの空白文字がスキップされます。
以下はマーカーストリームからの読み取りの例で、最初は表示されているバッファーの先頭にマーカーを配置されています。読み取られた値はシンボルThis
です。
---------- Buffer: foo ---------- This is the contents of foo. ---------- Buffer: foo ----------
(setq m (set-marker (make-marker) 1 (get-buffer "foo"))) ⇒ #<marker at 1 in foo>
(read m) ⇒ This
m
⇒ #<marker at 5 in foo> ;; 最初のスペースの前
以下では文字列のコンテンツから読み取っています:
(read "(When in) the course") ⇒ (When in)
以下はミニバッファーから読み取る例です。プロンプトは‘Lisp expression: ’です(このプロンプトはストリームt
から読み取る際は常に使用される)。ユーザーの入力はプロンプトの後に表示されます。
(read t)
⇒ 23
---------- Buffer: Minibuffer ----------
Lisp expression: 23 RET
---------- Buffer: Minibuffer ----------
最後はuseless-stream
という名前の関数ストリームから読み取る例です。ストリームを使用する前に変数useless-list
を文字のリストで初期化しています。その後はリスト内の次の文字を取得するため、または文字をリストの先頭に追加することにより読み戻すために関数useless-stream
を呼び出します。
(setq useless-list (append "XY()" nil)) ⇒ (88 89 40 41)
(defun useless-stream (&optional unread) (if unread (setq useless-list (cons unread useless-list)) (prog1 (car useless-list) (setq useless-list (cdr useless-list))))) ⇒ useless-stream
このストリームを使って以下のように読み取ります:
(read 'useless-stream) ⇒ XY
useless-list ⇒ (40 41)
開カッコと閉カッコがリスト内に残されることに注意してください。Lispリーダーは開カッコに出会うと、それを入力の終わりと判断して読み戻します。次にこのポイント位置からこのストリームを読み取ると、‘()’が読み取られてnil
がリターンされます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは、読み取りに関係のあるLisp関数と変数について説明します。
以下の関数ではstreamは入力ストリーム(前のセクションを参照)を意味します。streamがnil
または省略された場合のデフォルト値はstandard-input
です。
読み取りにおいて終端されていないリスト、ベクター、文字列に遭遇したらend-of-file
がシグナルされます。
この関数はstreamからテキスト表現されたLisp式を1つ読み取ってLispオブジェクトとしてリターンする。これは基本的なLisp入力関数である。
この関数はstring内のテキストからテキスト表現された最初のLisp式を読み取る。リターン値はCARがその式で、CDRが次に読み取られるその文字列内の残りの文字(読み取られていない最初の文字)の位置を与える整数であるようなコンスセルである。
startが与えられると、文字列内のインデックスstart(最初の文字はインデックス0)から読み取りが開始される。endを指定すると、残りの文字列が存在しないかのごとくそのインデックスの直前で読み取りがストップされる。
たとえば:
(read-from-string "(setq x 55) (setq y 5)") ⇒ ((setq x 55) . 11)
(read-from-string "\"A short string\"") ⇒ ("A short string" . 16)
;; 最初の文字から読み取りを開始
(read-from-string "(list 112)" 0)
⇒ ((list 112) . 10)
;; 2つ目の文字から読み取りを開始
(read-from-string "(list 112)" 1)
⇒ (list . 5)
;; 7番目の文字から読み取りを開始 ;; して9番目の文字で停止 (read-from-string "(list 112)" 6 8) ⇒ (11 . 8)
この変数はデフォルト入力ストリーム(引数streamがnil
のときにread
が使用するストリーム)を保持する。デフォルトはt
で、これはミニバッファーを使用することを意味する。
非nil
なら、この変数は循環構造(circular structure)と共有構造(shared
structures)の読み取りを有効にする。循環オブジェクトの読み取り構文を参照のこと。デフォルト値はt
。
batchモードでEmacsプロセスの標準入力ストリームや標準出力ストリームにたいして読み取りや書き込みを行う際には、任意のバイナリーデータにたいしてそのまま読み取りや書き込みを行ったり、改行とCRLFの変換を行わないことが要求されるときがあります。これはMS-WindowsとMS-DOSだけに存在し、Posixホストには存在しない問題です。以下の関数によってEmacsプロセスの標準ストリームすべての入出力モードを制御できます。
streamの入出力モードのテキストとバイナリーを切り替える。modeが非nil
ならバイナリーモード、それ以外ならテキストモードに切り替える。streamの値はstdin
、stdout
、stderr
のいずれか。この関数は副作用として保留されているstreamの出力データをすべてフラッシュして、streamの以前の入出力モードをリターンする。Posixホストでは常に非nil
値をリターンして、保留中の出力のフラッシュ以外は何も行わない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
出力ストリームはプリントによって生成された文字に何を行うかを指定します。ほとんどのプリント関数は引数としてオプションで出力ストリームを受け取ります。以下は利用できる出力ストリーム型です:
出力文字はbufferのポイント位置に挿入される。文字が挿入された分だけポイントが進む。
出力文字はmarkerがあるバッファーのマーカー位置に挿入される。文字が挿入された分だけマーカー位置が進む。ストリームがマーカーのときは、そのバッファー内のポイント位置にプリントは影響せず、この種のプリントでポイントは移動しない(マーカー位置がポイント位置かポイント位置より前の場合は除く。通常はテキストの周囲にポイントが進む)。
出力文字は文字を格納する役目をもつfunctionに渡される。この関数は1つの文字を引数に出力される文字の回数呼び出され、格納したい場所にその文字を格納する役目をもつ。
t
出力文字はエコーエリアに表示される。
nil
出力ストリームにnil
が指定された場合は、かわりにstandard-output
の値が使用されることを意味する。この値はデフォルトの出力ストリーム(default
output stream)であり、非nil
でなければならない。
出力ストリームとしてのシンボルは、(もしあれば)そのシンボルの関数定義と等価である。
有効な出力ストリームの多くは、入力ストリームとしても有効です。したがって入力ストリームと出力ストリームの違いは、Lispオブジェクトの型ではなく、どのようにLispオブジェクトを使うかという点です。
以下はバッファーを出力ストリームとして使用する例です。ポイントは最初は‘the’の中の‘h’の直前にあります。そして最後も同じ‘h’の直前に配置されます。
---------- Buffer: foo ---------- This is t∗he contents of foo. ---------- Buffer: foo ----------
(print "This is the output" (get-buffer "foo")) ⇒ "This is the output"
---------- Buffer: foo ---------- This is t "This is the output" ∗he contents of foo. ---------- Buffer: foo ----------
次はマーカーを出力ストリームとして使用する例です。マーカーは最初はバッファーfoo
内の単語‘the’の中の‘t’と‘h’の間にあります。最後には挿入されたテキストによってマーカーが進んで、同じ‘h’の前に留まります。通常の方法で見られるようなポイント位置への影響がないことに注意してください。
---------- Buffer: foo ---------- This is the ∗output ---------- Buffer: foo ----------
(setq m (copy-marker 10)) ⇒ #<marker at 10 in foo>
(print "More output for foo." m) ⇒ "More output for foo."
---------- Buffer: foo ---------- This is t "More output for foo." he ∗output ---------- Buffer: foo ----------
m ⇒ #<marker at 34 in foo>
以下はエコーエリアに出力を表示する例です:
(print "Echo Area output" t) ⇒ "Echo Area output" ---------- Echo Area ---------- "Echo Area output" ---------- Echo Area ----------
最後は関数を出力ストリームとして使用する例です。関数eat-output
は与えられたそれぞれの文字をlast-output
の先頭にconsします(コンスセルおよびリストの構築を参照)。最後にはリストには出力されたすべての文字が逆順で含まれます。
(setq last-output nil) ⇒ nil
(defun eat-output (c) (setq last-output (cons c last-output))) ⇒ eat-output
(print "This is the output" 'eat-output) ⇒ "This is the output"
last-output ⇒ (10 34 116 117 112 116 117 111 32 101 104 116 32 115 105 32 115 105 104 84 34 10)
このリストを逆転すれば正しい順序で出力することができます:
(concat (nreverse last-output)) ⇒ " \"This is the output\" "
concat
を呼び出してリストを文字列に変換すれば、内容をより明解に確認できます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではオブジェクトをオブジェクトのプリント表現に変換して、LispオブジェクトをプリントするLisp関数を説明します。
Emacsプリント関数には、正しく読み取れるように必要なとき出力にクォート文字を追加するものがあります。使用されるクォート文字は‘"’と‘\’です。これらは文字列をシンボルと区別するとともに、文字列とシンボル内の区切り文字が読み取りの際に区切り文字として扱われることを防ぎます。完全な詳細はプリント表現と読み取り構文を参照してください。クォートするかしないかはプリント関数の選択によって指定できます。
そのテキストがLispに読み戻す場合、またはLispプログラマーにLispオブジェクトを明解に説明するのが目的の場合は、曖昧さを避けるためにクォート文字をプリントするべきです。しかしプログラマー以外の人間にたいして出力の見栄えを良くするのが目的なら、通常はクォートなしでプリントしたほうがよいでしょう。
Lispオブジェクトは自己参照ができます。通常の方法で自己参照オブジェクトをプリントするにはテキストが無限に必要であり、その試みにより無限再帰が発生する恐れがあります。Emacsはそのような再帰を検知して、すでにプリントされたオブジェクトを再帰的にプリントするかわりに、‘#level’をプリントします。たとえば以下はカレントのプリント処理において、レベル0のオブジェクトを再帰的に参照することを示しています:
(setq foo (list nil)) ⇒ (nil) (setcar foo foo) ⇒ (#0)
以下の関数ではstreamは出力ストリームを意味します(出力ストリームの説明は前のセクションを参照)。streamがnil
または省略された場合のデフォルトはstandard-output
の値になります。
print
関数はプリントを行うための便利な手段である。この関数はobjectの前後に改行を付与してobjectのプリント表現をstreamにプリントする。クォート文字が使用される。print
はobjectをリターンする。たとえば:
(progn (print 'The\ cat\ in) (print "the hat") (print " came back")) -| -| The\ cat\ in -| -| "the hat" -| -| " came back" ⇒ " came back"
この関数はobjectのプリント表現をstreamに出力する。この関数はprint
のように出力を分割するための改行をプリントしないが、print
のようにクォート文字を使用する。objectをリターンする。
(progn (prin1 'The\ cat\ in) (prin1 "the hat") (prin1 " came back")) -| The\ cat\ in"the hat"" came back" ⇒ " came back"
この関数はobjectのプリント表現をstreamに出力する。objectをリターンする。
この関数はread
ではなく人間が読める出力を生成することを意図しているので、クォート文字を挿入せず文字列のコンテンツの前後にダブルクォート文字を配置しない。各呼び出しの間にスペースを何も出力しない。
(progn (princ 'The\ cat) (princ " in the \"hat\"")) -| The cat in the "hat" ⇒ " in the \"hat\""
この関数はstreamに改行を出力する。関数名は“terminate
print”に由来する。ensureが非nil
の場合は、もしstreamがすでに行頭にあれば何も改行をプリントしない。この場合はstreamは関数であってはならず、もし関数ならエラーがシグナルされることに注意。この関数は改行をプリントしたらt
をリターンする。
この関数はcharacterをstreamに出力する。characterをリターンする。
この関数は同じ引数でprin1
がプリントするテキストを含む文字列をリターンする。
(prin1-to-string 'foo) ⇒ "foo"
(prin1-to-string (mark-marker)) ⇒ "#<marker at 2773 in strings.texi>"
noescapeが非nil
なら出力中のクォート文字の使用を抑制する(この引数はEmacsバージョン19以降でサポートされた)。
(prin1-to-string "foo") ⇒ "\"foo\""
(prin1-to-string "foo" t) ⇒ "foo"
Lispオブジェクトのプリント表現を文字列として取得する別の手段については、文字列のフォーマットのformat
を参照のこと。
このマクロは出力を文字列に送るようstandard-output
をセットアップしてフォームbodyを実行する。その文字列をリターンする。
たとえばカレントバッファー名が‘foo’なら、
(with-output-to-string (princ "The buffer is ") (princ (buffer-name)))
は"The buffer is foo"
をリターンする。
この関数はprin1
と同じようにobjectをstreamに出力するが、より優雅(pretty)な方法でこれを行う。すなわちこの関数は人間がより読みやすいようにオブジェクトのインデントとパディングを行う。
batchモードでバイナリー入出力を使用する必要がある場合(このセクションで説明した非Posixホスト上で任意のバイナリーデータの書き込みや改行変換の回避するために関数を使用する場合)には、set-binary-modeを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この変数の値はデフォルト出力ストリーム(stream引数がnil
のときプリント関数が使用するストリーム)である。デフォルトはt
で、これはエコーエリアに表示することを意味する。
これが非nil
なら、省略されたリーダー構文(たとえば(quote
foo)
を'foo
、(function
foo)
を#'foo
のように)を使用してクォートされたフォームをプリントすることを意味する。
この変数が非nil
なら、文字列内の改行は‘\n’、改ページは‘\f’でプリントされる。これらの文字は通常は実際の改行と改ページとしてプリントされる。
この変数はクォートつきのプリントを行うプリント関数prin1
とprint
に影響を与える。princ
に影響はない。以下はprin1
を使用した場合の例である:
(prin1 "a\nb") -| "a -| b" ⇒ "a b"
(let ((print-escape-newlines t)) (prin1 "a\nb")) -| "a\nb" ⇒ "a b"
2つ目の式ではprin1
を呼び出す間はprint-escape-newlines
のローカルバインドが効果をもつが、結果をプリントするときには効果がない。
この変数が非nil
なら、クォートつきでプリントするプリント関数prin1
とprint
は文字列内のユニバイトの非ASCII文字を無条件でバックスラッシュシーケンスとしてプリントする。
これらの関数は出力ストリームがマルチバイトバッファー、あるいはマーカーがマルチバイトバッファーをポイントするときは、この変数の値に関わらずユニバイト非ASCII文字にたいしてバックスラッシュシーケンスを使用する。
この変数が非nil
なら、クォートつきでプリントするプリント関数prin1
とprint
は、文字列内のマルチバイトの非ASCII文字を無条件でバックスラッシュシーケンスとしてプリントする。
これらの関数は出力ストリームがユニバイトバッファー、あるいはマーカーがユニバイトバッファーをポイントするときは、この変数の値に関わらずマルチバイト非ASCII文字にたいしてバックスラッシュシーケンスを使用する。
この変数の値は任意のリスト、ベクター、ブールベクターをプリントする際の最大要素数である。プリントされるオブジェクトがこれより多くの要素をもつ場合は、省略記号(“...”)で省略される。
値がnil
(デフォルト)の場合は無制限。
(setq print-length 2) ⇒ 2
(print '(1 2 3 4 5)) -| (1 2 ...) ⇒ (1 2 ...)
この変数の値はプリント時の丸カッコ(parentheses: “()”)と角カッコ(brackets:
“[]"’)のネスト最大深さである。この制限を超える任意のリストとベクターは省略記号(“...”)で省略される。値nil
(デフォルト)は無制限を意味する。
これらはeval-expression
によって使用されるprint-length
とprint-level
の値であり、したがって間接的に多くのインタラクティブな評価コマンドにより使用される(Evaluating Emacs-Lisp Expressions in The GNU Emacs Manualを参照)。
以下の変数は循環構造および共有構造の検出と報告に使用されます:
非nil
なら、この変数はプリント時の循環構造と共有構造の検出を有効にする。循環オブジェクトの読み取り構文を参照のこと。
非nil
なら、この変数はプリント時のインターンされていないシンボル(シンボルの作成とinternを参照)の検出を有効にする。これが有効なら、インターンされていないシンボルはプレフィックス‘#:’とともにプリントされる。このプレフィックスは、Lispリーダーにたいしてインターンされていないシンボルを生成するよう告げる。
非nil
なら、複数のプリント呼び出しを通じて通番が振られることを意味する。これは‘#n=’ラベルと‘#m#’参照にたいしてプリントされる数字に影響する。この変数をsetq
でセットしてはならない。let
を使用して一時的にt
にバインドすること。これを行う場合はprint-number-table
もnil
にバインドすること。
この変数はprint-circle
機能を実装するために、プリント処理で内部的に使用されるベクターを保持する。print-continuous-numbering
をバインドするときにこの変数をnil
にバインドする以外は、この変数を使用するべきではない。
この変数は浮動小数点数をプリントする方法を指定する。デフォルトはnil
で、これは情報を失わずにその数値を表せるもっとも短い出力を使用することを意味する。
出力フォーマットをより精密に制御するために、この変数に文字列をセットできる。この文字列にはCのsprintf
関数で使用される‘%’指定子をセットする。この変数で使用することのできる制限についての詳細は、この変数のドキュメント文字列を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ミニバッファー(minibuffer)とは、単一の数プレフィックス引数(numeric prefix argument)より複雑な引数を読み取るためにEmacsコマンドが使用する特別なバッファーのことです。これらの引数にはファイル名、バッファー名、(M-xでの)コマンド名が含まれます。ミニバッファーはフレームの最下行、エコーエリア(エコーエリアを参照)と同じ場所に表示されますが、引数を読み取るときだけ使用されます。
19.1 ミニバッファーの概念 | ミニバッファーに関する基本的な情報。 | |
19.2 ミニバッファーでのテキスト文字列の読み取り | そのままのテキスト文字列を読み取る方法。 | |
19.3 ミニバッファーでのLispオブジェクトの読み取り | Lispオブジェクトや式を読み取る方法。 | |
19.4 ミニバッファーのヒストリー | ユーザーが再利用できるように以前のミニバッファー入力は記録される。 | |
19.5 入力の初期値 | ミニバッファーにたいして初期内容を指定する。 | |
19.6 補完 | 補完の呼び出しとカスタマイズ方法。 | |
19.7 Yes-or-Noによる問い合わせ | 問いにたいし単純な答えを求める。 | |
19.8 複数のY-or-Nの問い合わせ | 一連の類似する問いに答える。 | |
19.9 パスワードの読み取り | 端末からパスワードを読み取る。 | |
19.10 ミニバッファーのコマンド | ミニバッファー内でキーバインドとして使用されるコマンド。 | |
19.11 ミニバッファーのウィンドウ | 特殊なミニバッファーウィンドウを処理する。 | |
19.12 ミニバッファーのコンテンツ | どのようなコマンドがミニバッファーのテキストにアクセスするか。 | |
19.13 再帰的なミニバッファー | ミニバッファーへの再帰的なエントリーが許容されるかどうか。 | |
19.14 ミニバッファー、その他の事項 | カスタマイズ用のさまざまなフックや変数。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ほとんどの点においてミニバッファーは普通のEmacsバッファーです。編集コマンドのようなバッファーにたいする操作のほとんどはミニバッファーでも機能します。しかしバッファーを管理する操作の多くはミニバッファーに適用できません。ミニバッファーは常に‘ *Minibuf-number*’という形式の名前をもち変更はできません。ミニバッファーはミニバッファー用の特殊なウィンドウだけに表示されます。これらのウィンドウは常にフレーム最下に表示されます(フレームにミニバッファーウィンドウがないときやミニバッファーウィンドウだけをもつ特殊なフレームもある)。ミニバッファーとフレームを参照してください。
ミニバッファー内のテキストは常にプロンプト文字列(prompt
string)で開始されます。これはミニバッファーを使用しているプログラムが、ユーザーにたいしてどのような種類の入力が求められているか告げるために指定するテキストです。このテキストは意図せずに変更してしまわないように、読み取り専用としてマークされます。このテキストはbeginning-of-line
、forward-word
、forward-sentence
、forward-paragraph
を含む特定の移動用関数が、プロンプトと実際のテキストの境界でストップするようにフィールド(フィールドの定義と使用を参照)としてもマークされています。
ミニバッファーのウィンドウは通常は1行です。ミニバッファーのコンテンツがより多くのスペースを要求する場合は自動的に拡張されます。ミニバッファーのウィンドウがアクティブな間は、ウィンドウのサイズ変更コマンドで一時的にウィンドウのサイズを変更できます。サイズの変更はミニバッファーをexitしたときには、通常のサイズにリバートされます。ミニバッファーがアクティブでないときはフレーム内の他のウィンドウでウィンドウのサイズ変更コマンドを使用するか、マウスでモードラインをドラッグしてミニバッファーのサイズを永続的に変更できます(現実装ではこれが機能するにはresize-mini-windows
がnil
でなければならない)。フレームがミニバッファーだけを含む場合は、そのフレームのサイズを変更してミニバッファーのサイズを変更できます。
ミニバッファーの使用によって入力イベントが読み取られて、this-command
やlast-command
のような変数の値が変更されます(コマンドループからの情報を参照)。プログラムにそれらを変更させたくない場合は、ミニバッファーを使用するコードの前後でそれらをバインドするべきです。
ある状況下では、アクティブなミニバッファーが存在するときでもコマンドがミニバッファーを使用できます。そのようなミニバッファーは再帰ミニバッファー(recursive
minibuffer)と呼ばれます。この場合は最初のミニバッファーは‘ *Minibuf-1*’という名前になります。再帰ミニバッファーはミニバッファー名の最後の数字を増加することにより命名されます(名前はスペースで始まるので通常のバッファーリストには表示されない)。再帰ミニバッファーが複数ある場合は、最内の(もっとも最近にエンターされた)ミニバッファーがアクティブなミニバッファーになります。このバッファーが、いわゆるミニバッファーと通常は呼ばれるバッファーです。変数enable-recursive-minibuffers
、またはコマンドシンボルのその名前のプロパティをセットすることにより再帰ミニバッファーを許可したり禁止できます(再帰的なミニバッファーを参照)。
他のバッファーと同様、ミニバッファーは特別なキーバインドを指定するためにローカルキーマップ(キーマップを参照)を使用します。ミニバッファーを呼び出す関数も、処理を行うためにローカルマップをセットアップします。補完なしのミニバッファーローカルマップについてはミニバッファーでのテキスト文字列の読み取りを参照してください。補完つきのミニバッファーローカルマップについては補完を行うミニバッファーコマンドを参照してください。
ミニバッファーが非アクティブのときのメジャーモードはminibuffer-inactive-mode
、キーマップはminibuffer-inactive-mode-map
です。これらは実際にはミニバッファーが別フレームにある場合のみ有用です。ミニバッファーとフレームを参照してください。
Emacsがバッチモードで実行されている場合には、ミニバッファーからの読み取りリクエストは、実装にはEmacs開始時に提供された標準入力記述子から行を読み取ります。これは基本的な入力だけをサポートします。特別なミニバッファーの機能(ヒストリー、補完など)はバッチモードでは利用できません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ミニバッファー入力にたいする基本的なプリミティブはread-from-minibuffer
で、これは文字列とLispオブジェクトの両方からテキスト表現されたフォームを読み取ることができます。関数read-regexp
は特別な種類の文字列である正規表現式(正規表現を参照)の読み取りに使用されます。コマンドや変数、ファイル名などの読み取りに特化した関数もあります(補完を参照)。
ほとんどの場合でにはLisp関数の途中でミニバッファー入力関数を呼び出すべきではありません。かわりにinteractive
指定されたコマンドの引数の読み取りの一環として、すべてのミニバッファー入力を行います。コマンドの定義を参照してください。
この関数はミニバッファーから入力を取得するもっとも一般的な手段である。デフォルトでは任意のテキストを受け入れて、それを文字列としてリターンする。しかしreadが非nil
なら、テキストをLispオブジェクトに変換するためにread
を使用する(入力関数を参照)。
この関数が最初に行うのはミニバッファーをアクティブにして、プロンプトにprompt(文字列でなければならない)を用いてミニバッファーを表示することである。その後にユーザーはミニバッファーでテキストを編集できる。
ミニバッファーをexitするためにユーザーがコマンドをタイプするとき、read-from-minibuffer
はミニバッファー内のテキストからリターン値を構築する。通常はそのテキストを含む文字列がリターンされる。しかしreadが非nil
なら、read-from-minibuffer
はテキストを読み込んで結果を未評価のLispオブジェクトでリターンする(読み取りについての詳細はSee section 入力関数を参照)。
引数defaultはヒストリーコマンドを通じて利用できるデフォルト値を指定する。値には文字列、文字列リスト、またはnil
を指定する。文字列と文字列リストは、ユーザーがM-nで利用可能な“未来のヒストリー(future
history)”になる。
readが非nil
なら、ユーザーの入力が空のときのread
の入力としてもdefaultが使用される。defaultが文字列リストの!は、最初の文字列が入力として使用される。defaultがnil
なら、空の入力はend-of-file
エラーとなる。しかし通常(readがnil
)の場合には、ユーザーの入力が空のときread-from-minibuffer
はdefaultを無視して空文字列""
をリターンする。この点ではこの関数はこのチャプターの他のどのミニバッファー入力関数とも異なる。
keymapが非nil
なら、そのキーマップはミニバッファー内で使用されるローカルキーマップとなる。keymapが省略またはnil
なら、minibuffer-local-map
の値がキーマップとして使用される。キーマップの指定は補完のようなさまざまなアプリケーションにたいしてミニバッファーをカスタマイズする、もっとも重要な方法である。
引数historyは入力の保存やミニバッファー内で使用されるヒストリーコマンドが使用するヒストリーリスト変数を指定する。デフォルトはminibuffer-history
。同様にオプションでヒストリーリスト内の開始位置を指定できる。ミニバッファーのヒストリーを参照のこと。
変数minibuffer-allow-text-properties
が非nil
なら、リターンされる文字列にはミニバッファーでのすべてのテキストプロパティが含まれる。それ以外なら、値がリターンされるときすべてのテキストプロパティが取り除かれる。
引数inherit-input-methodが非nil
なら、ミニバッファーにエンターする前にカレントだったバッファーが何であれ、カレントの入力メソッド(入力メソッドを参照)、およびenable-multibyte-characters
のセッティング(テキストの表現方法を参照)が継承される。
ほとんどの場合、initialの使用は推奨されない。非nil
値の使用は、historyにたいするコンスセル指定と組み合わせる場合のみ推奨する。入力の初期値を参照のこと。
この関数はミニバッファーから文字列を読み取ってそれをリターンする。引数prompt、initial、history、inherit-input-methodはread-from-minibuffer
で使用する場合と同様。使用されるキーマップはminibuffer-local-map
。
オプション引数defaultはread-from-minibuffer
の場合と同様に使用されるが、ユーザーの入力が空の場合にリターンするデフォルト値も指定する。read-from-minibuffer
の場合と同様に値は文字列、文字列リスト、またはnil
(空文字列と等価)である。defaultが文字列のときは、その文字列がデフォルト値になる。文字列リストのときは、最初の文字列がデフォルト値になる(これらの文字列はすべて“未来のミニバッファーヒストリー(future
minibuffer history)”としてユーザーが利用できる)。
この関数はread-from-minibuffer
を呼び出すことによって機能する。
(read-string prompt initial history default inherit) ≡ (let ((value (read-from-minibuffer prompt initial nil nil history default inherit))) (if (and (equal value "") default) (if (consp default) (car default) default) value))
この関数はミニバッファーから文字列として正規表現を読み取ってそれをリターンする。ミニバッファーのプロンプト文字列promptが‘:’(とその後にオプションの空白文字)で終端されていなければ、この関数はデフォルトのリターン値(空文字列でない場合。以下参照)の前に‘: ’を付加する。
オプション引数defaultsは、入力が空の場合にリターンするデフォルト値を制御する。値は文字列、nil
(空文字列と等価)、文字列リスト、シンボルのうちのいずれか。
defaultsがシンボルの場合、read-regexp
は変数read-regexp-defaults-function
(以下参照)の値を調べて非nil
のときはdefaultsよりそちらを優先的に使用する。この場合は値は以下のいずれか:
regexp-history-last
。これは適切なミニバッファーヒストリーリスト(以下参照)の最初の要素を使用することを意味する。
nil
、文字列、文字列リストのいずれか)がdefaultsの値となる。
これでread-regexp
がdefaultsを処理した結果はリストに確定する(値がnil
または文字列の場合は1要素のリストに変換する)。このリストにたいしてread-regexp
は以下のような入力として有用な候補をいくつか追加する:
これで関数はユーザー入力を取得するためにread-from-minibuffer
に渡す正規表現のリストを得た。リストの最初の要素は入力が空の場合のデフォルト値である。リストのすべての要素は“未来のミニバッファーヒストリー(future
minibuffer history)”となるリスト(see future list in The GNU Emacs Manualを参照)としてユーザーが利用可能になる。
オプション引数historyが非nil
なら、それは使用するミニバッファーヒストリーリストを指定するシンボルである(ミニバッファーのヒストリーを参照)。これが省略またはnil
なら、ヒストリーリストのデフォルトはregexp-history
となる。
関数read-regexp
は、デフォルトの正規表現リストを決定するためにこの変数の値を使用するかもしれない。非nil
なら、この変数は以下のいずれかである:
regexp-history-last
。
nil
、文字列、文字列リストのいずれかをリターンする引数なしの関数。
これらの変数の使い方についての詳細は、上述のread-regexp
を参照のこと。
この変数がnil
なら、read-from-minibuffer
とread-string
はミニバッファー入力をリターンする前にすべてのテキストプロパティを取り除く。しかしread-no-blanks-input
(以下参照)、同様に補完つきでミニバッファー入力を行うread-minibuffer
とそれに関連する関数(Reading Lisp Objects With the
Minibufferを参照)は、この変数の値に関わらず無条件でテキストプロパティを破棄する。
これはミニバッファーからの読み取りにたいするデフォルトローカルキーマップである。デフォルトでは以下のバインディングをもつ:
exit-minibuffer
exit-minibuffer
abort-recursive-edit
next-history-element
previous-history-element
next-matching-history-element
previous-matching-history-element
この関数はミニバッファーから文字列を読み取るが、入力の一部として空白文字を認めず、そのかわりに空白文字は入力を終端させる。引数prompt、initial、inherit-input-methodはread-from-minibuffer
で使用するときと同様。
これは関数read-from-minibuffer
の簡略化されたインターフェイスであり、キーマップminibuffer-local-ns-map
の値をkeymap引数としてread-from-minibuffer
関数に渡す。キーマップminibuffer-local-ns-map
はC-qをリバインドしないので、クォートすることによって文字列内にスペースを挿入することが可能である。
minibuffer-allow-text-properties
の値に関わらず、この関数はテキストプロパティを破棄する。
(read-no-blanks-input prompt initial) ≡ (let (minibuffer-allow-text-properties) (read-from-minibuffer prompt initial minibuffer-local-ns-map))
このビルトイン変数は関数read-no-blanks-input
内でミニバッファーローカルキーマップとして使用されるキーマップである。デフォルトではminibuffer-local-map
のバインディングに加えて、以下のバインディングが有効になる:
exit-minibuffer
exit-minibuffer
self-insert-and-exit
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではミニバッファーでLispオブジェクトを読み取る関数を説明します。
この関数はミニバッファーを使用してLispオブジェクトを読み取って、それを評価せずにリターンする。引数promptとinitialはread-from-minibuffer
のときと同様に使用する。
これはread-from-minibuffer
関数にたいする簡略化されたインターフェイスである。
(read-minibuffer prompt initial) ≡ (let (minibuffer-allow-text-properties) (read-from-minibuffer prompt initial nil t))
以下の例では初期入力として文字列"(testing)"
を与えている:
(read-minibuffer
"Enter an expression: " (format "%s" '(testing)))
;; 以下はミニバッファーでの表示:
---------- Buffer: Minibuffer ---------- Enter an expression: (testing)∗ ---------- Buffer: Minibuffer ----------
ユーザーはRETをタイプして初期入力をデフォルトとして利用したり入力を編集することができる。
この関数はミニバッファーを使用してLisp式を読み取り、それを評価して結果をリターンする。引数promptとinitialの使い方はread-from-minibuffer
と同様。
この関数はread-minibuffer
の呼び出し結果を単に評価する:
(eval-minibuffer prompt initial) ≡ (eval (read-minibuffer prompt initial))
この関数はミニバッファーでLisp式を読み取り、それを評価して結果をリターンする。このコマンドとeval-minibuffer
の違いは、このコマンドでは初期値としてのformはオプションではなく、テキストの文字列ではないプリント表現に変換されたLispオブジェクトとして扱われることである。これはprin1
でプリントされるので、文字列の場合はテキスト初期値内にダブルクォート文字(‘"’)が含まれる。出力関数を参照のこと。
以下の例では、すでに有効なフォームであるようなテキスト初期値として式をユーザーに提案している:
(edit-and-eval-command "Please edit: " '(forward-word 1)) ;; 前の式を評価した後に、 ;; ミニバッファーに以下が表示される:
---------- Buffer: Minibuffer ---------- Please edit: (forward-word 1)∗ ---------- Buffer: Minibuffer ----------
すぐにRET をタイプするとミニバッファーをexitして式を評価するので、1単語分ポイントは前進する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ミニバッファーヒストリーリスト(minibuffer history list)は手軽に再利用できるように以前のミニバッファー入力を記録します。ミニバッファーヒストリーリストは、(以前に入力された)文字列のリストであり、もっとも最近の文字列が先頭になります。
多数のミニバッファーが個別に存在し、異なる入力の種類に使用されます。それぞれのミニバッファー使用にたいして正しいヒストリーリストを指定するのはLispプログラマーの役目です。
ミニバッファーヒストリーリストは、read-from-minibuffer
とcompleting-read
のオプション引数historyに指定します。以下が利用できる値です:
ヒストリーリストとしてvariable(シンボル)を使用する。
ヒストリーリストとしてvariable(シンボル)を使用して、ヒストリー位置の初期値をstartpos(負の整数)とみなす。
startposに0を指定するのは、単にシンボルvariableだけを指定するのと等価である。previous-history-element
はミニバッファー内のヒストリーリストの最新の要素を表示するだろう。
正のstartposを指定すると、ミニバッファーヒストリー関数は(elt variable(1-
startpos))
がミニバッファー内でカレントで表示されているヒストリー要素であるかのように振る舞う。
一貫性を保つためにミニバッファー入力関数のinitial引数(入力の初期値を参照)を使用して、ミニバッファーの初期内容となるヒストリー要素も指定すべきである。
historyを指定しない場合には、デフォルトのヒストリーリストminibuffer-history
が使用されます。他の標準的なヒストリーリストについては以下を参照してください。最初に使用する前にnil
に初期化するだけで、独自のヒストリーリストを作成することもできます。
read-from-minibuffer
とcompleting-read
は、どちらも新たな要素を自動的にヒストリーリストに追加して、ユーザーがそのリストのアイテムを再使用するためのコマンドを提供します。ヒストリーリストを使用するためにプログラムが行う必要があるのはリストの初期化と、使用するときに入力関数にリストの名前を渡すだけです。しかしミニバッファー入力関数がリストを使用していないときに手動でリストを変更しても問題はありません。
新たな要素をヒストリーリストに追加するEmacs関数は、リストが長くなりすぎたときに古い要素の削除を行うこともできます。変数history-length
は、ほとんどのヒストリーリストの最大長を指定する変数です。特定のヒストリーリストにたいして異なる最大長を指定するには、そのヒストリーリストのシンボルのhistory-length
プロパティにその最大長をセットします。変数history-delete-duplicates
にはヒストリー内の重複を削除するかどうかを指定します。
この関数はneweltが空文字列でなければ、それを新たな要素として変数history-varに格納されたヒストリーリストに追加して、更新されたヒストリーリストをリターンする。これはmaxeltかhistory-length
がが非nil
なら、リストの長さをその変数の値に制限する(以下参照)。maxeltに指定できる値の意味はhistory-length
の値と同様。
add-to-history
は通常はhistory-delete-duplicates
が非nil
ならば、ヒストリーリスト内の重複メンバーを削除する。しかしkeep-allが非nil
なら、それは重複を削除しないことを意味し、たとえneweltが空でもリストに追加する。
この変数の値がnil
なら、ミニバッファーから読み取りを行う標準的な関数はヒストリーリストに新たな要素を追加しない。これによりLispプログラムがadd-to-history
を使用して明示的に入力ヒストリーを管理することになる。デフォルト値はt
。
この変数の値は、最大長を独自に指定しないすべてのヒストリーリストの最大長を指定する。値がt
なら最大長がない(古い要素を削除しない)ことを意味する。ヒストリーリスト変数のシンボルのhistory-length
プロパティが非nil
なら、その特定のヒストリーリストにたいする最大長として、そのプロパティ値がこの変数をオーバーライドする。
この変数の値がt
なら、それは新たなヒストリー要素の追加時に以前からある等しい要素が削除されることを意味する。
以下は標準的なミニバッファーヒストリーリスト変数です:
ミニバッファーヒストリー入力にたいするデフォルトのヒストリーリスト。
query-replace
の引数(と他のコマンドの同様の引数)にたいするヒストリーリスト。
ファイル名引数にたいするヒストリーリスト。
バッファー名引数にたいするヒストリーリスト。
正規表現引数にたいするヒストリーリスト。
拡張コマンド名引数にたいするヒストリーリスト。
シェルコマンド引数にたいするヒストリーリスト。
評価されるためのLisp式引数にたいするヒストリーリスト。
フェイス引数にたいするヒストリーリスト。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ミニバッファー入力にたいする関数のいくつかには、initialと呼ばれる引数があります。これは通常のように空の状態で開始されるのではなく、特定のテキストとともにミニバッファーが開始されることを指定しますが、ほとんどの場合においては推奨されない機能です。
initialが文字列なら、ミニバッファーはその文字列のテキストを含む状態で開始され、ユーザーがそのテキストの編集を開始するとき、ポイントはテキストの終端にあります。ユーザーがミニバッファーをexitするために単にRETをタイプした場合には、この入力文字列の初期値をリターン値だと判断します。
initialにたいして非nil
値の使用には反対します。なぜなら初期入力は強要的なインターフェイスだからです。ユーザーにたいして有用なデフォルト入力を提案するためには、ヒストリーリストやデフォルト値の提供のほうがより有用です。
しかしinitial引数にたいして文字列を指定すべき状況が1つだけあります。それはhistory引数にコンスセルを指定したときです。ミニバッファーのヒストリーを参照してください。
initialは(string
.
position)
という形式をとることもできます。これはstringをミニバッファーに挿入するが、その文字列のテキスト中のpositionにポイントを配置するという意味です。
歴史的な経緯により、positionは異なる関数の間で実装が統一されていません。completing-read
ではpositionの値は0基準です。つまり値0は文字列の先頭、1は最初の文字の次、...を意味します。しかしread-minibuffer
、およびこの引数をサポートする補完を行わない他のミニバッファー入力関数では、1は文字列の先頭、2は最初の文字の次、...を意味します。
initialの値としてのコンスセルの使用は推奨されません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
補完(complete,
ompletion)は省略された形式から始まる名前の残りを充填する機能です。補完はユーザー入力と有効な名前リストを比較して、ユーザーが何をタイプしたかで名前をどの程度一意に判定できるか判断することによって機能します。たとえばC-x
b (switch-to-buffer
)とタイプしてからスイッチしたいバッファー名の最初の数文字をタイプして、その後にTAB
(minibuffer-complete
)をタイプすると、Emacsはその名前を可能な限り展開します。
標準的なEmacsコマンドはシンボル、ファイル、バッファー、プロセスの名前にたいする補完を提案します。このセクションの関数により、他の種類の名前にたいしても補完を実装できます。
try-completion
関数は補完にたいする基本的なプリミティブです。これは初期文字列にたいして文字列セットをマッチして、最長と判定された補完をリターンします。
関数completing-read
は補完にたいする高レベルなインターフェイスを提供します。completing-read
の呼び出しによって有効な名前リストの判定方法が指定されます。その後にこの関数は補完にたいして有用ないくつかのコマンドにキーバインドするローカルキーマップとともに、ミニバッファーをアクティブ化します。その他の関数は特定の種類の名前を補完つきで読み取る、簡便なインターフェイスを提供します。
19.6.1 基本的な補完関数 | 文字列を補完する低レベル関数。 | |
19.6.2 補完とミニバッファー | 補完つきでミニバッファーを呼び出す。 | |
19.6.3 補完を行うミニバッファーコマンド | ||
19.6.4 高レベルの補完関数 | 特別なケースに有用な補完(バッファー名や変数名などの読み取り)。 | |
19.6.5 ファイル名の読み取り | ファイル名やシェルコマンドの読み取りに補完を使用する。 | |
19.6.6 補完変数 | 補完の挙動を制御する変数。 | |
19.6.7 プログラムされた補完 | 独自の補完関数を記述する。 | |
19.6.8 通常バッファーでの補完 | 通常バッファー内でのテキスト補完。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の補完関数は、その関数自身ではミニバッファーで何も行いません。ここではミニバッファーを使用する高レベルの補完機能とともに、これらの関数について説明します。
この関数はcollection内のstringに可能なすべての補完の共通する最長部分文字列をリターンする。
collectionは補完テーブル(completion table)と呼ばれる。値は文字列リスト、コンスセル、obarray、ハッシュテーブル、または補完関数でなければならない。
try-completion
は補完テーブルにより指定された許容できる補完それぞれにたいして、stringと比較を行う。許容できる補完マッチが存在しなければnil
をリターンする。マッチする補完が1つだけで、それが完全一致ならばt
をリターンする。それ以外は、すべてのマッチ可能な補完に共通する最長の初期シーケンスをリターンする。
collectionがリストなら、許容できる補完(permissible
completions)はそのリストの要素によって指定される。リストの要素は文字列、またはCARが文字列、または(symbol-name
によって文字列に変換される)シンボルであるようなコンスセルである。リストに他の型の要素が含まれる場合は無視される。
collectionがobarray(シンボルの作成とinternを参照)なら、そのobarray内のすべてのシンボル名が許容できる補完セットを形成する。
collectionがハッシュテーブルの場合には、文字列かシンボルのキーが利用可能な補完となる。他のキーは無視される。
collectionとして関数を使用することもできる。この場合にはその関数だけが補完を処理する役目を担う。つまりtry-completion
は、この関数が何をリターンしようともそれをリターンする。この関数はstring、predicate、nil
の3つの引数で呼び出される(3つ目の引数は同じ関数をall-completions
でも使用して、どちらの場合でも適切なことを行うため)。プログラムされた補完を参照のこと。
引数predicateが非nil
の場合には、collectionがハッシュテーブルなら1引数、それ以外は2引数の関数でなければならない。これは利用可能なマッチのテストに使用され、マッチはpredicateが非nil
をリターンしたときだけ受け入れられる。predicateに与えられる引数は文字列、alistのコンスセル(CARが文字列)、またはobarrayのシンボル(シンボル名ではない)のいずれか。collectionがハッシュテーブルなら、predicateは文字列キー(string
key)と連想値(associated value)の2引数で呼び出される。
これらに加えて許容され得るためには、補完はcompletion-regexp-list
内のすべての正規表現にもマッチしなければならない。(collectionが関数なら、その関数自身がcompletion-regexp-list
を処理する必要がある)。
以下の1つ目の例では、文字列‘foo’がalistのうち3つのCARとマッチされている。すべてのマッチは文字‘fooba’で始まるので、それが結果となる。2つ目の例では可能なマッチは1つだけで、しかも完全一致なのでリターン値はt
になる。
(try-completion "foo" '(("foobar1" 1) ("barfoo" 2) ("foobaz" 3) ("foobar2" 4))) ⇒ "fooba"
(try-completion "foo" '(("barfoo" 2) ("foo" 3))) ⇒ t
以下の例では文字‘forw’で始まるシンボルが多数あり、それらはすべて単語‘forward’で始まる。ほとんどのシンボルはその後に‘-’が続くが、すべてではないので‘forward’までしか補完できない。
(try-completion "forw" obarray) ⇒ "forward"
最後に以下の例では述語test
に渡される利用可能なマッチは3つのうち2つだけである(文字列‘foobaz’は短すぎる)。これらは両方とも文字列‘foobar’で始まる。
(defun test (s) (> (length (car s)) 6)) ⇒ test
(try-completion "foo" '(("foobar1" 1) ("barfoo" 2) ("foobaz" 3) ("foobar2" 4)) 'test) ⇒ "foobar"
この関数はstringの利用可能な補完すべてのリストをリターンする。この関数の引数はtry-completion
の引数と同じであり、try-completion
が行うのと同じ方法でcompletion-regexp-list
を使用する。
collectionか関数ならstring、predicate、t
の3つの引数で呼び出される。この場合はその関数がリターンするのが何であれ、all-completions
はそれをリターンする。プログラムされた補完を参照のこと。
以下の例はtry-completion
の例の関数test
を使用している。
(defun test (s) (> (length (car s)) 6)) ⇒ test
(all-completions "foo" '(("foobar1" 1) ("barfoo" 2) ("foobaz" 3) ("foobar2" 4)) 'test) ⇒ ("foobar1" "foobar2")
この関数はstringがcollectionとpredicateで指定された有効な補完候補ならnil
をリターンする。引数はtry-completion
の引数と同じ。たとえばcollectionが文字列リストなら、stringがリスト内に存在して、かつpredicateを満足すればtrueとなる。
この関数はtry-completion
が行うのと同じ方法でcompletion-regexp-list
を使用する。
predicateが非nil
でcollectionが同じ文字列を複数含む場合には、completion-ignore-case
にしたがってcompare-strings
で判定してそれらすべてをリターンするか、もしくは何もリターンしない。それ以外ではtest-completion
のリターン値は基本的に予測できない。
collectionが関数の場合はstring、predicate、lambda
の3つの引数で呼び出される。それが何をリターンするにせよtest-completion
はそれをリターンする。
この関数はポイントの前のテキストがstring、ポイントの後がsuffixと仮定して、collectionが扱うフィールドの境界(boundary)をリターンする。
補完は通常は文字列(string)全体に作用するので、すべての普通のコレクション(collection)にたいして、この関数は常に(0
. (length
suffix))
をリターンするだろう。しかしファイルにたいする補完などの、より複雑な補完は1回に1フィールド行われる。たとえばたとえ"/usr/share/doc"
が存在しても、"/usr/sh"
の補完に"/usr/share/"
は含まれるが、"/usr/share/doc"
は含まれないだろう。また"/usr/sh"
にたいするall-completions
に"/usr/share/"
は含まれず、"share/"
だけが含まれるだろう。stringが"/usr/sh"
、suffixが"e/doc"
なら、completion-boundaries
は(5
.
1)
をリターンするだろう。これはcollectionが"/usr/"
の後ろにあり"/doc"
の前にある領域に関する補完情報だけをリターンするであろうことを告げている。
補完alistを変数に格納した場合は、変数のrisky-local-variable
プロパティに非nil
をセットして、その変数がrisky(危険)だとマークすること。ファイルローカル変数を参照のこと。
この変数の値が非nil
なら、補完でのcase(大文字小文字)の違いは意味をもたない。read-file-name
では、この変数はread-file-name-completion-ignore-case
(ファイル名の読み取りを参照)にオーバーライドされる。read-buffer
では、この変数はread-buffer-completion-ignore-case
(高レベルの補完関数を参照)にオーバーライドされる。
これは正規表現のリストである。補完関数はこのリスト内のすべての正規表現にマッチした場合のみ許容できる補完と判断する。case-fold-search
(検索と大文字小文字を参照)ではcompletion-ignore-case
の値にバインドされる。
この変数は変数varを補完のためのcollectionとしてlazy(lazy: 力のない、だらけさせる、のろのろした、怠惰な、不精な、眠気を誘う)な方法で初期化する。ここでlazyとは、collection内の実際のコンテンツを必要になるまで計算しないという意味。このマクロはvarに格納する値の生成に使用する。varを使用して最初に補完を行ったとき、真の値が実際に計算される。これは引数なしでfunを呼び出すことにより行われる。funがリターンする値はvarの永続的な値となる。
以下は例:
(defvar foo (lazy-completion-table foo make-my-alist))
既存の補完テーブルを受け取って変更したバージョンをリターンする関数がいくつかあります。completion-table-case-fold
は大文字小文字を区別しない、case-insensitiveなテーブルをリターンします。completion-table-in-turn
とcompletion-table-merge
は、複数の入力テーブルを異なる方法で組み合わせます。completion-table-subvert
はテーブルを異なる初期プレフィックス(initial
prefix)で変更します。completion-table-with-quoting
はクォートされたテキストの処理に適したテーブルをリターンします。completion-table-with-predicate
は述語関数(predicate
function)によるフィルタリングを行います。completion-table-with-terminator
は終端文字列(terminating
string)を追加します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは補完つきでミニバッファーから読み取るための、基本的なインターフェイスを説明します。
この関数は補完の提供によりユーザーを支援して、ミニバッファーから文字列を読み取る。prompt (文字列でなければならない)のプロンプトとともにミニバッファーをアクティブ化する。
実際の補完は補完テーブルcollectionと補完述語predicateを関数try-completion
(基本的な補完関数を参照)に渡すことにより行われる。これは補完の使用されるローカルキーマップに特定のコマンドをバインドしたとき発生する。これらのコマンドのいくつかはtest-completion
も呼び出す。したがってpredicateが非nil
なら、collectionとcompletion-ignore-case
が矛盾しないようにすること。Definition of test-completionを参照されたい。
collectionが関数のときの詳細な要件はプログラムされた補完を参照のこと。
オプション引数require-matchの値はユーザーがミニバッファーをexitする方法を決定する。
nil
なら、通常のミニバッファーexitコマンドはミニバッファーの入力と無関係に機能する。
t
なら、入力がcollectionの要素に補完されるまで通常のミニバッファーexitコマンドは機能しない。
confirm
なら、どのような入力でもユーザーはexitできるが、入力がconfirm
の要素に補完されていなければ確認を求められる。
confirm-after-completion
なら、どのような入力でもユーザーはexitできるが、前のコマンドが補完コマンド(たとえばminibuffer-confirm-exit-commands
の中のコマンドのいずれか)で、入力の結果がcollectionの要素でなければ確認を求められる。補完を行うミニバッファーコマンドを参照のこと。
t
と同じだが、exitコマンドは補完処理中はexitしない。
しかしrequire-matchの値に関わらず、空の入力は常に許容される。この場合completing-read
はdefaultがリストなら最初の要素、defaultがnil
なら""
、またはdefaultをリターンする。文字列とdefault内の文字列はヒストリーコマンドを通じてユーザーが利用できる。
関数completing-read
はrequire-matchがnil
ならキーマップとしてminibuffer-local-completion-map
を、require-matchが非nil
ならminibuffer-local-must-match-map
を使用する。補完を行うミニバッファーコマンドを参照のこと。
引数historyは入力の保存とミニバッファーヒストリーコマンドに、どのヒストリーリスト変数を使用するか指定する。デフォルトはminibuffer-history
。ミニバッファーのヒストリーを参照のこと。
initialはほとんどの場合は推奨されない。historyにたいするコンスセル指定と組み合わせた場合のみ非nil
値の使用を推奨する。入力の初期値を参照のこと。デフォルト入力にたいしてはかわりにdefaultを使用すること。
引数inherit-input-methodが非nil
なら、ミニバッファーにエンターする前にカレントだったバッファーが何であれ、カレントの入力メソッド(入力メソッドを参照)、およびenable-multibyte-characters
のセッティング(テキストの表現方法を参照)が継承される。
変数completion-ignore-case
が非nil
なら、利用可能なマッチにたいして入力を比較するときの補完はcaseを区別しない。基本的な補完関数を参照のこと。このモードでの操作では、predicateもcaseを区別してはならない(さもないと驚くべき結果となるであろう)。
以下はcompleting-read
を使用した例:
(completing-read "Complete a foo: " '(("foobar1" 1) ("barfoo" 2) ("foobaz" 3) ("foobar2" 4)) nil t "fo")
;; 前の式を評価後に、 ;; ミニバッファーに以下が表示される: ---------- Buffer: Minibuffer ---------- Complete a foo: fo∗ ---------- Buffer: Minibuffer ----------
その後ユーザーがDEL DEL b
RETをタイプすると、completing-read
はbarfoo
をリターンする。
completing-read
関数は、実際に補完を行うコマンドの情報を渡すために変数をバインドする。これらの変数は以降のセクションで説明する。
この変数の値は関数でなければならず、補完つきの読み取りを実際に行うためにcompleting-read
から呼び出される。この関数はcompleting-read
と同じ引数を受け入れる。他の関数のバインドして通常のcompleting-read
の振る舞いを完全にオーバーライドすることができる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは補完のためにミニバッファーで使用されるキーマップ、コマンド、ユーザーオプションを説明します。
この変数の値はミニバッファー内の補完に使用される補完テーブルである。これはcompleting-read
がtry-completion
に渡す補完テーブルを含んだグローバル変数である。minibuffer-complete-word
のようなミニバッファー補完コマンドにより使用される。
この変数の値はcompleting-read
がtry-completion
に渡す述語(predicate)である。この変数は他のミニバッファー補完関数にも使用される。
この変数はミニバッファーをexitする前にEmacsが確認を求めるかどうかを決定する。completing-read
はこの変数をバインドして、exitする前に関数minibuffer-complete-and-exit
がこの値をチェックする。値がnil
なら確認は求められない。値がconfirm
の場合は、入力が有効な補完候補でなくてもユーザーはexitするかもしれないがEmacsは確認を求めない。値がconfirm-after-completion
の場合、入力が有効な補完候補でなくてもユーザーはexitするかもしれないが、ユーザーがminibuffer-confirm-exit-commands
内の任意の補完コマンドの直後に入力を確定した場合にはEmacsは確認を求める。
この変数には、completing-read
の引数require-matchがconfirm-after-completion
のときにミニバッファーexit前にEmacsに確認を求めさせるコマンドのリストが保持されている。このリスト内のコマンドを呼び出した直後にユーザーがミニバッファーのexitを試みるとEmacsは確認を求める。
この関数はせいぜい1つの単語からミニバッファーを補完する。たとえミニバッファーのコンテンツが1つの補完しかもたない場合でも、minibuffer-complete-word
はその単語に属さない最初の文字を超えた追加はしない。構文テーブルを参照のこと。
この関数は可能な限りミニバッファーのコンテンツを補完する。
この関数はミニバッファーのコンテンツを補完して確認が要求されない場合(たとえばminibuffer-completion-confirm
がnil
のとき)はexitする。確認が要求される場合には、このコマンドを即座に繰り返すことによって確認が行われないようにする。このコマンドは2回連続で実行された場合は確認なしで機能するようにプログラムされている。
この関数はカレントのミニバッファーのコンテンツで利用可能な補完のリストを作成する。これはall-completions
の引数collectionに変数minibuffer-completion-table
の値、引数predicateにminibuffer-completion-predicate
の値を使用して呼び出すことによって機能する。補完リストは*Completions*と呼ばれるバッファーのテキストとして表示される。
この関数はstandard-output
内のストリーム(通常はバッファー)にcompletionsを表示する(ストリームについての詳細はLispオブジェクトの読み取りとプリントを参照)。引数completionsは通常はall-completions
がリターンする補完リストそのものだが、そうである必要はない。要素はシンボルか文字列で、どちらも単にプリントされる。文字列2つのリストでもよく、2つの文字列が結合されたかのようにプリントされる。この場合、1つ目の文字列は実際の補完で、2つ目の文字列は注釈の役目を負う。
この関数はminibuffer-completion-help
より呼び出される。一般的には以下のようにwith-output-to-temp-buffer
とともに使用される。
(with-output-to-temp-buffer "*Completions*" (display-completion-list (all-completions (buffer-string) my-alist)))
この変数が非nil
なら、次の文字が一意でなく決定できないために補完が完了しないときは常に、補完コマンドは利用可能な補完リストを自動的に表示する。
completing-read
の値は、補完の1つが完全に一致することを要求されないときにローカルキーマップとして使用される。デフォルトではこのキーマップは以下のバインディングを作成する:
minibuffer-completion-help
minibuffer-complete-word
minibuffer-complete
親キーマップとしてminibuffer-local-map
を使用する(Definition of
minibuffer-local-mapを参照)。
completing-read
は、1つの補完の完全な一致が要求されないときのローカルキーマップとしてこの値を使用する。したがってexit-minibuffer
にキーがバインドされていなければ、無条件にミニバッファーをexitする。デフォルトでは、このキーマップは以下のバインディングを作成する:
minibuffer-complete-and-exit
minibuffer-complete-and-exit
親キーマップはminibuffer-local-completion-map
を使用する。
これは単にSPCを非バインドするsparseキーマップ(sparse:
疎、希薄、まばら)を作成する。これはファイル名にスペースを含めることができるからである。関数read-file-name
は、このキーマップとminibuffer-local-completion-map
かminibuffer-local-must-match-map
のいずれかを組み合わせる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは特定の種類の名前を補完つきで読み取る便利な高レベル関数を説明します。
ほとんどの場合は、Lisp関数の中盤でこれらの関数を呼び出すべきではありません。可能なときはinteractive
指定の内部で呼び出して、ミニバッファーのすべての入力をコマンドの引数読み取りの一部にします。コマンドの定義を参照してください。
この関数はバッファーの名前を読み取ってそれを文字列でリターンする。プロンプトはprompt。引数defaultはミニバッファーが空の状態でユーザーがexitした場合にリターンされるデフォルト名として使用される。非nil
なら文字列、文字列リスト、またはバッファーを指定する。リストならリストの先頭の要素がデフォルト値になる。デフォルト値はプロンプトに示されるが、初期入力としてミニバッファーには挿入されない。
引数promptはコロンかスペースで終わる文字列である。defaultが非nil
なら、この関数はデフォルト値つきでミニバッファーから読み取る際の慣習にしたがってコロンの前のpromptの中にこれを挿入する。
オプション引数require-matchはcompleting-read
のときと同じ。補完とミニバッファーを参照のこと。
オプション引数predicateが非nil
なら、それは考慮すべきバッファーをフィルターする関数を指定する。この関数は可能性のある候補を引数として呼び出されて、候補を拒絶するならnil
、許容するなら非nil
をリターンすること。
以下の例ではユーザーが‘minibuffer.t’とエンターしてから、RETをタイプしている。引数require-matchはt
であり、与えられた入力で始まるバッファー名は‘minibuffer.texi’だけなので、その名前が値となる。
(read-buffer "Buffer name: " "foo" t)
;; 前の式を評価した後、 ;; 空のミニバッファーに ;; 以下のプロンプトが表示される:
---------- Buffer: Minibuffer ---------- Buffer name (default foo): ∗ ---------- Buffer: Minibuffer ----------
;; ユーザーがminibuffer.t RETとタイプする
⇒ "minibuffer.texi"
この変数が非nil
なら、それはバッファー名を読み取る関数を指定する。read-buffer
は通常行うことを行うかわりに、read-buffer
と同じ引数でその関数を呼び出す。
この変数が非non-nil
なら、バッファー名の読み取りの補完処理においてread-buffer
はcaseを無視する。
この関数はコマンドの名前を読み取って、Lispシンボルとしてそれをリターンする。引数promptはread-from-minibuffer
で使用される場合と同じ。それが何であれcommandp
がt
をリターンすればコマンドであり、コマンド名とはcommandp
がt
をリターンするシンボルだということを思い出してほしい。interactiveな呼び出しを参照のこと。
引数defaultはユーザーがnull入力をエンターした場合に何をリターンするか指定する。シンボル、文字列、文字列リストを指定できる。文字列ならread-command
はリターンする前にそれをinternする。リストならread-command
はリストの最初の要素をinternする。defaultがnil
ならデフォルトが指定されなかったことを意味する。その場合もしユーザーがnull入力をエンターすると、リターン値は(intern
"")
、つまり名前が空文字列のシンボルとなる。
(read-command "Command name? ")
;; 前の式を評価した後に、 ;; 空のミニバッファーに以下のプロンプトが表示される:
---------- Buffer: Minibuffer ---------- Command name? ---------- Buffer: Minibuffer ----------
ユーザーがforward-c RETとタイプすると、この関数はforward-char
をリターンする。
read-command
関数はcompleting-read
の簡略化されたインターフェイスである。実在するLisp変数のセットを補完するために変数obarray
、コマンド名だけを受け入れるために述語commandp
を使用する。
(read-command prompt) ≡ (intern (completing-read prompt obarray 'commandp t nil))
この変数はカスタマイズ可能な変数の名前を読み取って、それをシンボルとしてリターンする。引数の形式はread-command
の引数と同じ。この関数はcommandp
のかわりにcustom-variable-p
を述語に使用する点を除いてread-command
と同様に振る舞う。
この関数はカラー指定(カラー名、または#RRRGGGBBB
のような形式のRGB16進値)の文字列を読み取る。これはプロンプトにprompt(デフォルトは"Color
(name or #RGB
triplet):"
)を表示して、カラー名にたいする補完を提供する(16進RGB値は補完しない)。標準的なカラー名に加えて、補完候補にはポイント位置のフォアグラウンドカラーとバックグラウンドカラーが含まれる。
Valid RGB values are described in カラー名.
この関数のリターン値はミニバッファー内でユーザーがタイプした文字列である。しかしインタラクティブに呼び出されたとき、またはオプション引数convertが非nil
なら、入力されたカラー名のかわりにそれに対応するRGB値文字列をリターンする。この関数は入力として有効なカラー指定を求める。allow-emptyが非nil
でユーザーがnull入力をエンターした場合は空のカラー名が許容される。
インタラクティブに呼び出されたとき、またはdisplayが非nil
なら、エコーエリアにもリターン値が表示される。
ユーザー選択のコーディングシステムの関数read-coding-system
とread-non-nil-coding-system
、および入力メソッドのread-input-method-name
も参照されたい。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
高レベル補完関数read-file-name
、read-directory-name
、read-shell-command
はそれぞれファイル名、ディレクトリー名、シェルコマンドを読み取るようにデザインされています。これらはデフォルトディレクトリーの自動挿入を含む特別な機能を提供します。
この関数はプロンプトpromptとともに補完つきでファイル名を読み取る。
例外として以下のすべてが真ならば、この関数はミニバッファーのかわりにグラフィカルなファイルダイアログを使用してファイル名を読み取る:
use-dialog-box
が非nil
の場合。Dialog Boxes in The GNU Emacs Manualを参照のこと。
グラフィカルなファイルダイアログを使用したときの正確な振る舞いはプラットホームに依存する。ここでは単にミニバッファーを使用したときの振る舞いを示す。
read-file-name
はリターンするファイル名を自動的に展開しない。絶対ファイル名が必要なら、自分でexpand-file-name
を呼び出さなければならない。
オプション引数require-matchはcompleting-read
のときと同じ。補完とミニバッファーを参照のこと。
引数directoryは、相対ファイル名の補完に使用するディレクトリーを指定する。値は絶対ディレクトリー名。変数insert-default-directory
が非nil
なら、初期入力としてミニバッファーにdirectoryも挿入される。デフォルトはカレントバッファーのdefault-directory
の値。
initialを指定すると、それはミニバッファーに挿入する初期ファイル名になる(directoryが挿入された場合はその後に挿入される)。この場合、ポイントはinitialの先頭に配置される。initialのデフォルト値はnil
(ファイル名を挿入しない)。initialが何を行うか確認するには、ファイルをvisitしているバッファーでC-x
C-vを試すとよい。注意: ほとんどの場合はinitialよりもdefaultの使用を推奨する。
defaultが非nil
なら、最初にread-file-name
が挿入したものと等しい空以外のコンテンツを残してユーザーがミニバッファーをexitすると、この関数はdefaultをリターンする。insert-default-directory
が非nil
ならそれがデフォルトとなるので、ミニバッファーの初期コンテンツは常に空以外になる。require-matchの値に関わらずdefaultの有効性はチェックされない。とはいえrequire-matchが非nil
なら、ミニバッファーの初期コンテンツは有効なファイル名(またはディレクトリー名)であるべきだろう。それが有効でなければ、ユーザーがそれを編集せずにexitするとread-file-name
は補完を試みて、defaultはリターンされない。defaultはヒストリーコマンドからも利用できる。
defaultがnil
なら、read-file-name
はその場所に代用するデフォルトを探そうと試みる。この代用デフォルトは明示的にdefaultにそれが指定されたかのように、defaultとまったく同じ方法で扱われる。defaultがnil
でもinitialが非nil
なら、デフォルトはdirectoryとinitialから得られる絶対ファイル名になる。defaultとinitialの両方がnil
で、そのバッファーがファイルをvisitしているバッファーなら、read-file-name
はそのファイルの絶対ファイル名をデフォルトとして使用する。バッファーがファイルをvisitしていなければデフォルトは存在しない。この場合はユーザーが編集せずにRETをタイプすると、read-file-name
は前にミニバッファーに挿入されたコンテンツを単にリターンする。
空のミニバッファー内でユーザーがRETをタイプすると、この関数はrequire-matchの値に関わらず空文字列をリターンする。たとえばユーザーがM-x set-visited-file-nameを使用して、カレントバッファーをファイルをvisitしていないことにするために、この方法を使用している。
predicateが非nil
なら、それは補完候補として許容できるファイル名を決定する1引数の関数である。predicateが関数名にたいして非nil
をリターンすれば、それはファイル名として許容できる値である。
以下はread-file-name
を使用した例:
(read-file-name "The file is ") ;; 前の式を評価した後に、 ;; ミニバッファーに以下が表示される:
---------- Buffer: Minibuffer ---------- The file is /gp/gnu/elisp/∗ ---------- Buffer: Minibuffer ----------
manual TABをタイプすると以下がリターンされる:
---------- Buffer: Minibuffer ---------- The file is /gp/gnu/elisp/manual.texi∗ ---------- Buffer: Minibuffer ----------
ここでユーザーがRETをタイプすると、read-file-name
は文字列"/gp/gnu/elisp/manual.texi"
をファイル名としてリターンする。
非nil
なら、read-file-name
と同じ引数を受け取る関数である。read-file-name
が呼び出されたとき、read-file-name
は通常の処理を行なうかわりに与えられた引数でこの関数を呼び出す。
この変数が非nil
なら、read-file-name
は補完を行なう際にcaseを無視する。
この関数はread-file-name
と似ているが補完候補としてディレクトリーだけを許す。
defaultがnil
でinitialが非nil
なら、read-directory-name
はdirectory
(directoryがnil
ならカレントバッファーのデフォルトディレクトリー)とinitialを組み合わせて代用のデフォルトを構築する。この関数はdefaultとinitialの両方がnil
ならdirectory、directoryもnil
ならカレントバッファーのデフォルトディレクトリーを代用のデフォルトとして使用する。
この変数はread-file-name
により使用されるため、ファイル名を読み取るほとんどのコマンドにより間接的に使用される(これらのコマンドにはコマンドのインタラクティブフォームに‘f’や‘F’のコードレター(code
letter))をふくむすべてのコマンドが含まれる。Code Characters for
interactiveを参照されたい)。この変数の値は、(もしあれば)デフォルトディレクトリー名をミニバッファー内に配置してread-file-name
を開始するかどうかを制御する。変数の値がnil
なら、read-file-name
はミニバッファーに初期入力を何も配置しない(ただしinitial引数で初期入力を指定しない場合)。この場合には依然としてデフォルトディレクトリーが相対ファイル名の補完に使用されるが表示はされない。
この変数がnil
でミニバッファーの初期コンテンツが空なら、ユーザーはデフォルト値にアクセスするために次のヒストリー要素を明示的にフェッチする必要があるだろう。この変数が非nil
ならミニバッファーの初期コンテンツは常に空以外となり、ミニバッファーで編集をおこなわず即座にRETをタイプすることによって、常にデフォルト値を要求できる(上記参照)。
たとえば:
;; デフォルトディレクトリーとともにミニバッファーが開始
(let ((insert-default-directory t))
(read-file-name "The file is "))
---------- Buffer: Minibuffer ---------- The file is ~lewis/manual/∗ ---------- Buffer: Minibuffer ----------
;; ミニバッファーはプロンプトだけで空 ;; appears on its line. (let ((insert-default-directory nil)) (read-file-name "The file is "))
---------- Buffer: Minibuffer ---------- The file is ∗ ---------- Buffer: Minibuffer ----------
この関数はプロンプトpromptとインテリジェントな補完を提供して、ミニバッファーからシェルコマンドを読み取る。これはコマンド名にたいして適切な候補を使用してコマンドの最初の単語を補完する。コマンドの残りの単語はファイル名として補完する。
この関数はミニバッファー入力にたいするキーマップとしてminibuffer-local-shell-command-map
を使用する。history引数は使用するヒストリーリストを指定する。省略またはnil
の場合のデフォルトはshell-command-history
(shell-command-historyを参照)。オプション引数initialはミニバッファーの初期コンテンツを指定する(入力の初期値を参照)。もしあれば残りのargsはread-from-minibuffer
内のdefaultとinherit-input-methodとして使用される(ミニバッファーでのテキスト文字列の読み取りを参照)。
このキーマップはread-shell-command
により、コマンドとシェルコマンドの一部となるファイル名の補完のために使用される。これは親キーマップとしてminibuffer-local-map
を使用して、TABをcompletion-at-point
にバインドする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
補完のデフォルト動作を変更するために使用される変数がいくつかあります。
この変数の値は補完を行うために使用される補完スタイル(シンボル)である。補完スタイル(completion
style)とは、補完を生成するためのルールセットのこと。このリストにあるシンボルはそれぞれ、completion-styles-alist
内に対応するエントリーをもたなければならない。
この変数には補完スタイルのリストが格納される。リスト内の各要素は以下の形式をもつ
(style try-completion all-completions doc)
ここでstyleは補完スタイルの名前(シンボル)であり、そのスタイルを参照するために変数completion-styles
内で使用されるかもしれない。try-completionは補完を行なう関数で、all-completions補完をリストする関数、docは補完スタイルを説明する文字列である。
関数try-completionとall-completionsはstring、collection、predicate、pointの4つの引数をとる。引数string、collection、predicateの意味はtry-completion
(基本的な補完関数を参照)のときと同様。引数pointはstring内のポイント位置。各関数は自身の処理を行ったら非nil
、行わなかった場合(たとえば補完スタイルに一致するようにstringを行う方法がない場合)はnil
をリターンする。
ユーザーがminibuffer-complete
(補完を行うミニバッファーコマンドを参照)のような補完コマンドを呼び出すと、Emacsはcompletion-styles
に最初にリストされたスタイルを探して、そのスタイルのtry-completion関数を呼び出す。この関数がnil
をリターンしたら、Emacsは次にリストされた補完スタイルに移動してそのスタイルのtry-completion関数を呼び出すといったように、try-completion関数の1つが補完の処理に成功して非nil
値をリターンするまで順次これを行なう。同様の手順はall-completions関数を通じて補完のリストにも行われる。
利用できる補完スタイルについてはCompletion Styles in The GNU Emacs Manualを参照のこと。
この変数は特別な補完スタイルと、特定の種類のテキスト補完時に使用するその他の補完動作を指定する。この変数の値は(category
.
alist)
という形式の要素をもつようなalistである。categoryは何が補完されるかを記述するシンボルで、現在のところカテゴリーにbuffer
、file
、unicode-name
が定義されているが、これに特化した補完関数(プログラムされた補完を参照)を通じて他のカテゴリーを定義できる。alistはそのカテゴリーにたいして補完がどのように振る舞うべきかを記述する連想リスト。alistのキーとして以下がサポートされる:
styles
値は補完スタイル(シンボル)のリスト。
cycle
値はそのカテゴリーにたいするcompletion-cycle-threshold
(Completion Options in The GNU Emacs Manualを参照)の値。
将来、さらにalistエントリーが定義されるかもしれない。
この変数はカレント補完コマンドの特別なプロパティの指定に使用される。この変数は補完に特化したコマンドによりletバインドされることを意図している。値はプロパティ/値ペアーのリスト。以下のプロパティがサポートされる:
:annotation-function
値は補完バッファー内に注釈(annotation)を加える関数。この関数は引数completionを1つ受け取りnil
、または補完の隣に表示する文字列をリターンしなければならない。
:exit-function
値は補完を行った後に実行する関数。この関数は2つの引数stringとstatusを受け取る。stringは補完されたフィールドのテキストで、statusは行われた操作の種類を示す。操作の種類はテキストの補完が完了したならfinished
、それ以上補完できないが補完が完了していなければsole
、有効な補完だがさらに補完できるときはexact
となる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
意図した利用可能な補完のすべてを含むalistかobarrayを事前に作成するのが不可能または不便なことがあります。このような場合は与えられた文字列にたいする補完を計算するために独自の関数を提供できます。これはプログラム補完(programmed completion)と呼ばれます。Emacsは数あるケースの中でも特にファイル名の補完(ファイル名の補完を参照)でプログラム補完を使用しています。
この機能を使用するためには、関数をcompleting-read
のcollection引数として渡します。関数completing-read
はその補完関数がtry-completion
、all-completions
などの基本的な補完関数に渡されて、その関数がすべてを行えるよう取り計らいます。
補完関数は3つの引数を受け取ります:
nil
。関数は利用可能なマッチにたいしてこの述語(predicate)を呼び出して、述語がnil
をリターンしたらそのマッチを無視する。
nil
try-completion
を指定する。関数は指定された文字が一意かつ完全一致ならt
をリターンする。マッチが複数なら、すべてのマッチに共通する部分文字列をリターンする(文字列が補完候補の1つに完全一致するが、より長い他の候補にもマッチするならリターン値はその文字列)。マッチがなければnil
をリターンする。
t
all-completions
を指定する。関数は指定された文字列の利用可能なすべての補完のリストをリターンする。
lambda
test-completion
を指定する。関数は指定された文字列がいくつかの補完候補に完全一致するならt
、それ以外はnil
をリターンする。
(boundaries . suffix)
completion-boundaries
を指定する。関数は(boundaries start
.
end)
をリターンする。ここでstartは指定された文字列内の境界の開始位置、endはsuffix内の境界の終了位置。
metadata
カレント補完の状態に関する情報の要求を指定する。リターン値は(metadata
. alist)
の形式をもち、alistは以下で説明する要素をもつ連想配列。
フラグに他の値が指定されたら、補完関数はnil
をリターンする。
以下はmetadata
フラグ引数への応答として補完関数がリターンするかもしれないmetadataエントリーのリストです:
category
値は補完関数が補完を試みているテキストの種類を説明するシンボル。シンボルがcompletion-category-overrides
内のキーの1つにマッチする場合、通常の補完動作はオーバーライドされる。補完変数を参照のこと。
annotation-function
値は補完に注釈(annotation)を付ける関数。この関数は1つの引数stringを受け取り、これは利用可能な補完である。リターン値は文字列で、*Completions*バッファー内の補完stringの後に表示される。
display-sort-function
値は補完をソートする関数。関数は1つの引数をとる。これは補完文字列のリストで、ソートされた補完文字列リストがリターンされる。その入力のリストは破壊的に変更することが許容される。
cycle-sort-function
値はcompletion-cycle-threshold
が非nil
、かつユーザーが補完候補を巡回するときに補完をソートする関数。引数のリストとリターン値はdisplay-sort-function
と同様。
This function is a convenient way to write a function that can act as a
programmed completion function. The argument function should be a
function that takes one argument, a string, and returns an alist of possible
completions of it. It is allowed to ignore the argument and return a full
list of all possible completions. You can think of
completion-table-dynamic
as a transducer between that interface and
the interface for programmed completion functions.
オプション引数switch-bufferが非nil
、かつ補完がミニバッファーで行われた場合、functionはそのミニバッファーにエンターしたときのバッファーをカレントバッファーにセットして呼び出される。
これは前回の引数/結果ペアーを保存するcompletion-table-dynamic
にたいするラッパーである。これは同じ引数にたいする複数回の検査に必要なのが、1回のfunction呼び出しだけであることを意味する。これは外部プロセス呼び出しなど、処理が低速のとき有用かもしれない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
補完は通常はミニバッファー内で行われますが、補完機能は通常のEmacsバッファー内のテキストにも使用できます。多くのメジャーモードで、コマンドC-M-iまたはM-TABによってバッファー内補完が行われ、それらはcompletion-at-point
にバインドされています。Symbol
Completion in The GNU Emacs
Manualを参照してください。このコマンドはアブノーマルフック変数completion-at-point-functions
を使用します:
このアブノーマルフックの値は関数のリストである。これらの関数はポイント位置のテキストの補完にたいする補完テーブルの計算に使用される。これはメジャーモードによるモード特有な補完テーブル(メジャーモードの慣習を参照)の提供に使用できる。
コマンドcompletion-at-point
が実行されると、引数なしでリスト内の関数が1つずつ呼び出される。それぞれの関数はポイント位置のテキストにたいして補完テーブルを生成できないならnil
をリターンする。生成できたら以下の形式のリストをリターンする
(start end collection . props)
ここでstartとendは補完する(ポイントを取り囲む)テキストの区切りである。collectionはそのテキストを補完する補完テーブルであり、try-completion
(基本的な補完関数を参照)の2つ目の引数として渡すのに適した形式である。補完候補はcompletion-styles
(補完変数を参照)で定義された補完スタイルを通じて、この補完テーブルを通常の方法で使用して生成されるだろう。propsは追加の情報のためのプロパティリストである。completion-extra-properties
内のすべてのプロパティ(補完変数を参照)と、以下の追加のプロパティが認識される:
:predicate
値は補完候補が満足する必要がある述語。
:exclusive
値がno
の場合は、もし補完テーブルがポイント位置のテキストのマッチに失敗したなら、補完の失敗を報告するかわりにcompletion-at-point
はcompletion-at-point-functions
内の次の関数へ移動する。
補完リスト生成が処理が高価なら、collectionにたいして関数の提供を推奨する。Emacsは内部的にcompletion-at-point-functions
内の関数を多数回呼び出すかもしれないが、それらの呼び出しのいくつかにたいしてのみcollectionの値を考慮する。collectionにたいして関数を提供することにより、Emacsは必要になるまで補完の生成を遅延できる。ラッパー関数を作成するためにcompletion-table-dynamicを使用できる:
;; このパターンは避けて (let ((beg ...) (end ...) (my-completions (my-make-completions))) (list beg end my-completions)) ;; かわりに以下を使用する (let ((beg ...) (end ...)) (list beg end (completion-table-dynamic (lambda (_) (my-make-completions)))))
completion-at-point-functions
内の関数も、上述したリストのかわりに関数をリターンするかもしれない。その場合は引数なしでリターンされた関数が呼び出されてその関数が補完処理の全責任を負う。この方法は推奨されない。これはcompletion-at-point
を使用する古いコードの救済を意図したものだからである。
非nil
値を最初にリターンしたcompletion-at-point-functions
内の関数が、completion-at-point
によって使用される。残りの関数は呼び出されない。例外は上述の:exclusive
指定があるとき。
以下の関数はEmacsバッファー内の任意に拡張されたテキストにたいして便利な補完方法を提供します:
この関数はcollectionを使用してカレントバッファー内の位置startとendの間のテキストを補完する。引数collectionはtry-completion
(基本的な補完関数を参照)のときと同じ意味をもつ。
この関数は補完テキストを直接カレントバッファーに挿入する。completing-read
(補完とミニバッファーを参照)とは異なり、ミニバッファーをアクティブにしない。
この関数が機能するためには、ポイントがstartとendの間になければならない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではユーザーにyes-or-noの確認を求める関数を説明します。関数y-or-n-p
は1文字での応答に使用できます。この関数は不注意による誤った答えが深刻な結果を招かない場合に有用です。yes-or-no-p
は3文字から4文字の答えを要求するので、より重大な問いに適しています。
3つの関数はいずれもマウスを使用して呼び出されたコマンドの場合、より正確にはlast-nonmenu-event
(コマンドループからの情報を参照)がnil
かリストの場合は、問いに答えるためにダイアログボックスまたはポップアップメニューを使用します。それ以外の場合はキーボード入力を使用します。呼び出しの周囲でlast-nonmenu-event
に適切な値をバインドすることにより、マウスあるいはキーボードの使用を強制できます。
厳密に言うとyes-or-no-p
はミニバッファーを使用して、y-or-n-p
は使用しませんが、これらのコマンドは一緒に説明したほうがよいでしょう。
この関数はユーザーに答えを尋ねてミニバッファーに入力を求める。ユーザーがyをタイプしたらt
、nをタイプしたらnil
をリターンする。この関数はyesの意味でSPC、noの意味でDELも受け入れる。quitとしてC-gと同様にC-]も受け入れる。これは問いがミニバッファーのような外見をもち、ミニバッファーを抜けるためにユーザーがC-]の使用を試みるかもしれないという理由による。応答は1文字であり、問いを終了させるためのRETは必要ない。大文字と小文字は等価である。
“答えを尋ねる”とはエコーエリアにprompt、その後に文字列‘(y or n) ’をプリントすることを意味する。期待される答え(y、n、SPC、DEL、もしくは質問を終了するその他のキー)以外が入力されると、この関数は‘Please answer y or n.’と応答して繰り返し答えの入力を要求する。
この関数は答えの編集を許さないので、実際にはミニバッファーを使用しない。実際に使用するのはミニバッファーと同じスクリーンスペースを使用するエコーエリア(エコーエリアを参照)である。問いが答えられるまでカーソルはエコーエリアに移動される。
答えとその意味は、たとえ‘y’と‘n’であっても固定されたものではなく、キーマップquery-replace-map
によって指定される(検索と置換を参照)。特にユーザーがrecenter
、scroll-up
、scroll-down
、scroll-other-window
、scroll-other-window-down
(それぞれquery-replace-map
内でC-l、C-v、M-v、C-M-v、C-M-S-vにバインドされている)のような特殊な応答をエンターした場合、この関数はは指定されたウィンドウの再センタリングやスクロール操作を処理してから再度答えを求める。
エコーエリアのメッセージを連続する行で示しているが、スクリーン上に実際に表示されるのは一度に1行だけである。
y-or-n-p
と同様だがユーザーがseconds秒以内に答えないと、この関数は待つのをやめてdefaultをリターンする。これはタイマーをセットアップすることによって機能する。引数secondsは数字である。
この関数は質問してミニバッファーに答えの入力を求める。これはユーザーが‘yes’をエンターするとt
、‘no’をエンターするとnil
をリターンする。ユーザーは応答を終えるためにRETをタイプしなければならない。大文字と小文字は等価。
yes-or-no-p
はエコーエリアにpromptとその後に‘(yes or no) ’を表示することによって開始される。ユーザーは期待される応答の1つをタイプしなければならない。それ以外の答えなら、この関数は‘Please
answer yes or no.’と応答して約2秒待った後に要求を繰り返す。
yes-or-no-p
はy-or-n-p
より多くの作業をユーザーに要求するので、より重大な決定に適している。
以下は例:
(yes-or-no-p "Do you really want to remove everything? ") ;; 前の式を評価した後、 ;; 空のミニバッファーに ;; 以下のプロンプトが表示される:
---------- Buffer: minibuffer ---------- Do you really want to remove everything? (yes or no) ---------- Buffer: minibuffer ----------
ユーザーが最初にy RETとタイプしたら無効になる。なぜならこの関数は‘yes’という単語全体を要求しているので、一時停止して以下のプロンプトを説明のために表示する。
---------- Buffer: minibuffer ---------- Please answer yes or no. Do you really want to remove everything? (yes or no) ---------- Buffer: minibuffer ----------
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
同じような連続する質問と答えがある場合、たとえば各バッファーにたいして順に“Do you want to save this
buffer?”と確認を求めるような場合には、個別に質問するよりmap-y-or-n-p
を使用して質問のコレクションを尋ねるべきです。これはユーザーにたいして、質問全体にたいして1回で答えられるような便利な機能を提供します。
この関数はユーザーに一連の質問をし、それぞれの質問にたいしてエコーエリア内の1文字の答えを読み取る。
値listは質問をするオブジェクトを指定する。これはリスト、オブジェクト、または生成関数(generator
function)のいずれかである。関数の場合は引数なしで次に質問するオブジェクト、または質問の中止を意味するnil
のいずれかをリターンする。
引数prompterは各質問について問い合わせ方法を指定する。prompterが文字列なら質問テキストは以下のようになる:
(format prompter object)
ここでobjectは、(listから得られる)質問する次のオブジェクトである。
文字列でないければ、prompterは1つの引数(質問する次のオブジェクト)をとる関数で、質問テキストをリターンする。値が文字列ならユーザーに問う質問であること。関数はt
(ユーザーに尋ねずこのオブジェクトを処理する)、またはnil
(ユーザーに尋ねずこのオブジェクトを無視する)をリターンすることもできる。
引数actorはユーザーが与えた答えにたいして、どのように処理するかを指定する。これは引数が1つの関数で、ユーザーがyesと答えたオブジェクトを引数として呼び出される。引数は常にlistから取得したオブジェクトである。
引数helpが与えられたら、それは以下の形式のリストである:
(singular plural action)
singularはそのオブジェクトが概念的に何に作用するかを説明する単数形の名詞を含む文字列、pluralはそれに対応する複数形の名詞、actionはactorが何を行うかを説明する他動詞である。
helpを指定しない場合のデフォルトは("object" "objects" "act on")
。
質問のたびに、ユーザーはそのオブジェクトを処理するならy、YまたはSPC、そのオブジェクトをスキップするならn、N、またはDEL、以降のすべてのオブジェクトを処理するなら!、exit(以降のすべてのオブジェクトをスキップ)するならESCかq、カレントオブジェクトを処理した後にexitするなら.(ピリオド)、ヘルプを入手する場合はC-hをエンターする。これらはquery-replace
が受け入れるのと同じ答えである。キーマップquery-replace-map
はmap-y-or-n-p
にたいするそれらの意味を定義して、query-replace
にたいしても同様に定義する。検索と置換を参照のこと。
action-alistを使用して、利用できる追加の答えとそれらが何を意味するかを指定できる。これは要素が(char
function
help)
という形式のalistで、それぞれの要素が追加の答えを1つ定義する。要素の内容はcharが文字(答え)、functionが引数が1つ(listから取得するオブジェクト)の関数、helpが文字列である。
ユーザーの応答がcharなら、map-y-or-n-p
はfunctionを呼び出す。これが非nil
をリターンしたらそのオブジェクトが処理されたと判断して、map-y-or-n-p
はlist内の次のオブジェクトに進む。nil
をリターンしたら同じオブジェクトにたいして質問を繰り返す。
確認を求める間、map-y-or-n-p
は通常はcursor-in-echo-area
をバインドする。しかしno-cursor-in-echo-areaが非nil
ならバインドしない。
マウスを使用して呼び出されたコマンドからmap-y-or-n-p
が呼び出された場合(より正確にはlast-nonmenu-event
は非nil
かリストの場合。コマンドループからの情報を参照)には、確認を求めるためにダイアログボックスかポップアップメニューが使用される。この場合にはキーボード入力やエコーエリアは使用されない。呼び出しの前後でlast-nonmenu-event
を適切な値にバインドすることによって、マウスあるいはキーボードの入力を強制できる。
map-y-or-n-p
のリターン値は処理したオブジェクトの個数である。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
他のプログラムに渡すためのパスワードを読み取るために関数read-passwd
を使用できます。
この関数はプロンプトpromptを表示してパスワードを読み取る。これはユーザーがタイプしたパスワードのかわりに、パスワード内の各文字を‘.’に変更してエコーする。パスワードを隠すために別の文字を適用したければ、その文字をread-hide-char
にletバインドすること。
オプション引数confirmが非nil
なら、パスワードを2回読み取ることでそれらが同じものであることを強制する。同じでなければ、2回の入力が同じになるまで、ユーザーはパスワードを繰り返しタイプする必要がある。
オプション引数defaultは、ユーザーが空入力をエンターした場合のデフォルトパスワードである。defaultがnil
なら、read-passwd
はnull文字列をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではミニバッファー内で使用するコマンドを説明します。
このコマンドはアクティブなミニバッファーをexitする。これは通常はミニバッファー内のローカルキーマップのキーにバインドされる。
このコマンドはキーボードでタイプされた最後の文字を挿入した後にアクティブなミニバッファーをexitする。コマンドループからの情報)を参照のこと。
このコマンドはn個前(古い)のヒストリー要素の値でミニバッファー内のコンテンツを置換する。
このコマンドはn個先(新しい)のヒストリー要素の値でミニバッファー内のコンテンツを置換する。
このコマンドはpattern(正規表現)にマッチするn個前(古い)のヒストリー要素でミニバッファー内のコンテンツを置換する。
このコマンドはpattern(正規表現)にマッチするn個先(新しい)のヒストリー要素でミニバッファー内のコンテンツを置換する。
このコマンドはミニバッファー内のポイントの前のカレントコンテンツを、n個前(古い)ヒストリー要素の値で置換する。
このコマンドはミニバッファー内のポイントの前のカレントコンテンツを、n個先(新しい)ヒストリー要素の値で置換する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はミニバッファーウィンドウにアクセスと選択を行い、それがアクティブかどうかテストしてリサイズされる方法を制御します。
この関数はカレントでアクティブなミニバッファーウィンドウ、アクティブなウィンドウがなければnil
をリターンする。
この関数はフレームframeにたいして使用されるミニバッファーウィンドウをリターンする。frameがnil
ならカレントフレームを意味する。フレームに使用されるミニバッファーウィンドウは、そのフレームの一部である必要はないことに注意。自身のミニバッファーをもたないフレームは、必然的に他のフレームのミニバッファーウィンドウを使用する。
この関数はミニバッファーウィンドウとしてwindowを使用するよう指定する。これは通常のミニバッファーコマンドを呼び出さずにミニバッファーにテキストを入力する場合には、そのミニバッファーがどこに表示されるかに影響を及ぼす。通常のミニバッファー入力関数はすべてカレントフレームに対応するミニバッファーを選択して開始されるので影響はない。
この関数はwindowがミニバッファーウィンドウならnil
をリターンする。windowのデフォルトは選択されたウィンドウ。
(minibuffer-window)
の結果を比較して与えられたウィンドウがミニバッファーかどうか判断するのは正しくない。なぜなら複数のフレームがある場合には、ミニバッファーウィンドウも複数あり得るからである。
この関数はwindowがカレントでアクティブなミニバッファーウィンドウなら非nil
をリターンする。
以下の2つのオプションはミニバッファーウィンドウが自動的にリサイズされるか否か、およびその処理でミニバッファーが大きくなり得るサイズを制御します。
このオプションはミニバッファーウィンドウが自動的にリサイズされるかどうかを指定する。デフォルト値はgrow-only
で、これはミニバッファーが表示するテキストを収容するために、ミニバッファーウィンドウがデフォルトにより自動的に拡張されて、ミニバッファーが空になれば即座に1行に縮小されることを意味する。値がt
ならEmacsは常にミニバッファーが表示するテキストにミニバッファーウィンドウの高さをフィットさせるように試みる。値がnil
ならミニバッファーウィンドウのサイズが自動的に変更されることは決してない。この場合には、ミニバッファーウィンドウの高さの調節のために、ウィンドウリサイズコマンドを使用できる(ウィンドウのリサイズを参照)。
このオプションはミニバッファーウィンドウの自動的なリサイズにたいする最大高さを提供する。浮動小数点数はフレーム高さにたいする割合、整数は最大行数を指定する。デフォルト値は0.25。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はミニバッファーのプロンプトとコンテンツにアクセスします。
この関数はカレントでアクティブなミニバッファーのプロンプト文字列をリターンする。アクティブなミニバッファーがなければnil
をリターンする。
この関数はミニバッファーがカレントならミニバッファープロンプトの終端のカレント位置をリターンする。それ以外はバッファーの有効な最小位置をリターンする。
この関数はミニバッファーがカレントならミニバッファープロンプトのカレントの表示幅をリターンする。それ以外は0をリターンする。
この関数はミニバッファーがカレントなら、ミニバッファーの編集可能なコンテンツ(つまりプロンプト以外のすべて)を文字列でリターンする。それ以外はカレントバッファーのコンテンツ全体をリターンする。
これはminibuffer-contents
と同様だが、テキストプロパティをコピーせずに文字自身だけをリターンする。テキストのプロパティを参照のこと。
このコマンドはミニバッファーがカレントなら、ミニバッファーの編集可能なコンテンツ(つまりプロンプト以外のすべて)を削除する。それ以外はカレントバッファー全体を削除する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数と変数は再帰ミニバッファーを処理します(再帰編集を参照):
この関数はアクティブなミニバッファーのカレント再帰深さを正の整数でリターンする。アクティブなミニバッファーが存在しなければ0をリターンする。
この変数が非nil
ならミニバッファーウィンドウがアクティブでも、(find-file
のような)ミニバッファーを使用するコマンドを呼び出すことができる。このような呼び出しは新たなミニバッファーにたいして再帰編集レベル(recursive
editing level)を生成する。内側レベルの編集の間、外側レベルのミニバッファーは非表示になる。
この変数がnil
なら、ミニバッファーウィンドウがアクティブなときにたとえ他のウィンドウに切り替えても、ミニバッファーコマンドの呼び出しはできない。
コマンド名が非nil
のプロパティenable-recursive-minibuffers
をもつ場合には、たとえミニバッファーから呼び出された場合でも、そのコマンドは引数の読み取りにミニバッファーを使用できる。コマンドのinteractive宣言内でenable-recursive-minibuffers
をt
にしても、これを行うことができる(interactive
の使用を参照)。ミニバッファーコマンドnext-matching-history-element
(ミニバッファー内では通常M-s)は後者を行う。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はbuffer-or-nameがミニバッファーなら非nil
をリターンする。buffer-or-nameが省略されるとカレントバッファーをテストする。
これはミニバッファーがエンターされたときは常に実行されるノーマルフックである。フックを参照のこと。
これはミニバッファーがexitされたときは常に実行されるノーマルフックである。
この変数のカレント値はミニバッファー内でhelp-form
をローカルにリバインドするために使用される(ヘルプ関数を参照)。
この変数の値が非nil
なら、それはウィンドウオブジェクトである。ミニバッファー内で関数scroll-other-window
が呼び出されたときは、このウィンドウをスクロールする。
この関数はミニバッファーがエンターされたときに選択されていたウィンドウをリターンする。選択されたウィンドウがミニバッファー以外のときはnil
をリターンする。
この変数はミニバッファーウィンドウのリサイズにたいする最大高さを指定する。浮動小数点数ならフレーム高さにたいする割り合いを指定する。整数の場合は行数を指定する。
この関数は数秒、あるいは次の入力イベントが到着するまでミニバッファーテキストの最後に一時的にstringを表示する。変数minibuffer-message-timeout
は入力がない場合に待機する秒数を指定する(デフォルトは2)。argsが非nil
なら、実際のメッセージはformat-message
にstringとargsを渡して作成される。See section 文字列のフォーマットを参照のこと。
これはインタラクティブなミニバッファー内で使用されるメジャーモードである。キーマップminibuffer-inactive-mode-map
を使用する。ミニバッファーが別のフレームにある場合には有用かもしれない。ミニバッファーとフレームを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsを実行すると、ほぼ即座にエディターコマンドループ(editor command loop)に移行します。このループはキーシーケンスを読み取り、それらの定義を実行して結果を表示します。このチャプターではこれらが行われる方法と、Lispプログラムがこれらを行えるようにするサブルーチンを説明します。
20.1 コマンドループの概要 | コマンドループがコマンドを読み取る方法。 | |
20.2 コマンドの定義 | 関数が引数を読み取る方法を指定する。 | |
20.3 interactiveな呼び出し | 引数を読み取るようにコマンドを呼び出す。 | |
20.4 interactiveな呼び出しの区別 | インタラクティブな呼び出しとコマンドを区別する。 | |
20.5 コマンドループからの情報 | 検証用にコマンドループによりセットされる変数。 | |
20.6 コマンド後のポイントの調整 | コマンドの後にポイント位置を調整する。 | |
20.7 入力イベント | 入力を読み取るとき、入力がどのように見えるか。 | |
20.8 入力の読み取り | キーボードやマウスからの入力イベントを読み取る方法。 | |
20.9 スペシャルイベント | 即座かつ個別に処理されるイベント。 | |
20.10 時間の経過や入力の待機 | ユーザー入力または経過時間の待機。 | |
20.11 quit | C-gが機能する方法。quitのcatchや延期する方法。 | |
20.12 プレフィクスコマンド引数 | コマンドがプレフィクス引数が機能するようにセットするための方法。 | |
20.13 再帰編集 | 再帰編集への移行と、なぜ通常は再帰編集を行うべきでないのか。 | |
20.14 コマンドの無効化 | コマンドループが無効なコマンドを扱う方法。 | |
20.15 コマンドのヒストリー | コマンドヒストリーがセットアップされる方法と、どのようにアクセスされるか。 | |
20.16 キーボードマクロ | キーボードマクロが実装される方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コマンドループが最初に行わなければならないのはキーシーケンスの読み取りです。キーシーケンスはコマンドに変換される入力イベントのシーケンスです。これは関数read-key-sequence
を呼び出すことによって行われます。Lispプログラムもこの関数を呼び出すことができます(キーシーケンス入力を参照)。これらはより低レベルのread-key
やread-event
(単一イベントの読み取り)で入力を読み取ったり、discard-input
(その他のイベント入力の機能を参照)で保留中の入力を無視することもできます。
キーシーケンスはカレントでアクティブなキーマップを通じてコマンドに変換されます。これが行われる方法についてはキーの照合を参照してください。結果はキーボードマクロかインタラクティブに呼び出し可能な関数になります。キーがM-xなら他のコマンドの名前を読み取って、それを呼び出します。これはコマンドexecute-extended-command
(interactiveな呼び出しを参照)により行われます。
コマンドの実行に先立ち、Emacsはアンドゥ境界(undo
boundary)を作成するためにundo-boundary
を実行します。アンドゥリストの保守を参照してください。
コマンドを実行するために、Emacsはまずcommand-execute
を呼び出してコマンドの引数を読み取ります(interactiveな呼び出しを参照)。Lispで記述されたコマンドについては、interactive
指定で引数を読み取る方法を指定します。これはプレフィクス引数(プレフィクスコマンド引数を参照)を使用したり、ミニバッファー内(ミニバッファーを参照)で確認を求めて読み取りを行うかもしれません。たとえばコマンドfind-file
にはinteractive
指定があり、これはミニバッファーを使用してファイル名を読み取ることを指定します。find-file
の関数bodyはミニバッファーを使用しないので、Lispコードから関数としてfind-file
を呼び出す場合には、通常のLisp関数引数としてファイル名を文字列で与えなければなりません。
コマンドがキーボードマクロ(文字列やベクター)なら、Emacsはexecute-kbd-macro
を使用してそれを実行します(キーボードマクロを参照)。
このノーマルフックはコマンドを実行する前に、エディターコマンドループにより実行される。その際、this-command
には実行しようとするコマンドが含まれ、last-command
には前のコマンドが記述される。コマンドループからの情報を参照のこと。
このノーマルフックはコマンドを実行した後(quitやエラーにより早期に終了させられたコマンドを含む)に、エディターコマンドループにより実行される。その際、this-command
は正に実行されたコマンド、last-command
は前に実行されたコマンドを参照する。
このフックはEmacsが最初にコマンドループにエンターしたときにも実行される(その時点ではthis-command
とlast-command
はいずれもnil
)。
pre-command-hook
とpost-command-hook
の実行中は、quitは抑制されます。これらのフックのいずれかを実行中にエラーが発生しても、そのエラーはフックの実行を終了させません。そのかわりにエラーは黙殺されて、エラーが発生した関数はそのフックから取り除かれます。
Emacsサーバー(Emacs Server in The GNU Emacs Manualを参照)に届くリクエストは、キーボードコマンドが行うのと同じように、これらの2つのフックを実行します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
スペシャルフォームinteractive
はLisp関数をコマンドに変更します。interactive
フォームは関数bodyのトップレベルに置かなければならず、通常はbody内の最初のフォームとして記述されます。これはラムダ式(ラムダ式を参照)とdefun
(関数の定義を参照)の両方を受け入れます。このフォームはその関数が実際に実行される間は何も行いません。このフォームの存在はフラグとしての役割りをもち、Emacsコマンドループにたいしてその関数がインタラクティブに呼び出せることを告げます。interactive
フォームの引数はインタラクティブな呼び出しが引数を読み取る方法を指定します。
interactive
フォームのかわりに、関数シンボルのinteractive-form
プロパティで指定されることもあります。このプロパティが非nil
値なら、関数body内のinteractive
フォームより優先されます。この機能はほとんど使用されません。
インタラクティブに呼び出されることだけを意図していて、決してLispから直接呼び出されない関数が時折あります。この場合には、直接あるいはdeclare
(declare
フォームを参照)を通じて、その関数のinteractive-only
プロパティに非nil
を与えます。これにより、そのコマンドがLispから呼び出されるとバイトコンパイラーが警告を発します。describe-function
の出力にはこれに類似する情報が含まれます。このプロパティの値には文字列、t
、または任意のシンボルを指定できます。文字列なら、それはバイトコンパイラーによる警告内で直接使用されます(最初は大文字でなくピリオドで終端される文字列であること。たとえば\"use
(system-name) instead.\"
)。シンボルなら、それはLispコード内で使用されるかわりの関数です。
20.2.1 interactive の使用 | interactive にたいする一般的なルール。
| |
20.2.2 interactive にたいするコード文字 | さまざまな方法で引数を読み取る標準的な文字のコード。 | |
20.2.3 interactive の使用例 | インタラクティブ引数を読み取る方法の例。 | |
20.2.4 コマンド候補からの選択 | コマンド選択肢からの選択。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
interactive
の使用このセクションでは、Lisp関数をインタラクティブに呼び出し可能なコマンドにするinteractive
フォームの記述方法と、コマンドのinteractive
フォームの検証方法について説明します。
このスペシャルフォームは関数がコマンドであり、したがって(M-xを通じて、またはそのコマンドにバインドされたキーシーケンスをエンターすることにより)インタラクティブに呼び出すことができることを宣言する。引数arg-descriptorは、そのコマンドがインタラクティブに呼び出されたときに引数を計算する方法を宣言する。
コマンドは他の関数と同じようにLisp関数から呼び出されるかもしれないが、その場合には呼び出し側は引数を提供して、arg-descriptorは効果をもたない。
interactive
フォームは関数body内のトップレベルに置くか、関数シンボルのinteractive-form
プロパティ((シンボルのプロパティ)を参照)になければならない。これはコマンドループが関数を呼び出す前にinteractiveフォームを調べることにより効果をもつ(interactiveな呼び出しを参照)。一度関数が呼び出されると関数body内のすべてのフォームが実行される。このときbody内にinteractive
フォームが出現しても、そのフォームは引数の評価さえされず単にnil
をリターンする。
慣例によりinteractive
フォームは関数body内の最初のトップレベルフォームとするべきである。interactive
フォームがシンボルのinteractive-form
プロパティと関数bodyの両方に存在する場合には前者が優先される。interactive-form
フォームは既存の関数にinteractiveフォームを追加したり、その関数を再定義することなく引数をインタラクティブに処理する方法を変更するために使用できる。
引数arg-descriptorは以下の3つの可能性があります:
nil
ならコマンドは引数なしで呼び出される。コマンドが1つ以上の引数を要求する場合は即座にエラーとなる。
interactive
にたいするコード文字を参照)と、オプションでその後のプロンプト(コード文字として使用される文字やコード文字としては無視されるものもある)により構成される。以下は例である:
(interactive "P\nbFrobnicate buffer: ")
コード文字‘P’はそのコマンドの1つ目の引数をrawコマンドプレフィクス(プレフィクスコマンド引数を参照)にセットする。‘bFrobnicate buffer: ’は、ユーザーに‘Frobnicate buffer: ’のプロンプトを示して既存のバッファーの名前の入力を促し、これは2つ目かつ最後の引数になる。
プロンプト文字列には、プロンプト内の前の引数(1つ目の引数から始まる)の値を含めるために‘%’を使用できる。これはformat-message
(文字列のフォーマットを参照)を使用して行われる。たとえば以下は既存のバッファーの名前を読み取って、その後にそのバッファーに与える新たな名前を読み取る例である:
(interactive "bBuffer to rename: \nsRename buffer %s to: ")
文字列の先頭に‘*’がある場合、そのバッファーが読み取り専用ならエラーがシグナルされる。
文字列の先頭が‘@’で、そのコマンドの呼び出しに使用されたキーシーケンスに何らかのマウスイベントが含まれる場合は、そのコマンドを実行する前に、それらのうち最初のイベントに結びつくウィンドウが選択される。
文字列の先頭が‘^’で、そのコマンドがシフト転換(shift-translation)を通じて呼び出された場合は、そのコマンドを実行する前にマークをセットして一時的にリージョンをアクティブにするか、すでにアクティブなリージョンを拡張する。コマンドがシフト転換なしで呼び出されて、リージョンが一時的にアクティブな場合は、コマンドを実行する前にそのリージョンを非アクティブにする。シフト転換はshift-select-mode
によりユーザーレベルで制御される。Shift
Selection in The GNU Emacs Manualを参照のこと。
‘*’、‘@’、^
は一緒に使用でき、その場合は順序に意味はない。実際の引数の読み取りは残りのプロンプト文字列(‘*’、‘@’、^
以外の最初の文字以降)により制御される。
引数値としてポイントやマークを提供するのも一般的だが、何かを行いかつ(ミニバッファー使用の有無に関わらず)入力を読み取る場合には、読み取りの前にポイント値またはマーク値の整数を確実に取得しておくこと。カレントバッファーはサブプロセスの出力を受信するかもしれず、コマンドが入力を待つ間にサブプロセス出力が到着すると、ポイントやマークの再配置が起こり得る。
以下は行ってはいけない例である:
(interactive (list (region-beginning) (region-end) (read-string "Foo: " nil 'my-history)))
これにたいして以下はキーボード入力を読み取った後にポイントとマークを調べることにより、上記の問題を避ける例である:
(interactive (let ((string (read-string "Foo: " nil 'my-history))) (list (region-beginning) (region-end) string)))
警告:
引数値にはプリントや読み取りが不可能なデータ型を含めないこと。いくつかの機能は後続のセッションに読み込ませるためにcommand-history
をファイルに保存する。コマンドの引数に‘#<…>’構文を使用してプリントされるデータ型が含まれていると、それらの機能は動作しなくなるだろう。
しかしこれには少数の例外がある。(point)
、(mark)
、(region-beginning)
、(region-end)
などの一連の式に限定して使用することに問題はない。なぜならEmacsはこれらを特別に認識して、コマンドヒストリー内に(値ではなく)その式を配置すからである。記述した式がこれらの例外に含まれるかどうか確認するには、コマンドを実行した後に(car
command-history)
を調べればよい。
この関数はfunctionのinteractive
フォームをリターンする。functionがインタラクティブに呼び出し可能な関数(interactiveな呼び出しを参照)なら、値はそのコマンドの引数を計算する方法を指定するinteractive
フォーム((interactive
spec)
)である。それ以外では値はnil
である。functionがシンボルなら、そのシンボルの関数定義が使用される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
interactive
にたいするコード文字ここで説明されているコード文字には、以下で定義されるいくつかのキーワードが含まれています:
補完を提供する。TAB、SPC、RETはcompleting-read
(補完を参照)を使用して引数を読み取って名前の補完を行う。?で利用可能な補完リストを表示する。
既存オブジェクトの名前を要求する。無効な名前は受け付けられない。カレント入力が有効でなければ、ミニバッファーをexitするコマンドはexitしない。
ユーザーがテキストを何もエンターしなければ、ある種のデフォルト値が使用される。デフォルトはコード文字に依存する。
このコード文字は入力を読み取らずに引数を計算する。したがってプロンプト文字列を使用せず、与えられたプロンプト文字列は無視される。
たとえそのコード文字がプロンプト文字列を使用しなくても、それが文字列内で最後のコード文字でなければ、その後に改行を付加しなければならない。
コード文字の直後にプロンプトが続く。プロンプトの終端は文字列の終端、または改行。
このコード文字はインタラクティブ文字列の先頭にあるときのみ意味があり、プロンプトと改行を要求しない。単一の独立した文字。
以下はinteractive
で使用されるコード文字です:
カレントバッファーが読み取り専用ならエラーをシグナルする。[Special]
このコマンドを呼び出したキーシーケンス内の最初のマウスイベントに関連するウィンドウを選択する。[Special]
シフト転換を通じてコマンドが呼び出された場合はコマンドを実行する前に、マークをセットして一時的にリージョンをアクティブにするか、すでにリージョンがアクティブならリージョンを拡張する。シフト転換を通じずにコマンドが呼び出されて、リージョンが一時的にアクティブならコマンドを実行する前にそのリージョンを非アクティブにする。[Special]
関数名(fboundp
を満足するシンボル)。[Existing]、[Completion]、[Prompt]
既存バッファーの名前。デフォルトではカレントバッファー(バッファーを参照)の名前を使用する。[Existing]、[Completion]、[Default]、[Prompt]
バッファー名。そのバッファーが存在する必要はない。デフォルトではカレントバッファーではなくもっとも最近使用されたバッファーの名前を使用する。[Completion]、[Default]、[Prompt]
文字。カーソルはエコーエリアに移動しない。[Prompt]
コマンド名(commandp
を満足するシンボル)。[Existing]、[Completion]、[Prompt]
ポイント位置の整数(ポイントを参照)。[No I/O]
ディレクトリー名。デフォルトはカレントバッファーのカレントのデフォルトディレクトリーdefault-directory
(ファイル名を展開する関数を参照)。[Existing]、[Completion]、[Default]、[Prompt]
そのコマンドを呼び出したキーシーケンス内の1つ目か2つ目の非キーボードイベント。より正確には、‘e’はリストとしてイベントを取得するので、リスト内のデータを調べることができる。入力イベントを参照のこと。[No I/O]
‘e’はマウスイベント、および特別なシステムイベント(その他のシステムイベントを参照)にたいして使用する。コマンドが受け取るイベントリストは、そのイベントに依存する。入力イベントではそれぞれのイベントのリスト形式を、対応するサブセクションでそれぞれ説明しているので参されたい。
1つのコマンドのinteractive仕様の中で‘e’を複数回使用できる。そのコマンドを呼び出したキーシーケンスがイベントn(リスト)をもつなら、‘e’のn番目がそのイベントを提供する。フンクションキーやASCII文字のようなリスト以外のイベントは、‘e’に関連するイベントとしてカウントされない。
既存ファイルのファイル名(ファイルの名前を参照)。デフォルトのディレクトリーはdefault-directory
。[Existing]、[Completion]、[Default]、[Prompt]
ファイル名。ファイルが存在している必要はない。[Completion]、[Default]、[Prompt]
ファイル名。ファイルが存在している必要はない。ユーザーがディレクトリー名だけをエンターしたら値はそのディレクトリー名となり、そのディレクトリー名にファイル名は追加されない。[Completion]、[Default]、[Prompt]
無関係な引数。このコード文字は引数値として常にnil
を与える。[No I/O]
キーシーケンス(キーシーケンスを参照)。これはカレントキーマップ内でコマンド(または未定義のコマンド)が見つかるまで、イベントを読み取り続ける。キーシーケンス引数は文字列かベクターで表される。カーソルはエコーエリアに移動しない。[Prompt]
‘k’が(マウスの)down-eventで終わるキーシーケンスを読み取ると、後続の(マウスの)up-eventも読み取ってそれを廃棄する。コード文字‘U’によりup-eventへのアクセスを得られる。
この種の入力はdescribe-key
やglobal-set-key
のようなコマンドにより使用される。
キーシーケンス。その定義は変更されることを意図している。これは‘k’と同じように機能するが、キーシーケンス内の最後の入力イベントにたいして、通常は(必要なら)使用される未定義キーから定義済みキーへの変換を抑制する。
マーク位置の整数。[No I/O]
任意のテキスト。ミニバッファー内でカレントバッファーの入力メソッド(Input Methods in The GNU Emacs Manualを参照)を使用して読み取りを行い、それを文字列でリターンする。[Prompt]
数字。ミニバッファーで読み取られる。入力が数字でなければユーザーは再試行する必要がある。‘n’は決してプレフィクス引数を使用しない。[Prompt]
数引数(numeric prefix argument)。ただしプレフィクス引数がなければnのように数字を読み取る。値は常に数字。プレフィクスコマンド引数を参照のこと。[Prompt]
数引数(小文字の‘p’であることに注意)。[No I/O]
rawプレフィクス引数(大文字の‘P’であることに注意)。[No I/O]
2つの数引数(ポイントとマーク)。小さいほうが先。これは1つではなく連続する2つの引数を指定する唯一のコード文字である。[No I/O]
任意のテキスト。ミニバッファー内で読み取りを行って文字列としてリターンする(ミニバッファーでのテキスト文字列の読み取りを参照)。C-jかRETで入力を終端する(これらの文字を入力に含めるためにC-qを使用できる)。[Prompt]
intern済みのシンボル。名前はミニバッファー内で読み取られる。C-jかRETで入力を終端する。ここでは通常はシンボルを終端するその他の文字(たとえば空白文字、丸カッコ、角カッコ)では終端されない。[Prompt]
キーシーケンスかnil
。‘k’(または‘K’)が読み取った後に、(もしあれば)捨てられる(マウスの)up-eventを取得するために、引数‘k’(または‘K’)の後で使用され得る。捨てられたup-eventが存在しなければ、‘U’は引数としてnil
を提供する。[No
I/O]
ユーザーオプションとして宣言された変数(述語custom-variable-p
を満足する)。これはread-variable
を使用して変数を読み取る。Definition of read-variableを参照のこと。[Existing]、[Completion]、[Prompt]
Lispオブジェクト。そのオブジェクトの入力構文により指定され、C-jかRETで終端される。オブジェクトは評価されない。ミニバッファーでのLispオブジェクトの読み取りを参照のこと。[Prompt]
Lispフォームの値。‘X’は‘x’のように読み取りを行いフォームを評価して、その値がコマンドの引数になる。[Prompt]
コーディングシステム名(シンボル)。ユーザーがnull入力をエンターすると、引数値はnil
になる。コーディングシステムを参照のこと。[Completion]、[Existing]、[Prompt]
コマンドにプレフィクス引数があればコーディングシステム名。プレフィクス引数がなければ‘Z’は引数値としてnil
を提供する。[Completion]、[Existing]、[Prompt]
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
interactive
の使用例以下にinteractive
の例をいくつか示します:
(defun foo1 () ; foo1
は1つの引数をとり
(interactive) ; 単に2単語分前に移動する
(forward-word 2))
⇒ foo1
(defun foo2 (n) ;foo2
は引数を1つとる (interactive "^p") ; 引数は数引数 ;shift-select-mode
では、 ; リージョンをアクティブにするか、拡張する (forward-word (* 2 n))) ⇒ foo2
(defun foo3 (n) ; foo3
は引数を1つとる
(interactive "nCount:") ; 引数はミニバッファーで読み取られる
(forward-word (* 2 n)))
⇒ foo3
(defun three-b (b1 b2 b3) "Select three existing buffers. Put them into three windows, selecting the last one."
(interactive "bBuffer1:\nbBuffer2:\nbBuffer3:") (delete-other-windows) (split-window (selected-window) 8) (switch-to-buffer b1) (other-window 1) (split-window (selected-window) 8) (switch-to-buffer b2) (other-window 1) (switch-to-buffer b3)) ⇒ three-b
(three-b "*scratch*" "declarations.texi" "*mail*") ⇒ nil
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マクロdefine-alternatives
はジェネリックコマンド(generic
command)を定義するために使用できます。これらはユーザーの選択により複数の候補から選択可能なinteractive関数の実装です。
新たなコマンドcommand(シンボル)を定義する。
最初にユーザーがM-x command RETを実行したとき、Emacsはコマンドが使用する実際のフォームにたいして確認を求めて、その選択をカスタム変数として記録する。プレフィクス引数を使用すると選択肢の選択のプロセスを繰り返す。
変数command-alternatives
には、commandの実装候補がalistで含まれる。この変数がセットされるまでdefine-alternatives
は効果をもたない。
customizationsが非nil
なら、defcustom
キーワード(典型的には:group
と:version
)と、command-alternatives
の宣言に追加する値により構成される選択肢。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コマンドループはキーシーケンスをコマンドに変換した後、関数command-execute
を使用してその関数を呼び出します。そのコマンドが関数なら、command-execute
は引数を読み取りコマンドを呼び出すcall-interactively
を呼び出します。自分でこれらの関数を呼び出すこともできます。
このコンテキストにおいて用語“command”はインタラクティブにコール可能な関数(または関数likeなオブジェクト)やキーボードマクロを指すことに注意してください。つまりコマンドを呼び出すキーシーケンスのことではありません(キーマップを参照)。
この関数はobjectがコマンドならt
、それ以外はnil
をリターンする。
コマンドには文字列とベクター(キーボードマクロとして扱われる)、トップレベルのinteractive
フォーム(interactive
の使用を参照)を含むラムダ式、そのようなラムダ式から作成されたバイトコンパイル関数オブジェクト、interactiveとして宣言(autoload
の4つ目の引数が非nil
)されたautoloadオブジェクト、およびいくつかのプリミティブ関数が含まれる。interactive-form
プロパティが非nil
のシンボル、および関数定義がcommandp
を満足するシンボルもコマンドとされる。
for-call-interactivelyが非nil
なら、call-interactively
が呼び出すことができるオブジェクトにたいしてのみcommandp
はt
をリターンする。したがってキーボードマクロは該当しなくなる。
commandp
を使用する現実的な例については、ドキュメント文字列へのアクセス内のdocumentation
を参照のこと。
この関数はinteractive呼び出し仕様にしたがって引数を取得し、インタラクティブに呼び出し可能な関数commandを呼び出す。これはcommandがリターンするものが何であれ、それをリターンする。
たとえばもし以下の署名をもつ関数があり:
(defun foo (begin end) (interactive "r") ...)
以下を行うと
(call-interactively 'foo)
これはリージョン(point
とmark
)を引数としてfoo
を呼び出すだろう。
commandが関数でない、またはインタラクティブに呼び出せない(コマンドでない)場合にはエラーをシグナルする。たとえコマンドだとしても、キーボードマクロ(文字列かベクター)は関数ではないので許容されないことに注意。commandがシンボルならcall-interactively
はそれの関数定義を使用する。
record-flagが非nil
なら、このコマンドとコマンドの引数は無条件にリストcommand-history
に追加される。それ以外なら引数の読み取りにミニバッファーを使用した場合のみコマンドが追加される。コマンドのヒストリーを参照のこと。
引数keysが与えらたら、それはコマンドを呼び出すためにどのイベントを使用するかコマンドが問い合わせた場合に与えるべきイベントシーケンスを指定するベクターである。keysがnil
または省略された場合のデフォルトは、this-command-keys-vector
のリターン値である。Definition of this-command-keys-vectorを参照のこと。
この関数はfuncall
(関数の呼び出しを参照)と同様に機能するが、インタラクティブな呼び出しのように見える呼び出しを生成する。function内部でのcalled-interactively-p
の呼び出しはt
をリターンするだろう。functionがコマンドでなければ、エラーをシグラルすることなくそれを呼び出す。
この関数はcommandを実行する。引数commandは述語commandp
を満足しなければならない。つまりインタラクティブに呼び出し可能な関数かキーボードマクロでなければならない。
commandが文字列かベクターなら、execute-kbd-macro
により実行される。関数はrecord-flagおよびkeys引数とともにcall-interactively
に渡される(上記参照)。
commandがシンボルなら、その位置にシンボルの関数定義が使用される。autoload
定義のあるシンボルは、インタラクティブに呼び出し可能な関数を意味するよう宣言されていればコマンドとして判断される。そのような宣言は指定されたライブラリーのロードと、シンボル定義の再チェックにより処理される。
引数specialが与えられたら、それはプレフィクス引数を無視して、それをクリアーしないという意味である。これはスペシャルイベント(スペシャルイベントを参照)を実行する場合に使用される。
この関数はcompleting-read
(補完を参照)を使用して、ミニバッファーからコマンド名を読み取る。その後で指定されたコマンドを呼び出すためにcommand-execute
を使用する。そのコマンドがリターンするのが何であれ、それがexecute-extended-command
の値となる。
そのコマンドがプレフィクス引数を求める場合には、prefix-argumentの値を受け取る。execute-extended-command
がインタラクティブに呼び出されたら、カレントのrawプレフィクス引数がprefix-argumentに使用され、それが何であれ実行するコマンドに渡される。
通常はexecute-extended-command
はM-xの定義なので、プロンプトとして文字列‘M-x ’を使用する(execute-extended-command
を呼び出したイベントからプロンプトを受け取るほうが良いのだろうが実装は苦痛を併なう)。プレフィクス引数の値の説明がもしあれば、それもプロンプトの一部となる。
(execute-extended-command 3) ---------- Buffer: Minibuffer ---------- 3 M-x forward-word RET ---------- Buffer: Minibuffer ---------- ⇒ t
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
interactive呼び出しの際に、コマンドが(エコーエリア内の情報メッセージなどのような)視覚的な追加フィードバックを表示すべきときがあります。これを行うためには3つの方法があります。その関数がcall-interactively
を使用して呼び出されたかどうかテストするには、オプション引数print-message
を与えるとともに、interactive呼び出しで非nil
となるようにinteractive
仕様を使うのが推奨される方法です。以下は例です:
(defun foo (&optional print-message) (interactive "p") (when print-message (message "foo")))
数プレフィクス引数は決してnil
にならないので、わたしたちは"p"
を使用します。この方法で定義された関数はキーボードマクロから呼び出されたときにメッセージを表示します。
追加引数による上記の手法は、呼び出し側に“この呼び出しをinteractiveとして扱うように”伝えることができるので通常は最善です。しかしcalled-interactively-p
をテストすることによってこれを行うこともできます。
この関数は呼び出された関数がcall-interactively
を使用して呼び出されえいたらt
をリターンする。
引数kindはシンボルinteractive
かシンボルany
のいずれかである。これがinteractive
なら、called-interactively-p
はユーザーから直接呼び出しが行われたとき
—
たとえば関数呼び出しにバインドされたキーシーケンスをユーザーがタイプした場合がそれに該当するが、ユーザーがその関数を呼び出すキーボードマクロ(キーボードマクロを参照)を実行中した場合は該当しない —
だけt
をリターンする。kindがany
なら、called-interactively-p
はキーボードマクロを含む任意の種類のinteractive呼び出しにたいしてt
をリターンする。
疑わしい場合にはany
を使用すること。interactive
の使用が正しいと解っているのは、関数が実行中に役に立つメッセージを表示するかどうか判断が必要な場合だけである。
Lisp評価(またはapply
やfuncall
))を通じて呼び出された場合には、関数は決してインタラクティブに呼び出されたとは判断されない。
以下はcalled-interactively-p
を使用する例:
(defun foo () (interactive) (when (called-interactively-p 'any) (message "Interactive!") 'foo-called-interactively))
;; M-x fooとタイプする
-| Interactive!
(foo) ⇒ nil
以下はcalled-interactively-p
の直接呼び出しと間接呼び出しを比較した例。
(defun bar () (interactive) (message "%s" (list (foo) (called-interactively-p 'any))))
;; M-x barとタイプする
-| (nil t)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
エディターコマンドループは自分自身と実行するコマンドのために、いくつかのLisp変数にステータス記録を保持します。一般的にthis-command
とlast-command
以外は、Lispプログラム内でこれらの変数を変更するのは良いアイデアではありません。
この変数はコマンドループによって実行された以前のコマンド(前にカレントだったコマンド)の名前を記録する。値は通常は関数定義をもつシンボルだが、その保証はない。
コマンドがコマンドループからリターンするとき、this-command
から値がコピーされる。ただしそのコマンドが後続のコマンドにたいしてプレフィクス引数を指定されたときを除く。
この変数は常にカレント端末にたいしてローカルであり、バッファーローカルにできない。複数の端末を参照のこと。
この変数はEmacsによりlast-command
と同様にセットアップされるが、Lispプログラムから決して変更されない。
この変数は入力イベントの一部ではない、もっとも最近実行されたコマンドを格納する。これはコマンドrepeat
が再実行を試みるコマンドである。Repeating in The GNU Emacs Manualを参照のこと。
この変数はコマンドループにより現在実行中のコマンドの名前を記録する。last-command
と同様、通常は関数定義をもつシンボルである。
コマンドループはコマンドを実行する直前にこの変数をセットして、(そのコマンドが後続のコマンドのプレフィクス引数を指定しなければ)そのコマンドが終了したときにその値をlast-command
にコピーする。
いくつかのコマンドは次に実行されるコマンドが何であれ、それにたいするフラグとして実行中の間この変数をセットする。特にテキストをkillする関数はthis-command
をkill-region
にセットするので、直後に実行された任意のkillコマンドは、killしたテキストを前にkillされたテキストに追加するべきことが解かるだろう。
特定のコマンドでエラー発生時に前のコマンドとして認識されたくなければ、それを防ぐようにそのコマンドをコーディングしなければなりません。これを行う1つの方法は、以下のようにコマンドの最初でthis-command
にt
をセットして、最後にthis-command
に正しい値をセットする方法です:
(defun foo (args…)
(interactive …)
(let ((old-this-command this-command))
(setq this-command t)
… 処理を行う …
(setq this-command old-this-command)))
エラーならlet
は古い値をリストアするので、わたしたちはlet
でthis-command
をバインドしません。この場合におけるlet
の機能は、わたしたちが正に避けたいと思っていることを行ってしまうでしょう。
コマンドのリマップ(コマンドのリマップを参照)が発生したときを除き、これはthis-command
と同じ値をもつ。リマップが発生するとthis-command
は実際に実行されたコマンド、this-original-command
は実行を指定されたが他のコマンドにリマップされたコマンドを与える。
この関数は現在のコマンドを呼び出したキーシーケンスと、加えてそのコマンドにたいするプレフィクス引数を生成した前のコマンドを含む文字列かベクターをリターンする。read-event
を使用するコマンドにより、タイムアウトせずに読み取られたすべてのイベントが最後に加えられる。
しかしそのコマンドがread-key-sequence
を呼び出していたら、最後に読み取られたキーシーケンスをリターンする。キーシーケンス入力を参照のこと。シーケンス内のすべてのイベントが文字列として適当な文字なら文字列が値になる。入力イベントを参照のこと。
(this-command-keys)
;; これを評価するためにC-u C-x C-eを使用すると
⇒ "^U^X^E"
this-command-keys
と同様だが常にベクターでイベントをリターンするので、入力イベントを文字列内に格納する複雑さを処理する必要がない(文字列内へのキーボードイベントの配置を参照)。
この関数はthis-command-keys
がリターンするイベントテーブルを空にする。keep-recordがnil
なら、その後に関数recent-keys
(入力の記録を参照)がリターンするレコードも空にする。これは特定のケースにおいてパスワードを読み取った後、次のコマンドの一部として不用意にパスワードがエコーされるのを防ぐために有用である。
この変数はキーシーケンス(マウスメニューからのイベントは勘定しない)の一部として読み取られた最後の入力イベントを保持する。
この変数の1つの使い方は、x-popup-menu
にたいしてどこにメニューをポップアップすべきか告げる場合である。これは内部的に
y-or-n-p
(Yes-or-Noによる問い合わせを参照)にも使用されている。
この変数にはコマンドの一部としてコマンドループに読み取られた最後の入力イベントがセットされる。この変数は主にself-insert-command
内でどの文字が挿入されたか判断するために使用されている。
last-command-event
;; これを評価するためにC-u C-x C-eを使用すると
⇒ 5
C-eのASCIIコードの5が値になる。
この変数は最後の入力イベントが送られたフレームを記録する。これは通常はそのイベントが生成されたときに選択されていたフレームだが、そのフレームの入力が他のフレームにリダイレクトされていたら、そのリダイレクトされていたフレームが値となる。入力のフォーカスを参照のこと。
最後のイベントがキーボードマクロに由来する場合、値はmacro
になる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プロパティdisplay
やcomposition
をもつテキストや、非表示のテキストシーケンスの中間でポイント値を表示するのは簡単ではありません。したがってコマンドが終了した後にコマンドループにリターンするとき、そのようなシーケンス中にポイントがあれば、コマンドループは通常ポイントをそのようなシーケンスの端に移動します。
変数disable-point-adjustment
をセットすることにより、コマンドはこの機能を抑制できます:
この変数が非nil
ならコマンドがコマンドループにリターンするとき、コマンドループはこれらのテキストプロパティをチェックせず、これらのプロパティをもつシーケンスの外にポイントを移動しない。
コマンドループは各コマンドを実行する前にこの変数をnil
にセットするので、あるコマンドがこれをセットしても効果が適用されるのはそのコマンドにたいしてだけである。
この変数を非nil
にセットするとシーケンス外にポイントを移動する、これらの機能は完全にオフになる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsコマンドループは入力イベント(input events)のシーケンスを読み取ります。入力イベントとはキーボードやマウスのアクティビティ、またはEmacsに送られるシステムイベントを表します。キーボードアクティビティにたいするイベントは文字かシンボルです。それ以外のイベントは常にリストになります。このセクションでは入力イベントの表現と意味について詳細を説明します。
この関数はobjectが入力イベントかイベント型なら非nil
をリターンする。
イベントとイベント型として任意のシンボルが使用されるかもしれないことに注意。eventp
は、あるシンボルがLispコードによりイベントとして使用されることを意図しているか否か区別できない。そのかわりにカレントEmacsセッション内で、そのシンボルが入力として読み取られたイベント内で実際に使用されているか否かを区別する。シンボルがまだそのように使用されていなければeventp
はnil
をリターンする。
20.7.1 キーボードイベント | 通常の文字 — 自身にシンボルされるキー。 | |
20.7.2 ファンクションキー | ファンクションキー — 名前をもつがシンボルではない。 | |
20.7.3 マウスイベント | マウスイベントの概観。 | |
20.7.4 クリックイベント | マウスボタンのプッシュとリリース。 | |
20.7.5 ドラッグイベント | ボタンをリリースする前のマウス移動。 | |
20.7.6 ボタンダウンイベント | ボタンがプッシュされて、まだリリースされていない状態。 | |
20.7.7 リピートイベント | ダブル、トリプルのクリック(またはドラッグ、ダウン) | |
20.7.8 モーションイベント | ボタンを押さずに、マウスだけを移動する。 | |
20.7.9 フォーカスイベント | フレーム間のマウス移動。 | |
20.7.10 その他のシステムイベント | システムが生成可能なその他のイベント。 | |
20.7.11 イベントの例 | マウスイベントの例。 | |
20.7.12 イベントの分類 | イベントシンボル内の修飾キーを見つける。イベント型。 | |
20.7.13 マウスイベントへのアクセス | マウスイベントから情報抽出する関数。 | |
20.7.14 スクロールバーイベントへのアクセス | スクロールバーイベントから情報取得する関数。 | |
20.7.15 文字列内へのキーボードイベントの配置 | 文字列内にキーボード文字イベントを配すための特別な配慮。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
キーボードから取得できる入力には2つの種類があります。それは通常のキーとファンクションキーです。通常のキーは文字に対応し、それらが生成するイベントはLisp内では文字で表現されます。文字イベントのイベント型は文字自身(整数)です。イベントの分類を参照してください。
入力文字イベントは0から524287までの基本コード(basic code)に加えて、以下の修飾ビット(modifier bits)の一部、またはすべてによって構成されます:
文字コードのビット 2**27 はメタキーが押下された状態で文字がタイプされたことを示す。
文字コードのビット 2**26 は非ASCIIコントロール文字を示す。
C-aのような非ASCIIコントロール文字は、自身が特別な基本コードをもつため、それらを示すためにEmacsは特別なビットを必要としない。つまりC-aのコードは単なる1である。
しかし%のような非ASCIIとコントロールを組み合わせてタイプすると取得される数値は%に 2**26 を加えた値となる(端末が非ASCIIコントロール文字をサポートすると仮定する)。
文字コードのビット 2**25 はシフトキーが押下された状態でASCIIコントロール文字がタイプされたことを示す。
アルファベット文字にたいしては、基本コード自身が大文字か小文字かを示す。数字と句読点文字にたいしてシフトキーは、異なる基本コードをもつ完全に違う文字を選択する。可能な限りASCII文字として保つために、Emacsはこれらの文字にたいしてビット 2**25 を使用しない。
しかしASCIIはC-AとC-aを区別する方法を提供しないので、EmacsはC-Aにたいしてビット 2**25 を使用し、C-aには使用しない。
文字コードのビット 2**24 はハイパーキーが押下された状態で文字がタイプされたことを示す。
文字コードのビット 2**23 はスーパーキーが押下された状態で文字がタイプされたことを示す。
文字コードのビット 2**22 はアルトキーが押下された状態で文字がタイプされたことを示す(ほとんどのキーボードでAltとラベルされたキーは、実際にはアルトキーではなくメタキーとして扱われる)。
プログラム内での特定のビット数値の記述は避けるのが最善の方法です。文字の修飾ビットをテストするためには、関数event-modifiers
(イベントの分類を参照)を使用してください。キーバインディングを作成するときは、修飾ビットつきの文字にたいする読み取り構文を使用できます(‘\C-’、‘\M-’、...など)。define-key
でのキーバインディング作成では、文字を指定するために(control
hyper ?x)
のようなリストを使用できます(キーバインディングの変更を参照)。関数event-convert-list
はそのようなリストをイベント型に変換します(イベントの分類を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ほとんどのキーボードにはファンクションキー(function keys)があります。これは名前や文字以外のシンボルをもつキーです。Emacs
Lispではファンクションキーはシンボルとして表現されます。そのシンボル名はファンクションキーのラベルの小文字です。たとえばF1とラベルされたキーを押下すると、シンボルf1
で表される入力イベントが生成されます。
ファンクションキーのイベント型はイベントシンボル自身です。イベントの分類を参照してください。
ファンクションキーにたいするシンボルの命名規約には、以下のような特別なケースがいくつかあります:
backspace
、tab
、newline
、return
、delete
これらのキーは、ほとんどのキーボードにおいて特別にキーをもつ、一般的なASCIIコントロール文字に対応する。
ASCIIではC-iとTABは同じ文字である。端末がこれらを区別できるならEmacsは前者を整数の9、後者をシンボルtab
で表現することによってLispプログラムにこれらの違いを伝える。
ほとんどの場合はこれらの2つを区別するのは役に立たない。そのためlocal-function-key-map
(イベントシーケンス変換のためのキーマップを参照)はtab
を9にマップするようセットアップされている。したがって文字コード9(文字C-i)へのキーバインディングはtab
にも適用される。このグループ内の他のシンボルも同様である。関数read-char
がこれらのイベントを文字に変換する場合も同様である。
ASCIIではBSは実際はC-hである。しかしbackspace
は文字コード8(BS)ではなく、文字コード127(DEL)に変換される。ほとんどのユーザーにとってこれは好ましいだろう。
left
、up
、right
、down
矢印カーソルキー
kp-add
、kp-decimal
、kp-divide
、…キーパッドのキー(標準的なキーボードにおいては右側にある)。
kp-0
、kp-1
、…キーパッドの数字キー。
kp-f1
、kp-f2
、kp-f3
、kp-f4
キーパッドのPFキー。
kp-home
、kp-left
、kp-up
、kp-right
、kp-down
キーパッドの矢印キー。Emacsは通常これらを非キーパッドのキーhome
、left
、…に変換する。
kp-prior
、kp-next
、kp-end
、kp-begin
、kp-insert
、kp-delete
通常は他の箇所にあるキーと重複するキーパッド追加キー。Emacsは通常これらを同じような名前の非キーパッドキーに変換する。
ファンクションキーにたいしても修飾キーALT、CTRL、HYPER、META、SHIFT、SUPERを使用できます。シンボル名のプレフィクスとしてこれらを表します:
アルト修飾。
コントロール修飾。
ハイパー修飾。
メタ修飾。
シフト修飾。
スーパー修飾。
したがってMETAを押下した場合のF3キーにたいするシンボルはM-f3
になります。複雑のプレフィクスを使用する場合には、アルファベット順の記述を推奨します。とはいえキーバインディングが修飾されたファンクションキーを探す際に引数の順序は関係ありません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsは4つの種類のマウスイベントをサポートします。それはクリックイベント、ドラッグイベント、ボタンダウンイベント、モーションイベントです。すべてのマウスイベントはリストで表現されます。このリストのCARはイベント型です。イベント型はどのマウスボタンが関与するのか、それにたいしてどの修飾キーが使用されたかを示します。イベント型によりダブル、あるいはトリプルでボタンが押されたかを区別することもできます(リピートイベントを参照)。残りのリスト要素は位置と時間の情報を提供します。
キーの照合ではイベント型だけが問題になります。2つのイベントが同じコマンドを実行するには同じイベント型が必要です。実行されるコマンドはinteractiveのコード‘e’を使用して、これらのイベントの完全な値にアクセスできます。interactive
にたいするコード文字を参照してください。
マウスイベントで開始されたキーシーケンスはカレントバッファーではなく、マウスのあったウィンドウ内のバッファーのキーマップを使用して読み取られます。これはウィンドウ内でクリックすることによりそのウィンドウやそのウィンドウのバッファーが選択されることを意味しません。つまりそれは完全にそのキーシーケンスのコマンドバインディングの制御下にあるのです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ユーザーが同じ場所でマウスボタンを押してからリリース(release: 離す)すると、clickイベントが生成されます。すべてのマウスクリックイベントは同じフォーマットを共有します:
(event-type position click-count)
これはマウスボタンが使用されたことを示す。これはシンボルmouse-1
、mouse-2
、…のうちのいずれかで、マウスボタンは左から右に番号が付される。
ファンクションキーにたいして行うのと同様にアルト、コントロール、ハイパー、メタ、シフト、スーパーの修飾にたいしてプレフィクス‘A-’、‘C-’、‘H-’、‘M-’、‘S-’、‘s-’も使用できる。
このシンボルはイベントのイベント型としての役割りももつ。イベントのキーバインディングはこれらの型により示される。したがってmouse-1
にたいするキーバインディングが存在すれば、そのバインディングはevent-typeがmouse-1
であるようなすべてのイベントに適用されるだろう。
これはマウスクリックがどこで発生したかを表すマウス位置リスト(mouse position list)である。詳細は以下を参照のこと。
これは同じマウスボタンを素早く繰り返し押下したときの回数である。リピートイベントを参照のこと。
クリックイベントのpositionスロット内にあるマウス位置リストの内容にアクセスするためには、一般的にはマウスイベントへのアクセスに記述された関数を使用するべきです。このリストの明示的なフォーマットはどこでクリックが発生したかに依存します。テキストエリア、モードライン、ヘッダーライン、フリンジ、マージンエリアでのクリックにたいしてマウス位置リストは以下のフォーマットをもちます
(window pos-or-area (x . y) timestamp object text-pos (col . row) image (dx . dy) (width . height))
以下はこれらのリスト要素がもつ意味です:
クリックが発生したウィンドウ。
テキストエリア内でクリックされた文字のバッファー位置。またはテキストエリア外がクリックされたなら、クリックが発生したウィンドウエリア。これはシンボルmode-line
、header-line
、vertical-line
、left-margin
、right-margin
、left-fringe
、right-fringe
のいずれか。
特別なケースの1つとしてpos-or-areaが単なるシンボルではなく、(上記シンボルのいずれか1つの)シンボルを含むリストのような場合がある。これはEmacsにより登録されたイベントにたいする、イマジナリープレフィクスキー(imaginary prefix key)の後に発生する。キーシーケンス入力を参照のこと。
クリックの相対ピクセル座標(relative pixel
coordinates)。あるウィンドウのテキストエリア内でのクリックにたいする座標原点(0
. 0)
は、テキストエリアの左上隅となる。ウィンドウのサイズを参照のこと。モードラインやヘッダーライン内でのクリックにたいする座標原点は、そのウィンドウ自身の左上隅となる。フリンジ、マージン、垂直ボーダー(vertical
border)ではxは有意なデータをもたない。フリンジ、マージンではyはヘッダーラインの最下端からの相対位置である。すべてのケースにおいてxとyの座標はそれぞれ右方向と下方向で増加する。
そのイベントが発生した時刻をシステム依存の初期時刻(initial time)からの経過ミリ秒で表す整数。
クリック位置に文字列タイプのテキストプロパティが存在しなければnil
、存在すれば(string
. string-pos)形式のコンスセル:
クリックされた文字列。すべてのテキストプロパティを含む。
クリックが発生した文字列内の位置。
マージンエリアやフリンジにたいするクリックでは、そのウィンドウ内の対応する行内の最初の可視な文字のバッファー位置となる。モードラインやヘッダーラインにたいするクリックではnil
。他のイベントにたいしてはクリックされたバッファーのクリックされた最寄りの位置となる。
これらはx、yの位置にあるグリフ(gliph)の実際の行と列の座標数値である。行xがその行の実際のテキストの最後の列を超えるなら、colはデフォルトの文字幅をもつ仮想的な追加列数を加えた値が報告される。そのウィンドウがヘッダーラインをもつなら、行0はヘッダーラインとなり、ヘッダーラインをもたなければテキストエリアの上端ラインが行0となる。ウィンドウのテキストエリアのクリックにたいしては、テキストエリアの左端列が列0となり、モードラインまたはヘッダーラインのクリックにたいしてはそのラインの左端が列0となる。フリンジまたは垂直ボーダーのクリックにたいしては、これらは有意なデータをもたない。マージンのクリックにたいしては、colはマージンエリアの左端、rowはマージンエリアの上端から測られる。
これはクリックが発生した場所のイメージオブジェクトである。クリックされた場所にイメージが存在しなければnil
、イメージがクリックされたらfind-image
によりリターンされるイメージオブジェクト。
これらはobjectの左上隅(0
. 0)
からの相対的ピクセル座標である。objectがnil
なら、クリックされた文字グリフの左上隅からの相対座標。
これらはobjectのピクセル幅とピクセル高さであり、objectがnil
ならクリックされた文字グリフのピクセル幅とピクセル高さ。
スクロールバーへのクリックにたいして、positionは以下の形式をもちます:
(window area (portion . whole) timestamp part)
スクロールバーがクリックされたウィンドウ。
これはシンボルvertical-scroll-bar
である。
スクロールバーの上端からクリック位置までのピクセル数。GTK+を含むいくつかのツールキットでは、Emacsがこれらのデータを抽出できないので値は常に0
。
スクロールバーの全長のピクセル数。GTK+を含むいくつかのツールキットでは、Emacsがこれらのデータを抽出できないので値は常に0
。
イベントが発生したミリ秒時刻。GTK+を含むいくつかのツールキットでは、Emacsがこれらのデータを抽出できないので値は常に0
。
クリックが発生したスクロールバー部分。これはシンボルhandle
(スクロールバーのハンドル)、above-handle
(ハンドルの上側エリア)、below-handle
(ハンドルの下側エリア)、up
(スクロールバー端の上矢印)、down
(スクロールバー端の下矢印)のいずれか。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsでは特別なことをしなくてもドラッグイベントを取得できます。ドラッグイベント(drag event)はユーザーがマウスボタンを押下して、ボタンをリリースする前にマウスを異なる文字位置に移動すると毎回発生します。すべてのマウスイベントと同じように、ドラッグイベントはLispではリストで表現されます。このリストは以下のように開始マウス位置と最終位置ぼ両方を記録します:
(event-type (window1 START-POSITION) (window2 END-POSITION))
ドラッグイベントにたいしては、シンボルevent-typeの名前にプレフィクス‘drag-’が含まれます。たとえばボタン2を押下したままマウスをドラッグするとdrag-mouse-2
イベントが生成されます。このイベントの2つ目と3つ目の要素は、マウス位置リスト(クリックイベントを参照)としてドラッグの開始と終了の位置を与えます。任意のマウスイベントの2つ目の要素に同じ方法でアクセスできます。しかしドラッグイベントは最初に選択されていたフレームの境界外で終了するかもしれません。この場合のには3つ目の要素の位置リストに、ウィンドウのかわりにそのフレームが含まれます。
‘drag-’プレフィクスは、その後に‘C-’や‘M-’のような修飾キープレフィクスが続きます。
read-key-sequence
がキーバインディングをもたず、対応するクリックイベントにキーバインディングがあるようなドラッグイベントを受け取ると、この関数はそのドラッグイベントをドラッグ開始位置でのクリックイベントに変更します。これはもし望まなければクリックイベントとドラッグイベントを区別する必要がないことを意味します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
クリックイベントとドラッグイベントは、ユーザーがマウスボタンをリリースしたときに発生します。ボタンがリリースされるまでクリックとドラッグを区別することはできないので、リリース前にイベントが発生することはありません。
ボタンが押下されたらすぐに何か処理したいなら、ボタンダウン(button-down)イベントを処理する必要があります11。これらはevent-typeのシンボル名に‘down-’が含まれることを除き、クリックイベントとまったく同じようなリストにより表現されます。‘down-’プレフィクスの後には‘C-’や‘M-’のような修飾キープレフィクスが続きます。
関数read-key-sequence
はコマンドバインディングをもたないボタンダウンイベントを無視します。したがってEmacsコマンドループもこれらを無視します。これはボタンダウンイベントで何かしたい場合以外は、ボタンダウンイベントの定義について配慮する必要がないことを意味します。ボタンダウンイベントを定義する通常の理由は、ボタンがリリースされるまで(モーションイベントを読み取ることにより)マウスモーションを追跡できるからです。モーションイベントを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マウスを移動せずに同じマウスボタンを素早く2回以上連続して押下すると、Emacsは2回目とそれ以降の押下にたいして特別なリピート(repeat)マウスイベントを生成します。
もっとも一般的なリピートイベントはダブルクリック(double-click)イベントです。Emacsはボタンを2回クリックしたときにダブルクリックイベントを生成します。このイベントは、(すべてのクリックイベントが通常そうであるように)ボタンをリリースしたときに発生します。
ダブルクリックイベントのイベント型にはプレフィクス‘double-’が含まれます。したがってmetaを押しながら2つ目のマウスボタンをダブルクリックすると、LispプログラムにはM-double-mouse-2
が渡されます。ダブルクリックイベントがバインディングをもたなければ、対応する通常のクリックイベントのバインディングが実行に使用されます。したがって実際に望んだ場合でなければダブルクリック機能に注意を払う必要はありません。
ユーザーがダブルクリックを行うとき、Emacsはまず通常のクリックイベントを生成して、その後ダブルクリックイベントを生成します。したがってダブルクリックイベントのコマンドバインディングは、すでにシングルクリックイベントが実行された想定でデザインしなければなりません。つまりシングルクリックの結果から開始して、ダブルクリックの望むべき結果を生成しなければならないのです。
これはダブルクリックの意味合いが、シングルクリックの意味合いの何らかにもとづいて構築される場合は便利です。これはダブルクリックにたいするユーザーインターフェイスにおける推奨されるデザインプラクティスです。
ボタンをクリックした後にもう一度ボタンを押下して、そのままマウスの移動を開始すると、最終的にボタンをリリースしたときダブルドラッグ(double-drag)イベントが取得されます。このイベント型には単なる‘drag’のかわりに‘double-drag’が含まれます。ダブルドラッグイベントがバインディングをもたなければ、それがあたかも通常のドラッグイベントだったかのようにEmacsはかわりのバインディングを探します。
ダブルクリックやダブルドラッグイベントの前に、Emacsはユーザーが2回目にボタンを押したタイミングでダブルダウン(double-down)イベントを生成します。このイベント型には単なる‘down’のかわりに‘double-down’が含まれます。ダブルダウンイベントがバインディングをもたなければ、それがあたかも通常のボタンダウンイベントだったかのようにEmacsはかわりのバインディングを探します。どちらの方法でもバインディングが見つからなければダブルダウンイベントは無視されます。
要約するとボタンをクリックしてすぐにまた押したとき、Emacsは1回目のクリックにたいしてダウンイベントとクリックイベントを生成して、2回目に再度ボタンを押したときにダブルダウンイベント、そして最後にダブルクリックまたはダブルドラッグイベントを生成します。
ボタンを2回クリックした後にもう一度押したとき、それらすべてが素早く連続で行われたら、Emacsはトリプルダウン(triple-down)イベントと、その後続のトリプルクリック(triple-click)かトリプルドラッグ(triple-drag)イベントを生成します。これらイベントのイベント型には‘double’のかわりに‘triple’が含まれます。トリプルイベントがバインディングをもたなければEmacsは対応するダブルイベントに使用されるであろうバインディングを使用します。
ボタンを3回以上クリックした後に再度ボタンを押すと、3回を超えた押下にたいするイベントはすべてトリプルイベントになります。Emacsはクワドループル(quadruple: 4連)、クインティプル(quintuple: 5連)、...等のイベントにたいして個別のイベント型をもちません。しかしボタンが何回押下されたかを正確に調べるためにイベントリストを調べることができます。
この関数はeventを誘因した連続するボタン押下の回数をリターンする。eventがダブルダウン、ダブルクリック、ダブルドラッグなら値は2である。eventがトリプルイベントなら値は3以上になる。eventが(リピートイベントではない)通常のマウスイベントなら値は1。
リピートイベントを生成するためには、ほぼ同じスクリーン位置で連続でマウスボタンを押下しなければならない。double-click-fuzz
の値はダブルクリックを生成するために連続する2回のクリック間で、マウスが移動(水平と垂直)するかもしれない最大ピクセル数を指定する。
この変数はドラッグとみなされるマウスモーションの閾値でもある。
リピートイベントを生成するためには、連続するボタン押下のミリ秒間隔がdouble-click-time
の値より小さくなければならない。double-click-time
をnil
にセットすると複数回クリック検知が完全に無効になる。t
にセットすると時間制限が取り除かれる。その場合はEmacsは位置だけで複数回のクリックを検知する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsは、ボタンアクティビティが何もないマウスのモーション(motion: 動き)を記述するマウスモーション(mouse motion)イベントを生成するときがあります。マウスモーションイベントは以下のようなリストによって表現されます:
(mouse-movement POSITION)
positionはマウスカーソルのカレント位置を指定するマウス位置リスト(クリックイベントを参照)です。ドラッグイベントの終了位置のように、この位置リストは最初に選択されていた境界外の位置を表すかもしれず、その場合にはそのフレーム内のその位置のウィンドウが含まれます。
スペシャルフォームtrack-mouse
は、ボタン内でのモーションイベントの生成を有効にします。track-mouse
フォームの外側では、Emacsはマウスの単なるモーションにたいするイベントは生成せず、これらのイベントは発生しません。マウスの追跡を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウシステムはユーザーにたいしてどのウィンドウがキーボード入力を受け取るか制御するための一般的な方法を提供します。このウィンドウ選択はフォーカス(focus)と呼ばれます。Emacsのフレームを切り替えるためにユーザーが何かを行うと、それはフォーカスイベント(focus event)を生成します。フォーカスイベントの通常の定義はグローバルキーマップ内にあり、ユーザーが期待するようにEmacsで新たなフレームを選択するためのものです。入力のフォーカスではフォーカスイベントに関連するフックも説明しています。
フォーカスイベントは以下のようにLispのリストで表現されます:
(switch-frame new-frame)
ここでnew-frameは切り替え先のフレームです。
Xウィンドウマネージャーには、あるウィンドウにマウスを移動するだけで、そこにフォーカスされるようにセットアップするものがいくつかあります。通常は他の種類の入力が到着するまで、Lispプログラムがフォーカスの変更を知る必要はありません。Emacsはユーザーが新たなフレーム内で実際にキーボードのキーをタイプするかマウスボタンを押下したときしか、フォーカスイベントを生成しません。つまりフレーム間でマウスを移動させても、フォーカスイベントは生成されません。
キーシーケンスの途中におけるフォーカスイベントは、そのシーケンスを誤ったものにするかもしれません。そのためEmacsは決してキーシーケンスの途中でフォーカスイベントを生成しません。ユーザーがキーシーケンスの途中(つまりプレフィクス引数の後)でフォーカスを変更すると、複数イベントキーシーケンスの前か後にフォーカスイベントが到着するように、Emacsはフォーカスイベントを記録しておきます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
他にもシステム内での出来事を表現するイベント型がいくつかあります。
(delete-frame (frame))
このイベントの種類はユーザーがウィンドウマネージャーに特定のウィンドウを削除するコマンドを与えたことを示し、Emacsのフレームにたいして発生する。
フレーム削除(delete-frame)
イベントの標準的な定義ではframeが削除される。
(iconify-frame (frame))
このイベントの種類はウィンドウマネージャーを使用してユーザーがframeをアイコン化したことを示す。標準的な定義はignore
。これはそのフレームがすでにアイコン化されているので、Emacsが行う必要のことは何もないからである。このイベント型の目的は、望むならこのようなイベントの追跡を可能にしておくためである。
(make-frame-visible (frame))
このイベントの種類はウィンドウマネージャーを使用してユーザーがframeを非アイコン化したことを示す。標準的な定義はignore
。これは、そのフレームがすでに可視化されているので、Emacsが行う必要のことは何もないからである。
(wheel-up position)
(wheel-down position)
この種類のイベントはマウスホイールを移動したことにより発生する。position要素はそのイベント発生時のマウスカーソル位置を指定するマウス位置リスト(クリックイベントを参照)。
この種類のイベントはある種のシステムでのみ発生する。いくつかのシステムでは、かわりにmouse-4
とmouse-5
が使用される。可搬性のあるコードとするためには、マウスホイールにたいしてどのイベント型が期待されるかを決定するためにmwheel.el内で定義されている変数mouse-wheel-up-event
とmouse-wheel-down-event
を使用すること。
(drag-n-drop position files)
この種類のイベントはEmacs外部アプリケーション内でファイルグループが選択されて、それがEmacsフレーム内にドラッグアンドドロップされたときに発生する。
要素positionは、そのイベント位置を記述しマウスクリックイベントで使用されるフォーマット(クリックイベントを参照)と同じ。要素filesはドラッグアンドドロップされたファイル名のリスト。通常はそれらのファイルをvisitすることによってこのイベントは処理される。
この種類のイベントは現在のところある種のシステムでのみ生成される。
help-echo
この種類のイベントは、テキストプロパティhelp-echo
をもつバッファーテキスト部分上にマウスポインターが移動したときに生成される。生成されるイベントは以下の形式をもつ:
(help-echo frame help window object pos)
イベントパラメーターの正確な意味とヘルプテキストを表示するためにこれらのパラメーターを使用する方法は、Text help-echoで説明されている。
sigusr1
sigusr2
これらのイベントはEmacsプロセスがシグナルSIGUSR1
やSIGUSR2
を受け取ったときに生成される。シグナルは追加情報を運搬しないので追加データは含まれない。これらのシグナルはデバッグに有用(エラーによるデバッガへのエンターを参照)。
ユーザーシグナルをcatchするためには、special-event-map
(アクティブなキーマップを参照)内で対応するイベントにバインドする。そのコマンドは引数なしで呼び出され、last-input-event
内の特定のシグナルイベントが利用できる。たとえば:
(defun sigusr-handler () (interactive) (message "Caught signal %S" last-input-event)) (define-key special-event-map [sigusr1] 'sigusr-handler)
シグナルハンドラーをテストするために、自身でEmacsにシグナルを送信できる:
(signal-process (emacs-pid) 'sigusr1)
language-change
この種類のイベントはMS-Windows上で入力言語が変更されたときに生成される。これは通常はキーボードキーが異なる言語の文字でEmacsに送られることを意味する。生成されるイベントは以下の形式をもつ:
(language-change frame codepage language-id)
ここでframeは言語が変更されたときカレントだったフレーム、codepageは新たなコードページ番号(codepage
number)、language-idは新たな入力言語の数値IDである。codepageに対応するコーディングシステム(コーディングシステムを参照)は、cpcodepage
かwindows-codepage
。language-idを文字列に変更する(たとえばset-language-environment
のようなさまざまな言語依存機能にたいしこれを使用する)には、以下のようにw32-get-locale-info
関数を使用する:
;; 英語にたいする"ENU"のような言語の省略形を取得する (w32-get-locale-info language-id) ;; "English (United States)"のような ;; その言語の完全な英語名を取得する (w32-get-locale-info language-id 4097) ;; その言語の完全なローカライズ名を取得する (w32-get-locale-info language-id t)
キーシーケンスの途中、つまりプレフィクスキーの後にこれらのイベントの1つが到着すると、複数イベントキー内ではなくその前か後にそのイベントが到着するようにEmacsはそのイベントを記録する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ユーザーが同じ場所でマウス左ボタンを押して離すと、それは以下のようなイベントシーケンスを生成します:
(down-mouse-1 (#<window 18 on NEWS> 2613 (0 . 38) -864320)) (mouse-1 (#<window 18 on NEWS> 2613 (0 . 38) -864180))
コントロールキーを押したままユーザーがマウス第2ボタンを押してマウスをある行から次の行へドラッグすると、以下のような2つのイベントが生成されます:
(C-down-mouse-2 (#<window 18 on NEWS> 3440 (0 . 27) -731219)) (C-drag-mouse-2 (#<window 18 on NEWS> 3440 (0 . 27) -731219) (#<window 18 on NEWS> 3510 (0 . 28) -729648))
メタキーとシフトキーを押したままユーザーがそのウィンドウのモードライン上でマウス第2ボタンを押して他ウィンドウへマウスをドラッグすると、以下のようなイベントのペアが生成されます:
(M-S-down-mouse-2 (#<window 18 on NEWS> mode-line (33 . 31) -457844)) (M-S-drag-mouse-2 (#<window 18 on NEWS> mode-line (33 . 31) -457844) (#<window 20 on carlton-sanskrit.tex> 161 (33 . 3) -453816))
全画面表示されていないフレームに入力フォーカスがあってユーザーがマウスをそのフレームのスコープ外へマウスを移動すると、スペシャルフォームtrack-mouse
内では以下のようなイベントが生成されます:
(mouse-movement (#<frame *ielm* 0x102849a30> nil (563 . 205) 532301936))
SIGUSR1シグナルを処理するためにはインタラクティブ関数を定義して、それをsignal usr1
イベントシーケンスにバインドします:
(defun usr1-handler () (interactive) (message "Got USR1 signal")) (global-set-key [signal usr1] 'usr1-handler)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
すべてのイベントはイベント型(event type)をもっています。イベント型はキーバインディング目的でイベントをクラス分けします。キーボードイベントにたいするイベント型はイベント値と等しく、したがって文字のイベント型は文字、ファンクションキーシンボルのイベント型はそのシンボル自身になります。リストであるようなイベントのイベント型は、そのリストのCAR内のシンボルです。したがってイベント型は常にシンボルか文字です。
同じ型の2つのイベントはキーバインディングに関する限りは同じものです。したがってそれらは常に同じコマンドを実行します。これらが同じことを行う必要があるという意味ではありませんが、イベント全体を調べてから何を行うか決定するコマンドもいくつかあります。たとえばバッファー内でどこに作用するか決定するためにマウスイベントの場所を使用するコマンドもいくつかあります。
広範なイベントのクラス分けが役に立つときもあります。たとえば他の修飾キーやマウスボタンが使用されたかとは無関係に、METAキーとともに呼び出されたイベントを尋ねたいと思うかもしれません。
関数event-modifiers
やevent-basic-type
は、そのような情報を手軽に取得するために提供されています。
この関数はeventがもつ修飾子のリストをリターンする。この修飾子はシンボルでありshift
、control
、meta
、alt
、hyper
、super
が含まれる。さらにマウスイベントシンボルの修飾子リストには常にclick
、drag
、down
のいずれか1つが含まれる。ダブルイベントとトリプルイベントには、double
やtriple
も含まれる。
引数eventはイベントオブジェクト全体、または単なるイベント型かもしれない。eventがカレントEmacsセッション内で入力として読み取られたイベント内で決して使用されないシンボルなら、実際にeventが変更されたときでもevent-modifiers
はnil
をリターンできる。
いくつか例を挙げる:
(event-modifiers ?a) ⇒ nil (event-modifiers ?A) ⇒ (shift) (event-modifiers ?\C-a) ⇒ (control) (event-modifiers ?\C-%) ⇒ (control) (event-modifiers ?\C-\S-a) ⇒ (control shift) (event-modifiers 'f5) ⇒ nil (event-modifiers 's-f5) ⇒ (super) (event-modifiers 'M-S-f5) ⇒ (meta shift) (event-modifiers 'mouse-1) ⇒ (click) (event-modifiers 'down-mouse-1) ⇒ (down)
クリックイベントにたいする修飾リストは明示的にclick
を含むが、イベントシンボル名自身に‘click’は含まれない。
この関数はeventを記述するキー、またはマウスボタンをリターンする。event引数はevent-modifiers
の場合と同様。たとえば:
(event-basic-type ?a) ⇒ 97 (event-basic-type ?A) ⇒ 97 (event-basic-type ?\C-a) ⇒ 97 (event-basic-type ?\C-\S-a) ⇒ 97 (event-basic-type 'f5) ⇒ f5 (event-basic-type 's-f5) ⇒ f5 (event-basic-type 'M-S-f5) ⇒ f5 (event-basic-type 'down-mouse-1) ⇒ mouse-1
objectがマウス移動イベントなら、この関数は非nil
をリターンする。モーションイベントを参照のこと。
この関数は修飾子名リストと基本イベント型(basic event type)を、それらすべてを指定するイベント型に変換する。基本イベント型はそのリストの最後の要素でなければならない。たとえば、
(event-convert-list '(control ?a)) ⇒ 1 (event-convert-list '(control meta ?a)) ⇒ -134217727 (event-convert-list '(control super f1)) ⇒ C-s-f1
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではマウスボタンやモーションイベント内のデータアクセスに役立つ関数を説明します。同じ関数を使用してキーボードイベントデータにもアクセスできますが、キーボードイベントに不適切なデータ要素は0かnil
になります。
以下の2つの関数は、マウスイベントの位置を指定するマウス位置リスト(クリックイベントを参照)をリターンします。
これはeventの開始位置をリターンする。
eventがクリックイベントかボタンダウンイベントなら、この関数はそのイベントの位置をリターンする。eventがドラッグイベントなら、そのドラッグの開始位置をリターンする。
これはeventの終了位置をリターンする。
eventがドラッグイベントなら、この関数はユーザーがマウスボタンをリリースした位置をリターンする。eventがクリックイベントかボタンダウンイベントなら、値はそのイベント固有の開始位置となる。
この関数はobjectがクリックイベントに記述されたいずれかのフォーマットのマウス位置リストなら非nil
、それ以外ではnil
をリターンする。
以下の関数は引数にマウス位置リストを受け取り、そのリストのさまざまな部分をリターンします:
positionがあったウィンドウをリターンする。positionが最初にイベントがあったフレームの外部の位置を表す場合には、かわりにそのフレームをリターンする。
position内に記録されたウィンドウエリアをリターンする。そのウィンドウのテキストエリアでイベントが発生したときはnil
、それ以外ではイベントがどこで発生したかを識別するシンボルをリターンする。
position内のバッファー位置をリターンする。ウィンドウのテキストエリア、マージンエリア、フリンジでイベントが発生したときはバッファー位置を識別する整数値、それ以外では値は未定義。
position内のピクセル単位のxy座標をコンスセル(x
. y)
でリターンする。これらはposn-window
により与えられるウィンドウにたいする相対座標である。
以下はあるウィンドウのテキストエリア内のウィンドウ相対座標をフレーム相対座標に変換する方法を示す例:
(defun frame-relative-coordinates (position) "POSITIONのフレーム相対座標をリターンする。 POSITIONはウィンドウのテキストエリアにあるものとする。" (let* ((x-y (posn-x-y position)) (window (posn-window position)) (edges (window-inside-pixel-edges window))) (cons (+ (car x-y) (car edges)) (+ (cdr x-y) (cadr edges)))))
この関数はposition内のバッファー位置にたいして推定される列と行を含んだコンスセル(col
.
row)
をリターンする。リターン値はpositionにたいするxとyの値より計算され、そのフレームのデフォルト文字幅とデフォルト行高(行間スペースを含む)の単位で与えられる(そのため実際の文字サイズが非デフォルト値なら、実際の行と列はこれらの計算された値とは異なるかもしれない)。
rowはそのテキストエリアの上端から数えられることに注意。positionにより与えられるウィンドウがヘッダーライン(ウィンドウのヘッダーラインを参照)をもつなら、そのヘッダーラインはrowの数に含まれない。
position内の実際の行と列をコンスセル(col
. row)
でリターンする。値はpositionで与えられるウィンドウの実際の行と列。クリックイベントを参照のこと。positionが実際のポジション値を含まなければ、この関数はnil
をリターンする。この場合にはおおよその値を取得するためにposn-col-row
を使用できる。
この関数はタブ文字やイメージによるビジュアル列数のように、ディスプレイ上の文字のビジュアル幅を意味しない。標準的な文字単位の座標が必要なら、かわりにposn-col-row
を使用すること。
position内の文字列オブジェクトをnil
、またはコンスセル(string
. string-pos)
でリターンする。
position内のイメージオブジェクトをnil
、または(image ...)
でリターンする。
position内のイメージオブジェクト、または文字列オブジェクトをnil
、イメージ(image
...)
、またはコンスセル(string . string-pos)
でリターンする。
position内のオブジェクトの左上隅からのピクセル単位のxy座標をコンスセル(dx
.
dy)
でリターンする。positionがバッファーテキストなら、その位置にもっとも近いバッファーテキストの相対位置をリターンする。
position内のオブジェクトのピクセル幅とピクセル高さをコンスセル(width
. height)
でリターンする。positionがバッファー位置なら、その位置の文字のサイズをリターンする。
position内のタイムスタンプをリターンする。これはミリ秒で表されたイベント発生時刻である。
以下の関数は与えられた特定のバッファー、またはスクリーン位置によって位置リストを計算します。上述の関数でこの位置リスト内のデータにアクセスできます。
この関数はwindow内の位置posにたいする位置リストをリターンする。posのデフォルトはwindow内のポイント、windowのデフォルトは選択されたウィンドウ。
window内でposが不可視なら、posn-at-point
はnil
をリターンする。
この関数は指定されたフレームかウィンドウframe-or-window(デフォルトは選択されたウィンドウ)内のピクセル座標xとyに対応する位置情報をリターンする。xとyは、使用されたフレームかウィンドウにたいする相対座標である。wholeがnil
なら、座標はウィンドウのテキストエリアにたいする相対座標、それ以外ではスクロールバー、マージン、フリンジを含むウィンドウエリア全体にたいする相対座標。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はスクロールバーイベントの解析に役立ちます。
この関数はスクロールバーで発生したスクロールバーイベントの位置の垂直位置の割り合いをリターンする。値は位置の割り合いを表す2つの整数を含むコンスセル(portion
. whole)
。
この関数は、(実質的には)ratioにtotalを乗じて、結果を整数に丸める。引数ratioは数字ではなく、scroll-bar-event-ratio
によってリターンされる典型的な値ペア(num
. denom)
である。
この関数はスクロールバー位置をバッファー位置にスケーリングするのに有用。以下のように行う:
(+ (point-min) (scroll-bar-scale (posn-x-y (event-start event)) (- (point-max) (point-min))))
スクロールバーイベントは、xy座標ペアのかわりに割り合いを構成する2つの整数をもつことを思い出してほしい。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
文字列が使用される場所のほとんどにおいて、わたしたちはテキスト文字を含むもの、つまりバッファーやファイル内で見出すのと同種のものとして文字列を概念化します。Lispプログラムはときおりキーボード文字、たとえばキーシーケンスやキーボードマクロ定義かもしれないキーボード文字を概念的に含んだ文字列を使用します。しかし文字列内へのキーボード文字の格納は、歴史的な互換性の理由から複雑な問題であり、常に可能なわけではありません。
新たに記述するプログラムでは文字列内にキーボードイベントを格納しないことによって、これらの複雑さを扱うことを避けるよう推奨します。以下はこれを行う方法です:
lookup-key
とdefine-key
の引数として使用するのでなければ、キーシーケンスにたいして文字列のかわりにベクターを使用する。たとえばread-key-sequence
のかわりにread-key-sequence-vector
、this-command-keys
のかわりにthis-command-keys-vector
を使用できる。
define-key
に渡す場合でもベクターを使用する。
listify-key-sequence
(その他のイベント入力の機能を参照)を使用する。
複雑さはキーボード入力に含まれるかもしれない修飾ビットに起因します。メタ修飾以外の修飾ビットは文字列に含めることができず、メタ文字も特別な場合だけ許容されます。
GNU
Emacsの初期のバージョンでは、メタ文字を128から255のコードで表していました。その頃は基本的な文字コードの範囲は0から127だったので、すべてのキーボード文字を文字列内に適合させることができました。Lispプログラムの多くは、特にdefine-key
やその種の関数の引数として文字列定数内にメタ文字を意味する‘\M-’を使用していて、キーシーケンスとイベントシーケンスは常に文字列として表現されていました。
127超のより大きい基本文字コードと追加の修飾ビットにたいするサポートを加えたとき、わたしたちはメタ文字の表現を変更する必要がありました。現在では文字のメタ修飾を表すフラグは 2**27 であり、そのような値は文字列内に含めることができません。
プログラムで文字列定数内の‘\M-’をサポートするために、文字列内に特定のメタ文字を含めるための特別なルールがあります。以下は入力文字シーケンスとして文字列を解釈するためのルールです:
キーボード入力文字の文字列定数を構築するread-key-sequence
のような関数は、イベントが文字列内に適合しないときは文字列のかわりにベクターを構築するというルールにしたがいます。
文字列内で入力構文‘\M-’を使用すると、それは128から255の範囲のコード、つまり対応するキーボードイベントを文字列内に配すために変更するとき取得されるのと同じコードが生成されます。したがって文字列内のメタイベントは、それが文字列内にどのように配置されたかと無関係に一貫して機能します。
しかしほとんどのプログラムはこのセクションの冒頭の推奨にしたがって、これらの問題を避けたほうがよいでしょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
エディターコマンドループはキーシーケンスの読み取りに関数read-key-sequence
を使用して、この関数はread-event
を使用します。イベント入力にたいしてこれらの関数、およびその他の関数がLisp関数から利用できます。一時的な表示のmomentary-string-display
、および時間の経過や入力の待機のsit-for
も参照してください。端末の入力モードの制御、および端末入力のデバッグに関する関数と変数については、端末の入力を参照してください。
高レベル入力機能についてはミニバッファーを参照してください。
20.8.1 キーシーケンス入力 | キーシーケンスを読み取る方法。 | |
20.8.2 単一イベントの読み取り | イベントを1つだけ読み取る方法。 | |
20.8.3 入力イベントの変更と変換 | Emacsが読み取られたイベントを変更する方法。 | |
20.8.4 入力メソッドの呼び出し | 入力メソッドを使用するイベントを読み取る方法。 | |
20.8.5 クォートされた文字の入力 | 文字の指定をユーザーに問い合わせる。 | |
20.8.6 その他のイベント入力の機能 | 入力イベントの最読み取りや破棄の方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コマンドループはread-key-sequence
を呼び出すことによって、キーシーケンスの入力を一度に読み取ります。Lisp関数もこの関数を呼び出すことができます。たとえばdescribe-key
はキーを記述するためにこの関数を使用します。
この関数はキーシーケンスを読み取って、それを文字列かベクターでリターンする。この関数は完全なキーシーケンスに蓄積されるまで、つまりカレントでアクティブなキーマップを使用してプレフィクスなしでコマンドを指定するのに十分なキーシーケンスとなるまでイベントの読み取りを継続する(マウスイベントで始まるキーシーケンスは、カレントバッファーではなくマウスのあったウィンドウ内のバッファーのキーマップを使用して読み取られることを思い出してほしい)。
イベントがすべて文字で、それらがすべて文字列に適合すれば、read-key-sequence
は文字列をリターンする(文字列内へのキーボードイベントの配置を参照)。それ以外なら文字、シンボル、リストなどすべての種類のイベントを保持できるベクターをリターンする。文字列やベクターの要素は、キーシーケンス内のイベント。
キーシーケンスの読み取りには、そのイベントを変換するさまざまな方法が含まれる。イベントシーケンス変換のためのキーマップを参照のこと。
引数promptはプロンプトとしてエコーエリアに表示される文字列、プロンプトを表示しない場合はnil
。引数continue-echoが非nil
なら、それは前のキーの継続としてそのキーをエコーすることを意味する。
元となる大文字のイベントが未定義で、それと等価な小文字イベントが定義されていれば、通常は大文字のイベントが小文字のイベントに変換される。引数dont-downcase-lastが非nil
なら、それは最後のイベントを小文字に変換しないことを意味する。これはキーシーケンスを定義するときに適している。
引数switch-frame-okが非nil
なら、たとえ何かをタイプする前にユーザーがフレームを切り替えたとしても、この関数がswitch-frame
を処理すべきではないことを意味する。キーシーケンスの途中でユーザーがフレームを切り替えた場合、またはシーケンスの最初だがswitch-frame-okがnil
のときにフレームを切り替えた場合、そのイベントはカレントキーシーケンスの後に延期される。
引数command-loopが非nil
なら、そのキーシーケンスがコマンドを逐次読み取る何かによって読み取られることを意味する。呼び出し側が1つのキーシーケンスだけを読み取る場合には、nil
を指定すること。
以下の例ではEmacsはエコーエリアにプロンプト‘?’を表示して、その後ユーザーがC-x C-fをタイプする。
(read-key-sequence "?")
---------- Echo Area ---------- ?C-x C-f ---------- Echo Area ---------- ⇒ "^X^F"
関数read-key-sequence
はquitを抑制する。この関数による読み取りの間にタイプされたC-gは他の文字と同じように機能し、quit-flag
をセットしない。quitを参照のこと。
これはread-key-sequence
と同様だが、キーシーケンスを常にベクターでリターンして、文字列では決してリターンしない点が異なる。文字列内へのキーボードイベントの配置を参照のこと。
入力文字が大文字(またはシフト修飾をもつ)で、キーバインディングをもたないものの、等価な小文字はキーバインディングをもつ場合、read-key-sequence
はその文字を小文字に変換します。lookup-key
はこの方法によるcase変換を行わないことに注意してください。
入力を読み取った結果がシフト変換(shift-translation)されていたら、Emacsは変数this-command-keys-shift-translated
に非nil
値をセットします。シフト変換されたキーにより呼びだされたときに挙動を変更する必要があるLispプログラムは、この変数を調べることができます。たとえば関数handle-shift-selection
はリージョンをアクティブ、または非アクティブにするかを判断するためにこの変数の値を調べます(handle-shift-selectionを参照)。
関数read-key-sequence
もマウスイベントのいくつかを変換します。これはバインドされていないドラッグイベントをクリックイベントに変換して、バインドされていないボタンダウンイベントを完全に破棄します。さらにフォーカスイベントとさまざまなウィンドウイベントの再配置も行うため、これらのイベントはキーシーケンス中に他のイベントととも出現することは決してありません。
モードラインやスクロールバーのようなウィンドウの特別な箇所でマウスイベントが発生したとき、そのイベント型は特別なことは何も示さずにマウスボタンと修飾キーの組み合わせを通常表すのと同じシンボルになります。ウィンドウの箇所についての情報はイベント内の別のどこか、すなわち座標に保持されています。しかしread-key-sequence
はこの情報を仮想的なプレフィクスキーに変換します。これらはすべてシンボルでありheader-line
、horizontal-scroll-bar
、menu-bar
、mode-line
、vertical-line
、vertical-scroll-bar
です。これらの仮想的なプレフィクスキーを使用してキーシーケンスを定義することにより、ウィンドウの特別な部分でのカウスクリックにたいして意味を定義できます。
たとえばread-key-sequence
を呼び出した後にそのウィンドウのモードラインをマウスでクリックすると、以下のように2つのマウスイベントが取得されます:
(read-key-sequence "Click on the mode line: ") ⇒ [mode-line (mouse-1 (#<window 6 on NEWS> mode-line (40 . 63) 5959987))]
この変数の値は、そのEmacsセッション内で処理されたキーシーケンスの数である。これには端末からのキーシーケンスと、実行されるキーボードマクロによって読み取られたキーシーケンスが含まれる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
read-event
、read-char
、read-char-exclusive
はコマンド入力にたいするもっとも低レベルの関数です。
この関数はコマンド入力の次のイベントを読み取ってリターンする。必要ならイベントが利用可能になるまで待機する。
リターンされるイベントはユーザーからの直接のイベントかもしれないし、キーボードマクロからのイベントかもしれない。イベントはキーボードの入力コーディングシステム(端末I/Oのエンコーディングを参照)によりデコードされていない。
オプション引数promptが非nil
なら、それはエコーエリアにプロンプトとして表示される文字列である。nil
ならread-event
は入力待ちを示すメッセージを何も表示せず、エコーを行うことによってプロンプトの代用とする。エコーに表示される記述はカレントコマンドに至ったイベントや読み取られたイベント。エコーエリアを参照のこと。
inherit-input-methodが非nil
なら、(もしあれば)非ASCII文字の入力を可能にするためにカレントの入力メソッドが採用される。それ以外では、このイベントの読み取りにたいして入力メソッドの処理が無効になる。
cursor-in-echo-area
が非nil
の場合、read-event
はカーソルを一時的にエコーエリアの、そこに表示されているメッセージの終端に移動する。それ以外では、read-event
はカーソルを移動しない。
secondsが非nil
なら、それは入力を待つ最大秒数を指定する数値である。その時間内に入力が何も到着しなければ、read-event
は待機を終えてnil
をリターンする。浮動小数点数secondsは待機する秒の分数を意味する。いくつかのシステムではサポートされるのは整数の秒数だけであり、そのようなシステムではsecondsは切り捨てられる。secondsがnil
なら、read-event
は入力が到着するのに必要なだけ待機する。
secondsがnil
ならユーザー入力が到着するのを待つ間、Emacsはアイドル状態にあるとみなされる。この期間中にアイドルタイマー
— run-with-idle-timer
(アイドルタイマーを参照) —
を実行できる。しかしsecondsが非nil
なら、非アイドル状態は変更されずに残る。read-event
が呼び出されたときEmacsが非アイドルだったら、read-event
の処理を通じて非アイドルのままとなる。Emacsがアイドルだった場合(これはアイドルタイマー内部からその呼び出しが行われた場合に起こり得る)は、アイドルのままとまる。
read-event
がヘルプ文字として定義されたイベントを取得すると、ある状況においてはread-event
がリターンせずに直接イベントを処理することがある。ヘルプ関数を参照のこと。その他のスペシャルイベント(special events)(スペシャルイベントを参照)と呼ばれる特定のイベントもread-event
で直接処理される。
以下はread-event
を呼び出してから右矢印キーを押下したとき何が起こるかの例:
(read-event) ⇒ right
この関数はコマンド入力の文字を読み取ってそれをリターンする。ユーザーが文字以外(たとえばマウスクリックやファンクションキー)のイベントを生成すると、read-char
はエラーをシグナルする。引数はread-event
と同じように機能する。
1つ目の例ではユーザーは文字1(ASCIIコード49)をタイプしている。2つ目の例ではeval-expression
を使用してミニバッファーからread-char
を呼び出すキーボード定義を示している。read-char
はキーボードマクロの直後の文字1を読み取る。その後でeval-expression
はリターン値をエコーエリアに表示する。
(read-char) ⇒ 49
;; M-:を使用して以下を評価するものとする
(symbol-function 'foo)
⇒ "^[:(read-char)^M1"
(execute-kbd-macro 'foo) -| 49 ⇒ nil
この関数はコマンド入力の文字を読み取ってそれをリターンする。ユーザーが文字以外のイベントを生成すると、read-char-exclusive
はそれを無視して文字を取得するまで他のイベントを読み取る。引数はread-event
と同じように機能する。
上記の関数でquitを抑制するものはありません。
この変数は端末から受信した入力イベント(キーボードマクロにより生成されたイベントは勘定しない)の総数を保持する。
read-key-sequence
と異なり関数read-event
、read-char
、read-char-exclusive
はイベントシーケンス変換のためのキーマップで説明した変換を行わないことを強調しておきます。単一キー読み取りでこれらの変換を行いたければ関数read-key
を使用してください。
この関数は1つのキーを読み取る。これはread-key-sequence
とread-event
の間の中間的な関数である。read-key-sequence
と異なるのは、キーシーケンスではなく単一キーを読み取ることである。read-event
と異なるのは、rawイベントをリターンせずにinput-decode-map
、local-function-key-map
、key-translation-map
(イベントシーケンス変換のためのキーマップを参照)に合わせてデコードと変換を行うことである。
引数promptはプロンプトとしてエコーエリアに表示する文字列で、nil
はプロンプトを表示しないことを意味する。
この関数は1つの文字を読み取ってリターンするためにread-key
を使用する。これはchars(許容される文字のリスト)のメンバー以外の入力を無視する。オプションで有効な入力を待つ間のquitイベントも無視する。read-char-choice
呼び出しの間にhelp-form
(ヘルプ関数を参照)を非nil
値にバインドすると、help-char
の押下によりhelp-form
が評価され結果が表示される。その後で有効な入力文字、またはキーボードquitの待機を継続する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはextra-keyboard-modifiers
に合わせて読み取ったすべてのイベントを変更してread-event
からリターンする前に、(もし適切なら)keyboard-translate-table
を通じてそれを変換します。
この変数はLispプログラムにキーボード上の修飾キーを“押下”させる。値は文字。文字の修飾子だけが対象となる。ユーザーがキーボードのキーを押下するたびに、その修飾キーがすでに押下されたかのように処理される。たとえばextra-keyboard-modifiers
を?\C-\M-a
にバインドすると、このバインディングのスコープ内にある間、すべてのキーボード入力文字はコントロール修飾とメタ修飾を適用されるだろう。文字?\C-@
は0と等価なので、この目的にたいしてはコントロール文字として勘定されないが、修飾無しの文字として扱われる。したがってextra-keyboard-modifiers
を0にセットすることによって、すべての修飾をキャンセルできる。
ウィンドウシステムを利用していれば、この方法によってプログラムが任意の修飾キーを押下できる。それ以外ではCTLとMETAのキーだけを仮想的に押下できる。
この変数は実際にキーボードに由来するイベントだけに適用され、マウスイベントやその他のイベントには効果がないことに注意。
この端末ローカルな変数はキーボード文字にたいする変換テーブルである。これによりコマンドバインディングを変更することなく、キーボード上のキーを再配置できる。値は通常は文字テーブル、またはnil
(文字列かベクターも指定できるが時代遅れとされている)。
keyboard-translate-table
が文字テーブル(文字テーブルを参照)なら、キーボードから読み取られた各文字はその文字テーブルを調べる。非nil
の値が見つかったら実際の入力文字のかわりにそれを使用する。
この変換は文字が端末から読み取られた後、最初に発生することに注意。recent-keys
のような記録保持機能や文字を記録するdribbleファイルは、この変換の後に処理される。
さらにこの変換は入力メソッド(入力メソッドを参照)に文字を提供する前に行われることにも注意。入力メソッド処理の後に文字を変換したいならtranslation-table-for-input
(文字の変換を参照)を使用すること。
この関数は文字コードfromを文字コードtoに変換するためにkeyboard-translate-table
を変更する。
必要ならキーボード変換テーブルを作成する。
以下はC-xでカット、C-でコピー、C-vでペーストを処理するようにkeyboard-translate-table
を使用する例:
(keyboard-translate ?\C-x 'control-x) (keyboard-translate ?\C-c 'control-c) (keyboard-translate ?\C-v 'control-v) (global-set-key [control-x] 'kill-region) (global-set-key [control-c] 'kill-ring-save) (global-set-key [control-v] 'yank)
拡張ASCII入力をサポートするグラフィカルな端末上では、シフトキーとともにタイプすることによって、標準的なEmacsにおける意味をこれらの文字から依然として取得することが可能です。これはキーボード変換が関与する文字とは異なりますが、それらは通常と同じ意味をもちます。
read-key-sequence
のレベルでイベントシーケンスを変換するメカニズムについては、イベントシーケンス変換のためのキーマップを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
イベント読み取り関数は、もしあればカレント入力メソッドを呼び出します(入力メソッドを参照)。input-method-function
の値が非nil
なら関数を指定します。read-event
が修飾ビットのないプリント文字(SPCを含む)を読み取ったときは、その文字を引数としてその関数を呼び出します。
これが非nil
なら、その値はカレントの入力メソッド関数を指定する。
警告:
この変数をlet
でバインドしてはならない。この変数はバッファーローカルであることが多く、入力の前後(これは正にあなたがバインドするであろうタイミングである)でバインドすると、Emacsが待機中に非同期にバッファーを切り替えた場合に、誤ったバッファーに値がリストアされてしまう。
入力メソッド関数は入力として使用されるイベントのリストをリターンするべきです(このリストがnil
なら、それは入力がないことを意味するのでread-event
は他のイベントを待機する)。これらのイベントはunread-command-events
(その他のイベント入力の機能を参照)内のイベントの前に処理されます。入力メソッドによってリターンされるイベントは、たとえそれらが修飾ビットのないプリント文字であっても再度入力メソッドに渡されることはありません。
入力メソッド関数がread-event
やread-key-sequence
を呼び出したら、再帰を防ぐために最初にinput-method-function
をnil
にバインドするべきです。
キーシーケンスの2つ目および後続のイベントを読み取るときは、入力メソッド関数は呼び出されません。したがってそれらの文字は入力メソッドの処理対象外です。入力メソッド関数はoverriding-local-map
とoverriding-terminal-local-map
の値をテストするべきです。これらの変数のいずれかが非nil
なら入力メソッドは引数をリストにputして、それ以上の処理を行わずにそのリストをリターンするべきです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ユーザーが手軽にコントロール文字やメタ文字、リテラルや8進文字コードを指定できるように文字の指定をもとめることができます。コマンドquoted-insert
はこの関数を使用しています。
この関数はread-char
と同様だが、最初に読み取った文字が8進数(0–7)なら任意の個数の8進数(8進数以外の文字を見つけた時点でストップする)を読み取って、その文字コードにより表される文字をリターンする。8進シーケンスを終端させた文字がRETならそれは無視される。他の終端文字はこの関数がリターンした後の入力として使用される。
最初の文字の読み取り時にはquitは抑制されるので、ユーザーははC-gを入力できる。quitを参照のこと。
promptが与えられたら、それはユーザーへのプロンプトに使用する文字列を指定する。プロンプト文字列はその後に1つの‘-’とともに常にエコーエリアに表示される。
以下の例ではユーザーは8進数の177(10進数の127)をタイプしている。
(read-quoted-char "What character")
---------- Echo Area ---------- What character 1 7 7- ---------- Echo Area ---------- ⇒ 127
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではイベントを使い切らずに先読みする方法と、入力の保留や保留の破棄の方法について説明します。パスワードの読み取りの関数read-passwd
も参照してください。
この変数はコマンド入力として読み取り待機中のイベントのリストを保持する。イベントはこのリスト内の出現順に使用され、使用されるごとにリストから取り除かれる。
ある関数がイベントを読み取ってそれを使用するかどうか決定する場合がいくつかあるためにこの変数が必要になる。この変数にイベントを格納するとコマンドループやコマンド入力を読み取る関数によってイベントは通常のように処理される。
たとえば数引数を実装する関数は、任意の個数の数字を読み取る。数字イベントが見つからないとき、関数はそのイベントを読み戻す(unread)ので、そのイベントはコマンドループによって通常通り読み取られることができる。同様にインクリメンタル検索は、検索において特別な意味をもたないイベントを読み戻すためにこの機能を使用する。なぜならそれらのイベントは検索をexitして、通常どおり実行されるべきだからである。
unread-command-events
にイベントを置くためにキーシーケンスからイベントを抽出するには、listify-key-sequence
(以下参照)を使用するのが簡単で信頼のおける方法である。
もっとも最近読み戻したイベントが最初に再読み取りされるように、通常はこのリストの先頭にイベントを追加する。
このリストから読み取ったイベントは、通常はそのイベントが最初に読み取られたときにすでに一度追加されたときのように、カレントコマンドのキーシーケンスに(たとえばthis-command-keys
にリターンされたときのように)追加される。フォーム(t . event)
の要素はカレントコマンドのキーシーケンスにeventを強制的に追加する。
この関数は文字列かベクターのkeyをunread-command-events
にputすることができる個別のイベントのリストに変換する。
この関数はコマンド入力がカレントで読み取り可能かどうか判断する。入力が利用可能ならt
、それ以外はnil
を即座にリターンする。非常に稀だが入力が利用できないときはt
をリターンする。
オプション引数check-timersが非nil
なら、Emacsは準備ができるとすべてのタイマーを実行する。遅延実行のためのタイマーを参照のこと。
この変数は最後に読み取られた端末入力イベントがコマンドの一部なのか、それともLispプログラムによる明示的なものなのかを記録する。
以下の例では文字1(ASCIIコード49)をLispプログラムが読み取っている。C-e (C-x
C-eは式を評価するコマンドとする)がlast-command-event
に値として残っている間は、それがlast-input-event
の値となる。
(progn (print (read-char)) (print last-command-event) last-input-event) -| 49 -| 5 ⇒ 49
この構文はbodyフォームを実行して、入力が何も到着しない場合だけ最後のフォームの値をリターンする。bodyフォームを実行する間に何らかの入力が到着したら、それらの入力をabortする(quitのように機能する)。while-no-input
フォームは実際のquitによりabortしたらnil
、入力の到着によってabortしたらt
をリターンする。
bodyの一部でinhibit-quit
を非nil
にバインドすると、その部分の間に到着した入力はその部分が終わるまでabortしない。
両方のabort条件をbodyにより計算された可能なすべての値で区別できるようにしたければ、以下のようにコードを記述する:
(while-no-input (list (progn . body)))
この関数は端末入力バッファーの内容を破棄して定義処理中かもしれないキーボードマクロをキャンセルする。この関数はnil
をリターンする。
以下の例ではフォームの評価開始直後にユーザーが数字か文字をタイプするかもしれない。sleep-for
がスリープを終えた後にdiscard-input
はスリープ中にタイプされた文字を破棄する。
(progn (sleep-for 2) (discard-input)) ⇒ nil
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
特定のスペシャルイベント(special
event)は、読み取られると即座に非常に低レベルで処理されます。read-event
関数はそれらのイベントを自身で処理してそれらを決してリターンしません。かわりにスペシャルイベント以外の最初のイベントを待ってそれをリターンします。
スペシャルイベントはエコーされず、決してキーシーケンスにグループ化されず、last-command-event
や(this-command-keys)
の値として出現することもありません。スペシャルイベントは数引数を破棄して、unread-command-events
による読み戻しができず、キーボードマクロ内に出現することもなく、キーボードマクロ定義中にキーボードマクロに記録されることもありません。
しかしスペシャルイベントは読み取られた直後にlast-input-event
内に出現するので、これがイベント定義にたいして実際のイベントを探す方法になります。
イベント型iconify-frame
、make-frame-visible
、delete-frame
、drag-n-drop
、language-change
、およびsigusr1
ようなユーザーシグナルは通常はこの方法によって処理されます。何がスペシャルイベントで、スペシャルイベントをどのように処理するかを定義するキーマップは変数special-event-map
(アクティブなキーマップを参照)の中にあります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
待機関数(wait
function)は特定の時間が経過するか、入力があるまで待機するようにデザインされています。たとえば計算の途中でユーザーがディスプレイを閲覧できるように一時停止したいときがあるかもしれません。sit-for
は一時停止して画面を更新して、sleep-for
は画面を更新せずに一時停止して入力が到着したら即座にリターンします。
この関数は、(ユーザーからの保留中入力がければ)再描画を行ってからseconds秒、または入力が利用可能になるまで待機する。sit-for
の通常の目的は、表示したテキストをユーザーが読み取る時間を与えるためである。入力が何も到着せず(その他のイベント入力の機能を参照)、時間をフルに待機したらt
、それ以外はnil
が値となる。
引数secondsは整数である必要はない。浮動小数点数ならsit-for
は少数点数の秒を待機する。整数の秒だけをサポートするいくつかのシステムではsecondsは切り捨てられる。
保留中の入力が存在しなければ、式(sit-for
0)
は遅延なしで再描画をリクエストする(redisplay)
と等価である。強制的な再表示を参照のこと。
nodispが非nil
ならsit-for
は再描画を行わないが、それでも入力が利用可能になると(またはタイムアウト時間が経過すると)即座にリターンする。
batchモード(batchモードを参照)では、たとえ標準入力ディスクリプタからの入力でも割り込みできない。これは以下で説明するsleep-for
でも同様。
(sit-for seconds millisec
nodisp)
のように3つの引数でsit-for
を呼び出すことも可能だが、時代遅れだと考えられている。
この関数は表示を更新せず単にseconds秒の間一時停止する。これは利用可能な入力に注意を払わない。この関数はnil
をリターンする。
引数secondsは整数である必要はない。浮動小数点数ならsleep-for
は少数点数の秒を待機する。整数の秒だけをサポートするいくつかのシステムではsecondsは切り捨てられる。
オプション引数millisecはミリ秒単位で追加の待機時間を指定する。これはsecondsで指定された時間に追加される。システムが小数点数の秒数をサポートしなければ、非0のmillisecを指定するとエラーとなる。
遅延を保証したければsleep-for
を使用すること。
現在時刻を取得する関数については時刻を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lisp関数を実行中にC-gをタイプすると、Emacsが何を行っていてもEmacsをquit(中止、終了)させます。これはアクティブなコマンドループの最内に制御がリターンすることを意味します。
コマンドループがキーボード入力の待機中にC-gをタイプしてもquitはしません。これは通常の入力文字として機能します。もっともシンプルなケースでは、通常C-gはquitの効果をもつkeyboard-quit
を実行するので区別はできません。しかしプレフィクスキーの後のC-gは、未定義のキー組み合わせになります。これはプレフィクスキーやプレフィクス引数も同様にキャンセルする効果をもちます。
ミニバッファー内ではC-gは異なる定義をもち、それはミニバッファーをabort(失敗、中止、中断)します。これは実際にはミニバッファーをexitしてquitします(単にquitするのはミニバッファー内のコマンドループにリターンするだろう)。C-gがなぜコマンドリーダーが入力読み取り時に直接quitしないかという理由は、ミニバッファー内でのC-gの意味をこの方法によって再定義可能にするためです。プレフィクスキーの後のC-gはミニバッファー内で再定義されておらず、プレフィクスキーおよびプレフィクス引数のキャンセルという通常の効果をもちます。もしC-gが常に直接quitするならこれは不可能でしょう。
C-gが直接quitを行うときは、変数quit-flag
をt
にセットすることによってそれを行います。Emacsは適切なタイミングでこの変数をチェックして、nil
でなじぇればquitします。どのような方法でもquit-flag
を非nil
にセットするとquitが発生します。
Cコードのレベルでは任意の場所でquitを発生させることはできず、quit-flag
をチェックする特別な場所でのみquitが発生します。この理由は他の場所でquitすると、Emacsの内部状態で矛盾が生じるかもしれないからです。安全な場所までquitが遅延されるので、quitがEmacsをクラッシュさせることがなくなります。
read-key-sequence
やread-quoted-char
のような特定の関数は、たとえ入力を待機中でもquitを抑制します。quitするかわりにC-gは要求された入力として処理されます。read-key-sequence
の場合、これはコマンドループ内でのC-gの特別な振る舞いを引き起こすのに役立ちます。read-quoted-char
の場合、これはC-gをクォートするのにC-qを使用できるようにします。
変数inhibit-quit
を非nil
値にバインドすることにより、Lisp関数の一部でquitを抑止できます。その場合はquit-flag
がt
にセットされていても、C-gの通常の結果であるquitは抑止されます。let
フォームの最後でこのバインディングがunwindされるなどして、結果としてinhibit-quit
は再びnil
になります。このときquit-flag
がnil
なら、即座に要求されたquitが発生します。この挙動はプログラム中のクリティカルセクション内でquitが発生しないことを確実にしたいときに理想的です。
(read-quoted-char
のような)いくつかの関数では、quitを起こさない特別な方法でC-gが処理されます。これはinhibit-quit
をt
にバインドして入力を読み取り、再びinhibit-quit
がnil
になる前にquit-flag
をnil
にセットすることにより行われます。以下はこれを行う方法を示すためのread-quoted-char
の抜粋です。この例は入力の最初の文字の後で通常のquitを許す方法も示しています。
(defun read-quoted-char (&optional prompt)
"…documentation…"
(let ((message-log-max nil) done (first t) (code 0) char)
(while (not done)
(let ((inhibit-quit first)
…)
(and prompt (message "%s-" prompt))
(setq char (read-event))
(if inhibit-quit (setq quit-flag nil)))
… 変数code
をセット …)
code))
この変数が非nil
でinhibit-quit
がnil
なら、Emacsは即座にquitする。C-gをタイプすると通常はinhibit-quit
とは無関係にquit-flag
を非nil
にセットする。
この変数はquit-flag
が非nil
にセットされているときEmacsがquitするかどうかを決定する。inhibit-quit
が非nil
ならquit-flag
に特に効果はない。
このマクロはbodyを順番に実行するが、たとえこの構文の外部でinhibit-quit
が非nil
でも、少なくともローカルにbody内でのquitを許容する。このマクロはquitによりexitしたらnil
、それ以外はbody内の最後のフォームの値をリターンする。
inhibit-quit
がnil
ならwith-local-quit
へのエントリーでbodyだけが実行され、quit-flag
をセットすることにより通常のquitが発生する。しかし通常のquitが遅延されるようにinhibit-quit
が非nil
にセットされていれば、非nil
のquit-flag
は特別な種類のローカルquitを引き起こす。これはbodyの実行を終了して、quit-flag
を非nil
のままにしてwith-local-quit
のbodyをexitするので、許され次第(通常の)別のquitが発生する。bodyの先頭ですでにquit-flag
が非nil
なら即座にローカルquitが発生して結局bodyは実行されない。
このマクロは主にタイマー、プロセスフィルター、プロセスセンチネル、pre-command-hook
、post-command-hook
、およびinhibit-quit
が通常のようにt
にバイドされている場所で役に立つ。
この関数は(signal 'quit
nil)
によってquit
条件をシグナルする。これはquitが行うことと同じ(エラーのsignal
を参照)。
quitに使用するC-g以外の文字を指定できます。入力のモード内の関数set-input-mode
を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ほとんどのEmacsコマンドはプレフィクス引数(prefix
argument)を使用できます。プレフィクス引数はコマンド自身の前に数字を指定するものです(プレフィクス引数とプレフィクスキーを混同しないこと)。プレフィクス引数は常に値により表され、nil
のときはカレントでプレフィクス引数が存在しないことを意味します。すべてのコマンドはプレフィクス引数を使用するか、あるいは無視します。
プレフィクス引数には2つの表現があります。それはraw(生の、加工していない、原料のままの、未加工の)と数字(numeric)です。エディターコマンドループは内部的にraw表現を使用し、Lisp変数もその情報を格納するのにこれを使用しますが、コマンドはいずれかの表現を要求できます。
以下は利用できるrawプレフィクス引数の値です:
nil
はプレフィクス引数がないことを意味する。これの数値的な値は1だが多くのコマンドはnil
と整数1を区別する。
-
。これは後に数字をともなわないM--かC-u
-がタイプされたことを示す。数値的に等価な値は-1だが、整数の-1をシンボルの-
を区別するコマンドがいくつかある。
以下の関数をさまざまなプレフィクスで呼び出して、これらの可能なプレフィクスを説明しましょう:
(defun display-prefix (arg) "rawプレフィクス引数の値を表示する" (interactive "P") (message "%s" arg))
以下はさまざまなrawプレフィクス引数でdisplay-prefix
を呼び出した結果です:
M-x display-prefix -| nil C-u M-x display-prefix -| (4) C-u C-u M-x display-prefix -| (16) C-u 3 M-x display-prefix -| 3 M-3 M-x display-prefix -| 3 ; (C-u 3
と同じ) C-u - M-x display-prefix -| - M-- M-x display-prefix -| - ; (C-u -
と同じ) C-u - 7 M-x display-prefix -| -7 M-- 7 M-x display-prefix -| -7 ; (C-u -7
と同じ)
Emacsにはプレフィクス引数を格納するために2つの変数prefix-arg
とcurrent-prefix-arg
があります。他のコマンドにたいしてプレフィクス引数をセットアップするuniversal-argument
のようなコマンドは、プレフィクス引数をprefix-arg
内に格納します。対照的にcurrent-prefix-arg
はカレントコマンドにプレフィクス引数を引き渡すので、これらの変数をセットしても将来のコマンドにたいするプレフィクス引数に効果はありません。
コマンドは通常はinteractive
内で、プレフィクス引数にたいしてrawと数値のどちらの表現を使用するかを指定します(interactive
の使用を参照)。そのかわりに関数は変数current-prefix-arg
内のプレフィクス引数の値を直接調べるかもしれませんが、これは明確さで劣っています。
この関数はargの有効なrawプレフィクス引数の数値的な意味をリターンする。引数はシンボル、数字、またはリストかもしれない。これがnil
なら値1、-
なら-1がリターンされる。これが数字なら、その数字がリターンされる。リスト(数字であること)なら、そのリストのCARがリターンされる。
この変数はカレントのコマンドにたいするrawプレフィクス引数を保持する。コマンドはこの変数を直接調べるかもしれないが、この変数にたいするアクセスには通常は(interactive
"P")
を使用する。
この変数の値は次の編集コマンドにたいするrawプレフィクス引数である。後続のコマンドにたいしてプレフィクス引数を指定するuniversal-argument
のようなコマンドは、この変数をセットすることによって機能する。
このrawプレフィクス引数の値は、前のコマンドにより使用された値である。
以下のコマンドは、後続のコマンドにたいしてプレフィクス引数をセットアップするために存在します。これらを他の用途で呼び出さないでください。
このコマンドは入力を読み取って、後続のコマンドにたいするプレフィクス引数を指定する。何をしているかわかっているのでなければ、このコマンドを自分で呼び出してはならない。
このコマンドは、後続のコマンドにたいしてプレフィクス引数を追加する。引数argはこのコマンドの前のrawプレフィクス引数であり、これはプレフィクス引数を更新するために使用される。何をしているかわかっているのでなければ、このコマンドを自分で呼び出してはならない。
このコマンドは、次のコマンドにたいして数引数を追加する。引数argはこのコマンドの前のrawプレフィクス引数であり、この値に負の符号が付されて新しいプレフィクス引数を構築する。何をしているかわかっているのでなければ、このコマンドを自分で呼び出してはならない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはスタートアップ時に、自動的にEmacsコマンドループに移行します。このトップレベルのコマンドループ呼び出しは決してexitすることなく、Emacs実行中は実行を継続します。Lispプログラムもコマンドループを呼び出せます。これは複数のコマンドループを活性化するので、再帰編集(recursive editing)と呼ばれています。再帰編集レベルは呼び出したコマンドが何であれそれをサスペンドして、そのコマンドを再開する前にユーザーが任意の編集を行うことを可能にする効果をもちます。
再帰編集の間に利用可能なコマンドは、トップレベルの編集ループ内で利用できるコマンドと同じでありキーマップ内で定義されます。数少ない特別なコマンドだけが再帰編集レベルをexitして、他のコマンドは再帰編集レベルが終了したときに再帰編集レベルからリターンします(exitするための特別なコマンドは常に利用できるが再帰編集が行われていないときは何も行わない)。
再帰コマンドループを含むすべてのコマンドループは、コマンドループから実行されたコマンド内のエラーによってそのループをexitしないように、汎用エラーハンドラーをセットアップします。
ミニバッファー入力は特殊な再帰編集です。これはミニバッファーとミニバッファーウィンドウの表示を有効にするなどの欠点をもちますが、それはあなたが思うより少ないでしょう。ミニバッファー内では特定のキーの振る舞いが異なりますが、これははミニバッファーのローカルマップによるものです。ウィンドウを切り替えれば通常のEmacsコマンドを使用できます。
再帰編集レベルを呼び出すには関数recursive-edit
を呼び出します。この関数はコマンドループを含んでいます。さらにexit
をthrowすることにより再帰編集レベルのexitを可能にする、タグexit
をともなったcatch
呼び出しも含んでいます(明示的な非ローカル脱出: catch
とthrow
を参照)。t
以外の値をthrowすると、recursive-edit
は通常はそれを呼び出した関数にリターンします。コマンドC-M-c
(exit-recursive-edit
)がこれを行います。値t
をthrowすることによってrecursive-edit
がquitされるので、1レベル上位のコマンドループに制御がリターンされます。これはabortと呼ばれ、C-](abort-recursive-edit
)がこれを行います。
ほとんどのアプリケーションはミニバッファー使用の一部として使用する場合を除き、再帰編集を使用するべきではありません。カレントバッファーのメジャーモードから特殊なメジャーモードに一時的に変更する場合に、そのモードに戻るコマンドをもつ必要があるときは、通常は再帰編集のほうが便利です(Rmailのeコマンドはこのテクニックを使用)。またはユーザーが新たなバッファーの特殊なモードで、異なるテキストを再帰的に編集・作成・選択できるようにしたい場合が該当します。このモードでは処理を完了させるコマンドを定義して前のバッファーに戻ります(Rmailのmコマンドはこれを使用)。
再帰編集はデバッグに便利です。一種のブレークポイントとして関数定義内にdebug
を挿入して、関数がそこに達したときにその箇所を調べることができます。debug
は再帰編集を呼び出しますが、デバッガのその他の機能も提供します。
query-replace
内でC-rをタイプしたときやC-x q
(kbd-macro-query
)を使用したときにも再帰編集レベルが使用されます。
この関数はエディターコマンドループを呼び出す。これはユーザーに編集を開始させるために、Emacsの初期化により自動的に呼び出される。Lispプログラムから呼び出されたときは再帰編集レベルにエンターする。
カレントバッファーが選択されたウィンドウのバッファーと異なる場合、recursive-edit
はカレントバッファーの保存とリストアを行う。それ以外ではバッファーを切り替えると、recursive-edit
がリターンした後にその切り替えたバッファーがカレントになる。
以下の例では関数simple-rec
が最初にポイントを1単語分進めてからメッセージをエコーエリアにプリントして再帰編集にエンターする。その後ユーザーは望む編集を行い、C-M-cをタイプすれば再帰編集をexitしてsimple-rec
の実行を継続できる。
(defun simple-rec () (forward-word 1) (message "Recursive edit in progress") (recursive-edit) (forward-word 1)) ⇒ simple-rec (simple-rec) ⇒ nil
この関数は最内の再帰編集(ミニバッファー入力を含む)からexitする。関数の実質的な定義は(throw 'exit nil)
。
この関数は再帰編集をexitした後にquit
をシグナルすることにより、最内の再帰編集(ミニバッファー入力を含む)を要求したコマンドをabortする。関数の実質的な定義は(throw
'exit t)
。quitを参照のこと。
この関数はすべての再帰編集レベルをexitする。これはすべての計算を直接抜け出してメインのコマンドループに戻って値をリターンしない。
この関数は再帰編集のカレントの深さをリターンする。アクティブな再帰編集が存在しなければ0をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コマンドを無効化(disabling a command)とは、それを実行可能にする前にユーザーによる確認を要求するようにコマンドをマークすることです。無効化は初めてのユーザーを混乱させるかもしれないコマンドにたいして、意図せずそのコマンドが使用されるのを防ぐために使用されます。
コマンド無効化の低レベルにおけるメカニズムは、そのコマンドにたいするLispシンボルのdisabled
プロパティに非nil
をputすることです。これらのプロパティは、通常はユーザーのinitファイル(initファイルを参照)で以下のようなLisp式によりセットアップされます:
(put 'upcase-region 'disabled t)
いくつかのコマンドにたいしては、これらのプロパティがデフォルトで与えられています(これらを削除したければinitファイルで削除できる)。
disabled
プロパティの値が文字列なら、そのコマンドが無効化されていることを告げるメッセージにその文字列が含まれます。たとえば:
(put 'delete-region 'disabled "この方法で削除されたテキストはyankで戻せない!\n")
無効化されたコマンドをインタラクティブに呼び出したときに何が起こるかの詳細は、Disabling in The GNU Emacs Manualを参照してください。コマンドの無効化は、それをLispプログラムから関数として呼び出したときは効果がありません。
その時点から特別な確認なしでcommand(シンボル)が実行されることを許す。さらにユーザーのinitファイル(initファイルを参照)も修正するので将来のセッションにもこれが適用される。
その時点からcommand(シンボル)の実行に特別な確認を要求する。さらにユーザーのinitファイル(initファイルを参照)も修正するので将来のセッションにもこれが適用される。
この変数の値は関数であること。ユーザーが無効化されたコマンドを呼び出したときは無効化されたコマンドのかわりにその関数が呼び出される。そのコマンドを実行するためにユーザーが何のキーをタイプしたかを判断するためにthis-command-keys
を使用して、そのコマンド自体を探すことができる。
値はnil
もあり得る。その場合にはたとえ無効化されたコマンドでも、すべてのコマンドが通常のように機能する。
デフォルトでは値はユーザーに処理を行うかどうかを尋ねる関数。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コマンドループは複雑なコマンドを手軽に繰り返せるように、すでに実行された複雑なコマンドのヒストリー(history:
履歴)を保持します。複雑なコマンド(complex
command)とは、ミニバッファーを使用してinteractive引数を読み取るコマンドです。これにはM-xコマンド、M-:コマンド、およびinteractive
指定によりミニバッファーから引数を読み取るすべてのコマンドが含まれます。コマンド自身の実行の間に明示的にミニバッファーを使用するものは、複雑なコマンドとは判断されません。
この変数の値は最近実行された複雑なコマンドのリストであり、それぞれが評価されるべきフォームとして表現される。このリストは編集セッションの間、すべての複雑なコマンドを蓄積するが、最大サイズ(ミニバッファーのヒストリーを参照)に達したときは、もっとも古い要素が削除されて新たな要素が追加される。
command-history ⇒ ((switch-to-buffer "chistory.texi") (describe-key "^X^[") (visit-tags-table "~/emacs/src/") (find-tag "repeat-complex-command"))
このヒストリーリストは実際にはミニバッファーヒストリーの特殊ケースであり、それは要素が文字列ではなく式であることです。
以前のコマンドを編集したり再呼び出しするためのコマンドがいくつかあります。コマンドrepeat-complex-command
とlist-command-history
はユーザーマニュアルに説明されています(Repetition in The GNU Emacs Manualを参照)。ミニバッファー内では通常のミニバッファーヒストリーコマンドが利用できます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
キーボードマクロ(keyboard macro)はコマンドとして考えることが可能な入力イベントの記録されたシーケンスであり、キー定義によって作成されます。キーボードマクロのLisp表現はイベントを含む文字列かベクターです。キーボードマクロとLispマクロ(マクロを参照)を混同しないでください。
この関数はイベントシーケンスとしてkbdmacroを実行する。kbdmacroが文字列かベクターなら、たとえそれがユーザーによる入力であっても、その中のイベントは忠実に実行される。シーケンスは単一のキーシーケンスであることを要求されない。キーボードマクロ定義は、通常は複数のキーシーケンスを結合して構成される。
kbdmacroがシンボルなら、そのシンボルの関数定義はkbdmacroの箇所に使用される。それが別のシンボルならこのプロセスを繰り返す。最終的に結果は文字列かベクターになる。結果がシンボル、文字列、ベクターでなければエラーがシグナルされる。
引数countは繰り返すカウントであり、kbdmacroがその回数実行される。countが省略またはnil
なら1回実行される。0ならkbdmacroはエラーに遭遇するか検索が失敗するまで何度も実行される。
loopfuncが非nil
なら、それはマクロの繰り返しごとに呼び出される引数なしの関数である。loopfuncがnil
をリターンするとマクロの実行が停止する。
execute-kbd-macro
の使用例は単一イベントの読み取りを参照のこと。
この変数はカレントで実行中のキーボードマクロを定義する文字列かベクター。nil
ならカレントで実行中のマクロは存在しない。マクロの実行により実行されたときに異なる振る舞いをするように、コマンドはこの変数をテストできる。この変数を自分でセットしてはならない。
この変数はキーボードマクロの定義中のときだけ非nil
である。マクロ定義中の間は異なる振る舞いをするように、コマンドはこの変数をテストできる。既存のマクロ定義に追加する間、値はappend
になる。コマンドstart-kbd-macro
、kmacro-start-macro
、end-kbd-macro
はこの変数をセットする。この変数を自分でセットしてはならない。
この変数は常にカレント端末にたいしてローカルであり、バッファーローカルにできない。複数の端末を参照のこと。
この変数はもっとも最近定義されたキーボードマクロの定義である。値は文字列、ベクター、またはnil
。
この変数は常にカレント端末にたいしてローカルであり、バッファーローカルにできない。複数の端末を参照のこと。
これはキーボードマクロが終了したときに実行されるノーマルフックであり、何がキーボードマクロを終了させたか(マクロの最後に到達したのか、あるいはエラーにより最後到達する前に終了したのか)は問わない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力イベントのコマンドバインディングはキーマップ(keymap)と呼ばれるデータ構造に記録されます。キーマップ内の各エントリーは個別のイベント型(他のキーマップ、またはコマンド)に関連づけ(またはバインド)されます。イベント型がキーマップにバインドされていれば、そのキーマップは次の入力イベントを調べるために使用されます。これはコマンドが見つかるまで継続されます。このプロセス全体をキールックアップ(key lookup: キーの照合)と呼びます。
21.1 キーシーケンス | Lispオブジェクトとしてのキーシーケンス。 | |
21.2 キーマップの基礎 | キーマップの基本概念。 | |
21.3 キーマップのフォーマット | キーマップはLispオブジェクトとしてどのように見えるか。 | |
21.4 キーマップの作成 | キーマップの作成やコピーを行う関数。 | |
21.5 継承とキーマップ | キーマップが他のキーマップのバインディングを継承する方法。 | |
21.6 プレフィクスキー | キーマップの定義としてキーを定義する。 | |
21.7 アクティブなキーマップ | Emacsがアクティブなキーマップでキーバインディングを探す方法。 | |
21.8 アクティブなキーマップの検索 | アクティブなマップ検索のLisp処理概要。 | |
21.9 アクティブなキーマップの制御 | 各バッファーは標準(グローバル)のバインディングをオーバーライドするためのキーマップをもつ。マイナーモードもそれらをオーバーライドできる。 | |
21.10 キーの照合 | 1つのキーマップから、あるキーのバインディングを探す。 | |
21.11 キー照合のための関数 | キールックアップを要求する方法。 | |
21.12 キーバインディングの変更 | キーマップ内でのキーの再定義。 | |
21.13 コマンドのリマップ | キーマップはあるコマンドを他のコマンドに変換できる。 | |
21.14 イベントシーケンス変換のためのキーマップ | イベントシーケンスを変換するキーマップ。 | |
21.15 キーのバインドのためのコマンド | キーの再定義にたいするインタラクティブなインターフェイス。 | |
21.16 キーマップのスキャン | ヘルプをプリントするためにすべてのキーマップを走査する。 | |
21.17 メニューキーアップ | キーマップとしてキーマップを定義する。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
キーシーケンス(key
sequence)、短くはキー(key)とは1つの単位を形成する1つ以上の入力イベントのシーケンスです。入力イベントには文字、ファンクションキー、マウスアクション、またはiconify-frame
のようなEmacs外部のシステムイベントが含まれます(入力イベントを参照)。キーシーケンスにたいするEmacs
Lispの表現は文字列かベクターです。特に明記しない限り、引数としてキーシーケンスを受け取るEmacs
Lisp関数は両方の表現を処理することができます。
文字列表現ではたとえば"a"
はa、"2"
は2を表すといったように、英数字はその文字自身を意味します。コントロール文字イベントは部分文字列"\C-"
、メタ文字は"\M-"
によりプレフィクスされます。たとえば"\C-x"
はキーC-xを表します。それらに加えてTAB、RET、ESC、DELなどのイベントはそれぞれ"\t"
、"\r"
、"\e"
、"\d"
で表されます。複雑なキーシーケンスの文字列表現はイベント成分の文字列表現を結合したものです。したがって"\C-xl"
はキーシーケンスC-x
lを表します。
キーシーケンスにはファンクションキー、マウスボタンイベント、システムイベント、またはC-=やH-aのような文字列で表現できない非ASCII文字が含まれます。これらはベクターとして表現する必要があります。
ベクター表現ではベクターの各要素は1つの入力イベントをイベントのLisp形式で表します。入力イベントを参照してください。たとえばベクター[?\C-x ?l]
はキーシーケンスC-x lを表します。
キーシーケンスを文字列やベクターによる表現で記述する例は、Init Rebinding in The GNU Emacs Manualを参照してください。
この関数はテキストkeyseq-text(文字列定数)をキーシーケンス(文字列かベクターの定数)に変換する。keyseq-textの内容はC-x
C-k RET
(kmacro-edit-macro
)コマンドにより呼び出されたバッファー内と同じ構文を使用するべきである。特にファンクションキーの名前は‘<…>’で囲まなければならない。Edit
Keyboard Macro in The GNU Emacs Manualを参照のこと。
(kbd "C-x") ⇒ "\C-x" (kbd "C-x C-f") ⇒ "\C-x\C-f" (kbd "C-x 4 C-f") ⇒ "\C-x4\C-f" (kbd "X") ⇒ "X" (kbd "RET") ⇒ "\^M" (kbd "C-c SPC") ⇒ "\C-c " (kbd "<f1> SPC") ⇒ [f1 32] (kbd "C-M-<down>") ⇒ [C-M-down]
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
キーマップはさまざまなキーシーケンスにたいしてキーバインディング(key binding)を指定するLispデータ構造です。
1つのキーマップが、個々のイベントにたいする定義を直接指定します。単一のイベントでキーシーケンスが構成されるとき、そのキーシーケンスのキーマップ内でのバインディングは、そのイベントにたいするそのキーマップの定義です。それより長いキーシーケンスのバインディングは対話的プロセスによって見つけ出されます。まず最初にイベント(それ自身がキーマップでなければならない)の定義を探します。そして次にそのキーマップ内で2つ目のイベントを探すといったように、そのキーシーケンス内のすべてのイベントが処理されるまで、これを続けます。
あるキーシーケンスのバインディングがキーマップであるような場合、わたしたちはそのキーシーケンスをプレフィクスキー(prefix
key)と呼び、それ以外の場合には(それ以上イベントを追加できないので)コンプリートキー(complete
keylと呼んでいます。バインディングがnil
の場合、わたしたちはそのキーを未定義(undefined)と呼びます。C-c、C-x、C-x
4などはプレフィクスキーの例です。X、RET、C-x 4
C-fなどは定義されたコンプリートキーの例です。C-x C-gやC-c
3などは未定義なコンプリートキーの例です。詳細はプレフィクスキーを参照してください。
キーシーケンスのバインディングを見つけ出すルールは、(最後のイベントの前までに見つかる)中間的なバインディングがすべてキーマップであると仮定します。もしそうでなければ、そのイベントシーケンスは単位を形成せず、実際の単一キーシーケンスではありません。言い換えると任意の有効なキーシーケンスから1つ以上のイベントを取り除くと、常にプレフィクスキーにならなければなりません。たとえばC-f C-nはキーシーケンスではありません。C-fはプレフィクスキーではないので、C-fで始まるこれより長いシーケンスは、キーシーケンスではあり得ないからです。
利用可能な複数イベントキーシーケンスのセットは、プレフィクスキーにたいするバインディングに依存します。したがってこれはキーマップが異なれば異なるかもしれず、バインディングが変更されたときに変更されるかもしれません。しかし単一イベントキーシーケンスは整合性において任意のプレフィクスキーに依存しないので、常に単一のキーシーケンスです。
常に複数のプライマリーキーマップ(primary keymap: 主キーマップ)がアクティブであり、これらはキーバインディングを見つけるために使用されます。すべてのバッファーで共有されるグローバルキーマップ(global map)というキーマップが存在します。ローカルキーマップ(local keymap)は通常は特定のメジャーモードに関連します。そして0個以上のマイナーモードキーマップ(minor mode keymap)はカレントで有効なマイナーモードに属します(すべてのマイナーモードがキーマップをもつわけでなない)。ローカルキーマップは対応するグローバルバインディングをshadow(訳注: 隠すという意味)します。マイナーモードキーマップは、ローカルキーマップとグローバルキーマップの両方をshadowします。詳細はアクティブなキーマップを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
キーマップはそれぞれCARがシンボルkeymap
であるようなリストです。このリストの残りの要素はそのキーマップのキーバインディングを定義します。関数定義がキーマップであるようなシンボルもキーマップです。あるオブジェクトがキーマップかどうかテストするには、関数keymapp
(以下参照)を使用してください。
キーマップを開始するシンボルkeymap
の後には、いくつかの種類の要素が出現します:
(type . binding)
これは型typeのイベントにたいする1つのバインディングを指定する。通常のバインディングはそれぞれ、常に文字かシンボルであるような特定のイベント型(event type)のイベントに適用される。イベントの分類を参照のこと。この種のバインディングでは、bindingはコマンドである。
(type item-name . binding)
これはメニュー内でitem-nameとして表示されるシンプルなメニューアイテムでもあるようなバインディングを指定する。単純なメニューアイテムを参照のこと。
(type item-name help-string . binding)
これはヘルプ文字列help-stringのシンプルなメニューアイテムである。
(type menu-item . details)
これは拡張されたメニューアイテムでもあるようなバインディングを指定する。これは他の機能も使用できる。拡張メニューアイテムを参照のこと。
(t . binding)
これはデフォルトキーバインディング(default key
binding)を指定する。キーマップの他の要素でバインドされないイベントは、バインディングとしてbindingが与えられる。デフォルトバインディングにより、利用可能なすべてのイベント型を列挙することなくバインドできる。デフォルトバインディングをもつキーマップは、明示的にnil
にバインドされるイベント(以下参照)を除いて、より低い優先度にあるすべてのキーマップをマスクする。
char-table
キーマップのある要素が文字テーブル(char-table)なら、それは修飾ビットなしのすべての文字イベントにたいするバインディングを保持するとみなされる(modifier bitsを参照)。インデックスcの要素は文字cにたいしてバインドされる。これは多量のバインディングを記録するためのコンパクトな方法である。そのような文字テーブルのキーマップは、fullキーマップ(full keymap: 完全なキーマップ)と呼ばれる。それにたいして他のキーマップはsparseキーマップ(sparse keymaps: 疎なキーマップ)と呼ばれる。
vector
この種の要素は文字テーブルと類似する。インデックスcの要素は文字cにバインドされる。この方法でバインド可能な文字の範囲はそのベクターのサイズに制限され、かつベクターの作成により0からすべての文字コードまでスペースが割り当てられるので、バインディング自身が問題とならないメニューキーマップ(メニューキーアップを参照)の作成以外では、このフォーマットを使用しないこと。
string
キーにたいするバインディングを指定する要素は別として、キーマップは要素として文字列ももつことができる。これはoverallプロンプト文字列(overall prompt string: 全般的なプロンプト文字列)と呼ばれ、メニューとしてキーマップを使用することを可能にする。メニューの定義を参照のこと。
(keymap …)
キーマップのある要素それ自身がキーマップなら、外側のキーマップ内でこれが内側のキーマップとしてinline指定されているかのようにみなされる。これはmake-composed-keymap
内で行なわれるような多重継承にたいして使用される。
バインディングがnil
なら、それは定義の構成要素ではありませんが、デフォルトバインディングや親キーマップ内のバインディングに優先されます。一方nil
のバインディングは、より低い優先度のキーマップをオーバーライドしません。したがってローカルマップでnil
のバインディングが与えられると、Emacsはグローバルマップのバインディングを使用します。
キーマップはメタ文字にたいするバインディングを直接記録しません。かわりにメタ文字は1文字目がESC(または何であれmeta-prefix-char
のカレント値)であるような、2文字のキーシーケンスをルックアップするものとみなされます。したがってキーM-aは内部的にはESC
aで表され、そのグローバルバインディングはesc-map
内のaにたいするスロットで見つけることができます(プレフィクスキーを参照)。
この変換は文字にたいしてのみ適用され、ファンクションキーや他の入力イベントには適用されないのでM-endはESC endと何も関係ありません。
以下に例としてLispモードにたいするローカルキーマップ(sparseキーマップ)を挙げます。以下ではDEL、C-c C-z、C-M-q、C-M-xにたいするバインディングを定義しています(実際の値はメニューバインディングも含まれるが簡潔にするためここでは省略)。
lisp-mode-map ⇒
(keymap (3 keymap ;; C-c C-z (26 . run-lisp))
(27 keymap
;; C-M-xはESC C-xとして扱われる
(24 . lisp-send-defun))
;; この部分はlisp-mode-shared-map
から継承
keymap
;; DEL
(127 . backward-delete-char-untabify)
(27 keymap
;; C-M-qはESC C-qとして扱われる
(17 . indent-sexp)))
この関数はobjectがキーマップならt
、それ以外はnil
をリターンする。より正確にはこの関数はリストにたいしてそのCARがkeymap
か、あるいはシンボルにたいしてその関数定義がkeymapp
かどうかをテストする。
(keymapp '(keymap)) ⇒ t
(fset 'foo '(keymap)) (keymapp 'foo) ⇒ t
(keymapp (current-global-map)) ⇒ t
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はキーマップを作成する関数です。
この関数はエントリーをもたない新たなsparseキーマップを作成してそれをリターンする(sparseキーマップはあなたが通常望む類のキーマップのこと)。make-keymap
と異なり新たなキーマップは文字テーブルを含まず、何のイベントもバインドしない。
(make-sparse-keymap) ⇒ (keymap)
promptを指定すると、それはキーマップにたいするoverallプロンプト文字列になる。これはメニューキーマップ(メニューの定義を参照)にたいしてのみ指定すべきである。overallプロンプト文字列をともなうキーマップがアクティブなら、次の入力イベントのルックアップにたいしてマウスメニューとキーボードメニューを常に提示する。これはコマンドループにたいして毎回キーボードメニューを提示するので、overallプロンプト文字列をメインマップ、メジャーモードマップ、マイナーモードマップに指定しないこと。
この関数は新たなfullキーマップを作成してそれをリターンする。このキーマップは修飾されないすべての文字にたいするスロットをもつ文字テーブル(文字テーブルを参照)を含む。この新たなキーマップは初期状態ではすべての文字、およびその他の種類のイベントがnil
にバインドされている。引数promptはmake-sparse-keymap
のようにプロンプト文字列を指定する。
(make-keymap) ⇒ (keymap #^[nil nil keymap nil nil nil …])
fullキーマップは多くのスロットを保持するときはsparseキーマップより効果的であり、少ししかスロットを保持しないときはsparseキーマップのほうが適している。
この関数はkeymapのコピーをリターンする。keymap内でバインディングとして直接出現するすべてのキーマップも、すべてのレベルまで再帰的にコピーされる。しかしある文字の定義が関数定義にキーマップをもつ関数のときは再帰的なコピーは行われず、新たにコピーされたキーマップには同じシンボルがコピーされる。
(setq map (copy-keymap (current-local-map))) ⇒ (keymap
;; (これはメタ文字を実装する)
(27 keymap
(83 . center-paragraph)
(115 . center-line))
(9 . tab-to-tab-stop))
(eq map (current-local-map)) ⇒ nil
(equal map (current-local-map)) ⇒ t
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
キーマップは他のキーマップを継承することができ、この継承元のキーマップを親キーマップ(parent keymap)と呼びます。そのようなキーマップは以下のようなキーマップです:
(keymap elements… . parent-keymap)
これにはそのキーマップのキールックアップ時にparent-keymapのすべてのバインディングを継承するものの、それらにバインディングを追加したりelementsでオーバーライドできるという効果があります。
define-key
や他のキーバインディング関数を使用してparent-keymap内のバインディングを変更すると、変更されたバインディングはelementsで作られたバインディングにshadowされない限り継承されたキーマップ内で可視になります。逆は真ではありません。define-key
を使用して継承されたキーマップ内のバインディングを変更すると、これらの変更はelements内に記録されますがparent-keymapに影響はありません。
親キーマップからキーマップを構築するにはset-keymap-parent
を使用するのが正しい方法です。親キーマップから直接キーマップを構築するコードがあるなら、かわりにset-keymap-parent
を使用するようにプログラムを変更してください。
これはkeymapの親キーマップをリターンする。keymapに親キーマップがなければkeymap-parent
はnil
をリターンする。
これはkeymapの親キーマップをparentにセットしてparentをリターンする。parentがnil
ならこの関数はkeymapに親キーマップを与えない。
keymapがサブマップ(プレフィクスキーにたいするバインディング)をもつ場合は、それらも新たな親キーマップを受け取ってそれらのプレフィクスキーにたいしてparentが何を指定するかが反映される。
以下はtext-mode-map
から継承してキーマップを作成する方法を示す例です:
(let ((map (make-sparse-keymap))) (set-keymap-parent map text-mode-map) map)
非sparseキーマップも親キーマップをもつことができますが便利とは言えません。非sparseキーマップは修飾ビットをもたないすべての数値文字コードにたいするバインディングとして、たとえそれがnil
であっても常に何かを指定するので、これらの文字のバインディングが親キーマップから継承されることは決してないのです。
複数のマップからキーマップを継承したいときがあるかもしれません。これにたいして関数make-composed-keymap
が使用できます。
この関数は既存のキーマップから構成される新たなキーマップをリターンする。またオプションで親キーマップparentから継承を行う。mapsには単一のキーマップ、または複数のキーマップのリストを指定できる。リターンされた新たなマップ内でキーをルックアップするとき、Emacsはmaps内のキーマップを順に検索してからparent内を検索する。この検索は最初のマッチで停止する。mapsのいずれか1つのキーマップ内のnil
バインディングは、parent内のすべてのバインディングをオーバーライドするが、mapsにないキーマップの非nil
なバインディングはオーバーライドしない。
たとえば以下はbutton-buffer-map
とspecial-mode-map
の両方を継承するhelp-mode-map
のようなキーマップの親キーマップをEmacsがセットする方法です:
(defvar help-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map (make-composed-keymap button-buffer-map special-mode-map)) ... map) ... )
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プレフィクスキー(prefix
key)とは、バインディングがキーマップであるようなキーシーケンスです。このキーマップはプレフィクスキーを拡張するキーシーケンスが何を行うかを定義します。たとえばC-xはプレフィクスキーであり、これはキーマップを使用してそのキーマップは変数ctl-x-map
にも格納されています。このキーマップはC-xで始まるキーシーケンスにたいするバインディングを定義します。
標準的なEmacsのプレフィクスキーのいくつかは、Lisp変数でも見い出すことができるキーマップを使用しています:
esc-map
はプレフィクスキーESCにたいするグローバルキーマップである。したがってすべてのメタ文字にたいする定義は、このキーマップで見い出すことができる。このマップはESC-prefix
の関数定義でもある。
help-map
はプレフィクスキーC-hにたいするグローバルキーマップである。
mode-specific-map
はプレフィクスキーC-cにたいするグローバルキーマップである。このマップは実際にはモード特有(mode-specific)ではなくグローバルであるが、このプレフィクスキーは主にモード特有なバインディングに使用されるので、C-h
b (display-bindings
)の出力内のC-cに関する情報で、この名前は有意義な情報を提供する。
ctl-x-map
はプレフィクスキーC-xにたいして使用されるグローバルキーマップである。このマップはシンボルControl-X-prefix
の関数セルを通して見つけることができる。
mule-keymap
はプレフィクスキーC-x RET にたいして使用されるグローバルキーマップである。
ctl-x-4-map
はプレフィクスキーC-x 4にたいして使用されるグローバルキーマップである。
ctl-x-5-map
はプレフィクスキーC-x 5にたいして使用されるグローバルキーマップである。
2C-mode-map
はプレフィクスキーC-x 6にたいして使用されるグローバルキーマップである。
vc-prefix-map
はプレフィクスキーC-x vにたいして使用されるグローバルキーマップである。
goto-map
はプレフィクスキーM-gにたいして使用されるグローバルキーマップである。
search-map
はプレフィクスキーM-sにたいして使用されるグローバルキーマップである。
facemenu-keymap
はプレフィクスキーM-oにたいして使用されるグローバルキーマップである。
プレフィクスキーのキーマップバインディングは、プレフィクスキーに続くイベントをルックアップするために使用されます(これは関数定義がキーマップであるようなシンボルかもしれない。効果は同じだがシンボルはプレフィクスキーにたいする名前の役割を果たす)。したがってC-xのバインディングはシンボルControl-X-prefix
であり、このシンボルの関数セルがC-xコマンドにたいするキーマップを保持します(ctl-x-map
の値も同じキーマップ)。
プレフィクスキー定義は任意のアクティブなキーマップ内に置くことができます。プレフィクスキーとしてのC-c、C-x、C-h、ESCの定義はグローバルマップ内にもあるので、これらのプレフィクスキーは常に使用できます。メジャーモードとマイナーモードは、ローカルマップやマイナーモードのマップ内にプレフィクスキー定義を置くことによってキーをプレフィクスキーとして再定義できます。アクティブなキーマップを参照してください。
あるキーが複数のアクティブなマップ内でプレフィクスキーとして定義されていると、それぞれの定義がマージされて効果をもちます。まずマイナーモードキーマップ内で定義されたコマンド、次にローカルマップのプレフィクス定義されたコマンド、そしてグローバルマップのコマンドが続きます。
以下の例ではローカルキーマップ内でC-pをC-xと等価なプレフィクスキーにしています。するとC-p
C-fにたいするバインディングはC-x C-fと同様に関数find-file
になります。キーシーケンスC-p
6はすべてのアクティブなキーマップで見つけることができません。
(use-local-map (make-sparse-keymap)) ⇒ nil
(local-set-key "\C-p" ctl-x-map) ⇒ nil
(key-binding "\C-p\C-f") ⇒ find-file
(key-binding "\C-p6") ⇒ nil
この関数はプレフィクスキーのバインディングとして使用するためにsymbolを用意する。これはsparseキーマップを作成してそれをsymbolの関数定義として格納する。その後はsymbolにキーシーケンスをバインディングすると、そのキーシーケンスはプレフィクスキーになるだろう。リターン値はsymbol
。
この関数は値がそのキーマップであるような変数としてもsymbolをセットする。しかしmapvarが非nil
なら、かわりにmapvarを変数としてセットする。
promptが非nil
なら、これはそのキーマップにたいするoverallプロンプト文字列になる。プロンプト文字列はメニューキーマップにたいして与えらること(メニューの定義を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsには多くのキーマップを含まれていますが、常にいくつかのキーマップだけがアクティブです。Emacsがユーザー入力を受け取ったとき、それは入力イベントに変換されて(イベントシーケンス変換のためのキーマップを参照)、アクティブなキーマップ内でキーバインディングがルックアップされます。
アクティブなキーマップは通常は、(1) keymap
プロパティにより指定されるキーマップ、(2) 有効なマイナーモードのキーマップ、(3)
カレントバッファーのローカルキーマップ、(4)
グローバルキーマップの順です。Emacsは入力キーシーケンスそれぞれにたいして、これらすべてのキーマップ内を検索します。
これらの通常のキーマップのうち最優先されるのは、もしあればポイント位置のkeymap
テキストにより指定されるキーマップかoverallプロパティです(マウス入力イベントにたいしてはEmacsはポイント位置のかわりにイベント位置を使用する。
アクティブなキーマップの検索を参照されたい)。
次に優先されるのは有効なマイナーモードにより指定されるキーマップです。もしあればこれらのキーマップは変数emulation-mode-map-alists
、minor-mode-overriding-map-alist
、minor-mode-map-alist
により指定されます。アクティブなキーマップの制御を参照してください。
次に優先されるのはバッファーのローカルキーマップ(local
keymap)で、これにはそのバッファー特有なキーバインディングが含まれます。ミニバッファーもローカルキーマップをもちます(ミニバッファーの概念を参照)。ポイント位置にlocal-map
テキスト、またはoverlayプロパティがあるなら、それはバッファーのデフォルトローカルキーマップのかわりに使用するローカルキーマップを指定します。
ローカルキーマップは通常はそのバッファーのメジャーモードによってセットされます。同じメジャーモードをもつすべてのバッファーは、同じローカルキーマップを共有します。したがってあるバッファーでローカルキーマップを変更するためにlocal-set-key
(キーのバインドのためのコマンドを参照)を呼び出すと、それは同じメジャーモードをもつ他のバッファーのローカルキーマップにも影響を与えます。
最後はC-fのようなカレントバッファーとは関係なく定義されるキーバインディングを含んだグローバルキーマップ(global
keymap)です。このキーマップは常にアクティブであり変数global-map
にバインドされています。
これら通常のキーマップとは別に、Emacsはプログラムが他のキーマップをアクティブにするための特別な手段を提供します。1つ目はグローバルキーマップ以外の通常アクティブなキーマップを置き換えるキーマップを指定する変数overriding-local-map
です。2つ目は他のすべてのキーマップより優先されるキーマップを指定する端末ローカル変数overriding-terminal-local-map
です。この端末ローカル変数は通常はmodal(訳注:
他のキーマップを選択できない状態)かつ一時的なキーバインディングに使用されます(ここの変数にたいして関数set-transient-map
は便利なインターフェイスを提供する)。詳細はアクティブなキーマップの制御を参照してください。
これらを使用するのがキーマップをアクティブにする唯一の方法ではありません。キーマップはread-key-sequence
によるイベントの変換のような他の用途にも使用されます。イベントシーケンス変換のためのキーマップを参照してください。
いくつかの標準的なキーマップのリストは標準的なキーマップを参照してください。
これはカレント状況下でコマンドループによりキーシーケンスをルックアップするために使用される、アクティブなキーマップのリストをリターンする。これは通常はoverriding-local-map
とoverriding-terminal-local-map
を無視するが、olpが非nil
なら、それらのキーマップにも注意を払う。オプションでpositionにevent-start
によってリターンされるイベント位置、またはバッファー位置を指定でき、key-binding
で説明されているようにキーマップを変更するかもしれない。
この関数はカレントのアクティブキーマップでkeyにたいするバインディングをリターンする。そのキーマップ内でkeyが未定義なら結果はnil
。
引数accept-defaultsはlookup-key
(キー照合のための関数を参照)のようにデフォルトバインディングをチェックするかどうかを制御する。
コマンドがリマップ(remap: 再マップ。コマンドのリマップを参照)されたとき、key-binding
が実際に実行されるであろうリマップされたコマンドをリターンするように、通常のようにコマンドのリマップを行う。しかしno-remapが非nil
なら、key-binding
はリマップを無視してkeyにたいして直接指定されたバインディングをリターンする。
keyがマウスイベント(もしかしたらプレフィクスイベントが先行するかもしれない)で始まるなら、照合されるマップはそのイベントの位置を元に決定される。それ以外では、それらのマップはポイント値にもとづき決定される。しかしpositionを指定することによってこれらをオーバーライドできる。positionが非nil
なら、それはバッファー位置かevent-start
の値のようなイベント位置のいずれかである。その場合には照合されるマップはpositionにもとづいて決定される。
keyが文字列とベクターのいずれでもなければEmacsはエラーをシグナルする。
(key-binding "\C-x\C-f") ⇒ find-file
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はEmacsがアクティブなキーマップを検索する方法を示すLisp処理の概要です:
(or (if overriding-terminal-local-map (find-in overriding-terminal-local-map)) (if overriding-local-map (find-in overriding-local-map) (or (find-in (get-char-property (point) 'keymap)) (find-in-any emulation-mode-map-alists) (find-in-any minor-mode-overriding-map-alist) (find-in-any minor-mode-map-alist) (if (get-text-property (point) 'local-map) (find-in (get-char-property (point) 'local-map)) (find-in (current-local-map))))) (find-in (current-global-map)))
ここでfind-inとfind-in-anyはそれぞれ、1つのキーマップとキーマップのalistを検索する仮の関数です。関数set-transient-map
がoverriding-terminal-local-map
(アクティブなキーマップの制御を参照)をセットすることによって機能する点に注意してください。
上記の処理概要ではキーシーケンスがマウスイベント(マウスイベントを参照)で始まる場合には、ポイント位置のかわりにそのイベント位置、カレントバッファーのかわりにそのイベントのバッファーが使用されます。これは特にプロパティkeymap
とlocal-map
をルックアップする方法に影響を与えます。display
、before-string
、after-string
プロパティ(特殊な意味をもつプロパティを参照)が埋め込まれていてkeymap
かlocal-map
プロパティが非nil
の文字列上でマウスイベントが発生すると、それは基調となるバッファーテキストの対応するプロパティをオーバーライドします(バッファーテキストにより指定されたプロパティは無視される)。
アクティブなキーマップの1つでキーバインディングが見つかって、そのバインディングがコマンドなら検索は終了してそのコマンドが実行されます。しかしそのバインディングが値をもつ変数か文字列なら、Emacsは入力キーシーケンスをその変数の値か文字列で置き換えて、アクティブなキーマップの検索を再開します。 キーの照合を参照してください。
最終的に見つかったコマンドもリマップされるかもしれません。コマンドのリマップを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この変数はEmacsキーボード入力をコマンドにマップするデフォルトのグローバルキーマップを含む。通常はこのキーマップがグローバルキーマップである。デフォルトグローバルキーマップはself-insert-command
をすべてのプリント文字にバインドするfullキーマップである。
これはグローバルキーマップ内のバインディングを変更する通常の手段だが、この変数に開始時のキーマップ以外の値を割り当てるべきではない。
この関数はカレントのグローバルキーマップをリターンする。デフォルトグローバルキーマップとカレントグローバルキーマップのいずれも変更していなければglobal-map
と同じ値。リターン値はコピーではなく参照である。これにdefine-key
などの関数を使用すると、グローバルバインディングが変更されるだろう。
(current-global-map) ⇒ (keymap [set-mark-command beginning-of-line … delete-backward-char])
この関数はカレントバッファーのローカルキーマップをリターンする。ローカルキーマップがなければnil
をリターンする。以下の例では、(Lisp
Interactionモードを使用する)*scratch*バッファーにたいするキーマップは、ESC(ASCIIコード27)にたいするエントリーが別のsparseキーマップであるようなsparseキーマップである。
(current-local-map) ⇒ (keymap (10 . eval-print-last-sexp) (9 . lisp-indent-line) (127 . backward-delete-char-untabify)
(27 keymap (24 . eval-defun) (17 . indent-sexp)))
current-local-map
はローカルキーマップのコピーではなく参照をリターンします。これにdefine-key
などの関数を使用するとローカルバインディングが変更されるでしょう。
この関数はカレントで有効なメジャーモードのキーマップリストをリターンする。
この関数はkeymapを新たなカレントグローバルキーマップにする。これはnil
をリターンする。
グローバルキーマップの変更は異例である。
この関数はkeymapをカレントバッファーの新たなローカルキーマップにする。keymapがnil
なら、そのバッファーはローカルキーマップをもたない。use-local-map
はnil
をリターンする。ほとんどのメジャーモードコマンドはこの関数を使用する。
この変数はアクティブかどうかに関わらず、特定の変数の値にたいするキーマップを示すalistである。要素は以下のようになる:
(variable . keymap)
キーマップkeymapは
variableが非nil
値をもつときはアクティブである。variableは通常はメジャーモードを有効か無効にする変数である。キーマップとマイナーモードを参照のこと。
minor-mode-map-alist
の要素がminor-mode-alist
の要素と異なる構造をもつことに注意。マップは要素のCDRでなければならず、そうでなければ2つ目の要素にマップリストは用いられないだろう。CDRはキーマップ(リスト)、または関数定義がキーマップであるようなシンボルである。
1つ以上のマイナーモードキーマップがアクティブなとき、minor-mode-map-alist
内で前のキーマップが優先される。しかし互いが干渉しないようにマイナーモードをデザインすること。これを正しく行えば順序は問題にならない。
マイナーモードについての詳細な情報は、キーマップとマイナーモードを参照のこと。minor-mode-key-binding
(キー照合のための関数を参照)も確認されたい。
この変数はメジャーモードによる特定のマイナーモードにたいするキーバインディングのオーバーライドを可能にする。このalistの要素はminor-mode-map-alist
の要素のような(variable
. keymap)
という形式である。
ある変数がminor-mode-overriding-map-alist
の要素として出現するなら、その要素によって指定されるマップはminor-mode-map-alist
内の同じ変数にたいして指定されるすべてのマップを完全に置き換える。
すべてのバッファーにおいてminor-mode-overriding-map-alist
は自動的にバッファーローカルである。
この変数が非nil
ならバッファーのローカルキーマップ、テキストプロパティまたはoverlayによるキーマップ、マイナーモードキーマップのかわりに使用されるするキーマップを保持する。このキーマップが指定されると、カレントグローバルキーマップ以外のアクティブだった他のすべてのマップがオーバーライドされる。
この変数が非nil
ならoverriding-local-map
、バッファーのローカルキーマップ、テキストプロパティまたはoverlayによるキーマップ、およびすべてのマイナーモードキーマップのかわりに使用されるキーマップを保持する。
この変数はカレント端末にたいして常にローカルでありバッファーローカルにできない。複数の端末を参照のこと。これはインクリメンタル検索モードの実装に使用される。
この変数が非nil
なら、overriding-local-map
とoverriding-terminal-local-map
の値がメニューバーの表示に影響し得る。デフォルト値はnil
なので、これらのマップ変数なメニューバーに影響をもたない。
これら2つのマップ変数は、たとえこれらの変数がメニューバー表示に影響し得るを与えない場合でも、メニューバーを使用してエンターされたキーシーケンスの実行には影響を与えることに注意。したがってもしメニューバーキーシーケンスが到着したら、そのキーシーケンスをルックアップして実行する前に変数をクリアーすること。この変数を使用するモードは通常は何らかの手段でこれを行っている。これらのモードは通常は“読み戻し(unread)”とexitによって処理されないイベントに応答する。
この変数はスペシャルイベントにたいするキーマップを保持する。あるイベント型がこのキーマップ内でバインディングをもつなら、それはスペシャルイベントであり、そのイベントにたいするバインディングはread-event
によって直接実行される。スペシャルイベントを参照のこと。
この変数はエミュレーションモードにたいして使用するキーマップのalistのリストを保持する。この変数は複数マイナーモードキーマップを使用するモードとパッケージを意図している。リストの各要素はminor-mode-map-alist
と同じフォーマットと意味をもつキーマップのalistか、そのようなalist形式の変数バインディングをもつシンボルである。それぞれのalist内のアクティブなキーマップはminor-mode-map-alist
とminor-mode-overriding-map-alist
の前に使用される。
この関数は一時的(transient)なキーマップとしてkeymapを追加する。一時的なキーマップは1つ以上の後続するキーにたいして、他のキーマップより優先される。
keymapは通常は直後のキーをルックアップするために1回だけ使用される。しかし、オプション引数keep-predがt
なら、そのマップはユーザーがkeymap内で定義されたキーをタイプするまでアクティブのままとなる。keymap内にないキーをユーザーがタイプしたとき一時的キーマップは非アクティブとなり、そのキーにたいして通常のキールックアップが継続される。
keep-predには関数も指定できる。この場合にはkeymapがアクティブの間は、各コマンドの実行に優先してその関数が引数なしで呼び出される。keymapがアクティブの間、関数は非nil
をリターンすること。
オプション引数on-exitが非nilなら、それはkeymapが非アクティブになった後に引数なしで呼び出される関数を指定する。
この関数は他のすべてのアクティブなキーマップに優先される変数overriding-terminal-local-map
にたいして、keymapを追加または削除することによって機能する(アクティブなキーマップの検索を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
キールックアップ(key lookup: キー照合)とは与えられたキーマップからキーシーケンスのバインディングを見つけ出すことです。そのバインディングの使用や実行はキールックアップの一部ではありません。
キールックアップはキーシーケンス内の各イベントのイベント型だけを使用して、そのイベントの残りは無視します。実際のところキールックアップに使用されるキーシーケンスは、マウスイベントをイベント全体(リスト)のかわりにイベント型のみ(シンボル)を用いるでしょう。入力イベントを参照してください。そのようなキーシーケンスはcommand-execute
による実行には不十分ですが、キーのルックアップやリバインドには十分です。
キーシーケンスが複数イベントから構成されるとき、キールックアップはイベントを順に処理します。最初のイベントのバインディングが見つかったとき、それはキーマップでなければなりません。そのキーマップ内で2つ目のイベントを見つけ出して、そのキーシーケンス内のすべてのイベントが消費されるまで、このプロセスを続けます(故に最後のイベントにたいして見つかったイベントはキーマップかどうかはわからない)。したがってキールックアッププロセスはキーマップ内で単一イベントを見つけ出す、よりシンプルなプロセスで定義されます。これが行なわれる方法はキーマップ内でそのイベントに関連するオブジェクトの型に依存します。
キーマップ内のイベント型ルックアップによる値の発見を説明するために、キーマップエントリー(keymap
entry)という用語を導入しましょう(これにはメニューアイテムにたいするキーマップ内のアイテム文字列や他の余計な要素は含まれない。なぜならlookup-key
や他のキーマップルックアップ関数がリターン値にそれらを含まないから)。任意のLispオブジェクトがキーマップエントリーとしてキーマップに格納されるかもしれませんが、すべてがキールックアップに意味をもつわけではありません。以下のテーブルはキーマップエントリーで重要な型です:
nil
nil
はそれまでにルックアップに使用されたイベントが未定義キーを形成することを意味する。最終的にキーマップがイベント型を調べるのに失敗してデフォルトバインディングも存在しないときは、そのイベント型のバインディングがnil
であるのと同じである。
それまでにルックアップに使用されたイベントがコンプリートキーを形成して、commandがそのバインディングである。関数とは?を参照のこと。
array(文字列かベクター)はキーボードマクロである。それまでにルックアップに使用されたイベントはコンプリートキーを形成して、arrayがそのバインディングである。詳細はキーボードマクロを参照のこと。
それまでにルックアップに使用されたイベントはプレフィクスキーを形成する。そのキーシーケンスの次のイベントはkeymap内でルックアップされる。
listの意味はそのリストが何を含んでいるかに依存する:
keymap
なら、そのリストはキーマップでありキーマップとして扱われる(上記参照)。
lambda
なら、そのリストはラムダ式である。これは関数とみなされてそのように扱われる(上記参照)。キーバインディングとして正しく実行されるために、この関数はコマンドでなければならずinteractive
指定をもたなければならない。コマンドの定義を参照のこと。
symbolの関数定義がsymbolのかわりに使用される。もし関数定義もシンボルなら、任意の回数このプロセスが繰り返される。これは最終的にキーマップであるようなオブジェクト、コマンド、またはキーボードマクロに行き着くはずである。
キーマップとキーボードマクロ(文字列かベクター)は有効な関数ではないので関数定義にキーマップ、文字列、ベクターをもつシンボルは関数としては無効であることに注意。しかしキーバインディングとしては有効である。その定義がキーボードマクロなら、そのシンボルはcommand-execute
(interactiveな呼び出しを参照)の引数としても有効である。
シンボルundefined
は特記するに値する。これはそのキーを未定義として扱うことを意味する。厳密に言うとそのキーは定義されているが、そのバインディングがコマンドundefined
なのである。しかしこのコマンドは未定義キーにたいして自動的に行われるのと同じことを行う。これは(ding
を呼び出して)bellを鳴らすがエラーはシグナルしない。
undefined
はグローバルキーバインディングをオーバーライドして、そのキーをローカルに未定義とするために使用される。nil
にローカルにバインドしてもグローバルバインディングをオーバーライドしないであろうから、これを行うのに失敗するだろう。
オブジェクトの他の型が見つかったら、それまでにルックアップで使用されたイベントはコンプリートキーを形成してそのオブジェクトがバインディングになるが、そのバインディングはコマンドとして実行不可能である。
要約するとキーマップエントリーはキーマップ、コマンド、キーボードマクロ、あるいはそれらに導出されるシンボル、あるいはnil
のいずれかです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はキールックアップに関連する関数および変数です。
この関数はkeymap内のkeyの定義をリターンする。このチャプターで説明されているキーをルックアップする他のすべての関数がlookup-key
を使用する。以下は例:
(lookup-key (current-global-map) "\C-x\C-f") ⇒ find-file
(lookup-key (current-global-map) (kbd "C-x C-f")) ⇒ find-file
(lookup-key (current-global-map) "\C-x\C-f12345") ⇒ 2
文字列かベクターのkeyがkeymap内で指定されるプレフィクスキーとして有効なキーシーケンスでなければ、それは最後に余計なイベントをもった、単一のキーシーケンスに適合しない長過ぎるキーのはずである。その場合のリターン値は数となり、この数はコンプリートキーを構成するkeyの前にあるイベントの数である。
accept-defaultsが非nil
なら、lookup-key
はkey内の特定のイベントにたいするバインディングと同様にデフォルトバインディングも考慮する。それ以外ではlookup-key
は特定のkeyのシーケンスにたいするバインディングだけを報告して、明示的に指定したとき以外はデフォルトバインディングを無視する(これを行うにはkeyの要素としてt
を与える。キーマップのフォーマットを参照されたい)。
keyがメタ文字(ファンクションキーではない)を含むなら、その文字は暗黙にmeta-prefix-char
の値と対応する非メタ文字からなる2文字シーケンスに置き換えられる。したがって以下の1つ目の例は2つ目の例に変換されて処理される。
(lookup-key (current-global-map) "\M-f") ⇒ forward-word
(lookup-key (current-global-map) "\ef") ⇒ forward-word
read-key-sequence
とは異なり、この関数は指定されたイベントの情報を破棄する変更(キーシーケンス入力を参照)を行わない。特にこの関数はアルファベット文字を小文字に変更せず、ドラッグイベントをクリックイベントに変更しない。
キーを未定義にするためにキーマップ内で使用される。これはding
を呼び出すがエラーを発生ささない。
この関数はカレントのローカルキーマップ内のkeyにたいするバインディングをリターンする。カレントのローカルキーマップ内で未定義ならnil
をリターンする。
引数accept-defaultsはlookup-key
(上記)と同じようにデフォルトバインディングのチェックを制御する。
この関数はカレントのグローバルキーマップ内でコマンドkeyにたいするバインディングをリターンする。カレントのグローバルキーマップ内で未定義ならnil
をリターンする。
引数accept-defaultsはlookup-key
(上記)と同じようにデフォルトバインディングのチェックを制御する。
この関数はアクティブなマイナーモードのkeyのバインディングをリストでリターンする。より正確にはこの関数は(modename
.
binding)
のようなペアのalistをリターンする。ここでmodenameなそのマイナーモードを有効にする変数、bindingはそのモードでのkeyのバインディングである。keyがマイナーモードバインディングをもたなければ値はnil
。
最初に見つかったバインディングがプレフィクス定義(キーマップ、またはキーマップとして定義されたシンボル)でなければ、他のマイナーモードに由来するすべての後続するバインディングは完全にshadowされて省略される。同様にこのリストはプレフィクスバインディングに後続する非プレフィクスバインディングは省略される。
引数accept-defaultsはlookup-key
(上記)と同じようにデフォルトバインディングのチェックを制御する。
この変数はメタ/プレフィクス文字コードである。これはメタ文字をキーマップ内でルックアップできるように2文字シーケンスに変換する。有用な結果を得るために値はプレフィクスイベント(プレフィクスキーを参照)であること。デフォルト値は27で、これはESCにたいするASCIIコード。
meta-prefix-char
の値が27であるような限り、キールックアップは通常はbackward-word
コマンドとして定義されるM-bをESC
bに変換する。しかしmeta-prefix-char
を24(C-xのコード)にセットすると、EmacsはM-bをC-x
bに変換するだろうが、これの標準のバインディングはswitch-to-buffer
コマンドである。以下に何が起こるかを示す(実際にこれを行ってはならない!):
meta-prefix-char ; デフォルト値
⇒ 27
(key-binding "\M-b") ⇒ backward-word
?\C-x ; 文字.の ⇒ 24 ; プリント表現
(setq meta-prefix-char 24) ⇒ 24
(key-binding "\M-b") ⇒ switch-to-buffer ; 今やM-bをタイプすると ; C-x bをタイプしたようになる (setq meta-prefix-char 27) ; 混乱を避けよう! ⇒ 27 ; デフォルト値をリストア!
この単一イベントから2イベントへの変換は文字にたいしてのみ発生し、他の種類の入力イベントには発生しない。したがってファンクションキーM-F1はESC F1に変換されない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
キーのリバインド(rebind:
再バインド、再束縛)は、キーマップ内でそのキーのバインディングエントリーを変更することによって行われます。グローバルキーマップ内のバインディングを変更すると、その変更は(たとえローカルバインディングによりグローバルバインディングをshadowしているバッファーでは直接影響しないとしても)すべてのバッファーに影響します。カレントバッファーのローカルマップを変更すると、通常は同じメジャーモードを使用するすべてのバッファーに影響します。関数global-set-key
とlocal-set-key
は、これらの操作のための使いやすいインターフェイスです(キーのバインドのためのコマンドを参照)。より汎用的な関数define-key
を使用することもできます。その場合には変更するマップを明示的に指定しなければなりません。
Lispプログラムでリバインドするキーシーケンスを選択するときは、さまざまなキーの使用についてのEmacsの慣習にしたがってください(キーバインディングの慣習を参照)。
リバインドするキーシーケンスの記述では、コントロール文字とメタ文字にたいして特別なエスケープシーケンスを使用すると良いでしょう(文字列型を参照)。構文‘\C-’は後続する文字がコントロール文字でること、‘\M-’は後続する文字がメタ文字であることを意味します。したがって文字列"\M-x"
は1つのM-x、"\C-f"
は1つのC-f、"\M-\C-x"
と"\C-\M-x"
は1つのC-M-xとして読み取られます。ベクター内でもこのエスケープシーケンス、および文字列では使用できない他のエスケープシーケンスを使用できます。一例は‘[?\C-\H-x
home]’です。文字型を参照してください。
キー定義とルックアップ関数は、ベクターであるようなキーシーケンス内のイベント型にたいして別の構文を受け入れます。修飾名に基本イベント(文字かファンクションキー名)を付加したものを含んだリストを使用できます。たとえば(control
?a)
は?\C-a
、(hyper control
left)
はC-H-left
と等価です。このようなリストの利点の1つは、コンパイル済みファイル内に修飾ビットの正確な数値コードが出現しないことです。
以下の関数はkeymapがキーマップでない場合、およびkeyがキーシーケンスを表す文字列やベクターでない場合にはエラーをシグナルします。リストであるようなイベントにたいする略記として、イベント型(シンボル)を使用できます。kbd
関数(キーシーケンスを参照)はキーシーケンスを指定するための便利な方法です。
この関数はkeymap内でkeyにたいするバインディングをセットする(keyが長さ2以上のイベントなら、その変更は実際はkeymapから辿られる他のキーマップで行なわれる)。引数bindingには任意のLispオブジェクトを指定できるが、意味があるのは特定のオブジェクトだけである(意味のある型のリストはキーの照合を参照)。define-key
のリターン値はbindingである。
keyが[t]
なら、それはkeymap内でデフォルトバインディングをセットする。イベントが自身のバインディングをもたないとき、そのキーマップ内にデフォルトバインディングが存在すればEmacsコマンドループはそれを使用する。
keyのすべてのプレフィクスは、プレフィクスキー(キーマップにバインドされる)か、あるいは未定義でなけらばならず、それ以外ならエラーがシグナルされる。keyのいくつかのプレフィクスが未定義なら、define-key
はそれをプレフィクスキーとして定義するので、残りのkeyは指定されたように定義できる。
前にkeymap内でkeyにたいするバインディングが存在しなければ、新たなバインディングがkeymapの先頭に追加される。キーマップ内のバインディングの順序はキーボード入力にたいし影響を与えないが、メニューキーマップにたいしては問題となる(メニューキーアップを参照)。
以下はsparseキーマップを作成してその中にバインディングをいくつか作成する例:
(setq map (make-sparse-keymap)) ⇒ (keymap)
(define-key map "\C-f" 'forward-char) ⇒ forward-char
map ⇒ (keymap (6 . forward-char))
;; C-xにたいしsparseサブマップを作成して
;; その中でfをバインドする
(define-key map (kbd "C-x f") 'forward-word)
⇒ forward-word
map ⇒ (keymap (24 keymap ; C-x (102 . forward-word)) ; f (6 . forward-char)) ; C-f
;; C-pをctl-x-map
にバインド (define-key map (kbd "C-p") ctl-x-map) ;;ctl-x-map
⇒ [nil … find-file … backward-kill-sentence]
;; ctl-x-map
内でC-fをfoo
にバインド
(define-key map (kbd "C-p C-f") 'foo)
⇒ 'foo
map
⇒ (keymap ; ctl-x-map
内のfoo
に注目
(16 keymap [nil … foo … backward-kill-sentence])
(24 keymap
(102 . forward-word))
(6 . forward-char))
C-p
C-fにたいする新たなバインディングの格納は、実際にはctl-x-map
内のエントリーを変更することによって機能し、これはデフォルトグローバルマップ内のC-p
C-fとC-x C-fの両方のバインディングを変更する効果をもつことに注意。
関数substitute-key-definition
はキーマップから特定のバインディングをもつキーをスキャンして、それらを異なるバインディングにリバインドする。より明快かつ多くの場合には同じ結果を生成できる他の機能として、あるコマンドから別のコマンドへのリマップがある(コマンドのリマップを参照)。
この関数はkeymap内でolddefにバインドされるすべてのキーについてolddefをnewdefに置き換える。言い換えるとolddefが出現する箇所のすべてをnewdefに置き換える。この関数はnil
をリターンする。
たとえば以下をEmacsの標準バインディングで行うとC-x C-fを再定義する:
(substitute-key-definition 'find-file 'find-file-read-only (current-global-map))
oldmapが非nil
なら、どのキーをリバインドするかをoldmap内のバインディングが決定するようにsubstitute-key-definition
の動作を変更する。リバインディングは依然としてoldmapではなくkeymapで発生する。したがって他のマップ内のバインディングの制御下でマップを変更することができる。たとえば、
(substitute-key-definition 'delete-backward-char 'my-funny-delete my-map global-map)
これは標準的な削除コマンドにグローバルにバインドされたキーにたいしてmy-map
内の特別な削除コマンドを設定する。
以下はキーマップの置き換え(substitution)の前後を示した例:
(setq map '(keymap (?1 . olddef-1) (?2 . olddef-2) (?3 . olddef-1))) ⇒ (keymap (49 . olddef-1) (50 . olddef-2) (51 . olddef-1))
(substitute-key-definition 'olddef-1 'newdef map) ⇒ nil
map ⇒ (keymap (49 . newdef) (50 . olddef-2) (51 . newdef))
この関数はself-insert-command
をコマンドundefined
にリマップ(コマンドのリマップを参照)することによってfullキーマップのコンテンツを変更する。これはすべてのプリント文字を未定義にする効果をもつので、通常のテキスト挿入は不可能になる。suppress-keymap
はnil
をリターンする。
nodigitsがnil
なら、suppress-keymap
は数字がdigit-argument
、-がnegative-argument
を実行するように定義する。それ以外は残りのプリント文字と同じように、それらの文字も未定義にする。
suppress-keymap
関数はyank
やquoted-insert
のようなコマンドを抑制(suppress)しないのでバッファーの変更は可能。バッファーの変更を防ぐには、バッファーを読み取り専用(read-only)にすること(読み取り専用のバッファーを参照)。
この関数はkeymapを変更するので、通常は新たに作成したキーマップにたいして使用するだろう。他の目的のために使用されている既存のキーマップに操作を行うと恐らくトラブルの原因となる。たとえばglobal-map
の抑制はEmacsをほとんど使用不可能にするだろう。
この関数はテキストの挿入が望ましくないメジャーモードの、ローカルキーマップ初期化に使用され得る。しかしそのようなモードは通常はspecial-mode
(基本的なメジャーモードを参照)から継承される。この場合にはそのモードのキーマップは既に抑制済みのspecial-mode-map
から自動的に受け継がれる。以下にspecial-mode-map
が定義される方法を示す:
(defvar special-mode-map (let ((map (make-sparse-keymap))) (suppress-keymap map) (define-key map "q" 'quit-window) … map))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
あるコマンドから他のコマンドへのリマップ(remap)には、特別な種類のキーバインディングが使用できます。この機能を使用するためには、ダミーイベントremap
で始まり、その後にリマップしたいコマンド名が続くようなキーシーケンスにたいするキーバインディングを作成します。そしてそのバインディングにたいしては、新たな定義(通常はコマンド名だがキーバインディングにたいして有効な他の任意の定義を指定可能)を指定します。
たとえばMyモードというモードが、kill-line
のかわりに呼び出されるmy-kill-line
という特別なコマンドを提供するとします。これを設定するには、このモードのキーマップに以下のようなリマッピングが含まれるはずです:
(define-key my-mode-map [remap kill-line] 'my-kill-line)
その後はmy-mode-map
がアクティブなときは常に、ユーザーがC-k
(kill-line
にたいするデフォルトのグローバルキーシーケンス)をタイプするとEmacsはかわりにmy-kill-line
を実行するでしょう。
リマップはアクティブなキーマップでのみ行なわれることに注意してください。たとえばctl-x-map
のようなプレフィクスキーマップ内にリマッピングを置いても、そのようなキーマップはそれ自体がアクティブでないので通常は効果がありません。それに加えてリマップは1レベルを通じてのみ機能します。以下の例では、
(define-key my-mode-map [remap kill-line] 'my-kill-line) (define-key my-mode-map [remap my-kill-line] 'my-other-kill-line)
これはkill-line
をmy-other-kill-line
にリマップしません。かわりに通常のキーバインディングがkill-line
を指定する場合には、それがmy-kill-line
にリマップされます。通常のバインディングがmy-kill-line
を指定すると、my-other-kill-line
にリマップされます。
コマンドのリマップをアンドゥするには、以下のようにそれをnil
にリマップします:
(define-key my-mode-map [remap kill-line] nil)
この関数はカレントアクティブキーマップによって与えられるcommand(シンボル)にたいするリマッピングをリターンする。commandがリマップされていない(これは普通の状況である)、あるいはシンボル以外なら、この関数はnil
をリターンする。position
はkey-binding
の場合と同様、使用するキーマップを決定するためにバッファー位置かイベント位置をオプションで指定できる。
オプション引数keymaps
が非nil
なら、それは検索するキーマップのリストを指定する。この引数はposition
が非nil
なら無視される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
read-key-sequence
関数がキーシーケンス(キーシーケンス入力を参照)を読み取るときには、特定のイベントシーケンスを他のものに変換(translate)するために変換キーマップ(translation
keymaps)を使用します。input-decode-map
、local-function-key-map
、key-translation-map
(優先順)は変換キーマップです。
変換キーマップは他のキーマップと同じ構造をもちますが使い方は異なります。変換キーマップはキーシーケンスを読み取るときに、コンプリートキーシーケンスにたいするバインディングではなくキーシーケンスに行う変換を指定します。キーシーケンスが読み取られると、それらのキーシーケンスは変換キーマップにたいしてチェックされます。ある変換キーマップがkをベクターvにバインドするなら、キーシーケンス内のどこかにサブシーケンスとしてkが出現すると、それはv内のイベントに置き換えられます。
たとえばキーパッドキーPF1が押下されたとき、VT100端末はESC O
Pを送信します。そのような端末ではEmacsはそのイベントシーケンスを単一イベントpf1
に変換しなければなりません。これはinput-decode-map
内でESC
O Pを[pf1]
にバインドすることにより行われます。したがってその端末上でC-c
PF1をタイプしたとき、端末は文字シーケンスC-c ESC O
Pを発行して、read-key-sequence
がそれをC-c PF1に変換、ベクター[?\C-c
pf1]
としてリターンします。
変換キーマップは、(keyboard-coding-system
で指定された入力コーディングシステムを通じて)Emacsがキーボード入力をデコードした直後だけ効果をもちます。端末I/Oのエンコーディングを参照してください。
この変数は通常の文字端末上のファンクションキーから送信された文字シーケンスを記述するキーマップを保持する。
input-decode-map
の値は、通常はその端末のTerminfoかTermcapのエントリーに応じて自動的にセットアップされるが、Lispの端末仕様ファイルの助けが必要なときもある。Emacsには一般的な多くの端末の端末仕様ファイルが同梱されている。これらのファイルの主な目的はTermcapやTerminfoから推定できないエントリーをinput-decode-map
内に作成することである。端末固有の初期化を参照のこと。
この変数はinput-decode-map
と同じようにキーマップを保持するが、通常は優先される解釈選択肢(alternative
interpretation)に変換されるべきキーシーケンスを記述するキーマップを保持する。このキーマップはinput-decode-map
の後、key-translation-map
の前に適用される。
local-function-key-map
内のエントリーはマイナーモード、ローカルキーマップ、グローバルキーマップによるバインディングと衝突する場合には無視される。つまり元のキーシーケンスが他にバインディングをもたない場合だけリマッピングが適用される。
local-function-key-map
はfunction-key-map
を継承するがfunction-key-map
を直接使用しないこと。
この変数は入力イベントを他のイベントに変換するために、input-decode-map
と同じように使用される別のキーマップを保持する。input-decode-map
との違いは、local-function-key-map
の前ではなく後に機能する点である。このキーマップはlocal-function-key-map
による変換結果を受け取る。
input-decode-map
と同様だがlocal-function-key-map
とは異なり、このキーマップは入力キーシーケンスが通常のバインディングをもつかどうかかに関わらず適用される。しかしこのキーマップによりキーバインディングがオーバーライドされても、key-translation-map
では実際のキーバインディングが効果をもち得ることに注意。確かに実際のキーバインディングはlocal-function-key-map
をオーバーライドし、したがってkey-translation-map
が受け取るキーシーケンスは変更されるだろう。明確にするためにはこのような類の状況は避けたほうがよい。
key-translation-map
は通常はself-insert-command
にバインディングされるような通常文字を含めて、ユーザーがある文字を他の文字にマップすることを意図している。
キーシーケンスのかわりにキーの変換として関数を使用することにより、シンプルなエイリアスより多くのことにinput-decode-map
、local-function-key-map
、key-translation-map
を使用できます。その場合にはこの関数はそのキーの変換を計算するために呼び出されます。
キー変換関数は引数を1つ受け取ります。この引数はread-key-sequence
内で指定されるプロンプトです。キーシーケンスがエディターコマンドループに読み取られる場合はnil
です。ほとんどの場合にはプロンプト値は無視できます。
関数が自身で入力を読み取る場合、その関数は後続のイベントを変更する効果をもつことができます。たとえば以下はC-c hをハイパー文字に後続する文字とするために定義する方法の例です:
(defun hyperify (prompt) (let ((e (read-event))) (vector (if (numberp e) (logior (lsh 1 24) e) (if (memq 'hyper (event-modifiers e)) e (add-event-modifier "H-" e)))))) (defun add-event-modifier (string e) (let ((symbol (if (symbolp e) e (car e)))) (setq symbol (intern (concat string (symbol-name symbol)))) (if (symbolp e) symbol (cons symbol (cdr e))))) (define-key local-function-key-map "\C-ch" 'hyperify)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
そのキーシーケンスがコマンドにバインドされたとき、またはさらにイベントを追加してもコマンドにバインドされるシーケンスにすることができないとEmacsが判断したときにキーシーケンスの終わりが検出されます。
これは元のキーシーケンスがバインディングをもつかどうかに関わらず、input-decode-map
やkey-translation-map
を適用するときに、そのようなバインディングが変換の開始を妨げることを意味します。たとえば前述のVT100の例に戻って、グローバルマップにC-c
ESCを追加してみましょう。するとユーザーがC-c PF1をタイプしたとき、EmacsはC-c
ESC O PをC-c PF1に変換するのに失敗するでしょう。これはEmacsがC-x
ESCの直後に読み取りを停止して、O Pが読み取られずに残るからです。この場合にはユーザーが実際にC-c
ESCをタイプすると、ユーザーが実際にESCを押下したのか、あるいはPF1を押下したのか判断するためにEmacsが待つべきではないのです。
この理由によりキーシーケンスの終わりがキー変換のプレフィクスであるようなキーシーケンスをコマンドにバインドするのは、避けたほうがよいでしょう。そのような問題を起こす主なサフィックス、およびプレフィクスはESC、M-O (実際はESC O)、M-[ (実際はESC [)です。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではキーバインディングを変更するための便利な対話的インターフェイスを説明します。これらはdefine-key
を呼び出すことにより機能します。
ユーザーはinitファイルにたいしてシンプルなカスタマイズを行うとき、しばしばglobal-set-key
を使用します。たとえば、
(global-set-key (kbd "C-x C-\\") 'next-line)
または
(global-set-key [?\C-x ?\C-\\] 'next-line)
または
(global-set-key [(control ?x) (control ?\\)] 'next-line)
は、次の行に移動するようにC-x C-\を再定義します。
(global-set-key [M-mouse-1] 'mouse-set-point)
は、メタキーを押してマウスの第一ボタン(左ボタン)をクリックすると、クリックした箇所にポイントをセットするように再定義します。
バインドするキーのLisp指定に非ASCII文字のテキストを使用するときには注意してください。マルチバイトとして読み取られたテキストがあるなら、Lispファイル内でマルチバイトテキストが読み取られるときのように(非ASCII文字のロードを参照)、マルチバイトとしてキーをタイプしなければなりません。たとえば、
(global-set-key "ö" 'my-function) ; bind o-umlaut
または
(global-set-key ?ö 'my-function) ; bind o-umlaut
をLatin-1のマルチバイト環境で使用すると、これらのコマンドはLatin-1端末から送信されたバイトコード246(M-v)ではなく、コード246のマルチバイト文字に実際にはバインドされます。このバインディングを使用するためには適切な入力メソッド(Input Methods in The GNU Emacs Manualを参照)を使用して、キーボードをデコードする方法をEmacsに教える必要があります。
この関数はカレントグローバルマップ内でkeyのバインディングをbindingにセットする。
(global-set-key key binding) ≡ (define-key (current-global-map) key binding)
この関数はカレントグローバルマップからkeyのバインディングを削除する。
プレフィクスとしてkeyを使用する長いキーの定義の準備に使用するのもこの関数の1つの用途である。keyが非プレフィクスのようなバインディングをもつならこの使い方は許容されないだろう。たとえば、
(global-unset-key "\C-l") ⇒ nil
(global-set-key "\C-l\C-l" 'redraw-display) ⇒ nil
この関数は以下のようにdefine-key
を使用するのと等しい:
(global-unset-key key) ≡ (define-key (current-global-map) key nil)
この関数はカレントローカルキーマップ内のkeyのバインディングをbindingにセットする。
(local-set-key key binding) ≡ (define-key (current-local-map) key binding)
この関数はカレントローカルキーマップからkeyのバインディングを削除する。
(local-unset-key key) ≡ (define-key (current-local-map) key nil)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではすべてのカレントキーマップをスキャンして、ヘルプ情報をプリントするために使用される関数を説明します。
この関数は、(0個以上のプレフィクスキーを通じて)keymapから到達可能なすべてのキーマップのリストをリターンする。リターン値は(key
.
map)
のような形式の要素をもつ連想配列(alist)である。ここでkeyはkeymap内での定義がmapであるようなプレフィクスキーである。
alistの要素はkeyの長さにたいして昇順にソートされている。1つ目の要素は常に([] .
keymap)
。これは指定されたキーマップがイベントなしのプレフィクスによって、自分自身からアクセス可能だからである。
prefixが与えられたら、それはプレフィクスキーシーケンスである。その場合にはprefixで始まるプレフィクスキーをもつサブマップだけがaccessible-keymaps
に含まれる。これらの要素の意味は(accessible-keymaps)
の値の場合と同様であり、いくつかの要素が省略されている点だけが異なる。
以下の例ではリターンされるalistにより‘^[’と表示されるキーESCがプレフィクスキーであり、その定義がsparseキーマップ(keymap
(83 . center-paragraph) (115 . foo))
であることが示される。
(accessible-keymaps (current-local-map))
⇒(([] keymap
(27 keymap ; 以降ESCにたいするこのキーマップが繰り返されることに注意
(83 . center-paragraph)
(115 . center-line))
(9 . tab-to-tab-stop))
("^[" keymap (83 . center-paragraph) (115 . foo)))
また以下の例ではC-hは(keymap (118
.
describe-variable)…)
で始まるsparseキーマップを使用するプレフィクスキーである。他のプレフィクスC-x
4は変数ctl-x-4-map
の値でもあるキーマップを使用する。イベントmode-line
はウィンドウの特別な箇所でのマウスイベントにたいするプレフィクスとして使用される、いくつかのダミーイベントのうちの1つである。
(accessible-keymaps (current-global-map)) ⇒ (([] keymap [set-mark-command beginning-of-line … delete-backward-char])
("^H" keymap (118 . describe-variable) … (8 . help-for-help))
("^X" keymap [x-flush-mouse-queue … backward-kill-sentence])
("^[" keymap [mark-sexp backward-sexp … backward-kill-word])
("^X4" keymap (15 . display-buffer) …)
([mode-line] keymap (S-mouse-2 . mouse-split-window-horizontally) …))
これらが実際に目にするであろうキーマップのすべてではない。
関数map-keymap
はkeymap内のバインディングそれぞれにたいして1回functionを呼び出す。呼び出す際の引数はイベント型と、そのバインディングの値の2つ。keymapに親キーマップがあれば、その親キーマップのバインディングも含まれる。これは再帰的に機能する。つまりその親キーマップ自身が親キーマップをもてば、それのバインディングも含まれる、といった具合である。
これはキーマップ内のすべてのバインディングを検証するもっとも明快な方法である。
この関数はwhere-is
コマンド(Help in The GNU Emacs
Manualを参照)により使用されるサブルーチンである。これはキーマップのセット内でcommandにバインドされる、(任意の長さの)キーシーケンスすべてのリストをリターンする。
引数commandには任意のオブジェクトを指定できる。このオブジェクトはすべてのキーマップエントリーにたいして、eq
を使用して比較される。
keymapがnil
なら、overriding-local-map
の値とは無関係に(overriding-local-map
の値がnil
であると装って)、カレントアクティブキーマップをマップとして使用する。keymapがキーマップならkeymapとグローバルキーマップが検索されるマップとなる。keymapがキーマップのリストなら、それらのキーマップだけが検索される。
keymapにたいする式としては、通常はoverriding-local-map
を使用するのが最善である。その場合にはwhere-is-internal
は正にアクティブなキーマップを検索する。グローバルマップだけを検索するにはkeymapの値に(keymap)
(空のキーマップ)を渡せばよい。
firstonlyがnon-ascii
なら、値はすべての可能なキーシーケンスのリストではなく最初に見つかったキーシーケンスを表す単一のベクターとなる。firstonlyがt
なら、値は最初のキーシーケンスだが全体がASCII文字(またはメタ修飾されたASCII文字)で構成されるキーシーケンスが他のすべてのキーシーケンスに優先されて、リターン値がメニューバインディングになることは決してない。
noindirectが非nil
ならwhere-is-internal
は自身のコマンドを探すためにメニューアイテムの内部を調べない。これによりメニューアイテム自体の検索が可能になる。
5つ目の引数no-remapはこの関数がコマンドリマッピング(コマンドのリマップを参照)を扱う方法を決定する。興味深いケースが2つある:
no-remapがnil
ならother-commandにたいするバインディングを探して、commandにたいするバインディングであるかのようにそれらを扱う。no-remapが非nil
ならそれらのバインディングを探すかわりに、利用可能なキーシーケンスリストにベクター[remap
other-command]
を含める。
no-remapがnil
なら、commandではなくother-commandにたいするバインディングをリターンする。no-remapが非nil
なら、リマップされていることを無視してcommandにたいするバインディングをリターンする。
この関数はすべてのカレントキーバインディングのリストを作成して、*Help*という名前のバッファーにそれを表示する。テキストはモードごとにグループ化されて順番はマイナーモード、メジャーモード、グローバルバインディングの順である。
prefixが非nil
なら、それはプレフィクスキーである。その場合にはリストに含まれるのはprefixで始まるキーだけになる。
複数の連続するASCIIコードが同じ定義をもつとき、それらは‘firstchar..lastchar’のようにまとめて表示される。この場合にはそれがどの文字に該当するかを理解するには、そのASCIIコードを知っている必要がある。たとえばデフォルトグローバルマップでは文字‘SPC
..
~’は1行で記述される。SPCはASCIIの32,~はASCIIの126で、その間のすべての文字には通常のプリント文字(アルファベット文字や数字、区切り文字等)が含まれる。これらの文字はすべてself-insert-command
にバインドされる。
buffer-or-nameが非nil
のならそれはバッファーかバッファー名である。その場合はdescribe-bindings
はカレントバッファーのかわりに、そのバッファーのバインディングをリストする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
キーマップはキーボードキーやマウスボタンにたいするバインディング定義と同様に、メニューとして操作することができます。メニューは通常はマウスにより操作されますが、キーボードでも機能させことができます。次の入力イベントにたいしてメニューキーマップがアクティブならキーボードメニュー機能がアクティブになります。
21.17.1 メニューの定義 | メニューを定義するキーマップを作成する方法。 | |
21.17.2 メニューとマウス | ユーザーがマウスでメニューを操作する方法。 | |
21.17.3 メニューとキーボード | ユーザーがキーボードでメニューを操作する方法。 | |
21.17.4 メニューの例 | シンプルなメニューの作成。 | |
21.17.5 メニューバー Bar | メニューバーのカスタマイズ方法。 | |
21.17.6 ツールバー | イメージ行のツールバー。 | |
21.17.7 メニューの変更 | メニューへ新たなアイテムを追加する方法。 | |
21.17.8 easy-menu | メニュー作成のための便利なマクロ。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
キーマップがoverallプロンプト文字列(overall prompt string)をもつ場合には、そのキーマップはメニューとして動作します。overallプロンプト文字列はキーマップの要素として表される文字列です(キーマップのフォーマットを参照)。この文字列にはメニューコマンドの目的を記述します。(もしあれば)Emacsはメニュー表示に使用されるツールキットに応じて、メニュータイトルにoverallメニュー文字列を表示します12。キーボードメニューもoverallプロンプト文字列を表示します。
プロンプト文字列をもつキーマップを構築するもっとも簡単な方法はmake-keymap
、make-sparse-keymap
(キーマップの作成を参照)、define-prefix-command
(Definition of define-prefix-commandを参照)を呼び出すときに引数として文字列を指定する方法です。キーマップをメニューとして操作したくなければ、これらの関数にたいしてプロンプト文字列を指定しないでください。
この関数はkeymapのoverallプロンプト文字列、もしなければnil
をリターンする。
メニューのアイテムは、そのキーマップ内のバインディングです。各バインディングはイベント型と定義を関連付けますが、イベント型はメニューの外見には何の意味ももっていません(通常はイベント型としてキーボードが生成できない擬似イベントのシンボルをメニューアイテムのバインディングに使用する)。メニュー全体はこれらのイベントにたいするキーマップ内のバインディングから生成されます。
メニュー内のアイテムの順序はキーマップ内のバインディングの順序と同じです。define-key
は新たなバインディングを先頭に配置するので、メニューアイテムの順序が重要ならメニューの最後から先頭へメニューアイテムを定義する必要があります。既存のメニューにアイテムを追加するときには、define-key-after
を使用してメニュー内の位置を指定できます(メニューの変更を参照)。
21.17.1.1 単純なメニューアイテム | 単純なメニューのキーバインディング。 | |
21.17.1.2 拡張メニューアイテム | 複雑なメニューアイテムの定義。 | |
21.17.1.3 メニューセパレーター | メニューに水平ラインを描画する。 | |
21.17.1.4 メニューアイテムのエイリアス | メニューアイテムにコマンドエイリアスを使用する。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
メニューアイテムを定義するシンプル(かつ初歩的)な方法は、何らかのイベント型(何のイベント型かは問題ではない)を以下のようにバインドすることです:
(item-string . real-binding)
CARのitem-stringはメニュー内で表示される文字列です。これは短いほうが望ましく、1個から3個の単語が望ましいでしょう。この文字列は対応するコマンドの動作を記述します。すべてのグラフィカルツールキットが非ASCIIテキストを表示できる訳ではないことに注意してください(キーボードメニューとGTK+ツールキットの大部分では機能するだろう)。
以下のようにヘルプ文字列と呼ばれる2つ目の文字列を与えることもできます:
(item-string help . real-binding)
helpはマウスがそのアイテム上にあるときに、help-echo
テキストプロパティ(Help displayを参照)と同じ方法で表示されるhelp-echo文字列を指定します。
define-key
に関する限り、item-stringとhelp-stringはそのイベントのバインディングの一部です。しかしlookup-key
は単にreal-bindingだけをリターンし、そのキーの実行にはreal-bindingだけが使用されます。
real-bindingがnil
ならitem-stringはメニューに表示されますが選択できません。
real-bindingがシンボルでmenu-enable
プロパティが非nil
なら、そのプロパティはメニューアイテムが有効か無効かを制御する式です。メニュー表示にキーマップが使用されるたびにEmacsはその式を評価して、式の値が非nil
の場合のみそのメニューのメニューアイテムを有効にします。メニューアイテム無効なときには、そのアイテムはfuzzy形式で表示されて選択できなくなります。
メニューバーはメニューを調べる際にどのアイテムが有効かを再計算しません。これはXツールキットが事前にメニュー全体を要求するからです。メニューバーの再計算を強制するにはforce-mode-line-update
を呼び出してください(モードラインのフォーマットを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
メニューアイテムの拡張フォーマットは、単純なフォーマットに比べてより柔軟かつ明快です。拡張フォーマットではシンボルmenu-item
で始まるリストでイベント型を定義します。選択できない文字列にたいしては以下のようなバインディングになります:
(menu-item item-name)
2つ以上のダッシュで始まる文字列はリストのセパレーターを指定します。メニューセパレーターを参照してください。
選択可能な実際のメニューアイテムを定義するには以下のような拡張フォーマットでバインドします:
(menu-item item-name real-binding . item-property-list)
ここでitem-nameはメニューアイテム文字列を評価する式です。つまり文字列は定数である必要はありません。3つ目の引数real-bindingは実行するコマンドです。リストの最後の要素item-property-listは、その他の情報を含んだプロパティリストの形式です。
以下はサポートされるプロパティのテーブルです:
:enable form
formの評価結果はそのアイテムを有効にするかどうかを決定する(非nil
なら有効)。アイテムが無効なら▽まったくクリックできない。
:visible form
formの評価結果はそのアイテムを実際にメニューに表示するかどうかを決定する(非nil
なら表示)。アイテムが非表示ならそのアイテムが定義されていないかのようにメニューが表示される。
:help help
このプロパティhelpの値はそのアイテム上にマウスがある間に表示するhelp-echo文字列を指定する。この文字列はhelp-echo
テキストプロパティ(Help displayを参照)と同じ方法で表示される。これはテキストやoverlayにたいするhelp-echo
プロパティとは異なり、文字列定数でなければならないことに注意。
:button (type . selected)
このプロパティはラジオボタンとトグルボタンを定義する手段を提供する。CARのtypeには、:toggle
か:radio
のいずれかを指定する。CDRのselectedはフォームで、評価結果によってそのボタンがカレントで選択されているかどうかを指定する。
トグル(toggle)はselectedの値に応じてonかoffのいずれかがラベルされるメニューアイテムである。コマンド自身はselectedがnil
ならt
、t
ならnil
にselectedを切り替える(toggleする)こと。以下はdebug-on-error
フラグが定義されているときにメニューアイテムをトグルする方法の例:
(menu-item "Debug on Error" toggle-debug-on-error :button (:toggle . (and (boundp 'debug-on-error) debug-on-error)))
これはtoggle-debug-on-error
が変数debug-on-error
をトグルするコマンドとして定義されていることによって機能する。
ラジオボタンとはメニューアイテムのグループであり、常にただ1つのメニューアイテムだけが選択される(selected)。そのためにはどのメニューアイテムが選択されているかを示す変数が存在する必要がある。グループ内の各ラジオボタンにたいするselectedフォームは、そのボタンを選択するためにその変数が正しい値をもつかどうかをチェックする。そしてボタンのクリックにより変数をセットして、クリックされたボタンが選択される。
:key-sequence key-sequence
このプロパティはそのメニューアイテムによって呼び出されるのと同じコマンドにバインドされるかもしれないキーシーケンスを指定する。正しいキーシーケンスを指定すればメニュー表示の準備がより高速になる。
間違ったキーシーケンスを指定すると何の効果もない。Emacsはメニュー内のkey-sequenceの表示前に、実際にそのkey-sequenceがそのメニューアイテムと等価なのか検証する。
:key-sequence nil
このプロパティはそのメニューアイテムには等価なキーバインディングが通常は存在しないことを示す。このプロパティを使用することによりEmacsはそのメニューアイテムにたいして等価なキーボード入力をキーマップから検索する必要がなくなるので、メニュー表示の準備時間が短縮される。
しかしユーザーがそのアイテムの定義をキーシーケンスにリバインドすると、Emacsは:keys
プロパティを無視して結局は等価なキーボード入力を見つけ出す。
:keys string
このプロパティはそのメニューにたいする等価なキーボード入力として表示される文字列stringを指定する。string内ではドキュメント構文‘\\[...]’を使用できる。
:filter filter-fn
このプロパティはメニューアイテムを直接計算する手段を提供する。このプロパティの値filter-fnは引数が1つの関数で、呼び出し時の引数はreal-binding。この関数はかわりに使用するバインディングをリターンすること。
Emacs、メニューデータ構造の再表示や操作を行うすべてのタイミングでこの関数を呼び出すかもしれないので、いつ呼び出されても安全なように関数を記述すること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
メニューセパレーターはテキストを表示するかわりに、水平ラインでメニューをサブパーツに分割するメニューアイテムの一種です。メニューキーマップ内でセパレーターは以下のように見えるでしょう:
(menu-item separator-type)
ここでseparator-typeは2つ以上のダッシュで始まる文字列です。
もっとも単純なケースではダッシュだけでseparator-typeが構成されます。これはデフォルトのセパレーターを指定します(互換性のため""
と-
もセパレーターとみなされる)。
separator-typeにたいする他の特定の値は、異なるスタイルのセパレーターを指定します。以下はそれらのテーブルです:
"--no-line"
"--space"
実際のラインではない余分な垂直スペース。
"--single-line"
メニューのforegroundカラーの一重ライン。
"--double-line"
メニューのforegroundカラーの二重ライン。
"--single-dashed-line"
メニューのforegroundカラーの一重ダッシュライン。
"--double-dashed-line"
メニューのforegroundカラーの二重ダッシュライン。
"--shadow-etched-in"
3Dの窪んだ外観(3D sunken appearance)をもつ一重ライン。これはダッシュだけで構成されるセパレーターに使用されるデフォルト。
"--shadow-etched-out"
3Dの浮き上がった外観(3D raised appearance)をもつ一重ライン。
"--shadow-etched-in-dash"
3Dの窪んだ外観(3D sunken appearance)をもつ一重ダッシュライン。
"--shadow-etched-out-dash"
3Dの浮き上がった外観(3D raised appearance)をもつ一重ダッシュライン。
"--shadow-double-etched-in"
3Dの窪んだ外観をもつ二重ライン。
"--shadow-double-etched-out"
3Dの浮き上がった外観をもつ二重ライン。
"--shadow-double-etched-in-dash"
3Dの窪んだ外観をもつ二重ダッシュライン。
"--shadow-double-etched-out-dash"
3Dの浮き上がった外観をもつ二重ダッシュライン。
2連ダッシュの後にコロンを追加して1連ダッシュの後の単語の先頭の文字を大文字にすることによって、別のスタイルで名前を与えることもできます。つまり"--:singleLine"
は"--single-line"
と等価です。
メニューセパレーターにたいして:enable
や:visible
のようなキーワードを指定するために長い形式を使用できます。
(menu-item separator-type nil . item-property-list)
たとえば:
(menu-item "--" nil :visible (boundp 'foo))
いくつかのシステムとディスプレイツールキットは、これらすべてのセパレータータイプを実際に処理しません。サポートされていないタイプのセパレーターを使用すると、メニューはサポートされている似た種別のセパレーターを表示します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
同じコマンドを使用するものの有効条件が異なるメニューアイテムを作成できれば便利な場合が時折あります。Emacsでこれを行う最善の方法は拡張メニューアイテム(extended
menu
item)です。この機能が存在する以前にはエイリアスコマンドを定義して、それらをメニューアイテムで使用することによってこれを行っていました。以下はread-only-mode
にたいして2つのエイリアスを作成して、それらに異なる有効条件を与える例です:
(defalias 'make-read-only 'read-only-mode) (put 'make-read-only 'menu-enable '(not buffer-read-only)) (defalias 'make-writable 'read-only-mode) (put 'make-writable 'menu-enable 'buffer-read-only)
メニュー内でエイリアスを使用するときには、エイリアスではなく実際のコマンド名にたいする等価なキーバインディングを表示する方が便利な場合が多々あります(エイリアスは通常はメニュー自身を除いてキーバインディングをもたない)。これを要求するにはエイリアスシンボルのmenu-alias
プロパティに非nil
を与えます。したがって、
(put 'make-read-only 'menu-alias t) (put 'make-writable 'menu-alias t)
はmake-read-only
とmake-writable
にたいするメニューアイテムにread-only-mode
のキーバインディングを表示します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
メニューキーマップがメニューを生成する通常の方法は、それをプレフィクスキーの定義とすることです(Lispプログラムは明示的にメニューをポップアップしてユーザーの選択を受け取ることができる。ポップアップメニューを参照)。
プレフィクスキーがマウスイベントで終わる場合には、Emacsはユーザーがマウスで選択できるように可視なメニューをポップアップすることによってメニューキーマップを処理します。ユーザーがメニューアイテムをクリックしたときは、そのメニューアイテムによりもたらされるバインディングの文字やシンボルが何であれイベントが生成されます(メニューが複数レベルをもつ場合やメニューバー由来ならメニューアイテムは1連のイベントを生成するかもしれない)。
メニューのトリガーにbutton-downイベントを使用するのが最善な場合もしばしばあります。その場合にはユーザーはマウスボタンをリリースすることによってメニューアイテムを選択できます。
メニューキーマップがネストされたキーマップにたいするバインディングを含む場合、そのネストされたキーマップはサブメニュー(submenu)を指定します。それはネストされたキーマップのアイテム文字列によってラベル付けされれメニューアイテムをもち、そのアイテムをクリックすることによって指定されたサブメニューが自動的にポップアップされます。特別な例外としてメニューキーマップが単一のネストされたキーマップを含み、それ以外のメニューアイテムを含まなければ、そのメニューはネストされたキーマップの内容をサブメニューとしてではなく直接メニューに表示します。
しかしXツールキットのサポートなしでEmacsをコンパイルした場合、またはテキスト端末の場合にはサブメニューはサポートされません。ネストされたキーマップはメニューアイテムとして表示されますが、それをクリックしてもサブメニューは自動的にポップアップされません。サブメニューの効果を模倣したければ、ネストされたキーマップに‘@’で始まるアイテム文字列を与えることによってこれを行うことができます。これによりEmacsは別個のメニューペイン(menu pane)を使用してネストされたキーマップを表示します。‘@’の後の残りのアイテム文字列はそのペインのラベルです。XツールキットのサポートなしでEmacsをコンパイルした場合、またはメニューがテキスト端末で表示されている場合にはメニューペインは使用されません。この場合はアイテム文字列の先頭の‘@’は、メニューラベル表示時には省略されて他に効果はありません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
キーボードイベント(文字かファンクションキー)で終わるプレフィクスキーがメニューキーマップであるような定義をもつときには、そのキーマップはキーボードメニューのように動作します。ユーザーはキーボードでメニューアイテムを選択して次のイベントを指定します。
Emacsはエコーエリアにキーボードメニュー、そのマップのoverallプロンプト文字列、その後に選択肢(そのマップのバインディングのアイテム文字列)を表示します。そのバインディングを一度に全部表示できない場合、ユーザーはSPCをタイプして候補の次の行を確認できます。連続してSPCを使用するとメニューの最後に達して、その後は先頭へ巡回します(変数menu-prompt-more-char
はこのために使用する文字を指定する。デフォルトはSPC)。
ユーザーがメニューから望ましい候補を見つけたら、バインディングがその候補であるような対応する文字をタイプする必要があります。
この変数はメニューの次の行を確認するために使用する文字を指定する。初期値は32でこれはSPCのコード。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はメニューキーマップを定義する完全な例です。これはメニューバー内の‘Edit’メニューにサブメニュー‘Replace’を定義して、その定義内で拡張メニューフォーマット(拡張メニューアイテムを参照)を使用します。例ではまずキーマップを作成してそれに名前をつけています:
(defvar menu-bar-replace-menu (make-sparse-keymap "Replace"))
次にメニューアイテムを定義します:
(define-key menu-bar-replace-menu [tags-repl-continue]
'(menu-item "Continue Replace" tags-loop-continue
:help "Continue last tags replace operation"))
(define-key menu-bar-replace-menu [tags-repl]
'(menu-item "Replace in tagged files" tags-query-replace
:help "Interactively replace a regexp in all tagged files"))
(define-key menu-bar-replace-menu [separator-replace-tags]
'(menu-item "--"))
;; …
バインディングがそのシンボルのために作成されることに注意してください。これらのシンボルは定義されるキーシーケンス内の角カッコ内に記述されます。このシンボルはコマンド名と同じときもあれば異なることもあります。これらのシンボルはファンクションキーとして扱われますが、これらはキーボード上の実際のファンクションキーではありません。これらはメニュー自体の機能に影響しませんが、ユーザーがメニューから選択したときにエコーエリアにエコーされて、where-is
とapropos
の出力に現れます。
この例のメニューはマウスによる使用を意図しています。もしキーボードの使用を意図したメニュー、つまりキーボードイベントで終了するキーシーケンスにバインドされたメニューの場合には、メニューアイテムはキーボードでタイプできる文字、または本当のファンクションキーにバインドされるべきです。
定義が("--")
のバインディングはセパレーターラインです。実際のメニューアイテムと同様にセパレーターはキーシンボルをもち、この例ではseparator-replace-tags
です。1つのメニューが2つのセパレーターをもつ場合には、それらは2つの異なるキーシンボルをもたなければなりません。
以下では親メニュー内のアイテムとしてこのメニューがどのように表示されるかを記述しています:
(define-key menu-bar-edit-menu [replace] (list 'menu-item "Replace" menu-bar-replace-menu))
これはシンボルmenu-bar-replace-menu
自体ではなく、変数menu-bar-replace-menu
の値であるサブメニューキーマップを組み込むことに注意してください。menu-bar-replace-menu
はコマンドではないので親メニューアイテムにそのシンボルを使用するのは無意味です。
同じreplaceメニューをマウスクリックに割り当てたければ以下のようにしてこれを行うことができます:
(define-key global-map [C-S-down-mouse-1] menu-bar-replace-menu)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsは通常は各フレームの最上部にメニューバー(menu bar)を表示します。Menu Bars in The
GNU Emacs
Manualを参照してください。メニューバーのアイテムはアクティブキーマップ内で定義される偽りのファンクションキーmenu-bar
のサブコマンドです。
メニューバーにアイテムを追加するには、自分で偽りのファンクションキー(これをkeyと呼ぶこととする)を創作して、キーシーケンス[menu-bar
key]
にたいするキーバインディングを作成します。ほとんどの場合において、そのバインディングはメニューキーマップなので、メニューバーアイテム上でボタンを押下すると他のメニューに導かれます。
メニューバーにたいして同じファンクションキーを定義するアクティブなキーマップが1つ以上存在するとき、そのアイテムは一度だけ出現します。ユーザーがメニューバーのそのアイテムをクリックすると、そのアイテムのすべてのサブコマンド、すなわちグローバルサブコマンド、ローカルサブコマンド、マイナーモードサブコマンドが組み合わされた単一のメニューを表示します。
変数overriding-local-map
は通常はメニューバーのコンテンツを決定する際は無視されます。つまりメニューバーはoverriding-local-map
がnil
の場合にアクティブになるであろうキーマップから計算されます。アクティブなキーマップを参照してください。
以下はメニューバーのアイテムをセットアップする例です:
;; (プロンプト文字列とともに)メニューキーマップを作成して ;; それをメニューバーアイテムの定義にする (define-key global-map [menu-bar words] (cons "Words" (make-sparse-keymap "Words")))
;; メニュー内に具体的なサブコマンドを定義する
(define-key global-map
[menu-bar words forward]
'("Forward word" . forward-word))
(define-key global-map [menu-bar words backward] '("Backward word" . backward-word))
ローカルキーマップはグローバルキーマップにより作成されたメニューバーアイテムにたいして、同じ偽ファンクションキーをundefined
にリバインドしてキャンセルすることができます。たとえば以下はDiredが‘Edit’メニューバーアイテムを抑制する方法です:
(define-key dired-mode-map [menu-bar edit] 'undefined)
ここでedit
は‘Edit’メニューバーアイテムにたいしてグローバルキーマップにより使用される偽ファンクションキーです。グローバルメニューバーアイテムを抑制する主な理由は、モード特有のアイテム用にスペースを確保するためです。
メニューバーは通常はローカルマップで定義されるアイテムを終端にもつグローバルアイテムを表示する。
この変数は通常の順番による位置ではなく、メニューの最後に表示するアイテムのための偽ファンクションキーのリストを保持する。デフォルト値は(help-menu)
。したがって‘Help’メニューアイテムはメニューバーの最後、ローカルメニューアイテムの後に表示される。
このノーマルフックはメニューバーの再表示の前に、メニューバーのコンテンツ更新のための再表示によって実行される。コンテンツを変化させる必要があるメニューの更新に使用できる。このフックは頻繁に実行されるので、フックが呼び出す関数は通常は長い時間を要さないことを確実にするよう助言する。
Emacsはすべてのメニューバーアイテムの隣に、(もしそのようなキーバインディングが存在するなら)同じコマンドを実行するキーバインディングを表示します。これはキーバインディングを知らないユーザーにたいして有用なヒントを与える役目をもちます。コマンドが複数のバインディングをもつ場合、Emacsは通常は最初に見つけたバインディングを表示します。コマンドのシンボルプロパティ:advertised-binding
に割り当てることによって特定のキーバインディングを指定できます。ドキュメント内でのキーバインディングの置き換えを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ツールバー(tool bar)とはフレームの最上部、メニューバー直下にあるクリック可能なアイコンの行のことです。Tool Bars in The GNU Emacs Manualを参照してください。Emacsは通常はグラフィカルなディスプレイ上でツールバーを表示します。
各フレームではツールバーに何行分の高さを割り当てるかをフレームパラメーターtool-bar-lines
で制御します。値0はツールバーを抑制します。値が非0でauto-resize-tool-bars
が非nil
なら、指定されたコンテンツを維持するのに必要な分、ツールバーは拡大縮小されます。値がgrow-only
ならツールバーは自動的に拡大されますが、自動的に縮小はされません。
ツールバーのコンテンツは、(メニューバーが制御されるのと似た方法により)tool-bar
と呼ばれる偽りのファンクションキーに割り当てられるメニューキーマップにより制御されます。したがって以下のようにdefine-key
を使用してツールバーアイテムを定義します。
(define-key global-map [tool-bar key] item)
ここでkeyはそのアイテムを他のアイテムと区別する偽ファンクションキー、itemはそのアイテムを表示する方法とアイテムの振る舞いを示すメニューアイテムキーバインディングです(拡張メニューアイテムを参照)。
メニューキーマップの通常のプロパティ:visible
、:enable
、:button
、:filter
はツールバーバインディングでも有用で、いずれのプロパティも通常通りの意味をもちます。アイテム内のreal-bindingはキーマップではなくコマンドでなければなりません。言い換えるとこれはツールバーアイコンをプレフィクスキーとして定義するようには機能しないということです。
:help
プロパティは、そのアイテム上にマウスがある間表示するhelp-echo文字列を指定します。これはテキストプロパティhelp-echo
と同じ方法で表示されます(Help displayを参照)。
これらに加えて:image
プロパティも使用するべきでしょう。ツールバー内にイメージを表示するにはこのプロパティを使用します。
:image image
imageは単一イメージ様式(single image specification)か4ベクターイメージ様式(vector of four image specifications)で指定する(イメージを参照)。4ベクターを使用する場合には状況に応じて以下のいずれかが使用される:
アイテムが有効かつ選択されているときに使用。
アイテムが有効かつ未選択のときに使用。
アイテムが無効かつ選択されているときに使用。
アイテムが無効かつ未選択のときに使用。
GTK+バージョンとNSバージョンのEmacsは、無効および/または未選択のイメージをitem0から自動的に計算するので、item1からitem3は無視されます。
imageが単一イメージ様式なあ、Emacsはそのイメージにエッジ検出アルゴリズム(edge-detection algorithm)を適用することによってツールバーの無効な状態のボタンを描画します。
:rtl
プロパティには右から左に記述する言語のためのイメージ候補を指定します。これをサポートするのは現在のところGTK+バージョンのEmacsだけです。
メニューバーと同様、ツールバーはセパレーター(メニューセパレーターを参照)を表示できます。ツールバーのセパレーターは水平ラインではなく垂直ラインであり、1つのスタイルだけがサポートされます。これらはツールバーキーマップ内では(menu-item
"--")
エントリーで表されます。ツールバーのセパレーターでは、:visible
のようなプロパティはサポートされません。GTK+とNextstepのツールバーでは、セパレーターはネイティブに描画されます。それ以外ではセパレーターは垂直ラインイメージを使用して描画されます。
デフォルトツールバーはコマンドシンボルのmode-class
プロパティにspecial
をもつメジャーモードにたいしては、編集に特化したアイテムは表示しないよう定義されています(メジャーモードの慣習を参照)。メジャーモードは、ローカルマップ内でバインディング[tool-bar
foo]
によって、グローバルバーにアイテムを追加するかもしれません。デフォルトツールバーの多くを適宜流用するのができないかもしれないので、デフォルトツールバーを完全に置き換えることは、いくつかのメジャーモードにとっては有意義です。デフォルトバインディングでtool-bar-map
を通じてインダイレクトすることにより、これを簡単に行うことができます。
デフォルトではグローバルマップは[tool-bar]
を以下のようにバインドする:
(global-set-key [tool-bar] `(menu-item ,(purecopy "tool bar") ignore :filter tool-bar-make-keymap))
関数tool-bar-make-keymap
は、変数tool-bar-map
の値より順番に実際のツールバーマップをダイナミックに継承する。したがって通常はそのマップを変更することにより、デフォルト(グローバル)ツールバーを調整すること。Infoモードのようないくつかのメジャーモードは、tool-bar-map
をバッファーローカルにして、それに異なるキーマップをセットすることによりグローバルツールバーを完全に置き換える。
以下のようなツールバーアイテムを定義するのに便利な関数があります。
この関数はtool-bar-map
を変更することにより、ツールバーにアイテムを追加する。使用するイメージはiconにより定義され、これはfind-image
に配置されたXPM、XBM、PBMのイメージファイルの拡張子を除いたファイル名(basename)である。たとえばカラーディスプレイ上では、値に‘"exit"’を与えるとexit.xpm、exit.pbm、exit.xbmの順に検索されるだろう。モノクロディスプレイでは検索は‘.pbm’、‘.xbm’、‘.xpm’の順になる。使用するバインディングはコマンドdefで、keyはプレフィクスキーマップ内の偽ファンクションキーである。残りの引数propsはメニューアイテム仕様に追加する追加のプロパティリスト要素である。
あるローカルマップ内にアイテムを定義するためには、この関数呼び出しの周囲のlet
でtool-bar-map
をバインドする:
(defvar foo-tool-bar-map (let ((tool-bar-map (make-sparse-keymap))) (tool-bar-add-item …) … tool-bar-map))
この関数は既存のメニューバインディングと矛盾しないツールバーアイテムの定義に有用。commandのバインディングはmap(デフォルトはglobal-map
)内よりルックアップ(lookup:
照合)され、iconにたいするイメージ仕様はtool-bar-add-item
と同じ方法で見つけ出される。結果のバインディングはtool-bar-map
に配置されるので、この関数の使用はグローバルツールバーアイテムに限定される。
mapには[menu-bar]
にバインドされた適切なキーマップが含まれていなければならない。残りの引数propsはメニューアイテム仕様に追加する追加のプロパティリスト要素。
この関数は非グローバルツールバーアイテムの作成に使用される。in-mapに定義を作成するローカルマップを指定する以外はtool-bar-add-item-from-menu
と同じように使用する。引数from-mapはtool-bar-add-item-from-menu
のmapと同様。
この変数が非nil
なら定義されたすべてのツールバーアイテムを表示するためにツールバーは自動的にリサイズされるが、そのフレーム高さの1/4を超えてリサイズされることはない。
値がgrow-only
ならツールバーは自動的に拡張されるが縮小はされない。ツールバーを縮小するためにユーザーはC-lをエンターしてフレームを再描画する必要がある。
GTKやNextstepとともにEmacsがビルドされた場合、ツールバーが表示できるのは1行だけでありこの変数に効果はない。
この変数が非nil
ならツールバーアイテム上をマウスが通過したとき、浮き上がった形式(raised form)で表示される。
この変数はツールバーアイテムの周囲に追加する余白(extra margin)を指定する。値はピクセル数を整数で指定する。デフォルトは4。
この変数はツールバーアイテムの影(shadow)を指定する。値はピクセル数を整数で指定する。デフォルトは1。
この変数はツールバーエリアの下に描画するボーダー高さを指定する。値が整数なら高さのピクセル数。値がinternal-border-width
(デフォルト)かborder-width
のいずれかなら、ツールバーのボーダー高さはそのフレームの対応するパラメーターとなる。
シフトやメタ等の修飾キーを押下した状態でのツールバーアイテムのクリックに特別な意味を付与できます。偽りのファンクションキーを通じて元のアイテムに関連する追加アイテムをセットアップすることによって、これを行うことができます。より具体的には追加アイテムは、元のアイテムの命名に使用されたのと同じ偽ファンクションキーの修飾されたバージョンを使用するべきです。
つまり元のアイテムが以下のように定義されていれば、
(define-key global-map [tool-bar shell] '(menu-item "Shell" shell :image (image :type xpm :file "shell.xpm")))
シフト修飾とともに同じツールバーイメージをクリックしたときを以下のような方法で定義することができます:
(define-key global-map [tool-bar S-shell] 'some-command)
ファンクションキーに修飾を追加する方法についての詳細な情報は、ファンクションキーを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
既存のメニューに新たなアイテムを挿入するときは、そのメニューの既存のアイテムの中の特定の位置にアイテムを追加したいと思うかもしれません。define-key
を使用してアイテムを追加すると、そのアイテムは通常はメニューの先頭に追加されます。メニュー内の他の位置にアイテムを追加するにはdefine-key-after
を使用します:
define-key
と同じようにmap内にkeyにたいする値bindingのバインディングを定義するが、map内でのバインディング位置はイベントafterのバインディングの後になる。引数keyは長さ1
— 1要素だけのベクターか文字列にすること。しかしafterは単一のイベント型 —
シーケンスではないシンボルか文字にすること。新たなバインディングはafterのバインディングの後に追加される。afterがt
または省略された場合には、新たなバインディングはそのキーマップの最後に追加される。しかし新たなバインディングは継承されたすべてのキーマップの前に追加される。
以下は例:
(define-key-after my-menu [drink] '("Drink" . drink-command) 'eat)
これは偽ファンクションキーDRINKのバインディングを作成して、EATのバインディングの直後に追加する。
以下はShellモードの‘Signals’メニュー内のアイテムbreak
の後に‘Work’と呼ばれるアイテムを追加する方法:
(define-key-after (lookup-key shell-mode-map [menu-bar signals]) [work] '("Work" . work-command) 'break)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のマクロはポップアップメニューおよび/またはメニューバーメニューを定義する便利な方法を提供します。
このマクロはmenuにより与えるコンテンツのポップアップメニューおよび/またはメニューバーサブメニューを定義する。
symbolが非nil
なら、それはシンボルである。その場合、このマクロはドキュメント文字列docをもつ、メニューをポップアップ(ポップアップメニューを参照)する関数としてsymbolを定義する。symbolはクォートしないこと。
symbolの値とは関係なく、mapsがキーマップならメニューはメニューバーのトップレベルのメニュー(メニューバー Barを参照)としてmapsに追加される。これにはキーマップのリストも指定でき、その場合メニューはそれらのキーマップに個別に追加される。
menuの最初の要素は文字列でなければならず、それはメニューラベルの役割をもつ。値には以下のキーワード/引数ペアーが任意の個数続くかもしれない:
:filter function
functionは1つの引数(他のメニューアイテムのリスト)で呼び出される関数でなければならず、メニュー内に表示される実際のアイテムをリターンする。
:visible include
includeには式を指定する。その式がnil
に評価されるとメニューは不可視になる。:included
は:visible
にたいするエイリアス。
:active enable
enableは式を指定する。その式がnil
に評価されるとメニューは選択不可になる。:enable
は:active
にたいするエイリアス。
menu内の残りの要素はメニューアイテム。
メニューアイテムには3要素のベクター[name callback
enable]
を指定できる。ここでnameはメニューアイテム名(文字列)、callbackはアイテム選択時に実行するコマンドか評価される式。enableが式でnil
に評価されると、そのアイテムの選択は無効になる。
かわりにメニューアイテムは以下の形式をもつことができる:
[ name callback [ keyword arg ]... ]
ここでnameとcallbackは上記と同じ意味をもち、オプションのkeywordとargの各ペアーは以下のいずれかである:
:keys keys
keysはメニューアイテムにたいする等価なキーボード入力(文字列)である。等価なキーボード入力は自動的に計算されるので通常は必要ない。keysは表示前にsubstitute-command-keys
により展開される(ドキュメント内でのキーバインディングの置き換えを参照)。
:key-sequence keys
keysは最初にメニューを表示される際に、Emacsを高速化するヒントになる。等価なキーボード入力がないことが既知ならnil
を指定すること。それ以外ならメニューアイテムにたいする等価なキーボード入力を指定する文字列かベクターを指定すること。
:active enable
enableには式を指定する。その式がnil
に評価されるとアイテムは選択不可になる。enableは:active
にたいするエイリアス。
:visible include
includeには式を指定する。その式がnil
に評価されるとアイテムは不可視になる。:included
は:visible
にたいするエイリアス。
:label form
formはメニューアイテムのラベル(デフォルトはname)の役目をもつ値を取得するために表示される式である。
:suffix form
formは動的に評価される式であり、値はメニューエントリーのラベルに結合される。
:style style
styleはメニューアイテムの型を記述するシンボルであり、toggle
(チェックボックス)、radio
(ラジオボタン)、またはそれ以外(通常のメニューアイテムであることを意味する)のいずれかである。
:selected selected
selectedには式を指定し、その式の値が非nil
のときはチェックボックスまたはラジオボタンが選択状態になる。
:help help
helpはメニューアイテムを説明する文字列。
かわりにメニューアイテムに文字列を指定できる。その場合には文字列は選択不可なテキストとしてメニューに表示される。ダッシュから構成される文字列はセパレーターとして表示される(メニューセパレーターを参照)
かわりにメニューアイテムにmenuと同じフォーマットのリストを指定できる。これはサブメニューとなる。
以下はeasy-menu-define
を使用してメニューバー Bar内で定義したメニューと同等なメニューを定義する例:
(easy-menu-define words-menu global-map "単語単位コマンドにたいするメニュー" '("Words" ["Forward word" forward-word] ["Backward word" backward-word]))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
モード(mode)とはEmacsをカスタマイズする定義セットであり、編集時にオン/オフを切り替えることができます。モードには2つの種類があります。メジャーモード(major modes)とは互いに排他なモードであり、特定の種類のテキストの編集にたいして使用されます。マイナーモード(minor modes)はユーザーが個別に有効にすることができる機能を提供します。
このチャプターではメジャーモードとマイナーモードを記述する方法、それらをモードラインに示す方法、そしてそれらのモードがユーザーが提供するフックを実行する方法を説明します。キーマップ(keymaps)や構文テーブル(syntax tables)のような関連するトピックについてはキーマップと構文テーブルを参照してください。
22.1 フック | フックの使用法とフックを提供するコードの記述方法。 | |
22.2 メジャーモード | メジャーモードの定義。 | |
22.3 マイナーモード | マイナーモードの定義。 | |
22.4 モードラインのフォーマット | モードラインに表示されるテキストのカスタマイズ。 | |
22.5 Imenu | バッファーで作成された定義のメニューを提供する。 | |
22.6 Font Lockモード | モードが構文に応じてテキストをハイライトする方法。 | |
22.7 コードの自動インデント | メジャーモードにたいするインデントをEmacsに伝える方法。 | |
22.8 Desktop Saveモード | Emacsセッション間でモードがバッファー状態を保存する方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フック(hook)とは既存のプログラムから特定のタイミングで呼び出される関数(複数可)を格納できる変数のことです。Emacsはカスタマイズ用にフックを提供します。ほとんどの場合にはinitファイル内(initファイルを参照)でフックをセットアップしますが、Lispプログラムもフックをセットできます。標準的なフック変数のリストは標準的なフックを参照してください。
Emacsのほとんどのフックはノーマルフック(normal hooks)です。これらの変数は、引数なしで呼び出される関数のリストを含んでいます。慣習により名前が‘-hook’で終わるフックは、そのフックがノーマルフックであることを意味します。わたしたちは一貫した方法でフックを使用できるように、すべてのフックが可能な限りノーマルフックとなるよう努力しています。
すべてのメジャーモードコマンドは、初期化の最終ステップの1つとして、モードフック(mode
hook)と呼ばれるノーマルフックを実行するとみなされます。これによってそのモードですでに作成されたバッファーローカル変数割り当てをオーバーライドすることにより、ユーザーがそのモードの動作をカスタマイズするのが簡単になります。ほとんどのマイナーモード関数も最後にモードフックを実行します。しかしフックは他のコンテキストでも使用されます。たとえばフックsuspend-hook
は、Emacsが自身をサスペンド(Emacsのサスペンドを参照)する直前に実行されます。
フックにフック関数を追加するにはadd-hook
(フックのセットSetting Hooksを参照)を呼び出す方法が推奨されています。フック関数にはfuncall
(関数とは?を参照)が受け入れる任意の種類の関数を指定できます。ほとんどのフック変数の初期値はvoidです。add-hook
はこれを扱う方法を知っています。add-hook
によりグローバルフックやバッファーローカルフックのいずれも追加することが可能です。
フック変数の名前が‘-hook’で終わらなければ、それが恐らくアブノーマルフック(abnormal
hook)であることを示しています。これはフック関数が引数とともに呼ぶ出されること、または何らかの方法によってそのリターン値が使用されることを意味します。その関数の呼び出し方はそのフックのドキュメントに記載されています。アブノーマルフックとして関数を追加するためにadd-hook
を使用できますが、その関数はフック呼び出しの慣習にしたがって記述しななければなりません。慣習によりアブノーマルフックの名前の最後は‘-functions’です。
変数の名前が‘-function’で終われば、その値は関数のリストではなく単一の関数です。add-hook
を単一関数フックのように修正して使用することはできないので、かわりにadd-function
を使用します(Emacs Lisp関数にたいするアドバイスを参照)。
22.1.1 フックの実行 | フックの実行方法。 | |
22.1.2 フックのセットSetting Hooks | 関数をフックに登録、削除する方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではノーマルフックを実行するために使用されるrun-hooks
について説明します。またさまざまな種類のアブノーマルフックを実行する関数についても説明します。
この関数は引数として1つ以上のノーマルフック変数名を受け取って、各フックを順に実行する。引数はそれぞれノーマルフック変数であるようなシンボルであること。これらの引数は指定された順に処理される。
フック変数の値が非nil
ならその値は関数のリストであること。run-hooks
はすべての関数を引数なしで1つずつ呼び出す。
フック変数の値には、単一の関数(ラムダ式、またはシンボルの関数定義)も指定でき、その場合run-hooks
はそれを呼び出す。しかしこの使い方は時代遅れである。
フック変数がバッファーローカルならグローバル変数のかわりにそのバッファーローカル変数が使用される。しかしそのバッファーローカル変数が要素t
を含む場合には、そのグローバルフック変数も同様に実行されるだろう。
この関数は、hook内のすべての関数に1つの引数argsを渡して呼び出すことによってアブノーマルフックを実行する。
この関数は各フック関数を順に呼び出すことによりアブノーマルフック関数を実行し、それらのうち1つがnil
をリターンして失敗すると停止する。それぞれのフック関数は引数としてargsを渡される。この関数はフック関数の1つが失敗して停止したらnil
、それ以外は非nil
値をリターンする。
この関数は各フック関数を順に呼び出すことによりアブノーマルフック関数を実行して、それらのうち1つが非nil
値をリターンして成功したら停止する。それぞれのフック関数は引数としてargsを渡される。この関数はフック関数の1つが失敗して停止したらその値、それ以外はnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はLisp Interactionモードのときにモードフックを使用してAuto Fillモードをオンに切り替える例です:
(add-hook 'lisp-interaction-mode-hook 'auto-fill-mode)
この関数はフック変数に関数functionを追加する手軽な方法である。ノーマルフックと同じようにアブノーマルフックにたいしてもこの関数を使用できる。functionには正しい数の引数を受け付ける任意のLisp関数を指定できる。たとえば、
(add-hook 'text-mode-hook 'my-text-hook-function)
はtext-mode-hook
と呼ばれるフックにmy-text-hook-function
を追加する。
hook内にfunctionがすでに存在する場合(比較にはequal
を使用)、add-hook
は2回目の追加を行わない。
functionのプロパティpermanent-local-hook
が非nil
ならkill-all-local-variables
(またはメジャーモードを変更しても)はそのフック変数のローカル値から関数を削除しない。
ノーマルフックにたいしてフック関数は実行される順序に無関係であるようにデザインされるべきである。順序への依存はトラブルを招く。とはいえその順序は予測可能である。functionは通常はフックリストの先頭に追加されるので、(他のadd-hook
呼び出しがなければ)それは最初に実行される。オプション引数appendが非nil
なら、新たなフック関数はフックリストの最後に追加されて、実行されるのも最後になる。
add-hook
はhookがvoidのとき、または値が単一の関数の場合には、値を関数リストにセットまたは変更してそれらを扱うことができる。
localが非nil
なら、グローバルフックリストではなくバッファーローカルフックリストにfunctionを追加する。これはフックをバッファーローカルにして、そのバッファーローカルな値にt
を追加する。バッファーローカルな値へのt
の追加は、ローカル値と同じようにデフォルト値でもフック関数を実行するためのフラグである。
この関数はフック変数hookからfunctionを削除する。これはequal
を使用してfunctionとhook要素を比較するので、その比較はシンボルとラムダ式の両方で機能する。
localが非nil
なら、それはグローバルフックリストではなくバッファーローカルフックリストからfunctionを削除する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
メジャーモードは特定の種類のテキスト編集にEmacsを特化します。すべてのバッファーは一度に1つのメジャーモードをもちます。すべてのメジャーモードはメジャーモードコマンド(major mode command)に関連付けられていて、そのコマンド名は‘-mode’で終わるべきです。このコマンドはローカルキーマップのようなさまざまなバッファーローカル変数をセットすることにより、カレントバッファーないでそのモードに切り替える配慮をします。メジャーモードの慣習を参照してください。
Fundamentalモードと呼ばれるモードはもっとも特化されていないメジャーモードであり、モード特有な定義や変数セッティングをもちません。
これはFundamentalモードにたいするメジャーモードコマンドである。他のモードコマンドと異なり、このモードはカスタマイズしてはならないことになっているので、モードフックは何も実行されない(メジャーモードの慣習を参照)。
メジャーモードを記述するもっとも簡単な方法はマクロdefine-derived-mode
を使用する方法です。これは既存のメジャーモードを変形して新たなモードをセットアップします。派生モードの定義を参照してください。define-derived-mode
は多くのコーディング規約を自動的に強要するので、たとえ新たなモードが他のモードから明示的に派生されない場合でも、わたしたちはdefine-derived-mode
の使用を推奨します。派生元とするための一般的なモードについては基本的なメジャーモードを参照してください。
標準的なGNU EmacsのLispディレクトリーツリーには、いくつかのメジャーモードがtext-mode.el、texinfo.el、lisp-mode.el、rmail.elのようなファイルとして含まれています。モードの記述方法を確認するために、これらのライブラリーを学ぶことができます。
この変数のバッファーローカル値はカレントのメジャーモードにたいするシンボルを保持する。この変数のデフォルト値は新たなバッファーにたいするデフォルトのメジャーモードを保持する。標準的なデフォルト値はfundamental-mode
である。
デフォルト値がnil
なら、C-x b
(switch-to-buffer
)のようなコマンドを通じてEmacsが新たなバッファーを作成したとき、新たなバッファーは以前カレントだったバッファーのメジャーモードになる。例外として以前のバッファーのメジャーモードのシンボルプロパティmode-class
が値special
をもつ場合には、新たなバッファーはFundamentalモードになる(メジャーモードの慣習を参照)。
22.2.1 メジャーモードの慣習 | キーマップなどにたいするコーディング規約。 | |
22.2.2 Emacsがメジャーモードを選択する方法 | Emacsが自動的にメジャーモードを選択する方法。 | |
22.2.3 メジャーモードでのヘルプ入手 | モードの使用方法の探し方。 | |
22.2.4 派生モードの定義 | 他のメジャーモードにもとづき新たなメジャーモードを定義する。 | |
22.2.5 基本的なメジャーモード | 他のモードからよく派生元とされるモード。 | |
22.2.6 モードフック | メジャーモード関数の最後に実行されるフック。 | |
22.2.7 Tabulated Listモード | 表形式データを含むバッファーにたいする親モード。 | |
22.2.8 ジェネリックモード | コメント構文とFont Lockモードをサポートするシンプルなメジャーモードの定義。 | |
22.2.9 メジャーモードの例 | TextモードとLispモード。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
メジャーモードにたいするすべてのコードはさまざまなコーディング規約にしたがうべきであり、それらの規約にはローカルキーマップおよび構文テーブルの初期化、関数名や変数名、フックにたいする規約が含まれます。
define-derived-mode
マクロを使用すれば、これらの規約を自動的に配慮します。派生モードの定義を参照してください。FundamentalモードはEmacsのデフォルト状態を表すモードなので、これらの規約が該当しないことに注意してください。
以下の規約リストはほんの一部です。一般的にすべてのメジャーモードはEmacs全体が首尾一貫するよう、他のEmacsメジャーモードとの一貫性を目指すべきです。ここでこの問題を洗い出すすべての想定される要点をリストするのは不可能です。自身の開発するメジャーモードが通常の規約を逸脱する領域を示すような場合には、Emacs開発者は互換性を保つようにしてください。
そのユーザー自身のキーバインディングに自動的に適合してヘルプが表示されるように、ドキュメント文字列に特別なドキュメントサブストリング‘\[command]’、‘\{keymap}’、‘\<keymap>’を含めるとよいかもしれない。ドキュメント内でのキーバインディングの置き換えを参照のこと。
kill-all-local-variables
を呼び出すことによって開始すること。これはノーマルフックchange-major-mode-hook
を実行してから、前のメジャーモードで効力のあったバッファーローカル変数を解放する。バッファーローカルなバインディングの作成と削除を参照のこと。
major-mode
にメジャーモードコマンドのシンボルをセットすること。これはdescribe-mode
がプリントするドキュメントを探す手掛かりとなる。
mode-name
にそのモードの“愛称(pretty
name)”をセットすること(これは通常は文字列だが他の利用可能な形式についてはモードラインのデータ構造を参照)。このモード名はモードラインに表示される。
indent-line-function
に適切な関数をセットするとともに、インデント用のその他の変数をカスタマイズするべきだろう。コードの自動インデントを参照のこと。
use-local-map
を呼び出すこと。詳細はアクティブなキーマップを参照されたい。
このキーマップはmodename-mode-map
という名前のグローバル変数に永続的に格納されること。そのモードを定義するライブラリーは、通常はこの変数をセットする。
モード用のキーマップ変数をセットアップするコードの記述する方法に関するアドバイスは堅牢な変数定義のためのヒントを参照されたい。
メジャーモードはM-n、M-p、M-sなどのキーもリバインドできる。M-nとM-pにたいするバインディングは、通常は 前方か後方への移動を意味するような類のものであるべきだが、これが必ずしもカーソル移動を意味する必要はない。
そのモードにより適した方法でテキストに同じ処理を行うコマンドを提供する場合に、メジャーモードが標準的なキーシーケンスをリバインドするのは正当性がある。たとえばプログラム言語を編集するためのメジャーモードは、その言語にとってより良く機能する方法で、C-M-aを関数の先頭に移動するように再定義できる。
ある標準的なキーシーケンスの標準的な意味がそのモードではほとんど役に立たないような場合にも、メジャーモードが標準的なキーシーケンスをリバインドする正当性がある。たとえばM-rの標準的な意味はミニバッファーではほとんど使用されないので、このキーシーケンスをリバインドする。テキストの自己挿入を許さないDiredやRmailのようなメジャーモードがアルファベット文字や、その他のプリント文字を特別なコマンドに再定義することには正当性がある。
modename-mode-syntax-table
という名前の変数にそれを格納すること。構文テーブルを参照されたい。
modename-mode-abbrev-table
という名前の変数にそれを格納すること。メジャーモードコマンドが自身で何らかのabbrevを定義する場合には、define-abbrev
のsystem-flag引数にt
を渡すこと。abbrevの定義を参照されたい。
font-lock-defaults
にバッファーローカルな値をセットすることによって、Font
Lockモードにたいしてハイライトする方法を指定すること(Font Lockモードを参照)。
imenu-generic-expression
、imenu-prev-index-position-function
とimenu-extract-index-name-function
の2つの変数、または変数imenu-create-index-function
にバッファーローカルな値をセットすることによってImenuがバッファー内の定義やセクションを探す方法を指定すること(Imenuを参照)。
eldoc-documentation-function
にローカル値を指定して、ElDocモードがそのモードを処理する方法を指定できる。
completion-at-point-functions
に1つ以上のバッファーローカルエントリーを追加することにより、さまざまなキーワードの補完方法を指定できる。通常バッファーでの補完を参照のこと。
make-variable-buffer-local
ではなくメジャーモードコマンド内でmake-local-variable
を使用すること。関数make-variable-buffer-local
はそれ以降にカスタマイズ変数をセットするすべてのバッファーにたいしてその変数をローカルにして、そのモードを使用しないバッファーにたいしても影響があるだろう。そのようなグローバルな効果はモードにとって好ましくない。バッファーローカル変数を参照のこと。
稀な例外としてLispパッケージ内でmake-variable-buffer-local
を使用する唯一の正当な方法は、そのパッケージ内でのみ使用される変数にたいして使用をする場合である。他のパッケージにより使用される変数にたいしてこの関数を使用すると競合が発生するだろう。
modename-mode-hook
という名前のノーマルなモードフック(mode
hook)をもつこと。メジャーモードコマンドはrun-mode-hooks
の呼び出しを一番最後に行うこと。これはノーマルフックchange-major-mode-after-body-hook
、モードフック、その後にafter-change-major-mode-hook
を実行する。モードフックを参照のこと。
define-derived-mode
マクロの使用だが必須ではない。そのようなモードはdelay-mode-hooks
フォーム内で親のモードコマンドを呼び出すこと(define-derived-mode
は自動的にこれを行う)。派生モードの定義とモードフックを参照されたい。
change-major-mode-hook
にたいしてバッファーローカル値をセットアップできる(バッファーローカルなバインディングの作成と削除を参照)。
mode-class
という名前のプロパティに値special
をputすること:
(put 'funny-mode 'mode-class 'special)
これはEmacsにたいしてカレントバッファーがFunnyモードのときに新たなバッファーを作成したとき、たとえmajor-mode
のデフォルト値がnil
であってもそのバッファーをFunnyモードにしないよう指示する。デフォルトではmajor-mode
にたいする値nil
は新たなバッファー作成時にカレントバッファーのメジャーモードを使用することを意味するが(Emacsがメジャーモードを選択する方法を参照)、special
なモードにたいしてはかわりにFundamentalモードが使用される。Dired、Rmail、Buffer
Listのようなモードはこの機能を使用する。
関数view-buffer
はmode-classがspecialであるようなバッファーではViewモードを有効にしない。そのようなモードは通常は自身でViewに相当するバインディングを提供するからである。
define-derived-mode
マクロは親モードがspecialなら、自動的に派生モードをspecialにマークする。親モードでspecialモードが有用ならそれを継承したモードでも有用だろう。基本的なメジャーモードを参照のこと。
auto-mode-alist
に要素を追加する。autoload用にモードコマンドを定義する場合には、autoload
を呼び出すのと同じファイル内にその要素を追加すること。モードコマンドにたいしてautoload
cookieを使用する場合はに、その要素を追加するフォームにたいしてもautoload cookieを使用できる(autoload cookieを参照)。モードコマンドをautoloadしない場合には、モード定義を含むファイル内で要素を追加すれば十分である。
defvar
かdefcustom
を使用する(グローバル変数の定義を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはファイルをvisitするとき、ファイル名やファイル自体の内容などの情報を元にそのバッファーにたいするメジャーモードを選択します。またファイルのテキスト内で指定されたローカル変数も処理します。
この関数はカレントバッファーにたいして適切なメジャーモード、およびバッファーローカル変数のバインディングを設定する。これはまずset-auto-mode
(以下参照)を呼び出して、その後にhack-local-variables
を実行してパース処理を行い、そのファイルのローカル変数(ファイルローカル変数を参照)を適切にバインドまたは評価する。
normal-mode
のfind-file引数が非nil
なら、normal-mode
はfind-file
関数が自身を呼び出したとみなす。この場合、normal-mode
はそのファイル内の‘-*-’行、またはファイルの最後にあるローカル変数を処理できる。これを行うかどうかは変数enable-local-variables
が制御する。ファイルのローカル変数セクションの構文はLocal Variables in Files in The GNU Emacs Manualを参照のこと。
インタラクティブにnormal-mode
を実行すると、引数find-fileは通常はnil
である。この場合、normal-mode
は無条件に任意のファイルローカル変数を処理する。
この関数はメジャーモードを選択するためにset-auto-mode
を呼び出す。この関数がモードを特定しなければ、そのバッファーのmajor-mode
(以下参照)のデフォルト値により決定されるメジャーモードに留まる。
normal-mode
はメジャーモードコマンド呼び出しの周囲にcondition-case
を使用するのでエラーはcatchされて、‘File
mode specification error’とともに元のエラーメッセージがその後に報告される。
この関数はカレントバッファーにたいして適切なメジャーモードを選択する。この選択は関数自身の(優先順位による)決定にもとづく。優先順位は‘-*-’行、ファイル終端近傍の‘mode:’ローカル変数すべて、‘#!’行(interpreter-mode-alist
を使用)、バッファーの先頭のテキスト(magic-mode-alist
を使用)、最後がvisitされるファイル名(auto-mode-alist
を使用)の順である。How Major Modes are Chosen in The GNU Emacs
Manualを参照のこと。enable-local-variables
がnil
ならset-auto-mode
は‘-*-’行、およびファイル終端近傍にたいするmodeタグのチェックを何も行わない。
モード特定のためにファイル内容をスキャンするのがふさわしくないファイルタイプがいくつかある。たとえばtarアーカイブファイルの終端付近に特定のファイルにたいしてモードを指定するローカル変数セクションをもつアーカイブメンバーファイルがたまたま含まれているかもしれない。こがそのファイルを含んだtarファイルに適用されるべきではないだろう。同様にtiffイメージファイルが‘-*-’パターンにマッチするように見える行を最初の行に偶然含むかもしれない。これらの理由により、これらのファイル拡張子はいずれもinhibit-local-variables-regexps
リストのメンバーになっている。Emacsが、(モード指定に限らず)ファイルから任意の種類のローカル変数を検索することを防ぐには、このリストにパターンを追加する。
keep-mode-if-sameが非nil
なら、すでにそのバッファーが適切なメジャーモードをもつときにこの関数はモードコマンドを呼び出さない。たとえばset-visited-file-name
はユーザーがセットしたかもしれないバッファーローカル変数をkillすることを防ぐために、これをt
にセットする。
この関数はbufferのメジャーモードをmajor-mode
のデフォルト値にセットする。major-mode
がnil
なら、(それが適切なら)カレントバッファーのメジャーモードを使用する。例外としてbufferの名前が*scratch*なら、モードをinitial-major-mode
にセットする。
バッファーを作成する低レベルのプリミティブはこの関数を使用しないが、switch-to-buffer
やfind-file-noselect
のような中位レベルのコマンドは、バッファー作成時は常にこの関数を使用する。
この変数の値は*scratch*バッファーの初期のメジャーモードを決定する。値はメジャーモードコマンドであるようなシンボルであること。デフォルト値はlisp-interaction-mode
。
この変数は‘#!’行内のコマンドインタープリターを指定するスクリプトにたいして使用するメジャーモードを指定する。変数の値は(regexp
.
mode)
という形式の要素をもつalistである。これはそのファイルが\\`regexp\\'
にマッチするインタープリターを指定する場合にはmodeを使用することを意味する。たとえばデフォルト要素の1つは("python[0-9.]*"
. python-mode)
である。
この変数の値は(regexp
function)
という形式の要素をもつalistである。ここでregexpは正規表現、functionは関数、またはnil
である。ファイルをvisitした後にバッファーの先頭のテキストがregexpにマッチした場合、functionが非nil
ならset-auto-mode
はfunctionを呼び出す。functionがnil
ならauto-mode-alist
がモードを決定する。
これはmagic-mode-alist
と同様に機能するが、そのファイルにたいしてauto-mode-alist
がモードを指定しない場合だけ処理される点が異なる。
この変数はファイル名パターン(正規表現)と対応するメジャーモードコマンドの連想配列を含む。ファイル名パターンは通常は‘.el’や‘.c’のようなサフィックスをテストするが必須ではない。このalistの通常の要素は(regexp
. mode-function)
のようになる。
たとえば、
(("\\`/tmp/fol/" . text-mode) ("\\.texinfo\\'" . texinfo-mode) ("\\.texi\\'" . texinfo-mode)
("\\.el\\'" . emacs-lisp-mode) ("\\.c\\'" . c-mode) ("\\.h\\'" . c-mode) …)
バージョン番号とバックアップ用サフィックスをもつファイルをvisitしたとき、それらのサフィックスはfile-name-sans-versions
(ファイル名の構成要素を参照)を使用して展開されたファイル名(ファイル名を展開する関数を参照)から取り除かれてregexpとマッチされて、set-auto-mode
はそれに対応するmode-functionを呼び出す。この機能によりほとんどのファイルにたいしてEmacsが適切なメジャーモードを選択することが可能になる。
auto-mode-alist
の要素が(regexp function
t)
という形式なら、functionを呼び出した後にEmacsは前回マッチしなかったファイル名部分にたいしてマッチするために再度auto-mode-alist
を検索する。この機能は圧縮されたパッケージにたいして有用である。("\\.gz\\'"
function
t)
という形式のエントリーは、ファイルを解凍してから‘.gz’抜きのファイル名の解凍されたファイルを適切なモードに置く。
以下はauto-mode-alist
の先頭に複数のパターンペアーを追加する方法の例である(あなたはinitファイル内でこの種の式を使ったことがあるかもしれない)。
(setq auto-mode-alist (append ;; ドットで始まる(ディレクトリー名付きの)ファイル名 '(("/\\.[^/]*\\'" . fundamental-mode) ;; ドットのないファイル名 ("/[^\\./]*\\'" . fundamental-mode) ;; ‘.C’で終わるファイル名 ("\\.C\\'" . c++-mode)) auto-mode-alist))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
describe-mode
関数はメジャーモードに関する情報を提供します。これは通常はC-h
mにバインドされています。この関数は変数major-mode
(メジャーモードを参照)の値を使用します。すべてのメジャーモードがこの変数をセットする必要があるのはこれが理由です。
このコマンドはカレントバッファーのメジャーモードとマイナーモードのドキュメントを表示する。この関数はメジャーモードおよびマイナーモードのコマンドのドキュメント文字列を取得するためにdocumentation
関数を使用する(ドキュメント文字列へのアクセスを参照)。
buffer引数に非nil
を指定してLispから呼び出されると、この関数はカレントバッファーではなくそのバッファーのメジャーモードとマイナーモードのドキュメントを表示する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
新しいメジャーモードを定義する推奨方法は、define-derived-mode
を使用して既存のメジャーモードから派生させる方法です。それほど近いモードが存在しない場合はtext-mode
、special-mode
、またはprog-mode
から継承するべきです。基本的なメジャーモードを参照してください。これらがいずれも適切でなければ、fundamental-mode
から継承することができます(メジャーモードを参照)。
このマクロはvariantをメジャーモードコマンドとして定義して、nameをモード名の文字列形式とする。variantとparentはクォートされていないシンボルであること。
新たなコマンドvariantは関数parentを呼び出すよう定義されて、その後その親モードの特定の性質をオーバーライドする。
variant-map
という名前の、自身のsparseキーマップ(疎キーマップ)をもつ。define-derived-mode
はvariant-map
がすでにセットされていて、かつすでに親をもつ場合を除いて親モードのキーマップを新たなマップの親キーマップにする。
variant-syntax-table
に保持される。ただし:syntax-table
キーワード(以下参照)を使用してこれをオーバーライドした場合は異なる。define-derived-mode
はvariant-syntax-table
がすでにセットされていて、かつ標準的な構文テーブルよ異なる親をもつ場合を除いて、親モードの構文テーブルをvariant-syntax-table
の親とする。
variant-abbrev-table
に保持される。ただし:abbrev-table
キーワード(以下参照)を使用してこれをオーバーライドした場合は異なる。
variant-hook
をもつ。これはこのフックを実行した後に、最後にrun-mode-hooks
によって自身の祖先となるモードのフックを実行する。
これらに加えてbodyでparentのその他の性質をオーバーライドする方法を指定できます。コマンドvariantは通常のオーバーライドをセットアップした後、そのモードのフックを実行する直前にbody内のフォームを評価します。
parentが非nil
のmode-class
シンボルプロパティをもつ場合、define-derived-mode
はvariantのmode-class
プロパティに同じ値をセットします。これはたとえばparentがspecialモードならvariantもspecialモードになることを保証します(メジャーモードの慣習を参照)。
parentにたいしてnil
を指定することもできます。これにより新たなモードは親をもたなくなります。その後にdefine-derived-mode
は上述のように振る舞いますが、当然parentにつながるすべてのアクションは省略されます。
引数docstringは新たなモードにたいするドキュメント文字列を指定します。define-derived-mode
はこのドキュメント文字列の最後にそのモードフックに関する一般的な情報と、その後にそのモードのキーマップを追加します。docstringを省略するとdefine-derived-mode
がドキュメント文字列を生成します。
keyword-argsはキーワードと値のペアです。値は評価されます。現在のところ以下のキーワードがサポートされています:
:syntax-table
新たなモードにたいする構文テーブルを明示的に指定するためにこれを使用できる。nil
値を指定すると新たなモードはparentと同じ構文テーブル、parentもnil
なら標準的な構文テーブルを使用する(これはnil
値の非キーワード引数は引数を指定しないのと同じという通常の慣習にはしたがわないことに注意)。
:abbrev-table
新たなモードにたいするabbrevテーブルを明示的に指定するためにこれを使用できる。nil
値を指定すると新たなモードはparentと同じabbrevテーブル、parentもnil
ならfundamental-mode-abbrev-table
を使用する(繰り返すがnil
値はこのキーワードを指定しないことではない)。
:group
これが指定する場合、値はそのモードにたいするカスタマイズグループ(customization
group)であること(すべてのメジャーモードがカスタマイズグループをもつ訳ではない)。customize-mode
コマンドはこれを使用する。define-derived-mode
は指定されたカスタマイズグループを自動的に定義しない。
以下は架空の例:
(define-derived-mode hypertext-mode text-mode "Hypertext" "ハイパーテキスト用のメジャーモード \\{hypertext-mode-map}" (setq case-fold-search nil)) (define-key hypertext-mode-map [down-mouse-3] 'do-hyper-link)
define-derived-mode
が自動的に行うので、この定義内にinteractive
指定を記述してはならない。
この関数はカレントメジャーモードがシンボルmodesで与えられたメジャーモードのいずれかから派生されていたら非nil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Fundamentalモードは別として他のメジャーモードの一般的な派生元となるメジャーモードが3つあります。それはTextモード、Progモード、およびSpecialモードです。Textモードはその本来もつ機能から有用なモードです(たとえば.txtファイルの編集など)。一方、ProgモードとSpecialモードは主にそのようなモード以外のモードの派生元とするために存在します。
新たなモードは直接と間接を問わず、可能な限りそれら3つのモードから派生させるべきです。その理由の1つは関連のあるモードファミリー全体(たとえばすべてのプログラミング言語のモード)にたいして、ユーザーが単一のモードフックをカスタマイズできるからからです。
Textモードは人間の言語を編集するためのメジャーモードである。このモードは文字‘"’と‘\’を区切り文字構文(punctuation
syntax: 構文クラスのテーブルを参照)としてもち、M-TABをispell-complete-word
にバインドする(Spelling in The GNU Emacs Manualを参照)。
Textモードから派生されたメジャーモードの例としてHTMLモードがある。SGML and HTML Modes in The GNU Emacs Manualを参照のこと。
Progモードはプログラミング言語のソースコードを含むバッファーにたいする基本的なメジャーモードである。Emacsビルトインのプログラミング言語用メジャーモードはこのモードから派生されている。
Progモードはparse-sexp-ignore-comments
をt
(パースにもとづくモーションコマンドを参照)、bidi-paragraph-direction
をleft-to-right
(双方向テキストの表示を参照)にバインドする。
Specialモードはファイルから直接ではなく、Emacsにより特別(specially)に生成されたテキストを含むバッファーにたいする基本的なメジャーモードである。Specialモードから派生されたメジャーモードはmode-class
プロパティにspecial
が与えられる(メジャーモードの慣習を参照)。
Specialモードはバッファーを読み取り専用にセットする。このモードのキーマップはいくつかの一般的なバインディングを定義して、それにはquit-window
にたいするq、revert-buffer
(リバートを参照)にたいするgが含まれる。
Specialから派生されたメジャーモードの例としてはBuffer Menuモードがあり、これは*Buffer List*バッファーにより使用される。Listing Existing Buffers in The GNU Emacs Manualを参照のこと。
これらに加えて表形式データのバッファーにたいするモードをTabulated Listモードから継承できます。このモードはSpecialモードから順に派生されているモードです。Tabulated Listモードを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
すべてのメジャーモードコマンドはモード独自のノーマルフックchange-major-mode-after-body-hook
、そのモードのモードフック、ノーマルフックafter-change-major-mode-hook
を実行することによって終了すべきです。これはrun-mode-hooks
を呼び出すことにより行われます。もしそのモードが派生モードなら自身のbody内で他のメジャーモード(親モード)を呼び出す場合には、親モードが自身でこれらのフックを実行しないようにdelay-mode-hooks
の中でこれを行うべきです。かわりに派生モードは親のモードフックも実行するrun-mode-hooks
を呼び出します。メジャーモードの慣習を参照してください。
Emacs 22より前のバージョンのEmacsにはdelay-mode-hooks
がありません。またEmacs
24より前のバージョンにはchange-major-mode-after-body-hook
がありません。ユーザー実装のメジャーモードがrun-mode-hooks
を使用せず、これらの新しい機能を使用するようにアップデートされていないときは、これらのメジャーモードは以下の慣習に完全にしたがわないでしょう。それらのモードは親のモードフックをあまりに早く実行したり、after-change-major-mode-hook
の実行に失敗するかもしれません。そのようなメジャーモードに遭遇したら以下の慣習にしたがって修正をお願いします。
define-derived-mode
を使用してメジャーモードを定義したときは、自動的にこれらの慣習にしたがうことが保証されます。define-derived-mode
を使用せずにメジャーモードを“手動”で定義したら、これらの慣習を自動的に処理するように以下の関数を使用してください。
メジャーモードはこの関数を使用してそれらのモードフックを実行すること。これはrun-hooks
(フックを参照)と似ているが、change-major-mode-after-body-hook
とafter-change-major-mode-hook
も実行する。
この関数がdelay-mode-hooks
フォーム実行中に呼び出されたときはそれらのフックを即座には実行しない。かわりに次のrun-mode-hooks
呼び出しでそれらを実行するようにアレンジする。
あるメジャーモードコマンドが他のメジャーモードコマンドを呼び出すときはdelay-mode-hooks
の内部で行うこと。
このマクロはbodyを実行するが、body実行中はすべてのrun-mode-hooks
呼び出しにたいしてそれらのフックの実行を遅延するよう指示する。それらのフックは実際にはdelay-mode-hooks
構造の最後の後、次のrun-mode-hooks
呼び出しの間に実行されるだろう。
これはrun-mode-hooks
により実行されるノーマルフックである。これはそのモードのフックの前に実行される。
これはrun-mode-hooks
により実行されるノーマルフックである。これはすべての適切に記述されたメジャーモードコマンドの一番最後に実行される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Tabulated Listモードとは、表形式データ(エントリーから構成されるデータで各エントリーはそれぞれテキストの1行を占め、エントリーの内容は列に分割されるようなデータ)を表示するためのメジャーモードです。Tabulated Listモードは行列の見栄えよくプリントする機能、および各列の値に応じて行をソートする機能を提供します。これはSpecialモードから派生されたモードです(基本的なメジャーモードを参照)。
Tabulated Listモードは、より特化したメジャーモードの親モードとして使用されることを意図しています。例としてはProcess Menuモード(プロセスの情報を参照)、Package Menuモード(Package Menu in The GNU Emacs Manualを参照)が含まれます。
このような派生されたモードはtabulated-list-mode
を2つ目の引数に指定して、通常の方法でdefine-derived-mode
を使用するべきです(派生モードの定義を参照)。define-derived-mode
フォームのbodyは以下にドキュメントされている変数に値を割り当てることにより、表形式データのフォーマットを指定するべきです。その後にオプションで列名のヘッダーを挿入する関数tabulated-list-init-header
を呼び出すことができます。
派生されたモードはリスティングコマンド(listing command)も定義するべきです。これはモードコマンドではなく、(M-x
list-processesのように)ユーザーが呼び出すコマンドです。リスティングコマンドはバッファーを作成または切り替えて、派生モードをオンにして表形式データを指定し、最後にそのバッファーを事前設定(populate)するためにtabulated-list-print
を呼び出すべきです。
このバッファーローカル変数は表形式データのフォーマットを指定する。値はベクターであり、ベクターの各要素はデータ列を表すリスト(name
width sort)
である。ここで
nil
ならその列はソートに使用できない。t
なら列の文字列値を比較することによりソートされる。それ以外ならtabulated-list-entries
の要素と同じ形式の2つの引数をとる、sort
にたいする述語関数(predicate
function)であること。
このバッファーローカル変数はTabulated Listバッファー内に表示されるエントリーを指定する。値はリストか関数のいずれかであること。
値がリストなら各リスト要素は1つのエントリーに対応し、(id contents)
という形式であること。ここで
nil
、またはエントリーを識別するLispオブジェクト。Lispオブジェクトならエントリーを再ソートした際、カーソルは同じエントリー上に留まる。比較はequal
で行われる。
tabulated-list-format
と要素数が同じベクター。ベクター要素は文字列かリスト。文字列ならバッファーにそのまま挿入される。リスト(label
.
properties)
なら、labelとpropertiesを引数としてinsert-text-button
を呼び出すことによってテキストボタンを挿入することを意味する(ボタンの作成を参照)。
これらの文字列には改行を含めないこと。
それ以外なら、それは値は引数なしで呼び出されて上記形式のリストをリターンする関数であること。
このノーマルフックはTabulated
Listバッファーのリバートに先立ち実行される。派生モードはtabulated-list-entries
を再計算するためにこのフックに関数を追加できる。
この変数の値はポイント位置にエントリー(エントリーを終端する改行を含む)を挿入するために呼び出される関数である。この関数はtabulated-list-entries
と同じ意味をもつ2つの引数idとcontentsを受け取る。デフォルト値はエントリーをそのまま挿入する関数である。より複雑な方法でTabulated
Listモードを使用するモードは別の関数を指定できる。
この変数の値はTabulated
Listバッファーにたいするカレントのソートキーを指定する。nil
ならソートは行われない。それ以外なら(name
.
flip)
という形式の値をもつ。ここでnameはtabulated-list-format
内の列目の1つとマッチする文字列、flipが非nil
なら逆順でのソートを意味する。
この関数はTabulated
Listバッファーにたいするheader-line-format
を計算してセットし、列ヘッダー上でのクリックでソートを可能にするキーマップをヘッダー行に割り当てる。
Tabulated
Listから派生したモードは、上記の変数(特にtabulated-list-format
をセットした後のみ)をセットした後にこれを呼び出すこと。
この関数はカレントバッファーにエントリーを挿入する。これをリスティングコマンドとして呼び出すこと。この関数はバッファーを消去してtabulated-list-entries
で指定されるエントリーをtabulated-list-sort-key
にしたがってソートした後、各エントリーを挿入するためにtabulated-list-printer
で指定される関数を呼び出す。
オプション引数remember-posが非nil
なら、この関数はカレント行でid要素を探して、もしあればすべてのエントリーを(再)挿入して、その後にそのエントリーの移動を試みる。
オプション引数updateが非nil
なら、この関数は最後のプリント以降に変更されたエントリーの削除か追加だけを行う。この関数が最後に呼び出されて以降、ほとんどのエントリーが変更されていなければ、この関数は数倍高速になる。結果の違いはtabulated-list-put-tag
を通じて配置されたタグが変更されていないエントリーから削除されないことだけである(通常はすべてのタグが削除される)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
genericモード(汎用モード)とは、コメント構文にたいする基本的なサポートとFont
Lockモードをもつシンプルなメジャーモードです。genericモードを定義するにはマクロdefine-generic-mode
を使用します。define-generic-mode
の使い方の例は、ファイルgeneric-x.elを参照してください。
このマクロはmode
(クォートされていないシンボル)という名前のgenericモードコマンドを定義する。オプション引数docstringは、そのモードコマンドにたいするドキュメント文字列。これを与えなければdefine-generic-mode
がデフォルトのドキュメント文字列を生成する。
引数comment-listは要素が文字、2文字以下の文字列、またはコンスセルである。文字か文字列ならそのモードの構文テーブル内でコメント開始識別子としてセットアップされる。エントリーがコンスセルならCARはコメント開始識別子、CDRはコメント終了識別子としてセットアップされる(行末によりコメントを終端させたければ後者にnil
を使用する)。構文テーブルのメカニズムには実際にコメントの開始および終了識別子に関する制限があることに注意。
構文テーブルを参照のこと。
引数keyword-listはfont-lock-keyword-face
でハイライトするキーワードのリストである。キーワードは文字列であること。一方、font-lock-listはハイライトするための追加の式リストである。このリストの各要素はfont-lock-keywords
の要素と同じ形式をもつこと。検索ベースのフォント化を参照されたい。
引数auto-mode-listは変数auto-mode-alist
に追加する正規表現のリストである。これらのは、マクロ呼び出しの展開時ではなく、define-generic-mode
の実行時に追加される。
最後にfunction-listは追加セットアップのためにモードコマンドに呼び出される関数のリストである。これらの関数はモードフック変数mode-hook
の実行の直前に呼び出される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
おそらくTextモードは、Fundamentalを除いてもっともシンプルなモードです。上述した慣習の多くを説明するために以下にtext-mode.elの抜粋を示します:
;; このモード用に構文テーブルを作成
(defvar text-mode-syntax-table
(let ((st (make-syntax-table)))
(modify-syntax-entry ?\" ". " st)
(modify-syntax-entry ?\\ ". " st)
;; M-cで'hello'が'hello'でなく'Hello'になるよう'p'を追加
(modify-syntax-entry ?' "w p" st)
st)
"`text-mode'で使用される構文テーブル")
;; このモード用にキーマップを作成
(defvar text-mode-map (let ((map (make-sparse-keymap))) (define-key map "\e\t" 'ispell-complete-word) map) "`text-mode'のキーマップ `mail-mode'、`outline-mode'、`indented-text-mode'のような 他の多くのモードはこのマップ内で定義した全コマンドを継承する")
そして実際にモードコマンドが定義される方法が以下になります:
(define-derived-mode text-mode nil "Text" "人間が読むために記述されたテキストを編集するためのメジャーモード このモードではパラグラフを区切るのはブランク行か空白行だけである したがって適応型フィル(adaptive filling)の全恩恵を受けられる (変数`adaptive-fill-mode'を参照のこと) \\{text-mode-map} Textモードのオンによりノーマルフック`text-mode-hook'が実行される"
(set (make-local-variable 'text-mode-variant) t) (set (make-local-variable 'require-final-newline) mode-require-final-newline) (set (make-local-variable 'indent-line-function) 'indent-relative))
(現在はデフォルト値がindent-relative
なので最後の行が冗長だが将来のバージョンで削除する予定。)
3つのLisp用モード(Lispモード、Emacs Lispモード、Lisp Interactionモード)はTextモードより多くの機能をもち、それにふさわしくコードもより複雑です。そのようなモードの記述方法を説明するためにlisp-mode.elの抜粋を示します。
以下はLispモードの構文テーブルとabbrevテーブルを定義する方法です:
;; モード固有のテーブル変数の作成
(defvar lisp-mode-abbrev-table nil)
(define-abbrev-table 'lisp-mode-abbrev-table ())
(defvar lisp-mode-syntax-table
(let ((table (copy-syntax-table emacs-lisp-mode-syntax-table)))
(modify-syntax-entry ?\[ "_ " table)
(modify-syntax-entry ?\] "_ " table)
(modify-syntax-entry ?# "' 14" table)
(modify-syntax-entry ?| "\" 23bn" table)
table)
"`lisp-mode'で使用される構文テーブル")
Lisp用の3つのモードは多くのコードを共有します。たとえば以下の関数呼び出しによってさまざまな変数がセットされます:
(defun lisp-mode-variables (&optional syntax keywords-case-insensitive) (when syntax (set-syntax-table lisp-mode-syntax-table)) (setq local-abbrev-table lisp-mode-abbrev-table) …
その中でも特に以下の関数はLispコメントを処理するために変数comment-start
をセットアップします:
(make-local-variable 'comment-start) (setq comment-start ";") …
これらの異なるLisp用モードは、微妙に異なるキーマップをもちます。たとえばLispモードはC-c
C-zをrun-lisp
にバインドしますが、他のLisp用モードはこれを行いません。とはいえすべてのLisp用モードに共通なコマンドがいくつかあります。以下のコードはそれらの共通コマンドをセットアップします:
(defvar lisp-mode-shared-map (let ((map (make-sparse-keymap))) (define-key map "\e\C-q" 'indent-sexp) (define-key map "\177" 'backward-delete-char-untabify) map) "すべてのLisp用モードでコマンドを共有するためのキーマップ")
そして以下がLispモードのためのキーマップをセットアップするコードです:
(defvar lisp-mode-map (let ((map (make-sparse-keymap)) (menu-map (make-sparse-keymap "Lisp"))) (set-keymap-parent map lisp-mode-shared-map) (define-key map "\e\C-x" 'lisp-eval-defun) (define-key map "\C-c\C-z" 'run-lisp) … map) "通常のLispモード用キーマップ `lisp-mode-shared-map'のすべてのコマンドはこのマップを継承する")
最後はLispモードのためのメジャーモードコマンドです:
(define-derived-mode lisp-mode prog-mode "Lisp" "GNU Emacs Lisp以外のLispコードを編集するためのメジャーモード コマンド: あたかも後方に移動するようにタブをスペースに削除変換する パラグラフ区切りはブランク行でコメント開始はセミコロン \\{lisp-mode-map} `run-lisp'はinferior Lispジョブの開始と既存ジョブ から戻るための両方に使われるかもしれないことに注意
このモードへのエントリーによって `lisp-mode-hook'の値が非nilならそれを呼び出す" (lisp-mode-variables nil t) (set (make-local-variable 'find-tag-default-function) 'lisp-find-tag-default) (set (make-local-variable 'comment-start-skip) "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *") (setq imenu-case-fold-search t))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マイナーモード(minor mode)はメジャーモードの選択とは無関係にユーザーが有効や無効にできるオプション機能の使用を提供します。マイナーモードは個別、あるいは組み合わせて有効にできます。
ほとんどのマイナーモードはメジャーモードとは独立した機能を実装するので、ほとんどのメジャーモードと一緒に使用することができます。たとえばAuto Fillモードはテキスト挿入を許容する任意のメジャーモードとともに機能します。しかし少数ながら特定のメジャーモードに特化したマイナーモードもあります。たとえばDiff Auto RefineモードはDiffモードとの使用だけを意図したマイナーモードです。
理想的にはマイナーモードは他のマイナーモードの効果と無関係に期待した効果をもつべきです。任意の順序でマイナーモードをアクティブや非アクティブにすることも可能であるべきです。
この変数の値はすべてのマイナーモードコマンドのリスト。
22.3.1 マイナーモード記述の規約 | マイナーモードを記述するためのTips。 | |
22.3.2 キーマップとマイナーモード | マイナーモードが自身のキーマップをもつための方法。 | |
22.3.3 マイナーモードの定義 | マイナーモードを定義するための便利な機能。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
メジャーモードの記述に慣習があるように、マイナーモードの記述にも慣習があります。以下ではその慣習について説明します。これらの慣習にしたがうにはマクロdefine-minor-mode
を使用するのがもっとも簡単な方法です。マイナーモードの定義を参照してください。
nil
、有効なら非nil
になる。そのマイナーモードがバッファーローカルならこの変数もバッファーローカルであること。
この変数はモードラインにマイナーモードの名前を表示するためにminor-mode-alist
と結合して使用される。これはminor-mode-map-alist
を通じて、そのマイナーモードのキーマップがアクティブかどうかも判定する(アクティブなキーマップの制御を参照)。個々のコマンドやフックもこの変数の値をチェックできる。
モードコマンドは1つのオプション引数を受け入れること。プレフィクス引数なしでinteractiveに呼び出されたらモードをトグルする(toggle: 切り替える。たとえば無効なら有効に、有効なら無効にする)こと。プレフィクス引数とともにinteractiveに呼び出された場合にはその引数が正であればモードを有効にして、それ以外なら無効にすること。
モードコマンドがLispから(つまり非interactiveに)呼び出された場合は、引数が省略またはnil
ならモードを有効にすること。引数がシンボルtoggle
ならモードをトグルして、それ以外なら上述の数引数とともにinteractiveに呼び出されたときと同じ方法によってその引数を扱うこと。
以下はこの挙動の実装方法を示す例である(define-minor-mode
マクロが生成するコードもこれに類似する)。
(interactive (list (or current-prefix-arg 'toggle)))
(let ((enable (if (eq arg 'toggle)
(not foo-mode) ; このモードのモード変数
(> (prefix-numeric-value arg) 0))))
(if enable
do-enable
do-disable))
やや複雑なこの挙動の理由は、ユーザーが簡単かつinteractiveにマイナーモードをトグルできることと、以下のようにモードフック内で簡単にマイナーモードを有効にできるからである:
(add-hook 'text-mode-hook 'foo-mode)
foo-mode
モードコマンドは引数なしでLispから呼び出されたときは無条件にそのマイナーモードを有効にするので、これはfoo-mode
がすでに有効でもそうでなくても正しく振る舞う。モードフック内でマイナーモードを無効にする場合は少々醜くなる:
(add-hook 'text-mode-hook (lambda () (foo-mode -1)))
しかしこれは頻繁には行われない。
minor-mode-alist
に追加する(Definition of minor-mode-alistを参照)。この要素は以下の形式のリストであること:
(mode-variable string)
ここでmode-variableはマイナーモードの有効化を制御する変数、stringはモードラインに表示するためのスペースで始まる短い文字列である。一度に複数モードの文字列がスペースを占有するので、これらの文字列は短くなければならない。
minor-mode-alist
に要素を追加する際は、重複を避けるために既存要素のチェックにassq
を使用すること。たとえば:
(unless (assq 'leif-mode minor-mode-alist) (push '(leif-mode " Leif") minor-mode-alist))
または以下のようにadd-to-list
(リスト変数の変更を参照)を使用すること:
(add-to-list 'minor-mode-alist '(leif-mode " Leif"))
これらに加えてメジャーモードにたいする慣習のいくつかはマイナーモードにたいしても同様に適用されます。それらの慣習はグローバルシンボルの名前、初期化関数の最後でのフックの使用、キーマップおよびその他のテーブルの使用です。
マイナーモードは、可能ならCustom(カスタマイゼーション設定を参照)を通じた有効化と無効化をサポートするべきです。これを行うには、モード変数は:type
'boolean
とともにdefcustom
で通常は定義されるべきです。その変数をセットするだけではモードの有効化に不足なら、モードコマンドを呼び出すことによりモードを有効にする:set
メソッドも指定するべきです。そしてその変数のドキュメント文字列にCustomを通じて変数をセットしなければ効果がないことを注記してください。さらにその定義をautoload
cookie(autoload cookieを参照)でマークして、その変数のカスタマイズによりモードを定義するライブラリーがロードされるように:require
を指定します。たとえば:
;;;###autoload (defcustom msb-mode nil "msb-modeをトグルする この変数を直接セットしても効果がない \\[customize]か関数`msb-mode'を使用すること" :set 'custom-set-minor-mode :initialize 'custom-initialize-default :version "20.4" :type 'boolean :group 'msb :require 'msb)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マイナーモードはそれぞれ自身のキーマップをもつことができ、そのモードが有効になるとそのキーマップがアクティブになります。マイナーモード用のキーマップをセットアップするにはminor-mode-map-alist
というalistに要素を追加します。Definition of minor-mode-map-alistを参照してください。
特定の自己挿入文字にたいして自己挿入と同じような他の何かを行うように振る舞いを変更するのは、マイナーモードキーマップの1つの使い方です(self-insert-command
をカスタマイズする別の方法はpost-self-insert-hook
を通じて行う方法であり、これ以外のself-insert-command
カスタマイズ用の機能は特別なケースに限定されていてabbrevモードとAuto
Fillモードのためにデザインされている。self-insert-command
にたいする標準定義をあなた独自の定義に置き換えることを試みてはならない。エディターコマンドループはこの関数を特別に処理する)。
マイナーモードはコマンドをC-cとその後の区切り文字よって構成されるキーシーケンスにバインドできます。しかしC-cとその後の{}<>:;のいずれかの文字、またはコントロール文字、数字より構成されるシーケンスはメジャーモード用に予約済みです。またC-c letterはユーザー用に予約済みです。キーバインディングの慣習を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マクロdefine-minor-mode
は、自己完結した単一定義内にモードを実装する便利な方法を提供します。
このマクロは名前がmode(シンボル)の新たなマイナーモードを定義する。これはドキュメント文字列としてdocをもつマイナーモードをトグルするためにmodeという名前のコマンドを定義する。
トグルコマンドは1つのオプション(プレフィクス)引数を受け取る。引数なしでinteractiveに呼び出されると、そのモードのオンとオフをトグルする。正のプレフィクス引数はモードを有効にして、それ以外のプレフィクス引数はモードを無効にする。Lispから呼び出すと引数がtoggle
ならモードをトグルして、引数が省略かnil
ならモードを有効にする。これはたとえばメジャーモードフック内でマイナーモードを有効にするのを簡便にする。docがnil
なら、このマクロは上記を記述したデフォルトのドキュメント文字列を提供する。
デフォルトではこれはモードを有効にするとt
、無効にするとnil
にセットされる、modeという名前の変数も定義する。この変数はinit-valueに初期化される。通常(以下参照)はこの値はnil
でなければならない。
文字列lighterはモード有効時にモードライン内に何を表示するか指定する。これがnil
ならこのモードはモードライン内に表示されない。
オプション引数keymapはそのマイナーモードにたいするキーマップを指定する。非nil
なら、それは(値がキーマップであるような)変数の名前かキーマップ、または以下の形式のalistであること
(key-sequence . definition)
ここでkey-sequenceとdefinitionはdefine-key
に渡すのに適した引数である(キーバインディングの変更を参照)。keymapはキーマップかalistであり、これは変数mode-map
も定義する。
上記の3つの引数init-value、lighter、keymapはkeyword-argsが使用されたときは(部分的に)省略できる。keyword-argsはキーワードとその後の対応する値により構成され、いくつかのキーワードは特別な意味をもつ:
:group group
生成されるすべてのdefcustom
フォームで使用されるカスタムグループ名。mode
(後に‘-mode’がある場合はそれを除く)にたいするデフォルトである。警告:
そのグループを定義するためdefgroup
を正しく記述していなければ、このデフォルトグループ名を使用してはならない。カスタマイゼーショングループの定義を参照のこと。
:global global
非nil
ならそのマイナーモードがバッファーローカルでなくグローバルであることを指定する。デフォルトはnil
。
マイナーモードをグローバルにしたときの効果の1つは、mode変数がカスタマイズ変数になることである。Customizeインターフェイスを通じてこの変数をトグルするとモードがオンやオフになり、変数の値は将来のEmacsセッション用に保存できるようになる(Saving
Customizations in The GNU Emacs
Manualを参照)。保存された変数が機能するためにはEmacsが開始されるたびにdefine-minor-mode
フォームが確実に評価されるようにすること。Emacsの一部ではないパッケージにたいしては、:require
キーワードを指定するのがこれを行う一番簡単な方法である。
:init-value init-value
これはinit-value引数を指定するのと等しい。
:lighter lighter
これはlighter引数を指定するのと等しい。
:keymap keymap
これはkeymap引数を指定するのと等しい。
:variable place
これはそのモードの状態を格納するために使用されるデフォルトの変数modeを置き換える。これを指定するとmode変数は定義されず、すべてのinit-value引数は使用されない。placeは異なる名前の変数(あなた自身が定義しなければならない)、またはsetf
関数とともに使用され得るすべてのもの(ジェネリック変数を参照)。placeにはコンス(get
.
set)
も指定できる。ここでgetはカレント状態をリターンする式であり、setはそれをセットする1つの引数(状態)をとる関数である。
:after-hook after-hook
これはモードフック実行後に評価される単一のLispフォームを定義する。これをクォートしないこと。
その他のすべてのキーワード引数は変数modeにたいして生成されたdefcustom
に直接渡される。
modeという名前のコマンドは最初にmodeという名前の変数をセットする等の標準的な動作を処理した後に、もしあればbodyフォームを実行する。それからモードフック変数mode-hook
を実行してから:after-hook
内のフォームを評価して終了する。
init-valueの値はnil
でなければなりません。ただし、(1)Emacsによりそのモードが事前ロードされている、または(2)たとえユーザーが要求しなくともモードを有効にするためにロードするのが容易な場合を除きます。たとえば他の何かが有効でなければそのモードの効果がなく、常にそのタイミングでロードされるような場合には、デフォルトでそのモードを有効にすることに害はありません。しかしこの状況は通常はあり得ません。通常はinit-valueの値はnil
でなければなりません。
easy-mmode-define-minor-mode
という名前はこのマクロにたいするエイリアスです。
以下はdefine-minor-mode
の使い方の例です:
(define-minor-mode hungry-mode "Hungryモードをトグルする 引数なしでinteractiveに呼び出すとモードをトグルする 正のプレフィクス引数でモードを有効に、その他のプレフィクス引数で 無効にする。Lispから呼び出す場合、引数を省略、またはnilなら モードを有効に、`toggle'なら状態をトグルする Hungryモードが有効なときは、C-DELキーは、 最後を除く先行するすべての空白を飲み込む コマンド \\[hungry-electric-delete] を参照" ;; 初期値 nil ;; モードラインの標示 " Hungry" ;; マイナーモードのバインディング '(([C-backspace] . hungry-electric-delete)) :group 'hunger)
これは“Hungry
mode”という名前のマイナーモード、モードをトグルするhungry-mode
という名前のコマンド、モードが有効かどうかを示すhungry-mode
という名前の変数、モードが有効なときそのキーマップを保持するhungry-mode-map
という名前の変数を定義します。これはC-DELにたいするキーバインディングでキーマップを初期化します。また変数hungry-mode
をカスタムグループhunger
に配置します。bodyフォームはありません
— 多くのマイナーモードはそれを必要としません。
以下はこれを記述する等価な方法です:
(define-minor-mode hungry-mode "Hungryモードをトグルする ...省略..." ;; 初期値 :init-value nil ;; モードラインへのインジケーター :lighter " Hungry" ;; マイナーモードのバインディング :keymap '(([C-backspace] . hungry-electric-delete) ([C-M-backspace] . (lambda () (interactive) (hungry-electric-delete t)))) :group 'hunger)
これはglobal-modeという名前をグローバルにトグルする。これはmodeという名前のバッファーローカルなマイナーモードをすべてのバッファーで有効か無効にするということを意味する。あるバッファー内でそのマイナーモードをオンにするには関数turn-onを使用する。マイナーモードをオフにするには-1を引数としてmodeを呼び出す。
モードをグローバルに有効にすると、それ以降ファイルをvisitすることによって作成されるバッファーやFundamental以外のメジャーモードを使用するバッファーにも影響がある。しかしFundamentalで作成される新たなバッファーは検知しない。
これはCustomizeインターフェイス内でそのマイナーモードのオン/オフを切り替えるカスタムオプションglobal-mode
(カスタマイゼーション設定)を定義する。define-minor-mode
と同様に、たとえば:require
を与える等によってEmacs開始時に毎回確実にdefine-globalized-minor-mode
フォームが評価されるようにすること。
グローバルマイナーモードのモード変数にたいしてカスタムグループを指定するにはkeyword-args内で:group
group
を使用する。
一般的にはグローバル化されたマイナーモードを定義するときは、ユーザーがバッファーごとにモードを使用(または無効に)できるように非グローバル版も定義すること。これにより特定のメジャーモード内でそのモードのフックを使用すればグローバルに有効化されたマイナーモードを無効にすることができるようになる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsの各ウィンドウ(ミニバッファーウィンドウを除く)には、通常は最下部にモードラインがあってそのウィンドウ内に表示されたバッファーに関するステータス情報がモードラインに表示されます。モードラインにはバッファー名、関連するファイル、再帰編集の深さ、およびメジャーモードやマイナーモードなどのようなそのバッファーに関する情報が含まれています。ウィンドウはヘッダーライン(header line)をもつこともでき、これはモードラインによく似ていますがウィンドウの最上部に表示されます。
このセクションではモードラインおよびヘッダーラインのコンテンツの制御の仕方について説明します。このチャプターにモードラインを含めた理由は、モードラインに表示される情報の多くが有効化されたメジャーモードとマイナーモードに関連があるからです。
22.4.1 モードラインの基礎 | モードライン制御の基本概念。 | |
22.4.2 モードラインのデータ構造 | モードラインを制御するデータ構造。 | |
22.4.3 モードライン制御のトップレベル | トップレベル変数、mode-line-format。 | |
22.4.4 モードラインで使用される変数 | そのデータ構造で使用される変数。 | |
22.4.5 モードラインでの% 構造 | モードラインへの情報の配置。 | |
22.4.6 モードラインでのプロパティ | モードライン内でのテキストプロパティの使用。 | |
22.4.7 ウィンドウのヘッダーライン | モードラインに類似した最上部のライン。 | |
22.4.8 モードラインのフォーマットのエミュレート | モードラインのようにテキストをフォーマットする。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
モードラインのコンテンツはそれぞれバッファーローカル変数mode-line-format
によって指定されます(モードライン制御のトップレベルを参照)。この変数はモードライン構文(mode line
construct)を保持します。これはそのバッファーのモードラインに何を表示するかを制御するテンプレートです。header-line-format
の値は、同じ方法によってそのバッファーのヘッダーラインを指定します。同一のバッファーにたいするすべてのウィンドウは同じmode-line-format
とheader-line-format
を使用します。
効率的な理由によりEmacsは各ウィンドウのモードラインとヘッダーラインを連続で再評価しません。たとえばウィンドウ設定(window
configuration)の変更やバッファーの切り替え、バッファーのナローイング(narrowing)やワイドニング(widening)、スクロールやバッファーの変更等、それを呼び出す状況が出現したときにEmacsは再評価を行います。mode-line-format
やheader-line-format
(モードラインで使用される変数を参照)により参照されるすべての変数、またはテキストが表示される方法に影響を与えるデータ構造(Emacsのディスプレー表示を参照)を変更する場合には、表示を更新するために関数force-mode-line-update
を使用するべきです。
この関数は次の再表示サイクルの間にすべての関連する変数の最新の値にもとづいて、カレントバッファーのモードラインとヘッダーラインの更新をEmacsに強制する。オプション引数allが非nil
なら、すべてのモードラインとヘッダーラインの更新を強制する。
この関数はメニューバーとフレームタイトルの更新も強制する。
選択されたウィンドウのモードラインは、通常はフェイスmode-line
を使用して異なるカラーで表示されます。かわりに他のウィンドウのモードラインはフェイスmode-line-inactive
で表示されます。フェイスを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
モードラインのコンテンツはモードライン構文(mode line construct)と呼ばれるデータ構造によって制御されます。モードライン構文はリストやシンボル、数字を保持するバッファーローカル変数により構成されます。それぞれのデータ型は以下で説明するようにモードラインの外見にたいして特別な意味をもちます。フレームタイトル(フレームのタイトルを参照)とヘッダーライン(ウィンドウのヘッダーラインを参照)にも同じデータ構造が使用されます。
固定文字列のようなシンプルなモードライン構文の場合もありますが、通常はモードライン構文のテキストを構築するために固定文字列と変数の値を組み合わせる方法を指定します。これらの変数の多くはその変数自体がその値によりモードライン構文を定義する変数です。
以下はモードライン構文における、さまざまなデータ型の意味です:
string
モードライン構文における文字列は、文字列内に%
構文(%
-constructs)を含む以外はそのまま表現される。これらは他のデータによる置換を意味する。モードラインでの%
構造を参照のこと。
文字列の一部がface
プロパティをもつ場合には、バッファー内でそれらが表示されるときと同じようにテキスト表示を制御する。face
プロパティをもたない文字はデフォルトのフェイスmode-line
、またはmode-line-inactive
で表示される(Standard
Faces in The GNU Emacs
Manualを参照)。string内のhelp-echo
プロパティとkeymap
プロパティは特別な意味をもつ。モードラインでのプロパティを参照のこと。
symbol
モードライン構文におけるシンボルはその値を意味する。モードライン構文としては、symbolの値はsymbolの位置に使用される。しかしシンボルt
とnil
は値がvoidであるようなシンボルとして無視される。
例外が1つある。symbolの値が文字列なら、それはそのまま表示されて%
構成は認識されない。
symbolがrisky(危険)とマークされていない(非nil
のrisky-local-variable
プロパティをもつ)場合には、symbolの値中で指定されたテキストプロパティはすべて無視される。これにはsymbolの値中の文字列のテキストプロパティ、同様に文字列内の:eval
フォームと:propertize
フォームすべてが含まれる(これはセキュリティー上の理由による。危険とマークされていない変数は、ユーザーへの問い合わせなしでファイル変数から自動的にセットされ得る)。
(string rest…)
(list rest…)
最初の要素が文字列かリストであるようなリストは、すべての要素を再帰的に処理してその結果を結合することを意味する。これはモードライン構文においてもっとも一般的なフォームである。
(:eval form)
最初の要素がシンボル:eval
であるようなリストは、formを評価してその結果を表示する文字列として使用するよう指示する。この評価が任意のファイルをロードできないことを確認すること。ファイルをロードすると無限再帰が発生するかもしれない。
(:propertize elt props…)
最初の要素がシンボル:propertize
であるようなリストは、モードライン構文eltを再帰的に処理してpropsで指定されるテキストプロパティに結果を加えるよう指示する。引数propsは0個以上のtext-propertyとvalueのペアーで構成されること。
(symbol then else)
最初の要素がキーワード以外のシンボルであるようなリストは条件文を指定する。その意味はsymbolの値に依存する。symbolが非nil
値をもつ場合は、モードライン構文として2つ目の要素thenが再帰的に処理され、それ以外は3つ目の要素elseが再帰的に処理される。elseは省略でき、その場合にはsymbolの値がnil
かvoidならモードライン構文は何も表示しない。
(width rest…)
最初の要素が整数であるようなリストはrestの結果の切り詰め、またはパディングを指定する。残りの要素restはモードライン構文として再帰的に処理されて互いに結合される。widthが正で結果の幅がwidthより少なければ右側にスペースがパディングされる。widthが負で結果の幅が-widthより大きければ右側が切り詰められる。
たとえばウィンドウ最上部からのバッファー位置をパーセント表示するには(-3 "%p")
のようなリストを使用すればよい。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
変数mode-line-format
はモードラインの全体的な制御を行います。
この変数の値はモードラインのコンテンツを制御するモードライン構文である。これはすべてのバッファーにおいて常にバッファーローカルである。
あるバッファー内でこの変数にnil
をセットすると、そのバッファーはモードラインをもたない(高さが1行しかないウィンドウもモードラインを表示しない)。
mode-line-format
のデフォルト値はmode-line-position
やmode-line-modes
(これはmode-name
とminor-mode-alist
の値を組み込む)のような、他の変数の値を使用するようデザインされています。mode-line-format
自体を変更する必要があるモードはほとんどありません。ほとんどの用途にたいしては、mode-line-format
が直接または間接的に参照するいくつかの変数を修正すれば十分です。
mode-line-format
l自体の変更を行う場合には、コンテンツを複製したり異なる様式で情報を表示するのではなく、新たな値にはデフォルト値(モードラインで使用される変数を参照)に出現する同じ変数を使用するべきです。この方法を使用すればユーザーや(display-time
やメジャーモードのような)Lispプログラムにより行われたカスタマイズは、それらの変数への変更を通じて効力を保ちます。
以下はShellモードにたいして有用かもしれない架空のmode-line-format
の例です(実際にはShellモードはmode-line-format
をセットしない):
(setq mode-line-format (list "-" 'mode-line-mule-info 'mode-line-modified 'mode-line-frame-identification "%b--"
;; これはリスト作成中に評価されることに注意 ;; これは単なる文字列のモードライン構文を作成する (getenv "HOST")
":" 'default-directory " " 'global-mode-string " %[(" '(:eval (mode-line-mode-name)) 'mode-line-process 'minor-mode-alist "%n" ")%]--"
'(which-func-mode ("" which-func-format "--")) '(line-number-mode "L%l--") '(column-number-mode "C%c--") '(-3 "%p")))
(変数line-number-mode
、column-number-mode
、which-func-mode
は特定のマイナーモードを有効にする。これらの変数名は通常のようにマイナーモードコマンド名でもある。)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではmode-line-format
の標準的な値としてモードラインテキストに組み込まれる変数を説明します。これらの変数は本質的には特別なものではありません。mode-line-format
が使用する変数を他の変数に変更すれば、それらはモードライン上で同様の効果をもちます。しかしEmacsのさまざまな部分は、それらの変数がモードラインを制御するという認識の元でそれらの変数をセットします。したがって事実上モードラインでそれらの変数を使用するのは必須なのです。Optional
Mode Line in The GNU Emacs Manualも参照してください。
この変数は言語環境(language environment)、バッファーコーディングシステム、カレント入力メソッド(current input method)に関する情報のモードライン構文の値を保持する。非ASCII文字を参照のこと。
この変数はカレントバッファーが変更されたかどうかを表示するモードライン構文の値を保持する。デフォルト値ではバッファーが変更されていれば‘**’、バッファーが変更されていなければ‘--’、バッファーが読み取り専用なら‘%%’、読み取り専用だが変更されているときは‘%*’を表示する。
この変数を変更してもモードラインは強制的に更新されない。
この変数はカレントフレームを識別する。デフォルト値では複製フレームを表示可能なウィンドウシステムを使用している場合は"
"
、一度に1つのフレームだけを表示する通常の端末では"-%F "
を表示する。
この変数はそのウィンドウ内で表示されているバッファーを識別する。デフォルト値では少なくとも12列になるようスペースパディングされたバッファー名を表示する。
この変数はバッファー内での位置を表示する。デフォルト値ではバッファーのパーセント位置、オプションでバッファーサイズ、行番号、列番号を表示する。
変数vc-mode
は各バッファーにたいしてバッファーローカルであり、そのバッファーがvisitしているファイルがバージョンコントロールで保守されているかどうか、保守されている場合はバージョンコントロールシステムの種別を表示する。値はモードラインに表示される文字列、またはバージョンコントロールされていなければnil
。
この変数はそのバッファーのメジャーモードとマイナーモードを表示する。デフォルト値では再帰編集レベル(recursive editing level)、プロセス状態の情報、ナローイング(narrowing)効果の有無を表示する。
この変数はカレントバッファーのdefault-directory
がリモートかどうかを表示するために使用される。
この変数はemacsclient
フレームを識別するために使用される。
以下の3つの変数はmode-line-modes
内で使用されます:
このバッファーローカル変数はカレントバッファーのメジャーモードの“愛称(pretty
name)”を保持する。モードラインにモード名が表示されるように、すべてのメジャーモードはこの変数をセットすること。値は文字列である必要はなく、モードライン構文内で有効な任意のデータ型(モードラインのデータ構造を参照)を使用できる。モードライン内でモード名を識別する文字列の計算にはformat-mode-line
を使用する(モードラインのフォーマットのエミュレートを参照)。
このバッファーローカル変数には、そのモードにおいてサブプロセスとの通信にたいするプロセス状態のモードライン情報が含まれる。これはメジャーモード名の直後(間にスペースはない)に表示される。たとえば*shell*バッファーでの値は(":%s")
であり、これは‘(Shell:run)’のように、メジャーモードとともにその状態を表示する。この変数は通常はnil
。
この変数はモードラインの一番前に表示される。memory-fullメッセージがある場合を除き、デフォルトではこの構文はモードライン先頭の右側に表示される。
この変数はモードラインの終端に表示される。
その他の情報にたいするモードライン構文。デフォルトではglobal-mode-string
で指定される情報を表示する。
この変数はアクティブなマイナーモードをモードラインに示す方法を指定する要素をもった連想リスト(association
list)を保持する。minor-mode-alist
の各要素は以下のような2要素のリストであること:
(minor-mode-variable mode-line-string)
より一般的にはmode-line-stringは任意のモードライン構文を指定できる。minor-mode-variableの値が非nil
ならモードラインに表示され、それ以外なら表示されない。混合しないようにこれらの文字列はスペースで始めること。慣例的に特定のモードにたいするminor-mode-variableは、そのマイナーモードがアクティブになった際に非nil
値にセットされる。
minor-mode-alist
自体はバッファーローカルではない。このalist内で参照される各変数は、そのマイナーモードをバッファーごとに個別に有効にできるならバッファーローカルであること。
この変数はモードライン内でマイナーモードwhich-func-mode
がセットされていればその直後、セットされていなければmode-line-modes
の後に表示されるモードライン構文を保持する(デフォルト)。コマンドdisplay-time
は、」時間とロードの情報を含む文字列を保持する変数display-time-string
を参照するglobal-mode-string
をセットする。
‘%M’構文はglobal-mode-string
の値を置き換えるが、この変数はmode-line-format
からモードラインにincludeされるので時代遅れである。
以下はmode-line-format
のデフォルト値の簡略化バージョンです。実際のデフォルト値には追加のテキストプロパティ指定も含まれます。
("-" mode-line-mule-info mode-line-modified mode-line-frame-identification mode-line-buffer-identification
" " mode-line-position (vc-mode vc-mode) " "
mode-line-modes (which-func-mode ("" which-func-format "--")) (global-mode-string ("--" global-mode-string)) "-%-")
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
%
構造モードライン構文として使用される文字列では、さまざまな種類のデータを置き換えるために%
構文を使用できます。以下は定義済みの%
構文と意味のリストです。
‘%%’以外の構文では、フィールドの最小幅を指定するために‘%’の後に10進整数を追加できます。幅がそれより小さければそのフィールドは最小幅にパディングされます。純粋に数値的な構文(‘c’、‘i’、‘I’、‘l’)は左側、それ以外は右側にスペースを追加してパディングされます。
%b
buffer-name
関数により取得されるカレントバッファー名。バッファーの名前を参照のこと。
%c
ポイント位置のカレント列番号。
%e
EmacsがLispオブジェクトにたいしてメモリー不足になりそうなときは、それを伝える簡略なメッセージを示す。それ以外の場合は空。
%f
buffer-file-name
関数により取得されるvisit中のファイル名。バッファーのファイル名を参照のこと。
%F
選択されたフレームのタイトル(ウィンドウシステム上のみ)か名前。基本パラメーターを参照のこと。
%i
カレントバッファーのアクセス可能な範囲のサイズ。基本的には(- (point-max) (point-min))
。
%I
‘%i’と同様だが10^3は‘k’、10^6は‘M’、10^9は‘G’を使用して略記することで、より読みやすい方法でサイズをプリントする。
%l
ポイント位置のカレント行番号。そのバッファーのアクセス可能な範囲内でカウントされる。
%n
ナローイングが有効なときは‘Narrow’、それ以外は何も表示しない(ナローイングのnarrow-to-region
を参照)。
%p
ウィンドウの最上部より上にあるバッファーテキストのパーセント表示、または‘Top’、‘Bottom’、‘All’のいずれか。デフォルトのモードライン構文は、これを3文字に切り詰めることに注意。
%P
ウィンドウの最下部より上にあるバッファーテキスト(ウィンドウ内の可視なテキストと最上部の上にあるテキスト)のパーセント表示、およびバッファーの最上部がスクリーン上で可視なら、それに加えて‘Top’。または‘Bottom’か‘All’。
%s
process-status
により取得されるカレントバッファーに属するサブプロセスの状態。プロセスの情報を参照のこと。
%z
キーボード、端末、およびバッファーコーディングシステムのニーモニック。
%Z
‘%z’と同様だが、EOL形式(end-of-line format: 改行形式)を含む。
%*
バッファーが読み取り専用(buffer-read-only
を参照)なら‘%’、
変更(buffer-modified-p
を参照)されていればは‘*’、
それ以外は‘-’。バッファーの変更を参照のこと。
%+
バッファーが変更(buffer-modified-p
を参照)されていれば‘*’
バッファーが読み取り専用(buffer-read-only
を参照)なら‘%’、
それ以外は‘-’。これは読み取り専用バッファーの変更にたいしてのみ‘%*’と異なる。バッファーの変更を参照のこと。
%&
バッファーが変更されてれば‘*’、それ以外は‘-’。
%[
再帰編集レベルの深さを表示する(ミニバッファーレベルは勘定しない)編集レベル1つが‘[’。再帰編集を参照のこと。
%]
編集レベル1つが‘]’(ミニバッファーレベルは勘定しない)。
%-
モードラインの残りを充填するのに十分なダッシュ。
%%
文字‘%’。%
構文が許される文字列内にリテラル‘%’を含めるにはこの方法を使用する。
以下の2つの%
構文はまだサポートされていますが、同じ結果を変数mode-name
とglobal-mode-string
で取得できるので時代遅れです。
%m
mode-name
の値。
%M
global-mode-string
の値。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
モードライン内では特定のテキストプロパティが意味をもちます。face
プロパティはテキストの外見に影響します。help-echo
プロパティはそのテキストのヘルプ文字列に関連し、keymap
によりテキストをマウスに感応させることができます。
モードライン内のテキストにたいしてテキストプロパティを指定するには4つの方法があります:
(:propertize elt
props…)
構文を使用する。
:eval
form
を含むリストを使用する。
キーマップを指定するためにkeymap
プロパティを使用できます。このキーマップはマウスクリックにたいしてのみ実際の効果をもちます。モードライン内にポイントを移動させるのは不可能なので、これに文字キーやファンクションキーをバインドしても効果はありません。
risky-local-variable
が非nil
であるようなプロパティをもつ変数をモードラインが参照する場合には、その変数の値から取得または指定されるテキストプロパティはすべて無視されます。そのようなプロパティは呼び出される関数を指定するかもしれず、その関数はファイルローカル変数に由来するかもしれないからです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
最下部にモードラインをもつことができるのと同じように、ウィンドウは最上部にヘッダーライン(header
line)をもつことができます。ヘッダーライン機能は、それがheader-line-format
によって制御されることを除けばモードラインと同じように機能します。
すべてのバッファーにたいしてローカルなこの変数は、そのバッファーを表示するバッファーにたいしてヘッダーラインを表示する方法を指定する。この変数の値のフォーマットはmode-line-format
にたいするフォーマットと同じ(モードラインのデータ構造を参照)。この変数は通常はnil
なので、通常のバッファーはヘッダーラインをもたない。
この関数はwindowのヘッダーラインの高さをピクセルでリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。
高さが1行しかないウィンドウがヘッダーラインを表示することは決してありません。また高さが2行しかないウィンドウは、同時にモードラインとヘッダーラインを表示できません。そのようなウィンドウがモードラインをもつ場合にはヘッダーラインは表示されません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
関数format-mode-line
を使用して、特定のモードライン構文にもとづいてモードラインやヘッダーラインに表示されるテキストを計算できます。
この関数は、あたかもwindowにたいしてモードラインを生成するかのようにformatに応じてテキスト行をフォーマットするが、さらにそのテキストを文字列としてリターンする。引数windowのデフォルトは選択されたウィンドウ。bufferが非nil
なら、使用されるすべての情報はbufferから取得される。デフォルトではwindowのバッファーから取得される。
文字列の値は通常はモードラインがもつであろうフェイス、キーマップ等に対応したテキストプロパティをもつ。formatにより指定されるface
プロパティをもたないすべての文字は、faceにより決定されるデフォルト値を取得する。faceがt
の場合はwindowが選択されていればmode-line
、それ以外はmode-line-inactive
であることを意味する。faceがnil
または省略された場合はデフォルトのフェイスを意味する。faceが整数なら、この関数はテキストプロパティをもたない値をリターンするだろう。
faceの値として他の有効なフェイスを指定することもできる。指定された場合、それはformatでフェイスを指定されていない文字のface
プロパティのフェイスを提供する。
faceとしてmode-line
、mode-line-inactive
、header-line
を使用することにより、フォーマットされた文字列のリターンに加えて、対応するフェイスのカレント定義を使用して実際にモードラインやヘッダーラインの再描画が行われることに注意(他のフェイスでは再描画は行われない)。
たとえば(format-mode-line
header-line-format)
は選択されたウィンドウに表示されるテキスト(ヘッダーラインがない場合は""
)をリターンするだろう。(format-mode-line
header-line-format
'header-line)
は、各文字がヘッダーライン内でもつであろうフェイスをもつ同じテキストをリターンするとともに、それに加えてヘッダーラインの再描画も行う。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Imenuとはバッファー内の定義やセクションをすべてリストするメニューをユーザーが選択することによって、バッファー内の該当箇所に直接移動する機能です。Imenuは定義(またはバッファーのその他の名前つき範囲)の名前とその定義のバッファー内での位置をリストするバッファーインデックスを構築して、ユーザーがそれを選択すればポイントをそこに移動できるようにして機能します。メジャーモードはimenu-add-to-menubar
を使用して、メニューバーアイテムを追加することができます。
この関数はImenuを実行するためのnameという名前のローカルメニューバーを定義する。
Imenuを使用するためのユーザーレベルコマンドはEmacsマニュアルで説明されています(Imenu in the Emacs Manualを参照)。このセクションでは特定のメジャーモードにたいして定義や名前つき範囲を見つけるImenuメソッドのカスタマイズ方法を説明します。
変数imenu-generic-expression
をセットするのが通常、かつもっともシンプルな方法です:
この変数が非nil
なら、それはImenuにたいして定義を探すための正規表現を指定するリストである。シンプルなimenu-generic-expression
の要素は以下のようになる:
(menu-title regexp index)
ここでmenu-titleが非nil
なら、それはこの要素にたいするマッチがバッファーインデックスのサブメニューとなることを指示する。menu-title自体はそのサブメニューにたいして名前を指定する。menu-titleがnil
なら、この要素にたいするマッチは直接トップレベルのバッファーインデックスとなる。
このリストの2つ目の要素regexpは正規表現である(正規表現を参照)。これはバッファー内でこれにマッチするものは定義、あるいはバッファーインデックス内に記載すべき何かであると判断される。3つ目の要素indexは0以上の整数なら、regexp内の部分式(subexpression)が定義名にマッチすることを示す。
以下のような要素もある:
(menu-title regexp index function arguments…)
この要素にたいする各マッチはインデックスアイテムを作成して、ユーザーにがそのインデックスアイテムを選択したときアイテム名、バッファー位置、およびargumentsから構成される引数でfunctionを呼び出す。
Emacs Lispモードではimenu-generic-expression
は以下のようになるだろう:
((nil "^\\s-*(def\\(un\\|subst\\|macro\\|advice\\)\ \\s-+\\([-A-Za-z0-9+]+\\)" 2)
("*Vars*" "^\\s-*(def\\(var\\|const\\)\ \\s-+\\([-A-Za-z0-9+]+\\)" 2)
("*Types*" "^\\s-*\ (def\\(type\\|struct\\|class\\|ine-condition\\)\ \\s-+\\([-A-Za-z0-9+]+\\)" 2))
この変数はセットによりカレントバッファーにたいしてバッファーローカルになる。
この変数はimenu-generic-expression
の値中の正規表現マッチがcase(大文字小文字)を区別するかどうかを制御する。t
(デフォルト)ならcaseの違いを無視することを意味する。
この変数はセットによりカレントバッファーにたいしてバッファーローカルになる。
この変数はimenu-generic-expression
処理中に、カレントバッファーの構文テーブルをオーバーライドするために使用する構文テーブル変更用のalist。このalistの各要素は以下の形式をもつこと:
(characters . syntax-description)
CARのcharactersには文字か文字列を指定できる。この要素はその文字か文字列がsyntax-descriptionにより指定される構文であることを示し、modify-syntax-entry
に渡される(構文テーブルの関数を参照)。
典型的にはこの機能はシンボル構文(symbol syntax)をもつ文字にたいして単語構文(word
syntax)を与えるために通常は使用され、それによりimenu-generic-expression
が単純になってマッチングのスピードも向上する。たとえばFortranモードでは以下のようにこれを使用する:
(setq imenu-syntax-alist '(("_$" . "w")))
imenu-generic-expression
の正規表現は、‘\\(\\sw\\|\\s_\\)+’のかわりに、‘\\sw+’を使用できる。このテクニックは名前をモード名として許容されるより短い頭文字に制限する必要があるときは不便かもしれないことに注意。
この変数はセットによりカレントバッファーにたいしてバッファーローカルになる。
あるメジャーモードにたいしてImenuをカスタマイズする別の方法としてimenu-prev-index-position-function
とimenu-extract-index-name-function
があります:
この変数が非nil
なら、その値はポイント位置からバッファーを後方にスキャンしてバッファーインデックスに配置すべき次の定義を探すための関数であること。そしてポイントより前に他の定義が見つからなければnil
をリターンすること。見つかった場合には定義を見つけた場所にポイントを残して任意の非nil
値をリターンすること。
この変数はセットによりカレントバッファーにたいしてバッファーローカルになる。
この変数が非nil
なら、その値はポイントが定義中にある(imenu-prev-index-position-function
関数がポイントを残す場所)という想定にもとづき、その定義の名前をリターンする関数であること。
この変数はセットによりカレントバッファーにたいしてバッファーローカルになる。
メジャーモードにたいしてImenuをカスタマイズするための最後の方法は変数imenu-create-index-function
のセットです:
この変数はバッファーインデックスを作成するために使用する関数を指定する。この関数は引数がを受け取らず、カレントバッファーにたいするインデックスalist(index
alist)をリターンすること。この関数はsave-excursion
内で呼び出されるので、どこにポイントを残しても違いはない。
このインデックスalistは3つのタイプの要素をもつことができる。以下はシンプル要素(simple element)の例:
(index-name . index-position)
シンプル要素の選択はそのバッファー内の位置index-positionに移動する効果をもつ。スペシャル要素(special element)は以下のようなもの:
(index-name index-position function arguments…)
スペシャル要素の選択により以下が処理される:
(funcall function index-name index-position arguments…)
ネストされたサブalist要素(nested sub-alist element)は以下のようなもの:
(menu-title . sub-alist)
これはsub-alistにより指定されるサブメニューmenu-titleを作成する。
imenu-create-index-function
のデフォルト値はimenu-default-create-index-function
。この関数はインデックスalistを生成するためにimenu-prev-index-position-function
の値とimenu-extract-index-name-function
の値を呼び出す。しかしこれら2つ変数のいずれかがnil
なら、デフォルト関数はかわりにimenu-generic-expression
を使用する。
この変数はセットによりカレントバッファーにたいしてバッファーローカルになる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Font Lockモードとはバッファーの特定の部分にたいして、それらの構文的役割(syntactic
role)にもとづき自動的にface
プロパティをアタッチするバッファーローカルなマイナーモードです。このモードがバッファーをパースする方法はそのメジャーモードに依存します。ほとんどのメジャーモードは、どのコンテキストでどのフェイスを使用するかにたいして構文的条件(syntactic
criteria)を定義します。このセクションでは特定のメジャーモードにたいしてFont Lockをカスタマイズする方法を説明します。
Font Lockモードは2つの方法によりハイライトするテキストを探します。それは構文テーブル(syntax table)にもとづく構文解析と、(通常は正規表現にたいする)検索です。最初に構文的フォント表示(syntactic fontification)が発生します。これはコメントと文字列定数を見つけてそれらをハイライトします。検索ベースのフォント表示が発生するのは2番目です。
22.6.1 Font Lockの基礎 | Font Lockカスタマイズの概要。 | |
22.6.2 検索ベースのフォント化 | 正規表現にもとづくフォント表示。 | |
22.6.3 検索ベースのフォント化のカスタマイズ | 検索ベースフォント表示のカスタマイズ。 | |
22.6.4 Font Lockのその他の変数 | 追加のカスタマイズ機能。 | |
22.6.5 Font Lockのレベル | 多なりとも少ユーザーが選択できるように、それぞれのモードは代替レベルを定義できる。 | |
22.6.6 事前計算されたフォント化 | バッファーコンテンツを生成するLispプログラムが、どのようにしてそれをフォント表示する方法も指定できるか。 | |
22.6.7 Font Lockのためのフェイス | Font Lockにたいする具体的な特殊フェイス。 | |
22.6.8 構文的なFont Lock | 構文テーブルにもとづくフォント表示。 | |
22.6.9 複数行のFont Lock構造 | Font Lockに複数行構成の正しいハイライトを強制する方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Font Lock機能はいくつかの基本的な関数にもとづきます。これらはそれぞれ対応する変数により指定される関数を呼び出します。このインダイレクションによりメジャーモードとマイナーモードはそのモードにあるバッファーのフォント表示が機能する方法を変更したり、フォント表示を何も行わない機能にたいしてさえFont Lockメカニズムを使用することが可能になります(以下の記述で関数が何を行うか説明する際に“should(すること、するべき)”と表現しているのはこれが理由。モードは完全に異なる何かを行うように対応する変数をカスタマイズできる)。以下で言及される変数はFont Lockのその他の変数で説明されています。
font-lock-fontify-buffer
この関数はfont-lock-fontify-buffer-function
で指定される関数の呼び出しにより、カレントバッファーのアクセス可能範囲をフォント表示すること。
font-lock-unfontify-buffer
フォント表示削除のためにFont
Lockをオフに切り替える際に使用する。font-lock-unfontify-buffer-function
で指定される関数を呼び出す。
font-lock-fontify-region beg end &optional loudly
begとendの間のリージョンをフォント表示すること。loudlyが非nil
なら、フォント表示中にステータスメッセージを表示すること。font-lock-fontify-region-function
で指定される関数を呼び出す。
font-lock-unfontify-region beg end
begとendの間のリージョンのフォント表示を削除すること。font-lock-unfontify-region-function
で指定される関数を呼び出す。
font-lock-flush &optional beg end
この関数はbegとendの間のリージョンのフォント表示を期限切れ(outdated)とマークすること。begとendが未指定またはnil
なら、デフォルトはそのバッファーのアクセス可能範囲の先頭と終端。font-lock-flush-function
で指定される関数を呼び出す。
font-lock-ensure &optional beg end
この関数はbegとendの間のリージョンのフォント表示を保証すること。オプション引数begとendのデフォルトは、そのバッファーのアクセス可能範囲の先頭と終端。font-lock-ensure-function
で指定される関数を呼び出す。
Font
Lockモードのテキストのハイライト方法を制御する変数がいくつかあります。しかしメジャーモードはこれらの変数を直接セットするべきではありません。かわりにメジャーモードはバッファーローカル変数としてfont-lock-defaults
をセットするべきです。Font
Lockモードが有効なときは、他のすべての変数をセットするためにこの変数に割り当てられた値が使用されます。
この変数はそのモード内のテキストをフォント表示する方法を指定するためにモードによりセットされる。この変数はセットした際に自動的にバッファーローカルになる。変数の値がnil
ならFont
Lockモードはハイライトを行わず、バッファー内のテキストに明示的にフェイスを割り当てるために‘Faces’メニュー(メニューバーの‘Edit’の下の‘Text
Properties’)を使用できる。
非nil
なら値は以下のようであること:
(keywords [keywords-only [case-fold [syntax-alist other-vars…]]])
1つ目の要素keywordsは検索ベースのフォント表示を制御するfont-lock-keywords
の値を間接的に指定する。値にはシンボル、変数、またはfont-lock-keywords
にたいして使用するリストが値であるような関数を指定できる。またそれぞれのシンボルがフォント表示の可能なレベルであるような、いくつかのシンボルからなるリストも指定できる。この場合には、1つ目のシンボルはフォント表示の‘モードデフォルト(mode
default)’レベル、次のシンボルはフォント表示のレベル1、その次はレベル2、...のようになる。‘モードデフォルト’レベルは通常はレベル1と等しい。これはfont-lock-maximum-decoration
がnil
値をもつとき使用される。Font Lockのレベルを参照のこと。
2つ目の要素keywords-onlyは変数font-lock-keywords-only
の値を指定する。これが省略またはnil
なら、(文字列とコメントの)構文的フォント表示も行われる。非nil
なら構文的フォント表示は行われない。構文的なFont Lockを参照のこと。
3つ目の要素case-foldはfont-lock-keywords-case-fold-search
の値を指定する。非nil
なら検索ベースフォント表示の間、Font
Lockモードはcaseの違いを無視する。
4つ目の要素syntax-alistが非nil
なら、それは(char-or-string
.
string)
という形式のコンスセルのリストであること。これらは構文的フォント表示にたいする構文テーブルのセットアップに使用される。結果となる構文テーブルはfont-lock-syntax-table
に格納される。syntax-alistが省略またはnil
なら、構文的フォント表示はsyntax-table
関数によりリターンされる構文テーブルを使用する。構文テーブルの関数を参照のこと。
(もしあれば)残りすべての要素はまとめてother-varsと呼ばれる。これらの要素はすべて(variable
.
value)
という形式をもつこと。これはvariableをバッファーローカルにしてから、それにvalueをセットすることを意味する。これらother-varsを使用して、最初の5つの要素による制御とは別にフォント表示に影響する他の変数をセットできる。Font Lockのその他の変数を参照のこと。
モードがfont-lock-face
プロパティ追加により明示的にテキストをフォント表示する場合には、自動的なフォント表示すべてをオフにするためにfont-lock-defaults
に(nil
t)
を指定できます。しかしこれは必須ではありません。font-lock-face
を使用して何かをフォント表示して、それ以外の部分のテキストを自動的にフォント表示するようにセットアップすることが可能です。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
検索ベースのフォント表示を直接制御する変数はfont-lock-keywords
です。この変数は通常はfont-lock-defaults
内の要素keywordsを通じて指定されます。
この変数の値はハイライトするキーワードのリスト。Lispプログラムはこの変数を直接セットしないこと。通常はfont-lock-defaults
内の要素keywordsを使用してFont
Lockモードが自動的に値をセットする。この値は関数font-lock-add-keywords
とfont-lock-remove-keywords
を使用して変更することもできる(検索ベースのフォント化のカスタマイズを参照)。
font-lock-keywords
の各要素は、特定の例に該当するテキストを見つける方法や、それらをハイライトする方法を指定します。Font
Lockモードはfont-lock-keywords
の要素を逐次処理してマッチを探して、すべてのマッチを処理します。通常はテキストの一部はすでに一度はフォント表示されており、同じテキスト内で連続するマッチによりこれをオーバーライドすることははできません。しかしsubexp-highlighterの要素overrideを使用して異なる挙動を指定できます。
font-lock-keywords
の各要素は以下の形式のいずれかをもつべきです:
regexp
font-lock-keyword-face
を使用してregexpにたいするすべてのマッチをハイライトする。たとえば、
;; font-lock-keyword-face
を使用して
;; 単語‘foo’をハイライトする
"\\<foo\\>"
これらの正規表現を作成するときは慎重に行うこと。下手に記述されたパターンによりスピードが劇的に低下し得る! 関数regexp-opt
(正規表現の関数を参照)は、いくつかのキーワードとマッチするために最適な正規表現の計算に有用である。
function
functionを呼び出すことによりテキストを探し、font-lock-keyword-face
を使用して見つかったマッチをハイライトする。
functionは呼び出される際に1つの引数(検索のリミット)を受け取る。検索はポイント位置から開始しリミットを超えた検索は行わないこと。これは検索が成功したら非nil
をリターンして見つかったマッチを表すマッチデータをセットすること。nil
のリターンは検索の失敗を示す。
フォント表示は前の呼び出しでポイントが残された位置から同じリミットを用いてfunctionを呼び出し、functionが失敗するまでfunctionを繰り返し呼び出すだろう。検索が失敗しても何らかの特別な方法でfunctionがポイントをリセットする必要はない。
(matcher . subexp)
この種の要素ではmatcherは上述のregexpかfunctionのいずれかである。CDRのsubexpは、(matcherがマッチするテキスト全体のかわりに)matcherのどの部分式(subexpression)がハイライトされるべきかを指定する。
;; font-lock-keyword-face
を使用して
;; ‘bar’が‘fubar’の一部のときに
;; ハイライトする
("fu\\(bar\\)" . 1)
正規表現matcherの生成にregexp-opt
を使用する場合には、subexpにたいする値の計算にregexp-opt-depth
(正規表現の関数を参照)を使用できる。
(matcher . facespec)
この種の要素ではfacespecの値がハイライトに使用するフェイスを指定する。もっともシンプルな例ではfacespecは値がフェイス名であるようなはLisp変数(シンボル)。
;; fubar-face
の値のフェイスを使用して
;; ‘fubar’をハイライトする
("fubar" . fubar-face)
しかしfacespecは以下のような形式のリストに評価されてもよい:
(face face prop1 val1 prop2 val2…)
これはマッチしたテキストにフェイスfaceを指定し、さまざまなテキストプロパティをputする。これを行う場合には、この方法によってfont-lock-extra-managed-props
に値をセットする、他テキストプロパティ名を確実に追加すること。そうすればそれらのプロパティが妥当性を失ったとき、それらのプロパティもクリアーされるだろう。これらのプロパティをクリアーする関数を変数font-lock-unfontify-region-function
にセットすることもできる。Font Lockのその他の変数を参照のこと。
(matcher . subexp-highlighter)
この種の要素ではsubexp-highlighterはmatcherにより見つかったマッチをハイライトする方法を指定するリストである。これは以下の形式をもつ。
(subexp facespec [override [laxmatch]])
CARのsubexpはマッチのどの部分式をフォント表示するかを指定する整数(0はマッチしたテキスト全体を意味する)。これの2つ目の要素facespecは上述したような、値がフェイスを指定する式である。
subexp-highlighter内の残りの値overrideとlaxmatchはオプションのフラグである。overrideがt
なら、この要素は前のfont-lock-keywords
の要素により作成された既存のフォント表示をオーバーライドできる。値がkeep
なら、すでに他の要素によりフォント表示されていない文字がフォント表示される。値がprepend
なら、facespecにより指定されたフェイスがfont-lock-face
プロパティの先頭に追加される。値がappend
なら、そのフェイスがfont-lock-face
プロパティの最後に追加される。
laxmatchが非nil
なら、それはmatcher内で番号付けされた部分式subexpが存在しなくてもエラーにならないことを意味する。番号付けされた部分式subexpのフォント表示は当然発生しない。しかし他の部分式(と他のregexp)のフォント表示は継続されるだろう。laxmatchがnil
、かつ指定された部分式が存在しなければ、エラーがシグナルされて検索ベースのフォント表示は終了する。
以下はこのタイプの要素とそれが何を行うかの例:
;;foo-bar-face
を使用して、たとえハイライト済みでも ;; ‘foo’と‘bar’をハイライトする ;;foo-bar-face
は値がフェイスであるような変数であること ("foo\\|bar" 0 foo-bar-face t) ;;fubar-face
の値のフェイスを使用して ;; 関数fubar-match
が見つけた各マッチの ;; 最初の部分式をハイライトする (fubar-match 1 fubar-face)
(matcher . anchored-highlighter)
この種の要素ではanchored-highlighterはmatcherが見つけたマッチに後続するテキストをハイライトする方法を指定する。つまりmatcherが見つけたマッチは、anchored-highlighterにより指定されるその先の検索にたいするアンカー(anchor)として機能する。anchored-highlighterは以下の形式のリストである:
(anchored-matcher pre-form post-form subexp-highlighters…)
ここでanchored-matcherはmatcherと同様、正規表現か関数である。matcherにたいするマッチを見つけた後に、ポイントはそのマッチの終端に移動する。そこでFont Lockはフォームpre-formを評価する。それからanchored-matcherにたいするマッチを検索し、subexp-highlightersを使用してそれらのマッチをハイライトする。subexp-highlighterについては上記を参照のこと。最後にFont Lockはpost-formを評価する。
フォームpre-formとpost-formは、anchored-matcher使用時の事前の初期化と事後のクリーンアップに使用できる。pre-formは通常はanchored-matcherの開始前に、matcherのマッチに関連する何らかの位置にポイントを移動するために使用される。post-formは、matcherの再開前にポイントを戻すために使用できる。
pre-formを評価した後、Font Lockはその行の終端の先にたいしてanchored-matcherの検索を行わない。しかしpre-formがpre-form評価後のポイント位置より大きいバッファー位置をリターンした場合には、かわりにpre-formによりリターンされた位置が検索リミットとして使用される。その行の終端より大きい位置をリターンするのは、一般的にはよいアイデアではない。言い換えるとanchored-matcher検索は複数行にわたる(span lines)べきではない。
たとえば、
;; item-face
の値を使用して
;; 単語‘anchor’に(同一行内で)
;; 後続する単語‘item’をハイライトする
("\\<anchor\\>" "\\<item\\>" nil nil (0 item-face))
ここではpre-formとpost-formはnil
である。したがって‘item’にたいする検索は‘anchor’にたいするマッチの終端から開始されて、後続する‘anchor’インスタンスにたいする検索は‘item’にたいする検索が終了した位置から再開される。
(matcher highlighters…)
この種の要素は単一のmatcherにたいして複数のhighlighterリストを指定する。highlighterリストには、上述したsubexp-highlighterかanchored-highlighterのいずれかを指定できる。
たとえば、
;;anchor-face
の値内に現れる単語‘anchor’、 ;; および、(同じ行の)後続のitem-face
の ;; 値内に現れる単語‘item’をハイライトする ("\\<anchor\\>" (0 anchor-face) ("\\<item\\>" nil nil (0 item-face)))
(eval . form)
ここでformはバッファー内でこのfont-lock-keywords
の値が最初に使用されるときに評価される式である。この値は上述のテーブルで説明したいずれかの形式をもつこと。
警告:
複数行にわたるテキストにマッチさせるためにfont-lock-keywords
の要素をデザインしてはならない。これは確実に機能するとは言えない。詳細は複数行のFont Lock構造を参照のこと。
検索ベースのフォント表示がcaseを区別すべきかどうかを告げるfont-lock-keywords-case-fold-search
の値を指定するためにfont-lock-defaults
内でcase-foldを使用できる。
非nil
はfont-lock-keywords
のための正規表現マッチングがcaseを区別すべきではないことを意味する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
メジャーモードにたいして検索ベースフォント表示ルールを追加するためにfont-lock-add-keywords
、削除にはfont-lock-remove-keywords
を使用することができます。
この関数はカレントバッファー、またはメジャーモードmodeにたいしてハイライトするkeywordsを追加する。引数keywordsは変数font-lock-keywords
と同じ形式のリストであること。
modeが、c-mode
のようにメジャーモードのコマンド名であるようなシンボルなら、そのmode内でFont
Lockモードを有効にすることによってkeywordsがfont-lock-keywords
に追加される効果がある。非nil
値のmodeによる呼び出しは~/.emacsファイル内でのみ正しい。
modeがnil
なら、この関数はカレントバッファーのfont-lock-keywords
にkeywordsを追加する。この方法でのfont-lock-add-keywords
呼び出しは通常はモードフック関数内で使用される。
デフォルトではkeywordsはfont-lock-keywords
の先頭に追加される。オプション引数howがset
なら、それらはfont-lock-keywords
の値の置換に使用される。howがそれ以外の非nil
値なら、これらはfont-lock-keywords
の最後に追加される。
追加のハイライトパターンの使用を可能にする、特別なサポートを提供するモードがいくつかある。それらの例については変数c-font-lock-extra-types
、c++-font-lock-extra-types
、java-font-lock-extra-types
を参照のこと。
警告:
メジャーモードコマンドはモードフックを除き、いかなる状況においても直接間接を問わずfont-lock-add-keywords
を呼び出してはならない(これを行うといくつかのマイナーモードは不正な振る舞いを起こしかねない)。メジャーモードコマンドはfont-lock-keywords
をセットすることにより、検索ベースフォント表示のルールをセットアップすること。
この関数はカレントバッファー、またはメジャーモードmodeにたいしてfont-lock-keywords
からkeywordsを削除する。font-lock-add-keywords
の場合と同様、modeはメジャーモードコマンド名またはnil
であること。font-lock-add-keywords
にたいするすべての制約と条件はこの関数にも適用される。
たとえば以下はCモードに2つのフォント表示パターンを追加するコードの例である。フォント表示の1つはたとえコメント内であろうとも単語‘FIXME’をフォント表示し、もう1つは‘and’、‘or’、‘not’をキーワードとしてフォント表示する。
(font-lock-add-keywords 'c-mode '(("\\<\\(FIXME\\):" 1 font-lock-warning-face prepend) ("\\<\\(and\\|or\\|not\\)\\>" . font-lock-keyword-face)))
この例は厳密にCモードだけに効果がある。Cモード、およびその派生モードにたいして同じパターンを追加するには、かわりに以下を行う:
(add-hook 'c-mode-hook (lambda () (font-lock-add-keywords nil '(("\\<\\(FIXME\\):" 1 font-lock-warning-face prepend) ("\\<\\(and\\|or\\|not\\)\\>" . font-lock-keyword-face)))))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではfont-lock-defaults
内のother-varsを用いて、メジャーモードがセットできる追加の変数について説明します(Font Lockの基礎を参照)。
この変数が非nil
なら、それはコマンドM-o M-o
(font-lock-fontify-block
)で再フォント表示するテキスト範囲を選択するために引数なしで呼び出される関数であること。
この関数は結果を報告するために選択されたテキスト範囲にリージョンを配置すること。正しい結果を与えるのに十分、かつ再フォント表示が低速にならない程度のテキスト範囲がよい選択である。典型的な値はプログラミングのモードにたいしてはmark-defun
、テキストを扱うモードにたいしてはmark-paragraph
。
この変数は、(font-lock-face
以外の)Font
Lockにより管理される追加プロパティを指定する。これらの追加プロパティは通常はfont-lock-face
プロパティだけを管理する、font-lock-default-unfontify-region
により使用される。他のプロパティも同様にFont
Lockに管理させたければ、このリストに追加するのと同じようにfont-lock-keywords
内のfacespec内でもこれらを指定しなければならない。検索ベースのフォント化を参照のこと。
そのバッファーをフォント表示するために使用する関数。デフォルト値はfont-lock-default-fontify-buffer
。
そのバッファーを非フォント表示するために使用する関数。デフォルト値はfont-lock-default-unfontify-buffer
。
リージョンをフォント表示するための関数。この関数はリージョンの開始と終了の2つを引数に受け取り、オプションで3つ目の引数verboseを受け取ること。verboseが非nil
なら、その関数はステータスメッセージをプリントすべきである。デフォルト値はfont-lock-default-fontify-region
。
リージョンを非フォント表示するための関数。この関数はリージョンの開始と終了の2つを引数に受け取ること。デフォルト値はfont-lock-default-unfontify-region
。
リージョンのフォント表示の期限切れの宣言に使用する関数。そのリージョンの開始と終了という2つの引数を受け取る。この変数のデフォルト値はfont-lock-after-change-function
。
カレントバッファーのリージョンのフォント表示の保証に使用する関数。そのリージョンの開始と終了という2つの引数を受け取る。この変数のデフォルト値は、バッファーがフォント表示されていないときにfont-lock-default-fontify-buffer
を呼び出す関数。効果はそのバッファーのアクセス可能範囲全体がフォント表示されることの保証。
この関数はカレントバッファーの一部をフォント表示/非表示する必要がある任意のタイミングで、Font LockモードがLisp関数functionを実行することを宣言する。これはデフォルトのフォント表示関数が呼び出される前に、フォント表示/非表示するリージョンを指定する2つの引数startとendでfunctionを呼び出す。
オプション引数contextualが非nil
なら、行が更新されたときに限らずそのバッファーの構文的に関連する部分を常にフォント表示するようFont
Lockモードに強制する。この引数は通常は省略できる。
以前にjit-lock-register
を使用してフォント表示関数としてfunctionを登録した場合は、その関数を未登録にする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フォント表示にたいして3つの異なるレベルを提供するモードがいくつかあります。font-lock-defaults
内のkeywordsにたいしてシンボルのリストを使用することにより複数のレベルを定義できます。このリストのシンボルはそれぞれフォント表示の1レベルを指定します。これらのレベルの選択は、通常はfont-lock-maximum-decoration
をセットすることによりユーザーの責任で行われます(Font
Lock in the GNU Emacs
Manualを参照)。選択されたレベルのシンボルの値はfont-lock-keywords
の初期化に使用されます。
フォント表示レベルの定義方法に関する慣習を以下に挙げます:
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
list-buffers
やoccur
のようないくつかのメジャーモードは、バッファーのテキストをプログラム的に構築します。これらにたいしてFont
Lockモードをサポートするためには、そのバッファーにテキストを挿入するタイミングでテキストのフェイスを指定するのがもっとも簡単な方法です。
これはスペシャルテキストプロパティfont-lock-face
(特殊な意味をもつプロパティを参照)により、テキスト内にフェイスを指定することによって行われます。Font
Lockモードが有効になったとき、このプロパティはface
と同じように表示を制御します。Font
Lockモードが無効になるとfont-lock-face
は表示に効果をもちません。
モードが通常のFont
Lockメカニズムとともに、あるテキストにたいしてfont-lock-face
を使用しても問題はありません。しかしそのモードが通常のFont
Lockメカニズムを使用しない場合には、変数font-lock-face
をセットするべきではありません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Font Lockモードはハイライトに任意のフェイスを使用できますが、Emacsは特にFontLockがテキストのハイライトに使用するいくつかのフェイスを定義しています。これらのFont Lockフェイス(Font Lock faces)を以下にリストします。これらのフェイスはFontLockモードの外部における構文的なハイライトでメジャーモードが使用することもできます(メジャーモードの慣習を参照)。
以下の各シンボルはフェイス名であり、かつデフォルト値がシンボル自身であるような変数でもあります。つまりfont-lock-comment-face
のデフォルト値はfont-lock-comment-face
です。
リストはそのフェイスの典型的な使い方の説明とともに、重要度が高い順にソートされています。あるモードの構文的カテゴリーが以下の使い方の記述にうまく適合しない場合には、この並び順をガイドとして使用することによってフェイスを割り当てることができるでしょう。
font-lock-warning-face
Emacs Lispの‘;;;###autoload’、Cの‘#error’のような特有な構文、またはその他のテキストの意味を大きく変更する構文にたいして使用される。
font-lock-function-name-face
定義、または宣言される関数の名前にたいして使用される。
font-lock-variable-name-face
定義、または宣言される変数の名前にたいして使用される。
font-lock-keyword-face
Cの‘for’や‘if’のように、構文的に特別な意味をもつキーワードにたいして使用される。
font-lock-comment-face
コメントにたいして使用される。
font-lock-comment-delimiter-face
Cの‘/*’と‘*/’のようなコメント区切りにたいして使用される。ほとんどの端末ではこのフェイスはfont-lock-comment-face
を継承する。
font-lock-type-face
ユーザー定義データ型にたいして使用される。
font-lock-constant-face
Cの‘NULL’のような定数の名前にたいして使用される。
font-lock-builtin-face
ビルトイン関数の名前にたいして使用される。
font-lock-preprocessor-face
プロセッサーコマンドにたいして使用される。デフォルトでは、font-lock-builtin-face
を継承する。
font-lock-string-face
文字列定数にたいして使用される。
font-lock-doc-face
コード内のドキュメント文字列にたいして使用される。デフォルトではfont-lock-string-face
を継承する。
font-lock-negation-char-face
見逃しやすい否定文字にたいして使用される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
構文的フォント表示(syntactic
fontification)は、構文的に関連性のあるテキストを探してハイライトするために構文テーブル(syntax table: 構文テーブルを参照)を使用します。有効な場合には検索ベースのフォント表示に先立って実行されます。以下で説明する変数font-lock-syntactic-face-function
はどの構文的構造をハイライトするかを決定します。構文的フォント表示に影響を与える変数がいくつかあります。font-lock-defaults
のためにそれらをセットするべきです(Font Lockの基礎を参照)。
Font
Lockモードが一連のテキストにたいして構文的フォント表示を処理するときは、常にsyntax-propertize-function
で指定される関数を最初に呼び出します。メジャーモードは特別なケースではsyntax-table
テキストプロパティを適用してバッファーの構文テーブルをオーバーライドするために、これを使用することができます。構文プロパティを参照してください。
この変数の値が非nil
なら、Font
Lockは構文的フォント表示を行わずにfont-lock-keywords
にもとづく検索ベースのフォント表示だけを行う。これは通常はfont-lock-defaults
内のkeywords-only要素にもとづいてFont
Lockモードによりセットされる。
この変数はコメントと文字列のフォント表示に使用するための構文テーブルを保持する。これは通常はfont-lock-defaults
内のsyntax-alist要素にもとづいてFont
Lockモードによりセットされる。この値がnil
なら、構文的フォント表示はバッファーの構文テーブル(関数syntax-table
がリターンする構文テーブル。構文テーブルの関数を参照)を使用する。
この変数が非nil
なら、それは与えられた構文的要素にどのフェイスを使用するかを決定する関数であること。この値は通常はfont-lock-defaults
内のother-vars要素を通じてセットされる。
この関数は1つの引数で呼び出され、parse-partial-sexp
がリターンするポイントの状態をパースしてフェイスをリターンすること。リターンされるデフォルト値はコメントにたいしてはfont-lock-comment-face
、文字列にたいしてはfont-lock-string-face
(Font Lockのためのフェイスを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
font-lock-keywords
の要素は、通常は複数行にわたるマッチを行うべきではありません。それらの動作に信頼性はありません。なぜならFont
Lockは通常はバッファーのごく一部をスキャンするので、そのスキャンが開始される行境界をまたがる複数行構造を見逃しかねないからです(スキャンは通常は行頭から開始される)。
ある要素にたいして複数行構造にたいするマッチを正しく機能させるために2つの観点があります。それは識別(identification)の補正と、再ハイライト(rehighlighting)の補正です。1つ目はFont Lockがすべての複数行構造を探すことを意味します。2つ目は複数行構造が変更されたとき、たとえば以前は複数行構造の一部だったテキストが複数行構造から除外されたときに、関連するすべてのテキストをFont Lockに正しく再ハイライトさせることを意味します。これら2つの観点は密接に関連しており、一方を機能させることがもう一方を機能させるようなことが多々あります。しかし信頼性のある結果を得るためには、これら2つの観点双方にたいして明示的に注意しなければなりません。
複数行構造の識別を確実に補正するには3つの方法があります:
font-lock-extend-region-functions
に追加する。
font-lock-fontify-region-function
フックを使用する。
font-lock-multiline
でそれをマークする。
複数行構造の再ハイライトを行うには3つの方法があります:
font-lock-multiline
を配置する。これによりその構造の一部が変更されると構造全体が再ハイライトされるだろう。あるケースにおいてはそれを参照するfont-lock-multiline
変数をセットすることにより自動的にこれを行うことができる。
jit-lock-contextually
を確実にセットしてそれが行う処理に委ねる。これにより、実際の変更に続いて構造の一部だけが若干の遅延の後に再ハイライトされるだろう。これは複数行構造のさまざまな箇所のハイライトが後続行のテキストに依存しない場合のみ機能する。jit-lock-contextually
はデフォルトでアクティブなので、これは魅力的な解決策になり得る。
jit-lock-defer-multiline
を配置する。これはjit-lock-contextually
が使用された場合のみ機能し、再ハイライト前に同様の遅延を伴うが、font-lock-multiline
のように後続行に依存する箇所のハイライトも処理する。
22.6.9.1 複数行のFont Lock | テキストプロパティで複数行塊をマークする。 | |
22.6.9.2 バッファー変更後のリージョンのフォント化 | バッファー変更後にどのリージョンを再フォント表示するかを制御する。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
複数行構造のFont
Lockを確実に再ハイライトする方法の1つは、それらをテキストプロパティfont-lock-multiline
にputする方法です。複数行構造の一部であるようなテキストには値が非nil
であるようなこのプロパティが存在するべきです。
Font
Lockがテキスト範囲をハイライトしようとする際は、まずそれらがfont-lock-multiline
プロパティでマークされたテキストにならないように必要に応じて範囲の境界を拡張します。それからその範囲のすべてのfont-lock-multiline
を削除してハイライトします。ハイライト指定(大抵はfont-lock-keywords
)は、適宜このプロパティを毎回再インストールしなければなりません。
警告:
ハイライトが低速になるので大きなテキスト範囲にたいしてfont-lock-multiline
を使用してはならない。
font-lock-multiline
変数がt
にセットされているとFont
Lockは自動的に複数行構造にたいしてfont-lock-multiline
プロパティの追加を試みる。しかしこれによりFont
Lockが幾分遅くなるので普遍的解決策ではない。これは何らかの複数行構造を見逃したり、必要なものより多く、または少なくプロパティをセットするかもしれない。
matcherが関数であるような要素は、たとえ少量のサブパート(subpart)だけがハイライトされるような場合でも、submatch
0(訳注:正規表現の後方参照においてsubmatch
0はマッチした文字列全体を指す)が関連する複数行構造全体を確実に網羅するようにすべきである。単に手動でfont-lock-multiline
を追加するのが容易な場合も多々ある。
font-lock-multiline
プロパティは、正しい再フォント表示を確実に行うことを意図しています。これは新たな複数行構造を自動的に認識しません。Font
Lockの処理を要するものにたいする認識は、一度に処理を行うのに十分な大きさのchunk(塊)にたいして行われます。これは多くの場合にアクシデントにより発生し得るかもしれないので、複数行構造が魔法のように機能するような印象を与えるかもしれません。変数font-lock-multiline
を非nil
にセットすると、発見されたこれらの構造にたいするハイライトは変数のセット後は正しく更新されるので、さらにこの印象が強くなるでしょう。しかしこれは信頼性をもって機能しません。
信頼性を保ち複数行構造を見つけるためには、Font
Lockが調べる前にテキストのfont-lock-multiline
プロパティを手動で配置するか、font-lock-fontify-region-function
を使用しなければなりません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファーが変更されたときFont Lockが再フォント表示するリージョンは、デフォルトではその変更に関連する最小の行全体からなるシーケンスです。これはほとんどの場合は良好に機能しますが、うまく機能しないとき(たとえば変更がそれより前の行のテキストの構文的な意味を変更してしまうとき)もあります。
以下の変数をセットすることにより、再フォント表示するリージョンを拡張(または縮小さえ)することができます:
このバッファーローカル変数はnil
、またはFont
Lockモードにたいしてスキャンしてフォント表示すべきリージョンを決定するために呼び出される関数である。
この関数には標準的なbegとend、およびafter-change-functions
のold-len
(フックの変更を参照)という3つのパラメーターが渡される。この関数はフォント表示するリージョンのバッファー位置の開始と終了(この順)からなるコンスセル、またはnil
(標準的な方法でリージョンを選択することを意味する)のいずれかをリターンすること。この関数はポイント位置、match-data、カレントのナローイングを保つ必要がある。これがリターンするリージョンは、行の途中で開始や終了するかもしれない。
この関数はバッファーを変更するたびに呼び出されるので有意に高速であること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プログラミング言語のメジャーモードにとって、自動的なインデントの提供は重要な機能です。これには2つのパートがあります。1つ目は正しい行のインデントが何か、そして2つ目はいつ行を再インデントするかの判断です。デフォルトではelectric-indent-chars
に含まれる文字(デフォルトでは改行のみ)をタイプしたとき、Emacsは常に行を再インデントします。メジャーモードはその言語の構文に合わせてelectric-indent-chars
に文字を追加できます。
正しいインデントの決定はindent-line-function
によりEmacs内で制御されます(メジャーモードが制御するインデントを参照)。いくつかのモードでは右へのインデントは信頼性がないことが知られています。これは通常は複数のインデントが有効であり、それぞれが異なる意味をもつのでインデント自体が重要だからです。そのような場合には、そのモードは行が常にユーザーの意に反して行が毎回再インデントされないことを保証するためにelectric-indent-inhibit
をセットするべきです。
よいインデント関数の記述は難しく、その広範な領域において未だ黒魔術の域を脱していません。メジャーモード作者の多くは、単純なケース(たとえば前のテキスト行のインデントとの比較)にたいして機能する、単純な関数の記述からスタートすることでしょう。実際には行ベースではないほとんどのプログラミング言語にたいして、これは貧弱なスケールになりがちです。そのような関数にたいして、より多様な状況を処理するような改良を行うと関数はより一層複雑になり、最終的な結果は誰にも触れようとする気を起こさせない、巨大で複雑な保守不可能のインデント関数になる傾向があります。
よいインデント関数は、通常はその言語の構文に応じて実際にテキストをパースする必要があるでしょう。幸運なことにこのテキストパースはコンパイラーが要するほど詳細である必要はないでしょうが、その一方でインデントコードに埋め込まれたパーサーは構文的に不正なコードにたいして、コンパイラーより幾分寛容な振る舞いを求められるでしょう。
保守可能なよいインデント関数は、通常は2つのカテゴリーに落ち着きます。どちらも何らかの安全な開始ポイントから、関心のある位置まで前方か後方へパースを行います。この2つの方法は、いずれも一方が他方に明快に優る選択ではありません。後方へのパースはプログラミング言語が前方にパースされるようデザインされているため、前方へのパースに比べて難しいことが多々ありますが、インデントという目的においては安全な開始ポイントを推測する必要がないという利点があり、一般的にある行のインデントの判断のために分析を要するのは最小限のテキストだけという特性に恵まれているので、前の無関係なコード片内にある何らかの構文エラーの影響をインデントが受けにくくなる傾向があります。一方で前方へのパースは通常はより簡単であり、一度のパースでリージョン全体を効果的に再インデントすることが可能になるという利点があります。
インデント関数をスクラッチから記述するよりも、既存のインデント関数の使用と再利用、または一般的なインデントエンジンに委ねるほうが優る場合がしばしばあります。しかしそのようなエンジンは悲しむべきほど少数しかありません。(C、C++、Java、Awk、およびその類のモードに使用される)CCモードのインデントコードは年月を経てより一般化されてきているので、あなたの言語にこれらの言語と何らかの類似点があるなら、このエンジンの使用を試みるかもしれません。もう一方のSMIEはLispのsexp精神によるアプローチを採用して、それを非Lisp言語に適応します。
22.7.1 SMIE: 無邪気なインデントエンジン | SMIE: Simple Minded Indentation Engine(純真なインデントエンジン) |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SMIEは一般的な操作とインデントを提供するエンジンです。これは演算子順位文法(operator precedence grammar)を使用する非常にシンプルなパーサーにもとづいたエンジンであり、メジャーモードがLispのS式ベースの操作を非Lisp言語に拡張するのを助けるとともにシンプルに使用できるにも関わらず、信頼できる自動インデントを提供します。
演算子順位文法はコンパイラー内で使用されるより一般的なパーサーと比較すると非常に原始的なパーステクノロジーです。このパーサーには次のような特徴があります。このパーサーのパース能力は非常に限定的で構文エラーを大概は検出できません。しかしアルゴリズム的に前方パースと同様に後方パースを効果的に行うことが可能です。実際にそれはSMIEが後方パースにもとづくインデントを使用でき、forward-sexp
とbackward-sexp
の両方の機能を提供できるとともに、特別な努力を要さずに構文的に不正なコードにたいして自然に機能するであろうことを意味します。欠点はほとんどのプログラミング言語は、少なくとも何らかの特別なトリック(非力なパーサーの使用を参照)で再分類しなければSMIEを使用して正しくパースできないことをも意味することです。
22.7.1.1 SMIEのセットアップと機能 | ||
22.7.1.2 演算子順位文法 | 非常にシンプルなパース技術。 | |
22.7.1.3 言語の文法の定義 | 言語の文法を定義する。 | |
22.7.1.4 トークンの定義 | ||
22.7.1.5 非力なパーサーの使用 | パーサー制限の回避策。 | |
22.7.1.6 インデントルールの指定 | ||
22.7.1.7 インデントルールにたいするヘルパー関数 | ||
22.7.1.8 インデントルールの例 | ||
22.7.1.9 インデントのカスタマイズ |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SMIEは構造的な操作とコードの構造的構造にもとづくその他さまざまな機能、特に自動インデントにたいするワンストップショップ(一カ所で必要な全ての買い物ができる店やそのような場所)であることを意図しています。メインのエントリーポイントはsmie-setup
で、これは通常はメジャーモードセットアップの間に呼び出される関数です。
SMIEの操作とインデントをセットアップする。grammarはsmie-prec2->grammar
により生成される文法テーブル(grammar
table)、rules-functionはsmie-rules-function
で使用されるインデントルールのセット、keywordsは追加の引数であり以下のキーワードを含むことができる:
:forward-token
fun: 使用する前方lexer(lexer=lexical analyzer:
字句解析プログラム)を指定する。
:backward-token
fun: 使用する後方lexerを指定する。
この関数を呼び出せばforward-sexp
、backward-sexp
、transpose-sexps
のようなコマンドが、すでに構文テーブルにより処理されている単なるカッコのペア以外の、構造的な要素を正しく扱うことができるようになります。たとえば与えられた文法が十分に明快ならば、transpose-sexps
はその言語の優先順位のルールを考慮して+
演算子の2つの引数を正しく入れ替えることができます。
smie-setup
を呼び出すことにより、TABによるインデントを期待通り機能させるとともに、begin...end
のような要素に適用するためにblink-matching-paren
を拡張して、そのメジャーモードのキーマップ内でバインドできるいくつかのコマンドを提供することも満足されます。
このコマンドは、もっとも最近オープンされた(まだクローズされていない)ブロックをクローズする。
このコマンドはdown-list
と似ているが、begin...end
のようなカッコ以外のネストされたトークンにも注意を払う。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SMIEの演算子順位文法は、各トークンにたいしてシンプルに左優先(left-precedence)と右優先(right-precedence)という順位ペアを与えます。トークンT1
の右優先がトークンT2
の左優先より小さければT1
< T2
であると言うことにしましょう。これを解読するには<
をカッコの一種だとみなすのがよい方法です。... T1
something T2 ...
を見つけたら、これは... T1 something) T2 ...
ではなく... T1
(something T2 ...
とパースされるべきです。... T1 something) T2 ...
と解釈するのはT1
> T2
を見つけた場合でしょう。T1 =
T2
を見つけた場合、それはトークンT2とその後のトークンT1が同じ構文構成にあり、通常は"begin" =
"end"
を得ます。このような優先順位のペアは2項演算子(infix
operator)、カッコのようなネストされたトークン、およびその他多くのケースにたいして左結合(left-associativity)や右結合(right-associativity)を表現するのに十分です。
この関数はprec2文法tableを引数に受け取り、smie-setup
で使用するのに適したalistをリターンする。prec2文法tableは、それ自体が以下の関数のいずれかによりビルドされることを意図している。
この関数は複数のprec2文法tablesを、新たなprec2テーブルにマージする。
この関数は順位テーブルprecsからprec2テーブルをビルドする。precsは優先順(たとえば"+"
は"*"
より前にくる)にソートされたリストであり、要素は(assoc
op
...)
の形式であること。ここでopは演算子として振る舞うトークン、assocはそれらの結合法則でありleft
、right
、assoc
、nonassoc
のいずれかである。与えられた要素内のすべての演算子は同じ優先レベルと結合法則を共有する。
この関数によりBNF記法を使用した文法を指定することができる。これはその文法のbnf表記と、同様に競合解決ルールresolversを受け取ってprec2テーブルをリターンする。
bnfは(nonterm rhs1 rhs2
...)
という形式の非終端定義、各rhsは終端記号(トークンとも呼ばれる)、または非終端記号の(空でない)リストである。
すべての文法が許容される訳ではない:
さらに競合が発生し得る:
opener
(開カッコに似た何か)、closer
(閉カッコのようなもの)、またはこれら2つのいずれでもないneither
(2項演算子や"else"
のようなinnerトークン)である。
順位の競合はresolversを通じて解決され得る。これはprecsテーブル(smie-precs->prec2
を参照)のリストである。それぞれの順位競合にたいして、これらのprecs
テーブルが特定の制約を指定している場合は、かわりにこの制約により競合が解決され、それ以外は競合する制約のうち任意の1つが報告されて他は単に無視される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ある言語にたいしてSMIE文法を定義する通常の方法は、順位のテーブルを保持する新たなグローバル変数を定義してBNFルールのセットを与える方法です。たとえば小規模なPascal風言語の文法定義は以下のようになるでしょう:
(require 'smie) (defvar sample-smie-grammar (smie-prec2->grammar (smie-bnf->prec2
'((id) (inst ("begin" insts "end") ("if" exp "then" inst "else" inst) (id ":=" exp) (exp)) (insts (insts ";" insts) (inst)) (exp (exp "+" exp) (exp "*" exp) ("(" exps ")")) (exps (exps "," exps) (exp)))
'((assoc ";")) '((assoc ",")) '((assoc "+") (assoc "*")))))
注意すべき点がいくつかあります:
begin
... end
ブロックのようなsexpの任意のシーケンスがどこに、どのように出現しても自動的にそれを許容するだろう。
id
は右側に何ももたない。これはid
が空文字列だけにマッチ可能なことを意味しない。なぜなら上述のように任意のsexpシーケンスはどこに、どのような方法でも出現するからである。
";"
をセパレーター(separator)ステートメントのかわりとして扱っている。
","
や";"
のような)セパレーターは、BNFルールでは(foo (foo
"separator" foo) ...)
のように定義するのが最善である。これは順位の競合を生成するが、明示的に(assoc
"separator")
を与えることにより解決される、
("(" exps
")")
ルールにカッコをペアにする必要はなかった。(exps
の定義と併せて)これはかわりに","
がカッコの外に出現すべきではないことを明確にするためのルール。
left
やright
を選択することが優るという明白な理由がなければ、通常はassoc
を使用して演算子を結合演算子(associative)とマークするほうが優れている。この理由により上述の"+"
と"*"
は、たとえその言語がそれらを形式上は左結合(left
associative)と定義していてもassoc
として定義されている。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SMIEには事前定義された字句解析プログラムが付属しており、それは次の方法で構文テーブルを使用します:
文字の任意のシーケンスはトークンとみなせる単語構文(word syntax)かシンボル構文(symbol
syntax)をもち、区切り文字構文(punctuation
syntax)をもつ任意の文字シーケンスもトークンとみなされます。このデフォルトのlexerは開始ポイントとして適している場合が多々ありますが、任意の与えられた言語にたいして実際に正しいことは稀です。たとえばこれは"2,+3"
が3つのトークン"2"
、",+"
、"3"
から構成されていると判断するでしょう。
あなたの言語のlexerルールをSMIEにたいして説明するためには、次のトークンをfetchする関数と前のトークンをfetchする関数という2つの関数が必要になります。これらの関数は通常は最初に空白文字とコメントをスキップして、その後に次のテキストchunk(塊)を調べてそれが特別なトークンか確認します。これは通常は単にバッファーから抽出された文字列ですが、あなたが望む他の何かでも構いません。たとえば:
(defvar sample-keywords-regexp (regexp-opt '("+" "*" "," ";" ">" ">=" "<" "<=" ":=" "=")))
(defun sample-smie-forward-token () (forward-comment (point-max)) (cond ((looking-at sample-keywords-regexp) (goto-char (match-end 0)) (match-string-no-properties 0)) (t (buffer-substring-no-properties (point) (progn (skip-syntax-forward "w_") (point))))))
(defun sample-smie-backward-token () (forward-comment (- (point))) (cond ((looking-back sample-keywords-regexp (- (point) 2) t) (goto-char (match-beginning 0)) (match-string-no-properties 0)) (t (buffer-substring-no-properties (point) (progn (skip-syntax-backward "w_") (point))))))
これらのlexerがカッコの前にあるとき空文字列をリターンする方法に注目してください。これはSMIEが構文テーブル内で定義されているカッコにたいして自動的に配慮するからです。より厳密にはlexerがnil
、または空文字列をリターンしたら、SMIEは構文テーブルにしたがって対応するテキストをsexpとして処理します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SMIEが使用するパーステクニックは、異なるコンテキストでトークンが異なる振る舞いをすることを許容しません。ほとんどのプログラミング言語にたいして、これは順位の競合によりBNF文法を変換するとき明らかになります。
その文法を若干異なるように表現することにより、これらの競合を回避できる場合があります。たとえばModula-2にたいしては以下のようなBNF文法をもつことが自然に思えるかもしれません:
... (inst ("IF" exp "THEN" insts "ELSE" insts "END") ("CASE" exp "OF" cases "END") ...) (cases (cases "|" cases) (caselabel ":" insts) ("ELSE" insts)) ...
しかしこれは"ELSE"
にたいする競合を生み出すでしょう。その一方でIFルールは、(他の多くのものの中でも特に)"ELSE"
=
"END"
を暗示します。しかしその一方で"ELSE"
はcases
内に出現しますが、cases
は"END"
の左に出現するので、わたしたちは"ELSE"
> "END"
も得ることになります。これは以下を使用して解決できます:
... (inst ("IF" exp "THEN" insts "ELSE" insts "END") ("CASE" exp "OF" cases "END") ("CASE" exp "OF" cases "ELSE" insts "END") ...) (cases (cases "|" cases) (caselabel ":" insts)) ...
または
... (inst ("IF" exp "THEN" else "END") ("CASE" exp "OF" cases "END") ...) (else (insts "ELSE" insts)) (cases (cases "|" cases) (caselabel ":" insts) (else)) ...
文法書き換えによる競合の解決には欠点があります。なぜならSMIEはその文法がコードの論理的構造を反映すると仮定するからです。そのためBNFと意図する抽象的構文木の関係を密接に保つことが望まれます。
注意深く考慮した結果、これらの競合が深刻ではなく、smie-bnf->prec2
のresolvers引数を通じて解決する決心をする場合もあるでしょう。これは通常はその文法が単に不明瞭だからです。その文法により記述されるプログラムセットは競合の影響を受けませんが、それらのプログラムにたいする唯一の方法はパースだけです。'((assoc
"|"))
のようなリゾルバ(resolver:
解決するもの)を追加したいと望むような場合、通常それはセパレーターと2項結合演算子にたいするケースです。これが発生し得る他のケースは'((assoc
"else" "then"))
を使用するような場合における、古典的なぶら下がりelse問題(dangling else
problem)です。これは実際に競合があり解決不能なものの、実際のところ問題が発生しそうにないケースにたいしても発生し得ます。
最後に多くのケースではすべての文法再構築努力にも関わらず、いくつかの競合が残るでしょう。しかし失望しないでください。パーサーをより賢くすることはできませんが、あなたの望むようにlexerをスマートにすることは可能です。その方法は競合が発生したら競合を引き起こしたトークンを調べて、それらのうちの1つを2つ以上の異なるトークンに分割する方法です。たとえばトークン"begin"
にたいする互換性のない2つの使用を文法が区別する必要があり、見つかった"begin"
の種類によってlexerに異なるトークン(たとえば"begin-fun"
と"begin-plain"
)をリターンさせる場合です。これはlexerにたいして異なるケースを区別する処理を強制し、そのためにlexerは特別な手がかりを見つけるために周囲のテキストを調べる必要があるでしょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
提供された文法にもとづき、他に特別なことを行わなくてもSMIEは自動的なインデントを提供できるでしょう。しかし恐らく実際にはこのデフォルトのインデントスタイルでは十分ではありません。多くの異なる状況においてこれを微調整したいと思うかもしれません。
SMIEのインデントは、インデントルールは可能な限りローカルであるべきという考えにもとづきます。バーチャルインデント(virtual
indentation)という考えによってこの目的を達成しています。これは特定のプログラムポイント(program
point)は行頭にバーチャルインデントがあれば、それをもつだろう、という発想です。もちろんそのプログラムポイントが正に行頭にあれば、そのプログラムポイントのバーチャルインデントはプログラムポイントのカレントのインデントです。しかしそうでなければSMIEがそのポイントのバーチャルインデントを計算するためにインデントアルゴリズムを使用します。ところで実際にはあるプログラムポイントのバーチャルインデントは、その前に改行を挿入した場合にプログラムポイントがもつであろうインデントと等しい必要はありません。これが機能する方法を確認するためには、Cにおける{
の後のSMIEのインデントルールは{
がインデントする行自体にあるか、あるいは前の行の終端にあるかを配慮しないことが挙げられます。かわりにこれらの異なるケースは{
の前のインデントを決定するインデントルール内で処理されます。
他の重要な考え方としてparentの概念があります。あるトークンparentは周囲にある直近の構文構造の代表トークン(head
token)です。たとえばelse
のparentはそれが属するif
であり、if
のparentは周囲を取り囲む構造の先導トークン(lead
token)です。コマンドbackward-sexp
は、あるトークンからトークンのparentにジャンプしますが注意する点がいくつかあります。他のトークンではそのトークンの後のポイントから開始する必要があるのにたいして、opener
(if
のようなある構造を開始するトークン)ではそのトークンの前のポイントから開始する必要があります。backward-sexp
はparentトークンがそのトークンのopenerならparentトークンの前のポイントで停止し、それ以外ではparentトークンの後のポイントで停止します。
SMIEのインデントルールは、2つの引数methodとargを受け取る関数により指定されます。ここでargの値と期待されるリターン値はmethodに依存します。
methodには以下のいずれかを指定できます:
:after
:
この場合、argはトークンであり関数はargの後に使用するインデントにたいするoffsetをリターンすること。
:before
:
この場合、argはトークンであり関数はarg自体に使用するインデントのoffsetをリターンすること。
:elem
:
この場合、関数は関数の引数に使用するインデントのオフセット(argがシンボルarg
の場合)、または基本的ナインデントステップ(argがシンボルbasic
の場合)のいずれかをリターンすること。
:list-intro
:
この場合、argはトークンであり関数はそのトークンの後が単一の式ではなく、(任意のトークンにより区切られない)式のリストが続くなら非nil
をリターンすること。
argがトークンのとき関数はそのトークンの直前のポイントで呼び出されます。リターン値nil
は常にデフォルトの振る舞いへのフォールバックを意味するので、関数は期待した引数でないときはnil
をリターンするべきです。
offsetには以下のいずれかを指定できます:
nil
: デフォルトのインデントルールを使用する。
(column . column)
: 列columnにインデントする。
:after
にたいするカレントトークンであり、かつ:before
にたいしてparentであるようなトークン)にたいして相対的なnumberによるオフセット。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SMIEはインデントを決定する関数内で使用するために特別にデザインされたさまざまな関数を提供します(これらの関数のうちのいくつかは異なるコンテキスト内で使用された場合に中断する)。これらの関数はすべてプレフィックスsmie-rule-
で始まります。
カレントトークンが行の先頭にあれば非nil
をリターンする。
カレントトークンがhanging(ぶら下がり)なら非nil
をリターンする。トークンがその行の最後のトークンであり、他のトークンが先行する場合、そのトークンはhangingである。行に単独のトークンはhangingではない。
次のトークンがtokens内にあれば非nil
をリターンする。
前のトークンがtokens内にあれば非nil
をリターンする。
カレントトークンのparentがparents内にあれば非nil
をリターンする。
カレントトークンのparentが実際はsibling(兄弟)なら非nil
をリターンする。たとえば","
のparentが直前の","
のような場合が該当。
カレントトークンをparentとアライン(align:
桁揃え)するための適切なオフセットをリターンする。offsetが非nil
なら、それは追加オフセットとして適用される整数であること。
セパレーター(separator)としてカレントトークンをインデントする。
ここでのセパレーターとは周囲を取り囲む何らかの構文構造内でさまざまな要素を区切ることを唯一の目的とするトークンであり、それ自体は何も意味をもたないトークン(通常は抽象構文木内でノードとして存在しないこと)を意味する。
このようなトークンは結合構文をもち、その構文的parentと密に結び付けられることが期待される。典型的な例としては引数リスト内の","
(カッコで括られた内部)、または命令文シーケンス内の";"
({...}
やbegin...end
で括られたブロックの内部)が挙げられる。
methodはsmie-rules-function
に渡されるメソッド名であること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はインデント関数の例です:
(defun sample-smie-rules (kind token) (pcase (cons kind token) (`(:elem . basic) sample-indent-basic) (`(,_ . ",") (smie-rule-separator kind)) (`(:after . ":=") sample-indent-basic) (`(:before . ,(or `"begin" `"(" `"{"))) (if (smie-rule-hanging-p) (smie-rule-parent))) (`(:before . "if") (and (not (smie-rule-bolp)) (smie-rule-prev-p "else") (smie-rule-parent)))))
注意すべき点がいくつかあります:
sample-indent-basic
がnil
なら、SMIEはグローバルセッティングsmie-indent-basic
を使用する。メジャーモードがかわりにsmie-indent-basic
をバッファーローカルにセットするかもしれないが推奨しない。
","
にたいするルールによってカンマセパレーターが行頭にある場合にSMIEをより賢明に振る舞わせようとしている。これはセパレーターのインデントを解除(outdent)、カンマの後のコードにアラインされるよう試みる。たとえば:
x = longfunctionname ( arg1 , arg2 );
":="
を2項演算子として扱い、左の引数に併せて右の引数をアラインするであろうから、":="
の後のインデントのルールが存在する。
"begin"
の前のインデントのルールはバーチャルインデントの使用例である。このルールは"begin"
がhangingのときだけ使用され、これは"begin"
が行頭にないときのみ発生し得る。そのためこれは"begin"
自体のインデントには使用されないが、この"begin"
に関連する何かをインデントするときだけ使用される。このルールは具体的には以下のフォームを:
if x > 0 then begin dosomething(x); end
以下に変更する
if x > 0 then begin dosomething(x); end
"if"
の前のインデントのルールは"begin"
のインデントルールと似ているが、ここでの目的は"else
if"
を1単位として扱うことにあり、それにより各テストより右にインデントされずに一連のテストにアラインされる。この関数はsmie-rule-bolp
をテストして"if"
が別の行にないときだけこれを行う。
"else"
がそれの属する"if"
にたいして常にアラインされて、かつそれが常に行頭であるることが判っていれば、より効果的なルールを使用できる:
((equal token "if") (and (not (smie-rule-bolp)) (smie-rule-prev-p "else") (save-excursion (sample-smie-backward-token) (cons 'column (current-column)))))
この式の利点はこれがシーケンスの最初の"if"
まで戻ってすべてをやり直すのではなく、前の"else"
のインデントを再利用することである。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SMIEにより提供されるインデントを使用するモードを使っている場合には、好みに合わせてインデントをカスタマイズできます。これはモードごと(オプションsmie-config
を使用)、またはファイルごと(ファイルローカル変数指定内で関数smie-config-local
を使用)に行うことができます。
このオプションによりモードごとにインデントをカスタマイズできる。これは(mode
.
rules)
という形式の要素をもつalist。rulesの正確な形式については変数のドキュメントを参照のこと。しかしコマンドsmie-config-guess
を使用したほうが、より簡単に見つけられるかもしれない。
このコマンドは好みのスタイルのインデントを生成する適切セッティングの解決を試みる。あなたのスタイルでインデントされたファイルをvisitしているときに単にこのコマンドを呼び出せばよい。
smie-config-guess
を使用した後にこのコマンドを呼び出すと将来のセッション用にセッティングを保存する。
このコマンドはカレント行のインデントに使用されているルールを表示する。
このコマンドはカレント行のインデントに合わせてローカルルールを追加する。
この関数はカレントバッファーにたいするインデントルールとしてrulesを追加する。これらのルールはsmie-config
オプションにより定義された任意のモード固有ルールに追加される。特定のファイルにたいしてカスタムインデントルールを指定するには、eval:
(smie-config-local '(rules))
の形式のエントリーをそのファイルのローカル変数に追加する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Desktop Saveモードとは、あるセッションから別のセッションへEmacs状態を保存する機能です。Desktop Saveモードの使用に関するユーザーレベルのコマンドについては、GNU Emacsマニュアルに記載されています(Saving Emacs Sessions in the GNU Emacs Manualを参照)。バッファーでファイルをvisitしているモードでは、この機能を使うために何も行う必要はありません。
ファイルをvisitしていないバッファーについて状態を保存するには、そのメジャーモードがバッファーローカル変数desktop-save-buffer
を非nil
値にバインドしなければなりません。
このバッファーローカル変数が非nil
なら、デスクトップ保存時にそのバッファー状態がdesktopファイルに保存される。値が関数なら、その関数はデスクトップ保存時に引数desktop-dirnameで呼び出されて、関数が呼び出されたバッファーの状態とともに関数の値がdesktopファイルに保存される。補助的な情報の一部としてファイル名がリターンされたとき、それらは以下を呼び出してフォーマットされること
(desktop-file-name file-name desktop-dirname)
ファイルをvisitしていないバッファーがリストアされるようにするには、メジャーモードがその処理を行う関数を定義しなければならず、その関数は連想配列desktop-buffer-mode-handlers
にリストされなければならない。
以下を要素にもつalist
(major-mode . restore-buffer-function)
関数restore-buffer-functionは以下の引数リストで呼び出される
(buffer-file-name buffer-name desktop-buffer-misc)
この関数はリストアされたバッファーをリターンすること。ここでdesktop-buffer-miscは、オプションでdesktop-save-buffer
にバインドされる関数がリターンする値。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU Emacsには便利なビルトインのヘルプ機能があり、それらのほとんどは関数や変数のドキュメント文字列に付属するドキュメント文字列の情報が由来のものです。このチャプターではLispプログラムからドキュメント文字列にアクセスする方法について説明します。
ドキュメント文字列のコンテンツはある種の慣習にしたがう必要があります。特に最初の行はその関数や変数を簡単に説明する1つか2つの完全なセンテンスであるべきです。よいドキュメント文字列を記述する方法についてはドキュメント文字列のヒントを参照してください。
Emacs向けのドキュメント文字列はEmacsマニュアルと同じものではないことに注意してください。マニュアルはTexinfo言語で記述された独自のソースファイルをもちます。それにたいしドキュメント文字列はそれが適用される関数と変数の定義内で指定されたものです。ドキュメント文字列を収集してもそれはマニュアルとしては不十分です。なぜならよいマニュアルはそのやり方でまとめられたものではなく、議論にたいするトピックという観点でまとめられたものだからです。
ドキュメント文字列を表示するコマンドについては、Help in The GNU Emacs Manualを参照してください。
23.1 ドキュメントの基礎 | ドキュメント文字列が定義、格納される場所。 | |
23.2 ドキュメント文字列へのアクセス | Lispプログラムがドキュメント文字列にアクセスする方法。 | |
23.3 ドキュメント内でのキーバインディングの置き換え | カレントキーバインディングの置き換え。 | |
23.4 ヘルプメッセージの文字記述 | 非プリント文字やキーシーケンスをプリント可能な記述にする。 | |
23.5 ヘルプ関数 | Emacsヘルプ機能により使用されるサブルーチン。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ドキュメント文字列はテキストをダブルクォート文字で囲んだ文字列にたいするLisp構文を使用して記述されます。実はこれは実際のLisp文字列です。関数または変数の定義内の適切な箇所に文字列があると、それは関数や変数のドキュメントの役割を果たします。
関数定義(lambda
やdefun
フォーム)の中では、ドキュメント文字列は引数リストの後に指定され、通常は関数オブジェクト内に直接格納されます。関数のドキュメント文字列を参照してください。関数名のfunction-documentation
プロパティに関数ドキュメントをputすることもできます(ドキュメント文字列へのアクセスを参照)。
変数定義(defvar
フォーム)の中では、ドキュメント文字列は初期値の後に指定されます。グローバル変数の定義を参照してください。この文字列はその変数のvariable-documentation
プロパティに格納されます。
Emacsがメモリー内にドキュメント文字列を保持しないときがあります。それには、これには2つの状況があります。1つ目はメモリーを節約するためで、事前ロードされた関数と変数(プリミティブを含む)のドキュメントは、doc-directory
で指定されたディレクトリー内のDOCという名前のファイルに保持されます(ドキュメント文字列へのアクセスを参照)。2つ目は関数や変数がバイトコンパイルされたファイルからロードされたときで、Emacsはそれらのドキュメント文字列のロードを無効にします(ドキュメント文字列とコンパイルを参照)。どちらの場合も、ある関数にたいしてユーザーがC-h
f(describe-function
)を呼び出したとき等の必要なときだけEmacsはファイルのドキュメント文字列を照会します。
ドキュメント文字列にはユーザーがドキュメントを閲覧するときのみルックアップされるキーバインディングを参照する、特別なキー置換シーケンス(key substitution sequences)を含めることができます。これにより、たとえユーザーがデフォルトのキーバインディングを変更していてもヘルプコマンドが正しいキーを表示できるようになります。
オートロードされたコマンド(autoloadを参照)のドキュメント文字列ではこれらのキー置換シーケンスは特別な効果をもち、そのコマンドにたいするC-h fによってオートロードをトリガーします(これは*Help*バッファー内のハイパーリンクを正しくセットアップするために必要となる)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はプロパティproperty配下のsymbolのプロパティリスト内に記録されたドキュメント文字列をリターンする。これはほとんどの場合propertyをvariable-documentation
にして、変数のドキュメント文字列の照会に使用される。しかしカスタマイゼーショングループのような他の種類のドキュメント照会にも使用できる(が関数のドキュメントには以下のdocumentation
関数を使用する)。
そのプロパティの値がDOCファイルやバイトコンパイル済みファイルに格納されたドキュメント文字列を参照する場合、この関数はその文字列を照会してそれをリターンする。
プロパティの値がnil
や文字列以外でファイル内のテキストも参照しなければ、文字列を取得するLisp式として評価される。
最終的にこの関数はキーバインディングを置換するために、文字列をsubstitute-command-keys
に引き渡す(ドキュメント内でのキーバインディングの置き換えを参照)。verbatimが非nil
ならこのステップはスキップされる。
(documentation-property 'command-line-processed 'variable-documentation) ⇒ "Non-nil once command line has been processed"
(symbol-plist 'command-line-processed) ⇒ (variable-documentation 188902)
(documentation-property 'emacs 'group-documentation) ⇒ "Customization of the One True Editor."
この関数はfunctionのドキュメント文字列をリターンする。この関数はマクロ、名前付きキーボードマクロ、およびスペシャルフォームも通常の関数と同様に処理する。
functionがシンボルならそのシンボルのfunction-documentation
プロパティを最初に調べる。それが非nil
値をもつなら、その値(プロパティの値が文字列以外ならそれを評価した値)がドキュメントとなる。
functionがシンボル以外、あるいはfunction-documentation
プロパティをもたなければ、documentation
は必要ならファイルを読み込んで実際の関数定義のドキュメント文字列を抽出する。
最後にverbatimがnil
なら、この関数はsubstitute-command-keys
を呼び出す。結果はリターンするための文字列。
documentation
関数はfunctionが関数定義をもたなければvoid-function
エラーをシグナルする。しかし関数定義がドキュメントをもたない場合は問題ない。その場合はdocumentation
はnil
をリターンする。
この関数はfaceのドキュメント文字列をフェイスとしてリターンする。
以下はdocumentation
とdocumentation-property
を使用した例で、いくつかのシンボルのドキュメント文字列を*Help*バッファー内に表示します。
(defun describe-symbols (pattern) "Describe the Emacs Lisp symbols matching PATTERN. All symbols that have PATTERN in their name are described in the *Help* buffer." (interactive "sDescribe symbols matching: ") (let ((describe-func (function (lambda (s)
;; シンボルの説明をプリントする (if (fboundp s) ; これは関数 (princ (format "%s\t%s\n%s\n\n" s (if (commandp s) (let ((keys (where-is-internal s))) (if keys (concat "Keys: " (mapconcat 'key-description keys " ")) "Keys: none")) "Function")
(or (documentation s)
"not documented"))))
(if (boundp s) ; これは変数
(princ (format "%s\t%s\n%s\n\n" s (if (custom-variable-p s) "Option " "Variable")
(or (documentation-property s 'variable-documentation) "not documented"))))))) sym-list)
;; PATTERNにマッチするシンボルのリストを構築
(mapatoms (function
(lambda (sym)
(if (string-match pattern (symbol-name sym))
(setq sym-list (cons sym sym-list))))))
;; データを表示
(help-setup-xref (list 'describe-symbols pattern) (interactive-p))
(with-help-window (help-buffer)
(mapcar describe-func (sort sym-list 'string<)))))
describe-symbols
関数はapropos
のように機能しますが、より多くの情報を提供します。
(describe-symbols "goal") ---------- Buffer: *Help* ---------- goal-column Option Semipermanent goal column for vertical motion, as set by …
minibuffer-temporary-goal-position Variable not documented
set-goal-column Keys: C-x C-n Set the current horizontal position as a goal for C-n and C-p.
Those commands will move to this position in the line moved to rather than trying to keep the same horizontal position. With a non-nil argument ARG, clears out the goal column so that C-n and C-p resume vertical motion. The goal column is stored in the variable ‘goal-column’. msgid "" "(defun describe-symbols (pattern)\n" " \"Describe the Emacs Lisp symbols matching PATTERN.\n" "All symbols that have PATTERN in their name are described\n" "in the `*Help*' buffer.\"\n" " (interactive \"sDescribe symbols matching: \")\n" " (let ((describe-func\n" " (function\n" " (lambda (s)\n"
temporary-goal-column Variable Current goal column for vertical motion. It is the column where point was at the start of the current run of vertical motion commands. When moving by visual lines via the function ‘line-move-visual’, it is a cons cell (COL . HSCROLL), where COL is the x-position, in pixels, divided by the default column width, and HSCROLL is the number of columns by which window is scrolled from left margin. When the ‘track-eol’ feature is doing its job, the value is ‘most-positive-fixnum’. ---------- Buffer: *Help* ----------
この関数はEmacsビルド時の実行可能なEmacsダンプ直前に使用される。これはファイルfilename内に格納されたドキュメント文字列の位置を探して、メモリー上の関数定義および変数のプロパティリスト内にそれらの位置を記録する。Emacsのビルドを参照のこと。
Emacsはemacs/etcディレクトリーからファイルfilenameを読み込む。その後ダンプされたEmacs実行時に、ディレクトリーdoc-directory
内の同じファイルを照会する。filenameは通常は"DOC"
。
この変数はビルトインおよび事前ロードされた関数と変数のドキュメント文字列を含んだファイル"DOC"
があるべきディレクトリーの名前を保持する。
これはほとんどの場合はdata-directory
と同一。実際にインストールしたEmacsではなくEmacsをビルドしたディレクトリーからEmacsを実行したときは異なるかもしれない。Definition of data-directoryを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ドキュメント文字列がキーシーケンスを参照する際、それらはカレントである実際のキーバインディングを使用するべきです。これらは以下で説明する特別なキーシーケンスを使用して行うことができます。通常の方法によるドキュメント文字列へのアクセスは、これらの特別なキーシーケンスをカレントキーバインディングに置き換えます。これはsubstitute-command-keys
を呼び出すことにより行われます。あなた自身がこの関数を呼び出すこともできます。
以下はそれら特別なシーケンスと、その意味についてのリストです:
\[command]
これはcommandを呼び出すキーシーケンス、またはcommandがキーバインディングをもたなければ‘M-x command’。
\{mapvar}
これは変数mapvarの値であるようなキーマップの要約(summary)を意味する。この要約はdescribe-bindings
を用いて作成される。
\<mapvar>
これ自体は何のテキストも意味せず副作用のためだけに使用される。これはこのドキュメント文字列内にある、後続のすべての‘\[command]’にたいするキーマップとしてmapvarの値を指定する。
‘
`
この両者(左シングルクォーテーションマークとグレーブアクセント)は左クォートを意味する。これはtext-quoting-style
の値に応じて左シングルクォーテーションマーク、アポストロフィー、グレーブアクセントのいずれかを生成する。
’
'
この両者(右シングルクォーテーションマークとアポストロフィー)は右クォートを意味する。これはtext-quoting-style
の値に応じてアポストロフィー)はシングルクォーテーションマークかアポストロフィーのいずれかを生成する。
\=
これは後続の文字をクォートして無効にする。したがって‘\=\[’は‘\[’、‘\=\=’は‘\=’を出力する。
注意してください: Emacs Lisp内の文字列として記述する際は‘\’を2つ記述しなければなりません。
この変数の値はEmacsがヘルプとメッセージの文言でシングルクォートに使用するべきスタイルを指定するシンボルである。この変数の値がcurve
なら‘like
this’のようなcurved single quotesスタイル。値がstraight
なら'like
this'のようなstraight apostrophesスタイル。値がgrave
なら`like
this'のようなEmacsのバージョン25以前の標準であるgrave
accentとapostropheのスタイル。デフォルト値のnil
はcurved single
quotesが表示可能ならcurve
、それ以外ならgrave
と同様に振る舞う。
この変数はcurved quotesに問題のあるプラットフォームでエキスパートが使用可能。通常の使用を意図していないのでユーザーオプションではない。
この関数は上述の特別なシーケンスをstringからスキャンして、それらが意味するもので置き換えてその結果を文字列としてリターンする。これによりそのユーザー自身がカスタマイズした実際のキーシーケンスを参照するドキュメントが表示できる。
あるコマンドが複数のバインディングをもつ場合、通常この関数は最初に見つかったバインディングを使用する。以下のようにしてコマンドのシンボルプロパティ:advertised-binding
に割り当てることにより、特定のキーバインディングを指定できる:
(put 'undo :advertised-binding [?\C-/])
:advertised-binding
プロパティはメニューアイテム(メニューバー Barを参照)に表示されるバインディングにも影響する。コマンドが実際にもたないキーバインディングを指定するとこのプロパティは無視される。
以下は特別なキーシーケンスの例:
(substitute-command-keys "To abort recursive edit, type `\\[abort-recursive-edit]'.") ⇒ "To abort recursive edit, type ‘C-]’."
(substitute-command-keys "The keys that are defined for the minibuffer here are: \\{minibuffer-local-must-match-map}") ⇒ "The keys that are defined for the minibuffer here are:
? minibuffer-completion-help SPC minibuffer-complete-word TAB minibuffer-complete C-j minibuffer-complete-and-exit RET minibuffer-complete-and-exit C-g abort-recursive-edit "
(substitute-command-keys "To abort a recursive edit from the minibuffer, type \ `\\<minibuffer-local-must-match-map>\\[abort-recursive-edit]'.") ⇒ "To abort a recursive edit from the minibuffer, type ‘C-g’."
ドキュメント文字列内のテキストにたいしては他にも特別な慣習があります。それらはたとえばこのマニュアルの関数、変数、およびセクションで参照できます。詳細はドキュメント文字列のヒントを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はイベント、キーシーケンス、文字をテキスト表記(textual descriptions)に変換します。これらの変換された表記は、メッセージ内に任意のテキスト文字やキーシーケンスを含める場合に有用です。なぜなら非プリント文字や空白文字はプリント文字シーケンスに変換されるからです。空白文字以外のプリント文字はその文字自身が表記になります。
この関数はsequence内の入力イベントにたいしてEmacsの標準表記を含んだ文字列をリターンする。prefixが非nil
なら、それはsequenceに前置される入力イベントシーケンスであり、リターン値にも含まれる。引数には文字列、ベクター、またはリストを指定できる。有効なイベントに関する詳細は入力イベントを参照のこと。
(key-description [?\M-3 delete]) ⇒ "M-3 <delete>"
(key-description [delete] "\M-3") ⇒ "M-3 <delete>"
以下のsingle-key-description
の例も参照のこと。
この関数はキーボード入力にたいするEmacsの標準表記としてeventを表記する文字列をリターンする。通常のプリント文字はその文字自身で表れるが、コントロール文字は‘C-’で始まる文字列、メタ文字は‘M-’で始まる文字列、スペースやタブ等は‘SPC’や‘TAB’のように変換される。ファンクションキーのシンボルは‘<…>’のように角カッコ(angle brackets)の内側に表れる。リストであるようなイベントは、そのリストのCAR内のシンボル名が角カッコの内側に表れる。
オプション引数no-anglesが非nil
なら、ファンクションキーやイベントシンボルを括る角カッコは省略される。これは角カッコを使用しない古いバージョンのEmacsとの互換性のため。
(single-key-description ?\C-x) ⇒ "C-x"
(key-description "\C-x \M-y \n \t \r \f123") ⇒ "C-x SPC M-y SPC C-j SPC TAB SPC RET SPC C-l 1 2 3"
(single-key-description 'delete) ⇒ "<delete>"
(single-key-description 'C-mouse-1) ⇒ "<C-mouse-1>"
(single-key-description 'C-mouse-1 t) ⇒ "C-mouse-1"
この関数はテキスト内に出現する文字にたいするEmacsの標準表記としてcharacterを表記する文字列をリターンする。これはsingle-key-description
と似ているが、コントロール文字にカレットが前置されて表される点が異なる(これはEmacsバッファー内でコントロール文字を表示する通常の方法である)。他にもsingle-key-description
が2**27ビットをメタ文字とするのにたいし、text-char-description
は2**7ビットをメタ文字とする点が異なる。
(text-char-description ?\C-c) ⇒ "^C"
(text-char-description ?\M-m) ⇒ "\xed"
(text-char-description ?\C-\M-m) ⇒ "\x8d"
(text-char-description (+ 128 ?m)) ⇒ "M-m"
(text-char-description (+ 128 ?\C-m)) ⇒ "M-^M"
この関数は主にキーボードマクロを操作するために使用されるが、大雑把な意味でkey-description
の逆の処理にも使用できる。キー表記を含むスペース区切りの文字列でこれを呼び出すと、それに対応するイベントを含む文字列かベクターをリターンする(これは単一の有効なキーシーケンスであるか否かは問わず何のイベントを使用するかに依存する。キーシーケンスを参照のこと)。need-vectorが非nil
ならリターン値は常にベクター。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはさまざまなビルトインのヘルプ関数を提供しており、それらはすべてプレフィックスC-hのサブコマンドとしてユーザーがアクセスできます。それらについての詳細はHelp in The GNU Emacs Manualを参照してください。ここでは同様な情報に関するプログラムレベルのインターフェイスを説明します。
この関数は名前にaproposパターン(apropos pattern: 適切なパターン) patternを含む重要なすべてのシンボルを探す。マッチに使用されるaproposパターンは単語、最低2つはマッチしなければならないスペース区切りの単語、または(特別な正規表現文字があれば)正規表現のいずれか。あるシンボルが関数、変数、フェイスとしての定義、あるいはプロパティをもつならそのシンボルは重要とみなされる。
この関数は以下のような要素のリストをリターンする:
(symbol score function-doc variable-doc plist-doc widget-doc face-doc group-doc)
ここでscoreはマッチの面からそのシンボルがどれだけ重要に見えるかを比較する整数である。残りの各要素はsymbolにたいする関数、変数、...等のドキュメント文字列(またはnil
)。
これは*Apropos*という名前のバッファーにもシンボルを表示する。その際、各行にはドキュメント文字列の先頭から取得した1行説明とともに表示される。
do-allが非nil
、またはユーザーオプションapropos-do-all
が非nil
なら、apropos
は見つかった関数のキーバインディングも表示する。これは重要なものだけでなく、internされたすべてのシンボルも表示する(同様にリターン値としてもそれらをリストする)。
この変数の値はHelpキーC-hに続く文字にたいするローカルキーマップである。
このシンボルは関数ではなく関数定義セルにはhelp-map
としてキーマップを保持する。これはhelp.el内で以下のように定義されている:
(define-key global-map (string help-char) 'help-command) (fset 'help-command help-map)
この変数の値はヘルプ文字(help character:
Helpを意味する文字としてEmacsが認識する文字)。デフォルトの値はC-hを意味する8。この文字を読み取った際にhelp-form
が非nil
のLisp式なら、Emacsはその式を評価して結果が文字列の場合はウィンドウ内にそれを表示する。
help-form
の値は通常はnil
。その場合にはヘルプ文字はコマンド入力のレベルにおいて特別な意味を有さず、通常の方法におけるキーシーケンスの一部となる。C-hの標準的なキーバインディングは、複数の汎用目的をもつヘルプ機能のプレフィックスキー。
ヘルプ文字はプレフィックスキーの後でも特別な意味をもつ。ヘルプ文字がプレフィックスキーのサブコマンドとしてバインディングをもたなければ、そのプレフィックスキーのすべてのサブコマンドのリストを表示するdescribe-prefix-bindings
を実行する。
この変数の値はヘルプ文字の選択肢の役割を果たすイベント型のリスト。これらのイベントはhelp-char
で指定されるイベントと同様に処理される。
この変数が非nil
なら、その値は文字help-char
が読み取られるたびに評価されるフォームであること。そのフォームの評価によって文字列が生成されたらその文字列が表示される。
read-event
、read-char-choice
、read-char
を呼び出すコマンドは、それが入力を行う間は恐らくhelp-form
を非nil
にバインドするべきだろう(C-hが他の意味をもつなら行わないこと)。この式を評価した結果は、それが何にたいする入力なのかと、それを正しくエンターする方法を説明する文字列であること。
ミニバッファーへのエントリーにより、この変数はminibuffer-help-form
の値にバインドされる(Definition of minibuffer-help-formを参照)。
この変数はプレフィックスキーにたいするヘルプをプリントする関数を保持する。その関数はユーザーが後にヘルプ文字を伴うプレフィックスキーをタイプして、そのヘルプ文字がプレフィックスの後のバインディングをもたないたときに呼び出される。この変数のデフォルト値はdescribe-prefix-bindings
。
この関数はもっとも最近のプレフィックスキーのサブコマンドすべてにたいするリストを表示するdescribe-bindings
を呼び出す。記述されるプレフィックスは、そのキーシーケンスの最後のイベントを除くすべてから構成される(最後のイベントは恐らくヘルプ文字)。
以下の2つの関数はelectricモードのように制御を放棄せずにヘルプを提供したいモードを意図しています。これらは通常のヘルプ関数と区別するために名前が‘Helper’で始まります。
このコマンドはローカルキーマップとグローバルキーマップの両方のキーバインディングすべてのリストを含むヘルプバッファーを表示するウィンドウをポップアップする。これはdescribe-bindings
を呼び出すことによって機能する。
このコマンドはカレントモードにたいするヘルプを提供する。これはミニバッファー内でメッセージ‘Help (Type ? for further
options)’とともにユーザーに入力を求めて、その後キーバインディングが何か、何を意図するモードなのかを探すための助けを提供する。これはnil
をリターンする。
これはマップHelper-help-map
を変更することによってカスタマイズできる。
この変数はEmacsに付随する特定のドキュメントおよびテキストファイルを探すディレクトリーの名前を保持する。
この関数はヘルプバッファーの名前(通常は*Help*)をリターンする。そのようなバッファーが存在しなければ最初にそれを作成する。
このマクロはwith-output-to-temp-buffer
(一時的な表示を参照)のようにbodyを評価して、そのフォームが生成したすべての出力をbuffer-nameという名前のバッファーに挿入する(buffer-nameは通常は関数help-buffer
によりリターンされる値であること)。これは指定されたバッファーをHelpモードにして、ヘルプウィンドウのquitやスクロールする方法を告げるメッセージを表示する。これはユーザーオプションhelp-window-select
のカレント値が適切にセットされていればヘルプウィンドウの選択も行う。これはbody内の最後の値をリターンする。
この関数は*Help*バッファー内のクロスリファレンスデータを更新する。このクロスリファレンスはユーザーが‘Back’ボタンか‘Forward’ボタン上でクリックした際のヘルプ情報の再生成に使用される。*Help*バッファーを使用するほとんどのコマンドは、バッファーをクリアーする前にこの関数を呼び出すべきである。item引数は(function
.
args)
という形式であること。ここでfunctionは引数リストargsで呼び出されるヘルプバッファーを再生成する関数。コマンド呼び出しがinteractiveに行われた場合、interactive-p引数は非nil
。この場合には*Help*バッファーの‘Back’ボタンにたいするitemのスタックはクリアーされる。
help-buffer
、with-help-window
、help-setup-xref
の使用例はdescribe-symbols exampleを参照してください。
このマクロは提供するサブコマンドのリストを表示するプレフィックスキーのように振る舞う、fnameという名前のヘルプコマンドを定義する。
呼び出された際、fnameはウィンドウ内にhelp-textを表示してからhelp-mapに応じてキーシーケンスの読み取りと実行を行う。文字列help-textはhelp-map内で利用可能なバインディングを説明すること。
コマンドfnameはhelp-textの表示をスクロールすることによる、自身のいくつかのイベントを処理するために定義される。fnameがこれらのスペシャルイベントのいずれかを読み取った際には、スクロールを行った後で他のイベントを読み取る。自身が処理する以外のイベントを読み取りそのイベントがhelp-map内にバインディングを有す際は、そのキーのバインディングを実行した後にリターンする。
引数help-lineはhelp-map内の候補の1行要約であること。Emacsのカレントバージョンでは、オプションthree-step-help
をt
にセットした場合のみこの引数が使用される。
このマクロはC-h C-hにバインドされるコマンドhelp-for-help
内で使用される。
この変数が非nil
なら、make-help-screen
で定義されたコマンドは最初にエコーエリア内に自身のhelp-line文字列を表示して、ユーザーが再度ヘルプ文字をタイプした場合のみ長いhelp-text文字列を表示する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このチャプターでは検索、作成、閲覧、保存、その他ファイルとディレクトリーにたいして機能するEmacs Lispの関数と変数について説明します。その他のいくつかのファイルに関する関数についてはバッファー、バックアップとauto-save(自動保存)に関する関数についてはバックアップと自動保存で説明されています。
ファイル関数の多くはファイル名であるような引数を1つ以上受け取ります。このファイル名は文字列です。これらの関数のほとんどは関数expand-file-name
を使用してファイル名引数を展開するので、~は相対ファイル名(../を含む)として正しく処理されます。ファイル名を展開する関数を参照してください。
加えて特定のmagicファイル名は特別に扱われます。たとえばリモートファイル名が指定された際、Emacsは適切なプロトコルを通じてネットワーク越しにファイルにアクセスします。Remote Files in The GNU Emacs Manualを参照してください。この処理は非常に低レベルで行われるので、特に注記されたものを除いて、このチャプターで説明するすべての関数がファイル名引数としてmagicファイル名を受け入れると想定しても良いでしょう。詳細はSee section 特定のファイル名の“Magic”の作成を参照してください。
ファイルI/O関数がLispエラーをシグナルする際、通常はコンディションfile-error
を使用します(エラーを処理するコードの記述を参照)。ほとんどの場合にはオペレーティングシステムからロケールsystem-messages-locale
に応じたエラーメッセージが取得されて、コーディングシステムlocale-coding-system
を使用してデコードされます(localeを参照)。
24.1 ファイルのvisit | 編集のためにEmacsバッファーにファイルを読み込む。 | |
24.2 バッファーの保存 | 変更されたバッファーをファイルに書き戻す。 | |
24.3 ファイルの読み込み | ファイルをvisitせずにバッファーに読み込む。 | |
24.4 ファイルの書き込み | バッファーの一部から新たなファイルに書き込む。 | |
24.5 ファイルのロック | 複数名による同時編集を防ぐためにファイルをlockまたはunlockする。 | |
24.6 ファイルの情報 | ファイルの存在、アクセス権、サイズのテスト。 | |
24.7 ファイルの名前と属性の変更 | ファイル名のリネームやパーミッションの変更など。 | |
24.8 ファイルの名前 | ファイル名の分解と展開。 | |
24.9 ディレクトリーのコンテンツ | ディレクトリーないのファイルリストの取得。 | |
24.10 ディレクトリーの作成・コピー・削除 | ディレクトリーの作成と削除。 | |
24.11 特定のファイル名の“Magic”の作成 | 特定のファイル名にたいする特別な処理。 | |
24.12 ファイルのフォーマット変換 | さまざまなファイルフォーマットへ/からの変換。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ファイルのvisitとはファイルをバッファーに読み込むことを意味します。一度これを行うと、わたしたちはバッファーがファイルをvisit(訪問)していると言い、ファイルのことをバッファーのvisitされたファイルと呼んでいます。
ファイルとバッファーは2つの異なる事柄です。ファイルとは、(削除しない限り)コンピューター内に永続的に記録された情報です。一方バッファーとは編集セッションの終了(またはバッファーのkill)とともに消滅する、Emacs内部の情報です。あるバッファーがファイルをvistしているとき、バッファーにはファイルからコピーされた情報が含まれます。編集コマンドにより変更されるのはバッファー内のコピーです。バッファーへの変更によってファイルは変更されません。その変更を永続化するためにはバッファーを保存(save)しなければなりません。これは変更されたバッファーのコンテンツをファイルにコピーして書き戻すことを意味します。
ファイルとバッファーは異なるにも関わらず、人はバッファーという意味でファイルを呼んだり、その逆を行うことが多々あります。実際のところ、“わたしはまもなく同じ名前のファイルに保存するためのバッファーを編集している”ではなく、“わたしはファイルを編集している”と言います。人間がこの違いを明確にする必要は通常はありません。しかしコンピュータープログラムで対処する際には、この違いを心に留めておくのが良いでしょう。
24.1.1 ファイルをvisitする関数 | visit用の通常のインターフェイス関数。 | |
24.1.2 visitのためのサブルーチン | 通常のvisit関数が使用する低レベルのサブルーチン。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではファイルのvisitに通常使用される関数を説明します。歴史的な理由によりこれらの関数は‘visit-’ではなく、‘find-’で始まる名前をもちます。バッファーをvisitしているファイルの名前へのアクセスや、visitされたファイル名から既存のバッファーを見つける関数および変数についてはバッファーのファイル名を参照してください。
ファイル内容を見たいものの変更したくない場合にはテンポラリーバッファー(temporary buffer:
一時的なバッファー)でinsert-file-contents
を使用例するのが、Lispプログラム内ではもっとも高速な方法です。時間を要するファイルのvisitは必要ありません。ファイルの読み込みを参照してください。
このコマンドはファイルfilenameをvisitしているバッファーを選択する。visitしている既存のバッファーがあればそのバッファー、なければバッファーを新たに作成してそのバッファーにファイルを読み込む。これはそのバッファーをリターンする。
技術的な詳細を除けばfind-file
関数のbodyは基本的には以下と等価:
(switch-to-buffer (find-file-noselect filename nil nil wildcards))
(ウィンドウ内のバッファーへの切り替えのswitch-to-buffer
を参照されたい。)
wildcardsが非nil
(interactiveに呼び出された場合は常に真)の場合、find-file
はfilename内のワイルドカード文字を展開してマッチするすべてのファイルをvisitする。
find-file
がinteractiveに呼び出された際にはミニバッファー内でfilenameの入力を求める。
このコマンドはfind-file
が行うようにfilenameをvisitするが、フォーマット変換(ファイルのフォーマット変換を参照)、文字コード変換(コーディングシステムを参照)、EOL変換(End of line
conversionを参照)を何も行わない。ファイルをvisitしているバッファーはunibyteになり、ファイル名とは無関係にバッファーのメジャーモードはFundamentalモードになる。ファイル内で指定されたファイルローカル変数(ファイルローカル変数を参照)は無視され、自動的な解凍とrequire-final-newline
によるファイル終端への改行追加(require-final-newlineを参照)も無効になる。
Emacsがすでにリテラリー(literally:
文字通り、そのまま)でない方法で同じファイルをvisitしているバッファーをもつ場合には、Emacsはその同じファイルをリテラリーにvisitせず、単に既存のバッファーに切り替えることに注意。あるファイルのコンテンツにたいして確実にリテラリーにアクセスしたければテンポラリーバッファーを作成して、insert-file-contents-literally
を使用してファイルのコンテンツを読み込むこと(ファイルの読み込みを参照)。
これはファイルをvisitするすべての関数の要となる関数である。これはファイルfilenameをvisitしているバッファーをリターンする。望むならそのバッファーをカレントにしたり、あるウィンドウ内に表示することができるだろうがこの関数はそれを行わない。
関数は既存のバッファーがあればそれをリターンし、なければ新たにバッファーを作成してそれにファイルを読み込む。find-file-noselect
が既存のバッファーを使用する際は、まずファイルがそのバッファーに最後にvisit、または保存したときから変更されていないことを検証する。ファイルが変更されていれば、この関数は変更されたファイルを再読み込みするかどうかをユーザーに尋ねる。ユーザーが‘yes’と応えたら、以前に行われたそのバッファー内での編集は失われる。
ファイルの読み込みはEOL変換、フォーマット変換(ファイルのフォーマット変換を参照)を含むファイルコンテンツのデコードを要する(コーディングシステムを参照)。wildcardsが非nil
なら、find-file-noselect
はfilename内のワイルドカード文字を展開してマッチするすべてのファイルをvisitする。
この関数はオプション引数nowarnがnil
なら、さまざまな特殊ケースにおいて警告メッセージ(warning
message)、および注意メッセージ(advisory
message)を表示する。たとえば関数がバッファーの作成を必要とし、かつfilenameという名前のファイルが存在しなければ、エコーエリア内にメッセージ‘(New
file)’を表示してそのバッファーを空のままに留める。
find-file-noselect
関数は、ファイルを読み込んだ後に通常はafter-find-file
を呼び出す(visitのためのサブルーチンを参照)。この関数はバッファーのメジャーモードのセット、ローカル変数のパース、正にvisitしたファイルより新しいauto-saveファイルが存在する場合にユーザーへの警告を行い、find-file-hook
内の関数を実行することにより終了する。
オプション引数rawfileが非nil
ならafter-find-file
は呼び出されず、失敗時にfind-file-not-found-functions
は呼び出されない。さらに非nil
値のrawfileは、コーディングシステム変換とフォーマット変換を抑制する。
find-file-noselect
関数は、通常はファイルfilenameをvisitしているバッファーをリターンする。しかしワイルドカードが実際に使用、展開された場合には、それらのファイルをvisitしているバッファーのリストをリターンする。
(find-file-noselect "/etc/fstab") ⇒ #<buffer fstab>
このコマンドはファイルfilenameをvisitしているバッファーを選択するが、選択されたウィンドウではない他のウィンドウでこれを行う。これは別の既存ウィンドウを使用したり、ウィンドウを分割するかもしれない。ウィンドウ内のバッファーへの切り替えlを参照のこと。
このコマンドがinteractiveに呼び出された際はfilenameの入力を求める。
このコマンドはfind-file
のようにファイルfilenameをvisitしているバッファーを選択するが、そのバッファーを読み取り専用(read-only)とマークする。関連する関数と変数については読み取り専用のバッファーを参照のこと。
このコマンドがinteractiveに呼び出された際はfilenameの入力を求める。
この変数が非nil
なら、各種find-file
コマンドはワイルドカード文字をチェックして、それらにマッチするすべてのファイルをvisitする(interactiveに呼び出されたときやwildcards引数が非nil
のとき)。このオプションがnil
なら、find-file
コマンドはそれらのwildcards引数を無視してワイルドカード文字を特別に扱うことは決してない。
この変数の値はファイルがvisitされた後に呼び出される関数のリスト。ファイルのローカル変数指定は、(もしあれば)このフックが実行される前に処理されるだろう。フック関数実行時はそのファイルをvisitしているバッファーがカレントになる。
この変数はノーマルフックである。フックを参照のこと。
この変数の値はfind-file
やfind-file-noselect
が存在しないファイル名を受け取った際に呼び出される関数のリスト。存在しないファイルを検知するとfind-file-noselect
は直ちにこれらの関数を呼び出す。これらのいずれかが非nil
をリターンするまで、リスト順に関数を呼び出す。buffer-file-name
はすでにセットアップ済みである。
関数の値が使用されること、および多くの場合いくつかの関数だけが呼び出されるので、これはノーマルフックではない。
このバッファーローカル変数が非nil
値にセットされると、save-buffer
はあたかもそのバッファーがリテラリー、つまり何の変換も行わずにファイルをvisitしていたかのように振る舞う。コマンドfind-file-literally
はこの変数のローカル値をセットするが、その他の等価な関数およびコマンドも、たとえばファイル終端への改行の自動追加を避けるためにこれを同様に行うことができる。この変数は恒久的にローカルなのでメジャーモードの変更による影響を受けない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
find-file-noselect
関数は、2つの重要なサブルーチンcreate-file-buffer
とafter-find-file
を使用します。これらはユーザーのLispコードでも役に立つことがあります。このセクションではそれらの使い方について説明します。
この関数はfilenameのvisitにたいして適切な名前のバッファーを作成してそれをリターンする。これはfilename (ディレクトリーを含まず)の名前がフリーならバッファー名にそれを使用し、フリーでなければ未使用の名前を取得するために‘<2>’のような文字列を付加する。バッファーの作成も参照のこと。uniquifyライブラリーはこの関数の結果に影響を与えることに注意。Uniquify in The GNU Emacs Manualを参照のこと。
注意されたい:
create-file-buffer
はファイルに新たなバッファーを関連付けない。バッファーの選択もせず、さらにデフォルトのメジャーモードも使用しない。
(create-file-buffer "foo") ⇒ #<buffer foo>
(create-file-buffer "foo") ⇒ #<buffer foo<2>>
(create-file-buffer "foo") ⇒ #<buffer foo<3>>
この関数はfind-file-noselect
により使用される。この関数自身はgenerate-new-buffer
を使用する(バッファーの作成を参照)。
この関数はバッファーのメジャーモードをセットして、ローカル変数をパースする(Emacsがメジャーモードを選択する方法を参照)。これはfind-file-noselect
、およびデフォルトのリバート関数(リバートを参照)により呼び出される。
ファイルが存在しないという理由によりファイルの読み込みがエラーを受け取るがディレクトリーは存在するなら、呼び出し側はerrorにたいして非nil
値を渡すこと。この場合、after-find-file
は警告‘(New
file)’を発する。より深刻なエラーにたいしては、呼び出し側は通常はafter-find-file
を呼び出さないこと。
warnが非nil
なら、もしauto-saveファイルが存在して、かつそれがvisitされているファイルより新しければ、この関数は警告を発する。
noautoが非nil
なら、それはAuto-Saveモードを有効や無効にしないことを告げる。以前にAuto-Saveモードが有効なら有効のまま留まる。
after-find-file-from-revert-bufferが非nil
なら、それはこの関数がrevert-buffer
から呼び出されたことを意味する。これに直接的な効果はないが、モード関数とフック関数の中には、この変数の値をチェックするものがいくつかある。
nomodesが非nil
なら、それはバッファーのメジャーモードを変更せず、ファイル内のローカル変数指定を処理せず、find-file-hook
を実行しないことを意味する。この機能はあるケースにおいてrevert-buffer
により使用される。
after-find-file
はリストfind-file-hook
内のすべての関数を最後に呼び出す。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs内でファイルを編集するとき、実際にはそのファイルをvisitしているバッファーにたいして編集を行っています。つまりファイルのコンテンツをバッファーにコピーして、編集しているのはそのコピーなのです。そのバッファーにを変更してもバッファーを保存(save)するまでファイルは変更されません。保存とはバッファーのコンテンツをファイルにコピーすることを意味します。
この関数はバッファーが最後にvisitされたときや保存されたときから変更されていれば、カレントバッファーのコンテンツをバッファーによってvisitされているファイルに保存、変更されていなければ何も行わない。
save-buffer
はバックアップファイルの作成に責任を負う。backup-optionは通常はnil
であり、save-buffer
はファイルのvisit以降、それが最初の保存の場合のみバックアップファイルを作成する。backup-optionにたいする他の値は、別の条件によるバックアップファイル作成を要求する:
save-buffer
はバッファーの次回保存時にこのバージョンのファイルがバックアップされるようマークする。
save-buffer
関数はそれを保存する前に前バージョンのファイルを無条件にバックアップする。
このコマンドはファイルをvisitしている変更されたバッファーのいくつかを保存する。これは通常は各バッファーごとにユーザーに確認を求める。しかしsave-silently-pが非nil
なら、ユーザーに質問せずにファイルをvisitしているすべてのバッファーを保存する。
オプション引数predは、どのバッファーで確認を求めるか(またはsave-silently-pが非nil
ならどのバッファーで確認せずに保存するか)を制御する。これがnil
なら、それはファイルをvisitしているバッファーにたいしてのみ確認を求めることを意味する。t
なら、それはbuffer-offer-save
のバッファーローカル値がnil
であるような非ファイルバッファー以外の特定のバッファーの保存も提案することを意味する(バッファーのkillを参照)。ユーザーが非ファイルバッファーの保存にたいして‘yes’と応えると、保存に使用するファイル名の指定を求める。save-buffers-kill-emacs
関数はpredにたいして値t
を渡す。
predがt
とnil
のいずれでもなければ、それは引数なしの関数であること。その関数はそのバッファーの保存を提案するか否かを決定するためにバッファーごとに呼び出されるだろう。これが特定のバッファーで非nil
値をリターンした場合は、バッファーの保存を提案することを意味する。
この関数はカレントバッファーをファイルfilenameに書き込んで、バッファーがそのファイルをvisitしていることにして未変更とマークする。次にfilenameにもとづいてバッファー名をリネームする。バッファー名を一意にするため、必要なら‘<2>’のような文字列を付加する。処理のほとんどはset-visited-file-name
(バッファーのファイル名を参照)、およびsave-buffer
を呼び出すことにより行われる。
confirmが非nil
なら、それは既存のファイルを上書きする前に確認を求めることを意味する。ユーザーがプレフィックス引数を与えなければinteractiveに確認が求められる。
filenameが既存のディレクトリーや既存のディレクトリーへのシンボリックリンクなら、write-file
はディレクトリーfilename内でvisitされているファイルの名前を使用する。そのバッファーがファイルをvisitしていなければ、かわりにバッファーの名前を使用する。
バッファーの保存によって複数のフックが実行される。これはフォーマット変換も処理する(ファイルのフォーマット変換を参照)。
この変数の値はvisitされているファイルをバッファーに書き出す前に呼び出される関数のリスト。それらのうちのいずれかが非nil
をリターンしたら、そのファイルは書き込み済みだと判断されて残りの関数は呼び出されないし、ファイルを書き込むための通常のコードも実行されない。
write-file-functions
内の関数が非nil
をリターンしたら、(それが適切なら)その関数はファイルをバックアップする責任を負う。これを行うには以下のコードを実行する:
(or buffer-backed-up (backup-buffer))
backup-buffer
によりリターンされるファイルモードの値を保存して、(もし非nil
なら)書き込むファイルのモードビットをセットしたいと思うかもしれない。これは正にsave-buffer
が通常行うことである。Making Backup Filesを参照のこと。
write-file-functions
内のフック関数は、データのエンコード(が望ましければ)にも責任を負う。これらは適切なコーディングシステムと改行規則(Lispでのコーディングシステムを参照)を選択してエンコード(明示的なエンコードとデコードを参照)を処理して、使用されていたコーディングシステム(エンコーディングとI/Oを参照)をlast-coding-system-used
にセットしなければならない。
バッファー内でこのフックをローカルにセットすると、バッファーはそのファイル、またはバッファーのコンテンツを取得したファイルに類するものに関連付けられる。このようにして変数は恒久的にローカルとマークされるので、メジャーモードの変更がバッファーローカルな値を変更することはない。その一方でset-visited-file-name
を呼び出すことによって変数はリセットされるだろう。これを望まなければ、かわりにwrite-contents-functions
を使用したいと思うかもしれない。
たとえこれがノーマルフックでなくても、このリストを操作するためにadd-hook
とremove-hook
を使用することはできる。フックを参照のこと。
これは正にwrite-file-functions
と同様に機能するが、こちらはvisitしている特定のファイルやファイルの場所ではなくバッファーのコンテンツに関連するフックを意図している。そのようなフックはこの変数にたいするバッファーローカルなバインディングとして、通常はメジャーモードにより作成される。この変数がセットされた際には、常に自動的にバッファーローカルになる。新たなメジャーモードへの切り替えは常にこの変数をリセットするが、set-visited-file-name
の呼び出しではリセットされない。
このフック内の関数のいずれかが非nil
をリターンすると、そのファイルはすでに書き込み済みとみなされて、残りの関数は呼び出されずwrite-file-functions
内の関数も呼び出されない。
このノーマルフックはvisitしているファイルにバッファーが保存される前に実行される。保存が通常の方法で行われるか、あるいは上述のフックのいずれかで行われたかは問題ではない。たとえばcopyright.elプログラムは、ファイルの保存においてそれの著作権表示が今年であることを確認するためにこのフックを使用する。
このノーマルフックはvisitしているファイルにバッファーを保存した後に実行される。このフックの使用例の1つはFast Lockモードにある。このモードはキャッシュファイルにハイライト情報を保存するためにこのフックを使用している。
この変数が非nil
なら、save-buffer
は保存ファイルがもつ名前のかわりに一時的な名前で新たなファイルに書き込み、エラーがないことが明確になった後にファイルを意図する名前にリネームすることによって保存中のI/Oエラーから防御する。この手順は無効なファイルが原因となるディスク容量逼迫のような問題を防ぐ。
副作用としてバックアップ作成にコピーが必要になる。リネームかコピーのどちらでバックアップするか?を参照のこと。しかし同時にこの高価なファイル保存によって保存したファイルと他のファイル名との間のすべてのハードリンクは切断される。
いくつかのモードは特定のバッファーにおいてこの変数に非nil
のバッファーローカル値を与える。
この変数はファイルが改行で終わらないように書き込まれるかどうかを決定する。変数の値がt
なら、save-buffer
はバッファーの終端に改行がなければ暗黙理に改行を追加する。値がvisit
なら、Emacsはファイルをvisitした直後に不足している改行を追加する。値がvisit-save
なら、Emacsはvisitと保存の両方のタイミングで不足している改行を追加する。その他の非nil
値にたいしては、そのようなケースが生じるたびに改行を追加するかどうかsave-buffer
がユーザーに尋ねる。
変数の値がnil
ならsave-buffer
は改行を追加しない。デフォルト値はnil
だが、特定のバッファーでこれをt
にセットするメジャーモードも少数存在する。
バッファーのファイル名の関数set-visited-file-name
も参照されたい。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ファイルのコンテンツをバッファーにコピーするためには関数insert-file-contents
を使用します(マークをセットするのでLispプログラム内でコマンドinsert-file
は使用してはならない)。
この関数はファイルfilenameのコンテンツをカレントバッファーのポイントの後に挿入する。これは絶対ファイル名と挿入だれたデータの長さからなるリストをリターンする。filenameが読み取り可能なファイルの名前でなければエラーがシグナルされる。
この関数は定義されたファイルフォーマットに照らしてファイルのコンテンツをチェックして、適切ならそのコンテンツの変換、およびリストafter-insert-file-functions
内の関数の呼び出しも行う。ファイルのフォーマット変換を参照のこと。通常はリストafter-insert-file-functions
内のいずれかの関数がEOL変換を含むファイルコンテンツのデコードに使用されるコーディングシステム(コーディングシステムを参照)を判断する。しかしファイルにnullバイトが含まれる場合には、デフォルトではコード変換なしでvisitされる。inhibit-null-byte-detectionを参照のこと。
visitが非nil
なら、この関数は追加でそのバッファーを未変更とマークしてそのバッファーのさまざまなフィールドをセットアップして、バッファーがファイルfilenameをvisitしているようにする。これらのフィールドにはバッファーがvisitしたファイルの名前、最終保存したファイルのmodtimeが含まれる。これらの機能はfind-file-noselect
により使用されるものであり、恐らくあなた自身が使用するべきではない。
begとendが非nil
なら、それらはファイル挿入範囲を指定するバイトオフセット数値であること。この場合、visitはnil
でなければならない。たとえば、
(insert-file-contents filename nil 0 500)
これはファイルの先頭500文字(バイト)を挿入する。
引数replaceが非nil
なら、それはバッファーのコンテンツ(実際にはアクセス可能な範囲)をファイルのコンテンツで置き換えることを意味する。これは単にバッファーのコンテンツを削除してファイル全体を挿入するより優れている。なぜなら、(1)マーカー位置を維持して、(2)undoリストに配置するデータも少ないからである。
replaceとvisitがnil
なら、insert-file-contents
で(FIFOやI/Oデバイスのような)スペシャルファイルの読み取りが可能。
この関数はinsert-file-contents
のように機能するが、find-file-hook
を実行せず、フォーマットのデコード、文字コード変換、自動解凍、...などを行わない点が異なる。
他のプログラムがファイルを読めるように他プロセスにファイル名を渡したければ関数file-local-copy
を使用します。特定のファイル名の“Magic”の作成を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
関数append-to-file
とwrite-region
を使用することによってディスク上のファイルにバッファーのコンテンツやバッファーの一部を直接書き込むことができます。visitされているファイルに書き込むためにこれらの関数を使用しないでください。これによってvisitにたいするメカニズムが混乱するかもしれません。
この関数はカレントバッファー内でstartとendによるリージョンのコンテンツをファイルfilenameの終端に追加する。そのファイルが存在しなければ作成する。この関数はnil
をリターンする。
filenameに書込不可能なファイルやファイルを作成不可なディレクトリー内の存在しないファイルを指定するとエラーがシグナルされる。
Lispから呼び出した場合、この関数は以下と完全に等価:
(write-region start end filename t)
この関数はカレントバッファー内のstartとendで区切られたリージョンをfilenameで指定されたファイルに書き込む。
startがnil
なら、このコマンドはバッファーのコンテンツ全体(アクセス可能な範囲だけではない)をファイルに書き込んでendは無視する。
startが文字列なら、write-region
はバッファーのテキストではなくその文字列を追加する。その場合にはendは無視される。
appendが非nil
なら、指定されたテキストが(もしあれば)既存のファイルコンテンツに追加される。appendが数字ならwrite-region
はファイル開始位置からそのバイトオフセットをseekしてデータをそこに書き込む。
mustbenewが非nil
の場合、もしfilenameが既存ファイルの名前ならwrite-region
は確認を求める。mustbenewがシンボルexcl
の場合、ファイルがすでに存在すればwrite-region
は確認を求めるかわりにエラーfile-already-exists
をシグナルする。
mustbenewがexcl
のときは、存在するファイルのテストに特別なシステム機能を使用する。少なくともローカルディスク上のファイルにたいしては、Emacsがファイルを作成する前にEmacsに通知せずに他のプログラムが同じ名前のファイルを作成することはありえない。
visitがt
なら、Emacsはバッファーとファイルの関連付けを設定してそのバッファーがそのファイルをvictiする。またカレントバッファーにたいする最終ファイル変更日時にfilenameをセットして、そのバッファーを未変更としてマークする。この機能はsave-buffer
により使用されるが、おそらくあなた自身が使用するべきではないだろう。
visitが文字列なら、それはvisitするファイルの名前を指定する。この方法を使えば、そのバッファーが別のファイルをvisitしていると記録しつつ1つのファイル(filename)にデータを書き込むことができる。引数visitはエコーエリアに使用される他にファイルのロックにも使用され、visitがbuffer-file-name
に格納される。この機能はfile-precious-flag
の実装に使用される。自分が何をしているか本当にわかっているのでなければこれを使用してはならない。
オプション引数locknameが非nil
なら、それはロックとアンロックの目的に使用するfilenameとvisitをオーバーライドするファイル名を指定する。
関数write-region
は書き込むデータをbuffer-file-format
によって指定される適切なファイルフォーマットに変換しするとともに、リストwrite-region-annotate-functions
内の関数の呼び出しも行う。ファイルのフォーマット変換を参照のこと。
write-region
は通常はエコーエリア内にメッセージ‘Wrote
filename’を表示する。visitがt
、nil
、文字列のいずれでもない場合、こまたはEmacsがbatchモード(batchモードを参照)で処理中ならこのメッセージは抑制される。この機能は内部的な目的のためにユーザーが知る必要がないファイルを使用したり、Emacsがbatchモードで処理中に有用である。
with-temp-file
マクロは一時バッファー(temporary
buffer)をカレントバッファーとしてbodyフォームを評価して、最後にそのバッファーのコンテンツをfileに書き込む。これは終了時に一時バッファーをkillして、with-temp-file
フォームの前にカレントだったバッファーをリストアする。その後にbody内の最後のフォームの値をリターンする。
throw
やエラーによる異常なexit(abnormal exit)でも、カレントバッファーはリストアされる(非ローカル脱出を参照)。
The Current
Bufferのwith-temp-buffer
も参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
2人のユーザーが同時に同じファイルを編集する際、おそらく彼らは互いに干渉しあうことになるでしょう。Emacsはファイルが変更される際にファイルロック(file lock)を記録することによって、このような状況の発生を防ぎます。そしてEmacsは他のEmacsジョブにロックされているファイルをvisitしているバッファーへの変更の最初の試みを検知して、ユーザーに何を行うか尋ねます。このファイルロックの実態は、編集中のファイルと同じディレクトリーに格納される特別な名前をもつシンボリックリンクです(シンボリックリンクをサポートしないファイルシステムでは通常ファイルが使用される)。
ファイルのアクセスにNFSを使用する際には、可能性は小さいものの他のユーザーと同じファイルを同時にロックするかもしれません。これが発生すると2人のユーザーが同時にファイルを変更することが可能になりますが、それでもEmacsは2番目に保存するユーザーにたいして警告を発するでしょう。たファイルをvisitしているバッファーでディスク上でファイルの変更を検知することにより、ある種の同時編集を捕捉できます。バッファーの変更 Timeを参照してください。
この関数はファイルfilenameがロックされていなければnil
をリターンする。このEmacsプロセスによりロックされていればt
、他のEmacsジョブによりロックされている場合はロックしたユーザーの名前をリターンする。
(file-locked-p "foo") ⇒ nil
この関数はカレントバッファーが変更されていればファイルfilenameをロックする。引数filenameのデフォルトはカレントバッファーがvisitしているファイル。カレントバッファーがファイルをvisitしていない、バッファーが変更されていない、またはcreate-lockfiles
がnil
なら何もしない。
この関数はカレントバッファーが変更されていればバッファーによりvisitされているファイルをアンロックする。バッファーが変更されていなければ、そのファイルをロックしてはならないのでこの関数は何もしない。カレントバッファーがファイルをvisitしていない、またはファイルがロックされていなければこの関数は何もしない。
この変数がnil
ならEmacsはファイルをロックしない。
この関数はユーザーがfileの変更を試みたが、それが名前other-userのユーザーにロックされていたとき呼び出される。この関数のデフォルト定義は何を行うかユーザーに尋ねる関数。この関数がリターンする値はEmacsが次に何を行うかを決定する:
t
はそのファイルのロックを奪うことを意味する。その場合にはother-userはロックを失い、そのユーザーがファイルを編集することができる。
nil
はロックを無視して、とにかくユーザーがファイルを編集できるようにすることを意味する。
file-locked
をシグナルする。この場合には、ユーザーが行おうとしていた変更は行われない。
このエラーにたいするエラーメッセージは以下のようになる:
error→ File is locked: file other-user
ここでfile
はファイル名、other-userはそのファイルのロックを所有するユーザーの名前。
望むなら他の方法で判定を行う独自バージョンでask-user-about-lock
関数を置き換えることができる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではファイル(またはディレクトリーやシンボリックリンク)に関してファイルが読み込み可能か、書き込み可能か、あるいはファイルのサイズのようなさまざまなタイプの情報を取得する関数を説明します。これらの関数はすべて引数にファイルの名前を受け取ります。特に注記した場合を除きこれらの引数には既存のファイルを指定する必要があり、ファイルが存在しなければエラーをシグナルします。
スペースで終わるファイル名には気をつけてください。いくつかのファイルシステム(特にMS-Windows)では、ファイル名の末尾の空白文字は暗黙かつ自動的に無視されます。
24.6.1 アクセシビリティのテスト | そのファイルは読み取り可能か? 書き込み可能か? | |
24.6.2 ファイル種別の区別 | それはディレクトリー? それともシンボリックリンク? | |
24.6.3 本当の名前 | シンボリックリンクの最終的なファイル名。 | |
24.6.4 ファイルの属性 | ファイルのサイズや更新日時など。 | |
24.6.5 拡張されたファイル属性 | アクセス制御にたいするファイル属性の拡張。 | |
24.6.6 標準的な場所へのファイルの配置 | 標準的な場所でファイルを見つける方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はあるファイルの読み取りや書き込み、実行するためのパーミッションをテストします。明示しない限りこれらの関数はファイル名引数にたいするシンボリックリンクをすべてのレベル(ファイル自身のレベルと親ディレクトリーのレベル)において再帰的にフォロー(follow: 辿る)します。
いくつかのオペレーティングシステムではACL(Access Control Lists: アクセス制御リスト)のような機構を通じて、より複雑なアクセスパーミッションセットが指定できます。それらのパーミッションにたいする問い合わせやセットの方法については拡張されたファイル属性を参照してください。
この関数はファイル名filenameが存在すればt
をリターンする。これはそのファイルが読み取り可能である必要はなく、ファイルの属性を調べることが可能なこと意味する(UnixとGNU/Linu以外で、そのファイルが存在して、かつそのファイルを含むディレクトリーの実行パーミッションをもつ場合にはt
となり、そのファイル自体のパーミッションは無関係である)。
ファイルが存在しない、またはACLポリシーがファイル属性を調べることを禁止する場合には、この関数はnil
をリターンする。
ディレクトリーはファイルなので、ディレクトリー名が与えられるとfile-exists-p
はt
をリターンする。しかしシンボリックリンクは特別に扱われる。file-exists-p
はターゲットファイルが存在する場合のみシンボリックリンクにたいしてt
をリターンする。
この関数はfilenameという名前のファイルが存在して、それを読み取ることが可能ならt
、それ以外はnil
をリターンする。
この関数はfilenameという名前のファイルが存在して、それを実行することが可能ならt
、それ以外はnil
をリターンする。UnixとGNU/Linuxシステムでは、そのファイルがディレクトリーなら実行パーミッションはディレクトリー内のファイルの存在と属性をチェックでき、ファイルのモードが許容すればオープンできることを意味する。
この関数はfilenameという名前のファイルが書き込み可能か作成可能可能ならt
、それ以外はnil
をリターンする。ファイルが存在してそれに書き込むことができるならファイルは書き込み可能。ファイルが存在せず、指定されたディレクトリーが存在して、そのディレクトリーに書き込むことができるなら書き込み可能。
以下の例では、fooは親ディレクトリーが存在しないので、たとえユーザーがそのディレクトリーを作成可能であってもファイルは書き込み可能ではない。
(file-writable-p "~/no-such-dir/foo") ⇒ nil
この関数はファイルとしての名前がdirnameであるようなディレクトリー内にある既存のファイルをオープンするパーミッションをもつ場合はt
、それ以外(またはそのようなディレクトリーが存在しない場合)はnil
をリターンする。dirnameの値はディレクトリー名(/foo/など)、または名前がディレクトリー(最後のスラッシュがない/fooなど)であるようなファイル。
たとえば以下では/foo/内の任意のファイルを読み取る試みはエラーになると推測できる:
(file-accessible-directory-p "/foo") ⇒ nil
この関数は読み取り用にファイルfilenameをオープンして、クローズした後にnil
をリターンする。しかしオープンに失敗すると、stringをエラーメッセージのテキストに使用してエラーをシグナルする。
この関数はファイルfilenameを削除後に新たに作成してもファイルの所有者が変更されずに維持されるようならt
をリターンする。これは存在しないファイルにたいしてもt
をリターンする。
オプション引数groupが非nil
なら、この関数はファイルのグループが変更されないこともチェックする。
filenameがシンボリックリンクなら、file-ownership-preserved-p
はここで述べる他の関数と異なりfilenameをターゲットで置き換えない。しかしこの関数は親ディレクトリーのすべての階層においてシンボリックリンクを再帰的にフォローする。
この関数はfilenameのモードビット(mode
bits)をリターンする。これは読み取り、書き込み、実行パーミッションを要約する整数である。filenameでのシンボリックリンクは、すべての階層において再帰的にフォローされる。ファイルが存在しない場合のリターン値はnil
。
モードビットの説明はFile permissions in The GNU Coreutils
Manualを参照のこと。たとえば最下位ビットが1ならそのファイルは実行可能、2ビット目が1なら書き込み可能、...となる。設定できる最大の値は4095(8進の7777)であり、これはすべてのユーザーが読み取り、書き込み、実行のパーミッションをもち、他のユーザーとグループにたいしてSUIDビット、およびstickyビットがセットされる。
これらのパーミッションのセットに使用されるset-file-modes
関数についてはファイルの名前と属性の変更を参照のこと。
(file-modes "~/junk/diffs")
⇒ 492 ; 10進整数
(format "%o" 492)
⇒ "754" ; 8進に変換した値
(set-file-modes "~/junk/diffs" #o666) ⇒ nil
$ ls -l diffs -rw-rw-rw- 1 lewis lewis 3063 Oct 30 16:00 diffs
MS-DOSにたいする注意:
MS-DOSでは実行可能を表すようなファイルのモードビットは存在しない。そのためfile-modes
はファイル名が.com、.bat、.exeなどのような標準的な実行可能な拡張子のいずれかで終わればファイルを実行可能だと判断する。Unix標準の‘#!’署名で始まるshellスクリプトやPerlスクリプトも実行可能と判断される。Unixとの互換性のためにディレクトリーも実行可能と報告される。file-attributes
(ファイルの属性を参照)もこれらの慣習にしたがう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではディレクトリー、シンボリックリンク、および通常ファイルのようなさまざまな種類のファイルを区別する方法を説明します。
ファイルfilenameがシンボリックリンクなら、file-symlink-p
関数は(非再帰的な)リンクターゲットを文字列としてリターンする(リンクターゲット文字列は、そのターゲットの完全な絶対ファイル名である必要はない。リンクが指すのが完全なファイル名かどうかを判断するのは簡単な処理ではない。以下参照)。filenameのディレクトリー部分(leading
directory)にシンボリックリンクが含まれていれば、この関数はそれらを再帰的にフォローする。
ファイルfilenameがシンボリックリンクではない、または存在しなければfile-symlink-p
はnil
をリターンする。
この関数の使用例をいくつか示す:
(file-symlink-p "not-a-symlink") ⇒ nil
(file-symlink-p "sym-link") ⇒ "not-a-symlink"
(file-symlink-p "sym-link2") ⇒ "sym-link"
(file-symlink-p "/bin") ⇒ "/pub/bin"
3つ目の例では関数はsym-linkをリターンするものの、たとえそれ自体がシンボリックリンクであっても、リンク先の解決を行わないことに注意。これが上述した“非再帰的(non-recursive)”の意味するところであり、シンボリックリンクをフォローする処理はそのリンクターゲット自体がリンクなら再帰的に行われない。
この関数がリターンするのはそのシンボリックリンクに何が記録されているかを示す文字列であり、それにディレクトリー部分が含まれているかどうかは構わない。この関数は完全修飾されたファイル名を生成するためにリンクターゲットを展開しないし、リンクターゲットが絶対ファイル名でなければ、(もしあっても)filename引数のディレクトリー部分は使用しない。以下に例を示す:
(file-symlink-p "/foo/bar/baz") ⇒ "some-file"
ここでは、たとえ与えられた/foo/bar/bazが完全修飾されたファイル名であるにも関わらずその結果は異なり、実際には何のディレクトリー部分ももたない。some-file自体がシンボリックリンクかもしれないので、単にその前に先行ディレクトリーを追加することはできず、絶対ファイル名を生成するために単にexpand-file-name
(ファイル名を展開する関数を参照)を使用することもできないからである。
この理由により、あるファイルがシンボリックリンクか否かという単一の事実よりも多くを判定する必要がある場合にこの関数が有用であることは稀である。実際にリンクターゲットのファイル名が必要なら、本当の名前で説明するfile-chase-links
やfile-truename
を使用すること。
以下の2つの関数はfilenameにたいしてシンボリックリンクを全階層において再帰的にフォローする。
この関数はfilenameが既存のディレクトリー名ならt
、それ以外はnil
をリターンする。
(file-directory-p "~rms") ⇒ t
(file-directory-p "~rms/lewis/files.texi") ⇒ nil
(file-directory-p "~rms/lewis/no-such-file") ⇒ nil
(file-directory-p "$HOME") ⇒ nil
(file-directory-p (substitute-in-file-name "$HOME")) ⇒ t
この関数はファイルfilenameが存在して、かつそれが通常ファイル(ディレクトリー、名前付きパイプ、端末、その他I/Oデバイス以外)ならt
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ファイルの実名(truename)とは、全階層においてシンボリックリンクを残らずフォローした後に名前コンポーネントに出現する‘.’と‘..’を除いて簡略化した名前のことです。これはそのファイルにたいする正規名(canonical name)の一種です。ファイルが常に一意な実名をもつ訳ではありません。あるファイルにたいする異なる実名の個数は、そのファイルにたいするハードリンクの個数と同じです。しかし実名はシンボリックリンクによる名前の変動を解消するのに有用です。
この関数はファイルfilenameの実名をリターンする。引数が絶対ファイル名でなければ、この関数は最初にdefault-directory
にたいしてこれを展開する。
この関数は環境変数を展開しない。これを行うのはsubstitute-in-file-name
のみ。Definition of substitute-in-file-nameを参照のこと。
名前コンポーネントに出現する‘..’に先行するシンボリックリンクをフォローする必要があるなら、直接間接を問わずexpand-file-name
を呼び出す前にfile-truename
を呼び出すこと。そうしないと‘..’の直前にある名前コンポーネントは、file-truename
が呼び出される前に簡略化によって取り除かれてしまう。expand-file-name
呼び出しの必要を無くすため、file-truename
はexpand-file-name
が行うのと同じ方法で‘~’を扱う。Functions that Expand Filenamesを参照のこと。
この関数はfilenameで始まるシンボリックリンクを、シンボリックリンクではない名前のファイル名までフォローして、そのファイル名をリターンする。この関数は親ディレクトリーの階層にあるシンボリックリンクをフォローしない。
limitに数を指定するとその数のリンクを追跡した後、この関数はたとえそれが依然としてシンボリックリンクであってもそれをリターンする。
file-chase-links
とfile-truename
の違いを説明するために、/usr/fooがディレクトリー/home/fooへのシンボリックリンク、/home/foo/helloが(少なくともシンボリックリンクではない)通常ファイル、または存在しないファイルだとします。この場合には以下のようになります:
(file-chase-links "/usr/foo/hello") ;; 親ディレクトリーのリンクはフォローしない ⇒ "/usr/foo/hello" (file-truename "/usr/foo/hello") ;; /homeはシンボリックリンクではないと仮定 ⇒ "/home/foo/hello"
この関数はファイルfile1とfile2の名前が同じファイルならt
をリターンする。これはリモートファイル名も適切な方法で処理することを除いて実名の比較と似ている。file1かfile2が存在しなければリターン値は不定。
この関数は、fileがディレクトリーdir内のファイルかサブディレクトリーならt
をリターンする。またfileとdirが同じディレクトリーの場合もt
をリターンする。この関数は2つのディレクトリーの実名を比較する。dirが既存のディレクトリーの名前でなければリターン値はnil
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではファイルの詳細な情報を取得する関数について説明します。それらの情報にはファイルの所有者やグループの番号、ファイル名の個数、inode番号、サイズやアクセス日時、変更日時が含まれます。
この関数はファイルfilename1がファイルfilename2より新しければt
をリターンする。filename1が存在しなければnil
、filename1は存在するがfilename2が存在しなければt
をリターンする。
以下の例では、aug-19の書き込みが19日、aug-20の書き込みが20日、ファイルno-fileは存在しないものとする。
(file-newer-than-file-p "aug-19" "aug-20") ⇒ nil
(file-newer-than-file-p "aug-20" "aug-19") ⇒ t
(file-newer-than-file-p "aug-19" "no-file") ⇒ t
(file-newer-than-file-p "no-file" "aug-19") ⇒ nil
以下の2つの関数のfilename引数がシンボリックリンクなら、これらの関数はそれをリンクターゲットで置き換えません。しかしどちらの関数も、親ディレクトリーのすべての階層においてシンボリックリンクを再帰的にフォローします。
この関数はファイルfilenameの属性(attributes)のリストをリターンする。オープンできないファイルが指定されるとnil
をリターンする。オプション引数id-formatは属性UIDとGID(以下参照)にたいして望ましいフォーマットを指定する。有効な値は'string
と'integer
。デフォルトは'integer
だが、わたしたちはこれの変更を計画しているので、リターンされるUIDやGIDを使用する場合には、id-formatにたいして非nil
値を指定すること。
リストの要素は順に:
t
、シンボリックリンクにたいしては文字列(リンクされる名前)、テキストファイルにたいしてはnil
。
add-name-to-file
を使用して作成できる(ファイルの名前と属性の変更を参照)。
(sec-high sec-low microsec
picosec)
からなるリスト(これはcurrent-time
の値と似ている。時刻を参照)。いくつかのFATベースのファイルシステムでは最終アクセスの日付だけが記録されるので、この時刻には常に最終アクセス日の真夜中が保持されることに注意。
(high
.
low)
という形式の値になる。ここでlowは下位16ビット。それにたいしてすらinode番号が大きければ、値は(high
middle
.
low)
という形式になる。ここでhigh
は上位ビット、middleは中位24ビット、lowは下位16ビットを保持する。
たとえば以下はfiles.texiのファイル属性:
(file-attributes "files.texi" 'string) ⇒ (nil 1 "lh" "users" (20614 64019 50040 152000) (20000 23 0 0) (20614 64555 902289 872000) 122295 "-rw-rw-rw-" t (5888 2 . 43978) (15479 . 46724))
この結果を解釈すると:
nil
ディレクトリーでもシンボリックリンクでもない。
1
(カレントデフォルトディレクトリー内で名前files.texiは)単一の名前をもつ。
"lh"
名前"lh"のユーザーにより所有される。
"users"
名前"users"のグループ。
(20614 64019 50040 152000)
最終アクセスがOctober 23, 2012, at 20:12:03.050040152 UTC。
(20000 23 0 0)
最終更新がJuly 15, 2001, at 08:53:43 UTC。
(20614 64555 902289 872000)
最終ステータス変更がOctober 23, 2012, at 20:20:59.902289872 UTC。
122295
バイト長は122295バイト(しかしマルチバイトシーケンスが含まれていたり、EOLフォーマットがCRLFなら122295文字は含まれないかもしれない)。
"-rw-rw-rw-"
所有者、グループ、その他にたいして読み取り、書き込みアクセスのモードをもつ。
t
単なるプレースホルダーであり何の情報ももたない。
(5888 2 . 43978)
inode番号は6473924464520138。
(15479 . 46724)
ファイルシステムのデバイス番号は1014478468。
この関数はファイルfilenameがもつ名前(ハードリンク)の個数をリターンする。ファイルが存在しなければこの関数はnil
をリターンする。シンボリックリンクはリンク先のファイルの名前とは判断されないのでこの関数に影響しないことに注意。
$ ls -l foo* -rw-rw-rw- 2 rms rms 4 Aug 19 01:27 foo -rw-rw-rw- 2 rms rms 4 Aug 19 01:27 foo1
(file-nlinks "foo") ⇒ 2
(file-nlinks "doesnt-exist") ⇒ nil
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
いくつかのオペレーティングシステムでは、それぞれのファイルを任意の拡張ファイル属性(extended file attributes)に関連付けることができます。現在のところEmacsは拡張ファイル属性のうち2つの特定セット(ACL: Access Control List、およびSELinuxコンテキスト)にたいする問い合わせと設定をサポートします。これらの拡張ファイル属性は、前のセクションで議論したUnixスタイルの基本的なパーミッションより洗練されたファイルアクセス制御を強制するために、いくつかのシステムで利用されます。
ACLとSELinuxについての詳細な解説はこのマニュアルの範囲を超えています。わたしたちの目的のためには、それぞれのファイルはACL (ACLベースのファイル制御システムの元でACLのプロパティを指定)および/またはSELinuxコンテキスト (SELinuxシステムの元でSELinuxのプロパティを指定)に割り当てることができるという理解で問題ないでしょう。
この関数はファイルfilenameにたいするACLをリターンする。ACLにたいする正確なLisp表現は不確定(かつ将来のEmacsバージョンで変更され得る)だが、これはset-file-acl
が引数aclにとる値と同じである(ファイルの名前と属性の変更を参照)。
根底にあるACL実装はプラットフォームに固有である。EmacsはGNU/LinuxとBSDではPOSIX ACLインターフェイスを使用して、MS-WindowsではネイティブのファイルセキュリティAPIをPOSIX ACLインターフェイスでエミュレートする。
ACLサポートなしでEmacsがコンパイルされた場合には、ファイルが存在しないかアクセス不能な場合、またはその他の理由によりEmacsがACLエントリーを判断できなければリターン値はnil
。
この関数はファイルfilenameのSELinuxコンテキストを(user role
type
range)
という形式のリストでリターンする。リストの要素はそのコンテキストのユーザー、ロール、タイプ、レンジを文字列として表す値である。これらの実際の意味についての詳細はSELinuxのドキュメントを参照のこと。リターン値はset-file-selinux-context
がcontext引数で受け取るのと同じ形式(ファイルの名前と属性の変更を参照)。
SELinuxサポートなしでEmacsがコンパイルされた場合、ファイルが存在しないかアクセス不能な場合、またはシステムがSELinuxをサポートしなければリターン値は(nil
nil nil nil)
。
この関数はEmacsが認識するファイルfilenameの拡張属性をalistでリターンする。現在のところこの関数はACLとSELinuxの両方を取得するための便利な方法としての役目を果たす。他のファイルに同じファイルアクセス属性を適用するためにリターンされたalistを2つ目の引数としてset-file-extended-attributes
を呼び出すことができる(ファイルの名前と属性の変更を参照)。
要素のうちの1つは(acl . acl)
で、aclはfile-acl
がリターンするのと同じ形式。
他の要素は(selinux-context
. context)
で、contextはfile-selinux-context
がリターンするのと同じ形式。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではディレクトリーのリスト(パス(path))からファイルを検索したり、標準の実行可能ファイル用ディレクトリーから実行可能ファイルを検索する方法を説明します。
ユーザー固有の設定ファイル(configuration file)の検索については標準的なファイル名の関数locate-user-emacs-file
を参照してください。
この関数はpathで与えられるディレクトリーリスト内でfilenameという名前のファイルを検索して、suffixes内のサフィックスの検索を試みる。そのようなファイルが見つかったらファイルの絶対ファイル名(絶対ファイル名と相対ファイル名を参照)、それ以外はnil
をリターンする。
オプション引数suffixesは検索時にfilenameに追加するファイル名サフィックスのリストを与える。locate-file
は検索するディレクトリーごとにそれらのサフィックスを試みる。suffixesがnil
や("")
なら、サフィックスなしでfilenameだけがそのまま使用される。suffixesの典型的な値はexec-suffixes
(サブプロセスを作成する関数を参照)、load-suffixes
、load-file-rep-suffixes
、および関数get-load-suffixes
(ロードでの拡張子を参照)。
実行可能プログラムを探すときはexec-path
(サブプロセスを作成する関数を参照)、Lispファイルを探すときはload-path
(ライブラリー検索を参照)がpathの典型的な値である。filenameが絶対ファイル名ならpathの効果はないが、サフィックスにたいするsuffixesは依然として試行される。
オプション引数predicateが非nil
なら、それは候補ファイルが適切かどうかテストする述語関数を指定する。述語関数には単一の引数として候補ファイル名が渡される。predicateがnil
か省略なら述語としてfile-readable-p
を使用する。file-executable-p
やfile-directory-p
など、その他の有用な述語についてはファイル種別の区別を参照のこと。
互換性のためにpredicateにはexecutable
、readable
、writable
、exists
、またはこれらシンボルの1つ以上のリストも指定できる。
この関数はprogramという名前の実行可能ファイルを検索して、その実行可能ファイルの絶対ファイル名と、もしあればファイル名の拡張子も含めてリターンする。ファイルが見つからなければnil
をリターンする。この関数はexec-path
内のすべてのディレクトリーを検索して、exec-suffixes
内のすべてのファイル名拡張子の検索も試みる(サブプロセスを作成する関数を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションの関数はファイルのリネーム、コピー、リンク、(権限)モードのセットを行います。これらの関数はすべて処理に失敗すると、失敗した理由を記述するシステム固有ッセージを報告するためにfile-error
エラーをシグナルします。
newnameという引数をもつ関数では、newnameという名前のファイルが既に存在する場合には、その挙動が引数ok-if-already-existsの値に依存します。
nil
ならfile-already-exists
エラーがシグナルされる。
以下の4つのコマンドはすべて1つ目の引数にたいして親ディレクトリーの全階層のシンボリックリンクを再帰的にフォローしますが、その引数自体がシンボリックリンクならcopy-file
だけが(再帰的な)ターゲットを置き換えます。
この関数は、oldnameという名前のファイルにnewnameという名前を追加で与える。これはnewnameという名前がoldnameにたいする新たなハードリンクになることを意味する。
以下の例の最初の部分では2つのファイルfooとfoo3をリストする。
$ ls -li fo* 81908 -rw-rw-rw- 1 rms rms 29 Aug 18 20:32 foo 84302 -rw-rw-rw- 1 rms rms 24 Aug 18 20:31 foo3
ここでadd-name-to-file
を呼び出してハードリンクを作成して再度ファイルをリストする。このリストには1つのファイルにたいして2つの名前fooとfoo2が表示される。
(add-name-to-file "foo" "foo2") ⇒ nil
$ ls -li fo* 81908 -rw-rw-rw- 2 rms rms 29 Aug 18 20:32 foo 81908 -rw-rw-rw- 2 rms rms 29 Aug 18 20:32 foo2 84302 -rw-rw-rw- 1 rms rms 24 Aug 18 20:31 foo3
最後に以下を評価する:
(add-name-to-file "foo" "foo3" t)
そしてファイルを再度リストする。今度は1つのファイルにたいして3つの名前foo、foo2、foo3がある。foo3の古いコンテンツは失われた。
(add-name-to-file "foo1" "foo3") ⇒ nil
$ ls -li fo* 81908 -rw-rw-rw- 3 rms rms 29 Aug 18 20:32 foo 81908 -rw-rw-rw- 3 rms rms 29 Aug 18 20:32 foo2 81908 -rw-rw-rw- 3 rms rms 29 Aug 18 20:32 foo3
この関数は1つのファイルにたいして複数の名前をもつことが許されないオペレーティングシステムでは無意味である。いくつかのシステムでは、かわりにファイルをコピーすることにより複数の名前を実装している。
ファイルの属性のfile-nlinks
も参照のこと。
このコマンドはfilenameをnewnameにリネームする。
filenameがfilenameとは別に追加の名前をもつなら、それらは自身の名前をもち続ける。実際のところadd-name-to-file
で名前newnameを追加してからfilenameを削除するのは、瞬間的な遷移状態を別とするとリネームと同じ効果がある。
このコマンドはファイルoldnameをnewnameにコピーする。oldnameが存在しなければエラーをシグナルする。newnameがディレクトリーなら、その最後の名前コンポーネントを保持するようにそのディレクトリーの中にoldnameをコピーする。
timeが非nil
なら、この関数は新たなファイルにたいして古いファイルと同じ最終変更時刻を与える(これはいくつかの限られたオペレーティングシステムでのみ機能する)。時刻のセットでエラーが発生すると、copy-file
はfile-date-error
エラーをシグナルする。インタラクティブに呼び出された場合には、プレフィックス引数はtimeにたいして非nil
値を指定する。
引数preserve-uid-gidがnil
なら、新たなファイルのユーザーとグループの所有権の決定をオペレーティングシステムに委ねる(通常はEmacsを実行中のユーザー)。preserve-uid-gidが非nil
なら、そのファイルのユーザーとグループの所有権のコピーを試みる。これはいくつかのオペレーティングシステムで、かつそれを行うための正しいパーミッションをもつ場合のみ機能する。
オプション引数preserve-permissionsが非nil
なら、この関数はoldnameのファイルモード(または“パーミッション”)、同様にACL(Access
Control List)とSELinuxコンテキストをnewnameにコピーする。ファイルの情報を参照のこと。
それ以外では、newnameが既存ファイルならファイルモードは変更されず、新たに作成された場合はデフォルトのファイルパーミッション(以下のset-default-file-modes
を参照)によりマスクされる。どちらの場合でもACLやSELinuxコンテキストはコピーされない。
このコマンドはfilenameにたいしてnewnameという名前のシンボリックリンクを作成する。これはコマンド‘ln -s filename newname’と似ている。
この関数はシンボリックリンクをサポートしないシステムでは利用できない。
このコマンドはファイルfilenameを削除する。ファイルが複数の名前をもつ場合には、他の名前で存在し続ける。filenameがシンボリックリンクなら、delete-file
はシンボリックリンクだけを削除して、(たとえこれが親ディレクトリーの全階層のシンボリックリンクをフォローするとしても)ターゲットは削除しない。
ファイルが存在しない、または削除できなければ適切な種類のfile-error
エラーがシグナルされる(UnixとGNU/Linuxではファイルのディレクトリーが書き込み可能ならファイルは削除可能)。
オプション引数trashが非nil
、かつ変数delete-by-moving-to-trash
が非nil
なら、このコマンドはファイルを削除するかわりにシステムのTrash(ゴミ箱)にファイルを移動する。Miscellaneous File Operations in The GNU Emacs
Manualを参照のこと。インタラクティブに呼び出された際には、プレフィックス引数がなければtrashはt
、それ以外はnil
。
ディレクトリーの作成・コピー・削除のdelete-directory
も参照のこと。
この関数はfilenameのファイルモード(またはパーミッション)をmodeにセットする。この関数はfilenameにたいして全階層でシンボリックリンクをフォローする。
非インタラクティブに呼び出された場合には、modeは整数でなければならない。その整数の下位12ビットだけが使用される。ほとんどのシステムでは意味があるのは下位9ビットのみ。modeを入力するLisp構文を使用できる。たとえば、
(set-file-modes #o644)
これはそのファイルにたいして所有者による読み取りと書き込み、グループメンバーによる読み取り、その他のユーザーによる読み取り可能であることを指定する。モードビットの仕様の説明はFile
permissions in The GNU Coreutils
Manualを参照のこと。
インタラクティブに呼び出されると、modeはread-file-modes
(以下参照)を使用してミニバッファーから読み取られる。この場合にはユーザーは整数、またはパーミッションをシンボルで表現する文字列をタイプできる。
ファイルのパーミッションをリターンする関数file-modes
についてはファイルの属性を参照のこと。
この関数はEmacsとEmacsのサブプロセスが新たに作成するファイルに、デフォルトのパーミッションをセットする。Emacsにより作成されたすべてのファイルはこれらのパーミッション、およびそれらのサブセットとなるパーミッションをもつ(デフォルトファイルパーミッションが実行を許可してもwrite-region
は実行パーミッションを付与しないだろう)。UnixとGNU/Linuxでは、デフォルトのパーミッションは‘umask’の値のビット単位の補数で与えられる。
引数modeは上記のset-file-modes
と同様、パーミッションを指定する整数であること。意味があるのは下位9ビットのみ。
デフォルトのファイルパーミッションは、既存ファイルの変更されたバージョンを保存する際は効果がない。ファイルの保存では既存のパーミッションが保持される。
このマクロは新たなファイルにたいするデフォルトのパーミッションを一時的にmodes
(値は)set-file-modes
にたいする値と同様)にセットしてフォームbodyを評価する。終了時には元にデフォルトのファイルノパーミッションをリストアして、bodyの最後のフォームの値をリターンする。
これはたとえばプライベートファイルの作成に有用である。
この関数はデフォルトのファイルのパーミッションを整数でリターンする。
この関数はミニバッファーからファイルモードのビットのセットを読み取る。1つ目のオプション引数promptは非デフォルトのプロンプトを指定する。2つ目のオプション引数base-fileはユーザーが既存ファイルのパーミッションに相対的なモードビット指定をタイプした場合に、この関数がリターンするモードビッの元となる権限をもつファイルの名前を指定する。
ユーザー入力が8進数で表される場合には、この関数はその数字をリターンする。それが"u=rwx"
のようなモードビットの完全なシンボル指定なら、この関数はfile-modes-symbolic-to-number
を使用して、それを等価な数字に変換して結果をリターンする。"o+g"
のように相対的な指定なら、その指定の元となるパーミッションはbase-fileのモードビットから取得される。base-fileが省略またはnil
なら、この関数は元となるモードビットとして0
を使用する。完全指定と相対指定は"u+r,g+rx,o+r,g-w"
のように組み合わせることができる。ファイルモード指定の説明はFile
permissions in The GNU Coreutils
Manualを参照のこと。
この関数はmodes内のシンボルによるファイルモード指定を等価な整数に変換する。シンボル指定が既存ファイルにもとづく場合には、オプション引数base-modesからそのファイルのモードビットが取得される。その引数が省略またはnil
なら、0(すべてのアクセスが許可されない)がデフォルトになる。
この関数はfilenameのアクセス時刻と変更時刻をtimeにセットする。時刻が正しくセットされればt
、それ以外はnil
がリターン値となる。timeのデフォルトはカレント時刻であり、current-time
がリターンするフォーマットでなければならない(時刻を参照)。
この関数はfilename
にたいしてEmacsが認識する拡張ファイル属性をセットする。2つ目の引数attribute-alistはfile-extended-attributes
がリターンするalistと同じ形式であること。属性のセットが成功したらt
、それ以外はnil
がリターン値となる。拡張されたファイル属性を参照のこと。
この関数はfilenameにたいするSELinuxセキュリティコンテキストにcontextをセットする。context引数は各要素が文字列であるような(user
role type range)
というリストであること。拡張されたファイル属性を参照のこと。
この関数はfilenameのSELinuxコンテキストのセットに成功したらt
をリターンする。コンテキストがセットされなかった場合(SELinuxが無効、またはEmacsがSELinuxサポートなしでコンパイルされた場合等)にはnil
をリターンする。
この関数はfilenameにたいするACLにaclをセットする。acl引数は関数file-acl
がリターンするのと同じ形式であること。拡張されたファイル属性を参照のこと。
この関数はfilenameのACLのセットに成功したらt
、それ以外はnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ファイルは一般的に名前で参照され、これはEmacsでも他と同様です。Emacsではファイル名は文字列で表現されます。ファイルを操作する関数はすべてファイル名引数に文字列を期待します。
ファイル自体の操作に加えて、Emacs Lispプログラムでファイル名を処理する必要(ファイル名の一部を取得して関連するファイル名構築にその一部を使用する等)がしばしばあります。このセクションではファイル名を扱う方法を説明します。
このセクションの関数は実際にファイルにアクセスする訳ではないので、既存のファイルやディレクトリーを参照しないファイル名を処理できます。
MS-DOSとMS-Windowsでは、これらの関数は(実際にファイルを操作する関数と同様)、MS-DOSとMS-Windowsのファイル名構文を受け入れます。この構文はUnix構文のようにバックスラッシュでコンポーネントを区切りますが、これらの関数は常にUnix構文をリターンします。これによりUnix構文でファイル名を指定するLispプログラムが、変更なしですべてのシステムで正しく機能することが可能になるのです。13
24.8.1 ファイル名の構成要素 | ファイル名のディレクトリー部分と、それ以外。 | |
24.8.2 絶対ファイル名と相対ファイル名 | カレントディレクトリーにたいして相対的なファイル名。 | |
24.8.3 ディレクトリーの名前 | ディレクトリーとしてのディレクトリー名と、ファイルとしてのファイル名の違い。 | |
24.8.4 ファイル名を展開する関数 | 相対ファイル名から絶対ファイル名への変換。 | |
24.8.5 一意なファイル名の生成 | 一時ファイル用の名前の生成。 | |
24.8.6 ファイル名の補完 | 与えられたファイル名にたいする補完を探す。 | |
24.8.7 標準的なファイル名 | パッケージが固定されたファイル名を使用する際に、種々のオペレーティングシステムをシンプルに処理する方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
オペレーティングシステムはファイルをディレクトリーにグループ化します。あるファイルを指定するためには、ディレクトリーとそのディレクトリー内でのファイルの名前を指定しなければなりません。それゆえEmacsはファイル名をディレクトリー名パートと非ディレクトリー(またはディレクトリー内ファイル名)パートという、2つの主要パートから判断します。どちらのパートも空の場合があり得ます。これら2つのパートを結合することによって元のファイル名が再構築されます。
ほとんどのシステムでは最後のスラッシュ(MS-DOSとMS-Windowsではバックスラッシュも許される)までのすべてがディレクトリーパートです。残りが非ディレクトリーパートです。
ある目的のために、非ディレクトリーパートはさらに正式名称(the name proper)とバージョン番号に細分されます。ほとんどのシステムでは、名前にバージョン番号をもつのはバックアップファイルだけです。
この関数はfilenameのディレクトリーパートをディレクトリー名(ディレクトリーの名前を参照)としてリターンする。filenameがディレクトリーパートを含まなければnil
をリターンする。
GNUとUnixシステムでは、この関数がリターンする文字列は常にスラッシュで終わる。MS-DOSではコロンで終わることもあり得る。
(file-name-directory "lewis/foo") ; Unixの例
⇒ "lewis/"
(file-name-directory "foo") ; Unixの例
⇒ nil
この関数はfilenameの非ディレクトリーパートをリターンする。
(file-name-nondirectory "lewis/foo") ⇒ "foo"
(file-name-nondirectory "foo") ⇒ "foo"
(file-name-nondirectory "lewis/") ⇒ ""
この関数は、任意のファイルバージョン番号、バックアップバージョン番号、末尾のチルダを取り除いたfilenameをリターンする。
keep-backup-versionが非nil
なら、ファイルシステムなどが認識するような真のファイルバージョン番号は破棄されるが、バックアップバージョン番号は保持される。
(file-name-sans-versions "~rms/foo.~1~") ⇒ "~rms/foo"
(file-name-sans-versions "~rms/foo~") ⇒ "~rms/foo"
(file-name-sans-versions "~rms/foo") ⇒ "~rms/foo"
この関数はfilenameから、もしあればすべてのバージョン番号とバックアップ番号を取り除いた後の、終端の拡張子(extension)をリターンする。ファイル名の拡張子とは最後の名前コンポーネント(からすべてのバージョン番号とバックアップ番号を取り去った後)の最後の‘.’に後続するパートのこと。
この関数はfooのような拡張子のないファイル名にたいしてはnil
、foo.のようなnull拡張子にたいしては""
をリターンする。ファイル名の最終コンポーネントが‘.’で始まる場合には、その‘.’は拡張子の開始とはみなされない。したがって.emacsの拡張子は‘.emacs’ではなくnil
。
periodが非nil
なら、拡張子を区切るピリオドもリターン値に含まれる。その場合には、もしfilenameが拡張子をもたなければリターン値は""
。
この関数は、もしあればfilenameから拡張子を除いてリターンする。もしバージョン番号やバックアップ番号があるなら、ファイルが拡張子をもつ場合のみそれを削除する。たとえば、
(file-name-sans-extension "foo.lose.c") ⇒ "foo.lose" (file-name-sans-extension "big.hack/foo") ⇒ "big.hack/foo" (file-name-sans-extension "/my/home/.emacs") ⇒ "/my/home/.emacs" (file-name-sans-extension "/my/home/.emacs.el") ⇒ "/my/home/.emacs" (file-name-sans-extension "~/foo.el.~3~") ⇒ "~/foo" (file-name-sans-extension "~/foo.~3~") ⇒ "~/foo.~3~"
最後の2つの例の‘.~3~’は拡張子ではなくバックアップ番号であることに注意。
これはfile-name-sans-extension
とfile-name-nondirectory
を組み合わせた関数。たとえば、
(file-name-base "/my/home/foo.c") ⇒ "foo"
引数filenameのデフォルトはbuffer-file-name
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ファイルシステム内のすべてのディレクトリーはルートディレクトリーから開始されるツリーを形成します。このツリーのルートから開始されるすべてのディレクトリー名によってファイル名を指定することができ、それを絶対(absolute)ファイル名と呼びます。デフォルトディレクトリーからの相対的なツリー中の位置でファイルを指定することもでき、それは相対(relative)ファイル名と呼ばれます。UnixとGNU/Linuxでは、絶対ファイル名は‘/’か‘~’で始まり、相対ファイル名は異なります(abbreviate-file-nameを参照)。MS-DOSとMS-Windowsでは絶対ファイル名はスラッシュ、バックスラッシュ、またはドライブ指定‘x:/’で始まります。ここでxはドライブ文字(drive letter)です。
この関数はfilenameが絶対ファイル名ならt
、それ以外はnil
をリターンする。
(file-name-absolute-p "~rms/foo") ⇒ t
(file-name-absolute-p "rms/foo") ⇒ nil
(file-name-absolute-p "/user/rms/foo") ⇒ t
相対ファイル名が与えられるとexpand-file-name
を使用して、それを絶対ファイル名に変換できます(ファイル名を展開する関数を参照)。以下の関数は絶対ファイル名を相対ファイル名に変換します:
この関数はdirectory(絶対ディレクトリー名かディレクトリーファイル名)から相対的なファイルと仮定して、filenameと等価な相対ファイル名のリターンを試みる。directoryが省略かnil
なら、カレントバッファーのデフォルトディレクトリーがデフォルト。
絶対ファイル名がデバイス名で始まるオペレーティングシステムがいくつか存在する。そのようなシステムでは、2つの異なるデバイス名から開始されるfilenameは、directoryにもといた等価な相対ファイル名をもたない。この場合には、file-relative-name
は絶対形式でfilenameをリターンする。
(file-relative-name "/foo/bar" "/foo/") ⇒ "bar" (file-relative-name "/foo/bar" "/hack/") ⇒ "../foo/bar"
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ディレクトリー名(directory name)とは、ディレクトリーの名前のことです。ディレクトリーは実際にはファイルの一種なので、ディレクトリーファイル名(directory file name)と呼ばれるファイル名をもちます。これはディレクトリー名と関連がありますが同一ではありません(これはUnixの通常の用語とは異なる)。同じ実体にたいするこれら2つの異なる名前は、構文的な変換により関連付けられます。GNUとUnixシステムでは事は単純です。ディレクトリーファイル名はスラッシュで終わり、ファイルとしてのディレクトリーの名前にはそのスラッシュがありません。MS-DOSではこの関連付けはより複雑です。
ディレクトリー名とディレクトリーファイル名の違いは些細ですが重要です。Emacsの変数や関数の引数を記述する際には、引数がディレクトリーだとみなしており、ディレクトリーファイル名は許容されません。file-name-directory
が文字列をリターンするときは、常にディレクトリー名をリターンします。
以下の2つの関数は、ディレクトリー名とディレクトリーファイル名の間で変換を行います。これらの関数は‘$HOME’のような環境変数や‘~’、‘.’、‘..’などの構文にたいして、特別なことは何も行いません。
この関数はオペレーティングシステムがディレクトリーの名前(ディレクトリー名)と解釈する形式でfilenameを表す文字列をリターンする。これはほとんどのシステムでは、(もし終端にそれがなければ)これは文字列にスラッシュを追加することを意味する。
(file-name-as-directory "~rms/lewis") ⇒ "~rms/lewis/"
この関数はfilenameがディレクトリー区切り文字で終れば非nil
をリターンする。これはUnixとGNUシステムでは順スラッシュ‘/’、MS-WindowsとMS-DOSでは順スラッシュとバックスラッシュ‘\’の両方がディレクトリー区切り文字として認識される。
この関数は、オペレーティングシステムがファイルの名前(ディレクトリーファイル名)として解釈する形式でdirnameを表す文字列をリターンする。ほとんどのシステムでは、これは文字列から最後のスラッシュ(またはバックスラッシュ)を削除することを意味する。
(directory-file-name "~lewis/") ⇒ "~lewis"
ディレクトリー名にたいしてはconcat
を使用して相対ファイルと組み合わせることができます:
(concat dirname relfile)
これを行う前にファイル名が相対的であることを確認してください。絶対ファイル名を使用すると構文的に不正な結果となったり、間違ったファイルを参照する可能性があります。
ディレクトリーファイル名の作成にこのような組み合わせを使用しなければ、最初にfile-name-as-directory
を使用してそれをディレクトリー名に変換しなければなりません:
(concat (file-name-as-directory dirfile) relfile)
以下のように手動でスラッシュの結合を試みてはなりません
;;; 間違い!
(concat dirfile "/" relfile)
なぜならこれには可搬性がないからです。常にfile-name-as-directory
を使用してください。
上述の問題の回避や(たとえばload-path
の要素のように)dirnameの値がnilかもしれない場合には、以下を使用してください:
(expand-file-name relfile dirname)
ディレクトリー名をディレクトリーの省略名に変換するには以下の関数を使用します:
この関数はfilenameの省略された形式をリターンする。
これはdirectory-abbrev-alist
(File Aliases in The GNU Emacs
Manualを参照)で指定される省略名を適用して、引数で与えられるファイル名ががホームディレクトリーかそのサブディレクトリーにあれば、ユーザーのホームディレクトリーを‘~’に置換する。ホームディレクトリーがルートディレクトリーなの場合には、多くのシステムでは結果が短縮されないので‘~’で置き換えない。
これは名前の一部であるような省略形さえも認識するので、ディレクトリー名とファイル名にも使用できる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ファイル名の展開(expanding)とは相対ファイル名を絶対ファイル名に変換することを意味します。これはデフォルトディレクトリーから相対的に行われるため、展開されるファイル名と同様にデフォルトディレクトリーも指定しなければなりません。これは~/のような省略形 (abbreviate-file-nameを参照)、 の展開、および./やname/../のような冗長さの排除も行います。
この関数はfilenameを絶対ファイル名に変換する。directoryが与えられたなら、それはfilenameが相対的な場合に開始点となるデフォルトディレクトリーであること。それ以外ならカレントバッファーのdefault-directory
の値が使用される。たとえば:
(expand-file-name "foo") ⇒ "/xcssun/users/rms/lewis/foo"
(expand-file-name "../foo") ⇒ "/xcssun/users/rms/foo"
(expand-file-name "foo" "/usr/spool/") ⇒ "/usr/spool/foo"
結合されたファイル名の最初のスラッシュの前が‘~’なら、環境変数HOME
(通常はユーザーのホームディレクトリー)の値に展開される。最初のスラッシュの前が‘~user’で、かつuserが有効なログイン名なら、userのホームディレクトリーに展開される。
‘.’や‘..’を含むファイル名は正規化形式に簡略化される:
(expand-file-name "bar/../foo") ⇒ "/xcssun/users/rms/lewis/foo"
出力に‘..’部分が残り得る場合もある:
(expand-file-name "../home" "/") ⇒ "/../home"
これはルートディレクトリー/の上位のスーパールート(superroot)という概念をもつファイルシステムのためのものである。その他のファイルシステムでは/../は/とまったく同じに解釈される。
expand-file-name
は環境変数を展開しないことに注意。それを行うのはsubstitute-in-file-name
のみ。
(expand-file-name "$HOME/foo") ⇒ "/xcssun/users/rms/lewis/$HOME/foo"
expand-file-name
はあらゆる階層においてシンボリックリンクをフォローしないことにも注意。これは‘..’の扱いがfile-truename
とexpand-file-name
で異なることに起因する。‘/tmp/bar’がディレクトリー‘/tmp/foo/bar’にたいするシンボリックリンクであると仮定すると:
(file-truename "/tmp/bar/../myfile") ⇒ "/tmp/foo/myfile"
(expand-file-name "/tmp/bar/../myfile") ⇒ "/tmp/myfile"
直接間接を問わず事前にexpand-file-name
を呼び出さずに‘..’に先行するシンボリックリンクをフォローする必要があるかもしれない場合には、それを呼び出さずに確実にfile-truename
を呼び出すこと。本当の名前を参照されたい。
このバッファーローカル変数の値はカレントバッファーにたいするデフォルトディレクトリー。これは絶対ディレクトリー名であること。これは‘~’で始まるかもしれない。この変数はすべてのバッファーにおいてバッファーローカル。
2つ目の引数がnil
なら、expand-file-name
はデフォルトディレクトリーを使用する。
値は常にスラッシュで終わる文字列。
default-directory ⇒ "/user/lewis/manual/"
この関数はfilename内で参照される環境変数を環境変数の値に置き換える。標準的なUnixシェル構文にしたがい ‘$’は環境変数値を置き換るプレフィックスである。入力に‘$$’が含まれる場合には、それらは‘$’に置き換えられる。これによりユーザーが‘$’をクォートする手段が与えられる。
環境変数名は‘$’の後に続く一連の英数字(アンダースコアを含む)である。‘$’の後続文字が‘{’なら対応する‘}’までのすべてが変数名である。
substitute-in-file-name
により生成された出力でsubstitute-in-file-name
を呼び出すと不正な結果となる傾向がある。たとえば単一の‘$’をクォートするために‘$$’を使用しても正しく機能せずに環境変数値の中の‘$’は再帰的な置換を導くだろう。したがってこの関数を呼び出して出力をこの関数に渡すプログラムは、その後の不正な結果を防ぐためにすべての‘$’文字を二重化する必要がある。
以下ではユーザーのホームディレクトリー名を保持する環境変数HOME
は値‘/xcssun/users/rms’をもつ。
(substitute-in-file-name "$HOME/foo") ⇒ "/xcssun/users/rms/foo"
置き換え後には、‘/’の直後に‘~’や別の‘/’が出現すると、この関数は‘/’の前にあるすべてを無視する。
(substitute-in-file-name "bar/~/foo") ⇒ "~/foo"
(substitute-in-file-name "/usr/local/$HOME/foo")
⇒ "/xcssun/users/rms/foo"
;; /usr/local/は破棄された
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
一時ファイルに書き込む必要があるプログラムがいくつかあります。以下は、そのようなファイルを構築する便利な方法です:
(make-temp-file name-of-application)
make-temp-file
の役目は、2人の異なるユーザーやジョブが完全に一致する名前のファイルの使用を防ぐことです。
この関数は一時ファイルを作成してその名前をリターンする。EmacsはEmacsの各ジョブごとに異なるランダムないくつかの文字をprefixに追加することによって一時ファイルの名前を作成する。結果として新たに空のファイルが作成されることが保障される。MS-DOSでは8+3のファイル名制限に適合するように、文字列stringは切り詰められる可能性がある。prefixが相対ファイル名なら、それはtemporary-file-directory
にたいして展開される。
(make-temp-file "foo") ⇒ "/tmp/foo232J6v"
make-temp-file
がリターンした際には、一時ファイルは空で作成される。この時点でそのファイルに意図するコンテンツを書き込むこと。
dir-flagがnil
なら、make-temp-file
は空のファイルのかわりに空のディレクトリーを作成する。これはディレクトリー名ではなく、ディレクトリーのファイル名をリターンする。ディレクトリーの名前を参照のこと。
suffixが非nil
なら、make-temp-file
はそれをファイル名の最後に追加する。
同じEmacs内で実行される異なるライブラリー間での競合を防ぐために、make-temp-file
を使用する各Lispプログラムがプログラム自身のprefixを使用すること。prefixの最後に追加される数字は、異なるEmacsジョブ内で実行される同じアプリケーションを区別する。追加される文字により、同一のEmacsジョブ内でも多数の名前を区別することが可能になる。
一時ファイル用のデフォルトディレクトリーは変数temporary-file-directory
により制御されます。この変数によりすべての一時ファイルにたいして、ユーザーがディレクトリーを指定する一貫した方法が与えられます。small-temporary-file-directory
が非nil
なら、かわりにそれを使うプログラムもいくつかあります。これを使う場合には、make-temp-file
を呼び出す前に正しいディレクトリーにたいしてプレフィックスを展開するべきです。
この変数は一時ファイル作成用のディレクトリー名を指定する。値はディレクトリー名であるべきだが、もし値がディレクトリーのファイル名(ディレクトリーの名前を参照)ならば、Lispプログラムがかわりに対処すればよい。expand-file-name
の2つ目の引数としてその値を使用するのは、それを達成するよい方法である。
デフォルト値はオペレーティングシステムにたいして適切な方法により決定される。これは環境変数TMPDIR
、TMP
、TEMP
にもとづく値で、これらの変数が定義されていなければシステム依存の名前にフォールバックする。
一時ファイルの作成にmake-temp-file
を使用しない場合でも、一時ファイルを置くディレクトリーを判断するために依然としてこの変数を使用するべきである。しかし一時ファイルが小さくなることを求める場合には、small-temporary-file-directory
が非nil
ならそれを使用すること。
この変数はサイズが小さいと予想される特定の一時ファイル作成用のディレクトリー名を指定する。
小さくなるかもしれない一時ファイルに書き込みたいなら、以下のようにディレクトリーを計算すること:
(make-temp-file (expand-file-name prefix (or small-temporary-file-directory temporary-file-directory)))
この関数は一意なファイル名として使用できる文字列を生成する。この名前はbase-nameで始まり、それに各Emacsジョブごとに異なる複数のランダムな文字を追加したものである。これはmake-temp-file
と似ているが、(i)
名前だけを作成してファイルは作成しない、(ii)
base-nameは絶対ファイル名であること、という点が異なる(MS-DOSシステムでは8+3ファイル名制限に適合するようにbase-nameが切り詰められる)。
警告: この関数を使用するべきではない。かわりにmake-temp-file
を使用すること!
この関数は競合状態の影響を受けやすい。make-temp-name
呼び出しと一時ファイル作成のタイムラグはセキュリティーホールとなり得る。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではファイル名を補完するための低レベルサブルーチンについて説明します。より高レベルの関数についてはファイル名の読み取りを参照してください。
この関数はディレクトリーdirectory内でpartial-filenameで始まる名前のファイルにたいする、すべての補完可能なリストをリターンする。補完の順番はそのディレクトリー内でのファイル順序であり、これは予測不能であり何の情報ももたない。
引数partial-filenameは非ディレクトリーパートを含むファイル名でなければならず、スラッシュ(いくつかのシステムではバックスラッシュ)が含まれていてはならない。directoryが絶対ディレクトリーでなければ、directoryの前にカレントバッファーのデフォルトディレクトリーが追加される。
以下の例では~rms/lewisがカレントデフォルトディレクトリーで、名前が‘f’で始まる5つのファイルfoo、file~、file.c、file.c.~1~、file.c.~2~がある:
(file-name-all-completions "f" "") ⇒ ("foo" "file~" "file.c.~2~" "file.c.~1~" "file.c")
(file-name-all-completions "fo" "") ⇒ ("foo")
この関数はディレクトリーdirectory内でファイル名filenameを補完する。これはディレクトリーdirectory内で、filenameで始まるすべてのファイル名にたいして、最長の共通プレフィックスをリターンする。predicateが非nil
なら展開された絶対ファイル名を単一の引数として呼び出して、predicateを満足しない補完候補を無視する。
マッチが1つだけ存在して、かつfilenameが正確にそれにマッチする場合には、この関数はt
をリターンする。関数はディレクトリーdirectoryがfilenameで始まる名前のファイルを含まなければnil
をリターンする。
以下の例では~rms/lewisがカレントデフォルトディレクトリーで、名前が‘f’で始まる5つのファイルfoo、file~、file.c、file.c.~1~、file.c.~2~がある:
(file-name-completion "fi" "") ⇒ "file"
(file-name-completion "file.c.~1" "") ⇒ "file.c.~1~"
(file-name-completion "file.c.~1~" "") ⇒ t
(file-name-completion "file.c.~3" "") ⇒ nil
file-name-completion
はこのリスト内の任意の文字列で終わるファイル名を通常は無視する。すべての可能な補完がこれらのサフィックスのいずれか1つで終わるときはそれらを無視しない。この変数はfile-name-all-completions
に影響しない。
以下は典型的な値:
completion-ignored-extensions ⇒ (".o" ".elc" "~" ".dvi")
completion-ignored-extensions
のある要素がスラッシュ‘/’で終わる場合には、それはディレクトリーを示す。スラッシュで終わらない要素がディレクトリーにマッチすることは決してない。したがって上記の値はfoo.elcという名前のディレクトリーを除外しないだろう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs
Lispプログラムが特定の用途のために標準的なファイル名を指定することが必要な場合があります。典型的にはカレントユーザーによって指定された設定データを保持する場合が該当します。そのようなファイルは、通常はuser-emacs-directory
により指定されるディレクトリーに配置され、デフォルトでは~/.emacs.dです(initファイルを参照)。たとえばabbrev(abbreviation:
省略形)の定義は、デフォルトでは~/.emacs.d/abbrev_defsに格納されます。このようなファイル名を指定するためには、関数locate-user-emacs-file
を使用するのがもっとも簡単な方法です。
この関数はEmacs特有の設定ファイルやデータファイルにたいする絶対ファイル名をリターンする。引数base-nameは、相対ファイル名であること。リターン値はuser-emacs-directory
で指定されるディレクトリー内の絶対ファイル名。そのディレクトリーが存在しなければ、この関数はディレクトリーを作成する。
オプション引数old-nameが非nil
なら、それはユーザーのホームディレクトリー内のファイル~/old-nameを指定する。そのようなファイルが存在すれば、リターン値はbase-nameで指定されるファイルではなくそのファイルの絶対ファイル名となる。これはEmacsパッケージが後方互換を提供するために使用されることを意図した引数。たとえばuser-emacs-directory
導入前には、abbrevファイルは~/.abbrev_defsに置かれていた。以下はabbrev-file-name
の定義である:
(defcustom abbrev-file-name (locate-user-emacs-file "abbrev_defs" ".abbrev_defs") "Default name of file from which to read abbrevs." … :type 'file)
ファイル名の標準化のための低レベル関数はconvert-standard-filename
で、これはサブルーチンとしてlocate-user-emacs-file
により使用されます。
この関数はfilenameにもとづいたカレントオペレーティングシステムの慣習に適合するファイル名をリターンする。
GNUとUnixシステムでは、これは単にfilenameをリターンする。その他のオペレーティングシステムでは、システム固有のファイル名規約にしたがうだろう。たとえばMS-DOSでは、この関数はMS-DOSファイル名制限にしたがうように先頭の‘.’を‘_’に変換したり、‘.’の後続の文字を3文字に切り詰める等、さまざまな変更を行う。
この関数でGNUとUnixシステムの慣習に適合する名前を指定して、それをconvert-standard-filename
に渡すのが推奨される使用方法である。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ディレクトリーとはファイルの一種であり、さまざまな名前のファイルを含んでいます。ディレクトリーはファイルシステムの機能です。
Emacsはディレクトリー内のファイル名をLispのリストとして一覧したり、シェルコマンドls
を使用してバッファー内にファイル名を表示することができます。後者の場合には、Emacsはオプションで各ファイルに関する情報も表示でき、それはls
コマンドに渡すオプションに依存します。
この関数はディレクトリーdirectory内のファイルの名前のリストをリターンする。デフォルトではリストはアルファベット順。
この関数はfull-nameが非nil
ならファイルの絶対ファイル名、それ以外なら指定されたディレクトリーにたいする相対ファイル名をリターンする。
match-regexpが非nil
なら、この関数はその正規表現にたいするマッチを含むファイル名だけをリターンして、それ以外のファイル名はリストから除外される。case(大文字小文字)を区別するファイルシステムでは、caseを区別する正規表現マッチングが行われる。
nosortが非nil
ならdirectory-files
はリストをソートしないので、取得するファイル名に特定の順序はない。最大限の可能なスピードを得る必要がありファイル処理順を気にしなければこれを使用する。ユーザーから処理順が可視なら、名前をソートすれば多分ユーザーはより幸せになるだろう。
(directory-files "~lewis") ⇒ ("#foo#" "#foo.el#" "." ".." "dired-mods.el" "files.texi" "files.texi.~1~")
directoryが読み取り可能なディレクトリー名でなければエラーがシグナルされる。
regexpにマッチする名前をもつdirectory配下のすべてのファイルをリターンする。この関数はベースネーム(basename:
先行するディレクトリー部分を除外したファイル名)がregexpにマッチするファイルを、directoryとそのサブディレクトリーを再帰的に検索して、マッチしたファイルの絶対ファイル名(absolute file
namesを参照)のリストをリターンする。ファイル名は深さ優先順でリターンされ、それは親ディレクトリーの前に任意のサブディレクトリー内のファイルが配置されることを意味する。加えて各ディレクトリー内で見つかったファイルはベースネームにもとづいてソートされる。デフォルトではregexpにマッチする名前のディレクトリーはリストから省略されるが、オプション引数include-directoriesが非nil
ならそれらも含まれる。
これはどのファイルを報告するかとファイル名を報告する方法においてdirectory-files
と似ている。しかしこの関数はファイル名のリストをリターンするかわりに、各ファイルごとにリスト(filename
.
attributes)
をリターンする。ここでattributesはそのファイルにたいしてfile-attributes
がリターンするであろう値。オプション引数id-formatはfile-attributes
の対応する引数と同じ意味をもつ(Definition of file-attributesを参照)。
この関数はワイルドカードパターンpatternを展開して、それにマッチするファイル名のリストをリターンする。
絶対ファイル名としてpatternが記述されると値も絶対ファイル名になる。
patternが相対ファイル名で記述されていれば、それはカレントデフォルトディレクトリーにたいして相対的に解釈される。通常はリターンされるファイル名もカレントデフォルトディレクトリーにたいする相対ファイル名になる。しかしfullが非nil
なら絶対ファイル名がリターンされる。
この関数はls
のswitchesに対応するフォーマットで、(カレントバッファー内に)ディレクトリーfileのディレクトリーリストを挿入する。これは挿入したテキストの後にポイントを残す。switchesにはオプション文字列、または個別のオプションを表す文字列リストを指定できる。
引数fileにはディレクトリー名かワイルドカード文字を含むファイル名を指定できる。wildcardが非nil
なら、fileはワイルドカードを伴うファイル指定として扱われることを意味する。
full-directory-pが非nil
なら、ディレクトリーリストにたいしてディレクトリーの完全なコンテンツ表示を要求することを意味する。fileがディレクトリーでスイッチに‘-d’が含まれないときには、t
を指定すること(ls
へのオプション‘-d’は、ディレクトリーのコンテンツではなくファイルとしてディレクトリーを表示するよう指定する)。
ほとんどのシステムでは、この関数は変数insert-directory-program
の名前のディレクトリーリスト用プログラムを実行することにより機能する。wildcardが非nil
なら、ワイルドカード展開するためにshell-file-name
で指定されるシェルの実行も行う。
MS-DOSとMS-Windowsシステムは標準的なUnixプログラムls
を欠くので、この関数はLispコードでls
をエミュレートする。
技術的な詳細としてはswitchesにロングオプション‘--dired’が含まれる際に、insert-directory
はdiredのためにこれを特別に扱う。しかし他のオプションと同様、通常は等価なショートオプション‘-D’が単にinsert-directory-program
に渡されるだけである。
この変数の値は関数insert-directory
用にディレクトリーリストを生成するプログラムである。この値はLispコードでこのリストを生成するシステムでは無視される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs
Lispのファイル操作関数のほとんどは、ディレクトリーであるようなファイルに使用されたときはエラーとなります。たとえばdelete-file
でディレクトリーの削除はできません。以下のスペシャル関数はディレクトリーの作成と削除を行うために存在します。
このコマンドはdirnameという名前のディレクトリーを作成する。parentsが非nil
の場合(インタラクティブな呼び出しでは常に非nil
)には、その親ディレクトリーがまだ存在しなければ最初にそれを作成することを意味する。
mkdir
はこれにたいするエイリアス。
このコマンドはdirnameという名前のディレクトリーをnewnameにコピーする。newnameが既存のディレクトリーなら、dirnameはそのサブディレクトリーにコピーされるだろう。
これは常にコピーされるファイルのファイルモードを、対応する元のファイルモードと一致させる。
3つ目の引数keep-timeが非nil
なら、それはコピーされるファイルの修正時刻を保持することを意味する。プレフィックス引数を与えると、keep-timeは非nil
になる。
4つ目の引数parentsは、親ディレクトリーが存在しない場合に作成するかどうかを指定する。インタラクティブな場合には、これはデフォルトで発生する。
5つ目の引数copy-contentsが非nil
なら、それはnewnameが既存のディレクトリーならば、そのサブディレクトリーとしてdirnameをコピーするかわりにdirnameのコンテンツをnewnameにコピーする。
このコマンドはdirnameという名前のディレクトリーを削除する。関数delete-file
はディレクトリーであるようなファイルにたいして機能しない。それらにたいしてはdelete-directory
を使用しなければならない。recursiveがnil
でディレクトリー内にファイルが存在する場合には、delete-directory
はエラーをシグナルする。
delete-directory
は親ディレクトリーの階層のシンボリックリンクだけをフォローする。
オプション引数trashが非nil
、かつ変数delete-by-moving-to-trash
が非nil
なら、このコマンドはファイルを削除するかわりにシステムのTrash(ゴミ箱)にファイルを移動する。Miscellaneous File Operations in The GNU Emacs
Manualを参照のこと。インタラクティブに呼び出された際には、プレフィックス引数がなければtrashはt
、それ以外はnil
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
特定のファイル名にたいして特別な処理を実装できます。これはそれらの名前にたいするmagic化と呼ばれます。この機能は主にリモートファイルにたいするアクセスの実装用に使用されます(Remote Files in The GNU Emacs Manualを参照)。
magicファイル名を定義するには、名前クラスを定義するための正規表現とそれにマッチするファイル名用のEmacsファイル操作プリミティブすべてを実装するハンドラーを定義しなければなりません。
変数file-name-handler-alist
は各ハンドラーに適用するときを決定する正規表現とともにハンドラーのリストを保持します。各要素は以下の形式をもちます:
(regexp . handler)
ファイルアクセスとファイル名変換にたいするすべてのEmacsプリミティブは、file-name-handler-alist
にたいして与えられたファイル名をチェックします。そのファイル名がregexpにマッチしたら、そのプリミティブがhandlerを呼び出してファイルを処理します。
handlerの1つ目の引数には、プリミティブの名前をシンボルとして与えます。残りの引数はそのプリミティブに引数として渡されます(これらの引数の1つ目はほとんどの場合はファイル名自身)。たとえば以下を行って:
(file-exists-p filename)
filenameがハンドラーhandlerをもつなら、handlerは以下のように呼び出されます:
(funcall handler 'file-exists-p filename)
関数が2つ以上の引数を受け取る場合には、それらはファイル名でなければならず、関数はそれらのファイル名それぞれにたいしてハンドラーをチェックします。たとえば、
(expand-file-name filename dirname)
以下を行うと、filenameにたいするハンドラーをチェックした後にdirnameにたいするハンドラーをチェックします。どちらの場合でもhandlerは以下のように呼び出されます:
(funcall handler 'expand-file-name filename dirname)
その後にhandlerはfilenameとdirnameのいずれかを処理するか解決する必要があります。
指定されたファイル名が2つ以上のハンドラーにマッチする場合には、ファイル名の中で最後に開始するマッチが優先されます。リモートファイルアクセスのようなジョブにたいするハンドラーに先立って、解凍のようなジョブにたいするハンドラーが最初に処理されるようにこのルールが選択されました。
以下はmagicファイル名ハンドラーが処理する操作です:
access-file
、add-name-to-file
、byte-compiler-base-file-name
,
copy-directory
、copy-file
、delete-directory
、delete-file
、diff-latest-backup-file
、directory-file-name
、directory-files
、directory-files-and-attributes
、dired-compress-file
、dired-uncache
,
expand-file-name
、file-accessible-directory-p
、file-acl
、file-attributes
、file-directory-p
、file-equal-p
、file-executable-p
、file-exists-p
、file-in-directory-p
、file-local-copy
、file-modes
、file-name-all-completions
、file-name-as-directory
、file-name-completion
、file-name-directory
、file-name-nondirectory
、file-name-sans-versions
、file-newer-than-file-p
、file-notify-add-watch
、file-notify-rm-watch
、file-notify-valid-p
、file-ownership-preserved-p
、file-readable-p
、file-regular-p
、file-remote-p
、file-selinux-context
、file-symlink-p
、file-truename
、file-writable-p
、find-backup-file-name
、get-file-buffer
、insert-directory
、insert-file-contents
,
load
、make-auto-save-file-name
、make-directory
、make-directory-internal
、make-symbolic-link
,
process-file
、rename-file
、set-file-acl
、set-file-modes
、set-file-selinux-context
、set-file-times
、set-visited-file-modtime
、shell-command
、start-file-process
、substitute-in-file-name
,
unhandled-file-name-directory
、vc-registered
、verify-visited-file-modtime
、
write-region
.
insert-file-contents
にたいするハンドラーはvisit引数が非nil
なら、通常は(set-buffer-modified-p
nil)
によりそのバッファーの変更フラグをクリアーする必要があります。これにはもしそのバッファーがロックされていたら、ロックを解除する効果もあります。
ハンドラー関数は上記すべての操作を処理しなければならず、他の操作が将来追加される可能性もあります。これらの操作自体すべてを実装する必要はありません — 特定の操作にたいして特別なことを行う必要がないときには、その操作を通常の方法で処理するように、そのプリミティブを再呼び出しできます。認識できない操作にたいしては、常にそのプリミティブを再呼び出しするべきです。以下はこれを行う方法の1つです:
(defun my-file-handler (operation &rest args) ;; 特別に処理する必要がある、 ;; 特別な操作を最初にチェックする (cond ((eq operation 'insert-file-contents) …) ((eq operation 'write-region) …) … ;; 関知しないその他の操作を処理する (t (let ((inhibit-file-name-handlers (cons 'my-file-handler (and (eq inhibit-file-name-operation operation) inhibit-file-name-handlers))) (inhibit-file-name-operation operation)) (apply operation args)))))
ハンドラー関数が通常のEmacsプリミティブを呼び出す決定をした際には、無限再帰を引き起こすような同一ハンドラーからのプリミティブの再呼び出しを防ぐ必要があります。上記の例では変数inhibit-file-name-handlers
とinhibit-file-name-operation
によって、これを行う方法を示しています。上記の例のように、これらを正確に使用するよう注意してください。複数ハンドラーの正しい振る舞いと、それぞれがハンドラーをもつかもしれない2つのファイル名にたいする操作にたいする詳細は非常に重要です。
ファイルへの実アクセスにたいして実際には特別なことを行わないハンドラー(たとえばリモートファイル名にたいしてホスト名の補完を実装するハンドラー等)は、safe-magic
プロパティに非nil
をもつべきです。たとえばEmacsは通常はPATH
内で見い出されるようなディレクトリーがプレフィックス‘/:’によってmagicファイル名に見えるようなら、magicファイル名にならないように保護します。しかしsafe-magic
プロパティに非nil
をもつハンドラーがそれらにたいして使用された場合には、‘/:’は追加されません。
ファイル名ハンドラーは普通とは異なる方法でそれを処理(handle)するのがどの操作(operation)なのかを宣言するために、operations
プロパティをもつことができます。このプロパティが非nil
値をもつなら、それは操作のリストであるべきです。その場合には、それらの操作だけがハンドラーを呼び出すでしょう。これは無駄を省きますが、主な目的はオートロードされるハンドラー関数が実際に処理を行うとき以外はロードされないようにすることです。
通常のプリミティブにたいして単にすべての操作を延期しても機能しません。たとえばファイル名ハンドラーがfile-exists-p
にたいして適用された場合には、通常のload
コードは正しく機能しないでしょうから、ハンドラー自身でload
を処理しなければなりません。しかしハンドラーがfile-exists-p
プロパティを使用してfile-exists-p
を処理しないことを宣言した場合には、普通とは異なる方法でload
を処理する必要はなくなります。
この変数は特定の操作にたいして現在のところ使用を抑制されているハンドラーのリストを保持する。
特定のハンドラーにたいしてその時点で抑制されている操作。
この関数はfileというファイル名にたいするハンドラー関数、それが存在しなければnil
をリターンする。引数operationはそのファイルを処理する操作であること。これはハンドラー呼び出し時に1つ目の引数として渡すことになる値である。operationがinhibit-file-name-operation
と等しいか、そのハンドラーのoperations
内に存在しなければ、この関数はnil
をリターンする。
この関数はファイルfilenameがまだローカルマシン上になければ、それをローカルマシン上の通常の非magicファイルにコピーする。magicファイル名は、それらが他のマシン上のファイルを参照する場合には、file-local-copy
操作を処理するべきである。リモートファイルアクセス以外の目的にたいして使用されるmagicファイル名は、file-local-copy
を処理するべきではない。この場合には関数はそのファイルをローカルファイルとして扱うだろう。
filenameがローカルなら、それがmagicか否かにかかわらずこの関数は何も行わずにnil
をリターンする。それ以外ならローカルコピーファイルのファイル名をリターンする。
この関数はfilenameがリモートファイルかどうかをテストする。filenameがローカル(リモートではない)ならリターン値はnil
、filenameが正にリモートならリターン値はそのリモートシステムを識別する文字列。
この識別子文字列はホスト名とユーザー名、およびリモートシステムへのアクセスに使用されるメソッドを表す文字列も同様に含めることができる。たとえばファイル名/sudo::/some/file
にたいするリモート識別子文字列は/sudo:root@localhost:
。
2つの異なるファイルにたいしてfile-remote-p
が同じ識別子をリターンした場合には、それらが同じファイルシステム上に格納されていて互いに配慮しつつアクセス可能であることを意味する。これはたとえば同時に両方のファイルにアクセスするリモートプロセスを開始することが可能なことを意味する。ファイルハンドラーの実装者はこの方式を保証する必要がある。
identificationは文字列としてリターンされるべき識別子の一部を指定する。identificationにはmethod
、user
、host
のシンボルを指定できる。他の値はすべてnil
のように扱われて、それは完全な識別子文字列をリターンすることを意味する。上記の例ではリモートのuser
識別子文字列はroot
になるだろう。
connectedが非nil
なら、たとえfilenameがリモートであってもEmacsがそのホストにたいする接続をもたなければ、この関数はnil
をリターンする。これは接続が存在しない際の接続の遅延を回避したいときに有用。
この関数は非magicのディレクトリーの名前をリターンする。これは非magicのfilenameには対応するディレクトリー名(ディレクトリーの名前を参照)をリターンする。magicのfilenameには、何の値をリターンするかを決定するためにファイル名ハンドラーを呼び出す。filenameがローカルプロセスからアクセス不能なら、ファイル名ハンドラーはnil
をリターンすることによってそれを示すこと。
これはサブプロセスの実行に有用。すべてのサブプロセスは自身が所属するカレントディレクトリーとして非magicディレクトリーをもたなければならず、この関数はそれを導出するよい手段である。
リモートファイルの属性は、よりよいパフォーマンスのためにキャッシュすることができる。キャッシュがEmacsの制御外で変更されると、そのキャッシュ値は無効になり再読込しなければならない。
この変数がnil
にセットされているとキャッシュ値は決して失効しない。このセッティングはEmacs以外にリモートファイルを変更するものがないことが確実な場合のみ慎重に使用すること。これがt
にセットされているとキャッシュ値は決して使用されない。これはもっとも安全な値であるがパフォーマンスは低下するかもしれない。
折衷的な値としてはこれを正の数字にセットする。これはキャッシュされてからその数字の秒数の間は、ャッシュ値を使用することを意味する。リモートファイルが定期的にチェックされる場合には、この変数を定期的なチェックの間隔より小さい値にletバインドするのは、よい考えかもしれない。たとえば:
(defun display-time-file-nonempty-p (file) (let ((remote-file-name-inhibit-cache (- display-time-interval 5))) (and (file-exists-p file) (< 0 (nth 7 (file-attributes (file-chase-links file)))))))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはバッファー内のデータ(テキスト、テキストプロパティ、あるいはその他の情報)とファイルへの格納に適した表現との間で双方向の変換をするために複数のステップを処理します。このセクションでは、このフォーマット変換(format
conversion)を行う基本的な関数、すなわちファイルをバッファーに読み込むinsert-file-contents
と、バッファーをファイルに書き込むwrite-region
を説明します。
24.12.1 概要 | insert-file-contents とwrite-region
| |
24.12.2 ラウンドトリップ仕様 | format-alist の使用。
| |
24.12.3 漸次仕様 | 非ペアー変換の指定。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
関数insert-file-contents
:
format-alist
のエントリーで定義されているようにフォーマット処理してから
after-insert-file-functions
内の関数を呼び出す。
関数write-region
:
write-region-annotate-functions
内の関数を呼び出して
format-alist
のエントリーで定義されているようにフォーマット処理してから
これはもっとも低レベルでの操作を対照的に示したもので、対象の読み取りと書き込みの処理が逆順で対応しています。このセクションの残りの部分では、上記で名前を挙げた3つの変数を取り巻く2つの機能と、関連するいくつかの関数を説明します。文字のエンコードとデコードについての詳細はコーディングシステムを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
読み取りと書き込みのもっとも一般的な機能は変数format-alist
で制御されます。これはファイルフォーマット(file
format)仕様のリストで、Emacsバッファー内のデータにたいしてファイル内で使用されるテキスト表現を記述します。読み取りと書き込みの仕様記述はペアーになっており、わたしたちがそれを“ラウンドトリップ(round-trip)”仕様と呼ぶのはこれが理由です(非ペアー仕様については漸次仕様を参照)。
このリストには定義されるファイルフォーマットごとに1つのフォーマット定義が含まれる。フォーマット定義はそれぞれ以下の形式のリスト:
(name doc-string regexp from-fn to-fn modify mode-fn preserve)
以下はフォーマット定義内で要素がもつ意味:
フォーマットの名前。
フォーマットのドキュメント文字列。
このフォーマットで表現されるファイルの認識に使用される正規表現。nil
ならフォーマットが自動的に適用されることは決してない。
このフォーマットのデータをデコードする、(ファイルデータを通常のEmacsデータ表現に変換するための)シェルコマンドか関数。
シェルコマンドは文字列として表され、Emacsはそのコマンドを変換処理用のフィルターとして実行する。
from-fnが関数なら、それは変換するべきバッファー部分を指定する2つの引数beginとendで呼び出される。これはインプレースでテキストを編集することにより変換を行うこと。これはテキスト長を変更する可能性があるのでfrom-fnは変更されたend位置をリターンすること。
ファイルの先頭がこの変換によりregexpにマッチしないようにするのはfrom-fnの役目の1つである。そうしないとおそらく再度変換が呼び出される。
このフォーマットのデータをエンコード、すなわち通常のEmacsデータ表現をこのフォーマットに変換するためのシェルコマンドか関数。
to-fnが文字列ならそれはシェルコマンドである。Emacsは変換処理のためのフィルターとしてこのコマンドを実行する。
to-fnが関数なら、それは3つの引数で呼び出される。beginとendは変換されるべきバッファー部分、bufferでそれがどのバッファーかを指定する。変換を行うには2つの方法がある:
(position
.
string)
という形式の要素をもつリストで、positionは書き込まれるテキスト内での相対位置を指定する整数、stringはそこに追加される注釈である。このリストはto-fnがそれをリターンする際には、位置順でソートされていなければならない。
write-region
が実際にバッファーからファイルにテキストを書き込む際には、指定された注釈を対応する位置に混合する。これはすべてバッファーを変更せずに行われる。
フラグ。エンコード関数がバッファーを変更するならt
、注釈リストをリターンすることによって機能するならnil
。
このフォーマットから変換されたファイルをvisit後に呼び出されるマイナーモード関数。この関数は1つの引数で呼び出されて、それが整数1ならマイナーモード関数はそのモードを有効にする。
フラグ。format-write-file
がbuffer-file-format
からこのフォーマットを取り除くべきでなければt
。
関数insert-file-contents
は指定されたファイルを読み込む際にファイルフォーマットを自動的に認識します。これはフォーマット定義の正規表現にたいしてファイルの先頭テキストをチェックして、マッチが見つかったら、そのフォーマットにたいするデコード関数を呼び出します。その後は再度すべての既知のフォーマットをチェックします。適用できるフォーマットがない間はチェックを続行します。
find-file-noselect
やそれを使用するコマンドでファイルをvisitすることにより、同じように変換が行われます(内部でinsert-file-contents
を呼び出すため)。さらにそれをデコードする各フォーマットのモード関数も呼び出します。これはバッファーローカル変数buffer-file-format
内にフォーマット名のリストを格納します。
この変数はvisitしているファイルのフォーマットを表す。より正確にはこれはカレントバッファーのファイルをvisitに起因するデコードのファイルフォーマット名のリストである。これはすべてのバッファーにたいして常にローカル。
write-region
がデータをファイルに書き込む際には、まずbuffer-file-format
にリストされたフォーマットにたいするエンコード関数をリスト内での出現順に呼び出します。
このコマンドはカレントバッファーのコンテンツをフォーマット名のリストformatにもとづいたフォーマットでファイルfileに書き込む。これはformatを起点に、buffer-file-format
の値からpreserveフラグ(上記参照)が非nil
の要素にたいして、それがまだformat内に存在しなければ任意の個数それらを追加する。その後に将来の保存においてデフォルトとなるように、このフォーマットでbuffer-file-format
を更新する。format引数を除けばこのコマンドはwrite-file
と似ている。特にconfirmはwrite-file
での対応する引数と、意味やinteractiveでの扱いが同じである。Definition of write-fileを参照のこと。
このコマンドはファイルfileを探してそれをフォーマットformatにしたがって変換する。これは後でそのバッファーを保存する場合にformatをデフォルトにすることも行う。
引数formatはフォーマット名のリスト。formatがnil
なら何の変換も行われない。interactiveに呼び出した場合には、formatにたいして単にRETをタイプするとnil
が指定される。
このコマンドはファイルfileのコンテンツをフォーマットformatにしたがって変換して挿入する。begとendが非nil
なら、それはinsert-file-contents
と同様、ファイルのどの部分を読み込むかを指定する(ファイルの読み込みを参照)。
リターン値は絶対ファイル名のリスト、および挿入されたデータの長さ(変換後)であり、これはinsert-file-contents
がリターンするものと同様。
引数formatはフォーマット名のリスト。formatがnil
なら何の変換も行われない。interactiveに呼び出した場合には、formatにたいして単にRETをタイプするとnil
が指定される。
この変数は自動保存(auto-saving)にたいして使用するフォーマットを指定する。値はbuffer-file-format
と同様、ファイル名のリストだが、これはauto-saveファイルへの書き込みでbuffer-file-format
のかわりに使用される。値がt
(デフォルト)なら自動保存は当バッファーの通常の保存時と同じフォーマットを使用する。この変数はすべてのバッファーにおいて常にバッファーローカル。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
前のサブセクション(ラウンドトリップ仕様を参照)で説明したラウンドトリップ指定とは対照的に、変数after-insert-file-functions
とwrite-region-annotate-functions
を使用して読み取りと書き込みの変換を個別に制御できます。
変換はある表現を起点として他の表現を生成します。これを行う変換が1つだけのときは、何を起点とするかに関して競合は存在しません。しかし複数の変換呼び出しが存在する場合には、同じデータを起点にする必要がある2つの変換の間に競合が発生するかもしれません。
この状況を理解するには、write-region
中のテキストプロパティの変換コンテキストが最善です。たとえばあるバッファーの位置42の文字が‘X’で、それのテキストプロパティがfoo
だとします。foo
にたいする変換が、たとえばそのバッファーに‘FOO:’を挿入することにより行われる場合には、それは位置42の文字‘X’を‘F’に変更します。そして次の変換は間違ったデータを起点に開始されるでしょう。
競合を避けるためには協調的な変換がバッファーを変更せずに、position昇順でソートされた(position
. string)
という形式の要素をもつリストを注釈(annotations)に指定します。
2つ以上の変換が存在する場合には、write-region
はそれらの注釈を1つのソート済みリストに破壊的にマージします。後でそのバッファーのテキストを実際にファイルに書き込む際に、対応する位置にある指定された注釈を混合します。これはすべてバッファーを変更せずに行われます。
読み取り時にはこれとは対照的にそのテキストの混合された注釈は即座に処理されます。insert-file-contents
は変更される何らかのテキストの先頭にポイントをセットしてから、そのテキストの長さで変換関数を呼び出します。これらの関数は常に挿入されるテキストの先頭のポイントをリターンするべきです。最初の変換により注釈が削除されても、その後の変換が誤って処理することはないので、このアプローチは読み取りに際しては正しく機能します。すべての変換関数は、それが認識する注釈のスキャン、その注釈の削除、バッファーテキストの変更(たとえばテキストプロパティのセット等)、およびそれらの変更に由来する更新されたテキスト長のリターンを行うべきです。1つの関数によりリターンされた値は次の関数への引数になります。
write-region
にたいして呼び出す関数のリスト。リスト内の各関数は書き込まれるリージョンの開始と終了の2つの引数で呼び出される。これらの関数はそのバッファーのコンテンツを変更するべきではない。かわりに注釈をリターンすること。
特別なケースとして、関数がカレントと異なるバッファーをリターンするかもしれない。Emacsはこれを、出力される変更されたテキストをカレントバッファーが含むものとして理解する。つまりEmacsはwrite-region
呼び出しの引数startとendを、新たなバッファーのpoint-min
とpoint-max
に変更して与える。さらに以前のすべての注釈はこの関数により処理されるのでEmacsはそれらの破棄も行う。
この変数の値が非nil
なら、それは関数であること。この関数はwrite-region
完了後に引数なしで呼び出される。
write-region-annotate-functions
内のある関数がカレントと異なるバッファーをリターンした場合には、Emacsはwrite-region-post-annotation-function
を複数回呼び出す。Emacsは最後にカレントだったバッファーでそれを呼び出し、その前にカレントだったバッファーで再度これを呼び出す、...のようにして元のバッファーに戻る。
したがってwrite-region-annotate-functions
内の関数は、バッファーを作成して、kill-buffer
のそのバッファーでのローカル値にこの変数を与え、変更されたテキストでそのバッファーをセットアップして、そのバッファーをカレントにすることができる。そのバッファーは、write-region
完了後にkillされるだろう。
このリスト内の各関数は、挿入されるテキストの先頭にポイントがある状態で、挿入される文字数を1つの引数としてinsert-file-contents
により呼び出される。すべての関数はポイントを未変更のまま、その関数によって変更された挿入後テキストの新たな文字数をリターンすること。
わたしたちは、ユーザーがファイル内にテキストプロパティを格納したりそれらを取得するために、そしてさまざまなデータフォーマットを体験することにより適切なフォーマットを見つけるために、これらのフックを使用してLispプログラムを記述することを推奨します。最終的にはわたしたちがEmacs内にインストールできる、良質で汎用性のある拡張をユーザーが開発することを望みます。
わたしたちはテキストプロパティの名前や値として、任意のLispオブジェクトの処理を試みることは推奨しません — なぜなら汎用的なプログラムはおそらく記述が困難かつ低速だからです。かわりに十分な柔軟性をもちエンコードが難しすぎない、想定されるデータ型のセットを選択してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バックアップファイルとauto-save(自動保存)ファイルは、Emacsのクラッシュやユーザー自身のエラーからユーザーの保護を試みるための2つの手段です。自動保存(auto-saving)はカレントの編集セッションを開始した以降のテキストを保存します。一方バックアップファイルはカレントセッションの前のファイルコンテンツを保存します。
25.1 ファイルのバックアップ | バックアップファイルの作成と名前選択の方法。 | |
25.2 自動保存 | auto-saveファイルの作成と名前選択の方法。 | |
25.3 リバート | revert-buffer とその動作のカスタマイズ方法。
|
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バックアップファイル(backup file)とは編集中ファイルの古いコンテンツのコピーです。Emacsはvisitされているファイルにバッファーを最初に保存するときにバックアップファイルを作成します。したがってバックアップファイルには、通常はカレント編集セッションの前にあったファイルのコンテンツが含まれています。バックアップファイルを一度存在したら、そのコンテンツは変更されずに残ります。
バックアップは通常はvisitされているファイルを新たな名前にリネームすることによって作成されます。オプションでバックアップファイルがvisitされているファイルをコピーすることにより作成されるように指定できます。この選択により、複数の名前をもつファイルの場合に違いが生じます。また編集中のファイルの所有者が元のオーナーのままか、それとも編集ユーザーになるかにも影響し得ます。
デフォルトではEmacsは編集中のファイルごとに単一のバックアップファイルを作成します。かわりに番号付きバックアップ(numbered backup)を要求することもできます。その場合には新たなバックアップファイルそれぞれが新たな名前を得ます。必要なくなったときには古い番号付きバックアップを削除したり、Emacsにそれらを自動的に削除させることもできます。
25.1.1 バックアップファイルの作成 | Emacsがバックアップファイルを作成する方法とタイミング。 | |
25.1.2 リネームかコピーのどちらでバックアップするか? | 2つの選択肢: 古いファイルのリネームとコピー。 | |
25.1.3 番号つきバックアップファイルの作成と削除 | ソースファイルごとに複数のバックアップを保持する。 | |
25.1.4 バックアップファイルの命名 | バックアップファイル名の計算方法とカスタマイズ。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数は、もしそれが適切ならカレントバッファーにvisitされているファイルのバックアップを作成する。これは最初のバッファー保存を行う前にsave-buffer
により呼び出される。
リネームによりバックアップが作成されると、リターン値は(modes extra-alist
backupname)という形式のコンスセルになる。ここでmodesはfile-modes
(アクセシビリティのテストを参照)でリターンされるような元ファイルのモードビット、extra-alistはfile-extended-attributes
(拡張されたファイル属性を参照)によりリターンされるような元ファイルの拡張属性を示すalist、そしてbackupnameはバックアップの名前。
他のすべての場合(コピーによりバックアップが作成された、またはバックアップが作成されなかった)には、この関数はnil
をリターンする。
このバッファーローカル変数は、そのバッファーのファイルがバッファーによりバックアップされたかどうかを明示する。非nil
ならバックアップファイルは書き込み済み、それ以外なら(バックアップが有効なら)次回保存時にファイルはバックアップされる。この変数は永続的にローカルでありkill-all-local-variables
はこれを変更しない。
この変数はバックアップファイルを作成するかどうかを決定する。非nil
なら、Emacsは初回保存時にすべてのファイルのバックアップを作成する
— ただしbackup-inhibited
がnil
の場合(以下参照)。
以下の例はRmailバッファーだけで変数make-backup-files
を変更して、それ以外では変更しない方法を示す。この変数をnil
にセットすると、Emacsはそれらのファイルのバックアップ作成をストップするのでディスク容量の消費を節約するだろう(あなたはこのコードをinitファイルに配置したいと思うかもしれない)。
(add-hook 'rmail-mode-hook (lambda () (setq-local make-backup-files nil)))
この変数の値は、あるファイルがバックアップファイルをもつべきかどうかを決定するために、特定のタイミングで呼び出される関数ある。この関数は判断対象の絶対ファイル名という1つの引数を受け取る。この関数がnil
をリターンすると、そのファイルにたいするバックアップは無効になる。それ以外なら、このセクション内の他の変数がバックアップ作成の是非と方法を指定する。
デフォルト値はnormal-backup-enable-predicate
で、これはtemporary-file-directory
とsmall-temporary-file-directory
内のファイルをチェックする。
この変数が非nil
ならバックアップは抑制される。これはvisitされているファイル名にたいするbackup-enable-predicate
のテスト結果を記録する。さらにvisitされているファイルにたいするバックアップ抑制にもとづいたその他の機構からも使用され得る。たとえばVCはバージョンコントロールシステムに管理されるファイルのバックアップを防ぐために、この変数を非nil
にセットする。
これは永続的にローカルなのでメジャーモード変更により値は失われない。メジャーモードはこの変数ではなく、かわりにmake-backup-files
をセットすること。
この変数の値はファイル名パターンとバックアップディレクトリー名のalist。各要素は以下の形式
(regexp . directory)
この場合には名前がregexpにマッチするファイルのバックアップが、directory内に作成されるだろう。directoryには相対ディレクトリーか絶対ディレクトリーを指定できる。絶対ディレクトリーなら、マッチするすべてのファイルが同じディレクトリー内にバックアップされる。このディレクトリー内でのファイル名はクラッシュを避けるために、バックアップされるファイルの完全名のすべてのディレクトリー区切りが‘!’に変更される。結果の名前を切り詰めるファイルシステムでは、これは正しく機能しないだろう。
すべてのバックアップが単一のディレクトリーで行われる一般的なケースでは、このalistには‘"."’と適切なディレクトリーのペアという単一の要素が含まれるべきである。
この変数がnil
(デフォルト)、またはファイル名のマッチに失敗するとバックアップは元のファイルのディレクトリーに作成される。
長いファイル名がないMS-DOSファイルシステムでは、この変数は常に無視される。
この変数の値はバックアップファイル名を作成する関数。関数make-backup-file-name
はこれを呼び出す。Naming Backup Filesを参照のこと。
特定のファイルにたいして特別なことを行うために、これをバッファーローカルにすることもできる。変更する場合には、backup-file-name-p
とfile-name-sans-versions
を変更する必要もあるかもしれない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsのバックアップファイル作成には2つの方法があります:
デフォルトの方法は1つ目のリネームです。
変数backup-by-copying
が非nil
なら、それは2つ目の方法、つまり元のファイルをコピーして新たなバッファー内容で上書きすることを意味します。変数file-precious-flag
が非nil
の場合にも、(メイン機能の副作用として)この効果があります。バッファーの保存を参照してください。
この変数が非nil
なら、Emacsは常にコピーによりバックアップファイルを作成する。デフォルトはnil
。
以下の3つの変数が非nil
の際は、ある特定のケースに2つ目の方法が使用されます。その特定のケースに該当しないファイルの処理には影響はありません。
この変数が非nil
なら、Emacsは複数名(ハードリンク)をもつファイルにたいしてコピーによりバックアップを作成する。デフォルトはnil
。
backup-by-copying
が非nil
なら常にコピーによりバックアップが作成されるので、この変数はbackup-by-copying
がnil
のときだけ意味がある。
この変数が非nil
(デフォルト)なら、リネームによりファイルの所有者やグループが変更されるケースではEmacsはコピーによりバックアップを作成する。
リネームによりファイルの所有者やグループが変更されなければ、値に効果はない。つまり、そのディレクトリーで新たに作成されるファイルにたいするデフォルトのグループに属するユーザーにより所有されるファイルが該当する。
backup-by-copying
が非nil
なら常にコピーによりバックアップが作成されるので、この変数はbackup-by-copying
がnil
のときだけ意味がある。
この変数が非nil
なら、特定のユーザーID値(具体的には特定の値以下のID数値)にたいしてのみ、backup-by-copying-when-mismatch
と同じように振る舞うことを指定する。変数にはその数値をセットする。
したがってファイル所有者の変更を防ぐ必要がある際には、backup-by-copying-when-privileged-mismatch
を0にセットすればスーパーユーザーだけがコピーによるバックアップを行うことができる。
デフォルトは200。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ファイルの名前がfooなら、番号付きバックアップのバージョン名はfoo.~v~となります。vはfoo.~1~、foo.~2~、foo.~3~、…、foo.~259~のように、さまざまな整数です。
この変数は単一の非番号付きバックアップファイルを作成するか、それとも複数の番号付きバックアップを作成するかを制御する。
nil
visitされたファイルが番号付きバックアップなら番号付きバックアップを作成して、それ以外は作成しない。これがデフォルト。
never
番号付きバックアップを作成しない。
番号付きバックアップを作成する。
番号付きバックアップを使用することにより、バックアップのバージョン番号は最終的には非常に大きな番号になるので、それらを削除しなければなりません。Emacsはこれを自動で行うことができ、ユーザーに削除するか確認することもできます。
この変数の値は新たな番号付きバックアップが作成された際に保持するべき、もっとも新しいバージョンの個数。新たに作成されたバックアップもカウントされる。デフォルトは2。
この変数の値は新たな番号付きバックアップが作成された際に保持するべき、もっとも古いバージョンの個数。デフォルトは2。
番号が1、2、3、5、7のバックアップがあり、かつこれらの変数が値2をもつ場合には、番号が1と2のバックアップは古いバージョンとして保持されて、番号が5と7のバックアップは新しいバージョンとして保持される。そして番号が3のバックアップは余分なバックアップとなる。関数find-backup-file-name
(バックアップファイルの命名を参照)は、どのバージョンのバックアップを削除するかを決定する役目を負うが、この関数自身がバックアップを削除する訳ではない。
この変数がt
なら、ファイルの保存により余分なバージョンのバックアップは暗黙に削除される。nil
なら余分なバックアップの削除前に確認を求めるて、それ以外なら余分なバックアップは削除されないことを意味する。
この変数はDired内のコマンド.
(ピリオド。dired-clean-directory
)で、もっとも新しいバージョンのバックアップをいくつ保持するかを指定する。これは新たにバックアップファイルを作成する際にkept-new-versions
を指定するのと同等。デフォルトは2。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは、主にバックアップファイルの命名規則を再定義してカスタマイズできる関数を記載します。これらの1つを変更した場合には、おそらく残りも変更する必要があります。
この関数はfilenameがバックアップファイルとして利用可能なら非nil
値をリターンする。これは名前のチェックだけを行って、filenameという名前のファイルが存在するかどうかはチェックしない。
(backup-file-name-p "foo") ⇒ nil
(backup-file-name-p "foo~") ⇒ 3
この関数の標準的な定義は、以下のようになる:
(defun backup-file-name-p (file) "FILEがバックアップファイルなら\ (番号付きか否かに関わらず)非nilをリターンする" (string-match "~\\'" file))
このようにファイル名が‘~’で終われば、この関数は非nil
値をリターンする(ドキュメント文字列を分割するために1行目でバックスラッシュを使用しているが、これはドキュメント文字列内で単一行を生成する)。
この単純な式はカスタマイズのための再定義を簡便にするために、個々の関数内に配置されている。
この関数はファイルfilenameの非番号付きバックアップファイル名として使用される文字列をリターンする。Unixではこれは単にfilenameにチルダを追加する。
ほとんどのオペレーティングシステムでは、この関数の標準的な定義は以下のようになる:
(defun make-backup-file-name (file) "FILEにたいして非番号付きバックアップファイル名を作成する" (concat file "~"))
この関数を再定義することにより、バックアップファイルの命名規則を変更できる。以下はチルダの追加に加えて、先頭に‘.’を追加するようにmake-backup-file-name
を再定義する例:
(defun make-backup-file-name (filename) (expand-file-name (concat "." (file-name-nondirectory filename) "~") (file-name-directory filename)))
(make-backup-file-name "backups.texi") ⇒ ".backups.texi~"
Diredコマンドのいくつかを含むEmacsの一部では、バックアップファイル名が‘~’で終わることを仮定している。この規則にしたがわない場合、深刻な問題とはならないだろうが、それらのコマンドが若干好ましくない結果をもたらすかもしれない。
この関数はfilenameの新たなバックアップファイル用のファイル名を計算する。これは特定の既存バックアップファイルにたいする削除の提案も行うかもしれない。find-backup-file-name
はCARが新たなバックアップファイル名、CDRが削除を提案するバックアップファイルのリストであるようなリストをリターンする。値にはnil
も指定でき、これはバックアップが作成されないことを意味する。
kept-old-versions
とkept-new-versions
の2つの変数は、どのバージョンのバックアップを保持するべきかを決定する。この関数は値のCDRから該当するバージョンを除外することによってそれらを保持する。番号つきバックアップファイルの作成と削除を参照のこと。
以下の例の値は新しいバックアップファイルに使用する名前が~rms/foo.~5~、~rms/foo.~3~は呼び出し側が削除を検討するべき余分なバージョンであることを示している。
(find-backup-file-name "~rms/foo") ⇒ ("~rms/foo.~5~" "~rms/foo.~3~")
この関数はfilenameにたいするもっとも最近のバックアップファイル名、バックアップファイルがなければnil
をリターンする。
ファイル比較関数のいくつかは、自動的にもっとも最近のバックアップを比較できるようにこの関数を使用している。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsは、visitしているすべてのファイルを定期的に保存します。これは自動保存(auto-saving)と呼ばれます。自動保存はシステムがクラッシュした場合に失われる作業量を、一定の作業量以下にします。デフォルトでは自動保存は300キーストロークごと、またはidleになった30秒後に発生します。自動保存に関するユーザー向けの情報についてはAuto-Saving: Protection Against Disasters in The GNU Emacs Manualを参照してください。ここでは自動保存の実装に使用される関数と、それらを制御する変数について説明します。
このバッファーローカル変数はカレントバッファーの自動保存に使用されるファイル名。そのバッファーが自動保存されるべきでなければnil
。
buffer-auto-save-file-name ⇒ "/xcssun/users/rms/lewis/#backups.texi#"
これはバッファーローカルなマイナーモードであるAuto Saveモードにたいするモードコマンド。Auto Saveモードが有効なときはそのバッファーで自動保存が有効。呼び出し方法は他のマイナーモードと同様(マイナーモード記述の規約を参照)。
ほとんどのマイナーモードと異なりauto-save-mode
変数は存在しない。buffer-auto-save-file-name
が非nil
でbuffer-saved-size
(以下参照)が非0ならAuto
Saveモードが有効。
この関数はfilenameがauto-saveファイルのような文字列なら非nil
をリターンする。先頭と末尾がハッシュマーク(‘#’)であるような名前はauto-saveファイルの可能性があるという、auto-saveファイルにたいする通常の命名規則を想定する。引数filenameはディレクトリーパートを含まないこと。
(make-auto-save-file-name) ⇒ "/xcssun/users/rms/lewis/#backups.texi#"
(auto-save-file-name-p "#backups.texi#") ⇒ 0
(auto-save-file-name-p "backups.texi") ⇒ nil
この関数の標準的な定義は、以下のようになる:
(defun auto-save-file-name-p (filename) "FILENAMEが以下を満たすなら非nilをリターンする" (string-match "^#.*#$" filename))
この関数はauto-saveファイルの命名規則規則を変更したいときにカスタマイズできるようにするために存在する。これを再定義するなら、それに対応して関数make-auto-save-file-name
も忘れずに再定義すること。
この関数はカレントバッファーの自動保存に使用されるファイル名をリターンする。これはファイル名の先頭と末尾にハッシュマーク(‘#’)を単に追加する。この関数は変数auto-save-visited-file-name
(以下参照)を調べない。呼び出し側はまずその変数をチェックすること。
(make-auto-save-file-name) ⇒ "/xcssun/users/rms/lewis/#backups.texi#"
以下はこの関数の標準的な定義の簡略版:
(defun make-auto-save-file-name () "カレントバッファーの自動保存に使用される\ ファイル名をリターンする" (if buffer-file-name
(concat (file-name-directory buffer-file-name) "#" (file-name-nondirectory buffer-file-name) "#") (expand-file-name (concat "#%" (buffer-name) "#"))))
auto-saveファイルの命名規則をカスタマイズして再定義できるように、これは独立した関数として存在している。ただしこれに対応した方法でauto-save-file-name-p
も忘れずに変更すること。
この変数が非nil
ならEmacsはvisit中のファイルにバッファーを自動保存する。つまり自動保存は編集中ファイルと同じファイルにたいして行われる。この変数は通常はnil
なので、auto-saveファイルはmake-auto-save-file-name
で作成された別の名前をもつ。
この変数の値を変更した際、バッファー内でauto-saveモードを再度有効にするまで、既存バッファーにたいして新たな値は効果をもたない。すでにauto-saveモードが有効なら、再度auto-save-mode
が呼び出されるまで同じファイルに自動保存が行われる。
この関数はカレントバッファーが最後に読み込み、または保存されて以降に自動保存されていればt
をリターンする。
この関数はカレントバッファーを自動保存済みとマークする。そのバッファーは、バッファーテキストが再度変更されるまで自動保存されないだろう。この関数はnil
をリターンする。
この変数の値は自動保存の頻度を入力イベント数で指定する。この分の入力イベント読み取りごとに、Emacsは自動保存が有効なすべてのバッファーにたいして自動保存を行う。これを0にするとタイプした文字数にもとづいた自動保存は無効になる。
この変数の値は自動保存が発生すべきidle時間の秒数。この秒数分ユーザーが休止するたびに、Emacsは自動保存が有効なすべてのバッファーにたいして自動保存を行う(カレントバッファーが非常に大きければ、指定されたタイムアウトはサイズ増加とともに増加される因子で乗ぜられる。この因子は1MBのバッファーにたいしておよそ4)。
値が0かnil
ならidle時間にもとづいた自動保存は行われず、auto-save-interval
で指定される入力イベント数の後のみ自動保存が行われる。
このノーマルフックは自動保存が行われようとするたびに毎回実行される。
この変数が非nil
ならファイルをvisitするバッファーの自動保存がデフォルトで有効になり、それ以外では有効にならない。
この関数は自動保存される必要があるすべてのバッファーを自動保存する。これは自動保存が有効なバッファーであり、かつ前回の自動保存以降に変更されたすべてのバッファーを保存する。
いずれかのバッファーが自動保存される場合には、do-auto-save
は自動保存が行われる間、通常はそれを示すメッセージ‘Auto-saving...’をエコーエリアに表示する。しかしno-messageが非nil
ならこのメッセージは抑制される。
current-onlyが非nil
なら、カレントバッファーだけが自動保存される。
この関数はdelete-auto-save-files
が非nil
ならカレントバッファーのauto-saveファイルを削除する。これはバッファー保存時に毎回呼び出される。
この関数はforceがnil
なら最後に本当の保存が行われて以降、カレントEmacsセッションにより書き込まれたファイルだけを削除する。
この変数は関数delete-auto-save-file-if-necessary
により使用される。これが非nil
なら、Emacsは(visitされているファイルに)本当に保存が行われたときにauto-saveファイルを削除する。これはディスク容量を節約してディレクトリーを整理する。
この関数はvisitされているファイルの名前が変更されていればカレントバッファーのauto-saveファイルの名前を調整する。これはカレントEmacsセッションでauto-saveファイルが作成されていれば、既存のauto-saveファイルのリネームも行う。visitされているファイルの名前が変更されていなければ、この関数は何も行わない。
このバッファーローカル変数の値はカレントバッファーが最後に読み取り、保存、または自動保存されたときのバッファーの長さ。これはサイズの大幅な減少の検知に使用され、それに応じて自動保存がオフに切り替えられる。
-1なら、それはサイズの大幅な減少によりそのバッファーの自動保存が一時的に停止されていることを意味する。明示的な保存によりこの変数に正の値が格納されて、自動保存が再び有効になる。自動保存をオフやオンに切り替えることによってもこの変数は更新されるので、サイズの大幅な減少は忘れられさられる。
-2なら、特にバッファーサイズの変更により一時的に自動保存を停止されないように、そのバッファーがバッファーサイズの変更を無視することを意味する。。
この変数は、(非nil
なら)すべてのauto-saveファイルの名前を記録するファイルを指定する。Emacsが自動保存を行うたびには自動保存が有効な各バッファーごとに2行ずつ書き込みを行う。1行目はvisitされているファイルの名前(ファイルをvisitしないバッファーの場合は空)、2行目はauto-saveファイルの名前を示す。
Emacsを正常にexitした際にこのファイルは削除される。Emacsがクラッシュした場合にはこのファイルを調べることにより、失われるはずだった作業を含んだすべてのauto-saveファイルを探すことができる。recover-session
コマンドはそれらを見つけるためにこのファイルを使用する。
このファイルにたいするデフォルト名は、ユーザーのホームディレクトリーにある‘.saves-’で始まるファイルを指定する。この名前にはEmacsのプロセスIDとホスト名も含まれる。
initファイルを読み込んだ後、(nil
にセット済みでなければ)Emacsはこのプレフィックスにもとづいたホスト名とプロセスIDを追加して、auto-save-list-file-name
を初期化する。initファイル内でこれをnil
にセットした場合には、Emacsはauto-save-list-file-name
を初期化しない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
あるファイルにたいして大きな変更を行った後、気が変わって元に戻したくなった場合は、revert-buffer
コマンドでそのファイルの以前のバージョンを読み込むことにより、それらの変更を取り消すことができます。詳細は、Reverting a Buffer in The GNU Emacs Manualを参照してください。
このコマンドはバッファーのテキストをディスク上のvisitされているファイルのテキストで置き換える。これによりファイルがvisitや保存された以降に行ったすべての変更はアンドゥ(undo: 取り消し)される。
デフォルトでは、最新のauto-saveファイルのほうがvisitされているファイルより新しく引数ignore-autoがnil
なら、revert-buffer
はユーザーにたいしてかわりにauto-saveファイルを使用するかどうか確認を求める。このコマンドをinteractiveに呼び出したときプレフィックス数引数が指定されていなければ、ignore-autoはt
となる。つまりinteractive呼び出しは、デフォルトではauto-saveファイルのチェックを行わない。
revert-buffer
は通常はバッファーを変更する前に確認を求める。しかし引数noconfirmが非nil
ならrevert-buffer
は確認を求めない。
このコマンドは通常はnormal-mode
を使用することにより、そのバッファーのメジャーモードとマイナーモードを再初期化する。しかしpreserve-modesが非nil
ならモードは変更されずに残る。
リバート(revert:
戻す、復元する)はinsert-file-contents
の置き換え機能を使用することにより、バッファー内のマーカー位置の保持を試みる。バッファーのコンテンツとファイルのコンテンツがリバート操作を行う前と等しければリバートはすべてのマーカーを保持する。等しくなければリバートによってバッファーは変更される。この場合は、(もしあれば)バッファーの最初と最後にある未変更のテキスト内にあるマーカーは保持される。他のマーカーを保持してもそれらは正しくないだろう。
revert-buffer
は処理を行っている間、この変数を非nil
値にバインドする。
このセクションの残りの部分で説明する変数をセットすることにより、revert-buffer
が処理方法をカスタマイズできます。
この変数は問い合わせなしでリバートされるファイルのリストを保持する。値は正規表現のリスト。visitされているファイルの名前がこれらの正規表現のいずれかにマッチし、かつバッファーが未変更だがディスク上のファイルは変更されていれば、revert-buffer
はユーザーに確認を求めることなくファイルをリバートする。
いくつかのメジャーモードは以下の変数をローカルにバインドすることによりrevert-buffer
をカスタマイズします:
この変数の値はそのバッファーをリバートするために使用する関数。これはリバート処理を行うために2つのオプション引数をとる関数であること。2つのオプション引数ignore-autoとnoconfirmはrevert-buffer
が受け取る引数である。
Diredモードのような編集されるテキストにファイルのコンテンツが含まれず他の方式によって再生成され得るモードは、この変数のバッファーローカル値にコンテンツを再生成する特別な関数を与えることができる。
この変数の値はそのバッファーをリバートする際に更新されたコンテンツの挿入に使用される関数を指定する。その関数は2つの引数を受け取る。1つ目は使用するファイル名で2つ目がt
なら、ユーザーはauto-saveファイルの読み込みにたいして確認を求められる。
revert-buffer-function
のかわりにこの変数をモードが変更する理由は、revert-buffer
が行残りの処理(ユーザーへの確認、アンドゥリストのクリアー、適切なメジャーモードの決定、以下のフックの実行)にたいする重複や置き換えを避けるためである。
このノーマルフックは変更されたコンテンツを挿入する前に、デフォルトのrevert-buffer-function
により実行される。カスタマイズしたrevert-buffer-function
は、このフックを実行するかどうか判らない。
このノーマルフックは変更されたコンテンツを挿入した後に、デフォルトのrevert-buffer-function
によって実行される。カスタマイズしたrevert-buffer-function
は、このフックを実行するかどうか判らない。
この変数の値は、バッファーがリバートを要するかどうかをチェックするために呼び出される関数を指定する。デフォルト値では、修正時刻をチェックすることによってファイルをvisitするバッファーだけを処理する。ファイルをvisitしないバッファーにはカスタム関数が必要 ((emacs)Supporting additional buffersを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファー(buffer)とは編集されるテキストを含んだLispオブジェクトのことです。バッファーはvisitされるファイルのコンテンツを保持するために使用されます。しかしファイルをvisitしないバッファーも存在します。一度に複数のバッファーが存在するかもしれませんが、カレントバッファー(current buffer)に指定できるのは常に1つのバッファーだけです。ほとんどの編集コマンドはカレントバッファーのコンテンツにたいして作用します。カレントバッファーを含むすべてのバッファーは任意のウィンドウ内に表示されるときもあれば、表示されない場合もあります。
26.1 バッファーの基礎 | バッファーとは? | |
26.2 カレントバッファー | バッファーをカレントに指定することにより、プリミティブはバッファーのコンテンツにアクセスする。 | |
26.3 バッファーの名前 | バッファー名にたいするアクセスと変更。 | |
26.4 バッファーのファイル名 | バッファーファイル名は、どのファイルをvisitしているかを示す。 | |
26.5 バッファーの変更 | 保存が必要ならバッファーは変更されている(modified)。 | |
26.6 バッファーの変更 Time | Emacsの背後でvisitされているファイルが変更されたかどうかを判断する。 | |
26.7 読み取り専用のバッファー | 読み取り専用バッファーでのテキスト変更は許されない。 | |
26.8 バッファーリスト | すべての既存バッファーを閲覧する方法。 | |
26.9 バッファーの作成 | バッファーを作成する関数。 | |
26.10 バッファーのkill | 明示的にkillされるまで、バッファーは存在する。 | |
26.11 インダイレクトバッファー | インダイレクトバッファーは他のバッファーとテキストを共有する。 | |
26.12 2つのバッファー間でのテキストの交換 | ||
26.13 バッファーのギャップ | バッファー内のギャップ。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファー(buffer)とは編集されるテキストを含むLispオブジェクトのことです。バッファーはvisitされるファイルのコンテンツを保持するために使用されます。しかしファイルをvisitしないバッファーも存在します。一度に複数のバッファーが存在するかもしれませんが、カレントバッファー(current buffer)に指定できるのは常に1つのバッファーだけです。ほとんどの編集コマンドはカレントバッファーのコンテンツにたいして作用します。カレントバッファーを含むすべてのバッファーは、いずれかのウィンドウ内に表示されるときもあるし、表示されない場合もあります。
Emacs編集におけるバッファーとは個別に名前をもち、編集可能なテキストを保持するオブジェクトです。Lispプログラムにおけるバッファーはスペシャルデータ型として表されます。バッファーのコンテンツを拡張可能な文字列と考えることができます。挿入と削除はバッファー内の任意の箇所で発生し得ます。テキストを参照してください。
Lispのバッファーオブジェクトは多くの情報要素を含んでいます。これらの情報のいくつかは変数を通じてプログラマーが直接アクセスできるのにたいして、その他の情報は特殊な目的のための関数を通じてのみアクセスすることができます。たとえばvisitされているファイルの名前は変数を通じて直接アクセスできますが、ポイント値はプリミティブ関数からのみアクセスできます。
直接アクセス可能なバッファー固有の情報は、バッファーローカル(buffer-local)な変数バインディング内に格納されます。これは特定のバッファー内だけで効力のある変数値のことです。この機能により、それぞれのバッファーは特定の変数の値をオーバーライドすることができます。ほとんどのメジャーモードはこの方法でfill-column
やcomment-column
のような変数をオーバーライドしています。バッファーローカルな変数、およびそれらに関連する関数についての詳細はバッファーローカル変数を参照してください。
バッファーからファイルをvisitする関数および変数についてはファイルのvisitとバッファーの保存を参照してください。ウィンドウ内へのバッファー表示に関連する関数および変数についてはバッファーとウィンドウを参照してください。
この関数はobjectがバッファーならt
、それ以外はnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
一般的に1つのEmacsセッション内には多くのバッファーが存在します。常にそれらのうちの1つがカレントバッファー(current buffer)に指定されます。カレントバッファーとは、ほとんどの編集が行われるバッファーのことです。テキストを調べたり変更するプリミティブのほとんどは暗黙にカレントバッファーにたいして処理を行います(テキストを参照)。
通常は選択されたウィンドウ内に表示されるバッファーがカレントバッファーですが、常にそうではありません。Lispプログラムはバッファーのコンテンツを処理するために、スクリーン上に表示されているものを変更することなく任意のバッファーを一時的にカレントに指定できます。カレントバッファーの指定にたいするもっとも基本的な関数はset-buffer
です。
この関数はカレントバッファーをリターンする。
(current-buffer) ⇒ #<buffer buffers.texi>
この関数はbuffer-or-nameをカレントバッファーにする。buffer-or-nameは既存のバッファー、または既存のバッファーの名前でなければならない。リターン値はカレントになったバッファー。
この関数はそのバッファーをどのウィンドウにも表示しないので、必然的にユーザーはそのバッファーを見ることはできない。しかしLispプログラムはその後に、そのバッファーにたいして処理を行うことになるだろう。
編集コマンドがエディターコマンドループにリターンする際、Emacsは選択されたウィンドウ内に表示されているバッファーにたいして、自動的にset-buffer
を呼び出します。これは混乱を防ぐためであり、これによりEmacsがコマンドを読み取るときにカーソルのあるバッファーが、コマンドを適用されるバッファーになることが保証されます(コマンドループを参照)。したがって異なるバッファーを指示して切り替える場合にはset-buffer
を使用するべきではありません。これを行うためにはウィンドウ内のバッファーへの切り替えで説明されている関数を使用してください。
Lisp関数を記述する際は、処理後にカレントバッファーをリストアするためにコマンドループのこの振る舞いに依存しないでください。編集コマンドはコマンドループだけではなく、他のプログラムからLisp関数としても呼び出されます。呼び出し側にとっては、そのサブルーチンがカレントだったバッファーを変更しないほうが便利です(もちろんそれがサブルーチンの目的でない場合)。
他のバッファーにたいして一時的に処理を行うには、save-current-buffer
フォーム内にset-buffer
を配置します。以下の例はコマンドappend-to-buffer
の簡略版です:
(defun append-to-buffer (buffer start end) "リージョンのテキストをBUFFERに追加する" (interactive "BAppend to buffer: \nr") (let ((oldbuf (current-buffer))) (save-current-buffer (set-buffer (get-buffer-create buffer)) (insert-buffer-substring oldbuf start end))))
ここではカレントバッファーを記録するためにローカル変数にバインドしてから、後でsave-current-buffer
がそれを再びカレントにするようにアレンジしています。次にset-buffer
が指定されたバッファーをカレントにして、insert-buffer-substring
が元のバッファーの文字列を指定された(今はカレントの)バッファーにコピーします。
かわりにwith-current-buffer
マクロを使用することもできます:
(defun append-to-buffer (buffer start end) "BUFFERにリージョンのテキストを追加する" (interactive "BAppend to buffer: \nr") (let ((oldbuf (current-buffer))) (with-current-buffer (get-buffer-create buffer) (insert-buffer-substring oldbuf start end))))
いずれのケースでも、追加されるバッファーが偶然他のウィンドウに表示されていると、次回の再表示でそのテキストがどのように変更されたか表示されるでしょう。どのウィンドウにも表示されていなければスクリーン上で即座に変更を目にすることはありません。コマンドはバッファーを一時的にカレントにしますが、そのことがバッファーの表示を誘発する訳ではありません。
バッファーローカルなバインディングをもつ変数にたいして、(let
や関数引数などで)ローカルバインディングを作成する場合には、そのローカルバインディングのスコープの最初と最後で同じバッファーがカレントとなることを確認してください。そうしないと、あるバッファーではバインドして他のバッファーではバインドされないことになるかもしれません!
set-buffer
の使用において、カレントバッファーが戻ることに依存しないでください。なぜなら間違ったバッファーがカレントのときにquitが発生した場合には、その処理は行われないでしょう。たとえば上記の例に倣うと以下は間違ったやり方です:
(let ((oldbuf (current-buffer))) (set-buffer (get-buffer-create buffer)) (insert-buffer-substring oldbuf start end) (set-buffer oldbuf))
例で示したようにsave-current-buffer
やwith-current-buffer
を使用すれば、quitやthrow
を通常の評価と同様に処理できます。
スペシャルフォームsave-current-buffer
はカレントバッファーの識別を保存してbodyフォームを評価し、最後にそのバッファーをカレントにリストアする。リターン値はbody内の最後のフォームの値。throw
やエラーを通じた異常exitの場合にもカレントバッファーはリストアされる(非ローカル脱出を参照)。
カレントとして使用されていたバッファーがsave-current-buffer
によるexit時にkillされていたら、当然それが再びカレントとなることはない。かわりにexit直前にカレントバッファーが何であれ、それがカレントになる。
with-current-buffer
マクロはカレントバッファーの識別を保存してbuffer-or-nameをカレントにし、bodyフォームを評価してから最後にカレントバッファーをリストアする。buffer-or-nameには既存のバッファー、または既存のバッファー名を指定しなければならない。
リターン値はbody内の最後のフォームの値。throw
やエラーを通じた異常exitの場合にも、カレントバッファーはリストアされる(非ローカル脱出を参照)。
with-temp-buffer
マクロは一時的なバッファーをカレントバッファーとしてbodyフォームを評価する。これはカレントバッファーの識別を保存して一時的なバッファーを作成、それをカレントとしてbodyフォームを評価して、一時バッファーをkillする間に以前のカレントバッファーをリストアする。デフォルトではこのマクロにより作成されたバッファー内のアンドゥ情報(アンドゥを参照)は記録されない(が必要ならbodyでそれを有効にできる)。
リターン値はbody内の最後のフォームの値。最後のフォームとして(buffer-string)
を使用することにより、一時バッファーのコンテンツをリターンできる。
throw
やエラーを通じた異常exitの場合にも、カレントバッファーはリストアされる(非ローカル脱出を参照)。
Writing to
Filesのwith-temp-file
も参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
それぞれのバッファーは文字列で表される一意な名前をもちます。バッファーにたいして機能する関数の多くは、引数としてバッファーとバッファー名の両方を受け入れます。buffer-or-nameという名前の引数がこのタイプであり、それが文字列でもバッファーでもなければエラーがシグナルされます。bufferという名前の引数は名前ではなく実際のバッファーオブジェクトでなければなりません。
短命でユーザーが関心をもたないようなバッファーは名前がスペースで始まり、それらについてはlist-buffers
とbuffer-menu
コマンドは無視します(がファイルをvisitしているようなバッファーは無視されない)。スペースで始まる名前は初期状態ではアンドゥ情報の記録も無効になっています。アンドゥを参照してください。
この関数はbufferの名前を文字列としてリターンする。bufferのデフォルトはカレントバッファー。
buffer-name
がnil
をリターンした場合、それはbufferがkillされていることを意味する。バッファーのkillを参照のこと。
(buffer-name) ⇒ "buffers.texi"
(setq foo (get-buffer "temp")) ⇒ #<buffer temp>
(kill-buffer foo) ⇒ nil
(buffer-name foo) ⇒ nil
foo ⇒ #<killed buffer>
この関数はカレントバッファーをnewnameにリネームする。newnameが文字列でなければエラーをシグナルする。
newnameがすでに使用済みなら、rename-buffer
は通常はエラーをシグナルする。しかしuniqueが非nil
なら、未使用の名前となるようにnewnameを変更する。interactiveに呼び出した場合は、プレフィックス数引数によりuniqueに非nil
を指定できる(この方法によってコマンドrename-uniquely
は実装される)。
この関数は実際にバッファーに与えられた名前をリターンする。
この関数はbuffer-or-nameで指定されたバッファーをリターンする。buffer-or-nameが文字列で、かつそのような名前のバッファーが存在しなければ値はnil
。buffer-or-nameがバッファーなら与えられたバッファーをリターンする。これは有用とは言い難く、引数は通常は名前である。たとえば:
(setq b (get-buffer "lewis")) ⇒ #<buffer lewis>
(get-buffer b) ⇒ #<buffer lewis>
(get-buffer "Frazzle-nots") ⇒ nil
バッファーの作成の関数get-buffer-create
も参照のこと。
この関数は新たなバッファーにたいして一意となるような名前をリターンする — がバッファーは作成しない。この名前はstarting-nameで始まり内部が数字であるような‘<…>’を追加することにより、すべてのバッファーでカレントで使用されていない名前を生成する。この数字は2で始まり、既存バッファーの名前でないような名前になる数字まで増加される。
オプション引数ignoreが非nil
なら、それは潜在的にバッファー名であるような文字列であること。これは、たとえそれが(通常は拒絶されるであろう)既存バッファーの名前であっても、試みられた場合には潜在的に受容可能なバッファーとして考慮することを意味する。つまり‘foo’、‘foo<2>’、‘foo<3>’、‘foo<4>’という名前のバッファーが存在する場合には、
(generate-new-buffer-name "foo") ⇒ "foo<5>" (generate-new-buffer-name "foo" "foo<3>") ⇒ "foo<3>" (generate-new-buffer-name "foo" "foo<6>") ⇒ "foo<5>"
バッファーの作成の関連する関数generate-new-buffer
も参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファーファイル名(buffer file
name)とは、そのバッファーにvisitされているファイルの名前です。バッファーがファイルをvisitしていなければ、バッファーファイル名はnil
です。バッファー名は大抵はバッファーファイル名の非ディレクトリーパートと同じですが、バッファーファイル名とバッファー名は別物であり個別にセットすることができます。ファイルのvisitを参照してください。
この関数はbufferがvisitしているファイルの絶対ファイル名をリターンする。bufferがファイルをvisitしていなければ、buffer-file-name
はnil
をリターンする。bufferが与えられない場合のデフォルトはカレントバッファー。
(buffer-file-name (other-buffer)) ⇒ "/usr/user/lewis/manual/files.texi"
このバッファーローカル変数はカレントバッファーにvisitされているファイルの名前、ファイルをvisitしていなければnil
。これは永続的なローカル変数でありkill-all-local-variables
の影響を受けない。
buffer-file-name ⇒ "/usr/user/lewis/manual/buffers.texi"
他のさまざまな事項を変更せずにこの変数を変更するのは危険である。通常はset-visited-file-name
を使用するほうがよい(以下参照)。バッファー名の変更などのような、そこで行われることのいくつかは絶対必要という訳ではないが、その他の事項はEmacsが混乱するのを防ぐために必要不可欠である。
このバッファーローカル変数はカレントバッファーにvisitされているファイルの省略された形式の実名(truename)、ファイルをvisitしていなければnil
を保持する。これは永続的にローカルでありkill-all-local-variables
の影響を受けない。See section 本当の名前とabbreviate-file-nameを参照のこと。
このバッファーローカル変数はカレントバッファーにvisitされているファイルのファイル番号(file number)とデバイス番号(device
number)、ファイルをvisitしていなければnil
を保持する。これは永続的にローカルでありkill-all-local-variables
の影響を受けない。
値は通常は(filenum
devnum)
のような形式のリスト。この番号ペアはシステム上でアクセス可能なすべてのファイルの中からファイルを一意に識別する。より詳細な情報はファイルの属性のfile-attributes
を参照のこと。
buffer-file-name
がシンボリックリンク名なら、いずれの番号も再帰的なターゲットを参照する。
この関数はファイルfilenameをvisitしているバッファーをリターンする。そのようなバッファーが存在しなければnil
をリターンする。引数filenameは文字列でなければならず、展開(ファイル名を展開する関数を参照)された後に、killされていないすべてのバッファーがvisitしているファイル名と比較される。バッファーのbuffer-file-name
はfilenameの展開形と正確にマッチしなければならないことに注意。この関数は同じファイルにたいする他の名前は認識しないだろう。
(get-file-buffer "buffers.texi") ⇒ #<buffer buffers.texi>
特殊な状況下では、複数のバッファーが同じファイル名をvisitすることがあり得る。そのような場合には、この関数はバッファーリスト内の最初に該当するバッファーをリターンする。
これはget-file-buffer
と似ているが、そのファイルを違う名前でvisitしているかもしれないすべてのバッファーをリターンする。つまりバッファーのbuffer-file-name
はfilenameの展開形式と正確にマッチする必要はなく、同じファイルを参照することだけが要求される。predicateが非nil
なら、それはfilenameをvisitしているバッファーを1つの引数とする関数であること。そのバッファーにたいしてpredicateが非nil
をリターンした場合のみ適切なリターン値と判断される。リターンすべき適切なバッファーが見つからなければ、find-buffer-visiting
はnil
をリターンする。
filenameが非空文字列なら、この関数はカレントバッファーにvisitされているファイルの名前をfilenameに変更する(バッファーがファイルをvisitしていなければvisitするファイルとしてfilenameを与える)。そのバッファーにたいする次回の保存では、新たに指定されたファイルに保存されるだろう。
このコマンドは、たとえそのバッファーのコンテンツがその前にvisitされていたファイルとマッチしていても、(Emacsが関知するかぎり) filenameのコンテンツとはマッチしないのでバッファーが変更されている(modified)とマークする。これはその名前がすでに使用されていなければ、新たなファイル名に対応してバッファーをリネームする。
filenameがnil
か空文字列なら、それは“visitされているファイルがない”ことを意味する。この場合にはset-visited-file-name
はバッファーの変更フラグを変更することなく、そのバッファーがファイルをvisitしていないとマークする。
この関数はfilenameをvisitしているバッファーがすでに存在する場合は、通常はユーザーに確認を求める。しかしno-queryが非nil
ならこの質問を行わない。filenameをvisitしているバッファーがすでに存在し、かつユーザーが承認するかno-queryが非nil
なら、この関数は中に数字が入った‘<…>’をfilenameに追加して新たなバッファーの名前を一意にする。
along-with-fileが非nil
なら、それは前にvisitされていたファイルがfilenameにリネームされたと想定することを意味する。この場合、コマンドはバッファーの修正フラグを変更せず、そのバッファーの記録されている最終ファイル変更時刻をvisited-file-modtime
が報告する時刻(バッファーの変更 Timeを参照)で変更することもしない。along-with-fileがnil
なら、この関数はvisited-file-modtime
が0をリターンした後に、記録済みの最終ファイル変更時刻をクリアーする。
関数set-visited-file-name
がinteractiveに呼び出されたときはミニバッファー内でfilenameの入力を求める。
このバッファーローカル変数はvisitしているファイル名をもたないバッファーにたいして、バッファーリスト中のvisitしているファイル名を表示する場所に表示する文字列を指定する。Diredバッファーはこの変数を使用する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsは各バッファーにたいしてバッファーのテキストを変更したかどうかを記録するために、変更フラグ(modified
flag)と呼ばれるフラグを管理しています。このフラグはバッファーのコンテンツを変更すると常にt
にセットされ、バッファーを保存したときnil
にクリアーされます。したがってこのフラグは保存されていない変更があるかどうかを表します。フラグの値は通常はモードライン内(モードラインで使用される変数を参照)に表示され、保存(バッファーの保存を参照)と自動保存(自動保存を参照)を制御します。
いくつかのLispプログラムは、このフラグを明示的にセットします。たとえば、関数set-visited-file-name
は、このフラグをt
にセットします。なぜなら、たとえその前にvisitしていたファイルが変更されていなくても、テキストは新たにvisitされたファイルとマッチしないからです。
バッファーのコンテンツを変更する関数はテキストで説明されています。
この関数はバッファーbufferが最後にファイルから読み込まれたか、あるいは保存されてから変更されていればt
、それ以外ではnil
をリターンする。bufferが与えられなければカレントバッファーがテストされる。
この関数はflagが非nil
ならカレントバッファーを変更済みとして、nil
なら未変更としてマークする。
この関数を呼び出すことによる別の効果は、それがカレントバッファーのモードラインの無条件な再表示を引き起こすことである。実際のところ関数force-mode-line-update
は以下を行うことにより機能する:
(set-buffer-modified-p (buffer-modified-p))
set-buffer-modified-p
と同様だがモードラインにたいする強制的な再表示を行わない点が異なる。
このコマンドはカレントバッファーが変更されておらず保存する必要がないとマークする。argが非nil
なら変更されているとマークするので、次回の適切なタイミングでバッファーは保存されるだろう。interactiveに呼び出された場合には、argはプレフィックス引数。
この関数はエコーエリア内にメッセージをプリントするのでプログラム内で使用してはならない。かわりにset-buffer-modified-p
(上述)を使用すること。
この関数はbufferの変更カウント(modification-count)をリターンする。これはバッファーが変更されるたびに増加されるカウンター。bufferがnil
(または省略)ならカレントバッファーが使用される。このカウンター0にラップアラウンド(wrap around: 最初に戻る )され得る。
この関数はbufferの文字変更に関わる変更カウントをリターンする。テキストプロパティを変更してもこのカウンターは変化しない。しかしそのバッファーにテキストが挿入または削除されるたびに、このカウンターはbuffer-modified-tick
によりリターンされるであろう値にリセットされる。buffer-chars-modified-tick
を2回呼び出してリターンされる値を比較することにより、その呼び出しの間にバッファー内で文字変更があったかどうかを知ることができる。bufferがnil
(または省略)ならカレントバッファーが使用される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
あるファイルをvisitしてそのバッファー内で変更を行い、その一方ではディスク上でファイル自身が変更されたとします。この時点でバッファーを保存するとファイル内の変更は上書きされるでしょう。これが正に望んでいる動作のときもありますが、通常は有用な情報が失われてしまいます。したがってEmacsはファイルを保存する前に、以下で説明する関数を使用してファイルの変更時刻をチェックします(ファイルの変更時刻を調べる方法はファイルの属性を参照)。
この関数はbuffer(デフォルトはカレントバッファー)にvisitされているファイルにたいして記録されている変更時刻と、オペレーティングシステムにより記録された実際の変更時刻を比較する。これら2つの時刻はEmacsがそのファイルをvisitか保存して以降、他のプロセスにより書き込みがされていなければ等しくなるはずである。
この関数は実際の最終変更時刻とEmacsが記録した変更時刻が同じならt
、それ以外はnil
をリターンする。そのバッファーが記録済みの最終変更時刻をもたない、すなわちvisited-file-modtime
が0をリターンするような場合にもt
をリターンする。
これはたとえvisited-file-modtime
が非0の値をリターンしたとしても、ファイルをvisitしていないバッファーにたいしては常にt
をリターンする。たとえばDiredバッファーにたいして、この関数は常にt
をリターンする。また存在せず、
以前に存在したこともなかったファイルをvisitするバッファーにたいしてt
をリターンするが、visitしているファイルが削除されたバッファーにたいしてはnil
をリターンする。
この関数はカレントバッファーによりvisitされているファイルの最終変更時刻の記録をクリアーする。結果としてこのバッファーにを次回の保存ではファイルの変更時刻の食い違いは報告されなくなる。
この関数はset-visited-file-name
、および変更済みファイルの上書きを防ぐための通常テストを行わない例外的な箇所で呼び出される。
この関数はカレントバッファーにたいして記録された最終ファイル変更時刻を(high low
microsec
picosec)
のような形式のリストでリターンする(これはfile-attributes
が時刻値をリターンするために使用するフォーマットと同じ。ファイルの属性を参照)。
バッファーが最終変更時刻の記録をもたなければこの関数は0をリターンする。これが発生するのは、たとえばバッファーがファイルをvisitしていなかったり、clear-visited-file-modtime
で最終変更時刻が明示的にクリアーされた場合。しかしvisited-file-modtime
は、いくつかの非ファイルバッファーにたいするリストをリターンすることに注意。たとえばディレクトリーをリストするDiredバッファーでは、Diredが記録するそのディレクトリーの最終変更時刻がリターンされる。
バッファーがファイルをvisitしていなければ、この関数は-1をリターンする。
この関数はバッファーがvisitしているファイルの最終変更時刻の記録を、timeが非nil
ならtime、それ以外はvisitしているファイルの最終変更時刻に更新する。
timeがnil
や0でなければ、それはcurrent-time
で使用される形式(high
low microsec picosec)
というフォーマットであること(時刻を参照)。
この関数はバッファーが通常のようにファイルから読み取られたものでない場合や、ファイル自身が害のない既知の理由により変更されている場合に有用。
これはvisitしているファイルfilenameがバッファーのテキストより新しいときにバッファーの変更を試みた後、ユーザーに処理方法を尋ねるために使用する関数。Emacsはディスク上のファイルの変更時刻が、バッファーを最後に保存した時刻より新しいかどうかでこれを検知する。これはおそらく他のプログラムがそのファイルを変更したことを意味する。
この関数が正常にリターンするかどうかは、ユーザーの応答に依存する。関数はバッファーの変更が処理された場合は正常にリターンし、バッファーの変更が許可されなかった場合はデータ(filename)
とともにエラーfile-supersession
をシグナルする。
この関数は適切なタイミングでEmacsにより自動的に呼び出される。これは再定義することによりEmacsをカスタマイズ可能にするために存在する。標準的な定義はファイルuserlock.elを参照のこと。
ファイルのロックのファイルロックのメカニズムも参照されたい。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
あるバッファーが読み取り専用(read-only)の場合には、たとえスクロールやナローイングによってファイルのコンテンツのビューを変更しても、そのコンテンツを変更することはできません。
読み取り専用バッファーは、2つのタイプの状況において使用されます:
ここでの目的はユーザーにたいしてそのファイルへの保存を意図したバッファーの編集が無益、または望ましくないかもしれないことを伝えることである。それにも関わらずバッファーのテキストの変更を望むユーザーは、C-x C-qで読み取り専用フラグをクリアーした後にこれを行うことができる。
このようなモードのスペシャルコマンドは、buffer-read-only
を(let
によって)nil
にバインドしたり、テキストを変更する箇所ではinhibit-read-only
をt
にバインドする。
このバッファーローカル変数は、そのバッファーが読み取り専用かどうかを指定する。この変数が非nil
ならそのバッファーは読み取り専用。しかしテキストプロパティinhibit-read-only
をもつ文字は依然として編集可能。inhibit-read-onlyを参照のこと。
この変数が非nil
なら、読み取り専用バッファー、およびその実際の値に依存して、一部もしくはすべての読み取り専用文字が変更されている。バッファー内の読み取り専用文字とはテキストプロパティread-only
が非nil
の文字。テキストプロパティについての詳細は特殊な意味をもつプロパティを参照のこと。
inhibit-read-only
がt
なら、すべてのread-only
文字プロパティは効果がなくなる。inhibit-read-only
がリストの場合には、read-only
文字プロパティがリストのメンバーなら効果がなくなる(比較はeq
で行われる)。
これはバッファーローカルなマイナーモードRead
Onlyモードにたいするモードコマンド。このモードが有効なときは、そのバッファーのbuffer-read-only
は非nil
。無効なときは、そのバッファーのbuffer-read-only
はnil
。呼び出す際の慣習は、他のマイナーモードコマンドの慣習と同じ(マイナーモード記述の規約を参照)。
このマイナーモードは他のマイナーモードとは異なり、主にbuffer-read-only
にたいするラッパーの役目を果たし、別個にread-only-mode
変数は存在しない。Read
Onlyモードが無効なときでも、read-only
テキストプロパティが非nil
の文字は読み取り専用のままである。一時的にすべての読み取り専用ステータスを無視するには上述のinhibit-read-only
をバインドすること。
Read
Onlyモードを有効にする際、このモードコマンドはオプションview-read-only
が非nil
ならViewモードも有効にする。Miscellaneous Buffer Operations in The GNU Emacs
Manualを参照のこと。Read Onlyモードを無効にする際に、もしもViewモードが有効ならViewモードも無効にする。
この関数はカレントバッファーが読み取り専用ならbuffer-read-only
エラーをシグナルする。position
(デフォルトはポイント位置)のテキストのテキストプロパティinhibit-read-only
がセットされていればエラーは発生しないだろう。
カレントバッファーが読み取り専用の場合にエラーをシグナルする他の方法については、interactive
の使用を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファーリスト(buffer
list)とは、すべての生きた(killされていない)バッファーのリストです。このリスト内のバッファーの順序は主に、それぞれのバッファーがウィンドウに表示されたのがどれほど最近なのかにもとづきます。いくつかの関数、特にother-buffer
はこの順序を使用します。ユーザーに表示されるバッファーリストもこの順序にしたがいます。
バッファーを作成するとそれはバッファーリストの最後に追加され
バッファーをkillすることによってそのリストから削除されます。ウィンドウに表示するためにバッファーが選択されたとき(ウィンドウ内のバッファーへの切り替えを参照)、あるいはバッファーを表示するウィンドウが選択されたとき(ウィンドウの選択を参照)、そのバッファーは常にこのリストの先頭に移動します。バッファーがバリー(以下のbury-buffer
を参照)されたときは、このリストの最後に移動します。バッファーリストを直接操作するために利用できるLispプログラマー向けの関数は存在しません。
説明した基本バッファーリスト(fundamental buffer
list)に加えて、Emacsはそれぞれのフレームにたいしてローカルバッファーリスト(local buffer
list)を保守します。ローカルバッファーリストでは、そのフレーム内で表示されていた(または選択されたウィンドウの)バッファーが先頭になります(この順序はそのフレームのフレームパラメーターbuffer-list
に記録される。バッファーのパラメーターを参照)。並び順は基本バッファーリストにならい、そのフレームでは表示されていないフレームは後になになります。。
この関数はすべてのバッファーを含むバッファーリストをリターンする(名前がスペースで始まるバッファーも含む)。リストの要素はバッファーの名前ではなく実際のバッファー。
frameがフレームなら、frameのローカルバッファーリストをリターンする。frameがnil
か省略された場合は、基本バッファーリストが使用される。その場合には、そのバッファーを表示するフレームがどれかとは無関係に、もっとも最近に表示または選択されたバッファーの順になる。
(buffer-list) ⇒ (#<buffer buffers.texi> #<buffer *Minibuf-1*> #<buffer buffer.c> #<buffer *Help*> #<buffer TAGS>)
;; ミニバッファーの名前が ;; スペースで始まることに注意! (mapcar (function buffer-name) (buffer-list)) ⇒ ("buffers.texi" " *Minibuf-1*" "buffer.c" "*Help*" "TAGS")
buffer-list
からリターンされるリストはそれ専用に構築されたリストであって、Emacsの内部的なデータ構造ではなく、それを変更してもバッファーの並び順に影響はありません。基本バッファーリスト内のバッファーの並び順を変更したい場合に簡単なのは以下の方法です:
(defun reorder-buffer-list (new-list) (while new-list (bury-buffer (car new-list)) (setq new-list (cdr new-list))))
この方法により、バッファーを失ったり有効な生きたバッファー以外の何かを追加する危険を犯さずにリストに任意の並び順を指定できます。
特定のフレームのバッファーリストの並び順や値を変更するには、modify-frame-parameters
でそのフレームのbuffer-list
パラメーターをセットしてください(フレームパラメーターへのアクセスを参照)。
この関数はバッファーリスト中でbuffer以外の最初のバッファーをリターンする。これは通常は選択されたウィンドウ(フレームframe、または選択されたフレーム(入力のフォーカスを参照)にもっとも最近表示されたbuffer以外のバッファーである。名前がスペースで始まるバッファーは考慮されない。
bufferが与えられない(または生きたバッファーでない)場合には、other-buffer
は選択されたフレームのローカルバッファーリスト内の最初のバッファーをリターンする(frameが非nil
ならframeのローカルバッファーリスト内の最初のバッファーをリターンする)。
frameが非nil
のbuffer-predicate
パラメーターをもつ場合には、どのバッファーを考慮すべきかを決定するためにother-buffer
はその述語を使用する。これはそれぞれのバッファーごとにその述語を一度呼び出して、値がnil
ならそのバッファーは無視される。バッファーのパラメーターを参照のこと。
visible-okがnil
ならother-buffer
はやむを得ない場合を除き、任意の可視のフレーム上のウィンドウ内で可視のバッファーをリターンすることを避ける。visible-okが非nil
なら、バッファーがどこかで表示されているかどうかは問題にしない。
適切なバッファーが存在しなければ、バッファー*scratch*を(必要なら作成して)リターンする。
この関数はframeのバッファーリスト内からbuffer以外の最後のバッファーをリターンする。frameが省略またはnil
なら選択されたフレームのバッファーリストを使用する。
引数visible-okは上述したother-buffer
と同様に扱われる。適切なバッファーを見つけられなければバッファー*scratch*がリターンされる。
このコマンドはバッファーリスト内の他のバッファーの並び順を変更することなく、buffer-or-nameをバッファーリストの最後に配置する。つまりこのバッファーはother-buffer
がリターンする候補でもっとも期待度が低くなる。引数はバッファー自身かバッファーの名前を指定できる。
この関数は基本バッファーリストと同様にそれぞれのフレームのbuffer-list
パラメーターを操作する。したがってバリー(bury:
埋める、隠す)したバッファーは、(buffer-list
frame)
や(buffer-list)
の値の最後に置かれるだろう。さらにそのバッファーが選択されたウィンドウに表示されていれば、そのウィンドウのバッファーリストの最後にバッファーを配置することも行う(ウィンドウのヒストリーを参照)。
buffer-or-nameがnil
または省略された場合には、カレントバッファーをバリーすることを意味する。加えてカレントバッファーが選択されたウィンドウに表示されていれば、そのウィンドウを削除するか他のバッファーを表示する。より正確には選択されたウィンドウが専用(dedicated)のウィンドウ(see section 専用のウィンドウ)であり、かつそのフレーム上に他のウィンドウが存在する場合には専用ウィンドウは削除される。それがフレーム上で唯一のウィンドウであり、かつそのフレームが端末上で唯一のフレームでなければ、そのフレームはframe-auto-hide-function
で指定される関数を呼び出すことにより開放される(ウィンドウのquitを参照)。それ以外の場合はに、他のバッファーをそのウィンドウ内に表示するためにswitch-to-prev-buffer
を呼び出す(ウィンドウのヒストリーを参照)。buffer-or-nameが他のウィンドウで表示されていれば、そのまま表示され続ける。
あるバッファーにたいして、それを表示するすべてのウィンドウでバッファーを置き換えるにはreplace-buffer-in-windows
を使用する。バッファーとウィンドウを参照のこと。
このコマンドは選択されたフレームのローカルバッファーリストの最後のバッファーに切り替える。より正確には選択されたウィンドウ内で、last-buffer
(上記参照)がリターンするバッファーを表示するために関数switch-to-buffer
を呼び出す(ウィンドウ内のバッファーへの切り替えを参照)。
これはバッファーリストが変更されたときに常に実行されるノーマルフック。(暗黙に)このフックを実行する関数はget-buffer-create
(バッファーの作成を参照)、rename-buffer
(バッファーの名前を参照)、kill-buffer
(バッファーのkillを参照)、bury-buffer
(上記参照)、select-window
(ウィンドウの選択を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではバッファーを作成する2つのプリミティブについて説明します。get-buffer-create
は指定された名前の既存バッファーが見つからなければ作成します。generate-new-buffer
は常に新たにバッファーを作成してそれに一意な名前を与えます。
バッファーを作成するために使用できる他の関数にはwith-output-to-temp-buffer
(一時的な表示を参照)、およびcreate-file-buffer
(ファイルのvisitを参照)が含まれます。サブプロセスの開始によってもバッファーを作成することができます(プロセスを参照)。
この関数はbuffer-or-nameという名前のバッファーをリターンする。リターンされたバッファーはカレントにならない — この関数はカレントがどのバッファーであるかを変更しない。
buffer-or-nameは文字列、または既存バッファーのいずれかでなければならない。これが文字列で、かつ既存の生きたバッファーの名前なら、get-buffer-create
はそのバッファーをリターンする。そのようなバッファーが存在しなければ、新たにバッファーを作成する。buffer-or-nameが文字列ではなくバッファーなら、たとえそのバッファーが生きていなくても与えられたバッファーをリターンする。
(get-buffer-create "foo") ⇒ #<buffer foo>
新たに作成されたバッファーにたいするメジャーモードはFundamentalモードにセットされる(変数major-mode
のデフォルト値はより高いレベルで処理される。Emacsがメジャーモードを選択する方法を参照)。名前がスペースで始まる場合には、そのバッファーのアンドゥ情報の記録は初期状態では無効である(アンドゥを参照)。
この関数は新たに空のバッファーを作成してリターンするが、それをカレントにはしない。バッファーの名前は関数generate-new-buffer-name
にnameを渡すことにより生成される(バッファーの名前を参照)。つまりnameという名前のバッファーが存在しなければ、それが新たなバッファーの名前になり、その名前が使用されていたら‘<n>’という形式のサフィックスがnameに追加される。ここでnは整数。
nameが文字列でなければエラーがシグナルされる。
(generate-new-buffer "bar") ⇒ #<buffer bar>
(generate-new-buffer "bar") ⇒ #<buffer bar<2>>
(generate-new-buffer "bar") ⇒ #<buffer bar<3>>
新たなバッファーにたいするメジャーモードはFundamentalモードにセットされる。変数major-mode
のデフォルト値は、より高いレベルで処理される。Emacsがメジャーモードを選択する方法を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファーのkill(Killing a buffer)により、 そのバッファーの名前はEmacsにとって未知の名前となり、そのバッファーが占めていたメモリースペースは他の用途に使用できるようになります。
バッファーに対応するバッファーオブジェクトは、それを参照するものがあればkillされても存在し続けますが、それをカレントにしたり表示することができないように特別にマークされます。とはいえkillされたバッファーの同一性は保たれるので、2つの識別可能なバッファーをkillした場合には、たとえ両方死んだバッファーであってもeq
による同一性は残ります。
あるウィンドウ内においてカレント、あるいは表示されているバッファーをkillした場合、Emacsはかわりに他の何らかのバッファーを自動的に選択または表示します。これはバッファーのkillによってカレントバッファーが変更されることを意味します。したがってバッファーをkillする際には、(killされるバッファーがカレントを偶然知っていた場合を除き)カレントバッファーの変更に関しても事前に注意を払うべきです。カレントバッファーを参照してください。
1つ以上のインダイレクト バッファー(インダイレクトバッファーを参照) のベースとなるバッファーをkillした場合には、同様にインダイレクトバッファーも自動的にkillされます。
バッファーのbuffer-name
がnil
の場合のみバッファーはkillされます。killされていないバッファーは生きた(live)バッファーと呼ばれます。あるバッファーにたいして、そのバッファーが生きているか、またはkillされているかを確認するにはbuffer-live-p
を使用します(下記参照)。
この関数はバッファーbuffer-or-nameをkillして、そのバッファーのメモリーを他の用途のために開放、またはオペレーティングシステムに返却する。buffer-or-nameがnil
または省略された場合にはカレントバッファーをkillする。
そのバッファーをprocess-buffer
として所有するすべてのプロセスには、通常はプロセスを終了させるシグナルSIGHUP
(hangup)が送信される。プロセスへのシグナルの送信を参照のこと。
バッファーがファイルをvisitしていて、かつ保存されていない変更が含まれる場合には、kill-buffer
はバッファーをkillする前にユーザーにたいして確認を求める。これはkill-buffer
がinteractiveに呼び出されていなくても行われる。この確認要求を抑制するにはkill-buffer
の呼び出し前に、変更フラグ(modified
flag)をクリアーすればよい。バッファーの変更を参照のこと。
killされるバッファーをカレントで表示しているすべてのバッファーをクリーンアップするために、この関数はreplace-buffer-in-windows
を呼び出す。
すでに死んでいるバッファーをkillしても効果はない。
この関数は実際にバッファーをkillするとt
をリターンする。ユーザーが確認で拒否を選択、またはbuffer-or-nameがすでに死んでいる場合にはnil
をリターンする。
(kill-buffer "foo.unchanged") ⇒ t (kill-buffer "foo.changed") ---------- Buffer: Minibuffer ---------- Buffer foo.changed modified; kill anyway? (yes or no) yes ---------- Buffer: Minibuffer ---------- ⇒ t
保存されていない変更について確認を求める前に、kill-buffer
はリストkill-buffer-query-functions
内の関数を出現順に引数なしで呼び出す。それらが呼び出される際にはkillされるバッファーがカレントになる。この機能はこれらの関数がユーザーに確認を求めるというアイデアが元となっている。これらの関数のいずれかがnil
をリターンしたら、kill-buffer
はそのバッファーを殺さない。
これは尋ねることになっている質問をすべて終えた後、実際にバッファーをkillする直前にkill-buffer
により実行されるノーマルフック。この変数は永続的にローカルであり、メジャーモードの変更により、そのローカルバインディングはクリアーされない。
特定のバッファーにおいてこの変数が非nil
なら、save-buffers-kill-emacs
とsave-some-buffers
(この関数の2つ目のオプション引数がt
の場合)は、ファイルをvisitしているバッファーと同じようにそのバッファーの保存を提案する。Definition of save-some-buffersを参照のこと。何らかの理由により変数buffer-offer-save
をセットする際には自動的にバッファーローカルになる。バッファーローカル変数を参照のこと。
特定のバッファーにおいてこの変数が非nil
なら、save-buffers-kill-emacs
とsave-some-buffers
は、(バッファーが変更されていれば)ユーザーに確認を求めることなくそのバッファーを保存する。何らかの理由によりこの変数をセットする際には自動的にバッファーローカルになる。
この関数はobjectが生きたバッファー(killされていないバッファー)ならt
、それ以外はnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
インダイレクトバッファー(indirect buffer: 間接バッファー)とは、ベースバッファー(base buffer)と呼ばれる他のバッファーとテキストを共有します。いくつかの点においてインダイレクトバッファーはファイル間でのシンボリックリンクに類似しています。ベースバッファー自身はインダイレクトバッファーではない可能性があります。
インダイレクトバッファーのテキストは、常にベースバッファーのテキストと同一です。編集により一方が変更されると、それは即座に他方のバッファーから可視になります。これには文字自体に加えてテキストプロパティも同様に含まれます。
他のすべての観点において、インダイレクトバッファーとそのベースバッファーは完全に別物です。それらは別の名前、独自のポイント値、ナローイング、マーカー、オーバーレイ、メジャーモード、バッファーローカルな変数バインディングをもちます(ただしどちらかのバッファーでのテキストの挿入や削除を行うと両方のバッファーでマーカーとオーバーレイが再配置される)。
インダイレクトバッファーはファイルをvisitできませんがベースバッファーには可能です。インダイレクトバッファーの保存を試みると、実際にはベースバッファーが保存されます。
インダイレクトバッファーをkillしてもベースバッファーに影響はありません。ベースバッファーをkillするとインダイレクトバッファーはkillされて再びカレントバッファーにすることはできません。
これはベースバッファーがbase-bufferであるような、nameという名前のインダイレクトバッファーを作成してリターンする。引数base-bufferは生きたバッファー、または既存バッファーの名前(文字列)を指定できる。nameが既存バッファーの名前ならエラーがシグナルされる。
cloneが非nil
ならインダイレクトバッファーは最初はbase-bufferのメジャーモード、マイナーモード、バッファーローカル変数等の状態を共有する。cloneが省略またはnil
なら、インダイレクトバッファーの情報は新たなバッファーにたいするデフォルト状態にセットされる。
base-bufferがインダイレクトバッファーなら、新たなバッファーのベースとしてそれのベースバッファーが使用される。さらにcloneが非nil
なら、初期状態はbase-bufferではなく実際のベースバッファーからコピーされる。
この関数はカレントバッファーのベースバッファーを共有するインダイレクトバッファーを新たに作成して、カレントバッファーの残りの属性をコピーしてリターンする(カレントバッファーがインダイレクトバッファーでなければそれがベースバッファーとして使用される)。
display-flagが非nil
なら、それはpop-to-buffer
を呼び出すことにより新しいバッファーを表示することを意味する。norecordが非nil
なら、それは新しいバッファーをバッファーリストの先頭に置かないことを意味する。
この関数はbuffer
(デフォルトはカレントバッファー)のベースバッファーをリターンする。bufferがインダイレクトバッファーでなければ値はnil
、それ以外では値は他のバッファーとなり、そのバッファーがインダイレクトバッファーであることは決してない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
特別なモードでは、ユーザーが同一のバッファーから複数の非常に異なったテキストにアクセスできるようにしなければならない場合があります。たとえばバッファーのテキストのサマリーを表示して、ユーザーがそのテキストにアクセスできるようにする場合です。
これは、(ユーザーがテキストを編集した際には同期を保つ)複数バッファーや、ナローイング(ナローイングを参照)により実装することができるかもしれません。しかしこれらの候補案はときに退屈になりがちであり、特にそれぞれのテキストタイプが正しい表示と編集コマンドを提供するために高価なバッファーグローバル操作を要求する場合には、飛び抜けて高価になる場合があります。
Emacsはそのようなモードにたいして別の機能を提供します。buffer-swap-text
を使用すれば、2つのバッファー間でバッファーテキストを素早く交換することができます。この関数はテキストの移動は行わずに異なるテキスト塊(text
chunk)をポイントするように、バッファーオブジェクトの内部的なデータ構造だけを変更するため非常に高速です。これを使用することにより、2つ以上のバッファーグループから個々のバッファーのコンテンツすべてを併せもつような、単一の仮想バッファー(virtual
buffer)が実在するように見せかけることができます。
この関数はカレントバッファーのテキストと、引数bufferのテキストを交換する。2つのバッファーのいずれか一方がインダイレクトバッファー(インダイレクトバッファーを参照)、またはインダイレクトバッファーのベースバッファーの場合はエラーをシグナルする。
バッファーテキストに関連するすべてのバッファープロパティ、つまりポイントとマークの位置、すべてのマーカーとオーバーレイ、テキストプロパティ、アンドゥリスト、enable-multibyte-characters
フラグの値(enable-multibyte-charactersを参照)等も同様に交換される。
警告:
この関数をsave-excursion
内部で呼び出すと、位置とバッファーを保存するためにsave-excursion
が使用するマーカーも同様に交換されるので、そのフォームを抜ける際にはカレントバッファーはbufferにセットされるだろう。
ファイルをvisitしているバッファーにbuffer-swap-text
を使用する場合には、交換されたテキストではなくそのバッファーの元のテキストを保存するようにフックをセットアップするべきです。write-region-annotate-functions
は正にこの目的のために機能します。そのバッファーのbuffer-saved-size
を、おそらく交換されたテキストにたいする変更が自動保存に干渉しないであろう、-2にセットするべきです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsのバッファーは挿入と削除を高速にするために不可視のギャップ(gap)を使用して実装されています。挿入はギャップ部分を充填、削除はギャップを追加することにより機能します。もちろんこれは最初にギャップを挿入や削除の部位(locus)に移動しなければならないことを意味します。Emacsはユーザーが挿入か削除を試みたときだけギャップを移動します。大きなバッファー内の遠く離れた位置で編集した後に、他の箇所での最初の編集コマンドに無視できない遅延が発生する場合があるのはこれが理由です。
このメカニズムは暗黙に機能するものであり、Lispコードはギャップのカレント位置に影響されるべきでは決してありませんが、以下の関数はギャップ状態に関する情報の取得に利用できます。
この関数はカレントバッファー内のギャップのカレント位置をリターンする。
この関数はカレントバッファー内のギャップのサイズをリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このチャプターではEmacsのウィンドウに関連する関数と変数について説明します。Emacsが利用可能なスクリーン領域にウィンドウが割り当てられる方法についてはフレームを参照してください。ウィンドウ内にテキストが表示される方法についての情報はEmacsのディスプレー表示を参照してください。
27.1 Emacsウィンドウの基本概念 | ウィンドウ使用についての基本情報。 | |
27.2 ウィンドウとフレーム | ウィンドウとそれらが表示されるフレームとの関連。 | |
27.3 ウィンドウのサイズ | ウィンドウのサイズへのアクセス。 | |
27.4 ウィンドウのリサイズ | ウィンドウのサイズの変更。 | |
27.5 Preserving Window Sizes | ウィンドウのサイズの保存。 | |
27.6 ウィンドウの分割 | 新たなウィンドウの作成。 | |
27.7 ウィンドウの削除 | フレームからのウィンドウの削除。 | |
27.8 ウィンドウの再結合 | ウィンドウの分割や削除時のフレームレイアウトの保存。 | |
27.9 ウィンドウの選択 | 選択されたウィンドウとは編集を行っているウィンドウである。 | |
27.10 ウィンドウのサイクル順 | 既存のウィンドウ間の移動。 | |
27.11 バッファーとウィンドウ | それぞれのウィンドウはバッファーのコンテンツを表示する。 | |
27.12 ウィンドウ内のバッファーへの切り替え | バッファー切り替えのためのより高レベルな関数。 | |
27.13 表示するウィンドウの選択 | バッファーを表示するウィンドウの選択方法。 | |
27.14 display-buffer にたいするアクション関数 | display-buffer 用のサブルーチン。
| |
27.15 バッファー表示の追加オプション | バッファー表示方法に影響する拡張オプション。 | |
27.16 ウィンドウのヒストリー | それぞれのウィンドウは表示されていたバッファーを記憶する。 | |
27.17 専用のウィンドウ | 特定のウィンドウ内で他のバッファーの表示を無効にする。 | |
27.18 ウィンドウのquit | 以前に表示していたバッファーの状態をリストアする方法。 | |
27.19 ウィンドウとポイント | それぞれのウィンドウは自身の位置とポイントをもつ。 | |
27.20 ウィンドウの開始位置と終了位置 | ウィンドウ内でスクリーン表示されるテキストを表すバッファー位置。 | |
27.21 テキスト的なスクロール | ウィンドウを通じたテキストの上下移動。 | |
27.22 割り合いによる垂直スクロール | ウィンドウ上のコンテンツの上下移動。 | |
27.23 水平スクロール | ウィンドウ上のコンテンツの横移動。 | |
27.24 座標とウィンドウ | 座標からウィンドウへの変換。 | |
27.25 ウィンドウの構成 | スクリーンの情報の保存とリストア。 | |
27.26 ウィンドウのパラメーター | ウィンドウへの追加情報の割り当て。 | |
27.27 ウィンドウのスクロールと変更のためのフック | スクロール、ウィンドウのサイズ変更、ある特定のしきい値を超えたときに行われる再表示、ウィンドウ設定の変更にたいするフック。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウ(window)とは任意のバッファーを表示するために使用されるスクリーン領域です。Emacs LispではウィンドウはスペシャルLispオブジェクトとして表現されます。
ウィンドウはフレームへとグループ化されます(フレームを参照)。それぞれのフレームは最低でも1つのウィンドウを含みます。ユーザーは複数のバッファーを一度に閲覧するために、それを複数のオーバーラップしないウィンドウに分割することができます。Lispプログラムはさまざまな目的にたいして複数のウィンドウを使用できます。たとえばRmailでは1つのウィンドウでメッセージタイトル、もう一方のウィンドウで選択したメッセージのコンテンツを閲覧できます。
Emacsはグラフィカルなデスクトップ環境やX Window Systemのようなウィンドウシステムとは異なる意味で“ウィンドウ(window)”という単語を使用します。EmacsがX上で実行されているときはXのグラフィカルなXウィンドウは、Emacsでの(1つ以上のEmacsウィンドウを含んだ)フレームになります。Emacsがテキスト端末上で実行されているときはフレームが端末スクリーン全体を占有します。
Xのウィンドウとは異なり、Emacsのウィンドウはタイル表示(tiled)されるので、フレームの領域内でオーバーラップされることは決してありません。あるウィンドウが作成、リサイズ、削除されるとき変更されたウィンドウスペースの変更は各ウィンドウの調整により取得・譲与されるので、そのフレームの総領域に変化はありません。
この関数はobjectがウィンドウ(バッファーの表示有無に関わらず)ならt
、それ以外はnil
をリターンする。
生きたウィンドウ(live window)とは、あるフレーム内で実際にバッファーを表示しているウィンドウのことです。
この関数はobjectが生きたウィンドウならt
、それ以外はnil
をリターンする。生きたウィンドウとはバッファーを表示するウィンドウのこと。
各フレーム内のウィンドウはウィンドウツリー(window tree)内へと組織化されます。ウィンドウとフレームを参照してください。それぞれのウィンドウツリーのリーフノード(leaf nodes)は、実際にバッファーを表示している生きたウィンドウです。ウィンドウツリーの内部ノード(internal node)は内部ウィンドウ(internal windows)と呼ばれ、これらは生きたウィンドウではありません。
有効なウィンドウ(valid window)とは、生きたウィンドウか内部ウィンドウのいずれかです。有効なウィンドウにたいしては、それを削除(delete)、すなわちそのウィンドウのフレームから削除することができます(ウィンドウの削除を参照)。その場合、それは有効なウィンドウではなくなりますが、それを表すLispオブジェクトは依然として他のLispオブジェクトから参照されたままかもしれません。削除されたウィンドウは保存されたウィンドウ設定(window configuration)をリストアすることにより再び有効にすることができます(ウィンドウの構成を参照)。
window-valid-p
により、削除されたウィンドウから有効なウィンドウを区別できます。
この関数はobjectが生きたウィンドウかウィンドウツリー内の内部ウィンドウならt
をリターンする。それ以外(objectが削除されたウィンドウの場合も含む)はnil
をリターンする。
それぞれのフレーム内において、常にただ1つのEmacsウィンドウがそのフレームで選択されている(selected within the
frame)ウィンドウとして指定されます。選択されたフレームにたいして、そのウィンドウは選択されたウィンドウ(selected
window)と呼ばれます。選択されたウィンドウは編集のほとんどが行われるウィンドウであり、カーソルはその選択されたウィンドウに表示されます(カーソルのパラメーターを参照)。選択されたウィンドウのバッファーは、通常はset-buffer
が使用された場合を除きカレントバッファーでもあります(カレントバッファーを参照)。選択されていないフレームでは、そのフレームが選択されたときはそのフレームで選択されていたウィンドウが選択されたウィンドウになります。ウィンドウの選択を参照してください。
この関数は選択されたウィンドウをリターンする(これは常に生きたウィンドウ)。
たとえばFollowモード((emacs)Follow Modeを参照)の管理下では、あるウィンドウが単独で表示可能な部分より大きい部分をそのウィンドウにまとめて表示するように、複数のウィンドウが集合かつ協調してバッファーを表示することがあります。そのようなウィンドウグループ(window
group)を1つのエンティティーとしてとらえると便利なことがよくあります。window-group-start
(ウィンドウの開始位置と終了位置を参照)のようないくつかの関数では、グループ全体としてウィンドウの1つを引数に与えることにより、これを行うことができます。
選択されたウィンドウがウィンドウグループのメンバーなら、この関数はそのバッファーの最前箇所を表示するウィンドウが先頭になる順序で、グループ内のウィンドウのリストをリターンする。それ以外なら、この関数は選択されたウィンドウだけを含むリストをリターンする。
バッファーローカル変数selected-window-group-function
が関数にセットされているときは、選択されたウィンドウはグループの一部とみなされる。この場合には、selected-window-group
はその関数を引数なしで呼び出し、その結果をリターンする(これはそのグループ内のウィンドウのリストであること)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウはそれぞれ厳密に1つのフレームに属します(フレームを参照)。
この関数はウィンドウwindowが属するフレームをリターンする。windowがnil
の場合のデフォルトは選択されたウィンドウ。
この関数はフレームframeに属する生きたウィンドウのリストをリターンする。frameが省略またはnil
の場合のデフォルトは選択されたフレーム。
オプション引数minibufferはリターンされるリストにミニバッファーウィンドウを含めるべきかどうかを指定する。minibufferがt
ならミニバッファーウィンドウが含まれ、minibufferがnil
または省略された場合にはミニバッファーウィンドウがアクティブのときだけ含まれる。minibufferがnil
とt
以外ならミニバッファーウィンドウは含まれない。
オプション引数windowが非nil
なら、それは指定されたフレーム上の生きたウィンドウであること。その場合にはwindowがリターンされるリストの最初の要素になる。windowが省略またはnil
なら、そのフレームの選択されたウィンドウが最初の要素になる。
同一フレーム内のウィンドウは、リーフノード(leaf nodes)が生きたウィンドウであるようなウィンドウツリー(window tree)内に組織化されます。ウィンドウツリーの内部ノード(internal nodes)は生きたウィンドウではありません。これらのウィンドウは生きたウィンドウ間の関係を組織化するという目的のために存在します。ウィンドウツリーのルートノード(root node)はルートウィンドウ(root window)と呼ばれます。ルートノードは生きたウィンドウ(そのフレームにウィンドウが1つだけの場合)、または内部ウィンドウのいずれかです。
ミニバッファーウィンドウ(ミニバッファーのウィンドウを参照)は、そのフレームがミニバッファーだけのフレームでない限り、そのフレームのウィンドウツリーの一部にはなりません。にもかかわらず、このセクションのほとんどの関数は引数としてミニバッファーウィンドウを許容します。さらにこのセクションの最後に説明する関数window-tree
は、実際のウィンドウツリーと並べてミニバッファーウィンドウをリストします。
この関数はframe-or-windowにたいするルートウィンドウをリターンする。引数frame-or-windowはウィンドウかフレームのいずれかであること。これが省略またはnil
の場合のデフォルトは選択されたフレーム。frame-or-windowがウィンドウなら、リターン値はそのウィンドウのフレームのルートウィンドウ。
ウィンドウが分割(split)されているときは、以前は1つだった2つの生きたウィンドウが存在します。これらのうちの一方は、元のウィンドウと同じLispウィンドウオブジェクトとして表され、もう一方は新たに作成されたLispウィンドウオブジェクトとして表されます。これらの生きたウィンドウはいずれも単一の内部ウィンドウの子ウィンドウ(child windows)として、ウィンドウツリーのリーフノードになります。もし必要ならEmacsはこの内部ウィンドウを自動的に作成します。この内部ウィンドウは親ウィンドウ(parent window)とも呼ばれ、ウィンドウツリー内の適切な位置に配置されます。同じ親を共有するウィンドウセットは兄弟(sibling)と呼ばれます。
この関数はwindowの親ウィンドウ(parent
window)をリターンする。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。windowが親をもたない場合(ミニバッファーウィンドウやそのフレームのルートウィンドウ)にはリターン値はnil
。
内部ウィンドウはそれぞれ、常に最低でも2つの子ウィンドウをもちます。ウィンドウ削除によりこの数値が1になるとEmacsは自動的に内部ウィンドウを削除して、その残った単一の子ウィンドウがウィンドウツリー内のその位置に配置されます。
子ウィンドウはそれぞれ生きたウィンドウ、または(次に自身の子ウィンドウをもつであろう)内部ウィンドウのいずれかです。したがって各内部ウィンドウは、最終的にはその内部ウィンドウの子孫であるような生きたウィンドウにより占有される領域を結合した、特定の矩形スクリーン領域(screen area)を占有すると考えることができます。
内部ウィンドウそれぞれにたいして、近接する子たちのスクリーン領域は垂直(vertically)か水平(horizontally)のいずれかにより整列されます(両方で整列されることはない)。子ウィンドウが他の子ウィンドウと上下に整列される場合、それらは垂直コンビネーション(vertical combination)、左右に整列される場合は水平コンビネーション(horizontal combination)を形成すると表現されます。以下の例で考えてみましょう:
______________________________________ | ______ ____________________________ | || || __________________________ || || ||| ||| || ||| ||| || ||| ||| || |||____________W4____________||| || || __________________________ || || ||| ||| || ||| ||| || |||____________W5____________||| ||__W2__||_____________W3_____________ | |__________________W1__________________|
このフレームのルートウィンドウは内部ウィンドウW1です。これの子ウィンドウは、生きたウィンドウW2と内部ウィンドウW3からなる水平コンビネーションを形成します。W3の子ウィンドウは、生きたウィンドウW4とW5からなる垂直コンビネーションを形成します。したがって、このウィンドウツリー内の生きたウィンドウはW2、W4、およびW5です。
以下の関数は内部ウィンドウの子ウィンドウ、および子ウィンドウの兄弟を取得するために使用できます。
この関数は内部ウィンドウwindowの子ウィンドウが垂直コンビネーションを形成する場合には、windowの一番上の子ウィンドウをリターンする。他のタイプのウィンドウにたいするリターン値はnil
。
この関数は内部ウィンドウwindowの子ウィンドウが水平コンビネーションを形成する場合には、windowの一番左の子ウィンドウをリターンする。他のタイプのウィンドウにたいするリターン値はnil
。
この関数は内部ウィンドウwindowの最初の子ウィンドウをリターンする。これは垂直コンビネーションにたいしては一番上、水平コンビネーションにたいしては一番左の子ウィンドウ。windowが生きたウィンドウならリターン値はnil
。
この関数はwindowが垂直コンビネーションの一部である場合のみ非nil
をリターンする。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。
オプション引数horizontalが非nil
なら、windowが水平コンビネーションの一部である場合のみ非nil
をリターンすることを意味する。
この関数はウィンドウwindowの次の兄弟をリターンする。省略またはnil
なら、windowのデフォルトは選択されたウィンドウ。windowがその親の最後の子ならリターン値はnil
。
この関数はウィンドウwindowの前の兄弟をリターンする。省略またはnil
なら、windowのデフォルトは選択されたウィンドウ。windowがその親の最初の子ならリターン値はnil
。
関数window-next-sibling
とwindow-prev-sibling
を、ウィンドウのサイクル順(ウィンドウのサイクル順を参照)で次や前のウィンドウをリターンする関数next-window
とprevious-window
と混同しないでください。
任意のフレーム上の最初の生きたウィンドウや与えられたウィンドウにもっとも近いウィンドウを探すために以下の関数を使用できます。
この関数はframe-or-windowにより指定されたフレームの左上隅の生きたウィンドウをリターンする。引数frame-or-windowはウィンドウか生きたフレームを指定しなければならず、デフォルトは選択されたフレーム。frame-or-windowがウィンドウを指定する場合には、この関数はそのウィンドウのフレームの最初のウィンドウをリターンする。前の例のフレームが(frame-first-window)
で選択されたとするとW2がリターンされる。
この関数はウィンドウwindow内の位置window-point
から、方向directionにあるもっとも近い生きたウィンドウをリターンする。引数directionはabove
、below
、left
、right
のいずれかでなければならない。オプション引数windowは生きたウィンドウでなければならず、デフォルトは選択されたウィンドウ。
この関数はパラメーターno-other-window
が非nil
のウィンドウをリターンしない(ウィンドウのパラメーターを参照)。もっとも近いウィンドウのno-other-window
パラメーターが非nil
なら、この関数は指定された方向でno-other-window
パラメーターがnil
であるような他のウィンドウを探す。オプション引数ignoreが非nil
なら、たとえno-other-window
パラメーターが非nil
のウィンドウでもリターンされるだろう。
オプション引数signが負の数値なら、それは参照位置としてwindow-point
のかわりにwindowの右端、または下端を使用することを意味する。signが正の数値なら、それは参照位置としてwindowの左端か上端を使用することを意味する。
オプション引数wrapが非nil
なら、それはフレームのボーダー(borders:
枠線)をdirectionがラップアラウンド(wrap around:
最後に達したら最初に戻る)することを意味する。たとえばwindowはフレームの最上にありdirectionがabove
なら、そのフレームのミニバッファーウィンドウがアクティブでそれがフレームの他のウィンドウの最下にある場合には、この関数は通常はミニバッファーウィンドウをリターンする。
オプション引数miniがnil
なら、それはミニバッファーがカレントでアクティブな場合のみミニバッファーウィンドウをリターンすることを意味する。miniが非nil
なら、たとえ非アクティブなときでも、この関数はミニバッファーウィンドウをリターンする。しかしwrapが非nil
なら、常にminiがnil
であるかのように振る舞う。
適切なウィンドウが見つからなければ、この関数はnil
をリターンする。
以下の関数によりフレームのウィンドウツリー全体を取得できます:
この関数はフレームframeにたいするウィンドウツリーを表すリストをリターンする。frameが省略nil
の場合のデフォルトは選択されたフレーム。
リターン値は(root
mini)
という形式のリスト。ここでrootはそのフレームのウィンドウツリーのルートウィンドウ、miniはそのフレームのミニバッファーウィンドウを表す。
ルートウィンドウが生きていればrootはそのウィンドウ自身、それ以外ならrootはリスト(dir
edges w1 w2
...)
。ここでdirは水平コンビネーションならnil
、垂直コンビネーションならt
となり、edgesはそのコンビネーションのサイズと位置を与え、残りの要素は子ウィンドウである。子ウィンドウはそれぞれ、同じようにウィンドウオブジェクト(生きたウィンドウにたいして)、または上記フォーマットと同じ形式のリスト(内部ウィンドウにたいして)かもしれない。edges要素はwindow-edges
がリターンする値のようなリスト(left
top right bottom)
(座標とウィンドウを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の図は生きたウィンドウの構造を示しています:
____________________________________________ |______________ Header Line ______________|RD| ^ ^ |LS|LM|LF| |RF|RM|RS| | | | | | | | | | | | | | Window | | | | Text Area | | | | | Window Body | | | | | (Window Body) | | | | | Total Height | | | | | | | | | Height | | | | |<- Window Body Width ->| | | | | | v |__|__|__|_______________________|__|__|__| | | |_________ Horizontal Scroll Bar _________| | | |_______________ Mode Line _______________|__| | |_____________ Bottom Divider _______________| v <---------- Window Total Width ------------>
ウィンドウの中央はテキストエリア(text area: テキスト領域)、またはボディー(body: 本体、本文)と呼ばれるバッファーテキストが表示される場所です。テキストエリアは一連のオプションエリアで囲まれている可能性があります。左右には内側から外側に向かって図中にLFとRFで示される左右のフリンジ(フリンジを参照)、LMとRMで示される左右のマージン(マージン内への表示を参照)、そしてLSとRSはスクロールバー(スクロールバーを参照)で、これは常に表示されるのはいずれか一方だけです。さらにRDで示されるのが右ディバイダー(ウィンドウディバイダーを参照)です。ウィンドウ上端にはヘッダーライン(ウィンドウのヘッダーラインを参照)、ウィンドウ下端には水平スクロールバー(スクロールバーを参照)、モードライン(モードラインのフォーマットを参照)、下端ディバイダー(ウィンドウディバイダーを参照)があります。
Emacsはウィンドウの高さと幅を求めるためのさまざまな関数を提供します。これらの関数がリターンする値の多くはピクセル単位、または行単位と列単位のいずれかにより指定できます。グラフィカルなディスプレイでは後者は実際にはframe-char-height
とframe-char-width
(Frame Fontを参照)によりリターンされる、そのフレームのデフォルトフォントが指定するデフォルト文字の高さと幅に対応します。したがってあるウィンドウが異なるフォントやサイズでテキストを表示していると、そのウィンドウにたいして報告される行高さと列幅は、実際にウィンドウ内で表示されるテキスト行数と列数とは異なるかもしれません。
トータル高さ(total height)とは、そのウィンドウのボディーを構成する行数、ヘッダーライン、水平スクロールバー、モードライン、(もしあれば)下端ディバイダーです。
この関数はウィンドウwindowのトータル高さを行数でリターンする。windowが省略nil
の場合のデフォルトは選択されたウィンドウ。windowが内部ウィンドウなら、リターン値はそのウィンドウの子孫となるウィンドウにより占有されるトータル高さになる。
ウィンドウのピクセル高さがそのウィンドウがあるフレームのデフォルト文字高さの整数倍でなければ、そのウィンドウが占有する行数が内部で丸められる。これはそのウィンドウが親ウィンドウの場合には、すべての子ウィンドウのトータル高さの合計が、親ウィンドウのトータル高さと内部的に等しくなるような方法により行われる。これはたとえ2つのウィンドウのピクセル高さが等しくでも、内部的なトータル高さは1行分異なるかもしれないことを意味する。さらにこれはそのウィンドウが垂直コンビネーションされていて、かつ次の兄弟をもつ場合には、その兄弟の上端行は、このウィンドウの上端行とトータル高さから計算されるかもしれないことも意味する(座標とウィンドウを参照)。
オプション引数roundがceiling
なら、この関数はwindowのピクセル高さをそのフレームの文字高さで除した数より大であるような最小の整数、floor
なら除した数より小であるような最大の整数、それ以外のroundにたいしてはwindowsのトータル高さの内部値をリターンする。
トータル幅(total width)とはそのウィンドウのボディーを構成する列数、マージン、フリンジ、スクロールバー、(もしあれば)右ディバイダーです。
この関数はウィンドウwindowのトータル幅を列でリターンする。windowが省略nil
の場合のデフォルトは選択されたウィンドウ。windowが内部ウィンドウならリターン値はその子孫のウィンドウが占有するトータル幅になる。
ウィンドウのピクセル幅がそのウィンドウがあるフレームのデフォルト文字幅の整数倍でなければ、そのウィンドウが占有する列数が内部で丸められる。これはそのウィンドウが親ウィンドウの場合には、すべての子ウィンドウのトータル幅の合計が親ウィンドウのトータル幅と内部的に等しくなるような方法により行われる。これはたとえ2つのウィンドウのピクセル幅が等しくでも、内部的なトータル幅は1列分異なるかもしれないことを意味する。さらにこれはそのウィンドウが水平コンビネーションされていて、かつ次の兄弟をもつ場合、その兄弟の左端行はこのウィンドウの左端行とトータル幅から計算されるかもしれないことも意味する(座標とウィンドウを参照)。オプション引数roundはwindow-total-height
の場合と同様に振る舞う。
この関数はウィンドウwindowのトータル高さを行数、またはトータル幅を列数でリターンする。horizontalが省略またはnil
ならwindowにたいしてwindow-total-height
を呼び出すのと等価、それ以外ではwindowにたいしてwindow-total-width
を呼び出すのと等価である。オプション引数roundはwindow-total-height
の場合と同様に振る舞う。
以下の2つの関数はウィンドウのトータルサイズをピクセル単位で取得するために使用できます。
この関数はウィンドウwindowのトータル高さをピクセル単位でリターンする。windowは有効なウィンドウでなければならずデフォルトは選択されたウィンドウ。
リターン値には、(もしあれば)モードライン、ヘッダーライン、水平スクロールバー、下端ディバイダーが含まれる。windowが内部ウィンドウなら、そのピクセル高さは子ウィンドウたちによりスパンされるスクリーン領域のピクセル高さになる。
この関数はウィンドウwindowの幅をピクセル単位でリターンする。windowは有効なウィンドウでなければならずデフォルトは選択されたウィンドウ。
リターン値にはフリンジ、windowのマージン、同様にwindowに属する垂直ディバイダーとスクロールバーが含まれる。windowが内部ウィンドウなら、そのピクセル幅は子ウィンドウたちにより占有されるスクリーン領域の幅になる。
以下の関数は与えられたウィンドウに隣接するウィンドウがあるかどうかを判断するために使用できます。
この関数はフレーム内でwindowの上下に他のウィンドウがなければ非nil
をリターンする。より正確には、windowのトータル高さがそのフレームのルートウィンドウの高さに等しいことを意味する。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。
この関数はフレーム内でwindowの左右に他のウィンドウがなければ非nil
をリターンする(トータル幅がそのフレーム上のルートウィンドウと等しい)。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。
ウィンドウのボディー高さ(body height)とはモードライン、ヘッダーライン、水平スクロールバー、下端ディバイダーを含まないテキスト領域の高さです。
この関数はウィンドウwindowのボディーの高さを行数でリターンする。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ、それ以外なら生きたウィンドウでなければならない。
オプション引数pixelwiseが非nil
なら、この関数はピクセルで計算windowのボディー高さをリターンする。
pixelwiseがnil
の場合には、必要ならリターン値はもっとも近い整数に切り下げられる。これはテキスト領域の下端行が部分的に可視の場合にその行は計数されないこと、さらに任意のウィンドウのボディー高さはwindow-total-height
によりリターンされるそのウィンドウのトータル高さ決して超過し得ないことも意味する。
ウィンドウのボディー幅(body
width)とはスクロールバー、フリンジ、マージン、右ディバイダーを含まないテキスト領域の幅です。(幅を0にセットすることにより)一方または両方のフリンジが削除されたときには、継続と切り詰めのグリフを表示するためにディスプレーエンジンが文字セル2つを予約するので、テキスト表示にたいして2列少なくなることに注意してください(以下で説明するwindow-max-chars-per-line
はこの特性を考慮する)。
この関数はウィンドウwindowのボディーの幅を列数でリターンする。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ、それ以外なら生きたウィンドウでなければならない。
オプション引数pixelwiseが非nil
なら、この関数はwindowのボディーの幅をピクセル単位でリターンする。
pixelwiseがnil
なら、リターン値は必要に応じてもっとも近い整数に切り下げられる。これはテキスト領域の右端の列が部分的に可視な場合にその列が計数されないことを意味する。さらにこれはウィンドウのボディーの幅がwindow-total-width
によりリターンされるウィンドウのトータル幅を決して超過し得ないことをも意味する。
この関数はwindowのボディーの高さか幅をリターンする。horizontalが省略またはnil
ならwindowにたいしてwindow-body-height
、それ以外ならwindow-body-width
を呼び出すのと同じ。いずれの場合もオプション引数pixelwiseは呼び出された関数に渡される。
以前のバージョンのEmacsとの互換性のためにwindow-height
はwindow-total-height
、window-width
はwindow-body-width
にたいするエイリアスです。これらのエイリアス時代遅れと考えられていて将来は削除されるでしょう。
ウィンドウのモードラインとヘッダーラインのピクセル高さは以下の関数により取得できます。それらのリターン値は、そのウィンドウが以前に表示されていない場合を除いて通常は加算されます。その場合のリターン値はそのウィンドウのフレームにたいして使用を予想されるフォントが元になります。
この関数はwindowモードラインの高さをピクセルでリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。windowにモードラインがなければリターン値は0。
この関数はwindowのヘッダーラインの高さをピクセル単位でリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。windowにヘッダーラインがない場合のリターン値は0。
ウィンドウディバイダー(ウィンドウディバイダーを参照)、フリンジ(フリンジを参照)、スクロールバー(スクロールバーを参照)、ディスプレイマージン(マージン内への表示を参照)を取得する関数については、それぞれ対応するセクションで説明されています。
Lispプログラムでレイアウト上の判断を要する場合には、以下の関数を有用と思うでしょう:
この関数は指定されたウィンドウwindow
(生きたウィンドウであること)内で、指定されたフェイスfaceで表示される文字数をリターンする。faceがリマップ(フェイスのリマップを参照)されていたらリマップされたフェイスの情報がリターンされる。省略またはnil
の場合、faceのデフォルトはデフォルトフェイス、windowのデフォルトは選択されたウィンドウ。
この関数はwindow-body-width
と異なり、windowのフレームの正準文字幅(canonical
character
width)の単位ではなく、faceのフォントの実サイズを考慮する。またwindowの一方または両方のフリンジがなければ、継続グリフに使用されるスペースも考慮する。
ウィンドウのサイズを変更(ウィンドウのリサイズを参照)したりウィンドウを分割(split)するコマンド(ウィンドウの分割を参照)は、指定できるウィンドウの最小の高さと幅を指定する変数window-min-height
とwindow-min-width
にしたがう。これらのコマンドはウィンドウのサイズがfixed(固定)になる変数window-size-fixed
にもしたがう(Preserving Window Sizesを参照)。
このオプションは任意のウィンドウの最小のトータル高さを行で指定する。この値は最低でも1つのテキスト行、同様に(もしあれば)モードライン、ヘッダーライン、水平スクロールバー、下端ディバイダーに対応する必要がある。
このオプションはすべてのウィンドウの最小のトータル幅を列で指定する。この値は2つのテキスト列、同様に(もしあれば)マージン、フリンジ、スクロールバー、右ディバイダーに対応する必要がある。
以下の関数は、ある特定の大きさのウィンドウにたいして、それのwindow-min-height
とwindow-min-width
、およびwindow-size-fixed
(Preserving Window Sizesを参照)の値と領域のサイズを示す。
この関数はwindowの最小のサイズをリターンする。windowは有効なウィンドウでなければならず、デフォルトは選択されたウィンドウ。オプション引数horizontalが非nil
ならwindowの最小の列数、それ以外はwindowの最小の行数をリターンすることを意味する。
このリターン値によってwindowのサイズが実際にその値にセットされた場合にwindowのすべてのコンポーネントが完全に可視にとどまることが保証される。horizontalがnil
なら、(もしあれば)モードライン、ヘッダーライン、水平スクロールバー、下端ディバイダーが含まれる。horizontalが非nil
なら、(もしあれば)マージン、フリンジ、垂直スクロールバー、右ディバイダーが含まれる。
オプション引数ignoreが非nil
なら、window-min-height
やwindow-min-width
によりセットされる固定サイズのウィンドウに強いられる制限を無視することを意味する。ignoreがsafe
なら、生きたウィンドウは可能な限り小さなwindow-safe-min-height
の行、およびwindow-safe-min-width
の列を得る。ignoreにウィンドウが指定されると、そのウィンドウにたいする制限だけを無視する。その他の非nil
値では、すべてのウィンドウにたいする上記制限のすべてが無視されることを意味する。
オプション引数pixelwiseが非nil
なら、windowの最小サイズがピクセルで計数されてリターンされることを意味する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは、フレームのサイズを変更せずにウィンドウのサイズを変更する関数について説明します。生きたウィンドウはオーバーラップしないので、これらの関数は2つ以上のウィンドウを含む関数上でのみ意味があります(ウィンドウのリサイズにより隣接するウィンドウのサイズも変更される)。フレーム上に単一のウィンドウしか存在しなければ、フレームの変更以外にウィンドウのサイズ変更はできません(Size and Positionを参照)。
注記した場合を除き、これらの関数は引数として内部ウィンドウも許容します。内部ウィンドウのリサイズにより、同じスペースにフィットするように子ウィンドウもリサイズされます。
この関数はwindowのサイズがdelta行により垂直に変更され得る場合にはdeltaをリターンする。オプション引数horizontalが非nil
の場合には、windowがdelta列単位に水平方向にリサイズ可能ならかわりにdeltaをリターンする。これは実際にはウィンドウのサイズを変更しない。
windowがnil
の場合のデフォルトは選択されたウィンドウ。
deltaが正の値ならそのウィンドウが行または列の単位で拡張可能かどうかをチェックすることを意味し、deltaが負の値ならそのウィンドウが行または列の単位で縮小可能かどうかをチェックすることを意味する。deltaが非0の場合のリターン値0は、そのウィンドウがリサイズ可能であることを意味する。
変数window-min-height
とwindow-min-width
には通常は許容される最小のウィンドウサイズを指定する(ウィンドウのサイズを参照)。しかしオプション引数ignoreが非nil
なら、この関数はwindow-size-fixed
と同様にwindow-min-height
とwindow-min-width
を無視する。そのかわりに(もしあれば)ヘッダーライン、モードライン、水平スクロールバー、下端ディバイダーに加えて1行分の高さのテキストエリアから構成されるウィンドウを最小高さのウィンドウとし、(もしあれば)フリンジ、マージン、スクロールバー、右ディバイダーに加えて1列分の幅のテキストエリアから構成されるウィンドウを最小幅のウィンドウと判断する。
オプション引数pixelwiseが非nil
ならdeltaはピクセル単位として解釈される。
この関数はwindowをdelta増加することによりリサイズを行う。horizontalがnil
なら高さをdelta行、それ以外は幅をdelta行変更する。正のdeltaはウィンドウの拡大、負のdeltaは縮小を意味する。
windowがnil
の場合のデフォルトは選択されたウィンドウ。要求されたようにウィンドウをリサイズできなければエラーをシグナルする。
オプション引数ignoreは上述の関数window-resizable
の場合と同じ意味をもつ。
オプション引数pixelwiseが非nil
ならdeltaはピクセル単位として解釈される。
この関数がどのウィンドウのエッジを変更するかの選択はオプションwindow-combination-resize
の値、および関連するウィンドウのコンビネーションリミット(combination
limits: 組み合わせ制限)に依存し、両方のエッジを変更するような場合もいくつかある。ウィンドウの再結合を参照のこと。ウィンドウの下端か右端のエッジを移動することだけでリサイズするには関数adjust-window-trailing-edge
を使用すること。
この関数はwindowの下端エッジをdelta行分移動する。オプション引数horizontalが非nil
なら、かわりに右端エッジをdelta列分移動する。windowがnil
の場合のデフォルトは選択されたウィンドウ。
オプション引数pixelwiseが非nil
ならdeltaはピクセル単位として解釈される。
正のdeltaはエッジを下方か右方へ移動し、負のdeltaはエッジを上方か左方へ移動する。deltaで指定された範囲までエッジを移動できなければ、この関数はエラーをシグナルすることなく可能な限りエッジを移動する。
この関数は移動されたエッジに隣接するウィンドウのリサイズを試みる。何らかの理由(隣接するウィンドウが固定サイズの場合等)によりそれが不可能なら、他のウィンドウをリサイズするかもしれない。
このオプションの値が非nil
ならEmacsはウィンドウをピクセル単位でリサイズする。これは現在のところsplit-window
(ウィンドウの分割を参照)、maximize-window
、minimize-window
、fit-window-to-buffer
、fit-frame-to-buffer
、shrink-window-if-larger-than-buffer
(すべて以下に記述)のような関数に影響を与える。
あるフレームのピクセルサイズがそのフレームの文字サイズの整数倍でないときは、たとえこのオプションがnil
であっても少なくとも1つのウィンドウがピクセル単位でリサイズされるであろうことに注意。デフォルト値はnil
。
以下のコマンドは、より具体的な方法でウィンドウをリサイズします。これらがインタラクティブに呼び出されたときは選択されたウィンドウにたいして作用します。
このコマンドはwindowの高さか幅をウィンドウ内のテキストにフィットするように調整する。windowがリサイズできたら非nil
、それ以外はnil
をリターンする。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ、それ以外の場合には生きたウィンドウであること。
windowが垂直コンビネーションの一部なら、この関数はwindowの高さを調整する。新たな高さはそのウィンドウのバッファーのアクセス可能な範囲の実際の高さから計算される。オプション引数max-heightが非nil
なら、それはこの関数がwindowに与えることができる最大のトータル高さを指定する。オプション引数min-heightが非nil
なら、それは与えることができる最小のトータル高さを指定して、それは変数window-min-height
をオーバーライドする。max-heightとmin-heightはいずれも、(もしあれば)モードライン、ヘッダーライン、下端ディバイダーを含む行数で指定する。
windowが水平コンビネーションの一部で、かつオプションfit-window-to-buffer-horizontally
(以下参照)の値が非nil
なら、この関数はwindowの幅を調整する。新たな幅はwindowのカレントのスタート位置以降のバッファーの最長の行から計算される。オプション引数max-widthは最大幅を指定し、デフォルトはwindowのフレーム幅。オプション引数min-widthは最小幅を指定し、デフォルトはwindow-min-width
。max-widthとmin-widthはいずれも、(もしあれば)フリンジ、マージン、スクロールバーを含む列数で指定する。
オプション引数preserve-sizeが非nil
なら、将来のリサイズ操作の間のwindowのサイズを予約するパラメーターをインストールする(Preserving Window Sizesを参照)。
オプションfit-frame-to-buffer
(以下参照)が非nil
なら、この関数はfit-frame-to-buffer
(以下参照)を呼び出すことにより、windowのコンテンツにフィットするようにwindowのフレームのリサイズを試みるだろう。
これが非nil
なら、fit-window-to-buffer
はウィンドウを水平方向にリサイズできる。これがnil
(デフォルト)ならfit-window-to-buffer
はウィンドウ決して水平方向にリサイズしない。これがonly
ならウィンドウを水平方向だけにリサイズできる。その他の値ではfit-window-to-buffer
がウィンドウをどちらの方向にもリサイズできることを意味する。
このオプションが非nil
なら、fit-window-to-buffer
はフレームをフレームのコンテンツにフィットさせることができる。フレームは、フレームのルートウィンドウが生きたウィンドウで、かつこのオプションが非nil
の場合のみフィットされる。horizontally
ならフレームは水平方向にのみフィットされる。vertically
ならフレームは垂直方向にのみフィットされる。その他の非nil
値はフレームがどちらの方向にもフィットできることを意味する。
単一のウィンドウだけを表示するフレームではコマンドfit-frame-to-buffer
を使用してそのバッファーにフレームをフィットできます。
このコマンドはframeのサイズを、表示しているバッファーのコテンツに正確に調整する。frameには任意の生きたフレームを指定できデフォルトは選択されたフレーム。frameのルートウィンドウが生きている場合のみフィットが行われる。引数max-height、min-height、max-width、min-widthはframeのルートウィンドウの新たなトータルサイズの境界を指定する。min-heightとmin-widthのデフォルトはそれぞれwindow-min-height
とwindow-min-width
。
この関数はオプション引数onlyがvertically
なら垂直方向のみ、onlyがhorizontally
なら水平方向のみフレームをリサイズする。
fit-frame-to-buffer
の振る舞いは次にリストする2つのオプションで制御可能です。
このオプションはfit-frame-to-buffer
によりフィットされるフレーム周囲のマージンの指定に使用できる。このようなマージンは、たとえばフレームとタスクバーが重なることを回避するために有用。
これはフィットされるフレームの左右上下にフリーとして残されるピクセル数を指定する。デフォルトのnil
はそれぞれにたいしてマージンを使用しないことを指定する。ここで指定した値は、特定のフレームにたいしてもしそのフレームのfit-frame-to-buffer-margins
が与えられればオーバーライドされ得る。
このオプションはfit-frame-to-buffer
にたいしてサイズ境界を指定する。これは自身のバッファーにフィットされる任意のフレームのルートウィンドウの最大行と最小行、最大列と最小列のトータルを指定する。これらの値のいずれかが非nil
なら、fit-frame-to-buffer
の対応する引数をオーバーライドする。
このコマンドはwindowにたいしてそのバッファーを完全に表示できるが、window-min-height
以上の行を表示できるまで可能な限りwindowの高さを縮小する。リターン値はそのウィンドウがリサイズされれば非nil
、それ以外なら非nil
。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。それ以外では生きたウィンドウであること。
このコマンドはそのウィンドウがバッファーのすべてを表示するにはすでに高さが低すぎる場合、バッファーのどこかがスクリーンからスクロールオフされている場合、またはそのウィンドウがフレーム内で唯一の生きたウィンドウの場合は何も行わない。
このコマンドは自身の処理を行うためにfit-window-to-buffer
(上記参照)を呼び出す。
この関数は各ウィンドウにたいして完全な幅、および/または完全な高さを与えるような方法によって各ウィンドウのバランスをとる。window-or-frameにフレームを指定すると、そのフレーム上のすべてのウィンドウのバランスをとる。window-or-frameにウィンドウを指定すると、そのウィンドウとウィンドウのsiblings(兄弟)にたいしてのみのバランスをとる(ウィンドウとフレームを参照)。
この関数は選択されたフレーム上のすべてのウィンドウにたいして、おおよそ同じスクリーンエリアを与えようと試みる。完全な幅か高さをもつウィンドウにたいしては、他のウィンドウと比較してより多くのスペースは与えられない。
この関数は、windowにたいして、そのフレームをリサイズしたり他のウィンドウを削除することなく、水平垂直の両方向で可能な限り大きくなるように試みる。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。
この関数はwindowにたいして、そのフレームをリサイズしたりそのウィンドウを削除することなく、水平垂直の両方向で可能な限り小さくなるように試みる。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウは前セクションのいずれかの関数を使用して明示的にリサイズされたり、たとえばウィンドウの調整、ウィンドウの分割(ウィンドウの分割を参照)や削除(ウィンドウの削除を参照)、またはウィンドウのフレームのリサイズ(Size and Positionを参照)の際に暗黙にリサイズされるかもしれません。
同一フレーム上に1つ以上のリサイズ可能なウィンドウが他に存在する際には、特定のウィンドウにたいして暗黙のリサイズを避けることが可能です。この目的にたいして、Emacsにそのウィンドウのサイズの予約(preserve)をアドバイスしなければなりません。これを行うための基本的な方法が2つあります。
このバッファーローカル変数が非nil
なら、通常はそのバッファーを表示するすべてのウィンドウのサイズが変更できなくなる。ウィンドウ削除やそのフレームのサイズ変更により、それ以外に方法がなければ依然としてウィンドウのサイズは変更され得る。
値がheight
ならそのウィンドウの高さのみ、値がwidth
ならそのウィンドウの幅のみが固定される。その他の非nil
値では幅と高さの両方が固定される。
この変数がnil
でも、そのバッファーを表示している任意のウィンドウを任意の方向にリサイズできるとはいえない。これを判断するには関数window-resizable
を使用する。ウィンドウのリサイズを参照のこと。
影響を受けるウィンドウにたいする明示的なリサイズや分割の試みも同様に抑制するので、window-size-fixed
の積極性が過度な場合が多々あります。これはたとえそのウィンドウが暗黙にリサイズされた後にも、たとえば隣接するウィンドウの削除やウィンドウのフレームのリサイズの際に発生するかもしれません。以下の関数では、そのようなウィンドウのリサイズを絶対禁止としないよう試みます:
この関数は将来のリサイズ操作用にウィンドウwindowの高さを予約済み(preserved)としてマーク(または非マーク)する。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。オプション引数horizontalが非nil
ならwindowの幅を予約済みとしてマーク(または非マーク)する。
オプション引数preserveがt
ならwindowボディーのカレントの高さまたは幅を予約することを意味する。windowの高さまたは幅はEmacsが他によい選択をもたないときのみ変更される。この関数により予約されたウィンドウにたいする高さや幅のリサイズは決してエラーをthrowしない。
preserveがnil
なら、この関数の以前の呼び出しにより誘発されたwindowにたいする任意の拘束を解除して、windowの高さまたは幅の予約を停止することを意味する。引数にwindowを与えてenlarge-window
、shrink-window
、fit-window-to-buffer
を呼び出すことによっても対応する高速を削除できる。
現在のことろwindow-preserve-size
は以下の関数から呼び出されています:
fit-window-to-buffer
この関数のオプション引数preserve-sizeが非nil
なら、この関数により確保されたサイズは予約される(ウィンドウのリサイズを参照)。
display-buffer
この関数のalist引数にpreserve-size
エントリーがあれば、この関数により生成されるウィンドウサイズは予約される(表示するウィンドウの選択を参照)。
window-preserve-size
はウィンドウリサイズ関数に参照される、preserved-size
と呼ばれるウィンドウパラメーター(ウィンドウのパラメーターを参照)をインストールする。ウィンドウがwindow-preserve-size
呼び出し時に表示していたバッファーと異なるバッファーを表示していたり、呼び出し後にサイズが変更されていたら、このパラメーターはウィンドウのリサイズを妨げない。
以下の関数は特定のウィンドウの高さが予約済みかどうかチェックするために使用できます:
この関数はウィンドウwindowの予約済み高さをピクセル単位でリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。オプション引数horizontalが非nil
ならwindowの予約済み幅をリターンする。windowのサイズが予約されていなければnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは既存のウィンドウを分割(split: スプリットすることによって新たにウィンドウを作成する関数について説明します。
この関数はウィンドウwindowの隣に生きたウィンドウを新たに作成する。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。そのウィンドウは分割(split)されてサイズは縮小される。そのスペースはリターンされる新たなウィンドウによって吸収される。
オプションの第2引数sizeは、windowおよび/または新たなウィンドウのサイズを決定する。これが省略またはnil
なら、両方のウィンドウに同じサイズが割り当てられる。行数が奇数なら、余りの1行は新たなウィンドウに割り当てられる。sizeが正の数値なら、windowにsizeの行数(sideの値によっては列数)が与えられる。sizeが負の数値なら、新たなウィンドウに-sizeの行数(または列数)が与えられる。
sizeがnil
なら、この関数は変数window-min-height
とwindow-min-width
にしたがう(ウィンドウのサイズを参照)。つまり分割によりこれらの変数の指定より小さいウィンドウが作成されるようならエラーをシグナルする。しかしsizeにたいして非nil
値を指定すると、これらの変数は無視される。その場合には許容される最小のウィンドウはテキストエリアの高さが1行、および/または幅が2列のウィンドウとみなされる。
したがってsizeが指定された場合には、生成されるウィンドウがモードラインやスクロールバー等すべてのエリアを含むのに十分な大きさがあるかどうかチェックするのは呼び出し側の責任である。これに関して必要最小限のwindowを決定するために関数window-min-size
(ウィンドウのサイズを参照)を使用できる。新たなウィンドウは通常はモードラインやスクロールバー等のエリアをwindowから継承するので、この関数は新たなウィンドウの最小サイズも良好に推定する。呼び出し側は、次回の再表示前にこれに応じて継承されたエリアを削除する場合のみ、より小さなサイズを指定すること。
オプションの第3引数sideは新たなウィンドウの位置をwindowから相対的に指定する。nil
またはbelow
なら新たなウィンドウはwindowの下、above
ならwindowの上に配置される。どちらの場合でもsizeはウィンドウのトータル高さを行数で指定する。
sideがt
かright
なら新たなウィンドウはwindowの右、sideがleft
ならwindowの左に配置される。どちらの場合でもsizeはウィンドウのトータル幅を列数で指定する。
オプションの第4引数pixelwiseが非nil
なら、sizeを行や列ではなくピクセル単位で解釈することを意味する。
windowが生きたウィンドウの場合には、新たなウィンドウはマージンやスクロールバーを含むさまざまなプロパティを継承する。windowが内部ウィンドウ(internal window)の場合には、新たなウィンドウはwindowのフレームのプロパティを継承する。
変数ignore-window-parameters
がnil
の場合に限り、この関数の挙動はwindowなパラメーターにより変更されるかもしれない。ウィンドウパラメーターsplit-window
の値がt
なら、この関数はその他すべてのウィンドウパラメーターを無視する。それ以外ではウィンドウパラメーターsplit-window
の値が関数の場合には、split-window
の通常アクションのかわりに引数window、size、sideでその関数が呼び出される。値が関数以外なら、この関数は(もしあれば)ウィンドウパラメーターwindow-atom
またはwindow-side
にしたがう。ウィンドウのパラメーターを参照のこと。
例としてウィンドウとフレームで議論したウィンドウ構成(window
configuration)を得るための、一連のsplit-window
呼び出しを以下に示します。この例では生きたウィンドウの分割と、内部ウィンドウの分割も示しています。最初はW4で表される単一のウィンドウ(生きたルートウィンドウ)を含むフレームから開始します。(split-window
W4)
を呼び出すことにより以下のウィンドウ構成が得られます。
______________________________________ | ____________________________________ | || || || || || || ||_________________W4_________________|| | ____________________________________ | || || || || || || ||_________________W5_________________|| |__________________W3__________________|
split-window
呼び出しによりW5で示す生きたウィンドウが新たに作成されました。W3で示される内部ウィンドウも新たに作成され、これはルートウィンドウかつW4とW5の親ウィンドウになります。
次は引数として内部ウィンドウW3を渡して(split-window W3 nil 'left)
を呼び出します。
______________________________________ | ______ ____________________________ | || || __________________________ || || ||| ||| || ||| ||| || ||| ||| || |||____________W4____________||| || || __________________________ || || ||| ||| || ||| ||| || |||____________W5____________||| ||__W2__||_____________W3_____________ | |__________________W1__________________|
内部ウィンドウW3の左に生きたウィンドウW2が新たに作成されました。そして内部ウィンドウW1が新たに作成され、これが新たにルートウィンドウになります。
インタラクティブな使用にたいして、Emacsは選択されたウィンドウを常に分割するコマンドを2つ提供します。これらは内部でsplit-window
を呼び出しています。
この関数は選択されたウィンドウが左となるように、横並びの2つのウィンドウに分割する。sizeが正ならば左のウィンドウがsize列、負ならば右のウィンドウが-size列を与えられる。
この関数は選択されたウィンドウが上となるような、縦並びの2つのウィンドウに分割する。sizeが正ならば上のウィンドウがsize行、負ならば下のウィンドウが-size行を与えられる。
この変数の値が非nil
(デフォルト)ならsplit-window-below
は上述のように振る舞う。
nil
ならsplit-window-below
は再表示が最小となるように、2つのウィンドウの各ポイントを調節する(これは低速な端末で有用)。これは何であれ、以前ポイントがあったスクリーン行(screen
line)を含むウィンドウを選択する。これは低レベルsplit-window
関数ではなくsplit-window-below
だけに影響することに注意。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウを削除(delete)することにより、フレームのウィンドウツリーからウィンドウが取り除かれます。それが生きたウィンドウならスクリーンに表示されなくなります。内部ウィンドウならその子ウィンドウも削除されます。
ウィンドウを削除した後であっても、それへの参照が残っている限りはLispオブジェクトとして存在し続けます。ウィンドウ構成(window configuration)をリストアすることにより、ウィンドウの削除は取り消すことができます(ウィンドウの構成を参照)。
この関数は表示からwindowを削除してnil
をリターンする。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。そのウィンドウを削除するとウィンドウツリーにウィンドウが存在しなくなるような場合(それがフレーム内で唯一の生きたウィンドウである場合等)はエラーをシグナルする。
デフォルトではwindowが占めていたスペースは、(もしあれば)隣接する兄弟ウィンドウのうちの1つに与えられる。しかし変数window-combination-resize
が非nil
なら、そのスペースは同一ウィンドウコンビネーション内の残りのすべてのウィンドウに比例的に分配される。See section ウィンドウの再結合を参照のこと。
変数ignore-window-parameters
がnil
の場合に限り、この関数の振る舞いはwindowのウィンドウパラメーターにより変更される可能性がある。ウィンドウパラメーターdelete-window
の値がt
なら、この関数はその他すべてのウィンドウパラメーターを無視する。ウィンドウパラメーターdelete-window
が関数なら、通常のdelete-window
のかわりに引数windowでその関数が呼び出される。それ以外では、この関数は(もしあれば)ウィンドウパラメーターwindow-atom
またはwindow-side
にしたがう。ウィンドウのパラメーターを参照のこと。
この関数は必要に応じて他のウィンドウを削除することによりwindowでフレームを充填する。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。リターン値はnil
。
変数ignore-window-parameters
がnil
の場合に限り、この関数の振る舞いは変更される可能性がある。ウィンドウパラメーターdelete-other-windows
の値がt
なら、この関数は他のすべてのウィンドウパラメーターを無視する。ウィンドウパラメーターdelete-other-windows
の値が関数なら、delete-other-windows
の通常の動作のかわりに引数windowでその関数が呼び出される。それ以外では、この関数は(もしあれば)ウィンドウパラメーターwindow-atom
またはwindow-side
にしたがう。ウィンドウのパラメーターを参照のこと。
この関数はbuffer-or-nameを表示しているすべてのウィンドウにたいしてdelete-window
を呼び出すことによってそれらを削除する。buffer-or-nameはバッファー、またはバッファー名であること。省略またはnil
の場合のデフォルトはカレントバッファー。指定されたバッファーを表示するウィンドウが存在しなければ、この関数は何も行わない。ミニバッファーが指定されるとエラーをシグナルする。
そのバッファーの表示に専用(dedicated)のウィンドウがあり、フレーム上でそれが唯一のウィンドウの場合には、それが端末上で唯一のフレームでなければこの関数はそのフレームも削除する。
オプション引数frameは操作を行うフレームがどれかを指定する:
nil
すべてのフレームを処理することを意味する。
t
選択されたフレームを処理することを意味する。
visible
可視なすべてのフレームを処理することを意味する。
0
可視またはアイコン化されたすべてのフレームを処理することを意味する。
この引数の意味は、すべての生きたウィンドウを走査する他の関数(ウィンドウのサイクル順を参照)の場合とは異なることに注意。特にここでのt
とnil
のもつ意味は、これら他の関数の場合とは逆になる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウWの最後の兄弟を削除したときは、ウィンドウツリー内の親ウィンドウをWを置き換えることにより、その親ウィンドウも削除されます。これは新たなウィンドウコンビネーションを形成するために、Wがその親の兄弟たちと再結合されなければならないことを意味します。生きたウィンドウを削除することにより、必然的に2つの内部ウィンドウが削除されるかもしれない場合もあります。
______________________________________ | ______ ____________________________ | || || __________________________ || || ||| ___________ ___________ ||| || |||| || |||| || ||||____W6_____||_____W7____|||| || |||____________W4____________||| || || __________________________ || || ||| ||| || ||| ||| || |||____________W5____________||| ||__W2__||_____________W3_____________ | |__________________W1__________________|
この構成におけるW5の削除は、通常はW3とW4の削除を誘発します。残りの生きたウィンドウW2、W6、W7は親をW7とする水平コンビネーションを形成するために再結合されます。
しかし、ときにはW4のような親ウィンドウを削除しないほうが合理的な場合もあります。特に親ウィンドウが同じタイプのコンビネーション内に埋め込まれるコンビネーションを保護するために使用されるときは、それを削除するべきではありません。そのような埋め込みは、あるウィンドウを分割した後に続けて新たなウィンドウを削除する際、Emacsが関連するフレームで分割前にあったレイアウトを確実に再構築するために意味があります。
親がW1であるような2つの生きたウィンドウW2とW3を出発点とするシナリオを考えてみましょう。
______________________________________ | ____________________________________ | || || || || || || || || || || || || ||_________________W2_________________|| | ____________________________________ | || || || || ||_________________W3_________________|| |__________________W1__________________|
W2を分割すると以下のようにウィンドウW4が新たに作成されます。
______________________________________ | ____________________________________ | || || || || ||_________________W2_________________|| | ____________________________________ | || || || || ||_________________W4_________________|| | ____________________________________ | || || || || ||_________________W3_________________|| |__________________W1__________________|
ここでウィンドウを垂直方向に拡大すると、Emacsはもしそのようなウィンドウがあれば下位の兄弟ウィンドウから対応するスペースを得ようと試みます。このシナリオではW4の拡大により、W3からスペースが奪われます。
______________________________________ | ____________________________________ | || || || || ||_________________W2_________________|| | ____________________________________ | || || || || || || || || ||_________________W4_________________|| | ____________________________________ | ||_________________W3_________________|| |__________________W1__________________|
W4を削除すると、前にW3から奪ったスペースを含むスペース全体がW2に与えられるでしょう。
______________________________________ | ____________________________________ | || || || || || || || || || || || || || || || || ||_________________W2_________________|| | ____________________________________ | ||_________________W3_________________|| |__________________W1__________________|
これは特にW4が一時的にバッファーを表示するために使用されていて(一時的な表示を参照)、かつ初期のレイアウトで作業を継続したい場合には直感に反するかもしれません。
この振る舞いはW2を分割する際に新たな親ウィンドウを作成することにより解決できます。
この変数はウィンドウ分割により新たに親ウィンドウを作成させるかどうかを制御する。以下の値が認識される:
nil
これは既存のウィンドウコンビネーションと同じ方向で分割が発生した場合(これ以外の場合には、いずれにせよ内部ウィンドウが新たに作成される)は、既存の親ウィンドウが存在するなら新たな生きたウィンドウがそれを共有できることを意味する。
window-size
この場合には、display-buffer
はalist引数内のエントリーwindow-height
またはwindow-width
に親ウィンドウが渡されれば、新たに親ウィンドウを作成する(display-buffer
にたいするアクション関数を参照)。
temp-buffer
この値は一時的なバッファーを表示するウィンドウの分割に際し新たに親ウィンドウを作成する。
display-buffer
これはdisplay-buffer
(表示するウィンドウの選択を参照)がウィンドウを分割する際に常に親ウィンドウを新たに作成することを意味する。
t
この場合にはウィンドウを分割する際、常に親ウィンドウが新たに作成される。したがってこの変数の値が常にt
なら、すべてのウィンドウツリーは常に2分木(ルートウィンドウ以外のすべてのウィンドウが正確に1つの兄弟をもつようなツリー)になる。
デフォルトはnil
で、これら以外の値は将来のために予約済み。
この変数のセッティングの結果としてsplit-window
が新たに親ウィンドウを作成したら、新たに作成された内部ウィンドウにたいしてset-window-combination-limit
(以下参照)も呼び出す。これは子ウィンドウが削除された際のウィンドウツリーの再配置に影響する(以下参照)。
window-combination-limit
がt
なら、このシナリオの初期構成では以下のようになるでしょう:
______________________________________ | ____________________________________ | || __________________________________ || ||| ||| |||________________W2________________||| || __________________________________ || ||| ||| |||________________W4________________||| ||_________________W5_________________|| | ____________________________________ | || || || || ||_________________W3_________________|| |__________________W1__________________|
子としてW2と新たな生きたウィンドウをもつ内部ウィンドウW5が新たに作成されます。ここでW2はW4の唯一の兄弟なので、W4を拡大するとW3は変更せずにW2の縮小を試みるでしょう。W5は垂直コンビネーションW1に埋め込まれた2つのウィンドウからなる垂直コンビネーションを表すことに注意してください。
この関数はウィンドウwindowのコンビネーションリミット(combination limit:
結合限界)をlimitにセットする。この値は関数window-combination-limit
を通じて取得できる。効果については以下を参照のこと。これは内部ウィンドウにたいしてのみ意味をもつことに注意。split-window
は呼び出された際に変数window-combination-limit
がt
なら、t
をlimitとしてこの関数を呼び出す。
この関数はwindowにたいするコンビネーションリミットをリターンする。
コンビネーションリミットは内部ウィンドウにたいしてのみ意味をもつ。これがnil
ならEmacsはウィンドウ削除に応じて、兄弟同士で新たなウィンドウコンビネーションを形成することによりwindowの子ウィンドウをグループ化するために、windowの自動的な削除を許す。コンビネーションリミットがt
ならwindowの子ウィンドウがその兄弟と自動的に再結合されることは決してない。
このセクションの冒頭で示した構成の場合は、W4
(W6とW7の親ウィンドウ)のコンビネーションリミットはt
なのでt
を削除しても暗黙でW4も削除されることはない。
かわりに同じ構成内の中の1つのウィンドウが分割や削除されたときは、常に構成内のすべてのウィンドウをリサイズすることにより上記で示した問題を避けることができます。これはそのような操作にたいして、この方法以外では小さすぎるようなウィンドウの分割も可能にします。
この変数がnil
なら、split-window
はウィンドウ(以下window)自身と新たなウィンドウの両方にたいして、windowのスクリーンエリアが十分大きい場合のみwindowを分割できる。
この変数がt
なら、split-window
は新たなウィンドウに対応するためにwindowと同一コンビネーション内のすべてのウィンドウのリサイズを試みる。これは特にwindowが固定サイズウィンドウのときや、通常の分割には小さすぎるときもsplit-window
をが成功することを許す。さらに続けてwindowのリサイズや削除を行うと、そのコンビネーション内のその他すべてのウィンドウをリサイズする。
デフォルトはnil
で、それ以外の値は将来の使用のため予約済み。この変数の値はwindow-combination-limit
が非nil
なら無視される。
window-combination-resize
の効果を説明するために以下のフレームレイアウトを考えてください。
______________________________________ | ____________________________________ | || || || || || || || || ||_________________W2_________________|| | ____________________________________ | || || || || || || || || ||_________________W3_________________|| |__________________W1__________________|
window-combination-resize
がnil
なら、ウィンドウW3を分割してもW2のサイズは変更されません:
______________________________________ | ____________________________________ | || || || || || || || || ||_________________W2_________________|| | ____________________________________ | || || ||_________________W3_________________|| | ____________________________________ | || || ||_________________W4_________________|| |__________________W1__________________|
window-combination-resize
がt
なら、W3を分割すると3つの生きたウィンドウすべてをおおよそ同じ高さにします:
______________________________________ | ____________________________________ | || || || || ||_________________W2_________________|| | ____________________________________ | || || || || ||_________________W3_________________|| | ____________________________________ | || || || || ||_________________W4_________________|| |__________________W1__________________|
生きたウィンドウW2、W3、W4のいずれを削除しても、削除されたウィンドウのスペースは残りの2つの生きたウィンドウに相対的に分配されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はwindowを選択されたウィンドウにして、そのフレーム内で選択されたウィンドウ(Emacsウィンドウの基本概念を参照)にしてそのフレームを選択する。またwindowのバッファー(バッファーとウィンドウを参照)をカレントにして、そのバッファーのpoint
の値(ウィンドウとポイントを参照)をwindowのwindow-point
の値にセットする。windowは生きたウィンドウでなければならない。リターン値はwindow。
この関数はデフォルトではwindowのバッファーをバッファーリストの先頭(バッファーリストを参照)に移動して、windowをもっとも最近選択されたウィンドウにする。しかしオプション引数norecordが非nil
ならこれらの追加処理は省略される。
この関数はnorecordがnil
ならbuffer-list-update-hook
(バッファーリスト)を実行する。コーディングを単純化するためにアプリケーションや内部ルーチンは、しばしばウィンドウを一時的に選択することがあることに注意。一般的にはそのような選択(以下のマクロsave-selected-window
とwith-selected-window
による選択も含む)は記録されないので、buffer-list-update-hook
の汚染は避けられる。選択を実際にカウントするのはwindowのフレームの次回表示時に可視の変更が発生したときで、それらは常に記録されるべきである。これは、あるウィンドウが選択されるたびに関数を実行するためには、それをbuffer-list-update-hook
に配置するのが良い選択であることも意味している。
引数norecordに非nil
を指定したselect-window
の連続呼び出しは、ウィンドウの並び順を選択時刻により決定します。関数get-lru-window
は、もっとも昔に選択された生きたウィンドウ(ウィンドウのサイクル順を参照)を取得するために使用できます。
このマクロは選択されたフレーム、同様に各フレームの選択されたウィンドウを記録して、formsを順に実行してから以前に選択されていたフレームとウィンドウをリストアする。これはカレントバッファーの保存とリストアも行う。リターン値はforms内の最後のフォームの値。
このマクロはウィンドウのサイズ、コンテンツ、配置についての保存やリストアは何も行わない。したがってformsがそれらを変更すると、その変更は永続化される。あるフレームにおいて以前に選択されていたウィンドウがformsのexit時にすでに生きていなければ、そのフレームの選択されたウィンドウはそのまま放置される。以前に選択されていたウィンドウがすでに生きていなければformsの最後に選択されていたウィンドウが何であれ、それが選択されたままになる。カレントバッファーformsのexit時にそれが生きている場合のみリストアされる。
このマクロは、もっとも最近に選択されたウィンドウとバッファーリストの順番をいずれも変更しない。
このマクロはwindowを選択して、formsを順に実行してから以前に選択されていたウィンドウとカレントバッファーをリストアする。たとえば引数norecordをnil
でselect-window
を呼び出す等、forms内で故意に変更しない限り、もっとも最近に選択されたウィンドウとバッファーリストの順番は変更されない。
このマクロは、もっとも最近に選択されたウィンドウとバッファーリストの順番を変更しない。
この関数はフレームframe内で選択されているウィンドウをリターンする。frameは生きたフレームであること。省略またはnil
の場合のデフォルトは選択されたフレーム。
この関数はwindowをフレームframe内で選択されたウィンドウにする。frameは生きたフレームであること。省略またはnil
の場合のデフォルトは選択されたフレーム。windowは生きたウィンドウであること。省略またはnil
の場合のデフォルトは選択されたウィンドウ。
frameが選択されたフレームなら、windowを選択されたウィンドウにする。
オプション引数norecordが非nil
なら、この関数はもっとも最近に選択されたウィンドウのリストとバッファーリストをいずれも変更しない。
この関数はウィンドウwindowの使用回数をリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。
ウィンドウの使用回数(use
time)は実際にはtime値ではなく、nil
のnorecord引数によるselect-window
の呼び出しごとに毎回単調に増加する整数。通常は最小の使用回数をもつウィンドウはもっとも最近使用されていないウィンドウ(the
least recently used window)、最大の使用回数をもつウィンドウはもっとも最近使用されたウィンドウ(the most
recently used window)と呼ばれる(ウィンドウのサイクル順を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
他のウィンドウを選択するためにコマンドC-x o
(other-window
)を使う際には、特定の順番で生きたウィンドウを巡回します。与えられた任意のウィンドウ構成にたいして、この順序は決して変更されません。これはウィンドウのサイクル順序(cyclic
ordering of windows)と呼ばれます。
この順序は各フレームのリーフノードである生きたウィンドウを取得するために、ツリーを深さ優先で走査することにより決定されます(ウィンドウとフレームを参照)。ミニバッファーがアクティブならミニバッファーウィンドウも含まれます。この順序は巡回的(cyclic)なので、この順序の最後のウィンドウの次には最初のウィンドウが配置されます。
この関数はウィンドウのサイクル順でwindowの次の生きたウィンドウをリターンする。windowは生きたウィンドウであること。省略またはnil
の場合のデフォルトは選択されたウィンドウ。
オプション引数minibufは、サイクル順にミニバッファーウィンドウを含めるべきかどうかを指定する。minibufがnil
のときは、通常はミニバッファーウィンドウがカレントでアクティブな場合のみミニバッファーウィンドウが含まれる。これはC-x
oの振る舞いと合致する(ミニバッファーが使用されている限りミニバッファーウィンドウはアクティブであることに注意。ミニバッファーを参照)。
minibufがt
なら、サイクル順にはすべてのミニバッファーウィンドウが含まれる。minibufがt
とnil
のいずれとも異なる場合には、たとえアクティブであってもミニバッファーウィンドウは含まれない。
オプション引数all-framesは考慮にするフレームを指定する:
nil
はwindowのフレーム上にあるウィンドウを考慮することを意味する。(minibuf引数で指定されたことにより)ミニバッファーウィンドウが考慮される場合には、ミニバッファーウィンドウを共有するフレームも考慮される。
t
はすべての既存フレーム上のウィンドウを考慮することを意味する。
visible
はすべての可視フレーム上のウィンドウを考慮することを意味する。
複数のフレームが考慮される場合は、すべての生きたフレームのリストの順にしたがってそれらのフレームを順に追加することによりサイクル順を取得する(すべてのフレームを探すを参照)。
この関数はウィンドウのサイクル順においてwindowの前に位置する生きたウィンドウをリターンする。その他の引数はnext-window
の場合と同様に処理される。
この関数はウィンドウのサイクル順において、選択されたウィンドウからcount番目に位置する生きたウィンドウをリターンする。countが正の数ならcount個のウィンドウを前方にスキップし、負の数なら-count個のウィンドウを後方にスキップする。countが0なら選択されたウィンドウを単に再選択する.インタラクティブに呼び出された場合には、countはプレフィックス数引数。
オプション引数all-framesは、nil
のminibuf引数を指定したときのnext-window
の場合と同じ意味をもつ。
この関数は非nil
のウィンドウパラメーターno-other-window
をもつウィンドウを選択しない。
この関数は生きたウィンドウそれぞれにたいしてウィンドウを引数に関数funを呼び出す。
これはウィンドウのサイクル順にしたがう。オプション引数minibufとall-framesには、含まれるウィンドウセットを指定する。これらはnext-window
の引数の場合と同じ意味をもつ。all-framesがフレームを指定する場合には、最初に処理されるのはそのフレームの最初のウィンドウ(frame-first-window
がリターンするウィンドウ)であり、選択されたウィンドウである必要はない。
funがウィンドウの分割や削除によりウィンドウ構成を変更する場合でも、処理するウィンドウセットは初回のfun呼び出しに先立ち決定されるため変更されない。
この関数は選択されたウィンドウが唯一の生きたウィンドウならt
、それ以外はnil
をリターンする。
ミニバッファーウィンドウがアクティブなら、ミニバッファーウィンドウは通常は考慮される(そのためこの関数はnil
をリターンする)。しかしオプション引数no-miniが非nil
なら、たとえアクティブであってもミニバッファーウィンドウは無視される。オプション引数all-framesはnext-window
の場合と同じ意味をもつ。
以下は何らかの条件を満足するウィンドウを、それらを選択することなくリターンする関数です:
この関数は発見的に最近もっとも使用されていない生きたウィンドウをリターンする。オプション引数all-framesはnext-window
の場合と同じ意味をもつ。
フル幅のウィンドウが存在する場合にはは、それらのウィンドウだけが考慮される。ミニバッファーが候補になることは決してない。オプション引数dedicatedがnil
なら、専用バッファー(専用のウィンドウを参照)が候補になることは決してない。唯一の候補が選択されたウィンドウである場合以外は選択されたウィンドウを決してリターンしない。しかしオプション引数not-selectedが非nil
なら、そのような場合でもこの関数はnil
をリターンする。
この関数はget-lru-window
と同様だが、かわりにもっとも最近使用されたウィンドウをリターンする。引数の意味はget-lru-window
で説明と同様。
この関数は、もっとも大きいエリア(高さと幅の乗)をもつウィンドウをリターンする。オプション引数all-framesは検索するウィンドウを指定する。意味はnext-window
の場合と同様。
ミニバッファーウィンドウは決して候補とならない。オプション引数dedicatedがnil
なら、専用ウィンドウ(専用のウィンドウウィンドウを参照)は決して候補とならない。オプション引数not-selectedが非nil
なら、選択されたウィンドウは決して候補にならない。オプション引数not-selectedが非nil
、かつ唯一の候補が選択されたウィンドウなら、この関数はnil
をリターンする。
同サイズの候補ウィンドウが2つある場合には、この関数はウィンドウのサイクル順で選択されたウィンドウから数えて最初にあるウィンドウを優先する。
この関数はウィンドウのサイクル順内の各ウィンドウにたいして、そのウィンドウを引数として関数predicateを順に呼び出す。いずれかのウィンドウにたいしてpredicateが非nil
をリターンすると、この関数は処理を停止してそのウィンドウをリターンする。そのようなウィンドウが見つからなければリターン値はdefault
(これのデフォルトはnil
)。
オプション引数
minibufとall-framesは検索するウィンドウを指定する。意味はnext-window
の場合と同様。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではウィンドウのコンテンツを調べたりセットするための低レベルな関数を説明します。ウィンドウ内に特定のバッファーを表示するための高レベルな関数についてはウィンドウ内のバッファーへの切り替えを参照してください。
この関数はwindowが表示しているバッファーをリターンする。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。windowが内部ウィンドウならこの関数はnil
をリターンする。
この関数はwindowにbuffer-or-nameを表示させる。windowは生きたウィンドウであること。nil
の場合のデフォルトは選択されたウィンドウ。buffer-or-nameはバッファー、あるいは既存のバッファー名であること。この関数は選択されていたウィンドウを変更せず、カレントバッファーも直接変更しない(カレントバッファーを参照)。リターン値はnil
。
windowがあるバッファーにたいして特に専用(strongly dedicated)であり、かつbuffer-or-nameがそのバッファーを指定しなければ、この関数はエラーをシグナルする。専用のウィンドウを参照のこと。
デフォルトでは、この関数は指定されたバッファーのローカル変数にもとづいてwindowの位置、ディスプレイマージン、フリンジ幅、スクロールバーのセッティングをリセットする。しかしオプション引数keep-marginsが非nil
ならディスプレイマージンとフリンジ幅は未変更のままにする。
アプリケーションを記述する際には直接set-window-buffer
を呼び出さずに、通常はウィンドウ内のバッファーへの切り替えで説明する高レベルの関数を使用すること。
これはwindow-scroll-functions
の後にwindow-configuration-change-hook
を実行する。ウィンドウのスクロールと変更のためのフックを参照のこと。
このバッファーローカル変数はウィンドウ内にバッファーが表示された回数を記録する。。これはそのバッファーにたいしてset-window-buffer
が呼び出されるたびに増分される
このバッファーローカル変数はバッファーがウィンドウに最後に表示された時刻を記録する。バッファーが表示されたことがなければnil
をリターンする。これはそのバッファーにたいしてset-window-buffer
が呼び出されるたびにcurrent-time
がリターンする値により更新される(時刻を参照)。
この関数はウィンドウのサイクル順内で選択されたウィンドウを起点に、buffer-or-nameを表示する最初のウィンドウをリターンする(ウィンドウのサイクル順を参照)。そのようなウィンドウが存在しなければリターン値はnil
。
buffer-or-nameはバッファーかバッファーの名前であること。省略またはnil
の場合のデフォルトはカレントバッファー。オプション引数all-framesには考慮するウィンドウを指定する。
t
はすべての既存フレーム上のウィンドウを考慮することを意味する。
visible
はすべての可視フレーム上のウィンドウを考慮することを意味する。
これらの意味はnext-window
のall-frames引数の場合とは若干異なることに注意(ウィンドウのサイクル順を参照)。この不一致の解消のためにEmacsの将来のバージョンにおいて、この関数は変更されるかもしれない。
この関数はその時点でbuffer-or-nameを表示している、すべてのウィンドウのリストをリターンする。buffer-or-nameはバッファーまたは既存バッファーの名前であること。省略またはnil
の場合のデフォルトはカレントバッファー。カレントで選択されたウィンドウがbuffer-or-nameを表示していれば、それはこの関数がリターンするリストの先頭となる。
引数minibufとall-framesは、関数next-window
の場合と同じ意味をもつ(ウィンドウのサイクル順を参照)。all-frames引数は、get-buffer-window
の場合と正確に同じようには振る舞わないことに注意。
このコマンドはbuffer-or-nameを表示しているすべてのウィンドウで、それを他の何らかのバッファーに置き換える。buffer-or-nameはバッファーまたは既存のバッファーの名前であること。省略またはnil
の場合のデフォルトはカレントバッファー。
各ウィンドウで置き換えられるバッファーはswitch-to-prev-buffer
を通じて選択される(ウィンドウのヒストリーを参照)。buffer-or-nameを表示している専用ウィンドウは可能ならすべて削除される(専用のウィンドウを参照)。そのようなウィンドウがそのフレームで唯一のウィンドウで、かつ同一端末上に他のフレームが存在する場合には、そのフレームも同様に削除される。その端末上の唯一のフレームの唯一のウィンドウの場合は、いずれにせよそのバッファーは置き換えられる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは、あるウィンドウ内で特定のバッファーにスイッチするための高レベルな関数について説明します。“バッファーをスイッチする”とは一般的に、(1)そのバッファーをあるウィンドウに表示して、(2)そのウィンドウを選択されたウィンドウとし(かつそのフレームを選択されたフレームとし)、(3)そのバッファーウィンドウカレントバッファーにすることを意味します。
Lispプログラムがアクセスや変更できるように、バッファーを一時的にカレントにするためにこれらの関数を使用しないでください。これらはウィンドウヒストリー(ウィンドウのヒストリーを参照)の変更のような副作用をもつので、そのような方法での使用はユーザーを驚かせることになるでしょう。バッファーをLispで変更するためにカレントにしたければwith-current-buffer
、save-current-buffer
、set-buffer
を使用してください。カレントバッファーを参照してください。
このコマンドは選択されたウィンドウ内でbuffer-or-nameを表示して、それをカレントバッファーにしようと試みる。これはよくインタラクティブ(C-x bのバインディングで)に使用され、同様にLispプログラムでも使用される。リターン値はスイッチしたバッファー。
buffer-or-nameがnil
の場合のデフォルトはother-buffer
によりリターンされるバッファー(バッファーリストを参照)。buffer-or-nameが既存のバッファーの名前でない文字列なら、この関数はその名前で新たにバッファーを作成する。新たなバッファーのメジャーモードは変数major-mode
により決定される(メジャーモードを参照)。
通常は指定されたバッファーはバッファーリスト —
グローバルバッファーリストと選択されたフレームのバッファーリストの両方の先頭に置かれる(バッファーリストを参照)。しかしオプション引数norecordが非nil
なら、これは行われない。
選択されたウィンドウにそのバッファーを表示することが不適切なこともあるだろう。これは選択されたウィンドウがミニバッファーウィンドウの場合、および選択されたウィンドウがそのバッファーに特に専用(専用のウィンドウを参照)な場合に発生する。そのようなケースでは、このコマンドはpop-to-buffer
(以下参照)を呼び出すことにより、通常は別のウィンドウにバッファーの表示を試みる。
オプション引数force-same-windowが非nil
、かつ選択されたウィンドウがそのバッファーの表示に不適切なら、非インタラクティブに呼び出された際にはこの関数は常にエラーをシグナルする。インタクラクティブな使用においては、もし選択されたウィンドウがミニバッファーウィンドウなら、この関数はかわりに別のウィンドウの使用を試みる。選択されたウィンドウがそのバッファーにたいして特に専用なら、次に説明するオプションswitch-to-buffer-in-dedicated-window
が使用される。
このオプションが非nil
なら、switch-to-buffer
がインタラクティブに呼び出されて、かつ選択されたウィンドウがそのバッファーに特に専用な際に、処理を先に進めることが許される、
以下の値が許される:
nil
切り替えを許さず非インタラクティブな使用ではエラーをシグナルする。
prompt
切り替えを許すかどうかユーザーに確認を求める。
pop
処理を行うためにpop-to-buffer
を呼び出す。
t
選択されたウィンドウを非専用としてマークして処理を進める。
このオプションは非インタラクティブなswitch-to-buffer
の呼び出しには影響しない。
デフォルトではswitch-to-buffer
はバッファーのpoint
位置でバッファーを表示します。この振る舞いは以下のオプションを使用して調整可能です。
この変数がnil
なら、switch-to-buffer
はbuffer-or-nameにより指定されたバッファーを、そのバッファーのpoint
位置で表示する。この変数がalready-displayed
なら、そのバッファーが任意の可視またはアイコン化されたフレーム上の他のウィンドウで表示されていれば、選択されたウィンドウ内の以前の位置でバッファーの表示を試みる。この変数がt
なら、switch-to-buffer
は選択されたウィンドウ内の以前の位置でそのバッファーを表示しようと試みる。
この変数はバッファーがすでに選択されたウィンドウに表示されている、これまで表示されたことがない、またはバッファーを表示するためにswitch-to-buffer
がpop-to-buffer
を呼び出した場合には無視される。
以下の2つのコマンドは、説明している機能以外はswitch-to-buffer
と類似しています。
この関数はbuffer-or-nameで指定されたバッファーを、選択されたウィンドウ以外の別のウィンドウに表示する。これは関数pop-to-buffer
(以下参照)を内部で使用する。
選択されたウィンドウが指定されたバッファーをすでに表示していれば表示を続けるが、見つかった他のウィンドウも同様にそのバッファーを表示する。
引数buffer-or-nameとnorecordはswitch-to-buffer
の場合と同じ意味をもつ。
この関数はbuffer-or-nameで指定されたバッファーを新たなフレームに表示する。これは関数pop-to-buffer
(以下参照)を内部で使用する。
指定されたバッファーがすでにカレント端末上の任意のフレームの他のウィンドウに表示されている場合には、フレームを新たに作成せずにそのウィンドウに切り替える。しかしこれを行うために選択されたウィンドウを使用することは決してない。
引数buffer-or-nameとnorecordはswitch-to-buffer
の場合と同じ意味をもつ。
上述したコマンドは任意のウィンドウにバッファーを柔軟に表示して、編集用にそのウィンドウを選択する関数pop-to-buffer
を使用しています。次にpop-to-buffer
はバッファーの表示にdisplay-buffer
を使用します。したがってdisplay-buffer
に影響する変数も同様に影響します。display-buffer
のドキュメントについては表示するウィンドウの選択を参照してください。
この関数はbuffer-or-nameをカレントバッファーにして、なるべくカレントで選択されていたウィンドウではないウィンドウにそれを表示する。そしてその後に表示しているウィンドウを選択する。そのウィンドウが別のグラフィカルなフレーム上にある場合には、可能ならそのフレームが入力フォーカスを与えられる(入力のフォーカスを参照)。リターン値は切り替えたバッファー。
buffer-or-nameがnil
の場合のデフォルトはother-buffer
によりリターンされるバッファー(バッファーリストを参照)。buffer-or-nameが既存のバッファーの名前でない文字列なら、この関数はその名前で新たにバッファーを作成する。新たなバッファーのメジャーモードは変数major-mode
により決定される(メジャーモードを参照)。
actionが非nil
なら、それはdisplay-buffer
に渡すディスプレイアクション(display
action)であること(表示するウィンドウの選択を参照)。非nil
か非リスト値なら、たとえそのバッファーがすでに選択されたウィンドウに表示されていたとしても、選択されたウィンドウではなく別のウィンドウをポップ(pop)することを意味する。
この関数はswitch-to-buffer
と同じように、norecordがnil
ならバッファーリストを更新する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コマンドdisplay-buffer
は表示のために柔軟にウィンドウを選択して、そのウィンドウ内に指定されたバッファーを表示します。これはキーバインディングC-x
4
C-oを通じてインタラクティブに呼び出すことができます。またswitch-to-buffer
やpop-to-buffer
を含む多くの関数やコマンドにからサブルーチンとしても使用されます(ウィンドウ内のバッファーへの切り替えを参照)。
このコマンドはウィンドウ内に表示するウィンドウを探すために、いくつかの複雑なステップを実行します。これらのステップはディスプレイアクション(display
actions)を用いて記述されます。ディスプレイアクションは(function
.
alist)
という形式をもちます。ここで、functionは関数か関数リストであり、わたしたちはこれをアクション関数(action
functions)として参照します。alistは連想リスト(association
list)で、わたしたちはこれをアクションalist(action alist)として参照します。
アクション関数は表示するバッファーとアクションalistという、2つの引数を受け取ります。これは自身の条件にしたがってウィンドウウィンドウ選択または作成して、バッファーをウィンドウ内に表示します。成功した場合はそのウィンドウ、それ以外はnil
をリターンします。事前定義されたアクション関数についてはdisplay-buffer
にたいするアクション関数を参照してください。
display-buffer
は複数ソースからのディスプレイアクションを組み合わせて、アクション関数のいずれか1つがバッファーの表示を管理して非nil
値をリターンするまでアクション関数を順に呼び出します。
このコマンドは、ウィンドウウィンドウ選択したり、そのバッファーをカレントにすることなく、buffer-or-nameをウィンドウに表示させる。引数buffer-or-nameはバッファー既存のバッファーの名前でなければならない。リターン値はそのバッファーを表示するために選ばれたウィンドウ。
オプション引数actionが非nil
なら、それは通常はディスプレイアクション(上述)であること。display-buffer
は以下のソース(記載順)からディスプレイアクションを集約して、アクション関数リストとアクションalistを構築する:
display-buffer-overriding-action
。
display-buffer-alist
。
display-buffer-base-action
。
display-buffer-fallback-action
。
各アクション関数は、いずれかが非nil
をリターンするまで第1引数にバッファー、第2引数に組み合わせられたアクションalistで順番に呼び出される。呼び出し側はウィンドウ内にバッファーを表示しない場合を処理する用意があることを示すために、アクションalistの要素として(allow-no-window
. t)
を渡すことができる。
引数actionには非nil
の非list値も指定できる。これはたとえ選択されたウィンドウがすでにそのバッファーを表示していても、選択されたウィンドウではない別のウィンドウにバッファーが表示されるべきだという特別な意味をもつ。プレフィックス引数とともにインタラクティブに呼び出された場合には、actionはt
である。
オプション引数frameが非nil
なら、そのバッファーがすでに表示されているか判断する際に、どのフレームをチェックするかを指定する。これはactionのアクションalistに要素(reusable-frames
. frame)
を追加するのと等価。display-buffer
にたいするアクション関数を参照のこと。
この変数の値は、display-buffer
により最高の優先順で扱われるディスプレイアクションであること。デフォルト値は空(つまり(nil
. nil)
)。
このオプションの値はディスプレイアクションにコンディション(condition:
状態)をマップするalist。コンディションはそれぞれバッファー名にマッチする正規表現か2つの引数をとる関数であり、引数はバッファー名とdisplay-buffer
に渡すaction引数である。display-buffer
に渡されたバッファー名がこのalist内の正規表現にマッチするか、コンディションで指定された関数が非nil
をリターンした場合、display-buffer
はバッファーを表示すために対応するディスプレイアクションを使用する。
このオプションの値はディスプレイアクションであること。このオプションはdisplay-buffer
呼び出しにたいする標準のディスプレイアクションを定義するために使用できる。
このディスプレイアクションはdisplay-buffer
にたいして、他のディスプレイアクションが与えられなかった場合の代替え処理を指定する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
display-buffer
にたいするアクション関数以下の基本的なアクション関数がEmacs内で定義されています。これらの関数はそれぞれ表示するバッファーbufferとアクションalistという2つの引数をとります。それぞれのアクション関数は成功したらウィンドウ、失敗したらnil
をリターンします。
この関数は選択されたウィンドウ内にbufferの表示を試みる。選択されたウィンドウがミニバッファーウィンドウや他のバッファー専用(専用のウィンドウを参照)の場合には失敗する。alistに非nil
のinhibit-same-window
エントリーがある場合にも失敗する。
この関数はすでにbufferを表示しているウィンドウを探すことによりバッファーの表示を試みる。
alistに非nil
のinhibit-same-window
エントリーがある場合には、選択されたウィンドウは再利用に適さない。alistにreusable-frames
エントリーが含まれる場合には、その値により再利用可能なウィンドウをどのフレームで検索するか決定される:
nil
は選択されたフレーム(実際には最後の非ミニバッファーフレーム)上のウィンドウを考慮することを意味する。
t
はすべてのフレーム上のウィンドウを考慮することを意味する。
visible
はすべての可視フレーム上のウィンドウを考慮することを意味する。
これらはnext-window
にたいするall-frames引数の場合とは若干異なることに注意(ウィンドウのサイクル順を参照)。
alistにreusable-frames
エントリーが含まれなければ、この関数は通常は選択されたフレームだけを検索する。しかし変数pop-up-frames
が非nil
ならカレント端末上のすべてのフレームを検索する。バッファー表示の追加オプションを参照。
この関数が他のフレーム上のウィンドウを選択した場合には、そのフレームを可視にするとともに、alistがinhibit-switch-frame
エントリー(バッファー表示の追加オプションを参照)を含んでいなければ必要ならそのフレームを最前面に移動(raise)する。
この関数は新たにフレームを作成して、そのフレームのウィンドウ内にバッファーを表示する。これは実際にはpop-up-frame-function
(バッファー表示の追加オプションを参照)内で指定された関数を呼び出すことによりフレーム作成の処理を行う。alistがpop-up-frame-parameters
エントリーを含む場合には、その連想値(associated
value)が新たに作成されたフレームのパラメーターに追加される。
この関数は述語(デフォルトではカレント以外のすべてのフレーム)に合致するフレームを探すことによりbufferの表示を試みる。
この関数が他のフレーム上のウィンドウを選択した場合には、そのフレームを可視にするとともに、alistがinhibit-switch-frame
エントリー(バッファー表示の追加オプションを参照)を含んでいなければ必要ならそのフレームを最前面に移動(raise)する。
alistに非nil
のframe-predicate
エントリーがあれば、その値は1つの引数(フレーム)を受け取ってそのフレームが候補なら非nil
をリターンする、デフォルトの述語を置き換える関数。
alistに非nil
のinhibit-same-window
エントリーがあれば、選択されたウィンドウが使用される。つまり選択されたフレームにウィンドウが1つしかなければ、それは使用しない。
この関数は、最大のウィンドウ、もしくはもっとも長い間参照されていない(LRU: least
recently-used)ウィンドウを分割することによりbufferの表示を試みる。これは実際にはsplit-window-preferred-function
(バッファー表示の追加オプションを参照)内で指定された関数を呼び出すことによって分割を行う。
新たなウィンドウのサイズはalistにエントリーwindow-height
とwindow-width
を与えることにより調整できる。ウィンドウの高さを調整するにはCARがwindow-height
、CDRが以下のいずれかであるようなエントリーを使用する:
nil
は新たなウィンドウの高さを変更しないことを意味する。
shrink-window-if-larger-than-buffer
とfit-window-to-buffer
。ウィンドウのリサイズを参照のこと。
ウィンドウの幅を調整するにはCARがwindow-width
、CDRが以下のいずれかであるようなエントリーを使用する:
nil
は新たなウィンドウの幅を変更しないことを意味する。
alistにpreserve-size
エントリーが含まれるなら、Emacsは将来のリサイズ操作における、新たなウィンドウのサイズの予約を試みる(Preserving Window Sizesを参照)。このエントリーのCDRはコンスセルでなければならない。このコンスセルのCARが非nil
ならウィンドウの幅を予約し、CDRが非nil
ならウィンドウの高さを予約することを意味する。
この関数は何らかの理由により分割を行えるウィンドウが存在しなければ失敗する可能性がある(選択されたフレームがフレームパラメーターunsplittable
をもつ場合等。バッファーのパラメーターを参照)。
この関数は選択されたウィンドウの下のウィンドウ内にbufferの表示を試みる。これは選択されたウィンドウの分割、または選択されたウィンドウの下のウィンドウの使用を意味する。新たにウィンドウを作成した場合には、alistに適切なwindow-height
またはwindow-width
エントリーが含まれていればサイズの調整も行うだろう。上記を参照のこと。
この関数は以前にbufferを表示していたウィンドウ内にそのバッファーの表示を試みる。alistに非nil
のinhibit-same-window
エントリーがある場合には、選択されたウィンドウは再利用に適さない。alistにreusable-frames
エントリーが含まれる場合には、display-buffer-reuse-window
と同様に、その値は適正なウィンドウをどのフレームから検索するかを決定する。
alistにprevious-window
エントリーがある場合には、そのエントリーにより指定されたウィンドウは、たとえそのウィンドウが以前にbufferを表示したことが一度もなくても、上記メソッドが見つけた他のすべてのウィンドウをオーバーライドするだろう。
この関数は選択されたフレームの最下にあるウィンドウ内にbufferの表示を試みる。
これはフレーム最下のウィンドウまたはフレームのルートウィンドウを分割するか、選択されたフレーム最下の既存ウィンドウを再利用する。
この関数は既存のウィンドウを選択して、そのウィンドウ内にbufferを表示することによりバッファーの表示を試みる。すべてのウィンドウが他のバッファー専用なら、この関数は失敗する可能性がある(専用のウィンドウを参照)。
この関数はalistに非nil
のallow-no-window
エントリーがある場合にはbuffer
を表示しない。これによりデフォルトの動作をオーバーライドしてバッファーの表示を避けることができる。これは呼び出し側がallow-no-window
に非nil
値を指定してdisplay-buffer
からリターンされたnil
値を処理するようなケースを想定している。
アクション関数を説明するために以下の例を考えてみましょう。
(display-buffer (get-buffer-create "*foo*") '((display-buffer-reuse-window display-buffer-pop-up-window display-buffer-pop-up-frame) (reusable-frames . 0) (window-height . 10) (window-width . 40)))
上記のフォームを評価することにより、以下のようにdisplay-buffer
が実行されます:
(1)*foo*と呼ばれるバッファーがすでに可視またはアイコン化されたフレームに表示されていればそのウィンドウを再利用する。
(2)それ以外なら新たなウィンドウをポップアップ、それが不可能なら新たなフレームでバッファーを表示する。(3)
すべてのステップが失敗すると、それが何であれdisplay-buffer-base-action
とdisplay-buffer-fallback-action
が指示するものを使用して処理を行う。
さらにdisplay-buffer
は、(display-buffer
により*foo*が前からそこに配置されていたら)再使用されるウィンドウ、およびポップアップされたウィンドウにたいして調整を試みます。そのウィンドウが垂直コンビネーションの一部なら高さはその行数にセットされるでしょう。数字10のかわりに関数fit-window-to-buffer
を指定すると、display-buffer
は空のバッファーにフィットするようにウィンドウを1行にセットするでしょう。ウィンドウが水平コンビネーションの一部なら列数を40にセットします。新たなウィンドウが垂直または水平のどちらに組み合わせられるかは、ウィンドウの分割方向とsplit-window-preferred-function
、split-height-threshold
、split-width-threshold
の値に依存します(バッファー表示の追加オプションを参照)。
事前に以下のようなdisplay-buffer-alist
にたいするセットアップがあり、この呼び出しを組み合わせたとしましょう。
(let ((display-buffer-alist (cons '("\\*foo\\*" (display-buffer-reuse-window display-buffer-below-selected) (reusable-frames) (window-height . 5)) display-buffer-alist))) (display-buffer (get-buffer-create "*foo*") '((display-buffer-reuse-window display-buffer-pop-up-window display-buffer-pop-up-frame) (reusable-frames . 0) (window-height . 10) (window-width . 40))))
このフォームはまず選択されたフレーム上で*foo*を表示しているウィンドウを再利用するようにdisplay-buffer
に試行させます。そのようなウィンドウが存在しなければ、選択されたウィンドウの分割を試みるか、それが不可能なら選択されたウィンドウの下のウィンドウを使用します。
選択されたウィンドウの下にウィンドウがないか、下のウィンドウがそれのバッファーに専用なら、display-buffer
は前の例で説明したように処理を行うでしょう。しかし再利用されたウィンドウやポップアップされたウィンドウの高さ調整を試みる場合には、display-buffer
のaction引数内の行数に対応する指定をオーバーライドする行数5へのセットを試みることに注意してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
さまざまなユーザーオプションによりdisplay-buffer
の標準のディスプレイアクション(表示するウィンドウの選択を参照)を変更できます。
この変数の値が非nil
なら、display-buffer
は表示のために既存のバッファーを分割して新たなウィンドウを作成できる。
この変数は主に後方互換のために提供される。値がnil
のときはアクション関数display-buffer-pop-up-window
(display-buffer
にたいするアクション関数を参照)を呼び出すだけのdisplay-buffer-fallback-action
内の特別なメカニズムを経由してdisplay-buffer
にしたがう。この変数はdisplay-buffer-alist
等により直接指定できる、display-buffer-pop-up-window
自体からは参照されない。
この変数はバッファーを表示する新たなウィンドウを作成するためにウィンドウを分割する関数を指定する。これは実際にウィンドウを分割するためにアクション関数display-buffer-pop-up-window
により使用される(display-buffer
にたいするアクション関数を参照)。
デフォルト値split-window-sensibly
は以下で説明する。値はウィンドウを引数とする関数でなければならず、(要求されたバッファーを表示するために使用されるであろう)新たなウィンドウ、またはnil
(分割の失敗を意味する)をリターンしなければならない。
この関数はwindowを分割して新たに作成したウィンドウをリターンする。windowを分割できなければnil
をリターンする。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。
この関数はウィンドウが分割できるかどうか判断する際の通常のルールにしたがう(ウィンドウの分割を参照)。最初にまずsplit-height-threshold
(以下参照)とその他が課す制約の下に新たなウィンドウが下になるように分割を試みる。これが失敗したらsplit-width-threshold
(以下参照)が課す制約の下に新たなウィンドウが右になるように分割を試みる。これが失敗かつそのウィンドウがそのフレームの唯一のウィンドウなら、この関数はsplit-height-threshold
を無視して新たなウィンドウが下になるように再度分割を試みる。これも同様に失敗したら、この関数は諦めてnil
をリターンする。
これはsplit-window-sensibly
により使用される変数であり、ウィンドウを分割して新たなウィンドウを下に配置するかどうかを指定する。整数なら元のウィンドウが最低でもその行数なければ分割せず、nil
ならこの方法では分割しないことを意味する。
これはsplit-window-sensibly
により使用される変数であり、ウィンドウを分割して新たなウィンドウを右に配置するかどうかを指定する。整数なら元のウィンドウが最低でもその列数なければ分割せず、nil
ならこの方法では分割しないことを意味する。
この変数が非nil
なら、display-buffer
が既存ウィンドウを再利用する際は常にウィンドウサイズを選択されたウィンドウを均等にして、そのウィンドウを選択されたウィンドウに隣接させる。
値がwidth-only
なら再利用されるウィンドウが選択されたウィンドウの左か右にあり、かつ選択されたウィンドウが再利用されるウィンドウより広い場合のみサイズは均等になる。値がheight-only
なら再利用されるウィンドウが選択されたウィンドウの上か下にあり、かつ選択されたウィンドウが再利用されるウィンドウより高い場合のみサイズは均等になる。その他の非nil
値は、選択されたウィンドウと再利用されるウィンドウをコンビネーション的に比較して選択されたウィンドウの方が大ならサイズを均等にすることを意味する。
この変数の値が非nil
なら、新たにフレームを作成することによりdisplay-buffer
がバッファーを表示できることを意味する。デフォルトはnil
。
非nil
値はdisplay-buffer
がすでにbuffer-or-nameを表示しているウィンドウを探す際に、選択されたフレームだけでなく可視およびアイコン化されたフレームを検索できることも意味する。
この変数は主に後方互換のために提供されている。値が非nil
のときはアクション関数display-buffer-pop-up-frame
(display-buffer
にたいするアクション関数を参照)を呼び出すだけのdisplay-buffer-fallback-action
内の特別なメカニズムを経由してdisplay-buffer
にしたがう。この変数はdisplay-buffer-alist
等により直接指定できる、display-buffer-pop-up-window
自体からは参照されない(これはウィンドウの分割前に行われる)。この変数はdisplay-buffer-alist
等により直接指定できるdisplay-buffer-pop-up-frame
自体からは参照されない。
この変数はバッファーを表示する新たなウィンドウを作成するためにフレームを作成する関数を指定する。これはアクション関数display-buffer-pop-up-frame
により使用される(display-buffer
にたいするアクション関数を参照)。
値はフレーム、またはフレームを作成できなかったらnil
をリターンする引数をとらない関数であること。デフォルト値はpop-up-frame-alist
(以下参照)により指定されるパラメーターを使用してフレームを作成する関数。
この変数はフレームを新たに作成するためのpop-up-frame-function
のデフォルト関数により使用されるフレームパラメーター(フレームのパラメーターを参照)のalistを保持する。デフォルトはnil
。
選択されたウィンドウ内に表示されるべきバッファー名のリスト。このリスト内にバッファーの名前があれば、display-buffer
は選択されたウィンドウ内にそのバッファーを表示することによりそのバッファーを処理する。
選択されたウィンドウ内に表示されるバッファーを指定する正規表現のリスト。バッファー名がこのリスト内の正規表現のいずれかにマッチする場合には、display-buffer
は選択されたウィンドウ内にそのバッファーを表示することによりそのバッファーを処理する。
この関数はbuffer-nameという名前のバッファーをdisplay-buffer
で表示する場合に、それが選択されたウィンドウ内に表示されるバッファーならt
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウはそれぞれリスト内に以前表示されていたバッファーと、それらのバッファーがウィンドウから削除された順序を記憶しています。このヒストリーが、たとえばreplace-buffer-in-windows
(バッファーとウィンドウを参照)により使用されます。このリストはEmacsにより自動的に保守されますが、これを明示的に調べたり変更するために以下の関数を使用できます:
この関数はwindowの前のコンテンツを指定するリストをリターンする。オプション引数windowには生きたウィンドウを指定すること。デフォルトは選択されたウィンドウ。
リスト要素はそれぞれ(buffer window-start
window-pos)
という形式をもつ。ここでbufferはそのウィンドウで前に表示されていたウィンドウ、window-startはそのバッファーが最後に表示されていたときのウィンドウのスタート位置(ウィンドウの開始位置と終了位置を参照)、window-posはwindow内にそのバッファーが最後に表示されていたときのポイント位置(ウィンドウとポイントを参照)。
このリストは順序付きであり、より前の要素がより最近に表示されたバッファーに対応してして、通常は最初の要素がそのウィンドウからもっとも最近削除されたバッファーに対応する。
この関数はwindowの前のバッファーをprev-buffersの値にセットする。引数windowは生きたウィンドウでなければならず、デフォルトは選択されたウィンドウ。引数prev-buffersはwindow-prev-buffers
によりリターンされるリストと同じ形式であること。
これらに加えて、それぞれのバッファーは次バッファー(next
buffers)のリストを保守します。これはswitch-to-prev-buffer
(以下参照)により再表示されたバッファーのリストです。このリストは主に切り替えるバッファーを選択するために、switch-to-prev-buffer
とswitch-to-next-buffer
により使用されます。
この関数はswitch-to-prev-buffer
を通じてwindow内に最近表示されたバッファーのリストをリターンする。window引数は生きたウィンドウかnil
(選択されたウィンドウの意)でなければならない。
この関数はwindowの次バッファーリストをnext-buffersにセットする。window引数は生きたウィンドウかnil
(選択されたウィンドウの意)、引数next-buffersはバッファーのリストであること。
以下のコマンドはbury-buffer
やunbury-buffer
のように、グローバルバッファーリストを巡回するために使用できます。ただしこれらはグローバルバッファーリストではなく、指定されたウィンドウのヒストリーリストのしたがって巡回します。それに加えてこれらはウィンドウ固有なウィンドウのスタート位置とポイント位置をリストアして、すでに他のウィンドウに表示されているバッファーをも表示できます。特にswitch-to-prev-buffer
コマンドは、ウィンドウにたいする置き換えバッファーを探すためにreplace-buffer-in-windows
、bury-buffer
、quit-window
により使用されます。
このコマンドはwindow内に前のバッファーを表示する。引数windowは生きたウィンドウかnil
(選択されたウィンドウの意)であること。オプション引数bury-or-killが非nil
なら、それはwindow内にカレントで表示されているバッファーは今まさにバリーもしくはkillされるバッファーであり、したがって将来におけるこのコマンドの呼び出しでこのバッファーに切り替えるべきではないことを意味する。
前のバッファーとは、通常はwindow内にカレントで表示されているバッファーの前に表示されていたバッファーである。しかしバリーやkillされたバッファー、または直近のswitch-to-prev-buffer
呼び出しですでに表示されたバッファーは前のバッファーとしては不適格となる。
このコマンドを繰り返して呼び出すことによりwindow内で前に表示されたすべてのバッファーが表示されてしまったら、将来の呼び出しではwindowが表示されているフレームのバッファーリスト(バッファーリストを参照)から、そのフレームの他のウィンドウで表示済みのバッファーをスキップしてバッファーの表示を試みる。
このコマンドはwindow内の次バッファーに切り替える。つまりwindow内での最後のswitch-to-prev-buffer
コマンドの効果をアンドゥする。引数windowは生きたウィンドウであること。デフォルトは選択されたウィンドウ。
アンドゥ可能なswitch-to-prev-buffer
の直近の呼び出しが存在しなければ、この関数はwindowが表示されているフレームのバッファーリスト(バッファーリストを参照)からバッファーの表示を試みる。
デフォルトでは、switch-to-prev-buffer
とswitch-to-next-buffer
は同一フレーム上の他のウィンドウで表示済みのバッファーに切り替えることができます。この挙動をオーバーライドするために以下のオプションを使用できます。
この変数が非nil
なら、そのバッファーが当該ウィンドウで過去に表示されていれば、switch-to-prev-buffer
とswitch-to-next-buffer
は同一フレーム上ですでに可視のバッファーに切り替えることができる。nil
なら、switch-to-prev-buffer
とswitch-to-next-buffer
は同一フレーム上ですでに可視なバッファーへの切り替えを常に避けるよう試みる。デフォルトはt
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
特定のウィンドウがそのウィンドウのバッファーにたいして専用(dedicated)であるとマークすることにより、バッファーを表示する関数にそのウィンドウを使用しないように告げることができます。display-buffer
(表示するウィンドウの選択を参照)は、他のバッファーの表示に専用バッファーを決して使用しません。
get-lru-window
とget-largest-window
(ウィンドウのサイクル順を参照)は、dedicated引数が非nil
のときは専用ウィンドウを候補とはみなしません。専用ウィンドウにたいする配慮に関してset-window-buffer
(バッファーとウィンドウを参照)の挙動は若干異なります。以下を参照してください。
ウィンドウからのバッファー削除、およびフレームからのウィンドウ削除を意図した関数は、処理するウィンドウが専用ウィンドウのときは特別な挙動を示す可能性があります。ここでは3つの基本ケース、すなわち(1)そのウィンドウがフレーム上で唯一のウィンドウの場合、(2)ウィンドウはフレーム上で唯一のウィンドウだが同一端末上に別のフレームがある場合、(3)そのウィンドウが同一端末上で唯一のフレームの唯一のウィンドウの場合、を明確に区別することにします。
特にdelete-windows-on
(ウィンドウの削除を参照)は関連するフレームを削除する際にケース(2)を、フレーム上で唯一のウィンドウに他のバッファーを表示する際にケース(3)を処理します。バッファーがkillされる際に呼び出される関数replace-buffer-in-windows
(バッファーとウィンドウを参照)は、ケース(1)ではウィンドウを削除して、それ以外ではdelete-windows-on
のように振る舞います。
bury-buffer
(バッファーリストを参照)が選択されたウィンドウを操作する際は、選択されたフレームを処理するためにframe-auto-hide-function
(ウィンドウのquitを参照)を呼び出すことによってケース(2)を取り扱います。他の2つのケースはreplace-buffer-in-windows
と同様に処理されます。
この関数はwindowがそのバッファーにたいして専用なら非nil
、それ以外はnil
をリターンする。より正確には最後のset-window-dedicated-p
呼び出しで割り当てられた値、set-window-dedicated-p
がwindowを引数として呼び出されたことがなければnil
がリターン値となる。windowのデフォルトは選択されたウィンドウ。
この関数はflagが非nil
ならwindowがそのバッファーに専用、それ以外は非専用とマークする。
特別なケースとしてflagがt
の場合には、windowはそのバッファーにたいして特に専用(strongly
dedicated)になる。set-window-buffer
は処理対象のウィンドウが特に専用のウィンドウで、かつ表示を要求されたバッファーが表示済みでなければエラーをシグナルする。その他の関数はt
を他の非nil
値と区別して扱わない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファーを表示するために使用しているウィンドウを削除したいときには、フレームからそのウィンドウを削除するためにdelete-window
やdelete-windows-on
を呼び出すことができます(ウィンドウの削除を参照)。そのバッファーが別フレームで表示されているときには、かわりにdelete-frame
を呼び出したいと思うかもしれません(フレームの削除を参照)。その一方でバッファーを表示するためにウィンドウが再利用されている場合には、関数switch-to-prev-buffer
を呼び出して前に表示されていたバッファーを表示したいと思うかもしれません(ウィンドウのヒストリーを参照)。最終的にはそのウィンドウのバッファーをバリー(バッファーリストを参照)やkill(バッファーのkillを参照)したいと思うかもしれません。
以下のコマンドは、最初にどのようにバッファーを表示するウィンドウを取得するかという情報を使用して、上述で説明した処理の自動化を試みます。
このコマンドはwindowをquitしてそのバッファーをバリーする。引数windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。プレフィックス引数killが非nil
ならバッファーをバリーするかわりにkillする。これはウィンドウとそのバッファーを処理するために、次に説明する関数quit-restore-window
を呼び出す。
この関数はwindowにたいして、そのバッファーが表示される前に存在した状態へのリストアを試みる。オプション引数windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。
windowがそのバッファーを表示するために特別に作成されたバッファーなら、この関数はそのフレームに他に少なくとも1つの生きたウィンドウがなければwindowを削除しない。windowがそのフレームで唯一のウィンドウであり、かつそのフレームの端末上に他のフレームが存在する場合には、オプション引数bury-or-killがそのウィンドウをどうするかを決定する。bury-or-killがkill
なら無条件でフレームは削除される。それ以外ではフレームの運命はそのフレームを単一の引数とするframe-auto-hide-function
(以下参照)呼び出しにより決定される。
特別に作成されたウィンドウでなければ、この関数はwindow内で前に表示されていたバッファーの再表示を試みる。これは前に表示されていたバッファーのウィンドウのスタート位置(ウィンドウの開始位置と終了位置を参照)とポイント位置(ウィンドウとポイントを参照)のリストアも試みる。加えてwindowのバッファーが過去に一時的にリサイズされていたら、この関数はwindowの元の高さのリストアも試みる。
これまで説明したケースでは、window内で表示されているバッファーは依然としてそのウィンドウにたいする最後のバッファー表示関数で表示されたバッファーである。その時点で他のバッファーが表示されているか、前に表示されていたバッファーがもはや存在しなければ、この関数はかわりに何か他のバッファーを表示するためにswitch-to-prev-buffer
(ウィンドウのヒストリーを参照)を呼び出す。
オプション引数bury-or-killにはwindowを処理する方法を指定し、以下の値が処理される。
nil
これはバッファーを特別な方法で処理しないことを意味する。その結果としてwindowが削除されない場合には、switch-to-prev-buffer
の呼び出しにより通常はそのバッファーが再び表示されるだろう。
append
これはwindowが削除されない場合には、そのバッファーをwindowの前のバッファーリストの最後に移動するので、将来のswitch-to-prev-buffer
呼び出しでこのバッファーには切り替わることは少なくなる。これはそのバッファーをフレームのバッファーリストの最後への移動も行う。
bury
これはwindowが削除されない場合には、そのバッファーをwindowの前のバッファーリストから削除する。これはそのバッファーをフレームのバッファーリストの最後への移動も行う。この値はバッファーをkillすることなくswitch-to-prev-buffer
がこのバッファーに再び切り替えさせないようにする、もっとも信頼できる解決手段を提供する。
kill
これはwindowのバッファーをkillすることを意味する。
quit-restore-window
はwindowのquit-restore
ウィンドウパラメーター(ウィンドウのパラメーターを参照)の情報にもとづいて判定を行い、処理後にそれをnil
にリセットしている。
以下のオプションはquitすべきウィンドウ、あるいはバリーすべきバッファーをもつウィンドウを1つだけ含むフレームを処理する方法を指定します。
このオプションで指定された関数は自動的にフレームを隠すために呼び出される。この関数はフレームを唯一の引数として呼び出される。
ここで指定される関数は選択されたウィンドウが専用(dedicated)であり、かつバリーされるバッファーを表示しているときにbury-buffer
(バッファーリストを参照)から呼び出される。またquitされるウィンドウのフレームがそのウィンドウのバッファーを表示するために特別に作成されたフレームで、かつそのバッファーがkillされないときにもquit-restore-window
(上記)から呼び出される。
デフォルトではiconify-frame
(フレームの可視性を参照)を呼び出す。かわりにフレームをディスプレイから削除するdelete-frame
(フレームの削除を参照)、フレームを変更せずに残すignore
、またはフレームを唯一の引数とする任意の関数のいずれかを指定できる。
このオプションで指定された関数は指定されたフレームが生きたウィンドウただ1つを含み、かつ同一端末上に少なくとも1つ他のフレームが存在する場合のみ呼び出されることに注意。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
それぞれのウィンドウは独自のポイント値(ポイントを参照)をもち、同じバッファーを表示する他のウィンドウの間でも、ポイント値はそれぞれ独立しています。これは1つのバッファーを複数ウィンドウで表示するのに有用です。
ユーザーが関与し続ける限りポイントはカーソル位置にあり、ユーザーが他のバッファーに切り替えた際には、カーソルはそのバッファーのポイント位置へとジャンプします。
この関数はwindow内のカレントのポイント位置をリターンする。選択されていないウィンドウでは、そのウィンドウが選択された場合の、(そのウィンドウのバッファーの)ポイント値である。windowにたいするデフォルトは選択されたウィンドウ。
windowが選択されたウィンドウのときのリターン値は、そのウィンドウのバッファーのポイント値。厳密にはすべてのsave-excursion
フォームの外側のトップレベルのポイント値のほうがより正確であろう。しかしこの値は見つけるのが困難である。
この関数はwindow内のポイントをwindowのバッファー内の位置positionに配置する。リターン値はposition。
windowが選択されていれば単にwindow内でgoto-char
を行う。
この変数はwindow-point
のマーカー挿入型(Marker 挿入タイプを参照)を指定する。デフォルトはnil
で、window-point
は挿入されたテキストの後に留まるだろう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウはそれぞれバッファー位置を追跡するために、バッファー内で表示を開始すべき位置を指定するマーカーを保守しています。この位置はそのウィンドウのdisplay-start(表示開始)、または単にstart(開始)と呼ばれます。この位置の後の文字がウィンドウの左上隅に表示される文字となります。これは通常はテキスト行の先頭になりますが必須ではありません。
ウィンドウやバッファーの切り替え後やいくつかのケースにおいては、ウィンドウが行の途中で開始される場合にEmacsがィンドウの開始を行の開始に調整します。これは行中で無意味な位置のウィンドウ開始のまま特定の操作が行われるのを防ぐためです。この機能はLispモードのコマンドを使用して実行することによりある種のLispコードをテストする場合には、それらのコマンドがこの再調整を誘発してしまうので邪魔かもしれません。そのようなコードをテストするためには、それをコマンド内に記述して何らかのキーにバインドしてください。
この関数はウィンドウwindowの表示開始位置をリターンする。windowがnil
なら選択されたウィンドウが使用される。
ウィンドウを作成したり他のバッファーをウィンドウ内に表示する際、display-start位置は同じバッファーにたいしてもっとも最近に使用されたdisplay-start位置、そのバッファーがそれをもたなければpoint-min
にセットされる。
ポイントがスクリーン上に確実に現れるように、再表示はwindow-start位置を更新する(前の再表示以降にwindow-start位置を明示的に指定していない場合)。再表示以外にwindow-start位置を自動的に変更するものはない。ポイントを移動した場合には、次の再表示後までポイントの移動に応じてwindow-startが変更されることを期待してはならない。
この関数はwindow-start
と同様だが、windowがウィンドウグループ(Window Groupを参照)の一部なら、window-group-start
はグループ全体の開始位置をリターンする点が異なる。この条件はバッファーローカル変数window-group-start-function
に関数がセットされている際に保持される。この場合には、window-group-start
はその関数を単一の引数windowで呼び出して結果をリターンする。
この関数はwindowのバッファーの最後を表示する位置をリターンする。windowにたいするデフォルトは選択されたウィンドウ。
バッファーテキストの単なる変更やポイントの移動ではwindow-end
がリターンする値は更新されない。この値はEmacsが再表示を行って、妨害されることなく再表示が完了したときのみ更新される。
windowの最後の再表示が妨害されて完了しなかったら、Emacsはそのウィンドウ内の表示のend位置を知らない。関数はこの場合はnil
をリターンする。
updateが非nil
なら、window-end
はwindow-start
のカレント値にもとづき、どこが表示のendなのか最新の値をリターンする。以前に保存された位置の値がまだ有効なら、window-end
はその値をリターンする。それ以外はバッファーのテキストをスキャンして正しい値を計算する。
たとえupdateが非nil
でポイントが画面外に移動していても、window-end
は実際の再表示が行うような表示のスクロールを試みない。これはwindow-start
の値を変更しない。これは実際にはスクロールが要求されない場合に表示されたテキストのendがどこかを報告する。
この関数はwindow-end
と同様だが、windowがウィンドウグループ(Window Groupを参照)の一部なら、window-group-end
はグループ全体の終了位置をリターンする点が異なる。この条件はバッファーローカル変数window-group-end-function
に関数がセットされている際に保持される。この場合には、window-group-end
はその関数を2つの引数windowとupdateで呼び出して結果をリターンする。引数updateはwindow-end
の場合と同じ意味をもつ。
この関数はwindowのdisplay-start位置をwindowのバッファーのpositionにセットする。リターン値はposition。
バッファーが表示されたときに表示ルーチンはポイント位置が可視になることを強要する。これらはポイントを可視にするために必要なときは、通常は常にdisplay-start位置を変更(つまりウィンドウをスクロール)する。しかしこの関数でnoforceにnil
を使用してstart位置を指定すると、たとえポイントを画面外になるような場所に配置したとしてもpositionでの表示開始を望むことを意味する。これによりポイントが画面外に配置されると、表示ルーチンはポイントをウィンドウ内の中央行の左マージンに移動する。
たとえばポイントが1のときにウィンドウのstartを次行の開始37にセットすると、ポイントはウィンドウの最上端より上になるだろう。表示ルーチンは再表示が発生したときにポイントが1のままならポイントを動かすことになる。以下は例:
;; 以下は式set-window-start
実行前
;; ‘foo’の様子
---------- Buffer: foo ---------- ∗This is the contents of buffer foo. 2 3 4 5 6 ---------- Buffer: foo ----------
(set-window-start (selected-window) (save-excursion (goto-char 1) (forward-line 1) (point))) ⇒ 37
;; 以下は式set-window-start
実行後の
;; ‘foo’の様子
---------- Buffer: foo ----------
2
3
∗4
5
6
---------- Buffer: foo ----------
noforceが非nil
で、かつ次回の再表示でポイントが画面外に配される場合、再表示はポイントと協調して機能する位置となるような新たなwindow-startを計算するので、positionは使用されない。
この関数はset-window-start
と同様だが、windowがウィンドウグループ(Window Groupを参照)の一部なら、set-window-group-start
はグループ全体の開始位置をリターンする点が異なる。この条件はバッファーローカル変数set-window-group-start-function
に関数がセットされている際に保持される。この場合には、set-window-group-start
はその関数を3つの引数window、position、noforceで呼び出して結果をリターンする。この関数の引数positionとnoforceはset-window-start
の場合と同じ意味をもつ。
この関数はwindow内のpositionが画面上カレントで可視のテキスト範囲内にあれば非nil
、positionが表示範囲のスクロール外にあればnil
をリターンする。partiallyがnil
なら部分的に不明瞭な位置は可視とは判断されない。引数positionのデフォルトはwindow内のポイントのカレント位置、windowのデフォルトは選択されたウィンドウ。positionがt
なら、それはwindowの最後に可視だった行の位置、またはEOB(end-of-buffer:
バッファー終端位置のいずれか前方になる位置をチェックすることを意味する。
この関数は垂直スクロールだけを考慮する。positionが表示範囲外にある理由が、windowが水平にスクロールされただけなら、いずれにせよpos-visible-in-window-p
は非nil
をリターンする。水平スクロールを参照のこと。
positionが可視でpartiallyがnil
なら、pos-visible-in-window-p
はt
をリターンする。partiallyが非nil
でposition以降の文字が完全に可視なら、(x
y)
という形式のリストをリターンする。ここでxとyはウィンドウの左上隅からの相対的なピクセル座標。position以降の文字が完全に可視ではなければ、拡張された形式のリスト(x
y rtop rbot rowh
vpos)
をリターンする。ここでrtopとrbotはpositionでウィンドウ外となった上端と下端のピクセル数、rowhはその行の可視な部分の高さ、vposはその行の垂直位置(0基準の行番号)を示す。
以下は例:
;; ポイントが画面外ならrecenterする
(or (pos-visible-in-window-p
(point) (selected-window))
(recenter 0))
この関数はpos-visible-in-window-p
と同様だが、windowがウィンドウグループ(Window Groupを参照)の一部なら、pos-visible-in-window-group-p
はwindow単独ではなく、グループ全体でposの可視性をテストする点が異なる。この条件はバッファーローカル変数pos-visible-in-window-group-p-function
に関数がセットされている際に保持される。この場合には、pos-visible-in-window-group-p
はその関数を3つの引数position、window、partiallyで呼び出して結果をリターンする。この関数の引数positionとpartiallyはpos-visible-in-window-p
の場合と同じ意味をもつ。
この関数はwindow内のテキスト行lineの高さをリターンする。lineがheader-line
、mode-line
、window-line-height
のいずれかなら、そのウィンドウの対応する行についての情報をリターンする。それ以外では、lineは0から始まるテキスト行番号。負数ならそのウィンドウのendから数える。lineにたいするデフォルトはwindow内のカレント行、windowにたいするデフォルトは選択されたウィンドウ。
表示が最新でなければwindow-line-height
はnil
をリターンする。その場合には関連する情報を入手するためにpos-visible-in-window-p
を使用できる。
指定されたlineに対応する行がなければ、window-line-height
はnil
をリターンする。それ以外では、リスト(height
vpos ypos
offbot)
をリターンする。ここでheightはその行の可視部分のピクセル高さ、vposとyposは最初のテキスト行上端からのその行への相対的な垂直位置の行数とピクセル数、offbotはそのテキスト行下端のウィンドウ外のピクセル数。(最初の)テキスト行上端にウィンドウ外のピクセルがある場合にはyposは負となる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
テキスト的なスクロール(textual
scrolling)とは、ウィンドウ内のテキストを上や下に移動することを意味します。これはそのウィンドウのdisplay-startを変更することにより機能します。これはポイントを画面上に維持するためにwindow-point
の値も変更するかもしれません(ウィンドウとポイントを参照)。
テキスト的なスクロールの基本的な関数は、(前方にスクロールする) scroll-up
、および(後方にスクロールする)
scroll-down
です。これらの関数の名前の“up”と“down”は、バッファーテキストのそのウィンドウにたいする相対的な移動方向を示しています。そのテキストが長いロール紙に記述されていて、スクロールコマンドはその上を上下に移動すると想像してみてください。つまりバッファーの中央に注目している場合には、繰り返してscroll-down
を呼び出すと最終的にはバッファーの先頭を目にすることになるでしょう。
これは残念なことに時折混乱を招きます。なぜならある人はこれを逆の慣習にもとづいて考える傾向があるからです。彼らはテキストがその場所に留まりウィンドウが移動して、“down”コマンドによりバッファー終端に移動するだろうと想像します。この慣習はそのようなコマンドが現代風のキーボード上のPageDownという名前のキーにバインドされているという事実と一致しています。
選択されたウィンドウ内で表示されているバッファーがカレントバッファーでなければ、(scroll-other-window
以外の)テキスト的スクロール関数の結果は予測できません。カレントバッファーを参照してください。
(たとえば大きなイメージがある等で)ウィンドウにウィンドウの高さより高い行が含まれる場合には、スクロール関数は部分的に可視な行をスクロールするためにそのウィンドウの垂直スクロール位置を調整します。Lisp呼び出し側は変数auto-window-vscroll
をnil
にバインドすることにより、この機能を無効にできます(割り合いによる垂直スクロールを参照)。
この関数は選択されたウィンドウ内でcount行前方にスクロールする。
countが負ならかわりに後方へスクロールする。countがnil
(または省略)ならスクロールされる距離は、そのウィンドウのテキストエリアの高さより小さいnext-screen-context-lines
となる。
この関数は選択されたウィンドウがそれ以上スクロールできなければエラーをシグナルして、それ以外はnil
をリターンする。
この関数は選択されたウィンドウ内でcount行後方にスクロールする。
countが負ならかわりに前方へスクロールする。それ以外の点ではこれはscroll-up
と同様に振る舞う。
これはscroll-up
と同様に振る舞うが選択されたウィンドウがそれ以上スクロールできず、かつ変数scroll-error-top-bottom
の値がt
なら、かわりにそのバッファーの終端への移動を試みる。ポイントがすでに終端にあればエラーをシグナルする。
これはscroll-down
と同様に振る舞うが選択されたウィンドウがそれ以上スクロールできず、かつ変数scroll-error-top-bottom
の値がt
なら、かわりにそのバッファーの先頭への移動を試みる。ポイントがすでに先頭にあればエラーをシグナルする。
この関数は他のウィンドウ内のテキストを上方にcount行スクロールする。countが負かnil
ならscroll-up
のように処理される。
変数other-window-scroll-buffer
にバッファーをセットすることにより、どのバッファーをスクロールするかを指定できる。そのバッファーが表示されていなければ、scroll-other-window
はそれを何らかのウィンドウにそれを表示する。
選択されたウィンドウがミニバッファーのとき、次ウィンドウは通常はそのウィンドウの直上最左のウィンドウである。変数minibuffer-scroll-window
をセットすることにより、スクロールする別のウィンドウを指定できる。この変数はミニバッファー以外のウィンドウが選択されているときは効果がない。これが非nil
、かつミニバッファーが選択されているときにはother-window-scroll-buffer
より優先される。Definition of minibuffer-scroll-windowを参照のこと。
ミニバッファーがアクティブのとき選択されたウィンドウが下端右角のウィンドウなら、ミニバッファーが次ウィンドウになる。この場合にはscroll-other-window
はミニバッファーのスクロールを試みる。ミニバッファーに含まれるのが1行だけならどこにもスクロールできないので、エコーエリアにメッセージ‘End
of buffer’を瞬時表示した後にその行を再表示する。
この変数が非nil
なら、それはscroll-other-window
がどのバッファーのウィンドウをスクロールするかを指定する。
このオプションはスクロールマージン(ポイントとウィンドウの上端/下端との最小行数)のサイズを指定する。ポイントがウィンドウの上端/下端からその行数になったとき、(可能なら)再表示はポイントをそのマージン外のウィンドウ中央付近に移動するためにテキストを自動的にスクロールする。
この変数はポイントがスクリーン外(またはスクロールマージン内)に移動したときに自動的にスクロールを行う方法を指定する。値が正の整数nなら再表示はそれが正しい表示範囲内にポイントを戻すなら、いずれかの方向にn行以下のテキストをスクロールする。この振る舞いは保守的なスクロール(conservative
scrolling)と呼ばれる。それ以外ならスクロールはscroll-up-aggressively
やscroll-down-aggressively
のような他の変数の制御の下に通常の方法で発生する。
デフォルトの値は0でこれは保守的スクロールが発生し得ないことを意味する。
この変数の値はnil
、または0から1までの小数点数fであること。小数点数ならスクリーン上でポイントが置かれたとき下にスクロールする場所を指定する。より正確にはポイントがウィンドウstartより上という理由でウィンドウが下にスクロールされるときには、新たなstart位置がウィンドウ上端からウィンドウ高さのfの箇所にポイントが置かれるように選択される。より大きなfなら、よりaggressive(積極的)にスクロールする。
その効果はポイントを中央に配置することであり、値nil
は.5と等価である。どのような方法によりセットされたときでも、この変数は自動的にバッファーローカルになる。
scroll-up-aggressively
と同様。値fはポイントがウィンドウ下端からどれほどの位置に置かれるべきかを指定する。つまりscroll-up-aggressively
と同じように大きな値ではよりaggressive(積極的)になる。
この変数はscroll-conservatively
の古い変種である。違いは値がnならn以下の値ではなく、正確にnだけのスクロールを許容することである。この機能はscroll-margin
とは共に機能しない。デフォルトは0。
このオプションがt
なら、スクロールによりポイントがウィンドウ外に移動したとき、Emacsは常にポイントがポイントの上下端ではなくカーソルがそのウィンドウ内の元の垂直位置に保たれるようポイントの調整を試みる。
値が非nil
かつ非t
なら、たとえスクロールコマンドによりポイントがウィンドウ外に移動していなくとも、Emacsはカーソルが同じ垂直位置に保たれるようにポイントを調整する。
このオプションはシンボルプロパティscroll-command
が非nil
であるような、すべてのスクロールコマンドに影響する。
この変数の値は全画面スクロールされたときに継続して残される行数を指定する。たとえば引数がnil
のscroll-up
はウィンドウ上端ではなく下端に残される行数でスクロールする。デフォルト値は2
。
このオプションがnil
(デフォルト)なら、それ以上のスクロールが不可能な際にscroll-up-command
とscroll-down-command
は単にエラーをシグナルする。
値がt
なら、これらのコマンドはかわりにポイントをバッファーの先頭か終端(スクロール方向に依存する)に移動する。ポイントがすでにその位置にある場合のみエラーをシグナルする。
この関数は選択されたウィンドウ内の指定された垂直位置にポイントを表示するようにウィンドウ内のテキストをスクロールする。これはテキストに応じたポイント移動を行わない。
countが非負の数なら、そのウィンドウ上端からcount行下にポイントを含む行を配置する。countが負ならウィンドウ下端から上に数えるので、-1はそのウィンドウ内で最後の利用可能な行となる。
countがnil
(または非nil
のリスト)なら、recenter
はポイントを含む行をウィンドウの中央に配置する。countがnil
なら、この関数はrecenter-redisplay
の値に応じてフレームを再描画するかもしれない。
recenter
がインタラクティブに呼び出されたときはrawプレフィックス引数がcountとなる。したがってプレフィックスとしてC-uをタイプするとcountに非nil
、C-u
4ではcountに4がセットされte、後者ではカレント行を上端から4行目にセットする。
引数0ではrecenter
はカレント行をウィンドウ上端に配置する。コマンドrecenter-top-bottom
はこれを達成するためにより簡便な方法を提供する。
この関数はrecenter
と同様だが、選択されたウィンドウがウィンドウグループ(Window Groupを参照)の一部の際には、recenter-window-group
がグループ全体をスクロールする点が異なる。この条件はバッファーローカル変数recenter-window-group-function
が関数にセットされている際に保持される。この場合にはrecenter-window-group
はその関数を引数countで呼び出して結果をリターンする。引数countはrecenter
の場合と同様の意味をもつが、ウィンドウグループ全体に作用する。
この変数が非nil
なら引数nil
でrecenter
を呼び出すことによりフレームを再描画する。デフォルト値はtty
で、これはフレームがttyフレームのときだけフレームを再描画することを意味する。
デフォルトではC-lにバインドされているこのコマンドは、recenter
と同様に動作するが引数なしで呼び出されたときの動作が異なる。この場合には連続して呼び出すことにより変数recenter-positions
で定義されるサイクル順に応じてポイントを配置する。
これはrecenter-top-bottom
を引数なしで呼び出したときの挙動を制御する。デフォルト値は(middle top
bottom)
で、これは引数なしでrecenter-top-bottom
を連続して呼び出すとポイントをウィンドウの中央、上端、下端と巡回して配置することを意味する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
垂直フラクショナルスクロール(vertical fractional scrolling)とは、指定された値を行に乗ずるることによりウィンドウ内のテキストを上下にシフトすることを意味します。ウィンドウはそれぞれ、決して0より小さくなることはない垂直スクロール位置(vertical scroll position)という数値をもっています。これはウィンドウのコンテンツをどこから表示開始(raise)するかを指定します。ウィンドウのコンテンツの表示開始により一般的には上端の何行かすべて、または一部が表示されなくなり、他の何行かのすべて、または一部が下端に表示されるようになります。通常の値は0です。
垂直スクロール位置は通常行の高さ(デフォルトフォントの高さ)の単位で数えられます。したがって値が.5なら、それはウィンドウのコンテンツが通常行の半分の高さで上にスクロールされていること、3.3なら通常行の3倍を若干超える高さで上にスクロールされていることを意味します。
垂直スクロールが覆い隠す(cover)のがどれほどの行断片(fraction of a line)なのか、あるいは行数かはそれらの行に何が含まれるかに依存します。3.3という値により高い行やイメージの一部だけを画面外にスクロールできることもあれば、.5という値が非常に小さい高さの行を画面外にスクロールできることもあります。
この関数はwindowのカレントの垂直スクロール位置をリターンする。windowのデフォルトは選択されたウィンドウ。pixels-pが非nil
ならリターン値は通常行高さ単位ではなくピクセル単位で測定される。
(window-vscroll) ⇒ 0
この関数はwindowの垂直スクロール位置をlinesにセットする。windowがnil
なら選択されたウィンドウが使用される。引数linesは0または正であること。それ以外は0として扱われる。
実際の垂直スクロール位置は常にピクセルの整数に対応しなければならないため、指定した値はそれに応じて丸められる。
この丸め結果がリターン値となる。
(set-window-vscroll (selected-window) 1.2) ⇒ 1.13
pixels-pが非nil
ならlinesはピクセル数を指定する。この場合にはリターン値はlines。
この変数が非nil
なら関数line-move
、scroll-up
、scroll-down
は、たとえば大きなイメージが存在する等でウィンドウ高さより高いディスプレイ行をスクロールするために垂直スクロール位置を自動的に変更するだろう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
水平スクロール(horizontal scrolling)とは指定された通常文字幅の倍数でウィンドウ内のイメージを左右にシフトすることを意味します。ウィンドウはそれぞれ、決して0より小さくなることはない水平スクロール位置(horizontal scroll position)という数値をもっています。これはコンテンツをどれほど左にシフトするかを指定します。ウィンドウのコンテンツを左にシフトすることにより一般的には左にある文字のすべて、または一部が表示されなくなり右にある文字のすべて、または一部が表示されることを意味します。通常の値は0です。
水平スクロール位置は通常の文字幅を単位として数えられます。したがって値が5なら、それはウィンドウのコンテンツは通常文字幅の5倍左にスクロールされることを意味します。左の何文字が表示されなくなるかは、それらの文字の文字幅とに依存していて、それは行ごとに異なります。
読み取りを行う際には内側のループ(inner loop)で横方向、外側のループ(outer loop)で上から下に読み取るため、水平スクロールの効果はテキスト的スクロールや垂直スクロールとは異なります。テキスト的スクロールは表示するためのテキスト範囲の選択を引き起こし、垂直スクロールはウィンドウコンテンツを連続して移動します。しかし水平スクロールはすべての行の一部をスクリーン外へスクロールします。
通常は水平スクロールは行われないので、ウィンドウ左端には最左列があります。この状態では右スクロールにより左端に新たに表示されるデータは存在しないので、右へのスクロールはできません。左スクロールによってテキストの1列目がウィンドウ端からウィンドウ外にスクロールされ、右端にはその前は切り詰められていた(truncated)列が新たに表示されるので左へのスクロールはできます。ウィンドウが左へ非0の値で水平スクロールされていれば右スクロールしてそれを戻すことができますが、正味の水平スクロールが0に減少するまでの間のみ右スクロールができます。左へどれほどスクロールできるかに制限はありませんが、最終的にはすべてのテキストが左端の外に消えるでしょう。
auto-hscroll-mode
がセットされている場合には、再表示はポイントが常に可視となることを保証するために必要に応じて水平スクロールを自動的に変更する。とはいえ依然として水平スクロール位置を明示的に指定するのは可能である。指定した値は自動スクロールの下限値としての役目を果たす(自動スクロールは指定された値より小さい列にウィンドウをスクロールしない)。
この関数は選択されたウィンドウを左( countが負なら右)にcount列スクロールする。countのデフォルトはウィンドウ幅から2を減じた値。
リターン値はwindow-hscroll
(以下参照)がリターンする値と同じように、変更後に実際に左に水平スクロールされたトータル量。
基本方向がR2L(双方向テキストの表示を参照)のパラグラフ内のテキストは、正のcount値でscroll-left
が呼び出された際には右へと移動するように、反対方向に移動することに注意。
ウィンドウを可能な限り右にスクロールした後は、左スクロールの合計が0であるような通常の位置に戻り、右へのそれ以上のスクロールの試みは効果をもたない。
set-minimumが非nil
なら新たなスクロール量は自動スクロールの下限値となる。つまり自動スクロールはこの関数がリターンする値より小さい列にウィンドウをスクロールしないだろう。インタラクティブに呼び出すとset-minimumに非nil
を渡す。
この関数は選択されたウィンドウを右(
countが負なら左)にcount列スクロールする。countのデフォルトはウィンドウ幅から2を減じた値。スクロール方向を除けばこれはscroll-left
と同様に機能する。
この関数はwindowの左への水平スクロールのトータル(左マージンを超えて左にスクロールされたwindow内のテキスト列数)をリターンする(R2Lパラグラフでの値はかわりに右方向への総スクロール量となる)。windowのデフォルトは選択されたウィンドウ。
リターン値が負になることは決してない。windowで水平スクロールが行われていない場合(これが通常)にはリターン値は0。
(window-hscroll) ⇒ 0
(scroll-left 5) ⇒ 5
(window-hscroll) ⇒ 5
この関数はwindowの水平スクロールをセットする。columnsの値はスクロール量を左マージン(R2Lパラグラフでは右マージン)からの列数で指定する。引数columnsは0または正の数であること。そうでない場合ニは0とみなされる。小数点数のcolumns値は現在のところサポートされない。
シンプルにM-:を呼び出して評価する方法でテストすると、set-window-hscroll
が機能していないように見えるかもしれないことに注意。ここで何が発生しているかというと、この関数は水平スクロール値をセットしてリターンするが、その後にポイントを可視にするために水平スクロールを調整するよう再表示が行なわれて、これが関数の行った処理をオーバーライドしている。この関数の効果は左マージンからポイントまでのスクロール量が、ポイントが可視のまま留まるように関数を呼び出すことにより観察できる。
リターン値はcolumns。
(set-window-hscroll (selected-window) 10) ⇒ 10
以下は与えられた位置positionが水平スクロールによりスクリーン外にあるかどうかを判断する例です:
(defun hscroll-on-screen (window position) (save-excursion (goto-char position) (and (>= (- (current-column) (window-hscroll window)) 0) (< (- (current-column) (window-hscroll window)) (window-width window)))))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではウィンドウ位置をレポートする関数について説明します。これらの関数はそのウィンドウのフレームのネイティブ位置(Frame Geometryを参照)を原点とする相対的な位置をレポートすることに注意してください。そのウィンドウのフレームのディスプレーを原点とする相対位置をレポートする関数もいくつかあります。どのような場合でも原点は座標(0, 0)、右方向でX座標、下方向でY座標が増加します。
以下の関数ではX座標とY座標は整数の文字単位(行数と列数)で報告されます。グラフィカルなディスプレイ上での“行”と“列”はそれぞれ、そのフレームのデフォルトフォントにより指定されるデフォルト文字の高さと幅に対応します(Frame Fontを参照)。
この関数はwindow端の座標のリストをリターンする。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。
リターン値は(left top right
bottom)
という形式をもつ。リストの要素は順にそのウィンドウにより占有される最左列のX座標、最上行のY座標、最右列より1列右のX座標、最下行より1行下のY座標。
これらはヘッダーライン、モードライン、スクロールバー、ウィンドウディバイダー、ディスプレイマージンを含むウィンドウの実際の端であることに注意。テキスト端末ではそのウィンドウの右に隣接するウィンドウがあれば、ウィンドウの右端にはそのウィンドウと隣接するウィンドウの間のセパレーターラインが含まれる。
オプション引数bodyがnil
なら、それはwindowの総サイズに対応する端をリターンすることを意味する。bodyが非nil
ならwindowのボディー(テキスト領域)の端をリターンすることを意味する。bodyが非nil
ならwindowには生きたウィンドウを指定しなければならない。
オプション引数absoluteがnil
なら、それはwindowのフレームのネイティブ位置に相対的な端のリターンを意味する。absoluteが非nil
ならwindowのディスプレーの原点(0,
0)からの相対座標のリターンを意味する。非グラフィカルなシステムではこの引数に効果はない。
オプション引数pixelwiseがnil
なら、それはwindowのフレームのデフォルト文字の幅と高さの単位で座標をリターンすることを意味する。pixelwiseが非nil
ならピクセル単位で座標をリターンすることを意味する。rightとbottomで指定されるピクセルはこれらの端の外側であることに注意。absoluteが非nil
なら、pixelwiseも暗黙に非nil
となる。
この関数はwindowのボディーの端をリターンする(ウィンドウのサイズを参照)。(window-body-edges window)
の呼び出しは(window-edges window
t)
(上記参照)の呼び出しと等価。
以下の関数は一連のフレーム相対座標(frame-relative coordinates)からウィンドウへの関連付けに使用できます:
この関数はframeのネイティブ位置(Frame Geometryを参照)から相対的に、デフォルト文字単位(Frame Fontを参照)で与えられる座標xとyにある生きたウィンドウをリターンする。
その位置にウィンドウがなければリターン値はnil
。frameが省略またはnil
の場合のデフォルトは選択されたフレーム。
この関数はウィンドウwindowがフレーム相対座標coordinatesを占有するかどうかをチェックして、もしそうならウィンドウのどの部分かをチェックする。windowは生きたウィンドウであること。
coordinatesは(x
.
y)
という形式のコンスセルであること。ここでxとyはwindowのフレームのネイティブ位置(Frame Geometryを参照)から相対的に、デフォルト文字サイズ(Frame Fontを参照)の単位で与えられる。
指定された位置にウィンドウが存在しなければリターン値はnil
。それ以外ではリターン値は以下のいずれか:
(relx . rely)
その座標はwindow内にある。数値relxとrelyは指定された位置にたいする、ウィンドウ左上隅を原点に0から数えたウィンドウ相対座標と等価。
mode-line
その座標はwindowのモードライン内にある。
header-line
その座標はwindowのヘッダーライン内にある。
right-divider
その座標はwindowと右に隣接するウィンドウを分けるディバイダー内にある。
bottom-divider
その座標はwindowと下にあるウィンドウを分けるディバイダー内にある。
vertical-line
その座標はwindowと右に隣接するウィンドウを分ける垂直ライン内にある。この値はウィンドウにスクロールバーがないときのみ発生し得る。スクロールバー内の位置はこれらの目的にたいしてはウィンドウ外側と判断される。
left-fringe
right-fringe
その座標はウィンドウの左か右のフリンジ内にある。
left-margin
right-margin
その座標はウィンドウの左か右のマージン内にある。
nil
その座標はwindowのいずれの部分でもない。
関数coordinates-in-window-p
はwindowのあるフレームを使用するので引数としてフレームを要求しない。
以下の関数は文字単位ではなくピクセル単位でウィンドウ位置をリターンします。主にグラフィカルなディスプレイで有用ですがテキスト端末上でも呼び出すことができ、その場合は各文字の占めるスクリーン領域が1ピクセルとなります。
この関数はwindow端にたいするピクセル座標のリストをリターンする。(window-pixel-edges
window)
の呼び出しは、(window-edges window nil nil t)
(上記参照)の呼び出しと等価。
この関数はwindowのボディー端をピクセルでリターンする。(window-body-pixel-edges
window)
の呼び出しは、(window-edges window t nil t)
(上記参照)の呼び出しと等価。
以下の関数はフレーム原点ではなく、ディスプレイ画面(display screen)の原点に相対的なウィンドウ位置をピクセルでリターンします。
この関数はwindowのフレームのディスプレーの原点(0,
0)から相対的なwindowのピクセル座標をリターンする。(window-absolute-pixel-edges)
の呼び出しは、(window-edges
window nil t t)
(上記参照)の呼び出しと等価。
この関数はwindowのフレームのディスプレーの原点(0,
0)から相対的なwindowのボディーのピクセル座標をリターンする。(window-absolute-body-pixel-edges
window)
の呼び出しは、(window-edges window t t t)
(上記参照)の呼び出しと等価。
set-mouse-absolute-pixel-position
と組み合わせることにより、あるウィンドウ内で可視な任意のバッファー位置にマウスポインターを移動するためにこの関数を使用できる。
(let ((edges (window-absolute-body-pixel-edges)) (position (pos-visible-in-window-p nil nil t))) (set-mouse-absolute-pixel-position (+ (nth 0 edges) (nth 0 position)) (+ (nth 1 edges) (nth 1 position))))
グラフィカルな端末では上記フォームは選択されたウィンドウのポイントにあるグリフ左上隅にマウスカーソルを“ワープ”させる。この方法で計算される位置は、そこにツールチップウィンドウを表示するためにも使用できる。
以下の関数はウィンドウ内で可視なバッファー位置のスクリーン座標をリターンします。
バッファー位置positionがウィンドウwindow内で可視なら、この関数はpositionにあるグリフの左上隅のディスプレー座標をリターンする。リターン値はwindowのディスプレー原点(0,
0)から相対的な、X座標とY座標からなるコンスセル。window内でpositionが不可視ならnil
をリターンする。
windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。positionのデフォルトはwindowのwindow-point
の値。
これは選択されたウィンドウ内のポイント位置へのマウスポインターの移動は、以下のような記述で足りることを意味する:
(let ((position (window-absolute-pixel-position))) (set-mouse-absolute-pixel-position (car position) (cdr position)))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウ構成(window configuration)とは1つのフレーム上全体のレイアウト —
すべてのウィンドウとサイズ、どんなバッファーを含んでいるか、それらのバッファーがスクロールされる方法、およびポイント値を記録して、更にフリンジ、マージン、スクロールバーのセッティングも記録します。これにはminibuffer-scroll-window
の値も含まれます。特別な例外としてウィンドウ構成には選択されたウィンドウのカレントバッファーのポイント値は記録されません。
以前に保存されたウィンドウ構成をリストアすることにより、フレーム全体のレイアウトをリストアすることができます。1つだけではなくすべてのフレームのレイアウトを記録したければ、ウィンドウ構成のかわりにフレーム構成(frame configuration)を使用します。フレーム構成を参照してください。
この関数はframeのカレントのウィンドウ構成を表す新たなオブジェクトをリターンする。frameのデフォルトは選択されたフレーム。変数window-persistent-parameters
はこの関数により保存されるウィンドウパラメーター(もしあれば)を指定する。ウィンドウのパラメーターを参照のこと。
この関数はconfigurationが作成されたフレームにたいして、ウィンドウとバッファーの構成をconfigurationで指定された構成にリストアする。
引数configurationは以前にcurrent-window-configuration
がリターンした値でなければならない。この構成はそのフレームが選択されているか否かに関わらず、configurationが作成時のフレームから当該フレームにリストアされる。これは常にウィンドウのサイズ変更とみなされて、window-size-change-functions
(ウィンドウのスクロールと変更のためのフックを参照)の実行をトリガーする。なぜならset-window-configuration
は新たな構成が古い構成と実際に異なるかを示す方法を知らないからである。
configurationが保存されたフレームが死んでいる(生きていない)場合には、この関数が行うのは3つの変数window-min-height
、window-min-width
、minibuffer-scroll-window
のリストアのみ。この場合には関数はnil
、それ以外はt
をリターンする。
以下はsave-window-excursion
と同様な効果を得るためにこの関数を使用する例:
(let ((config (current-window-configuration))) (unwind-protect (progn (split-window-below nil) …) (set-window-configuration config)))
このマクロは選択されたフレームのウィンドウ構成を記録して、formsを順に実行してから以前のウィンドウ構成をリストアする。リターン値はforms内の最後のフォームの値。
Lispコードのほとんどはこのマクロを使用するべきではない。大抵はsave-selected-window
で十分であろう。特にこのマクロはforms内で新たなウィンドウをオープンするコードを確実に防ぐことができず、新たなウィンドウは別のフレーム内でオープンされるかもしれないが(表示するウィンドウの選択を参照)、save-window-excursion
が保存とリストアするのはカレントフレーム上のウィンドウ構成だけだからである。
このマクロをwindow-size-change-functions
内で使用してはならない。このマクロをexitすることによりwindow-size-change-functions
の実行がトリガーされるが無限ループを引き起こす。
この関数はobjectがウィンドウ構成ならt
をリターンする。
この関数はポイント値、保存されたスクロール位置を無視して(つまりこれらの観点が異なってもt
をリターンし得る)、ウィンドウ構造の観点から2つのウィンドウ構成を比較する。
関数equal
も2つのウィンドウ構成を比較できる。これはすべての点からたとえ1つでも異なるものがあれば等しい構成とはみなさず、たとえ保存されたポイント値が異なるだけでも等しくないとみなす。
この関数はウィンドウ構成configが作成されたフレームをリターンする。
ウィンドウ構成の内部を調べる他のプリミティブも有用かもしれませんが、わたしたちはこれらを必要としないので実装されていません。ウィンドウ構成にたいしてより多くの操作を知りたければ、ファイルwinner.elを参照してください。
current-window-configuration
がリターンするオブジェクトはEmacsプロセスとともに死滅します。ウィンドウ構成をディスク上に格納してそれを別のEmacsセッションに読み戻すために、次に説明する関数を使用できます。これらの関数はフレームの状態を任意の生きたウィンドウにクローンする場合にも有用です(set-window-configuration
はフレームのウィンドウをそのフレームのルートウィンドウだけに効果的にクローンする)。
この関数はwindowの状態をLispオブジェクトとしてリターンする。引数windowは有効なウィンドウでなければならずデフォルトは選択されたフレームのルートウィンドウ。
オプション引数writableが非nil
なら、それはwindow-point
やwindow-start
のようなサンプリング位置にたいするマーカーを使用しないことを意味する。この状態をディスクに書き込んで別のセッションに読み戻すなら、この引数は非nil
であること。
この関数によりどのウィンドウパラメーターが保存されるかは、引数writableと変数window-persistent-parameters
の両方で指定する。ウィンドウのパラメーターを参照のこと。
window-state-get
によりリターンされる値は、同一セッション内の他のウィンドウ内にあるウィンドウのクローンを作成するために使用できます。これはディスクに書き込んで別のセッションに読み戻すこともできます。いずれの場合にもウィンドウの状態をリストアするためには以下の関数を使用します。
この関数はウィンドウ状態stateをwindow内にputする。引数stateは以前に呼び出したwindow-state-get
がリターンしたウィンドウ状態であること。オプション引数windowには生きたウィンドウか内部ウィンドウ(ウィンドウとフレームを参照)のいずれかを指定でき、デフォルトは選択されたウィンドウ。windowが生きていなければ、stateをputする前に生きたウィンドウに置き換える。
オプション引数ignoreが非nil
なら、それは最小ウィンドウサイズと固定サイズの制限を無視することを意味する。ignoreがsafe
なら、それは1行および/または2列までできる限り小さくできることを意味する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではウィンドウに追加の情報を関連付けるためにウィンドウパラメーターを使用する方法を説明します。
この関数はwindowのparameterの値をリターンする。windowのデフォルトは選択されたウィンドウ。windowにparameterにたいするセッティングがなければ、この関数はnil
をリターンする。
この関数はwindowのすべてのパラメーターと値をリターンする。windowのデフォルトは選択されたウィンドウ。リターン値はnil
、または(parameter
. value)
という形式をもつ要素からなる連想リスト。
この関数はwindowのparameterの値にvalueをセットしてvalueをリターンする。windowのデフォルトは選択されたウィンドウ。
デフォルトではウィンドウ構成(window configuration)やウィンドウ状態(states of
windows)の保存とリストアを行う関数は、ウィンドウパラメーターについては関知しません(ウィンドウの構成を参照)。これはsave-window-excursion
のbody内でパラメーターの値を変更したときは、そのマクロのexit時に以前の値がリストアされないことを意味します。これはまた以前にwindow-state-get
で保存されたウィンドウ状態をwindow-state-put
でリストアしたときは、クローンされたすべてのウィンドウのパラメーターがnil
にリセットされることも意味します。以下の変数によってこの標準の挙動をオーバーライドできます:
この変数はcurrent-window-configuration
とwindow-state-get
により保存、set-window-configuration
とwindow-state-put
によりリストアされるパラメーターを指定するalistである。ウィンドウの構成を参照のこと。
このalistの各エントリーのCARはパラメーターを指定するシンボル。CDRは以下のいずれかであること:
nil
この値はそのパラメーターがwindow-state-get
とcurrent-window-configuration
のいずれによっても保存されていないことを意味する。
t
この値はそのパラメーターがcurrent-window-configuration
、および(writable引数がnil
なら)window-state-get
により保存されたことを意味する。
writable
これはそのパラメーターが無条件でcurrent-window-configuration
とwindow-state-get
の両方により保存されたことを意味する。この値は入力構文(read
syntax)をもたないパラメーターに使用するべきではない。使用した場合には、別のセッションでwindow-state-put
を呼び出すとinvalid-read-syntax
エラーで失敗するだろう。
いくつかの関数(特にdelete-window
、delete-other-windows
、split-window
)は、window引数にパラメーターセットをもつ場合には特別な挙動を示すかもしれません。以下の変数を非nil
値にバインドすることにより、そのような特別な挙動をオーバーライドできます:
この変数が非nil
なら、いくつかの標準関数はウィンドウパラメーターを処理しない。現在のところ影響を受ける関数はsplit-window
、delete-window
、delete-other-windows
、other-window
。
これらの関数の呼び出し周辺でアプリケーションはこの変数を非nil
にバインドできる。これを行うと、そのアプリケーションはその関数のexit時に関連するすべてのウィンドウのパラメーターを正しく割り当てる責任をもつ。
以下のパラメーターは現在のところウィンドウ管理コードにより使用されています:
delete-window
このパラメーターはdelete-window
の実行に影響する(ウィンドウの削除を参照)。
delete-other-windows
このパラメーターはdelete-other-windows
の実行に影響する(ウィンドウの削除を参照)。
split-window
このパラメーターはsplit-window
の実行に影響する(ウィンドウの分割を参照)。
other-window
このパラメーターはother-window
の実行に影響する(ウィンドウのサイクル順を参照)。
no-other-window
このパラメーターはそのウィンドウをother-window
による選択が不可だとマークする(ウィンドウのサイクル順を参照)。
clone-of
このパラメーターはそのウィンドウがクローンされたことを指定する。これはwindow-state-get
によりインストールされる(ウィンドウの構成を参照)。
preserved-size
このパラメーターはバッファー、方向(nil
は垂直でt
は水平)、ピクセル単位のサイズを指定する。そのウィンドウが指定されたバッファーを表示していて、かつ指示された方向のサイズがこのパラメーターで指定されたサイズと等しければ、Emacsはそのウィンドウの指示された方向のサイズを予約する。関数window-preserve-size
によりこのパラメーターのインストールと更新が行われる(Preserving Window Sizesを参照)。
quit-restore
このパラメーターはバッファー表示関数によりインストールされて、quit-restore-window
により参照される(ウィンドウのquitを参照)。これは4つの要素を含む:
1つ目の要素はwindow
(ウィンドウはdisplay-buffer
により特別に作成される)、frame
(別フレームを作成する)、same
(ウィンドウは前と同じバッファーを表示する)、other
(ウィンドウは前と異なるバッファーを表示する)のシンボルのいずれかである。
2つ目の要素はシンボルwindow
、frame
、または要素がそのウィンドウに前に表示されていたバッファー、そのときのウィンドウstart位置、ウィンドウポイント位置、ウィンドウの高さであるようなリストのいずれか。
3つ目の要素はそのパラメーター作成時点に選択されていたウィンドウ。関数quit-restore-window
は、その引数としてこのウィンドウが渡された際にはそのウィンドウの再選択を試みる。
4つ目の要素はその表示がこのパラメーターの生成を引き起こしたバッファー。quit-restore-window
は指定されたウィンドウがまだそのバッファーを表示している場合のみそれを削除する。
min-margins
このパラメーターの値は、(非nil
なら)
CARとCDRがそのウィンドウの左右のマージンの最小値(列数)を指定するようなコンスセル。与えられた際には、Emacsはウィンドウを水平方向に分割または縮小できるかを決定するために、実際のマージン幅のかわりにこれらの値を使用するだろう。
すべてのウィンドウにたいして、分割やリサイズ後にEmacsがマージンの自動調整をすることは決してない。これはそのウィンドウト分割のためにこのウィンドウのマージンを継承する新たなウィンドウニタイシテ、マージンを調整するためにこのパラメーターをセットするすべてのアプリケーション単独の責任である。window-configuration-change-hook
とwindow-size-change-functions
はいずれもこの用途に使用すること(ウィンドウのスクロールと変更のためのフックを参照)。
これはウィンドウ内でバッファーをセンタリングするために大きなマージンを使用するアプリケーションのサポート用にEmacsのバージョン25.1から導入されたパラメーターであり、それらのアプリケーションと排他となるよう留意して使用すること。Emacsの将来のバージョンで改善策により置換され得る。
追加のパラメーターとしてwindow-atom
とwindow-side
があります。これらは予約済みでアプリケーションが使用するべきではありません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは、あるウィンドウがそのバッファーの違う部分を表示したり、別のバッファーを表示したとき常にLispプログラムを実行可能にする方法について説明します。これを変更できる3つのアクションがあります。それはウィンドウのスクロール、ウィンドウ内でのバッファーの切り替え、ウィンドウのサイズ変更です。最初の2つのアクションはwindow-scroll-functions
、最後のアクションはwindow-size-change-functions
を実行します。
この変数はウィンドウのスクロールによりEmacsが再表示前に呼び出すべき関数のリストを保持する。そのウィンドウ内に異なるバッファーを表示したときもこれらの関数が実行される。
この変数はそれぞれの関数が2つの引数、ウィンドウとウィンドウの新たなdisplay-start位置で呼び出されるのでノーマルフックではない。
これらの関数はwindow-end
(ウィンドウの開始位置と終了位置を参照)を使用する際には気をつけなければならない。最新の値が必要なら、それを確実に入力するためにupdate引数を使用しなければならない。
警告: ウィンドウのスクロール方法を変更するためにこの機能を使用してはならない。これはそのような用途のためにデザインされておらず、そのような使用では機能しないだろう。
この変数は、理由は何であれ任意のウィンドウのサイズが変更された場合に呼び出される関数のリストを保持する。これらの関数は、再表示サイクルの先頭、およびサイズ変更が発生したフレーム上で1回呼び出される。
それぞれの関数はフレームを唯一の引数として呼び出される。そのフレーム上のどのウィンドウのサイズが変更されたか、および変更された正確な方法を直接探す方法はない。とはいえ各呼び出しにおいてsize-change関数が既存のウィンドウとサイズを記録すれば、現在のサイズと以前のサイズを比較することも可能である。
ウィンドウの作成と削除はサイズの変更とみなされるので、これらの関数の呼び出しを引き起こす。フレームのサイズ変更は既存のウィンドウのサイズを変更するので、これも変更とみなされる。
これらの関数内でsave-selected-window
を使用できる(ウィンドウの選択を参照)。しかしsave-window-excursion
(ウィンドウの構成を参照)を使用してはならない。このマクロのexitはサイズ変更とみなされ、それはこれらの関数の際限ない呼び出しを引き起こすだろう。
既存フレームのウィンドウ構成を変更するたびに毎回実行されるノーマルフック。これにはウィンドウの分割と削除、ウィンドウのサイズ変更、ウィンドウ内への異なるバッファーの表示が含まれる。
このフックのバッファーローカルな部分は影響を受けるフレーム上の各ウィンドウにたいして、関係するウィンドウを選択およびそのバッファーをカレントにして1回実行される。グローバルな部分は変更されたフレームにたいして、そのフレームを選択して1回実行される。
加えてFont Lockフォント表示関数(Font Lock fontification
function)を登録するためにjit-lock-register
を使用できる。バッファーの一部が(再)フォント表示されたときは、ウィンドウがスクロールまたはサイズ変更されたという理由で、これが常に呼び出されるだろう。Font Lockのその他の変数を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレーム(frame)とは、1つ以上のEmacsウィンドウを含むスクリーンオブジェクトです(ウィンドウを参照)。これはグラフィカル環境では“ウィンドウ”と呼ばれる類のオブジェクトです。しかしEmacsはこの単語を異なる方法で使用しているので、ここではそれを“ウィンドウ”と呼ぶことはできません。Emacs Lispにおいてフレームオブジェクト(frame object)とは、スクリーン上のフレームを表すLispオブジェクトです。フレーム型を参照してください。
フレームには最初は1つのメインウィンドウおよび/またはミニバッファーウィンドウが含まれます。メインウィンドウは、より小さいウィンドウに垂直か水平に分割することができます。ウィンドウの分割を参照してください。
端末(terminal)とは1つ以上のEmacsフレームを表示する能力のあるデバイスのことです。Emacs Lispにおいて端末オブジェクト(terminal object)とは端末を表すLispオブジェクトです。端末型を参照してください。
端末にはテキスト端末(text terminals)とグラフィカル端末(graphical
terminals)という2つのクラスがあります。テキスト端末はグラフィック能力をもたないディスプレイであり、xterm
やその他の端末エミュレーターが含まれます。テキスト端末上ではそれぞれのEmacsフレームはその端末のスクリーン全体を占有します。たとえ追加のフレームを作成してそれらを切り替えることができたとしても、端末が表示するのは一度に1つのフレームだけです。一方でグラフィカル端末はXウィンドウシステムのようなグラフィカルディスプレイシステムにより管理されています。これによりEmacsは同一ディスプレイ上に複数のフレームを同時に表示することができます。
GNUおよびUnix systemsシステムでは、単一のEmacsセッション内でそのEmacsがテキスト端末とグラフィカル端末のいずれで開始されたかに関わらず、任意の利用可能な端末上で追加のフレームを作成することができます。Emacsは、グラフィカル端末とテキスト端末の両方を同時に表示することができます。 これはたとえばリモートから同じセッションに接続する際などに便利でしょう。複数の端末を参照してください。
この述語(predicate)はobjectがフレームなら非nil
、それ以外はnil
をリターンする。フレームにたいしてはフレームが使用するディスプレイの種類が値:
t
そのフレームはテキスト端末上で表示されている。
x
そのフレームはXグラフィカル端末上で表示されている。
w32
そのフレームはMS-Windowsグラフィカル端末上で表示されている。
ns
そのフレームはGNUstepかMacintosh Cocoaグラフィカル端末上で表示されている。
pc
そのフレームはMS-DOS端末上で表示されている。
この関数はframeを表示する端末オブジェクトをリターンする。frameがnil
または未指定の場合のデフォルトは選択されたフレーム。
この述語はobjectが生きた(削除されていない)端末なら非nil
、それ以外はnil
をリターンする。生きた端末にたいしては、リターン値はその端末上で表示されているフレームの種類を示す。可能な値は上述のframep
と同様。
28.1 フレームの作成 | 追加のフレームの作成。 | |
28.2 複数の端末 | 異なる複数デバイス上での表示。 | |
28.3 Frame Geometry | Geometric properties of frames. | |
28.4 フレームのパラメーター | フレームのサイズと位置、フォント等の制御。 | |
28.5 端末のパラメーター | 端末上のすべてのフレームにたいして一般的なパラメーター。 | |
28.6 フレームのタイトル | フレームタイトルの自動的な更新。 | |
28.7 フレームの削除 | 明示的に削除されるまでフレームは存続する。 | |
28.8 すべてのフレームを探す | すべての既存フレームを調べる方法。 | |
28.9 ミニバッファーとフレーム | フレームが使用するミニバッファーを見つける方法。 | |
28.10 入力のフォーカス | 選択されたフレームの指定。 | |
28.11 フレームの可視性 | フレームは可視や不可視、またはアイコン化されているかもしれない。 | |
28.12 フレームを前面や背面に移動する | フレームを前面に移動して他のウィンドウを隠し、背面に移動して他のウィンドウがフレームを隠す。 | |
28.13 フレーム構成 | すべてのフレームの状態の保存。 | |
28.14 マウスの追跡 | マウス移動時のイベントの取得。 | |
28.15 マウスの位置 | マウスの場所や移動を問い合わせる。 | |
28.16 ポップアップメニュー | ユーザーに選択させるためのメニューの表示。 | |
28.17 ダイアログボックス | yes/noを問い合わせるためのボックスの表示。 | |
28.18 ポインターの形状 | マウスポインターのシェイプの指定。 | |
28.19 ウィンドウシステムによる選択 | 他のXクライアントとのテキストの転送。 | |
28.20 ドラッグアンドドロップ | ドラッグアンドドロップの実装の内部。 | |
28.21 カラー名 | カラー名定義の取得。 | |
28.22 テキスト端末のカラー | テキスト端末のカラーの定義。 | |
28.23 Xリソース | サーバーからのリソース値の取得。 | |
28.24 ディスプレー機能のテスト | 端末の機能の判定。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
新たにフレームを作成するためには関数make-frame
を呼び出します。
この関数はカレントバッファーを表示するフレームを作成してそれをリターンする。
alist引数は新たなフレームのフレームパラメーターを指定するalist。フレームのパラメーターを参照のこと。alist内でterminal
パラメーターを指定すると新たなフレームはその端末上で作成される。それ以外ならalist内でwindow-system
フレームパラメーターを指定した場合には、それはフレームがテキスト端末とグラフィカル端末のどちらで表示されるべきかを決定する。ウィンドウシステムを参照のこと。どちらも指定されなければ新たなフレームは選択されたフレームと同じ端末上に作成される。
alistで指定されなかったパラメーターのデフォルトは、default-frame-alist
というalist内の値。そこでも指定されないパラメーターのデフォルトはXリソース、またはそのオペレーティングシステムで同等のものの値となる(X Resources in The GNU Emacs
Manualを参照)。フレームが作成された後にEmacsはframe-inherited-parameters
(以下参照)内にリストされたすべてのパラメーターを適用して、引数にないものはmake-frame
呼び出し時に選択されていたフレームから値を取得する。
マルチモニターディスプレイ(複数の端末を参照)では、ウィンドウマネージャーがalist内の位置パラメーター(位置のパラメーターを参照)の指定とは異なる位置にフレームを配置するかもしれないことに注意。たとえばウィンドウの大きな部分、いわゆる支配モニター(dominating monitor)上のフレームを表示するポリシーをもつウィンドウマネージャーがいくつかあります。
この関数自体が新たなフレームを選択されたフレームにする訳ではない。入力のフォーカスを参照のこと。以前に選択されていたフレームは選択されたままである。しかしグラフィカル端末上ではウィンドウシステム自身の理由によって新たなフレームが選択されるかもしれない。
make-frame
がフレームを作成する前に、それにより実行されるノーマルフック。
make-frame
がフレームを作成した後に、それにより実行されるアブノーマルフック。after-make-frame-functions
内の各関数は作成された直後のフレームを単一の引数として受け取る。
この変数はカレントで選択されているフレームから継承して新たに作成されたフレームのフレームパラメーターのリストを指定する。リスト内の各要素はmake-frame
の引数として与えられなかったパラメーター(シンボル)であり、make-frame
は新たに作成されたフレームのそのパラメーターに選択されたフレームのパラメーターの値をセットする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはそれぞれの端末を端末オブジェクト(terminal object)というデータ型で表します(端末型を参照)。GNUおよびUnixシステムではEmacsはそれぞれのセッション内で複数の端末を同時に実行できます。その他のシステムでは単一の端末だけが使用できます。端末オブジェクトはそれぞれ以下の属性をもちます:
terminal-live-p
によりリターンされるシンボル(たとえばx
、t
、w32
、ns
、pc
)。フレームを参照のこと。
端末オブジェクトを作成するプリミティブはありません。make-frame-on-display
(以下参照)を呼び出したときなどに、Emacsが必要に応じてそれらを作成します。
この関数はterminalにより使用されるデバイスのファイル名をリターンする。terminalが省略またはnil
の場合のデフォルトは選択されたフレームの端末。terminalはフレームでもよく、その場合はそのフレームの端末。
この関数はすべての生きた端末オブジェクトのリストをリターンする。
この関数はdeviceにより与えられたデバイス名の端末をリターンする。deviceが文字列なら端末デバイス名、または‘host:server.screen’という形式のXディスプレイのいずれかを指定できる。deviceならこの関数はそのフレームの端末をリターンする。nil
は選択されたフレームを意味する。最後にもしdeviceが生きた端末を表す端末オブジェクトなら、その端末がリターンされる。引数がこれらのいずれとも異なれば、この関数はエラーをシグナルする。
この関数はterminal上のすべてのフレームを削除して、それらが使用していたリソースを解放する。これらはアブノーマルフックdelete-terminal-functions
を実行して、各関数の引数としてterminalを渡す。
terminalが省略またはnil
の場合のデフォルトは選択されたフレームの端末。terminalはフレームでもよく、その場合はそのフレームの端末を意味する。
この関数は通常は唯一アクティブな端末の削除を試みるとエラーをシグナルするが、forceが非nil
ならこれを行うことができる。端末上で最後のフレームを削除した際には、Emacsは自動的にこの関数を呼び出す(フレームの削除を参照)。
delete-terminal
により実行されるアブノーマルフック。各関数はdelete-terminal
に渡されたterminalを唯一の引数として受け取る。技術的な詳細により、この関数は端末の削除の直前または直後のいずれかに呼び出される。
数は多くありませんが、Lisp変数のいくつかは端末ローカル(terminal-local)です。つまりそれらは端末それぞれにたいして個別にバインディングをもちます。いかなるときも実際に効果をもつバインディングはカレントで選択されたフレームに属する端末にたいして1つだけです。これらの変数にはdefault-minibuffer-frame
、defining-kbd-macro
、last-kbd-macro
、system-key-alist
が含まれます。これらは常に端末ローカルであり、決してバッファーローカル(バッファーローカル変数を参照)にはできません。
GNUおよびUnixシステムでは、Xディスプレイはそれぞれ別のグラフィカル端末になります。Xウィンドウシステム内でEmacsが開始された際は環境変数DISPLAY
、または‘--display’オプション(Initial
Options in The GNU Emacs
Manualを参照)により指定されたXディスプレイを使用します。Emacsはコマンドmake-frame-on-display
を通じて別のXディスプレイに接続できます。それぞれのXディスプレイは、それぞれが選択されたフレームとミニバッファーをもちます。しかしあらゆる瞬間(入力のフォーカスを参照)において、それらのフレームのうちの1つだけが、いわゆる選択されたフレームになります。emacsclient
との対話により、Emacsが別のテキスト端末と接続することさえ可能です。Emacs
Server in The GNU Emacs Manualを参照してください。
1つのXサーバーが1つ以上のディスプレイを処理できます。各Xディスプレイには‘hostname:displaynumber.screennumber’という3つの部分からなる名前があります。1つ目の部分のhostnameはその端末が物理的に接続されるマシン名です。2つ目の部分のdisplaynumberは同じキーボードとポインティングデバイス(マウスやタブレット等)を共有するマシンに接続された1つ以上のモニターを識別するための0基準の番号です。3つ目の部分のscreennumberは、そのXサーバー上の単一のモニターコレクション(a single monitor collection)の一部である0基準のスクリーン番号(個別のモニター)です。1つのサーバー配下にある2つ以上のスクリーンを使用する際には、Emacsはそれらの名前の同一部分から、それらが単一のキーボードを共有することを知ることができるのです。
MS-WindowsのようにXウィンドウシステムを使用しないシステムはXディスプレイの概念をサポートせず、各ホスト上には1つのディスプレイだけがあります。これらのシステム上のディスプレイ名は上述したような3つの部分からなる名前にしたがいません。たとえばMS-Windowsシステム上のディスプレイ名は文字列定数‘w32’です。これは互換性のために存在するものであり、ディスプレイ名を期待する関数にこれを渡すことができます。
この関数はdisplay上に新たにフレームを作成してそれをリターンする。その他のフレームパラメーターは、parametersというalistから取得する。displayはXディスプレイの名前(文字列)であること。
この関数はフレーム作成前にEmacsがグラフィックを表示するためにセットアップされることを保証する。(テキスト端末上で開始された等で)たとえばEmacsがXリソースを未処理ならこの時点で処理を行う。他のすべての点においては、この関数はmake-frame
(フレームの作成を参照)と同様に振る舞う。
この関数はEmacsがどのXディスプレイに接続したかを識別するリストをリターンする。このリストの要素は文字列で、それぞれがディスプレイ名を表す。
この関数はディスプレイ上にフレームを作成することなく、Xディスプレイdisplayへの接続をオープンする。通常はmake-frame-on-display
が自動的に呼び出すので、Emacs
Lispプログラムがこの関数を呼び出す必要はない。これを呼び出す唯一の理由は、与えられたXディスプレイにたいして通信を確立できるかどうかチェックするためである。
オプション引数xrm-stringが非nil
なら、それは.Xresourcesファイル内で使用されるフォーマットと同一なリソース名とリソース値。X Resources in The GNU Emacs
Manualを参照のこと。これらの値はそのXサーバー上で記録されたリソース値をオーバーライドして、このディスプレイ上で作成されるすべてのEmacsフレームにたいして適用される。以下はこの文字列がどのようなものかを示す例:
"*BorderWidth: 3\n*InternalBorder: 2\n"
must-succeedが非nil
なら、接続オープンの失敗によりEmacsが終了させられる。それ以外なら通常のLispエラーとなる。
この関数はディスプレイdisplayへの接続をクローズする。これを行う前には、まずそのディスプレイ上でオープンしたすべてのフレームを削除しなければならない(フレームの削除を参照)。
マルチモニターのセットアップにおいて、単一のXディスプレイが複数の物理モニターに出力される場合があります。そのようなセットアップを取得するために関数display-monitor-attributes-list
とframe-monitor-attributes
を使用できます。
この関数はdisplay上の物理モニターの属性のリストをリターンする。displayにはディスプレイ名(文字列)、端末、フレームを指定でき、省略またはnil
の場合のデフォルトは選択されたフレームのディスプレイ。このリストの各要素は物理モニターの属性を表す連想リスト。1つ目の要素はプライマリーモニターである。以下は属性のキーと値:
‘(x y width height)’のようなピクセル単位でのそのモニターのスクリーンの左上隅の位置とサイズ。そのモニターがプライマリーモニターでなければ、いくつかの座標が負になり得る。
‘(x y width height)’のようなピクセル単位でのワークエリア(使用可能なスペース)の左上隅の位置とサイズ。ウィンドウマネージャーのさまざまな機能(dock、taskbar等)によりそのスペースが占有される‘geometry’とは異なり、これはワークエリアから除外され得る。そのような機能が実際にワークエリアから差し引かれるかどうかは、そのプラットフォームと環境に依存する。繰り返しになるが、そのモニターがプライマリーモニターでなければ、いくつかの座標は負になり得る。
‘(width height)’<のようなミリメートル単位での幅と高さ。
その物理モニターが支配(dominate)するフレームのリスト(以下参照)。
stringのようなその物理モニターの名前。
stringのようなマルチモニターの情報ソース(例: ‘XRandr’、‘Xinerama’等)。
x、y、width、heightは整数。‘name’と‘source’は欠落しているかもしれない。
あるモニター内にフレームの最大領域がある、または(フレームがどの物理モニターにも跨がらないなら)そのモニターがフレームに最も近いとき、フレームは物理モニターにより支配(dominate)される。グラフィカルなディスプレイ内の(ツールチップではない)すべてのフレームは、たとえそのフレームが複数の物理モニターに跨がる(または物理モニター上にない)としても、(可視か否かによらず)正確に1つの物理モニターにより支配される。
以下は2つのモニターディスプレイ上でこの関数により生成されたデータの例:
(display-monitor-attributes-list) ⇒ (((geometry 0 0 1920 1080) ;; 左手側プライマリーモニター (workarea 0 0 1920 1050) ;; タスクバーが幾分かの高さを占有 (mm-size 677 381) (name . "DISPLAY1") (frames #<frame emacs@host *Messages* 0x11578c0> #<frame emacs@host *scratch* 0x114b838>)) ((geometry 1920 0 1680 1050) ;; 右手側モニター (workarea 1920 0 1680 1050) ;; スクリーン全体を使用可 (mm-size 593 370) (name . "DISPLAY2") (frames)))
この関数はframeを支配(上記参照)する物理モニターの属性をリターンする。 frameのデフォルトは選択されたフレーム。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレームのジオメトリー(geometry)は、そのEmacsインスタンスのビルドに使用されたツールキット、およびそのフレームを表示する端末に依存します。このチャプターではこれらの依存関係とそれらを処理するいくつかの関数を説明します。これらの関数すべてにたいして、frame引数には生きたフレームを指定する必要があることに注意してください(フレームの削除を参照)。省略またはnil
なら選択されたフレーム(入力のフォーカスを参照)が指定されます。
28.3.1 Frame Layout | フレームの基本的なレイアウト。 | |
28.3.2 Frame Font | フレームのデフォルトフォントとセット方法。 | |
28.3.3 Size and Position | フレームのサイズと位置の変更。 | |
28.3.4 Implied Frame Resizing | フレームの暗黙なリサイズと予約方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下にグラフィカル端末上のフレームレイアウトを図示します:
<------------ Outer Frame Width -----------> ___________________________________________ ^(0) ___________ External Border __________ | | | |_____________ Title Bar ______________| | | | (1)_____________ Menu Bar ______________| | ^ | | (2)_____________ Tool Bar ______________| | ^ | | (3) _________ Internal Border ________ | | ^ | | | | ^ | | | | | | | | | | | | | Outer | | | Inner | | | Native Frame | | | Frame | | | Frame Height | | | Height | | | Height | | | | | | | | | | | | |<--+--- Inner Frame Width ------->| | | | | | | | | | | | | | | | |___v______________________________| | | | | | |___________ Internal Border __________| | v v |______________ External Border _____________| <-------- Native Frame Width -------->
図示したすべての領域が実際に存在するわけではありません。これらの領域はそれぞれ以下を意味しています:
アウターフレーム(outer frame)とは上図で示すすべての領域を網羅する矩形。この矩形の端はそのフレームのアウターエッジ(outer edges)と呼ばれる。フレームのアウター幅(outer width)とアウター高さ(outer height)はこの矩形のサイズを指定する。
(上図‘(0)’で示される)アウターフレームの左上隅はフレームのアウター位置(outer
position)。これはフレームパラメーターleft
とtop
による指定(位置のパラメーターを参照)、同様に関数frame-position
とset-frame-position
(Size and Positionを参照)を通じてセットできる。
エクスターナルボーダー(external border)はウィンドウマネージャーにより供給される装飾の一部。マウスによるフレームのリサイズで典型的に使用される。エクスターナルボーダーは、通常は“全画面化(fullboth)”および最大化されたフレームでは表示されず(サイズのパラメーターを参照)、テキスト端末のフレームには存在しない。
フレームパラメーターborder-width
(レイアウトのパラメーターを参照)で指定されるアウターボーダー(outer
border)とエクスターナルボーダーを混同しないこと。アウターボーダーはほとんどのプラットフォームで通常は無視されるので、ここでは説明しない。
タイトルバー(title bar)もウィンドウマネージャーによる装飾の一部であり、典型的にはフレームタイトルの表示(フレームのタイトルを参照)、フレームの最小化や最大化、削除のためのボタン表示に使用される。タイトルバーは全画面表示(サイズのパラメーターを参照やツールチップフレームでは通常は表示されない。テキスト端末フレームではタイトルバーは存在しない。
メニューバー(メニューバー Barを参照)にはインターナル(Emacs自身が描画)とエクスターナル(ツールキットが描画)がある。ほとんどのビルド(GTK+、Lucid、Motif、Windows)にはエクスターナルメニューバーが存在する。NSでもエクスターナルメニューバーを使用するがアウターフレームの一部ではない。非ツールキットのビルドではインターナルメニューバーが提供可能。テキスト端末のフレームでは、メニューバーはフレームのルートウィンドウの(ウィンドウとフレームを参照)一部である。
メニューバーのように、ツールバー(ツールバーを参照)にもインターナル(Emacs自身が描画)とエクスターナル(ツールキットが描画)がある。GTK+とNSのビルドには、そのツールキットが描画するツールバーがある。その他のビルドはインターナルツールバーを使用する。GTK+ではツールバーはフレーム側面かインターナルボーダー(以下参照)の外側にのいずれかに配置され得る。
ネイティブフレーム(native frame)はアウターフレーム内全体に配置される矩形。エクスターナルボーダーとタイトルバー、およびエクスターナルメニューとエクスターナルツールバーが占有する領域は除外される。ネイティブフレームで囲まれた領域は、そのフレームのディスプレー領域(display area)として参照されることもある。ネイティブフレームのエッジは、そのフレームのネイティブエッジ(native edges)と呼ばれる。フレームのネイティブ幅(native width)とネイティブ高さ(native height)は、この矩形のサイズを指定する。
ネイティブフレームの左上隅は、そのフレームのネイティブ位置(native position)を指定する。上図(1)から(3)では種々ビルドにたいする位置を示す:
これに応じてフレームのネイティブ高さにはツールバーの高さが含まれるがメニューバーの高さ(Lucid、Motif、Windows)や、メニューバーとツールバーの高さ(非ツールキットとテキスト端末のフレーム)は含まれない。
フレームのネイティブ位置はマウスのカレント位置のセットやリターンを行う関数(マウスの位置を参照)、およびwindow-edges
、window-at
、coordinates-in-window-p
のようなウィンドウの位置を扱う関数(座標とウィンドウを参照)にたいして基準となる位置である。
インターナルボーダー(レイアウトのパラメーターを参照)はEmacsがインナーフレーム(以下参照)周囲に描画するボーダー。
インナーフレーム(inner frame)はフレームのウィンドウが確保する矩形。インターナルボーダーに囲まれているが、それはインナーフレームの一部ではない。それのエッジはフレームのインナーエッジ(inner edges)と呼ばれる。インナー幅(inner width)とインナー高さ(inner height)は、その矩形のサイズを指定する。
ルールとしてインナーフレームはフレームのルートウィンドウ(ウィンドウとフレームを参照)とミニバッファーウィンドウ(ミニバッファーのウィンドウを参照)に細分される。この2つには注目すべき2つの例外がある。それはミニバッファーウィンドウをもたないルートウィンドウのみのミニバッファーlessフレーム(minibuffer-less frame)と、ミニバッファーウィンドウだけをもち、それがフレームのルートウィンドウの役目も果たすミニバッファーonlyウィンドウ(minibuffer-only frame)である。そのようなフレーム構成を作成する方法はフレームの初期パラメーターを参照のこと。
フレームのテキストエリア(text area)とは、ネイティブフレーム内に全体が配置される架空な類のエリアである。このエリアはネイティブフレームからすべてのインターナルボーダー、垂直スクロールバーと水平スクロールバー、およびそのフレームにたいして指定された左右のフリンジを取り除くことにより取得できる。レイアウトのパラメーターを参照のこと。
フレームやフレームのエッジの絶対位置(absolute position)とは、通常はそのフレームのディスプレーの位置(0, 0)にある原点から計測したピクセル単位で与えられます。複数モニターの原点は、使用可能なディスプレーエリア全体の左上隅と一致する必要はないことに注意してください。そのため、そのような環境ではフレームの絶対アウター位置やアウターフレーム、ネイティブフレーム、インナーフレームのエッジの絶対位置は、たとえそのフレームが完全に可視であっても負になり得ます。
以下の関数はグラフィカル端末上のフレームにたいして上述したエリアのサイズをリターンします:
この関数はframeのジオメトリーに関する属性をリターンする。リターン値は属性の連想配列。すべての座標、高さ、幅はピクセル単位の整数。
outer-position
frameのディスプレー位置(0, 0)にある原点から相対的なframeのアウター位置を表す、絶対X座標と絶対Y座標によるコンス。
outer-size
frameのアウター幅とアウター高さを表すコンス。
external-border-size
ウィンドウマネージャーにより与えられる、frameエクスターナルボーダーの水平幅と垂直幅を表すコンス。ウィンドウマネージャーによりこれらの値が提供されなければ、Emacsはアウターフレームとインナーフレームの座標からそれらの推測を試みる。
title-bar-size
ウィンドウマネージャーまたはオペレーティングシステムが与える、frameのタイトルバーの幅と高さを表すコンス。いずれも0なら、そのフレームにタイトルバーはない。幅だけが0なら、Emacsが幅の情報を取得できなかったことを意味する。
menu-bar-external
非nil
なら、それはメニューバーがエクスターナルである(frameのネイティブフレームの一部ではない)ことを意味する。
menu-bar-size
frameのメニューバーの幅と高さを表すコンス。
tool-bar-external
非nil
なら、それはツールバーがエクスターナルである(frameのネイティブフレームの一部ではない)ことを意味する。
tool-bar-position
これはツールバーがframeのどの端に配置されているかを示しleft
、top
、right
、bottom
のいずれか。現在のところtop
以外の値をサポートするツールキットはGTK+のみ。
tool-bar-size
frameのツールバーの幅と高さを表すコンス。
internal-border-width
frameのインターナルボーダーの幅。
以下の関数はフレームにたいするアウター、ネイティブ、インナーのエッジの取得に使用できます。
この関数はframeのアウターフレーム、ネイティブフレーム、インナーフレームのエッジをリターンする。frameは生きたフレームでなければならずデフォルトは選択されたフレーム。リターンされるリストは(left top right bottom)という形式をもち、すべての値はframeのディスプレーの位置(0, 0)から相対的なピクセル値。端末フレームではleftとtopはいずれも0。
オプション引数typeはリターンするエッジのタイプを指定する。outer-edges
はframeのアウターエッジ、native-edges
(またはnil
)はネイティブエッジ、inner-edges
はインナーエッジをリターンすることを意味する。
bottomおよびrightの位置のピクセルは、対応するフレームのすぐ外側になることに注目。これはたとえば、左フレームの右アウターエッジが右フレームの左アウターエッジと等しいような横並びの2つのフレームがあるような場合には、そのエッジを表すピクセルは右フレームの一部であることを意味する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレームにはそれぞれ、そのフレームにたいするデフォルト文字サイズを指定するデフォルトフォント(default font)があります。このサイズは、行や列の単位でのフレームサイズの取得や変更での使用を意図したものです(サイズのパラメーターを参照)。これはウィンドウのリサイズ(ウィンドウのサイズを参照)や分割(ウィンドウの分割を参照)の際にも使用されます。
“デフォルト文字高さ(default character height)t”のかわりに行高さ(line height)や正準文字高さ(canonical character height)という用語を使用するときがあります。同様に“デフォルト文字幅(default character width)”のかわりに列幅(column width)や正準文字幅(canonical character width)という用語も使用されます。
これらの関数はピクセルで測ったframe内の文字のデフォルトの高さまたは幅をリターンする。両者をあわせたサイズによりframeのframeのサイズが確立される。値はframeにたいして選択されたフォントに依存する。フォントとカラーのパラメーターを参照のこと。
以下の関数でデフォルトフォントを直接セットすることもできます:
これはデフォルトフォントにfontをセットする。インタラクティブに呼び出された際にはフォント名の入力を求めて、選択されたフレームにそのフォントを使用する。Lispから呼び出す際には、fontはフォント名(文字列)、フォントオブジェクト、フォントエンティティー、フォントspecのいずれかであること。
オプション引数keep-sizeがnil
ならフレームの行数と列数を固定に保つ(非nil
なら次セクションで説明するオプションframe-inhibit-implied-resize
がこれをオーバーライドするだろう)。keep-sizeが非nil
(またはプレフィクス引数を指定)なら行数と列数を調節することにより、カレントフレームのディスプレーエリアのサイズの維持を試みる。
オプション引数framesがnil
なら、そのフォントは選択されたフレームだけに適用される。framesが非nil
ならそれは作用するフレームのリスト、またはすべての既存フレームおよび将来のすべてのグラフィカルフレームを意味するt
のいずれかであること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレームパラメーターleft
とtop
(位置のパラメーターを参照)を使用してフレームの位置、およびパラメーターheight
とwidth
(サイズのパラメーターを参照)を使用してフレームのサイズの読み取りや変更ができます。サイズと位置を処理するために特別な機能があります。これらの関数すべてにたいして、引数frameは生きたフレームでなければならず、デフォルトは選択されたフレームです。
この関数はframeのアウター位置(Frame Layoutを参照)のピクセル単位でリターンする。値はframeのアウターフレームの左上隅にたいして、フレームのディスプレーの位置(0, 0)から相対的な座標を与えるコンス。テキスト端末フレームではいずれも0。
この関数はframeのアウターフレームの位置をXとYにセットする。後者の引数はピクセル単位で、通常はframeのディスプレーの位置(0, 0)にある原点から計測される。
負のパラメーター値はスクリーン右エッジから-xピクセルのアウターフレームの右エッジ、またはスクリーン下エッジから-yピクセルのアウターフレームの下エッジを指す。
この関数はテキスト端末フレームでは効果がない。
これらの関数はframeのインナー高さやインナー幅(ディスプレーエリアの高さと幅。Frame Layoutを参照)をピクセル単位でリターンする。テキスト端末では結果はピクセル単位ではなく文字単位。
これらの関数はピクセルで測ったframeのテキストエリア(Frame Layoutを参照)の高さや幅をリターンする。テキスト端末では結果はピクセルではなく文字単位。
frame-text-height
がリターンする値はすべてのインターナルなツールバーとメニューバーの高さ、水平スクロールバーの高さやインターナルボーダーの幅を含まないので、frame-pixel-height
のリターン値とは異なる。
frame-text-width
垂直スクロールバーの幅や左右フリンジの幅、およびインターナルボーダーの幅を含まないので、frame-pixel-width
のリターン値とは異なる。
これらの関数はframeのテキストエリアの高さと幅を、frameのデフォルトフォントの高さと幅を単位に計測してリターンする。これらの関数は単に(frame-parameter
frame 'height)
と(frame-parameter frame 'width)
を略記したもの。
ピクセルで計測したframeのテキストエリアがデフォルトフォントサイズの倍数でなければ、これらの関数がリターンする値はテキストエリアに完全に収まるデフォルトフォントの文字数に切り捨てられる。
このオプションがnil
なら、通常はフレームリサイズ時にサイズがそのフレームのframe-char-height
とframe-char-width
のカレント値の倍数に丸められる。非nil
なら丸めは行われず、フレームのサイズはピクセル単位で増加/減少が可能になる。
この変数をセットすることにより次回のリサイズ処理では、通常はウィンドウマネージャーにこれに相当するサイズのヒントを渡す。これはユーザーの初期ファイル内でのみこの変数をセットすべきで、アプリケーションが一時的にこれをバインドすべきではないことを意味する。
このオプションにたいしてnil
値がもつ正確な意味は使用されるツールキットに依存する。マウスによるエクスターナルボーダーのドラッグは、ウィンドウマネージャーが対応するサイズヒントを処理する意思があれば文字単位で行われる。文字サイズの整数倍ではないフレームサイズを引数としてset-frame-size
(以下参照)を呼び出すと、もしかしたら丸められたり(GTK+)、あるいは受容される(Lucid、Motif、MS-Windows)かもしれない。
いくつかのウィンドウマネージャーでは、フレームを本当に最大化や全画面で表示させるために、これを非nil
にセットする必要があるかもしれない。
この関数はframeのテキストエリアのサイズを、frameの文字の正準高さと正準幅で計測した単位でセトする(Frame Fontを参照)。
オプション引数pixelwiseが非nil
なら、かわりにピクセル単位で新たな幅と高さを測ることを意味する。frame-resize-pixelwise
がnil
の場合には、それが文字の整数倍でフレームサイズを増加や減少させないなら、この要求を完全には尊重せずに拒絶するツールキットがいくつかあることに注意。
この関数はframeのテキストエリアをheight行の高さにリサイズする。frame内の既存ウィンドウのサイズはフレームにフィットするよう比例して変更される。
pretendが非nil
なら、Emacsはframe内でheight行の出力を表示するが、そのフレームの実際の高さにたいする値は変更しない。これはテキスト端末上でのみ有用。端末が実際に実装するより小さい高さの使用は、より小さいスクリーン上での振る舞いの再現したり、スクリーン全体を使用時の端末の誤動作を観察するとき有用かもしれない。フレームの高さの直接セットは常に機能するとは限らない。なぜならテキスト端末上でのカーソルを正しく配置するために、正確な実サイズを知る必要があるかもしれないからである。
オプションの第4引数pixelwiseが非nil
なら、それはframeの高さがheightピクセル高くなることを意味する。frame-resize-pixelwise
がnil
なら、それが文字の整数倍でフレームサイズを増加や減少させない場合には、この要求を完全には尊重せずに拒絶するツールキットがいくつかあることに注意。
この関数は文字単位でframeのテキストエリアの幅をセットする。引数pretendはset-frame-height
のときと同じ意味をもつ。
オプションの第4引数pixelwiseが非nil
なら、それはframeの幅がheightピクセル広くなることを意味する。frame-resize-pixelwise
がnil
なら、それが文字の整数倍でフレームサイズを増加あるいは減少させない場合には、この要求を完全には尊重せずに拒絶するツールキットがいくつかあることに注意。
これら3つの関数のうち、すべてのウィンドウとともにスクロールバー、フリンジ、マージン、ディバイダー、モードライン、ヘッダーラインを表示するために必要なサイズよりフレームを小さくする関数はありません。これはたとえばマウスによるフレームのエクスターナルボーダーのドラッグのようなウィンドウマネージャーのリクエストとは対照的です。フレーム右下隅にある表示できない部分は必要に応じてクリッピングするとにより、そのようなリクエストは常に尊重されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
たとえばメニューバーの追加や削除、デフォルトフォントの変更、フレームのスクロールバーの幅のセットの際、Emacsはデフォルトではフレームのテキストエリアの行数と列数を未変更に保つように試みます。しかしこれはそのような場合のサイズ変更を調停するために、Emacsがウィンドウマネージャーに依頼しなければならないことを意味します。メニューバーやツールバーのでは、通常はフレームのフレームサイズをリサイズしないので、表示される行数に変更はないことに注意してください。
たとえばフレームの最大化や全画面化の際のように、そのような暗黙なフレームのリサイズ(implied frame resizing)がおそらく望ましくないケースもあります(デフォルトではオフになっている)。それ以外のケースでは以下のオプションで暗黙のリサイズを無効にできます。
このオプションがnil
ならフレームが表示する列数と行数を確保するために特定フレームのフォント、メニューバー、ツールバー、インターナルボーダー、フリンジ、スクロールバーの変更によってフレームのディスプレーエリアを暗黙に変更できる。このオプションが非nil
なら暗黙のリサイズは行われない。
このオプションの値はフレームパラメーターのリストかもしれない。この場合には、このリスト内に出現するパラメーター変更時の暗黙のリサイズは抑制される。このオプションで処理されるフレームパラメーター現在のところfont
、font-backend
、internal-border-width
、menu-bar-lines
、tool-bar-lines
。
フレームパラメーターscroll-bar-width
、scroll-bar-height
、vertical-scroll-bars
、horizontal-scroll-bars
、left-fringe
、right-fringe
のいずれかにたいする変更は、あたかもそのフレームが単一の生きたウィンドウを含むかのように処理される。これはたとえば複数の横並びのウィンドウをフレームで垂直スクロールバーを削除すると、このオプションがnil
ならnil
はスクロールバーの幅の分だけ縮小されて、t
やvertical-scroll-bars
を含む場合には未変更に保たれることを意味する。
デフォルト値はLucid、Motif、Windowsにたいしては'(tool-bar-lines)
(ツールバーの追加や削除でアウターフレーム高さを変更しない)、GTK+を含むその他のウィンドウシステムではnil
(上述したすべてのパラメーターの変更によりアウターフレームのサイズは変更され得る)、それ以外ならt
(ウィンドウシステムのサポートがないときには暗黙に変更が行われることはない)。
フレームが上述のいずれかのパラメーターにたいする変更の調停に不十分な際には、たとえこのオプションが非nil
でもEmacsがフレームの拡大を試みるかもしれないことに注意。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレームにはその外見と挙動を制御する多くのパラメーターがあります。フレームがどのようなパラメーターをもつかは、そのフレームが使用するディスプレイのメカニズムに依存します。
フレームパラメーターは主にグラフィカルディスプレイのために存在します。ほとんどのフレームパラメーターはテキスト端末上のフレームへの適用時には効果がありません。テキスト端末上のフレームで何か特別なことを行うパラメーターはheight
、width
、name
、title
、menu-bar-lines
、buffer-list
、buffer-predicate
だけです。その端末がカラーをサポートする場合にはforeground-color
、background-color
、background-mode
、display-type
などのパラメーターも意味をもちます。その端末が透過フレーム(frame
transparency)をサポートする場合には、パラメーターalpha
にも意味があります。
28.4.1 フレームパラメーターへのアクセス | フレームのパラメーターの変更方法。 | |
28.4.2 フレームの初期パラメーター | フレーム作成時に指定するフレームパラメーター。 | |
28.4.3 ウィンドウフレームパラメーター | ウィンドウシステムにたいするフレームパラメーターのリスト。 | |
28.4.4 ジオメトリー | ジオメトリー仕様の解析。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数でフレームのパラメーター値の読み取りと変更ができます。
この関数はframeのパラメーターparameter
(シンボル)の値をリターンする。frameがnil
なら選択されたフレームのパラメーターをリターンする。frameがparameterにたいするセッティングをもたなければ、この関数はnil
をリターンする。
関数frame-parameters
はframeのすべてのパラメーターとその値をリストするalistをリターンする。frameが省略またはnil
なら選択されたフレームのパラメーターをリターンする。
この関数はalistの要素にもとづきフレームframeを変更する。alist内の要素はそれぞれ(parm
. value)
という形式をもつ。ここでparmはパラメーターを名付けるシンボルである。
alist内に指定されないパラメーターの値は変更されない。frameがnil
の場合のデフォルトは選択されたフレーム。
いくつかのパラメーターは特定の種類のディスプレー上のフレーム(フレームを参照)でのみ意味がある。frameのディスプレーで意味をもたないパラメーターがalistに含まれているようなら、この関数はそのフレームのパラメーターリスト内の値を変更するが、その他の値を変更しないパラメーターは無視するだろう。
frameの新たなサイズに影響し得る値をもつようなパラメーターがalistで複数指定されている際には、フレームの最終的なサイズは使用しているツールキットに応じて異なるかもしれない。たとえばあるフレームにたいしてメニューバーおよび/またはツールバーをもたない状態から保有するように指定して、同時に新たなフレーム高さを指定すると、必然的にフレームの高さの再計算を招くだろう。そのようなケースでは、概念的にはこの関数は明示的な高さ指定を優先するよう試みる。しかしツールキットによりその後に処理されるメニューバーやツールバーの追加(や削除)を除外することはできないので、高さ指定を優先するという意図は打ち消されてしまうだろう。
ここで概略した問題は、この関数の呼び出し前後にframe-inhibit-implied-resize
(Implied Frame Resizingを参照)を非nil
値にバインドすることで訂正できる場合がある。しかしそのようなバインディングが正に問題を引き起こす場合もある。
この関数はフレームパラメーターparmに指定されたvalueをセットする。frameがnil
の場合のデフォルトは選択されたフレーム。
この関数は
alistに応じて既存のフレームすべてのフレームパラメーターを変更してから、今後に作成されるフレームに同じパラメーター値を適用するために、default-frame-alist
(必要ならinitial-frame-alist
も)を変更する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
initファイル(initファイルを参照)の内部でinitial-frame-alist
をセットすることにより、フレームの初期スタートアップにパラメーターを指定できます。
この変数の値は初期フレーム作成時に使用されるパラメーター値のalist。以降のフレームを変更することなく初期フレームの外見を指定するためにこの変数を使用できる。要素はそれぞれ以下の形式をもつ:
(parameter . value)
Emacsはinitファイル読み取り前に初期フレームを作成する。Emacsはこのファイル読み取り後にinitial-frame-alist
をチェックして、変更する値に含まれるパラメーターのセッティングを作成済みの初期フレームに適用する。
これらのセッティングがフレームのジオメトリーと外見に影響する場合には、間違った外見のフレームを目にした後に、指定した外見に変更される様を目にするだろう。これが煩わしければ、Xリソースで同じジオメトリーと外見を指定できる。これらはフレーム作成前に効果をもつ。X Resources in The GNU Emacs Manualを参照のこと。
Xリソースセッティングは、通常はすべてのフレームに適用される。初期フレームのためにあるXリソースを単独で指定して、それ以降のフレームには適用したくなければ、次の方法によりこれを達成できる。それ以降のフレームにたいするXリソースをオーバーライドするためにdefault-frame-alist
内でパラメーターを指定してから、それらが初期フレームに影響するのを防ぐためにinitial-frame-alist
内の同じパラメーターにたいしてXリソースにマッチする値を指定すればよい。
これらのパラメーターに(minibuffer
.
nil)
が含まれていれば、それは初期フレームがミニバッファーをもつべきではないことを示しています。この場合には、Emacsは同じようにミニバッファーonlyフレーム(minibuffer-only
frame)を個別に作成します。
この変数の値は、初期ミニバッファーonlyフレーム(
initial-frame-alist
がミニバッファーのないフレームを指定する場合にEmacsが作成するミニバッファーonlyフレーム)を作成時に使用されるパラメーター値のalist。
これはすべてのEmacsフレーム(最初のフレームとそれ以降のフレーム)にたいしてフレームパラメーターのデフォルト値を指定するalist。Xウィンドウシステム使用時には、大抵はXリソースで同じ結果を得られる。
この変数のセットは既存フレームに影響しない。さらに別フレームにバッファーを表示する関数は、自身のパラメーターを提供することによりデフォルトパラメーターをオーバーライドできる。
フレームの外見を指定するコマンドラインオプションとともにEmacsを呼び出すと、これらのオプションはinitial-frame-alist
かdefault-frame-alist
のいずれかに要素を追加することにより効果を発揮します。‘--geometry’や‘--maximized’のような初期フレームだけに影響するオプションはinitial-frame-alist
、その他のオプションはdefault-frame-alist
に要素を追加します。Command Line Arguments for Emacs Invocation in The GNU
Emacs Manualを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレームがどんなパラメーターをもつかは、どのようなディスプレイのメカニズムがそれを使用するかに依存します。このセクションでは一部、またはすべての端末種類において特別な意味をもつパラメーターを説明します。これらのうちname
、title
、height
、width
、buffer-list
、buffer-predicate
は端末フレームにおいて意味をもつ情報を提供し、tty-color-mode
はテキスト端末上のフレームにたいしてのみ意味があります。
28.4.3.1 基本パラメーター | 基本的なパラメーター。 | |
28.4.3.2 位置のパラメーター | スクリーン上のフレームの位置。 | |
28.4.3.3 サイズのパラメーター | フレームのサイズ。 | |
28.4.3.4 レイアウトのパラメーター | フレームのパーツのサイズ、一部パーツの有効化と無効化。 | |
28.4.3.5 バッファーのパラメーター | 表示済みまたは表示されるべきバッファーはどれか。 | |
28.4.3.6 ウィンドウ管理のパラメーター | ウィンドウマネージャーとの対話。 | |
28.4.3.7 カーソルのパラメーター | カーソルの外見の制御。 | |
28.4.3.8 フォントとカラーのパラメーター | フレームテキストにたいするフォントとカラー。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のフレームパラメーターはフレームに関するっとも基本的な情報を提供します。title
とname
はすべての端末において意味をもちます。
display
このフレームをオープンするためのディスプレイ。これは環境変数DISPLAY
のような‘host:dpy.screen’という形式の文字列であること。ディスプレイ名についての詳細は、複数の端末を参照のこと。
display-type
このパラメーターはこのフレーム内で使用できる利用可能なカラーの範囲を記述する。値はcolor
、grayscale
、mono
のいずれか。
title
フレームが非nil
のtitleをもつ場合には、それはフレーム上端にあるウィンドウシステムのタイトルバーに表示され、mode-line-frame-identification
に‘%F’
(モードラインでの%
構造を参照)を使用していればそのフレーム内のウィンドウのモードラインにも表示される。これは通常はEmacsがウィンドウシステムを使用しておらず、かつ同時に1つのフレームのみ表示可能なケースが該当する。フレームのタイトルを参照のこと。
name
そのフレームの名前。title
が未指定かnil
ならフレーム名はフレームタイトルにたいしてデフォルトの役割りを果たす。nameを指定しなければEmacsは自動的にフレーム名をセットする(フレームのタイトルを参照)。
フレーム作成時に明示的にフレーム名を指定すると、そのフレームにたいしてXリソースを照合する際にも、(Emacs実行可能形式名のかわりに)その名前が使用される。
explicit-name
フレーム作成時にフレーム名が明示的に指定されると、このパラメーターはその名前。明示的に名付けられなかったら、このパラメーターはnil
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
位置のパラメーターの値はピクセル単位で計測されます(以下のパラメーターはTTYフレームには存在しないことに注意)。
left
スクリーンの左(右)エッジからフレームの左(右)エッジまでの、ピクセル単位での位置。値は:
正の整数はスクリーン左エッジをフレーム左エッジに、負の整数はフレーム右エッジをスクリーン右エッジに関連付ける。
(+ pos)
これはスクリーン左エッジにたいしフレーム左エッジの相対的位置を指定する。整数posは正か負の値をとり得る。負の値はスクリーン外側、または(マルチモニターディスプレイにたいしては)プライマリーモニター以外のモニター上の位置を指定する。
(- pos)
これはスクリーン右エッジにたいしフレーム右エッジの相対的位置を指定する。整数posは正か負の値をとり得る。負の値はスクリーン外側、または(マルチモニターディスプレイにたいしては)プライマリーモニター以外のモニター上の位置を指定する。
プログラムで指定した位置を無視するウィンドウマネージャーがいくつかある。指定した位置が無視されないことを保証したければ、パラメーターuser-position
にも同様に非nil
値を指定すること。
ウィンドウマネージャがスクリーン左右のエッジにあるフレームの位置揃えを拒絶するようなら、以下のように位置指定とuser-position
を組み合わせる
(modify-frame-parameters nil '((user-position . t) (left . (+ -4))))
このようにすれば、そのような挙動をオーバーライドする助けとなるだろう。
top
スクリーン上(下)エッジにたいして、上(下)エッジのスクリーン位置をピクセル単位で指定する。方向が水平ではなく垂直である点を除き、これはleft
と同様に機能する。
icon-left
スクリーン左エッジから数えた、フレームアイコン左エッジのピクセル単位のスクリーン位置。ウィンドウマネージャーがこの機能をサポートすれば、これはフレームをアイコン化したとき効果を発揮する。このパラメーターに値を指定する場合にはicon-top
にも値を指定しなければならず、その逆も真。
icon-top
スクリーン上端から数えたフレームアイコン上端のピクセル単位のスクリーン位置。ウィンドウマネージャーがこの機能をサポートすれば、これはフレームをアイコン化したときに効果を発揮する。
user-position
フレームを作成してパラメーターleft
とtop
で位置を指定する際は、指定した位置がユーザー指定(人間であるユーザーにより明示的に要求された位置)なのか、それとも単なるプログラム指定(プログラムにより選択された位置)なのかを告げるためにこのパラメーターを使用する。非nil
値はそれがユーザー指定の位置であることを告げる。
ウィンドウマネージャーは一般的にユーザー指定位置に留意するとともに、プログラム指定位置にも幾分か留意する。しかし多くのウィンドウマネージャーはプログラム指定位置を無視して、ウィンドウをウィンドウマネージャーのデフォルトの方法で配置するかユーザーのマウスによる配置に任せる。twm
を含むウィンドウマネージャーのいくつかは、プログラム指定位置にしたがうか無視するかをユーザーの指定に任せる。
make-frame
を呼び出す際にパラメーターleft
やtop
の値がそのユーザーにより示される嗜好を表すなら、このパラメーターに非nil
値、それ以外はnil
を指定すること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレームパラメーターはフレームのサイズを文字単位で指定します。グラフィカルなディスプレイ上では、default
フェイスがこれら文字単位の実際のピクセルサイズを決定します(フェイスの属性を参照)。
height
フレームのテキストエリアの文字単位の高さ(Frame Geometryを参照)。
width
フレームのテキストエリアの文字単位の幅(Frame Geometryを参照)。
user-size
これはサイズパラメーターheight
とwidth
にたいして、user-position
(user-positionを参照)がtop
とleft
が行うのと同じことを行う。
fullscreen
このパラメータはフレームの幅、高さ、またはその両方を最大化するかどうかを指定する。値はfullwidth
、fullheight
、fullboth
、またはmaximized
。フレームがfullwidthなら幅、fullheightなら高さ、fullbothまら幅と高さが可能なかぎり大きくなる。maximizedは“fullboth”と同様だが、通常はタイトルバーとフレームのリサイズやクローズ用のボタンが維持される点が異なる。同様に最大化されたフレームでは、デスクトップ上に表示されているタスクバーやパネルが見えなくなること通常はない。一方で“fullboth(全画面)”のフレームは、通常はタイトルバーは省略されて、利用可能なスクリーンスペース全体を占有する。
この点ではfullheightやfullwidthのフレームは最大化されたフレームと類似している。しかしこれらは通常は最大化フレームでは存在しないエクスターナルボーダーを表示する。したがって最大化されたフレームの高さと幅は、fullheightのフレームの高さやfullwidthのフレームの幅とあ数ピクセル異なることがある。
いくつかのウィンドウマネージャでは、フレームを真に最大化または全画面で表示させるために、変数frame-resize-pixelwise
(Size and Positionを参照)のカスタマイズが必要になる。更に全画面や最大化の種々の状態間での円滑な繊維をサポートしないウィンドウマネージャもいくつかあるだろう。これらに対処するために変数x-frame-normalize-before-maximize
のカスタマイズが助けとなるだろう。
fullscreen-restore
このパラメータはtoggle-frame-fullscreen
コマンド (Frame Commands in The GNU Emacs
Manualを参照)呼び出し後の“fullboth”状態での、望ましい全画面状態を指定する。このパラメーターはFrame
Commands in The GNU Emacs
Manualを参照の切り替え時に、このコマンドによって自動的にインストールされる。しかしEmacsが“fullboth”の状態で開始された場合には、以下の例のように初期ファイル内で望ましい挙動を指定する必要がある
(setq default-frame-alist '((fullscreen . fullboth) (fullscreen-restore . fullheight)))
これはF11の初回タイプ後に、フレームに新たにfullheightを与えるだろう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のフレームパラメーターによりフレームのさまざまなパーツを有効または無効にしたりサイズを制御できます。
border-width
ピクセル単位でのフレームのボーダー幅。
internal-border-width
テキスト(またはフリンジ)とフレームボーダーとのピクセル単位による距離。
vertical-scroll-bars
フレームが垂直スクロール用のスクロールバーをもつべきかと、スクロールバーをフレームのどちら側に置くか。可能な値はleft
、right
、スクロールバーなしはnil
。
horizontal-scroll-bars
フレームが水平スクロール用のスクロールバーをもつべきかと、スクロールバーをフレームのどちら側に置くか(t
とbottom
はスクロールバーあり、nil
はスクロールバーなしを意味する)。
scroll-bar-width
垂直スクロールバーのピクセル単位による幅。nil
はデフォルト幅の使用を意味する。
scroll-bar-height
垂直スクロールバーのピクセル単位による高さ。nil
はデフォルト高さの使用を意味する。
left-fringe
right-fringe
そのフレーム内のウィンドウの左右フリンジのデフォルト幅(フリンジを参照)。いずれかが0なら対応するフリンジを削除する効果がある。
これら2つのフレームパラメーターの値を問い合わせるためにframe-parameter
を使用する際のリターン値は常に整数。nil
値を渡してset-frame-parameter
を使用する際には、実際のデフォルト値8ピクセルが課せられる。
right-divider-width
フレーム上のすべてのウィンドウの右ディバイダー(ウィンドウディバイダーを参照)用に予約されるピクセル単位の幅(厚さ)。値0は右ディバイダーを描画しないことを意味する。
bottom-divider-width
フレーム上のすべてのウィンドウの下ディバイダー(ウィンドウディバイダーを参照)用に予約されるピクセル単位の幅(厚さ)。値0は下ディバイダーを描画しないことを意味する。
menu-bar-lines
メニューバー用にフレーム上端に割り当てる行数。Menu Barモードが有効の場合のデフォルトは1、それ以外は0。Menu Bars in The GNU Emacs Manualを参照のこと。
tool-bar-lines
ツールバー用に使用する行数。Tool Barモードが有効の場合のデフォルトは1、それ以外は0であ。Tool Bars in The GNU Emacs Manualを参照のこと。
tool-bar-position
ツールバーの位置。現在のところGTKツールバーのみ。可能な値はtop
、bottom
、left
、right
。デフォルトはtop
。
line-spacing
各テキスト行の下に残すピクセル単位の追加スペース(正の整数)。詳細は行の高さを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はフレーム内でどのバッファーが表示されているか、表示されるべきかを扱うためのフレームパラメーターであり、すべての種類の端末上で意味があります。
minibuffer
そのフレームが自身のミニバッファーをもつか否か。もつ場合にはt
、もたない場合はnil
、only
ならそのフレームが正にミニバッファーであることを意味する。値が(別フレーム内の)ミニバッファーウィンドウなら、そのフレームはそのミニバッファーを使用する。
このフレームパラメーターはフレーム作成時に効果があち、その後は変更できない。
buffer-predicate
このフレームにたいするバッファー述語関数。関数other-buffer
はこの述語が非nil
なら、(選択されたフレームから)どのバッファーを考慮すべきか決定するためにこれを使用する。これは各バッファーにたいして、そのバッファーを唯一の引数としてこの述語を1回呼び出す。この述語が非nil
値をリターンしたら、そのバッファーは考慮される。
buffer-list
そのフレーム内で選択されたことのあるバッファーにたいする、もっとも最近選択されたバッファーが先頭になるような順のリスト。
unsplittable
非nil
なら、このフレームのウィンドウは決して自動的に分割されることはない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のフレームパラメーターは、ウィンドウマネージャーとフレームとの相互作用に関するさまざまな側面を制御します。これらはテキスト端末上では効果がありません。
visibility
フレームの可視性(visibility)の状態。可能な値は3つありnil
は不可視、t
は可視、icon
はアイコン化されていることを意味する。フレームの可視性を参照のこと。
auto-raise
非nil
なら、Emacsはそのフレーム選択時に自動的にそれを前面に移動(raise)する。これを許さないウィンドウマネージャーがいくつかある。
auto-lower
非nil
なら、Emacsはそのフレームの選択解除時に自動的にそれを背面に移動(lower)する。これを許さないウィンドウマネージャーがいくつかある。
icon-type
そのフレームに使用するアイコンのタイプ。値が文字列なら使用するビットマップを含むファイル、nil
ならアイコンなしを指定する(何を表示するかはウィンドウマネージャーが決定する)。その他の非nil
値はデフォルトのEmacsアイコンを指定する。
icon-name
このフレームにたいするアイコンで使用する名前。アイコンを表示する場合は、その際に表示される。これがnil
ならフレームのタイトルが使用される。
window-id
グラフィカルディスプレイがこのフレームにたいして使用するID番号。Emacsはフレーム作成時にこのパラメーターを割り当てる。このパラメーターを変更しても実際のID番号に効果はない。
outer-window-id
そのフレームが存在する最外殻のウィンドウシステムのウィンドウのID番号。window-id
と同じように、このパラメーターを変更しても実際の効果はない。
wait-for-wm
非nil
ならジオメトリー変更を確認するために、ウィンドウマネージャーを待機するようXtに指示する。Fvwm2およびKDEのバージョンを含むウィンドウマネージャーのいくつかは確認に失敗してXtがハングする。これらウィンドウマネージャーのハングを防ぐためには、これをnil
にセットすること。
sticky
非nil
なら仮想デスクトップを伴うシステム上のすべての仮想デスクトップ上でそのフレームが可視になる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このフレームパラメーターはカーソルの外見を制御します。
cursor-type
カーソルの表示方法。適正な値は:
box
塗りつぶされた四角形(filled box)を表示する(デフォルト)。
hollow
中抜きの四角形(hollow box)を表示する。
nil
カーソルを表示しない。
bar
文字間に垂直バー(vertical bar)を表示する。
(bar . width)
文字間に幅がwidthピクセルの垂直バー(vertical bar)を表示する。
hbar
文字間に水平バー(horizontal bar)を表示する。
(hbar . height)
文字間に高さがheightピクセルの水平バー(horizontal bar)を表示する。
フレームパラメーターcursor-type
は変数cursor-type
とcursor-in-non-selected-windows
によりオーバーライドされるかもしれません。
このバッファーローカル変数は選択されたウィンドウ内で表示されているそのバッファーのカーソルの外見を制御する。この値がt
なら、それはフレームパラメーターcursor-type
で指定されたカーソルのーを使用することを意味する。それ以外では値は上記リストのカーソルタイプのいずれかであるべきであり、これはフレームパラメーターcursor-type
をオーバーライドする。
このバッファーローカル変数は選択されていないウィンドウ内でのカーソルの外見を制御する。これはフレームパラメーターcursor-type
と同じ値をサポートする。さらにnil
は選択されていないウィンドウ内にはカーソルを表示せず、t
は通常のカーソルタイプの標準的な変更(塗りつぶされた四角形は中抜きの四角形、バーはより細いバーになる)の使用を意味する。
この変数はタブや伸長された空白文字のようなエクストラワイドグリフで表示されるblockカーソルの幅を制御する。デフォルトではそのフォントのデルト文字だけの幅で、これはカーソル一のグリフがエクストラワイドなら幅を完全にカバーしないだろう。この変数にたいする非nil
値はカーソル位置のグリフの幅に応じてblockカーソルを描画することを意味する。デフォルト値はnil
。
テキストモードのフレームではEmacsの制御外部の端末によりカーソルが描画されるので、この変数に効果はない。
この変数はカーソルのブリンク(blink: 点滅)方法を指定する。各要素は(on-state
.
off-state)
という形式をもつ。カーソルタイプがon-stateと等しい(equal
を用いて比較)ときは、これに対応するoff-stateがブリンクが“off”の際のカーソルの外見を指定する。on-stateとoff-stateはどちらもフレームパラメーターcursor-type
に適した値であること。
それぞれのカーソルタイプのブリンク方法にたいして、そのタイプがここでon-stateとして指定されていなければ、さまざまなデフォルトが存在する。フレームパラメーターcursor-type
で指定した際に限り、この変数内での変更は即座に効果を発揮しない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のフレームパラメーターはフォントとカラーの使用を制御します。
font-backend
フレーム内でフォントの描画に使用するためのフォントバックエンド(font
backends)を指定するシンボルの優先順のリスト。Xでは現在のところx
(X core font
driver)とxft
(Xft font
driver)の2つの利用可能なフォントバックエンドがある。MS-Windowsでは現在のところgdi
とuniscribe
の2つの利用可能なフォントバックエンドがある(Windows
Fonts in The GNU Emacs
Manualを参照)。その他のシステムでは利用可能なフォントバックエンドは1つだけなので、このフレームパラメーターを変更しても意味がない。
background-mode
このパラメーターはdark
かlight
のいずれかで、それぞれバックグラウンドを暗く(dark)するか、明るく(light)するかに対応する。
tty-color-mode
このパラメーターは端末上で使用するカラーモードを指定して、そのシステムの端末機能データベース(terminal capabilities
database、termcap)により与えられた端末のカラーサポートを、その値でオーバーライドする。値にはシンボルか数値を指定できる。数値なら使用するカラー数(および間接的にはそれぞれのカラーを生成するためのコマンド)を指定する。たとえば(tty-color-mode
. 8)
は、標準的なテキストカラーにたいしてANSIエスケープシーケンスの使用を指定する。値-1はカラーサポートをオフに切り替える。
このパラメーターの値がシンボルなら、それはtty-color-mode-alist
の値を通じて数値を指定するもので、そのシンボルに割り当てられた数値がかわりに使用される。
screen-gamma
これが数値ならEmacsはすべてのカラーの輝度を調整するガンマ補正(gamma correction)を行う。値はディスプレイのスクリーンのガンマであること。
通常のPCモニターはスクリーンガンマが2.2なので、EmacsとXウィンドウのカラー値は一般的にそのガンマ値のモニター上で正しく表示するよう校正されている。screen-gamma
にたいして2.2を指定すると、それは補正が不必要であることを意味する。その他の値は通常のモニター上のガンマ値2.2で表示されるように、補正したカラーがスクリーン上に表示されることを意図された補正を要求する。
モニターが表示するカラーが明るすぎる場合には、screen-gamma
に2.2より小さい値を指定すること。これはカラーをより暗くする補正を要求する。スクリーンガンマの値1.5は、LCDカラーディスプレイにたいして良好な結果を与えるだろう。
alpha
このパラメーターは可変透明度(variable
opacity)をサポートするグラフィカルディスプレイ上でそのフレームの透明度を指定する。これは0から100の整数であるべきで0は完全な透明、100は完全な不透明を意味する。nil
値をもつこともでき、これはEmacsにフレームのopacityをセットしないよう告げる(ウィンドウマネージャーに委ねる)。
フレームが完全に見えなくなるのを防ぐために、変数frame-alpha-lower-limit
は透明度の最低限度を定義する。フレームパラメーターの値がこの変数の値より小さければEmacsは後者を使用する。デフォルトのframe-alpha-lower-limit
は20。
フレームパラメーターalpha
にはコンスセル(
も指定できる。ここでactive
.
inactive
)active
は選択時のフレームの透明度、inactive
は未選択時の透明度。
以下は特定のフェイスの特定のフェイス属性と自動的に等しくなるので、ほぼ時代遅れとなったフレームパラメーターです(Standard Faces in The Emacs Manualを参照)。
font
フレーム内でテキストを表示するためのフォントの名前。これはシステムで有効なフォント名か、Emacsフォントセット名(フォントセットを参照)のいずれかであるような文字列。これはdefault
フェイスのfont
属性と等価。
foreground-color
文字のイメージに使用するカラー。これはdefault
フェイスの:foreground
属性と等価。
background-color
文字のバックグラウンドに使用するカラー。これはdefault
フェイスの:background
属性と等価。
mouse-color
マウスポインターのカラー。これはmouse
フェイスの:background
属性と等価。
cursor-color
ポイントを表示するカーソルのカラー。これはcursor
フェイスの:background
属性と等価。
border-color
これはフレームのボーダーのカラー。これはborder
フェイスの:background
属性と等価。
scroll-bar-foreground
非nil
ならスクロールバーのフォアグラウンドカラー。これはscroll-bar
フェイスの:foreground
属性と等価。
scroll-bar-background
非nil
ならスクロールバーのバックグラウンドカラー。これはscroll-bar
フェイスの:background
属性と等価。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はXスタイルのウィンドウジオメトリー指定によるアクションのデータを調べる方法です:
関数x-parse-geometry
は標準的なXウィンドウのジオメトリー文字列をmake-frame
の引数の一部として使用できるalistに変換する。
このalistはgeom内で指定されたパラメーターと、そのパラメーターに指定された値を記述する。各要素は(parameter
.
value)
のような形式。可能なparameterの値はleft
、top
、width
、height
。
サイズのパラメーターの値は整数でなければならない。位置のパラメーターleft
とtop
の名前に関しては、かわりに右端または下端の位置を示す値もいくつかあるので完全に正確ではない。位置パラメーターにたいして可能なvalueは前述したような整数(位置のパラメーターを参照)、リスト(+ pos)
、リスト(- pos)
である。
以下は例:
(x-parse-geometry "35x70+0-0") ⇒ ((height . 70) (width . 35) (top - 0) (left . 0))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
端末はそれぞれ関連するパラメーターのリストをもっています。これら端末パラメーター(terminal parameters)は主に端末ローカル変数を格納するための便利な手段ですが、いくつかの端末パラメーターは特別な意味をもっています。
このセクションでは端末のパラメーター値の読み取りや変更を行う関数を説明します。これらはすべて引数として端末かフレームいずれかを受け入れます。フレームならそれはそのフレームの端末の使用を意味します。引数nil
は選択されたフレームの端末という意味です。
この関数はterminalnのすべてのパラメーターとその値をリストするalistをリターンする。
この関数はterminalのパラメーターparameter
(シンボル)の値をリターンする。terminalがparameterにたいするセッティングをもたなければ、この関数はnil
をリターンする。
This function sets the parameter parameter of terminal to the specified value, and returns the previous value of that parameter.
以下は特別な意味をもついくつかの端末パラメーターのリストです:
background-mode
端末のバックグラウンドカラーの区分でlight
かdark
のいずれか。
normal-erase-is-backspace
値は1か0で、これはその端末上でnormal-erase-is-backspace-mode
がオンまたはオフのいずれに切り替えられたかに依存する。DEL
Does Not Delete in The Emacs Manualを参照のこと。
terminal-initted
端末の初期化後に端末固有の初期化関数にセットされる。
tty-mode-set-strings
与えられた際には、読み取り用にttyを設定時にEmacsが出力するエスケープシーケンスを含む文字列のリスト。Emacsは端末の設定時のみこれらの文字列を発行する。すでにアクティブな端末上(たとえばtty-setup-hook
内)でモードを有効にしたければ、tty-mode-set-strings
へのシーケンスの追加に加えて、send-string-to-terminal
を使用して明示的に必要なエスケープシーケンスを出力すること。
tty-mode-reset-strings
与えられた際には、tty-mode-set-strings
内の文字列の効果をアンドゥする文字列のリスト。Emacsはexit、端末の削除、Emacs自身のサスペンドの際にそれらの文字列を発行する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレームにはそれぞれname
というパラメーターがあります。これはウィンドウシステムが通常フレーム上端に表示するフレームタイトルにたいするデフォルトとしての役割をもちます。フレームプロパティname
をセットすることにより明示的に名前を指定できます。
通常は名前を明示的に指定せずに、Emacsが変数frame-title-format
に格納されたテンプレートにもとづいて自動的にフレーム名を計算します。Emacsはフレームが再表示されるたびに名前を再計算します。
この変数はフレーム名が明示的に指定されないときにフレーム名を計算する方法を指定する。この変数の値は実際にはmode-line-format
のようなモードライン構文(mode
line construct)だが、‘%c’と‘%l’の構文は無視される。モードラインのデータ構造を参照のこと。
この変数はフレームタイトルを明示的に指定しないときの、アイコン化されたフレームの名前の計算方法を指定する。このタイトルはアイコン自体に表示される。
この変数はEmacsにより自動的にセットされる。フレームが2つ以上(ミニバッファーのみのフレームと不可視のフレームは勘定に入らない)のとき、値はt
となる。frame-title-format
のデフォルト値はフレームが複数存在する場合のみ、フレーム名にバッファー名を入れるためにmultiple-frames
を使用する。
この変数の値はframe-title-format
とicon-title-format
の処理中を除き正確である保証はない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
生きたフレーム(live frame)とは削除されていないフレームのことです。フレームが削除される際には、たとえそれへの参照元がなくなるまでLispオブジェクトとして存在し続けるとしても端末ディスプレイからは削除されます。
この関数はフレームframeを削除する。frameがツールチップでなければ、まずフックdelete-frame-functions
を実行する(フックの各関数は唯一の引数としてframeを受け取る)。デフォルトではframeは選択されたフレーム。
フレームのミニバッファーが別のフレームの代替えミニバッファー(surrogate
minibuffer)としての役割をもつかぎり削除することはできない。他のフレームがすべて不可視なら通常はフレームを削除できないが、forceが非nil
なら削除が可能。
関数frame-live-p
はフレームframeが削除されていなければ非nil
をリターンする。リターンされ得る非nil
の値はframep
と同様。フレームを参照のこと。
いくつかのウィンドウマネージャーはウィンドウを削除するコマンドを提供します。これらはそのウィンドウを操作するプログラムに特別なメッセージを送ることにより機能します。Emacsがそれらメッセージのいずれかを受け取ったときはdelete-frame
イベントを生成します。このイベントの通常の定義は関数delete-frame
を呼び出すコマンドです。その他のシステムイベントを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はすべての生きたフレーム(削除されていないフレーム)のリストをリターンする。これはバッファーにたいするbuffer-list
に類似しており、すべての端末上のフレームが含まれる。リターンされるリストは新たに作成されたものであり、このリストを変更してもEmacs内部への影響はない。
この関数はカレントで可視なフレームだけのリストをリターンする。See section フレームの可視性を参照のこと。テキスト端末上のフレームは、実際に表示されるのが選択されたフレームだけだとしても常に可視であるとみなされる。
この関数はカレントディスプレイ上のすべてのフレームを、任意のフレームを開始点としいて巡回するのに有用。これはそのその巡回サイクル上でframeの次に該当するフレームをリターンする。frameが省略またはnil
の場合のデフォルトは選択されたフレーム(入力のフォーカスを参照)。
2つ目の引数minibufはどのフレームを考慮するかを示す:
nil
ミニバッファーのみのフレームを除外。
visible
すべての可視フレームを考慮する。
すべての可視フレームとアイコン化されたフレームを考慮する。
特定のウィンドウをミニバッファーとして使用するフレームだけを考慮する。
すべてのフレームを考慮する。
next-frame
と同様だがすべてのフレームを逆方向に巡回する。
ウィンドウのサイクル順のnext-window
とprevious-window
も参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
それぞれのフレームは通常は下端に自身のミニバッファーウィンドウをもち、そのフレームが選択された際には常にそれを使用します。フレームにミニバッファーがある場合には、minibuffer-window
でそれを取得できます(ミニバッファーのウィンドウを参照)。
しかしミニバッファーをもたないフレームも作成できます。そのようなフレームは、別のフレームのミニバッファーを使用しなければなりません。この別フレームはそのフレームにたいする代替えミニバッファーフレーム(surrogate
minibuffer
frame)としての役目を果たし、そのフレームが生きているかぎりdelete-frame
で削除することはできなくなります(フレームの削除を参照)。
フレーム作成時に、(別フレーム上にある)使用するミニバッファーを明示的に指定できます。これを行わない場合には、変数default-minibuffer-frame
の値のフレーム内でミニバッファーを探します。この値はミニバッファーをもつフレームにしてください。
ミニバッファーのみのフレームを使用する場合には、ミニバッファーにエンター時にそのフレームを前面に移動(raise)したいと思うかもしれません。その場合には変数minibuffer-auto-raise
にt
をセットします。フレームを前面や背面に移動するを参照してください。
この変数はデフォルトでミニバッファーウィンドウとして使用するフレームを指定する。これは既存のフレームには影響しない。これはカレント端末にたいして常にローカルであり、バッファーローカルにはできない。複数の端末を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
どんなときでもEmacs内のただ1つのフレームが選択されたフレーム(selected frame)です。選択されたウィンドウは常に選択されたフレーム上にあります。
Emacsがフレームを複数端末(複数の端末を参照)上に表示する際には、各端末は自身の選択されたフレームをもちます。しかしそれらのうち1つだけが、いわゆる選択されたフレームであり、それはもっとも最近に入力があった端末に属すフレームです。つまり特定の端末からのコマンドをEmacsが実行する際には、その端末上の1つが選択されたフレームです。Emacsが実行するコマンドは常に1つだけなので、選択されたフレームは常に1つだけだと考える必要があります。このフレームこそが、このマニュアルで選択されたフレームと呼ぶフレームです。選択されたフレームを表示するディスプレイは、選択されたフレームのディスプレイ(selected frame’s display)です。
この関数は選択されたフレームをリターンする。
いくつかのウィンドウシステムおよびウィンドウマネージャーは、マウスがあるウィンドウオブジェクトにキーボード入力をダイレクトします。それ以外は、さまざまなウィンドウオブジェクトにフォーカスをシフト(shift
the
focus)するために、明示的なクリックやコマンドを要求します。どちらの方法でもEmacsはフォーカスをもつフレームを自動的に追跡します。Lisp関数から別フレームに明示的に切り替えるためには、select-frame-set-input-focus
を呼び出します。
関数select-frame
を呼び出すことにより、Lispプログラムが一時的にフレームを切り替えることもできます。これはそのウィンドウシステムのフォーカス概念を変更はしません。変更ではなく何らかの方法により制御が再確認(reasserted)されるまで、ウィンドウマネージャーの制御から抜け出す(escape)のです。
テキスト端末使用時はその端末上で一度に表示できるフレームは1つだけなので、select-frame
呼び出し後に次回の再表示で新たに選択されたフレームが実際に表示されます。このフレームは次のselect-frame
呼び出しまで選択されたままです。テキスト端末上の各フレームはバッファー名の前に表示される番号をもちます(モードラインで使用される変数を参照)。
この関数はframeを選択して、(他のフレームのせいで不明瞭な場合には)それを前面に移動(raise)してXサーバーのフォーカス授与を試みる。テキスト端末上では、次回再表示時に端末スクリーン全体に新たにフレームが表示される。オプション引数norecordはselect-frame
(下記参照)のときと同じ意味をもつ。この関数のリターン値に意味はない。
この関数はフレームframeを選択して、Xサーバーのフォーカスがあればそれを一時的に無視する。frameにたいする選択は次回ユーザーが別フレームに何かを行うか、この関数の次回呼び出しまで継続する(ウィンドウシステムを使用する場合には以前に選択されていたフレームに依然としてウィンドウシステムの入力フォーカスがあるかもしれないので、コマンドループからリターン後にそのフレームが選択されたフレームとしてリストアされるかもしれない)。
指定されたframeは選択されたフレームとなり、その端末が選択された端末になる。その後でこの関数はframe内で選択されていたウィンドウを第1引数、norecordを第2引数として、サブルーチンとしてselect-window
を呼び出す(したがってnorecordが非nil
ならもっとも最近に選択されたウィンドウとバッファーリストの変更を避ける)。ウィンドウの選択を参照のこと。
この関数はframe、frameが削除されていればnil
をリターンする。
一般的には実行後に端末を戻すよう切り替えることなく、別の端末に切り替えるのが可能な手段としてselect-frame
を決して使用しないこと。
Emacsはサーバーやウィンドウマネージャーのリクエストとしてフレーム選択をアレンジすることによりウィンドウシステムと協調します。これは適切なときにフォーカス(focus)と呼ばれる特殊な入力イベントを生成することにより行われます。コマンドループはhandle-switch-frame
を呼び出してフォーカスイベントを処理します。フォーカスイベントを参照してください。
この関数はフレームframe選択によりフォーカスイベントを処理する。
フォーカスイベントは、通常はこのコマンドを呼び出すことによりその処理を行う。他の理由でこれを呼び出しではならない。
この関数はframeからfocus-frameにフォーカスをリダイレクトする。これはframeにかわってfocus-frameが以降のキーストロークとイベントを受け取るであろうことを意味する。そのようなイベント後にはlast-event-frame
の値はfocus-frameになるだろう。またframeを指定したswitch-frameイベントも、かわりにfocus-frameを選択するだろう。
focus-frameが省略またはnil
なら、frameにたいするすべての既存のリダイレクションがキャンセルされるので、frameが自身のイベントを再度受け取ることになる。
フォーカスリダイレクトの用途の1つは、ミニバッファーをもたないフレームにたいしてである。これらのフレームは別フレーム上のミニバッファーを使用する。別フレーム上のミニバッファーをアクティブにすることは、そのフレームにフォーカスをリダイレクトすることである。これはたとえマウスがミニバッファーをアクティブにしたフレーム内に留まっていても、ミニバッファーが属すフレームにフォーカスを置く。
フレーム選択はフォーカスリダイレクションの変更も可能にする。foo
が選択されているときにフレームbar
を選択することにより、foo
を指すすべてのリダイレクションはかわりにbar
を指す。これはユーザーがselect-window
を使用してあるフレームから別のフレームに切り替えた際に、フォーカスのリダイレクトが正しく機能することを可能にする。
これはフォーカスが自身にリダイレクトされたフレームが、フォーカスがリダイレクトされていないフレームとは異なる扱いを受けることを意味する。前者にたいしてselect-frame
は影響するが、後者には影響がない。
このリダイレクションは、それを変更するためにredirect-frame-focus
が呼び出されるまで継続する。
これはEmacsフレームが入力フォーカスを得た際に実行されるノーマルフック。
これはEmacsフレームが入力フォーカスを失った際に実行されるノーマルフック。
これはユーザーがマウスを移動した際に、ウィンドウマネージャーがフォーカスを転送するかどうかをEmacsに告げるためのオプション。非nil
ならフォーカスは転送される。その場合にはコマンドother-frame
は新たに選択されたフレームと一貫性のある位置にマウスを移動する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
グラフィカルなディスプレイ上のフレームは可視(visible)、不可視(invisible)、またはアイコン化(iconified)されているかもしれません。可視ならそのコンテンツは通常の方法により表示されます。アイコン化されている場合にはそのコンテンツは表示されませんが、ビュー内にフレームを戻すための小さいアイコンがどこかにあります(いくつかのウィンドウマネージャーはこの状態をアイコン化ではなく最小化と呼ぶがEmacsの見地ではこれらは同等である)。フレームが不可視ならまったく表示されません。
テキスト端末では実際に表示されるのは常にただ1つの選択されたフレームだけなので、可視性に意味はありません。
この関数はフレームframeの可視性の状態をリターンする。値はframeが可視ならt
、不可視ならnil
、アイコン化されていればicon
。
テキスト端末上ではたとえ1つのフレームだけが表示されているとしても、この関数の目的にたいしてはすべてのフレームが可視とみなされる。フレームを前面や背面に移動するを参照のこと。
この関数はフレームframeをアイコン化する。frameを省略すると選択されたフレームをアイコン化する。
この関数はフレームframeを可視にする。frameを省略すると選択されたフレームを可視にする。これはフレームを前面に移動しないが、望むならraise-frame
でこれを行うことができる(フレームを前面や背面に移動するを参照)。
この関数はフレームframeを不可視にする。frameを省略すると選択されたフレームを不可視にする。
forceがnil
なら、この関数は他のすべてのフレームが不可視の場合にframeを不可視にすることを拒絶する。
フレームの可視性の状態はフレームパラメーターとしても利用可能である。つまりフレームパラメーターとして読み取りと変更ができる。ウィンドウ管理のパラメーターを参照のこと。ウィンドウマネージャーによりユーザーがフレームのアイコン化や非アイコン化を行うこともできる。これはEmacsが何らかの制御を及ぼすのが可能なレベルより下のレベルにおいて発生するが、Emacsはそのような変化を追跡するために使用するイベントを提供する。その他のシステムイベントを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ほとんどのウィンドウシステムでは、デスクトップというメタファー(metaphor:
比喩的概念)は使用されます。このメタファーの一部はシステムレベルのウィンドウ(Emacsではフレーム)がスクリーン表面に向かって、概念的な3次元の垂直方向に積まれていくというアイデアです。2つが重なる箇所では、より高い一方がより低い一方を覆い隠します。関数raise-frame
やlower-frame
を使用して、フレームを前面に移動(raise:
より高い位置へ上げる)したり背面に移動(lower: より低い位置へ移動)したりすることができます。
この関数はフレームframe (デフォルトは選択されたフレーム)を前面に移動する。frameが不可視もしくはアイコン化されていればそれを可視にする。
この関数はフレームframe (デフォルトは選択されたフレーム)を背面に移動する。
これが非nil
ならミニバッファーをアクティブにすることにより、ミニバッファーウィンドウのあるフレームが前面に移動される。
ウィンドウシステム上ではフレームパラメーターを使用して、(フレーム選択時に)auto-raising、(フレーム選択解除時に)auto-loweringを有効にできます。ウィンドウ管理のパラメーターを参照してください。
フレームを前面や背面に移動するという概念は、テキスト端末のフレームにも適用できます。各テキスト端末上では一度に表示されるのは常に最前面のフレームだけです。
この関数はterminal上の最前面のフレームをリターンする。terminalは端末オブジェクト、フレーム(そのフレームの端末を意味する)、またはnil
(選択されたフレームの端末を意味する)であること。これがテキスト端末を参照しなければリターン値はnil
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレーム構成(frame configuration)はフレームのカレント配置、すべてのプロパティ、および各ウィンドウのウィンドウ構成(ウィンドウの構成を参照)を記録します。
この関数はフレームのカレント配置とそのコンテンツを記述するフレーム構成のリストをリターンする。
この関数はフレームの状態をconfigurationの記述にリストアする。ただしこの関数は削除されたフレームはリストアしない。
この関数は通常はconfiguration内にリストされない既存フレームすべてを削除する。しかしnodeleteが非nil
なら、それらのフレームはかわりにアイコン化される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マウスをトラック(track: 追跡)するのが有用なことが時折あります。マウスのトラックとはマウスの位置を示す何かを表示して、マウス移動とともにそのインジケーターを移動するという意味です。効果的にマウスをトラックするためには、マウスが実際に移動するまで待機する手段が必要になります。
マウスをトラックするためには、マウスのモーション(motion: 移動)を表すイベントを問い合わせるのが便利な方法です。その後はそのイベントを待機することによりモーションを待機できます。それに加えて発生し得る他の類のイベントも簡単に処理できます。ボタンのリリースのような何か他のイベントだけを待機してマウスを永久にトラックすることは、通常は望ましくないのでこれは有用です。
このスペシャルフォームはマウスモーションイベントの生成を有効にしてbodyを実行する。bodyはモーションイベントを読み取るために通常はread-event
を使用して、それに対応して表示を変更する。マウスモーションイベントのフォーマットについてはモーションイベントを参照のこと。
track-mouse
の値はbody内の最後のフォームの値。ボタンのリリースを示すup-event、またはトラックを止めるべきタイミングを意味する類のイベントを確認した際にはリターンするようにbodyをデザインすること。
track-mouse
フォームでは変数track-mouse
を非nil
値にバインドすることにより、Emacsにマウスモーションイベントを生成させる。この変数が特別な値dragging
をもつなら、ディスプレーエンジンにマウスポインターのシェイプ(形状)の変更を控えるように追加で指示する。これはEmacsが表示する大きな範囲を横断するマウスドラッグを要するLispプログラムでは、そうしなければ表示箇所に応じてマウスポインターのシェイプが変更されてしまうので望ましいだろう(ポインターの形状を参照)。したがってドラッグ中にオリジナルのマウスポインターシェイプを保つ必要があるLispプログラムは、bodyの先頭でtrack-mouse
を値dragging
にバインドすること。
マウスモーションをトラックする通常の目的は、それ以降に発生するボタンのプッシュやリリースをカレント位置に示すことです。
多くの場合はテキストプロパティmouse-face
(特殊な意味をもつプロパティを参照)を使用することにより、マウスをトラックする必要性を回避できます。これはより低レベルで機能して、かつLispレベルのマウストラッキングよりスムーズに実行されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
関数mouse-position
とset-mouse-position
はマウスのカレント位置にたいするアクセスを提供します。
この関数はマウス位置の記述子をリターンする。値は(frame x
. y)
のような形式であり、xとyはframeのネイティブ位置(Frame Geometryを参照)から相対的に、frameのデフォルト文字サイズ(Frame Fontを参照)の単位で位置を与える整数(丸められている可能性あり)。
この変数の値は非nil
ならmouse-position
にたいして呼び出される関数。mouse-position
はリターン直前に、自身の通常のリターン値を唯一の引数としてこの関数を呼び出して、それが何であれその関数がリターンした値をリターンする。
このアブノーマルフックはxt-mouse.elのようにLispレベルでマウス処理を行う必要があるパッケージのために存在する。
この関数はフレームframe内の位置x、yにマウスをワープ(warps the mouse)する。引数xとyはframeのネイティブ位置(Frame Geometryを参照)から相対的に、frameのデフォルト文字サイズ(Frame Fontを参照)の単位で位置を与える整数(丸められている可能性あり)。
結果となるマウス位置はframeのネイティブフレームに拘束される。この関数はframeが不可視なら何も行わない。リターン値に意味はない。
この関数はmouse-position
と似ているが文字単位ではなくピクセル単位の座標をリターンする。
この関数はset-mouse-position
のようにマウスをワープするが、xとyが文字単位ではなくピクセル単位である点が異なる。
結果となるマウス位置はframeのネイティブフレームに拘束される。この関数はframeが不可視なら何も行わない。リターン値に意味はない。
フラフィカルな端末上では、以下の2つの関数によりマウスカーソルの絶対位置の取得とセットができます。
この関数は選択されたフレームのディスプレーの位(0, 0)から相対的に、マウスカーソルの位置の座標をピクセル単位のコンスセル(x . y)でリターンする。
この関数はマウスカーソルを位置(x, y)に移動する。座標xとyは、選択されたフレームのディスプレーの位置(0, 0)から相対的なピクセル値と解釈される。
以下の関数はフレーム上のマウスカーソルがレントで可視かどうかを確認します:
この述語関数はframe上に表示されたマウスポインターが可視なら非nil
、それ以外はnil
をリターンする。frameが省略またはnil
ならそれは選択されたフレームを意味する。これはmake-pointer-invisible
がt
にセットされているときに有用。これによりポインターが隠されていることを知ることができる。Mouse
Avoidance in The Emacs Manualを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispプログラムがポップアップメニューを表示して、ユーザーがマウスで候補を選択できます。テキスト端末上では、マウスが利用不可ならキーボードのモーションキーC-nやC-p、上矢印キーや下矢印キーで候補を選択できます。
この関数はポップアップメニューを表示して、ユーザーが何を選択したかの指標をリターンする。
引数positionには、メニュー左上隅をスクリーン上のどこに置くか指定する。これはマウスボタンイベント(ユーザーがボタンを操作した位置にメニューを置くよう指示する)、または以下の形式のリストのいずれか:
((xoffset yoffset) window)
ここでxoffsetとyoffsetはwindowの左上隅からピクセル単位で測られた座標である。windowはウィンドウかフレーム。
positionがt
なら、それはマウスのカレント位置の使用を意味する(テキスト端末上でマウスが利用不可ならフレーム左上隅)。positionがnil
なら、それは実際にメニューをポップアップせずに、menu内で指定されたキーマップと等価なキーバインディングを事前に計算することを意味する。
引数menuはメニュー内で何を表示するかを意味する。これはキーマップかキーマップのリストを指定できる(メニューキーアップを参照)。この場合にはリターン値はユーザー選択に対応するイベントのリスト。選択がサブメニュー内で発生した場合には、このリストには複数の要素がある(x-popup-menu
はそのイベントシーケンスにバインドされたコマンドを実際には実行しないことに注意)。テキスト端末やメニュータイトルをサポートするツールキットでは、menuがキーマップならタイトルはmenuのプロンプト文字列、menuがキーマップのリストなら最初のキーマップのプロンプト文字列から取得される(メニューの定義を参照)。
かわりにmenuは以下の形式をもつこともできる:
(title pane1 pane2...)
ここでpaneはそれぞれ以下の形式のリストである
(title item1 item2...)
itemはそれぞれコンスセル(line
.
value)
であること。ここでlineは文字列、valueはlineが選択された場合にリターンされる値。メニューキーマップとは異なりnil
のvalueは選択不可のメニューアイテムを作成しない。かわりにitemにコンスセルではなく文字列を指定できる。これは選択不可のメニューアイテムを作成する。
たとえば有効な選択からマウスを外してクリックしたり、C-gをタイプすることにより、有効な選択を行うことなくユーザーがメニューを取り除いた場合は、通常はquitしてx-popup-menu
はリターンしない。しかしpositionがマウスボタンイベント(ユーザーがマウスでメニューを呼び出したことを示す)なら、quitは発生せずにx-popup-menu
はリターンする。
使用上の注意:
メニューキーマップで定義したプレフィクスキー処理を行える場合には、メニューの表示にx-popup-menu
を使用しないでください。メニューの実装にメニューキーマップを使用する場合には、C-h
cとC-h
aでメニュー内の個別アイテムの確認、およびそれらにたいするヘルプを提供できます。かわりにx-popup-menu
を呼び出すコマンドを定義することによりメニューを実装した場合には、ヘルプ機能はそのコマンド内部で何が起こっているか知ることができず、そのメニューアイテムのヘルプを何も与えることはできません。
マウス移動によってサブメニュー間を切り替えるメニューバーのメカニズムは、それがx-popup-menu
を呼び出すか確認するためにコマンドの定義を見ることができません。したがってx-popup-menu
を使用してサブメニューの実装を試みた場合には、それは統合された方式でメニューバーとともに機能しません。メニューバーのすべてのサブメニューは親メニューのメニューキーマップにより実装されて、決してx-popup-menu
で実装されないのはこれが理由です。メニューバー Barを参照してください。
メニューバーのサブメニューのコンテンツを変化させたい場合にも、その実装には依然としてメニューキーマップを使用するべきです。コンテンツを変化させるためには、必要に応じてメニューキーマップのコンテンツを更新するためにフック関数をmenu-bar-update-hook
に追加してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ダイアログボックスとはポップアップメニューの一種です。外見は多少異なり常にフレーム中央に表示されて、階層を1つしかもたず1つ以上のボタンがあります。ユーザーが“yes”、“no”、および別のいくつかの候補で応答ができる質問を尋ねるのがダイアログボックスの主な用途です。単一のボタンではユーザーに重要な情報の確認を強いることもできます。関数y-or-n-p
やyes-or-no-p
は、マウスのクリックで呼び出されたコマンドから呼び出された際には、キーボードのかわりにダイアログボックスを使用します。
この関数はポップアップダイアログボックスを表示してユーザーが何を選択したかの指標をリターンする。引数contentsは提供する選択肢を指定する。これは以下のフォーマットをもつ:
(title (string . value)…)
これはx-popup-menu
にたいして単一のpaneを指定するリストのように見える。
リターン値は選択された候補のvalue。
x-popup-menu
の場合と同じように、このリストの要素はコンスセル(string
. value)
のかわりに単なる文字列かもしれない。これは選択不可のボックスを作成する。
このリスト内にnil
がある場合には、それは左手側と右手側のアイテムを分ける。つまりnil
より前のアイテムは左、nil
より後のアイテムは右に表示される。リスト内にnil
を含めない場合には、およそ半数ずつが両サイドに表示される。
ダイアログボックスは常にフレームの中央に表示される。引数positionはどのフレームかを指定する。可能な値はx-popup-menu
の場合と同様だが、正確な座標や個別のウィンドウは問題ではなくフレームだけが問題となる。
headerが非nil
ならボックスのフレームタイトルは‘Information’、それ以外は‘Question’になる。前者はmessage-box
(message-boxを参照)にたいして使用される(テキスト端末上ではボックスタイトルは表示されない)。
いくつかの構成ではEmacsは本当のダイアログボックスを表示できないので、かわりにフレーム中央のポップアップメニュー内に同じアイテムを表示する。
たとえばウィンドウマネージャーを使用して有効な選択を行うことなくユーザーがダイアログボックスを取り除いた場合には、通常はquitしてx-popup-dialog
はリターンしない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
テキストプロパティpointer
や、イメージならイメージプロパティ:pointer
と:map
を使用して、特定のテキストやイメージにたいしてマウスポインターのスタイルを指定できます。これらのプロパティに使用できる値はtext
(またはnil
)、arrow
、hand
、vdrag
、hdrag
、modeline
、hourglass
です。text
はテキスト上で使用される通常のマウスポインタースタイルを意味します。
ウィンドウの空部分(void parts:
バッファーコンテンツのどの部分にも対応しない部分)の上では、マウスポインターは通常arrow
スタイルを使用しますが、void-text-area-pointer
をセットすることにより異なるスタイルを指定できます。
この変数は空テキストエリアにたいするマウスポインタースタイルを指定する。このエリアには行末の後やバッファー終端行の下が含まれる。デフォルトではarrow
(non-text)ポインタースタイルを使用する。
Xを使用する際は変数x-pointer-shape
をセットすることによりtext
の実際の外見を指定できます。
この変数はEmacsフレーム内でポインタースタイルtext
に通常使用するポインターシェイプを指定する。
この変数はマウスがマウスセンシティブテキスト上にあるときのポインターシェイプを指定する。
これらの変数は新たに作成されるフレームに影響します。これらは通常は既存のフレームに効果はありませんが、フレームのマウスカラーのインストール時にはこれら2つ変数のカレント値もインストールされます。フォントとカラーのパラメーターを参照してください。
これらのポインターシェイプのいずれかを指定するために使用可能な値はファイルlisp/term/x-win.el内で定義されています。それらのリストを確認するにはM-x apropos RET x-pointer RETを使用してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Xのようなウィンドウシステムでは、異なるアプリケーション間のデータ転送は選択(selections)により行われます。Xは任意の数の選択タイプ(selection types)を定義し、それぞれが独自にデータを格納できます。しかし一般的に使用されるのはクリップボード(clipboard)、プライマリー選択(primary selection)、セカンダリー選択(secondary selection)の3つだけです。それ以外のウィンドウシステムではクリップボードだけがサポートされます。これら3つの選択を使用するEmacsコマンドについてはCut and Paste in The GNU Emacs Manualを参照してください。このセクションではウィンドウシステムによる選択の読み取りとセットを行う低レベル関数について説明します。
この関数はウィンドウシステムの選択をセットする。これは選択タイプtype、それに割り当てる値dataという2つの引数を受け取る。
typeはシンボルであること。通常はPRIMARY
、SECONDARY
、CLIPBOARD
のいずれかである。これらはXウィンドウシステムの慣例に対応する大文字のシンボル名である。typeがnil
ならそれはPRIMARY
を意味する。
dataがnil
なら、それはその選択をクリアーすることを意味する。それ以外ならdataは文字列、シンボル、整数(2つの整数からなるコンスかリスト)、オーバーレイ、同じバッファーを指す2つのマーカーのコンスを指定できる。オーバーレイとマーカーのペアは、そのオーバーレイまたはマーカー間のテキストを意味する。引数dataには有効な非ベクターの選択のベクターも指定できる。
この関数はdataをリターンする。
この関数はEmacsや他のプログラムによりセットアップされた選択にアクセスする。これはtypeとdata-typeの2つの引数を受け取る。typeは選択のタイプでありデフォルトはPRIMARY
。
data-type引数は別のXクライアントから取得したrawデータをLispデータに変換するためにデータ変換に使用する形式を指定する。有意義な値にはTEXT
、STRING
、UTF8_STRING
、TARGETS
、LENGTH
、DELETE
、FILE_NAME
、CHARACTER_POSITION
、NAME
、LINE_NUMBER
、COLUMN_NUMBER
、OWNER_OS
、HOST_NAME
、USER
、CLASS
、ATOM
、INTEGER
が含まれる(これらは対応するX慣習の大文字シンボル名である)。data-typeのデフォルトはSTRING
。X以外のウィンドウシステムは、通常はSTRING
に加えて、少数の部分集合だけをサポートする。
この変数は選択やクリップボードに読み書きする際のコーディングシステムを指定する。コーディングシステムを参照のこと。デフォルトはcompound-text-with-extensions
で、これはX11が通常使用するテキスト表現に変換する。
EmacsがMS-Windows上で実行されている際には、一般的にX選択はサポートされませんがクリップボードはサポートされます。MS-Windowsでのgui-get-selection
とgui-set-selection
は、テキストデータタイプだけをサポートします。クリップボードが他のタイプのデータを保持している場合には、Emacsはクリップボードを空として扱います。サポートされるデータタイプはSTRING
です。
後方互換性のためにgui-get-selection
とgui-set-selection
にたいして、Emacs
25.1以前の名前x-get-selection
とx-set-selection
が時代遅れのエイリアスとして存在します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ユーザーが別のアプリケーションからEmacsに何かをドラッグをした際には、その別アプリケーションはEmacsがドラッグされたデータを処理可能か告げることを期待します。変数x-dnd-test-function
は何を応答するか決定するためにEmacsにより使用されます。デフォルト値はx-dnd-default-test-function
で、これはドロップされたデータのタイプがx-dnd-known-types
内にあればドロップを受け入れます。何か別の条件にもとづいてEmacsにドロップを許容または拒絶させたければ、x-dnd-test-function
および/またはx-dnd-known-types
をカスタマイズできます。
Emacsが異なるタイプのドロップを処理する方法を変更したり新たなタイプを追加したければx-dnd-types-alist
をカスタマイズします。これには他のアプリケーションがドラッグアンドドロップに使用するタイプが何なのか詳細な知識が要求されます。
EmacsにURLがドロップされたとき、それはファイルかもしれませんが他のURLタイプ(ftp、http、...)であるかもしれません。EmacsはまずそのURLに何を行うべきか判断するために、dnd-protocol-alist
をチェックします。それにマッチがなく、かつbrowse-url-browser-function
がalistならEmacsはそこでマッチを探します。それでもマッチが見つからなければ、そのURLにたいするテキストを挿入します。これらの変数をカスタマイズすればEmacsの挙動を変更できます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
カラー名(color name)とはカラーを指定するテキスト(通常は文字列)です。‘black’、‘white’、‘red’等を指定できます。定義された名前のリストはM-x list-colors-displayを使用して確認できます。‘#rgb’や‘RGB:r/g/b’のような数値的な形式でカラーを指定することもできます。ここでrは赤(red)、gは緑(green)、bは青(blue)のレベルを指定します。1桁、2桁、3桁、または4桁の16進数をrに使用できます。その後のgとbには同じ桁数の16進数を同様に使用しなければなりません。これにより総桁数が3、6、9、または12桁の16進数となります(カラーの数値的なRGB指定についての詳細はXウィンドウシステムのドキュメントを参照)。
以下の関数は有効なカラー名と、それらの外見を判断する手段を提供します。以下で説明するようにその値は選択されたフレーム(selected frame)に依存する場合があります。“選択されたフレーム”という用語の意味については入力のフォーカスを参照してください。
補完付きでカラー名のユーザー入力を読み取るにはread-color
を使用します(read-colorを参照)。
この関数はカラー名が有意かどうかを報告する。もし有意ならt
、それ以外はnil
をリターンする。引数frameはどのフレームのディスプレイにたいして問い合わせるかを指定する。frameが省略またはnil
の場合は選択されたフレームが使用される。
これは使用しているディスプレイがそのカラーをサポートするかどうかは告げないことに注意。X使用時にはすべての種類のディスプレイ上のすべての定義されたカラーを問い合わせることができ、何らかの結果(通常は可能な限り近いカラー)を得ることができるだろう。あるフレームが特定のカラーを実際に表示できるかどうか判断するためにはcolor-supported-p
(以下参照)を使用する。
この関数は以前はx-color-defined-p
と呼ばれており、その名前は今でもエイリアスとしてサポートされている。
この関数はframe(デフォルトは選択されたフレーム)上で定義されていて、かつサポートされるカラー名のリストをリターンする。frameがカラーをサポートしなければ値はnil
。
この関数は以前はx-defined-colors
と呼ばれており、その名前は今でもエイリアスとしてサポートされている。
これは、frameが実際にカラーcolor
(または最低でもそれに近いカラー)を表示可能ならt
をリターンする。frameが省略またはnil
ならこの問いは選択されたフレームに適用される。
フォアグラウンドとバックグラウンドにたいして異なるカラーセットをサポートする端末がいくつかある。background-pが非nil
なら、それはcolorがバックグラウンドとして、それ以外はフォアグラウンドとして使用可能かどうかを問うことを意味する。
引数colorは有効なカラー名でなければならない。
これはcolorがframeのディスプレイ上の定義としてグレイスケールならt
をリターンする。frameが省略またはnil
なら、この問いは選択されたフレームに適用される。colorが有効なカラー名でなければ、この関数はnil
をリターンする。
この関数はframe上で理想的にはcolorがどのように見えるべきかを記述する値をリターンする。colorが定義済みなら値は赤、緑、青の割合を与える3つの整数からなるリストとなる。それぞれの整数の範囲は原則として0から65535だが、この範囲全体を使用しないディスプレイもいくつか存在するだろう。この3要素のリストはカラーのRGB値(rgb values)と呼ばれる。
colorが未定義なら値はnil
。
(color-values "black") ⇒ (0 0 0) (color-values "white") ⇒ (65280 65280 65280) (color-values "red") ⇒ (65280 0 0) (color-values "pink") ⇒ (65280 49152 51968) (color-values "hungry") ⇒ nil
カラーの値はframeのディスプレイにたいしてリターンされる。frameが省略またはnil
の場合には、この情報は選択されたフレームのディスプレイにたいしてリターンされる。このフレームがカラーを表示できなければ値はnil
。
この関数は以前はx-color-values
と呼ばれており、その名前は今でもエイリアスとしてサポートされている。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
テキスト端末は通常は少しのカラーしかサポートせず、コンピューターはカラー選択に小さい整数を使用します。これは選択したカラーがどのように見えるかコンピューターが信頼性をもって告げることができず、どのカラーがどのような小さい整数に対応するかという情報をアプリケーションに伝える必要があることを意味します。しかしEmacsは標準的なカラーセットを知っており、それらの自動的な使用を試みるでしょう。
このセクションで説明する関数はEmacsが端末カラーを使用する方法を制御します。
これらの関数のうちのいくつかはカラー名で説明したRGB値(rgb values)を使用またはリターンします。
これらの関数はオプション引数としてディスプレイ(フレームまたは端末名のいずれか)を受け取ります。わたしたちは将来には異なる端末上で異なるカラーをEmacsにサポートさせたいと望んでいます。そうすればこの引数はどの端末を処理するか(デフォルトは選択されたフレームの端末。入力のフォーカスを参照)を指定するようになるでしょう。しかし現在のところframe引数に効果はありません。
この関数はカラー名nameをその端末上のカラー値numberに関連付ける。
オプション引数rgbが指定された場合、それはそのカラーが実際にどのように見えるかを指定する3つの数値のリストからなるRGB値である。rgbを指定しなければEmacsはそれがどのように見えるか知らないので、そのカラーを他のカラーに近似するためにtty-color-approximate
で使用することができない。
この関数はテキスト端末の定義済みカラーのテーブルをクリアーする。
この関数はテキスト端末がサポートする既知のカラーを記録したalistをリターンする。
それぞれの要素は(name number . rgb)
、または(name
number)
という形式をもつ。ここでnameはカラー名、numberはその端末でカラー指定に使用される数値。rgbが与えられたら、それはそのカラーが実際にどのように見えるかを告げる3つのカラー値(赤、緑、青)のリストである。
この関数はdisplayにたいしてサポートされた既知のカラーの中から、RGB値rgb
(カラー値のリスト)で記述されたもっとも近いカラーを探す。リターン値はtty-color-alist
の要素。
この関数はdisplayにたいしてサポートされた既知のカラーの中から、もっとも近いカラーのインデックス(整数)をリターンする。名前colorが未定義なら値はnil
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではXリソース、または他のオペレーティングシステム上での等価物を問い合わせたり使用する関数および変数をいくつか説明します。Xリソースにたいする詳細な情報はX Resources in The GNU Emacs Manualを参照してください。
関数x-get-resource
はXウィンドウのデフォルトデータベースからリソース値を取得する。
リソースはキー(key)とクラス(class)の組み合わせによりインデックス付けされている。この関数は‘instance.attribute’という形式をキー(instanceはEmacsが呼び出されたときの名前)、クラスとして‘Emacs.class’として使用することにより検索を行う。
オプション引数componentとsubclassは、それぞれキーとクラスを追加する。指定する場合には両方を指定するか、さもなくばどちらも指定してはならない。これらを指定した場合にはキーは‘instance.component.attribute’、クラスは‘Emacs.class.subclass’となる。
この変数はx-get-resource
が照会すべきアプリケーション名を指定する。デフォルト値は"Emacs"
。x-get-resource
の呼び出し周辺で、この変数を他のアプリケーション名の文字列にバインドすることにより、アプリケーション名にたいしてXリソースを調べることができる。
この変数はx-get-resource
が照会すべきインスタンス名を指定する。デフォルト値はEmacs呼び出し時の名前、またはスイッチ‘-name’、または‘-rn’で指定された値。
上述のいくつかを説明するためにXリソースファイル(通常は~/.Xdefaultsや~/.Xresources)内に以下のような行があるとしましょう:
xterm.vt100.background: yellow
その場合は:
(let ((x-resource-class "XTerm") (x-resource-name "xterm")) (x-get-resource "vt100.background" "VT100.Background")) ⇒ "yellow"
(let ((x-resource-class "XTerm") (x-resource-name "xterm")) (x-get-resource "background" "VT100" "vt100" "Background")) ⇒ "yellow"
この変数が非nil
ならEmacsはXリソースを照会せず、新たなフレーム作成時にXリソースは何も効果をもたない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションの関数は特定のディスプレイの基本的な能力を説明します。Lispプログラムはそのディスプレイが行えることに挙動を合わせるために、それらを使用できます。たとえばポップアップメニューがサポートされなければ、通常はポップアップメニューを使用するプログラムはミニバッファーを使用できます。
これらの関数のオプション引数displayは問い合わせるディスプレイを指定します。これにはディスプレイ名、フレーム(フレームがあるディスプレイを指定)、またはnil
(選択されたフレームのディスプレイを参照する。入力のフォーカスを参照)を指定できます。
ディスプレイに関する情報を取得するその他の関数についてはカラー名を参照してください。
この関数はdisplay上でポップアップメニューがサポートされていればt
、それ以外はnil
をリターンする。Emacsディスプレイのある部分をマウスでクリックすることによりメニューがポップアップするので、ポップアップメニューのサポートにはマウスが利用可能であることが要求される。
この関数はdisplayが一度に複数フレームおよび複数の異なるフォントを表示する能力を有すグラフィックディスプレイならt
をリターンする。これはXのようなウィンドウシステムのディスプレイにたいしては真、テキスト端末にたいしては偽となる。
この関数はdisplayでマウスが利用可能ならt
、それ以外はnil
をリターンする。
この関数はそのスクリーンがカラースクリーンならt
をリターンする。これは以前はx-display-color-p
と呼ばれており、その名前はエイリアスとして今でもサポートされる。
この関数はスクリーンがグレースケールを表示可能ならt
をリターンする(カラーディスプレイはすべてこれを行うことができる)。
この関数はattributes内のすべてのフェイス属性がサポートされていれば非nil
をリターンする(フェイスの属性を参照)。
幾分発見的ではあるが“サポートされる”という言葉は、基本的にはあるフェイスがattributes内のすべての属性を含み、ディスプレイにたいしてデフォルトフェイスにマージ時に、
2つ目のポイントによると属性:weight black
は太字(bold)表示可能、同様に属性:foreground
"yellow"
は黄色がかった何らかのカラーを表示可能なすべてのディスプレイで満たされるだろうが、属性:slant
italic
は斜体(italic)を自動的に淡色(dim)に置き換えるttyの表示コードでは満たされないであろうことを暗示している。
この関数はdisplayが選択(selections)をサポートすればt
をリターンする。ウィンドウ化されたディスプレイでは通常は選択がサポートされるが、他の場合にもサポートされ得る。
この関数はdisplayがイメージを表示可能ならt
をリターンする。ウィンドウ化されたディスプレイは原則イメージを処理するが、イメージにたいするサポートを欠くシステムもいくつかある。イメージをサポートしないディスプレイ上ではEmacsはツールバーを表示できない。
この関数はそのディスプレイに割り当てられたスクリーンの数をリターンする。
この関数はスクリーンの高さをピクセルでリターンする。文字端末では文字数で高さを与える。
マルチモニターにセットアップされているグラフィカル端末では、displayに割り当てられたすべての物理モニターのピクセル幅を参照することに注意。複数の端末を参照のこと。
この関数はスクリーンの幅をピクセルでリターンする。文字端末では文字数で幅を与える。
マルチモニターにセットアップされているグラフィカル端末では、displayに割り当てられたすべての物理モニターのピクセル幅を参照することに注意。複数の端末を参照のこと。
この関数はスクリーンの高さをミリメートルでリターンする。nil
ならEmacsがその情報を取得できなかったことを意味する。
マルチモニターにセットアップされているグラフィカル端末では、displayに割り当てられたすべての物理モニターのピクセル幅を参照することに注意。複数の端末を参照のこと。
この関数はスクリーンの幅をミリメートルでリターンする。nil
ならEmacsがその情報を取得できなかったことを意味する。
マルチモニターにセットアップされているグラフィカル端末では、displayに割り当てられたすべての物理モニターのピクセル幅を参照することに注意。複数の端末を参照のこと。
この変数はシステムの提供する値が不正な場合にdisplay-mm-height
とdisplay-mm-width
がリターンするグラフィカルなディスプレイのサイズをユーザーが指定できるようにする。
この関数はそのディスプレイのバッキングストアー(backing store)の能力をリターンする。バッキングストアーとは非露出ウィンドウ(およびウィンドウの一部)のピクセルを記録しておいて、露出時に素早く表示できるようにすることを意味する。
値はシンボルalways
、when-mapped
、not-useful
。特定の種類のディスプレイにたいしてこの問いが適用外の際には、この関数はnil
をリターンすることもある。
この関数はそのディスプレイがSaveUnder機能をサポートすれば非nil
をリターンする。この機能はポップアップウィンドウに隠されるピクセルを保存して素早くポップダウンができるようにするために使用される。
この関数はそのディスプレイがサポートする平面数(number of planes)をリターンする。これは通常はピクセルごとのビット数(bits per pixel: 色深度[bpp])。ttyディスプレイではサポートされるカラー数の2進対数(log to base two)。
この関数はそのスクリーンのビジュアルクラスをリターンする。値はシンボルstatic-gray
(カラー数変更不可の限定されたグレイ)、gray-scale
(フルレンジのグレイ)、static-color
(カラー数変更不可の限定されたカラー)、pseudo-color
(限定されたカラー数のカラー)、true-color
(フルレンジのカラー)、およびdirect-color
(フルレンジのカラー)のいずれか。
この関数はそのスクリーンがサポートするカラーのセル数をリターンする。
以下の関数はEmacsが指定されたdisplayを表示する場所に使用されるウィンドウシステムの追加情報を取得します(関数名先頭のx-
は歴史的理由による)。
この関数はGNUおよびUnixシステム上のXサーバーのような、display上で実行されているGUIウィンドウシステムのバージョン番号のリストをリターンする。値は3つの整数からなるリストで、1つ目と2つ目の整数はそのプロトコルのメジャーバージョン番号とマイナーバージョン番号、3つ目の整数はウィンドウシステムソフトウェア自体のディストリビューター固有のリリース番号。GNUおよびUnixシステムでは、通常これらはXプロトコルのバージョン番号と、Xサーバーソフトウェアのディストリビューター固有のリリース番号。MS-WindowsではWidowsのOSバージョン番号。
この関数はウィンドウシステムソフトウェアを提供するベンダー(文字列)をリターンする。GNUおよびUnixシステムでは、それが誰であれそのXサーバーを配布するベンダーを意味する。MS-WindowsではWidows OSのベンダーID文字列(Microsoft)。
X開発者がソフトウェア配布者を“vendors”とラベル付けしたことは、いかなるシステムも非商業的に開発および配布できないと彼らが誤って仮定したことを示している。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
位置(position)とは、バッファーのテキストの文字のインデックスです。より正確には、位置とは2つの文字間(または最初の文字の前か最後の文字の後)の箇所を識別して、与えられた位置の前あるいは後の文字のように表現することができます。しかし“ある位置にある文字”のように表現することもあり、その場合にはその位置の後にある文字を意味します。
位置は通常は1から始まる整数として表されますが、マーカー(markers)として表現することもできます。関数は引数に位置(整数)を期待しますが、代替としてマーカーも受け入れ、通常はそのマーカーが指すのがどのバッファーなのかは無視します。これらの関数はマーカーを整数に変換して、たとえそのマーカーが誤ったバッファーを指していたとしても、まるで引数として単にその整数が渡されたかのようにその整数を使用します。整数に変換できない場所を指すマーカーを整数のかわりに使用するとエラーとなります。マーカーを参照してください。
多くのカーソルモーションコマンドにより使用される関数を提供するフィールド(field)機能も参照してください(フィールドの定義と使用を参照)。
29.1 ポイント | 編集タスクが行われる特別な位置。 | |
29.2 モーション | ポイントの変更。 | |
29.3 エクスカーション | 一時的な移動とバッファーの変更。 | |
29.4 ナローイング | バッファーの一部に編集を限定する。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ポイント(point)とは多くの編集コマンドにより使用されるバッファーの特別な位置のことです。これらのコマンドには自己挿入型のタイプ文字やテキスト挿入関数が含まれます。その他のコマンドは別の箇所でテキストの編集や挿入ができるようにポイントを移動します。
ポイントは他の位置と同様に特定の文字ではなく、2つの文字の間(または最初の文字の前か最後の文字の後)を指します。端末では通常はポイント直後の文字の上にカーソルを表示します。つまりポイントは実際はカーソルのある文字の前にあります。
ポイントの値は1より小さくなることはなく、そのバッファーのサイズに1を加えた値より大きくなることはありません。ナローイング(ナローイングを参照)が効力をもつ場合には、ポイントはそのバッファーのアクセス可能な範囲内(範囲の境界はバッファーの先頭か終端のいずれかの可能性がある)に拘束されます。
バッファーはそれぞれ自身のポイント値をもち、それは他のバッファーのポイント値とは無関係です。ウィンドウもそれぞれポイント値をもち、他のウィンドウ内の同じバッファー上のポイント値とは無関係です。同じバッファーを表示する種々のウィンドウが異なるポイント値をもてるのはこれが理由です。あるバッファーがただ1つのウィンドウに表示されているときは、そのバッファーのポイントとそのウィンドウのポイントは通常は同じ値をもち、区別が重要になることは稀です。詳細はウィンドウとポイントを参照してください。
この関数はカレントバッファー内のポイントの値を整数でリターンする。
(point) ⇒ 175
この関数はカレントバッファー内のアクセス可能なポイントの最小値をリターンする。これは通常は1だがナローイングが効力をもつ場合は、ナローイングしたリージョンの開始位置となる(ナローイングを参照)。
この関数はカレントバッファー内のアクセス可能なポイントの最大値をリターンする。これはナローイングされていなければは(1+
(buffer-size))
だが、ナローイングが効力をもつ場合は、ナローイングしたリージョンの終端位置となる(ナローイングを参照)。
この関数はflagが0より大なら(point-max)
、それ以外は(point-min)
をリターンする。引数flagは数値でなければならない。
この関数はカレントバッファー内の文字数のトータルをリターンする。ナローイング(ナローイングを参照)されていなければ、point-max
はこれに1を加えた値をリターンする。
bufferにバッファーを指定すると値はbufferのサイズになる。
(buffer-size) ⇒ 35
(point-max) ⇒ 36
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
モーション関数はポイントのカレント値、バッファーの先頭か終端、または選択されたウィンドウ端のいずれかより相対的にポイントの値を変更します。ポイントを参照してください。
29.2.1 文字単位の移動 | 文字単位での移動。 | |
29.2.2 単語単位の移動 | 単語単位での移動。 | |
29.2.3 バッファー終端への移動 | バッファー先頭や終端への移動。 | |
29.2.4 テキスト行単位の移動 | テキスト行単位での移動。 | |
29.2.5 スクリーン行単位の移動 | 表示される行単位での移動。 | |
29.2.6 バランスのとれたカッコを越えた移動 | リストやS式の解析による移動。 | |
29.2.7 文字のスキップ | 特定の集合に属す文字のスキップ。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数は文字数にもとづいてポイントを移動します。 goto-char
は基本的なプリミティブであり、その他の関数はこれを使用しています。
この関数はカレントバッファー内のポイントの値をpositionにセットする。
ナローイングが効力をもつ場合でもpositionは依然としてバッファー先頭から数えられるが、ポイントをアクセス可能な範囲外に移動することはできない。positionが範囲外なら、goto-char
はアクセス可能な範囲の先頭または終端にポイントを移動する。
この関数がインタラクティブに呼び出された際は、positionの値は数プレフィクス引数、プレフィクス引数が与えられなかった場合はミニバッファーから値を読み取る。
goto-char
はpositionをリターンする。
この関数は前方、すなわちバッファーの終端方向にポイントをcount文字移動する(countが負なら後方、すなわちバッファーの先頭方向にポイントを移動する)。countがnil
の場合のデフォルトは1。
バッファー(ナローイングが効力をもつ場合はアクセス可能な範囲の境界)の先頭か終端を超えて移動を試みるとエラーシンボルbeginning-of-buffer
かend-of-buffer
のエラーをシグナルする。
インタラクティブな呼び出しでは数プレフィクス引数がcountとなる。
移動方向が逆であることを除いて、これはforward-char
と同様。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下で説明する単語をパースする関数は、与えられた文字が単語の一部かどうかを判断するために構文テーブルとchar-script-table
を使用します。構文テーブルと文字のプロパティを参照してください。
この関数はcountの単語数分ポイントを前方に移動する。(countが負なら後方に移動する)。countが省略またはnil
の場合のデフォルトは1。インタラクティブな呼び出しでは、countは数プレフィクス引数により指定される。
“単語1つ移動”とは単語構成文字を横断して、単語の先頭を示す単語区切り文字に遭遇するまでポイントを移動することを意味する。単語境界(word
boundaries)として知られる単語の開始と終了の文字は、デフォルトではカレントバッファーの構文テーブル(構文クラスのテーブルを参照)により定義されるが、以下で説明するfind-word-boundary-function-table
を適切にセットすることによりモードはこれをオーバーライドできる。(char-syntax-table
で定義される)異なるスクリプトに属するも単語境界を定義する(文字のプロパティを参照)。いくつかのケースでは、この関数はバッファーのアクセス可能範囲の境界およびフィールド境界(フィールドの定義と使用を参照)を超えてポイントを移動できない。フィールド境界のもっとも一般的な例は、ミニバッファー内のプロンプト終端である。
バッファー境界やフィールド境界により途中で停止することなく単語count個分の移動が可能なら値はt
となる。それ以外ではリターン値はnil
となり、ポイントはバッファー境界またはフィールド境界で停止する。
inhibit-field-text-motion
が非nil
なら、この関数はフィールド境界を無視する。
この関数は単語の前に遭遇するまで前方ではなく後方に移動することを除いてforward-word
と同様。
この変数は、forward-word
とbackward-word
、およびそれらを使用するすべての関数の挙動に影響する。これが非nil
なら、構文クラスescapeとcharacter-quote内の文字は単語の一部とみなされる。それ以外なら単語の一部とはみなされない。
この変数が非nil
ならforward-word
、forward-sentence
、forward-paragraph
を含む特定のモーション関数はフィールド境界を無視する。
この変数はforward-word
とbackward-word
、およびそれらを使用するすべての挙動に影響する。値は単語境界を検索するための関数の文字テーブル(文字テーブルを参照)。このテーブル内である文字が非nil
のエントリーをもつ場合には、単語がその文字で開始または終了する際に対応する関数が2つの引数posとlimitで呼び出される。この関数は別の単語境界の位置をリターンすること。具体的には、posがlimitより小さければposは単語の先頭にあり関数はその単語の最後の文字の後の位置、それ以外ならposは単語の最後の文字にあり関数はその単語の最初の文字の位置をリターンすること。
この関数はforward-word
と同様だがfind-word-boundary-function-table
による影響を受けない点が異なる。このテーブルをセットするsubword-mode
のようなモードにより単語単位の移動が変更されている際に挙動を変えるべきではないLispプログラムは、forward-word
のかわりにこの関数を使用すること。
この関数はbackward-word
と同様だが、find-word-boundary-function-table
の影響を受けない点が異なる。forward-word-strictly
と同様に、構文テーブルだけを考慮して単語単位の移動を行う必要がある際には、backward-word
のかわりにこの関数を使用すること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファーの先頭にポイントを移動するには以下のように記述します:
(goto-char (point-min))
同様にバッファーの終端に移動するには以下を使用します:
(goto-char (point-max))
以下の2つのコマンドは、ユーザーがこれらを行うためのコマンドです。これらはマークをセットしてメッセージをエコーエリアに表示するため、Lispプログラム内で使用しないよう警告するためにここに記述します。
この関数はバッファー(ナローイングが効力をもつ場合はアクセス可能範囲の境界)の先頭にポイントを移動して、以前の位置にマークをセットする(Transient Markモードの場合にはマークがすでにアクティブならマークはセットしない)。
nが非nil
ならバッファーのアクセス可能範囲の先頭からn/10の位置にポイントを配置する。インタラクティブな呼び出しではnは数プレフィクス引数が与えられればその値、それ以外でのデフォルトはnil
。
警告: この関数をLispプログラム内で使用してはならない。
この関数はバッファー(ナローイングが効力をもつ場合はアクセス可能範囲の境界)の終端にポイントを移動して、以前の位置にマークをセットする(Transient
Markモードの場合にはマークがすでにアクティブならマークはセットしない)。nが非nil
ならバッファーのアクセス可能範囲の終端からn/10の位置にポイントを配置する。
インタラクティブな呼び出しではnは数プレフィクス引数が与えられればその値、それ以外でのデフォルトはnil
。
警告: この関数をLispプログラム内で使用してはならない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
テキスト行とは改行で区切られたバッファーの範囲です。改行は前の行の一部とみなされます。最初のテキスト行はバッファー先頭で始まり、最後のテキスト行は最後の文字が改行かどうかは関係なくバッファー終端で終わります。バッファーからテキスト行への分割はそのウィンドウの幅、表示の行継続、タブやその他の制御文字の表示方法に影響されません。
この関数はカレント行の先頭にポイントを移動する。引数countが非nil
または1以外なら前方にcount-1行移動してから、その行の先頭に移動する。
この関数は別の行に移動する場合を除いてフィールド境界(フィールドの定義と使用を参照)を超えてポイントを移動しない。したがってcountがnil
か1で、かつポイントがフィールド境界で開始される場合にはポイントを移動しない。フィールド境界を無視させるにはinhibit-field-text-motion
をt
にバインドするか、かわりにforward-line
関数を使用する。たとえばフィールド境界を無視することを除けば、(forward-line
0)
は(beginning-of-line)
と同じことを行う。
この関数がバッファー(ナローイングが効力をもつ場合はアクセス可能範囲)の終端に到達したらポイントをその位置に配置する。エラーはシグナルされない。
(beginning-of-line count)
が移動するであろう位置をリターンする。
この関数は、カレント行の終端にポイントを移動する。引数countが非nil
または1以外なら前方にcount-1行移動してから、その行の終端に移動する。
この関数は別の行に移動する場合を除いてフィールド境界(フィールドの定義と使用を参照)を超えてポイントを移動しない。したがってcountがnil
または1で、かつポイントがフィールド境界で開始される場合にはポイントを移動しない。フィールド境界を無視させるにはinhibit-field-text-motion
をt
にバインドする。
この関数がバッファー(ナローイングが効力をもつ場合はアクセス可能範囲)の終端に到達したらポイントをその位置に配置する。エラーはシグナルされない。
(end-of-line count)
が移動するであろう位置をリターンする。
この関数は後続行へ前方にcount行移動して、その行の先頭にポイントを移動する。countが負なら先行行へ後方に-count行移動して、その行の先頭にポイントを移動する。countが0ならカレント行の先頭にポイントを移動する。countがnil
ならそれは1を意味する。
forward-line
が指定された行数を移動する前にバッファー(またはアクセス可能範囲)の先頭か終端に遭遇したら、そこにポイントをセットする。エラーはシグナルされない。
forward-line
はcountと実際に移動した行数の差をリターンする。3行しかないバッファーの先頭から5行下方への移動を試みると、ポイントは最終行の終端で停止して値は2となるだろう。明示的な例外としてアクセス可能な最終行が空ではなく改行がなければ(バッファーが改行で終わらない場合)、この関数はその行の終端にポイントをセットして、この関数がリターンする値はその行を移動に成功した1行として計数する。
インタラクティブな呼び出しでは数プレフィクス引数がcountとなる。
この関数はカレントバッファー内の位置startとendの間の行数をリターンする。startとendが等しければリターン値は0。それ以外は、たとえstartとendが同一行にあっても最小でも1をリターンする。これらの間にあるテキストは、それだけを孤立して考えたると、それが空でない限りは最小でも1行を含まなければならないからである。
この関数はカレントバッファー内の位置startとendの間にある単語の数をリターンする。
この関数はインタラクティブに呼び出すこともできる。その場合はバッファー、またはリージョンがアクティブならリージョン内の行数、単語数、文字数を報告するメッセージをプリントする。
この関数はカレントバッファー内のバッファー位置posに対応する行番号をリターンする。posがnil
または省略されるとカレントのバッファー位置が使用される。
ポイント周辺のテキストを調べるの関数bolp
とeolp
も参照してください。これらの関数はポイントを移動しませんが、ポイントがすでに行頭または行末にあるかどうかをテストします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
前のセクションの行関数は、改行文字で区切られたテキスト行だけを数えました。それらとは対照的に以下の関数はスクリーン行を数えます。スクリーン行はスクリーン上でテキストが表示される方法にしたがって定義されます。あるテキスト行1行が選択されたウィンドウの幅にフィット可能な程に十分短ければそれはスクリーン行で1行になりますが、それ以外は複数のスクリーン行になり得ます。
テキスト行が追加スクリーン行に継続されずに、そのスクリーンで切り詰められる(truncated)場合があります。そのような場合にはvertical-motion
でforward-line
のようにポイントを移動します。切り詰めを参照してください。
文字列が与えられると、その幅は文字の外見を制御するフラグに依存するために与えられたテキスト断片にたいして、たとえそれが選択されたウィンドウ上でさえも(幅、切り詰めの有無、ディスプレイテーブルはウィンドウごとに異なり得るので)、そのテキストがあるバッファーに応じてvertical-motion
の挙動は異なります。通常の表示の慣習を参照してください。
以下の関数はスクリーン行のブレーク位置を判断するためにテキストをスキャンするために、スキャンする長さに比例して時間を要します。
この関数はポイントのあるスクリーン行からスクリーン行でcount行下方に移動して、そのスクリーン行の先頭にポイントを移動する。countが負ならかわりに上方に移動する。
count引数には整数のかわりにコンスセル(cols
.
lines)
を指定できる。その場合には関数はスクリーン行でlines行移動して、そのスクリーン行の視覚的な行頭(visual
start)からcols列目にポイントを配置する。colsはその行の視覚的(visual)な開始から数えられることに注意。そのウィンドウが水平スクロール(水平スクロールを参照)されていれば、ポイントが配置される列は、スクロールされたテキストの列数が加えられるだろう。
リターン値はポイントが移動したスクリーン行の行数。バッファーの先頭か終端に到達していたら、この値は絶対値ではcountより小になるかもしれない。
ウィンドウwindowは幅、水平スクロール、ディスプレイテーブルのようなパラメーターの取得に使用される。しかしvertical-motion
は、たとえwindowがカレントで他のバッファーを表示していたとしても、常にカレントバッファーにたいして処理を行う。
オプション引数cur-colはこの関数呼び出しの際のカレント列を指定する。これはそのフレームのデフォルトフェイスのフォント幅を単位として計測される、ウィンドウに相対的なポイントの水平座標でる。カレント列の判定のために戻る必要がないので、特に長い行における関数の高速化を提供する。cur-colも行の視覚的な開始から計数されることに注意。
この関数はbegからendのテキスト内のスクリーン行の行数をリターンする。スクリーン行数は行継続やディスプレイテーブル等により実際の行数とは異なるかもしれない。begとendがnil
、または省略された場合のデフォルトは、そのバッファーのアクセス可能範囲の先頭と終端。
そのリージョンが改行で終わる場合には、オプションの第3引数count-final-newlineがnil
ならそれは無視される。
オプションの第4引数windowは幅や水平スクロール等のパラメーターを取得するウィンドウを指定する。デフォルトは選択されたウィンドウのパラメーターを使用する。
vertical-motion
と同じうように、count-screen-lines
はwindow内にどのバッファーが表示されていようと常にカレントバッファーを使用する。これによりバッファーが何らかのウィンドウにカレントで表示されているか否かにかかわらず、任意にバッファーにたいしてcount-screen-lines
の使用が可能になる。
この関数は選択されたウィンドウ内にカレントで表示されているテキストに応じてポイントを移動する。これはウィンドウ上端からスクリーン行でcount行目の先頭にポイントを移動する。countが負なら、それはバッファー下端(バッファーが指定されたスクリーン位置の上で終わる場合はバッファーの最終行)から、-count行目の位置を指定する。
countがnil
ならポイントはウィンドウ中央の行の先頭に移動する。countの絶対値がウィンドウサイズより大の場合には、ウィンドウが十分に高かったらそのスクリーン行は表示されていたであろう位置にポイントを移動する。これはおそらく次回の再表示の際に、その箇所がスクリーン上になるようなスクロールを発生させるだろう。
インタラクティブな呼び出しでは数プレフィクス引数がcountとなる。
リターン値はウィンドウ上端行の番号を0とする、ポイントが移動した先の行番号。
この関数はmove-to-window-line
と同様だが、選択されたウィンドウがウィンドウグループ(Window Groupを参照)の一部なら、move-to-window-group-line
は単一のウィンドウではなくグループ全体にたいする位置に移動する。この条件はバッファーローカル変数move-to-window-group-line-function
に関数がセットされている際に保持される。この場合にはmove-to-window-group-line
は引数countでその関数を呼び出して、その結果をリターンする。
この関数はカレントバッファーをスキャンしてスクリーン位置を計算する。これは位置fromがスクリーン座標fromposにあると仮定して、そこから位置toまたは座標toposのいずれか先に到達したほうまでバッファーを前方にスキャンする。これはスキャン終了のバッファー位置とスクリーン座標をリターンする。
座標引数fromposとtoposは、(hpos . vpos)
という形式のコンスセル。
引数widthはテキストを表示するために利用可能な列数。これは継続行の処理に影響する。nil
はそのウィンドウ内で使用可能な実際のテキスト列数であり、(window-width
window)
がリターンする値と等しい。
引数offsetsはnil
、または(hscroll
.
tab-offset)
という形式のコンスセルのいずれかであること。ここでhscrollは左マージンのために表示されない列数であり、呼び出し側のほとんどはwindow-hscroll
を呼び出すことによりこれを取得する。一方tab-offsetはスクリーン上の列数とバッファー内の列数の間のオフセットである。これは継続行において前のスクリーン行の幅がtab-width
の整数倍でないときは非0になる可能性がある。非継続行ではこれは常に0。
ウィンドウwindowの唯一の役割は使用するディスプレイテーブルの指定である。compute-motion
はwindow内に表示されているのがどのバッファーであろうとカレントバッファーを処理する。
リターン値は5つの要素をもつリストである:
(pos hpos vpos prevhpos contin)
ここでposはスキャンが停止したバッファー位置、vposは垂直スクリーン位置、hposは水平スクリーン位置である。
結果のprevhposはposから1文字戻った水平位置、continは最後の行が前の文字の後(または中)から継続されていればt
となる。
たとえばあるウィンドウのスクリーン行lineの列colのバッファー位置を求めるには、そのウィンドウのdisplay-start(表示開始)位置をfrom、そのウィンドウの左上隅の座標をfromposとして渡す。スキャンをそのバッファーのアクセス可能範囲の終端に制限するために、バッファーの(point-max)
をto、lineとcolをtoposに渡す。以下はこれを行う関数:
(defun coordinates-of-position (col line) (car (compute-motion (window-start) '(0 . 0) (point-max) (cons col line) (window-width) (cons (window-hscroll) 0) (selected-window))))
ミニバッファーにたいしてcompute-motion
を使う際には、最初のスクリーン行の先頭の水平位置を取得するためにminibuffer-prompt-width
を使用する必要がある。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はバランスの取れたカッコ式(balanced-parenthesis。これらの式を横断して移動することと関連してEmacsではsexp(S式)とも呼ばれる)と関係のあるいくつかの関数です。これらの関数がさまざまな文字を処理する方法は構文テーブル(syntax table)が制御します。構文テーブルを参照してください。sexpやその一部にたいする低レベルのプリミティブについては式のパースを参照してください。ユーザーレベルのコマンドについてはCommands for Editing with Parentheses in The GNU Emacs Manualを参照してください。
この関数はバランスの取れたカッコのグループをarg (デフォルトは1)グループ前方に移動する(単語やクォート文字のペアーでクォートされた文字列は無視される)。
この関数はバランスの取れたカッコのグループをarg (デフォルトは1)グループ後方に移動する(単語やクォート文字のペアーでクォートされた文字列は無視される)。
この関数はarg (デフォルトは1)の外側のカッコへ前方に移動する。負の引数では後方へ移動するが、それでもより浅いスポットへと移動する。
escape-stringsが非nil
(インタラクティブ時が該当)なら、取り囲まれた文字列の外側にも同様に移動する。no-syntax-crossingが非nil
(インタラクティブ時が該当)なら、複数の文字列を横断してリスト先頭に移動するかわりに、取り囲む文字列から脱け出すことを優先する。エラー時にはポイントの位置は未定義。
この関数はup-list
とど同様だが引数の正負が逆。
この関数はカッコをarg (デフォルトは1)レベル内側、前方に移動する。負の引数では後方に移動するが、それでも深いレベル(-argレベル)に移動する。
この関数はバランスの取れた式(balanced expressions)をarg (デフォルトは1)前方に移動する。バランスの取れた式にはカッコ等で区切られた式、および単語や文字列定数のようなものも含まれる。式のパースを参照のこと。たとえば、
---------- Buffer: foo ---------- (concat∗ "foo " (car x) y z) ---------- Buffer: foo ----------
(forward-sexp 3) ⇒ nil ---------- Buffer: foo ---------- (concat "foo " (car x) y∗ z) ---------- Buffer: foo ----------
この関数はバランスの取れた式(balanced expressions)を、arg (デフォルトは1)後方に移動する。
この関数は後方にarg番目のdefunの先頭に移動する。argが負なら実際には前方に移動するが、defunの終端ではなく先頭に移動することは変わらない。argのデフォルトは1。
この関数は前方にarg番目のdefunの終端に移動する。argが負なら実際には後方に移動するが、defunの先頭ではなく終端に移動することは変わらない。argのデフォルトは1。
このバッファーローカル変数は非nil
ならdefunの始まりとなる開きカッコの前に出現し得るテキストを指定する正規表現を保持する。つまりこの正規表現にたいするマッチで始まり、その後に開きカッコ構文(open-parenthesis
syntax)が続くものがdefunである。
この変数の値が非nil
なら列0にある開きカッコはdefunの始まりとみなされる。nil
なら列0の開きカッコは特別な意味をもたない。デフォルトはt
。
この変数は非nil
ならdefunの開始を見つける関数を保持する。関数beginning-of-defun
は通常の手法を使うかわりに、この関数に自身のオプション引数を渡して呼び出す。引数が非nil
なら、その関数はその回数分の関数呼び出しによってbeginning-of-defun
が行うように後方に移動すること。
この変数は非nil
ならdefunの終端を見つける関数を保持する。関数end-of-defun
は、通常の手法を使うかわりにその関数を呼び出す。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の2つの関数は指定された文字セットを超えてポイントを移動します。これらの関数は、たとえば空白文字をスキップするためによく使用されます。関連する関数についてはモーションと構文を参照してください。
これらの関数は検索関数(検索とマッチングを参照)が行うように、そのバッファーがマルチバイト(multibyte)ならマルチバイトに、ユニバイト(unibyte)ならユニバイトにその文字列セットを変換します。
この関数は与えられた文字セットをスキップしてカレントバッファー内のポイント前方に移動する。これはポイントの後の文字を調べて、その文字がcharacter-setにマッチすればポイントを進める。そしてマッチしない文字に到達するまでこれを継続する。この関数は飛び超えて移動した文字数をリターンする。
引数character-setは文字列であり正規表現での‘[…]’内部と同様だが、‘]’で終端されず‘\’が‘^’、‘-’、‘\’をクォートする点が異なる。つまり"a-zA-Z"
はすべての英字をスキップして最初の非英字の前で停止、"^a-zA-Z"
はすべての非英字をスキップして最初の英字の前で停止する。正規表現を参照のこと。"[:alnum:]"
のような文字クラスも使用できる。see section 文字クラスを参照のこと。
limit (数字かマーカー)が与えられたら、それはポイントがスキップして到達できるそのバッファー内の最大位置を指定する。ポイントはlimit、またはlimitの前でストップするだろう。
以下の例ではポイントは最初‘T’の直前に置かれている。フォーム評価後にポイントはその行の末尾( ‘hat’の‘t’と改行の間)に配置される。この関数はすべての英字とスペースをスキップするが改行はスキップしない。
---------- Buffer: foo ---------- I read "∗The cat in the hat comes back" twice. ---------- Buffer: foo ----------
(skip-chars-forward "a-zA-Z ") ⇒ 18 ---------- Buffer: foo ---------- I read "The cat in the hat∗ comes back" twice. ---------- Buffer: foo ----------
この関数はlimitに至るまでcharacter-setにマッチする文字をスキップしてポイントを後方に移動する。これはskip-chars-forward
と同様だがポイントを移動する方向が異なる。
リターン値は移動した距離を示す。これは0以上の整数。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プログラム中の限定された部分でポイントを一時的に移動するのが便利なことが時折あります。これはエクスカーション(excursion:
遠足、小旅行)と呼ばれるもので、スペシャルフォームsave-excursion
により行われます。この構文は初期のカレントバッファー自体とポイントの値を記憶して、そのエクスカーション完了時にそれらをリストアします。これはプログラムのある部分においてプログラムの他の部分に影響を与えることなくポイントを移動する標準的な手段であり、EmacsのLispソース内では何度も使用されています。
カレントバッファー自体のみの保存やリストアが必要なら、かわりにsave-current-buffer
やwith-current-buffer
を使用してください(カレントバッファーを参照)。ウィンドウ構成の保存やリストアが必要なら、ウィンドウの構成とフレーム構成で説明されているフォームを参照してください。
このスペシャルフォームはカレントバッファー自体とポイント値を保存、bodyを評価してから最後にバッファーと保存したポイントとマークの値をリストアする。throw
やエラーを通じたアブノーマルexit(非ローカル脱出を参照)の場合にも、保存されたいずれの値もリストアされる。
save-excursion
がリターンする値はbody内の最後のフォームの結果、またはbodyフォームが与えられなければnil
をリターンする。
save-excursion
はエクスカーション開始時にカレントだったバッファーのポイントだけを保存するために、そのエクスカーション中に変更された他のバッファーのポインはその後も効果が残るでしょう。これはしばしば予期せぬ結果を招くので、エクスカーション中にset-buffer
を呼び出すとバイトコンパイラーは警告を発します:
Warning: Use ‘with-current-buffer’ rather than save-excursion+set-buffer
このような問題を回避するためには、以下の例のように望むカレントバッファーをセット後にのみsave-excursion
を呼び出すべきです:
(defun append-string-to-buffer (string buffer) "BUFFER末尾にSTRINGを追加" (with-current-buffer buffer (save-excursion (goto-char (point-max)) (insert string))))
同様にsave-excursion
はswitch-to-buffer
のような関数が変更したウィンドウ/バッファーの対応をリストアしません。
警告:
保存されたポイント値に隣接する通常のテキスト挿入は、それがすべてのマーカーを再配置するのと同じように、保存されたポイントカーを再配置します。より正確には保存される値は挿入タイプnil
のマーカーです。Marker 挿入タイプを参照してください。したがって保存されたポイント値は、リストア時には通常は挿入されたテキストの直前になります。
このマクロはsave-excursion
と同様だが、マークの位置とmark-active
の保存とリストアも行う点が異なる。このマクロはEmacsのバージョン25.1以前にsave-excursion
が行っていたことを行う。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ナローイング(narrowing)とはEmacs編集コマンドがアドレス指定可能なテキストを、あるバッファー内の制限された文字範囲に限定することを意味します。アドレス可能なテキストは、そのバッファーのアクセス可能範囲(accessible portion)と呼ばれます。
ナローイングは2つのバッファー位置により指定されるもので、それらの位置がアクセス可能範囲の開始と終了になります。ほとんどの編集コマンドやプリミティブにたいして、これらの位置はそれぞれそのバッファーの先頭と終端に置き換えられます。ナローイングが効果をもつ間にはアクセス可能範囲外のテキストは表示されず、その外部にポイントを移動することはできません。ナローイングは実際のバッファー位置(ポイントを参照)を変更しないことに注意してください。ほとんどの関数はアクセス可能範囲外のテキストにたいする操作を受け入れません。
バッファーを保存するコマンドはナローイングの影響を受けません。どんなナローイングであろうと、それらはバッファー全体を保存します。
単一バッファー内にタイプが大きく異なるテキストを複数表示する必要がある場合には、2つのバッファー間でのテキストの交換で説明する代替機能の使用を考慮してください。
この関数はアクセス可能範囲の開始と終了にカレントバッファーのstartとendをセットする。どちらの引数も文字位置で指定すること。
インタラクティブな呼び出しでは、startとendはカレントリージョンにセットされる(ポイントとマークで小さいほうが前者)。
この関数はカレントページだけを含むようにカレントバッファーのアクセス可能範囲をセットする。1つ目のオプション引数move-countが非nil
なら、move-countで前方か後方へ移動後に1ページにナローすることを意味する。変数page-delimiter
はページの開始と終了の位置を指定する(編集で使用される標準的な正規表現を参照)。
インタラクティブな呼び出しではmove-countには数プレフィクス引数がセットされる。
この関数はカレントバッファーにたいするすべてのナローイングをキャンセルする。これはワイドニング(widening)と呼ばれる。これは以下の式と等価:
(narrow-to-region 1 (1+ (buffer-size)))
この関数はそのバッファーがナローされていれば非nil
、それ以外はnil
をリターンする。
このスペシャルフォームはアクセス可能範囲のカレントのバインドを保存してbodyを評価、その後に以前有効だったナローイング(またはナローイングがない状態)と同じ状態になるように、最後に保存された境界をリストアする。ナローイングの状態は、throw
やエラーを通じたアブノーマルexit(非ローカル脱出を参照)イベント内においてもリストアされる。したがってこの構文は一時的にバッファーをナローする明快な手段である。
save-restriction
がリターンする値はbody内の最後のフォームのリターン値、bodyフォームが与えられなければnil
。
注意: save-restriction
使用の際は間違いを起こしやすい。これを試みる前にこの説明全体に目を通すこと。
bodyがカレントバッファーを変更する場合でもsave-restriction
は依然として元のバッファー(その制限が保存されたバッファー)上の制限をリストアするが、カレントバッファー自体はリストアしない。
save-restriction
はポイントをリストアしない。これを行うにはsave-excursion
を使用する。save-restriction
とsave-excursion
の両方を共に使用するなら、始め(外側)にsave-excursion
を記述すること。それ以外では一時的なナローイング影響下で古いポイント値がリストアされる。古いポイント値が一時的なナローイング境界外なら、それを実際にリストアすることは失敗するだろう。
以下はsave-restriction
の正しい使い方の簡単な例:
---------- Buffer: foo ---------- This is the contents of foo This is the contents of foo This is the contents of foo∗ ---------- Buffer: foo ----------
(save-excursion (save-restriction (goto-char 1) (forward-line 2) (narrow-to-region 1 (point)) (goto-char (point-min)) (replace-string "foo" "bar"))) ---------- Buffer: foo ---------- This is the contents of bar This is the contents of bar This is the contents of foo∗ ---------- Buffer: foo ----------
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マーカー(marker)とは、あるバッファー内で取り囲んでいるテキストにたいして相対的な位置を指定するために使用されるオブジェクトです。テキストが挿入や削除される際には、常にマーカーは自動的にそのバッファーの先頭からのオフセットを自動的に変更して自身の左右にある文字の間に留まります。
30.1 マーカーの概要 | マーカー構成要素と再配置方法。 | |
30.2 マーカーのための述語 | オブジェクトがマーカーか否かのテスト。 | |
30.3 マーカーを作成する関数 | 空マーカーや特定箇所のマーカーの作成。 | |
30.4 マーカーからの情報 | マーカーのバッファーや文字位置を探す。 | |
30.5 Marker 挿入タイプ | マーカーが指す位置への挿入時にマーカーを再配置する2つの方法。 | |
30.6 マーカー位置の移動 | 新たなバッファーや位置にマーカーを移動する。 | |
30.7 マーク | マーカーによるマークの実装方法。 | |
30.8 リージョン | リージョンへのアクセス方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マーカーはバッファーとそのバッファー内の位置を指定します。マーカーは位置を要求する関数内において、整数と同じように位置を表すために使用することができます。その場合には、そのマーカーのバッファーは通常は無視されます。この方法で使用されるマーカーは、通常はその関数が処理するバッファー内の位置を指しますが、それは完全にプログラマーの責任です。位置についての完全な説明はポジションを参照してください。
マーカーはマーカー位置(marker position)、マーカーバッファー(marker buffer)、挿入タイプ(insertion type)という3つの属性をもちます。マーカー位置はそのバッファー内の位置としてのマーカーと(その時点において)等しい整数です。しかしマーカー位置はマーカーの生存期間中に変化し得るものであり頻繁に変更されます。バッファー内でのテキストの挿入や削除によってマーカーは再配置されます。マーカー前後の2文字以外の場所で挿入や削除がおこなわれても、マーカー位置はその2文字間に留まるというのがこのアイデアです。再配置によってマーカーと等価な整数は変更されます。
マーカー位置周辺のテキストを削除することにより、そのマーカーは削除されたテキストの直前と直後にある文字の間に残されます。マーカー位置へのテキスト挿入では、マーカーは通常は新たなテキストの前か後のいずれかに配置されます。その挿入がinsert-before-markers
(テキストの挿入を参照)で行われたものでなければ、どちらに配置されるかはマーカーの挿入タイプ(Marker 挿入タイプを参照)に依存します。
バッファーでの挿入と削除では、すべてのマーカーをチェックして必要ならそれらを再配置しなければなりません。これは多数のマーカーをもつバッファーでの処理を低速にします。この理由によりそれ以上マーカーが不必要なことが確信できるなら、存在しない場所を指さないようにマーカーを設定することはよいアイデアといえるでしょう。それ以上アクセスされる可能性がないマーカーは最終的には削除されます(ガーベージコレクションを参照)。
マーカー位置にたいして算術演算を行うことは一般的なので、それらの演算子のほとんど(+
や-
を含む)が引数としてマーカーに渡すことができます。そのような場合でのマーカーはカレント位置を意味します。
以下ではマーカーの作成とセットを行ってポイントをマーカーに移動しています:
;; 最初はどこも指さない新たなマーカーを作成:
(setq m1 (make-marker))
⇒ #<marker in no buffer>
;; カレントバッファーの99と100番目の
;; 文字間を指すようm1
をセット:
(set-marker m1 100)
⇒ #<marker at 100 in markers.texi>
;; ここでバッファー先頭に1文字挿入:
(goto-char (point-min))
⇒ 1
(insert "Q")
⇒ nil
;; m1
は適切に更新された
m1
⇒ #<marker at 101 in markers.texi>
;; 同じ位置を指す2つのマーカーは ;;equal
だがeq
に非ず (setq m2 (copy-marker m1)) ⇒ #<marker at 101 in markers.texi> (eq m1 m2) ⇒ nil (equal m1 m2) ⇒ t
;; マーカー使用終了時、存在しない場所を指すようセット
(set-marker m1 nil)
⇒ #<marker in no buffer>
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
あるオブジェクトがマーカーなのか、それとも整数かマーカーのいずれかであるかを確認するためのテストを行うことができます。後者のテストはマーカーと整数の両方にたいして機能する算術関数において有用です。
この関数はobjectがマーカーならnil
、それ以外はt
をリターンする。多くの関数はマーカーか整数のいずれかを受け入れるだろうが、整数はマーカーとは異なることに注意。
この関数はobjectが整数かマーカーならt
、それ以外はnil
をリターンする。
この関数はobjectが数値(整数か浮動小数点数)またはマーカーならt
、それ以外はnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マーカーを新たに作成する際には存在しない場所、ポイントの現在位置、バッファーのアクセス可能範囲の先頭や終端、または別の与えられたマーカーと同じ箇所を指すようにすることができます。
以下の4つの関数はすべて挿入タイプnil
のマーカーをリターンします。Marker 挿入タイプを参照してください。
この関数はどこも指さないマーカーを新たに作成してリターンする。
(make-marker) ⇒ #<marker in no buffer>
この関数はカレントバッファーのポイント現在位置を指すマーカーを新たに作成してリターンする。ポイントを参照のこと。例は以下のcopy-marker
を参照のこと。
この関数はバッファーのアクセス可能範囲の先頭を指すマーカーを新たに作成してリターンする。ナローイングが効力をもたなければ、これはバッファーの先頭になるだろう。ナローイングを参照のこと。
この関数はバッファーのアクセス可能範囲の終端を指すマーカーを新たに作成してリターンする。ナローイングが効力をもたなければ、これはバッファーの終端になるだろう。ナローイングを参照のこと。
以下はこのチャプターのテキストのソースファイルのバージョンを含むバッファーにたいして、この関数とpoint-min-marker
を使用する例。
(point-min-marker) ⇒ #<marker at 1 in markers.texi> (point-max-marker) ⇒ #<marker at 24080 in markers.texi>
(narrow-to-region 100 200) ⇒ nil
(point-min-marker) ⇒ #<marker at 100 in markers.texi>
(point-max-marker) ⇒ #<marker at 200 in markers.texi>
引数としてマーカーを渡されると、copy-marker
はmarker-or-integerが行うように同じバッファーの同じ位置を指すマーカーを新たに作成してリターンする。整数を渡されると、copy-marker
はカレントバッファーの位置marker-or-integerを指すマーカーを新たに作成してリターンする。
新たなマーカーの挿入タイプは引数insertion-typeにより指定される。Marker 挿入タイプを参照のこと。
(copy-marker 0) ⇒ #<marker at 1 in markers.texi>
(copy-marker 90000) ⇒ #<marker at 24080 in markers.texi>
markerがマーカーと整数のいずれでもなければエラーがシグナルされる。
2つのマーカーはそれらが同じバッファーの同じ位置、またはどちらも存在しない場所を指す場合には、(eq
ではないが)equal
とみなされます。
(setq p (point-marker)) ⇒ #<marker at 2139 in markers.texi>
(setq q (copy-marker p)) ⇒ #<marker at 2139 in markers.texi>
(eq p q) ⇒ nil
(equal p q) ⇒ t
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではマーカーオブジェクトの構成要素にアクセスする関数を説明します。
この関数はmarkerが指す位置、存在しない場所ならnil
をリターンする。
この関数はmarkerがその内部を指すバッファー、存在しない場所を指す場合にはnil
をリターンする。
(setq m (make-marker)) ⇒ #<marker in no buffer>
(marker-position m) ⇒ nil
(marker-buffer m) ⇒ nil
(set-marker m 3770 (current-buffer)) ⇒ #<marker at 3770 in markers.texi>
(marker-buffer m) ⇒ #<buffer markers.texi>
(marker-position m) ⇒ 3770
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マーカーが指す位置に直接テキストを挿入する際には、そのマーカーを再配置するために利用可能な手段が2つあります。そのマーカーは挿入されたテキストの前か後を指すことができます。マーカーの挿入タイプ(insertion
type)を指定することにより、マーカーがどちらを行うか指定できます。insert-before-markers
を使用する場合には、マーカーの挿入タイプを無視して常にマーカーが挿入されたテキストの後を指すよう再配置されることに注意してください。
この関数はマーカーmarkerの挿入タイプをtypeにセットする。typeがt
なら、テキスト挿入時にmarkerはその位置まで進められるだろう。typeがnil
なら、テキスト挿入時にmarkerはそこまで進められることはない。
この関数はmarkerのカレント挿入タイプを報告する。
挿入タイプを指定するための引数を受け取らずにマーカーを作成するすべての関数は、挿入タイプnil
でマーカーを作成します。マークもデフォルトでは挿入タイプnil
をもちます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは既存マーカーの位置を変更する方法について説明します。これを行う際にはそのマーカーがあなたのプログラム外部に使用されているかどうか、もし使用されているならマーカーを移動した結果どのような影響が生じるかを確実に理解する必要があります。さもないとEmacsの他の部分で混乱した出来事が発生するかもしれません。
この関数はbuffer内でmarkerをpositionに移動する。bufferが与えられなかった場合のデフォルトはカレントバッファー。
positionがnil
、または存在しない場所を指すマーカーなら、markerは存在しない場所を指すようにセットされる。
リターン値はmarker。
(setq m (point-marker)) ⇒ #<marker at 4714 in markers.texi>
(set-marker m 55) ⇒ #<marker at 55 in markers.texi>
(setq b (get-buffer "foo")) ⇒ #<buffer foo>
(set-marker m 0 b) ⇒ #<marker at 1 in foo>
これはset-marker
の別名。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファーはそれぞれマーク(mark)というバッファー専用の特別なマーカーをもちます。バッファーが新たに作成される際には、このマーカーはすでに存在していますがどこも指していません。これはそのバッファーにはまだマークが存在しないことを意味します。それ以降のコマンドがマークをセットできます。
マークはkill-region
やindent-rigidly
のような多くのコマンドにたいしてテキスト範囲をバインドするための位置を指定します。これらのコマンドは、通常はポイントとマークの間のリージョン(region)と呼ばれるテキストに作用します。リージョンを操作するコマンドを記述する場合にはマークを直接調べず、かわりに‘r’指定とともにinteractive
を使用してください。このようにすればインタラクティブな呼び出しではコマンドの引数としてポイントとマークの値が提供され、かつ他のLispプログラムは引数を明示的に指定できます。interactive
にたいするコード文字を参照してください。
いくつかのコマンドは副作用(side-effect)としてマークをセットします。コマンドはユーザーがそれを使用する可能性がある場合のみマークをセットするべきであって、決してコマンドの内部的な目的にたいして使用してはなりません。たとえばreplace-regexp
コマンドは何らかの置換を行う前にマークにポイントの値をセットしますが、その理由はこれによりユーザーが置換を終えた後に簡単にその位置に戻ることが可能になるからです。
一度バッファー内にマークが存在すれば、その存在は通常は決して消えることはありません。しかしTransient
Markモードが有効だとマークが非アクティブ(inactive)になることはあります。バッファーローカル変数mark-active
が非nil
なら、それはマークがアクティブであることを意味します。コマンドはマークを直接非アクティブにするために関数deactivate-mark
を呼び出すことができ、変数deactivate-mark
を非nil
値にセットすることにより、エディターコマンドループ(editor
command loop)にリターン時にマークの非アクティブ化を要求できます。
Transient Markモードが有効だと、通常ならポイント近傍に適用される特定の編集コマンドはマークがアクティブなときはかわりにリージョンに適用されます。これがTransient Markモードを使用する主な動機です(他にもマークアクティブ時にはリージョンのハイライトが有効になるという理由もある。Emacsのディスプレー表示を参照)。
マークに加えてバッファーはそれぞれマークリング(mark
ring)をもっています。これは以前のマーク値を含むマーカーのリストです。編集コマンドがマークを変更する際には、それらのコマンドは通常はマークの旧値をマークリングに保存するべきです。変数mark-ring-max
はマークリング内のエントリー最大数を指定します。リストがこの長さに達すると最後の要素を削除して新たな要素が追加されます。
これとは別にグローバルマークリング(global mark ring)がありますが、それは少数の特定のユーザーレベルコマンドでのみ使用されて、Lispプログラムとは関連しないのでここでは説明しません。
この関数はカレントバッファーのマーク位置を整数でリターンする。そのバッファー内でそれまでマークがセットされていなければnil
をリターンする。
Transient
Markモードが有効、かつmark-even-if-inactive
がnil
の場合、マークが非アクティブならmark
はエラーをシグナルする。しかし、forceが非nil
なら、mark
はマークの非アクティブ性を無視して、何にせよマーク位置(かnil
)をリターンする。
この関数はカレントバッファーのマークを表すマーカーをリターンする。これはコピーではなく内部的に使用されるマーカー。したがってこのマーカー位置にたいする変更は、そのバッファーのマークに直接影響する。それが望む効果でなければこれを行ってはならない。
(setq m (mark-marker)) ⇒ #<marker at 3420 in markers.texi>
(set-marker m 100) ⇒ #<marker at 100 in markers.texi>
(mark-marker) ⇒ #<marker at 100 in markers.texi>
他のマーカー同じように、このマーカーを任意のバッファー位置にセットできる。このマーカーにたいして、これがマークする以外のバッファーを指すようにすると、完全に整合性があるものの、いささか奇妙な結果を得ることになるだろう。わたしたちはこれを行わないことを推奨する!
この関数はマークをpositionにセットして、そのマークをアクティブにする。マークの旧値はマークリングにpushされない。
注意:
マークが移動したことをユーザーに確認させて、かつ前のマーク位置が失われることを望む場合のみこの関数を使用すること。通常はマークセット時に古いマークをmark-ring
にpushすること。この理由により、ほとんどのアプリケーションはset-mark
ではなく、push-mark
とpop-mark
を使用するべきである。
Emacs Lisp初心者のプログラマーは誤った用途にマークの使用を試みがちである。ユーザーの利便のために位置を保存するのがマークである。編集コマンドはマーク変更がコマンドのユーザーレベル機能の一部でない限りマークを変更しないこと(そのような場合にはその効果をドキュメントするべきである)。Lispプログラムの内部的な使用のために位置を記憶するためには、マークをLisp変数に格納すること。たとえば:
(let ((beg (point))) (forward-line 1) (delete-region beg (point)))
この関数はカレントバッファーのマークをpositionにセットして、前のマークをmark-ring
にpushする。positionがnil
ならポイントの値を使用する。
関数push-mark
は通常はマークをアクティブにしない。アクティブにする場合には引数activateにt
を指定する。
nomsgがnil
ならメッセージ‘Mark set’が表示される。
この関数はmark-ring
のトップ要素をpopして、そのマークをバッファーの実際のマークにする。これはバッファー内のポイントを移動せず、mark-ring
が空なら何も行わない。これはマークを非アクティブ化する。
この変数が非nil
ならTransient Markモードを有効にする。Transient
Markモードでは、すべてのバッファー変更プリミティブがdeactivate-mark
をセットする。結果としてバッファーを変更するほとんどのコマンドもマークを非アクティブにする。
Transient
Markモードが有効かつマークがアクティブなら、通常はポイント近傍に適用されるコマンドの多くは、かわりにリージョンに適用される。そのようなコマンド、リージョンを処理すべきかどうかをテストするために、関数use-region-p
を使用すること。リージョンを参照のこと。
Lispプログラムは一時的にTransient
Markモードを有効にするために、transient-mark-mode
をnil
でもt
でもない値にセットできる。値がlambda
なら、通常ならマークを非アクティブ化するバッファー変更ような操作の後に、Transient
Markモードを自動的にオフに切り替える。値が(only . oldval)
なら後続のコマンドがポイントを移動かつシフト変換(shift-translationを参照)されていない場合、あるいは通常はマークを非アクティブにするその他の操作の場合にに、transient-mark-mode
に値oldvalをセットする。
これが非nil
なLispプログラムおよびEmacsユーザーは、たとえ非アクティブでもマークを使用できる。このオプションはTransient
Markモードの動作に影響を及ぼす。このオプションが非nil
ならマークの非アクティブ化によりリージョンのハイライトはオフに切り替えられるが、マークを使用するコマンドは、あたかもマークがアクティブであるかのように振る舞う。
エディターコマンドがこの変数を非nil
にセットすると、エディターコマンドループはコマンドのリターン後に、(Transient
Markモードが有効なら)マークを非アクティブにする。バッファーを変更するすべてのプリミティブは、コマンド終了時にマークを非アクティブにするためにdeactivate-mark
をセットする。この変数はセットすらことによりバッファーローカルになる。
コマンド終了時にマークを非アクティブにすることなくバッファーを変更するLispコードを記述するためには、変更を行うコードの周辺でdeactivate-mark
をnil
にバインドすること。たとえば:
(let (deactivate-mark) (insert " "))
Transient
Markモードが有効、またはforceが非nil
なら、この関数はマークを非アクティブにしてノーマルフックdeactivate-mark-hook
を実行して、それ以外は何も行わない。
この変数が非nil
ならマークはアクティブ。この変数はそれぞれのバッファーにたいして常にローカル。通常はポイント近傍を操作するコマンドが、かわりにリージョンを操作すべきかどうかを判断するためにこの変数の値を使用してはならない。その目的にたいしては関数use-region-p
を使用すること(リージョンを参照)。
これらのノーマルフックはマークがアクティブや非アクティブになった際に順次実行される。マークがアクティブかつリージョンが変更された可能性があるなら、コマンドループの最後にフックactivate-mark-hook
も実行される。
この関数はポイント移動コマンドのシフト選択(shift-selection)の動作を実装する。Shift Selection in The GNU Emacs
Manualを参照のこと。これはinteractive
指定に文字‘^’を含むコマンドの呼び出し時は常に、そのコマンド自身を実行する前にEmacsコマンドループにより自動的に呼び出される(^を参照)。
shift-select-mode
が非nil
、かつカレントコマンドがシフト変換(shift-translationを参照)を通じて呼び出された場合には、この関数はマークをセットして一時的にリージョンをアクティブにする(すでにこの方法によりリージョンが一時的にアクティブにされている場合を除く)。それ以外ではリージョンが一時的にアクティブにされていればマークを非アクティブにして、変数transient-mark-mode
に前の値をリストアする。
このバッファーローカル変数の値は、もっとも最近のものが先頭となるような、以前に保存されたカレントバッファーのマークのリスト。
mark-ring ⇒ (#<marker at 11050 in markers.texi> #<marker at 10832 in markers.texi> …)
この変数の値はmark-ring
の最大サイズ。これより多くのマークがmark-ring
にpushされると、push-mark
新たなマーク追加時には古いマークを破棄する。
Delete Selectionモード(Delete Selection in The GNU
Emacs
Manualを参照)が有効な際には、アクティブリージョン(いわゆる“選択”)を操作するコマンドは若干異なる振る舞いをします。これはpre-command-hook
に関数delete-selection-pre-hook
を追加することにより機能します(コマンドループの概要を参照)。この関数はそのコマンドにたいして適切なように選択を削除するためにdelete-selection-helper
を呼び出します。コマンドをDelete
Selectionモードに適応させたければ、その関数シンボルのdelete-selection
プロパティにputしてください(シンボルのプロパティへのアクセスを参照)。シンボルにこのプロパティをもたないコマンドは選択を削除しません。そのコマンドに期待される挙動を調整するために、このプロパティはいくつかの値のいずれかをもつことができます。詳細はdelete-selection-pre-hook
とdelete-selection-helper
のドキュメント文字列を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ポイントとマークの間のテキストは、リージョン(region)という名で知られています。さまざまな関数がポイントとマークで区切られたテキストを操作しますが、ここではリージョンそのものに特に関連する関数だけを説明します。
以下の2つの関数はマークが何処も指していなければエラーをシグナルします。Transient
Markモードが有効、かつmark-even-if-inactive
がnil
な、マークが非アクティブな場合にエラーをシグナルします。
この関数はリージョンの先頭位置を、(整数として)リターンする。これはポイントかマークのいずれか小さいほうの位置。
この関数はリージョンの終端位置を、(整数として)リターンする。これはポイントかマークのいずれか大きいほうの位置。
リージョンにたいして操作を行うようにデザインされたコマンドがリージョンの先頭と終端を探すためには、region-beginning
やregion-end
を使用するかわりに、通常は‘r’指定とともにinteractive
を使用するべきです。これにより他のLispプログラムが引数として明示的にリージョンの境界を指定できるようになります。interactive
にたいするコード文字を参照してください。。
この関数はTransient
Markモードが有効でマークがアクティブであり、かつバッファー内に有効なリージョンがあればt
をリターンする。この関数はマークアクティブ時にはポイント近傍のテキストのかわりにリージョンを操作するコマンドにより使用されることを意図している。
リージョンはそれが非0のサイズをもつか、あるいはユーザーオプションuse-empty-active-region
が非nil
(デフォルトはnil
)なら有効。関数region-active-p
はuse-region-p
と同様だが、すべてのリージョンを有効とみなす。リージョンが空ならポイントにたいして操作を行うほうが適切な場合が多いために、ほとんどの場合はregion-active-p
を使用するべきではない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このチャプターではバッファー内のテキストを扱う関数を説明します。ほとんどはカレントバッファー内のテキストにたいして検査、挿入、削除を行ってポイント位置やポイントに隣接するテキストを操作することが多々あります。その多くはインタラクティブ(interactive: 対話的)です。テキストを変更するすべての関数は、その変更にたいするundo(アンドゥ、取り消し)を提供します(アンドゥを参照)。
テキストに関連する関数の多くが、startとendという名前の引数として渡された2つのバッファー位置により定義されるテキストのリージョンを操作します。これらの引数はマーカー(マーカーを参照)か数値的な文字位置(ポジションを参照)のいずれかであるべきです。これらの引数の順序は関係ありません。startがリージョンの終端でendがリージョンの先頭であっても問題はありません。たとえば(delete-region
1 10)
と(delete-region 10
1)
は等価です。startとendのいずれかがバッファーのアクセス可能範囲の外部ならargs-out-of-range
エラーがシグナルされます。インタラクティブな呼び出しでは、これらの引数にポイントとマークが使用されます。
このチャプターを通じて、“テキスト(text)”とは(関係あるときは)そのプロパティも含めたバッファー内の文字を意味します。ポイントは常に2つの文字の間にあり、カーソルはポイントの後の文字上に表示されることを覚えておいてください。
31.1 ポイント周辺のテキストを調べる | ポイント付近のテキストを調べる。 | |
31.2 バッファーのコンテンツを調べる | 一般的な方法によってテキストを調べる。 | |
31.3 テキストの比較 | バッファーの部分文字列を比較する。 | |
31.4 テキストの挿入 | バッファーへの新たなテキストの追加。 | |
31.5 ユーザーレベルの挿入コマンド | テキスト挿入のためのユーザーレベルコマンド。 | |
31.6 テキストの削除 | バッファーからテキストを削除する。 | |
31.7 ユーザーレベルの削除コマンド | テキスト削除のためのユーザーレベルコマンド。 | |
31.8 killリング | テキスト削除時にユーザーのためにそれを保存する場所。 | |
31.9 アンドゥ | バッファーのテキストにたいする変更の取り消し。 | |
31.10 アンドゥリストの保守 | undo情報の有効と無効。情報をどれだけ保持するか制御する方法。 | |
31.11 fill | 明示的にフィルを行う関数。 | |
31.12 fillのマージン | フィルコマンドにたいしてマージンを指定する方法。 | |
31.13 Adaptive Fillモード | コンテキストからフィルプレフィクスを選択するAdaptive Fillモード。 | |
31.14 オートfill | 行ブレークにたいするauto-fillの実装方法。 | |
31.15 テキストのソート | バッファーの一部をソートする関数。 | |
31.16 列を数える | 水平位置の計算とその使用方法。 | |
31.17 インデント | インデントの挿入や調整のための関数。 | |
31.18 大文字小文字の変更 | バッファーの一部にたいする大文字小文字変換。 | |
31.19 テキストのプロパティ | テキスト文字にたいするLispプロパティリストの追加。 | |
31.20 文字コードの置き換え | 与ええられた文字の出現箇所を置換する。 | |
31.21 レジスター | レジスターの実装方法。レジスターに格納されたテキストや位置にアクセスする。 | |
31.22 テキストの交換 | バッファーの2つの部分を交換する。 | |
31.23 圧縮されたデータの処理 | 圧縮データの扱い。 | |
31.24 Base 64エンコーディング | Base64エンコーディングとの変換。 | |
31.25 チェックサムとハッシュ | 暗号ハッシュの計算。 | |
31.26 HTMLとXMLの解析 | HTMLおよびXMLの解析。 | |
31.27 グループのアトミックな変更 | 複数バッファーへの変更をアトミックにインストールする。 | |
31.28 フックの変更 | テキスト変更時に実行する関数の指定。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ポイント付近にある文字を調べるための関数が数多く提供されています。簡単な関数のいくつかはここで説明します。正規表現の検索のlooking-at
も参照してください。
以下の4つの関数でのバッファーの“先頭(beginning)”と“終端(end)”はそれぞれ、アクセス可能範囲の先頭と終端を意味します。
この関数はカレントバッファーの位置position
(つまり直後)の文字をリターンする。positionがこの目的にたいする範囲の外にある場合、すなわちバッファーの先頭より前、またはバッファーの終端以降にあるなら値はnil
。positionのデフォルトはポイント。
以下の例ではバッファーの最初の文字が‘@’であると仮定する:
(string (char-after 1)) ⇒ "@"
この関数はカレントバッファーの位置positionの直前の文字をリターンする。positionがこの目的にたいする範囲の外にある場合、すなわちバッファーの先頭より前、またはバッファーの終端より後にあるなら値はnil
。positionのデフォルトはポイント。
この関数はカレントバッファーのポイントの後にある文字をリターンする。これは(char-after
(point))
と同様。ただしポイントがバッファー終端にある場合には、following-char
は0をリターンする。
ポイントが常に2つの文字の間にあり、カーソルは通常はポイント後の文字上に表示されることを思い出してほしい。したがってfollowing-char
がリターンする文字はカーソル上の文字となる。
以下の例では‘a’と‘c’の間にポイントがある。
---------- Buffer: foo ---------- Gentlemen may cry ``Pea∗ce! Peace!,'' but there is no peace. ---------- Buffer: foo ----------
(string (preceding-char)) ⇒ "a" (string (following-char)) ⇒ "c"
この関数はカレントバッファーのポイントの前の文字をリターンする。上記following-char
の下の例を参照のこと。ポイントがバッファー先頭にあれば、preceding-char
は0をリターンする。
この関数はポイントがバッファー先頭にあればt
をリターンする。ナローイングが効力をもつなら、これはテキストのアクセス可能範囲の先頭を意味する。ポイントのpoint-min
も参照のこと。
この関数はポイントがバッファー終端にあればt
をリターンする。ナローイングが効力をもつなら、これはテキストのアクセス可能範囲の終端を意味する。ポイントのpoint-max
も参照のこと。
この関数はポイントが行の先頭にあればt
をリターンする。テキスト行単位の移動を参照のこと。バッファー(またはアクセス可能範囲)の先頭は、常に行の先頭とみなされる。
この関数はポイントが行の終端にあればt
をリターンする。テキスト行単位の移動を参照のこと。バッファー(またはアクセス可能範囲)の終端は常に行の先頭とみなされる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではLispプログラムがバッファー内の任意の範囲にあるテキストを文字列に変換するための関数を説明します。
この関数はカレントバッファー内の位置startとendで定義されるリージョンのテキストのコピーを含む文字列をリターンする。引数がバッファーのアクセス可能範囲内の位置でなければ、buffer-substring
はargs-out-of-range
エラーをリターンする。
以下の例ではFont-Lockモードが有効でないものとする:
---------- 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\n"
コピーされるテキストが何らかのテキストプロパティをもっていたら、それらのプロパティが属する文字とともに文字列にコピーされる。しかしバッファー内のオーバーレイ(オーバーレイを参照)、およびそれらのプロパティは無視されるためコピーされない。
たとえばFont-Lockモードが有効なら以下のような結果を得るだろう:
(buffer-substring 1 10) ⇒ #("This is t" 0 1 (fontified t) 1 9 (fontified t))
これはbuffer-substring
と同様だが、テキストプロパティはコピーせずに文字自体だけをコピーする点が異なる。テキストのプロパティを参照のこと。
この関数はカレントバッファーのアクセス可能範囲全体のコンテンツを文字列としてリターンする。
異なる場所からのコピー時に双方向テキストの再配置によって結果の文字列の視覚的外見が変更されないように保証する必要があるなら、buffer-substring-with-bidi-context
関数を使用すること(buffer-substring-with-bidi-contextを参照)。
この関数は変数filter-buffer-substring-function
により指定された関数を使用して、startとendの間のバッファーテキストをフィルターしてその結果をリターンする。
デフォルトのフィルター関数は時代遅れとなったラッパーフックfilter-buffer-substring-functions
、および同様に時代遅れとなった変数buffer-substring-filters
を参照する。これらがいずれもnil
ならバッファーから未変更のテキスト、すなわちbuffer-substring
がリターンするであろうテキストをリターンする。
deleteが非nil
なら、この関数はdelete-and-extract-region
と同じように、コピー後にstartとendの間のテキストを削除する。
Lispコードはkillリング、Xクリップボード、レジスターのようなユーザーがアクセス可能なデータ構造内にコピーする際にはbuffer-substring
、buffer-substring-no-properties
、delete-and-extract-region
のかわりにこの関数を使用すること。メジャーモードとマイナーモードはバッファー外部にコピーするテキストを変更するためにfilter-buffer-substring-function
を変更することができる。
この変数の値は実際の処理を行うためにfilter-buffer-substring
が呼び出す関数。その関数はfilter-buffer-substring
と同じように3つの引数を受けとり、それらはfilter-buffer-substring
にドキュメントされているように扱うこと。関数はフィルターされたテキストをリターン(およびオプションでソーステキストを削除)すること。
以下の2つの変数はfilter-buffer-substring-function
により時代遅れになりましたが、後方互換のために依然としてサポートされます。
これは時代遅れとなったラッパーフックであり、このフックのメンバーはfun、start、end、deleteの4つの引数を受け取る関数であること。funは3つの引数(start、end、delete)を受け取り、文字列をリターンする関数。いずれも引数start、end、deleteはfilter-buffer-substring
のときと同様の意味をもつ。
1つ目のフック関数はfilter-buffer-substring
のデフォルトの処理と同じくstartとendの間の(任意のbuffer-substring-filters
により処理された)バッファー部分文字列をリターン、オプションでバッファーから元テキストを削除する関数であり、それがfunに渡される。ほとんどの場合にはフック関数はfunを1回だけ呼び出してから、その結果にたいして自身の処理を行う。次のフック関数はこれと等しいfunを受け取って、それが順次繰り返されていく。実際のリターン値はすべてのフック関数が順次処理した結果。
時代遅れとなったこの変数の値は、文字列を唯一の引数ちして別の文字列をリターンする関数のリストであること。デフォルトのfilter-buffer-substring
関数は、バッファー部分文字列をこのリストの1つ目の関数に渡して、そのリターン値を次の関数に渡して、これがそれぞれの関数にたいして順次繰り返される。最後の関数のリターン値はfilter-buffer-substring-functions
に渡される。
この関数はポイント位置またはその付近のシンボル(または単語)を文字列としてリターンする。リターン値にテキストプロパティは含まれない。
オプション引数really-wordが非nil
なら単語、それ以外はシンボル(単語文字とシンボル構成文字の両方を含む)を探す。
オプション引数strictが非nil
のならポイントは単語(またはシンボル)の内部にあるか隣接しなければならない。そこに単語(またはシンボル)がなければ、この関数はnil
をリターンする。strictがnil
ならポイントと同一行にある近接する単語(またはシンボル)を許容する。
ポイントに隣接または周辺にあるthingを文字列としてリターンする。
引数thingは構文エンティティの種別を指定するシンボルである。可能なシンボルとしてはsymbol
、list
、sexp
、defun
、filename
、url
、word
、sentence
、whitespace
、line
、page
、および他が含まれる。
オプション引数no-propertiesは非nil
なら、この関数はリターン値からテキストプロパティを取り除く。
---------- 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
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数により最初にバッファー内のテキストを文字列内にコピーすることなく、バッファー内のテキスト断片を比較することが可能になります。
この関数により1つのバッファー、または2つの異なるバッファーの2つの部分文字列(substrings)を比較できる。最初の3つの引数はバッファーとそのバッファー内の2つの位置を与えることにより、1つの部分文字列を指定する。最後の3つの引数は、同様の方法によりもう一方の部分文字列を指定する。buffer1とbuffer2のいずれか、または両方にたいしてカレントバッファーを意味するnil
を使用できる。
1つ目の部分文字列が2つ目の部分文字列より小なら負、大なら正、等しければ値は0となる。結果の絶対値は部分文字列内で最初に異なる文字のインデックスに1を和した値。
case-fold-search
が非nil
なら、この関数はcase(大文字小文字)の違いを無視する。テキストプロパティは常に無視される。
カレントバッファー内にテキスト‘foobarbar haha!rara!’がある。そしてこの例では2つの部分文字列が‘rbar ’と‘rara!’だとする。1つ目の文字列の2つ目の文字が大きいので値は2となる。
(compare-buffer-substrings nil 6 11 nil 16 21) ⇒ 2
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
挿入(insertion)とはバッファーへの新たなテキストの追加を意味します。テキストはポイント位置、すなわちポイント前の文字とポイント後の文字の間に追加されます。挿入関数は挿入されたテキストの後にポイントを残しますが、前にポイントを残す関数もいくつかあります。前者の挿入をポイント後挿入(after point)、後者をポイント前挿入(before point)と呼びます。
挿入により挿入位置の後にあったマーカーは、テキストを取り囲むように移動されます(マーカーを参照)。マーカーが挿入箇所をさしている際には、挿入によるマーカーの再配置の有無はそのマーカーの挿入タイプに依存します(Marker 挿入タイプを参照)。insert-before-markers
のような特定のスペシャル関数は、マーカーの挿入タイプとは関係なく挿入されたテキストの後にそのようなすべてのマーカーを再配置します。
カレントバッファーが読み取り専用(読み取り専用のバッファーを参照)、または読み取り専用テキスト(特殊な意味をもつプロパティを参照)を挿入しようとすると、挿入関数はエラーをシグナルします。
以下の関数は文字列やバッファーからプロパティとともにテキスト文字をコピーします。挿入される文字はコピー元の文字と完全に同一のプロパティをもちます。それとは対照的に文字列やバッファーの一部ではない個別の引数として指定された文字は、隣接するテキストからテキストプロパティを継承します。
テキストが文字列かバッファー由来なら、マルチバイトバッファーに挿入するために挿入関数はユニバイトからマルチバイトへの変換、およびその逆も行います。しかしたとえカレントバッファーがマルチバイトバッファーであったとしても、コード128から255までのユニバイトはマルチバイトに変換しません。テキスト表現の変換を参照してください。
この関数は文字列および/または1つ以上の文字argsをカレントバッファーのポイント位置に挿入して、ポイントを前方に移動する。言い換えるとポイントの前にテキストを挿入する。すべてのargsが文字列が文字列と文字のいずれでもなければエラーをシグナルする。値はnil
。
この関数は文字列および/または1つ以上の文字argsをカレントバッファーのポイント位置に挿入して、ポイントを前方に移動する。すべてのargsが文字列が文字列と文字のいずれでもなければエラーをシグナルする。値はnil
。
この関数は他の挿入関数と異なり、挿入されたテキストの後を指すように、まずマーカーが挿入位置を指すよう再配置する。挿入位置からオーバーレイが開始される場合には、挿入されたテキストはそのオーバーレイの外側に出される。空でないオーバーレイが挿入位置で終わる場合には、挿入されたテキストはそのオーバーレイの内側に入れられる。
このコマンドはカレントバッファーのポイントの前に、characterのインスタンスをcount個挿入する。引数countは整数、characterは文字でなければならない。
インタラクティブに呼び出された際には、このコマンドはcharacterにたいしてコードポイントかUnicode名による入力を求める。Inserting Text in The GNU Emacs Manualを参照のこと。
この関数はたとえカレントバッファーがマルチバイトバッファーであっても、コード128から255のユニバイト文字をマルチバイト文字に変換しない。テキスト表現の変換を参照のこと。
inheritが非nil
なら、挿入された文字は挿入位置前後の2文字からステッキーテキストプロパティ(sticky text
properties)を継承する。テキストプロパティの粘着性を参照のこと。
この関数はカレントバッファーのポイント前に、バッファー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 ----------
これはinsert-buffer-substring
と似ているが、テキストプロパティをコピーしない点が異なる。
テキスト挿入に加えて、隣接するテキストからテキストプロパティを継承する他の関数についてはテキストプロパティの粘着性を参照のこと。インデント関数により挿入された空白文字もテキストプロパティを継承する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではテキスト挿入のための高レベルコマンド、ユーザーによる使用を意図しているがLispプログラムでも有用なコマンドについて説明します。
このコマンドはfrom-buffer-or-name
(存在しなければならない)のアクセス可能範囲全体をカレントバッファーのポイントの後に挿入する。マークは挿入されたテキストの後に残される。値はnil
。
このコマンドはタイプされた最後の文字を挿入する。これをポイント前でcount回繰り返してnil
をリターンする。ほとんどのプリント文字はこのコマンドにバインドされる。通常の使用ではself-insert-command
はEmacsでもっとも頻繁に呼び出される関数だが、Lispプログラムではそれをキーマップにインストールする場合を除いて使用されるのは稀。
インタラクティブな呼び出しではcountは数プレフィクス引数。
自己挿入では入力文字はtranslation-table-for-input
を通じて変換される。文字の変換を参照のこと。
これは、入力文字がテーブルauto-fill-chars
内にあり、auto-fill-function
が非nil
なら常にそれを呼び出す(オートfillを参照)。
このコマンドはAbbrevモードが有効で、かつ入力文字が単語構成構文をもたなければabbrev展開を行う(abbrevとabbrev展開と構文クラスのテーブルを参照)。さらに入力文字が閉カッコ構文(close parenthesis
syntax)をもつ場合にはblink-paren-function
を呼び出す責任もある(カッコの点滅を参照)。
このコマンドは最後にフックpost-self-insert-hook
を実行する。たとえばタイプされたテキストにしたがい自動インデントするためにこれを使用できる。
self-insert-command
の標準的な定義にたいして、独自の定義による置き換えを試みてはならない。エディターコマンドループはこのコマンドを特別に扱うからだ。
このコマンドはカレントバッファーのポイントの前に改行を挿入する。number-of-newlinesが与えられたら、その個数の改行文字が挿入される。
この関数はカレント列数がfill-column
より大、かつnumber-of-newlinesがnil
ならauto-fill-function
を呼び出す。auto-fill-function
が通常行うのは改行の挿入であり、最終的な結果としてはポイント位置と、その行のより前方の位置という2つの異なる箇所に改行を挿入する。number-of-newlinesが非nil
ならnewline
はauto-fillを行わない。
このコマンドは左マージンが0でなければ、左マージンにインデントする。fillのマージンを参照のこと。
リターン値はnil
。インタラクティブな呼び出しではcountは数プレフィクス引数。
この変数はoverwriteモードが効力をもつかどうかを制御する。値はoverwrite-mode-textual
、overwrite-mode-binary
、またはnil
。overwrite-mode-textual
はテキスト的なoverwriteモード(改行とタブを特別に扱う)、overwrite-mode-binary
はバイナリーoverwriteモード(改行とタブを普通の文字と同様に扱う)を指定する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
削除とはバッファー内のテキストの一部をkillリングに保存せずに取り除くことを意味します(killリングを参照)。削除されたテキストをyankすることはできませんが、undoメカニズム(アンドゥを参照)を使用すれば再挿入が可能です。特別なケースにおいてはkillリングにテキストの保存を行う削除関数がいくつかあります。
削除関数はすべてカレントバッファーにたいして処理を行います。
この関数はカレントバッファーのテキスト全体(アクセス可能範囲だけではない)を削除してバッファーが読み取り専用ならbuffer-read-only
、バッファー内の一部テキストが読み取り専用ならtext-read-only
をシグナルする。それ以外では確認なしでテキストを削除する。リターン値はnil
。
バッファーからの大量テキストの削除では、バッファーが大幅に縮小されたという理由により、通常はさらなる自動保存が抑制される。しかしerase-buffer
は将来のテキストが以前のテキストと関連があるのは稀であり、以前のテキストのサイズと比較されるべきではないというアイデアにもとづいてこれを行わない。
このコマンドはカレントバッファー内の位置startからendまでの間のテキストを削除してnil
をリターンする。削除されるリージョン内にポイントがあれば、リージョン削除後のポイントの値はstart。それ以外の場合は、マーカーが行うようにポイントはテキストを取り囲むように再配置される。
この関数はカレントバッファー内の位置startからendまでの間のテキストを削除して、削除されたテキストを含む文字列をリターンする。
削除されるリージョン内にポイントがあれば、リージョン削除後のポイントの値はstart。それ以外ならマーカーが行うようにポイントはテキストを取り囲むように再配置される。
このコマンドはポイント直後のcount文字、countが負なら直前のcount文字を削除する。killpが非nil
なら削除した文字をkillリングに保存する。
インタラクティブな呼び出しでは、countは数プレフィクス引数、killpは未処理プレフィクス引数(unprocessed prefix argument)。すなわちプレフィクス引数が与えられたらそのテキストはkillリングに保存され、与えられなければ1文字が削除されて、それはkillリングに保存されない。
リターン値は常にnil
。
このコマンドはポイント直前のcount文字、countが負なら直後のcount文字を削除する。killpが非nil
なら、削除した文字をkillリングに保存する。
インタラクティブな呼び出しでは、countは数プレフィクス引数、killpは未処理プレフィクス引数(unprocessed prefix argument)。すなわちプレフィクス引数が与えられたらそのテキストはkillリングに保存され、与えられなければ1文字が削除されて、それはkillリングに保存されない。
リターン値は常にnil
。
このコマンドはタブをスペースに変換しながら、後方にcount文字を削除する。次に削除する文字がタブなら、まず適正な位置を保つような数のスペースに変換してから、それらのうちのスペース1つをタブのかわりに削除する。killpが非nil
なら、このコマンドは削除した文字をkillリングに保存する。
タブからスペースへの変換はcountが正の場合のみ発生する。負の場合はポイント後の正確に-count文字が削除される。
インタラクティブな呼び出しでは、countは数プレフィクス引数、killpは未処理プレフィクス引数(unprocessed prefix argument)。すなわちプレフィクス引数が与えられたらそのテキストはkillリングに保存され、与えられなければ1文字が削除されて、それはkillリングに保存されない。
リターン値は常にnil
。
このオプションはbackward-delete-char-untabify
が空白文字を扱う方法を指定する。可能な値にはuntabify
(タブを個数分のスペースに変換してスペースを1つ削除。これがデフォルト)、hungry
(1コマンドでポイント前のタブとスペースすべてを削除する)、all
(ポイント前のタブとスペース、および改行すべてを削除する)、nil
(空白文字にたいして特に何もしない)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは、主にユーザーにたいして有用ですがLispプログラムでも有用なテキストを削除するための高レベルのコマンドを説明します。
この関数はポイント近辺のすべてのスペースとタブを削除する。リターン値はnil
。
backward-onlyが非nil
なら、この関数はポイント前のスペースとタブを削除するがポイント後のスペースとタブは削除しない。
以下の例では、各行ごとに2番目と3番目の間にポイントを置いて、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 ----------
この関数はポイントのある行をその前の行に結合(join)する。結合においてはすべての空白文字を削除、特定のケースにおいてはそれらを1つのスペースに置き換える。join-following-pが非nil
なら、delete-indentation
はかわりに後続行と結合を行う。この関数はnil
をリターンする。
fillプレフィクスがあり、結合される2つ目の行もそのプレフィクスで始まる場合には、行の結合前にdelete-indentation
はそのfillプレフィクスを削除する。fillのマージンを参照のこと。
以下の例では‘events’で始まる行にポイントがあり、前の行の末尾に1つ以上のスペースが存在しても違いは生じない。
---------- 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
の責任である。
この関数はポイントを取り囲むすべての水平スペースを、コンテキストに応じて1つのスペースまたはスペースなしに置き換える。リターン値はnil
。
行の先頭や末尾において、スペースの適正な数は0。閉カッコ構文(close parenthesis syntax)の前の文字、開カッコの後の文字、式プレフィクス構文(expression-prefix syntax)においても、スペースの適正な数は0。それ以外ではスペースの適正な数は1。構文クラスのテーブルを参照のこと。
以下の例では最初に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 ----------
このコマンドはポイントを取り囲むすべてのスペースを1つのスペース、nが指定された場合はn個のスペースで置き換える。リターン値はnil
。
この関数はポイントを取り囲む空行を削除する。ポイントが前後に1行以上の空行がある空の行にある場合には、1行を除いてそれらすべてを削除する。ポイントが孤立した空行にあればその行を削除する。ポイントが空でない行にあれば、その直後にあるすべての空白を削除する。
空行とはタブまたはスペースのみを含む行として定義される。
delete-blank-lines
はnil
をリターンする。
startとendで定義されるリージョン内から末尾の空白文字を削除する。
このコマンドはリージョン内の各行の最後の非空白文字後にある空白文字を削除する。
このコマンドがバッファー全体(マークが非アクティブな状態で呼び出された場合やLispからendとnil
で呼び出された場合)にたいして動作する場合には、変数delete-trailing-lines
が非nil
ならバッファーの終端行の末尾の行も削除する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
kill関数(kill functions)は削除関数のようにテキストを削除しますが、ユーザーがyankにより再挿入できるようにそれらを保存する点が異なります。これらの関数のほとんどは‘kill-’という名前をもちます。対照的に名前が‘delete-’で始まる関数は、(たとえ削除をundoできるとしても)通常はyank用にテキストを保存しません。それらは削除(deletion)関数です。
ほとんどのkillコマンドは主にインタラクティブな使用を意図しており、ここでは説明しません。ここで説明するのは、そのようなコマンドの記述に使用されるために提供される関数です。テキストをkillするために、これらの関数を使用できます。Lisp関数の内部的な目的のためにテキストの削除を要するときは、killリング内のコンテンツに影響を与えないように通常は削除関数を使用するべきでしょう。テキストの削除を参照してください。
killされたテキストは後のyank用にkillリング(kill
ring)内に保存されます。これは直前のkillだけでなく直近のkillのいくつかを保持するリストです。yankがそれをサイクル順に要素をもつリストとして扱うので、これを“リング(ring)”と称しています。このリストは変数kill-ring
に保持されており、リスト用の通常関数で操作可能です。このセクションで説明する、これをリングとして扱うために特化された関数も存在します。
特にkillされた実体が破壊されてしまわないような操作を参照するという理由から、“kill”という単語の使用が不適切だと考える人もいます。これは通常の生活において死は永遠であり、killされた実体は生活に戻ることはないことと対照的です。したがって他の比喩表現も提案されてきました。たとえば、“cutリング(cut ring)”という用語は、コンピューター誕生前に原稿を再配置するためにハサミで切り取って貼り付けていたような人に意味があるでしょう。しかし今となってはこの用語を変更するのは困難です。
31.8.1 killリングの概念 | killリング内のテキストがどのように見えるか。 | |
31.8.2 killリングのための関数 | テキストをkillする関数。 | |
31.8.3 yank | yankが行われる方法。 | |
31.8.4 yankのための関数 | killリングにアクセスするコマンド。 | |
31.8.5 低レベルのkillリング | killリングアクセス用の関数と変数。 | |
31.8.6 killリングの内部 | killリングのデータを保持する変数。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
killリングはリスト内でもっとも最近にkillされたテキストが先頭になるように、killされたテキストを記録します。たとえば短いkillリングは以下のようになるでしょう:
("some text" "a different piece of text" "even older text")
このリストのエントリー長がkill-ring-max
に達すると、新たなエントリー追加により最後のエントリーが自動的に削除されます。
killコマンドが他のコマンドと混ざり合っているときは、各killコマンドはkillリング内に新たなエントリーを作成します。連続する複数のkillコマンドは単一のkillリングエントリーを構成します。これは1つの単位としてyankされます。2つ目以降の連続するkillコマンドは、最初のkillにより作成されたエントリーにテキストを追加します。
yankにたいしては、killリング内のただ1つのエントリーが、そのリングの先頭のエントリーとなります。いくつかのyankコマンドは、異なる要素を先頭に指定することにより、リングを回転(rotate)させます。しかしこの仮想的回転はリスト自身を変更しません。もっとも最近のエントリーが、常にリスト内の最初に配置されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
kill-region
はテキストkill用の通常サブルーチンです。この関数を呼び出すすべてのコマンドはkillコマンドです(そして恐らくは名前に‘kill’が含まれる)。kill-region
は新たにkillされたテキストをkillリング内の最初の要素内に置くか、それをもっとも最近の要素に追加します。これは前のコマンドがkillコマンドか否かを、(last-command
を使用して)自動的に判別して、もしkillコマンドならkillされたテキストをもっとも最近のエントリーに追加します。
以下で説明するコマンドはkillされるテキストがkillリングに保存される前に、それらをフィルターできます。これらの関数は、このフィルタリングを行うためにfilter-buffer-substring
を呼び出します(バッファーのコンテンツを調べるを参照)。デフォルトではこれらはフィルタリングを行いませんが、バッファーにあったときと異なるようにテキストをkillリングに保存するために、マイナーモードとフック関数はフィルタリングをセットアップできます。
この関数はstartとendの間のテキスト範囲をkillするが、オプション引数regionが非nil
なら、かわりにカレントリージョンのテキストをkillする。そのテキストは削除されるが、そのテキストプロパティと共にkillリングに保存される。値は常にnil
。
インタラクティブな呼び出しではstartとendはポイントとマークでregionは常に非nil
なので、このコマンドは常にカレントリージョン内のテキストをkillする。
バッファーまたはテキストが読み取り専用なら、kill-region
は同じようにkillリングを変更後に、バッファーを変更せずにエラーをシグナルする。これはユーザーが一連のkillコマンドで、読み取り専用バッファーからkillリングにテキストをコピーするのに有用。
このオプションが非nil
なら、バッファーやテキストが読み取り専用でもkill-region
はエラーをシグナルしない。かわりにバッファーを変更せずにkillリングを更新して単にリターンする。
この関数はstartとendの間のテキスト範囲(テキストプロパティを含む)をkillリングに保存するが、バッファーからそのテキストを削除しない。しかしオプション引数regionが非nil
なら、この関数はstartとendを無視して、かわりにカレントリージョンを保存する。この関数は常にnil
をリターンする。
インタラクティブな呼び出しではstartとendはポイントとマークでregionは常に非nil
なので、このコマンドは常にカレントリージョン内のテキストをkillする。
このコマンドは後続のkillコマンドが同一のkillリングエントリーに追加しないように、this-command
にkill-region
をセットしない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
yankとはkillリングからテキストを挿入しますが、それが単なる挿入ではないことを意味します。yank
とそれに関連するコマンドは、テキスト挿入前に特別な処理を施すためにinsert-for-yank
を使用します。
この関数はinsert
と同様に機能するが、結果をカレントバッファーに挿入する前にテキストプロパティyank-handler
、同様に変数yank-handled-properties
とyank-excluded-properties
に応じてstring内のテキストを処理する点が異なる。
この関数はinsert-buffer-substring
と似ているが、yank-handled-properties
とyank-excluded-properties
に応じてテキストを処理する点が異なる(これはyank-handler
プロパティを処理しないが、いずれにせよバッファー内のテキストでは通常は発生しない)。
文字列の一部またはすべてにテキストプロパティyank-handler
をputすると、insert-for-yank
が文字列を挿入する方法が変更されます。文字列の別の箇所が異なるyank-handler
の値をもつ場合(比較はeq
)、部分文字列はそれぞれ個別に処理されます。プロパティ値は以下の形式からなる1から4要素のリストでなければなりません(2番目以降の要素は省略可):
(function param noexclude undo)
これらの要素が何を行うかを以下に示します:
functionが非nil
なら、insert
のかわりに文字列を挿入するために、挿入する文字列を単一の引数として、その関数が呼び出される。
非nil
のparamが与えられた場合には、それはstring
(または処理されるstringの部分文字列)を置き換えるオブジェクトとしてfunction
(またはinsert
)に渡される。たとえばfunctionがyank-rectangle
なら、paramは矩形(rectangle)として挿入されるべき文字列のリスト。
非nil
のnoexcludeが与えられたら、挿入される文字列にたいするyank-handled-properties
とyank-excluded-properties
の通常の動作を無効にする。
非nil
のundoが与えられたら、それはカレントオブジェクトの挿入をundoするためにyank-pop
が呼び出す関数。この関数はカレントリージョンのstartとendという2つの引数で呼び出される。functionはyank-undo-function
をセットすることによりundoの値をオーバーライドできる。
この変数はyankされるテキストの状態を処理するスペシャルテキストプロパティを指定する。これは(通常の方法、またはyank-handler
を通じた)テキストの挿入後、yank-excluded-properties
が効力をもつ前に効果を発揮する。
値は要素が(prop
.
fun)
であるようなalistであること。alistの各要素は順番に処理される。挿入されるテキストはテキスト範囲にたいして、テキストプロパティがpropとeq
なものがスキャンされる。そのような範囲にたいしてプロパティの値、そのテキストの開始と終了の位置という3つの引数によりfunが呼び出される。
この変数の値は挿入されるテキストから削除するためのプロパティのリスト。デフォルト値にはマウスに応答したりキーバインディングの指定を引き起こすテキストのような、煩わしい結果をもたらすかもしれないプロパティが含まれる。これはyank-handled-properties
の後に効果を発揮する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではyank用の高レベルなコマンドを説明します。これらのコマンドは主にユーザー用に意図されたものですが、Lispプログラム内での使用にたいしても有用です。yank
とyank-pop
はいずれも、変数yank-excluded-properties
とテキストプロパティyank-handler
にしたがいます(yankを参照)。
このコマンドはkillリングの先頭にあるテキストをポイントの前に挿入する。これはpush-mark
(マークを参照)を使用して、そのテキストの先頭にマークをセットする。
argが非nil
のリスト(これはユーザーがインタラクティブに数字を指定せずにC-uタイプ時に発生する)なら、yank
は上述のようにテキストを挿入するがポイントはyankされたテキストの前、マークはyankされたテキストの後に置かれる。
argが数字ならyank
はarg番目に最近killされたテキスト、すなわちkillリングリストのarg番目の要素を挿入する。この順番はコマンドの目的にたいして1番目の要素としてみなされるリスト先頭の要素から巡回的に数えられる。
yank
は、それが他のプログラムから提供されるテキストを使用しないかぎり(使用する場合はそのテキストをkillリングにpushする)、killリングのコンテンツを変更しない。しかしargが非1の整数なら、killリングを転回(rotate)してyankされるテキストをリング先頭に置く。
yank
はnil
をリターンする。
このコマンドはkillリング上の正にyankされたばかりのエントリーをkillリングの別エントリーで置き換える。
このコマンドはyank
か別のyank-pop
の直後のみ許される。そのような際にそのリージョンには、yankにより正に挿入されたテキストが含まれる。yank-pop
はそのテキストを削除して、killされた別のテキスト片をその位置に挿入する。そのテキスト片はすでにkillリング内のどこか別の箇所にあるので、これは削除されたテキストをkillリングに追加しない。しかし新たにyankされたテキストが先頭になるように、killリングの転回は行う。
argがnil
なら置換テキストはkillリングの1つ前の要素。argが数字なら置換テキストはkillリングのarg個前の要素である。argが負なら、より最近のkillが置換される。
killリング内のkillされたエントリーの順序はラップする。すなわちもっとも古いkillの次にもっとも新しいkill、もっとも新しいkillの前はもっとも古いkillとなる。
リターン値は常にnil
である。
この変数が非nil
なら、関数yank-pop
は前のyank
やyank-pop
により挿入されたテキストを削除するために、delete-region
のかわりにこの変数の値を使用する。値はカレントリージョンの開始と終了という2つの引数をとる関数でなければならない。
関数insert-for-yank
はテキストプロパティyank-handler
の要素undoに対応して、この変数を自動的にセットする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数と変数はkillリングにたいして低レベルなアクセスを提供しますが、それらはウィンドウシステムの選択(ウィンドウシステムによる選択を参照)との相互作用にも留意するので、Lispプログラム内での使用に関しても依然として有用です。
関数current-kill
はkillリングの先頭を指すyankポインターを、(新しいkillから古いkillに)
n個転回して、リング内のその箇所のテキストをリターンする。
オプションの第2引数do-not-moveが非nil
なら、current-kill
はyankポインターを変更しない。カレントyankポインターからn個目のkillを単にリターンする。
nが0ならそれは最新のkillの要求を意味しており、current-kill
はkillリング照会前にinterprogram-paste-function
(以下参照)の値を呼び出す。その値が関数であり、かつそれが文字列か複数の文字列からなるリストをリターンすると、current-kill
はその文字列をkillリング上にpushして最初の文字列をリターンする。これはdo-not-moveの値に関わらず、interprogram-paste-function
がリターンする最初の文字列のkillリングエントリーを指すようにyankポインターのセットも行う。それ以外ではcurrent-kill
はnにたいする0値を特別に扱うことはなく、yankポインターが指すエントリーをリターンしてyankポインターの移動は行わない。
この関数はテキストstringをkillリング上にpushして、yankポインターがそれを指すようにセットする。それが適切ならもっとも古いエントリーを破棄する。interprogram-cut-function
(以下参照)の呼び出しも行う。
replaceが非nil
ならkill-new
はkillリング上にstringをpushせずに、killリングの1つ目の要素をstringに置き換える。
この関数はkillリング内の最初のエントリーにテキストstringを追加して、その結合されたエントリーを指すようにyankポインターをセットする。通常はそのエントリーの終端にstringが追加されるが、before-pが非nil
ならエントリーの先頭に追加される。この関数はinterprogram-cut-function
(以下参照)の呼び出しも行う。
この変数は他のプログラムからkillリングへkillされたテキストを転送する方法を提供する。値はnil
、または引数のない関数であること。
値が関数なら、もっとも最近のkillを取得するためにcurrent-kill
はそれを呼び出す。その関数が非nil
値をリターンすると、その値がもっとも最近のkillとして使用される。nil
をリターンしたらkillリングの先頭が使用される。
複数選択をサポートするウィンドウシステムのサポートを容易にするために、この関数は文字列のリストをリターンすることもある。その場合には1つ目の文字列がもっとも最近のkillとして使用され、その他の文字列はすべてyank-pop
によるアクセスを容易にするためにkillリング上にpushされる。
この関数の通常の用途は、たとえそれが他アプリケーションに属する選択であっても、もっとも最近のkillとしてウィンドウシステムのクリップボードからそれを取得することである。しかしクリップボードのコンテンツがカレントEmacsセッションに由来するなら、この関数はnil
をリターンする筈である。
この変数はウィンドウシステム使用時に、他のプログラムにkillされたテキストを転送する方法を提供する。値はnil
、または1つの引数を要求する関数であること。
値が関数ならkill-new
とkill-append
はkillリングの新たな1つ目要素を引数としてそれを呼び出す。
この関数の通常の用途は、新たにkillされたテキストをウィンドウシステムのクリップボードに配置することである。ウィンドウシステムによる選択を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
変数kill-ring
は、文字列リスト形式でkillリングのコンテンツを保持します。もっとも最近のkillが常にこのリストの先頭になります。
変数kill-ring-yank-pointer
は、CARが次のyankのテキストであるような、killリングリスト内のリンクをpointします。これをリングの先頭を識別すると言います。そして、kill-ring-yank-pointer
を異なるリンクに移動することをkillリングの転回(rotating
the kill
ring)と呼びます。yankポインターを移動する関数はyankポインターをリスト終端から先頭、またはその逆へラップするのでkillリングを“ring”と呼びます。killリングの転回は仮想的なものであってkill-ring
の値は変更しません。
kill-ring
とkill-ring-yank-pointer
はいずれも、通常は値がリストであるようなLisp変数です。kill-ring-yank-pointer
の名前にある単語“pointer”は、その変数の目的が次回yankコマンドにより使用されるリストの最初の要素を指すことであることを示します。
kill-ring-yank-pointer
の値は常にkillリングリスト内の1つのリンクとeq
です。それが指す要素は、そのリンクのCARです。killリングを変更するkillコマンドも、この変数にkill-ring
の値をセットします。その効果は新たにkillされた先頭になるように、リングを転回することです。
以下は変数kill-ring-yank-pointer
が、killリング("some text" "a different
piece of text" "yet older text")
内の2番目のエントリーを指すことを表すダイアグラムです。
kill-ring ---- kill-ring-yank-pointer | | | v | --- --- --- --- --- --- --> | | |------> | | |--> | | |--> nil --- --- --- --- --- --- | | | | | | | | -->"yet older text" | | | --> "a different piece of text" | --> "some text"
この状態はC-y (yank
)の直後にM-y (yank-pop
)を行うことにより発生し得ます。
この変数はもっとも最近にkillされたテキストが先頭になるように、killされたテキストのシーケンスのリストを保持する。
この変数の値は、yankにたいして使用されるkillリングの先頭にある要素を示す。より正確には値はkill-ring
の値のtail値であり、そのCARがC-yによりyankされるはずのkill文字列。
この変数の値は、リング終端の要素を破棄する前にkillリングが成長し得る最大長。kill-ring-max
のデフォルト値は60。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ほとんどのバッファーは、バッファーのテキストにたいして行われた変更をundoできるように、すべての変更を記録するundoリスト(undo
list)をもっています(undoリストをもたないバッファーとは通常はEmacsがundoを有用とみなさない特殊用途のバッファーである。特に名前がスペースで始まるバッファーはすべてundoの記録がデフォルトでオフになっている。バッファーの名前を参照)。バッファー内でテキストを変更するすべてのプリミティブはundoリストの先頭に自動的に要素を追加して、それは変数buffer-undo-list
に格納されます。
このバッファーローカル変数の値は、カレントバッファーのundoリスト。値がt
ならundo情報の記録を無効にする。
以下はundoリストが保有可能な要素の種類です:
position
この種の要素は前のポイント値を記録する。この要素をundoすることによりポイントはpositionに移動する。通常のカーソル移動はどのような類のundo記録も作成しないが、削除操作はそのコマンド以前にポイントがあった場所を記録するためにこのエントリーを使用する。
(beg . end)
この種の要素は挿入されたテキストを削除する方法を示す。挿入においてそのテキストはバッファー内の範囲begからendを占める。
(text . position)
この種の要素は削除されたテキストを再度挿入する方法を示す。文字列textは削除されたテキストそのもの。削除されたテキストを再挿入する位置は(abs
position)
。positionが正ならポイントがあったのは削除されたテキストの先頭、それ以外では末尾。この要素の直後に0個以上の(marker
. adjustment)要素が続く。
(t . time-flag)
この種の要素は未変更のバッファーが変更されたことを示す。(sec-high sec-low
microsec
picosec)
という形式のtime-flagは、visitされたファイルにたいしてそれが以前にvisitや保存されたときの更新時刻(modification
time)を、current-time
と同じ形式を用いて表す。時刻を参照のこと。time-flagが0ならそのバッファーに対応するファイルがないことを、-1ならvisitされたファイルは以前は存在しなかったことを意味する。primitive-undo
はバッファーを再度未変更とマークするかどうかを判断するために、これらの値を使用する(ファイルの状態がtime-flagのそれとマッチする場合のみ未変更とマーク)。
(nil property value beg . end)
この種の要素はテキストプロパティの変更を記録する。変更をundoする方法は以下のようになる:
(put-text-property beg end property value)
(marker . adjustment)
この種の要素はマーカーmarkerがそれを取り囲むテキストの削除により再配置されて、adjustment文字位置を移動したということを記録する。undoリスト内の前にある要素(text . position)とマーカーの位置が一致する場合には、この要素をundoすることによりmarker - adjustment文字移動する。
(apply funname . args)
これは拡張可能なundoアイテムであり、引数argsとともにfunnameを呼び出すことによりundoが行われる。
(apply delta beg end funname . args)
これは拡張可能なundoアイテムであり、begからendまでに限定された範囲にたいして、そのバッファーのサイズをdelta文字増加させる変更を記録する。これは引数argsとともにfunnameを呼び出すことによりundoが行われる。
この種の要素は、それがリージョンと関係するか否かを判断することによりリージョンに限定されたundoを有効にする。
nil
この要素は境界(boundary)である。2つの境界の間にある要素を変更グループ(change group)と呼び、それぞれの変更グループは通常1つのキーボードコマンドに対応するとともに、undoコマンドは通常はグループを1つの単位として全体をundoを行う。
この関数はundoリスト内に境界を配置する。このような境界ごとにundoコマンドは停止して、連続するundoコマンドは、より以前の境界へとundoを行っていく。この関数はnil
をリターンする。
この関数を明示的に呼び出すことは、あるコマンドの効果を複数単位に分割するために有用である。たとえばquery-replace
はユーザーが個別に置換をundoできるように、それぞれの置換後にundo-boundary
を呼び出している。
しかしほとんどの場合には、この関数は適切なタイミングで自動的に呼び出される。
エディターコマンドループは各アンドゥがが通常はそれぞれ1つのコマンドの効果をアンドゥするように、各キーシーケンスを実行する直前にundo-boundary
を呼び出す。少数の例外は融合(amalgamating)コマンドである。これらのコマンドは一般的にバッファーにたいして小さい変更を発生させるので、変更をグループとしてアンドゥできるように、20回目のコマンドごとに境界が挿入される。デフォルトでは自己挿入入力文字を生成するコマンドself-insert-command
(ユーザーレベルの挿入コマンドを参照)、文字を削除するコマンドdelete-char
(テキストの削除を参照)は融合コマンドである。複数バッファーのコンテンツに影響するコマンド、たとえば発生し得るとすればpost-command-hook
上の関数がcurrent-buffer
以外のバッファーに影響を及ぼす場合には、影響を受ける各バッファーごとにundo-boundary
が呼び出されるだろう。
プロセスバッファーのようないくつかのバッファーでは、何もコマンドを実行していなくても変更が発生し得る。このような場合には、通常はundo-boundary
この変数内のタイマーにより定期的に呼び出される。この挙動を抑制するには、この変数を非nil
にセットすること。
この変数は通常はnil
だが、undoコマンドはこれをt
にバインドする。これによりさまざまな種類の変更フックがundoにより呼び出された際に、それを告げることが可能になる。
これはundoリストの要素のundoにたいする基本的な関数。これはlistの最初のcount要素をundoしてlistの残りをリターンする。
primitive-undo
はバッファー変更時に、そのバッファーのundoリストに要素を追加する。undoコマンドは混乱を避けるためにundo操作シーケンス冒頭にundoリストの値を保存する。その後でundo操作は保存された値の使用と更新を行う。undoにより追加された新たな要素はこの保存値の一部でないので継続するundoと干渉しない。
この関数はundo-in-progress
をバインドしない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは与えられたバッファーにたいしてundo情報を有効や無効にする方法を説明します。undoリストが巨大化しないようにundoリストを切り詰める方法も説明します。
新たに作成されたバッファー内のundo情報記録は、通常は開始とともに有効になります。しかしバッファー名がスペースで始まる場合には、undoの記録は初期状態では無効になっています。以下の2つの関数、または自身でbuffer-undo-list
をセットすることにより、undo記録の有効化や無効化を明示的に行うことができます。
このコマンドは以降の変更をundo可能にするように、バッファーbuffer-or-nameのundo情報記録を有効にする。引数が与えられなければカレントバッファーを使用する。そのバッファー内のundo記録がすでに有効ならこの関数は何も行わない。リターン値はnil
。
インタラクティブな呼び出しではbuffer-or-nameはカレントバッファーであり、他のバッファーを指定することはできない。
この関数はbuffer-or-nameのundoリストを破棄して、それ以上のundo情報記録を無効にする。結果として以前の変更と以後のすべての変更にたいするそれ以上のundoは不可能になる。buffer-or-nameのundoリストがすでに無効ならこの関数に効果はない。
インタラクティブな呼び出しではBUFFER-OR-NAMEはカレントバッファー。他のバッファーを指定することはできない。リターン値はnil
。
編集が継続されるにつれてundoリストは次第に長くなっていきます。利用可能なメモリー空間すべてを使い尽くすのを防ぐために、ガベージコレクションがundoリストを設定可能な制限サイズに切り詰めて戻します(この目的のためにundoリストのサイズはリストを構成するコンスセルに加えて削除された文字列により算出される)。undo-limit
、undo-strong-limit
、undo-outer-limit
の3つの変数は、許容できるサイズの範囲を制御します。これらの変数においてサイズは専有するバイト数で計数され、それには保存されたテキストとその他データが含まれます。
これは許容できるundoリストサイズのソフトリミット。このサイズを超過した箇所の変更グループは最新の変更グループ1つが保持される。
これはundoリストの許容できるサイズの上限。このサイズを超過する箇所の変更グループは(その他すべてのより古い変更グループとともに)自身を破棄する。1つ例外がありundo-outer-limit
を超過すると最新の変更グループだけが破棄される。
ガベージコレクション時にカレントコマンドのundo情報がこの制限を超過したら、Emacsはその情報を破棄して警告を表示する。これはメモリーオーバーフローを防ぐための最後の回避用リミットである。
この変数が非nil
ならundo情報のundo-outer-limit
超過時に、Emacsはその情報を破棄するかどうかをエコーエリアで尋ねる。デフォルト値はnil
でこれは自動的な破棄を意味する。
このオプションは主にデバッグを意図している。これを尋ねる際にはガベージコレクションは抑制されており、もしユーザーがその問にたいして答えるのをあまりに長くかかるなら、Emacsがメモリーリークを起こすかもしれないことを意味する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フィル(fill:
充填)とは、指定された最大幅付近(ただし超過せず)に、(行ブレークを移動することにより)行の長さを調整することを意味します。加えて複数行を位置揃え(justify)することもできます。位置揃えとはスペースを挿入して左および/または右マージンを正確に整列させることを意味します。その幅は変数fill-column
により制御されます。読みやすくするために行の長さは70列程度を超えないようにするべきです。
テキストの挿入とともに自動的にテキストをフィルするAuto Fillモードを使用できますが、既存テキストの変更では不適切にフィルされたままになるかもしれません。その場合にはテキストを明示的にフィルしなければなりません。
このセクションのコマンドのほとんどは有意な値をリターンしません。フィルを行うすべての関数はカレント左マージン、カレント右マージン、カレント位置揃えスタイルに留意します(fillのマージンを参照)。カレント位置揃えスタイルがnone
なら、フィル関数は実際には何も行いません。
フィル関数のいくつかは引数justifyを受け取ります。これが非nil
なら、それは何らかの類の位置揃えを要求します。特定の位置揃えスタイルを要求するためにleft
、right
、full
、center
を指定できます。これがt
なら、それはそのテキスト部分にたいしてカレント位置揃えスタイルを使用することを意味します(以下のcurrent-justification
を参照)。その他すべての値はfull
として扱われます。
インタラクティブにフィル関数を呼び出すには際、プレフィクス引数の使用はjustifyにたいして暗に値full
を指定します。
このコマンドはポイント位置、またはその後のパラグラフ(paragraph:
段落)をフィルする。justifyが非nil
なら、同様に各行が位置揃えされる。これはパラグラフ境界を探すために、通常のパラグラフ移動コマンドを使用する。Paragraphs in The GNU Emacs Manualを参照のこと。
もしregionが非nil
で、Transient
Markモードが有効かつマークがアクティブなら、このコマンドはカレントパラグラフのみフィルするかわりに、リージョン内すべてのパラグラフをフィルするためにコマンドfill-region
を呼び出す。このコマンドがインタラクティブに呼び出された際は、regionはt
。
このコマンドはstartからendのリージョン内のすべてのパラグラフをフィルする。justifyが非nil
なら同様に位置揃えも行う。
nosqueezeが非nil
なら、それは行ブレーク以外の空白文字を残すことを意味する。to-eopが非nil
なら、それはパラグラフ終端(以下のuse-hard-newlines
が有効なら次のhard改行)までのフィルを維持することを意味する。
変数paragraph-separate
はパラグラフを分割する方法を制御する。編集で使用される標準的な正規表現を参照のこと。
このコマンドはリージョン内の各パラグラフを、それの固有なフィルプレフィクスに応じてフィルする。したがってパラグラフの行がスペースでインデントされていれば、フィルされたパラグラフは同じ様式でインデントされた状態に保たれるだろう。
最初の2つの引数startとendはフィルするリージョンの先頭と終端。3つ目の引数justify、4つ目の引数citation-regexpはオプション。justifyが非nil
なら、そのパラグラフはフィルと同様に位置揃えも行われる。citation-regexpが非nil
なら、それはこの関数がメールメッセージを処理しているのでヘッダーラインをフィルするべきではないことを意味する。citation-regexpが文字列なら、それは正規表現として扱われる。それが行の先頭にマッチすれば、その行は引用マーカー(citation
marker)として扱われる。
fill-individual-paragraphs
は通常はインデントの変更を新たなパラグラフの開始とみなす。fill-individual-varying-indent
が非nil
ならセパレーターラインだけがパラグラフを分割する。その場合には、最初の行からさらにインデントが追加されたパラグラフを処理することが可能になる。
この変数は上述のようにfill-individual-paragraphs
の動作を変更する。
このコマンドはテキストのリージョンを1つのパラグラフとみなしてそれをフィルする。そのリージョンが多数のパラグラフから構成されていたらパラグラフ間の空行は削除される。justifyが非nil
ならフィルとともに位置揃えも行う。
nosqueezeが非nil
なら、それは改行以外の空白に手を加えずに残すことを意味する。squeeze-afterが非nil
なら、それはリージョン内の位置を指定して、その位置より前にあるスペースについては標準化を行わないことを意味する。
Adaptive
Fillモードでは、このコマンドはフィルプレフィクスを選択するためにデフォルトでfill-context-prefix
を呼び出す。Adaptive Fillモードを参照のこと。
このコマンドはその行が正確にfill-column
で終わるように単語間にスペースを挿入する。リターン値はnil
。
引数howが非nil
なら、それは位置揃えスタイルを明示的に指定する。指定できる値はleft
、right
、full
、center
、またはnone
。値がt
なら、それは指定済みの位置揃えスタイル(以下のcurrent-justification
を参照)にしたがうことを意味する。nil
は位置揃えfull
と同じ。
eopが非nil
なら、それはcurrent-justification
がfull位置揃えを指定する場合にleft位置揃えだけを行うことを意味する。これはパラグラフ最終行にたいして使用される。パラグラフ全体がfull位置揃えだったとしても最終行はfull位置揃えであるべきではない。
nosqueezeが非nil
なら、それは内部のスペースを変更しないことを意味する。
この変数の値は位置揃えに使用するスタイルをテキストプロパティで指定しないテキストにたいするスタイルを指定する。可能な値はleft
、right
、full
、center
、またはnone
。デフォルト値はleft
。
この関数はポイント周辺のフィルに使用するための適正な位置揃えスタイルをリターンする。
これはポイント位置のテキストプロパティjustification
の値、そのようなテキストプロパティが存在しなければ変数default-justificationの値をリターンする。しかし、“位置揃えなし”の場合には、none
ではなくnil
をリターンする。
この変数が非nil
ならピリオドの後の単一のスペースをセンテンスの終わりとみなさず、フィル関数はそのような箇所でのラインブレークを行わない。
この変数が非nil
なら、ピリオドなしでセンテンスは終了できる。これはたとえばピリオドなしの2連スペースでセンテンスが終わるタイ語などに使用される。
この変数が非nil
なら、それは後にスペースをともなうことなくセンテンスを終了させ得る文字列であること。
この変数はパラグラフのフィルをオーバーライドする手段を提供する。この値が非nil
なら、fill-paragraph
はその処理を行うためにその関数を呼び出す。その関数が非nil
値をリターンすると、fill-paragraph
は処理が終了したとみなして即座にその値をリターンする。
この機能の通常の用途はプログラミング言語のモードにおいてコメントをフィルすることである。通常の方法でその関数がパラグラフをフィルする必要があるなら、以下のようにそれを行うことができる:
(let ((fill-paragraph-function nil)) (fill-paragraph arg))
この変数はfill-region
やfill-paragraph
のようなフィル関数が次のパラグラフへ前方に移動する方法をオーバーライドするための手段を提供する。値は移動するパラグラフの数nを唯一の引数として呼び出される関数であり、nと実際に移動したパラグラフ数の差をリターンすること。この変数のデフォルト値はforward-paragraph
。Paragraphs in The GNU Emacs Manualを参照のこと。
この変数が非nil
なら、フィル関数はテキストプロパティhard
をもつ改行を削除しない。これらのhard改行、パラグラフのセパレーターとして機能する。Hard and Soft Newlines in The GNU Emacs
Manualを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このバッファーローカル変数が非nil
なら、それは通常のテキスト行の先頭に出現して、それらのテキスト行をフィルする際には無視されるべきテキスト文字列を指定する。そのフィルプレフィクスで始まらない行はパラグラフの開始とみなされ、フィルプレフィクスで始まる行はその後にスペースが追加される。フィルプレフィクスで始まりその後に追加のスペースがない行はフィル可能な通常のテキスト行。結果となるフィル済みの行もフィルプレフィクスで開始される。
もしあればフィルプレフィクスは左マージンのスペースの後になる。
このバッファーローカル変数はフィルされる行の最大幅を指定する。値は列数を表す整数であること。Auto Fillモード(オートfillを参照)を含むフィル、位置揃え、センタリングを行うすべてのコマンドがこの変数の影響を受ける。
実際の問題として他の人が読むためのテキストを記述する場合には、fill-column
を70より大きくするべきではない。これにしたがわないと人が快適に読むには行が長くなり過ぎてしまい、下手に記述されたテキストに見えてしまうだろう。
fill-column
のデフォルト値は70。
これはfromからtoのテキストのleft-margin
プロパティに値marginをセットする。Auto
Fillモードが有効なら、このコマンドは新たなマージンにフィットするようにリージョンの再フィルも行う。
これはfromからtoのテキストのright-margin
プロパティに値marginをセットする。Auto
Fillモードが有効なら、このコマンドは新たなマージンにフィットするようにリージョンの再フィルも行う。
この関数はポイント周辺をフィルするために使用する、適切な左マージン値をリターンする。値はカレント行開始文字のleft-margin
プロパティの値(なければ0)と変数left-margin
の値の合計。
この関数はポイント周辺のテキストをフィルするために使用する、適切なフィル列値をリターンする。値は変数fill-column
からポイント後の文字のright-margin
プロパティの値を減じた値。
この関数はカレント行の左マージンにポイントを移動する。移動先の列は関数current-left-margin
により決定される。引数nが非nil
なら、まずmove-to-left-margin
はn行前方に移動する。
forceが非nil
なら、それは行のインデントが左マージン値とマッチしなければインデントを修正するように指定する。
この関数はfromからtoの間のテキストから左マージンのインデントを取り除く。削除するインデントの量はcurrent-left-margin
を呼び出すことにより決定される。この関数が非空白文字を削除することはない。fromとtoが省略された場合のデフォルトはそのバッファー全体。
この関数はカレント行の先頭のインデントを変数left-margin
に指定された値に調整する(これにより空白文字の挿入や削除が起こるかもしれない)。Paragraph-Indent
Textモード内の変数indent-line-function
の値はこの関数。
この変数は左マージンの基本列を指定する。Fundamentalモードでは、RETはこの列にインデントする。この変数は手段の如何を問わずセットされると自動的にバッファーローカルになる。
この変数はメジャーモードにたいして、特定の箇所で行ブレークしないように指定する手段を提供する。値は関数のリストであること。フィルがバッファー内の特定箇所で行ブレークすると判断されるときは、常にその箇所にポイントを置いた状態でこれらの関数を引数なしで呼び出す。これらの関数のいずれかが非nil
をリターンすると、その行のその箇所では行ブレークしない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Adaptive Fillモードが有効なとき、Emacsは事前定義された値を使用するのではなく、フィルされる各パラグラフのテキストから自動的にフィルプレフィクスを決定します。fillとオートfillで説明されているように、このフィルプレフィクスはフィルの間にそのパラグラフの2行目以降の行頭に挿入されます。
この変数が非nil
ならAdaptive Fillモードは有効。デフォルトはt
。
この関数はAdaptive Fillモード実装の肝である。これはfromからto、通常はパラグラフの開始から終了にあるテキストにもとづいてフィルプレフィクスを選択する。これは以下で説明する変数にもとづき、そのパラグラフの最初の2行を調べることによりこれを行う。
この関数は通常は文字列としてフィルプレフィクスをリターンする。しかしこれを行う前に、この関数はそのプレフィクスで始まる行がパラグラフの開始とは見えないだろうか、最終チェックを行う(以降では特に明記しない)。これが発生した場合には、この関数はかわりにnil
をリターンすることにより異常を通知する。
以下はfill-context-prefix
が行う詳細:
adaptive-fill-function
内の関数、次にadaptive-fill-regexp
(以下参照)の正規表現を試みる。これらの非nil
の最初の結果、いずれもnil
なら空文字列が1行目の候補となる。
adaptive-fill-first-line-regexp
の説明を参照)。
nil
をリターンする。
Adaptive Fillモードは、(もしあれば)行の左マージン空白文字の後から開始されるテキストにたいしてこの正規表現をマッチする。マッチする文字列がその行のフィルプレフィクス候補。
デフォルト値は空白文字と特定の句読点文字が混在した文字列にマッチする。
この正規表現は1行だけのパラグラフに使用され、1つの可能なフィルプレフィクス候補の追加の妥当性評価として機能する。その候補はこの正規表現にマッチするか、comment-start-skip
にマッチしなければならない。マッチしなければfill-context-prefix
はその候補を同じ幅のスペース文字列に置き換える。
この変数のデフォルト値は "\\`[ \t]*\\'"
であり、これは空白文字列だけにマッチする。このデフォルトの効果は1行パラグラフで見つかったフィルプレフィクスが、常に純粋な空白文字となるよう強制することである。
この変数に関数をセットすることにより、自動的なフィルプレフィクス選択にたいしてより複雑な方法を指定することが可能になる。その関数は、(もしあれば)行の左マージンの後のポイントで呼び出され、かつポイントを保たなければならない。その関数はその行のフィルプレフィクス、またはプレフィクスの判断に失敗したことを意味するnil
のいずれかをリターンすること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Auto Fillモードはテキスト挿入とともに自動的に行をフィルするマイナーモードです。このセクションではAuto Fillモードにより使用されるフックを説明します。既存テキストを明示的にフィルしたり位置揃えすることができる関数の説明はfillを参照してください。
Auto Fillモードではテキスの一部を再フィルするためにマージンや位置揃えを変更する関数も利用できます。fillのマージンを参照してください。
このバッファーローカル変数の値は、テーブルauto-fill-chars
の文字の自己挿入後に呼び出される関数(引数なし)であること。nil
も可であり、その場合は特に何もしない。
Auto-Fillモードが有効ならauto-fill-function
の値はdo-auto-fill
。これは行ブレークにたいする通常の戦略を実装することを唯一の目的とする関数。
この変数はAuto Fillがオンのときはauto-fill-function
にたいして使用する関数を指定する。Auto
Fillの動作方法を変更するためにメジャーモードはこの変数にバッファーローカル値をセットできる。
文字が自己挿入された際にauto-fill-function
を呼び出す文字からなる文字テーブル(ほとんどの言語環境においてはスペースと改行)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションで説明するソート関数は、すべてバッファー内のテキストを再配置します。これはリスト要素を再配置するsort
関数とは対照的です(see section リストを再配置する関数)。これらの関数がリターンする値に意味はありません。
この関数はバッファーをレコードに細分してそれらをソートする一般的なテキストソートルーチン。このセクションのコマンドのほとんどは、この関数を使用する。
sort-subr
が機能する方法を理解するためには、バッファーのアクセス可能範囲をソートレコード(sort
records)と呼ばれる分離された断片に分割すると考えればよい。レコードは連続、あるいは非連続かもしれないがオーバーラップしてはならない。各ソートレコードの一部(全体かもしれない)はソートキーとして指定される。これらソートキーによるソートによりレコードは再配置される。
レコードは通常はソートキー昇順で再配置される。sort-subr
の1つ目の引数reverseが非nil
ならレコードはソートキー降順にソートされて再配置される。
sort-subr
にたいする以下の4つの引数は、ソートレコード間でポイントを移動するために呼び出される。これらはsort-subr
内で頻繁に呼び出される。
sort-subr
が呼び出された際には、ポイント位置が1つ目のレコードの開始とみなされる。したがってsort-subr
を呼び出す前は、通常はそのバッファーの先頭にポイントを移動すること。
この関数はバッファー終端にポイントを残すことにより、それ以上のソートレコードがないことを示すことができるできる。
nil
値、またはnil
(ソートキーはそのバッファー内のポイント位置から始まることを示す)のいずれかをリターンすること。後者の場合にはソートキー終端を見るけるためにendkeyfunが呼び出される。
nil
をリターンし、かつこの引数が省略(またはnil
)の場合には、そのソートキーはレコード終端まで拡張される。startkeyfunが非nil
値をリターンした場合にはendkeyfunは不要。
引数predicateはキーを比較するために使用される関数。キーが数字の場合のデフォルトは<
、それ以外ではstring<
がデフォルト。
sort-subr
の例として以下はsort-lines
関数の完全な定義である:
;; ドキュメント文字列の冒頭2行は ;; ユーザー閲覧時には1行となることに注意 (defun sort-lines (reverse beg end) "リージョン内の行をアルファベット順にソート;\ 引数は降順を意味する プログラムから呼び出す場合は、以下の3つの引数がある:
REVERSE(非nilは逆順の意)、\ およびBEGとEND(ソートするリージョン) 変数`sort-fold-case'は英字\ 大文字小文字の違いが ソート順に影響するかどうかを決定する"
(interactive "P\nr") (save-excursion (save-restriction (narrow-to-region beg end) (goto-char (point-min)) (let ((inhibit-field-text-motion t)) (sort-subr reverse 'forward-line 'end-of-line)))))
ここでforward-line
は次のレコードの先頭にポイントを移動して、end-of-line
はレコードの終端にポイントを移動する。レコード全体をソートキーとするので引数startkeyfunとendkeyfunは渡していない。
sort-paragraphs
はほとんど同じだが、sort-subr
の呼び出しが以下のようになる:
(sort-subr reverse (function (lambda () (while (and (not (eobp)) (looking-at paragraph-separate)) (forward-line 1)))) 'forward-paragraph)
ソートレコード内を指す任意のマーカーは、sort-subr
リターン後は無意味なマーカー位置のまま取り残される。
この変数が非nil
なら、sort-subr
とその他のバッファーソート関数は文字列比較時にcase(大文字小文字)の違いを無視する。
このコマンドはstartからendの間のリージョンを、record-regexpとkey-regexpで指定されたようにアルファベット順にソートする。reverseが負の整数なら逆順にソートする。
アルファベット順のソートとは2つのソートキーにたいして、それぞれの1つ目の文字同士、2つ目の文字同士、...のように比較することにより、キーを比較することを意味する。文字が一致しなければ、それはソートキーが不等なことを意味する。最初の不一致箇所で文字が小さいソートキーが小さいソートキーとなる。個別の文字はEmacs文字セット内の文字コードの数値に応じて比較される。
引数record-regexpの値はバッファーをソートレコードに分割する方法を指定する。各レコードの終端で、この正規表現にたいする検索は完了して、これにマッチするテキストが次のレコードとして採用される。たとえば改行の前に少なくとも1つの文字がある行にマッチする正規表現‘^.+$’は、そのような行をソートレコードとするだろう。正規表現の構文と意味については正規表現を参照のこと。
引数key-regexpの値は各レコードのどの部分がソートキーかを指定する。key-regexpはレコード全体、またはその一部にマッチすることができる。後者の場合にはレコードの残りの部分はソート順に影響しないが、レコードが新たな位置に移動される際はともに移動される。
引数key-regexpはrecord-regexpの部分式(subexpression)、またはその正規表現自体にマッチしたテキストを参照できる。
key-regexpには以下を指定できる:
record-regexp内でdigit番目のカッコ‘\(...\)’でグループ化によりマッチしたテキストがソートキーになる。
レコード全体がソートキーとなる。
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-regexpとkey-regexpの入力を求める。
このコマンドはstartとendの間のリージョン内の行をアルファベット順にソートする。reverseが非nil
なら逆順にソートする。
このコマンドはstartとendの間のリージョン内のパラグラフをアルファベット順にソートする。reverseが非nil
なら逆順にソートする。
このコマンドはstartとendの間のリージョン内のページをアルファベット順にソートする。reverseが非nil
なら逆順にソートする。
このコマンドはstartとendの間のリージョン内の行にたいして、各行のfield番目のフィールドをアルファベット順に比較することに行をソートする。fieldは空白文字により区切られて、1から数えられる。fieldが負なら行の終端から-field番目のフィールドでソートする。このコマンドはテーブルのソートに有用。
このコマンドはstartとendの間のリージョン内の行にたいして、各行のfield番目のフィールドを数値的に比較することにより行をソートする。fieldは空白文字により区切られて、1から数えられる。リージョン内の各行の指定されたフィールドは数字を含んでいなければならない。0で始まる数字は8進数、‘0x’で始まる数字は16進数として扱われる。
fieldが負なら行の終端から-field番目のフィールドでソートする。このコマンドはテーブルのソートに有用。
この変数はsort-numeric-fields
にたいして数字を解析するための基本基数を指定する。
このコマンドはbegとendの間にある行にたいして特定の列範囲をアルファベット順に比較することによりソートする。begとendの列位置はソートが行われる列範囲にバインドされる。
reverseが非nil
なら逆順にソートする。
このコマンドが通常と異なるのは、位置begを含む行全体と位置endを含む行全体がソートされるリージョンに含まれることである。
タブは指定された列に分割される可能性があるので、sort-columns
はタブを含むテキストを受け付けないことに注意。ソート前にM-x
untabifyを使用してタブをスペースに変換すること。
可能ならユーティリティプログラムsort
を呼び出すことにより、このコマンドは実際に機能する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
列関数は文字位置(バッファー先頭から数えた文字数)と列位置(行先頭から数えたスクリーン文字数)を変換する関数です。
これら列関数はスクリーン上占める列数に応じて各文字を数えます。これはコントロール文字はctl-arrow
の値に応じて2列または4列を、タブはtab-width
の値と、タブが始まる列の位置に依存する列数を占めるものとして数えられることを意味します。通常の表示の慣習を参照してください。
列数計算はウィンドウ幅と水平スクロール量を無視します。結果として列値は任意に大きくなる可能性があります。最初(または左端)の列は0と数えられます。列値は不可視性を別としてオーバーレイとテキストプロパティを無視します。
この関数は左マージンを0として列単位で数えたポイントの水平位置をリターンする。列の位置はカレント行の開始からポイントまでの間の文字の表示上の表現すべての幅の和。
この関数はカレント行のcolumnにポイントを移動する。columnの計算には行の開始からポイントまでの文字の表示上の表現の幅が考慮される。
インタラクティブに呼び出された際には、columnはプレフィクス数引数の値。columnが整数でなければエラーがシグナルされる。
列columnがタブのような複数列を占める文字の中間にあるために列を移動することが不可能なら、ポイントはその文字の終端に移動される。しかしforceが非nil
、かつcolumnがタブの中間にあるなら、move-to-column
はタブをスペースに変換して正確に列columnに移動することができる。それ以外の複数列文字については、それらを分割する手段がないのでforce指定に関わらず異常を引き起こす恐れがある。
その行が列columnに達するほど長くない場合にも引数forceは効果をもつ。columnがt
ならその列に達するよう行端に空白を追加することを意味する。
リターン値は実際に移動した列番号。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
インデント関数は行の先頭にある空白文字の調査、移動、変更に使用されます。行の他の箇所にある空白文字を変更できる関数もいくつかあります。列とインデントは左マージンを0として数えられます。
31.17.1 インデント用のプリミティブ | インデントのカウントと挿入に使用される関数。 | |
31.17.2 メジャーモードが制御するインデント | 異なるモード用にインデントをカスタマイズする。 | |
31.17.3 リージョン全体のインデント | リージョン内すべての行のインデント。 | |
31.17.4 前行に相対的なインデント | 前の行にもとづきカレント行をインデントする。 | |
31.17.5 Adjustable Tab Stops | 調整可能なタイプライター形式のタブストップ。 | |
31.17.6 インデントにもとづくモーションコマンド | 最初の非ブランク文字への移動。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではインデントのカウントと挿入に使用されるプリミティブ関数について説明します。以降のセクションの関数はこれらのプリミティブを使用します。関連する関数については表示されるテキストのサイズを参照してください。
この関数はカレント行のインデント、すなわち最初の非ブランク文字の水平位置をリターンする。行のコンテンツ全体がブランクなら、それは行終端の水平位置である。
この関数はポイントからcolumnに達するまでタブとスペースでインデントを行う。minimumが指定されて、かつそれが非nil
なら、たとえcolumnを超えることが要求される場合であっても、少なくともその個数のスペースが挿入される。それ以外ではポイントがすでにcolumnを超える場合には、この関数は何も行わない。値は挿入されたインデントの終端列。
挿入される空白文字は周囲のテキスト(通常は先行するテキストのみ)のテキストプロパティを継承する。テキストプロパティの粘着性を参照のこと。
この変数が非nil
なら、インデント関数はスペースと同じようにタブを挿入でき、それ以外ではスペースだけを挿入できる。この変数はセットすることにより自動的にカレントバッファー内でバッファーローカルになる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
すべてのメジャーモードにとって重要な関数は、編集対象の言語にたいして正しくインデントを行うようにTABキーをカスタマイズします。このセクションではTABキーのメカニズムと、それを制御する方法について説明します。このセクションの関数は予期せぬ値をリターンします。
これはほとんどの編集用モードでTABにバインドされるコマンド。これの通常の動作はカレント行のインデントだが、かわりにタブ文字の挿入やリージョンのインデントを行うこともできる。
これは以下のことを行う:
indent-region
を呼び出す(リージョン全体のインデントを参照)。
indent-line-function
内のインデント関数がindent-to-left-margin
の場合、または変数tab-always-indent
が挿入する文字としてタブ文字を指定する場合(以下参照)にはタブ文字を挿入する。
indent-line-function
内の関数を呼び出すことにより行われる。その行がすでにインデント済みで、かつtab-always-indent
の値がcomplete
(以下参照)ならポイント位置のテキストの補完を試みる。
rigidが非nil
(インタラクティブな場合はプレフィクス引数)なら、このコマンドが行をインデントした後、あるいはタブを挿入後に新たなインデントを反映するために、このコマンドはカレント行先頭にあるバランスされた式全体も厳正にインデントする。この引数はコマンドがリージョンをインデントする場合は無視される。
この変数の値はカレント行をインデントするためにindent-for-tab-command
、およびその他種々のインデントコマンドにより使用される関数。これは通常はメジャーモードにより割り当てられ、たとえばLispモードはこれをlisp-indent-line
、Cモードはc-indent-line
のようにセットする。デフォルト値はindent-relative
。コードの自動インデントを参照のこと。
このコマンドはカレントのメジャーモードに適した方法でカレント行をインデントするためにindent-line-function
内の関数を呼び出す。
この関数は改行を挿入後に、メジャーモードに応じて新たな行(挿入した改行の次の行)をインデントする。これはindent-according-to-mode
を呼び出すことによりインデントを行う。
このコマンドはカレント行の再インデント、ポイント位置への改行の挿入、その後に新たな行(挿入した改行の次の行)のインデントを行う。これはindent-according-to-mode
を呼び出すことにより両方の行をインデントする。
この変数はTAB
(indent-for-tab-command
)コマンドの挙動のカスタマイズに使用できる。値がt
(デフォルト)ならコマンドは通常はカレント行だけをインデントする。値がnil
ならコマンドはポイントが左マージン、またはその行のインデント内ににあるときのみカレント行をインデントして、それ以外はタブ文字を挿入する。値がcomplete
ならコマンドはまずカレント行のインデントを試みて、その行がすでにインデント済みならポイント位置のテキストを補完するためにcompletion-at-point
を呼び出す(通常バッファーでの補完を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではリージョン内すべての行をインデントするコマンドを説明します。これらは予期せぬ値をリターンします。
このコマンドはstart (含む)からend
(含まず)で始まる非ブランク行すべてをインデントする。to-columnがnil
ならindent-region
はカレントモードのインデント関数、すなわちindent-line-function
の値を呼び出すことにより非ブランク行すべてをインデントする。
to-columnが非nil
なら、それはインデントの列数を指定する整数であること。その場合には、この関数は空白文字を追加か削除することにより正確にその量のインデントを各行に与える。
フィルプレフィクスがある場合には、indent-region
はそのフィルプレフィクスで開始されるように各行をインデントする。
この変数の値はショートカットとしてindent-region
により使用されるかもしれない関数。その関数はリージョンの開始と終了という2つの引数を受け取ること。その関数はリージョンの行を1行ずつインデントするときと同じような結果を生成するようにデザインするべきだが、おそらくより高速になるであろう。
値がnil
ならショートカットは存在せずindent-region
は実際に1行ずつ機能する。
ショートカット関数はindent-line-function
が関数定義先頭をスキャンしなければならないCモードやLispモードのようなモードにたいして有用であり、それを各行に適用するためには行数の2乗に比例する時間を要するだろう。ショートカットは各行のインデントとともに移動してスキャン情報を更新でき、それは線形時間である。行を個別にインデントするのが高速なモードではショートカットの必要性はない。
引数to-columnが非nil
のindent-region
では意味は異なり、この変数は使用しない。
この関数はstart (含む)からend (含まず)までのすべての行を横にcount列インデントする。これは影響を受けるリージョンの外観を保ち、それを厳密な単位として移動する。
これはインデントされていないテキストリージョンのインデントだけでなく、フォーマット済みコードのリージョンにたいするインデントにも有用。たとえばcountが3なら、このコマンドは指定されたリージョン内で始まるすべての行のインデントに3を追加する。
プレフィクス引数なしでインタラクティブに呼び出された場合には、このコマンドはインデントを厳密に調整するためにTransient Markモードを呼び出す。Indentation Commands in The GNU Emacs Manualを参照のこと。
これはindent-rigidly
と似ているが文字列やコメントで始まる行を変更しない点が異なる。
加えて( nochange-regexpが非nil
なら)
nochange-regexpが行先頭にマッチする場合にはその行を変更しない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは前の行のコンテンツにもとづいてカレント行をインデントするコマンドを2つ説明します。
このコマンドは前の非ブランク行の次のインデントポイント(indent point)と同じ列に拡張されるように、ポイント位置に空白文字を挿入する。インデントポイントとは後に空白文字をともなった非空白文字。次のインデントポイントはポイントのカレント列より大きい、最初のインデントポイントになる。たとえばポイントがテキスト行の最初の非ブランク文字の下と左にある場合には、空白文字を挿入してその列に移動する。
前の非ブランク行に次のインデントポイントがない(列の位置が十分大きくない)場合には、(
unindented-okが非nil
なら)何もしないか、あるいは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.
このコマンドは引数unindented-okにt
を指定してindent-relative
を呼び出すことにより、前の非ブランク行に倣ってカレント行をインデントする。リターン値は予測できない。
カレント列より先のインデントポイントが前の非ブランク行に存在しなければこのコマンドは何もしない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではユーザー指定のタブストップ(tab stops)と、それらの使用やセットするメカニズムについて説明します。“タブストップ”という名前はタイプライターのタブストップと機能が類似しているため使用されています。この機能は次のタブストップ列に到達するために、適切な数のスペースとタブを挿入することにより機能します。これはバッファー内のタブ文字の表示に影響を与えません(通常の表示の慣習を参照)。Textモードのような少数のメジャーモードだけが、TAB文字を入力としてこのタブストップ機能を使用することに注意してください。Tab Stops in The GNU Emacs Manualを参照してください。
このコマンドはtab-stop-list
により定義される次のタブストップ列までポイント前にスペースかタブを挿入する。
この変数はtab-to-tab-stop
により使用されるタブストップ列を定義する。これはnil
、もしくは増加(均等に増加する必要はない)していく整数のリストであること。このリストは暗黙に、最後の要素と最後から2番目の要素の間隔(またはリストの要素が2未満ならtab-width
)を繰り返すことにより無限に拡張される。値nil
は列tab-width
ごとにタブストップすることを意味する。
インタラクティブにタブストップの位置を編集するにはM-x edit-tab-stopsを使用すればよい。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下は主にインタラクティブに使用されるコマンドであり、テキスト内のインデントにもとづいて動作します。
このコマンドはカレント行(ポイントのある行のこと)の最初の非空白文字にポイントを移動する。リターン値はnil
。
このコマンドは後方へarg行ポイントを移動した後に、その行の最初の非ブランク文字にポイントを移動する。リターン値はnil
。argが省略またはnil
のときのデフォルトは1。
このコマンドは前方へarg行ポイントを移動した後に、その行の最初の非ブランク文字にポイントを移動する。リターン値はnil
。argが省略またはnil
のときのデフォルトは1。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ここで説明するcase(大文字小文字)変換コマンドはカレントバッファー内のテキストに作用します。文字列と文字のcase変換コマンドはLispでの大文字小文字変換、大文字や小文字に変換する文字やその変換方法のカスタマイズはcaseテーブルを参照してください。
この関数はstartとendで定義されるリージョン内のすべての単語をcapitalizeする。capitalizeとは各単語の最初の文字を大文字、残りの文字を小文字に変換することを意味する。この関数はnil
をリターンする。
リージョンのいずれかの端が単語の中間にある場合には、リージョン内にある部分を単語全体として扱う。
インタラクティブにcapitalize-region
が呼び出された際には、startとendはポイントとマークになり小さいほうが先になる。
---------- Buffer: foo ---------- This is the contents of the 5th foo. ---------- Buffer: foo ----------
(capitalize-region 1 37) ⇒ nil ---------- Buffer: foo ---------- This Is The Contents Of The 5th Foo. ---------- Buffer: foo ----------
この関数はstartとendで定義されるリージョン内のすべての英文字を小文字に変換する。この関数はnil
をリターンする。
インタラクティブにdowncase-region
が呼び出された際には、startとendはポイントとマークになり小さいほうが先になる。
この関数はstartとendで定義されるリージョン内のすべての英文字を大文字に変換する。この関数はnil
をリターンする。
インタラクティブにupcase-region
が呼び出された際には、startとendはポイントとマークになり小さいほうが先になる。
この関数はポイントの後のcount単語をcapitalizeして、変換後その後にポイントを移動する。capitalizeとは各単語の先頭を大文字、残りを小文字に変換することを意味する。countが負なら、この関数は前の-count単語をcapitalizeするがポイントは移動しない。値はnil
。
ポイントが単語の中間にある場合には、ポイントの前にある単語部分は前方に移動する際は無視される。そして残りの部分が単語全体として扱われる。
インタラクティブにcapitalize-word
が呼び出された際には、countに数プレフィクス引数がセットされる。
この関数はポイントの後のcount単語を小文字に変換して、変換後その後にポイントを移動する。countが負なら、この関数は前の-count単語を小文字に変換するがポイントは移動しない。値はnil
。
インタラクティブにdowncase-word
が呼び出された際には、countに数プレフィクス引数がセットされる。
この関数はポイントの後のcount単語を大文字に変換して、変換後その後にポイントを移動する。countが負なら、この関数は前の-count単語を小文字に変換するがポイントは移動しない。値はnil
。
インタラクティブにupcase-word
が呼び出された際には、countに数プレフィクス引数がセットされる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファーや文字列内の各文字位置は、シンボルにおけるプロパティリスト(プロパティリストを参照)のようにテキストプロパティリスト(text property list)をもつことができます。特定の位置の特定の文字に属するプロパティ、たとえばこのセンテンス先頭の文字‘T’ (訳注: 翻訳前のセンテンスは"The properties belong to a ..."で始まる)、または‘foo’の最初の‘o’など、もし同じ文字が異なる2箇所に存在する場合には、2つの文字は一般的に異なるプロパティをもちます。
それぞれのプロパティには名前と値があります。どちらも任意のLispオブジェクトをもつことができますが、名前は通常はシンボルです。典型的にはそれぞれのプロパティ名シンボルは特定の目的のために使用されます。たとえばテキストプロパティface
は、文字を表示するためのフェイスを指定します(特殊な意味をもつプロパティを参照)。名前を指定してそれに対応する値を尋ねるのが、このプロパティリストにアクセスするための通常の方法です。
ある文字がcategory
プロパティをもつ場合は、それをその文字のプロパティカテゴリー(property
category)と呼びます。これはシンボルであるべきです。そのシンボルのプロパティはその文字のプロパティにたいしてデフォルトとしての役割をもちます。
文字列とバッファーの間でのテキストのコピーでは、文字とともにそのプロパティが保持されます。これにはsubstring
、insert
、buffer-substring
のようなさまざまな関数が含まれます。
31.19.1 テキストプロパティを調べる | 単一の文字のプロパティを調べる。 | |
31.19.2 テキストプロパティの変更 | テキスト範囲のプロパティをセットする。 | |
31.19.3 テキストプロパティの検索関数 | プロパティが値を変更する場所の検索。 | |
31.19.4 特殊な意味をもつプロパティ | 特別な意味をもつ特定のプロパティ。 | |
31.19.5 Formatted Text Properties | テキストのフォーマットを表すプロパティ。 | |
31.19.6 テキストプロパティの粘着性 | 挿入されたテキストが隣接するテキストからプロパティを取得する方法。 | |
31.19.7 テキストプロパティのlazyな計算 | テキストが調べられる際のみ、ものぐさな方法でテキストプロパティを計算する。 | |
31.19.8 クリック可能なテキストの定義 | テキストプロパティを使用して、テキストリージョンがクリック時に何か行うようにする。 | |
31.19.9 フィールドの定義と使用 | バッファー内にフィールドを定義するfield プロパティ。
| |
31.19.10 なぜテキストプロパティはインターバルではないのか | テキストプロパティがLispから可視なテキスト間隔をもたない理由。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
テキストプロパティを調べるもっともシンプルな方法は、特定の文字の特定のプロパティの値を尋ねる方法です。これを行うにはget-text-property
を使用します。ある文字のプロパティリスト全体を取得するにはtext-properties-at
を使用します。複数の文字のプロパティを一度に調べる関数についてはテキストプロパティの検索関数を参照してください。
以下の関数は文字列とバッファーの両方を処理します。バッファー内の位置は1から始まりますが、文字列内の位置は0から始まることに留意してください。
この関数はobject (バッファーか文字列)内の位置posの後にある文字のプロパティpropの値をリターンする。引数objectはオプションでありデフォルトはカレントバッファー。
厳密な意味でpropプロパティは存在しないが、その文字がシンボルのプロパティカテゴリーをもつなら、get-text-property
はそのシンボルのpropプロパティをリターンする。
この関数はget-text-property
と似ているが、まずオーバーレイをチェックして次にテキストプロパティをチェックする点が異なる。オーバーレイを参照のこと。
引数objectは文字列、バッファー、あるいはウィンドウかもしれない。ウィンドウならそのウィンドウ内に表示されているバッファーのテキストプロパティとオーバーレイが使用されるが、そのウィンドウにたいしてアクティブなオーバーレイだけが考慮される。objectがバッファーなら、そのバッファー内のオーバーレイがまず優先的に考慮されて、その後にテキストプロパティが考慮される。objectが文字列なら文字列がオーバーレイをもつことは決してないのでテキストプロパティだけが考慮される。
この関数はget-char-property
と似ているが、position
(すぐ右)にある文字のプロパティのかわりにプロパティのstickiness(粘着性)とオーバーレイのadvancement(前向的)のセッティングに注意を払う点が異なる。
これはget-char-property
と似ているが、そのプロパティ値が由来するオーバーレイについて追加情報を与える点が異なる。
値はCARがプロパティ値であるようなコンスセルであり、これは同じ引数によりget-char-property
がリターンするであろう値と同じ。CDRはそのプロパティが見つかった箇所のオーバーレイ、テキストプロパティとして見つかった場合や見つからなかった場合にはnil
。
positionがobjectの終端ならCARとCDRの値はどちらもnil
。
この変数はプロパティ名と代替となるプロパティ名リストをマップするalistを保持する。文字があるプロパティにたいして直接値を指定しなければ、順に代替プロパティ名が調べられて最初の非nil
値が使用される。この変数はdefault-text-properties
より優先されて、この変数よりcategory
プロパティが優先される。
この関数は文字列かバッファーobject内の位置positionにある文字のプロパティリスト全体をリターンする。objectがnil
ならデフォルトはカレントバッファー。
この変数はテキストプロパティにたいしてデフォルト値を与えるプロパティリストを保持する。あるプロパティにたいして文字が直接、あるいはカテゴリーシンボルやchar-property-alias-alist
を通じて値を指定しないときは、常にこのリストに格納された値がかわりに使用される。以下は例:
(setq default-text-properties '(foo 69) char-property-alias-alist nil) ;; 文字1は自身のプロパティをもたない (set-text-properties 1 2 nil) ;; 取得される値はデフォルト値 (get-text-property 1 'foo) ⇒ 69
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プロパティを変更するプリミティブは、バッファーや文字列内の指定されたテキスト範囲に適用されます。関数set-text-properties
(セクションの最後を参照)は、その範囲内のテキストのプロパティリスト全体をセットします。名前を指定することにより特定のプロパティだけを追加、変更、削除するためにも有用です。
テキストプロパティはバッファー(か文字列)のコンテンツの一部とみなされ、かつスクリーン上でのバッファーの見栄えに影響を与えることができるので、バッファー内のテキストプロパティの変更はすべてバッファーを変更済みとマークします。バッファーテキストプロパティの変更もアンドゥできます(アンドゥを参照)。バッファー内の位置は1から始まりますが、文字列内の位置は0から始まります。
この関数は文字列かバッファーobject内のstartとendの間のテキストにたいして、プロパティpropにvalueをセットする。objectがnil
ならデフォルトはカレントバッファー。
この関数は文字列かバッファーobject内のstartとendの間のテキストにたいして、テキストプロパティを追加またはオーバーライドする。objectがnil
ならデフォルトはカレントバッファー。
引数propsには追加するプロパティを指定する。これはプロパティリストの形式(プロパティリストを参照)、つまりプロパティ名と対応する値が交互に出現するような要素を含むリストであること。
関数が実際に何らかのプロパティの値を変更したらt
、それ以外(
propsがnil
、またはプロパティの値がテキスト内のプロパティの値と一致している場合)はnil
がリターン値となる。
たとえば以下はテキストの範囲にcomment
とface
のプロパティをセットする例:
(add-text-properties start end '(comment t face highlight))
この関数は文字列かバッファーobject内のstartとendの間のテキストから、指定されたテキストプロパティを削除する。objectがnil
ならデフォルトはカレントバッファー。
引数propsは削除するプロパティを指定する。これはプロパティリストの形式(プロパティリストを参照)、つまりプロパティ名と対応する値が交互に出現するような要素を含むリストであること。しかし問題となるのは名前であって付随する値は無視される。たとえばface
プロパティを削除するには以下のようにすればよい。
(remove-text-properties start end '(face nil))
関数が実際に何らかのプロパティの値を変更したらt
、それ以外(
propsがnil
、または指定されたテキスト内にそれらのプロパティをもつ文字がない場合)はnil
がリターン値となる。
特定のテキストからすべてのテキストプロパティを削除するには、新たなプロパティリストにnil
を指定してset-text-properties
を使用すればよい。
remove-text-properties
と同様だが、list-of-propertiesがプロパティ名と値が交互になったリストではなくプロパティ名だけのリストである点が異なる。
この関数は文字列かバッファーobject内のstartからendの間のテキストにたいするテキストプロパティリストを完全に置き換える。objectがnil
ならデフォルトはカレントバッファー。
引数propsは新たなプロパティリスト。これはプロパティ名と対応する値が交互となるような要素のリストであること。
set-text-properties
のリターン後には、指定された範囲内のすべての文字は等しいプロパティをもつ。
propsがnil
なら、指定されたテキスト範囲からすべてのプロパティを取り除く効果がある。以下は例:
(set-text-properties start end nil)
この関数のリターン値を信用してはならない。
この関数はstartとendの間のテキストのテキストプロパティface
にフェイスfaceを追加するように動作する。faceはフェイス名、もしくはanonymousフェイス(anonymous
face: 無名フェイス)のようなface
プロパティ(特殊な意味をもつプロパティを参照)にたいして有効な値であること(フェイスを参照)。
リージョン内の任意のテキストがすでに非nil
のface
プロパティをもつなら、それらのフェイスは保たれる。この関数はface
プロパティに、最初の要素(デフォルト)がface、以前に存在していたフェイスが残りの要素であるようなフェイスのリストをセットする。オプション引数appendが非nil
なら、faceはかわりにリストの最後に追加される。フェイスリスト内では各属性にたいして最初に出現する値が優先されることに注意。
たとえば以下のコードではstartとendの間のテキストにグリーン斜体のフェイスを割り当てるだろう:
(add-face-text-property start end 'italic) (add-face-text-property start end '(:foreground "red")) (add-face-text-property start end '(:foreground "green"))
オプション引数objectが非nil
なら、それはカレントバッファーではなく動作するバッファーか文字列を指定する。objectが文字列ならstartとendは0基準で文字列内をインデックス付けする。
文字列にテキストプロパティを付するもっとも簡単な方法はpropertize
です:
この関数はテキストプロパティpropertiesを追加したstringのコピーをリターンする。これらのプロパティはリターンされる文字列内のすべての文字に適用される。以下はface
プロパティとmouse-face
プロパティとともに文字列を構築する例:
(propertize "foo" 'face 'italic 'mouse-face 'bold-italic) ⇒ #("foo" 0 3 (mouse-face bold-italic face italic))
文字列のさまざまな部分に異なるプロパティをputするには、それぞれの部分をpropertize
で構築して、それらをconcat
で結合すればよい:
(concat (propertize "foo" 'face 'italic 'mouse-face 'bold-italic) " and " (propertize "bar" 'face 'italic 'mouse-face 'bold-italic)) ⇒ #("foo and bar" 0 3 (face italic mouse-face bold-italic) 3 8 nil 8 11 (face italic mouse-face bold-italic))
プロパティではなくバッファーからテキストをコピーする関数buffer-substring-no-properties
についてはバッファーのコンテンツを調べるを参照してください。
バッファーを未変更のままバッファーにテキストプロパティの追加や削除を行いたければ、上記の呼出をwith-silent-modifications
で囲むことができます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
テキストプロパティの通常の使用では、ほとんどの場合は複数または多くの連続する文字が同じ値のプロパティをもちます。文字を1つずつ調べるプログラムを記述するよりも、同じプロパティ値をもつテキスト塊(chunks of text)を処理するほうがより高速です。
以下はこれを行うことに使用できる関数です。これらはプロパティ値の比較にeq
を使用します。すべての関数においてobjectのデフォルトはカレントバッファーです。
より良いパフォーマンスのためには、特に単一のプロパティを検索する関数におけるlimit引数の使用が重要です。さもないと興味のあるプロパティが変化しない場合に、バッファー終端までのスキャンで長い時間を要するでしょう。
これらの関数はポイントを移動しません。そのかわりに位置(またはnil
)をリターンします。ポイントは常に文字と文字の間にあることを思い出してください。これらの関数によりリターンされる位置は、異なるプロパティをもつ2つの文字の間にあります。
この関数は文字列かバッファーobject内の位置posから、何らかのテキストプロパティの変化が見つかるまでテキストを前方にスキャンして、変化のあった位置をリターンする。言い換えるとposの直後の文字とプロパティが等しくない、posの先にある最初の文字の位置をリターンする。
limitが非nil
ならスキャンは位置limitで停止する。そのポイントより前にプロパティが変化しなければ、この関数はlimitをリターンする。
プロパティがobject終端まで変化せず、かつlimitがnil
なら値はnil
。値が非nil
なら、それはpos以上の位置。limitがposと等しいときのみ値はposになる。
以下はすべてのプロパティが定数であるようなテキスト塊によりバッファーをスキャンする方法の例:
(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)))
これはnext-property-change
と似ているが、posから前方ではなく後方にスキャンする点が異なる。値が非nil
なら、それはpos以下の位置。limitとposが等しい場合のみposをリターンする。
この関数はプロパティprop内の変化にたいしてテキストをスキャンして、変化があった位置をリターンする。このスキャンは文字列かバッファーobject内の位置posから前方に行われる。言い換えるとposの直後の文字とプロパティpropが等しくない、posの先にある最初の文字の位置をリターンする。
limitが非nil
ならスキャンは位置limitで終了する。そのポイントより前にプロパティの変化がなければ、next-single-property-change
はlimitをリターンする。
プロパティがobject終端まで変化せず、かつlimitがnil
なら値はnil
。値が非nil
なら、それはpos以上の位置。limitがposと等しいときのみ値はposになる。
これはnext-single-property-change
と似ているが、posから前方ではなく後方にスキャンする点が異なる。値が非nil
なら、それはpos以下の位置。limitとposが等しい場合のみposをリターンする。
next-property-change
と似ているが、これはテキストプロパティと同様にオーバーレイも考慮して、バッファー終端より前に変化が見つからなければ、nil
ではなくバッファー位置の最大をリターンする点が異なる(この点ではnext-property-change
よりも対応するオーバーレイ関数next-overlay-change
と似ている)。この関数はカレントバッファーだけを処理するのでobjectオペランドは存在しない。これはいずれかの種類のプロパティが変化した、次のアドレスをリターンする。
これはnext-char-property-change
と似ているが、posから前方ではなく後方へスキャンすること、および変化が見つからなければバッファー位置の最小をリターンする点が異なる。
next-single-property-change
と似ているが、これはテキストプロパティと同様にオーバーレイも考慮して、object終端より前に変化が見つからなければ、nil
ではなくobject内の有効な位置の最大をリターンする点が異なる。next-char-property-change
と異なり、この関数はobjectオペランドをもつ。objectが非バッファーならテキストプロパティだけが考慮される。
これはnext-single-char-property-change
と似ているが、posから前方ではなく後方へスキャンすること、および変化が見つからなければobject内の有効な位置の最小をリターンする点が異なる。
この関数はstartとendの間に少なくともプロパティpropに値valueをもつ文字が1つあれば非nil
をリターンする。より正確には、これはそのような最初の文字の位置、それ以外はnil
をリターンする。
5つ目のオプション引数objectはスキャンする文字列かバッファーを指定する。位置はobjectにたいして相対的。objectのデフォルトはカレントバッファー。
この関数はstartとendの間に少なくともプロパティpropに値valueをもたない文字が1つあれば非nil
をリターンする。より正確には、これはそのような最初の文字の位置、それ以外はnil
をリターンする。
5つ目のオプション引数objectはスキャンする文字列かバッファーを指定する。位置はobjectにたいして相対的。objectのデフォルトはカレントバッファー。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はビルトインで特別な意味をもつテキストプロパティ名のテーブルです。以降のセクションではフィルとプロパティ継承を制御する特別なプロパティ名をいくつか追加でリストしています。これ以外のすべての名前は特別な意味をもたず自由に使用できます。
注意:
プロパティcomposition
、display
、invisible
、intangible
はすべてのEmacsコマンドの後に好ましい箇所にポイントを移動させることもできます。コマンド後のポイントの調整を参照してください。
category
ある文字がcategory
プロパティをもつ場合には、それをその文字のプロパティカテゴリー(property
category)と呼ぶ。これはシンボルであること。このシンボルのプロパティはその文字のプロパティのデフォルトとしての役割をもつ。
face
face
プロパティはその文字の外観を制御する(フェイスを参照)。このプロパティの値は以下が可能:
(keyword value
…)
形式のプロパティリスト。keywordはそれぞれフェイス属性名、valueはその属性の値。
(foreground-color . color-name)
または(background-color
. color-name)
形式のコンスセル。これは(:foreground
color-name)
や(:background
color-name)
と同じようにフォアグラウンドやバックグラウンドを指定する。この形式は後方互換のためだけにサポートされており無視すること。
Font Lockモード(Font Lockモードを参照)はほとんどのバッファーにおいて、コンテキストにもとづき文字のface
プロパティを動的に更新することにより機能する。
add-face-text-property
関数は、このプロパティをセットする便利な手段を提供する。テキストプロパティの変更を参照のこと。
font-lock-face
このプロパティはFont Lockモードが配下にあるテキストに適用すべきface
プロパティにたいして値を指定する。これはFont
Lockモードに使用されるフォント表示手法の1つであり、独自のハイライトを実装する特別なモードにたいして有用。事前計算されたフォント化を参照のこと。Font Lockモードが無効ならfont-lock-face
に効果はない。
mouse-face
このプロパティは文字上または近傍にマウスがあるとき、face
のかわりに使用される。この目的にたいして“近傍”とは文字とマウス位置の間のすべてのテキストが同じmouse-face
プロパティの値をもつことを意味する。
Emacsはテキストサイズ(:height
、:weight
、:slant
)を変更するmouse-face
プロパティ由来の属性すべてを無視する。これらの属性はハイライトされていないテキストと常に等しい。
fontified
このプロパティはそのテキストの表示準備が整っているかどうかを告げる。nil
ならEmacsの再表示ルーチンはバッファーの該当部分を表示する前に、準備のためにfontification-functions
(フェイスの自動割り当てを参照)の中の関数を呼び出す。これはフォントロックのコードのjust-in-timeにより内部的に使用される。
display
このプロパティはテキストが表示される方法を変更するさまざまな機能をアクティブ化する。たとえばこれによりテキスト外観を縦長(taller)または縦短(short)したり、高く(higher)または低く(lower)、太く(wider)または細く(narrower)したり、あるいはイメージに置き換えることができる。display
プロパティを参照のこと。
help-echo
テキストがhelp-echo
プロパティに文字列をもつ場合には、そのテキスト上にマウスを移動した際にEmacsはエコーエリアかツールチップウィンドウ(Tooltipsを参照)にその文字列を表示する。
help-echo
プロパティの値が関数なら、その関数はwindow、object、posの3つの引数で呼び出されてヘルプ文字列、ヘルプ文字列が存在しなければnil
をリターンすること。1つ目の引数windowはそのヘルプが見つかったウィンドウ。2つ目の引数objectはhelp-echo
プロパティをもつバッファー、オーバーレイ、または文字列。pos引数は以下のとおり:
help-echo
プロパティをもちposはそのオーバーレイのバッファー内の位置。
display
プロパティにより表示された文字列)ならposはその文字列内の位置。
help-echo
プロパティの値が関数と文字列のいずれでもなければ、それはヘルプ文字列を得るために評価される。
変数show-help-function
をセットすることにより、ヘルプテキストが表示される方法を変更できる(Help displayを参照)。
この機能はモードライン内、およびその他のアクティブテキストにたいして使用される。
keymap
keymap
プロパティはコマンドにたいして追加のキーマップを指定する。このキーマップを適用する際には、マイナーモードキーマップとバッファーのローカルマップの前に、このマップがキー照合のために使用される。アクティブなキーマップを参照のこと。プロパティ値がシンボルなら、そのシンボルの関数定義がキーマップとして使用される。
ポイントの前の文字のプロパティの値は、それが非nil
でrear-stickyであり、かつポイントの後の文字のプロパティ値が非nil
でfront-stickyなら適用される(マウスクリックではポイント位置のかわりにクリック位置が使用される)。
local-map
このプロパティはkeymap
と同じように機能するが、これはそのバッファーのローカルマップのかわりに使用するキーマップを指定する点が異なる。ほとんど(もしかするとすべて)の目的にたいしてはkeymap
を使用するほうが良いだろう。
syntax-table
syntax-table
プロパティは特定の文字にたいしてどのシンタックステーブルがオーバーライドするかを告げる。構文プロパティを参照のこと。
read-only
ある文字がプロパティread-only
をもつなら、その文字の変更は許可されない。これを行おうとするすべてのコマンドはtext-read-only
エラーを受け取る。プロパティの値が文字列ならその文字列がエラーメッセージとして使用される。
read-only文字に隣接する箇所への挿入は、そこに通常のテキストの行うことがstickinessによるread-only
プロパティを継承するならエラーとなる。つまりstickinessを制御することによりread-onlyテキストに隣接する挿入の権限を制御することができる。テキストプロパティの粘着性を参照のこと。
プロパティ変更はバッファー変更とみなされるので、特別なトリック(inhibit-read-only
を非nil
にバインドしてからプロパティを削除する)を知らないかぎり、read-only
プロパティを取り除くことは不可能。読み取り専用のバッファーを参照のこと。
inhibit-read-only
プロパティinhibit-read-only
をもつ文字はたとえ読み取り専用バッファーでも編集できる。読み取り専用のバッファーを参照のこと。
invisible
非nil
のinvisible
プロパティにより、スクリーン上で文字を不可視にできる。詳細は不可視のテキストを参照のこと。
intangible
連続する文字のグループが非nil
の等しいintangible
プロパティをもつなら、それらの文字の間にポイントを置くことは不可能。そのグループ内に前方へポイントの移動を試みると、ポイントは実際にはそのグループの終端に移動する。そのグループ内に後方へポイントの移動を試みると、ポイントは実際にはそのグループの先頭に移動する。
連続する文字のグループが非nil
の等しくないintangible
プロパティをもつなら、それらの文字は個別のグループに属して、各グループは上述のように別のグループとして扱われる。
変数inhibit-point-motion-hooks
が非nil
(デフォルト)ならintangible
プロパティは無視される。
注意せよ:
このプロパティは非常に低レベルで処理されて、予想外の方法により多くのコードに影響する。そのため使用に際しては特別な注意を要する。誤った使用方法としては不可視のテキストにintangibleプロパティをputするのが一般的な誤りであり、コマンドループは各コマンドの終わりに不可視テキストの外部へポイントを移動するだろうから、これは実際には必要ない。コマンド後のポイントの調整を参照のこと。これらの理由によりこのプロパティは時代遅れであり、かわりにcursor-intangible
プロパティを使用すること。
cursor-intangible
マイナーモードcursor-intangible-mode
がオンの際には、非nil
のcursor-intangible
プロパティをもつすべての位置から、再表示の発生直前にポイントが移動させられる。
field
同じfield
プロパティをもつ連続する文字はフィールドを構成する。forward-word
やbeginning-of-line
を含むいくつかの移動関数はフィールド境界で移動を停止する。フィールドの定義と使用を参照のこと。
cursor
カーソルは通常はカレントバッファー位置にあるオーバーレイ、およびテキストプロパティ文字列の先頭か終端に表示される。文字に非nil
のcursor
テキストプロパティを与えることにより、それら文字列内の任意の望む文字にカーソルを置くことができる。加えてcursor
プロパティの値が整数なら、それはカーソルがその文字上に表示されるようにオーバーレイまたはdisplay
プロパティが始まる位置から数えたバッファーの文字位置の数字を指定する。特にある文字のcursor
プロパティの値が数字nなら、カーソルは範囲[ovpos..ovpos+n)
内の任意のバッファー位置にあるその文字上に表示されるだろう。ここでovposはoverlay-start
(オーバーレイの管理を参照)により与えられるオーバーレイ開始位置、またはそのバッファー内でdisplay
プロパティが始まる位置である。
言い換えると文字列の非nil
値のcursor
プロパティをもつ文字はカーソルが表示される文字である。このプロパティの値はカーソルを表示するバッファーの位置を告げる。値が整数ならオーバーレイまたはdisplay
プロパティの始まりからn後ろの位置までの間にポイントがあるとき、カーソルはそこに表示される。値がそれ以外の非nil
ならポイントがdisplay
プロパティの先頭、またはoverlay-start
の位置だけに表示される。
バッファーのテキストを網羅するオーバーレイ文字列(before-stringを参照)や文字列であるようなdisplay
プロパティがバッファーに多くある場合には、それらの文字列を走査する間にカーソルを置く箇所をEmacsに合図するために、cursor
プロパティを使用するのはよいアイデアである。これはdisplayやオーバーレイ文字列に“カバー”された何らかのバッファー位置にポイントがある際に、Lispプログラムやユーザーがカーソルを配置したい箇所でディスプレイエンジンと直接通信する。
pointer
これはそのテキストやイメージ上にマウスポインターがあるときの特定のマウスシェイプを指定する。利用できるポインターシェイプについてはポインターの形状を参照のこと。
line-spacing
改行は改行で終わるディスプレイ行の高さを制御するテキストプロパティやオーバーレイプロパティline-spacing
をもつことができる。このプロパティ値はデフォルトのフレーム行スペーシングと、バッファーローカル変数line-spacing
をオーバーライドする。行の高さを参照のこと。
line-height
改行は改行で終わるディスプレイ行のトータル高さを制御するテキストプロパティ、またはオーバーレイプロパティline-height
をもつことができる。行の高さを参照のこと。
wrap-prefix
テキストがwrap-prefix
プロパティをもつなら、それが定義するプレフィクスはテキストラッピング(text wrapping:
テキスト折り返し)に由来するすべての継続行の先頭に表示時に追加されるだろう(行が切り詰められた場合にはwrap-prefixが使用されることはない)。これは文字列、イメージ(その他のディスプレー仕様を参照)、あるいはディスプレイプロパティ:width
や:align-to
(スペースの指定を参照)により指定された空白文字範囲かもしれない。
wrap-prefixはバッファーローカル変数wrap-prefix
を使用して、バッファー全体にも指定され得る(がwrap-prefix
テキストプロパティはwrap-prefix
変数の値より優先される)。切り詰めを参照のこと。
line-prefix
テキストがline-prefix
プロパティをもつなら、それが定義するプレフィクスは表示時にすべての非継続行の先頭に追加されるだろう。これは文字列、イメージ(その他のディスプレー仕様を参照)、あるいはディスプレイプロパティ:width
や:align-to
(スペースの指定を参照)により指定された空白文字範囲かもしれない。
line-prefixはバッファーローカル変数line-prefix
を使用して、バッファー全体にも指定され得る(がline-prefix
テキストプロパティはline-prefix
変数の値より優先される)。切り詰めを参照のこと。
modification-hooks
ある文字がプロパティmodification-hooks
をもつなら、その値は関数のリストであること。その文字の変更により、実際の変更前にそれらの関数すべてが呼び出される。それぞれの関数は、変更されようとするバッファー部分の先頭と終端という2つの引数を受け取る。特定のmodificationフック関数が単一のプリミティブにより変更されつつある複数の文字に出現する場合は、その関数が呼び出される回数を予測することはできない。さらに挿入は既存の文字を変更しないので、このフックは文字の削除、他の文字への置換、またはそれらのテキストプロパティ変更時のみ実行されるだろう。
これらの関数がバッファーを変更する場合には、これらのフックを呼び出す内部的メカニズムの混乱を避けるために、それらの関数はそれを行う前後にinhibit-modification-hooks
をt
にバインドすること。
オーバーレイもmodification-hooks
プロパティをサポートするが詳細は若干異なる(オーバーレイのプロパティを参照)。
insert-in-front-hooks
insert-behind-hooks
あるバッファーへの挿入操作は後続文字のinsert-in-front-hooks
プロパティ、および先行文字のinsert-behind-hooks
プロパティにリストされる関数の呼び出しも行う。これらの関数は挿入されるテキストの先頭と終端という2つの引数を受け取る。関数は優先される実際の挿入が行われた後に呼び出される。
バッファー内のテキスト変更時にに呼び出される他のフックについてはフックの変更も参照のこと。
point-entered
point-left
スペシャルプロパティpoint-entered
とpoint-left
はポイント移動をリポートするフック関数を記録する。ポイントを移動するたびにEmacsは以下の2つのプロパティ値を比較する:
point-left
プロパティ。
point-entered
プロパティ。
これらの2つの値が異なる場合には、(nil
でなければ)古いポイント値と新しいポイント値という2つの引数とともにそれらそれぞれ呼び出される。
同じ比較は古い位置と新しい位置の前の文字にたいしても行われる。この結果として2つのpoint-left
関数(同じ関数かもしれない)、および/または2つのpoint-entered
関数(同じ関数かもしれない)が実行される可能性がある。ある場合においては、まずすべてのpoint-left
関数が呼び出されて、その後にすべてのpoint-entered
関数が呼び出される。
さまざまなバッファー位置にたいして、そこにポイントを移動することなく文字を調べるためにchar-after
を使用することができる。実際のポイント値変更だけがこれらのフック関数を呼び出す。
変数inhibit-point-motion-hooks
はデフォルトではpoint-left
とpoint-entered
のフック実行を抑制する。Inhibit point motion hooksを参照のこと。
これらのプロパティは時代遅れであり、かわりにcursor-sensor-functions
を使用してほしい。
cursor-sensor-functions
このスペシャルプロパティはカーソル移動に反応する関数リストを記録する。このリスト内の各関数は影響を受けるウィンドウ、既知のカーソルの以前の位置、このプロパティをもつテキストにカーソルが入ったか離れたかに依存するシンボルentered
かleft
という3つの受け取って再表示の直前に呼び出される。関数はマイナーモードcursor-sensor-mode
がオンのときのみ呼び出される。
composition
このテキストプロパティは文字シーケンスをコンポーネントから構成される単一グリフ(single
glyph)として表示するために使用される。しかしこのプロパティの値自身は完全にEmacsの内部的なものであり、たとえばput-text-property
などで直接操作しないこと。
この時代遅れの変数が非nil
のときは、point-left
とpoint-entered
のフックは実行されずintangible
プロパティは効果をもたない。この変数はグローバルにセットせずlet
でバインドすること。この変数の影響を受けるプロパティは時代遅れなので、それらを効果的に無効にするためにデフォルト値はt
。
この変数が非nil
なら、それはヘルプ文字列を表示するために呼び出される関数を指定する。これらはhelp-echo
プロパティ、メニューヘルプ文字列(単純なメニューアイテムと拡張メニューアイテムを参照)、ツールバーヘルプ文字列(ツールバーを参照)かもしれない。指定された関数は表示するためのヘルプ文字列(この関数に与えられる前にsubstitute-command-keys
に渡される。ドキュメント内でのキーバインディングの置き換えを参照)という単一の引数とともに呼び出される。Tooltipモード(Tooltips in The GNU Emacs Manualを参照)が例を提供している。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のテキストプロパティはフィルコマンドの挙動に影響を与えます。これらはフォーマットされたテキストを表すために使用されます。fillとfillのマージンを参照してください。
hard
改行文字がこのプロパティをもつならそれは“hard”改行。フィルコマンドはhard改行を変更せずそれらを横断して単語を移動しない。しかしこのプロパティはマイナーモードuse-hard-newlines
が有効な場合のみ影響を与える。Hard and Soft Newlines in The GNU Emacs
Manualを参照のこと。
right-margin
このプロパティはその部分のテキストのフィルにたいして余分な右マージンを指定する。
left-margin
このプロパティはその部分のテキストのフィルにたいして余分な左マージンを指定する。
justification
このプロパティはその部分のテキストのフィルにたいして位置揃え(justification)のスタイルを指定する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ユーザーがそれらをタイプした際にはバッファーに挿入される自己挿入文字(ユーザーレベルの挿入コマンドを参照)は、通常は先行する文字と同じプロパティをもちます。これはプロパティの継承(inheritance)と呼ばれます。
対照的にLispプログラムは継承の有無に関わらず挿入を行うことができ、それは挿入プリミティブの選択に依存します。insert
のような通常のテキスト挿入関数は何もプロパティを継承しません。これらは挿入される文字列と正確に同じプロパティをもち、それ以外のプロパティはもちません。これはたとえばkillリング外部にたいしてのように、あるコンテキストから他のコンテキストにテキストをコピーするプログラムにたいして適正です。継承つきで挿入を行うためには、このセクションで説明するスペシャルプリミティブを使用します。自己挿入文字はこれらのプリミティブを使用するのでプロパティを継承します。
継承つきで挿入を行う際に、何のプロパティがどこから継承されるかはsticky(スティッキー、粘着する)に依存します。ある文字の後への挿入における、それらの文字のプロパティ継承はrear-sticky(後方スティッキー)です。ある文字の前への挿入における、それらの文字ノプロパティ継承はfront-sticky(前方スティッキー)です。これら両側のstickyが同じプロパティにたいして異なるsticky値をもつ場合には、前の文字の値が優先します。
デフォルトではテキストプロパティはfront-stickyではなくrear-stickyです。したがってデフォルトでは、すべてのプロパティは前の文字から継承して、後の文字からは何も継承しません。
さまざまなテキストプロパティのstickiness(スティッキネス、スティッキー性、粘着性、粘着度)は、2つのテキストプロパティfront-sticky
とrear-nonsticky
、および変数text-property-default-nonsticky
で制御できます。与えられたプロパティにたいして異なるデフォルトを指定するためにこの変数を使用できます。テキストの任意の特定部分に特定のstickyや非stickyプロパティを指定するために、これら2つのテキストプロパティを使用できます。
ある文字のfront-sticky
プロパティがt
なら、その文字のすべてのプロパティはfront-stickyです。front-sticky
プロパティがリストなら、その文字のstickyなプロパティは名前がそのリスト内にあるプロパティです。たとえばある文字が値が(face
read-only)
であるようなfront-sticky
プロパティをもつなら、その文字の前への挿入ではその文字のface
プロパティとread-only
プロパティは継承できますが他のプロパティは継承できません。
rear-nonsticky
は逆の方法で機能します。ほとんどのプロパティはデフォルトでrear-stickyであり、rear-nonsticky
プロパティはどのプロパティがrear-stickyではないかを告げます。ある文字のrear-nosticky
プロパティがt
なら、その文字のすべてのプロパティはrear-stickyではありません。rear-nosticky
プロパティがリストなら、その文字のstickyなプロパティは名前がそのリスト内にないプロパティです。
この変数はさまざまなテキストプロパティのデフォルトのrear-stickinessを定義するalist。各要素は(property
.
nonstickiness)
という形式をもち、これは特定のテキストプロパティpropertyのstickinessを定義する。
nonstickinessが非nil
なら、それはプロパティpropertyがデフォルトでrear-nonstickyであることを意味する。すべてのプロパティはデフォルトではfront-nonstickyなので、これによりpropertyは両方向にたいしてデフォルトでnonstickyになる。
テキストプロパティfront-sticky
とrear-nonsticky
が使用された際には、text-property-default-nonsticky
内で指定されたデフォルトのnonstickinessより優先される。
以下はプロパティ継承つきでテキストを挿入する関数です:
関数insert
と同じように文字列stringsを挿入するが、隣接するテキストからすべてのstickyなプロパティを継承する。
関数insert-before-markers
と同じように文字列stringsを挿入するが、隣接するテキストからすべてのstickyなプロパティを継承する。
継承を行わない通常の挿入関数についてはテキストの挿入を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファー内のすべてのテキストにたいしてテキストプロパティを計算するかわりに、何かがテキスト範囲に依存している場合にはテキストプロパティを計算するようにアレンジできます。
プロパティとともにバッファーからテキストを抽出するプリミティブはbuffer-substring
です。この関数はプロパティを調べる前にアブノーマルフックbuffer-access-fontify-functions
を実行します。
この変数はテキストプロパティ計算用の関数のリストを保持する。buffer-substring
がバッファーの一部のテキストとテキストプロパティをコピーする前にこのリスト内の関数すべてを呼び出す。各関数はアクセスされるバッファー範囲を指定する2つの引数を受け取る(バッファーは常にカレントバッファー)。
関数buffer-substring-no-properties
はいずれにせよテキストプロパティを無視するので、これらの関数を呼び出さない。
同じバッファー部分にたいして複数回フック関数が呼び出されるのを防ぐために変数buffer-access-fontified-property
を使用できる。
この変数の値が非nil
なら、それはテキストプロパティ名として使用されるシンボル。そのテキストプロパティにたいする非nil
値は、その文字にたいする他のテキストプロパティはすでに計算済みであることを意味する。
buffer-substring
にたいして指定された範囲内のすべての文字、このプロパティにたいする値として非nil
をもつなら、buffer-substring
はbuffer-access-fontify-functions
の関数を呼び出さない。それらの文字がすでに正しいテキストプロパティをもつとみなして、それらがすでに所有するプロパティを単にコピーする。
buffer-access-fontify-functions
の関数にこのプロパティ、同様に他のプロパティを処理対象の文字に追加させることがこの機能の通常の用途である。この方法では同じテキストにたいして、それらの関数が何度も呼び出されるのを防ぐことができる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
クリック可能テキスト(clickable text)とは何らかの結果を生成するためにマウスやキーボードコマンドを通じてクリックできるテキストです。多くのメジャーモードがテキスト的なハイパーリンク、略してリンク(link)を実装するためにクリック可能テキストを使用しています。
リンクの挿入や操作を行うもっとも簡単な方法はbutton
パッケージの使用です。ボタンを参照してください。このセクションではテキストプロパティを使用してバッファー内に手作業でクリック可能テキストをセットアップする方法を説明します。簡略にするためにクリック可能テキストをリンクと呼ぶことにします。
リンクの実装には、(1)リンク上にマウスが移動した際にクリック可能であることを示し、(2)そのリンク上のRETかmouse-2で何かを行うようにして、(3)そのリンクがmouse-1-click-follows-link
にしたがうようfollow-link
をセットアップする、という3つのステップが含まれます。
クリック可能なことを示すためには、そのリンクのテキストにmouse-face
プロパティを追加します。するとEmacsはそれ以降マウスがその上に移動した際にリンクをハイライトするでしょう。加えてhelp-echo
テキストプロパティを使用してツールチップかエコーエリアメッセージを定義するべきです。特殊な意味をもつプロパティを参照してください。たとえば以下はDiredがファイル名がクリック可能なことを示す方法です:
(if (dired-move-to-filename) (add-text-properties (point) (save-excursion (dired-move-to-end-of-filename) (point)) '(mouse-face highlight help-echo "mouse-2: visit this file in other window")))
リンクをクリック可能にするためには、 RETとmouse-2を望むアクションを行うコマンドにバインドします。各コマンドはリンク上から呼び出されたかチェックして、それに応じて動作するべきです。たとえばDiredメジャーモードのキーマップはmouse-2を以下のコマンドにバインドします:
(defun dired-mouse-find-file-other-window (event) "In Dired, visit the file or directory name you click on." (interactive "e") (let ((window (posn-window (event-end event))) (pos (posn-point (event-end event))) file) (if (not (windowp window)) (error "No file chosen")) (with-current-buffer (window-buffer window) (goto-char pos) (setq file (dired-get-file-for-visit))) (if (file-directory-p file) (or (and (cdr dired-subdir-alist) (dired-goto-subdir file)) (progn (select-window window) (dired-other-window file))) (select-window window) (find-file-other-window (file-name-sans-versions file t)))))
このコマンドはクリックがどこで発生したかを判断するために関数posn-window
とposn-point
、visitするファイルの判断に関数dired-get-file-for-visit
を使用します。
マウスコマンドをメジャーモードキーマップ内でバインドするかわりに、keymap
プロパティ(特殊な意味をもつプロパティを参照)を使用してリンクテキスト内でバインドできます。たとえば:
(let ((map (make-sparse-keymap))) (define-key map [mouse-2] 'operate-this-button) (put-text-property link-start link-end 'keymap map))
この手法により異なるリンクに異なるコマンドを簡単に定義できます。さらにそのバッファー内の残りのテキストにたいしては、RETとmouse-2のグローバル定義を利用可能なまま残すことができます。
リンク上でのクリックにたいするEmacsの基本コマンドはmouse-2です。しかし他のグラフィカルなアプリケーションとの互換性のために、ユーザーがマウスを動かさずに素早くリンクをクリックするという条件の下で、Emacsはリンク上でのmouse-1クリックも認識します。この振る舞いはユーザーオプションmouse-1-click-follows-link
により制御されます。Mouse
References in The GNU Emacs Manualを参照してください。
mouse-1-click-follows-link
にしたがうようにリンクをセットアップするには、(1)そのテキストにfollow-link
テキストプロパティまたはオーバーレイプロパティを適用する、または(2)follow-link
イベントをキーマップ(keymap
テキストプロパティを通じたメジャーモードキーマップまたはローカルキーマップ)にバインドするかの、いずれかを行わなければなりません。follow-link
プロパティの値、またはfollow-link
イベントにたいするバインディングはリンクアクションにたいするコンディション(condition)として機能します。この条件はEmacsにたいして2つのことを告げます。それはmouse-1のクリックがそのリンクの内側で発生したとみなすべき状況、そしてmouse-1のクリックを何に変換するかを告げるアクションコード(action
code)を計算する方法です。そのリンクのアクション条件は以下のうちの1つです:
mouse-face
コンディションがシンボルmouse-face
の場合には、その位置に非nil
のmouse-face
プロパティがあればそれはリンク内側の位置。アクションコードは常にt
。
以下はInfoモードがmouse-1を処理する例:
(define-key Info-mode-map [follow-link] 'mouse-face)
コンディションが関数funcの場合には、(func
pos)
が非nil
に評価されれば、位置posはリンクの内側。funcがリターンする値はアクションコードとして機能する。
以下はpcvsがファイル名の上でのみmouse-1によるリンクのフォローを有効にする方法の例:
(define-key map [follow-link] (lambda (pos) (eq (get-char-property pos 'face) 'cvs-filename-face)))
コンディション値がそれ以外の場合には、その位置はリンク内側であり、そのコンディション自体がアクションコード。(バッファー全体に適用されないように)リンクテキストのテキストプロパティかオーバーレイプロパティを通じてコンディションを適用するときのみ、この類のコンディションを指定すべきなのは明確である。
アクションコードはmouse-1がリンクをフォローする方法を告げます:
アクションコードが文字列かベクターなら、mouse-1イベントは文字列かベクターの最初の要素に変換される。つまりmouse-1クリックのアクションはその文字、またはシンボルのローカルかグローバルのバインディング。したがってアクションコードが"foo"
なら、mouse-1はf、[foo]
ならmouse-1はfooに変換される。
その他の非nil
のアクションコードでは、mouse-1イベントは同じ位置のmouse-2イベントに変換される。
define-button-type
で定義されるボタンをアクティブにするようにmouse-1を定義するには、そのボタンにfollow-link
プロパティを与えます。このプロパティの値は上述したリンクのアクションコンディションであるべきです。ボタンを参照のこと。たとえば以下はHelpモードがMouse-1を処理する例です。
(define-button-type 'help-xref 'follow-link t 'action #'help-button-action)
define-widget
で定義されたウィジェットにmouse-1を定義するには、そのウィジェットに:follow-link
プロパティを与えます。このプロパティの値は、上述したようなリンクのアクションコンディションであるべきです。たとえば以下はmouse-1クリックがRETに変換されるようにlink
ウィジェットを指定する方法の例です:
(define-widget 'link 'item "An embedded link." :button-prefix 'widget-link-prefix :button-suffix 'widget-link-suffix :follow-link "\C-m" :help-echo "Follow the link." :format "%[%t%]")
この関数はカレントバッファー内の位置posがリンク上なら非nil
をリターンする。posはevent-start
がリターンするようなマウスイベント位置でもよい(マウスイベントへのアクセスを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フィールドとはバッファー内にある連続する文字範囲であり、field
プロパティ(テキストプロパティかオーバーレイプロパティ)に同じ値(eq
で比較)をもつことにより識別されます。このセクションではフィールドの操作に利用できるスペシャル関数を説明します。
フィールドはバッファー位置posで指定します。各フィールドはバッファー位置の範囲を含むと考えて、指定した位置はその位置を含むフィールドを表します。
posの前後の文字は同じフィールドに属し、どのフィールドがposを含むかという疑問はありません。それらの文字が属するフィールドがそのフィールドです。posがフィールド境界のときは、それがどのフィールドに属すかは、取り囲む2つの文字のfield
プロパティのstickinessに依存します(テキストプロパティの粘着性を参照)。posに挿入されたテキストからプロパティが継承されたフィールドがposを含むフィールドです。
posに新たに挿入されたテキストが、いずれの側からもfield
プロパティを継承しない異常なケースがあります。これは前の文字のfield
プロパティがrear-stickyでなく、後の文字のfield
プロパティがfront-stickyでもない場合に発生します。このケースではposは前後のフィールドいずれにも属しません。フィールド関数はそれを、開始と終了がposであるような空フィールドに属するものとして扱います。
以下のすべての関数では、posが省略かnil
ならポイントの値がデフォルトとして使用されます。ナローイング(narrowing)が効力をもつ場合には、posはアクセス可能部分にあるはずです。ナローイングを参照してください。
この関数はposで指定されたフィールドの先頭をリターンする。
posが自身のフィールド先頭にあり、かつescape-from-edgeが非nil
なら、pos周辺のfield
プロパティのstickinessに関わらず、リターン値は常にposが終端であるような、前にあるフィールドの先頭になる。
limitが非nil
なら、それはバッファーの位置。そのフィールドの先頭がlimitより前なら、かわりにlimitがリターンされるだろう。
この関数はposで指定されるフィールドの終端をリターンする。
posが自身のフィールド終端にあり、かつescape-from-edgeが非nil
なら、pos周辺のfield
プロパティのstickinessに関わらず、リターン値は常にposが先頭であるような後のフィールドの終端になる。
limitが非nil
なら、それはバッファーの位置である。そのフィールドの終端がlimitより後なら、かわりにlimitがリターンされるだろう。
この関数はposで指定されるフィールドのコンテンツを文字列としてリターンする。
この関数はposで指定されるフィールドのコンテンツを、テキストプロパティを無視して文字列としてリターンする。
この関数はposで指定されるフィールドのテキストを削除する。
この関数はnew-posをold-posが属するフィールドに“拘束(constrain)”する。言い換えると、これは old-posと同じフィールド内でnew-posにもっとも近い位置をリターンする。
new-posがnil
なら、constrain-to-field
はかわりにポイントの値を使用してポイントをリターンすることに加えて、その位置にポイントを移動する。
old-posが2つのフィールドの境界なら、許容できる最後の位置は引数escape-from-edgeに依存する。escape-from-edgeがnil
なら、new-posは新たに文字がold-posが挿入されたときに継承するであろう値と、field
プロパティが等しいフィールドでなければならない。escape-from-edgeが非nil
ならnew-posは隣接する2つのフィールド内のどこでも構わない。さらに2つのフィールドが特別な値boundary
により他のフィールドで分割されている場合には、このスペシャルフィールド内のすべてのポイントも境界上とみなされる。
引数なしのC-aコマンドのように、特別な種類の位置に後方へ移動して一度そこに留まるには、おそらくescape-from-edgeにたいしてnil
を指定するべきであろう。フィールドをチェックする他の移動コマンドにたいしては、おそらくt
を渡すべきである。
オプション引数only-in-lineが非nil
、かつnew-posを通常の方法により拘束することにより異なる行へ移動するような場合には、new-posは非拘束でリターンされる。これはnext-line
やbeginning-of-line
のような行単位の移動コマンドで、それらのコマンドが正しい行へ移動できる場合のみフィールド境界を尊重するようにするために用いられる。
オプション引数inhibit-capture-propertyが非nil
、かつold-posがその名前の非nil
のプロパティをもつ場合には、すべてのフィールド境界は無視される。
変数inhibit-field-text-motion
を非nil
値にバインドすることにより、constrain-to-field
にすべてのフィールド境界を無視(何者にも拘束されることがない)させることができる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ユーザーにテキスト内のインターバル(訳注: 原文のインターバルはIT用語としては時間や距離などの間隔を示す用語として用いれることが多いと思いますが、ここでは『範囲』を示す言葉として用いられているようです。他の箇所で『範囲』と訳したrange等と異なる機能なので、ここではそのまま『インターバル』としました)を指定させて、そのインターバルにプロパティを追加するために、バッファー内のテキストへの属性の追加をサポートするエディターがいくつかあります。それらのエディターはユーザーやプログラマーが個別にインターバルの開始と終了を決定することを許可します。わたしたちはテキスト変更に関連する特定の逆説的振る舞いを避けるために、故意に異なる種類のインターフェイスをEmacs Lisp内に提供しました。
複数のインターバルに細分化することが実際に意味をもつなら、それは特定のプロパティをもつ単一のインターバルのバッファーと、同じテキストをもち両方が同じプロパティをもつ2つのインターバルに分割されたバッファーを区別できることを意味します。
インターバルを1つだけもつバッファーがあり、その一部をkillすることを考えてみてください。そのそのバッファーに残されるのは1つのインターバルであり、killリング(とundoリスト)内のコピーは別個のインターバルになります。そのkillされたテキストをyankで戻すと、同じプロパティをもつ2つのインターバルを得ることになります。したがって編集では1つのインターバルと2つのインターバルの違いは保たれません。
テキスト挿入時に2つのインターバルを結合することにより、この問題に“対応”したとします。これはそのバッファーが元々単一のインターバルだったなら上手く機能します。 しかしかわりに同じプロパティをもつ隣接する2つのインターバルがあり、そのうちの1つのインターバルからテキストをkillしてyankで戻すことを考えてみてください。あるケースを解決する同じインターバル結合機能が、他のケースにおいては問題を引き起こすのです。このyank後にインターバルはただ1つとなります。繰り返します、編集では1つのインターバルと2つのインターバルの違いは保たれないのです。
インターバルの間の境界上へのテキスト挿入においても満足できる回答が存在しないような問題が発生します。
しかし“バッファーにあるテキスト位置または文字列位置のプロパティは何か?”という形式の問にたいして、編集が一貫した振る舞いをするようアレンジするのは簡単です。そこでわたしたちはこれらが合理的な唯一の問いであると判断したのです。わたしたちはインターバルの開始と終了の場所を問うような実装をしませんでした。
実際には明白にインターバル境界であるような箇所では、通常はテキストプロパティ検索関数を使用できます。可能であるならインターバルは常に結合されるとみなすことにより、それらがインターバル境界を探すと考えることができます。テキストプロパティの検索関数を参照してください。
Emacsはプレゼンテーション機能として明示的なインターバルも提供します。オーバーレイを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数は文字コードにもとづいて指定されたリージョン内の文字を置き換えます。
この関数はstartとendで定義されるカレントバッファーのリージョン内に出現する文字old-charをnew-charに置き換える。
noundoが非nil
ならsubst-char-in-region
はundo用に変更を記録せず、バッファーを変更済みとマークしない。これは古い機能である選択的ディスプレイ(選択的な表示を参照)にとって有用だった。
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 ----------
この関数はバッファー内の位置startとendの間の文字にたいして、変換テーブル(translation table)を適用する。
変換テーブルtableは文字列か文字テーブル。(aref table
ochar)
はocharに対応した変換後の文字を与える。tableが文字列なら、tableの長さより大きいコードの文字はこの変更により変更されない。
translate-region
のリターン値は、その変換により実際に変更された文字数。変換テーブル内でその文字自身にマップされる文字は勘定に入らない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
レジスター(register)とは、Emacs内の編集においてさまざまな異なる種類の値を保持できる一種の変数です。レジスターはそれぞれ1文字で命名されます。すべてのASCII文字、およびそれらのメタ修飾された変種(ただしC-gは例外)をレジスターの命名に使用できます。したがって利用可能なレジスター数は255になります。Emacs Lispではレジスターは自身の名前となるその文字により指定されます。
この変数は要素が(name
.contents)
という形式のalist。使用中のEmacsレジスターごとに通常は1つの要素が存在する。
オブジェクトnameはレジスターを識別する文字(整数)。
レジスターのcontentsには、いくつかのタイプがある:
数字はそれ自身を意味する。insert-register
はレジスター内の数字を探して10進数に変換する。
マーカーはジャンプ先のバッファー位置を表す。
文字列の場合はレジスター内に保存されたテキスト。
矩形は文字列のリストを表す。
(window-configuration position)
これは1つのフレームにリストアされるウィンドウ構成、およびカレントバッファー内のジャンプ先の位置を表す。
(frame-configuration position)
これはリストア用のフレーム構成とカレントバッファー内のジャンプ先の位置。
これはvisitするファイルを表し、この値にジャンプすることによりファイルfilenameをvisitする。
これはvisitするファイルとファイル内の位置を表す。この値にジャンプすることによりファイルfilenameをvisitしてバッファー位置positionに移動する。このタイプの位置をリストアすると、まずユーザーにたいして確認を求める。
このセクションの関数は特に明記しない限り予期せぬ値をリターンします。
この関数はレジスターregのコンテンツ、コンテンツがなければnil
をリターンする。
この関数はレジスターregのコンテンツにvalueをセットする。レジスターには任意の値をセットできるが、その他のレジスター関数は特定のデータ型を期待する。リターン値はvalue。
このコマンドはレジスターregに何が含まれているかを表示する。
このコマンドはカレントバッファーにレジスターregのコンテンツを挿入する。
このコマンドは通常は挿入したテキストの前にポイント、後にマークを配置する。しかしオプションの第2引数beforepが非nil
ならマークを前、ポイントを後に配置する。インタラクティブな呼び出しでは、プレフィクス引数を与えることにより2つ目の引数beforepにnil
を渡すことができる。
このコマンドはインタラクティブに呼び出された際には、デフォルトではテキストの後にポイントを配置して、プレフィクス引数を与えるとこの反対の振る舞いを行う。
レジスターに矩形が含まれる場合には、その矩形はポイントの左上隅に挿入される。これはそのテキストがカレント行と、その下に続く行に挿入されることを意味する。
レジスターが保存されたテキスト(文字列)または矩形(リスク)以外の何かを含む場合には、現在のところは役に立つようなことは起きない。これは将来変更されるかもしれない。
この関数はprompt、およびもしかしたら既存レジスターとそのコンテンツをプレビューしてレジスターの名前を読み取ってレジスター名をリターンする。このプレビューはユーザーオプションregister-preview-delay
とregister-alist
がいずれも非nil
なら、register-preview-delay
で指定された遅延の後に一時ウィンドウ内に表示される。このプレビューはユーザーが(たとえばヘルプ文字のタイプにより)ヘルプを要求した場合にも表示される。レジスター名を読み取るンタラクティブな関数には、この関数の使用を推奨する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はテキストの一部を置き換えるために使用できます:
この関数はバッファーの重複しない2つの部分を交換する。引数start1とend1は一方の部分の両端、引数start2とend2はもう一方の部分の両端を指定する。
transpose-regions
は通常は置き換えたテキストにともないマーカーを再配置する。以前は2つの置き換えたテキストのうちの一方の部分に位置していたマーカーは、その部分とともに移動されるので、それを挟む2つの文字の新たな位置の間に留まることになる。しかしleave-markersが非nil
なら、transpose-regions
はこれを行わず、すべてのマーカーを再配置せずに残す。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
auto-compression-mode
が有効なときは、Emacsは圧縮されたファイルをvisitする際に自動的に解凍して、それを変更して保存する際は自動的に再圧縮します。Compressed
Files in The GNU Emacs Manualを参照してください。
上記の機能は外部の実行可能ファイル(例:
gzip
)を呼び出すことにより機能します。zlibライブラリーを使用したビルトインの解凍サポートつきでEmacsをコンパイルすることもでき、これは外部プログラムの実行に比べて高速です。
この関数はビルトインzlib解凍が利用可能なら非nil
をリターンする。
この関数はビルトインのzlib解凍を使用してstartとendの間のリージョンを解凍する。このリージョンにはgzipかzlibで圧縮されたデータが含まれていなければならない。成功したら、この関数はリージョンのコンテンツを解凍されたデータに置き換える。失敗すると関数はリージョンを未変更のままnil
をリターンする。この関数はユニバイトバッファーでのみ呼び出すことができる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Base64コードは8ビットシーケンスをより長いASCIIグラフィック文字シーケンスにエンコードするためにemail内で使用されます。これはインターネットRFC2045で定義されます14。このセクションでは、このコードへの変換および逆変換を行う関数について説明します。
この関数はbegからendのリージョンをBase64コードに変換する。これはエンコードされたテキストの長さをリターンする。リージョン内の文字がマルチバイトならエラーをシグナルする(マルチバイトバッファーではリージョンにはascii
、eight-bit-control
、eight-bit-graphic
の文字以外は含まれてはならない)。
この関数は通常は行が長くなりすぎるのを防ぐために、エンコードされたテキストに改行を挿入する。しかしオプション引数no-line-breakが非nil
なら、これらの改行は追加されず出力は長い単一の行となる。
この関数は文字列stringをBase64コードに変換する。これはエンコードされたテキストを含む文字列をリターンする。base64-encode-region
と同じように文字列内の文字がマルチバイトならエラーをシグナルする。
この関数は通常は行が長くなりすぎるのを防ぐためにエンコードされたテキストに改行を挿入する。しかしオプション引数no-line-breakが非nil
なら、これらの改行は追加されず結果となる文字列は長い単一の行となる。
この関数はbegからendのリージョンのBase64コードを対応するデコードされたテキストに変換する。これはデコードされたテキストの長さをリターンする。
デコード関数はエンコード済みテキスト内の改行文字を無視する。
この関数は文字列stringを、Base64コードから対応するデコード済みテキストに変換する。これはデコード済みテキストを含むユニバイトをリターンする。
デコード関数はエンコード済みテキスト内の改行文字を無視する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsには暗号化ハッシュ(cryptographic hashes)計算用のビルトインのサポートがあります。暗号化ハッシュ、またはチェックサム(checksum)とはデータ断片にたいするデジタルな指紋(fingerprint)であり、そのデータが変更されていないかチェックするために使用できます。
EmacsはMD5、SHA-1、SHA-2、SHA-224、SHA-256、SHA-384、SHA-512のような一般的な暗号化ハッシュアルゴリズムをサポートします。これらのアルゴリズムのうちMD5はもっとも古く、ネットワーク越しに転送されたメッセージの整合性をチェックするために一般的にはメッセージダイジェスト(message digests)内で使用されています。MD5は‘衝突耐性(collision resistant)をもたない(同じMD5ハッシュをもつ異なるデータ片を故意にデザインすることが可能)ので、セキュリティに関連することに使用するべきではありません。同様な理論上の欠点はSHA-1にも存在します。したがってセキュリティに関連するアプリケーションにたいしては、SHA-2のような他のハッシュタイプを使用するべきです。
この関数はobjectにたいするハッシュをリターンする。引数algorithmはどのハッシュを計算するかを示すシンボルでmd5
、sha1
、sha224
、sha256
、sha384
、sha512
のいずれか。引数objectはバッファーまたは文字列であること。
オプション引数startとendは、メッセージダイジェストを計算するobject部分を指定する文字位置。これらがnil
か省略なら、object全体にたいしてハッシュを計算する。
引数binaryが省略かnil
なら、通常のLisp文字列としてハッシュのテキスト形式(text
form)をリターンする。binaryが非nil
なら、ユニバイト文字列に格納されたバイトシーケンスとしてハッシュのバイナリー形式(binary
form)をリターンする。
この関数はobjectのテキストの内部表現(テキストの表現方法を参照)からハッシュを直接計算しない。かわりにコーディングシステム(コーディングシステムを参照)を使用してテキストをエンコードして、そのエンコード済みテキストからハッシュを計算する。objectがバッファーなら使用されているコーディングが、そのテキストをファイルに書き込むためのデフォルトとして選択される。objectが文字列ならユーザーの好むコーディングシステムが使用される(Recognize Coding in GNU Emacs Manualを参照)。
この関数はMD5ハッシュをリターンする。これはほとんどの目的において、algorithm引数にmd5
を指定してsecure-hash
を呼び出すのと等価であり半ば時代遅れである。引数のobject、start、endはsecure-hash
のときと同じ意味をもつ。
coding-systemが非nil
なら、それはテキストをエンコードするために使用するコーディングシステムを指定する。省略またはnil
なら、secure-hash
と同様にデフォルトコーディングシステムが使用される。
md5
は通常は指定や選択されたコーディングシステムを使用してテキストをエンコードできなければエラーをシグナルする。しかしnoerrorが非nil
なら、かわりに黙ってraw-text
コーディングシステムを使用する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsがlibxml2サポートつきでコンパイルされたときは、HTMLやXMLのテキストをLispオブジェクトツリーにパースするために以下の関数が利用可能です。
この関数はstartとendの間のテキストをHTMLとしてパースして、HTMLパースツリー(parse tree)を表すリストをリターンする。これは構文誤りにたいして強力に対処することにより、現実世界のHTMLの処理を試みる。
オプション引数base-urlが非nil
なら、それはリンク内に出現する相対URLにたいするベースURLを指定する文字列であること。
オプション引数discard-commentsが非nil
なら、パースツリーはコメントなしで作成される。
パースツリー内では各HTMLノードは1つ目の要素がノード名を表すシンボル、2つ目の要素がノード属性のalist、残りの要素はサブノードであるようなリストにより表される。
以下の例でこれを示す。以下の(不正な)HTMLドキュメントを与えると:
<html><head></head><body width=101><div class=thing>Foo<div>Yes
libxml-parse-html-region
呼び出しにより以下のDOM (document object
model)がリターンされる:
(html nil (head nil) (body ((width . "101")) (div ((class . "thing")) "Foo" (div nil "Yes"))))
この関数はdom内のパース済みHTMLをカレントバッファー内に描画する。引数domはlibxml-parse-html-region
で生成されるようなリストであること。この関数はたとえばEWW in The Emacs Web Wowser Manualにより使用される。
この関数はlibxml-parse-html-region
と同様だが、HTMLではなくXML(構文についてより厳格)としてテキストをパースする点が異なる。
31.26.1 Document Object Model | DOMにたいするアクセス、操作、検索。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
libxml-parse-html-region
(およびその他のXMLパース関数)がリターンするDOMはツリー構造です。このツリー構造ではそれぞれのノードがノード名(タグ(tag)と呼ばれる)をもち、オプションでkey/value値からなる属性(attribute)リスト、その後に子ノード(child
nodes)が続きます。子ノードは文字列かDOMオブジェクトのいずれかです。
(body ((width . "101")) (div ((class . "thing")) "Foo" (div nil "Yes")))
この関数はタイプtagのDOMノードを作成する。もしattributesが与えられたら、それはkey/valueペアのリストであること。もしchildrenが与えられたら、それはDOMノードであること。
この構造を処理するために以下の関数を使用できます。それぞれの関数はDOMノードかノードのリストを受け取ります。後者の場合には、そのリストの最初のノードだけが使用されます。
シンプルなアクセサー
dom-tag node
ノードのタグ (“ノード名”とも呼ばれる)をリターンする。
dom-attr node attribute
ノードの属性の値をリターンする。以下は一般的な使用例:
(dom-attr img 'href) => "http://fsf.org/logo.png"
dom-children node
ノードのすべての子をリターンする。
dom-non-text-children node
ノードのすべての非文字列の子をリターンする。
dom-attributes node
ノードの属性のkey/valueペアのリストをリターンする。
dom-text node
ノードのすべてのテキスト的な要素を連結された文字列としてリターンする。
dom-texts node
ノードのすべてのテキスト的な要素、およびノードのすべての子のテキスト的な要素を、連結された文字列として再帰的にリターンする。この関数はテキスト的な要素の間に挿入するオプションのセパレーターも受け取る。
dom-parent dom node
dom内でのnodeの親をリターンする。
以下はDOMを変更するための関数です。
dom-set-attribute node attribute value
ノードのattributeにvalueをセットする。
dom-append-child node child
nodeの最後の子としてchildを追加する。
dom-add-child-before node child before
nodeの子リストのノードbeforeの前にchildを追加する。beforeがnil
なら、childが最初の子になる。
dom-set-attributes node attributes
ノードのすべての属性を新たなkey/valueリストに置き換える。
以下はDOM内の要素を検索する関数です。これらはマッチしたノードのリストをリターンします。
dom-by-tag dom tag
dom内のタイプがtagのすべてのノードをリターンする。典型的な使用例は:
(dom-by-tag dom 'td) => '((td ...) (td ...) (td ...))
dom-by-class dom match
dom内のクラス名が正規表現matchにマッチするすべてのノードをリターンする。
dom-by-style dom style
dom内のスタイルが正規表現matchにマッチするすべてのノードをリターンする。
dom-by-id dom style
dom内のIDが正規表現matchにマッチするすべてのノードをリターンする。
dom-strings dom
DOM内のすべての文字列をリターンする。
ユーティリティ関数:
dom-pp dom &optional remove-empty
ポイント位置のdomにたいしてプリティプリント(pp: 優雅なプリント)を行う。remove-emptyなら空白文字だけを含むテキスト的ノードはプリントしない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
データベース用語においてのアトミック(atomic: 原子的、不可分)な変更とは、全体として成功か失敗をすることはできるが、部分的にはできない個別の変更のことです。Lispプログラムは単一もしくは複数のバッファーにたいする一連の変更をアトミック変更グループ(atomic change group)にすることができます。これはその一連の変更全体がそれらのバッファーに適用されるか、またはエラーの場合は何も適用されないかの、いずれかであることを意味します。
すでにカレントであるような単一のバッファーにたいしてこれを行うには、以下のように単に変更を行うコードの周囲にatomic-change-group
の呼び出しを記述します:
(atomic-change-group (insert foo) (delete-region x y))
atomic-change-group
のbody内部でエラー(またはその他の非ローカルexit)が発生した場合には、そのbodyの実行の間にそのバッファーでのすべての変更が行われなかったことになります。この類の変更グループは他のバッファーには影響を与えず、それらのバッファーにたいする変更はそのまま残されます。
さまざまなバッファー内で行った変更から1つのアトミックグループを構成する等、より複雑な何かを必要とする場合には、atomic-change-group
が使用する、より低レベルな関数を直接呼び出さなければなりません。
この関数はbuffer (デフォルトはカレントバッファー)にたいする変更グループをセットアップする。これはその変更グループを表すhandleをリターンする。変更グループをactivateしたり、その後でそれを完了するためにはこのhandleを使用しなければならない。
変更グループを使用するためには、それをactivate(アクティブ化)しなければなりません。これはbufferのテキストを変更する前に行わなければなりません。
これはhandleが指定する変更グループをactiveにする。
変更グループをactivateした後には、そのバッファー内で行ったすべての変更は変更グループの一部となります。そのバッファー内で目論んでいたすべての変更を行ったら、変更グループをfinish(完了)しなければなりません。すべての変更を受け入れる(確定する)か、すべてをキャンセルするという2つの方法により、これを行うことができます。
この関数はhandleにより指定される変更グループ内のすべての変更にたいして、finalizeすることにより変更を受け入れる。
この関数はhandleにより指定される変更グループ内のすべての変更をキャンセルしてundoする。
グループが常に確実にfinishされるようにするために、コードではunwind-protect
を使用するべきです。activate-change-group
の呼び出しは、実行直後にユーザーがC-gをタイプする場合に備えてunwind-protect
内部にあるべきです(これがprepare-change-group
とactivate-change-group
が別関数となっている1つの理由。なぜなら通常はunwind-protect
開始前にprepare-change-group
を呼び出すであろうから)。グループを一度finishしたら、そのhandleを再度使用してはなりません。特に同じ変更グループを2回finishしないでください。
複数バッファー変更グループ(multibuffer change
group)を作成するためには、カバーしたいバッファーそれぞれでprepare-change-group
を一度呼び出してから、以下のようにリターン値を結合するためにnconc
を使用してください:
(nconc (prepare-change-group buffer-1) (prepare-change-group buffer-2))
その後は1回のactivate-change-group
呼び出しで複数変更グループをアクティブにして、1回のaccept-change-group
かcancel-change-group
呼び出しでそれをfinishしてください。
同一バッファーにたいするネストされた複数の変更グループ使用は、あなたが期待するであろう通りに機能します。同一バッファーにたいするネストされていない変更グループの使用によりEmacsが混乱した状態になるので、これが発生しないようにしてください。与えられた何らかのバッファーにたいして最初に開始した変更グループは最後にfinishする変更グループです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のフック変数によりバッファー(これらをバッファーローカルにした場合には特定のバッファー)での変更にたいして、通知を受け取るようにアレンジすることができます。テキストの特定部分にたいする変更の検出方法については特殊な意味をもつプロパティも参照してください。
これらのフック内で使用する関数は、もしそれらが正規表現を使用して何かを行う場合にはマッチしたデータの保存とリストアを行うべきです。さもないとそれらが呼び出す編集処理に奇妙な方法で干渉するでしょう。
この変数はEmacsがバッファー変更を行おうとする際に呼び出す関数のリストを保持する。各関数は変更されようとするリージョンの先頭と終端を整数で表す2つの引数を受け取る。変更されようとするバッファーは関数の呼び出しの際には常にカレントバッファーである。
この変数はEmacsがバッファー変更を行った後に呼び出す関数のリストを保持する。各関数は正に変更されたリージョンの先頭と終端、およびその変更前に存在したテキストの長さという3つの引数を受け取る。これら3つの変数は、すべて整数。変更されたバッファーは関数の呼び出しの際には常にカレントバッファーである。
古いテキストの長さは、変更される前のテキストでのテキストの前後のバッファー位置の差で与えられる。変更されたテキストでは、その長さは単に最初の2つの引数の差で与えられる。
これらの関数は*Messages*バッファーへのメッセージの出力では呼び出されず、特定の処理用にEmacsが作成する内部的なバッファーのようなLispプログラムからは可視であるべきではないバッファーへの変更でも呼び出されません。
バッファーへのそれぞれの変更の周辺で、before-changeフックとafter-changeフックが釣り合いの取れたペアであることを期待しないでください。またEmacsが削除しようとするテキスト塊(chunk of text)ごとにbefore-changeフックが呼び出されることも期待してはなりません。これらのフックはLispプログラムがbefore-changeかafter-changeの両方ではなく、いずれかを使用するという想定で提供されており、その変更が発生したリージョン境界には実際に変更があったテキストだけではなく、少量にたいして行われた変更を複数集めて一塊とした変更さえ含まれるかもしれません。
このマクロは普通にbodyを実行するが、もしそれが安全なように見えるなら一連の複数の変更にたいして正に一度、after-change関数を呼び出すようにアレンジする。
そのバッファーの同じ領域内でプログラムが複数のテキスト変更を行う場合には、その部分のプログラムの周囲でマクロcombine-after-change-calls
を使用することにより、after-changeフック使用中の実行がかなり高速になり得る。after-changeフックが最終的に呼び出される際には、その引数はcombine-after-change-calls
のbody内で行われたすべての変更にたいして含むバッファーの範囲を指定する。
警告:
フォームcombine-after-change-calls
のbody内でafter-change-functions
の値を変更してはならない。
警告: 組み合わされた変更がバッファーの広い範囲に点在してに出現する場合でも、これは依然として機能するが推奨できない。なぜならこれは、ある変更フック関数を非効率的な挙動へと導くかもしれないからである。
この変数は以前は未変更の状態だったバッファーが変更された際は常に実行されるノーマルフック。
この変数が非nil
ならすべての変更フックは無効。それらは何も実行されない。これはこのセクションで説明したすべてのフック変数、同様に特定のスペシャルテキストプロパティ(特殊な意味をもつプロパティを参照)とオーバーレイプロパティ(オーバーレイのプロパティを参照)にアタッチされたフックに影響を与える。
これらの同一フック変数上の関数の実行の間、バッファー変更によるデフォルトの変更フックが他の変更フック実行中に実行されないように、この変数は非nil
にバインドされる。それ自体が変更フックから実行される特定のコード断片内で変更フックを実行したければ、inhibit-modification-hooks
をnil
にローカルに再バインドすること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このチャプターは文字に関する特別な問題と、それらが文字列やバッファーに格納される方法について網羅しています。
32.1 テキストの表現方法 | Emacsがテキストを表す方法。 | |
32.2 マルチバイト文字の無効化 | マルチバイト使用を制御する。 | |
32.3 テキスト表現の変換 | ユニバイトとマルチバイトの相互変換。 | |
32.4 表現の選択 | バイトシーケンスをユニバイトやマルチバイトとして扱う。 | |
32.5 文字コード | ユニバイトやマルチバイトが個々の文字のコードと関わる方法。 | |
32.6 文字のプロパティ | 文字の挙動と処理を定義する文字属性。 | |
32.7 文字セット | 利用可能な文字コード空間はさまざまな文字セットに分割される。 | |
32.8 文字セットのスキャン | バッファーで使用されている文字セットは? | |
32.9 文字の変換 | 変換に使用される変換テーブル。 | |
32.10 コーディングシステム | コーディングシステムはファイル保存のための変換である。 | |
32.11 入力メソッド | 入力メソッドによりユーザーは特別なキーボードなしで非ASCII文字を入力できる。 | |
32.12 locale | POSIX localeとの対話。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsのバッファーと文字列は、既知のスクリプトで記述されたほとんどすべてのテキストをユーザーがタイプしたり表示できるように、多種多様な言語の広大な文字レパートリーをサポートします。
多種多様な文字やスクリプトをサポートするために、EmacsはUnicode標準(Unicode
Standard)に厳密にしたがいます。Unicode標準はすべての文字それぞれにたいして、コードポイント(codepoint)と呼ばれる一意な番号を割り当てています。コードポイントの範囲はUnicode、またはUnicodeコード空間(codespace)により定義され、範囲は0..#x10FFFF
(16進表記、範囲両端を含む)です。Emacsはこれを範囲#x110000..#x3FFFFF
のコードポイント範囲に拡張します。この範囲はUnicodeとして統一されていない文字や、文字として解釈できない8ビットrawバイト(raw
8-bit bytes)を表すために使用します。したがってEmacs内の文字コードポイントは22ビットの整数になります。
メモリー節約のために、Emacsはバッファーや文字列内のテキスト文字にたいするコードポイントである22ビットの整数を固定長で保持しません。かわりにEmacsは文字の内部表現として可変長を使用します。これはそのコードポイントの値に応じて、各文字を5ビットから8ビットのバイトシーケンスとして格納するものです15。たとえばすべてのASCII文字は1バイト、Latin-1文字は2バイトといった具合です。わたしたちはこれをテキストのマルチバイト(multibyte)表現と呼んでいます。
Emacs外部ではISO-8859-1、GB-2312、Big-5等のような多種の異なるエンコーディングで文字を表すことができます。Emacsはバッファーや文字列へのテキスト読み込み時、およびディスク上のファイルへのテキスト書き込みや他プロセスへの引き渡し時に、これらの外部エンコーディングと内部表現の間で適切な変換を行います。
Emacsがエンコード済みテキストや非テキストデータをバッファーや文字列に保持したり操作する必要がある場合も時折あります。たとえばEmacsがファイルをvisitする際には、まずそのファイルのテキストをそのままバッファーに読み込んで、その後にのみそれを内部表現に変換します。この変換前にバッファーに保持されいるのはエンコード済みテキストです。
Emacsに関する限り、エンコードされたテキストは実際のテキストではなく8ビットrawバイトです。エンコード済みテキストを保持するバッファーや文字列は、Emacsがそれらを個々のバイトシーケンスとして扱うことから、ユニバイト(unibyte)のバッファー(文字列)と呼んでいます。Emacsは通常はユニバイトのバッファーや文字列を\237
のような8進コードで表示します。エンコード済みテキストやバイナリー非テキストデータを処理する場合を除いて、ユニバイトバッファーとユニバイト文字列は決して使用しないよう推奨します。
バッファーでは変数enable-multibyte-characters
のバッファーローカルな値が使用する表現を指定します。文字列での表現は文字列構築時に判断して、それを文字列内に記録します。
この変数はカレントバッファーのテキスト表現を指定する。非nil
ならバッファーはマルチバイトテキスト、それ以外ならエンコード済みユニバイトテキスト、またはバイナリー非テキストデータが含れる。
この変数は直接セットできない。バッファーの表現の変更には、かわりに関数set-buffer-multibyte
を使用すること。
バッファー位置は文字単位で測られる。この関数はカレントバッファー内のバッファー位置を、それに対応するバイト位置でリターンする。これはバッファー先頭を1としてバイト単位で増加方向に数えられる。positionが範囲外なら値はnil
。
カレントバッファー内で与えられたbyte-positionに対応するバッファー位置を文字単位でリターンする。byte-positionが範囲外なら値はnil
。マルチバイトバッファーではbyte-positionの任意の値が文字境界上になく、1文字として表現されたマルチバイトシーケンス内にあるかもしれない。この場合には関数はその文字のマルチバイトシーケンスがbyte-positionを含むようなバッファー位置をリターンする。言い換えるとこの値は同じ文字に属するすべてのバイト位置にたいして変化しない。
以下の2つの関数はバッファーにvisitされているファイル内でのバイトオフセットとバッファー位置をLispプログラムがマッピングする際に有用です。
この関数はposition-bytes
と似ているがカレントバッファー内でのバイト位置ではなく、バッファー内のpositionにより与えられる文字に対応するカレントバッファーのファイル先頭からのオフセットをリターンする点が異なる。この変換にはバッファーのファイル内でテキストがエンコードされる方法を知ることが要求される。これがcoding-system引数の存在意義であり、デフォルトはbuffer-file-coding-system
の値。オプション引数qualityは結果のあるべき正確さを指定する。これは以下いずれかであること:
exact
結果は正確でなければならない。関数はバッファーの大きな範囲をエンコードおよびデコードする必要があるだろう。
approximate
近似的な値が可能。関数は高価な処理を回避して不正確な結果をリターンするかもしれない。
nil
正確な結果に高価な処理を要するなら、関数は近似値ではなくnil
をリターンするだろう。これは引数が省略された場合のデフォルト。
この関数はbyte
(ファイル先頭からの0基準のバイトオフセット)が指定するファイル位置に対応するバッファー位置をリターンする。この関数はbufferpos-to-filepos
が行う変換と逆の処理を行う。オプション引数qualityとcoding-systemのもつ意味と値はbufferpos-to-filepos
の場合と同様。
stringがマルチバイト文字列ならt
、それ以外はnil
をリターンする。この関数はstringが文字列以外でもnil
をリターンする。
この関数はstring内のバイト数をリターンする。stringがマルチバイト文字列なら、これは(length
string)
より大きいかもしれない。
この関数は引数bytesをすべて結合して、その結果をユニバイト文字列で作成する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
デフォルトではEmacsはマルチバイトモードで開始されます。Emacsはマルチバイトシーケンスを使用して非ASCII文字を表現する内部エンコーディングを使用することにより、バッファーや文字列のコンテンツを格納します。マルチバイトモードでは、サポートされるすべての言語とスクリプトを使用できます。
非常に特別な状況下においては、特定のバッファーでマルチバイト文字のサポートを無効にしたいときがあるかもしれません。あるバッファーにおいてマルチバイト文字が無効になっているときには、それをユニバイトモード(unibyte mode)と呼びます。ユニバイトモードではバッファー内の各文字は0から255(8進の0377)の範囲の文字コードをもちます。0から127(8進の0177)はASCII文字、128から255(8進の0377)は非ASCII文字を表します。
特定のファイルをユニバイト表現で編集するためには、find-file-literally
を使用してファイルをvisitします。ファイルをvisitする関数を参照してください。マルチバイトバッファーをファイルに保存してバッファーをkillした後に、再びそのファイルをfind-file-literally
でvisitすることによりマルチバイトバッファーをユニバイトに変換できます。かわりにC-x
RET
c(universal-coding-system-argument
)を使用して、ファイルをvisitまたは保存するコーディングシステムとして‘raw-text’を指定することもできます。Specifying a Coding System for File Text in GNU Emacs
Manualを参照してください。find-file-literally
とは異なり、‘raw-text’としてファイルをvisitしてもフォーマット変換、解凍、自動的なモード選択は無効になりません。
バッファーローカル変数enable-multibyte-characters
はマルチバイトバッファーなら非nil
、ユニバイトバッファーならnil
です。マルチバイトバッファーかどうかはモードラインにも示されます。グラフィカルなディスプレイでのマルチバイトバッファーには文字セットを示すモードライン部分と、そのバッファーがマルチバイトであること(とそれ以外の事項)を告げるツールチップがあります。ユニバイトバッファーでは文字セットのインジケーターはありません。したがって(グラフィカルなディスプレイ使用時の)ユニバイトバッファーでは入力メソッドを使用していなければ、visitしているファイルの行末変換(コロン、バックスラッシュ等)の標識の前には通常は何も標識がありません。
特定のバッファーでマルチバイトサポートをオフに切り替えるには、そのバッファー内でコマンドtoggle-enable-multibyte-characters
を呼び出してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはユニバイトテキストをマルチバイトに変換できます。マルチバイトテキストに含まれるのがASCIIと8ビットrawバイトだけという条件つきでマルチバイトテキストからユニバイトへの変換もできます。一般的にこれらの変換はバッファーへのテキスト挿入時、または複数の文字列を1つの文字列に合成してテキストにputするときに発生します。文字列のコンテンツを明示的にいずれかの表現に変換することもできます。
Emacsはそのテキストの構成にもとづいて文字列の表現を選択します。一般的なルールではユニバイトテキストが他のマルチバイトテキストと組み合わされていればマルチバイト表現のほうがより一般的であり、ユニバイトテキストのすべての文字を保有できるのでユニバイトテキストをマルチバイトテキストに変換します。
バッファーへのテキスト挿入時にEmacsはそのバッファーのenable-multibyte-characters
の指定にしたがってテキストをそのバッファーの表現に変換します。特にユニバイトバッファーにマルチバイトテキストを挿入する際には、たとえ一般的にはマルチバイトテキスト内のすべての文字を保持することはできなくてもEmacsはテキストをユニバイトに変換します。バッファーコンテンツをマルチバイトに変換するという自然な代替方法は、そのバッファーの表現が自動的にオーバーライドできないユーザーによる選択にもとづく表現であるため許容されません。
ユニバイトテキストからマルチバイトテキストへの変換ではASCII文字は未変更のまま残されて、128から255のコードをもつバイトが8ビットrawバイトのマルチバイト表現に変換されます。
マルチバイトテキストからユニバイトテキストへの変換では、すべてのASCIIと8ビット文字が、それらの1バイト形式に変換されますが、各文字のコードポイントの下位8ビット以外は破棄されるために非ASCII文字の情報は失われます。ユニバイトテキストからマルチバイトテキストに変換してそれをユニバイトに戻せば、元のユニバイトテキストが再生成されます。
以下の2つの関数は引数string、またはテキストプロパティをもたない新たに作成された文字列のいずれかをリターンします。
この関数はstringと同じ文字シーケンスを含むマルチバイト文字列をリターンする。stringがマルチバイト文字列なら未変更のままそれがリターンされる。この関数はstringがASCII文字と8ビットrawバイトだけを含むと仮定する。後者は#x3FFF80
から#x3FFFFF
(両端を含む)に対応する8ビットrawバイトのマルチバイト表現に変換される(codepointsを参照)。
この関数はstringと同じ文字シーケンスを含むユニバイト文字列をリターンする。stringに非ASCII文字が含まれる場合にはエラーをシグナルする。stringがユニバイト文字列なら未変更のままそれがリターンされる。ASCII文字と8ビット文字だけを含むstring引数にたいしてのみこの関数を使用すること。
この関数は文字データbyteの単一バイトを含むユニバイト文字列をリターンする。byteが0から255までの整数でなければエラーをシグナルする。
これはマルチバイト文字charをユニバイト文字に変換してその文字をリターンする。charがASCIIと8ビットのいずれでもなければこの関数は-1をリターンする。
これはcharがASCIIか8ビットrawバイトのいずれかであると仮定してユニバイト文字ASCIIをマルチバイト文字に変換する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
既存のバッファーや文字列がユニバイトの際に、それらをマルチバイトとして調べたり、その逆を行うことが有用なときがあります。
カレントバッファーの表現タイプをセットする。multibyteが非nil
ならバッファーはマルチバイト、nil
ならユニバイト。
この関数はバイトシーケンスとして認識時にはバッファーを未変更のままとする。結果として文字として認識時にはコンテンツを変更できる。たとえばマルチバイト表現では1文字として扱われる3バイトのシーケンスは、ユニバイト表現では3文字として数えられるだろう。例外はrawバイトを表す8ビット文字。これらはユニバイトバッファーでは1バイトで表現されるが、バッファーをマルチバイトにセットした際は2バイトのシーケンスに変換されて、その逆の変換も行われる。
この関数はどの表現が使用されているかを記録するためにenable-multibyte-characters
をセットする。これは以前の同じテキストをカバーするように、バッファー内のさまざまなデータ(オーバーレイ、テキストプロパティ、マーカーを含む)を調整する。
ナローイングはマルチバイト文字シーケンス中間で発生するかもしれないので、この関数はバッファーがナローイングされている場合はエラーをシグナルする。
そのバッファーがインダイレクトバッファー(indirect buffer: 間接バッファー)の場合にもエラーをシグナルする。インダイレクトバッファーは常にベースバッファー(base buffer: 基底バッファー)の表現を継承する。
stringがすでにユニバイト文字列なら、この関数はstring自身をリターンする。それ以外はstringと同じバイトだが、それぞれの文字を個別の文字としてとして扱って新たな文字列をリターンする(値はstringより多くの文字をもつかもしれない)。例外としてrawバイトを表す8ビット文字は、それぞれ単一のバイトに変換される。新たに作成された文字列にテキストプロパティは含まれない。
stringがすでにマルチバイト文字列なら、この関数はstring自身をリターンする。それ以外はstringと同じバイトだが、それぞれのマルチバイトシーケンスを1つの文字としてとして扱って新たな文字列をリターンする。これは値がstringより少ない文字をもつかもしれないことを意味する。string内のバイトシーケンスが単一文字のマルチバイト表現として無効なら、そのシーケンスないの各バイトは8ビットrawバイトとして扱われる。新たに作成された文字列にはテキストプロパティは含まれない
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ユニバイトやマルチバイトによるテキスト表現は異なる文字コードを使用します。ユニバイト表現にたいして有効な文字コードの範囲は0から#xFF
(255)でこれは1バイト範囲に収まる値です。マルチバイト表現にたいして有効な文字コードの範囲は0から#x3FFFFF
です。このコード空間では値0から#x7F
(127)がASCII文字用、値#x80
(128)から#x3FFF7F
(4194175)が非ASCII文字用になります。
Emacsの文字コードは、Unicode標準のスーパーセット(superset:
上位集合)です。値0から#x10FFFF
(1114111)は同じコードポイントのUnicode文字に対応します。値#x110000
(1114112)から#x3FFF7F
(4194175)はUnicodeに統一されていない文字、値#x3FFF80
(4194176)から#x3FFFFF
(4194303)は8ビットrawバイトを表します。
これはcharcodeが有効な文字ならt
、それ以外はnil
をリターンする。
(characterp 65) ⇒ t
(characterp 4194303) ⇒ t
(characterp 4194304) ⇒ nil
この関数は有効な文字コードポイントが保有し得る最大の値をリターンする。
(characterp (max-char)) ⇒ t
(characterp (1+ (max-char))) ⇒ nil
この関数はカレントバッファー内の文字位置posにあるバイトをリターンする。カレントバッファーがユニバイトなら、その位置のバイトをそのままリターンする。バッファーがマルチバイトなら、8ビットrawバイトは8ビットコードに変換される一方で、ASCII文字のバ値は文字コードポイントと同じになる。この関数はposにある文字が非ASCIIならエラーをシグナルする。
オプション引数stringはカレントバッファーのかわりに文字列からバイト値を得ることを意味する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
文字プロパティ(character propertyとは、その文字の振る舞いとテキストが処理や表示される間にどのように処理されるべきかを指定する名前つきの文字属性です。したがって文字プロパティはその文字の意味を指定するための重要な一部です。
全体としてEmacsは自身の文字プロパティ実装においてはUnicode標準にしたがいます。特にEmacsはUnicode Character Property Modelをサポートしており、Emacs文字プロパティデータベースはUnicode文字データベース(UCD: Unicode Character Database)から派生したものです。Unicode文字プロパティとその意味についての詳細な説明はCharacter Properties chapter of the Unicode Standardを参照してください。このセクションでは、あなたがすでにUnicode標準の該当する章に親しんでいて、その知識をEmacs Lispプログラムに適用したいものと仮定します。
Emacsでは各プロパティは名前をもつシンボルであり、そのシンボルは利用可能な値セットをもち、値の型はプロパティに依存します。ある文字が特定のプロパティをもたなければ、その値はnil
になります。一般的なルールとしてEmacsでの文字プロパティ名は対応するUnicodeプロパティ名を小文字にして、文字‘_’をダッシュ文字‘-’で置き換えることにより生成されます。たとえばCanonical_Combining_Class
はcanonical-combining-class
となります。しかし簡単に使用できるように名前を短くすることもあります。
UCDによりいくつかのコードポイントは未割り当て(unassigned)のまま残されており、それらに対応する文字はありません。Unicode標準は、そのようなコードポイントのプロパティにたいしてデフォルト値を定義しています。それらについては以下の各プロパティごとに注記することにします。
以下はEmacsが関知するすべての文字プロパティにたいする値タイプの完全なリストです:
name
UnicodeプロパティName
に対応する。値はラテン大文字のAからZ、数字、スペース、ハイフン‘-’の文字から構成される文字列。未割り当てのコードポイントにたいする値はnil
。
general-category
UnicodeプロパティGeneral_Category
に対応する。値はその文字の分類をアルファベット2文字に略したものを名前としてもつようなシンボル。未割り当てのコードポイントにたいする値はCn
。
canonical-combining-class
UnicodeプロパティCanonical_Combining_Class
に対応する。値は整数。未割り当てのコードポイントにたいする値は0。
bidi-class
UnicodeプロパティBidi_Class
に対応する。値はその文字のUnicode方向タイプ(directional
type)が名前であるようなシンボル。Emacsは表示のために双方向テキストを並び替える際にこのプロパティを使用する(双方向テキストの表示を参照)。未割り当てのコードポイントにたいする値はそのコードポイントが属するコードブロックに依存する。未割り当てのコードポイントのほとんどはL
(強い左方向)だが、AL
( Arabic letter: アラビア文字)やR
(強い右方向)を受け取るコースポイントもいくつかある。
decomposition
UnicodeプロパティのDecomposition_Type
とDecomposition_Value
に対応する。値は最初の要素がsmall
のような互換性のあるフォーマットタグ(compatibility
formatting
tag)であるかもしれないリスト16。分割シーケンス(compatibility
decomposition
sequence)をもたない文字、および未割り当てのコードポイントにたいする値はその文字自身が唯一のメンバーであるようなリスト。
decimal-digit-value
Numeric_Type
が‘Decimal’であるような文字UnicodeプロパティNumeric_Value
に対応する。値は整数、その文字が10進値をもたなければnil
。未割り当てのコードポイントにたいする値は、NaNまたは“not
a number(数字ではない)”を意味するnil
。
digit-value
Numeric_Type
が‘Digit’であるような文字のUnicodeプロパティNumeric_Value
に対応する。値は整数。このような文字には互換性のある添字や上付き数字が含まれ、値は対応する数字。何も数値をもたない文字および未割り当てのコードポイントにたいする値はNaNを意味するnil
。
numeric-value
Numeric_Type
が‘Numeric’であるような文字のUnicodeプロパティNumeric_Value
に対応する。このプロパティの値は数字。このプロパティをもつ文字の例には分数、添字、上付き数字、ローマ数字、通貨分数(訳注:
原文は“currency
numerators”でベンガル語の分数値用の歴史的な記号を指すと思われる)、丸数字が含まれる。たとえば文字U+2155
(VULGAR
FRACTION ONE FIFTH:
(訳注)スラッシュで分子と分母を区切った表記による5分の1のこと)にたいするこのプロパティの値は0.2
。数値を何ももたない文字および未割り当てのコードポイントにたいする値はNaNを意味するnil
。
mirrored
UnicodeプロパティBidi_Mirrored
に対応する。このプロパティの値はY
かN
いずれかのシンボル。未割り当てのコードポイントにたいする値はN
。
mirroring
UnicodeプロパティBidi_Mirroring_Glyph
に対応する。このプロパティの値は、そのグリフ(glyph)がその文字のグリフの鏡像(mirror
image)を表すような文字、定義済みの鏡像グリフがなければnil
。mirrored
プロパティがN
であるようなすべての文字のmirroring
プロパティはnil
。しかしmirrored
プロパティがY
の文字でも、鏡像をもつ適切な文字がないという理由によりmirroring
がnil
の文字もある。Emacsは適切な際は鏡像を表示するためにこのプロパティを使用する(双方向テキストの表示を参照)。未割り当てのコードポイントにたいする値はnil
。
paired-bracket
UnicodeプロパティBidi_Paired_Bracket
に対応する。このプロパティの値は文字のpaired
bracket(カッコのペア)のコードポイント、その文字がbracket文字でなければnil
。これはUnicode双方向アルゴリズム(Unicode
Bidirectional Algorithm)によりカッコのペアとして扱われる文字間のマッピングを確立する。
Emacsは丸カッコ(parentheses)や角カッコ(braces)、およびその類の文字を再配置する方法を決定する際にこのプロパティを使用する(双方向テキストの表示を参照)。
bracket-type
UnicodeのBidi_Paired_Bracket_Type
プロパティに対応する。paired-bracket
プロパティが非nil
の文字にたいするこのプロパティはo
(開カッコ文字)かc
(閉カッコ文字)を表すシンボルのいずれか。paired-bracket
プロパティがnil
の文字にたいする値はn
(None: なし)。paired-bracket
と同じようにこのプロパティは双方向ディスプレーにより使用される。
old-name
UnicodeプロパティUnicode_1_Name
に対応する。値は文字列。未割り当てのコードポイント、およびこのプロパティにたいする値をもたない文字では値はnil
。
iso-10646-comment
UnicodeプロパティISO_Comment
に対応する。値は文字列かnil
。未割り当てのコードポイントにたいする値はnil
。
uppercase
UnicodeプロパティSimple_Uppercase_Mapping
に対応する。このプロパティの値は単一の文字。未割り当てのコードポイントの値はnil
であり、これはその文字自身を意味する。
lowercase
UnicodeプロパティSimple_Lowercase_Mapping
に対応する。このプロパティの値は単一の文字。未割り当てのコードポイントの値はnil
であり、これはその文字自身を意味する。
titlecase
UnicodeプロパティSimple_Titlecase_Mapping
に対応する。タイトルケース(title
case)とは単語の最初の文字を大文字にする必要がある際に使用される文字の特別な形式のこと。このプロパティの値は単一の文字。未割り当てのコードポイントにたいする値はnil
であり、これはその文字自身を意味する。
この関数はcharのプロパティpropnameの値をリターンする。
(get-char-code-property ?\s 'general-category) ⇒ Zs
(get-char-code-property ?1 'general-category) ⇒ Nd
;; U+2084 SUBSCRIPT FOUR (get-char-code-property ?\u2084 'digit-value) ⇒ 4
;; U+2155 VULGAR FRACTION ONE FIFTH (get-char-code-property ?\u2155 'numeric-value) ⇒ 0.2
;; U+2163 ROMAN NUMERAL FOUR (get-char-code-property ?\u2163 'numeric-value) ⇒ 4
(get-char-code-property ?\( 'paired-bracket) ⇒ 41 ;; closing parenthesis
(get-char-code-property ?\) 'bracket-type) ⇒ c
この関数はプロパティpropのvalueの説明文字列(description
string)、valueが説明をもたなければnil
をリターンする。
(char-code-property-description 'general-category 'Zs) ⇒ "Separator, Space"
(char-code-property-description 'general-category 'Nd) ⇒ "Number, Decimal Digit"
(char-code-property-description 'numeric-value '1/5) ⇒ nil
この関数は文字charのプロパティpropnameの値としてvalueを格納する。
この変数の値は、それぞれの文字にたいしてそのUnicodeプロパティGeneral_Category
をシンボルとして指定する文字テーブル(文字テーブルを参照)。
この変数の値は、それぞれの文字がシンボルを指定するような文字テーブル。シンボルの名前はUnicodeコードスペースからスクリプト固有ブロックへのUnicode標準分類にしたがうような、その文字が属するスクリプト。この文字テーブルは余分のスロットを1つもち、値はすべてのスクリプトシンボルのリスト。
この変数の値は、それぞれの文字がスクリーン上で占めるであろう幅を列単位で指定する文字テーブル。
この変数の値は、それぞれの文字にたいしてそれがプリント可能かどうかを指定する文字テーブル。すなわち(aref printable-chars
char)
を評価した結果がt
ならプリント可、nil
なら不可。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsの文字セット(character
set、もしくはcharset)とは、それぞれの文字が数字のコードポイントに割り当てられれた文字セットのことです(Unicode標準ではこれを符号化文字集合(coded
character
set)と呼ぶ)。Emacsの各文字セットはシンボルであるような名前をもちます。1つの文字が任意の数の異なる文字セットに属することができますが、各文字セット内で異なるコードポイントをもつのが一般的でしょう。文字セットの例にはascii
、iso-8859-1
、greek-iso8859-7
、windows-1255
が含まれます。文字セット内で文字に割り当てられるコードポイントは、Emacs内のバッファーや文字列内で使用されるコードポイントとは通常は異なります。
Emacsは特別な文字セットをいくつか定義しています。文字セットunicode
はEmacsコードポイントが0..#x10FFFF
の範囲のすべての文字セットを含みます。文字セットemacs
はすべてのASCII、および非ASCII文字を含みます。最後にeight-bit
文字セットは8ビットrawバイトを含みます。テキスト内でrawバイトを見つけたときにEmacsはこれを使用します。
objectは文字セットを命名するシンボルならt
、それ以外はnil
をリターンする。
値はすべての定義済み文字セットの名前のリスト。
この関数はすべての定義済み文字セットの優先順にソートされたリストをリターンする。highestpが非nil
なら、この関数はもっとも優先度の高い文字セット1つをリターンする。
この関数はcharsetsをもっとも高い優先度の文字セットにする。
この関数はcharacterが属する文字セットで、もっとも優先度の高い文字セットの名前をリターンする。ただしASCII文字は例外であり、この関数は常にascii
をリターンする。
restrictionが非nil
なら、それは検索する文字セットのリストであること。かわりにコーディングシステムも指定でき、その場合にはそのコーディングシステムによりサポートされている必要がある(コーディングシステムを参照)。
この関数は文字セットcharsetのプロパティをリターンする。たとえcharsetがシンボルだったとしても、これはそのシンボルのプロパティリストと同じではない。文字セットプロパティにはドキュメント文字列、短い名前等、その文字セットに関する重要な情報が含まれる。
この関数はcharsetのプロパティpropnameに与えられたvalueをセットする。
この関数はcharsetのプロパティpropnameの値をリターンする。
このコマンドは文字セットcharset内の文字のリストを表示する。
Emacsは文字の内部的な表現と、その文字の特定の文字セット内でのコードポイントを相互に変換することができます。以下はこれらをサポートするための関数です。
この関数はcharset内でcode-pointに割り当てられた文字をEmacsの対応する文字にデコードしてリターンする。そのコードポイントの文字がcharsetに含まれなければ値はnil
。code-pointがLisp整数(most-positive-fixnumを参照)に収まらなければ、コンスセル(high
. low)
で指定できる。ここでlowはその値の下位来る16ビット、highは上位16ビット。
この関数はcharset内で文字charに割り当てられたコードポイントをリターンする。結果がLisp整数に収まらなければ、上述のdecode-char
の2つ目の引数のようにコンスセル(high
.
low)
としてリターンされる。charsetがcharにたいするコードポイントをもたなければ値はnil
。
以下の関数は文字セット内の文字の一部、またはすべてにたいして特定の関数を適用するのに有用です。
charset内の文字にたいしてfunctionを呼び出す。functionは2つの引数で呼び出される。1つ目はコンスセル(from
.
to)
であり、fromとtoは文字セット内に含まれる文字の範囲。argは2つ目の引数としてfunctionに渡される。
デフォルトではfunctionに渡されるコードポイントの範囲にはcharset内のすべての文字が含まれるが、オプション引数from-codeとto-codeにより、それはcharsetの2つのコードポイント間にある文字範囲に制限される。from-codeかto-codeのいずれかがnil
の場合のデフォルトは、charsetのコードポイントの最初か最後。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
特定の文字がどの文字セットに属するか調べられると便利なときがあります。これの用途の1つは、どのコーディングシステム(コーディングシステムを参照)が問題となっているテキストすべてを表現可能か判断することです。他にもそのテキストを表示するフォントの判断があります。
この関数は、カレントバッファー内の位置posにある文字を含む、もっとも高い優先度の文字セットをリターンする。posが省略またはnil
の場合のデフォルトはポイントのカレント値。posが範囲外なら値はnil
。
この関数はカレントバッファー内の位置begからendの間の文字を含む、もっとも優先度の高い文字セットのリストをリターンする。
オプション引数translationはテキストのスキャンに使用するための変換テーブルを指定する(文字の変換を参照)。これが非nil
ならリージョン内の各文字はそのテーブルを通じて変換され、リターンされる値にはバッファーの実際の文字ではなく変換された文字が記述される。
この関数はstring内の文字を含む、もっとも優先度の高い文字セットのリストをリターンする。これはfind-charset-region
と似ているが、カレントバッファーの一部ではなくstringのコンテンツに適用される点が異なる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
変換テーブル(translation table)とは文字から文字へのマッピングを指定する文字テーブルです(文字テーブルを参照)。これらのテーブルはエンコーディング、デコーディング、および他の用途にも使用されます。独自に変換テーブルを指定するコーディングシステムもいくつかあります。他のすべてのコーディングシステムに適用されるデフォルトの変換テーブルも存在します。
変換テーブルには余分のスロット(extra
slots)が2つあります。1つ目のスロットはnil
、または逆の変換を処理する変換テーブルです。2つ目のスロットは変換する文字シーケンスを照合する際の最大文字数です(以下のmake-translation-table-from-alist
の説明を参照)。
この関数は引数translationsにもとづいて変換テーブルをリターンする。translationsの各要素は(from
. to)
という形式のリストであること。これはfromからtoへの文字の変換を指示する。
各引数内の引数とフォームは順に処理され、もし前のフォームですでにtoがたとえばto-altに変換されていればfromもto-altに変換される。
デコードを行う間、その変換テーブルの変換は通常のデコーディングの結果の文字に適用されます。あるコーディングシステムがプロパティ:decode-translation-table
をもつなら、それは使用する変換テーブル、または順に適用するべき変換テーブルのリストを指定します(これはコーディングシステムの名前であるようなシンボルのプロパティではなく、coding-system-get
がリターンするようなコーディングシステムのプロパティ。Basic Concepts of Coding
Systemsを参照)。最後にもしstandard-translation-table-for-decode
が非nil
なら、結果となる文字はそのテーブルにより変換されます。
エンコードを行う間は、その変換テーブルの変換はバッファー内の文字に適用されて、変換結果は実際にエンコードされます。あるコーディングシステムがプロパティ:encode-translation-table
をもつならそれは使用する変換テーブル、または順に適用するべき変換テーブルのリストを指定します。加えてもし変数standard-translation-table-for-encode
が非nil
なら、それは変換結果にたいして使用するべき変換テーブルを指定します。
これはデコード用のデフォルトの変換テーブル。あるコーディングシステムが独自に変換テーブルを指定する場合には、この変数の値が非nil
なら、それら独自のテーブルを適用後にこの変数の変換テーブルが適用される。
これはエンコード用のデフォルトの変換テーブル。あるコーディングシステムが独自に変換テーブルを指定する場合には、この変数の値が非nil
ならそれら独自のテーブル適用後にこの変数の変換テーブルが適用される。
自己挿入文字は挿入前にこの変換テーブルを通じて変換が行われる。検索コマンドもバッファー内の内容とより信頼性のある比較ができるようにこのテーブルを通じて入力を変換する。
この変数はセット時に自動的にバッファーローカルになる。
この関数はバイト(値は0から#xFF)から文字にマップする256要素の配列であるような、vecから作成した変換テーブルをリターンする。未変換のバイトにたいする要素はnil
かもしれない。リターンされるテーブルは余分な1つ目のスロットにそのマッピングを保持する変換テーブル、2つ目の余分なスロットに値1
をもつ。
この関数は各バイトを特定の文字にマップするようなプライベートなコーディングシステムを簡単に作成する手段を提供する。define-coding-system
のprops引数のプロパティ:decode-translation-table
と:encode-translation-table
に、リターンされるテーブルと逆変換テーブルを指定できる。
この関数はmake-translation-table
と似ているが、シンプルな1対1のマッピングを行う変換テーブルではなく、より複雑な変換テーブルをリターンする。alistの各要素は(from
.
to)
という形式をもち、ここでfromおよびtoは文字または文字シーケンスを指定するベクター。fromが文字なら、その文字はto(文字か文字シーケンス)に変換される。fromが文字のベクターならそのシーケンスはtoに変換される。リターンされるテーブルは1つ目の余分なスロットに逆のマッピングを行う変換テーブル、2つ目の余分なスロットには文字シーケンスfromすべての最大長をもつ。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsがファイルにたいして読み書きをしたりサブプロセスとテキストの送受信を行う際には、通常は特定のコーディングシステム(coding system)の指定にしたがって文字コード変換や行末変換を行います。
コーディングシステムの定義は難解な問題であり、ここには記述しません。
32.10.1 コーディングシステムの基本概念 | 基本的な概念。 | |
32.10.2 エンコーディングとI/O | ファイル入出力関数がコーディングシステムを扱う方法。 | |
32.10.3 Lispでのコーディングシステム | コーディングシステム名を処理する関数。 | |
32.10.4 ユーザー選択のコーディングシステム | ユーザーにコーディングシステムの選択を求める。 | |
32.10.5 デフォルトのコーディングシステム | デフォルトの選択の制御。 | |
32.10.6 単一の操作にたいするコーディングシステムの指定 | 単一ファイル処理にたいして特定のコーディングシステムを要求する。 | |
32.10.7 明示的なエンコードとデコード | 入出力を伴わないテキストのエンコードおよびデコード。 | |
32.10.8 端末I/Oのエンコーディング | 端末入出力にたいするエンコーディングの使用。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
文字コード変換(character code conversion)により、Emacs内部で使用される文字の内部表現と他のエンコーディングの間で変換が行われます。Emacsは多くの異なるエンコーディングをサポートしており、それらは双方向に変換が可能です。たとえばLatin 1、Latin 2、Latin 3、Latin 4、Latin 5、およびいくつかのISO 2022の変種等のようなエンコーディングにたいしてテキストを双方向に変換できます。あるケースにおいては同じ文字にたいしてEmacsは複数のエンコーディング候補をサポートします。たとえばキリル(ロシア語)のアルファベットにたいしてはISO、Alternativnyj、KOI8のように3つにコーディングシステムが存在します。
コーディングシステムはそれぞれ特定の文字コード変換セットを指定しますが、undecided
というコーディングシステムは特別です。これはそれぞれのファイルにたいして、そのファイルのデータにもとづいて発見的に選択が行われるように選択を未指定のままに留めます。
コーディングシステムは一般的に可逆的な同一性を保証しません。あるコーディングシステムを使用してバイトシーケンスをデコードしてから、同じコーディングシステムで結果テキストをエンコードしても異なるバイトシーケンスが生成される可能性があります。しかしデコードされたオリジナルのバイトシーケンスとなることを保証するコーディングシステムもいくつかあります。以下にいくつかの例を挙げます:
iso-8859-1、utf-8、big5、shift_jis、euc-jp
バッファーテキストのエンコードと結果のデコードでもオリジナルテキストの再生成に失敗する可能性があります。たとえばその文字をサポートしないコーディングシステムで文字をエンコードした場合の結果は予測できず、したがって同じコーディングシステムを使用してそれをデコードしても異なるテキストが生成されるでしょう。現在のところEmacsは未サポート文字のエンコーディングによる結果をエラーとして報告できません。
行末変換(end of line conversion: 改行変換)はファイル内の行末を表すために、さまざまなシステム上で使用される3つの異なる慣例を扱います。GNUやUnixシステムで使用されるUnixの慣例ではLF文字(linefeed文字、改行とも呼ばれる)が使用されます。MS-WindowsやMS-DOSシステムで使用されるDOSの慣例では行末にCR文字(carriage-return文字、復帰文字とも呼ばれる)とLF文字が使用されます。Macの慣例ではCR文字だけが使用されます(これはOS X以前のMacintoshシステムで使用されていた慣例)。
latin-1
のようなベースコーディングシステム(base coding systems:
基本コーディングシステム)では、データにもとづいて選択されるように行末変換は未指定となっています。latin-1-unix
、latin-1-dos
、latin-1-mac
のようなバリアントコーディングシステム(variant
coding systems:
変種コーディングシステム)では行末変換を明示的に指定します。ほとんどのベースコーディングシステムは‘-unix’、‘-dos’、‘-mac’を追加した3つの対応する形式の変種をもちます。
raw-text
は文字コード変換を抑制して、このコーディングシステムでvisitされたバッファーがユニバイトバッファーとなる点において特殊なコーディングシステムです。歴史的な理由によりこのコーディングシステムによりユニバイトとマルチバイト両方のテキストを保存できます。マルチバイトテキストのエンコードにraw-text
を使用した際には1文字コード変換を行います。8ビット文字は1バイトの外部表現に変換されます。raw-text
は通常のようにデータにより判断できるように行末変換を指定せず、通常のように行末変換を指定する3つの変種をもちます。
no-conversion
(とエイリアスのbinary
)はraw-text-unix
と等価です。これは文字コードおよび行末にたいする変換をいずれも指定しません。
utf-8-emacs
はデータがEmacsの内部エンコーディング(テキストの表現方法を参照)で表されることを指定するコーディングシステムです。コード変換が何も発生しない点ではこれはraw-text
と似ていますが、結果がマルチバイトデータである点が異なります。emacs-internal
という名前はutf-8-emacs
にたいするエイリアスです。
この関数はコーディングシステムcoding-systemの指定されたプロパティをリターンする。コーディングシステムのプロパティのほとんどは内部的な目的のために存在するが、:mime-charset
については有用と思うかもしれない。このプロパティの値はそのコーディングシステムが読み書きできる文字コードにたいしてMIME内で使用される名前。以下は例:
(coding-system-get 'iso-latin-1 :mime-charset) ⇒ iso-8859-1 (coding-system-get 'iso-2022-cn :mime-charset) ⇒ iso-2022-cn (coding-system-get 'cyrillic-koi8 :mime-charset) ⇒ koi8-r
:mime-charset
プロパティの値はそのコーディングシステムにたいするエイリアスとしても定義されている。
この関数はcoding-systemのエイリアスのリストをリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コーディングシステムの主な目的はファイルの読み込みと書き込みへの使用です。関数insert-file-contents
はファイルデータのデコードにコーディングシステムを使用して、write-region
はバッファーコンテンツのエンコードにコーディングシステムを使用します。
使用するコーディングシステムは明示的(単一の操作にたいするコーディングシステムの指定を参照)、またはデフォルトメカニズム(デフォルトのコーディングシステムを参照)を使用して暗黙的に指定できます。しかしこれらの手法は何を行うかを完全には指定しないかもしれません。たとえばこれらはデータから文字コード変換を行わないundefined
のようなコーディングシステムを選択するかもしれません。このような場合にはI/O処理はコーディングシステム選択によって処理を完了します。後でどのコーディングシステムが選択されたか調べたいことが頻繁にあるでしょう。
このバッファーローカル変数はバッファーの保存、およびwrite-region
によるバッファー部分のファイルへの書き出しに使用されるコーディングシステムを記録する。書き込まれるテキストがこの変数で指定されたコーディングシステムを使用して安全にエンコードできない場合には、これらの操作は関数select-safe-coding-system
を呼び出すことにより代替となるエンコーディングを選択する(ユーザー選択のコーディングシステムを参照)。異なるエンコーディングの選択がユーザーによるコーディングシステムの指定を要するなら、buffer-file-coding-system
は新たに選択されたコーディングシステムに更新される。
buffer-file-coding-system
はサブプロセスへのテキスト送信に影響しない。
この変数は、(buffer-file-coding-system
をオーバーライドして)バッファーを保存するためのコーディングシステムを指定する。これはwrite-region
には使用されないことに注意。
あるコマンドがバッファーを保存するためにbuffer-file-coding-system
(またはsave-buffer-coding-system
)の使用を開始して、そのコーディングシステムがバッファー内の実際のテキストを処理できなければ、(select-safe-coding-system
を呼び出すことにより)そのコマンドは他のコーディングシステムの選択をユーザーに求める。これが発生した後はコマンドはユーザー指定のコーディングシステムを表すためにbuffer-file-coding-system
の更新も行う。
ファイルやサブプロセスにたいするI/O操作は、使用したコーディングシステムの名前をこの変数にセットする。明示的にエンコードとデコードを行う関数(明示的なエンコードとデコードを参照)もこの変数をセットする。
警告: サブプロセス出力の受信によりこの変数がセットされるため、この変数はEmacsがwaitしている際は常に変更され得る。したがって興味対象となる値を格納する関数呼び出し後は、間を空けずにその値をコピーすること。
変数selection-coding-system
はウィンドウシステムにたいして選択(selection)をエンコードする方法を指定します。ウィンドウシステムによる選択を参照してください。
変数file-name-coding-system
はファイル名のエンコーディングに使用するコーディングシステムを指定する。Emacsは、すべてのファイル操作にたいして、ファイル名のエンコードにそのコーディングシステムを使用する。file-name-coding-system
がnil
ならEmacsは選択された言語環境(language
environment)により決定されたデフォルトのコーディングシステムを使用する。デフォルト言語環境ではファイル名に含まれるすべての非ASCII文字は特別にエンコードされない。これらはEmacsの内部表現を使用してファイルシステム内で表される。
警告: Emacsのセッション中にfile-name-coding-system
(または言語環境)を変更した場合には、以前のコーディングシステムを使用してエンコードされた名前をもつファイルをvisitしていると、新たなコーディングシステムでは異なるように扱われるので問題が発生し得る。これらのvisitされたファイル名でこれらのバッファーの保存を試みると、保存で間違ったファイル名が使用されたりエラーとなるかもしれない。そのような問題が発生したら、そのバッファーにたいして新たなファイル名を指定するためにC-x
C-wを使用すること。
Windows 2000以降ではEmacsはOSに渡すファイル名にデフォルトでUnicode
APIを使用するため、file-name-coding-system
の値は大部分が無視される。Lispレベルでファイル名のエンコードやデコードを必要とするLispアプリケーションは、system-type
がwindows-nt
のときはutf-8
をコーディングシステムに使用すること。UTF-8でエンコードされたファイル名から、OSと対話するために適したエンコーディングへの変換はEmacsにより内部的に処理される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はコーディングシステムと連携するLisp機能です:
この関数はすべてのコーディングシステムの名前(シンボル)をリターンする。base-onlyが非nil
なら、値にはベースコーディングシステムだけが含まれる。それ以外ならエイリアス、およびバリアントコーディングシステムも同様に含まれる。
この関数はobjectがコーディングシステムの名前ならt
、またはnil
をリターンする。
この関数はcoding-systemの有効性をチェックする。有効ならcoding-systemをリターンする。coding-systemがnil
なら、この関数はnil
をリターンする。それ以外の値にたいしてはerror-symbol
がcoding-system-error
であるようなエラーをシグナルする(signalを参照)。
この関数は行末(eolとも言う)をcoding-systemで使用されるタイプに変換する。coding-systemが特定のeol変換を指定する場合にはリターン値は0、1、2のいずれかであり、それらは順にunix
、dos
、mac
を意味する。coding-systemが明示的にeol変換を指定しなければ、リターン値は以下のようにそれぞれが可能なeol変換タイプをもつようなコーディングシステムのベクター:
(coding-system-eol-type 'latin-1) ⇒ [latin-1-unix latin-1-dos latin-1-mac]
この関数がベクターをリターンしたら、Emacsはテキストのエンコードやデコードプロセスの一部として使用するeol変換を決定するだろう。デコードではテキストの行末フォーマットは自動検知され、eol変換はそれに適合するようセットされる(DOSスタイルのCRLFフォーマットは暗黙でeol変換にdos
をセットする)。エンコードにたいしては適切なデフォルトコーディングシステム(buffer-file-coding-system
にたいするbuffer-file-coding-system
のデフォルト値)、または背景にあるプラットフォームにたいして適切なデフォルトeol変換が採用される。
この関数はcoding-systemと似ているがeol-type
で指定されたeol変換の異なるコーディングシステムをリターンする。eol-typeはunix
、dos
、mac
、またはnil
であること。これがnil
ならリターンされるコーディングシステムは、データのeol変換により決定される。
eol-typeはunix
、dos
、mac
を意味する0、1、2でもよい。
この関数はeol-codingの行末変換と、text-codingのテキスト変換を使用するコーディングシステムをリターンする。text-codingがnil
ならこれはundecided
、またはeol-codingに対応するバリアントの1つをリターンする。
この関数はfromとtoの間のテキストのエンコードに使用可能なコーディングシステムのリストをリターンする。このリスト内のすべてのリストは、そのテキスト範囲内にあるすべてのマルチバイト文字を安全にエンコードできる。
そのテキストがマルチバイト文字を含まれなければ、この関数はリスト(undecided)
をリターンする。
この関数はstringのテキストのエンコードに使用可能な、コーディングシステムのリストをリターンする。このリスト内のすべてのリストはstringにあるすべてのマルチバイト文字を安全にエンコードできる。そのテキストがマルチバイト文字を含まれなければ、この関数はリスト(undecided)
をリターンする。
この関数はリストcharsets内のすべての文字セットのエンコードに使用可能なコーディングシステムのリストをリターンする。
この関数はリストcoding-system-list
内のコーディングシステムがstartとendの間のリージョン内にあるすべての文字をエンコード可能かどうかをチェックする。このリスト内のすべてのコーディングシステムが指定されたテキストをエンコード可能なら、この関数はnil
をリターンする。ある文字をエンコードできないコーディングシステムがある場合には、各要素が(coding-system1
pos1 pos2
…)
という形式のalistが値となる。これはcoding-system1がバッファーの位置pos1、pos2、...にある文字をエンコードできないことを意味する。
startは文字列かもしれず、その場合にはendは無視されてリターン値はバッファー位置のかわりに文字列のインデックスを参照することになる。
この関数はstartからendのテキストのデコードに適したコーディングシステムを選択する。このテキストはバイトシーケンス、すなわちユニバイトテキスト、ASCIIのみのマルチバイトテキスト、8ビット文字のシーケンスであること(明示的なエンコードとデコードを参照)。
この関数は通常はスキャンしたテキストのデコーディングを処理可能なコーディングシステムのリストをリターンする。これらのコーディングシステムは優先度降順でリストされる。しかしhighestが非nil
なら、リターン値はもっとも高い優先度のコーディングシステムただ1つとなる。
リージョンにISO-2022のESC
のようなISO-2022制御文字を除いてASCII文字だけが含まれる場合には値はundecided
、(undecided)
、またはテキストから推論可能ならeol変換を指定するバリアントとなる。
リージョンにnullバイトが含まれる場合には、あるコーディングシステムによりエンコードされたテキストがリージョン内に含まれる場合でも値はno-conversion
となる。
この関数はdetect-coding-region
と似ているがバッファー内のバイトのかわりにstringのコンテンツを処理する点が異なる。
この変数が非nil
値をもつなら、リージョンや文字列のエンコーディング検出時にnullバイトを無視する。これによりIndexノードをもつInfoファイルのようなnullバイトを含むテキストのエンコーディングを正しく検出できる。
この変数が非nil
値をもつなら、リージョンや文字列のエンコーディング検出時にISO-2022エスケープシーケンスを無視する。結果としてこれまでいくつかのISO-2022エンコーディングにおいてエンコード済みと検出されていたテキストがなくなり、バッファー内ですべてのエスケープシーケンスが可視になる。警告:
この変数の使用には特に注意を払うこと。なぜならEmacsディストリビューション内で多くのファイルがISO-2022エンコーディングを使用するからである。
この関数はcoding-systemがサポートする文字セット(文字セットを参照)のリストをリターンする。リストすべき文字セットを非常に多くサポートするいくつかのコーディングシステムでは特別な値がリストされる:
(emacs)
。
(unicode)
。
iso-2022
。
emacs-mule
。
サブプロセスへの入出力に使用されるコーディングシステムのチェックやセットの方法についてはProcess
Information、特に関数process-coding-system
やset-process-coding-system
の説明を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数は指定されたテキストをエンコードするために、必要ならユーザーに選択を求めてコーディングシステムを選択する。指定されるテキストは通常はカレントバッファーのfromとtoの間のテキスト。fromが文字列なら、その文字列がエンコードするテキストを指定して、toは無視される。
指定されたテキストにrawバイト(テキストの表現方法を参照)が含まれる場合には、select-safe-coding-system
はそのエンコーディングにraw-text
を提案する。
default-coding-systemが非nil
なら、それは試行すべき最初のコーディングシステムである。それがテキストを処理できるなら、select-safe-coding-system
はそのコーディングシステムをリターンする。これはコーディングシステムのリストの可能性もある。その場合にはこの関数はそれらを1つずつ試みる。それらをすべて試した後に、(undecided
以外なら)カレントバッファーのbuffer-file-coding-system
の値、次にbuffer-file-coding-system
のデフォルト値、最後にユーザーがもっとも好むコーディングシステム(コマンドprefer-coding-system
でセットできる最優先されるコーディングシステム)を試みる(Recognizing Coding Systems in The GNU Emacs Manualを参照)。
これらのうちいずれかのコーディングシステムが指定されたテキストすべてを安全にエンコード可能なら、select-safe-coding-system
はそれを選択およびリターンする。それ以外ならコーディングシステムのリストからすべてのテキストをエンコードできるコーディングシステムの選択をユーザーに求めてユーザーの選択をリターンする。
default-coding-systemは最初の要素がtで、他の要素がコーディングシステムであるようなリストかもしれない。その場合には、もしリスト内にテキストを処理できるコーディングシステムがなければ、select-safe-coding-system
は上述した3つの代替えいずれを試みることなく即座にユーザーに問い合わせる。
オプション引数accept-default-pが非nil
なら、それはユーザーとの対話なしで選択されたコーディングシステムが許容できるかどうかを判断する関数であること。select-safe-coding-system
は選択されたコーディングシステムのベースコーディングシステムを唯一の引数としてこの関数を呼び出す。accept-default-pがnil
をリターンしたら、select-safe-coding-system
は選択されたコーディングシステムを暗黙に拒絶して、可能な候補リストからコーディングシステムの選択をユーザーに求める。
変数select-safe-coding-system-accept-defaultf-p
が非nil
なら、それは1つの引数をとる関数であること。これはaccept-default-p引数に与えられた値をオーバーライドすることによりaccept-default-pのかわりに使用される。
最後のステップとして選択されたコーディングシステムをリターンする前に、select-safe-coding-system
はもしリージョンのコンテンツがファイルから読み込まれたものだったとしたなら選択されたであろうコーディングシステムと、そのコーディングシステムが一致するかどうかをチェックする(異なるならその後の再visitと編集でファイル内のデータ汚染が起こり得る)。select-safe-coding-system
は通常はこの目的のためのファイルとしてbuffer-file-name
を使用するが、fileが非nil
ならかわりにそのファイルを使用する(これはwrite-region
や類似の関数に関連し得る)。明らかな不一致が検出された場合にはselect-safe-coding-system
はそのコーディングシステムを選択する前にユーザーに問い合わせる。
以下の2つの関数は補完つきでユーザーにコーディングシステムの選択を求めるために使用できます。補完を参照してください。
この関数は文字列promptをプロンプトにミニバッファーを使用してコーディングシステムを読み取り、そのコーディングシステムの名前をシンボルとしてリターンする。defaultはユーザーの入力が空の場合にリターンするべきコーディングシステムを指定する。これはシンボルか文字列であること。
この関数は文字列promptをプロンプトにミニバッファーを使用してコーディングシステムを読み取り、そのコーディングシステムの名前をシンボルとしてリターンする。ユーザーが空の入力を試みると再度ユーザーに問い合わせを行う。コーディングシステムを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは特定のファイルや特定のサブプロセス実行時のデフォルトコーディングシステムを指定する変数、およびそれらへアクセスするためのI/O処理が使用する関数について説明します。
これらの変数は希望するデフォルトにそれらすべてを一度セットして、その後は再びそれを変更しないというアイデアにもとづいています。Lispプログラム内の特定の処理で特定のコーディングシステムを指定するために、これらの変数を変更しないでください。かわりにcoding-system-for-read
やcoding-system-for-write
を使用して、それらをオーバーライドしてください(単一の操作にたいするコーディングシステムの指定を参照)。
この変数はテキストパターンと対応するコーディングシステムのalist。要素はそれぞれ(regexp
.
coding-system)
という形式をもつ。冒頭の数キロバイトがregexpにマッチするファイルは、そのコンテンツをバッファーに読み込む際にcoding-systemによりデコードされる。このalist内のセッティングはファイル内のcoding:
タグ、およびfile-coding-system-alist
(以下参照)の内容より優先される。デフォルト値は、Emacsが自動的にBabylフォーマットのメールファイルを認識してコード変換なしでそれらを読み取れるようにセットされている。
この変数は特定のファイルの読み書きに使用するコーディングシステムを指定するalist。要素はそれぞれ(pattern
.
coding)
という形式をもち、patternは特定のファイル名にマッチする正規表現。この要素はpatternにマッチするファイル名に適用される。
要素のCDRとなるcodingはコーディングシステム、2つのコーディングシステムを含むコンスセル、または関数名(関数定義をもつシンボル)であること。codingがコーディングシステムなら、そのコーディングシステムはファイルの読み込みと書き込みの両方で使用される。codingが2つのコーディングシステムを含むコンスセルなら、CARはデコード用のコーディングシステム、CDRはエンコード用のコーディングシステムを指定する。
codingが関数名なら、それはfind-operation-coding-system
に渡されたすべての引数からなるリストを唯一の引数とする関数であること。これはコーディングシステム、または2つのコーディングシステムを含むコンスセルをリターンしなければならない。この値は上記と同じ意味をもつ。
coding (または上記関数のリターン値)がundecided
なら通常のコード検出が行われる。
この変数は特定のファイルの読み書きに使用するコーディングシステムを指定するalist。この変数の形式はfile-coding-system-alist
の形式と似ているが、後者と異なるのはこの変数がファイル内のcoding:
タグより優先されること。
この変数は何のプログラムがサブプロセス内で実行中かによって、そのサブプロセスにたいしてどのコーディングシステムを使用するかを指定するalist。これはfile-coding-system-alist
と同じように機能するが、patternがそのサブプロセスを開始するために使用されたプログラム名にたいしてマッチされる点が異なる。コーディングシステム、またはalist内で指定されたコーディングシステムは、そのサブプロセスへのI/Oに使用されるコーディングシステムの初期化に使用されるが、set-process-coding-system
を使用して後から他のコーディングシステムを指定できる。
警告:
データからコーディングシステムを判断するundecided
のようなコーディングシステムは、非同期のサブプロセスでは完全な信頼性をもって機能はしない。これはEmacsが非同期サブプロセスの出力を到着によりバッチ処理するためである。そのコーディングシステムが文字コード変換や行末変換を未指定にしておくと、Emacsは一度に1バッチから正しい変換の検出を試みなければならず、これは常に機能するとは限らない。
したがって非同期サブプロセスでは可能なら文字コード変換と行末変換の両方を判断するコーディングシステム、つまりundecided
やlatin-1
ではなくlatin-1-unix
のようなコーディングシステムを使用すること。
この変数はネットワークストリームに使用するコーディングシステムを指定するalist。これはfile-coding-system-alist
と同じように機能するが、要素内のpatternがポート番号、または正規表現かもしれない点が異なる。正規表現ならそのネットワークストリームのオープンに使用されたネットワークサービス名にたいしてマッチされる。
この変数は他に何を行うか指定されていない際に、サブプロセス(とネットワークストリーム)への入出力に使用するコーディングシステムを指定する。
値は(input-coding
.
output-coding)
という形式のコンスセルであること。ここでinput-codingはサブプロセスからの入力、output-codingはサブプロセスへの出力に適用される。
この変数はファイルのデコードされていないコンテンツにもとづいて、ファイルにたいするコーディングシステムの判断を試みる関数のリストを保持する。
このリスト内の各関数は、いかなる方法にせよそれを変更しないようにカレントバッファー内のテキストを調べるように記述されていること。そのバッファーはファイルの一部であるデコードされていないテキストを含むだろう。各関数はポイントを始点に何文字を調べるかを指定する唯一の引数sizeを受け取ること。関数がそのファイルにたいするコーディングシステムの決定に成功したら、そのコーディングシステムをリターンすること。それ以外はnil
をリターンすること。
ファイルに‘coding:’タグがある場合にはそれが優先されるので、これらの関数が呼び出されることはないだろう。
この関数はfilenameに適するコーディングシステムの判定を試みる。これは上記で説明した変数により指定されたルールのいずれかにマッチするまで、それらの変数を順に使用してファイルをvisitするバッファーを調べる。そして(coding
.
source)
という形式のコンスセルをリターンする。ここでcodingは使用するコーディングシステム、sourceはauto-coding-alist
、auto-coding-regexp-alist
、:coding
、auto-coding-functions
のいずれかであるようなシンボルであり、マッチングルールとして提供されるルールを示す。値:coding
はファイル内のcoding:
タグによりコーディングシステムが指定されたことを意味する(coding tag in The GNU Emacs
Manualを参照)。マッチングルールを調べる順序はauto-coding-alist
、auto-coding-regexp-alist
、coding:
、auto-coding-functions
の順。マッチングルールが見つからなければこの関数はnil
をリターンする。
2つ目の引数sizeはポイントの後のテキストの文字単位のサイズ。この関数はポイントの後のsize文字のテキストだけを調べる。coding:
タグが置かれる箇所としてはファイルの先頭2行が想定される箇所の1つなので、通常はバッファーの先頭位置でこの関数を呼び出すこと。その場合にはsizeはそのバッファーのサイズであること。
この関数はファイルfilenameに適するコーディングシステムをリターンする。これはコーディングシステムを探すためにfind-auto-coding
を使用する。コーディングシステムを決定できなかったら、この関数はnil
をリターンする。引数sizeの意味はfind-auto-coding
と同様。
この関数はoperationをargumentsで行う際に、(デフォルトで)使用するコーディングシステムをリターンする。値は以下の形式:
(decoding-system . encoding-system)
1つ目の要素decoding-systemはデコード(operationがデコードを行う場合)、encoding-systemはエンコード(operationがエンコードを行う場合)に使用するコーディングシステム。
引数operationはシンボルでwrite-region
、start-process
、call-process
、call-process-region
、insert-file-contents
、open-network-stream
のいずれかであること。これらは文字コード変換と行末変換を行うことができるEmacsのI/Oプリミティブの名前である。
残りの引数は対応するI/Oプリミティブに与えられる引数と同じであること。そのプリミティブに応じてこれらの引数のうち1つがターゲットとして選択される。たとえばoperationがファイルI/Oならファイル名を指定する引数がターゲット。サブプロセス用のプリミティブではプロセス名がターゲット。open-network-stream
ではサービス名またはポート番号がターゲット。
operationに応じてこの関数はfile-coding-system-alist
、process-coding-system-alist
、network-coding-system-alist
の中からターゲットを探す。このalist内でターゲットが見つかったらfind-operation-coding-system
はalist内のassociation(連想:
キーと連想値からなるコンスセル)、それ以外はnil
をリターンする。
operationがinsert-file-contents
ならターゲットに対応する引数は(filename
.
buffer)
という形式のコンスセルだろう。この場合にはfilenameはfile-coding-system-alist
内で照合されるファイル名であり、bufferはそのファイルの(デコードされていない)コンテンツを含むバッファー。file-coding-system-alist
がこのファイルにたいして呼び出す関数を指定していて、かつ(通常行われるように)ファイルのコンテンツを調べる必要があるならファイルを読み込むかわりにbufferのコンテンツを調べること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
変数coding-system-for-read
および/またはcoding-system-for-write
をバインドすることにより、特定の操作にたいしてコーディングシステムを指定できます。
この変数が非nil
なら、それはファイルの読み込みや同期サブプロセスプロセスからの入力にたいして使用するコーディングシステムを指定する。
これは非同期サブプロセスやネットワークストリームにも適用されるが方法は異なる。サブプロセス開始時やネットワークストリームオープン時のcoding-system-for-read
の値は、サブプロセスやネットワークストリームにたいして入力のデコードメソッドを指定する。そのサブプロセスやネットワークストリームにたいして、オーバーライドされるまでそれが使用され続ける。
特定のI/O操作にたいしてlet
でバインドするのがこの変数の正しい使い方である。この変数のグローバル値は常にnil
であり、他の値にグローバルにセットするべきではない。以下はこの変数の正しい使用例:
;; 文字コード変換なしでファイルを読み込む
(let ((coding-system-for-read 'no-conversion))
(insert-file-contents filename))
この変数の値が非nil
のときはfile-coding-system-alist
、process-coding-system-alist
、network-coding-system-alist
を含む、入力にたいして使用するコーディングシステムを指定するすべてのメソッドよりこの変数が優先される。
これはcoding-system-for-read
と同じように機能するが、入力ではなく出力に適用される点が異なる。これはファイルへの書き込み、同様にサブプロセスおよびネットワークストリームへの出力の送信にも適用される。
単一の操作がcall-process-region
やstart-process
のように入力と出力の両方を行う際には、coding-system-for-read
とcoding-system-for-write
の両方がそれに影響する。
この変数が非nil
なら、どのコーディングシステムが指定されたかに関わらず行末変換は何も行われない。これはEmacsすべてのI/Oやサブプロセスにたいするプリミティブ、および明示的なエンコード関数(明示的なエンコードとデコードを参照)とデコード関数に適用される。
ある操作にたいして固定された1つのコーディングシステムではなく複数のコーディングシステムを選択する必要があることがあります。Emacsでは使用するコーディングシステムにたいして優先順位を指定できます。これはfind-coding-systems-region
(Lispでのコーディングシステムを参照)のような関数によりリターンされるコーディングシステムのリストのソート順に影響します。
この関数はコーディングシステムのカレント優先順にコーディングシステムのリストをリターンする。オプション引数highestpが非nil
なら、それはもっとも高い優先度のコーディングシステムだけをリターンすることを意味する。
この関数はコーディングシステムの優先リストの先頭にcoding-systemsを配置して、それらを他のコーディングシステムすべてより高い優先度とする。
このマクロはcoding-systemsをコーディングシステム優先リスト先頭に配置して、progn
(prognを参照)が行うようにbodyを実行する。coding-systemsはbody実行中に選択するコーディングシステムのリストであること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs内外へテキストを転送するすべての操作は、そのテキストをエンコードまたはデコードする能力をもっています。このセクション内の関数を使用してテキストの明示的なエンコードやデコードを行うことができます。
エンコード結果やデコーディングへの入力は通常のテキストではありません。これらは理論的には一連のバイト値から構成されており、すなわち一連のASCII文字と8ビット文字から構成されます。ユニバイトのバッファーや文字列では、これらの文字は0から#xFF(255)の範囲のコードをもちます。マルチバイトのバッファーや文字列では8ビット文字は#xFFより大きい文字コードをもちますが(テキストの表現方法を参照)、そのようなテキストのエンコードやデコードの際にEmacsは透過的にそれらを単一バイト値に変換します。
コンテンツを明示的にデコードできるようにバイトシーケンスとしてバッファーにファイルを読み込むには、insert-file-contents-literally
(ファイルの読み込みを参照)を使用するのが通常の方法です。あるいはfind-file-noselect
でファイルをvisitする際には、引数rawfileに非nil
を指定することもできます。これらのメソッドの結果はユニバイトバッファーになります。
テキストを明示的にエンコードした結果であるバイトシーケンスは、たとえばそれをwrite-region
(ファイルの書き込みを参照)で書き込み、coding-system-for-write
をno-conversion
にバインドすることによりエンコードを抑制する等、それをファイルまたはプロセスへコピーするのが通常の使い方です。
以下はエンコードやデコードを明示的に行う関数です。エンコード関数とはバイトシーケンスを生成し、デコード関数とはバイトシーケンスを操作する関数のことを意味します。これらの関数はすべてテキストプロパティを破棄します。これらは自身が使用したコーディングシステムを、正確にlast-coding-system-used
にセットすることも行います。
このコマンドはstartからendのテキストをコーディングシステムcoding-systemでエンコードする。バッファー内の元テキストは通常はエンコードされたテキストで置き換えられるが、オプション引数destinationでそれを変更できる。destinationがバッファーなら、エンコードされたテキストはそのバッファーのポイントの後に挿入される(ポイントは移動しない)。t
ならこのコマンドはエンコードされたテキストを挿入せずにユニバイトとしてリターンする。
エンコードされたテキストが何らかのバッファーに挿入された場合には、このコマンドはエンコードされたテキストの長さをリターンする。
エンコードされた結果は理論的にはバイトシーケンスだが、バッファーが以前マルチバイトだったならマルチバイトのまま留まり、すべての8ビットのバイトはマルチバイト表現に変換される(テキストの表現方法を参照)。
期待しない結果となる恐れがあるので、テキストをエンコードする際にはcoding-systemにundecided
を使用してはならない。coding-systemにたいして自明な適値が存在しなければ適切なエンコードを提案させるために、かわりにselect-safe-coding-system
を使用すること(select-safe-coding-systemを参照)。
この関数はコーディングシステムcoding-systemでstring内のテキストをエンコードする。これはエンコードされたテキストを含む新たな文字列をリターンするが、nocopyが非nil
の場合には、それが些細なエンコード処理ならこの関数はstring自身をリターンする。エンコード結果はユニバイト文字列。
このコマンドはコーディングシステムcoding-systemで、startからendのテキストをデコードする。明示的なデコードを使いやすくするためにデコード前のテキストはバイトシーケンス値であるべきだが、マルチバイトとユニバイトのバッファーいずれでも許すようになっている(マルチバイトバッファーの場合rawバイト値は8ビット文字で表現されていること)。デコードされたテキストにより通常はバッファー内の元のテキストは置き換えられるが、オプション引数destinationはそれを変更する。destinationがバッファーなら、デコードされたテキストはそのバッファーのポイントの後に挿入される(ポイントは移動しない)。これがt
ならこのコマンドはデコードされたテキストを挿入せずにマルチバイト文字列としてリターンする。
デコードされたテキストが何らかのバッファーに挿入された場合には、このコマンドはデコードされたテキストの長さをリターンする。
このコマンドはデコードされたテキストにテキストプロパティcharset
をputする。このプロパティの値は元のテキストのデコードに使用された文字セットを示す。
この関数はcoding-systemでstring内のテキストをデコードする。これはデコードされたテキストを含む新たな文字列をリターンするが、nocopyが非nil
の場合には、それが些細なデコード処理ならstring自体をリターンするかもしれない。明示的なデコードを使いやすくするために、stringのコンテンツはバイトシーケンス値をもつユニバイト文字列であるべきだが、マルチバイト文字列も許すようになっている(マルチバイト形式で8ビットバイトを含むと仮定する)。
オプション引数bufferがバッファーを指定する場合には、デコードされたテキストはそのバッファー内のポイントの後に挿入される(ポイントは移動しない)。この場合にはリターン値はデコードされたテキストの長さとなる。
この関数はデコードされたテキストにテキストプロパティcharset
をputする。このプロパティの値は元のテキストのデコードに使用された文字セットを示す。
(decode-coding-string "Gr\374ss Gott" 'latin-1) ⇒ #("Grüss Gott" 0 9 (charset iso-8859-1))
この関数はfromからtoのテキストを、あたかも与えられた残りの引数でinsert-file-contents
を使用してファイルfilenameから読み込んだかのようにデコードする。
デコードせずにファイルからテキストを読み込んだ後で、やはりデコードすることを決心したときに使用するのがこの関数の通常の使い方である。テキストを削除して再度読み込むかわりに、この関数を呼び出せばデコードして読み込むことができる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはキーボード入力のデコード、および端末出力のエンコードにコーディングシステムを使用できます。これはLatin-1のような特定のエンコーディングを使用したテキストの送信や表示を行う端末にとって有用です。端末I/Oをエンコードまたはデコードする際には、Emacsはlast-coding-system-used
をセットしません。
この関数はterminalからのキーボード入力をデコードするために使用するコーディングシステムをリターンする。no-conversion
という値は何のデコーディングも行われていないことを意味する。terminalが省略またはnil
なら、それは選択されたフレームの端末を意味する。複数の端末を参照のこと。
このコマンドはterminalからのキーボード入力のデコードに使用するコーディングシステムとしてcoding-systemを指定する。coding-systemがnil
なら、キーボード入力をデコードしないことを意味する。terminalがフレームなら、それはそのフレームの端末を意味する。nil
ならそれはカレントで選択されたフレームの端末を意味する。複数の端末を参照のこと。
この関数はterminalからの端末出力のエンコードに使用中のコーディングシステムをリターンする。no-conversion
という値は何のデコーディングも行われていないことを意味する。terminalがフレームならそれはそのフレームの端末を意味する。nil
ならそれはカレントで選択されたフレームの端末を意味する。
この関数はterminalからの端末出力のエンコードに使用するためのコーディングシステムとしてcoding-systemを指定する。coding-systemがnil
なら端末出力をエンコードしないことを意味する。terminalがフレームならそれはそのフレームの端末を意味する。nil
ならそれはカレントで選択されたフレームの端末を意味する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力メソッド(input methods)はキーボードから非ASCII文字を簡単に入力する手段を提供します。プログラムが読み取ることを意図して非ASCII文字とエンコーディングを相互に変換するコーディングシステムとは異なり、入力メソッドはヒューマンフレンドリーなコマンドを提供します(テキストを入力するためにユーザーが入力メソッドを使う方法についてはInput Methods in The GNU Emacs Manualを参照)。入力メソッドの定義方法はまだこのマニュアルにはありませんが、ここではそれらの使い方について説明します。
現在のところ入力メソッドは文字列で名前をもっていますが、将来的には入力メソッド名としてシンボルも利用可能になるかもしれません。
この変数はカレントバッファーで現在アクティブな、入力メソッドの名前を保持する(方法に関わらずセット時には各バッファーで自動的にローカルになる)。バッファーで現在アクティブな入力メソッドがなければ値はnil
。
この変数は入力メソッドを選択するコマンドにたいしてデフォルトの入力メソッドを保持する。current-input-method
と異なり、この変数は通常はグローバルである。
このコマンドはカレントバッファーで入力メソッドinput-methodをアクティブにする。同様にdefault-input-method
にinput-methodのセットも行う。input-methodがnil
なら、このコマンドはカレントバッファーで入力メソッドを非アクティブにする。
この関数はプロンプトpromptとともにミニバッファーで入力メソッドの名前を読み取る。defaultが非nil
の場合には、ユーザーの入力が空ならそれがデフォルトとしてリターンされる。しかしinhibit-nullが非nil
なら空の入力はエラーをシグナルする。
リターン値は文字列。
この変数はサポートされているすべての入力メソッドを定義する。各要素は1つの入力メソッドを定義して、それぞれ以下の形式をもつ:
(input-method language-env activate-func title description args...)
ここでinput-methodはメソッド名の文字列、language-envはこの入力メソッドが推奨される言語環境の名前の文字列(これはドキュメントとしての目的のみの役割を果たす)。
activate-funcはこのメソッドをアクティブにするために呼び出す関数、もしあればargsはactivate-funcに渡す引数。つまりactivate-funcの引数はinput-methodとargs。
titleは、その入力メソッドがアクティブな間にモードライン内に表示するための文字列、descriptionはそのメソッドを説明して、それが何に適するかを説明する文字列。
入力メソッドのための基本的インターフェースは変数input-method-function
です。単一イベントの読み取りと入力メソッドの呼び出しを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
POSIXでは、言語に関連する機能において使用する言語を制御するためにlocaleという概念があります。以下のEmacs変数はEmacsがこれらの機能と相互作用する方法を制御します。
この変数は標準出力とエラーストリームへのバッチ出力の送信、format-time-string
にたいするformat引数のエンコーディング、format-time-string
のリターン値のデコーディングに際してシステムエラーメッセージ(およびXウィンドウシステムに限りキーボード入力)をデコーディングするコーディングシステムを指定する。
この変数はシステムエラーメッセージを生成するために使用するlocaleを指定する。locale変更によりメッセージが異なる言語になったり異なる表記になり得る。この変数がnil
なら通常のPOSIX方式のようにlocaleは環境変数により指定される。
この変数はタイムバリューをフォーマットするために使用するlocaleを指定する。locale変更により異なる慣習によりメッセージが表示され得る。この変数がnil
なら通常のPOSIX方式のようにlocaleは環境変数により指定される。
この変数は、もし利用可能ならカレントPOSIX localeにたいするlocaleデータitemをリターンする。itemは以下のシンボルのいずれかであること:
codeset
文字列として文字セットをリターンする(localeアイテムのCODESET
)。
days
曜日名からなる7要素のベクターをリターンする(localeアイテムのDAY_1
からDAY_7
)。
months
月の名前からなる12要素のベクターをリターンする(localeアイテムのMON_1
からMON_12
)。
paper
(width
height)
というリストで、デフォルト用紙サイズをmm単位でリターンする(localeアイテムPAPER_WIDTH
とPAPER_HEIGHT
)。
システムが要求された情報を提供できなかったり、itemが上記いずれのシンボルでもなければ値はnil
。リターン値内のすべての文字列はlocale-coding-system
を使用してデコードされる。localeとlocaleアイテムについての詳細な情報はLocales in The GNU Libc Manualを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU Emacsはバッファーから指定されたテキストを検索するために2つの手段を提供します。それは文字列の正確一致検索(exact string search)と正規表現検索(regular expression search)です。正規表現検索の後で、マッチしたテキストが正規表現全体にマッチしたのか、それとも正規表現のさまざまな部分に一致したかを判断するためにマッチデータ(match data)を調べることができます。
33.1 文字列の検索 | 正確なマッチの検索。 | |
33.2 検索と大文字小文字 | case-independentまたはcase-significantな検索。 | |
33.3 正規表現 | 文字列クラスの記述。 | |
33.4 正規表現の検索 | regexpにたいするマッチの検索。 | |
33.5 POSIX正規表現の検索 | 最長マッチにたいするPOSIXスタイルのマッチ。 | |
33.6 マッチデータ | 文字列またはregexp検索後にテキストがマッチした部分を見つける。 | |
33.7 検索と置換 | 検索と置換を繰り返すコマンド。 | |
33.8 編集で使用される標準的な正規表現 | センテンスやページ等を探すために有用なregexp。 |
‘skip-chars…’関連の関数もある種の検索を行います。文字のスキップを参照してください。文字プロパティ内の変更の検索はテキストプロパティの検索関数を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファー内のテキストを検索するためのプリミティブ関数が存在します。これらはプログラム内での使用を意図したものですがインタラクティブに呼び出すこともできます。これらをインタラクティブに呼び出すと検索文字列の入力を求めて、引数limitとnoerrorはnil
、repeatは1になります。インタラクティブ検索に関するより詳細な情報はSearching and Replacement in The GNU Emacs Manualを参照してください。
以下の検索関数はバッファーがマルチバイトバッファーならマルチバイト、ユニバイトバッファーならユニバイトに検索文字列を変換します。テキストの表現方法を参照してください。
この関数はstringにたいする正確なマッチをポイントから前方に検索する。成功したら見つかったマッチの終端にポイントをセットしてポイントの新たな値をリターンする。マッチが見つからない場合の値と副作用はnoerror (以下参照)に依存する。
以下の例ではポイントは最初は行の先頭にある。その後の(search-forward
"fox")
によってポイントは‘fox’の最後の文字の後に移動する:
---------- Buffer: foo ---------- ∗The quick brown fox jumped over the lazy dog. ---------- Buffer: foo ----------
(search-forward "fox") ⇒ 20 ---------- Buffer: foo ---------- The quick brown fox∗ jumped over the lazy dog. ---------- Buffer: foo ----------
引数limitは検索の境界を指定するもので、それはカレントバッファー内の位置であること。その位置を超えるようなマッチは受け入れられない。limitが省略またはnil
の場合のデフォルトは、そのバッファーのアクセス可能範囲の終端。
検索失敗時に何が起こるかはnoerrorの値に依存する。noerrorがnil
ならsearch-failed
はエラーをシグナルする。noerrorがt
ならsearch-forward
はnil
をリターンして何も行わない。noerrorがnil
とt
いずれでもなければ、search-forward
はポイントを境界上限に移動してnil
をリターンする。
引数noerrorはマッチに失敗した有効な検索だけに影響する。無効な引数はnoerrorとは無関係にエラーとなる。
repeatが正の数nなら検索はn回繰り返される。一連の検索は前回のマッチの終端から毎回検索が開始される。これらの一連の検索が成功すると、関数呼び出しは成功となりポイントを移動して新たな値をリターンする。それ以外は関数の呼び出しは失敗となり、結果は上述のようにnoerrorの値に依存する。repeatが負の数-nなら検索は逆方向(後方)へn回行われる。
この関数はポイントから後方にstringを検索する。これはsearch-forward
と似ているが、前方ではなく後方に検索する点が異なる。後方への検索ではポイントはマッチの先頭に残される。
この関数はポイントから前方にstringにたいする単語(word)のマッチを検索する。マッチが見つかったら見つかったマッチの終端にポイントをセットしてポイントの新たな値をリターンする。
単語マッチはstringを単語のシーケンスとみなし、それらを分割する句読点は無視する。これはバッファーから同じ単語シーケンスを検索する。単語はそれぞれバッファー内で明確に区別されていなければならない(単語‘ball’の検索は単語‘balls’にマッチしない)が、句読点やスペース等の細部は無視される(‘ball boy’を検索すると‘ball. Boy!’にマッチする)。
以下の例ではポイントは最初バッファー先頭にある。検索によりポイントは‘y’と‘!’の間に残される。
---------- Buffer: foo ---------- ∗He said "Please! Find the ball boy!" ---------- Buffer: foo ----------
(word-search-forward "Please find the ball, boy.") ⇒ 39 ---------- Buffer: foo ---------- He said "Please! Find the ball boy∗!" ---------- Buffer: foo ----------
limitが非nil
なら、それはカレントバッファー内の位置であること。これはその検索の境界上限を指定する。見つかったマッチはその位置を超えてはならない。
noerrorがnil
ならword-search-forward
はエラーをシグナルする。noerrorがt
なら、エラーをシグナルするかわりにnil
をリターンする。noerrorがnil
とt
いずれでもなければ、ポイントをlimit(またはバッファーのアクセス可能範囲の終端)に移動してnil
をリターンする。
countが正の数なら、それは連続して検索する回数を指定する。ポイントは最後のマッチの終端に配置される。countが負の数なら、逆方向に検索してポイントは最後のマッチの先頭に配置される。
word-search-forward
および関連する関数は、stringから句読点を無視した正規表現に変換するために、内部的には関数word-search-regexp
を使用する。
このコマンドはword-search-forward
と同じだが、stringが空白で開始か終了していなければ、stringの先頭か終端が単語境界にマッチする必要がない点が異なる。たとえば‘ball
boy’の検索は‘ball boyee’にはマッチするが、‘balls boy’にはマッチしない。
この関数はポイントから後方へstringにマッチする単語を検索する。この関数はword-search-forward
と同様だが、後方に検索して通常はマッチの先頭にポイントを残す点が異なる。
このコマンドはword-search-backward
と同じだが、文字列が空白で開始か終了していなければ、stringの先頭か終端が単語境界にマッチする必要がない点が異なる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
デフォルトのEmacs検索では検索するテキストのcase(大文字と小文字)は無視されます。検索対象に‘FOO’を指定すると、‘Foo’や‘foo’もマッチとみなされます。これは正規表現にも適用されます。つまり‘[aB]’は‘a’、‘A’、‘b’、‘B’にもマッチするでしょう。
この機能が望ましくなければ変数case-fold-search
にnil
をセットしてください。その場合にはすべての文字はcaseを含めて正確にマッチしなければなりません。これはバッファーローカル変数です。この変数の変更はカレントバッファーだけに影響を与えます(バッファーローカル変数の概要を参照)。かわりにデフォルト値を変更することもできます。Lispコードではlet
を使用してcase-fold-search
を望む値にバインドするほうが、より一般的でしょう。
ユーザーレベルのインクリメンタル検索機能ではcaseの区別が異なることに注意してください。検索文字列に含まれるのが小文字だけなら検索はcaseを無視しますが、検索文字列に1つ以上の大文字が含まれれば検索はcaseを区別するようになります。しかしLispコード内で使用される検索関数では、これは何も行いません。Incremental Search in The GNU Emacs Manualを参照してください。
このバッファーローカル変数は検索がcaseを無視するべきかどうかを決定する。この変数がnil
なら検索はcaseを無視しない。それ以外(とデフォルト)ではcaseを無視する。
この変数は高レベルの置換関数がcaseを保持するべきかどうかを決定する。この変数がnil
なら、それは置換テキストをそのまま使用することを意味する。非nil
値は置換されるテキストに応じて、置換テキストのcaseを変換することを意味する。
この変数は関数replace-match
の引数として渡すことにより使用される。マッチしたテキストの置換を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
正規表現(regular expression)、略してregexpは文字列の(もしかしたら無限の)セットを表すパターンのことです。regexpにたいするマッチの検索はとても強力な処理です。このセクションではregexpの記述方法、それ以降のセクションではそれらを検索する方法を示します。
正規表現を対話的に開発するためにM-x re-builderコマンドを使用できます。このコマンドは別のバッファーに即座に視覚的なフィードバックを表示することにより、正規表現を作成するための便利なインターフェースを提供します。regexp編集とともにターゲットとなるバッファーのすべてのマッチがハイライトされます。カッコで括られたregexpの部分式(sub-expression)は別のフェイスで表示され、非常に複雑なregexpを簡単に検証することが可能になります。
33.3.1 正規表現の構文 | 正規表現の記述ルール。 | |
33.3.2 正規表現の複雑な例 | 正規表現構文の説明。 | |
33.3.3 正規表現の関数 | 正規表現を操作する関数。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
正規表現は少数の文字が特別な構成要素であり、残りは通常の文字であるような構文をもちます。通常の文字はその文字自身だけにマッチするシンプルな正規表現です。特別な文字は‘.’、‘*’、‘+’、‘?’、‘[’、‘^’、‘$’、および‘\’です。将来に新たなスペシャル文字が定義されることはないでしょう。文字候補で終わる場合には‘]’はスペシャル文字です。文字候補の間では‘-’はスペシャル文字です。‘[:’と対応する‘:]’は文字候補内の文字クラスです。正規表現内に出現する他の文字は‘\’が前置されていない限り通常の文字です。
たとえば‘f’はスペシャル文字ではなく通常文字なので、‘f’は文字列‘f’にマッチして他の文字にはマッチしない正規表現です(これは文字列‘fg’にはマッチしないが、その文字列の部分にマッチする)。同様に‘o’は‘o’だけにマッチします。
任意の2つの正規表現aとbを結合することができます。結合した結果は文字列の先頭からある長さの文字列がaにマッチして、残りの文字列がbにマッチするような文字列にマッチする正規表現になります。
単純な例として文字列‘fo’だけにマッチする正規表現の構成要素‘fo’を取得するために正規表現‘f’と‘o’を結合できます。
33.3.1.1 正規表現内の特殊文字 | 正規表現内のスペシャル文字。 | |
33.3.1.2 文字クラス | 正規表現内で使用される文字クラス。 | |
33.3.1.3 正規表現内のバッククラッシュ構造 | 正規表現内のバックスラッシュシーケンス。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下は正規表現内で特別な文字のリストです:
これは改行を除く1文字にマッチする。結合を使用して‘a.b’のような正規表現を作成できる。これは‘a’で始まり‘b’で終わる3文字の文字列にマッチする。
これはそれ自身が構成要素ではない。これは前置された正規表現を可能な限り繰り返したものにマッチすることを意味する後置演算子である。したがって‘o*’は任意の個数の‘o’にマッチする(‘o’を含まない場合にもマッチする)。
‘*’は常に前置された表現の最小の表現に適用される。つまり‘fo*’は‘o’の繰り返しであり‘fo’の繰り返しではない。これは‘f’、‘fo’、‘foo’、...にマッチする。
マッチを行う処理は構成要素‘*’を、マッチングにより即座に見つけ得る回数分処理して、その後にパターンの残りを継続する。これが失敗したら残りのパターンのマッチが可能になるかもしれないという期待のもとに、‘*’の変更された構成のうちいくつかのマッチを破棄することによるバックトラッキングが発生する。たとえば文字列‘caaar’にたいして‘ca*ar’をマッチングすると、‘a*’はまず3つすべての‘a’へのマッチを試みる。しかし残りのパターンは‘ar’でありマッチ対象に残されているのは‘r’だけなのでこの試みは失敗する。‘a*’にたいする次の代替策は2つの‘a’だけへのマッチである。この選択では残りのregexpのマッチは成功する。
警告: ネストされた繰り返し処理は、それらが曖昧なマッチとなるような場合には無期限な長時間の実行となり得る。たとえば文字列‘xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz’にたいして正規表現‘\(x+y*\)*a’のマッチを試みると、それが最終的に失敗するまでに数時間を要す可能性がある。Emacsはその試みのいずれも機能しないと結論する前に、‘x’のグループ化のそれぞれを試みなければならない。さらに悪いことに‘\(x*\)*’は無数の方法でnull文字列にマッチ可能なので無限ループを引き起こす。これらの問題を避けるにはネストされた繰り返しがバックトラッキングでの組み合わせ爆発(combinatorial explosion)が発生しないことを確実にするために注意深くチェックすること。
これは‘*’のような後置演算子だが前置された表現に少なくとも1回マッチしなければならない点が異なる。たとえば‘ca+r’は文字列‘car’や‘caaaar’にマッチするが文字列‘cr’にはマッチせず、その一方で‘ca*r’はこれら3つすべての文字列にマッチする。
これは‘*’のような後置演算子だが前置された表現に1回、またはマッチしないかのいずれかでなければならない点が異なる。例えば‘ca?r’は‘car’と‘cr’にマッチするが他にはマッチしない。
演算子 ‘*’、‘+’、‘?’には非欲張り(non-greedy)な変種が存在する。これらの演算子が可能な最長の部分文字列(含まれる表現全体へのマッチと等しい)とマッチするのにたいして、非欲張りな変種は可能な最短の部分文字列(含まれる表現全体と等しい)にマッチする。
たとえば正規表現‘c[ad]*a’を文字列‘cdaaada’に適用すると文字列全体にマッチするが、正規表現‘c[ad]*?a’を同じ文字列に適用すると‘cda’だけにマッチする(ここでマッチが許された表現全体にたいする‘[ad]*?’の可能な最短マッチは‘d’)。
これは‘[’で始まり‘]’で終端される文字候補(character alternative)。もっとも単純なケースでは、この2つのカッコ(brackets)の間にある文字が、この文字候補がマッチ可能な文字。
したがって‘[ad]’は1つの‘a’と1つの‘d’の両方にマッチし、‘[ad]*’は‘a’と‘d’だけで構成された任意の文字列(空文字列を含む)にマッチする。つまり‘c[ad]*r’は‘cr’、‘car’、‘cdr’、‘caddaar’等にマッチする。
開始文字と終了文字の間に‘-’を記述することにより、文字候補内に文字範囲を含めることができる。つまり‘[a-z]’は小文字のASCIIアルファベット文字にマッチする。範囲は‘[a-z$%.]’のように個別の文字と自由に組み合わせることができる。これは任意のASCII小文字アルファベットと‘$’、‘%’、またはピリオドとマッチする。
case-fold-search
が非nil
なら、‘[a-z]’は大文字アルファベットにもマッチする。‘[a-z]’のような範囲はそのlocaleの照合順に影響されず、常にASCII順のシーケンスを表すことに注意。
さらに通常のregexpスペシャル文字は文字候補内では特別ではないことにも注意。文字候補内部では‘]’、‘-’、‘^’という完全に異なる文字セットが特別に扱われる。
文字候補内に‘]’を含めるには、それを最初の文字にしなければならない。たとえば‘[]a]’は‘]’と‘a’にマッチする。‘-’を含めるには文字候補の最初または最後の文字として‘-’を記述するか、範囲の後に配置すること。つまり‘[]-]’は‘]’と‘-’の両方にマッチする(以下で説明するように、ここでは‘\’は特別ではないので、文字候補内に‘]’を含めるために‘\]’は使用できない)。
文字候補内に‘^’を含めるには先頭以外のいずれかの場所に置くこと。
ある範囲がユニバイト文字cで始まり、マルチバイト文字c2で終われば、その範囲は2つの部分に分割される。1つはユニバイト文字‘c..?\377’、もう1つはマルチバイト文字‘c1..c2’。ここでc1はc2が属する文字セットの最初の文字。
文字候補には名前付き文字クラスも指定できる(文字クラスを参照)。これはPOSIXの機能である。たとえば‘[[:ascii:]]’は任意のASCII文字にマッチする。文字クラスの使用は、そのクラス内すべての文字を記述するのと等しい。しかし異なる文字を数千含むクラスもあるので、後者は実際は実現可能ではない。
‘[^’は補完文字候補(complemented character alternative)を開始する。これは指定された以外の任意の文字とマッチする。つまり‘[^a-z0-9A-Z]’はアルファベットと数字以外の、すべての文字にマッチする。
‘^’は文字クラス内では先頭に記述されない限り特別ではない。‘^’に続く文字は、あたかもそれが先頭にあるかのように扱われる(言い換えると‘-’や‘]’はここでは特別ではない)。
マッチしない文字の1つとして改行が記述されていなければ、補完文字候補は改行にマッチできる。これはgrep
のようなプログラム内でのregexpの扱いとは対照的である。
文字候補のように名前付き文字クラスを指定できる。たとえば‘[^[:ascii:]]’は任意の非ASCII文字にマッチする。文字クラスを参照のこと。
バッファーのマッチングの際には‘^’は空文字列、ただしマッチ対象のテキスト内にある行の先頭(またはバッファーのアクセス可能範囲の先頭)だけにマッチする。それ以外のマッチはすべて失敗する。つまり‘^foo’は行の先頭に出現する‘foo’にマッチする。
バッファーではなく文字列とマッチする際には、‘^’は文字列の先頭か改行文字の後にマッチする。
歴史的な互換性という理由により‘^’は正規表現の先頭、または‘\(’、‘\(?:’、‘\|’の後でのみ使用できる。
これは‘^’と似ているが、行の終端(またはバッファーのアクセス可能範囲の終端)だけにマッチする。つまり‘x+$’は行末にある1つ以上の‘x’からなる文字列にマッチする。
バッファーではなく文字列とマッチする際には、‘$’は文字列の終端か改行文字の前にマッチする。
歴史的な互換性という理由により‘$’は正規表現の先頭、または‘\(’、‘\(?:’、‘\|’の前でのみ使用できる。
これはスペシャル文字(‘\’を含む)のクォートと、追加のスペシャル文字の導入という2つの機能をもつ。
‘\’はスペシャル文字をクォートするので‘\$’は‘$’、‘\[’は‘[’だけにマッチする正規表現のようになる。
‘\’はLisp文字列(文字列型を参照)の入力構文(read
syntax)内でも特別な意味をもち、‘\’でクォートしなければならないことに注意。たとえば文字‘\’にマッチする正規表現は‘\\’。文字‘\\’を含むLisp文字列を記述するには、別の‘\\’で‘\\’をクォートすることをLisp構文は要求する。したがって‘\’にマッチする正規表現にたいする入力構文は"\\\\"
となる。
注意してください: 歴史的な互換性のために、スペシャル文字はそれらがもつ特別な意味が意味を成さないコンテキスト内にある場合には通常の文字として扱われます。たとえば‘*foo’は‘*’が作用可能な前置された表現がないので、通常の‘*’として扱われます。この挙動に依存するのは悪い習慣です。どこにそれが出現しようとスペシャル文字はすべてクォートしてください。
文字候補内で‘\’は何ら特別ではないので、‘-’や‘]’の特別な意味を取り除くことは決してありません。特別な意味をもたないような場合でも、これらの文字をクォートするべきではありません。バックスラッシュ以外の任意の1文字にマッチする‘[^\]’
(Lisp文字列構文では"[^\\]"
)内でのように、これらの文字が特別な意味をもつ箇所では、これらの文字にバックスラッシュを前置することには正当性があるので、何もそれほど明解にはしないでしょう。
実際には正規表現内に出現する‘]’は文字候補に近接しており、それ故そのほとんどがスペシャル文字です。しかしリテラルの‘[’と‘]’の複雑なパターンにたいしてマッチを試みることも時にはあるかもしれません。そのような状況では文字候補を囲う角カッコがどれなのかを判断するために、regexpを最初から注意深く解析することが必要なときもあるかもしれません。たとえば‘[^][]]’は補完文字候補‘[^][]’ (角カッコ以外の任意の1文字とマッチする)と、その後のリテラルの‘]’により構成されます。
厳密にはregexp先頭の‘[’は特別で、‘]’は特別ではないというのがルールです。これはクォートされていない最初の‘[’で終わり、その後は文字候補になります。(文字クラス開始を除き)‘[’はもはや特別ではありませんが、‘]’は直後にスペシャル文字‘[’があるか、その‘[’の後に‘^’がある場合を除いて特別です。これは文字クラス終了ではない次のスペシャル文字‘]’まで続きます。これは文字候補を終了させて、通常の正規表現の構文をリストアします。クォートされていない‘[’は再び特別となり、‘]’は特別ではなくなります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下は文字候補内で使用できるクラスと、その意味についてのテーブルです:
これは任意のASCII文字(コード0 – 127)にマッチする。
これは任意の英数字にマッチする。マルチバイト文字では、アルファベット文字か数字であることを示すUnicodeプロパティ‘general-category’ (文字のプロパティを参照)をもつ文字にマッチする。
これは任意のアルファベットにマッチする。マルチバイト文字では、アルファベット文字であることを示すUnicodeプロパティ‘general-category’ (文字のプロパティを参照)をもつ文字にマッチする。
これはスペースとタブだけにマッチする。
これはASCII制御文字にマッチする。
これは‘0’から‘9’までにマッチする。つまり‘[-+[:digit:]]’は‘+’と‘-’、同様に任意の数にマッチする。
これはUnicodeの‘general-category’プロパティで示されるようなグラフィック文字(空白文字、ASCIIと非ASCIIの制御文字、サロゲートードポイント、Unicodeで未割り当てのコードポイントを除くすべて)にマッチする(文字のプロパティを参照)。
これはカレントのcaseテーブル(caseテーブルを参照)で小文字と判断される文字すべてにマッチする。case-fold-search
が非nil
なら大文字にもマッチする。
これは任意のマルチバイト文字にマッチする(テキストの表現方法を参照)。
これは非ASCII文字にマッチする。
これは任意のプリント文字(空白文字か‘[:graph:]’でマッチされるグラフィック文字のいずれか)にマッチする。
これは任意の句読点文字(punctuation character)にマッチする(現在のところマルチバイト文字では単語構文以外のすべてにマッチする)。
これは空白文字構文(構文クラスのテーブルを参照)をもつ任意の文字にマッチする。
これは任意のユニバイト文字(テキストの表現方法を参照)にマッチする。
これはカレントのcaseテーブル(caseテーブルを参照)で大文字と判断される文字すべてにマッチする。case-fold-search
が非nil
ならこれは小文字にもマッチする。
これは単語構文(構文クラスのテーブルを参照)をもつ任意の文字にマッチする。
これは16進数の数字‘0’から‘9’、‘a’から‘f’と‘A’から‘F’にマッチする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ほとんどの場合では、‘\’の後の任意の文字はその文字だけにマッチします。しかし例外もいくつかあります。‘\’で始まる特定のシーケンスには、特別な意味をもつものがあります。以下は特別な‘\’構成要素のテーブルです。
これは選択肢を指定する。2つの正規表現aとb、その間にある‘\|’により、aかbのいずれかにマッチする表現が形成される。
つまり‘foo\|bar’は、‘foo’か‘bar’のいずれかにマッチして他の文字列にはマッチしない。
‘\|’は周囲の適用可能な最大の表現に適用される。‘\|’を取り囲む‘\( … \)’でグループ化することによりグループ化の効力を制限できる。
複数の‘\|’の処理するための完全なバックトラッキング互換が必要なら、POSIX正規表現関数を使用すること(POSIX正規表現の検索を参照)。
これは前のパターンを正確にm回繰り返す後置演算子。つまり‘x\{5\}’は文字列‘xxxxx’にマッチして、それ以外にはマッチしない。‘c[ad]\{3\}r’は‘caaar’、‘cdddr’、‘cadar’等にマッチする。
これは最小でm回、最大でn回の繰り返しを表す、より一般的な後置演算子。m省略時の最小は0、n省略時の最大は存在しない。
たとえば‘c[ad]\{1,2\}r’は文字列‘car’、‘cdr’、‘caar’、‘cadr’、‘cdar’、‘cddr’にマッチして、それ以外にはマッチしない。
‘\{0,1\}’や‘\{,1\}’は‘?’と同じ。
‘\{0,\}’や‘\{,\}’は‘*’と同じ。
‘\{1,\}’は‘+’と同じ。
これは以下の3つの目的を果たす役目をもつグループ化構成要素:
この最後の目的はカッコによるグループ化というアイデアによるものではない。これは同じ構成要素‘\( … \)’にたいする2つ目の目的に割当てられた別の機能だが、実際のところ2つの意味は衝突しない。しかし稀に衝突が発生することがあり、それが内気(shy)なグループの導入をもたらした。
これは内気なグループ(shy group)の構成要素。内気なグループは通常のグループの最初の2つの役目(他の演算子のネスト制御)を果たすが、これは番号を取得せず‘\digit’でその値を後方参照できない。内気なグループは通常の非内気なグループを変更することなく自動的に追加できるので、機械的に正規表現を構築するのに特に適している。
内気なグループ化は非キャプチャリング(non-capturing)、番号なしグループ(unnumbered groups)とも呼ばれる。
これは明示的番号付きグループ(explicitly numbered group)の構成要素。通常のグループ化では位置をもとに番号が暗黙で取得されるが、これが不便な場合もあるだろう。この構成要素により特定のグループに番号を強制できる。番号の付与に特別な制限はなく、複数のグループに同じ番号を付与でき、その場合は最後の1つ(もっとも右のマッチ)がマッチとして採用される。暗黙に番号付けされたグループは、常に前のグループより大きい最小の整数となる番号を取得する。
これはグループ構成要素(‘\( … \)’)のdigit番目にマッチしたテキストと同じテキストにマッチする。
言い換えると最後のグループの後に、マッチ処理はそのグループによりマッチされたテキストの開始と終了を記憶する。その正規表現の先の箇所で‘\’とその後にdigitを使用すれば、それが何であれ同じテキストにマッチさせることができる。
検索やマッチングを行う関数に渡される正規表現全体の中で、最初の9つのグループ化構成要素にマッチする文字列には、その正規表現内で開カッコが出現する順に1から9までの番号が割り当てられる。したがって‘\1’から‘\9’までを使用して、対応するグループ化構成要素によりマッチされたテキストを参照できる。
たとえば‘\(.*\)\1’は、一方がもう一方と等しいような2つの文字列から構成される、改行を含まない任意の文字列にマッチする。‘\(.*\)’は前半分にマッチし、これは何でもよいが、それに続く‘\1’はそれと同じテキストに正確にマッチしなければならない。
構成要素‘\( … \)’が2回以上マッチする場合(これはたとえば後に‘*’をしたがえるとき発生し得る)には最後のマッチだけが記録される。
正規表現内の特定のグループ化構成要素がマッチしなかった場合には、たとえばそれが使用されない選択肢内にあったり、回数が0回の繰り返しの内部にあるなら、それに対応する‘\digit’構文は何にもマッチしない。作為的な例を用いると‘\(foo\(b*\)\|lose\)\2’は‘lose’にマッチできない。外側のグループ内の2つ目の選択肢がマッチするが、‘\2’が未定義となり何にたいしてもマッチできない。しかし‘foobb’にたいしては、1つ目の選択肢が‘foob’にマッチして、‘\2’が‘b’にマッチするのでマッチが可能になる。
これは任意の単語構成文字にマッチする。エディターの構文テーブルが、どの文字が単語構成文字かを決定する。構文テーブルを参照のこと。
これは任意の非単語構成文字にマッチする。
これは構文がcodeであるような任意の文字にマッチする。ここでcodeは、構文コードを表す文字。‘w’は単語構成要素、‘-’は空白文字、‘(’は開カッコ、...等。空白文字構文を表すには、‘-’かスペース文字のいずれかを使用する。構文コードとそれらを意味する文字のリストは構文クラスのテーブルを参照のこと。
これは構文がcodeでないような任意の文字にマッチする。
これはカテゴリーがcであるような任意の文字にマッチする。ここでcはカテゴリーを表す文字。つまり標準カテゴリーテーブルで‘c’はChinese(中国語)、‘g’はGreek(ギリシャ語)の文字となる。M-x
describe-categories
RETで現在定義済みの全カテゴリーのリストを確認できる。define-category
関数を使用すれば、標準カテゴリーに加えてカテゴリーを独自に定義することもできる(カテゴリーを参照)。
これはカテゴリーがcではない任意の文字にマッチする。
以下は空文字列にマッチ(つまり文字を何も消費しない)しますが、マッチするかどうかはコンテキストに依存するような正規表現を構築します。これらすべてにたいして、そのバッファーのアクセス可能範囲の先頭と終端は、あたかもそのバッファーの実際の先頭と終端のように扱われます。
これは空文字列、ただしバッファー先頭またはマッチ対象の文字列の先頭だけにマッチする。
これは空文字列、ただしバッファー終端またはマッチ対象の文字列の終端だけにマッチする。
これは空文字列、ただしポイント位置だけにマッチする(この構成要素はマッチ対象が文字列なら定義されない)。
これは空文字列、ただし単語の先頭だけにマッチする。つまり‘\bfoo\b’は個別の単語として出現する‘foo’だけにマッチする。‘\bballs?\b’は、個別の単語として‘ball’か‘balls’にマッチする。
‘\b’は、隣接するテキストが何であるかと無関係に、バッファー(か文字列)の先頭または終端にマッチする。
これは空文字列、単語の先頭や終端、またはバッファー(か文字列)の先頭や終端以外にマッチする。
これは空文字列、ただし単語の先頭だけにマッチする。‘\<’は後に単語構成文字が続く場合のみバッファー(か文字列)の先頭にマッチする。
これは空文字列、ただし単語の終端だけにマッチする。‘\<’はコンテンツが単語構成文字で終わる場合のみバッファー(か文字列)の終端にマッチする。
これは空文字列、ただしシンボルの先頭だけにマッチする。シンボルとは1つ以上の単語かシンボル構成文字のシーケンス。‘\_<’は後にシンボル構成文字が続く場合のみバッファー(か文字列)の先頭にマッチする。
これは空文字列、ただし単語の終端だけにマッチする。‘\_>’はコンテンツがシンボル構成文字で終わる場合のみバッファー(か文字列)の終端にマッチする。
すべての文字列が、有効な正規表現な訳ではありません。たとえば終端の‘]’がない文字選択肢の内側で終わる文字列は無効であり、単一の‘\’で終わる文字列も同様です。いずれかの検索関数にたいして無効な正規表現が渡されるとinvalid-regexp
エラーがシグナルされます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下は後続の空白文字とともにセンテンスの終わりを認識するために、以前のEmacsで使用されていた複雑な正規表現の例です(現在のEmacsは関数sentence-end
により構築される、同様のより複雑なregexpを使用する。編集で使用される標準的な正規表現を参照)。
以下ではまず、(スペースとタブ文字を区別するために)Lisp構文の文字列としてregexpを示して、それを評価した結果を示します。文字列定数の開始と終了はダブルクォーテーションです。‘\"’は文字列の一部としてのダブルクォーテーション、‘\\’は文字列の一部としてのバックスラッシュ、‘\t’はタブ、‘\n’は改行を意味します。
"[.?!][]\"')}]*\\($\\| $\\|\t\\| \\)[ \t\n]*" ⇒ "[.?!][]\"')}]*\\($\\| $\\| \\| \\)[ ]*"
改行とタブは、それら自身として出力されます。
この正規表現は連続する4つのパートを含み、以下のように解読できます:
[.?!]
この正規表現の1つ目のパートはピリオド、疑問符、感嘆符の3つのうちいずれか1つにマッチする文字選択肢。マッチはこれら3つの文字のいずれかで開始されなければならない(これは旧正規表現とEmacsが使用する新たなデフォルトregexpが異なる1つのポイントである。新たな値は後続の空白文字なしでセンテンスを終端する、いくつかの非ASCII文字を許容する)。
[]\"')}]*
パターンの2つ目のパートは任意の0個以上の閉カッコとクォーテーションマークであり、その後にピリオド、疑問符、感嘆符があるかもしれない。\"
は文字列内でのダブルクォーテーションマークにたいするLisp構文。最後の‘*’は直前の正規表現(この場合は文字選択肢)の0回以上の繰り返しを示す。
\\($\\| $\\|\t\\| \\)
パターンの3つ目のパートはセンテンスの後の空白文字、すなわち行の終端(スペースがあっても可)、タブ、または2つのスペースにマッチする。2連バックスラッシュはカッコと垂直バーを正規表現構文としてマークする。すなわちカッコはグループを句切り、垂直バーは選択肢を区別する。ダラー記号は行の終端へのマッチに使用される。
[ \t\n]*
最後にパターンの最終パートはセンテンスを終端させるために必要とされる以上の、余分な空白文字にマッチする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数は正規表現を扱います。
この関数はstringだけに正確にマッチするような正規表現をリターンする。looking-at
内でこの正規表現を使用すると、そのバッファー内の次の文字がstringのときだけ成功するだろう。検索関数でのこの正規表現の使用は、検索されるテキストがstringを含むなら成功するだろう。正規表現の検索を参照のこと。
これにより、その正規表現を求める関数呼び出し時に正確な文字列マッチや検索を要求できる。
(regexp-quote "^The cat$") ⇒ "\\^The cat\\$"
正規表現として記述されたコンテキストにおいて、正確な文字列マッチを結合することがregexp-quote
の1つの使い方である。たとえば以下は空白文で囲まれたstringの値であるような文字列を検索する:
(re-search-forward (concat "\\s-" (regexp-quote string) "\\s-"))
この関数はリストstringsの文字列だけにマッチする効果的な正規表現をリターンする。これはマッチングや検索を可能な限り高速にする必要があるとき、たとえばFont Lockモードで有用である17。
オプション引数parenには以下のいずれかを指定できる:
文字列なら結果regexpはparenと後の‘\)’により生成される。つまり番号付きグループを明示的に生成するためには‘"\\(?1:"’を使用する。
words
なら結果regexpは‘\<\(’と‘\)\>’で囲まれる。
symbols
ならなら結果regexpは‘\_<\(’と‘\)\_>’で囲まれる(これはプログラミング言語のキーワードやその類のマッチング時に適切なことが多い)。
非nil
ならなら結果regexpは‘\(’と‘\)’で囲まれる。
nil
なら、追加される後置演算子が式全体に確実に適用させるために必要な場合には、結果regexpは‘\(?:’と‘\)’で囲まれる。
regexp-opt
の結果regexpはその単純化されたバージョンと等価だが、通常はより効果的である。
(defun simplified-regexp-opt (strings &optional paren) (let ((parens (cond ((stringp paren) (cons paren "\\)")) ((eq paren 'words) '("\\<\\(" . "\\)\\>")) ((eq paren 'symbols) '("\\_<\\(" . "\\)\\_>")) ((null paren) '("\\(?:" . "\\)")) (t '("\\(" . "\\)"))))) (concat (car paren) (mapconcat 'regexp-quote strings "\\|") (cdr paren))))
この関数はregexp内のグループ化された構成要素(カッコで囲まれた正規表現)の総数をリターンする。これには内気なグループは含まれない(正規表現内のバッククラッシュ構造を参照)。
この関数は文字リストchars内の文字にマッチする正規表現をリターンする。
(regexp-opt-charset '(?a ?b ?c ?d ?e)) ⇒ "[a-e]"
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU Emacsではインクリメンタルと非インクリメンタルの両方で正規表現(正規表現の構文を参照)にたいする次のマッチを検索できます。インクリメンタル検索コマンドについてはRegular Expression Search in The GNU Emacs
Manualを参照してください。ここではプログラム内で有用な検索関数だけを説明します。重要な関数はre-search-forward
です。
これらの検索関数はバッファーがマルチバイトならルチバイト、ユニバイトならユニバイトに正規表現を変換します。テキストの表現方法を参照してください。
この関数はカレントバッファー内で、正規表現regexpにマッチするテキスト文字列を前方へ検索する。この関数はregexpにマッチしない任意の量のテキストをスキップして、見つかった最初のマッチの終端にポイントを残す。これはポイントの新たな値をリターンする。
引数limitは検索の境界を指定し、それはカレントバッファー内の位置であること。limitが非nil
ならカレントバッファー内の位置でなければならない。これは検索の上限位置を指定するその位置を超えるようなマッチは、受け入れられない。limitが省略またはnil
の場合のデフォルトは、そのバッファーのアクセス可能範囲の終端である。
検索失敗時にre-search-forward
が何を行うかはnoerrorの値に依存する。
nil
search-failed
エラーをシグナルする。
t
何もせずnil
をリターンする。
ポイントをlimit (またはバッファーのアクセス可能範囲の終端)に移動してnil
をリターンする。
引数noerrorはマッチに失敗した有効な検索だけに影響する。無効な引数はnoerrorとは無関係にエラーとなる。
repeatが正の数nなら検索はn回繰り返される。一連の検索は前回のマッチの終端から毎回検索が開始される。これらの一連の検索が成功すると、関数呼び出しは成功となりポイントを移動して新たな値をリターンする。それ以外は関数の呼び出しは失敗となり、結果は上述のようにnoerrorの値に依存する。repeatが負の数-nなら検索は逆方向(後方)へn回行われる。
以下の例ではポイントは最初は‘T’の前にある。この検索を評価することにより、その行の終端( ‘hat’の‘t’と改行の間)にポイントは移動する。
---------- Buffer: foo ---------- I read "∗The cat in the hat comes back" twice. ---------- Buffer: foo ----------
(re-search-forward "[a-z]+" nil t 5) ⇒ 27 ---------- Buffer: foo ---------- I read "The cat in the hat∗ comes back" twice. ---------- Buffer: foo ----------
この関数はカレントバッファー内で正規表現regexpにマッチするテキスト文字列を後方へ検索して、見つかった最初のマッチの先頭にポイントを残す。
この関数はre-search-forward
と似ているが単なるミラーイメージ(mirror-image:
鏡像)ではない。re-search-forward
は先頭が開始ポイントと可能な限り近いマッチを探す。re-search-backward
が完全なミラーイメージなら終端が可能な限り近いマッチを探すだろう。しかし実際には先頭が可能な限り近い(かつ開始ポイントの前で終わる)マッチを探す。これは与えられた位置にたいする正規表現マッチングが常に正規表現の先頭から終端に機能して、指定された開始位置から開始されることが理由。
re-search-forward
の真のミラーイメージには、正規表現を終端から先頭へマッチする特別な機能が要求されるだろう。それを実装することによる問題と比較して、値する価値はない。
この関数はstring内で正規表現regexpにたいする最初のマッチの開始位置のインデックスをリターンする。string内のそのインデックスから検索が開始される。
たとえば、
(string-match "quick" "The quick brown fox jumped quickly.") ⇒ 4
(string-match "quick" "The quick brown fox jumped quickly." 8) ⇒ 27
文字列の最初の文字のインデックスは1、2文字目は2、...となる。
この関数がマッチを見つけたら、そのマッチの先の最初の文字のインデックスは(match-end 0)
で利用できる。マッチデータを参照のこと。
(string-match "quick" "The quick brown fox jumped quickly." 8) ⇒ 27
(match-end 0) ⇒ 32
この述語関数はstring-match
と同じことを行うが、マッチデータの変更を避ける。
この関数はカレントバッファー内のポイント直後のテキストが正規表現regexpにマッチするかどうかを判断する。“直後”の正確な意味は、その検索が“固定”されていて、ポイントの後の最初の文字からマッチが開始する場合のみ成功するということ。成功なら結果はt
、それ以外はnil
。
この関数はポイントを移動しないがマッチデータは更新する。マッチデータを参照のこと。マッチデータを変更せずにテストする必要があるなら、以下で説明するlooking-at-p
を使用すること。
以下の例ではポイントは‘T’の直前にある。それ以外の場所にあれば結果はnil
になるだろう。
---------- Buffer: foo ---------- I read "∗The cat in the hat comes back" twice. ---------- Buffer: foo ---------- (looking-at "The cat in the hat$") ⇒ t
この関数はポイントの直前の(ポイントで終わる)テキストがregexpとマッチしたらt
、それ以外はnil
をリターンする。
正規表現マッチングは前方だけに機能するので、ポイントで終わるマッチをポイントから後方へ検索するように実装された。長い距離を検索する必要がある場合には、これは極めて低速になり得る。非nil
値をlimitを指定してその前を検索しないよう告げることにより、検索に要する時間を制限できる。この場合には、マッチデータはlimitかその後で始まらなければならない。以下は例:
---------- Buffer: foo ---------- I read "∗The cat in the hat comes back" twice. ---------- Buffer: foo ---------- (looking-back "read \"" 3) ⇒ t (looking-back "read \"" 4) ⇒ nil
greedyが非nil
なら、この関数は可能な限り後方へマッチを拡張して、前方の1文字がregexpがマッチの一部とならなければ停止する。マッチが拡張されたときには、マッチ開始位置がlimitの前にあっても許される。
一般的にlooking-back
は低速なので、可能な限り使用を避けることを推奨する。この理由によりlooking-back-p
の追加は計画されていない。
この述語関数はlooking-at
と同様に機能するがマッチデータを更新しない。
この変数が非nil
なら、それは空白文字を検索する方法を告げる正規表現であること。この場合には検索される正規表現内のすべてのスペース属は、この正規表現を使用することを意味する。しかし‘[…]’、‘*’‘+’、‘?’のような構文要素内のスペースはsearch-spaces-regexp
の影響を受けない。
この変数はすべての正規表現検索とマッチ構文要素に影響するので、コードの可能な限り狭い範囲にたいして一時的にバインドすること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
通常の正規表現関数は、‘\|’や繰り返しの構文要素を処理するために必要なときだけバックトラッキングを行いますが、何らかのマッチが見つかるまでの間だけこれを継続します。そして成功した後に見つかった最初のマッチを報告します。
このセクションでは正規表現にたいしてPOSIX標準で指定された完全なバックトラッキングを処理する他の検索関数を説明します。これらはPOSIXが要求する最長マッチを報告できるようにすべての可能なマッチを試みて、すべてのマッチが見つかるまでバックトラッキングを継続します。これは非常に低速なので、本当に最長マッチが必要なときだけこれらの関数を使用してください。
POSIXの検索とマッチ関数は、非欲張りな繰り返し演算子(non-greedyを参照)を正しくサポートしません。これはPOSIXのバックトラッキングが非欲張りな繰り返しのセマンチックと競合するからです。
これはre-search-forward
と似ているが、正規表現マッチングにたいしてPOSIX標準が指定する完全なバックトラッキングを行う点が異なる。
これはre-search-backward
と似ているが、正規表現マッチングにたいしてPOSIX標準が指定する完全なバックトラッキングを行う点が異なる。
これはlooking-at
と似ているが、正規表現マッチングにたいしてPOSIX標準が指定する完全なバックトラッキングを行う点が異なる。
これはstring-match
と似ているが、正規表現にたいしてPOSIX標準が指定する完全なバックトラッキングを行う点が異なる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsは検索の間に見つかったテキスト片の開始と終了の位置を追跡します。これはマッチデータ(match data)と呼ばれます。このマッチデータのおかげで、メールメッセージ内のデータのような複雑なパターンを検索した後に、そのパターンの制御下でマッチ部分を抽出できるのです。
マッチデータには通常はもっとも最近の検索だけが記述されるので、後で参照したい検索とそのマッチデータの使用の間に誤って別の検索を行わないように注意しなければなりません。誤って別の検索を避けるのが不可能な場合には、マッチデータの上書きを防ぐために前後でマッチデータの保存とリストアを行わなければなりません。
上書きを行わないと明記されていない限り、すべての関数は上書きを許されていることに注意してください。結果としてバックグラウンド(遅延実行のためのタイマーとアイドルタイマーを参照)で暗黙に実行される関数は、おそらく明示的にマッチデータの保存とリストアを行うべきでしょう。
33.6.1 マッチしたテキストの置換 | マッチされた部分文字列の置換。 | |
33.6.2 単純なマッチデータへのアクセス | 特定の部分式開始箇所のようなマッチデータの単一アイテムへのアクセス。 | |
33.6.3 マッチデータ全体へのアクセス | リストとしてマッチデータ全体に一度にアクセスする。 | |
33.6.4 マッチデータの保存とリストア |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数は、最後の検索でマッチされたテキストのすべて、または一部を置換します。これはマッチデータにより機能します。
この関数はバッファーや文字列にたいして置換処理を行う。
あるバッファーで最後の検索を行った場合には、string引数を省略またはnil
を指定すること。また最後に検索を行ったバッファーがカレントバッファーであることを確認すること。その場合には、この関数はマッチしたテキストをreplacementで置換することにより、そのバッファーを編集する。これは置換したテキスト終端にポイントを残す。
文字列にたいして最後の検索を行った場合には、同じ文字列がstringに渡される。その場合には、この関数はマッチしたテキストがreplacementに置き換えられた新たなテキストをリターンする。
fixedcaseが非nil
ならreplace-match
は大文字小文字を変更せずに置換テキストを使用して、それ以外は置換されるテキストがcapitalize(先頭が大文字)されているかどうかに応じて、置換テキストを変換する。元のテキストがすべて大文字なら置換テキストを大文字に変換する。元のテキストの単語すべてがcapitalizeされていたら置換テキストのすべての単語をcapitalizeする。すべての単語が1文字かつ大文字なら、それらはすべて大文字の単語ではなくcapitalizeされた単語として扱われる。
literalが非nil
ならreplacementはそのまま挿入されるが、必要に応じてcaseの変更だけが行われる。これがnil
(デフォルト)なら文字‘\’は特別に扱われる。replacement内に‘\’が出現した場合には、それは以下のシーケンスのいずれかの一部でなければならない:
これは置換されるテキスト全体を意味する。
これは元のregexpのn番目の部分式にマッチするテキストを意味する。この部分式とは‘\(…\)’の内部にグループかされた式のこと。n番目のマッチがなければ空文字列が代用される。
これは置換テキスト内で単一の‘\’を意味する。
これはそれ自身を意味する(replace-regexp
と関連するコマンドの互換用。Regexp Replace in The GNU Emacs Manualを参照)。
これら以外の‘\’に続く文字はエラーをシグナルする。
‘\&’や‘\n’により行われる代替えは、もしあればcase変換の後に発生する。したがって代替えする文字列は決してcase変換されない。
subexpが非nil
なら、それは全体のマッチではなくマッチされたregexpの部分式番号subexpだけを置換することを指定する。たとえば‘foo
\(ba*r\)’のマッチング後にreplace-match
を呼び出すと、subexpが1なら‘\(ba*r\)’にマッチしたテキストだけを置換することを意味する。
この関数はreplace-match
によりバッファーに挿入されるであろうテキストをリターンするがバッファーを変更しない。これは‘\n’や‘\&’のような構文要素をマッチしたグループで置き換えた実際の結果をユーザーに示したいとき有用。引数replacement、およびオプションのfixedcase、literal、string、subexpはreplace-match
のときと同じ意味をもつ。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは最後の検索やマッチング操作で、それが成功した場合に何がマッチされたのかを調べるために、マッチデータを使用する方法について説明します。
マッチしたテキスト全体または正規表現のカッコで括られた特定の部分式にたいして問い合わせることができます。以下の関数では、countによりどの部分式かを指定できます。countが0ならマッチ全体、countが正なら望む部分式を指定します。
正規表現での部分式とは、エスケープされたカッコ‘\(…\)’でグループ化された表現だったことを思い出してください。count番目の部分式は正規表現全体の先頭から‘\(’を数えることで見つけられます。最初の部分式が1、2つ目が2、...となります。正規表現だけが部分式をもつことができ、単純な文字列検索の後で利用できるのはマッチ全体の情報だけです。
成功したすべての検索はマッチデータをセットします。したがって検索後は別の検索を行うかもしれない関数を呼び出す前に、検索の直後にマッチデータを問い合わせるべきです。別の検索を呼び出すかもしれない関数の前後で、かわりにマッチデータの保存とリストアすることもできます(マッチデータの保存とリストアを参照)。またはstring-match-p
のようなマッチデータを変更しないと明示されている関数を使用してください。
検索が成功しようと失敗しようとマッチデータは変更されます。現在はこのように実装されていますが、これは将来変更されるかもしれません。失敗した後のマッチデータを信用しないでください。
この関数は最後の検索やマッチ処理でマッチしたテキストを文字列としてリターンする。これはcountが0ならテキスト全体、countが正ならcount番目のカッコで括られた部分式に対応する部分だけをリターンする。
そのような最後の処理が文字列にたいするstring-match
呼び出しなら、引数in-stringには同じ文字列を渡すこと。バッファーの検索やマッチの後は、in-stringを省略するかnil
を渡すこと。しかし最後に検索やマッチを行ったバッファーが、match-string
呼び出し時にカレントバッファーであることを確認すること。このアドバイスにしたがわなければ誤った結果となるだろう。
countが範囲外、‘\|’選択肢内部の部分式が使用されない、または0回の繰り返しなら値はnil
。
この関数はmatch-string
と似ているが結果がテキストプロパティをもたない点が異なる。
最後の正規表現検索がマッチを見つけたら、この関数はマッチしたテキストか部分式の開始位置をリターンする。
countが0なら値はマッチ全体の開始位置。それ以外ならcountは正規表現内の部分式を指定するので、この関数の値はその部分式にたいするマッチの開始位置。
使用されない、あるいは0回の繰り返しであるような‘\|’選択肢内部の部分式にたいしての値はnil
。
この関数はmatch-beginning
と似ているがマッチの開始ではなく終了位置である点が異なる。
以下はマッチデータを使用する例です。コメントの数字はテキスト内での位置を示しています:
(string-match "\\(qu\\)\\(ick\\)" "The quick fox jumped quickly.") ;0123456789 ⇒ 4
(match-string 0 "The quick fox jumped quickly.") ⇒ "quick" (match-string 1 "The quick fox jumped quickly.") ⇒ "qu" (match-string 2 "The quick fox jumped quickly.") ⇒ "ick"
(match-beginning 1) ; ‘qu’にたいするマッチ先頭の ⇒ 4 ; インデックスは4
(match-beginning 2) ; ‘ick’にたいするマッチ先頭の ⇒ 6 ; インデックスは6
(match-end 1) ; ‘qu’にたいするマッチ終端の ⇒ 6 ; インデックスは6 (match-end 2) ; ‘ick’にたいするマッチ終端の ⇒ 9 ; インデックスは9
別の例を以下に示します。ポイントは最初は行の先頭にあります。検索の後はポイントはスペースと単語‘in’の間にあります。マッチ全体の先頭はバッファーの9つ目の文字‘T’、1つ目の部分式にたいするマッチの先頭は13番目の文字‘c’です。
(list (re-search-forward "The \\(cat \\)") (match-beginning 0) (match-beginning 1)) ⇒ (17 9 13)
---------- Buffer: foo ---------- I read "The cat ∗in the hat comes back" twice. ^ ^ 9 13 ---------- Buffer: foo ----------
(この場合にはリターンされるインデックスはバッファー位置であり、バッファーの1つ目の文字を1と数える。)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
関数match-data
とset-match-data
は、マッチデータ全体にたいして一度に読み取り、または書き込みを行います。
この関数は最後の検索によりマッチしたテキストのすべての情報を記録する位置(マーカーか整数)をリターンする。要素0は正規表現全体にたいするマッチの先頭の位置。要素1はその正規表現にたいするマッチの終端の位置。次の2つの要素は1つ目の部分式にたいするマッチの先頭と終了、...となる。一般的に要素番号
2n
は(match-beginning n)
、要素番号
2n + 1
は(match-end n)
に対応する。
すべての要素は通常はマーカーかnil
だが、もしintegersが非nil
ならマーカーのかわりに整数を使用することを意味する(この場合にはマッチデータの完全なリストアを容易にするために、リストの最後の要素としてバッファー自身が追加される)。最後の検索がstring-match
により文字列にたいして行われた場合には、マーカーは文字列の内部をポイントできないので常に整数が使用される。
reuseが非nil
なら、それはリストであること。この場合には、match-data
はマッチデータをreuse内に格納する。つまりreuseは破壊的に変更される。reuseが正しい長さである必要はない。特定のマッチデータにたいして長さが十分でなければリストは拡張される。reuseが長過ぎる場合には、長さはそのままで使用しない要素にnil
がセットされる。この機能にはガベージコレクションの必要頻度を減らす目的がある。
reseatが非nil
なら、reuseリスト内のすべてのマーカーは存在しない場所を指すよう再設定される。
他の場合と同じように検索関数とその検索のマッチデータへのアクセスを意図するmatch-data
呼び出しの間に介入するような検索があってはならない。
(match-data) ⇒ (#<marker at 9 in foo> #<marker at 17 in foo> #<marker at 13 in foo> #<marker at 17 in foo>)
この関数はmatch-listの要素からマッチデータをセットする。match-listは前のmatch-data
呼び出しの値であるようなリストであること(正確には同じフォーマットなら他のものでも機能するだろう)。
match-listが存在しないバッファーを参照する場合でもエラーとはならない。これは無意味だが害のない方法でマッチデータをセットする。
reseatが非nil
なら、リストmatch-list内のすべてのマーカーは存在しない場所を指すよう再設定される。
store-match-data
はset-match-data
の半ば時代遅れなエイリアス。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以前に行った検索にたいするマッチデータを後で使用するために保護する必要があるなら、検索を行うかもしれない関数の呼び出し時に呼び出しの前後でマッチデータの保存とリストアを行う必要があるでしょう。以下はマッチデータ保存に失敗した場合に発生する問題を示す例です:
(re-search-forward "The \\(cat \\)")
⇒ 48
(foo) ; foo
が他の検索を行うと
(match-end 0)
⇒ 61 ; 結果は期待する48と異なる!
save-match-data
でマッチデータの保存とリストアができます:
このマクロはbodyを実行して、その前後のマッチデータの保存とリストアを行う。リターン値はbody内の最後のフォームの値。
set-match-data
とmatch-data
を一緒に使用して、save-match-data
の効果を模倣することができます。以下はその方法です:
(let ((data (match-data)))
(unwind-protect
… ; 元のマッチデータを変更してもOK
(set-match-data data)))
プロセスフィルター関数(プロセスのフィルター関数を参照)、およびプロセスセンチネル(センチネル: プロセス状態の変更の検知を参照)の実行時には、Emacsが自動的にマッチデータの保存とリストアを行います。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファーのある部分でregexpにたいするすべてのマッチを見つけてそれらを置換したい場合には、以下のようにre-search-forward
とreplace-match
を使用して明示的なループを記述するのが最良の方法です:
(while (re-search-forward "foo[ \t]+bar" nil t) (replace-match "foobar"))
replace-match
の説明はReplacing the Text that
Matchedを参照してください。
しかし文字列内のマッチの置換、特に置換を効果的に行いたい場合には、より複雑になります。そのためにEmacsはこれを行うための関数を提供します。
この関数はstringをコピーしてregexpにたいするマッチを検索、それらをrepに置き換える。これは変更されたコピーをリターンする。startが非nil
ならマッチにたいする検索はstring内のそのインデックスから開始されて、そのインデックスより前で始まるマッチは変更されない。
この関数は置換を行うためにオプション引数fixedcase、literal、subexpを渡してreplace-match
を使用する。
repは文字列のかわりに関数でもよい。この場合にはreplace-regexp-in-string
はそれぞれのマッチにたいして、そのテキストを単一の引数としてrepを呼び出す。これはrepがリターンする値を収集して、それを置換文字列としてreplace-match
に渡す。この時点でのマッチデータはstringの部分文字列にたいするregexpのマッチ結果。
query-replace
の行に関するコマンドを記述したい場合には、perform-replace
を使用してこれを行うことができます。
これはquery-replace
と関連するコマンドの根幹となる関数。これは位置startとendの間にあるテキスト内に出現するfrom-stringの一部またはすべてを置換する。startがnil
(または省略)ならかわりにポイント、endにはそのバッファーのアクセス可能範囲の終端が使用される。
query-flagがnil
ならすべてのマッチを置換する。それ以外なら、それぞれにたいしてユーザーにたいして何をすべきか問い合わせる。
regexp-flagが非nil
ならfrom-stringは正規表現、それ以外はリテラルとしてマッチしなければならない。delimited-flagが非nil
なら単語境界に囲まれた置換だけが考慮される。
引数replacementsはマッチを何で置き換えるかを指定する。文字列ならその文字列を使用する。サイクル順に使用される文字列リストでもよい。
replacementsがコンスセル(function . data)
なら、置換テキストを取得するためにそれぞれのマッチ後にfunctionを呼び出すことを意味する。この関数はdataとすでに置換された個数という、2つの引数で呼び出される。
repeat-countが非nil
なら、それは整数であること。その場合にはサイクルを次に進める前に、replacementsリスト内の各文字列を何度使用するかを指定する。
from-stringが大文字アルファベットを含む場合には、perform-replace
はcase-fold-search
をnil
にバインドして大文字小文字を変換せずにreplacementsを使用する。
キーマップquery-replace-map
は通常は問い合わせにたいして可能なユーザー応答を定義する。引数mapが非nil
なら、それはquery-replace-map
のかわりに使用するキーマップを指定する。
この関数はfrom-stringの次のマッチを検索するために2つの関数のうちいずれか1つを使用する。これらの関数は2つの変数replace-re-search-function
とreplace-search-function
により指定される。引数regexp-flagが非nil
なら前者、nil
なら後者が呼び出される。
この変数はperform-replace
にたいする有効なユーザー応答を定義するスペシャルキーマップを保持して、コマンドはy-or-n-p
やmap-y-or-n-p
と同様にそれを使用する。このマップは2つの点において普通のマップと異なる。
read-key-sequence
を使用しないからである。
query-replace-map
にたいして意味をもつバインディングがあります。それらのうちいくつかはquery-replace
とその同族にたいしてのみ意味をもちます。
act
判断している対象にたいしてアクションを起こす(言い換えると“yes”)。
skip
この問いにたいしてアクションを起こさない(言い換えると“no”)。
exit
この問いにたいして“no”を答えて、さらに一連の問いすべてにたいして“no”が応答されたとみなして問い合わせをあきらめる。
exit-prefix
exit
と似ているが、unread-command-events
にたいして押下されたキーを追加する(その他のイベント入力の機能を参照)。
act-and-exit
この問いにたいして“yes”を答えて、さらに一連の問いすべてにたいして後続の問いに“no”が応答されるとみなして問い合わせをあきらめる。
act-and-show
この問いに“yes”を答えるが、結果を表示してまだ次の問いへ進まない。
automatic
これ以上のユーザーとの対話を行わず、この問いと後続の問いにたいして“yes”を答える。
backup
前に問い合わせた以前の場所に戻る。
edit
この問いに対処するために、通常とられるアクションのかわりに再帰編集にエンターする。
edit-replacement
ミニバッファー内で、この問いにたいする置換を編集する。
delete-and-edit
検討中のテキストを削除して、それを置換するために再帰編集にエンターする。
recenter
scroll-up
scroll-down
scroll-other-window
scroll-other-window-down
指定されたウィンドウスクロール操作を行って同じ問いを再度尋ねる。この問いにはy-or-n-p
と関連する関数だけが使用される。
quit
即座にquitを行う。この問いにはy-or-n-p
と関連する関数だけが使用される。
help
ヘルプを表示して再度尋ねる。
この変数はマルチバッファー置換で有用な追加キーバインディングを提供することによりquery-replace-map
を拡張するキーマップを保持する。追加されるバインディングは以下のとおり:
automatic-all
残りすべてのバッファーにたいして、それ以上の対話をせずその問いと後続のすべての問いに“yes”を答える。
exit-current
この問いに“no”を答えてカレントバッファーにたいする一連の問いすべてをあきらめる。そしてシーケンス内の次のバッファーへ問いを継続する。
この変数は置換する次の文字列を検索するためにperform-replace
が呼び出す関数を指定する。デフォルト値はsearch-forward
。それ以外の値の場合にはsearch-forward
の最初の3つの引数を引数とする関数を指定すること(文字列の検索を参照)。
この変数は置換する次のregexpを検索するためにperform-replace
が呼び出す関数を指定する。デフォルト値はre-search-forward
。それ以外の値の場合にはre-search-forward
の最初の3つの引数を引数とする関数を指定すること(正規表現の検索を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは、編集において特定の目的のために使用される正規表現を保持するいくつかの変数を説明します。
これはページを分割する行開始を記述する正規表現。デフォルト値は"^\014"
("^^L"
または"^\C-l"
)。これはフォームフィード文字(改頁文字)で始まる行とマッチする。
以下の2つの正規表現が、常に行頭からマッチが始まる正規表現とみなすべきではありません。これらを‘^’にマッチするアンカーとして使用するべきではありません。ほとんどの場合では、パラグラフコマンドは行頭にたいしてのみマッチのチェックを行うので、これは‘^’が不要であることを意味します。非0の左マージンが存在する場合には、これらは左マージンの後から始まるマッチに適用されます。その場合には、‘^’は不適切でしょう。しかし左マージンを決して使用しないモードでは‘^’は無害でしょう。
これはパラグラフを分割する行の開始を認識する正規表現(これを変更する場合はparagraph-start
も変更する必要があるかもしれない)。デフォルト値は"[ \t\f]*$"
であり、これは(左マージン以降)すべてがスペース、タブ、フォームフィードで構成される行とマッチする。
これはパラグラフを開始または分割する行の開始を認識する正規表現。デフォルト値は"\f\\|[ \t]*$"
であり、これは(左マージン以降)すべてが空白文字で構成される行やフォームフィードで始まる行とマッチする。
非nil
なら、以降に続く空白文字を含めてセンテンスの終わりを記述する正規表現であること(これとは無関係にパラグラフ境界もセンテンスを終了させる)。
値がnil
(デフォルト)なら、関数sentence-end
がregexpを構築する。センテンス終端の認識に使用するregexpを得るために常に関数sentence-end
を使用するべきなのはこれが理由。
この関数は変数sentence-end
が非nil
ならその値をリターンする。それ以外なら変数sentence-end-double-space
(Definition of sentence-end-double-spaceを参照)、sentence-end-without-period
、sentence-end-without-space
にもとづくデフォルト値をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
構文テーブル(syntax table)はバッファー内のそれぞれの文字にたいして構文的な役割を指定します。単語、シンボル、その他の構文要素の開始と終了の判定にこれを使用できます。この情報はFont Lockモード(Font Lockモードを参照)や、種々の複雑な移動コマンド(モーションを参照)を含む多くのEmacs機能により使用されます。
34.1 構文テーブルの概念 | 構文テーブルの基本的概念。 | |
34.2 構文記述子 | 文字がクラス分けされる方法。 | |
34.3 構文テーブルの関数 | 構文テーブルを作成、調査、変更する方法。 | |
34.4 構文プロパティ | テキストプロパティによる構文テーブルのオーバーライド。 | |
34.5 モーションと構文 | 特定の構文による文字間の移動。 | |
34.6 式のパース | 構文テーブル使用によるバランスのとれた式の解析。 | |
34.7 構文テーブルの内部 | 構文テーブルの情報が格納される方法。 | |
34.8 カテゴリー | 文字構文をクラス分けする別の手段。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
構文テーブルは、それぞれの文字の構文クラス(syntax class)やその他の構文的プロパティを照合するために使用できるデータ構造です。構文テーブルはテキストを横断したスキャンや移動のためにLispプログラムから使用されます。
構文テーブルは内部的には文字テーブルです(文字テーブルを参照)。インデックスcの要素はコードcの文字を記述します。値は該当する文字の構文を指定するコンスセルです。詳細は構文テーブルの内部を参照してください。しかし構文テーブルの内容を変更や確認するためにaset
やaref
を使用するかわりに、通常は高レベルな関数char-syntax
やmodify-syntax-entry
を使用するべきです。これらについては構文テーブルの関数で説明します。
この関数はobjectが構文テーブルならt
をリターンする。
バッファーはそれぞれ自身のメジャーモードをもち、それぞれのメジャーモードはさまざまな文字の構文クラスにたいして独自の考えをもっています。たとえばLisモードでは文字‘;’はコメントの開始ですが、Cモードでは命令文の終端になります。これらのバリエーションをサポートするために、構文テーブルはそれぞれのバッファーにたいしてローカルです。一般的に各メジャーモードは自身の構文テーブルをもち、そのモードを使用するすべてのバッファーにそれがインストールされます。たとえば変数emacs-lisp-mode-syntax-table
はEmacsのLispモードが使用する構文テーブル、c-mode-syntax-table
はCモードが使用する構文テーブルを保持します。あるメジャーモードの構文テーブルを変更すると、そのモードのバッファー、およびその後でそのモードに置かれるすべてのバッファーの構文も同様に変更されます。複数の類似するモードが1つの構文テーブルを共有することがときおりあります。構文テーブルをセットアップする方法の例はメジャーモードの例を参照してください。
別の構文テーブルから構文テールを継承(inherit)できます。これを親構文テーブル(parent syntax table)と呼びます。構文テーブルは、ある文字にたいして構文クラス“inherit”を与えることにより、構文クラスを未指定にしておくことができます。そのような文字は親構文テーブルが指定する構文クラスを取得します(構文クラスのテーブルを参照)。Emacsは標準構文テーブル(standard syntax table)を定義します。これはデフォルトとなる親構文テーブルであり、Fundamentalモードが使用する構文テーブルでもあります。
この関数は標準構文テーブルをリターンする。これはFundamentalモードが使用する構文テーブルである。
Emacs Lispリーダーは変更不可な独自のビルトイン構文ルールをもつので、構文テーブルは使用しません(いくつかのLispシステムはリード構文を再定義する手段を提供するが、わたしたちは単純化のためこの機能をEmacs Lisp外部に留める決定をした)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
構文クラス(syntax class)の文字は、その文字の構文的な役割を記述します。各構文テーブルは、それぞれの文字の構文クラスを指定します。ある構文テーブルでの文字のクラスと、別のテーブルにおけるその文字のクラスとの間に関連性がある必要はありません。
構文テーブルはそれぞれニーモニック文字(mnemonic character)により選別され、クラスを指定する必要がある際にはそのクラスの名前としての役割を果たします。この指定子文字(designator character)は通常はそのクラスに割当てられることが多々あります。しかしその指定子としての意味は不変であり、その文字がカレントでもつ構文とは独立しています。つまりカレント構文テーブルにおいて実際に文字‘\’が構文をもつかどうかに関係なく、指定子文字としての‘\’は常にエスケープ文字(escape character)を意味します。 構文クラスとそれらの指定子文字のリストは構文クラスのテーブルを参照してください。
構文記述子(syntax
descriptor)とは文字の構文クラスと、その他の構文的なプロパティを記述するLisp文字列です。ある文字の構文を変更したい際には、関数modify-syntax-entry
を呼び出して引数に構文記述子を渡すことにより行います(構文テーブルの関数を参照)。
構文記述子の1つ目の文字は構文クラスの指定子文字でなければなりません。2つ目の文字がもしあれば、マッチング文字を指定します(Lispでは‘(’にたいするマッチング文字は‘)’)。スペースはマッチング文字が存在しないことを指定します。その後に続く文字は追加の構文プロパティを指定します(構文フラグを参照)。
マッチング文字やフラグが必要なければ、(構文クラスを指定する)1つの文字だけで十分です。
たとえばCモードでの文字‘*’の構文記述子は". 23"
(区切り記号、マッチング文字用スロットは未使用、コメント開始記号の2つ目の文字、コメント終了記号の1つ目の文字)、‘/’にたいするエントリーは‘. 14’ (区切り記号、マッチング文字用スロットは未使用、コメント開始記号の1つ目の文字、コメント終了記号の2つ目の文字)です。
Emacsは低レベルでの構文クラスを記述するために使用されるraw構文記述子(raw syntax descriptors)も定義しています。構文テーブルの内部を参照してください。
34.2.1 構文クラスのテーブル | ||
34.2.2 構文フラグ | 各文字が所有できる追加のフラグ。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下は構文クラス、それらの指定子となる文字と意味、および使用例を示すテーブルです。
シンボルや単語を区別する文字。空白文字は通常は他の構文的な意義をもたず、複数の空白文字は構文的には単一の空白文字と等しい。スペース、タブ、フォームフィードは、ほとんどすべてのメジャーモードにおいて空白文字にクラス分けされる。
この構文クラスは‘ ’か‘-’により指定できる。両指定子は等価。
人間の言語における単語の一部。これらは通常はプログラム内において変数やコマンドの名前として使用される。すべての大文字と小文字、および数字は通常は単語構成文字。
単語構成文字とともに変数やコマンドの名前で使用される追加の文字。例としてはLispモードの文字‘$&*+-_<>’が含まれ、これらはたとえ英単語の一部ではないとしてもシンボルの名前の一部となり得る。標準Cではシンボル内において非単語構成文字で有効な文字はアンダースコア(‘_’)のみ。
人間の言語において句読点として使用される文字、またはプログラミング言語でシンボルを別のシンボルと区別するために使用される文字。Emacs Lispモードのようないくつかのプログラミング言語のモードでは、単語構成文字およびシンボル構成文字のいずれでもないいくつかの文字はすべて他の用途をもつので、このクラスの文字をもたない。Cモードのような他のプログラミング言語のモードでは演算子にたいして区切り文字構文が使用される。
文や式を囲うために異なるペアとして使用される文字。そのようなグループ化は開カッコで開始され、閉カッコで終了する。開カッコ文字はそれぞれ特定の閉カッコ文字にマッチして、その逆も成り立つ。Emacsは通常は閉カッコ挿入時にマッチする開カッコを示す。カッコの点滅を参照のこと。
人間の言語やCのコードでは、カッコのペアは‘()’、‘[]’、‘{}’。Emacs Lispではリストとベクターにたいする区切り文字(‘()’と‘[]’)はカッコ文字としてクラス分けされる。
文字列定数を区切るために使用される文字。文字列の先頭と終端に同じ文字列クォート文字が出現する。このようなクォート文字列はネストされない。
Emacsのパース機能は文字列を単一のトークンとみなす。文字列内ではその文字の通常の構文的な意味は抑制される。
Lispモードはダブルクォーテーション(‘"’)と垂直バー(‘|’)とう2つの文字列クォート文字をもつ。Emacs Lispでは‘|’は使用しないがCommon Lispでは使用される。Cも文字列にたいするダブルクォート文字、および文字定数にたいするシングルアポストロフィ(‘'’)という2つのクォート文字をもつ。
人間用のテキストには文字列クォート文字がない。そのクォーテーション内の別の文字の通常の構文的プロパティを、クォーテーションマークがオフに切り替えることを、わたしたちは望まない。
文字列や文字定数内で使用されるようなエスケープシーケンスで始まる文字。CとLispの両方で文字‘\’はこのクラスに属する(Cでは文字列内でのみ使用されるが、Cコード中を通じてこのように扱っても問題ないことがわかった)。
words-include-escapes
が非nil
なら、このクラスの文字は単語の一部とみなされる。単語単位の移動を参照のこと。
その文字の通常の構文的な意義を失うように、後続の文字をクォートするために使用される文字。これは直後に続く文字だけに影響する点がエスケープ文字と異なる。
words-include-escapes
が非nil
なら、このクラスの文字は単語の一部とみなされる。単語単位の移動を参照のこと。
このクラスはTeXモードのバックスラッシュにたいして使用される。
文字列クォート文字と似ているが、この区切りの間にある文字の構文的なプロパティは抑制されない点が異なる。現在のところTeXモードだけが区切りペアを使用する(‘$’によりmathモードに出入りする)。
式に隣接して出現した場合には式の一部とみなされる構文的演算子にたいして使用される文字。Lispモードではアポストロフィー‘'’ (クォートに使用)、カンマ‘,’ (マクロに使用)、‘#’ (特定のデータ型にたいするリード構文として使用)が、これらの文字に含まれる。
さまざまな言語においてコメントを区切るために使用する文字。人間用のテキストはコメント文字をもたない。Lispではセミコロン(‘;’)がコメントの開始、改行かフォームフィードで終了する。
この構文クラスは特定の構文を指定しない。これはその文字の構文を探すために標準構文テーブルを照合するよう告げる。
特殊なコメントを開始または終了させる文字。任意の汎用コメント区切りは任意の汎用コメント区切りにマッチするが、コメント開始とコメント終了はマッチできない。汎用コメント区切りは汎用コメント区切り同士としかマッチできない。
この構文クラスは主としてsyntax-table
テキストプロパティ(構文プロパティを参照)とともに使用することを意図している。任意の文字範囲の最初と最後の文字にたいして、それらが汎用コメント区切りであることを示すsyntax-table
プロパティを付与することにより、その範囲がコメントを形成するとマークすることができる。
文字列を開始や終了させる文字。任意の汎用文字列区切りは任意の汎用文字列区切りにマッチするが、通常の文字列クォート文字とはマッチできない。
この構文クラスは主としてsyntax-table
テキストプロパティ(構文プロパティを参照)とともに使用することを意図している。任意の文字範囲の最初と最後の文字にたいして、それらが汎用文字列区切りであることを示すsyntax-table
プロパティを付与することにより、その範囲が文字列定数を形成するとマークすることができる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
構文テーブル内の文字全体にたいして構文クラスに加えてフラグを指定できます。利用できる8つのフラグがあり、それらは文字‘1’、‘2’、‘3’、‘4’、‘b’、‘c’、‘n’、‘p’で表されます。
‘p’を除くすべてのフラグはコメント区切りを記述するために使用されます。数字のフラグは2文字から構成されるコメント区切りにたいして使用されます。これらは文字の文字クラスに関連付けられた構文的プロパティに加えて、その文字も同様にコメントシーケンスの一部となれることを示します。Cモードでは区切り文字であり、かつコメントシーケンス開始(‘/*’)の2文字目であり、かつコメントシーケンス終了(‘*/’)の1文字目である‘*’のような文字のためにフラグとクラスは互いに独立しています。フラグ‘b’、‘c’、‘n’は対応するコメント区切りを限定するために使用されます。
以下は文字cにたいして利用できるフラグと意味を示すテーブルです:
Emacsは任意の構文テーブル1つにたいして、同時に複数のコメントスタイルをサポートする。コメントスタイルはフラグ‘b’、‘c’、‘n’の組み合わせなので8個の異なるコメントスタイルが可能である。コメント区切りはそれぞれスタイルをもち、同じスタイルのコメント区切りとのみマッチできる。つまりコメントがスタイル“bn”のコメント開始シーケンスで開始されるなら、そのコメントは次のスタイル“bn”のコメント終了シーケンスにマッチするまで拡張されるだろう。
C++にたいして適切なコメント構文は以下のようになる:
‘124’
‘23b’
‘>’
これは4つのコメント区切りシーケンスを定義する:
これは2文字目の‘*’が‘b’フラグをもつので、“b”スタイルのコメント開始シーケンス。
これは2文字目の‘/’が‘b’フラグをもたないので、“a”スタイルのコメント開始シーケンス。
これは1文字目の‘*’が‘b’フラグをもつので、“b”スタイルのコメント終了シーケンス。
これは改行文字が‘b’フラグをもたないので、“a”スタイルのコメント終了シーケンス。
関数backward-prefix-chars
はこれらの文字、同様にメインの構文クラスがプレフィクスであるような文字(‘'’)を超えて後方に移動する。モーションと構文を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは構文テーブルの作成、アクセス、変更を行う関数を説明します。
この関数は新たに構文テーブルを作成する。tableが非nil
なら新たな構文テーブルの親はtable、それ以外なら標準構文テーブルが親になる。
新たな構文テーブルでは最初はすべての文字に構文クラス“inherit”(‘@’)が与えられて、それらの構文は親テーブルから継承される(構文クラスのテーブルを参照)。
この関数はtableのコピーを構築してそれをリターンする。tableが省略またはnil
なら標準構文テーブルのコピーをリターンする。それ以外の場合には、tableが構文テーブルでなければエラーをシグナルする。
この関数はsyntax-descriptorに応じてcharの構文エントリーをセットする。charは文字、または(min
. max)
という形式のコンスセルでなければならない。後者の場合には、この関数はminとmax
(両端を含む)の間のすべての文字にたいして構文エントリーをセットする。
構文はtable (デフォルトはカレントバッファーの構文テーブル)にたいしてのみ変更されて、他のすべての構文テーブルにたいしては変更されない。
引数syntax-descriptorは構文記述子、すなわち1文字目が構文クラス指定子、2文字目以降がオプションでマッチング文字と構文フラグを指定する文字列。構文記述子を参照のこと。syntax-descriptorが有効な構文記述子でなければエラーがシグナルされる。
この関数は常にnil
をリターンする。この文字にたいするテーブル内の古い構文情報は破棄される。
例:
;; 空白文字クラスのスペースをputする
(modify-syntax-entry ?\s " ")
⇒ nil
;; ‘$’を開カッコ文字にして、 ;; ‘^’を対応する閉カッコにする (modify-syntax-entry ?$ "(^") ⇒ nil
;; ‘^’を閉カッコ文字にして ;; ‘$’を対応する開カッコにする (modify-syntax-entry ?^ ")$") ⇒ nil
;; ‘/’を区切り文字で ;; コメント開始シーケンス1文字目、 ;; かつコメント終了シーケンス2文字目とする ;; これはCモードで使用される (modify-syntax-entry ?/ ". 14") ⇒ nil
この関数は指定子文字(構文クラスのテーブルを参照)の表現でcharacterの構文クラスをリターンする。これはクラスだけをリターンして、マッチング文字や構文フラグはリターンしない。
以下の例はCモードにたいして適用する(
char-syntax
がリターンする文字を確認しやすいようにstring
を使用する)。
;; スペース文字は空白文字構文クラスをもつ (string (char-syntax ?\s)) ⇒ " "
;; スラッシュ文字は区切り文字構文をもつ。
;; コメント開始やコメント終了シーケンスの一部でもある場合、
;; char-syntax
呼び出しはこれを明らかにしないことに注意。
(string (char-syntax ?/))
⇒ "."
;; 開カッコ文字は開カッコ構文をもつ。
;; これがマッチング文字‘)’をもつことは
;; char-syntax
呼び出しでは自明ではないことに注意。
(string (char-syntax ?\())
⇒ "("
この関数はカレントバッファーの構文テーブルをtableにする。これはtableをリターンする。
この関数はカレント構文テーブル(カレントバッファーのテーブル)をリターンする。
このコマンドはbuffer (デフォルトはカレントバッファー)の構文テーブルのコンテンツをhelpバッファーに表示する。
このマクロはtableをカレント構文テーブルとして使用してbodyを実行する。これは古いカレント構文テーブルのリストア後にbodyの最後のフォームの値をリターンする。
各バッファーは独自にカレント構文テーブルをもつので、マクロはこれを入念に行うべきだろう。with-syntax-table
はマクロの実行開始時には、そのときカレントのバッファーが何であれカレント構文テーブルを一時的に変更する。他のバッファーは影響を受けない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ある言語の構文を指定するのに構文テーブルが十分に柔軟でないときは、
バッファー内に出現する特定の文字にたいしてテキストプロパティsyntax-table
を適用することにより構文テーブルをオーバーライドできます。テキストプロパティを適用する方法についてはテキストのプロパティを参照してください。
以下はテキストプロパティsyntax-table
の有効な値です:
プロパティの値が構文テーブルなら、根底となるテキスト文字の構文を決定するカレントバッファーの構文テーブルのかわりにそのテーブルが使用される。
(syntax-code . matching-char)
この形式のコンスセルは根底となるテキスト文字の構文クラスを直接指定するraw構文テーブル(構文テーブルの内部を参照)。
nil
このプロパティがnil
なら、その文字の構文はカレント構文テーブルにより通常の方法で決定される。
これが非nil
ならforward-sexp
のような構文をスキャンする関数は、syntax-tableテキストプロパティに注意を払い、それ以外ならカレント構文テーブルだけを使用する。
この変数が非nil
なら特定のテキスト範囲にたいしてsyntax-table
プロパティを適用する関数を格納すること。これはモードに適した方法でsyntax-table
プロパティを適用する関数をインストールするようにメジャーモードで使用されることを意図している。
この関数はsyntax-ppss
(ある位置のパース状態を調べるを参照)、および構文フォント表示化(構文的なFont Lockを参照)の間にFont
Lockモードにより呼び出される。これは作用すべきテキスト部分の開始startと終了endという2つの引数で呼び出される。これはendの前の任意の位置でsyntax-ppss
を呼び出すことが許されている。しかしsyntax-ppss-flush-cache
を呼び出すべきではなく、そのためある位置でsyntax-ppss
を呼び出して後からバッファー内の前の位置を変更することは許されていない。
このアブノーマルフックはsyntax-propertize-function
呼び出しに先立ち構文解析コードにより実行される。これはsyntax-propertize-function
に渡すために安全なバッファーの開始と終了の位置を見つける助けをする役割をもつ。たとえばメジャーモードは複数行の構文構成を識別して、境界が複数行の中間にならないようにこのフックに関数を追加できる。
このフック内の各関数は引数startとendを受け取ること。これは2つのバッファー位置を調整するコンスセル(new-start
.
new-end)
、調整が必要なければnil
をリターンするべきである。フック関数はそれらすべてがnil
をリターンするまで順番に繰り返し実行される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは、特定の構文クラスをもつ文字間を横断して移動する関数を説明します。
この関数はsyntaxesで指定された構文クラス(構文クラスの文字列)をもつ文字を横断してポイントを前方に移動する。バッファー終端か、(与えられた場合は)位置limitに到達、もしくはスキップしない文字に達した際に停止する。
syntaxesが‘^’で始まる場合には、この関数は構文がsyntaxesではない文字をスキップする。
リターン値は移動した距離を表す非負の整数。
この関数はsyntaxesで指定された構文クラスをもつ文字を横断してポイントを後方に移動する。バッファー先頭か、(与えられた場合は)位置limitに到達、もしくはスキップしない文字に達した際に停止する。
syntaxesが‘^’で始まる場合には、この関数は構文がsyntaxesではない文字をスキップする。
リターン値は移動した距離を表す0以下の整数。
この関数は式プレフィクス構文の任意個数の文字を横断して後方にポイントを移動する。これには式プレフィクス構文クラスとフラグ‘p’の文字の両方が含まれる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではバランスのとれた式の解析やスキャンを行う関数を説明します。たとえこれらの関数がLisp以外の言語にたいして作用可能であったとしても、Lisp用語にしたがってそのような式のことをsexpsという用語で参照することにします。基本的にsexpはバランスのとれたカッコによるグループ化、または文字列、シンボル(構文が単語構成要素かシンボル構成要素である文字シーケンス)のいずれかです。しかし式プレフィクス構文(構文クラスのテーブルを参照)の文字は、それらがsexpに隣接する場合にはsexpの一部として扱われます。
構文テーブルは文字の解釈を制御するので、これらの関数はLispモードでのLisp式、CモードでのCの式にたいして使用できます。バランスのとれた式にたいして有用な高レベル関数についてはバランスのとれたカッコを越えた移動を参照してください。
ある文字の構文はパーサー自身の状態の記述ではなくパーサー状態の変更方法を制御します。たとえば文字列区切り文字はin-stringとin-codeの間でパーサー状態をトグルしますが、文字の構文が直接文字列内部にあるかどうかを告げることはありません。たとえば(15は汎用文字列区切りの構文コードであることに注意)、
(put-text-property 1 9 'syntax-table '(15 . nil))
これはEmacsにたいしてカレントバッファーの最初の8文字が文字列であることを告げますが、それらはすべて文字列区切りです。結果としてEmacsはそれらを連続する4つの空文字列定数として扱います。
34.6.1 パースにもとづくモーションコマンド | パースにより機能する移動関数。 | |
34.6.2 ある位置のパース状態を調べる | ある位置の構文状態を判断する。 | |
34.6.3 パーサー状態 | Emacsが構文状態を表す方法。 | |
34.6.4 低レベルのパース | 指定されたリージョンを横断するパース。 | |
34.6.5 パースを制御するためのパラメーター | パースに影響するパラメーター。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは式のパースにもとづいて処理を行うシンプルなポイント移動関数を説明します。
この関数は位置fromからバランスのとれたカッコのグループを前方にcount個スキャンする。これはスキャンが停止した位置をリターンする。countが負ならスキャンは後方に移動する。
depthが非0なら開始位置のカッコのネスト深さをdepthとして扱う。スキャナーはネスト深さが0になるまで繰り返してcount回、前方か後方に移動する。そのため正のdepthは開始位置からカッコをdepthレベル抜け出して移動する効果があり、負のdepthはカッコがdepthレベル深くなるよう移動する効果をもつ。
parse-sexp-ignore-comments
が非nil
ならスキャンはコメントを無視する。
count個のカッコのグループをスキャンする前にスキャンがバッファーのアクセス可能範囲の先頭か終端に達した場合には、そのポイントのネスト深さが0なら値nil
をリターンする。ネスト深さが非0ならscan-error
エラーをシグナルする。
この関数は位置fromからcount個のsexpを前方にスキャンする。これはスキャンが停止した位置をリターンする。countが負ならスキャンは後方へ移動する。
parse-sexp-ignore-comments
が非nil
ならスキャンはコメントを無視する。
カッコのグループの中間でバッファー(のアクセス可能範囲)の先頭か終端に達したらエラーをシグナルする。count個を消費する前にカッコのグループの間でバッファーの先頭か終端に達したらnil
をリターンする。
この関数はcount個の完全なコメント(すなわち、もしあれば開始区切りと終了区切りを含む)、および途中で遭遇する任意の空白文字を横断してポイントを前方に移動する。countが負なら後方に移動する。コメントまたは空白文字以外のものに遭遇したら停止して停止位置にポイントを残す。これには、(たとえば)前方に移動してコメント開始を調べる際にコメント終了を探すことも含まれる。この関数は指定された個数の完全なコメントを横断して移動した後にも即座に停止する。空白以外のものがコメント間に存在せずに期待どおりcount個のコメントが見つかったらt
、それ以外はnil
をリターンする。
この関数はコメントを横断する際に、それが文字列内に埋め込まれているかどうか区別できない。それらがコメントのように見えればコメントとして扱われる。
ポイントの後のすべてのコメントと空白文字を飛び越して移動するには(forward-comment
(buffer-size))
を使用する。バッファー内のコメント数は(buffer-size)
を超えることはできないので、これは引数としての使用に適している。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
インデントのような構文分析にとっては、与えられたバッファー位置に応じた構文状態の計算が有用なことが多々あります。それを手軽に行うのが以下の関数です。
この関数はパーサーがバッファー先頭から開始して位置posで停止するだろうというパーサー状態をリターンする。 パーサー状態の説明はパーサー状態を参照のこと 。
リターン値はバッファー先頭からposまでパースするために低レベル関数parse-partial-sexp
(低レベルのパースを参照)を呼び出した場合と同じようになる。しかしsyntax-ppss
は計算速度向上のためにキャッシュを使用する。この最適化のために、リターンされるパーサー状態のうち2つ目の値(前の完全な部分式)と6つ目の値(最小のカッコ深さ)は意味をもたない。
この関数はsyntax-ppss-flush-cache
(以下参照)にたいして、before-change-functions
(フックの変更を参照)にバッファーローカルなエントリーを追加するという副作用をもつ。このエントリーはバッファー変更にたいしてキャッシュの一貫性を保つ。とはいえbefore-change-functions
が一時的にletでバインドされている間にsyntax-ppss
が呼び出された場合、またはinhibit-modification-hooks
使用時のようにバッファーがフックを実行せずに変更される場合にはキャッシュは更新されないかもしれない。そのような場合には明示的にsyntax-ppss-flush-cache
を呼び出す必要がある。
この関数はsyntax-ppss
が使用するキャッシュを位置begからフラッシュする。残りの引数ignored-argsは無視される。before-change-functions
(フックの変更を参照)のような関数で直接使用できるように、この関数はそれらの引数を受け入れる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
パーサー状態(parser
state)とはバッファー内の指定された開始位置と終了位置の間のテキストをパースした後の構文パーサーの状態を記述する10要素のリストです。syntax-ppss
のようなパース関数
(ある位置のパース状態を調べるを参照)
は値としてパーサー状態をリターンします。いくつかのパース関数はパースを再開するために引数としてパーサー状態を受け取ります。
以下はパーサー状態の要素の意味です:
nil
。
nil
。
nil
。より正確には文字列を終端させるであろう文字、または汎用文字列区切りが終端すべきような場合にはt
。
t
、ネスト可なコメントの内部ならコメントのネストレベル。
t
。
nil
、スタイル‘b’のコメントなら1、スタイル‘c’のコメントなら2、汎用コメント区切り文字で終端されるべきコメントならsyntax-table
。
nil
。
パース継続のために渡す場合には要素1、2、6は無視されて要素8と9は特に重要ではない場面でのみ使用されます。これらの要素は主にパーサーコードにより内部的に使用されます。
以下の関数を使用することにより追加でさらにパーサー状態から有用な情報を利用できます:
この関数はパーサー状態stateから文法構造上トップレベルでのパースでのスキャンした最後の位置をリターンする。“トップレベル”とはすべてのカッコ、コメント、文字列の外部であることを意味する。
stateがトップレベルの位置に到達したパースを表す場合には値はnil
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
式パーサーを使用するもっとも基本的な方法は特定の状態で与えられた位置からパースを開始して、指定した位置でパースを終了するよう指示する方法です。
この関数はカレントバッファー内のsexpを、startから開始してlimitを超えてスキャンしないようパースを行う。これは位置limit、または以下に記述する特定の条件に適合したら停止してパースが停止した位置にポイントをセットする。これはポイントが停止した位置でのパースの状態を記述するパーサー状態 をリターンする。
3つ目の引数target-depthが非nil
の場合には、カッコの深さがtarget-depthと等しくなったらパースを停止する。この深さは0、またはstate内で与えられる深さなら何であれそこから開始される。
4つ目の引数stop-beforeが非nil
の場合には、sexpの開始となる任意の文字に到達したらパースは停止する。stop-commentが非nil
ならコメントの開始でパースは停止する。stop-commentがシンボルsyntax-table
ならコメントか文字列の開始の後、またはコメントか文字列の終了のいずれか先に到達した方でパースは停止する。
stateがnil
なら、startは関数定義先頭のようなカッコ構造のトップレベルであるとみなされる。かわりにこの構造の中間でパースを再開したいと思うかもしれない。これを行うにはパースの初期状態を記述するstate引数を提供しなければならない。前のparse-partial-sexp
呼び出しでリターンされた値で、これをうまく行うことができるだろう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この変数が非nil
なら構文テーブルがそれらについて何と言っているかに関わらず、scan-sexps
はすべての非ASCII文字をシンボル構成要素として扱う(とはいえ依然としてテキストプロパティは構文をオーバーラードできるが)。
この値が非nil
ならこのセクション内の関数、およびforward-sexp
、scan-lists
、scan-sexps
はコメントを空白文字として扱う。
parse-partial-sexp
の振る舞いもparse-sexp-lookup-properties
の影響を受けます(構文プロパティを参照)。
このバッファーローカル変数が非nil
なら、通常ならコメントを終端するような単一の文字は、エスケープ時にはコメントを終端しない。これはCとC++のモードにおいて‘\’でエスケープされた改行により、‘//’で開始される行コメントを次行に継続させるために使用される。
1つ、または複数のコメントを横断して前方や後方に移動するにはforward-comment
を使用できます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
構文テーブルは文字テーブル(文字テーブルを参照)として実装されていますが、ほとんどのLispプログラムが直接それらの要素に作用することはありません。構文テーブルは構文データとして構文記述子を格納しません(構文記述子を参照)。それらは内部的なフォーマットを使用しており、それについてはこのセクションで説明します。この内部的フォーマットは構文プロパティとして割り当てることもできます(構文プロパティを参照)。
構文テーブル内の各要素はraw構文記述子(raw syntax descriptor)という(syntax-code
.
matching-char)
という形式のコンスセルです。syntax-codeは下記のテーブルに応じて構文クラスと構文フラグをエンコードする整数です。matching-charが非nil
なら、それはマッチング文字(構文記述子内の2つ目の文字と同様)を指定します。
以下はさまざまな構文クラスに対応する構文コードです。
Code | Class | Code | Class |
0 | 空白文字 | 8 | 区切り文字ペアー |
1 | 句読点 | 9 | エスケープ |
2 | 単語 | 10 | 文字クォート |
3 | シンボル | 11 | コメント開始 |
4 | 開カッコ | 12 | コメント終了 |
5 | 閉カッコ | 13 | 継承 |
6 | 式プレフィクス | 14 | 汎用コメント |
7 | 文字列クォート | 15 | 汎用文字列 |
たとえば標準構文テーブルでは‘(’にたいするエントリーは(4 . 41)
、41は‘)’の文字コードです。
構文フラグは最下位ビットから16ビット目より始まる高位ビットにエンコードされます。以下のテーブルは対応する各構文フラグにたいして2のべき乗を与えます。
Prefix | Flag | Prefix | Flag |
‘1’ | (lsh 1 16) | ‘p’ | (lsh 1 20) |
‘2’ | (lsh 1 17) | ‘b’ | (lsh 1 21) |
‘3’ | (lsh 1 18) | ‘n’ | (lsh 1 22) |
‘4’ | (lsh 1 19) |
与えられた構文記述子desc(文字列)にたいして、この関数は対応するraw構文記述子をリターンする。
この関数はバッファー内の位置posの後の文字にたいして、構文テーブルと同様に構文プロパティも考慮したraw構文記述子をリターンする。posがバッファーのアクセス可能範囲(accessible portionを参照)の外部ならリターン値はnil
。
この関数はraw構文記述子syntaxにたいする構文コードをリターンする。より正確にはこれはraw構文記述子のsyntax-code要素から構文フラグを記録する高位16ビットをマスクして、その結果の整数をリターンする。
syntaxがnil
ならリターン値はnil
。これは以下の式
(syntax-class (syntax-after pos))
はpos
がバッファーのアクセス可能範囲外部なら、エラーをthrowしたり不正なコードをリターンすることなくnil
に評価されるため。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
カテゴリー(categories)は構文的に文字をクラス分けする別の手段を提供します。必要に応じて複数のカテゴリーを定義して、それぞれの文字に独立して1つ以上のカテゴリーを割り当てることができます。構文クラスと異なりカテゴリーは互いに排他ではありません。1つの文字が複数のカテゴリーに属すのは普通のことです。
バッファーはそれぞれカテゴリーテーブル(category table)をもっています。これはどのカテゴリーが定義されていて、各カテゴリーにどの文字が属すかを記録しています。カテゴリーテールは自身のカテゴリーを定義しますが、標準カテゴリーはすべてのモードで利用可能なので、これらは通常は標準カテゴリーテーブルをコピーすることにより初期化されます。
カテゴリーはそれぞれ‘ ’から‘~’の範囲のASCIIプリント文字による名前をもちます。define-category
で定義する際にはカテゴリーの名前を指定します。
カテゴリーテーブルは実際には文字テーブルです(文字テーブルを参照)。カテゴリーテーブルのインデックスcの要素は、文字cが属するカテゴリーを示すカテゴリーセット(category
set)というブールベクターです。このカテゴリーセット内で、もしインデックスcatの要素がt
ならcatはそのセットのメンバーであり、その文字cはカテゴリーcatに属することを意味します。
以下の3つの関数のオプション引数tableのデフォルトは、カレントバッファーのカテゴリーテーブルです。
この関数はカテゴリーテーブルtableにたいして名前がchar、ドキュメントがdocstringであるような新たなカテゴリーを定義する。
以下ではR2L(right-to-left: 右から左)への強い方向性(directionality)をもつ文字(双方向テキストの表示を参照)にたいするカテゴリーを新たに定義して、それを特別なカテゴリーテーブル内で使用する例を示す。文字の方向性に関する情報を取得するために、コード例ではUnicodeプロパティ‘bidi-class’ (bidi-classを参照)を使用する。
(defvar special-category-table-for-bidi ;; Make an empty category-table. (let ((category-table (make-category-table)) ;; Create a char-table which gives the 'bidi-class' Unicode ;; property for each character. (uniprop-table (unicode-property-table-internal 'bidi-class))) (define-category ?R "Characters of bidi-class R, AL, or RLO" category-table) ;; Modify the category entry of each character whose 'bidi-class' ;; Unicode property is R, AL, or RLO -- these have a ;; right-to-left directionality. (map-char-table #'(lambda (key val) (if (memq val '(R AL RLO)) (modify-category-entry key ?R category-table))) uniprop-table) category-table))
この関数はカテゴリーテーブルtable内のカテゴリーcategoryのドキュメント文字列をリターンする。
(category-docstring ?a) ⇒ "ASCII" (category-docstring ?l) ⇒ "Latin"
この関数はtable内で現在のところ未定義なカテゴリーの名前(文字)をリターンする。table内で利用可能なカテゴリーがすべて使用済みならnil
をリターンする。
この関数はカレントバッファーのカテゴリーテーブルをリターンする。
この関数はobjectがカテゴリーテーブルならt
、それ以外はnil
をリターンする。
この関数は標準カテゴリーテーブルをリターンする。
この関数はtableのコピーを構築してリターンする。tableが与えられない(またはnil
)なら、標準カテゴリーテーブルのコピーをリターンする。それ以外の場合には、もしtableがカテゴリーテーブルでなければエラーをシグナルする。
この関数はtableをカレントバッファーのカテゴリーテーブルにする。リターン値はtable。
これは空のカテゴリーテーブルを作成してリターンする。空のカテゴリーテーブルでは、どのカテゴリーも割り当てられておらず何らかのカテゴリーに属する文字もない。
この関数は初期内容が文字列categoriesにリストされるカテゴリーであるような、新たなカテゴリーセット(ブールベクター)をリターンする。categoriesの要素はカテゴリー名であること。新たなカテゴリーセットはそれらのカテゴリーにたいしてt
、それ以外のすべてのカテゴリーにたいしてnil
をもつ。
(make-category-set "al") ⇒ #&128"\0\0\0\0\0\0\0\0\0\0\0\0\2\20\0\0"
この関数はカレントバッファーのカテゴリーテーブル内で、文字charにたいするカテゴリーセットをリターンする。これは文字charが属するカテゴリーを記録するブールベクター。関数char-category-set
はカテゴリーテーブル内にある同じブールベクターをリターンするのでメモリーの割り当ては行わない。
(char-category-set ?a) ⇒ #&128"\0\0\0\0\0\0\0\0\0\0\0\0\2\20\0\0"
この関数はカテゴリーセットcategory-setを、そのセットのメンバーのカテゴリーを指定する文字を含む文字列に変換する。
(category-set-mnemonics (char-category-set ?a)) ⇒ "al"
この関数はカテゴリーテーブルtable
(デフォルトはカレントバッファーのカテゴリーテーブル)内のcharのカテゴリーセットを変更する。charには文字、または(min
.
max)
という形式のコンスセルを指定できる。後者の場合には、この関数はminとmaxの間(両端を含む)の範囲にあるすべての文字のカテゴリーセットを変更する。
これは通常はカテゴリーセットにcategoryを追加することにより変更を行う。しかしresetが非nil
なら、かわりにcategoryを削除する。
この関数はカレントカテゴリーテーブル内のカテゴリー仕様を説明する。これはその説明をバッファーに挿入してから、そのバッファーを表示する。buffer-or-nameが非nil
なら、かわりにそのバッファーのカテゴリーテーブルを説明する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
略語(abbreviationまたはabbrevは、より長い文字列へと展開される文字列です。ユーザーはabbrev文字列を挿入して、それを探して自動的にabbrevの展開形に置換できます。これによりタイプ量を節約できます。
カレントで効果をもつabbrevsのセットはabbrevテーブル(abbrev table)内に記録されます。バッファーはそれぞれローカルにabbrevテーブルをもちますが、通常は同一のメジャーモードにあるすべてのバッファーが1つのabbrevテーブルを共有します。グローバルabbrevテーブルも存在します。通常は両者が使用されます。
abbrevテーブルはobarrayとして表されます。obarraysについての情報はシンボルの作成とinternを参照してください。abbrevはそれぞれobarray内のシンボルとして表現されます。そのシンボルの名前がabbrevであり、値が展開形になります。シンボルの関数定義は展開を行うフック関数です(abbrevの定義を参照)。またシンボルのプロパティセルには使用回数やそのabbrevが展開された回数を含む、さまざまな追加プロパティが含まれます(abbrevプロパティーを参照)。
システムabbrev(system
abbrevs)と呼ばれる特定のabbrevは、ユーザーではなくメジャーモードにより定義されます。システムabbrevは非nil
の:system
プロパティにより識別されます(abbrevプロパティーを参照)。abbrevがabbrevファイルに保存される際には、システムabbrevは省略されます。ファイルへのabbrevの保存を参照してください。
abbrevに使用されるシンボルは通常のobarrayにinternされないので、Lisp式の読み取り結果として現れることは決してありません。実際のところ通常はabbrevを扱うコードを除いて、それらが使用されることはありません。したがってそれらを非標準的な方法で使用しても安全なのです。
マイナーモードであるAbbrevモードが有効な場合には、バッファーローカル変数abbrev-mode
は非nil
となり、そのバッファー内でabbrevは自動的に展開されます。abbrev用のユーザーレベルのコマンドについてはAbbrev Mode in The GNU Emacs Manualを参照してください。
35.1 abbrevテーブル | abbrevテーブルの作成と操作。 | |
35.2 abbrevの定義 | 略語の指定とそれらの展開。 | |
35.3 ファイルへのabbrevの保存 | ||
35.4 略語の照会と展開 | 展開の制御と展開サブルーチン。 | |
35.5 標準的なabbrevテーブル | 種々メジャーモードに使用されるabbrevテーブル。 | |
35.6 abbrevプロパティー | abbrevプロパティの読み取りとセットを行う方法。どのプロパティが何の効果をもつか。 | |
35.7 abbrevテーブルのプロパティー | abbrevテーブルプロパティの読み取りとセットを行う方法。どのプロパティが効果をもつか。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではabbrevテーブルの作成と操作を行う方法について説明します。
この関数は空のabbrevテーブル(シンボルを含まないobarray)を作成してリターンする。これは0で充填されたベクター。propsは新たなテーブルに適用されるプロパティリスト(abbrevテーブルのプロパティーを参照)。
この関数はobjectがabbrevテーブルなら非nil
をリターンする。
この関数はabbrev-table内のabbrevをすべて未定義として空のまま残す。
この関数はabbrev-tableのコピー(同じabbrev定義を含む新たなabbrevテーブル)をリターンする。これは名前、値、関数だけをコピーしてプロパティリストは何もコピーしない。
この関数はabbrevテーブル名(値がabbrevテーブルであるような変数)としてtabname
(シンボル)を定義する。これはそのテーブル内にdefinitionsに応じて、abbrevを定義する。definitionsは(abbrevname
expansion [hook]
[props...])
という形式の要素をもつリスト。これらの要素は引数としてdefine-abbrev
に渡される。
オプション文字列docstringは変数tabnameのドキュメント文字列。プロパティリストpropsはabbrevテーブルに適用される(abbrevテーブルのプロパティーを参照)。
同一のtabnameにたいしてこの関数が複数回呼び出されれると、元のコンテンツ全体を上書きせずに後続の呼び出しはdefinitions内の定義をtabnameに追加する(後続の呼び出しではdefinitions内で明示的に再定義または未定義にした場合のみabbrevを上書きできる)。
これは値がabbrevテーブルであるようなシンボルのリスト。define-abbrev-table
はこのリストに新たなabbrevテーブル名を追加する。
この関数はポイントの前に名前がnameのabbrevテーブルの説明を挿入する。引数nameは値がabbrevテーブルであるようなシンボル。
humanが非nil
なら人間向けの説明になる。システムabbrevはそのようにリストされて識別される。それ以外なら説明はLisp式(カレントで定義されているようにnameを定義するがシステムabbrevとしては定義しないようなdefine-abbrev-table
呼び出し)となる(nameを使用するモードまたはパッケージはそれらを個別にnameに追加すると想定されている)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
define-abbrev
はabbrevテーブル内にabbrevを定義するための基本的な低レベル関数です。
メジャーモードがシステムabbrevを定義する際には、:system
プロパティにt
を指定してdefine-abbrev
を呼び出すべきです。すべての保存された非システムabbrevは起動時(何らかのメジャーモードがロードされる前)にリストアされることに注意してください。したがってメジャーモードは最初にそのモードがロードされた際には、それらのモードのabbrevテーブルが空であると仮定するべきではありません。
この関数はabbrev-table内にnameという名前でexpansionに展開されて、hookを呼び出すabbrevをプロパティprops
(abbrevプロパティーを参照)とともに定義する。リターン値はname。ここではprops内の:system
プロパティは特別に扱われる。このプロパティが値force
をもつなら、たとえ同じ名前の非システムabbrevでも既存の定義を上書きするだろう。
nameは文字列であること。引数expansionは通常は望む展開形(文字列)であり、nil
ならそのabbrevを未定義とする。これが文字列またはnil
以外の何かなら、そのabbrevはhookを実行することにより単に展開される。
引数hookは関数またはnil
であること。hookが非nil
ならabbrevがexpansionに置換された後に引数なしでそれが呼び出される。hook呼び出しの際にはポイントはexpansionの終端に配置される。
hookがno-self-insert
プロパティが非nil
であるような非nil
のシンボルなら、hookは展開をトリガーするような自己挿入入力文字を挿入できるかどうかを明示的に制御できる。この場合には、hookが非nil
をリターンしたらその文字の挿入を抑止する。対照的にhookがnil
をリターンしたら、あたかも実際には展開が行われなかったかのようにexpand-abbrev
(またはabbrev-insert
)もnil
をリターンする。
define-abbrev
は実際にabbrevを変更した場合には、通常は変数abbrevs-changed
にt
をセットする。これはいくつかのコマンドがabbrevの保存を提案するためである。いずれにせよシステムabbrevは保存されないので、システムabbrevにたいしてこれは行われない。
この変数が非nil
なら、それはユーザーがグローバルabbrevのみの使用を計画していることを意味する。これはモード固有のabbrevを定義するコマンドにたいして、かわりにグローバルabbrevを定義するよう指示する。この変数はこのセクション内の関数の振る舞いを変更しない。それは呼び出し側により検証される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
abbrev定義が保存されたファイルは実際にはLispコードのファイルです。abbrevは同じコンテンツの同じabbrevテーブルを定義するLispプログラムの形式で保存されます。したがってそのファイルはload
によってロードすることができます(プログラムがロードを行う方法を参照)。しかしより簡便なインターフェースとして関数quietly-read-abbrev-file
が提供されています。Emacsは起動時に自動的にこの関数を呼び出します。
save-some-buffers
のようなユーザーレベルの機能は、ここで説明する変数の制御下で自動的にabbrevをファイルに保存できます。
これはabbrevの読み込みと保存にたいするデフォルトのファイル名。デフォルトではEmacsは~/.emacs.d/abbrev_defsを探して、見つからなければ~/.abbrev_defsを探して、いずれにもファイルが存在しなければ~/.emacs.d/abbrev_defsを作成する。
この関数は以前にwrite-abbrev-file
で書き込まれたfilenameという名前のファイルからabbrevの定義を読み込む。filenameが省略またはnil
ならabbrev-file-name
内で指定されているファイルが使用される。
関数の名前が暗示するようにこの関数は何のメッセージも表示しない。
save-abbrevs
にたいする非nil
値はファイル保存時に、(もし何か変更されていれば)Emacsがabbrevの保存を提案するべきであることを意味する。値がsilently
ならEmacsはユーザーに尋ねることなくabbrevを保存する。abbrev-file-name
はabbrevを保存するファイルを指定する。デフォルト値はt
。
この変数はabbrev(システムabbrevを除く)の定義や変更によりセットされる。さまざまなEmacsコマンドにとって、これはユーザーにabbrevの保存を提案するためのフラグとしての役目をもつ。
abbrev-table-name-list
内にリストされたすべてのabbrevテーブルにたいして、ロード時に同じabbrevを定義するであろうLispプログラム形式で、すべてのabbrev定義(システムabbrevを除く)をファイルfilename内に保存する。filenameがnil
ならabbrev-file-name
が使用される。この関数はnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
abbrevは通常はself-insert-command
を含む特定のinteractiveなコマンドにより展開されます。このセクションではそのようなコマンドの記述に使用されるサブルーチン、並びに通信のために使用される変数について説明します。
この関数はabbrevという名前のabbrevを表すシンボルをリターンする。そのabbrevが定義されていなければnil
をリターンする。オプションの2つ目の引数tableはそれを照合するためのabbrevテーブル。tableがnil
ならこの関数はまずカレントバッファーのローカルabbrevテーブル、次にグローバルabbrevテーブルを試みる。
この関数はabbrevが展開されるであろう文字列(カレントバッファーにたいして使用されるabbrevテーブルで定義される文字列)をリターンする。これはabbrevが有効なabbrevでなければnil
をリターンする。オプション引数tableはabbrev-symbol
の場合と同じように使用するabbrevテーブルを指定する。
このコマンドは、(もしあれば)ポイントの前のabbrevを展開する。ポイントがabbrevの後になければこのコマンドは何もしない。展開を行うためにこれは変数abbrev-expand-function
の値となっている関数を引数なしで呼び出して、何であれその関数がリターンしたものをリターンする。
デフォルトの展開関数は展開を行ったらabbrevのシンボル、それ以外はnil
をリターンする。そのabbrevシンボルがno-self-insert
プロパティが非nil
のシンボルであるようなフック関数をもち、そのフック関数が値としてnil
をリターンした場合には、たとえ展開が行われたとしてもデフォルト展開関数はnil
をリターンする。
この関数はstart
とend
の間のテキストを置換することによりabbrev
のabbrev展開形を挿入する。start
が省略された場合のデフォルトはポイント。name
が非nil
なら、それはこのabbrevが見つかった名前(文字列)であること。これは展開形のcapitalizationを調整するかどうかを判断するために使用される。この関数はabbrevの挿入に成功したらabbrev
、それ以外はnil
をリターンする。
このコマンドはポイントのカレント位置をabbrevの開始としてマークする。expand-abbrev
の次回呼び出しでは、通常のように以前の単語ではなく、ここからポイント(その時点での位置)にあるテキストが展開するべきabbrevとして使用される。
このコマンドは、まずargがnil
ならポイントの前の任意のabbrevを展開する(インタラクティブな呼び出しではargはプレフィクス引数)。それから展開する次のabbrevの開始を示すためにポイントの前にハイフンを挿入する。実際の展開ではハイフンは削除される。
これが非nil
にセットされているときは、すべて大文字で入力されたabbrevはすべて大文字を使用して展開される。それ以外ならすべて大文字で入力されたabbrevは、展開形の単語ごとにcapitalizeして展開される。
この変数の値は次にabbrevを展開する開始位置としてexpand-abbrev
に使用されるバッファー位置。値はnil
も可能であり、それはかわりにポイントの前の単語を使用することを意味する。abbrev-start-location
はexpand-abbrev
の呼び出しごとに毎回nil
にセットされる。この変数はabbrev-prefix-mark
からもセットされる。
この変数の値はabbrev-start-location
がセットされたバッファー。他のバッファーでabbrev展開を試みることによりabbrev-start-location
はクリアーされる。この変数はabbrev-prefix-mark
によりセットされる。
これは直近のabbrev展開のabbrev-symbol
。これはunexpand-abbrev
コマンド(Expanding Abbrevs in The GNU Emacs
Manualを参照)のためにexpand-abbrev
により残された情報である。
これは直近の.abbrev展開の場所。これにはunexpand-abbrev
コマンドのためにexpand-abbrev
により残された情報が含まれる。
これは直近のabbrev展開の正確な展開形を、(もしあれば)大文字小文字変換した後のテキストである。そのabbrevがすでに非展開されていれば値はnil
。これにはunexpand-abbrev
コマンドのためにexpand-abbrev
ga残sita情報が含まれる。
この変数の値は展開を行うためにexpand-abbrev
が引数なしで呼び出すであろう関数。この関数では展開を行う前後に行いたいことを行うことができる。展開が行われた場合にはそのabbrevシンボルをリターンすること。
以下のサンプルコードではabbrev-expand-function
のシンプルな使い方を示します。このサンプルではfoo-mode
が‘#’で始まる行がコメントであるような特定のファイルを編集するためのモードであるとします。それらコメント行にたいしてはTextモードのabbrevの使用が望ましく、その他すべての行にたいしては正規のローカルabbrevテーブルfoo-mode-abbrev-table
が適しています。local-abbrev-table
とtext-mode-abbrev-table
の定義については、標準的なabbrevテーブルを参照してください。add-function
についての詳細はEmacs Lisp関数にたいするアドバイスを参照してください。
(defun foo-mode-abbrev-expand-function (expand) (if (not (save-excursion (forward-line 0) (eq (char-after) ?#))) ;; 通常の展開を行う (funcall expand) ;; コメント内はtext-modeのabbrevを使用 (let ((local-abbrev-table text-mode-abbrev-table)) (funcall expand)))) (add-hook 'foo-mode-hook #'(lambda () (add-function :around (local 'abbrev-expand-function) #'foo-mode-abbrev-expand-function)))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はEmacsの事前ロードされるメジャーモード用のabbrevテーブルを保持する変数のリストです。
これはモードに非依存なabbrev用のabbrevテーブル。この中で定義されるabbrevはすべてのバッファーに適用される。各バッファーはローカルabbrevテーブルももつかもしれず、それのabbrev定義はグローバルテーブル内のabbrev定義より優先される。
このバッファーローカル変数の値はカレントバッファーの(モード固有な)abbrevテーブルである。これはそのようなテーブルのリストでもあり得る。
この変数の値は(mode
.
abbrev-table)
という形式のリスト。ここでmodeは変数の名前。その変数が非nil
にバインドされていればabbrev-tableはアクティブ、それ以外なら無視される。abbrev-tableはabbrevテーブルのリストでもあり得る。
これはFundamentalモードで使用されるローカルabbrevテーブル。言い換えるとこれはFundamentalモードにあるすべてのバッファーのローカルabbrevテーブルである。
これはTextモードで使用されるローカルabbrevテーブル。
これはLispモードで使用されるローカルabbrevテーブルであり、Emacs Lispモードで使用されるローカルabbrevテーブルの親テーブル。abbrevテーブルのプロパティーを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
abbrevはプロパティをもち、それらのいくつかはabbrevの働きに影響します。これらのプロパティをdefine-abbrev
の引数として提供して以下の関数で操作できます:
abbrevのプロパティpropに値valをセットする。
abbrevのプロパティprop、そのabbrevがそのようなプロパティをもたなければnil
をリターンする。
以下のプロパティには特別な意味があります:
:count
このプロパティはそのabbrevが展開された回数を計数する。明示的にセットしなければdefine-abbrev
により0に初期化される。
:system
非nil
ならこのプロパティはシステムabbrevとしてそのabbrevをマスクする。そのようなabbrevは保存されない(ファイルへのabbrevの保存を参照)。
:enable-function
非nil
の場合には、そのabbrevが使用されるべきでなければnil
、それ以外ならt
をリターンするような引数なしの関数であること。
:case-fixed
非nil
なら、このプロパティはそのabbrevのcase(大文字小文字)には意味があり、同じパターンにcapitalizeされたテキストだけにマッチすべきことを示す。これは展開のcapitalizationを変更するコードも無効にする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
abbrevと同じようにabbrevテーブルもプロパティをもち、それらのいくつかはabbrevテーブルの働きに影響を与えます。これらのプロパティをdefine-abbrev-table
の引数として提供して、それらを関数で操作できます:
abbrevテーブルtableのプロパティpropに値valをセットする。
abbrevテーブルのプロパティprop、そのabbrevテーブルがそのようなをプロパティもたなければnil
をリターンする。
以下のプロパティには特別な意味があります:
:enable-function
abbrevプロパティ:enable-function
と似ているが、そのテーブル内のすべてのabbrevに適用される点が異なる。これはポイントの前のabbrevを探すことを試みる前にも使用されるのでabbrevテーブルを動的に変更することが可能。
:case-fixed
これはabbrevプロパティ:case-fixed
と似ているが、そのテーブル内のすべてのabbrevに適用される点が異なる。
:regexp
非nil
なら、このプロパティはそのテーブルを照合する前にポイント前のabbrev名を抽出するための方法を示す正規表現。その正規表現がポイントの前にマッチしたときは、そのabbrev名はsubmatchの1と期待される。このプロパティがnil
ならデフォルトはbackward-word
とforward-word
を使用してabbrevの名前を探す。このプロパティにより単語構文以外の文字を含む名前のabbrevが使用できる。
:parents
このプロパティは他のabbrevを継承したテーブルのリストを保持する。
:abbrev-table-modiff
このプロパティはそのテーブルにabbrevが追加される度に増分されるカウンターを保持する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
オペレーティングシステムの用語ではプロセス(process)とはプログラムを実行できるスペースのことです。Emacsはプロセス内で実行されます。Emacs Lispプログラムは別のプログラムをそれら自身のプロセス内で呼び出すことができます。これらは親プロセス(parent process)であるEmacsプロセスのサブプロセス(subprocesses)、または子プロセス(child processes)と呼ばれます。
Emacsのサブプロセスは同期(synchronous)か非同期(asynchronous)であり、それはそれらが作成された方法に依存します。同期サブプロセスを作成した際には、Lispプログラムは実行を継続する前にそのサブプロセスの終了を待機します。非同期サブプロセスを作成したときには、それをLispプログラムと並行して実行できます。この種のサブプロセスはEmacsではLispオブジェクととして表現され、そのオブジェクトも“プロセス”と呼ばれています。Lispプログラムはサブプロセスとのやり取りやサブプロセスの制御のためにこのオブジェクトを使用できます。たとえばシグナル送信、ステータス情報の取得、プロセス出力の受信やプロセスへ入力を送信することができます。
プログラムを実行するプロセスに加えて、Lispプログラムは同一または他のマシン上で実行中のデバイスやプロセスにたいして、いくつかのタイプの接続をオープンできます。サポートされる接続タイプはネットワーク接続のTCPとUDP、シリアルポート接続、およびパイプ接続です。そのような接続はそれぞれプロセスオブジェクトとしても表現されます。
この関数は、objectがEmacsのプロセスオブジェクトを表すならt
、それ以外はnil
をリターンする。プロセスオブジェクトはプログラム実行中のサブプロセスやサポートされた任意のタイプの接続を表すことができる。
カレントEmacsセッションのサブプロセスに加えて、そのマシン上で実行中の他のプロセスにアクセスすることもできます。別のプセスへのアクセスを参照してください。
36.1 サブプロセスを作成する関数 | サブプロセスを開始する関数。 | |
36.2 shell引数 | shellに渡すために引数をクォートする。 | |
36.3 同期プロセスの作成 | 同期サブプロセス使用の詳細。 | |
36.4 非同期プロセスの作成 | 非同期サブプロセスの起動。 | |
36.5 プロセスの削除 | 非同期サブプロセスの削除。 | |
36.6 プロセスの情報 | 実行状態および他の属性へのアクセス。 | |
36.7 プロセスへの入力の送信 | 非同期サブプロセスへの入力の送信。 | |
36.8 プロセスへのシグナルの送信 | 非同期サブプロセスの停止、継続、割り込み。 | |
36.9 プロセスからの出力の受信 | 非同期サブプロセスからの出力の収集。 | |
36.10 センチネル: プロセス状態の変更の検知 | プロセスの実行状態変更時に実行されるセンチネル。 | |
36.11 exit前の問い合わせ | exitによりプロセスがkillされる場合に問い合わせるかどうか。 | |
36.12 別のプセスへのアクセス | そのシステム上で実行中の別プロセスへのアクセス。 | |
36.13 トランザクションキュー | サブプロセスとのトランザクションベースのコミュニケション。 | |
36.14 ネットワーク接続 | ネットワーク接続のopen。 | |
36.15 ネットワークサーバー | Emacsによるネット接続のacceptを可能にするネットワークサーバー。 | |
36.16 データグラム | UDPネットワーク接続。 | |
36.17 低レベルのネットワークアクセス | 接続およびサーバーを作成するための、より低レベルだがより汎用的な関数。 | |
36.18 その他のネットワーク機能 | ネット接続用の追加の関連する関数。 | |
36.19 シリアルポートとの対話 | シリアルポートでのやり取り。 | |
36.20 バイト配列のpackとunpack | bindatを使用したバイナリーデータのpackとunpack。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
内部でプログラムを実行するサブプロセスを作成するために3つのプリミティブが存在します。それらの1つはmake-process
であり、これは非同期プロセスを作成してプロセスオブジェクトをリターンします(非同期プロセスの作成を参照)。他の2つはcall-process
とcall-process-region
です。これらは同期プロセスを作成してプロセスオブジェクとをリターンしません(同期プロセスの作成を参照)。特定のタイプのプロセスを実行するために、これらのプリミティブを利用するさまざまな高レベル関数が存在します。
同期プロセスと非同期プロセスについては、以降のセクションで説明します。この3つの関数はすべて類似した様式で呼び出されるので、ここではそれらに共通の引数について説明します。
すべての場合において、関数は実行するプログラムを指定します。ファイルが見つからなかったり実行できなければエラーがシグナルされます。ファイル名が相対的なら、検索するディレクトリーのリストは変数exec-path
に格納されています。Emacsは起動の際に環境変数PATH
の値にもとづいてexec-path
を初期化します。exec-path
内では標準的なファイル名構成要素‘~’、‘.’、‘..’は通常どおりに解釈されますが、環境変数の置換(‘$HOME’等)は認識されません。それらの置換を行うにはsubstitute-in-file-name
を使用してください(ファイル名を展開する関数を参照)。このリスト内でnil
はdefault-directory
を参照します。
プログラムの実行では指定された名前にサフィックスの追加を試みることもできます:
この変数は指定されたプログラムファイル名への追加を試みるためのサフィックス(文字列)のリスト。指定されたとおりの名前を試みたいならリストに""
を含めること。デフォルト値はシステム依存。
注意してください: 引数programにはプログラムのファイル名だけが含まれて、コマンドライン引数を含めることはできない。これらを提供するために以下で説明する別の引数argsを使用しなければならない。
サブプロセス作成関数にはそれぞれbuffer-or-name引数があります。これはプログラムの出力の行き先を指定します。これはバッファーかバッファー名であるべきです。バッファー名の場合には、もしそのバッファーがまだ作成されていなければバッファーを作成します。nil
を指定することもでき、その場合にはカスタム製のフィルター関数が出力を処理するのでなければ出力を破棄するよう指示します(プロセスのフィルター関数とLispオブジェクトの読み取りとプリントを参照)。通常は出力がランダムに混在してしまうために、同一バッファーに複数プロセスの出力を送信するのは避けるべきです。同期プロセスにたいしてはバッファーのかわりにファイルに出力を送信できます(したがって対応する引数はより適切なdestinationという名前で呼ばれる)。デフォルトでは標準出力と標準エラーの両ストリームの行き先(destination)は同じだが、3つのプリミティブはすべてオプションで標準エラーストリームに別の行き先を指定できる。
これら3つのサブプロセス作成関数は、すべて実行するプロセスにコマンドライン引数を指定できます。call-process
とcall-process-region
では、これらは&rest
形式の引数argsで与えられます。make-process
では実行するプログラムとコマンドライン引数はいずれも文字列のリストとして指定されます。コマンドライン引数はすべて文字列でなければならず、それらは別個の引数文字列としてプログラムに与えられます。文字列は指定されたプログラムに直接渡されるので、ワイルドカード文字やその他のshell構文はこれらの文字列内では特別な意味をもちません。
サブプロセスはその環境をEmacsから継承しますが、process-environment
でそれをオーバーラードするよう指定することができます。オペレーティングシステムの環境を参照してください。サブプロセスは自身のカレントディレクトリーをdefault-directory
の値から取得します。
この変数の値はGNU
Emacsとともに配布されて、Emacsにより呼び出されることを意図したプログラムを含むディレクトリーの名前(文字列)。プログラムmovemail
はそのようなプログラムの例であり、Rmailはinboxから新しいメールを読み込むためにこのプログラムを使用する。
この変数の値はサブプロセス内で実行するためのプログラムを検索するためのディレクトリーのリスト。要素はそれぞれディレクトリーの名前(文字列)、またはnil
のいずれか。nil
はデフォルトディレクトリー(default-directory
の値)を意味する。この検索の詳細はexecutable-findを参照のこと。
exec-path
の値は、program引数が絶対ファイル名でないときにcall-process
とstart-process
により使用される。
一般的にはexec-path
を直接変更するべきではない。かわりにEmacs起動前に環境変数PATH
が適切にセットされているか確認すること。PATH
とは独立にexec-path
の変更を試みると混乱した結果へと導かれ得る。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispプログラムがshellを実行して、ユーザーが指定したファイル名を含むコマンドを与える必要がある場合が時折あります。これらのプログラムは任意の有効なファイル名をサポート可能であるはずです。しかしshellは特定の文字を特別に扱い、それらの文字がファイル名に含まれているとshellを混乱させるでしょう。これらの文字を処理するためには関数shell-quote-argument
を使用します。
この関数は実際のコンテンツがargumentであるような引数を表す文字列をshellの構文でリターンする。リターン値をshellコマンドに結合して実行のためにそれをshellに渡すことにより、信頼性をもって機能するはずである。
この関数が正確に何を行うかはオペレーティングシステムに依存する。この関数はそのシステムの標準shellの構文で機能するようデザインされている。非標準のshellを使用する場合には、この関数を再定義する必要があるだろう。Security Considerationsを参照のこと。
;; この例はGNUおよびUnixシステムでの挙動を示す (shell-quote-argument "foo > bar") ⇒ "foo\\ \\>\\ bar" ;; この例はMS-DOSおよびMS-Windowsでの挙動を示す (shell-quote-argument "foo > bar") ⇒ "\"foo > bar\""
以下はshell-quote-argument
を使用してshellコマンドを構築する例:
(concat "diff -u " (shell-quote-argument oldfile) " " (shell-quote-argument newfile))
以下の2つの関数はコマンドライン引数の文字列のリストを単一の文字列に結合したり、単一の文字列を個別のコマンドライン引数のリストへ分割するために有用です。これらの関数は主にミニバッファーでのユーザー入力であるLisp文字列をmake-process
、call-process
やstart-process
に渡す文字列引数のリストへ変換したり、そのような引数のリストをミニバッファーやエコーエリアに表示するためのLisp文字列に変換することを意図しています。(call-process-shell-command
を使用して)shellが呼び出される場合には、引数を依然としてshell-quote-argument
で保護する必要があることに注意。combine-and-quote-strings
はshellの評価から特殊文字を保護することを意図していない。
この関数はsplit-string
(文字列の作成を参照)が行うように、正規表現separatorsにたいするマッチでstringを部分文字列に分割する。さらに加えてその部分文字列からクォートを削除する。それから部分文字列のリストを作成してリターンする。
separatorsが省略またはnil
の場合のデフォルトは"\\s-+"
であり、これは空白文字構文(構文クラスのテーブルを参照)をもつ1つ以上の文字にマッチする正規表現である。
この関数は2つのタイプのクォートをサポートする。1つは文字列全体をダブルクォートで囲う"…"
のようなクォートで、もう1つはバックスラッシュ‘\’によるエスケープで文字を個別にクォートするタイプである。後者はLisp文字列内でも使用されるので、この関数はそれらも同様に扱うことができる。
この関数はlist-of-stringsの各文字を必要に応じてクォートして単一の文字列に結合する。これはさらに各文字ペアーの間にseparator文字列も挿入する。separatorが省略またはnil
の場合のデフォルトは"
"
。リターン値はその結果の文字列。
list-of-strings内のクォートを要する文字列には、部分文字列としてseparatorを含むものが該当する。文字列のクォートはそれをダブルクォートで"…"
のように囲う。もっとも単純な例では、たとえば個別のコマンドライン引数からコマンドをコンス(cons)する場合には、埋め込まれたブランクを含む文字列はそれぞれクォートされるだろう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
同期プロセス(synchronous process)の作成後、Emacsは継続する前にそのプロセスの終了を待機します。GNUやUnix18でのDiredの起動が例です。プロセスは同期的なので、Emacsがそれにたいして何か行おうと試みる前にディレクトリーのリスト全体がバッファーに到着します。
同期サブプロセス終了をEmacsが待機する間に、ユーザーはC-gをタイプすることでquitが可能です。最初のC-gはSIGINT
シグナルによりサブプロセスのkillを試みます。しかしこれはquitする前に実際にそのサブプロセスが終了されるまで待機します。その間にユーザーがさらにC-gをタイプするとそれはSIGKILL
で即座にサブプロセスをkillしてquitします(別プロセスにたいするkillが機能しないMS-DOSを除く)。quitを参照してください。
同期サブプロセス関数はプロセスがどのように終了したかの識別をリターンします。
同期サブプロセスからの出力はファイルからのテキスト読み込みと同じように、一般的にはコーディングシステムを使用してデコードされます。call-process-region
によりサブプロセスに送信された入力は、ファイルへのテキスト書き込みと同じようにコーディングシステムを使用してエンコードされます。コーディングシステムを参照してください。
この関数はprogramを呼び出して完了するまで待機する。
サブプロセスのカレントワーキングディレクトリーはdefault-directory
。
新たなプロセスの標準入力はinfileが非nil
ならファイルinfile、それ以外ならnullデバイス。引数destinationはプロセスの出力をどこに送るかを指定する。以下は可能な値:
そのバッファーのポイントの前に出力を挿入する。これにはプロセスの標準出力ストリームと標準エラーストリームの両方が含まれる。
その名前のバッファーのポイントの前に出力を挿入する。
t
カレントバッファーのポイントの前に出力を挿入する。
nil
出力を破棄する。
出力を破棄してサブプロセス完了を待機せずに即座にnil
をリターンする。
この場合にはプロセスはEmacsと並列に実行可能なので真に同期的ではない。しかしこの関数リターン後は本質的にはすみやかにEmacsがサブプロセスを終了するという点から、これを同期的と考えることができる。
MS-DOSは非同期サブプロセスをサポートせずこのオプションは機能しない。
(:file file-name)
指定されたファイルに出力を送信して、ファイルが既に存在すれば上書きする。
(real-destination error-destination)
標準出力ストリームを標準エラーストリームと分けて保持する。通常の出力はreal-destinationの指定にしたがって扱い、エラー出力はerror-destinationにしたがって処分する。error-destinationがnil
ならエラー出力の破棄、t
なら通常の出力と混合することを意味して、文字列ならそれはエラー出力をリダイレクトするファイルの名前である。
エラー出力先に直接バッファーを指定することはできない。ただしエラー出力を一時ファイルに送信して、サブプロセス終了時にそのファイルをバッファーに挿入すればこれを達成できる。
displayが非nil
なら、call-process
は出力の挿入にしたがってバッファーを再表示する(しかし出力のデコードに選択されたコーディングシステムが実データからエンコーディングを推論することを意味するundecided
なら、非ASCIIに一度遭遇すると再表示が継続不能になることがある。これを修正するのが困難な根本的理由が存在する。プロセスからの出力の受信を参照)。
それ以外なら関数call-process
は再表示を行わずに、通常のイベントに由来するEmacsの再表示時だけスクリーン上で結果が可視になります。
残りの引数argsはそのプログラムにたいしてコマンドライン引数を指定する文字列です。文字列はそれぞれ別個の引数としてprogramに渡されます。
(待機するよう告げた場合には)
call-process
がリターンする値はプロセスが終了した理由を示します。この数字はそのサブプロセスのexitステータスであり0が成功、それ以外のすべての値は失敗を意味します。シグナルによりそのプロセスが終了された場合には、call-process
はそれを記述する文字列をリターンします。call-process
に待機しないように指示した場合にはnil
をリターンします。
以下の例ではカレントバッファーは‘foo’です。
(call-process "pwd" nil t) ⇒ 0 ---------- Buffer: foo ---------- /home/lewis/manual ---------- Buffer: foo ----------
(call-process "grep" nil "bar" nil "lewis" "/etc/passwd") ⇒ 0 ---------- Buffer: bar ---------- lewis:x:1001:1001:Bil Lewis,,,,:/home/lewis:/bin/bash ---------- Buffer: bar ----------
以下はcall-process
の使用例であり、このような使用例はinsert-directory
関数の定義内で見つけることができます:
(call-process insert-directory-program nil t nil switches (if full-directory-p (concat (file-name-as-directory file) ".") file))
この関数は別プロセス内でファイルを同期的に処理する。これはcall-process
と似ているが、サブプロセスのカレントワーキングディレクトリーを指定する変数default-directory
の値にもとづいて、ファイルハンドラーを呼び出すかもしれない。
引数はcall-process
の場合とほとんど同様の方法で処理されるが以下の違いがある:
引数infile、buffer、displayのすべての組み合わせと形式をサポートしないファイルハンドラーがあるかもしれない。たとえば実際に渡された値とは無関係に、displayがnil
であるかのように振る舞うファイルハンドラーがいくつかある。他の例としてはbuffer引数で標準出力とエラー出力を分離するのをサポートしないかもしれないファイルハンドラーがいくつか存在する。
ファイルハンドラーが呼び出されると、1つ目の引数programにもとづいて実行するプログラムを決定する。たとえばリモートファイルにたいするハンドラーが呼び出されたと考えてみよ。その場合にはプログラムの検索に使用されるパスはexec-path
とは異なるかもしれない。
2つ目の引数infileはファイルハンドラーを呼び出すかもしれない。そのファイルハンドラーは、process-file
関数自身にたいして選択されたハンドラーと異なるかもしれない(たとえばdefault-directory
がリモートホスト上にありinfileは別のリモートホスト上の場合があり得る。もしくはdefault-directory
は普通だがinfileはリモートホスト上にあるかもしれない).
bufferが(real-destination
error-destination)
という形式のリストであり、かつerror-destinationがファイルの名前ならinfileと同じ注意が適用される。
残りの引数(args)はそのままプロセスに渡される。Emacsはargs内で与えられたファイル名の処理に関与しない。混乱を避けるためにはargs内で絶対ファイル名を使用しないのが最善であり、default-directory
からの相対ファイル名ですべてのファイルを指定するほうがよいだろう。関数file-relative-name
はそのような相対ファイル名の構築に有用。
この変数はprocess-file
呼び出しがリモートファイルを変更するかどうかを示す。
この変数はデフォルトではprocess-file
呼び出しがリモートホスト上の任意のファイルを潜在的に変更し得ることを意味するt
に常にセットされる。nil
にセットされた際には、リモートファイル属性のキャッシュにしたがうことによりファイルハンドラーの挙動を最適化できる可能性がある。
この変数は決してsetq
ではなく、常にletバインディングでのみ変更すること。
この関数はstartからendのテキストを、実行中のプロセスprogramに標準入力として送信する。これはdeleteが非nil
なら送信したテキストを削除する。これは出力をカレントバッファーの入力箇所に挿入するために、destinationをt
に指定している際に有用。
引数destinationとdisplayはサブロセスからの出力にたいして何を行うか、および出力の到着にともない表示を更新するかどうかを制御する。詳細は上述のcall-process
の説明を参照のこと。destinationが整数の0ならcall-process-region
は出力を破棄して、サブプロセス完了を待機せずに即座にnil
をリターンする(これは非同期サブプロセスがサポートされる場合、つまりMS-DOS以外でのみ機能する)。
残りの引数argsはそのプログラムにたいしてコマンドライン引数を指定する文字列です。
call-process-region
のリターン値はcall-process
の場合と同様。待機せずにリターンするよう指示した場合にはnil
、数字か文字列ならそれはサブプロセスが終了した方法を表す。
以下の例ではバッファー‘foo’内の最初の5文字(単語‘input’)を標準入力として、call-process-region
を使用してcat
ユーティリティを実行する。cat
は自身の標準入力を標準出力へコピーする。引数destinationがt
なので出力はカレントバッファーに挿入される。
---------- Buffer: foo ---------- input∗ ---------- Buffer: foo ----------
(call-process-region 1 6 "cat" nil t) ⇒ 0 ---------- Buffer: foo ---------- inputinput∗ ---------- Buffer: foo ----------
たとえばshell-command-on-region
コマンドは以下のような方法でcall-process-region
を使用する:
(call-process-region
start end
shell-file-name ; プログラム名
nil ; リージョンを削除しない
buffer ; 出力をbuffer
に送信
nil ; 出力中に再表示を行わない
"-c" command) ; shellへの引数
この関数はshellコマンドcommandを非同期に実行する。他の引数はcall-process
の場合と同様に処理される。古い呼び出し規約はdisplayの後に任意個数の追加引数を許容して、これはcommandに結合される。これはまだサポートされるものの使用しないことを強く推奨する。
この関数はcall-process-shell-command
と同様だが内部的にprocess-file
を使用する点が異なる。default-directory
に依存してcommandはリモートホスト上でも実行可能。古い呼び出し規約はdisplayの後に任意個数の追加引数を許容して、これはcommandに結合される。これはまだサポートされるものの使用しないことを強く推奨する。
この関数はshellコマンドとしてcommand (文字列)を実行してコマンドの出力を文字列としてリターンする。
この関数はprogramを実行して完了を待機して、出力を文字列のリストとしてリターンする。リスト内の各文字列はプログラムのテキスト出力の1つの行を保持する。各行のEOL文字(行末文字)は取り除かれる。programの後の引数argsはそのプログラム実行に際して、コマンドライン引数を指定する文字列。
programが非0のexitステータスでexitすると、この関数はエラーをシグナルする。
この関数はcall-process
を呼び出すことにより機能して、プログラムの出力はcall-process
の場合と同じ方法でデコードされる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは非同期プロセス(asynchronous process)を作成する方法について説明します。非同期プロセスは作成後はEmacsと並列に実行されて、Emacsは以降のセクション(プロセスへの入力の送信とプロセスからの出力の受信を参照)で説明する関数を使用してプロセスとコミュニケーションができます。プロセスコミュニケーションは部分的に非同期なだけであることに注意してください。Emacsは特定の関数を呼び出したときだけプロセスにデータを送信でき、Emacsは入力の待機中か一定の遅延時間の後にのみプロセスのデータを受け取ることができます。
非同期プロセスはpty(pseudo-terminal:
疑似端末)かたはpipeのいずれかを通じて制御されます。ptyかpipeの選択は、デフォルトでは変数process-connection-type
(以下参照)の値にもとづいてプロセス作成時に行われます。ptyが利用可能なら、通常はShellモード内のようにユーザーから可視なプロセスに適しています。ptyではプロセスとその子プロセスとの間でジョブ制御(C-c、C-z、...等)が可能であり、対話的なプログラムはptyを端末デバイスとして扱いますが、これらはpipeではサポートされない機能だからです。Lispプログラムの内部的な目的のために使用されるサブプロセスにたいしては、pipeのほうが適している場合が多々あります。それはpipeがより効率的であり、ptyが大量の文字(500byte前後)にたいして導入する迷入文字インジェクション(stray
character
injections)にたいして免疫があるのが理由です。さらに多くのシステムではptyの合計数に制限があり、それを浪費するのは得策ではありません。
この関数は非同期サブプロセスを開始するための基本的な低レベルなプリミティブである。これはサブプロセスを表すプロセスオブジェクトをリターンする。以下で説明するより高レベルなstart-process
と比較すると、この関数はキーワード引数を受け取り、より柔軟であり、単独の呼び出しでプロセスフィルターやセンチネルを指定できる。
引数argsはkeyword/argumentペアのリスト。キーワードの省略は値nil
でそれを指定することと常に等価。以下は意味のあるキーワード:
プロセス名として文字列nameを使用する。その名前のプロセスがすでに存在すれば、(‘<1>’、...の追加により)一意となるようにnameを修正する。
プロセスバッファーとしてbufferを使用する。値がnil
なら、そのサブプロセスには何のバッファーも関連付けられない。
プロセスのコマドラインとしてcommandを使用する。値はプログラムの実行可能ファイル名で始まり、後にプログラムの引数として与える文字列が続くリストであること。リストの最初の要素がnil
なら、Emacsは新たな擬似端末(pty)を作成して、実際には何もプログラムを実行せずに入出力をbufferに関連付ける。この場合には残りのリスト要素は無視される。
codingがシンボルなら、それはその接続にたいする読み取りと書き込みの両方で使用するコーディングシステムを指定する。codingがコンスセル(decoding . encoding)
なら読み取りにdecoding、書き込みにencodingが使用される。プログラムに書き込むデータのエンコーディングに使用されるコーディングシステムは、コマンドライン引数のエンコーディングにも使用される(しかしプログラム自身にたいしてファイル名を別のファイル名にエンコードすることはない。file-name-coding-systemを参照)。
codingがnil
なら、デフォルトのコーディングシステム検出ルールを適用する。デフォルトのコーディングシステムを参照のこと。
サブプロセスとの対話に使用するデバイスのタイプを初期化する。指定できる値はptyを使用するpty
、pipeを使用するpipe
、またはprocess-connection-type
変数の値のデフォルトデバイスを使用するnil
。:stderr
パラメーターに非nil
値が指定されると、このパラメーターとprocess-connection-type
の値は無視される。この場合にはタイプは常にpipe
になる。
プロセスqueryフラグをquery-flagに初期化する。exit前の問い合わせを参照のこと。
stoppedが非nil
なら、停止状態でプロセスを開始する。
プロセスフィルターをfilterに初期化する。未指定ならデフォルトフィルターが提供されるが、これは後からオーバーライドできる。プロセスのフィルター関数を参照のこと。
プロセスセンチネルをsentinelに初期化する。未指定ならデフォルトセンチネルが使用されるが、これは後からオーバーライドできる。センチネル: プロセス状態の変更の検知を参照のこと。
プロセスの標準エラーにstderrを割り当てる。値が非nil
ならバッファー、または以下で説明するmake-pipe-process
で作成されたpipeのいずれかであること。
実際の接続情報で修正されたオリジナルの引数リストはprocess-contact
を通じて利用できる。
この関数は子プロセスにアタッチ可能な双方向のpipeを作成する。これはmake-process
の:stderr
キーワードと併用することで有用。この関数はプロセスオブジェクトをリターンする。
引数argsはkeyword/argumentペアのリスト。キーワードの省略はそのキーワードに値nil
を指定することと常に等価。
以下は意味のあるキーワード。
プロセス名として文字列nameを使用する。make-process
の場合のように、一意にするために必要に応じて変更され得る。
プロセスバッファーとしてbufferを使用する。
codingがシンボルなら、それはその接続にたいする読み取りと書き込みの両方で使用するコーディングシステムを指定する。codingがコンスセル(decoding . encoding)
なら読み取りにdecoding、書き込みにencodingが使用される。
codingがnil
なら、デフォルトのコーディングシステム検出ルールを適用する。デフォルトのコーディングシステムを参照のこと。
プロセスqueryフラグをquery-flagに初期化する。exit前の問い合わせを参照のこと。
stoppedが非nil
なら、停止状態でプロセスを開始する。
プロセスフィルターをfilterに初期化する。未指定ならデフォルトフィルターが提供されるが後で変更できる。プロセスのフィルター関数を参照のこと。
プロセスセンチネルをsentinelに初期化する。未指定ならデフォルトセンチネルが使用されるが後で変更できる。センチネル: プロセス状態の変更の検知を参照のこと。
実際の接続情報で修正されたオリジナルの引数リストはprocess-contact
を通じて利用できる。
この関数はcall-process
の類似したインターフェースを提供する、make-process
周辺の高レベルのラッパー。これは新たに非同期サブプロセスを作成して、指定されたprogramの実行をその内部で開始する。これはLispで新たなサブプロセスを意味するプロセスオブジェクトをリターンする。引数nameはプロセスオブジェクトの名前を指定する。make-process
の場合のように、一意な名前となるように必要に応じて修正する。バッファーbuffer-or-nameはそのプロセスに関連付けるバッファー。
programがnil
ならEmacsは疑似端末(pty)を新たにオープンして、サブプロセスを新たに作成することなくptyの入力と出力をbuffer-or-nameに関連付ける。この場合には残りの引数argsは無視される。
残りのargsはサブプロセスにコマンドライン引数を指定する文字列。
以下の例では1つ目のプロセスを開始して100秒間実行(というよりはsleep)される。その間に2つ目のプロセスを開始して、一意性を保つために‘my-process<1>’という名前が与えられる。これは1つ目のプロセスが終了する前にバッファー‘foo’の最後にディレクトリーのリストを挿入する。その後に2つ目のプロセスは終了して、その旨のメッセージがバッファーに挿入される。さらに遅れて1つ目のプロセスが終了して、バッファーに別のメッセージが挿入される。
(start-process "my-process" "foo" "sleep" "100") ⇒ #<process my-process>
(start-process "my-process" "foo" "ls" "-l" "/bin") ⇒ #<process my-process<1>> ---------- Buffer: foo ---------- total 8336 -rwxr-xr-x 1 root root 971384 Mar 30 10:14 bash -rwxr-xr-x 1 root root 146920 Jul 5 2011 bsd-csh … -rwxr-xr-x 1 root root 696880 Feb 28 15:55 zsh4 Process my-process<1> finished Process my-process finished ---------- Buffer: foo ----------
start-process
と同じようにこの関数は非同期サブプロセスを開始して、その内部でprogramを実行してそのプロセスオブジェクトをリターンする。
start-process
との違いは、この関数がdefault-directory
の値にもとづいてファイルハンドラーを呼び出すかもしれないという点である。このハンドラーはローカルホスト上、あるいはdefault-directory
に応じたリモートホスト上でprogramを実行すること。後者の場合には、default-directory
のローカル部分はそのプロセスのワーキングディレクトリーになる。
この関数はprogram、またはargsの残りにたいしてファイル名ハンドラーの呼び出しを試みない。
そのファイルハンドラーの実装によっては、リターン結果のプロセスオブジェクトにprocess-filter
やprocess-sentinel
を適用することができないかもしれない。プロセスのフィルター関数とセンチネル: プロセス状態の変更の検知を参照のこと。
いくつかのファイルハンドラーはstart-file-process
をサポートしないかもしれない(たとえばange-ftp-hook-function
関数)。そのような場合には、この関数は何も行わずにnil
をリターンする。
この関数はstart-process
と同様だが、指定されたcommandの実行にshellを使用する点が異なる。引数commandはshellコマンド文字列。変数shell-file-name
はどのshellを使用するかを指定する。
make-process
やstart-process
でプログラムを実行せずにshellを通じて実行することの要点は、引数内のワイルドカード展開のようなshell機能を利用可能にするためである。そのためにはコマンド内に任意のユーザー指定引数を含めるなら、任意の特別なshell文字がshellでの特別な意味をもたないように、まずshell-quote-argument
でそれらをクォートするべきである。shell引数を参照のこと。ユーザー入力にもとづいたコマンド実行時には当然セキュリティ上の影響も考慮するべきである。
この関数はstart-process-shell-command
と似ているが、内部的にstart-file-process
を使用する点が異なる。これによりdefault-directory
に応じてリモートホスト上でもcommandを実行できる。
この変数は非同期サブプロセスと対話するために使用するデバイスタイプを制御する。これが非nil
の場合には利用可能ならpty、それ以外ならpipeが使用される。
process-connection-type
の値はmake-process
やstart-process
の呼び出し時に効果を発揮する。そのためにこれらの関数の呼び出し前後でこの変数をバインドすることにより、サブプロセスとやり取りする方法を指定できる。
この変数の値はmake-process
が非nil
値の:stderr
パラメーターで呼び出された際には無視される。この場合には、Emacsはpipeを使用してプロセスと対話する。
(let ((process-connection-type nil)) ; pipeを使用
(start-process …))
与えられたサブプロセスが実際にはpipeとptyのどちらを取得したかを判断するには関数process-tty-name
を使用する(プロセスの情報を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プロセス削除(deleting a process)とはEmacsをサブプロセスから即座に切断することです。プロセスは終了後に自動的に削除されますが即座に削除される必要はありません。任意のタイミングで明示的にプロセスを削除できます。終了したプロセスが自動的に削除される前に明示的に削除しても害はありません。実行中のプロセスの削除はプロセス(もしあれば子プロセスにも)を終了するためにシグナルを送信してプロセスセンチネルを呼び出します。センチネル: プロセス状態の変更の検知を参照してください。
プロセスが削除される際、そのプロセスオブジェクト自体はそれを参照する別のLispオブジェクトが存在する限り継続し続けます。プロセスオブジェクトに作用するすべてのLispプリミティブはプロセスの削除を受け入れますが、I/Oを行ったりシグナルを送信するプリミティブはエラーを報告するでしょう。プロセスマークは通常はプロセスからの出力がバッファーに挿入される箇所となる、以前と同じ箇所をポイントし続けます。
この変数は、(exit
呼び出しやシグナルにより)終了したプロセスの自動的な削除を制御する。これがnil
ならユーザーがlist-processes
を実行するまでプロセスは存在し続けて、それ以外ならexit後に即座に削除される。
この関数はプロセスがプログラムを実行していたらSIGKILL
シグナルでkillすることによりプロセスを削除する。引数はプロセス、プロセスの名前、バッファー、バッファーの名前かもしれない(バッファーやバッファー名ならget-buffer-process
がリターンするプロセスを意味する)。実行中のプロセスにdelete-process
を呼び出すことによりプロセスを終了してプロセス状態を更新して即座にセンチネルを実行する。そのプロセスがすでに終了していれば、delete-process
呼び出しはプロセス状態、または(遅かれ早かれ発生するであろう)プロセスセンチネルの実行に影響を与えない。
プロセスオブジェクトがネットワーク接続、シリアル接続、pipe接続を表す場合には状態はclosed
、それ以外ならそのプロセスがexit済みでなければsignal
に変更される。process-statusを参照のこと。
(delete-process "*shell*") ⇒ nil
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プロセスの状態に関する情報をリターンする関数がいくつかあり。
このコマンドは、すべての生きたプロセスのリストを表示する。加えてこれは最後に、状態が‘Exited’か‘Signaled’だったすべてのプロセスを削除する。このコマンドはnil
をリターンする。
プロセスはメジャーモードがProcess Menuモードであるような、*Process List*という名前のバッファーに表示される(オプション引数bufferで他の名前を指定していない場合)。
query-onlyが非nil
なら、queryフラグが非nil
のプロセスだけをリストする。exit前の問い合わせを参照のこと。
この関数は削除されていないすべてのプロセスのリストをリターンする。
(process-list) ⇒ (#<process display-time> #<process shell>)
この関数はname
(文字列)というプロセス、存在しなければnil
をリターンする。引数nameはプロセスオブジェクトでもよく、この場合にはそれがリターンされる。
(get-process "shell") ⇒ #<process shell>
この関数はprocessを開始するために実行されたコマンドをリターンする。これは文字列のリストで1つ目の文字列は実行されたプログラム、残りの文字列はそのプログラムに与えられた引数。ネットワーク接続、シリアル接続、pipe接続にたいしてはnil
(プロセスは実行中)かt
(プロセスは停止中)のいずれか。
(process-command (get-process "shell")) ⇒ ("bash" "-i")
この関数はネットワーク接続、シリアル接続、pipe接続がセットアップされた方法に関する情報をリターンする。keyがnil
ならネットワーク接続には(hostname
service)
、シリアル接続には(port
speed)
、pipe接続にはt
をリターンする。普通の子プロセスにたいしては、この関数はkeyがnil
で呼び出されると常にt
をリターンする。
keyがt
なら値はその接続、サーバー、シリアルポート、またはpipeについての完全な状態情報、すなわちmake-network-process
、make-serial-process
、またはmake-pipe-process
内で指定されるキーワードと値のリストとなる。ただしいくつかの値については、指定した値のかわりにカレント状態を表す値となる。
ネットワークプロセスにたいしては以下の値が含まれる(完全なリストはmake-network-process
を参照):
:buffer
値にはプロセスのバッファーが割り当てられる。
:filter
値にはプロセスのフィルター関数が割り当てられる。プロセスのフィルター関数を参照のこと。
:sentinel
値にはプロセスのセンチネル関数が割り当てられる。センチネル: プロセス状態の変更の検知を参照のこと。
:remote
接続にたいしては内部的なフォーマットによるリモートピアーのアドレス。
:local
内部的なフォーマットによるローカルアドレス。
:service
この値はサーバーではserviceにt
を指定すると実際のポート番号。
make-network-process
内で明示的に指定されていなくても:local
と:remote
は値に含まれる。
シリアル接続についてはmake-serial-process
、キーのリストはserial-process-configure
を参照のこと。pipe接続についてはmake-pipe-process
を参照のこと。
keyがキーワードなら、この関数はそのキーワードに対応する値をリターンする。
この関数はprocessのPIDをリターンする。これは同じコンピューター上でカレント時に実行中の他のすべてのプロセスからプロセスprocessを区別するための整数。プロセスのPIDはプロセスの開始時にオペレーティングシステムのカーネルにより選択されて、そのプロセスが存在する限り定数として保たれる。この関数はネットワーク接続、シリアル接続、pipe接続にはnil
をリターンする。
この関数はprocessの名前を文字列としてリターンする。
この関数はprocess-nameの状態を文字列でリターンする。引数process-nameはプロセス、バッファー、またはプロセス名(文字列)でなければならない。
実際のサブプセスにたいして可能な値は:
run
実行中のプロセス。
stop
停止しているが継続可能なプロセス。
exit
exitしたプロセス。
signal
致命的なシグナルを受信したプロセス。
open
オープンされたネットワーク接続、シリアル接続、またはpipe接続。
closed
クローズされたネットワーク接続、シリアル接続、またはpipe接続。一度クローズされた接続は、たとえ同じ場所にたいして新たな接続をオープンすることができたとしても再度オープンすることはできない。
connect
完了を待つ非ブロッキング接続。
failed
完了に失敗した非ブロッキング接続。
listen
listen中のネットワークサーバー。
nil
process-nameが既存のプロセス名でない場合。
(process-status (get-buffer "*shell*")) ⇒ run
ネットワーク接続、シリアル接続、pipe接続にたいしてprocess-status
はopen
、stop
、またはclosed
いずれかのシンボルをリターンする。closed
は相手側が接続をクローズしたか、あるいはEmacsがdelete-process
を行なったことを意味する。値stop
はその接続でstop-process
が呼び出されたことを意味する。
この関数はprocessがアクティブなら、非nil
をリターンする。状態がrun
、open
、listen
、connect
、stop
のプロセスはアクティブとみなされる。
この関数はネットワーク接続やサーバーにたいしてはnetwork
、シリアルポート接続にたいしてはserial
、pipe接続にたいしてはpipe
、プログラム実行用に作成されたサブプロセスにたいしてはreal
というシンボルをリターンする。
この関数はprocessのexitステータス、またはプロセスをkillしたシグナル番号をリターンする(いずれであるかの判定にはprocess-status
の結果を使用)。processがまだ終了していなければ値は0。すでにcloseされたネットワーク接続、シリアル接続、pipe接続についての値は接続のcloseが正常か異常かによって0か256のいずれかとなる。
この関数はprocessがEmacsとの対話に使用する端末名、ptyではなくpipeを使用する場合にはnil
をリターンする(非同期プロセスの作成のprocess-connection-type
を参照)。processがリモートホスト上で実行中のプログラムを表す場合には、プロセスのremote-tty
プロパティとしてリモートホスト上でそのプログラムに使用される端末名が提供される。processがネットワーク接続、シリアル接続、pipe接続を表す場合には値はnil
。
この関数はprocessからの出力のデコードに使用するコーディングシステムと、processへの入力のエンコードに使用するコーディングシステムを記述するコンスセル(decode
. encode)
をリターンする(コーディングシステムを参照)。
この関数はprocessにたいする後続の入出力に使用するコーディングシステムを指定する。これはサブプロセスの出力のデコードにdecoding-system、入力のエンコードにencoding-systemを使用する。
すべてのプロセスには、そのプロセスに関連するさまざまな値を格納するために使用できるプロパティリストもあります。
この関数はprocessのプロパティpropnameの値をリターンする。
この関数はprocessのプロパティpropnameの値にvalueをセットする。
この関数はprocessのプロセスplistをリターンする。
この関数はprocessのプロセスplistにplistをセットする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
非同期サブプロセスはEmacsにより入力が送信されたときに入力を受信して、それはこのセクション内の関数で行われます。これを行うには入力を送信するプロセスと送信するための入力データを指定しなければなりません。サブプロセスがプログラムを実行していたら、データはプログラムの標準入力として出現します。接続にたいしては、データは接続されたデバイスかプログラムに送信されます。
オペレーティングシステムにはptyのバッファーされた入力にたいして制限をもつものがいくつかあります。それらのシステムでは、Emacsは他の文字列の間に定期的かつ強制的にEOFを送信します。ほとんどのプログラムにたいして、これらのEOFは無害です。
サブプロセスの入力はテキストをファイルに書き込むときと同じように、通常はサブプロセスが受信する前、コーディングシステムを使用してエンコードされます。どのコーディングシステムを使用するかを指定するにはset-process-coding-system
を使用できます(プロセスの情報を参照)。それ以外の場合には、非nil
ならcoding-system-for-write
がコーディングシステムとなり、さもなくばデフォルトのメカニズムがコーディングシステムを決定します(デフォルトのコーディングシステムを参照)。
入力バッファーが一杯でシステムがプロセスからの入力を受け取ることができないことがあります。これが発生したときには送信関数はしばらく待機してからサブプロセスの出力を受け取って再度送信を試みます。これは保留となっている更なる入力を読み取ってバッファーに空きを作る機会をサブプロセスに与えます。これはフィルター、センチネル、タイマーの実行も可能にするのでコードを記述する際はそれを考慮してください。
以下の関数ではprocess引数はプロセス、プロセス名、またはバッファー、バッファー名(get-buffer-process
で取得されるプロセス)、nil
はカレントバッファーのプロセスを意味します。
この関数はstringのコンテンツを標準入力としてprocessに送信する。たとえばファイルをリストするShellバッファーを作成するには:
(process-send-string "shell<1>" "ls\n") ⇒ nil
この関数はstartとendで定義されるリージョンのテキストを標準入力としてprocessに送信する。
startとendが、カレントバッファー内の位置を示す整数かマーカーでなければエラーがシグナルされる(いずれかの大小は重要ではない)。
この関数はprocessが入力内のEOF (end-of-file)を見ることを可能にする。EOFはすべての送信済みテキストの後になる。この関数はprocessをリターンする。
(process-send-eof "shell") ⇒ "shell"
この関数はprocessが接続ではない実際のサブプロセスであり、端末の制御を自身の子プロセスに与えたかどうかを示す。これが真なら関数はprocessのフォアグラウンドプロセスグループの数値ID、これが真ではないとEmacsが判断すればnil
をリターンする。これが真かどうかをEmacsが判断できなければ値はt
。processがネットワーク接続、シリアル接続、pipe接続、またはサブプロセスが非アクティブなら関数はエラーをシグナルする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
サブプロセスへのシグナル送信(sending a
signal)はプロセス活動に割り込む手段の1つです。異なる複数のシグナルがあり、それぞれが独自に意味をもちます。シグナルのセットとそれらの意味はオペレーティングシステムにより定義されます。たとえばシグナルSIGINT
はユーザーがC-cをタイプしたか、それに類似する何かが発生したことを意味します。
各シグナルはサブプロセスに標準的な効果をもちます。ほとんどのシグナルはサブプロセスをkillしますが、かわりに実行を停止(や再開)するものもいくつかあります。ほとんどのシグナルはオプションでプログラムでハンドル(処理)することができます。プログラムがそのシグナルをハンドルする場合には、その影響についてわたしたちは一般的には何も言うことはできません。
このセクション内の関数を呼び出すことにより明示的にシグナルを送信できます。Emacsも特定のタイミングで自動的にシグナルを送信します。バッファーのkillにより、それに関連するプロセスにはSIGHUP
シグナル、Emacsのkillにより残されたすべてのプロセスにSIGHUP
シグナルが送信されます(SIGHUP
は通常はユーザーが“hung
up the phone”、電話を切った、つまり接続を断ったことを示す)。
シグナル送信関数はそれぞれprocessとcurrent-groupいう2つのオプション引数を受け取ります。
引数processはプロセス、プロセス名、バッファー、バッファー名、またはnil
のいずれかでなければなりません。バッファーやバッファー名はget-buffer-process
を通じて得られるプロセスを意味します。nil
はカレントバッファーに関連付けられたプロセスを意味します。stop-process
and
continue-process
を除いて、processがプロセスを識別しない、あるいはネットワーク接続、シリアル接続、pipe接続を表す場合にはエラーがシグナルされます。
引数current-groupは、Emacsのサブプロセスとしてジョブ制御shell(job-control
shell)を実行中の場合に異なる処理を行うためのフラグです。これが非nil
なら、そのシグナルはEmacsがサブプロセスとの対話に使用する端末のカレントプロセスグループに送信されます。そのプロセスがジョブ制御shellなら、これはそのshellのカレントのsubジョブになります。current-groupがnil
なら、そのシグナルはEmacs自身のサブプロセスのプロセスグループに送信されます。そのプロセスがジョブ制御shellなら、それはshell自身になります。current-groupがlambda
なら、端末を所有するもののそれ自身はshellでない場合にはプロセスグループにシグナルを送信します。
サブプロセスとの対話にpipeが使用されている際には、オペレーティングシステムがpipeの区別をサポートしないのでフラグcurrent-groupに効果はありません。同じ理由によりpipeが使用されていればジョブ制御shellは機能しないでしょう。非同期プロセスの作成のprocess-connection-type
を参照してください。
この関数はシグナルSIGINT
を送信することによりプロセスprocessに割り込む。Emacs外部ではinterrupt
character(割り込み文字。いくつかのシステムでは通常はC-c、それ以外のシステムではDEL)をタイプすることによりシグナルが送信される。引数current-groupが非nil
のときは、Emacsがサブプロセスと対話する端末上でC-cがタイプされたと考えることができる。
この関数はシグナルSIGKILL
を送信することにより、プロセスprocessをkillする。このシグナルは即座にサブプロセスをkillしてサブプロセスでハンドルすることはできない。
この関数はプロセスprocessにシグナルSIGQUIT
を送信する。これはEmacs外部ではquit
character(通常はC-\)により送信されるシグナル。
この関数は指定したprocessを停止する。それがプログラムを実行中の実際のサブプロセスなら、そのサブプロセスにシグナルSIGTSTP
を送信する。processがネットワーク接続、シリアル接続、pipe接続を表す場合には、この関数はその接続から到達するデータのハンドリングを抑制する。ネットワークサーバーでは、これは新たな接続をacceptしないことを意味する。通常の実行の再開にはcontinue-process
を使用すること。
ジョブ制御をもつシステム上のEmacs外部ではstop
character(通常はC-z)がSIGTSTP
シグナルを送信する。current-groupが非nil
なら、この関数をサブプロセスとの対話にEmacsが使用する端末上でC-zがタイプされたと考えることができる。
この関数はプロセスprocessの実行を再開する。それがプログラムを実行中の実際のサブプロセスなら、そのサブプロセスにシグナルSIGCONT
を送信する。この関数はprocessが以前に停止されたとみなす。processがネットワーク接続、シリアル接続、pipe接続を表す場合には、この関数はその接続から到達するデータのハンドリングを再開する。シリアル接続ではプロセス停止中に到達したデータは失われるかもしれない。
この関数はプロセスprocessにシグナルを送信する。引数signalはどのシグナルを送信するかを指定する。これは整数、または名前がシグナルであるようなシンボルであること。
process引数にはシステムプロセスID (整数)を指定できる。これによりEmacsの子プロセス以外のプロセスにシグナルを送信できる。別のプセスへのアクセスを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
非同期サブプロセスが自身の標準出力に書き込んだ出力はフィルター関数(filter function)と呼ばれる関数に渡されます。デフォルトのフィルター関数は単に出力をバッファーに挿入します。このバッファーをプロセスに関連付けられたバッファーと呼びます(プロセスのバッファーを参照)。プロセスがバッファーをもたなければデフォルトフィルターは出力を破棄します。
サブプロセスが標準エラーストリームに書き込む場合には、デフォルトではエラー出力もフィルター関数に渡されて処理されます。Emacsがサブプロセスとの対話に疑似端末(pty:
pseudo-TTY)を使用する場合には、疑似端末は出力チャンネルを1つしかもてないので、サブプロセスの標準出力ストリームと標準エラーストリームを区別するのは不可能です。それらのストリームの出力を区別して保ちたい場合は、たとえば
start-process-shell-command
や類似コマンドを通じて適当なshellコマンドを使用することにより、いずれか1つをファイルにリダイレクトする必要があります。
エラー出力先を標準出力から区別するためには、かわりに非nil
の:stderr
パラメーターでmake-process
(make-processを参照)を呼び出すことができます。この場合には、サブプロセスとの対話にEmacsはpipeを使用することになります。
サブプロセス終了時にEmacsは保留中の出力を読み取って、その後そのサブプロセスからの出力の読み取りを停止します。したがってそのサブプロセスに生きた子プロセスがあり、まだ出力を生成するような場合には、Emacsはその出力を受け取らないでしょう。
サブプロセスからの出力はEmacsが待機している間の端末入力読み取り時(関数waiting-for-user-input-p
、時間の経過や入力の待機のsit-for
とsleep-for
、およびプロセスからの出力を受け入れるのaccept-process-output
を参照)のみ到着可能です。これは並列プログラミングで普遍的に悩みの種であるタイミングエラーの問題を最小化します。たとえば安全にプロセスを作成して、その後でのみプロセスのバッファーやフィルター関数を指定できます。その間にあるコードが待機するプリミティブを何も呼び出さなければ完了するまで到達可能な出力はありません。
いくつかのシステムではEmacsがサブプロセスの出力を読み取る際に出力データを非常に小さいブロックで読み取るために、結果として潜在的に非常に貧弱なパフォーマンスとなることがる。この挙動は変数process-adaptive-read-buffering
を非nil
値(デフォルト)にセットして拡張することにより改善し得る。これにより、そのようなプロセスからの読み取りを自動的に遅延して、Emacsが読み取りを試みる前に出力がより多く生成されるようになる。
36.9.1 プロセスのバッファー | デフォルトでは出力はバッファーに送信される。 | |
36.9.2 プロセスのフィルター関数 | フィルター関数はプロセスからの出力を受け取る。 | |
36.9.3 プロセス出力のデコード | フィルターはユニバイトやマルチバイトの文字列を取得できる。 | |
36.9.4 プロセスからの出力を受け入れる | プロセスの出力到着まで待機する方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プロセスは関連付けられたバッファー(associated buffer)をもつことができます(通常はもつ)。これは普通のEmacsバッファーであり、2つの目的のために使用されます。1つはプロセスからの出力の格納、もう1つはプロセスをkillする時期を判断するためです。通常の習慣では任意の与えられたバッファーにたいして関連付けられるプロセスは1つだけなので、処理対象のプロセスを識別するためにそのバッファーを使用することもできます。プロセス使用の多くはプロセスに送信する入力を編集するためにもこのバッファーを使用しますが、これはEmacs Lispの組み込みではありません。
デフォルトでは、プロセスの出力は関連付けられたバッファーに挿入されます(カスタムフィルター関数の定義により変更可能。プロセスのフィルター関数を参照)。出力を挿入する位置はprocess-mark
により決定されます。これは正に挿入されたテキストの終端にポイントを更新します。通常(常にではない)はprocess-mark
はバッファーの終端になります。
プロセスに関連付けられたバッファーをkillすることによりプロセスもkillされます。そのプロセスのprocess-query-on-exit-flag
が非nil
なら、Emacsはまず確認を求めます(exit前の問い合わせを参照)。この確認は関数process-kill-buffer-query-function
により行われて、これはkill-buffer-query-functions
から実行されます(バッファーのkillを参照)。
この関数は指定されたprocessの関連付けられたバッファーをリターンする。
(process-buffer (get-process "shell")) ⇒ #<buffer *shell*>
この関数はprocessにたいするプロセスマーカーをリターンする。これはプロセスからの出力をどこに挿入するかを示すマーカー。
processがバッファーをもたなければ、process-mark
は存在しない場所を指すマーカーをリターンする。
デフォルトのフィルター関数はプロセス出力の挿入場所の決定にこのマーカーを使用して、挿入したテキストの後にポイントを更新する。連続するバッチ出力が連続して挿入されるのはこれが理由。
カスタムフィルター関数はこのマーカーを通常は同じ方式で使用すること。process-mark
を使用するフィルター関数の例はProcess Filter Exampleを参照のこと。
ユーザーにプロセスバッファー内でプロセスに送信するための入力を期待する際には、プロセスマーカーは以前の出力から新たな入力を区別する。
この関数はprocessに関連付けられたバッファーにbufferをセットする。bufferがnil
ならプロセスはバッファーに関連付けられない。
この関数はbuffer-or-nameで指定されるバッファーに関連付けられた、削除されていないプロセスをリターンする。そのバッファーに複数のプロセスが関連付けられている場合には、この関数はいずれか1つ(現在のところもっとも最近作成されたプロセスだがこれを期待しないこと)を選択する。プロセスの削除(delete-process
を参照)により、そのプロセスはこの関数がリターンするプロセスとしては不適格となる。
同一のバッファーに複数のプロセスを関連付けるのは、通常は悪いアイデアである。
(get-buffer-process "*shell*") ⇒ #<process shell>
プロセスのバッファーをkillすることにより、SIGHUP
シグナルでサブプロセスをkillしてプロセスを削除する(プロセスへのシグナルの送信を参照)。
プロセスのバッファーがウィンドウに表示されている場合には、プロセスが出力をスクリーンのサイズに適応させるのと同様に、Lispプログラムでウィンドウのサイズにプロセス出力を適応させるようにプロセスに指示したいと思うでしょう。以下の関数によりプロセスにたいしてこの種の情報をやり取りできます。しかしすべてのシステムが基礎となる機能をサポートする訳ではないので、コマンドライン引数や環境変数を通じたフォールバックを提供するのが最良です。
processにたいして、その論理ウィンドウサイズが文字単位でwidthとheightのサイズであることを告げる。関数がこの情報をプロセスとやり取りすることに成功したらt
、それ以外はnil
をリターンする。
プロセスに関連付けられたバッファーを表示するウィンドウがサイズを変更された際には、影響を受けるプロセスはその変更にたいして通知される必要があります。デフォルトではウィンドウ構成(window
configuration)が変更されると、ウィンドウにバッファーが表示されている各プロセスにかわり、プロセスのバッファーを表示するすべてのウィンドウのうち最小のサイズのウィンドウを引数として、Emacsが自動的にset-process-window-size
を呼び出します。これはバッファーが少なくとも1つのウィンドウに表示されているプセスそれぞれにたいして、変数window-adjust-process-window-size-function
の値である関数を呼び出すように指定するwindow-configuration-change-hook
(ウィンドウのスクロールと変更のためのフックを参照)を通じて機能します。この変数をセットすることにより、この振る舞いをカスマイズできます。
この変数の値はプロセスとプロセスのバッファーを表示するウィンドウのリストという2つの引数を受け取る関数であること。その関数が呼び出される際には、そのプロセスのバッファーがカレントバッファーとなる。関数はset-process-window-size
の呼び出しを通じて渡される論理プロセスウィンドウ(logical
process window)を記述するコンスセル(width . height)
をリターンすること。関数はnil
をリターンすることもでき、Emacsはこの場合にはそのプロセスにたいしてset-process-window-size
を呼び出さない。
この変数にたいしてEmacsは2つの事前定義された値を提供する。1つはwindow-adjust-process-window-size-smallest
であり、これはプロセスのバッファーを表示するウィンドウのすべてのサイズから最小のサイズもう1つのwindow-adjust-process-window-size-largest
は最大のサイズをリターンする。より複雑な方式には独自の関数を記述すること。
この変数はバッファーローカルにできる。
プロセスがadjust-window-size-function
プロパティ(プロセスの情報を参照)をもつ場合には、その値はwindow-adjust-process-window-size-function
のグローバル値とバッファーロール値をオーバーライドします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プロセスのフィルター関数(filter function)は、関連付けられたプロセスからの標準出力を受信します。そのプロセスのすべての出力はそのフィルターに渡されます。デフォルトのフィルターは単にプロセスバッファーに直接出力します。
デフォルトではプロセス作成時にエラーストリームの出力先が標準出力と分離されていなければ(プロセスからの出力の受信を参照)、プロセスからのエラー出力があればそれはフィルター関数にも渡されます。
サブプロセスからの出力はEmacsが何かを待機している間だけ到着するので、フィルター関数はそのようなときだけ呼び出し可能です。Emacsは端末入力読み取り時(関数waiting-for-user-input-p
、時間の経過や入力の待機のsit-for
とsleep-for
、およびプロセスからの出力を受け入れるのaccept-process-output
を参照)に待機します。
フィルター関数は関連付けられたプロセス、およびそのプロセスから正に受信した出力である文字列という2つの引数を受け取らなければなりません。関数はその後に出力にたいして何であれ自由に行うことができます。
quitは通常はフィルター関数内では抑制されます。さもないとコマンドレベルでのC-gのタイプ、またはユーザーコマンドのquitは予測できません。フィルター関数内部でのquitを許可したければinhibit-quit
をnil
にバインドしてください。ほとんどの場合において、これを行う正しい方法はマクロwith-local-quit
です。quitを参照してください。
フィルター関数の実行中にエラーが発生すると、フィルター開始時に実行中だったプログラムが何であれ実行を停止しないように自動的にcatchされます。しかしdebug-on-error
が非nil
ならエラーはcatchされません。これによりLispデバッガーを使用したフィルター関数のデバッグが可能になります。Lispデバッガを参照してください。
多くのフィルター関数は時折(または常に)、デフォルトフィルターの動作を真似てプロセスのバッファーにその出力を挿入します。そのようなフィルター関数は確実にカレントバッファーの保存と、(もし異なるなら)出力を挿入する前に正しいバッファーを選択して、その後に元のバッファーをリストアする必要があります。またそのバッファーがまだ生きているか、プロセスマーカーを更新しているか、そしていくつかのケースにおいてはポイントの値を更新しているかもチェックするべきです。以下はこれらを行う方法です:
(defun ordinary-insertion-filter (proc string) (when (buffer-live-p (process-buffer proc)) (with-current-buffer (process-buffer proc) (let ((moving (= (point) (process-mark proc))))
(save-excursion
;; テキストを挿入してプロセスマーカーを進める
(goto-char (process-mark proc))
(insert string)
(set-marker (process-mark proc) (point)))
(if moving (goto-char (process-mark proc)))))))
新たなテキスト到着時にフィルターが強制的にプロセスバッファーを可視にするためにwith-current-buffer
構成の直前に以下のような行を挿入できます:
(display-buffer (process-buffer proc))
以前の位置に関わらず新たな出力の終端にポイントを強制するには、例から変数moving
を削除して無条件でgoto-char
を呼び出してください。
フィルター関数の実行中には、Emacsが自動的にマッチデータの保存とリストアを行うことに注意してください。マッチデータを参照してください。
フィルターへの出力は任意のサイズのchunkで到着する可能性があります。同じ出力を連続して2回生成するプログラムは一度に200文字を1回のバッチで送信して、次に40文字を5回のバッチで送信するかもしれません。フィルターが特定のテキスト文字列をサブプロセスの出力から探す場合には、それらの文字列が2回以上のバッチ出力を横断するケースに留意して処理してください。これを行うには受信したテキストを一時的なバッファーに挿入してから検索するのが1つの方法です。
この関数はprocessにフィルター関数filterを与える。filterがnil
なら、そのプロセスにたいしてプロセスバッファーにプロセス出力を挿入するデフォルトフィルターを与える。
この関数はprocessのフィルター関数をリターンする。
そのプロセスの出力を複数のフィルターに渡す必要がある場合には、既存のフィルターに新たなフィルターを組み合わせるためにadd-function
を使用できる。Emacs Lisp関数にたいするアドバイスを参照のこと。
以下はフィルター関数の使用例:
(defun keep-output (process output) (setq kept (cons output kept))) ⇒ keep-output
(setq kept nil) ⇒ nil
(set-process-filter (get-process "shell") 'keep-output) ⇒ keep-output
(process-send-string "shell" "ls ~/other\n") ⇒ nil kept ⇒ ("lewis@slug:$ "
"FINAL-W87-SHORT.MSS backup.otl kolstad.mss~ address.txt backup.psf kolstad.psf backup.bib~ david.mss resume-Dec-86.mss~ backup.err david.psf resume-Dec.psf backup.mss dland syllabus.mss " "#backups.mss# backup.mss~ kolstad.mss ")
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsが直接マルチバイトバッファーにプロセス出力を書き込む際には、プロセス出力のコーディングシステムに応じて出力をデコードします。コーディングシステムがraw-text
かno-conversion
ならEmacsはstring-to-multibyte
を使用してユニバイト出力をマルチバイトに変換して、その結果のマルチバイトテキストを挿入します。
どのコーディングシステムを使用するかはset-process-coding-system
を使用して指定できます(プロセスの情報を参照)。それ以外ではcoding-system-for-read
が非nil
ならそのコーディングシステム、nil
ならデフォルトのメカニズムが使用されます(デフォルトのコーディングシステムを参照)。プロセスのテキスト出力にnullバイトが含まれる場合には、Emacsはそれにたいしてデフォルトではno-conversion
を使用します。この挙動を制御する方法についてはinhibit-null-byte-detectionを参照してください。
警告:
データからコーディングシステムを判断するundecided
のようなコーディングシステムは、非同期サブプロセスの出力にたいして完全な信頼性をもって機能しません。これはEmacsが到着に応じて非同期サブプロセスの出力をバッチで処理する必要があるからです。Emacsは1つのバッチが到着するたびに正しいコーディングシステムを検出しなければならずこれは常に機能するわけではありません。したがって可能であれば文字コード変換とEOL変換の両方を決定するコーディングシステムつまりlatin-1-unix
、undecided
、latin-1
のようなコーディングシステムを指定してください。
Emacsがプロセスフィルター関数を呼び出す際には、そのプロセスのフィルターのコーディングシステムに応じてEmacsはプロセス出力をマルチバイト文字列、またはユニバイト文字列で提供します。Emacsはプロセス出力のコーディングシステムに応じて出力をデコードします。これはbinary
やraw-text
のようなコーディングシステムを除いて、通常はマルチバイト文字列を生成します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
非同期サブプロセスからの出力は、通常はEmacsが時間の経過や端末入力のような、ある種の外部イベントを待機する間だけ到着します。特定のポイントで出力の到着を明示的に許可したり、あるいはプロセスからの出力が到着するまで待機することでさえ、Lispプログラムでは有用な場合が時折あります。
この関数はプロセスからの保留中の出力をEmacsが読み取ることを許す。この出力はプロセスのフィルター関数により与えられる。processが非nil
なら、この関数はprocessから何らかの出力を受け取るまでリターンしない。
引数secondsとmillisecによりタイムアウトの長さを指定できる。前者は秒単位、後者はミリ秒単位でタイムアウトを指定する。この2つの秒数は、互いに足し合わせることによりタイムアウトを指定して、その秒数経過後はサブプロセスの出力が存在しなくてもリターンする。
secondsに浮動小数点数を指定することにより秒を少数点で指定できるので引数millisecは時代遅れ(であり使用するべきではない)。secondsが0ならこの関数は保留中の出力が何であれ受け取り待機しない。
processがプロセスで引数just-this-oneが非nil
ならプロセスからの出力だけが処理され、そのプロセスからの出力を受信するかタイムアウトとなるまで他のプロセスの出力は停止される。just-this-oneが整数ならタイマーの実行も抑制される。この機能は一般的には推奨されないが、音声合成のような特定のアプリケーションにとっては必要かもしれない。
関数accept-process-output
はprocess、processがnil
なら任意のプロセスから出力を取得したら非nil
をリターンする。出力の到着前にタイムアウトが到来したらnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プロセスセンチネル(process sentinel: プロセス番兵)とは、(Emacsにより送信されたか、そのプロセス自身の動作が原因で送信された)プロセスを終了、停止、継続するシグナルを含む、何らかの理由により関連付けられたプロセスの状態が変化した際には常に呼び出される関数のことです。プロセスがexitする際にもプロセスセンチネルが呼び出されます。センチネルはイベントが発生したプロセスとイベントのタイプを記述する文字列という2つの引数を受け取ります。
プロセスにたいして何もセンチネル関数が指定されていなければ、プロセスのバッファーにプロセス名とイベントを記述する文字列とともにメッセージを挿入するデフォルトのセンチネル関数を使用します。
イベントを記述する文字列は以下のいずれかのような外見をもちます:
"finished\n"
.
"deleted\n"
.
"exited abnormally with code exitcode (core dumped)\n"
."failed with code fail-code\n"
.
"signal-description (core
dumped)\n"
.SIGKILL
にたいする"killed"
のようなシステム依存の説明テキスト。“core
dumped”の部分はオプションであり、プロセスがコアをダンプした場合のみ出現する。
"open from host-name\n"
.
"open\n"
.
"connection broken by remote peer\n"
.
センチネルはEmacsが(端末入力や時間経過、またはプロセス出力を)待機している間だけ実行されます。これは他のLispプログラムの途中のランダムな箇所で実行されるセンチネルが原因となるタイミングエラーを無視します。プログラムはセンチネルが実行されるように、sit-for
やsleep-for
(時間の経過や入力の待機を参照)、またはaccept-process-output
(プロセスからの出力を受け入れるを参照)を呼び出すことにより待機することができます。Emacsはコマンドループが入力を読み取る際にもセンチネルの実行を許可します。delete-process
は実行中のプログラムを終了させる際にセンチネルを呼び出します。
Emacsは1つのプロセスのセンチネル呼び出しの理由のために複数のキューを保持しません。これはカレント状態と変化があった事実だけを記録します。したがって非常に短い間隔で連続して状態に2つの変化があった場合には、一度だけセンチネルが呼び出されます。しかしプロセスの終了は常に正確に1回センチネルを実行するでしょう。これは終了後にプロセス状態が再び変更されることはないからです。
Emacsはプロセスセンチネル実行の前にプロセスからの出力をチェックします。プロセス終了によりセンチネルが一度実行されると、そのプロセスから更なる出力は到着しません。
プロセスのバッファーに出力を書き込むセンチネルは、そのバッファーがまだ生きているかチェックするべきです。死んだバッファーへの挿入を試みるとエラーになるでしょう。そのバッファーがすでに死んでいれば(buffer-name
(process-buffer process))
はnil
をリターンします。
quitは通常はセンチネル内では抑制されます。さもないとコマンドレベルでのC-gのタイプ、またはユーザーコマンドのquitは予測できません。センチネル内部でのquitを許可したければinhibit-quit
をnil
にバインドしてください。ほとんどの場合において、これを行う正しい方法はマクロwith-local-quit
です。quitを参照してください。
センチネルの実行中にエラーが発生した場合には、センチネル開始時に実行中だったプログラムが何であれ実行を停止しないように自動的にcatchされます。しかしdebug-on-error
が非nil
ならエラーはcatchされません。これによりLispデバッガーを使用したセンチネルのデバッグが可能になります。Lispデバッガを参照してください。
センチネルの実行中にはセンチネルが再帰的に実行されないように、プロセスセンチネルは一時的にnil
にセットされます。この理由によりセンチネルが新たにセンチネルを指定することはできません。
センチネル実行中にはEmacsが自動的にマッチデータの保存とリストアを行うことに注意してください。マッチデータを参照してください。
この関数はsentinelをprocessに関連付ける。sentinelがnil
なら、そのプロセスはプロセス状態変更時にプロセスのバッファーにメッセージを挿入するデフォルトのセンチネルをもつことになるだろう。
プロセスセンチネルの変更は即座に効果を発揮する。そのセンチネルは実行される予定だがまだ呼び出されておらず、かつ新たなセンチネルを指定した場合には、最終的なセンチネル呼び出しには新たなセンチネルが使用されるだろう。
(defun msg-me (process event) (princ (format "Process: %s had the event '%s'" process event))) (set-process-sentinel (get-process "shell") 'msg-me) ⇒ msg-me
(kill-process (get-process "shell")) -| Process: #<process shell> had the event 'killed' ⇒ #<process shell>
この関数はprocessのセンチネルをリターンする。
あるプロセス状態の変化を複数のセンチネルに渡す必要がある場合には、既存のセンチネルと新たなセンチネルを組み合わせるためにadd-function
を使用できます。Emacs Lisp関数にたいするアドバイスを参照してください。
この関数はセンチネルやフィルター関数の実行中に、もしEmacsがセンチネルやフィルター関数呼び出し時にユーザーのキーボード入力を待機していたら非nil
、そうでなければnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsがexitする際にはすべてのサブプロセスを終了します。プログラムを実行しているサブプロセスにはSIGHUP
を送信して、接続は単にcloseされます。それらのサブプロセスはさまざまな処理を行っているかもしれないので、Emacsは通常ユーザーにたいしてそれらを終了しても大丈夫かどうか確認を求めます。各プロセスはquery(問い合わせ)のためのフラグをもち、これが非nil
ならEmacsはプロセスをkillしてexitする前に確認を行うべきであることを示します。queryフラグにたいするデフォルトはt
で、これは問い合わせを行うことを意味しています。
これはprocessのqueryフラグをリターンする。
この関数はprocessのqueryフラグをflagにセットする。これはflagをリターンする。
以下はshellプロセス上で問い合わせを回避するためにset-process-query-on-exit-flag
を使用する例:
(set-process-query-on-exit-flag (get-process "shell") nil) ⇒ nil
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
カレントEmacsセッションのサブプロセスにたいするアクセスと操作に加えて、同一マシン上で実行中の他のプロセスにたいしてEmacs Lispプログラムがアクセスすることもできます。Emacsのサブプロセスと区別するために、わたしたちはこれらをシステムプロセス(system processes)と呼んでいます。
Emacsはシステムプロセスへのアクセス用のプリミティブをいくつか提供します。これらのプリミティブはすべてのプラットフォームではサポートされません。これらのプリミティブはサポートされないシステムではnil
をリターンします。
この関数はそのシステム上で実行中のすべてのプロセスのリストをリターンする。各プロセスはPIDというOSから割り当てられた数値によるプロセスIDにより識別され、同一時に同一マシン上で実行中の他のプロセスと区別される。
この関数はプロセスID
pidで指定されるプロセスにたいする属性のalistをリターンする。このalist内の各属性は(key
.
value)
という形式でありkeyは属性、valueはその属性の値である。この関数がリターン可能なさまざまな属性にたいするkeyを以下にリストした。これらすべての属性をすべてのプラットフォームがサポートする訳ではない。ある属性がサポートされていなければ、その連想値はリターンされるalist内に出現しない。数値であるような値は整数か浮動小数点数のいずれかが可能であり、それは値の大小に依存する。
euid
そのプロセスを呼び出したユーザーの実効ユーザーID(effective user
ID)。対応するvalueは数値。プロセスがカレントEmacsセッションを実行したユーザーと同じなら値はuser-uid
がリターンする値と等しくなる(ユーザーの識別を参照)。
user
そのプロセスの実効ユーザーIDに対応するユーザー名であるような文字列。
egid
実行ユーザーIDのグループIDであるような数値。
group
実効ユーザーのグループIDに対応するグループ名であるような文字列。
comm
そのプロセス内で実効したコマンドの名前。これは通常は先行するディレクトリーを除いた実行可能ファイル名を指定する文字列。しかしいくつかの特別なシステムプロセスは、実行可能ファイルやプログラムに対応しない文字列を報告する可能性がある。
state
そのプロセスの状態コード。これはそのプロセスのスケジューリング状態をエンコードする短い文字列。以下は頻繁に目にするコードのリスト:
"D"
割り込み不可のsleep(通常はI/Oによる)
"R"
実行中
"S"
割り込み可能なsleep(何らかのイベント待ち)
"T"
ジョブ制御シグナルにより停止された
"Z"
zombie: 終了したが親プロセスに回収されていないプロセス
可能な状態の完全なリストはps
コマンドのman pageを参照のこと。
ppid
親プロセスのプロセスIDであるような数値。
pgrp
そのプロセスのプロセスグループIDであるような数値。
sess
そのプロセスのセッションID。これはそのプロセスのセッションリーダー(session leader)のプロセスIDであるような数値。
ttname
そのプロセスの制御端末の名前であるような文字列。これはUnixやGNUシステムでは通常は/dev/pts65のような対応する端末デバイスのファイル名。
tpgid
そのプロセスの端末を使用するフォアグラウンドプロセスグループのプロセスグループIDであるような数値。
minflt
そのプロセス開始以降に発生したマイナーなページフォルト数(マイナーなページフォルトとはディスクからの読み込みを発生させないページフォルト)。
majflt
そのプロセス開始以降に発生したメジャーなページフォルト数(メジャーなページフォルトとはディスクからの読み込みを要し、それ故にマイナーページフォルトより高価なページフォルト)。
cminflt
cmajflt
minflt
やmajflt
と似ているが与えられたプロセスのすべての子プロセスのページフォルト数を含む。
utime
アプリケーションのコード実行にたいしてユーザーコンテキスト内でプロセスに消費された時間。対応するvalueは(high low microsec picosec)
というフォーマットであり、これは関数current-time
が使用するフォーマットと同じ(current-time)とファイルの属性のfile-attributes
を参照)。
stime
システムコールの処理にたいしてシステム(kernel)コンテキスト内でプロセスに消費された時間。対応するvalueはutime
と同じフォーマット。
time
utime
とstime
の和。対応するvalueはutime
と同じフォーマット。
cutime
cstime
ctime
utime
やstime
と同様だが与えられたプロセスのすべての子プロセスの時間が含まれる点が異なる。
pri
そのプロセスの数値的な優先度。
nice
そのプロセスのnice値(nice value)であるような数値(小さいnice値のプロセスがより優先的にスケジュールされる)。
thcount
そのプロセス内のスレッド数。
start
file-attributes
やcurrent-time
が使用するのと同じフォーマット(high
low microsec picosec)
による、そのプロセスが開始された時刻。
etime
(high low microsec
picosec)
というフォーマットによる、そのプロセスが開始されてから経過した時間。
vsize
そのプロセスの仮想メモリーのKB単位でのサイズ。
rss
そのプロセスがマシンの物理メモリー内で占める常駐セット(resident set)のKB単位でのサイズ。
pcpu
プロセス開始以降に使用されたCPU時間のパーセンテージ。対応するvalueは0から100の間の浮動小数点数。
pmem
マシンにインストールされた物理メモリー合計のうち、そのプロセスの常駐セットのパーセンテージ。値は0から100の間の浮動小数点数。
args
そのプロセスが呼び出されたときのコマンドライン。これは個々のコマンドライン引数がブランクで区切られた文字列。引数に埋め込まれた空白文字はシステムに応じて適切にクォートされる。GNUやUnixではバックスラッシュ文字によるエスケープ、Windowsではダブルクォート文字で囲まれる。つまりこのコマンドライン文字列はshell-command
のようなプリミティブにより直接使用できる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
トランザクションを用いてサブプロセスと対話するためにトランザクションキュー(transaction
queue)を使用できます。まずtq-create
を使用して指定したプロセスと対話するためのトランザクションキューを作成します。それからトランザクションを送信するためにtq-enqueue
を呼び出すことができます。
この関数はprocessと対話するトランザクションキューを作成してリターンする。引数processはバイトストリームを送受信する能力をもつサブプロセスであること。これは子プロセス、または(おそらく別のマシン上の)サーバーへのTCP接続かもしれない。
この関数はキューqueueにトランザクションを送信する。キューの指定は対話するサブプロセスを指定する効果をもつ。
引数questionはトランザクションを開始するために発信するメッセージ。引数fnは、それにたいする応答が返信された際に呼び出す関数。これはclosureと受信した応答という2つの引数で呼び出される。
引数regexpは応答全体の終端にマッチして、それより前にはマッチしない正規表現であること。これはtq-enqueue
が応答の終わりを決定する方法である。
引数delay-questionが非nil
なら、そのプロセスが以前に発信したすべてのメッセージへの返信が完了するまでメッセージの送信を遅延する。これによりいくつかのプロセスにたいして、より信頼性のある結果が生成される。
保留中のすべてのトランザクションの完了を待機して、トランザクションキューqueueをシャットダウンして、それから接続または子プロセスを終了する。
トランザクションキューはフィルター関数により実装されています。プロセスのフィルター関数を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs
Lispプログラムは同一マシンまたは他のマシン上の別プロセスにたいしてストリーム(TCP)やデータグラム(UDP)のネットワーク接続(データグラムを参照)をオープンできます。ネットワーク接続はLispによりサブプロセスと同様に処理されて、プロセスオブジェクトとして表されます。しかし対話を行うそのプロセスはEmacsの子プロセスではなく、プロセスIDをもたず、それをkillしたりシグナルを送信することはできません。行うことができるのはデータの送信と受信だけです。delete-process
は接続をクローズしますが、他方の端のプログラムをkillしません。そのプログラムは接続のクローズについて何を行うか決定しなければなりません。
ネットワークサーバーを作成することによりLispプログラムは接続をlistenできます。ネットワークサーバーもある種のプロセスオブジェクトとして表されますが、ネットワーク接続とは異なりネットワークサーバーがデータ自体を転送することは決してありません。接続リクエストを受信したときは、それにたいして作成した接続を表す新たなネットワーク接続を作成します(そのネットワーク接続はサーバーからプロセスplistを含む特定の情報を継承する)。その後でネットワークサーバーは更なる接続リクエストのlistenに戻ります。
ネットワーク接続とサーバーは、キーワード/引数のペアーで構成される引数リストでmake-network-process
を呼び出すことにより作成されます。たとえば:server
t
はサーバープロセス、:type 'datagram
はデータグラム接続を作成します。詳細は低レベルのネットワークアクセスを参照してください。以下で説明するopen-network-stream
を使用することもできます。
異なるプロセスのタイプを区別するためにprocess-type
関数はネットワーク接続とサーバーにはnetwork
、シリアルポート接続はserial
、pipe接続にはpipe
、実際のサブプロセスにはreal
をリターンします。
ネットワーク接続にたいしてprocess-status
関数はopen
、closed
、connect
、stop
、またはfailed
をリターンします。ネットワークサーバーにたいしては状態は常にlisten
になります。実際のサブプロセスにたいしてはstop
以外の値はリターンされません。プロセスの情報を参照してください。
stop-process
とcontinue-process
を呼び出すことにより、ネットワークプロセスの処理の停止と再開が可能です。サーバープロセスにたいする停止は新たな接続の受け付けないことを意味します(サーバー再開時は5つまでの接続リクエストがキューされる。これがOSによる制限でなければこの制限は増やすことができる。make-network-process
のmake-network-process
の:server
を参照)。ネットワークストリーム接続にたいしては、停止は入力の処理を行わないことを意味します(到着するすべての入力は接続の再開まで待つ)。データグラム接続にたいしては、いくらかのパケットはキューされますが入力は失われるかもしれません。ネットワーク接続またはサーバーが停止しているかどうかを判断するために、関数process-command
を使用できます。これが非nil
なら停止しています。
ビルトインや外部のサポートを使用することによりEmacsは暗号化されたネットワーク接続を作成できます。ビルトインのサポートはGnuTLSライブラリー(TLS:
Transport Layer Security)を使用します。the GnuTLS project
pageを参照してください。GnuTLSサポートつきでEmacsをコンパイルした場合には関数gnutls-available-p
が定義されて非nil
をリターンします。詳細はOverview in The Emacs-GnuTLS
manualを参照してください。外部のサポートの場合はstarttls.elライブラリーを使用します。これはシステム上にgnutls-cli
のようなヘルパーユーティリティーのインストールを必要とします。open-network-stream
関数は利用可能なサポートを何であれ使用して暗号化接続作成の詳細を透過的に処理できます。
この関数はオプションで暗号つきでTCP接続をオープンして、その接続を表すプロセスオブジェクトをリターンする。
name引数はプロセスオブジェクトの名前を指定する。これは必要に応じて一意になるよう変更される。
buffer引数はその接続に関連付けるバッファー。その接続からの出力は出力を処理する独自のフィルター関数を指定していない場合には、bufferがnil
ならその接続はバッファーに関連付けられない。
引数hostとserviceはどこに接続するかを指定する。hostはホスト名(文字列)、serviceは定義済みのネットワークサービス名(文字列)、またはポート番号(数字)。
残りの引数parametersは主に暗号化された接続に関連するキーワード/引数のペアー:
:nowait boolean
非nil
なら非同期接続を試みる。
:type type
接続のタイプ。オプションは以下のとおり:
plain
通常の暗号化されていない接続。
tls
ssl
TLS (Transport Layer Security)接続。
nil
network
plain接続を開始してパラメーター‘:success’と‘:capability-command’が与えられたら、STARTTLSを通じて暗号化接続への更新を試みる。これが失敗したら暗号化されていない接続のまま留まる。
starttls
nil
と同様だがSTARTTLSが失敗したらその接続を切断する。
shell
shell接続。
:always-query-capabilities boolean
非nil
なら、たとえ‘plain’な接続を行っているときでも常にサーバーの能力を問い合わせる。
:capability-command capability-command
ホストの能力を問い合わせるためのコマンド文字列。
:end-of-command regexp
:end-of-capability regexp
コマンドの終端、またはコマンドcapability-commandの終端にマッチする正規表現。前者は後者のデフォルト。
:starttls-function function
単一の引数(capability-commandにたいする応答)をとりnil
、またはサポートされていればSTARTTLSをアクティブにするコマンドをリターンする関数。
:success regexp
成功したSTARTTLSネゴシェーションにマッチする正規表現。
:use-starttls-if-possible boolean
非nil
なら、たとえEmacsがビルトインのTLSサポートをもっていなくても、日和見的(opportunistic)にSTARTTLSアップグレードを行う。
:warn-unless-encrypted boolean
非nil
、かつ:return-value
も非nil
なら、接続が暗号化されていない場合にはEmacsは警告するだろう。これはほとんどのユーザーがネットワークトラフィックが暗号化されているこを期待するであろうIMAPやその類のプロトコルにたいして有用。
:client-certificate list-or-t
証明書(certificate)のキーと、証明書のファイル自身を命名する(key-file
cert-file)
という形式のリスト、またはこの情報にたいしてauth-source
を尋ねることを意味するt
のいずれか(Overview in The Auth-Source
Manualを参照)。TLSやSTARTTLSにたいしてのみ使用される。
:return-list cons-or-nil
この関数のリターン値。省略またはnil
ならプロセスオブジェクトをリターンする。それ以外なら(process-object
. plist)
という形式のコンスセルをリターンする。ここでplistは以下のキーワード:
:greeting string-or-nil
非nil
ならホストからリターンされたgreeting(挨拶)文字列。
:capabilities string-or-nil
非nil
ならホストの能力(capability)文字列。
:type symbol
接続タイプであり、‘plain’か‘tls’のいずれか。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
:server
t
でmake-network-process
を呼び出すことによりサーバーが作成されます(make-network-process
を参照)。そのサーバーはクライアントからの接続リクエストをlistenするでしょう。クライアントの接続リクエストをaccept(受け入れる)する際は以下のようなパラメーターで、それ自体がプロセスオブジェクトであるようなネットワーク接続を作成します。
サーバーのプロセスバッファーの値が直接使用されることは決してないが、log関数は接続のログを記録するためにそれを取得して、そこにテキストを挿入して使用することができる。
process-contact
のキーワード:host
、:service
、:remote
に関連付けられる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
データグラム(datagram)接続は、データストリームではなく個別のパッケージで対話します。process-send
を呼び出すたびに1つのデータグラムパケット(プロセスへの入力の送信を参照)が送信されて、受信されたデータグラムごとに1回フィルター関数が呼び出されます。
データグラム接続は毎回同じリモートピア(remote
peer)と対話する必要はありません。データグラム接続はデータグラムの送信先を指定するリモートピアアドレス(remote peer
address)をもちます。フィルター関数にたいして受信されたデータグラムが渡されるたびに、そのデータグラムの送信元アドレスがピアアドレスにセットされます。このようにもしフィルター関数がデータグラムを送信したら、それは元の場所へ戻ることになります。:remote
キーワードを使用してデータグラム接続を作成する際にはリモートピアアドレスを指定できます。set-process-datagram-address
を呼び出すことにより後からそれを変更できます。
processがデータグラム接続かサーバーなら、この関数はそれのリモートピアアドレスをリターンする。
processがデータグラム接続かサーバーなら、この関数はそのリモートピアアドレスにaddressをセットする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
make-network-process
を使用することにより、open-network-stream
より低レベルでの処理からネットワーク接続を作成することもできます。
36.17.1 make-network-process | make-network-process の使用。
| |
36.17.2 ネットワークのオプション | 更なるネットワーク接続の制御。 | |
36.17.3 ネットワーク機能の可用性のテスト | 使用中マシン上で動作するネットワーク機能を判断する。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
make-network-process
ネットワーク接続やネットワークサーバーを作成する基本的な関数はmake-network-process
です。これは与えられた引数に応じて、これらの仕事のいずれかを行うことができます。
この関数はネットワーク接続やサーバーを作成して、それを表すプロセスオブジェクトをリターンする。引数argsはキーワード/引数のペアからなるリスト。キーワードの省略は:coding
、:filter-multibyte
、:reuseaddr
を除いて、常に値としてnil
を指定したのと同じことになる。重要なキーワードを以下に示す(ネットワークオプションに対応するキーワードを以降のセクションにリストする)。
プロセス名として文字列nameを使用する。一意にするために必要に応じて変更され得る。
コミュニケーションのタイプを指定する。値nil
はストリーム接続(デフォルト)、datagram
はデータグラム接続、seqpacket
はシーケンスパケットストリーム(sequenced
packet stream)による接続を指定する。接続およびサーバーの両方でこれらのタイプを指定できる。
server-flagが非nil
ならサーバー、それ以外なら接続を作成する。ストリームタイプのサーバーではserver-flagはそのサーバーへの保留中の接続キューの長さを指定する整数を指定できる。キューのデフォルト長は5。
接続するホストを指定する。hostはホスト名かインターネットアドレスを表す文字列、またはローカルホストを表すシンボルlocal
であること。サーバーのときにhostを指定する場合には有効なローカルホストのアドレスを指定しなければならず、そのアドレスに接続するクライアントだけが受け入れられるだろう。
serviceは接続先のポート番号、またはサーバーにたいしてはlistenするポート番号。これはポート番号に変換されるようなサービス名、または直接ポート番号を指定する整数であること。サーバーにたいしてはt
も指定でき、これは未使用のポート番号をシステムに選択させることを意味する。
familyは接続のアドレス(またはプロトコル)のファミリーを指定する。nil
は与えられたhostとserviceにたいして自動的に適切なアドレスファミリーを決定する。local
はUnixのsocketを指定して、この場合にはhostは無視される。ipv4
とipv6
はそれぞれIPv4とIPv6の使用を指定する。
サーバープロセスではlocal-addressはlistenするアドレスである。これはfamily、host、serviceをオーバーライドするので、これらを指定しないこともできる。
接続プロセスではremote-addressは接続先のアドレス。これはfamily、host、serviceをオーバーライドするので、これらを指定しないこともできる。
データグラムサーバーではremote-addressはリモートデータグラムアドレスの初期セッティングを指定する。
local-addressとremote-addressのフォーマットはアドレスファミリーに依存する:
[a b c
d
p]
で表され、それぞれ数値的なIPv4アドレスa.b.c.d、およびポート番号pに対応する。
[a b c d e
f g h
p]
で表され、それぞれ数値的なIPv6アドレスa:b:c:d:e:f:g:h、およびポート番号pに対応する。
(f
.
av)
で表される。ここでfはファミリー名、avはアドレスデータバイトごとに1つの要素を使用するソケットアドレスを指定するベクター。可搬性のあるコードでこのフォーマットを信頼してはならない。これは実装定義の定数、データサイズ、データ構造のアライメントに依存する可能性があるからだ。
ストリーム接続にたいしてboolが非nil
なら、その接続の完了を待機せずにリターンする。接続の成功や失敗時には、Emacsは"open"
(成功時)、または"failed"
(失敗時)にマッチするような第2引数によりセンチネル関数を呼び出すだろう。デフォルトではwaitせずにblockするので、make-network-process
はその接続が成功または失敗するまでリターンしない。
stoppedが非nil
ならstopped(停止)の状態でネットワーク接続、またはサーバーを開始する。
プロセスバッファーとしてbufferを使用する。
このプロセスにたいするコーディングシステムとしてcodingを使用する。接続からのデータのデコードおよび接続への送信データのエンコードに異なるコーディングシステムを指定するには、codingにたいして(decoding
. encoding)
と指定する。
このキーワードをまったく指定しないかった場合のデフォルトは、そのデータからコーディングシステムを判断する。
プロセスqueryフラグをquery-flagに初期化する。exit前の問い合わせを参照のこと。
プロセスフィルターをfilterに初期化する。
multibyteが非nil
ならマルチバイト文字列、それ以外ならユニバイト文字列がプロセスフィルターに与えられるデフォルトはenable-multibyte-characters
のデフォルト値。
プロセスセンチネルをsentinelに初期化する。
サーバープロセスのlog関数をlogに初期化する。サーバーがクライアントからネットワーク接続をacceptするたびにそのlog関数が呼び出される。log関数に渡される引数はserver、connection、message。ここでserverはサーバープロセス、connectionはその接続にたいする新たなプロセス、messageは何が発生したかを説明する文字列。
プロセスplistをplistに初期化する。
実際の接続情報で修正されたオリジナルの引数リストはprocess-contact
を通じて利用できる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のネットワークオプションはネットワークプロセス作成時に指定できます。:reuseaddr
を除き、set-network-process-option
を使用してこれらのオプションを後からセットや変更することもできます。
サーバープロセスにたいしては、make-network-process
で指定されたオプションはクライアントに継承されないので、子接続が作成されるたびに必要なオプションをセットする必要があるでしょう。
device-nameがネットワークインターフェースを指定する空でない文字列なら、そのインターフェースで受信したパケットだけを処理する。device-nameがnil
(デフォルト)なら任意のインターフェースが受信したパケットを処理する。
このオプションの使用にたいして特別な特権を要求するシステムがいくつかあるかもしれない。
データグラムプロセスにたいしてbroadcast-flagが非nil
なら、そのプロセスはブロードキャストアドレスに送信されたデータグラムパケットを受信して、ブロードキャストアドレスにパケットを送信できるだろう。これはストリーム接続では無視される。
dontroute-flagが非nil
ならプロセスはローカルホストと同一ネットワーク上のホストだけに送信することができる。
ストリーム接続にたいしてkeepalive-flagが非nil
なら、低レベルのkeep-aliveメッセージの交換が有効になる。
linger-argが非nil
なら、接続を削除(delete-process
を参照)する前にキューされたすべてのパケットの送信が成功するまで待機する。linger-argが整数なら、接続クローズ前のキュー済みパケット送信のために待機する最大の秒数を指定する。デフォルトはnil
で、これはプロセス削除時に未送信のキュー済みパケットを破棄することを意味する。
ストリーム接続にたいしてoobinline-flagが非nil
なら、通常のデータストリーム内の帯域外(out-of-band)データを受信して、それ以外なら帯域外データは破棄する。
この接続で送信するパケットの優先順位を整数priorityにセットする。たとえばこの接続で送信するIPパケットのTOS(type of service)フィールドにセットする等、この数字の解釈はプロトコルに固有である。またそのネットワークインターフェース上で特定の出力キューを選択する等、これにはシステム依存の効果もある。
ストリームプロセスサーバーにたいしてreuseaddr-flagが非nil
(デフォルト)なら、そのホスト上の別プロセスがそのポートですでにlistenしていなければ、このサーバーは特定のポート番号(:service
を参照)を再使用できる。reuseaddr-flagがnil
なら、(そのホスト上の任意のプロセスが)そのポートを最後に使用した後、そのポート上で新たなサーバーを作成するのが不可能となるような一定の期間が存在するかもしれない。
この関数はネットワークプロセスprocessにたいしてネットワークオプションのセットや変更を行う。指定できるオプションはmake-network-process
と同様。no-errorが非nil
なら、optionがサポートされないオプションの場合に、この関数はエラーをシグナルせずにnil
をリターンする。この関数が成功裏に完了したらt
をリターンする。
あるオプションのカレントのセッティングはprocess-contact
関数を通じて利用できる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
与えられネットワーク機能が利用可能かテストするためには以下のようにfeaturep
を使用します:
(featurep 'make-network-process '(keyword value))
このフォームの結果はmake-network-process
内でkeywordに値valueを指定することが機能するならt
になります。以下はこの方法でテストできるkeyword/valueペアーのいくつかです。
(:nowait t)
非ブロッキング接続がサポートされていれば非nil
。
(:type datagram)
データグラムがサポートされていれば非nil
。
(:family local)
ローカルsocket(別名“UNIX domain”)がサポートされていれば非nil
。
(:family ipv6)
IPv6がサポートされていれば非nil
。
(:service t)
サーバーにたいしてシステムがポートを選択できれば非nil
。
与えられたネットワークオプションが利用可能かテストするためには、以下のようにfeaturep
を使用します:
(featurep 'make-network-process 'keyword)
指定できるkeywordの値は:bindtodevice
等です。完全なリストはネットワークのオプションを参照してください。このフォームはmake-network-process
(またはset-network-process-option
)が特定のネットワークオプションをサポートしていれば非nil
をリターンします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の追加の関数はネットワーク接続の作成や操作に有用です。これらはいくつかのシステムでのみサポートされることに注意してください。
この関数は使用しているマシン上のネットワークインターフェースを記述するリストをリターンする。値は要素が(name
.
address)
という形式をもつようなalist。addressはmake-network-process
の引数local-addressやremote-addressと同じ形式。
この関数はifnameという名前のネットワークインターフェースに関する情報をリターンする。値は(addr
bcast netmask hwaddr flags)
という形式をもつリスト。
インターネットプロトコルアドレス。
ブロードキャストアドレス。
ネットワークマスク。
レイヤー2アドレス(たとえばイーサネットMACアドレス)。
そのインターフェースのカレントのフラグ。
この関数はネットワークアドレスのLisp表現を文字列に変換する。
5要素のベクター[a b c d
p]
はIPv4アドレスa.b.c.d、およびポート番号pを表す。format-network-address
はこれを文字列\"a.b.c.d:p\"
に変換する。
9要素のベクター[a b c d e f g
h
p]
はポート番号とともにIPv6アドレスを表す。format-network-address
はこれを文字列"[a:b:c:d:e:f:g:h]:p"
に変換する。
このベクターにポート番号が含まれない、またはomit-portが非nil
なら結果にサフィックス:p
は含まれない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはシリアルポートと対話できます。インタラクティブなM-x
serial-termの使用にたいしては端末ウィンドウをオープンして、Lispプログラムmake-serial-process
にたいしてはプロセスオブジェクトを作成します。
シリアルポートはクローズと再オープンなしで実行時に設定することができます。関数serial-process-configure
によりスピード、バイトサイズ、およびその他のパラメーターを変更できます。serial-term
で作成された端末ウィンドウではモードラインをクリックして設定を行うことができます。
シリアル接続はプロセスオブジェクトとして表されて、サブプロセスやネットワークプロセスと同様の方法で使用できます。これによりデータの送受信やシリアルポートの設定ができます。しかしシリアルプロセスオブジェクトにプロセスIDはありません。それにたいしてシグナルの送信はできずステータスコードは他のタイプのプロセスオブジェクトとは異なります。プロセスオブジェクトへのdelete-process
、またはプロセスバッファーにたいするkill-buffer
は接続をクローズしますが、そのシリアルポートに接続されたデバイスに影響はありません。
関数process-type
はシリアルポート接続を表すプロセスオブジェクトにたいするシンボルserial
をリターンします。
シリアルポートはGNU/LinuxやUnix、そしてMS Windowsのシステムで利用できます。
新たなバッファー内でシリアルポートにたいする端末エミュレーターを開始する。portは接続先のシリアルポートの名前。たとえばUnixではこれは/dev/ttyS0のようになるだろう。MS WindowsではCOM1や\\.\COM10のようになるかもしれない(Lisp文字列ではバックスラッシュは2重にすること)。
speedはビット毎秒でのシリアルポートのスピード。一般的な値は9600。そのバッファーはTermモードになる。このバッファーで使用するコマンドについてはTerm Mode in The GNU Emacs Manualを参照のこと。モードラインメニューからスピードと設定を変更できる。
この関数はプロセスとバッファーを作成する。引数はキーワード/引数ペアーで指定する。以下は意味のあるキーワードのリストで、最初の2つ(portとspeed)は必須:
:port port
これはシリアルポートの名前。UnixやGNUシステムでは/dev/ttyS0のようなファイル名、WindowsではCOM1、COM9より高位のポートでは\\.\COM10のようになるかもしれない(Lisp文字列ではバックスラッシュは2重にすること)。
:speed speed
ビット毎秒でのシリアルポートのスピード。この関数はserial-process-configure
を呼び出すことによりスピードを操作する。この関数の更なる詳細については以降のドキュメントを参照のこと。
:name name
そのプロセスの名前。nameが与えられなければportがプロセス名の役目も同様に果たす。
:buffer buffer
そのプロセスに関連付けられたバッファー。値はバッファー、またはそれがバッファーの名前であるような文字列かもしれない。出力を処理するために出力ストリームやフィルター関数を指定しなければ、プロセス出力はそのバッファーの終端に出力される。bufferが与えられなければ、そのプロセスバッファーの名前は:name
キーワードから取得される。
:coding coding
codingはこのプロセスにたいする読み書きに使用されるコーディングシステムを指定する。codingがコンス(decoding
.
encoding)
なら読み取りにdecoding、書き込みにはencodingが使用される。指定されない場合のデフォルトはデータ自身から判断されるコーディングシステム。
:noquery query-flag
プロセスqueryフラグをquery-flagに初期化する。exit前の問い合わせを参照のこと。未指定の場合のフラグのデフォルトはnil
。
:stop bool
boolが非nil
ならstoppedの状態でプロセスを開始する。stopped状態ではシリアルプロセスは入力データを受け付けないが出力データの送信は可能。stopped状態のクリアーはcontinue-process
、セットはstop-process
で行う。
:filter filter
プロセスフィルターとしてfilterをインストールする。
:sentinel sentinel
プロセスセンチネルとしてsentinelをインストールする。
:plist plist
プロセスの初期plistとしてplistをインストールする。
:bytesize
:parity
:stopbits
:flowcontrol
これらはmake-serial-process
が呼び出すserial-process-configure
により処理される。
後の設定により変更され得るオリジナルの引数リストは関数process-contact
を通じて利用可能。
以下は例:
(make-serial-process :port "/dev/ttyS0" :speed 9600)
この関数はシリアルポート接続を設定する。引数はキーワード/引数ペアーで指定する。与えられない属性はそのプロセスのカレントの設定(関数process-contact
を通じて利用可能)から再初期化されるか、妥当なデフォルトにセットされる。以下の引数が定義されている:
:process process
:name name
:buffer buffer
:port port
設定するプロセスを識別するために、これらの引数のいずれかが与えられる。これらの引数が何も与えられなければカレントバッファーのプロセスが使用される。
:speed speed
ビット毎秒、別名ボーレート(baud
rate)によるシリアルポートのスピード。値には任意の数字が可能だが、ほとんどのシリアルポートは1200から115200の間の数少ない定義済みの値でのみ機能して、もっとも一般的な値は9600。speedがnil
なら、この関数は他のすべての引数を無視してそのポートを設定しない。これは接続を通じて送信された‘AT’コマンドでのみ設定可能な、Bluetooth/シリアル変換アダプターのような特殊なシリアルポートで有用かもしれない。speedにたいする値nil
はmake-serial-process
かserial-term
の呼び出しにより、すでにオープン済みの接続にたいしてのみ有効。
:bytesize bytesize
ビット/バイトでの数値で7か8を指定できる。bytesizeが与えられない、またはnil
の場合のデフォルトは8。
:parity parity
値にはnil
(パリティなし)、シンボルodd
(奇数パリティ)、シンボルeven
(偶数パリティ)を指定できる。parityが与えられない場合のデフォルトはパリティなし。
:stopbits stopbits
各バイトの送信を終了するために使用されるストップビットの数値。stopbitsには1か2が可能。stopbitsが与えられない、またはnil
の場合のデフォルトは1。
:flowcontrol flowcontrol
この接続にたいして使用するフロー制御のタイプでnil
(フロー制御を使用しない)、シンボルhw
(RTS/CTSハードウェアフロー制御)、シンボルsw
(XON/XOFFソフトウェアフロー制御)のいずれか。flowcontrolが与えられない場合のデフォルトはフロー制御なし。
シリアルポートの初期設定のためにmake-serial-process
は内部的にserial-process-configure
を呼び出す。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは通常はバイナリーのネットワークプロトコル用のバイト配列をpackやunpackする方法を説明します。以下の関数はバイト配列とalistとの間で相互に変換を行います。バイト配列はユニバイト文字列、または整数ベクターとして表現することができます。一方でalistはシンボルを固定サイズのオブジェクト、または再帰的な副alistのいずれかに関連付けます。このセクションで参照する関数を使用するためにはbindat
ライブラリーをロードしてください。
バイト配列からネストされたalistへの変換は逆方向への変換がシリアライズ化(serializing)またはpack化(packing)として呼ばれることから、非シリアル化【deserializing)またはunpack化(unpacking)として知られています。
36.20.1 データレイアウトの記述 | ||
36.20.2 バイトのunpackとpackのための関数 | unpack化とpack化を行う。 | |
36.20.3 バイトのunpackとpackの例 | bindat.elが行えることのサンプル。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
unpackとpackを制御するためにはデータレイアウト仕様(data layout specification)を記述します。これは名前付きかつタイプ付けされたフィールド(field)を記述する特別なネスト化リストです。これは処理する各フィールドの長さ、およびそれをpackおよびunpackする方法を制御します。わたしたちは名前が‘-bindat-spec’で終わる変数ではbindatの仕様を遵守します。この類の変数名は自動的にrisky(危険)だと認識されます。
フィールドのタイプ(type)はフィールドが表すオブジェクトのサイズ(バイト単位)、およびそれがマルチバイトフィールドならフィールがバイトオーダーされる方法を記述します。可能なオーダーはビッグエンディアン(big
endian。ネットワークバイトオーダーとも呼ばれる)、およびリトルエンディアン(little
endian)の2つです。たとえば数字#x23cd
(10進の9165)のビッグエンディアンは#x23
#xcd
の2バイト、リトルエンディアンは#xcd
#x23
になるでしょう。以下は可能なタイプの値です:
u8
byte
長さ1の符号なしタイプ。
u16
word
short
長さ2のネットワークバイトオーダーによる符号なし整数。
u24
長さ3のネットワークバイトオーダーによる符号なし整数。
u32
dword
long
長さ4のネットワークバイトオーダーによる符号なし整数。注意: これらの値はEmacsの整数の実装に制限されるだろう。
u16r
u24r
u32r
それぞれ長さ2、3、4のリトルエンディアンオーダーによる符号なし整数。
str len
長さlenの文字列。
strz len
長さlenの固定長フィールド内のNUL終端された文字列。
vec len [type]
タイプtype
(デフォルトはbyte)のlen要素のベクター。typeは上述した単純なタイプのいずれか、あるいは(vec
len [type])
という形式のリストによる別ベクターの指定。
ip
インターネットアドレスを表す4つのbyteのベクター。たとえばlocalhostは[127 0 0 1]
。
bits len
lenバイト内のセットされたビット位置のリスト。バイトはビッグエンディアンでビット位置は8 * len
- 1
で始まり0で終わるよう番号が付与される。たとえばbits 2
では、#x28
#x1c
は(2 3 4 11 13)
、#x1c
#x28
は(3 5 10 11
12)
にunpackされる。
(eval form)
formはフィールドがpackやunpackされた瞬間に評価されるLisp式。評価した結果は上記にリストしたタイプ使用のいずれかであること。
固定長フィールドでは長さlenがフィールド内のバイト数を指定する整数として与えられます。
フィールド長が固定でなければ通常は先行するフィールドの値に依存します。この場合には長さlenは後述のbindat-get-field
のフォーマット指定によりフィールド名(field
name)を指定するリスト(name ...)
、または式(eval form)
(formはフィールド長を指定する整数に評価されること)のいずれかで与えることもできます。
フィールド仕様は一般的に([name]
handler)
という形式をもち、nameはオプションです。紛らわしくなるのでタイプ仕様(上述)やハンドラー仕様(後述)で意味をもつシンボルの名前は使用しないでください。nameはシンボルまたは式(eval
form)
でもよく、この場合にはformはシンボルに評価される必要があります。
handlerはそのフィールドがpackやunpackされる方法を記述して、以下のいずれかを指定できます:
type
タイプ仕様typeに応じてこのフィールドのunpack/packを行う。
eval form
副作用のためだけにLisp式formを評価する。フィールド名が指定されたら値はそのフィールド名にバインドされる。
fill len
lenバイトをスキップする。pack化ではそれらを未変更のままとして、通常それらは0のままとなることを意味する。unpack化ではそれらが無視されることを意味する。
align len
lenバイトの次の倍数にスキップする。
struct spec-name
副仕様(sub-specification)としてspec-nameを処理する。これは別の構造体内にネストされる構造体を記述する。
union form (tag spec)…
Lisp式formを評価、それにマッチする最初のtagを探して、それに関連付けられたレイアウト仕様specを処理する。マッチングは以下の3つのいずれかで発生し得る:
(eval
expr)
という形式をもつ場合には、変数tag
を動的にformの値にバインドしてexprを評価する。結果が非nil
ならマッチを示す。
equal
ならマッチ。
t
なら無条件にマッチ。
repeat count field-specs…
field-specsを再帰的に順次処理した後に、最初のものから繰り返して、すべての仕様全体をcount回処理する。countはフィールド長と同じフォーマットを使用して与えられる。eval
フォームが使用された場合には1回だけ評価される。正しく処理されるためには、field-specs内の各仕様が名前を含まなければならない。
bindat仕様内で仕様される(eval
form)
フォームでは、評価の間にformはこれらの動的にバインドされた変数へのアクセスと更新が可能である。
last
最後に処理されたフィールドの値。
bindat-raw
バイト配列のデータ。
bindat-idx
unpack化/pack化にたいする、(bindat-raw
での)カレントインデックス。
struct
これまでにunpackされた構造化データ、またはpackされた構造体全体を含むalist。この構造体の特定のフィールドにアクセスするためにbindat-get-field
を使用できる。
count
index
repeat
ブロック内部では、これらは(countパラメーターで指定された)繰り返しの最大回数、および(0から数えた)カレント繰り返し回数を含む。count
を0にセットすることにより、カレントの繰り返し終了後に最内繰り返しブロックを終了する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以降のドキュメントではspecはデータレイアウト仕様、bindat-raw
はバイト配列、structはunpackされたフィールドデータを表すalistを参照します。
この関数はユニバイト文字列、またはバイト配列bindat-raw
のデータをspecに応じてunpackする。これは通常はバイト配列の先頭からunpack化を開始するが、bindat-idxが非nil
ならかわりに使用する0基準の開始位置を指定する。
値はそれぞれの要素がunpackされたフィールドを記述するalistかネストされたalist。
この関数はネストされたalistであるstructからフィールドのデータを選択する。structは通常はbindat-unpack
がリターンしたもの。nameが単一の引数に対応する場合にはトップレベルのフィールド値を抽出することを意味する。複数のname引数は副構造体を繰り返して照合することを指定する。整数の名前は配列のインデックスとして動作する。
たとえばnameが(a b 2
c)
なら、それはフィールドa
の副フィールドb
の3番目の要素内のフィールドc
(Cではstruct.a.b[2].c
に相当)を意味する。
packやunpackの処理をすることによりメモリー内でデータ構造が変化しても、そのデータの全フィールド長の合計バイト数であるトータル長(total length)は保たれます。この値は一般的に仕様またはalist単独では固有ではありません。そのかわりこれら両方の情報がこの計算に役立ちます。同様にunpackされる文字列や配列の長さは仕様の記述にしたがってデータのトータル長より長くなるかもしれません。
この関数はstruct内のデータのspecに応じたトータル長をリターンする。
この関数はalist
struct内のデータからspecに応じてpackされたバイト配列をリターンする。これは通常は先頭から充填された新たなバイト配列を作成する。しかしbindat-rawが非nil
なら、それはpack先として事前に割り当てられたユニバイト文字列かベクターを指定する。bindat-idxが非nil
ならbindat-raw
へpackする開始オフセットを指定する。
事前に割り当てる際にはout-of-rangeエラーを避けるために、(length
bindat-raw)
がトータル長またはそれ以上であることを確認すること。
インターネットアドレスのベクターipを通常のドット表記による文字列に変換する。
(bindat-ip-to-string [127 0 0 1]) ⇒ "127.0.0.1"
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はバイトにたいしてunpackおよびpackを行う完全な例です:
(require 'bindat) (defvar fcookie-index-spec '((:version u32) (:count u32) (:longest u32) (:shortest u32) (:flags u32) (:delim u8) (:ignored fill 3) (:offset repeat (:count) (:foo u32))) "fortuneクッキーのインデックスファイル内容") (defun fcookie (cookies &optional index) "ファイルCOOKIESからランダムなfortuneクッキーを表示する。 オプションの第2引数INDEXは関連付けられるインデックス ファイル名を指定し、デフォルトは\"COOKIES.dat\"。 バッファー\"*Fortune Cookie: BASENAME*\"内にクッキーを表示。 BASENAMEはディレクトリー部分を除いたCOOKIES" (interactive "fCookies file: ") (let* ((info (with-temp-buffer (insert-file-contents-literally (or index (concat cookies ".dat"))) (bindat-unpack fcookie-index-spec (buffer-string)))) (sel (random (bindat-get-field info :count))) (beg (cdar (bindat-get-field info :offset sel))) (end (or (cdar (bindat-get-field info :offset (1+ sel))) (nth 7 (file-attributes cookies))))) (switch-to-buffer (get-buffer-create (format "*Fortune Cookie: %s*" (file-name-nondirectory cookies)))) (erase-buffer) (insert-file-contents-literally cookies nil beg (- end 3)))) (defun fcookie-create-index (cookies &optional index delim) "ファイルCOOKIESをスキャンしてインデックスファイルに書き込む。 オプション引数INDEXは、インデックスファイル名を指定。デフォルトは\"COOKIES.dat\"。 オプション引数DELIMはユニバイト文字で、それがCOOKIES内 のある行で見つかったら、その行はエントリー間の境界を示す。" (interactive "fCookies file: ") (setq delim (or delim ?%)) (let ((delim-line (format "\n%c\n" delim)) (count 0) (max 0) min p q len offsets) (unless (= 3 (string-bytes delim-line)) (error "Delimiter cannot be represented in one byte")) (with-temp-buffer (insert-file-contents-literally cookies) (while (and (setq p (point)) (search-forward delim-line (point-max) t) (setq len (- (point) 3 p))) (setq count (1+ count) max (max max len) min (min (or min max) len) offsets (cons (1- p) offsets)))) (with-temp-buffer (set-buffer-multibyte nil) (insert (bindat-pack fcookie-index-spec `((:version . 2) (:count . ,count) (:longest . ,max) (:shortest . ,min) (:flags . 0) (:delim . ,delim) (:offset . ,(mapcar (lambda (o) (list (cons :foo o))) (nreverse offsets)))))) (let ((coding-system-for-write 'raw-text-unix)) (write-file (or index (concat cookies ".dat")))))))
以下は複雑な構造体を定義してunpackする例です。以下のようなCの構造体があるものとします:
struct header { unsigned long dest_ip; unsigned long src_ip; unsigned short dest_port; unsigned short src_port; }; struct data { unsigned char type; unsigned char opcode; unsigned short length; /* ネットワークバイトオーダー */ unsigned char id[8]; /* NUL終端文字列 */ unsigned char data[/* (length + 3) & ~3 */]; }; struct packet { struct header header; unsigned long counters[2]; /* リトルエンディアンオーダー */ unsigned char items; unsigned char filler[3]; struct data item[/* items */]; };
対応するデータレイアウト仕様が以下です:
(setq header-spec '((dest-ip ip) (src-ip ip) (dest-port u16) (src-port u16))) (setq data-spec '((type u8) (opcode u8) (length u16) ; ネットワークバイトオーダー (id strz 8) (data vec (length)) (align 4))) (setq packet-spec '((header struct header-spec) (counters vec 2 u32r) ; リトルエンディアンオーダー (items u8) (fill 3) (item repeat (items) (struct data-spec))))
バイナリーデータによる表現は:
(setq binary-data [ 192 168 1 100 192 168 1 101 01 28 21 32 160 134 1 0 5 1 0 0 2 0 0 0 2 3 0 5 ?A ?B ?C ?D ?E ?F 0 0 1 2 3 4 5 0 0 0 1 4 0 7 ?B ?C ?D ?E ?F ?G 0 0 6 7 8 9 10 11 12 0 ])
対応するデコードされた構造体は:
(setq decoded (bindat-unpack packet-spec binary-data)) ⇒ ((header (dest-ip . [192 168 1 100]) (src-ip . [192 168 1 101]) (dest-port . 284) (src-port . 5408)) (counters . [100000 261]) (items . 2) (item ((data . [1 2 3 4 5]) (id . "ABCDEF") (length . 5) (opcode . 3) (type . 2)) ((data . [6 7 8 9 10 11 12]) (id . "BCDEFG") (length . 7) (opcode . 4) (type . 1))))
以下はこの構造体からデータを取得する例です:
(bindat-get-field decoded 'item 1 'id) ⇒ "BCDEFG"
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このチャプターではEmacsによるユーザーへのプレゼンテーションとなる、表示に関連するいくつかの機能を説明します。
37.1 スクリーンのリフレッシュ | スクリーン上にあるすべてのもののクリアーと再描画。 | |
37.2 強制的な再表示 | 再描画の強制。 | |
37.3 切り詰め | 長いテキストの折り畳みと折り返し。 | |
37.4 エコーエリア | スクリーン最下部へのメッセージ表示。 | |
37.5 警告のレポート | ユーザーへの警告メッセージの表示。 | |
37.6 不可視のテキスト | バッファーのテキストの一部を隠す。 | |
37.7 選択的な表示 | バッファーのテキストの一部を隠す(旧来の方式)。 | |
37.8 一時的な表示 | 自動的に消える表示。 | |
37.9 オーバーレイ | オーバーレイを使用したバッファーの一部のハイライト。 | |
37.10 表示されるテキストのサイズ | 表示されたテキストの大きさ。 | |
37.11 行の高さ | 行の高さの制御。 | |
37.12 フェイス | テキスト文字のグラフィカルスタイル(フォント、カラー等)を定義するフェイス。 | |
37.13 フリンジ | ウィンドウフリンジの制御。 | |
37.14 スクロールバー | スクロールバーの制御。 | |
37.15 ウィンドウディバイダー | ウィンドウを視覚的に区別する。 | |
37.16 display プロパティ | 特別な表示機能の有効化。 | |
37.17 イメージ | Emacsバッファー内でのイメージ表示。 | |
37.18 Embedded Native Widgets | Emacsバッファー内でのネイティブウィジェットの表示。 | |
37.19 ボタン | Emacsバッファー内へのイメージ表示クリック可能ボタン追加。 | |
37.20 抽象的なディスプレー | オブジェクトコレクション用のEmacsウィジェット。 | |
37.21 カッコの点滅 | Emacsがマッチする開カッコを表示する方法。 | |
37.22 文字の表示 | Emacsがマッチする個々の文字を表示する方法。 | |
37.23 ビープ | ユーザーへの可聴シグナル。 | |
37.24 ウィンドウシステム | どのウィンドウシステムが使用されているか。 | |
37.25 Tooltips | Emacsでのツールチップの表示。 | |
37.26 双方向テキストの表示 | アラビア語やペルシア語のような双方向スクリプトの表示。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
関数redraw-frame
は与えられたフレーム(フレームを参照)のコンテンツ全体にたいしてクリアーと再描画を行います。これはスクリーンが壊れている(corrupted)場合に有用です。
この関数はフレームframeのクリアーと再表示を行う。frameが省略またはnilの場合のデフォルトは選択されたフレーム。
更に強力なのはredraw-display
です:
この関数はすべての可視なフレームのクリアーと再描画を行う。
Emacsではユーザー入力は再描画より優先されます。入力が可能なときにこれらの関数を呼び出すと、これらはすぐに再描画はしませんが、要求された再描画はすべての入力処理後に行われます。
テキスト端末では通常はEmacsのサスペントと再開によりスクリーンのリフレッシュも行われます。Emacsのようなディスプレイ指向のプログラムと通常のシーケンシャル表示のプログラムで、コンテンツを区別して記録する端末エミュレーターがいくつかあります。そのような端末を使用する場合には、おそらく再開時の再表示を抑制したいでしょう。
この変数はEmacsがサスペンドや再開された後にスクリーン全体を再描画するかどうかを制御する。非nil
なら再描画は不要、nil
なら再描画が必要であることを意味する。デフォルトはnil
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsは入力の待機時は常に再表示を試みます。以下の関数により実際に入力を待機することなく、Lispコードの中から即座に再表示を試みることを要求できます。
この関数は即座に再表示を試みる。オプション引数forceが非nil
の場合には、入力が保留中なら横取りされるかわりに強制的に再表示が行われる。
この関数は実際に再表示が試行されたならt
、それ以外はnil
をリターンする。t
という値は再表示の試行が完了したことを意味しない。新たに到着した入力に横取りされた可能性がある。
redisplay
が即座に再表示を試みたとしても、Emacsがフレーム(複数可)のどの部分を再表示するか決定する方法が変更されるわけではありません。それとは対照的に以下の関数は特定のウィンドウを、(あたかもコンテンツが完全に変更されたかのように)保留中の再表示処理に追加します。しかし再描画を即座には試みません。
この関数はEmacsが次に再表示を行う際にいくつか、あるいはすべてのウィンドウが更新されるよう強制する。objectがウィンドウならそのウィンドウ、バッファーやバッファー名ならそのバッファーを表示するすべてのウィンドウ、nil
(または省略)ならすべてのウィンドウが更新される。
この関数は即座に再表示を行わない。再表示はEmacsが入力を待機時、または関数redisplay
呼び出し時に行われる。
再表示の直前に実行される関数。これは再表示されるウィンドウセットを単一の引数として呼び出される。ウィンドウセットは選択されたウィンドウを意味するnil
、すべてのウィンドウを意味するt
を指定できる。
このフックは再表示の直前に実行される。これは再表示されようとするウィンドウそれぞれにたいして、そのウィンドウに表示されているバッファーをcurrent-buffer
にセットして1回呼び出される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはテキスト行がウィンドウ右端を超過する際には、その行を継続(continue)させる(次のスクリーン行へwrap、すなわち折り返す)か、あるいはその行を切り詰め(truncate)て表示(その行をスクリーン行の1行に制限)することができます。長いテキスト行を表示するために使用される追加のスクリーン行は継続(continuation)行と呼ばれます。継続はフィルとは異なります。継続はバッファーのコンテンツ内ではなくスクリーン上でのみ発生して、単語境界ではなく正確に右マージンで行をブレークします。fillを参照してください。
グラフィカルなディスプレイでは切り詰めと継続はウィンドウフリンジ内の小さな矢印イメージで示されます(フリンジを参照)。テキスト端末では切り詰めはそのウィンドウの最右列の‘$’、折り返しは最右列の‘\’で示されます(ディスプレイテーブルでこれを行うための代替え文字を指定できる。ディスプレーテーブルを参照)。
このバッファーローカル変数が非nil
ならウィンドウ右端を超過する行は切り詰められて、それ以外なら継続される。特別な例外として部分幅(partial-width)ウィンドウ(フレーム全体の幅を占有しないウィンドウ)では変数truncate-partial-width-windows
が優先される。
この変数は部分幅(partial-width)ウィンドウ内の行の切り詰めを制御する。部分幅ウィンドウとはフレーム全体の幅を占有しないウィンドウ(ウィンドウの分割を参照)。値がnil
なら行の切り詰めは変数truncate-lines
(上記参照)により決定される。値が整数nの場合には、部分幅ウィンドウの列数がnより小さければtruncate-lines
の値とは無関係に行は切り詰められて、部分幅ウィンドウの列数がn以上なら行の切り詰めはtruncate-lines
により決定される。それ以外の非nil
値ではtruncate-lines
の値とは無関係にすべての部分幅ウィンドウで行は切り詰められる。
ウィンドウ内で水平スクロール(水平スクロールを参照)を使用中は切り詰めが強制されます。
このバッファーローカル変数が非nil
なら、それはEmacsが各継続行の先頭に表示する折り返しプレフィックス(wrap
prefix)を定義する(行を切り詰めている場合にはwrap-prefix
は使用されない)。この値は文字列、またはイメージ(その他のディスプレー仕様を参照)やディスプレイプロパティ:width
や:align-to
で指定されるような伸長された空白文字を指定できる(スペースの指定を参照)。値はテキストプロパティdisplay
と同じ方法で解釈される。display
プロパティを参照のこと。
折り返しプレフィックスはテキストプロパティかオーバーレイプロパティwrap-prefix
を使用することにより、テキストのリージョンにたいして指定することもできる。これはwrap-prefix
変数より優先される。特殊な意味をもつプロパティを参照のこと。
このバッファーローカル変数が非nil
なら、それはEmacsがすべての非継続行の先頭に表示する行プレフィックス(line
prefix)を定義する。この値は文字列、イメージ(その他のディスプレー仕様を参照)、またはディスプレイプロパティ:width
や:align-to
で指定されるような伸長された空白文字を指定できる(スペースの指定を参照)。値はテキストプロパティdisplay
と同じ方法で解釈される。display
プロパティを参照のこと。
行プレフィックスはテキストプロパティまたはオーバーレイプロパティline-prefix
を使用することにより、テキストのリージョンにたいして指定することもできる。これはline-prefix
変数より優先される。特殊な意味をもつプロパティを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
エコーエリア(echo
area)はエラーメッセージ(エラー)やmessage
プリミティブで作成されたメッセージの表示、およびキーストロークをエコーするために使用されます。(アクティブ時には)ミニバッファーがスクリーン上のエコーエリアと同じ場所に表示されるという事実にも関わらずエコーエリアはミニバッファーと同じではありません。The Minibuffer in The GNU Emacs Manualを参照してください。
このセクションに記述された関数とは別に、出力ストリームとしてt
を指定することによりエコーエリアにLispオブジェクトをプリントできます。出力ストリームを参照してください。
37.4.1 エコーエリアへのメッセージの表示 | エコーエリア内に明示的にテキストを表示する。 | |
37.4.2 処理の進捗レポート | 長時間の処理の進行状況をユーザーに知らせる。 | |
37.4.3 *Messages*へのメッセージのロギング | ユーザー用にログされるエコーエリアメッセージ。 | |
37.4.4 エコーエリアのカスタマイズ | エコーエリアの制御。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではエコーエリア内にメッセージを表示する標準的な関数を説明します。
この関数はエコーエリア内にメッセージを表示する。format-message
関数(文字列のフォーマットを参照)の場合と同じようにformat-stringはフォーマット文字列、argumentsはそのフォーマット仕様にたいするオブジェクトである。フォーマットされた結果文字列はエコーエリア内に表示される。それにface
テキストプロパティが含まれる場合には指定されたフェイスにより表示される(フェイスを参照)。この文字列は*Messages*バッファーにも追加されるがテキストプロパティは含まれない(*Messages*へのメッセージのロギングを参照)。
変数text-quoting-style
は何のクォートを生成するかを制御する。ドキュメント内でのキーバインディングの置き換えを参照のこと。"Missing `%s'"のようなgrave
accentとapostropheをもつフォーマットを使用する呼び出しは、典型的には"Missing ‘foo’のようにマッチするcurved
quoをもつメッセージを生成する。対照的に"Missing
'%s'"のようにapostropheだけをもつフォーマットを使用した呼び出しでは、英語では普通は使用されないclosing curved
quoteだけをもつ"Missing ’foo’"のようなメッセージが生成される。
バッチモードでは後に改行が付加されたメッセージが標準エラーストリームにプリントされる。
inhibit-message
が非nil
のときはエコーエリアにはメッセージを何も表示せずに‘*Messages*’へのロギングだけとなる。
format-stringがnil
か空文字列なら、message
はエコーエリアをクリアーする。エコーエリアが自動的に拡張されていたら、これにより通常のサイズに復元される。ミニバッファーがアクティブなら、これによりスクリーン上に即座にミニバッファーのコンテンツが復元される。
(message "Reverting `%s'..." (buffer-name)) -| Reverting ‘subr.el’... ⇒ "Reverting ‘subr.el’..."
---------- Echo Area ---------- Reverting ‘subr.el’... ---------- Echo Area ----------
エコーエリアやポップバッファー内に自動的にメッセージを表示するには、そのサイズに応じてdisplay-message-or-buffer
(以下参照)を使用する。
警告: 逐語的なメッセージとして独自の文字列を使用したければ、単に(message
string)
と記述してはならない。stringに‘%’、‘`’、‘'’が含まれていると望まぬ結果に再フォーマットされるかもしれない。かわりに(message
"%s" string)
を使用すること。
この変数が非nil
なら、message
および関連する関数はメッセージの表示にエコーエリアを使用しない。
この構文はbody実行の間にエコーエリア内にメッセージを一時的に表示する。これはmessageを表示してbodyを実行して、それからエコーエリアの前のコンテンツをリストアするとともにbodyの最後のフォームの値をリターンする。
この関数はmessage
と同様にメッセージを表示するが、エコーエリアではなくダイアログボックスにメッセージを表示するかもしれない。この関数があるコマンド内からマウスを使用して呼び出されると
— より正確にはlast-nonmenu-event
(コマンドループからの情報を参照)がnil
かリストならメッセージの表示にダイアログボックスかポップアップメニュー、それ以外ならエコーエリアを使用する(これはy-or-n-p
が同様の決定を行う際に使用する条件と同じ。Yes-or-Noによる問い合わせを参照)。
呼び出しの前後でlast-nonmenu-event
を適切な値にバインドすることによりエコーエリアでのマウスの使用を強制できる。
この関数はmessage
と同様にメッセージを表示するが、利用可能なら常にダイアログボックス(かポップアップメニュー)を使用する。端末がサポートしないためにダイアログボックスやポップアップメニューが使用できなければ、message-box
はmessage
と同様にエコーエリアを使用する。
この関数はメッセージmessageを表示する。messageには文字列かバッファーを指定できる。これがmax-mini-window-height
で定義されるエコーエリアの最大高さより小さければ、message
を使用してエコーエリアに表示される。それ以外ならメッセージを表示するためにdisplay-buffer
はポップアップバッファーを使用する。
エコーエリアに表示したメッセージ、またはポップアップバッファー使用時はその表示に使用したウィンドウをリターンする。
messageが文字列ならオプション引数buffer-nameはポップアップバッファー使用時にメッセージ表示に使用するバッファー名(デフォルトは*Message*)。messageが文字列でエコーエリアに表示されていれば、いずれにせよコンテンツをバッファーに挿入するかどうかは指定されない。
オプション引数actionとframeはdisplay-buffer
の場合と同様に、バッファーが表示されている場合のみ使用される。
この関数はエコーエリア内にカレントで表示されているメッセージ、またはそれが存在しなければnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
処理の完了まで暫く時間を要するかもしれない際には、進行状況についてユーザーに通知するべきです。これによりユーザーが残り時間を予測するとともに、Emacsがhungしているのではなく処理中であることを明確に確認できます。プログレスリポーター(progress reporter: 進行状況リポーター)を使用するのが、これを行う便利な方法です。
以下は何も有用なことを行わない実行可能な例です:
(let ((progress-reporter (make-progress-reporter "Collecting mana for Emacs..." 0 500))) (dotimes (k 500) (sit-for 0.01) (progress-reporter-update progress-reporter k)) (progress-reporter-done progress-reporter))
この関数は以下に挙げる他の関数の引数として使用されることになるプログレスリポーターオブジェクトを作成してリターンする。これはプログレスリポーターを高速にするように、可能なかぎり多くのデータを事前に計算するというアイデアが元となっている。
この後にプログレスリポーターを使用する際には、進行状況のパーセンテージを後に付加してmessageが表示されるだろう。messageは単なる文字列として扱われる。たとえばファイル名に依存させる必要があるなら、この関数の呼び出し前にformat-message
を使えばよい。
引数min-valueとmax-valueは処理の開始と終了を意味する数値であること。たとえばバッファーをスキャンする処理なら、これらをそれぞれpoint-min
とpoint-max
にセットするべきだろう。max-valueはmin-valueより大であること。
かわりにmin-valueとmax-valueをnil
にセットすることができる。この場合にはプログレスリポーターは進行状況のパーセンテージを報告しない。かわりにプログレスリポーターを更新するたびに刻み(notch)を回転する“スピナー(spinner)”を表示する。
min-valueとmax-valueが数値なら、進行状況の初期の数値を与える引数current-valueを与えることができる。省略時のデフォルトはmin-value。
残りの引数はエコーエリアの更新レートを制御する。プログレスリポーターは次のメッセージを表示する前に、その処理が少なくともmin-changeパーセントより多く完了するまで待機する。デフォルトは1パーセント。min-timeは連続するプリントの間に空ける最小時間をミリ秒単位で指定する(いくつかのオペレーティングシステムではプログレスリポーターは秒の少数部をさまざまな精度で処理するかもしれない)。
この関数はprogress-reporter-update
を呼び出すので、最初のメッセージは即座にプリントされる。
この関数は操作の進行状況報告に関する主要な機能を担う。これはreporterのメッセージと、その後にvalueにより決定された進行状況のパーセンテージを表示する。パーセンテージが0、または引数min-changeとmin-timeに比べて十分0に近ければ出力は省略される。
reporterはmake-progress-reporter
呼び出しがリターンした結果でなければならない。valueは処理のカレント状況を指定して、make-progress-reporter
に渡されたmin-valueとmax-valueの間(両端を含む)でなければならない。たとえばバッファーのスキャンにおいては、valueはpoint
び呼び出し結果であるべきだろう。
この関数はmake-progress-reporter
に渡されたmin-changeとmin-timeにしたがい、毎回の呼び出しで新たなメッセージを出力しない。したがってこれは非常に高速であり、通常はこれを呼び出す回数を減らすことを試みるべきではない。結果として生じるオーバーヘッドは、あなたの努力をほぼ否定するだろう。
この関数はprogress-reporter-update
と同様だが、これは無条件にメッセージをエコーエリアにプリントする点が異なる。
最初の2つの引数はprogress-reporter-update
の場合と同じ意味をもつ。オプションのnew-messageでreporterのメッセージを変更できる。この関数は常にエコーエリアを更新するので、そのような変更は即座にユーザーに示されるだろう。
この関数は処理の完了時に呼び出されること。これはエコーエリア内に単語‘done’を付加したreporterのメッセージを表示する。
progress-reporter-update
に‘100%’とプリントさせようとせずに、常にこの関数を呼び出すこと。まずこの関数は決してそれをプリントしないだろうし、これが発生しないために多くの正当な理由がある。次に‘done’はより自明である。
これはdotimes
と同じ方法で機能するが、上述の関数を使用してループ進行状況(loop
progress)の報告も行う便利なマクロである。これによりタイプ量を幾分節約できる。
以下の方法でこのマクロを使用することにより、このセクション冒頭の例を書き換えることができる:
(dotimes-with-progress-reporter (k 500) "Collecting some mana for Emacs..." (sit-for 0.01))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
エコーエリア内に表示されるほとんどすべてのメッセージは、ユーザーが後で参照できるように*Messages*バッファー内にも記録されます。これにはmessage
により出力されたメッセージも含まれます。デフォルトではこのバッファーは読み取り専用でメジャーモードmessages-buffer-mode
を使用します。ユーザーによる*Messages*バッファーのkillを妨げるものは何もありませんが、次回のメッセージ表示でバッファーは再作成されます。*Messages*バッファーに直接アクセスする必要があり、それが確実に存在するようにしたいLispコードは、すべて関数messages-buffer
を使用するべきです。
この関数は*Messages*バッファーをリターンする。バッファーが存在しなければ作成してバッファーをmessages-buffer-mode
に切り替える。
この変数は*Messages*バッファー内に保持するべき行数を指定する。値t
は保持すべき行数に制限がないことを意味して、値nil
はメッセージのロギングを完全に無効にする。以下はメッセージを表示して、それがロギングされることを防ぐ例:
(let (message-log-max) (message …))
*Messages*にたいするユーザーの利便性を向上させるために、ロギング機能は連続する同じメッセージを結合します。さらに2つのケースのために連続する関連メッセージの結合も行います。2つのケースとは応答を後にともなう質問(question followed by answer)、および一連のプログレスメッセージ(series of progress messages)です。
応答を後にともなう質問(question followed by an
answer)とは、1つ目が‘question’、2つ目が‘question...answer’のようにy-or-n-p
が生成するような2つのメッセージをもつ応答です。1つ目のメッセージは2つ目のメッセージ以上の追加情報を伝えないので、2つ目のメッセージをロギングして1つ目のメッセージは破棄します。
一連のプログレスメッセージ(series of progress
messages)は、make-progress-reporter
が生成するような連続するメッセージをもちます。これらは‘base...how-far’のような形式であり、how-farは毎回異なりますがbaseは常に同じです。このシリーズ内の各メッセージのロギングでは、そのメッセージが前のメッセージと連続していれば前のメッセージを破棄します。
関数make-progress-reporter
とy-or-n-p
は、メッセージログ結合機能をアクティブにするために何ら特別なことを行う必要はありません。これは‘...’で終わる共通のプレフィックスを共有する連続する2つのメッセージをログする際には常にこの処理を行います。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の変数はエコーエリアが機能する方法の詳細を制御します。
この変数はエコーエリア内にメッセージ表示時にカーソルを表示する場所を制御する。これが非nil
ならカーソルはメッセージの終端、それ以外ならカーソルはエコーエリア内ではなくポイント位置に表示される。
この値は通常はnil
。Lispプログラムは短時間の間、これをt
にバインドする。
このノーマルフックは(message nil)
、または別の何らかの理由によりエコーエリアが作成されると常に実行される。
この変数はコマンド文字をエコーする前に、どれだけの時間を待機するかを決定する。この値は数字でなければならず、エコー前に待機する秒数を指定する。ユーザーが(C-xのような)プレフィックスキーをタイプしてから、継続してタイプを継続するのをこの秒数遅延した場合、エコーエリア内にそのプレフィックスキーがエコーされる(あるキーシーケンスで一度エコーが開始されると、同一のキーシーケンス内の後続するすべての文字は即座にエコーされる)。
値が0ならコマンド入力はエコーされない。
長いメッセージの表示により、そのメッセージ全体を表示するために、通常はエコーエリアはリサイズされる。しかし変数message-truncate-lines
が非nil
なら、エコーエリアをリサイズせずエコーエリアに収まるようメッセージは切り詰められる。
ミニバッファーウィンドウのリサイズの最大高さを指定する変数max-mini-window-height
はエコーエリアにも適用される(エコーエリアは真にミニバッファーウィンドウの特殊な使い方である。ミニバッファー、その他の事項を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
警告(warnings)とはプログラムがユーザーにたいして問題の可能性を知らせるが、実行は継続するための機能です。
37.5.1 警告の基礎 | 警告の概念と報告するための関数。 | |
37.5.2 警告のための変数 | プログラムが警告をカスタマイズするためにバインドする変数。 | |
37.5.3 警告のためのオプション | ユーザーが警告の表示を制御するためにセットする変数。 | |
37.5.4 遅延された警告 | コマンド終了まで警告を延期する。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
すべての警告は、ユーザーに問題を説明するためのテキストのメッセージと、重大レベル(severity level)をもっています。重大レベルはシンボルです。以下は可能性のある重大レベルとその意味を、重大度の降順でリストしたものです:
:emergency
直ちに対処しなければEmacs処理が間もなく深刻に害される問題。
:error
本質的に悪いデータや状況のリポート。
:warning
本質的に悪くはないが、可能性のある問題を励起する恐れのあるデータや状況のリポート。
:debug
デバッグ中なら有用かもしれない情報のリポート。
あなたのプログラムが無効な入力データに遭遇した際には、error
呼び出しによるLispエラーのシグナルするか、または重大度:error
の警告をリポートすることができます。Lispエラーのシグナルはもっとも簡単に行えることですが、それはプログラムが処理を継続できないことを意味します。間違ったデータでも処理を継続するための方法を実装するためにトラブルを受け取めたい場合には、その問題をユーザーに知らせるために重大度:error
の警告をリポートするのが正しい方法です。たとえばEmacs
Lispバイトコンパイラーはこの方法によりエラーを報告して、他の関数のコンパイルを継続できます(プログラムがLispエラーをシグナルしてcondition-case
でhandleしたならユーザーがそのエラーを確認することはないだろう。これは警告としてリポートすることによりユーザーにメッセージを示すことができる)。
クラス分けのために警告にはそれぞれ警告タイプ(warning
type)があります。このタイプはシンボルのリストです。最初のシンボルはそのプログラムのユーザーオプションとして使用するカスタムグループであるべきです。たとえばバイトコンパイラーの警告は警告タイプ(bytecomp)
を使用します。もし望むなら、このリスト内で更にシンボルを使用することにより警告をサブカテゴリー化することもできます。
この関数はメッセージとしてmessage、警告タイプとしてtypeを使用して警告をリポートする。levelは重大レベルであること。デフォルトは:warning
。
buffer-nameが非nil
なら、それは警告をロギングするためのバッファー名を指定する。デフォルトは*Warnings*。
この関数は*Warnings*バッファー内のメッセージとして(format-message message
args...)
の値を使用して警告をリポートする。他の点ではこれはdisplay-warning
と同じ。
この関数はメッセージとして(format-message message
args...)
の値、タイプとして(emacs)
、重大レベルとして:warning
を使用して警告をリポートする。これは互換性のためだけに存在する。固有な警告タイプを指定するべきであり、この関数の使用は推奨しない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクション内で説明する変数をバインドすることにより、プログラムは警告が表示される方法をカスタマイズできます。
このリストは警告の重大レベルの意味と重大度の順序を定義する。それぞれの要素は1つの重大レベルを定義して、それらを重大度の降順で配置した。
各要素は(level string
function)
という形式をもち、levelはその要素が定義する重大レベル。stringはそのレベルのテキストによる説明。stringは警告タイプ情報の配置箇所の指定に‘%s’を使用するか、さもなくばその情報を含まぬよう‘%s’を省略できる。
オプションのfunctionが非nil
なら、これはユーザーの注目を得るために引数なしで呼び出される関数であること。
通常はこの変数の値を変更しないこと。
値が非nil
なら、それは警告用にプレフィックスを生成する関数であること。プログラムはこの変数を適切な関数にバインドできる。display-warning
はwarningsバッファーがカレントの状態でこの関数を呼び出して、関数はそのバッファーにテキストを挿入できる。そのテキストが警告メッセージの先頭になる。
この関数は重大レベル、およびwarning-levels
内でのその重大レベルのエントリーという2つの引数で呼び出される。これはエントリーとして使用するためのリストをリターンすること(この値はwarning-levels
の実際のメンバーである必要はない)。この値を構築することにより関数はその警告の重大レベルを変更したり、与えられた重大レベルにたいして異なる処理を指定することができる。
この変数の値がnil
なら呼び出される関数は存在しない。
プログラムは次の警告がシリーズの開始であることを告げるために、この変数をt
にバインドできる。複数の警告がシリーズを形成するということは、それぞれの警告にたいしてポイントが維持されるように移動して、最後の警告にポイントが表示されるのではなくシリーズの最初の警告にポイントを残すことを意味する。このシリーズは、そのローカルバインドが非バインドされてwarning-series
が再びnil
になったときに終了する。
この値は関数定義をもつシンボルでもよい。これは次の警告によりwarningsバッファーがカレントの状態で、引数なしでその関数が呼び出されることを除きt
と等価。この関数は警告シリーズのヘッダーの役目をもつであろうテキストを挿入できる。
あるシリーズが開始されると、その値はwarningsバッファー内でシリーズ開始となるバッファー位置を指すマーカーとなる。
この変数の通常の値はnil
で、これはそれぞれの警告を個別に処理することを意味する。
この変数が非nil
なら、それは各警告テキストのフィルに使用するフィルプレフィックスを指定する。
この変数は警告メッセージ内の警告タイプを表示するためのフォーマットを指定する。この方法でフォーマットされたタイプは、warning-levels
内のエントリー内の文字列制御下にあるメッセージに含まれることになる。デフォルト値は"
(%s)"
。これを""
にバインドすると警告タイプはまったく表示されなくなる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の変数は何が発生したときにLispプログラムが警告をリポートするかをユーザーが制御するために使用されます。
このユーザーオプションはユーザーにたいして即座に表示されるべき最小の重大レベルを指定する。デフォルトは:warning
であり、これは:debug
警告を除くすべての警告が即座に表示されることを意味する。
このユーザーオプションはwarningsバッファー内にログされるべき最小の重大レベルを指定する。デフォルトは:warning
であり、これは:debug
警告を除くすべての警告がログされることを意味する。
このリストはユーザーにたいしてどの警告タイプを即座に表示するべきではないかを指定する。このリスト内の各要素はシンボルのリストであること。それの要素が警告タイプ内の最初の要素にマッチしたら警告は即座に表示されない。
このリストはユーザーにたいしてどの警告タイプがwarningsバッファーにログされるべきではないかを指定する。このリスト内の各要素はシンボルのリストであること。それの要素が警告タイプ内の最初の数要素にマッチしたら警告はログされない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コマンド実行中には警告の表示を避けてコマンドの終わりでのみ警告を表示したいことがあるかもしれません。これは変数delayed-warnings-list
により行うことができます。
この変数の値はカレントのコマンド完了後に表示される警告のリスト。各要素は以下のようなリストでなければならない:
(type message [level [buffer-name]])
これらはdisplay-warning
の引数リストと同じ形式、同じ意味である(警告の基礎を参照)。post-command-hook
(コマンドループの概要を参照)の実行直後に、Emacsのコマンドループはこの変数で指定されたすべての警告を表示してから変数をnil
にリセットする。
遅延警告メカニズムをよりカスタマイズする必要があるプログラムは変数delayed-warnings-hook
を変更することができます:
これは遅延警告を処理して表示するために、post-command-hook
の後にEmacsコマンドループが実行するノーマルフック。
デフォルト値は2つの関数からなるリスト:
(collapse-delayed-warnings display-delayed-warnings)
関数collapse-delayed-warnings
はdelayed-warnings-list
から重複するエントリーを削除する。関数display-delayed-warnings
はdelayed-warnings-list
内の各要素にたいして順次display-warning
を呼び出してから、delayed-warnings-list
をnil
にセットする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
invisible
プロパティにより、スクリーン上に表示されないように文字を不可視(invisible)にすることができます。これはテキストプロパティ(テキストのプロパティを参照)、またはオーバーレイプロパティ(オーバーレイを参照)のいずれかで行うことができます。カーソル移動もこれらの文字を部分的に無視します。あるコマンドの後に不可視テキスト範囲内にポイントがあることをコマンドループが検知した場合には、コマンドループはポイントをそのテキストの別サイドへ再配置します。
もっともシンプルなケースでは、非nil
のinvisible
プロパティにより文字は不可視になります。これがデフォルトのケースであり、もしbuffer-invisibility-spec
のデフォルト値を変更したくない場合には、これがinvisible
プロパティを機能させる方法です。自身でbuffer-invisibility-spec
をセットする予定がなければ、invisible
プロパティの値として通常はt
を使用するべきです。
より一般的にはどのinvisible
の値がテキストを不可視にするかを制御するために変数buffer-invisibility-spec
を使用できます。テキストにたいして異なるinvisible
の値を与えることにより、事前に別のサブセットへテキストをクラス分けした後にbuffer-invisibility-spec
の値を変更して、さまざまなサブセットを可視や不可視にすることができます。
特にデータベース内のエントリーのリストを表示するプログラム内では、buffer-invisibility-spec
による可視性の制御は有用です。これによりデータベース内の一部だけを閲覧するフィルターコマンドを簡便に実装することが可能になります。この変数をセットするのは非常に高速であり、バッファー内のすべてのテキストにたいしてプロパティが変更されたかスキャンするよりはるかに高速です。
この変数はどの種類のinvisible
プロパティが実際に文字を不可視にするかを指定する。この変数はセットすることによりバッファーローカルになる。
t
invisible
プロパティが非nil
ならその文字は不可視になる。これがデフォルト。
このリスト内の各要素は不可視性の条件を指定する。ある文字のinvisible
プロパティがこれらの条件のいずれかに適合したら、その文字は不可視になる。このリストは2種類の要素をもつことができる:
atom
invisible
プロパティの値がatom、またはatomをメンバーにもつリストならその文字は不可視になる。比較はeq
により行われる。
(atom . t)
invisible
プロパティの値がatom、またはatomをメンバーにもつリストならその文字は不可視になる。比較はeq
により行われる。さらにそのような文字シーケンスは省略記号(ellipsis)として表示される。
特にbuffer-invisibility-spec
への要素の追加と削除のために2つの関数が提供されています。
この関数は、buffer-invisibility-spec
に要素elementを追加する。buffer-invisibility-spec
がt
なら、これはリスト(t)
に変更されてinvisible
プロパティがt
のテキストは不可視のまま留まる。
この関数はbuffer-invisibility-spec
から要素elementを削除する。リスト内にelementがなければ何も行わない。
buffer-invisibility-spec
を使用するための規約として、メジャーモードはbuffer-invisibility-spec
の要素、およびinvisible
プロパティの値として自身のモード名を使用することになっている。
;; 省略記号を表示したければ: (add-to-invisibility-spec '(my-symbol . t)) ;; 表示したくなければ: (add-to-invisibility-spec 'my-symbol) (overlay-put (make-overlay beginning end) 'invisible 'my-symbol) ;; 不可視状態が終わったら: (remove-from-invisibility-spec '(my-symbol . t)) ;; または各々を: (remove-from-invisibility-spec 'my-symbol)
以下の関数を使用することにより不可視性をチェックできます:
pos-or-propがマーカーか数字の場合には、その位置のテキストが不可視ならこの関数は非nil
をリターンする。
pos-or-propが別の類のLispオブジェクトなら、テキストプロパティかオーバーレイプロパティとして可能な値を意味すると解釈される。この場合にはbuffer-invisibility-spec
のカレント値にもとづき、もしその値がテキストを不可視とするようならこの関数は非nil
をリターンする。
テキストを操作したりポイントを移動する関数は、通常はそのテキストが不可視かどうかに注意を払わずに、可視と不可視のテキストを同様に処理します。next-line
やprevious-line
のようなユーザーレベルの行移動関数はline-move-ignore-invisible
が非nil
(デフォルト)なら不可視な改行を無視します。これらの関数は不可視な改行がそのバッファーに存在しないかのように振る舞いますが、それはそう振る舞うように明示的にプログラムされているからです。
あるコマンドが不可視テキストの境界内側のポイントで終了した場合には、メイン編集ループはその不可視テキストの両端のうちのいずれかにポイントを再配置します。そのコマンドの移動関数の全体的な方向と同じになるようにEmacsが再配置の方向を決定します。これに疑問がある場合には、挿入された文字がinvisible
プロパティを継承しないような位置を優先してください。加えてそのテキストが省略記号で置換されずに、コマンドが不可視テキスト内への移動のみを行う場合には、ポイントを1文字余計に移動して目に見えるようカーソルを移動することにより、そのコマンドの移動を反映するよう試みます。
したがってコマンドが(通常のstickinessをもつ)不可視範囲に後方へとポイントを移動すると、Emacsはポイントをその範囲の先頭に後方へと移動します。コマンドが不可視範囲へ前方にポイントを移動した場合には、Emacsは不可視テキストの前にある最初の可視文字に前方へとポイントを移動して、その後さらに前方へ1文字余計に移動します。
これら不可視テキスト中間で終了するポイントにたいするこれらの調整(adjustments)は、disable-point-adjustment
を非nil
にセットすることにより無効にできます。コマンド後のポイントの調整を参照してください。
インクリメンタル検索はマッチが不可視テキストを含む場合には、一時的および/または永続的に不可視オーバーレイを可視にすることができます。これを有効にするためには、そのオーバーレイが非nil
のisearch-open-invisible
プロパティをもつ必要があります。プロパティの値は、そのオーバーレイを引数として呼び出される関数であるべきです。その関数はオーバーレイを永続的に可視にする必要があります。これは検索からのexit時にマッチがそのオーバーレイに重なるときに使用されます。
検索の間にそのようなオーバーレイのinvisible、およびintangibleプロパティを一時的に変更することによりオーバーレイは一時的に可視にされます。特定のオーバーレイにたいして異なる方法でこれを行いたいなら、それをisearch-open-invisible-temporary
プロパティ(関数)に与えてください。その関数は2つの引数により呼び出されます。1つ目はそのオーバーレイ、2つ目はnil
ならオーバーレイを可視、t
なら再び不可視にします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
選択的表示(selective display)とはスクリーン上で特定の行を隠蔽する関連する機能ペアーを指します。
1つ目の変種は明示的な選択的表示であり、これはLispプログラム内で使用するようにデザインされています。これはテキスト変更により、どの行を隠すかを制御します。この種の隠蔽は現在では時代遅れです。かわりにinvisible
プロパティで同じ効果を得ることができます(不可視のテキストを参照)。
2つ目の変種はインデントにもとづいて隠す行の選択を自動的に行います。この変種はユーザーレベルの機能としてデザインされています。
選択的表示を明示的に制御する方法では改行(control-j)を復帰(control-m)に置換します。これにより以前は行末に改行があった行は隠蔽されます。厳密に言うと改行だけが行を分離できるので、これはもはや一時的には行ではなく前の行の一部です。
選択的表示は編集コマンドに直接影響を与えません。たとえばC-f
(forward-char
)は隠蔽された行へと気軽にポイントを移動します。しかし復帰文字による改行文字の置換は、いくつかの編集コマンドに影響を与えます。たとえばnext-line
は改行だけを検索するために、隠蔽された行をスキップします。選択的表示を使用するモードは改行を考慮するコマンドを定義したり、テキストのどの部分を隠すか制御することもできます。
選択的表示されたバッファーをファイルに書き込む際には、control-mはすべて改行として出力されます。これはファイル内のテキストを読み取る際には、すべて問題なく隠蔽されずに表示されることを意味します。選択的表示はEmacs内でのみ顕在する効果です。
このバッファーローカル変数は選択的表示を有効にする。これは行、または行の一部を隠すことができることを意味する。
selective-display
の値がt
なら、文字control-mが隠蔽されたテキストの開始をマークする。control-mと後続する行の残りは表示されない。これは明示的な選択的表示である。
selective-display
の値が正の整数なら、それより多くの列によるインデントで始まる行は表示されない。
バッファーの一部が隠蔽されている際には、垂直移動コマンドはあたかもその部分を存在しないかのように処理して、1回のnext-line
コマンドで任意の行数の隠蔽された行をスキップできる。しかし(forward-char
のような)文字移動コマンドは隠蔽された部分をスキップせずに、(注意すれば)隠蔽された部分にたいしてテキストの挿入と削除が可能である。
以下の例ではselective-display
の値の変更によるバッファーfoo
の外観表示を示す。このバッファーのコンテンツは変更されない。
(setq selective-display nil) ⇒ nil ---------- Buffer: foo ---------- 1 on this column 2on this column 3n this column 3n this column 2on this column 1 on this column ---------- Buffer: foo ----------
(setq selective-display 2) ⇒ 2 ---------- Buffer: foo ---------- 1 on this column 2on this column 2on this column 1 on this column ---------- Buffer: foo ----------
このバッファーローカル変数が非nil
なら、Emacsは隠蔽されたテキストを後にともなう行の終端に‘…’を表示する。以下は前の例からの継続。
(setq selective-display-ellipses t) ⇒ t ---------- Buffer: foo ---------- 1 on this column 2on this column ... 2on this column 1 on this column ---------- Buffer: foo ----------
省略記号(‘…’)にたいして他のテキストを代替えするためにディスプレイテーブルを使用できる。ディスプレーテーブルを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
一時的表示(temporary display)は出力をバッファーに配置して編集用ではなく閲覧用としてユーザーに示すためにLispプログラムにより使用されます。多くのヘルプコマンドはこの機能を使用します。
この関数はbuffer-nameという名前のバッファー(必要なら最初に作成される)にプリントされた任意の出力が挿入されるようアレンジ、さらにバッファーをHelpモードにしてbody内のフォームを実行する(類似する以下のフォームwith-temp-buffer-window
を参照)。最後にそのバッファーはいずれかのウィンドウに表示されるが、そのウィンドウは選択されない。
body内のフォームが出力バッファーのメジャーモードを変更しないため、実行の最後においても依然としてHelpモードにあるなら、with-output-to-temp-buffer
は最後にそのバッファーを読み取り専用するとともに、クリック可能なクロスリファレンスとなるように関数名と変数名のスキャンも行う。特にドキュメント文字列内のハイパーリンク上アイテムに関する詳細はTips for Documentation Stringsを参照のこと。
文字列buffer-nameは一時的なバッファーを指定して、これはあらかじめ存在する必要はない。引数はバッファーではなく文字列でなければならない。そのバッファーは最初に消去されて(確認なし)、with-output-to-temp-buffer
のexit後は未変更(unmodified)とマークされる。
with-output-to-temp-buffer
はstandard-output
を一時的バッファーにバインドしてbody内のフォームを評価する。body内のLisp出力関数を使用した出力のデフォルト出力先は、そのバッファーになる(しかしスクリーン表示やエコーエリア内のメッセージは一般的な世界の感覚では“出力”であるものの影響は受けない)。出力関数を参照のこと。
この構構文の振る舞いをカスタマイズするために利用できるフックがいくつかあり、それらは以下にリストしてある。
リターン値はbody内の最後のフォームの値。
---------- Buffer: foo ---------- This is the contents of foo. ---------- Buffer: foo ----------
(with-output-to-temp-buffer "foo" (print 20) (print standard-output)) ⇒ #<buffer foo> ---------- Buffer: foo ---------- 20 #<buffer foo> ---------- Buffer: foo ----------
この変数が非nil
なら、with-output-to-temp-buffer
はヘルプバッファーを表示する処理を行うためにその関数を呼び出す。この関数は表示すべきバッファーという1つの引数を受け取る。
with-output-to-temp-buffer
が通常行うように、save-selected-window
内部や選択されたウィンドウ内でバッファーか選択された状態でtemp-buffer-show-hook
を実行するのは、この関数にとってよいアイデアである。
このノーマルフックはbodyを評価する前にwith-output-to-temp-buffer
により実行される。フック実行時には一時的バッファーがカレントになる。このフックは通常はそのバッファーをHelpモードにするための関数にセットアップされる。
このノーマルフックは一時的バッファー表示後にwith-output-to-temp-buffer
により実行される。フック実行時には一時的バッファーがカレントになり、それが表示されているウィンドウが選択される。
このマクロはwith-output-to-temp-buffer
と類似している。with-output-to-temp-buffer
構文と同様に、これはプリントされる任意の出力がbuffer-or-nameという名前のバッファーに挿入されるようにアレンジしてbodyを実行して、そのバッファーをいずれかのウィンドウに表示する。しかしwith-output-to-temp-buffer
とは異なり、このマクロはそのバッファーを自動的にHelpモードに切り替えない。
引数buffer-or-nameは一時的バッファーを指定する。これはバッファー(既存でなければならない)、または文字列を指定でき、文字列の場合には必要ならその名前のバッファーが作成される。そのバッファーはwith-temp-buffer-window
のexit時には、未変更かつ読み取り専用とマークされる。
このマクロはtemp-buffer-show-function
を呼び出さない。かわりにそのバッファーを表示するためにaction引数をdisplay-buffer
(表示するウィンドウの選択を参照)に渡す。
引数quit-functionが指定されていなければbody内の最後のフォームの値がリターンされる。指定されている場合には、そのバッファーを表示するウィンドウとbodyの結果という2つの引数で呼び出される。その場合には、最終的なリターン値は何であれquit-functionがリターンした値となる。
このマクロはwith-output-to-temp-buffer
により実行される類似フックのかわりにノーマルフックtemp-buffer-window-setup-hook
とtemp-buffer-window-show-hook
を使用する。
次の2つの構文はwith-temp-buffer-window
とほとんど同じですが、説明している点が異なります:
このマクロはwith-temp-buffer-window
と同様だが、bodyの実行に際してbuffer-or-nameで指定したバッファーをカレントにする点が異なる。
このマクロはwith-temp-buffer-window
と同様だが、bodyの実行の前にbuffer-or-nameで指定したバッファーを表示する点が異なる。
一時的バッファーを表示するウィンドウは、以下のモードを使用してバッファーのサイズをフィットさせることができます:
このマイナーモードが有効なときは、一時的バッファーを表示しているウィンドウはバッファーのコンテンツにフィットするように自動的にリサイズされる。
そのバッファーにたいして特別に作成されたウィンドウの場合のみウィンドウはリサイズされる。特に前に別のバッファーを表示していたウィンドウはリサイズされない。デフォルトではこのモードはリサイズにfit-window-to-buffer
を使用する(ウィンドウのリサイズを参照)。以下のオプションtemp-buffer-max-height
とtemp-buffer-max-width
をカスタマイズして他の関数を指定できる。
このオプションはtemp-buffer-resize-mode
が有効な際に一時的バッファーを表示するウィンドウの最大高さ(行数)を指定する。その種のバッファーの高さ選択のために呼び出す関数でもよい。これはバッファーを唯一の引数として受け取り、正の整数をリターンすること。関数の呼び出し時にはリサイズされるウィンドウが選択される。
このオプションはtemp-buffer-resize-mode
が有効な際に一時的バッファーを表示するウィンドウの最大幅(列数)を指定する。その種のバッファーの高さ選択のために呼び出す関数でもよい。これはバッファーを唯一の引数として受け取り、正の整数をリターンすること。関数の呼び出し時にはリサイズされるウィンドウが選択される。
以下の関数は一時的な表示にカレントバッファーを使用します:
この関数はカレントバッファー内のpositionにstringを瞬間表示(momentarily display)する。これはundoリストやバッファーの変更状態(modification status)に影響を与えない。
瞬間表示は次の入力イベントまで留まる。次の入力イベントがcharならmomentary-string-display
はそれを無視してリターンする。それ以外ならそのイベントは後続の入力として使用するためにバッファリングされる。つまりcharとタイプすると表示からその文字列を単に削除して、(たとえば)
charではないC-fとタイプすると表示からその文字列を削除して、その後に(おそらく)ポイントを前方へ移動するだろう。引数charのデフォルトはスペース。
momentary-string-display
のリターン値に意味はない。
文字列stringがコントロール文字を含まなければ、before-string
プロパティでオーバーレイを作成(その後に削除)することで、同じことをより汎用的に行うことができる。オーバーレイのプロパティを参照のこと。
messageが非nil
なら、バッファー内にstringが表示されている間はエコーエリアにそれが表示される。nil
の場合のデフォルトは、継続するためにはcharをタイプするように告げるメッセージ。
以下の例では最初はポイントは2行目の先頭に置かれている:
---------- Buffer: foo ---------- This is the contents of foo. ∗Second line. ---------- Buffer: foo ----------
(momentary-string-display "**** Important Message! ****" (point) ?\r "Type RET when done reading") ⇒ t
---------- Buffer: foo ---------- This is the contents of foo. **** Important Message! ****Second line. ---------- Buffer: foo ---------- ---------- Echo Area ---------- Type RET when done reading ---------- Echo Area ----------
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファーのテキストのスクリーン上の見栄えを変更するために、 プレゼンテーション機能としてオーバーレイ(overlay)を使用できます。オーバーレイとは個々のバッファーに属するオブジェクトであり、指定された開始と終了をもっています。確認したりセットすることができるプロパティももっています。それらはオーバーレイをもつテキストの表示に影響を与えます。
オーバーレイの視覚的効果は、対応するテキストプロパティと同様です(テキストのプロパティを参照)。しかし実装が異なるために、オーバーレイは一般的にスケーラブルではありません(処理数に応じてバッファー内のオーバーレイ数に比例した時間を要する)。バッファー内の多数の部分の視覚的外観に効果を及ぼす必要がある場合にはテキストプロパティの使用を推奨します。
オーバーレイはその開始と終了を記録するためにマーカーを使用します。したがってバッファーのテキスト編集では、すべてのオーバーレイがそのテキストに留まるように開始と終了が調整されます。オーバーレイ作成時にはオーバーレイの先頭、または同様に終端にテキストが挿入された場合に、それがオーバーレイの内側(または外側)になるべきなのかを指定できます。
37.9.1 オーバーレイの管理 | オーバーレイの作成と変更。 | |
37.9.2 オーバーレイのプロパティ | プロパティ読み取りとセットの方法。どのプロパティがスクリーン表示に何を行うか。 | |
37.9.3 オーバーレイにたいする検索 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではオーバーレイの作成、削除、移動、およびそれらのコンテンツを調べる関数を説明します。オーバーレイはバッファーのコンテンツの一部ではないので、その変更はバッファーのundoリストに記録されません。
この関数はobjectがオーバーレイならt
をリターンする。
この関数はbufferに属する、startからendの範囲のオーバーレイを作成してリターンする。startとendはいずれもバッファーの位置を指定しなければならず、整数かマーカーを指定できる。bufferが省略されると、そのオーバーレイはカレントバッファーに作成される。
startとendが同一のバッファー位置を指定するオーバーレイは空(empty)のオーバーレイとして知られる。startとendの間のテキストが削除されれば、非空のオーバーレイも空になり得る。これが発生したとき、デフォルトではオーバーレイは削除されないが、‘evaporate’プロパティを与えることにより削除されるようにできる(evaporate propertyを参照)。
引数front-advanceとrear-advanceはそれぞれオーバーレイの開始と終了にたいするマーカーの挿入タイプを指定する。Marker 挿入タイプを参照のこと。どちらもnil
(デフォルト)なら、そのオーバーレイは先頭に挿入された任意のテキストを含むように拡張されるが、終端に挿入されたテキストにたいしては拡張されない。front-advanceが非nil
なら、オーバーレイの先頭に挿入されたテキストはオーバーレイから除外される。rear-advanceが非nil
なら、オーバーレイの終端に挿入されたテキストはオーバーレイに含まれる。
この関数はoverlayが開始する位置を整数でリターンする。
この関数はoverlayが終了する位置を整数でリターンする。
この関数はoverlayが所属するバッファーをリターンする。overlayが削除されていたらnil
をリターンする。
この関数はoverlayを削除する。そのオーバーレイはLispオブジェクトとして存在し続けて、そのプロパティリストは変更されないがバッファーへの所属と表示にたいするすべての効果を失う。
削除済みオーバーレイが永続的に非接続という訳ではない。move-overlay
を呼び出すことによりバッファー内の位置を与えることができる。
この関数はoverlayをbufferに移動して、その境界をstartとendに配置する。startとendの引数はいずれもバッファーの位置を指定しなければならず、整数かマーカーを指定できる。
bufferが省略された場合、overlayはすでに関連付けられている同じバッファーに留まる。さらにoverlayが削除されていたら、それをカレントバッファーに所属させる。
リターン値はoverlay。
これはオーバーレイの両端位置を変更する唯一の有効な方法である。手作業でオーバーレイ内のマーカーの変更を試みてはならない。それにより他の重要なデータ構造の更新が失敗して、いくつかのオーバーレイが失われる可能性がある。
この関数はプロパティnameが値valueをもつような、startとendの間のすべてのオーバーレイを削除する。これによりオーバーレイの両端位置が変更されたり分割される可能がある。
nameが省略かnil
なら、それは指定されたリージョン内のすべてのオーバーレイを削除することを意味する。startおよび/またはendが省略かnil
なら、それぞれバッファーの先頭と終端を意味する。したがって(remove-overlays)
はカレントバッファー内のすべてのオーバーレイを削除する。
この関数はoverlayのコピーをリターンする。このコピーはoverlayと同じ両端位置とプロパティをもつ。しかしオーバーレイの開始と終了にたいするマーカー挿入タイプはデフォルト値にセットされる(Marker 挿入タイプを参照)。
以下にいくつか例を示します:
;; オーバーレイの作成 (setq foo (make-overlay 1 10)) ⇒ #<overlay from 1 to 10 in display.texi> (overlay-start foo) ⇒ 1 (overlay-end foo) ⇒ 10 (overlay-buffer foo) ⇒ #<buffer display.texi> ;; 後でチェックできるようプロパティ付与 (overlay-put foo 'happy t) ⇒ t ;; プロパティが付与されたか検証 (overlay-get foo 'happy) ⇒ t ;; オーバーレイを移動 (move-overlay foo 5 20) ⇒ #<overlay from 5 to 20 in display.texi> (overlay-start foo) ⇒ 5 (overlay-end foo) ⇒ 20 ;; オーバーレイを削除 (delete-overlay foo) ⇒ nil ;; 削除されたか検証 foo ⇒ #<overlay in no buffer> ;; 削除済みオーバーレイは位置をもたない (overlay-start foo) ⇒ nil (overlay-end foo) ⇒ nil (overlay-buffer foo) ⇒ nil ;; オーバーレイの削除取り消し (move-overlay foo 1 20) ⇒ #<overlay from 1 to 20 in display.texi> ;; 結果の検証 (overlay-start foo) ⇒ 1 (overlay-end foo) ⇒ 20 (overlay-buffer foo) ⇒ #<buffer display.texi> ;; オーバーレイの移動と削除では、オーバーレイのプロパティは変更されない (overlay-get foo 'happy) ⇒ t
Emacsはそれぞれのバッファーのオーバーレイを任意の中心位置(center position)で分割される2つのリストに格納します。一方のリストはバッファーの中心位置から後方に拡張されて、もう一方は中心位置から前方へと拡張されます。中心位置はバッファーの任意の位置をとることができます。
この関数はカレントバッファーのオーバーレイを位置posの周辺に再センタリングする。これにより位置pos近傍のオーバーレイの照合は高速になるが、posから離れた位置にたいしては低速になる。
バッファーを前方にスキャンしてオーバーレイを作成するループは、最初に(overlay-recenter
(point-max))
を行うことにより高速になる可能性があります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
オーバーレイプロパティは文字が表示される方法をどちらのソースからも取得できるという点においてテキストプロパティと似ています。しかしほとんどの観点において両者は異なります。これらの比較はテキストのプロパティを参照してください。
テキストプロパティはそのテキストの一部として考えることができます。オーバーレイとそのプロパティは特にテキストの一部とはみなされません。したがってさまざまなバッファーや文字列の間でテキストをコピーすると、テキストプロパティは保持されますがオーバーレイを保持しようとは試みません。バッファーのテキストプロパティの変更はバッファーを変更済みとマークしますが、オーバーレイの移動やプロパティの変更は違います。テキストプロパティの変更とは異なり、オーバーレイプロパティの変更はバッファーのundoリストに記録されません。
複数のオーバーレイが同じ文字にたいしてプロパティ値を指定できるので、Emacsは各オーバーレイにたいして優先度の指定を許容します。2つのオーバーレイが同じ値の優先度をもち、一方が他方にネストされている場合には、内側のオーバーレイが外側のオーバーレイより高い優先度をもちます。いずれのオーバーレイも他方をネストしない場合には、どちらのオーバーレイが優先されるかについて予測するべきではありません。
以下の関数はオーバーレイのプロパティの読み取りとセットを行います:
この関数はoverlay内に記録されたプロパティpropの値をリターンする。そのプロパティにたいしてoverlayが何も値を記録していないが、シンボルであるようなcategory
プロパティをもつ場合には、そのシンボルのpropプロパティが使用される。それ以外なら値はnil
。
この関数はoverlay内に記録されたプロパティpropの値にvalueをセットする。リターン値はvalue。
これはoverlayのプロパティリストのコピーをリターンする。
与えられた文字にたいしてテキストプロパティとオーバーレイプロパティの両方をチェックする関数get-char-property
も参照してください。テキストプロパティを調べるを参照してください。
多くのオーバーレイプロパティには特別な意味があります。以下はそれらのテーブルです:
priority
このプロパティの値はオーバーレイの優先度を決定する。優先度にたいして値を指定したければnil
(か0)、または正の整数を使用すること。それ以外のすべての値にたいする動作は未定義。
2つ以上のオーバーレイが同じ文字をカバーして、いずれもが同じプロパティを指定する場合には優先度が重要になる。他よりpriority
の値が大きいほうが他をオーバーライドする。face
プロパティにたいしては、より高い優先度のオーバーレイの値は他の値を完全にはオーバーライドしない。かわりにより低い優先度のface
プロパティのface属性を高い優先度のface属性がオーバーライドする。
現在のところ、すべてのオーバーレイはテキストプロパティより優先される。
Emacsは内部的なオーバーレイのいくつかにたいして非数値の優先度を使用することがあるので、(自分が作成したオーバーレイでなければ)オーバーレイ優先度の算術演算を試みないように注意すること。オーバーレイを優先度順に配置する必要があるなら、overlays-at
のsorted引数を使用すること。オーバーレイにたいする検索を参照のこと。
window
window
プロパティが非nil
ならオーバーレイはそのウィンドウだけに適用される。
category
オーバーレイがcategory
プロパティをもつなら、それをオーバーレイのカテゴリー(category)と呼ぶ。これはシンボルであること。そのシンボルのプロパティはオーバーレイのプロパティにたいしてデフォルトの役割を果たす。
face
このプロパティはテキストの外観を制御する(フェイスを参照)。プロパティの値は以下のいずれか:
(keyword value
…)
という形式のプロパティリストでありkeywordはフェイス属性名、valueはその属性の値。
(foreground-color . color-name)
か(background-color
. color-name)
という形式のコンスセル。これは(:foreground
color-name)
や(:background
color-name)
と同じように、フォアグラウンドとバックグラウンドのカラーを指定する。この形式は後方互換性のためだけにサポートされており、使用は避けること。
mouse-face
このプロパティはマウスがオーバーレイ範囲内にあるときに、face
のかわりに使用される。しかしEmacsはこのプロパティに由来するテキストのサイズを変更するようなフェイス属性(:height
、:weight
、:slant
)をすべて無視する。これらの属性はハイライトされていないテキストでは常に同一である。
display
このプロパティはテキストが表示される方法を変更するさまざまな機能をアクティブにする。たとえばこれはテキストの外観を縦長(taller)や横長(shorter)にしたり、高く(higher)したり低く(lower)したり、イメージによる置き換えを行う。display
プロパティを参照のこと。
help-echo
あるオーバーレイがhelp-echo
プロパティをもつなら、そのオーバーレイ内のテキスト上にマウスを移動した際に、Emacsはエコーエリアかツールチップウィンドウにヘルプ文字列を表示する。詳細はText help-echoを参照のこと。
field
同じfield
プロパティをもつ連続する文字はフィールド(field)を形成する。forward-word
やbeginning-of-line
を含むいくつかの移動関数はフィールド境界で移動を停止する。フィールドの定義と使用を参照のこと。
modification-hooks
このプロパティの値はオーバーレイ内の任意の文字の変更、またはオーバーレイの厳密に内側にテキストが挿入された場合に呼び出される関数のリスト。
このフックの関数は各変更の前後両方で呼び出される。これらの関数が受け取った情報を保存して呼び出し間で記録を比較すれば、バッファー内のテキストでどのような変更が行われたかを正確に判断できる。
変更前に呼び出された際にはオーバーレイ、nil
、変更されたテキスト範囲の開始と終了という4つの引数を各関数は受け取る。
変更後に呼び出された際にはオーバーレイ、t
、変更されたテキスト範囲の開始と終了、およびその範囲により置き換えられた変更前のテキスト長という5つの引数を各関数は受け取る(変更前の長さは挿入では0、削除では削除された文字数であり、変更後の先頭と終端が等しくなる)。
これらの関数がバッファーを変更する場合には、これらのフックを呼び出す内部的メカニズムの混乱を避けるために、それを行う前後でinhibit-modification-hooks
をt
にバインドすること。
テキストプロパティもmodification-hooks
プロパティをサポートするが詳細は幾分異なる(特殊な意味をもつプロパティを参照)。
insert-in-front-hooks
このプロパティの値はオーバーレイ先頭へのテキスト挿入前後に呼び出される関数のリスト。呼び出し方はmodification-hooks
の関数と同様。
insert-behind-hooks
このプロパティの値はオーバーレイ終端へのテキスト挿入前後に呼び出される関数のリスト。呼び出し方はmodification-hooks
の関数と同様。
invisible
invisible
プロパティによりオーバーレイ内のテキストを不可視にできる。これはそのテキストがスクリーン上に表示されないことを意味する。詳細は不可視のテキストを下さいのこと。
intangible
オーバーレイのintangible
プロパティは正にintangible
テキストプロパティと同様に機能する。これは時代遅れである。詳細はSee section 特殊な意味をもつプロパティを参照のこと。
isearch-open-invisible
このプロパティはインクリメンタル検索にたいして最後のマッチがそのオーバーレイに重なる場合に、不可視なオーバーレイを永続的に可視にする方法を告げる。不可視のテキストを参照のこと。
isearch-open-invisible-temporary
このプロパティはインクリメンタル検索にたいして、検索の間に不可視なオーバーレイを一時的に可視にする方法を告げる。不可視のテキストを参照のこと。
before-string
このプロパティの値はオーバーレイ先頭に表示するために追加する文字列。この文字列はいかなる意味においてもバッファー内には出現せずにスクリーン上にのみ表れる。
after-string
このプロパティの値はオーバーレイ終端に表示するために追加する文字列。この文字列はいかなる意味においてもバッファー内には出現せずにスクリーン上にのみ表れる。
line-prefix
このプロパティは表示時にそれぞれの非継続行の後に追加するディスプレイ仕様(display spec)を指定する。切り詰めを参照のこと。
wrap-prefix
このプロパティは表示時にそれぞれの継続行の前に追加するディスプレイ仕様(display spec)を指定する。切り詰めを参照のこと。
evaporate
このプロパティが非nil
の場合には、そのオーバーレイが空(長さが0)になったら自動的に削除される。空のオーバーレイ(empty
overlayを参照)にたいして非nil
のevaporate
プロパティを与えた場合には即座に削除される。オーバーレイがこのプロパティをもたなければ、バッファーからオーバーレイの開始位置と終了位置の間のテキストが削除された際に削除されないことに注意。
keymap
このプロパティがnil
なら、そのテキスト範囲にたいしてキーマップを指定する。このキーマップはポイントの後の文字がそのオーバーレイ内にあるときに使用されて、他のほとんどのキーマップより優先される。アクティブなキーマップを参照のこと。
local-map
local-map
プロパティはkeymap
プロパティと同様だが、既存のキーマップに付け加えるのではなくバッファーのローカルマップを置き換える点が異なる。これはそのキーマップがマイナーモードキーマップより低い優先度をもつことも意味する。
keymap
とlocal-map
プロパティはbefore-string
、after-string
、display
プロパティにより表示された文字列には影響しません。これはポイントがその文字列上にない場合のマウスクリックや、その文字列に関する他のマウスイベントにのみ関係があります。その文字列に特別なマウスイベントをバインドするには、そのイベントをkeymap
かlocal-map
プロパティに割り当てます。特殊な意味をもつプロパティを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はカレントバッファー内の位置posにある文字をカバーするすべてオーバーレイのリストをリターンする。sortedが非nil
ならリストは優先度降順、それ以外なら特定の順にはソートされない。オーバーレイがpos、またはそれより前から始まり、かつposの後で終わるなら位置posはオーバーレイに含まれる。
以下はポイント位置の文字にたいしてプロパティpropを指定するオーバーレイのリストをリターンするLisp関数の使用例:
(defun find-overlays-specifying (prop) (let ((overlays (overlays-at (point))) found) (while overlays (let ((overlay (car overlays))) (if (overlay-get overlay prop) (setq found (cons overlay found)))) (setq overlays (cdr overlays))) found))
この関数はbegからendのリージョンと重複(overlap)するオーバーレイのリストをリターンする。オーバーレイがリージョン内の文字を少なくとも1つ含めば、オーバーレイとリージョンは重複している。空のオーバーレイ(empty overlayを参照)がbegにある場合、厳密にはbegとbegの間、またはendがバッファー終端の位置を意味するときはendにある場合には重複している。
この関数はposの後にあるオーバーレイの開始か終了となるバッファー位置をリターンする。それが存在しなければ(point-max)
をリターンする。
この関数はposの前にあるオーバーレイの開始か終了となるバッファー位置をリターンする。それが存在しなければ(point-min)
をリターンする。
以下に例としてプリミティブ関数next-single-char-property-change
(テキストプロパティの検索関数を参照)の単純化(かつ非効率的)したバージョンを示します。これは位置posから前方へ与えられたプロパティprop
にたいして、オーバーレイプロパティまたはテキストプロパティのいずれかの値が変化した次の位置を検索します。
(defun next-single-char-property-change (position prop) (save-excursion (goto-char position) (let ((propval (get-char-property (point) prop))) (while (and (not (eobp)) (eq (get-char-property (point) prop) propval)) (goto-char (min (next-overlay-change (point)) (next-single-property-change (point) prop))))) (point)))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
すべての文字が同じ幅をもつ訳ではありませんが、以下の関数により文字の幅をチェックできます。関連する関数についてはインデント用のプリミティブとスクリーン行単位の移動を参照してください。
この関数は文字charがカレントバッファーに表示された場合(つまりそのバッファーのディスプレイテーブルがあれば考慮に入れる。ディスプレーテーブルを参照)の幅を列数でリターンする。タブ文字の幅、通常はtab-width
(通常の表示の慣習を参照)。
この関数は文字列stringがカレントバッファーおよび選択されたウィンドウに表示された場合の幅を列数でリターンする。
この関数はstringの一部を列数widthにフィット新たな文字列としてリターンする。
stringがwidthに満たなければ文字列終端が結果の終端となる。string内の1つの複数列文字が列widthを超えて跨がるようなら、その文字は結果に含まれない。つまり結果はwidthより短くなるかもしれないが超えることはできない。
オプション引数start-columnは開始列を指定する。これが非nil
なら、その文字列の最初のstart-column列は値から省かれる。string内の1つの複数列文字が列start-columnを超えて跨がるようなら、その文字は結果に含まれない。
オプション引数paddingが非nil
なら、結果となる文字列の幅を正確にwidth列に拡張するためにパディング文字が追加される。結果文字列がwidthより短ければ結果文字列の終端にパディング文字が使用される。string内の1つの複数列文字が列start-columnを跨ぐ場合は先頭にもパディング文字が使用される。
ellipsisが非nil
なら、それはstringの表示幅がellipsisの表示幅以下でなければwidthを超えてしまう場合に、stringの終端(任意のパディングを含む)を置き換える文字列であること。ellipsisが非nil
かつ文字列以外なら、それは変数truncate-string-ellipsis
の値を意味する。
(truncate-string-to-width "\tab\t" 12 4) ⇒ "ab" (truncate-string-to-width "\tab\t" 12 4 ?\s) ⇒ " ab "
以下の関数は与えられたウィンドウにあるテキストを表示したときのサイズをピクセル単位でリターンします。この関数はテキストを含むためにウィンドウを十分大きくするためにfit-window-to-buffer
とfit-frame-to-buffer
(ウィンドウのリサイズを参照)により使用されます。
この関数はwindowのバッファーのテキストサイズをピクセル単位でリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。リターン値は任意のテキスト行の最大ピクセル幅と、すべてのテキスト行の最大ピクセル高さのコンス。
オプション引数fromが非nil
なら、それは考慮すべき最初のテキスト位置を指定する。デフォルトはそのバッファーのアクセス可能な最小の位置。fromがt
なら改行文字ではないアクセス可能な最小位置を使用する。オプション引数toが非nil
なら、それは考慮すべき最後のテキスト位置を指定する。デフォルトはそのバッファーのアクセス可能な最大の位置。toがt
なら改行文字ではないアクセス可能な最大位置を使用する。
オプション引数x-limitが非nil
なら、それはリターンされ得る最大ピクセル幅を指定する。x-limitがnil
または省略された場合には、windowのbody(ウィンドウのサイズを参照)のピクセル幅を使用する。これは呼び出し側がwindowの幅の変更を意図しない場合に有用。それ以外なら呼び出し側はここで想定されるwindowのbodyの最大幅を指定すること。X座標を超えるテキストのx-limitは無視される。長い行の幅の計算には多くの時間を要する可能性があるので、いずれにせよ切り詰められるであろう長い行を含むバッファーの場合には、特に必要に応じてこの引数の値を小さくすることはよいアイデアである。
オプション引数y-limitが非nil
なら、それはリターンされ得る最大ピクセル高さを指定する。Y座標を超えるテキストのy-limitは無視される。大きなバッファーのピクセル高さの計算には多くの時間を要する可能性があるので、特に呼び出し側がバッファーのサイズを知らない場合におけるこの変数の指定は合理的である。
オプション引数mode-and-header-lineがnil
または省略された場合には、リターン値にwindowのモードラインとヘッダーラインの高さを含めないことを意味する。これがシンボルmode-line
かheader-line
のいずれかなら、それらが存在する場合にはリターン値にそのラインの高さだけを含める。これがt
なら存在する場合は両方の高さをリターン値に含める。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
各ディスプレイ行のトータル高さは、その行のコンテンツ高さにディスプレイ上部や下部にオプションで追加される垂直行スペーシングを加えて構成されます。
行のコンテンツ高さは、もしあれば最後の改行を含む、そのディスプレイ行の文字またはイメージの最大高さです(継続されるディスプレイ行には最後の改行が含まれない)。特にこれより大きい高さを指定しなければ、これがデフォルトの行高さになります(これは一般的には対応するフレームのデフォルトのフォント高さに等しい。Frame Fontを参照)。
より大きい行高さを明示的に指定するためにはディスプレイ行の絶対高さ、または垂直スペースを指定する複数の方法が存在します。しかし何を指定したかに関わらず、実際の行高さがデフォルトの高さより小さくなることはありません。
改行はその改行で終わるディスプレイ行のトータル高さを制御するテキストプロパティとオーバーレイプロパティline-height
をもつことができます。
プロパティの値がt
なら改行文字はその行の表示高さにたいして効果をもたず、可視なコンテンツだけが高さを決定します。この場合には以下で説明するline-spacing
プロパティも無視されます。これはイメージ間に追加のブランク領域をもたない、小さなイメージ(やイメージスライス)にたいして有用です。
プロパティの値が(height
total)
という形式のリストなら、これはディスプレイ行の下部に余分なスペースを追加します。最初にEmacsは、その行の上部の余分なスペースを制御するための高さspecとして、heightを使用します。それから行のトータル高さをtotalにするために、行の下部に必要なスペースを追加します。この場合には、改行にたいするline-spacing
プロパティのすべての値は無視されます。
他の種類のプロパティ値は高さspec(height spec)です。これは行の高さを指定する数値に変換されます。高さspecを記述するためには複数の方法があります。以下はそれらが数値に変換される方法です:
integer
高さspecが正の整数なら高さの値はその整数。
float
高さspecが浮動小数点数floatなら高さ数値はそのフレームのデフォルト行高さのfloat倍。
(face . ratio)
高さspecがこのフォーマットのコンスなら、高さ数値はフェイスfaceの高さのratio倍。ratioには任意の型の数値を指定でき、nil
は1のratioを意味する。faceがt
ならカレントフェイスを参照する。
(nil . ratio)
高さspecがこのフォーマットのコンスなら高さ数値はその行のコンテンツ高さのratio倍。
したがって任意の有効な種々の高さspecによりピクセル単位で高さが決定されます。行のコンテンツ高さがこれより小さければ、Emacsは指定されたトータル高さになるように余分な垂直スペースを行の上部に追加します。
line-height
プロパティを指定しない場合には、その行の高さは行のコンテンツ高さとに行スペーシングを追加して構成されます。Emacsの異なるさまざまな部分のテキストにたいして、行スペーシングを指定する複数の方法が存在します。
グラフィカルなディスプレイではフレームパラメーターline-spacing
(レイアウトのパラメーターを参照)を使用することにより、フレーム内のすべての行にたいして行スペーシングを指定できます。しかしline-spacing
のデフォルト値が非nil
なら、それはそのフレームのフレームパラメーターline-spacing
をオーバーライドします。整数は行の下部に配するピクセル数を指定します。浮動小数点数はフレームのデフォルト行高さに相対的にスペーシングを指定します。
バッファーローカル変数line-spacing
を通じて、バッファー内のすべての行の行スペーシングを指定できます。整数は行の下部に配するピクセル数を指定します。浮動小数点数はデフォルトフレーム行高さに相対的にスペーシングを指定します。これはそのフレームにたいして指定された行スペーシングをオーバーライドします。
最後に改行は改行で終わるディスプレイ行にたいしてデフォルトフレーム行スペーシングを広くできるテキストプロパティとオーバーレイプロパティline-spacing
、および変数line-spacing
をもつことができます。その値がバッファーやフレームのデフォルトより大きければ、その改行で終端されるディスプレイ行にはかわりにその値が使用されます。
種々の方法によりこれらのメカニズムは各行のスペーシングにたいするLisp値を指定します。値は高さspecで、これは上述したLisp値に変換されます。しかしこの場合には高さ数値は行高さではなく行スペーシングを指定します。
テキスト端末では行スペーシングは変更できません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フェイス(face)とはフォント、フォアグラウンドカラー、バックグラウンドカラー、オプションのアンダーライン等のテキストを表示するためのグラフィカルな属性のコレクションのことです。フェイスはEmacsがバッファー内や、同様にモードラインのようなフレームの他の部分でテキストを表示する方法を制御します。
フェイスを表現する1つの方法として(:foreground "red" :weight
bold)
のような属性のプロパティリストがあります。このようなリストはanonymousフェイス(anonymous
face)と呼ばれます。たとえばface
テキストプロパティとしてanonymousフェイスを割り当てることができ、Emacsは指定された属性でテキストを表示するでしょう。特殊な意味をもつプロパティを参照してください。
より一般的にはフェイスはフェイス名(face
name)を通じて参照されます。これはフェイス属性のセットに関連付けられたLispシンボル19です。名前つきフェイスはdefface
マクロを使用して定義できます(フェイスの定義を参照)。Emacsにはいくつかの標準名前つきフェイスが同梱されています(基本的なフェイスを参照)。
Emacsの多くの箇所で名前つきフェイスが要求されていて、anonymousフェイスは受け入れられません。これらにはフェイス属性のための関数に記述される関数、および変数font-lock-keywords
(検索ベースのフォント化を参照)が含まれます。特に明記しないかぎり名前つきフェイスの参照に限定して用語フェイスを使用することにします。
この関数はobjectが名前つきフェイス(フェイス名の役目をもつLispシンボルか文字列)なら非nil
、それ以外ならnil
をリターンする。
37.12.1 フェイスの属性 | フェイスとは? | |
37.12.2 フェイスの定義 | フェイスを定義する方法。 | |
37.12.3 フェイス属性のための関数 | フェイス属性の確認やセットを行う関数。 | |
37.12.4 フェイスの表示 | ある文字にたいして指定されたフェイスをEmacsが組み合わせる方法。 | |
37.12.5 フェイスのリマップ | フェイスを別の定義にリマップする。 | |
37.12.6 フェイスを処理するための関数 | フェイスの定義と確認を行う方法。 | |
37.12.7 フェイスの自動割り当て | 自動的にフェイスを割り当てるフック。 | |
37.12.8 基本的なフェイス | デフォルトで定義されるフェイス。 | |
37.12.9 フォントの選択 | あるフェイスに最適なフォントを見つける。 | |
37.12.10 フォントの照会 | 利用可能なフォント名とそれらの情報の照会。 | |
37.12.11 フォントセット | フォントセットは文字セットの範囲を処理するフォントコレクション。 | |
37.12.12 低レベルのフォント表現 | 文字表示フォントのLisp表現。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フェイス属性(Face attributes)は、フェイスの視覚的外観を決定します。以下はすべてのフェイス属性と、それらの可能な値と効果に関するテーブルです。
以下の値とは別に各フェイス属性は値unspecified
をもつことができます。この特殊な値はフェイスがその属性を直接指定しないことを意味します。unspecified
属性はEmacsにかわりに親フェイス(以下の:inherit
属性の記述を参照)を参照して、それに失敗したら基礎フェイス(フェイスの表示を参照)を参照することを指示します。default
フェイスはすべての属性を指定しなければなりません。
これらの属性のいくつかは特定の種類のディスプレイにおいてのみ意味があります。ディスプレイが特定の属性を処理できなければ、その属性は無視されます。
:family
フォントファミリーかフォントセット(文字列)。フォントファミリーに関する詳細はSee Fonts in The GNU Emacs
Manualを参照のこと。関数font-family-list
(以下参照)は利用可能なファミリー名のリストをリターンする。フォントセットに関する情報はフォントセットを参照のこと。
:foundry
:family
属性により指定されるフォントファミリーにたいするフォントfoundry (文字列)。Fonts in The GNU Emacs Manualを参照のこと。
:width
相対的な文字幅。これはシンボルultra-condensed
、extra-condensed
、condensed
、semi-condensed
、normal
、semi-expanded
、expanded
、extra-expanded
、ultra-expanded
のいずれかであること。
:height
フォントの高さ。もっともシンプルなケースでは1/10ポイントを単位とする整数。
値には基礎フェイス(underlying face)にたいして相対的に高さを指定する浮動小数点数、または関数も指定できる(フェイスの表示を参照)。浮動小数点数は基礎フェイスの高さをスケーリングする量を指定する。関数値は基礎フェイスの高さを単一の引数として呼び出されて、新たなフェイスの高さをリターンする。関数が整数を引数として渡された場合には整数をリターンしなければならない。
デフォルトフェイスの高さは整数を使用して指定しなければならない。浮動小数点数や関数は受け入れられない。
:weight
フォントのweight。シンボルultra-bold
、extra-bold
、bold
、semi-bold
、normal
、semi-light
、light
、extra-light
、ultra-light
(太字から細字順)のいずれか。可変輝度テキストをサポートするテキスト端末では、normalより大なweightはより高輝度、小なweightはより低輝度で表示される。
:slant
フォントのslant。シンボルitalic
、oblique
、normal
、reverse-italic
、reverse-oblique
のいずれか。可変輝度テキストをサポートするテキスト端末ではslantされたテキストはhalf-brightで表示される。
:foreground
フォアグラウンドカラー(文字列)。値にはシステム定義済みカラー、または16進カラー仕様を指定できる。カラー名を参照のこと。白黒ディスプレイでは特定のグレー色調が点描パターンで実装されている。
:distant-foreground
代替えのフォアグラウンドカラー(文字列)。これは:foreground
と似ているが、使用されるであろうフォアグラウンドカラーがバックグラウンドカラーに近いときのみフォアグラウンドカラーとして使用される点が異なる。これはたとえばテキストをマーク時(リージョンフェイス)に有用。そのテキストがリージョンフェイスとして可視なフォアグラウンドをもつ場合には、そのフォアグラウンドが使用される。フォアグラウンドがリージョンフェイスのバックグラウンドに近ければ、テキストを可読にするために:distant-foreground
が使用される。
:background
バックグラウンドカラー(文字列)。値にはシステム定義済みカラー、または16進カラー仕様を指定できる。カラー名を参照のこと。
:underline
文字にアンダーラインを引くべきか否か、およびその方法。:underline
属性として可能な値は以下のとおり:
nil
アンダーラインを引かない。
t
そのフェイスのフォアグラウンドカラーでアンダーラインを引く。
文字列colorで指定されたカラーでアンダーラインを引く。
(:color color :style style)
colorは文字列、またはそのフェイスのフォアグラウンドカラーを意味するシンボルforeground-color
。属性:color
の省略はフェイスのフォアグラウンドカラーの使用を意味する。styleは直線を意味するline
、または波線を意味するwave
いずれかのシンボルであること。属性:style
の省略は直線を意味する。
:overline
文字にオーバーラインを引くべきか否か、およびそのカラー。値がt
ならフェイスのフォアグラウンドカラーを使用してオーバーラインを引く。値が文字列ならそのカラーを使用してオーバーラインを引く。値nil
はオーバーラインを引かないことを意味する。
:strike-through
文字に取り消し線を引くべきか否か、およびそのカラー。値は:overline
で使用される値と同じ。
:box
文字周囲に枠(box)を描画するか否か、そのカラー、枠線の幅、および3D外観。以下は:box
の可能な値と意味:
nil
枠を描画しない。
t
幅1のフォアグラウンドカラーで枠線を描画する。
幅1のカラーcolorで枠線を描画する。
(:line-width width :color color :style style)
この方法では枠のすべての形相を明示的に指定できる。値widthは描画する線の幅を指定して、デフォルトは1。負の幅-nは基礎テキストのスペースを占有する線幅nを意味して、文字の高さや幅の増加を避けることができる。
値colorは描画するカラーを指定する。シンプルな枠線ではフェイスのフォアグラウンドカラー、3D枠線ではフェイスのバックグラウンドカラーがデフォルト。
値styleは3D枠線を描画するか否かを指定する。released-button
なら押下された3Dボタンのような外観、pressed-button
なら押下されていない3Dボタンのような外観、nil
または省略された場合には2D枠線が使用される。
:inverse-video
文字が反転表示されて表示されるべきか否か。値はt
(反転表示する)かnil
(反転表示しない)のいずれか。
:stipple
バックグラウンドの点描(ビットマップ)。
値には文字列を指定できる。外部形式Xビットマップデータを含むファイルの名前であること。ファイルは変数x-bitmap-file-path
にリストされるディレクトリー内で検索される。
かわりに(width height
data)
という形式のリストによりビットマップで直接値を指定できる。ここでwidthとheightはピクセル単位によるサイズ、dataは行単位でビットマップのrawビットを含む文字列。各行は文字列内で連続する(width
+ 7) / 8バイトを占める(最善の結果を得るためにはユニバイト文字列であること)。これは各行が常に少なくとも1バイト全体を占めることを意味する。
値がnil
なら点描パターンを使用しないことを意味する。
これは特定のグレー色調を処理するために自動的に使用されるので、通常はstipple属性のセットは必要ない。
:font
そのフェイスの表示に使用されるフォント。値はフォントオブジェクトであること。フォントオブジェクト、フォントスペース、フォントエンティティーに関する情報は低レベルのフォント表現を参照のこと。
set-face-attribute
(フェイス属性のための関数を参照)を使用してこの属性を指定する際にはフォントspec、フォントエンティティー、または文字列を与えることもできる。Emacsはそのような値を適切なフォントオブジェクトに変換して、実際の属性値としてそのフォントオブジェクトを格納する。文字列を指定する場合には、その文字列のコンテンツはフォント名であること(Fonts in The GNU Emacs
Manualを参照)。フォント名がワイルドカードを含むXLFDなら、Emacsはそれらのワイルドカードに最初にマッチするフォントを選択する。この属性の指定により:family
、:foundry
、:width
、:height
、:weight
、:slant
の属性値も変更される。
:inherit
属性を継承するフェイス名かフェイス名のリスト。継承フェイス由来の属性は基礎フェイスより高い優先度で、基礎フェイスの場合と同じような方法でマージされる(フェイスの表示を参照)。フェイスのリストが使用された場合には、リスト内で先頭側フェイスの属性が末尾側フェイスの属性をオーバーライドする。
この関数は利用可能なフォントファミリー名のリストをリターンする。オプション引数frameはそのテキストが表示されるフレームを指定する。これがnil
なら選択されたフレームが使用される。
この変数はアンダーラインが引かれたテキスト表示時に、ベースラインとアンダーライン間の最小距離をピクセル単位で指定する。
この変数は:stipple
属性のビットマップファイルを検索するディレクトリーのリストを指定する。
これはobject、:stipple
(上記参照)での使用に適した有効なビットマップ仕様ならt
、それ以外ならnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フェイスを定義する通常の方法はdefface
マクロを通じて定義する方法です。このマクロはフェイス名(シンボル)をデフォルトのフェイスspec(face
spec)と関連付けます。フェイスspecとは任意の与えられた端末上でフェイスがどの属性をもつべきかを指定する構文です。たとえばあるフェイスspecは高カラー端末ではあるフォアグラウンドカラーし、低カラー端末では異なるフォアグラウンドカラーを指定するかもしれません。
値がフェイス名であるような変数を作りたがる人がいます。ほとんどの場合には、これは必要ありません。通常の手順はdefface
でフェイスを定義して、その名前を直接使用することです。
このマクロはspecによりデフォルトフェイスspecが与えられるような名前つきフェイスとしてfaceを宣言する。シンボルfaceはクォートせずに‘-face’で終わらないこと(冗長かもしれない)。引数docはフェイスにたいするドキュメント文字列。追加のkeyword引数はdefgroup
やdefcustom
の場合と同じ意味をもつ(一般的なキーワードアイテムを参照)。
faceがすでにデフォルトフェイスspecをもつ場合には、このマクロは何も行わない。
デフォルトフェイスspecは何もカスタマイゼーション(カスタマイゼーション設定を参照)の効果がないときのfaceの外観を決定する。faceが(Customテーマやinitファイルから読み込んだカスタマイズにより)すでにカスタマイズ済みなら、その外観はデフォルトフェイスspecのspecをオーバーライドするカスタムフェイスspecにより決定される。しかしその後カスタマイゼーションが削除されたら、faceの外観は再びそのデフォルトフェイスspecにより決定されるだろう。
例外としてEmacs LispモードでC-M-x
(eval-defun
)からdefface
を評価した場合には、eval-defun
の特別な機能によりdefface
が何を指示するかをフェイスが正確に反映するように、そのフェイス上の任意のカスタムフェイスをオーバーライドする。
spec引数は異なる種別の端末上でそのフェイスがどのような外観で表示されるべきかを示すフェイスspec。これは各要素が以下の形式であるようなalistであること
(display . plist)
displayは端末のクラス(以下参照)を指定する。plistはそのような端末上でフェイスがどのような外観かを指定するフェイス属性とその値からなるプロパティリストであること。後方互換性のために(display
plist)
のように要素を記述することもできる。
specの要素のdisplayの部分は、その要素がマッチする端末を決定する。与えられた端末にたいして複数の要素がマッチした場合には、最初にマッチした要素がその端末にたいして使用される。displayには以下の3つが可能:
default
specのこの要素はどの端末にもマッチしない。かわりにすべての端末に適用されるデフォルトを指定する。この要素が使用する場合には、specの最初の要素でなければならない。この後の要素はこれらのデフォルトの一部、またはすべてをオーバーライドできる。
t
specのこの要素はすべての端末にマッチする。したがってspecの後続要素が使用されることはない。t
は通常はspecの最後(か唯一)の要素として使用される。
displayがリストなら各要素は(characteristic
value…)
という形式をもつこと。ここでcharacteristicは端末をクラス分けする方法、valueはdisplayに適用されるべき可能なクラス分類。characteristicに利用可能な値は:
type
その端末が使用するウィンドウシステムの種類でgraphic
(任意のグラフィック対応ディスプレイ)、x
、pc
(MS-DOSコンソール)、w32
(MS Windows 9X/NT/2K/XP)、またはtty
(グラフィック非対応ディスプレイ)のいずれか。window-systemを参照のこと。
class
その端末がサポートするカラーの種類でありcolor
、grayscale
かmono
のいずれか。
background
バックグラウンドの種類でありlight
かdark
のいずれか。
min-colors
その端末がサポートするべき最小カラー数を表す整数。端末のdisplay-color-cells
の値が少なくとも指定された整数ならその端末にマッチ。
supports
その端末がvalue…で与えられたフェイス属性を表示可能か否か(フェイスの属性を参照)。このテストがどのように行われるかについてのより正確な情報はDisplay Face Attribute Testingを参照のこと。
与えられたcharacteristicにたいしてdisplayの要素が複数のvalueを指定する場合には、いずれの値も許容され得る。displayが複数の要素をもつ場合には、各要素は異なるcharacteristicを指定すること。その端末のそれぞれのcharacteristicはdisplay内で指定された値のいずれか1つとマッチしなければならない。
たとえば以下は標準フェイスhighlight
の定義です:
(defface highlight '((((class color) (min-colors 88) (background light)) :background "darkseagreen2") (((class color) (min-colors 88) (background dark)) :background "darkolivegreen") (((class color) (min-colors 16) (background light)) :background "darkseagreen2") (((class color) (min-colors 16) (background dark)) :background "darkolivegreen") (((class color) (min-colors 8)) :background "green" :foreground "black") (t :inverse-video t)) "Basic face for highlighting." :group 'basic-faces)
内部的にはEmacsはフェイスのシンボルプロパティface-defface-spec
内にそれぞれのフェイスのデフォルトspecを格納します(シンボルのプロパティを参照)。saved-face
プロパティはカスタマイゼーションバッファーを使用してユーザーが保存した任意のフェイスspecを格納します。customized-face
プロパティはカレントセッションにたいしてカスタマイズされた保存されていないフェイスspecを格納します。そしてtheme-face
プロパティはそのフェイスにたいするアクティブなカスタマイゼーションセッティングと、フェイスspecをもつCustomテーマを関連付けるalistです。そのフェイスのドキュメント文字列はface-documentation
プロパティ内に格納されます。
フェイスは通常はdefface
を使用して1回だけ宣言されて、その外観にたいするそれ以上の変更はCustomizeフレームワーク(Customizeユーザーインターフェースかcustom-set-faces
関数を通じて。カスタマイゼーションの適用を参照)、またはフェイスリマッピング(フェイスのリマップを参照)により行われます。Lispから直接フェイスspec変更を要する稀な状況ではface-spec-set
関数を使用できます。
この関数はface
にたいするフェイスspecとしてspecを適用する。specは上述したdefface
にたいするフェイスspecであること。
この関数はもしfaceが既存のものでなければ有効なフェイス名としてfaceを定義して、既存フレームのその属性の(再)計算も行う。
引数spec-typeはどのspecをセットするべきかを決定する。これがnil
かface-override-spec
なら、この関数はオーバーライドspec(override
spec)をセットする。これはface上の他のすべてのフェイスspecをオーバーライドする。customized-face
やsaved-face
なら、この関数はカスタマイズされたspec、または保存されたカスタムspecをセットする。face-defface-spec
ならこの関数はデフォルトフェイスspec(defface
によりセットされるものと同一)をセットする。reset
ならこの関数はfaceからすべてのカスタマイゼーションspecとオーバーライドspecをクリアーする(この場合にはspecの値は無視される)。spec-typeにたいする他のすべての値は内部的な使用のために予約済み。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは名前つきフェイスの属性に直接アクセスしたり変更する関数を説明します。
この関数はframe上のfaceにたいする属性attributeの値をリターンする。
frameがnil
ならそれは選択されたフレームを意味する(入力のフォーカスを参照)。frameがt
ならこの関数は新たに作成されるフレームにたいして指定された属性の値をリターンする(これは下記のset-face-attribute
を使用して何らかの値を指定していなければ通常はunspecified
)。
inheritがnil
ならfaceにより定義される属性だけが考慮されるのでリターンされる値はunspecified
、または相対的な値かもしれない。inheritが非nil
ならfaceのattributeの定義が、:inherit
属性で指定されたフェイスとマージされる。しかしリターンされる値は依然としてunspecified
、または相対的な値かもしれない。inheritがフェイスかフェイスのリストなら、指定された絶対的な値になるまで結果はそのフェイス(1つ以上)と更にマージされる。
リターン値が指定されていて、かつ絶対的であることを保証するためにはinheritにたいしてdefault
の値を使用すること。(常に完全に指定される)default
フェイスとマージすることにより、すべての未指定や相対的な値は解決されるだろう。
たとえば
(face-attribute 'bold :weight) ⇒ bold
この関数はvalueがフェイス属性attributeの値として使用された際に相対的なら非nil
をリターンする。これはフェイスリスト内の後続のフェイス、または継承した他のフェイスが由来となる任意の値で完全にオーバーライドするのではなく、それが変更されるであろうことを意味する。
すべての属性にたいしてunspecified
は相対的な値。:height
にたいしては浮動小数点数と関数値も相対的である。
たとえば:
(face-attribute-relative-p :height 2.0) ⇒ t
この関数はfaceの属性のalistをリターンする。結果の要素は(attr-name . attr-value)
という形式の名前/値ペアー。オプション引数frameはリターンするべきfaceの定義をもつフレームを指定する。省略かnil
ならリターン値には新たに作成されるフレームにたいするfaceのデフォルト属性が記述される。
value1がフェイス属性attributeにたいして相対的な値なら、基礎的な値value2とマージしてリターンする。それ以外の場合にはvalue1がフェイス属性attributeにたいして絶対的な値ならvalue1を変更せずにリターンする。
Emacsは通常は各フレームのフェイス属性を自動的に計算するために、各フェイスのフェイスspecを使用します(フェイスの定義を参照)。関数set-face-attribute
は特定またはすべてのフレームのフェイスに直接属性を割り当てることにより、この計算をオーバーライドできます。この関数は主として内部的な使用を意図したものです。
この関数はframeにたいするfaceの1つ以上の属性をセットする。この方法で指定された属性はfaceに属するフェイスspec(1つ以上)をオーバーライドする。
余分の引数argumentsはセットするべき属性と値を指定する。これらは(:family
や:underline
のような)属性名と値が交互になるように構成されていること。つまり、
(set-face-attribute 'foo nil :weight 'bold :slant 'italic)
これは属性:weight
をbold
、.属性:slant
をitalic
にセットする。
frameがt
ならこの関数は新たに作成されるフレームにたいするデフォルト属性をセットする。frameがnil
ならこの関数はすべての既存フレーム、同様に新たに作成されるフレームにたいしてその属性をセットする。
以下のコマンドと関数は主として古いバージョンのEmacsにたいする互換性のために提供されます。これらはset-face-attribute
を呼び出すことにより機能します。これらのframe引数にたいする値t
とnil
は、set-face-attribute
やface-attribute
の場合と同様に処理されます。コマンドがインタラクティブに呼び出された場合にはミニバッファーを使用して引数を読み取ります。
これらはそれぞれfaceの:foreground
属性、または:background
属性にcolorをセットする。
これはfaceの:stipple
属性にpatternをセットする。
これはfaceの:font
属性にfontをセットする。
これはfaceの:weight
属性にたいしてbold-pがnil
ならnormal、それ以外ならboldをセットする。
これはfaceの:slant
属性にたいしてitalic-pがnil
ならnormal、それ以外ならitalicをセットする。
これはfaceの:underline
属性にunderlineをセットする。
これはfaceの:inverse-video
属性にinverse-video-pをセットする。
これはフェイスfaceのフォアグラウンドカラーとバックグラウンドカラーを交換する。
以下はフェイスの属性を調べる関数です。これらは主として古いバージョンのEmacsとの互換性のために提供されます。これらにたいしてframeを指定しなければ選択されたフレーム、t
なら新たなフレームにたいするデフォルトデータを参照します。フェイスがその属性にたいして何の値も定義していなければunspecified
がリターンされます。inheritがnil
ならそのフェイスにより直接定義された属性だけがリターンされます。inheritが非nil
ならそのフェイスの:inherit
属性により指定される任意のフェイス、inheritがフェイスまたはフェイスのリストなら指定された属性が見つかるまでそれらも考慮します。リターンされる値が常に指定された値であることを保証するためにはinheritに値default
を使用してください。
この関数はフェイスfaceのフォント名をリターンする。
オプション引数frameが指定されたら、そのフレームのfaceのフォント名をリターンする。frameが省略かnil
なら選択されたフレームを使用する。そしてこの場合には、オプションの3つ目の引数characterが与えられると、characterにたいして使用されるフォント名をリターンする。
これらの関数はそれぞれフェイスfaceのフォアグラウンドカラーとバックグラウンドカラーを文字列としてリターンする。
この関数はフェイスfaceのバックグラウンド点描パターンの名前、もしなければnil
をリターンする。
この関数はfaceの:weight
属性がnormalよりbold寄り(semi-bold
、bold
、extra-bold
、ultra-bold
のいずれか)なら非nil
、それ以外ならnil
をリターンする。
この関数はfaceの:slant
属性がitalic
かoblique
なら非nil
、それ以外ならnil
をリターンする。
この関数はフェイスfaceが非nil
の:underline
属性を指定すれば非nil
をリターンする。
この関数はフェイスfaceが非nil
の:inverse-video
属性を指定すれば非nil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsが与えられたテキスト断片を表示する際には、そのテキストの視覚的外観は異なるソースから描画されるフェイスにより決定されるかもしれません。これら種々のソースが特定の文字にいたいして複数のフェイスを指定する場合には、Emacsはそれらのさまざまなフェイスの属性をマージします。以下にEmacsがフェイスをマージする順序を優先度順に記します:
region
フェイスを使用してそれをハイライトする。Standard
Faces in The GNU Emacs Manualを参照のこと。
nil
のface
属性をもつオーバーレイにテキストがある場合には、Emacsはそのプロパティにより指定されるフェイス(1つ以上)を適用する。そのオーバーレイがmouse-face
プロパティをもち、マウスがそのオーバーレイに十分に近ければEmacsはかわりにmouse-face
で指定されるフェイスかフェイス属性を適用する。オーバーレイのプロパティを参照のこと。
1つの文字を複数のオーバーレイがカバーする場合には、高優先度のオーバーレイが低優先度のオーバーレイをオーバーライドする。オーバーレイを参照のこと。
face
やmouse-face
プロパティを含む場合には、Emacsは指定されたフェイスやフェイス属性を適用する。特殊な意味をもつプロパティを参照のこと(これはFont Lockモードのフェイス適用方法。Font Lockモードを参照)。
mode-line
フェイスを適用する。選択されていないウィンドウのモードラインではEmacsはmode-line-inactive
フェイスを使用する。ヘッダーラインにたいしてはEmacsはheader-line
フェイスを適用する。
default
フェイスの属性を適用する。
各ステージにおいてフェイスが有効な:inherit
属性をもつ場合には、Emacsは値unspecified
をもつすべての属性が、親フェイス(1つ以上)由来で描画に使用される対応する値をもつものとして扱います。フェイスの属性を参照してください。親フェイスでも属性がunspecifiedのままかもしれないことに注意してください。その場合にはフェイスマージの次レベルでもその属性はunspecifiedのままです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
変数face-remapping-alist
はあるフェイスの外観のバッファーローカル、またはグローバルな変更にたいして使用されます。たとえばこれはtext-scale-adjust
コマンド(Text
Scale in The GNU Emacs Manualを参照)の実装に使用されています。
この変数の値は要素が(face
.
remapping)
という形式をもつalist。これによりEmacsはフェイスfaceをもつ任意のテキストを、通常のfaceの定義ではなくremappingで表示する。
remappingにはテキストプロパティface
にたいして適切な任意のフェイスspec、すなわちフェイス(フェイス名か属性/値ペアーのプロパティリスト)、またはフェイスのリストのいずれかを指定できる。詳細は特殊な意味をもつプロパティのface
テキストプロパティの記述を参照のこと。remappingはリマップされるフェイスにたいる完全な仕様としての役目をもつ。これは通常のfaceを変更せずに置き換える。
face-remapping-alist
がバッファーローカルなら、そのローカル値はそのバッファーでのみ効果をもつ。
注意:
フェイスのリマッピングは再帰的ではない。remappingが同じフェイス名faceを参照する場合には、直接またはremapping内の他の何らかのフェイスの:inherit
属性を通じて、その参照はfaceの通常の定義を使用する。たとえばmode-line
フェイスがface-remapping-alist
内の以下のエントリーでリマップされるなら:
(mode-line italic mode-line)
mode-line
フェイスの新たな定義はitalic
フェイス、および(リマップされていない)通常のmode-line
フェイスの定義から継承される。
以下の関数はface-remapping-alist
にたいする高レベルなインターフェースを実装します。ほとんどのLispコードはリマッピングが他の場所に適用されてしまうのを避けるために、face-remapping-alist
を直接セットするのではなくこれらの関数を使用するべきです。これらの関数はバッファーローカルなリマッピングを意図しており、すべてが副作用としてface-remapping-alist
をバッファーローカルにします。これらは以下の形式のface-remapping-alist
エントリーを管理します
(face relative-spec-1 relative-spec-2 ... base-spec)
上述したようにrelative-spec-Nとbase-specはそれぞれフェイス名か属性/値ペアーのプロパティリストです。相対的リマッピング(relative
remapping)エントリーrelative-spec-Nはそれぞれ関数face-remap-add-relative
とface-remap-remove-relative
により管理されます。これらはテキストサイズ変更のような単純な変更を意図しています。ベースリマッピング(base
remapping)エントリーbase-specは最低の優先度をもち、関数face-remap-set-base
とface-remap-reset-base
により管理されます。これはメジャーモードが制御下のバッファーでフェイスをリマップするために用いることを意図しています。
この関数はカレントバッファー内のフェイスfaceにたいして、相対的リマッピングとしてspecs内にフェイスspecを追加する。残りの引数specsはフェイス名のリスト、または属性/値ペアーのプロパティリストのいずれかの形式であること。
リターン値はcookieとしての役目をもつLispオブジェクト。後でそのリマッピングの削除を要する場合には、引数としてface-remap-remove-relative
にこのオブジェクトを渡すことができる。
;; 'escape-glyph'フェイスを'highlight'と'italic' ;; を組み合わせたフェイスにリマップする (face-remap-add-relative 'escape-glyph 'highlight 'italic) ;; 'default'フェイスのサイズを50%増加: (face-remap-add-relative 'default :height 1.5)
この関数は以前face-remap-add-relative
で追加された相対的リマッピングを削除する。cookieはリマッピングが追加されたときにface-remap-add-relative
がリターンしたLispオブジェクトであること。
この関数はカレントバッファー内のfaceのベースリマッピングをspecsにセットする。specsが空ならface-remap-reset-base
(以下参照)を呼び出したようにデフォルトベースリマッピングがリストアされる。これは単一の値nil
を含むspecsとは異なることに注意。これは逆の結果をもたらす(faceのグローバル定義は無視される)。
これはグローバルなフェイス定義を継承したデフォルトのbase-specを上書きするので、必要ならそのような継承を追加するのは呼び出し側の責任である。
この関数はfaceのベースリマッピングに、faceのグローバル定義から継承したデフォルト値にセットする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はフェイスの作成や処理を行う追加の関数です。
この関数はすべての定義済みフェイス名のリストをリターンする。
この関数はフェイスfaceのフェイス番号(face number)をリターンする。これはEmacs内の低レベルでフェイスを一意に識別する番号。フェイス番号によるフェイス参照を要するのは稀である。
この関数はフェイスfaceのドキュメント文字列、指定されていなければnil
をリターンする。
これはフェイスface1とフェイスface2が表示にたいして同じ属性をもつならt
をリターンする。
これはフェイスfaceの表示がデフォルトフェイスと異なるなら非nil
をリターンする。
フェイスエイリアス(face
alias)はあるフェイスにたいして等価な名前を提供します。エイリアスシンボルのface-alias
プロパティに対象となるフェイス名を与えることによってフェイスエイリアスを定義できます。以下の例ではmode-line
フェイスにたいするエイリアスとしてmodeline
を作成します。
(put 'modeline 'face-alias 'mode-line)
このマクロはcurrent-faceのエイリアスとしてobsolete-face
を定義するとともに、将来に削除されるかもしれないことを示すためにobsolete(時代遅れ)とマークする。whenはobsolete-face
がobsoleteになる時期を示す文字列であること(通常はバージョン番号文字列)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のフックはバッファー内のテキストに自動的にフェイスを割り当てるために使用されます。これはJit-Lockモードの実装の一部でありFont-Lockにより使用されます。
この変数は再表示を行う直前にEmacsの再表示により呼び出される関数のリストを保持する。これらはFont
Lockが有効でないときでも呼び出される。Font
Lockモードが有効なら、この変数は通常は単一の関数jit-lock-function
だけを保持する。
関数はバッファー位置posを単一の引数としてリストされた順に呼び出される。これらはカレントバッファー内のposで開始されるテキストにたいして集合的にフェイスの割り当てを試みること。
関数はface
プロパティをセットすることにより割り当てるフェイスを記録すること。またフェイスを割り当てたすべてのテキストに非nil
のfontified
プロパティも追加すること。このプロパティは再表示にたいして、そのテキストにたいしてそのフェイスがすでに割り当て済みであることを告げる。
posの後の文字がすでに非nil
のfontified
プロパティをもつがフォント表示化を要さない場合には、何も行わない関数を追加するのがおそらくよいアイデアである。ある関数が前の関数による割り当てをオーバーライドする場合には、実際に問題となるのは最後の関数終了後のプロパティである。
効率化のために通常は各呼び出しにおいて400から600前後の文字にフェイスを割り当てるように、これらの関数を記述することを推奨する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
テキストにたいしてEmacs Lispプログラムが何らかのフェイス割り当てを要する場合には、完全に新たなフェイスを定義するより特定の既存フェイス、またはそれらを継承したフェイスを使用するほうがよいアイデアである場合がしばしばあります。Emacsに特定の外観を与えるために別のユーザーが基本フェイス(basic face)をカスタマイズしていても、この方法なら追加のカスタマイズなしでプログラムは適合することでしょう。
以下にEmacsが定義する基本フェイスのいくつかをリストしました。これらに加えて、ハイライトがFont Lockモードによりまだ処理されていなかったり、いくつかのFont Lockフェイスが使用されていなければ、構文的ハイライトのためにFont Lockフェイスを使うようにしたいと思うかもしれません。Font Lockのためのフェイスを参照してください。
default
属性がすべて指定されたデフォルトフェイス。他のすべてのフェイスは暗にこのフェイスを継承する。未指定(unspecified)な任意の属性は、このフェイスの属性をデフォルトとする(フェイスの属性を参照)。
bold
italic
bold-italic
underline
fixed-pitch
variable-pitch
これらは名前に示されるような属性をもち(bold
はboldの:weight
属性をもつ)、それ以外のすべての属性は未指定(そのためにdefault
により与えられる)。
shadow
テキストの淡色表示(dimmed out)用。たとえばこれはミニバッファー内で無視されるファイル名部分に使用される(Minibuffers for File Names in The GNU Emacs Manualを参照)。
link
link-visited
ユーザーを別のバッファーや位置へと送るクリック可能テキストボタン用。
highlight
一時的に強調するべきテキスト範囲用。たとえば一般的にカーソルのハイライトにはmouse-face
プロパティが割り当てられる(特殊な意味をもつプロパティを参照)。
match
isearch
lazy-highlight
それぞれ定型検索(permanent search)のマッチ、インタラクティブ検索のマッチ、カレントのインタラクティブな検索のマッチ以外のlazyハイライトにたいするテキスト用。
error
warning
success
エラー、警告、成功に関するテキスト用。たとえば*Compilation*内のメッセージにたいして使用される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsがグラフィカルなディスプレイ上で文字を描画可能になる前に、まずその文字にたいするフォント(font)を選択しなければなりません20。Fonts in The GNU
Emacs
Manualを参照してください。Emacsは通常はその文字に割り当てられたフェイス、特にフェイス属性:family
、:weight
、:slant
、:width
(フェイスの属性を参照)にもとづいて自動的にフォントを選択します。フォントの選択は表示される文字にも依存します。表示できるのは文字セットが限定されているフォントもいくつかあります。利用可能なフォントがこの要件を完全に満たさなければEmacsはもっとも近いフォント(closest
matching font)を探します。このセクション内の変数はEmacsがこの選択を行う方法を制御します。
あるfamilyが指定されたが存在しなければ、この変数は試みるべき代替えのフォントファミリーを指定する。各要素は以下の形式をもつ:
(family alternate-families…)
familyが指定されたが利用できなければ、Emacsはalternate-familiesで与えられるファミリーで存在するものが見つかるまで1つずつファミリーを試みる。
希望するすべてのフェイス属性(:width
、:height
、:weight
、:slant
)に完全にマッチするフォントが存在しなければ、この変数はもっとも近いフォントの選択時に考慮すべきこれらの属性の順序を指定する。値はこれらの属性シンボルを重要度降順で含むリストであること。デフォルトは(:width
:height :weight :slant)
。
フォント選択はまずこのリスト内の最初の属性にたいして利用可能な最適マッチを探す。その後に、この方法で最適なフォントの中から2つ目の属性にたいして最適なマッチを検索、...のように選択を行う。
属性:weight
と:width
はnormal
を中心とする範囲のようなシンボリック値をもつ。より極端(normal
から離れた)なマッチは、より極端ではない(normal
に近い)マッチより幾分優先される。これは可能なかぎり非normalなフェイスが、normalなフェイスとは対照的になることを保証するようにデザインされている。
この変数が違いを生むケースの例はデフォルトフォントに等価なイタリックがない場合である。デフォルトの順ではitalic
フェイスはデフォルトのフォントに類似した非イタリックのフォントを使用するだろう。しかし:height
の前に:slant
を配置すると、italic
フェイスはたとえheightが同じでなくともイタリックフォントを使用するだろう。
この変数はregistryが指定されたがそれが存在しない場合に試みるべき代替えのフォントレジストリーを指定する。各要素は以下の形式をもつ:
(registry alternate-registries…)
registryが指定されたが利用できなければ、Emacsはalternate-registries内で存在するレジストリーが見つかるまで他のレジストリーを1つずつ試みる。
Emacsがスケーラブルフォントを使用するようにできますがデフォルトではそれらを使用しないようになっています。
この変数はどのスケーラブルフォントを使用するかを制御する。値nil
(デフォルト)はスケーラブルフォントを使用しないことを意味する。t
はそのテキストにたいして適切と思われる任意のスケーラブルフォントを使用することを意味する。
それ以外なら値は正規表現のリストであること。その場合には名前がこのリスト内の正規表現にマッチする任意のスケーラブルフォントの使用が有効になる。たとえば、
(setq scalable-fonts-allowed '("iso10646-1$"))
これはレジストリーがiso10646-1
のようなスケーラブルフォントの使用を可能にする。
この変数は特定のフォントにたいするスケーリングを指定する。値は以下の形式の要素をもつリストであること
(fontname-regexp . scale-factor)
使用しようとするフォントの名前がfontname-regexpにマッチする場合には、これはファクターscale-factorに対応した同様な大きさのフォントの選択を指示する。特定のフォントが提示する通常のheightやwidthが大きい、または小さい場合にフォントサイズを正規化するためにこの機能を使用できるだろう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はnameにマッチする利用可能なフォント名のリストをリターンする。nameはFontconfig、GTK、またはXLFDのいずれかのフォーマットによるフォント名を含む文字列であること(Fonts in The GNU Emacs Manualを参照)。XLFD文字列ではワイルドカード文字が使用できる。‘*’文字は任意の部分文字列、‘?’は任意の単一文字にマッチする。フォント名のマッチングではcase(大文字小文字)の違いは無視される。
オプション引数reference-faceとframeが指定された場合には、リターンされるリストにはその時点でフレームframe上でのreference-face (フェイス名)と同じサイズのフォントだけが含まれる。
オプション引数maximumはリターンされるフォント数の制限をセットする。これが非nil
ならリターン値は最初にマッチしたmaximum個のフォントの後が切り捨てられる。maximumに小さい値を指定すれば、そのパターンに多くのフォントがマッチするような場合に関数をより高速にできる。
オプション引数widthは希望するフォントの幅を指定する。これが非nil
なら、この関数は文字の幅(平均)がreference-faceのwidth倍の幅であるようなフォントだけをリターンする。
この関数はframe上のファミリーfamilyにたいして利用可能なフォントを記述するリストをリターンする。familyが省略かnil
ならこのリストはすべてのファミリーに適用されて、それはすなわち利用可能なすべてのフォントを含む。それ以外ならfamilyは文字列であること。これにはワイルドカード‘?’と‘*’を含めることができる。
このリストはframeのあるディスプレイを記述する。frameが省略かnil
なら、これは選択されたフレームのディスプレイに適用される(入力のフォーカスを参照)。
このリスト内の各要素は以下の形式のベクターであること:
[family width point-size weight slant fixed-p full registry-and-encoding]
最初の5つの要素はフェイス属性に対応する。あるフェイスにたいしてこれらの属性を指定した場合には、そのフォントが使用されるだろう。
最後の3つの要素は、そのフォントに関する追加の情報を与える。そのフォントが固定ピッチ(fixed-pitch)でなければfixed-pは非nil
。fullはそのフォントのフルネーム、registry-and-encodingはそのフォントのレジストリーとエンコーディングを与える。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フォントセット(fontset)とは、それぞれが文字コードの範囲に割り当てられるフォントのリストのことです。個々のフォントではEmacsがサポートする文字の全範囲を表示できませんが、フォントセットであれば表示することができます。フォントのようにフォントセットは名前をもつことができ、フレームやフェイスにたいしてフォントを指定する際に、フォント名としてフォントセット名を使用できます。以下はLispプログラム制御下でのフォントセット定義に関する情報です。
この関数は仕様文字列fontset-specに応じて新たなフォントセットを定義する。この文字列は以下のような形式であること:
fontpattern, [charset:font]…
カンマの前後の空白文字は無視される。
この文字列の最初の部分fontpatternは、最後の2つのフィールドが‘fontset-alias’であることを除外して標準Xフォント名形式をもつこと。
新たなフォントセットはlong名とshort名という2つの名前をもつ。long名はそれ全体がfontpattern、short名は‘fontset-alias’。いずれの名前でもこのフォントセットを参照できる。同じ名前がすでに存在するフォントセットではnoerrorがnil
ならエラーがシグナルされ、noerrorが非nil
ならこの関数は何も行わない。
オプション引数style-variant-pが非nil
なら、そのフォントセットのbold、italic、およびbold-italicも同様に作成するよう指示する。これらの変種フォントセットはshort名をもたずbold、および/またはitalicを示すようにfontpatternを変更して作成したlong名だけをもつ。
仕様文字列はそのフォントセット内でどのフォントを使用するかも宣言する。詳細は以下を参照。
構文‘charset:font’はある特定の文字セットにたいして、(このフォントセット内の)どのフォントを使用するかを指定します。ここでcharsetは文字セットの名前、fontはその文字セットにたいして使用するフォントです。仕様文字列内ではこの構文を任意の回数使用できます。
明示的に指定しなかった残りの文字セットにたいして、Emacsはfontpatternにもとづいてフォントを選択します。これは‘fontset-alias’をその文字セットを命名する値に置き換えます。文字セットASCIIにたいしては、‘fontset-alias’は‘ISO8859-1’に置き換えられます。
加えて後続の複数フィールドがワイルドカードなら、Emacsはそれらを1つのワイルドカードにまとめます。これは自動スケールフォント(auto-scaled fonts)の使用を防ぐためです。フォントを大きくスケーリングすることにより作成されたフォントは編集に使用できず、小さくスケーリングされたフォントは、それ自身のサイズがより小さいフォントを使用する(Emacsが行う方法)ほうがよいので有用ではありません。
つまり以下のようなfontpatternなら
-*-fixed-medium-r-normal-*-24-*-*-*-*-*-fontset-24
ASCIIにたいするフォントspecは以下のようになるでしょう:
-*-fixed-medium-r-normal-*-24-*-ISO8859-1
またChinese GB2312文字にたいするフォントspecは以下のようになるでしょう:
-*-fixed-medium-r-normal-*-24-*-gb2312*-*
上記のフォントspecにマッチするChineseフォントをもっていないかもしれません。ほとんどのXディストリビューションには、familyフィールドに‘song ti’か‘fangsong ti’をもつChineseフォントだけが含まれます。そのような場合には以下のように‘Fontset-n’を指定できます:
Emacs.Fontset-0: -*-fixed-medium-r-normal-*-24-*-*-*-*-*-fontset-24,\ chinese-gb2312:-*-*-medium-r-normal-*-24-*-gb2312*-*
この場合にはChinese GB2312以外のすべての文にたいするフォントspecはfamilyフィールドに‘fixed’をもち、Chinese GB2312にたいするフォントspecはfamilyフィールドにワイルドカード‘*’をもちます。
この関数は指定されたcharacterにたいして、font-specのフォントマッチングを使用するように既存のフォントセットnameを変更する。
nameがnil
ならこの関数はframeのフォントセット、frameがnil
なら選択されたフレームのフォントセットを変更する。
nameがt
ならこの関数はshort名が‘fontset-default’であるようなデフォルトフォントセットを変更する。
characterには(from
.
to)
のようなコンスを指定できる。ここでfromとtoは文字コードポイント。この場合には範囲fromからto
(両端を含む)までのすべての文字にたいしてfont-specを使用する。
characterには文字セットも指定できる。この場合にはその文字セット内のすべての文字にたいしてfont-specを使用する。
characterにはスクリプト名も指定できる。この場合にはその文字セット内のすべての文字にたいしてfont-specを使用する。
font-specは関数font-spec
が作成したfont-specオブジェクトかもしれない(低レベルのフォント表現を参照)。
font-specにはコンス(family
.
registry)
を指定できる。ここでfamilyはフォントのファミリー名(先頭にfoundry名が含まれるかもしれない)、registryはフォントのレジストリー名(末尾にエンコーディング名が含まれるかもしれない)。
font-specにはフォント名文字列も指定できる。
font-specには、指定されたcharacterにたいするフォントが存在しないことを明示的に指定するnil
を指定できる。これはたとえばUnicodeのPUA(Private
Use Area)由来のようなグリフをもたない文字のフォントにたいするシステムワイドの高価な検索を避けるために有用。
オプション引数addが非nil
なら以前セットされたフォントspecにfont-specを追加する方法を指定する。prepend
ならfont-specは先頭、append
ならfont-specは末尾に追加される。デフォルトではfont-specは以前のセッティングをオーバーライドする。
たとえば以下は文字セットjapanese-jisx0208
に属するすえての文字にたいして、ファミリー名が‘Kochi
Gothic’であるようなフォントを使用するようにデフォルトフォントセットを変更する。
(set-fontset-font t 'japanese-jisx0208 (font-spec :family "Kochi Gothic"))
この関数はEmacsがcharを表示できるようならt
をリターンする。より正確には選択されたフレームのフォントセットが、charが属する文字セットを表示するためのフォントをもてばt
をリターンする。
フォントセットは文字単位でフォントを指定できる。フォントセットがこれを行う場合には、この関数の値は正確ではないかもしれない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
通常はフォントを直接扱う必要はありません。これを行う必要がある場合にはこのセクションでその方法を説明します。
Emacs Lispではフォントはフォントオブジェクト(font objects)、フォントspec(font specs)、フォントエンティティー(font entities)という3つの異なるLispオブジェクトを使用して表現されます。
objectがフォントオブジェクト、フォントspec、フォントエンティティーならt
、それ以外ならnil
をリターンする。
オプション引数typeが非nil
なら、チェックするLispオブジェクトの正確なタイプを決定する。この場合にはtypeはfont-object
、font-spec
、font-entity
のいずれかであること。
フォントオブジェクトはEmacsがオープンしたフォントを表します。Lispでフォントオブジェクトは変更できませんが調べることはできます。
ウィンドウwindow内の位置positionにある文字を表示するために使用されているフォントオブジェクトをリターンする。windowがnil
の場合のデフォルトは選択されたウィンドウ。stringがnil
ならpositionはカレントバッファー内の位置を指定する。それ以外ならstringは文字列、positionはその文字列内での位置を指定すること。
フォントspecはフォントを探すために使用できる仕様セットを含むLispオブジェクトです。フォントspec内の仕様にたいして1つ以上のフォントがマッチすることができます。
arguments内の仕様を使用して新たなフォントspecをリターンする。これはproperty
-value
のペアーであること。可能な仕様は以下のとおり:
:name
XLFD、Fontconfig、GTKいずれかのフォーマットによるフォント名(文字列)。Fonts in The GNU Emacs Manualを参照のこと。
:family
:foundry
:weight
:slant
:width
これらは同名のフェイス属性と同じ意味をもつ。フェイスの属性を参照のこと。
:size
フォントサイズ。非負の整数はピクセル単位、浮動小数点数ならポイントサイズを指定する。
:adstyle
‘sans’のような、そのフォントにたいするタイポグラフィックスタイル(typographic style)の追加情報。値は文字列かシンボルであること。
:registry
‘iso8859-1’のようなフォントの文字セットレジストリーとエンコーディング。値は文字列かシンボルであること。
:script
そのフォントがサポートしなければならないスクリプト(シンボル)。
:lang
そのフォントがサポートするべき言語。値は名前が2文字のISO-639言語名であるようなシンボルであること。Xでは値は(もし空でなければ)フォントのXLFD名の“Additional Style”フィールドにたいしてマッチされる。MS-Windowsではそのspecにマッチするフォントにはその言語にたいして必要なコードページのサポートが要求される。現在のところこのプロパティでは‘ja’、‘ko’、‘zh’というCJK言語の小セットだけがサポートされる。
:otf
複雑なテキストレイアウトを必要とするスクリプトをサポートするGNU/Linux上の‘libotf’のようなライブラリーとともにEmacsがコンパイルされているような場合には、そのフォントはそれらのOpenType機能をサポートするOpenTypeフォントでなければならない。値は以下の形式のリストでなければならない
(script-tag langsys-tag gsub gpos)
ここでscript-tagはOpenTypeスクリプトタグシンボル、langsys-tagはOpenType言語システムタグシンボル(nil
ならデフォルト言語システムを使用)、gsub
はOpenType
GSUB機能タグシンボル(何も要求されなければnil
)、gpos
はOpenType
GPOS機能タグシンボルのリスト(何も要求されなければnil
)。gsub
やgpos
がリストなら、そのリスト内のnil
要素は、そのフォントが残りすべてのタグシンボルにマッチしてはならないことを意味する。gpos
は省略可。
フォントspec font-spec内のプロパティpropertyにvalueをセットする。
フォントエンティティーはオープンする必要がないフォントへの参照です。フォントオブジェクトとフォントspecの中間的な性質をもちフォントspecとは異なり、フォントオブジェクトと同じように単一かつ特定のフォントを参照します。フォントオブジェクトとは異なりフォントエンティティーの作成では、そのフォントのコンテンツはコンピューターへのメモリーにロードされません。Emacsはスケーラブルフォントを参照するために単一のフォントエンティティーから複数の異なるサイズのフォントオブジェクトをオープンするかもしれません。
この関数はフレームframe上のフォントspec
font-specにもっともマッチするフォントエンティティーをリターンする。frameがnil
の場合のデフォルトは選択されたフレーム。
この関数はフォントspec font-specにマッチするすべてのフォントエンティティーのリストをリターンする。
オプション引数frameが非nil
なら、そのフォントが表示されるフレームを指定する。オプション引数numが非nil
なら、それはリターンされるリストの最大長を指定する整数だること。オプション引数preferが非nil
なら、それはリターンされるリスト順を制御するために使用する別のフォントspecであること。リターンされるフォントspecはそのフォントspecにもっとも近い降順にソートされて格納される。
:font
属性の値としてフォントspec、フォントエンティティー、フォント名文字列を渡してset-face-attribute
を呼び出すと、Emacsは表示に利用可能なもっともマッチするフォントをオープンします。そしてそのフェイスにたいする:font
属性の実際の値として、対応するフォントオブジェクトを格納します。
以下の関数はフォントに関する情報を取得するために使用できます。これらの関数のfont引数にはフォントオブジェクト、フォントエンティティー、またはフォントspecを指定できます。
この関数はfontにたいするフォントプロパティpropertyの値をリターンする。
fontがフォントspecであり、そのフォントspecがpropertyを指定しなければリターン値はnil
。fontがフォントオブジェクトかフォントエンティティーなら、:scriptプロパティにたいする値はそのフォントがサポートするスクリプトのリストかもしれない。
この関数はfontに対応するフェイス属性のリストをリターンする。オプション引数frameはフォントが表示されるフレームを指定する。これがnil
なら選択されたフレームが使用される。リターン値は以下の形式
(:family family :height height :weight weight :slant slant :width width)
ここでfamily、height、weight、slant、widthの値はフェイス属性の値。fontにより指定されない場合には、いくつかのキー/属性ペアーはこのリストから省略されるかもしれない。
この関数はfontにマッチするXLFD((X Logical Font
Descriptor))を文字列としてリターンする。XLFDに関する情報はFonts in The GNU Emacs
Manualを参照のこと。その名前がXLFD(最大255文字を含むことが可能)にたいして長すぎれば、この関数はnil
をリターンする。
オプション引数fold-wildcardsが非nil
なら連続するワイルドカードは1つにまとめられる。
以下の2つの関数はフォントに関して重要な情報をリターンします。
この関数はframeで使用されるような文字列nameで指定されたフォントに関する情報をリターンする。frameが省略かnil
の場合のデフォルトは選択されたフレーム。
この関数は[opened-name full-name size height
baseline-offset relative-compose default-ascent
max-width ascent descent space-width
average-width filename
capability]
という形式のベクターによる値をリターンする。以下はこのベクターの各コンポーネントの意味:
フォントのオープンに使用された名前(文字列)。
フォントの完全名(文字列)。
フォントのピクセルサイズ。
フォント高さ(ピクセル単位)。
ASCIIベースラインからのピクセル単位のオフセット(上方が正)。
文字の組み合わせ(compose)の方式を制御する数値。
このフォントのアセント(ascent)とディセント(descent)。これら2つの数値の合計は上述のheightと等しくなること。
そのフォントのスペース文字の幅(ピクセル単位)。
そのフォントの文字の平均幅。これが0ならEmacsは表示のテキストレイアウト計算時にかわりにspace-widthの値を使用する。
フォントのファイル名(文字列)。フォントのバックエンドがフォントのファイル名を見つける手段を提供しなければnil
もあり得る。
最初の要素がフォントタイプを表すx
、opentype
、truetype
、type1
、pcf
、bdf
のいずれかのシンボルであるようなリスト。OpenTypeフォントでは、フォントによりサポートされる機能GSUBとGPOSの2つの要素が含まれる。これらの要素はそれぞれ((script
(langsys feature …) …)
…)
という形式のリストであり、ここでscriptはOpenTypeのscriptタグを表すシンボル、langsysはOpenTypeのlangsysタグを表すシンボル(またはデフォルトのlangsysを表すnil
)、そよびfeatureはそれぞれOpenTypeのfeatureタグを表す。
この関数はfont-objectに関する情報をリターンする(これは引数としてフォント名を文字列で受け取るfont-info
とは対照的)。
この関数は[name filename pixel-size max-width
ascent descent space-width average-width
capability]
という形式のベクターで値をリターンする。以下はこのベクターの各要素の意味:
フォント名(文字列)。
フォントのファイル名(文字列)。フォントのバックエンドがフォントのファイル名を見つける手段を提供しなければnil
もあり得る。
フォントをオープンするために使用されたフォントのピクセルサイズ。
フォントの最大のアドバンス幅。
このフォントのアセント(ascent)とディセント(descent)。これら2つの数値の合計はフォントの高さを与える。
そのフォントのスペース文字の幅(ピクセル単位)。
そのフォントの文字の平均幅。これが0ならEmacsは表示のテキストレイアウト計算時にかわりにspace-widthの値を使用する。
最初の要素がフォントタイプを表すx
、opentype
、truetype
、type1
、pcf
、bdf
のいずれかのシンボルであるようなリスト。OpenTypeフォントでは、フォントによりサポートされる機能GSUBとGPOSの2つの要素が含まれる。これらの要素はそれぞれ((script
(langsys feature …) …)
…)
という形式のリストであり、ここでscriptはOpenTypeのscriptタグを表すシンボル、langsysはOpenTypeのlangsysタグを表すシンボル(またはデフォルトのlangsysを表すnil
)、そよびfeatureはそれぞれOpenTypeのfeatureタグを表す。
以下の4つの関数はさまざまなフェイスにより使用されるフォントに関するサイズ情報をリターンして、Lispプログラム内でのさまざまなレイアウトの検討を可能にします。これらの関数は問い合わせられたフェイスがリマップされていたら、リマップされたフェイスに関する情報をリターンすることによりフェイスのシマップを考慮します。フェイスのリマップを参照してください。
この関数はカレントバッファーのデフォルトフェイスで使用されるフォントの平均幅をピクセル単位でリターンする。
この関数はカレントバッファーのデフォルトフェイスで使用されるフォントの高さをピクセル単位でリターンする。
この関数はwindow内のfaceで使用されるフォントの平均幅をピクセル単位でリターンする。windowには生きたウィンドウを指定しなければならない。nil
か省略ならwindowのデフォルトは選択されたウィンドウ、faceのデフォルトはwindow内のデフォルトフェイス。
この関数はwindow内のfaceで使用されるフォントの高さをピクセル単位でリターンする。windowには生きたウィンドウを指定しなければならない。nil
か省略ならwindowのデフォルトは選択されたウィンドウ、faceのデフォルトはwindow内のデフォルトフェイス。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
グラフィカルなディスプレイではEmacsは各ウィンドウに隣接してフリンジ(fringes)を描画します。これは切り詰め(truncation)、継続(continuation)、水平スクロールを示すビットマップを表示できる側面の細い垂直ストリップです。
37.13.1 フリンジのサイズと位置 | ウィンドウフリンジの配置場所を指定する。 | |
37.13.2 フリンジのインジケーター | ウィンドウフリンジ内にインジケーターアイコンを表示する。 | |
37.13.3 フリンジのカーソルFringe Cursors | 右フリンジ内にカーソルを表示する。 | |
37.13.4 フリンジのビットマップ | フリンジインジケーターにたいしてビットマップを指定する。 | |
37.13.5 フリンジビットマップのカスタマイズ | フリンジ内で使用する独自ビットマップの指定。 | |
37.13.6 オーバーレイ矢印 | 位置を示す矢印の表示。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のバッファーローカル変数はバッファーを表示するウィンドウのフリンジの位置と幅を制御します。
フリンジは通常はディスプレイマージンとウィンドウテキストの間に表示される。この値が非nil
ならフリンジはディスプレイマージンの外側に表示される。マージン内への表示を参照のこと。
この変数が非nil
なら、それは左フリンジの幅をピクセル単位で指定する。値nil
はそのウィンドウのフレームの左フリンジ幅を使用することを意味する。
この変数が非nil
なら、それは右フリンジの幅をピクセル単位で指定する。値nil
はそのウィンドウのフレームの右フリンジ幅を使用することを意味する。
これらの変数にたいして値を指定しないすべてのバッファーは、フレームパラメーターleft-fringe
およびright-fringe
で指定された値を使用します(レイアウトのパラメーターを参照)。
上記の変数はサブルーチンとしてset-window-fringes
を呼び出す関数set-window-buffer
(バッファーとウィンドウを参照)を通じて実際に効果をもちます。これらの変数のいずれかを変更しても影響を受ける各ウィンドウでset-window-buffer
を呼び出さなければ、そのバッファーを表示する既存のウィンドウのフリンジ表示は更新されません。個別のウィンドウでのフリンジ表示を制御するためにset-window-fringes
を使用することもできます。
この関数はウィンドウwindowのフリンジ幅をセットする。windowがnil
なら選択されたウィンドウが使用される。
引数leftは左フリンジ、同様にrightは右フリンジにたいしてピクセル単位で幅を指定する。いずれかにたいする値nil
はデフォルトの幅を意味する。outside-marginsが非nil
ならフリンジをディスプレイマージンの外側に表示することを指定する。
この関数はウィンドウwindowのフリンジに関する情報をリターンする。windowが省略かnil
なら選択されたウィンドウが使用される。値は(left-width
right-width outside-margins)
という形式。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フリンジインジケーター(Fringe indicators)は行の切り詰めや継続、バッファー境界などを示すウィンドウフリンジ内に表示される小さいアイコンのことです。
これが非nil
ならEmacsはグラフィカルなディスプレイ上で、バッファー終端にある空行それぞれにたいしてフリンジ内に特別なグリフを表示する。フリンジを参照のこと。この変数はすべてのバッファーにおいて自動的にバッファーローカルになる。
このバッファーローカル変数はウィンドウフリンジ内でバッファー境界とウィンドウのスクロールを示す方法を制御する。
Emacsはバッファー境界(そのバッファーの最初の行と最後の行)がスクリーン上に表示された際には、それを三角アイコン(angle icon)で示すことができる。加えてスクリーンより上にテキストが存在すれば上矢印(up-arrow)、スクリーンの下にテキストが存在すれば下矢印(down-arrow)をフリンジ内に表示してそれを示すことができる。
基本的な値として3つの値がある:
nil
これらのフリンジアイコンを何も表示しない。
left
左フリンジに三角アイコンと矢印を表示する。
right
右フリンジに三角アイコンと矢印を表示する。
左フリンジに三角アイコンを表示して矢印を表示しない。
値がそれ以外ならどのフリンジインジケーターをどこに表示するかを指定するalistであること。alistの各要素は(indicator
.
position)
のような形式をもつ。ここでindicatorはtop
、bottom
、up
、down
、またはt
(指定されていないすべてのアイコンをカバーする)のいずれかでありpositionはleft
、right
、またはnil
のいずれか。
たとえば((top . left) (t . right))
は左フリンジにtop angleビットマップを、右フリンジにbottom
angleビットマップと両arrowビットマップを配置する。左フリンジにangleビットマップを表示してarrowビットマップを表示しないようにするには((top
. left) (bottom . left))
を使用する。
このバッファーローカル変数は論理的ロジカルフリンジインジケーターから、ウィンドウフリンジ内に実際に表示されるビットマップへのマッピングを指定する。値は(indicator
.
bitmaps)
のような要素をもつalist。ここでindicatorは論理的インジケータータイプ、bitmapsはそのインジケーターに使用するフリンジビットマップを指定する。
indicatorはそれぞれ以下のシンボルのいずれかであること:
truncation
、continuation
。行の切り詰めと継続に使用される。
up
、down
、top
、bottom
、top-bottom
indicate-buffer-boundaries
が非nil
の際に使用される。up
とdown
は、そのウィンドウ端より上と下にあるバッファー境界を示す。top
とbottom
はバッファーの最上端と最下端のテキスト行を示す。top-bottom
はバッファー内にテキスト行1行だけが存在することを示す。
empty-line
indicate-empty-lines
が非nil
の際に空行を示すために使用される。
overlay-arrow
オーバーレイ矢印に使用される(オーバーレイ矢印を参照)。
各bitmapsの値にはシンボルのリスト(left right [left1
right1])
を指定できる。シンボルleftとrightは特定のインジケーターにたいして左および/または右フリンジに表示するビットマップを指定する。left1とright1はインジケーターbottom
とtop-bottom
に固有であり、最後の改行をもたない最後のテキスト行を示すために使用される。かわりにbitmapsに左フリンジと右フリンジの両方で使用される単一のシンボルを指定することもできる。
標準のビットマップシンボルのリストと自身で定義する方法についてはフリンジのビットマップを参照のこと。加えてnil
は空ビットマップ(表示されないインジケーター)を表す。
fringe-indicator-alist
がバッファーローカルな値をもち、論理的インジケーターにたいしてビットマップが定義されていないかビットマップがt
ならば、fringe-indicator-alist
のデフォルト値から対応する値が使用される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ある行がウィンドウと正確に同じ幅なとき、2行を使用するかわりにEmacsは右フリンジ内にカーソルを表示します。フリンジ内のカーソルを表すために使用されるビットマップの違いはカレントバッファーのカーソルタイプに依存します。
これが非nil
なら、ウィンドウと正確に同じ幅の(最後の改行文字に継続されない)行は継続されない。ポイントが行端に達した際には、カーソルはかわりに右フリンジに表示される。
この変数は論理的カーソルタイプから、右フリンジ内に実際に表示されるフリンジビットマップへのマッピングを指定する。値は各要素が(cursor-type
.
bitmap)
のような形式をもつようなalist。ここでbitmapは使用するフリンジビットマップ、cursor-typeは表示するカーソルタイプ。
cursor-typeはそれぞれbox
、hollow
、bar
、hbar
、hollow-small
のいずれかであること。最初の4つはフレームパラメーターcursor-type
の場合と同じ意味をもつ(カーソルのパラメーターを参照)。hollow-small
タイプは特定のディスプレイ行にたいして通常のhollow-rectangle
が高すぎる際にhollow
のかわりに使用される。
bitmapはそれぞれ、その論理的カーソルタイプにたいして表示されるフリンジビットマップを指定するシンボルであること。 詳細はフリンジのビットマップを参照のこと。
fringe-cursor-alist
がバッファーローカルな値をもち、カーソルタイプにたいして定義されたビットマップが存在しなければ、fringes-indicator-alist
のデフォルト値の対応する値が使用される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フリンジビットマップ(fringe
bitmaps)は行の切り詰めや継続、バッファー境界、オーバーレイ矢印等にたいする論理的フリンジインジケーターを表現する実際のビットマップです。それぞれのビットマップはシンボルにより表されます。
これらのシンボルはフリンジインジケーターからビットマップへのマッピングを行う変数fringe-indicator-alist
(フリンジのインジケーターを参照)、およびフリンジカーソルからビットマップへのマッピングを行う変数fringe-cursor-alist
(フリンジのカーソルFringe Cursorsを参照)から参照されます。
Lispプログラムも行内に出現する文字の1つにdisplay
プロパティを使用することにより、左フリンジまたは右フリンジ内にビットマップを直接表示することができます。そのような表示指定は以下の形式をもちます
(fringe bitmap [face])
fringeは、left-fringe
かright-fringe
いずれかのシンボルです。bitmapは表示するビットマップを識別するシンボルです。オプションのfaceは、そのフォアグラウンドカラーをビットマップの表示に使用するフェイスの名前です。このフェイスは自動的にfringe
フェイスにマージされます。
以下はEmacsが定義する標準的なフリンジビットマップと、(fringe-indicator-alist
とfringe-cursor-alist
を通じて)Emacs内で現在それらが使用される方法のリストです。
left-arrow
、right-arrow
切り詰められた行を示すために使用される。
left-curly-arrow
、right-curly-arrow
継続された行を示すために使用される。
right-triangle
、left-triangle
前者はオーバーレイ矢印により使用され、後者は使用されない。
up-arrow
、down-arrow
、top-left-angle
top-right-angle
bottom-left-angle
、bottom-right-angle
top-right-angle
、top-left-angle
left-bracket
、right-bracket
、top-right-angle
、top-left-angle
バッファー境界を示すために使用される。
filled-rectangle
、hollow-rectangle
filled-square
、hollow-square
vertical-bar
、horizontal-bar
フリンジカーソルの異なるタイプにたいして使用される。
empty-line
、exclamation-mark
、question-mark
、exclamation-mark
Emacsの中核機能では使用されない。
次のサブセクションではフリンジビットマップを独自に定義する方法を説明します。
この関数はウィンドウwindow内の位置posを含むディスプレイ行のフリンジビットマップをリターンする。リターン値は(left
right
ov)
という形式をもつ。ここでleftは左フリンジ内のフリンジビットマップにたいするシンボル(ビットマップなしならnil
)、rightは同様に右フリンジにたいして、ovが非nil
なら左フリンジにオーバーレイ矢印が存在することを意味する。
window内でposが可視でなければ値はnil
。windowがnil
なら選択されたウィンドウを意味する。posがnil
ならwindow内のポイントの値を意味する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はシンボルbitmapを新たなフリンジビットマップとして定義、またはその名前の既存のビットマップを置き換える。
引数bitsは使用するイメージを指定する。これは各要素(整数)が対応するビットマップの1行を指定する文字列か整数ベクターであること。整数の各ビットはそのビットマップの1ピクセル、低位ビットはそのビットマップの最右ピクセルに対応する。
高さは通常はbitsの長さ。しかし非nil
のheightにより異なる高さを指定できる。幅は通常は8だが非nil
のwidthにより異なる幅を指定できる。widthは1から16の整数でなければならない。
引数alignはそのビットマップが使用される行範囲に相対的なビットマップの位置を指定する。デフォルトはそのビットマップの中央。指定できる値はtop
、center
、bottom
。
align引数にはリスト(align
periodic)
も指定できて、alignは上述のように解釈される。periodicが非nil
なら、それはbits
内の行が指定される高さに達するのに十分な回数繰り返されるべきであることを指定する。
この関数はbitmapにより識別されるフリンジビットマップを破棄する。bitmapが標準フリンジビットマップを識別する場合には、それを完全に消去するかわりに実際にはそのビットマップの標準定義をリストアする。
これはフリンジビットマップbitmapにたいするフェイスにfaceをセットする。faceがnil
ならfringe
フェイスを選択する。ビットマップのフェイスはそれを描画するカラーを制御する。
faceはfringe
にマージされるためfaceは通常はフォアグラウンドカラーだけを指定すること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
オーバーレイ矢印(overlay arrow)は、バッファー内の特定の行にたいしてユーザーに注意を促すために有用です。たとえばデバッガーでのインターフェースに使用されるモードでは、オーバーレイ矢印は実行されているコード行を示します。この機能はオーバーレイ(overlays)にたいして何も行いません(オーバーレイを参照)。
この変数は特定の行にたいして注意を喚起するために表示する文字列、または矢印機能が使用されていなければnil
を保持する。グラフィカルなディスプレイではこの文字列のコンテンツは無視され、かわりにフリンジ領域からディスプレイ領域左側にグリフが表示される。
この変数はオーバーレイ矢印を表示する箇所を示すマーカーを保持する。これは行の先頭となるポイントであること。非グラフィカルなディスプレイではその行の先頭に矢印テキストが表示され、矢印テキストが表示されないときに表示されるべきテキストがオーバーレイされる。その矢印は通常は短く行は普通はインデントで開始されるので、上書きが問題となることは通常はない。
オーバーレイ矢印の文字列は、そのバッファーのoverlay-arrow-position
の値がバッファー内を指せば与えられた任意のバッファーで表示される。したがってoverlay-arrow-position
のバッファーローカルなバインディングを作成することにより、複数のオーバーレイ矢印の表示が可能である。しかしこれを達成するためには、overlay-arrow-variable-list
を使用するほうが通常はより明快。
before-string
プロパティをもつオーバーレイを作成することにより同様のことを行うことができます。オーバーレイのプロパティを参照してください。
変数overlay-arrow-variable-list
を通じて複数のオーバーレイ矢印を定義できます。
この変数の値は、それぞれがオーバーレイ矢印の位置を指定する変数のリスト。変数overlay-arrow-position
はこのリスト上にあるために通常の意味をもつ。
このリスト上の各変数は対応するオーバーレイ矢印位置に表示するためのオーバーレイ矢印文字列を指定するoverlay-arrow-string
プロパティ(テキスト端末用)、およびフリンジビットマップを指定するoverlay-arrow-bitmap
プロパティ(グラフィカル端末用)をもつことができます。これらのプロパティがセットされていなければデフォルトのフリンジインジケーターoverlay-arrow-string
とoverlay-arrow
が使用されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレームパラメーターvertical-scroll-bars
はそのフレーム内のウィンドウが垂直スクロールバーをもつべきかと、それらが左か右のいずれかに配置されるべきかを通常は制御します。フレームパラメーターscroll-bar-width
はそれらの幅を指定します(nil
はデフォルトを意味する)。
フレームパラメーターhorizontal-scroll-bars
はフレーム内のウィンドウが水平スクロールバーをもつかどうかを制御します。フレームパラメーターscroll-bar-height
はそれらの高さを指定します(nil
はデフォルトを意味する)。レイアウトのパラメーターを参照のしてください。
水平スクロールバーはすべてのプラットフォームで利用可能ではありません。引数を受け取らない関数horizontal-scroll-bars-available-p
は、システム上で水平スクロールバーが利用可能なら非nil
をリターンします。
以下の3つの関数は引数として生きたフレームを受け取り、デフォルトは選択されたフレームです。
この関数はフレームframeのスクロールバーのタイプを報告する。値はコンスセル(vertical-type .
horizontal-type)
。ここでvertical-typeはleft
、right
、またはnil
(スクロールバーなしを意味する)のいずれか。horizontal-typeはbottom
かnil
(水平スクロールバーなしを意味する)のいずれか。
この関数はウィンドウwindowにたいして垂直スクロールバーの幅をピクセル単位でリターンする。
この関数はframeの水平スクロールバーの高さをピクセル単位でリターンする。
以下の関数を使用することにより、特定のウィンドウにたいするフレーム固有のセッティングをオーバーライドできます:
この関数はウィンドウwindowのスクロールバーの幅および/または高さ、タイプをセットする。
widthはピクセル単位で垂直スクロールバーの幅を指定する(nil
はそのフレームにたいして指定された幅の使用を意味する)。vertical-typeは垂直スクロールバーをもつかどうか、もつ場合にはその位置を指定する。可能な値はleft
、right
、t
(フレームのデフォルトの使用を意味する)、垂直スクロールバーなしならnil
のいずれか。
heightはピクセル単位で水平スクロールバーの高さを指定する(nil
はそのフレームにたいして指定された高さの使用を意味する)。horizontal-typeは水平スクロールバーをもつかどうかを指定する。可能な値はbottom
、t
(フレームのデフォルトの使用を意味する)、水平スクロールバーなしならnil
のいずれか。
windowがnil
なら選択されたウィンドウが使用される。
以下の4つの関数は引数として生きたウィンドウを受け取り、デフォルトは選択されたウィンドウです。
この関数は(width columns vertical-type height
lines horizontal-type)
という形式のリストをリターンする。
値widthは垂直スクロールバーの幅に指定された値(nil
もあり得る)。columnsは垂直スクロールバーが実際に占有する列数(丸められているかもしれない)。
値heightは水平スクロールバーの高さに指定された値(nil
もあり得る)。linesは水平スクロールバーが実際に占有する行数(丸められているかもしれない)。
この関数はウィンドウwindowにたいするスクロールバータイプを報告する。値はコンスセル(vertical-type
.
horizontal-type)
。window-scroll-bars
とは異なりフレームのデフォルトとscroll-bar-mode
を考慮して実際に使用されているスクロールバータイプを報告する。
この関数はwindowの垂直スクロールバーの幅をピクセル単位でリターンする。
この関数は、windowの水平スクロールバーの高さをピクセル単位でリターンする。
あるウィンドウにたいしてset-window-scroll-bars
でこれらの値を指定しない場合には、表示されようとするバッファーのバッファーローカル変数vertical-scroll-bar
、horizontal-scroll-bar
、scroll-bar-width
、scroll-bar-height
がウィンドウのスクロールバーを制御します。set-window-buffer
はこれらの変数を調べる関数です。あるウィンドウですでに可視なバッファーでこれらを変更した場合には、すでに表示されているのと同じバッファーを指定してset-window-buffer
を呼び出すことにより、そのウィンドウに新たな値を記録させることができます。
以下の変数をセット(セットにより自動的にバッファーローカルになる)することにより、特定のバッファーのスクロールバーの外観を制御できます。
この変数は垂直スクロールバーの配置を指定する。可能な値はleft
、right
、そのフレームのデフォルトの使用を意味するt
、スクロールバーなしのnil
のいずれか。
この変数は水平スクロールバーの配置を指定する。可能な値はbottom
、そのフレームのデフォルトの使用を意味するt
、スクロールバーなしのnil
のいずれか。
この変数はそのバッファーの垂直スクロールバーをピクセル単位で量った幅を指定する。値nil
はフレームにより指定された値の使用を意味する。
この変数はそのバッファーの水平スクロールバーをピクセル単位で量った高さを指定する。値nil
はフレームにより指定された値の使用を意味する。
最後に変数scroll-bar-mode
とhorizontal-scroll-bar-mode
をカスタマイズすることにより、すべてのフレームでのスクロールバーの表示を切り替えることができます。
この変数はすべてのフレームに垂直スクロールバーを配置するべきかと、その場所を制御する。可能な値は、スクロールバーなしのnil
、左にスクロールバーを配置するleft
、右にスクロールバーを配置するright
のいずれか。
この変数はすべてのフレームに水平スクロールバーを表示するかどうかを制御する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウディバイダーとはフレームのウィンドウ間に描画されるバーのことです。右(right)ディバイダーはあるウィンドウと、その右に隣接する任意のウィンドウの間に描画されます。その幅(厚さ)はフレームパラメーターright-divider-width
で指定されます。下(bottom)ディバイダーはあるウィンドウと、その下に隣接するウィンドウやエコーエリアとの間に描画されます。その幅はフレームパラメーターbottom-divider-width
で指定されます。いずれの場合でも幅に0を指定すると、そのようなディバイダーを描画しないことを意味します。レイアウトのパラメーターを参照してください。
技術的には右ディバイダーはそれの左にあるウィンドウに所属して、その幅がそのウィンドウのトータル幅に寄与することを意味します。下ディバイダーは上にあるウィンドウに所属して、その幅がそのウィンドウのトータル高さに寄与することを意味します。ウィンドウのサイズを参照してください。あるウィンドウが右ディバイダーと左ディバイダーの両方をもつ場合には下ディバイダーが優勢になります。これは右ディバイダーが下ディバイダーの上で終端されるのに比べて、下ディバイダーはそのウィンドウの完全なトータル幅で描画されることを意味しています。
ディバイダーはマウスでドラッグできるのでマウスで隣接するウィンドウのサイズを調整するために有用です。これらはスクロールバーやモードラインが表示されていないときに隣接するウィンドウを視覚的に分離する役目もあります。以下の3つのフェイスによりディバイダーの外観をカスタマイズできます:
window-divider
ディバイダーの幅が3ピクセル未満のときは、このフェイスのフォアグラウンドカラーで塗りつぶしで描画される。これより広いディバイダーでは、最初と最後のピクセルを除いた内部にたいしてのみこのフェイスが使用される。
window-divider-first-pixel
これは少なくとも幅が3ピクセルあるディバイダーの最初のピクセルを描画するために使用される。塗りつぶし(solid)の外観を得るためにはwindow-divider
フェイスに使用されるのと同じ値をセットすること。
window-divider-last-pixel
これは少なくとも幅が3ピクセルあるディバイダーの最後のピクセルを描画するために使用される。塗りつぶし(solid)の外観を得るためにはwindow-divider
フェイスに使用されるのと同じ値をセットすること。
以下の2つの関数により特定のウィンドウのディバイダーのサイズを取得できます。
windowの右ディバイダーの幅(厚さ)をピクセル単位でリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。最右ウィンドウにたいするリターン値は常に0。
windowの下ディバイダーの幅(厚さ)をピクセル単位でリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。ミニバッファーウィンドウやミニバッファーがないフレームの最下ウィンドウにたいするリターン値は常に0。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
display
プロパティテキストプロパティ(またはオーバーレイプロパティ)のdisplay
はテキストへのイメージ挿入、およびテキスト表示のその他の事相を制御します。display
プロパティの値はディスプレイ仕様、または複数のディスプレイ仕様を含むリストかベクターであるべきです。同じdisplay
プロパティ値内のディスプレイ仕様は、一般的にはそれらがカバーするテキストにたいして並行して適用されます。
複数のソース(オーバーレイおよび/またはテキストプロパティ)がdisplay
プロパティにたいして値を指定しますが1つの値だけが効果をもち、それはget-char-property
のルールにしたがいます。テキストプロパティを調べるを参照してください。
このセクションの残りの部分では、複数の種類のディスプレイ仕様とそれらの意味を説明します。
37.16.1 テキストを置換するディスプレー仕様 | テキストを置換するディスプレイspec。 | |
37.16.2 スペースの指定 | 指定された幅に1つのスペースを表示する。 | |
37.16.3 スペースにたいするピクセル指定 | ピクセル単位でスペースの幅や高さを指定する。 | |
37.16.4 その他のディスプレー仕様 | イメージの表示。高さ、スペーシング、その他のテキストプロパティの調整。 | |
37.16.5 マージン内への表示 | メインテキスト側面へのテキストやイメージの表示。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ある種のディスプレイ仕様は、そのプロパティをもつテキストのかわりに表示する何かを指定します。これらは置換(replacing)ディスプレイ仕様と呼ばれます。Emacsはユーザーにたいして、この方法で置換されたバッファーテキストの中間への対話的なポイント移動を許可しません。
ディスプレイ仕様のリストに1つ以上の置換ディスプレイ仕様が含まれる場合には、最初の置換ディスプレイ仕様が残りをオーバーライドします。置換ディスプレイ仕様は他のほとんどのディスプレイ仕様は置換を許容しないので、それらとは無関係です。
置換ディスプレイ仕様では、そのプロパティをもつテキストとは、display
プロパティとして同一のLispオブジェクトをもつ連続したすべての文字を意味します。これらの文字は単一の単位として置換されます。display
プロパティに異なるLispオブジェクト(eq
ではないオブジェクト)をもつ2つの文字は個別に処理されます。
以下はこの要点を示すための例です。文字列が置換ディスプレイ仕様としての役割をもち、指定された文字列のプロパティをもつテキストを置換します(その他のディスプレー仕様を参照)。以下の関数を考えてみてください:
(defun foo () (dotimes (i 5) (let ((string (concat "A")) (start (+ i i (point-min)))) (put-text-property start (1+ start) 'display string) (put-text-property start (+ 2 start) 'display string))))
この関数はバッファー内の最初の10文字それぞれにたいして文字列"A"
であるようなdisplay
プロパティを与えますが、これらはすべて同じ文字列オブジェクトを取得しません。最初の2文字は同じ文字列オブジェクトなので1つの‘A’に置換されます。2つの別々のput-text-property
呼び出しでそのディスプレイプロパティが割り当てられたという事実は無関係です。同様に次の2文字は2つ目の文字列(concat
により新たに作成された文字列オブジェクト)を取得するので1つの‘A’で置換されて、...となります。したがって10文字は5つのAで表示されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
指定された幅および/または高さのスペースを表示するためには(space
.
props)
という形式のディスプレイ仕様を使用します。このプロパティを1つ以上の連続する文字にputすることができます。これらすべての文字のかわりに指定された高さと幅のスペースが表示されます。以下はスペースのウェイトを指定するためにprops内で使用できるプロパティです:
:width width
widthが数字なら、それはスペースの幅が通常の文字幅のwidth倍であるべきかを指定する。widthはピクセル幅(pixel width)仕様でも可(スペースにたいするピクセル指定を参照)。
:relative-width factor
幅の広さは同じdisplay
プロパティをもつ連続する文字のグループ内の最初の文字から計算される必要があることを指定する。スペースの幅はその文字のピクセル幅にfactorを乗じた幅である(テキストモード端末では文字の“ピクセル幅”は通常は1だがTAB文字や2倍の幅をもつCJK文字では1以上になり得る)。
:align-to hpos
スペースがhposに達するほど十分に広くあるべきことを指定する。hposが数字なら通常の文字幅の単位で量られる。hposはピクセル幅(pixel width)仕様でも可(スペースにたいするピクセル指定を参照)。
上記プロパティのいずれか1つだけを使用するべきです。以下のプロパティでスペースの高さも指定できます:
:height height
スペースの高さを指定する。heightが数字ならスペースの高さが通常の文字高さのheight倍であるべきことを指定する。heightはピクセル高さ仕様(pixel height)でも可(スペースにたいするピクセル指定を参照)。
:relative-height factor
このディスプレイ仕様をもつテキストの通常の高さにfactorを乗じることによりスペースの高さを指定する。
:ascent ascent
ascentの値が非負の100以下の数字ならスペースの高さのascentパーセントをスペースのアセント(ascent: 上方)、すなわちベースラインより上の部分とみなす。ピクセルアセント(pixel ascent)仕様によりアセントをピクセル単位で指定することも可(スペースにたいするピクセル指定を参照)。
:height
と:relative-height
を両方同時に使用しないでください。
:width
と:align-to
プロパティは非グラフィック端末でサポートされますが、このセクションのその他のスペースプロパティはサポートされません。
スペースプロパティは双方向テキスト表示の並べ替えのためのパラグラフ区切りとして扱われます。詳細は双方向テキストの表示を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プロパティ:width
、:align-to
、:height
、:ascent
の値は再表示の間に評価される特別な種類の式です。その評価の結果はピクセルの絶対数として使用されます。
以下の式がサポートされています:
expr ::= num | (num) | unit | elem | pos | image | form num ::= integer | float | symbol unit ::= in | mm | cm | width | height
elem ::= left-fringe | right-fringe | left-margin | right-margin | scroll-bar | text pos ::= left | center | right form ::= (num . expr) | (op expr ...) op ::= + | -
フォームnumはデフォルトフレームフォントの高さか幅、フォーム(num)
は絶対ピクセル数を指定します。numがシンボルsymbolなら、それにたいするバッファーローカルな変数バインディングが使用されます。
単位in
、mm
、cm
はそれぞれインチ、ミリメートル、センチメートルごとのピクセル数を指定します。単位width
とheight
はそれぞれカレントフェイスのデフォルトの幅と高さに対応します。イメージ仕様image
はイメージの幅や高さに対応します。
要素left-fringe
、right-fringe
、left-margin
、right-margin
、scroll-bar
、text
はそのウィンドウの対応する領域の幅を指定します。
位置left
、center
、right
はテキストエリアの左端、中央、右端から相対的に位置を指定するために:align-to
とともに使用できます。
(text
を除いた)上記ウィンドウ要素は与えられたエリアの左端から相対的に位置を指定するために:align-to
とともに使用することもできます。(最初に出現するこれらシンボルのいずれかにより)相対的位置にたいするベースオフセットが一度セットがされると、残りのシンボルは指定されたエリアの幅として解釈されます。たとえば左マージンの中央に位置揃えするには以下のようにします
:align-to (+ left-margin (0.5 . left-margin))
位置揃えにたいしてベースオフセットが何も指定されなければ、テキストエリア左端にたいして常に相対的になります。たとえばヘッダーライン内の‘:align-to 0’はテキストエリアの最初のテキスト行に位置揃えします。
(num
. expr)
という形式の値はnumとexprにより生成される値を意味します。たとえば(2
. in)
は2インチの幅、(0.5 . image)
は指定されたイメージの幅(や高さ)の半分を指定します。
フォーム(+ expr ...)
は式の値を合計します。フォーム(- expr
...)
は式の値を符号反転または減算します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はdisplay
テキストプロパティ内で使用できる他のディスプレイ仕様です。
string
このプロパティをもつテキストのかわりにstringを表示する。
再帰的なディスプレイ仕様はサポートされない。つまりstringのdisplay
プロパティがあっても使用されない。
(image . image-props)
この種のディスプレイ仕様はイメージディスクリプタである(イメージを参照)。ディスプレイ仕様として使用時には、そのディスプレイ仕様をもつテキストのかわりに表示するイメージを意味する。
(slice x y width height)
この仕様はimage
とともに、表示するイメージのスライス(slice:
イメージの特定の領域)を指定する。要素yとxはイメージ内での左上隅、widthとheightはそのスライスの幅と高さを指定する。整数はピクセル数、0.0から1.0までの浮動小数点数はイメージ全体の幅や高さの割合を意味する。
((margin nil) string)
この形式のディスプレイ仕様は、このディスプレイ仕様をもつテキストのかわりにテキストと同じ位置に表示するstringを意味する。これは単にstringを使用するのと同じだが、マージン表示(マージン内への表示を参照)の特殊なケースとして行われる点が異なる。
(left-fringe bitmap [face])
(right-fringe bitmap [face])
テキスト行の任意の文字がこのディスプレイ仕様をもつ場合には、その文字のかわりにその行の左や右のフリンジに表示するbitmapを指定する。オプションのfaceはビットマップにたいして使用するカラーを指定する。詳細はフリンジのビットマップを参照のこと。
(space-width factor)
このディスプレイ仕様は、この仕様をもつテキスト内のすべてのスペース文字に効果を及ぼす。これらすべてのスペースは通常の幅のfactor倍の幅で表示される。要素factorは整数か浮動小数点数であること。スペース以外の文字は影響を受けない。特にこれはタブ文字に影響を与えない。
(height height)
このディスプレイ仕様はテキストを高く(taller)、または低く(shorter)する。heightには以下を指定できる:
(+ n)
これはnステップ大きいフォントの使用を意味する。ステップは利用可能なフォントのセットから定義される。利用可能なフォントとは、具体的には、このような場合でなければ、heightを除いてそのテキストに指定されたすべての属性にマッチするフォント。適切なフォントの各サイズは別のステップとして利用可能とみなされる。nは整数であること。
(- n)
これはnステップ小さいフォントの使用を意味する。
数値factorはデフォルトフォントのfactor倍高いフォントの使用を意味する。
高さを計算する関数。この関数はカレントの高さを引数として呼び出されて、使用する新たな高さをリターンすること。
heightの値が上記のいずれにもマッチしなければ、それはフォームである。Emacsはheight
をカレントで指定されたフォントの高さにバインドして新たな高さを取得するためにフォームを評価する。
(raise factor)
この種のディスプレイ仕様は、その行のベースラインに相対的にテキストを上(raise)か下(lower)に指定する。
factor、影響を受けるテキストの高さにたいする乗数として解釈される数値でなければならない。これが正なら文字を上に、負なら下に表示することを意味する。
そのテキストがheight
ディスプレイ仕様ももつ場合には、上や下に表示する量には影響を与えない。上や下に表示する量はテキストにたいして使用されるフェイスにもとづく。
任意のディスプレイ仕様にたいして条件を作成できます。これを行うには、(when condition
.
spec)
という形式の別リスト内にパッケージします。この場合には、仕様specはconditionが非nil
値に評価されたときだけ適用されます。この評価の間にobject
は条件つきdisplay
プロパティをもつ文字列、またはバッファーにバインドされます。position
とbuffer-position
はそれぞれobject
内の位置、およびdisplay
プロパティが見つかったバッファー位置にバインドされます。object
が文字列の際には両者の位置は異なるかもしれません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファーはその左側と右側にディスプレイマージン(display
margins)と呼ばれるブランクエリアをもつことができます。それらのエリア内には通常はテキストが出現することはありませんが、display
プロパティを使用してディスプレイマージン内に何かを配置することができます。現在のところマージン内のテキストやイメージをマウスセンシティブにする方法はありません。
マージン内に何かを表示するにはテキストのdisplay
プロパティのマージン表示仕様(margin display
specification)で指定します。これは配置したテキストが表示されないことを意味する置換表示仕様です。マージン表示は表示されますがそのテキストは表示されません。
マージン表示仕様とは((margin right-margin) spec)
や((margin
left-margin)
spec)
のようなものです。ここでspecはマージン内に何を表示するかを告げる別の表示仕様です。典型的にはこれは表示するテキスト文字列やイメージディスクリプタです。
特定のバッファーテキストに割り当てられたマージンに何かを表示するためには、そのテキストにbefore-string
プロパティを付してコンテンツとしてマージン表示仕様をputします。
ディスプレイマージンが何かを表示可能になる前に、それらに非0の幅を与えなければなりません。これを行う通常の方法は以下の変数をセットする方法です:
この変数は左マージンの幅を文字セル(別名は“列”)単位で指定する。これ、すべてのバッファーでバッファーローカルである。値nil
は左マージンエリアなしを意味する。
この変数は右マージンの幅を文字セル単位で指定する。これはすべてのバッファーでバッファーローカルである。値nil
は右マージンエリアなしを意味する。
これらの変数をセットしてもウィンドウには即座には反映されません。これらの変数はウィンドウ内に新たなバッファーを表示する際にチェックされます。したがってset-window-buffer
を呼び出すことにより変更を反映することができます。
マージン幅を即座にセットすることもできます。
この関数はウィンドウwindowのマージン幅、文字セル単位で指定する。引数leftは左マージン、rightは右マージン(デフォルトは0
)を制御する。
この関数はwindowの左マージンと右マージンの幅を(left . right)
という形式のコンスセルでリターンする。2つのマージンエリアのいずれか一方が存在しなければ幅はnil
でリターンされる。2つのマージンがどちらも存在しなければ、この関数は(nil)
をリターンする。windowがnil
なら選択されたウィンドウが使用される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsバッファー内にイメージを表示するためには最初にイメージディスクリプタを作成して、それを表示されるテキストのdisplay
プロパティ(display
プロパティを参照)内のディスプレイ指定子として使用しなければなりません。
Emacsはグラフィカルな端末で実行時には、通常はイメージの表示が可能です。テキスト端末、イメージサポートを欠く特定のグラフィカル端末、またはイメージサポートなしでコンパイルされたEmacsではイメージを表示できません。原則的にイメージが表示可能か判断するためには関数display-images-p
を使用できます(ディスプレー機能のテストを参照)。
37.17.1 イメージのフォーマット | サポートされるイメージフォーマット。 | |
37.17.2 イメージのディスクリプタ | :display 内で使用されるイメージの指定方法。
| |
37.17.3 XBMイメージ | XBMフォーマット用の特別な機能。 | |
37.17.4 XPMイメージ | XPMフォーマット用の特別な機能。 | |
37.17.5 PostScriptイメージ | PostScriptフォーマット用の特別な機能。 | |
37.17.6 ImageMagickイメージ | ImageMagickを通じて利用できる特別な機能。 | |
37.17.7 その他のイメージタイプ | サポートされる他のさまざまなフォーマット。 | |
37.17.8 イメージの定義 | 後で使用するためにイメージを定義する便利な方法。 | |
37.17.9 イメージの表示 | 一度定義されたイメージを表示するための便利な方法。 | |
37.17.10 マルチフレームのイメージ | 1つ以上のフレームを含むイメージ。 | |
37.17.11 イメージキャッシュ | イメージ表示の内部的メカニズム。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはいくつかの異なるフォーマットのイメージを表示できます。これらのイメージフォーマットのいくつかは、特定のサポートライブラリーがインストールされている場合のみサポートされます。いくつかのプラットフォームではEmacsはオンデマンドでサポートライブラリーをロードできます。そのような場合には、それらの動的ライブラリーにたいする既知の名前セットを変更するために変数dynamic-library-alist
を使用できます。動的にロードされるライブラリーを参照してください。
サポートされるイメージフォーマット(と要求されるサポートライブラリー)にはPBMとXBM(サポートライブラリーに依存せず常に利用可能)、XPM(libXpm
)、GIF
(libgif
またはlibungif
)、PostScript(gs
)、JPEG(libjpeg
)、TIFF(libtiff
)、PNG(libpng
)、SVG
(librsvg
)が含まれます。
これらのイメージフォーマットはそれぞれイメージタイプシンボル(image type
symbol)に関連付けられます。上記のフォーマットにたいするシンボルは順にpbm
、xbm
、xpm
、gif
、postscript
、jpeg
、tiff
、png
、svg
です。
さらにImageMagick(libMagickWand
)のサポートつきでEmacsをビルドした場合には、EmacsはImageMagickが表示可能なイメージフォーマットを表示できます。ImageMagickイメージを参照してください。ImageMagickを通じて表示されるすべてのイメージはタイプシンボルimagemagick
をもちます。
この変数はカレント構成で潜在的にサポートされるイメージフォーマットにたいするタイプシンボルのリストを含む。
“潜在的”とはEmacsがそのイメージタイプを知っていることを意味しており、実際に使用可能である必要はない(たとえば動的ライブラリーが利用できないせいかもしれない)。どのイメージタイプが実際に利用できるか知るためにはimage-type-available-p
を使用すること。
この関数はタイプtypeのイメージのロードと表示が可能なら非nil
をリターンする。typeはイメージタイプシンボルであること。
サポートライブラリーが静的にリンクされたイメージタイプにたいして、この関数は常にt
をリターンする。サポートライブラリーが動的にロードされるイメージタイプにたいしてはライブラリーがロード可能ならt
、それ以外ならnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
イメージディスクリプタ(image
descriptor)とは、イメージにたいする基礎的なデータと表示する方法を指定するリストです。これは通常はオーバーレイプロパティかテキストプロパティdisplay
(その他のディスプレー仕様を参照)の値を通じて使用されますが、バッファーにイメージを挿入する便利なヘルパー関数についてはイメージの表示を参照してください。
イメージディスクリプタはそれぞれ(image
.
props)
という形式をもちます。ここでpropsはキーワードシンボルと値のペアーからなるプロパティリストであり、少なくともそのイメージタイプを指定するペアー:type
type
を含みます。
以下はすべてのイメージタイプにたいして意味のあるプロパティのリストです(以降のサブセクションで説明するように特定のイメージタイプにたいしてのみ意味があるプロパティも存在する):
:type type
イメージタイプ。 イメージのフォーマットを参照のこと。 すべてのイメージディスクリプタは。このプロパティを含まなければならない。
:file file
これはファイルfileからイメージをロードすることを意味する。fileが絶対ファイル名でなければdata-directory
内で展開される。
:data data
これはrawイメージデータを指定する。すべてのイメージディスクリプタは:data
か:file
のいずれかをもたなければならないが両方もつことはできない。
ほとんどのイメージタイプにたいして、:data
プロパティの値はイメージデータを含む文字列であること。いくつかのイメージタイプは:data
をサポートしない。それ以外のイメージタイプにたいしては:data
単独では不十分であり、:data
とともに他のイメージプロパティを使用する必要がある。詳細は以下のサブセクションを参照のこと。
:margin margin
これはイメージ周囲に余分なマージンとして何ピクセル追加するかを指定する。値marginは非負の数値か、そのような数値のペアー(x
.
y)
でなければならない。ペアーならxは水平方向に追加するピクセル数、yは垂直方向に追加するピクセル数を指定する。:margin
が指定されない場合のデフォルトは0。
:ascent ascent
これはイメージのアセント(ベースラインの上の部分)に使用するイメージの高さの分量を指定する。値ascentは0から100の数値かシンボルcenter
でなければならない。
ascentが数値ならアセントに使用するイメージの高さのパーセンテージであること。
ascentがcenter
なら、イメージにたいしてテキストプロパティやオーバーレイプロパティにより指定される方法で、センターライン(そのイメージ位置にテキストを描画する際の垂直方向のセンターライン)の垂直方向中心にイメージが配置される。
このプロパティが省略された場合のデフォルトは50。
:relief relief
これはイメージ周辺にシャドー矩形を追加する。値reliefはシャドーライン幅をピクセルで指定する。reliefが負ならボタンを押下した状態、それ以外はボタンを押下していない状態のイメージでシャドーを描画する。
:conversion algorithm
これはイメージを表示する前に適用するべき変換アルゴリズムを指定する。値algorithmは何のアルゴリズムかを指定する。
laplace
emboss
カラーの大きな差異を強調して小さな差異を不鮮明にするラプラスエッジ検出アルゴリズム(Laplace edge detection algorithm)を指定する。無効なボタンのイメージ表示に、これが役立つと考える人もいます。
(edge-detection :matrix matrix :color-adjust adjust)
一般的なエッジ検出アルゴリズムを指定する。matrixは数値からなる9要素のリストかベクターでなければならない。変換されたイメージ内の位置x/yにあるピクセルは、その位置周辺にある元のピクセルから計算される。matrixはx/yに近接する各ピクセルにたいして、そのピクセルが変換先ピクセルに影響するファクター(factor: 要因)を指定する。以下のように要素0はx-1/y-1にあるピクセルのファクター、要素1はx/y-1にあるピクセルにたいするファクター、...を指定する。
(x-1/y-1 x/y-1 x+1/y-1 x-1/y x/y x+1/y x-1/y+1 x/y+1 x+1/y+1)
結果となるピクセルは周辺ピクセルのRGB値を合計したカラーを指定されたファクターで乗じて、その合計をファクター絶対値の合計で除した色強度から計算される。
ラプラスエッジ検出は現在のところは以下のマトリクス
(1 0 0 0 0 0 0 0 -1)
エンボスエッジ検出(Emboss edge-detection)は以下のマトリクスを使用する
( 2 -1 0 -1 0 1 0 1 -2)
disabled
イメージが無効(disabled)に見えるよう変換することを指定する。
:mask mask
maskがheuristic
か(heuristic
bg)
なら、フレームのバックグラウンドがイメージ背後に見えるようにイメージのクリッピングマスクを構築する。bgが未指定かt
なら、イメージ4隅に最頻するカラーをそのイメージのバックグラウンドカラーとみなしてバックグラウンドカラーを決定する。それ以外ならbgはイメージのバックグラウンドとみなすべきカラーを指定するリスト(red
green blue)
でなければならない。
maskがnil
なら、イメージがマスクをもつ場合にはマスクを削除する。マスクを含むフォーマットのイメージは:mask
nil
を指定することにより削除される可能性がある。
:pointer shape
これはマウスポインターがそのイメージ上にある際のポインターシェイプを指定する。利用可能なポインターシェイプについてはポインターの形状を参照のこと。
:map map
これはイメージにホットスポット(hot spots)のイメージマップを関連付ける。
イメージマップは各要素が(area id
plist)
という形式をもつalist。areaにはrectangle(矩形)、circle(円)、またはpolygon(ポリゴン、多角形)のいずれかを指定する。
rectangleは矩形エリアの左上隅と右下隅のピクセル座標を指定するコンス(rect . ((x0 . y0)
. (x1 . y1)))
。
circleは円の中心と半径を指定するコンス(circle . ((x0 . y0)
. r))
。rは整数か浮動小数点数。
polygonは各ペアーが多角形の1つの頂点を記述するコンス(poly . [x0 y0 x1
y1 ...])
。
マウスポインターがホットスポット上にある際には、ホットスポットのplistが参照される。これがhelp-echo
プロパティを含むならそのホットスポットのツールチップ、pointer
プロパティを含む場合はマウスカーソルがホットスポット上にあるときのマウスカーソルのシェイプを指定する。利用可能なポインターシェイプについてはポインターの形状を参照のこと。
マウスポインターがホットスポット上にあるときにマウスをクリックしたときのイベントは、ホットスポットのidとマウスイベントを組み合わせて構成される。たとえばホットスポットのidがarea4
なら[area4
mouse-1]
。
この関数はイメージspecがマスクビットマップをもつならt
をリターンする。frameはそのイメージが表示されるフレーム。frameがnil
か省略された場合には選択されたフレームが使用される(入力のフォーカスを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
XBMフォーマットを使用するにはイメージタイプとしてxbm
を指定します。このイメージフォーマットは外部ライブラリーを要求せず、このタイプのイメージは常にサポートされます。
xbm
イメージタイプにたいして追加のイメージプロパティがサポートされます:
:foreground foreground
値foregroundはそのイメージのフォアグラウンドカラーを指定する文字列、またはデフォルトカラーを指定するnil
であること。このカラーはXBM内の1の各ピクセルに使用される。デフォルトはフレームのフォアグラウンドカラー。
:background background
値backgroundはそのイメージのバックグラウンドカラーを指定する文字列、またはデフォルトカラーを指定するnil
であること。このカラーはXBM内の0の各ピクセルに使用される。デフォルトはフレームのバックグラウンドカラー。
外部ファイルのかわりにEmacs内のデータを指定してXBMイメージを指定するには以下の3つのプロパティを使用する:
:data data
値dataはイメージのコンテンツを指定する。dataとして使用できる3つのフォーマットが存在する:
:height
と:width
を指定する。
:height
と:width
を指定してはならない。これらを省略することが、そのデータがXBMファイルのフォーマットをもつことを示すからである。イメージの高さと幅はファイルのコンテンツにより指定される。
height
ビットを含むこと。この場合にはその文字列がXBMファイル全体ではなく、単にビットだけを含むことを示すとともに、そのイメージのサイズを指定するために:height
と:width
を指定しなければならない。
:width width
値widthはピクセル単位でイメージの幅を指定する。
:height height
値heightはピクセル単位でイメージの高さを指定する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
XPMフォーマットを使用するにはイメージタイプにxpm
を指定します。xpm
イメージタイプでは追加のプロパティ:color-symbols
にも意味があります。
:color-symbols symbols
値symbolsは要素が(name
.
color)
という形式をもつようなalistであること。各要素においてnameはイメージファイル内に出現するカラー名、colorはそのカラー名の実際の表示に使用するカラーを指定する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
あるイメージにたいしてPostScriptを使用するにはイメージタイプpostscript
を指定します。これはGhostscriptがインストールされている場合のみ機能します。常に以下の3つのプロパティを使用しなければなりません:
:pt-width width
値widthはポイント(1/72インチ)単位で測ったイメージの幅を指定する。widthは整数でなければならない。
:pt-height height
値heightはポイント(1/72インチ)単位で測ったイメージの高さを指定する。heightは整数でなければならない。
:bounding-box box
値boxは4つの整数からなるリストかベクターでなければならない。これらの整数は、PostScriptファイルの‘BoundingBox’に類似したPostScriptイメージのバウンディングボックスを指定する。
%%BoundingBox: 22 171 567 738
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ImageMagickのサポートつきでEmacsをビルドした場合には、多くくのイメージフォーマットをロードするためにImageMagickライブラリーを使用できます(File
Conveniences in The GNU Emacs
Manualを参照)。ImageMagickを通じてロードしたイメージのイメージタイプシンボルは、基礎となる実際のイメージフォーマットとは無関係にimagemagick
になります。
この関数はカレントのImageMagickインストールによりサポートされるイメージファイル拡張子のリストをリターンする。リストの各要素は.bmpイメージはBMP
のような、イメージタイプにたいして内部的なImageMagick名を表すシンボル。
この変数の値はEmacsがImageMagickを使用してレンダリングを試みるかもしれないImageMagickイメージタイプのリスト。リストの各要素はimagemagick-types
がリターンするリスト内のシンボルのいずれか、または等価な文字列。もしくは値t
はImageMagickにたいして利用できるすべてのイメージタイプを有効にする。この変数の値とは関係なくimagemagick-types-inhibit
(以下参照)が優先される。
この変数の値はimagemagick-enabled-types
の値とは無関係に、ImageMagickを使用して決してレンダリングされることのないImageMagickイメージタイプのリスト。値t
はImageMagickを完全に無効にする。
この変数はイメージタイプをファイル名拡張子にマッピングするalist。EmacsはImageMagickライブラリーにイメージのタイプに関するヒントを与えるために、この変数と:format
イメージプロパティ(以下参照)を組み合わせて使用する。各要素は(type
extension)
という形式をもちtypeはイメージのcontent-typeを指定するシンボル、extensionは関連付けられるファイル名拡張子を指定する文字列。
ImageMagickによりロードされたイメージは、追加で以下のイメージディスクリプタプロパティをサポートします:
:background background
backgroundが非nil
なら、カラーを指定する文字列であること。これはイメージが透明度をサポートする場合に、イメージのバックグラウンドカラーとして使用される。値がnil
の場合のデフォルトはフレームのバックグラウンドカラー。
:width width, :height height
キーワード:width
と:height
はイメージのスケーリングに使用される。いずれか一方のみが指定された場合には、アスペクト比を保つためにもう一方が算出される。両方が指定された場合にはアスペクト比は保たれないかもしれない。
:max-width max-width, :max-height max-height
キーワード:max-width
と:max-height
は、イメージのサイズがこれらの値を超過した場合のスケーリングに使用される。:width
がセットされた場合にはmax-width
より優先されて、:height
がセットされた場合にはmax-height
より優先されるだろうが、それ以外ではこれらのキーワードを望むように混交できる。:max-width
と:max-height
は常にアスペクト比を保つであろう。
:format type
値typeはimage-format-suffixes
で見られるような、イメージのタイプを指定するシンボルであること。これはイメージが関連付けられたファイル名をもたない際に、イメージタイプを検出する助けとなるヒントをImageMagickに提供する。
:rotation angle
回転角度を度数で指定する。
:index frame
マルチフレームのイメージを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
PBMイメージにはイメージタイプpbm
を指定します。カラー、グレースケール、およびモノクロのイメージがサポートされます。モノクロのPBMイメージにたいしては、2つの追加イメージプロパティがサポートされます。
:foreground foreground
値foregroundはイメージのフォアグラウンドカラーを指定する文字列、またはデフォルトカラーならnil
であること。このカラーはPBM内の1であるようなピクセルすべてに使用される。デフォルトはフレームのフォアグラウンドカラー。
:background background
値backgroundはイメージのバックグラウンドカラーを指定する文字列、またはデフォルトカラーならnil
であること。このカラーはPBM内の0であるようなピクセルすべてに使用される。デフォルトはフレームのバックグラウンドカラー。
Emacsがサポート可能な残りのイメージタイプは以下のとおり:
イメージタイプgif
。:index
プロパティをサポートする。マルチフレームのイメージを参照のこと。
イメージタイプjpeg
。
イメージタイプpng
。
イメージタイプsvg
。
イメージタイプtiff
。:index
プロパティをサポートする。マルチフレームのイメージを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
関数create-image
、defimage
、find-image
はイメージディスクリプタを作成するための便利な手段を提供します。
この関数はfile-or-data内のデータを使用するイメージディスクリプタを作成してリターンする。file-or-dataはファイル名、またはイメージデータを含む文字列を指定できる。前者ならdata-pはnil
、後者なら非nil
であること。
オプション引数typeはイメージタイプを指定するシンボル。typeが省略かnil
なら、create-image
はファイル先頭の数バイトかファイル名からイメージタイプの判断を試みる。
残りの引数propsは追加のイメージプロパティを指定する。たとえば、
(create-image "foo.xpm" 'xpm nil :heuristic-mask t)
この関数はそのタイプのイメージがサポートされていなければnil
、それ以外ならイメージディスクリプタをリターンする。
このマクロはイメージマクロとしてsymbolを定義する。引数specsはイメージの表示方法を指定するリストである。3つ目の引数docはオプションのドキュメント文字列。
specs内の各要素はプロパティリストの形式をもち、それぞれが少なくとも:type
プロパティと、:file
か:data
いずれかのプロパティをもつこと。:type
の値はイメージタイプを指定するシンボル、:file
の値はイメージをロードするファイル、:data
の値は実際のイメージデータを含む文字列であること。以下は例:
(defimage test-image ((:type xpm :file "~/test1.xpm") (:type xbm :file "~/test1.xbm")))
defimage
はそれが使用可能か、つまりそのタイプがサポートされているかとファイルが存在するかを確認するために各要素を1つずつテストする。最初に使用可能な引数がsymbol内に格納するイメージディスクリプタを作成するために使用される。
機能する候補がなければsymbolはnil
として定義される。
この関数はイメージ仕様specsのリストの1つを満足するイメージを探すための、便利な手段を提供する。
specs内の各仕様はイメージタイプに応じた内容のプロパティリストである。すべての仕様は少なくとも:type
type
、および:file file
か:data data
のいずれかのプロパティを含まなければならない。ここでtypeはxbm
のようにイメージタイプを指定するシンボル、fileはイメージをロードするファイル、dataは実際のイメージデータを含む文字列。このリスト内でtypeがサポートされていて、かつfileが存在する最初の仕様が、リターンされるイメージ仕様の構築に使用される。満足する仕様がなければnil
がリターンされる。
イメージはimage-load-path
内で検索される。
この変数の値はイメージファイルを検索する場所のリストである。要素が文字列、または値が文字列であるような変数シンボルなら、その文字列は検索を行うディレクトリーとみなされる。値がリストであるような変数シンボルなら、検索を行うディレクトリーのリストとみなされる。
デフォルトではdata-directory
で指定されたディレクトリーのサブディレクトリーimages、次にdata-directory
で指定されたディレクトリー、最後にload-path
で指定されたディレクトリー内を検索する。サブディレクトリーは自動的には検索に含まれないので、イメージファイルをサブディレクトリー内に配置した場合には、サブディレクトリー名を明示的に与える必要がある。たとえばdata-directory
内でイメージimages/foo/bar.xpmを見つけるには、以下のようにそのイメージを指定すること:
(defimage foo-image '((:type xpm :file "foo/bar.xpm")))
この関数はLispパッケージlibraryにより使用されるイメージにたいして適切な検索パスをリターンする。
この関数はまずimage-load-path
(data-directory
/imagesを除外)を使用し、次にload-path
の後にlibraryにとって適切なパス(ライブラリーファイル自身にたいする相対パス../../etc/imagesと../etc/imagesを含む)を補い、最後にdata-directory
/imagesからimageを検索する。
それからこの関数は先頭にimageが見つかったディレクトリー、その後にload-path
の値が続くディレクトリーのリストをリターンする。pathが与えられたらload-path
のかわりに使用する。
no-errorが非nil
、かつ適切なパスが見つからない場合にはエラーをシグナルしない。かわりに前記のディレクトリーリストをリターンするが、イメージのディレクトリーの箇所にnil
が出現する点が異なる。
以下はimage-load-path-for-library
の使用例:
(defvar image-load-path) ; shush compiler (let* ((load-path (image-load-path-for-library "mh-e" "mh-logo.xpm")) (image-load-path (cons (car load-path) image-load-path))) (mh-tool-bar-folder-buttons-init))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
自分でdisplay
プロパティをセットアップしてイメージディスクリプタを使用できますが、このセクションの関数を使用するほうがより簡単です。
この関数はカレントバッファーのポイント位置にimageを挿入する。imageはイメージディスクリプタであること。これはcreate-image
によりリターンされた値、またはdefimage
で定義されたシンボルの値を使用できる。引数stringはイメージを保持するためにバッファー内に配置するテキストを指定する。これが省略かnil
なら、insert-image
はデフォルトで"
"
を使用する。
引数areaはマージン内にイメージを置くかどうかを指定する。これがleft-margin
なら左マージンにイメージが表示され、right-margin
なら右マージンを指定する。areaがnil
か省略なら、イメージはバッファーのテキスト内のポイント位置に表示される。
引数sliceは挿入するイメージのスライスを指定する。sliceがnil
か省略された場に合はイメージ全体が挿入される。それ以外では、sliceがリスト(x
y width
height)
ならxとyは位置、widthとheightは挿入するイメージの領域を指定する。整数値はピクセル単位。0.0から1.0までの浮動小数点数はイメージ全体の幅や高さにたいする割合を指定する。
この関数は内部的にはバッファー内にstringを挿入して、imageを指定するdisplay
プロパティにそれを渡す。display
プロパティを参照のこと。
この関数はinsert-image
と同様にカレントバッファー内にimageを挿入するが、イメージをrows✕colsの同一サイズのスライスに分割する点が異なる。
Emacsは各スライスを個別のイメージとして表示して、(巨大な)イメージを表示するバッファーのページングの際にイメージ全体を上下にジャンプするのではなく、より直感的な上下スクロールが可能になる。
この関数はカレントバッファー内のposの前にイメージimageを配置する。引数posは整数かマーカーであること。これはイメージが表示されるべきバッファー位置を指定する。引数stringは代替として表示されるべきデフォルトのイメージを保持するテキストであること。
引数imageはイメージディスクリプタでなければならず、それはcreate-image
がリターンされたか、あるいはdefimage
により格納されたイメージディスクリプタかもしれない。
引数areaはマージン内にイメージを置くかどうかを指定する。これがleft-margin
なら左マージンにイメージが表示され、right-margin
なら右マージンを指定する。areaがnil
か省略なら、イメージはバッファーのテキスト内のポイント位置に表示される。
内部的には、この関数はオーバーレイを作成して、値がそのイメージであるようなdisplay
プロパティをもつテキストを含む、before-string
プロパティをそのオーバーレイに与えている(なんと!)。
この関数はbufferの位置startとendの間のイメージを削除する。bufferが省略かnil
ならカレントバッファーからイメージを削除する。
これはput-image
が行う方法でbufferに配置されたイメージだけを削除して、insert-image
や他の方法で挿入されたイメージは削除しない。
この関数はペアー(width . height)
としてイメージのサイズをリターンする。specはイメージ仕様。pixelsが非nil
ならピクセル単位、それ以外ならframeのデフォルトの文字サイズの単位で量ったサイズをリターンする。frameはイメージが表示されるフレーム。frameがnil
か省略された場合はに選択されたフレームを使用する(入力のフォーカスを参照)。
この変数はEmacsがロードするイメージの最大サイズを定義するために使用される。Emacsはこの制限より大きいイメージのロード(と表示)を拒絶するだろう。
値が整数ならピクセル単位で量ったイメージの最大の高さと幅を直接指定する。浮動小数点数ならフレームの高さと幅にたいする比率として、イメージの最大の高さと幅を指定する。値が数値でなければイメージサイズにたいする明示的な制限は存在しない。
この変数の目的は意図せずEmacsに不当に大きなイメージがロードされるとを防ぐことである。これはイメージの初回ロード時だけ効果がある。イメージが一度イメージキャッシュに置かれると、その後にmax-image-size
の値が変更されても、そのイメージは常に表示可能である(イメージキャッシュを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
複数のイメージを含むことができるイメージファイルがいくつかあります。わたしたちはこのような場合には、イメージ内に複数の“フレーム”があると表現しています。現在のところEmacsはGIF、TIFF、およびDJVMのような特定のImageMagickフォーマットにたいする複数フレームをサポートします。
フレームは複数のページを表現するため(通常はたとえばマルチフレームTIFFのケースが該当)、あるいはアニメーションを作成するため(通常はマルチフレームGIFファイルのケースが該当)に使用できます。
マルチフレームイメージは、表示されるフレームを指定する整数値(0から数える)が値であるようなプロパティ:index
をもっています。
この関数はimageが2つ以上のフレームを含めば非nil
をリターンする。実際のリターン値はコンス(nimages
.
delay)
でありnimagesはフレーム数、delayはフレーム間の遅延秒数、イメージが遅延を指定しなければnil
。通常はアニメーションを意図されたイメージはフレームの遅延を指定して、複数ページとして扱われることを意図したイメージは指定しない。
この関数はimageにたいして0から数えたカレントフレーム番号のインデックスをリターンする。
この関数はimageをフレーム番号nとスイッチする。nocheckがnil
なら有効範囲外のフレーム番号を範囲終端に置き換える。imageが指定された番号のフレームを含まなければイメージは中抜きの四角(hollow
box)で表示される。
この関数はimageをアニメーション表示する。オプションの整数indexは開始するフレームを指定する(デフォルトは0)。オプション引数limitはアニメーションの長さを制御する。これが省略かnil
ならアニメーション回数は1回、t
なら永久にループ表示する。数値ならその秒数後にアニメーションは停止する。
アニメーションはタイマーにより処理されます。Emacsは最小のフレーム遅延を0.01秒(
image-minimum-frame-delay
の値)とすることに注意してください。そのイメージ自身が遅延を指定しなければEmacsはimage-default-frame-delay
を使用します。
この関数はもし存在すればimageのアニメーションに責任をもつタイマーをリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはイメージをより効果的に再表示できるようにイメージをキャッシュします。Emacsがイメージを表示する際には、既存のイメージ仕様が望む仕様とequal
なイメージキャッシュを検索します。マッチが見つかったらイメージはキャッシュから表示され、それ以外ではイメージは通常のようにロードされます。
この関数はフレームframeのイメージキャッシュから仕様specのイメージを削除する。イメージ仕様の比較にはequal
を使用する。frameがnil
の場合のデフォルトは選択されたフレーム。frameがt
ならイメージはすべての既存フレームでフラッシュされる。
Emacsの現実装では各グラフィカル端末はイメージキャッシュを処理して、それはその端末上のすべてのフレームにより共有される(複数の端末を参照)。つまりあるフレームでイメージをリフレッシュすると、同一端末上の他のすべてのフレームでもリフレッシュされる。
image-flush
の1つの用途はEmacsにイメージファイルの変更を伝えることです。イメージ仕様が:file
プロパティを含む場合には、そのイメージの初回表示時にファイルコンテンツにもとづいてイメージがキャッシュされます。たとえその後にファイルが変更されても、Emacsはそのイメージの古いバージョンを表示し続けます。image-flush
を呼び出すことによりそのイメージはキャッシュからフラッシュされて、イメージの表示が次回必要になった際にEmacsにファイルの再読み込みを強制します。
image-flush
の他の用途はメモリー節約です。Lispプログラムでimage-cache-eviction-delay
(以下参照)より遥かに短い期間に多数の一時イメージを作成する場合には、Emacsが自動的に行うことを待たずに自身で使用されていないイメージのフラッシュを選択できます。
この関数はイメージキャッシュ内に格納されたすべてのイメージを削除してイメージキャッシュをクリアーする。filterが省略かnil
なら選択されたフレームにたいしてキャッシュをクリアーする。filterがフレームなら、そのフレームにたいしてキャッシュをクリアーする。filterがt
なら、すべてのイメージキャッシュをクリアーする。それ以外ならfilterはファイル名として解釈されて、すべてのイメージキャッシュからそのファイル名に関連付けられたすべてのイメージを削除する。
イメージキャッシュ内のイメージが指定された期間内に表示されなければ、Emacsはそれをキャッシュから削除して割り当てられたメモリーを解放します。
この変数は表示されることなくイメージがキャッシュ内に残留できる秒数を指定する。あるイメージがこの秒数の間に表示されなければ、Emacsはそれをイメージキャッシュから削除する。
ある状況下では、もしキャッシュ内のイメージ数が大きくなり過ぎた場合には実際の立ち退き遅延(eviction delay)はこれより短くなり得る。
値がnil
なら明示的にキャッシュをクリアーした場合を除き、Emacsはキャッシュからイメージを削除しない。このモードはデバッグ時に有用かもしれない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsは必要なライブラリーのサポート付きでビルドされていて、かつグラフィカル端末上で実行中なら、Emacsバッファー内にGTK
WebKitウィジェットのようなネイティブのウィジェットを表示できます。埋め込みウィジェットの表示をEmacsがサポートするかどうかをテストするためには、xwidget-internal
機能が利用可能かどうかをチェックしてください(名前つき機能を参照)。
Emacsバッファー内に埋め込みウィジェットを表示するためには、最初にxwidgetオブジェクトを作成して、テキストプロパティまたはオーバーレイプロパティdisplay
内のディスプレイ仕様としてそのオブジェクトを使用します(display
プロパティを参照)。
これはxwidgetオブジェクトを作成してリターンする。bufferが省略かnil
の場合のデフォルトはカレントバッファー。bufferが存在しないバッファーの名前を指定する場合には作成する。typeはxwidgetコンポーネントを識別するもので以下のいずれかが可能:
webkit
WebKitコンポーネント。
引数widthとheightはウィジェットのサイズをピクセル単位で指定して、titleはそのタイトルを指定する文字列。
この関数はobjectがxwidgetならt
、それ以外はnil
をリターンする。
この関数はxwidgetのプロパティリストをリターンする。
この関数はplistで与えられた新たなプロパティリストでxwidgetのプロパティリストを置き換える。
この関数はxwidgetのバッファーをリターンする。
この関数はbufferに関連付けられたxwidgetオブジェクトのリストをリターンする。bufferはバッファーオブジェクトか既存のバッファー名(文字列)を指定できる。bufferにxwidgetが含まれなければ値はnil
。
この関数は与えられたxwidget内で指定したuriをブラウズ(browse: 閲覧)する。uriはファイルかURLを指定する文字列。
この関数はxwidgetで指定されるブラウザウィジェットに、script
で指定するJavaScriptを実行させる。
この関数はxwidget-webkit-execute-script
と同様に指定したscriptを実行するが、スクリプトのリターン値も文字列としてリターンする。この関数はscriptが値をリターンしなければdefault、defaultが省略されたらnil
をリターンする。
この関数はxwidgetのタイトルを文字列としてリターンする。
この関数は指定したxwidgetをwidthxheightのサイズ(ピクセル単位)にリサイズする。
この関数はxwidgetのサイズを(width
height)
という形式のリストでリターンする。単位はピクセル。
この関数は[type title width
height]
という形式のベクターでxwidgetの属性をリターンする。属性は通常はxwidgetの作成時にmake-xwidget
で決定される。
この関数はEmacsがxwidgetに関連付けられたバッファーのexitやkillの前にユーザーに確認を求めるようにアレンジすることを可能にする。flagが非nil
ならEmacsはユーザーに確認を求めて、それ以外なら確認を求めない。
この関数はxwidgetのquery-on-exitフラグのカレントセッティングをt
かnil
のいずれかでリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Buttonパッケージはマウスやキーボードコマンドでアクティブ化することができる、ボタン(buttons)の挿入と操作に関する関数を定義します。これらのボタンは典型的には種々のハイパーリンクに使用されます。
本質的にボタンとはバッファー内のテキスト範囲にアタッチされたテキストプロパティやオーバーレイのプロパティのセットです。これらのプロパティはボタンプロパティ(button properties)と呼ばれます。これらのプロパティのうちの1つはアクションプロパティ(action property)であり、これはユーザーがキーボードかマウスを使用してボタンを呼び出した際に呼び出される関数を指定します。アクション関数はボタンを調べ、必要に応じて他のプロパティを使用できます。
いくつかの機能面でButtonパッケージとWidgetパッケージは重複しています。Introduction in The Emacs Widget Libraryを参照してください。Buttonパッケージの利点は、より高速で小さくプログラムにたいしてよりシンプルであることです。ユーザーの観点からは、2つのパッケージが提供するインターフェイスは非常に類似しています。
37.19.1 ボタンのプロパティ | 特別な意味をもつボタンプロパティ。 | |
37.19.2 ボタンのタイプ | ボタンのクラスにたいして一般的なプロパティを定義する。 | |
37.19.3 ボタンの作成 | Emacsバッファーへのボタンの追加。 | |
37.19.4 ボタンの操作 | ボタンプロパティの取得とセット。 | |
37.19.5 ボタンのためのバッファーコマンド | ボタンにたいするバッファー規模のコマンドとバインディング。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ボタンはその外観と振る舞いを定義するプロパティの連想リスト(associated list)をもち、アプリケーションの特別な目的のために他の任意のプロパティを使用できます。以下のプロパティはButtonパッケージにたいして特別な意味をもちます:
action
ユーザーがボタンを呼び出した際に呼び出す関数であり、単一の引数buttonを渡して呼び出される。デフォルトではこれは何も行わないignore
。
mouse-action
これはaction
と似ているが与えられた際には、(RET押下のかわりに)マウスクリックによりボタンが呼び出された場合naction
のかわりに使用される。与えられなければマウスクリックはかわりにaction
を使用する。
face
このタイプのボタンが表示される方法を制御するEmacsフェイス。デフォルトはbutton
フェイス。
mouse-face
ボタン上にマウスがある際の外観を制御する追加のフェイス(通常のbuttonフェイスとマージされる)。デフォルトはEmacsの通常のhighlight
フェイス。
keymap
そのボタンリージョン(button
region)でアクティブなバインディングを定義するボタンのキーマップ。デフォルトは変数button-map
に格納された通常のボタンリージョンキーマップであり、これはボタン呼び出しにたいしてRETとmouse-2を定義している。
type
ボタンのタイプ。ボタンのタイプを参照のこと。
help-echo
Emacsのツールチップヘルプシステムにより表示あれる文字列。デフォルトは"mouse-2, RET: Push this
button"
。
follow-link
このボタンにたいしてmouse-1クリックが振る舞う方法を定義するfollow-linkプロパティ。クリック可能なテキストの定義を参照のこと。
button
すべてのボタンは非nil
のbutton
プロパティをもち、これはボタンを含むテキストリージョンを探すのに有用かもしれない(標準的なボタン関数はこれを行う)。
ボタン内のテキストリージョンにたいして定義された他のプロパティも存在しますが、それらは典型的な用途にたいしては一般的には無関係でしょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
すべてのボタンはボタンのプロパティにたいするデフォルト値を定義するボタンタイプ(button type)をもっています。ボタンタイプは、より汎用的なタイプから特化したタイプへと継承される階層構造で構成されており、特定のタスクにたいして特殊用途のボタンを簡単に定義できます。
name (シンボル)と呼ばれるボタンタイプを定義する。残りの引数はproperty
valueペアーのシーケンスを形成する。これはそのタイプのボタンにたいするデフォルトのプロパティ値を指定する(ボタンのタイプはキーワード引数:type
を使用してボタン作成時にそれをtype
プロパティに与えることによりセット可能)。
加えてnameがデフォルトプロパティ値を継承するボタンタイプ指定するためにキーワード引数:supertype
を使用できる。この継承はnameの定義時のみ発生することに注意。その後にsupertypeに行われた変更はsubtypeには反映されない。
define-button-type
を使用してボタンのデフォルトプロパティを定義するのは必須ではありません —
特定のタイプをもたないボタンはビルトインのボタンタイプbutton
を使用します —
が推奨しません。これを行うことにより通常はコードがより明快かつ効果的になるからです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ボタンはボタン固有の情報を保持するために、オーバーレイプロパティかテキストプロパティを使用してテキストのリージョンに関連付けられます。これらはすべてボタンのタイプ(デフォルトはビルトインのボタンタイプbutton
)から初期化されます。すべてのEmacsテキストと同じようにボタンの外観はface
プロパティにより制御されます。(ボタンタイプbutton
から継承されたface
プロパティを通じることにより)デフォルトでは典型的なウェブページリンクのようなシンプルなアンダーラインです。
簡便さのために2種類のボタン作成関数があります。1つはバッファーの既存リージョンにボタンプロパティを追加するmake-...button
と呼ばれる関数、もう1つはボタンテキストを挿入するinsert-...button
と呼ばれる関数です。
すべてのボタン作成関数は&rest
引数のpropertiesを受け取ります。これはボタンに追加するプロパティを指定するproperty
valueペアーのシーケンスである必要があります。ボタンのプロパティを参照してください。これに加えて他のプロパティの継承元となるボタンタイプの指定にキーワード引数:type
を使用できます。ボタンのタイプを参照してください。作成の間に明示的に指定されなかったプロパティは、(そのタイプがそのようなプロパティを定義していれば)そのボタンのタイプから継承されます。
以下の関数はボタンプロパティを保持するためにオーバーレイを使用してボタンを追加します(オーバーレイを参照)。
これはカレントバッファー内のbegからendにボタンを作成してリターンする。
これはポイント位置にラベルlabelのボタンを挿入してリターンする。
以下の関数も同様ですが、ボタンプロパティを保持するためにテキストプロパティを使用します(テキストのプロパティを参照)。この種のボタンはバッファーにマーカーを追加しないので、非常に多数のボタンが存在してもバッファーでの編集が低速になることはありません。しかしそのテキストに既存のfaceテキストプロパティが存在する場合(たとえばFont Lockモードにより割り当てられたフェイス)には、そのボタンのフェイスは可視にならないかもしれません。これらの関数はいずれも新たなボタンの開始位置をリターンします。
これはテキストプロパティを使用してカレントバッファー内のbegからendにボタンを作成する。
これはテキストプロパティを使用してポイント位置にラベルlabelのボタンを挿入する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ボタンのプロパティの取得やセットを行う関数が存在します。これらは何を行うかを判断するためにボタンが呼び出す関数からよく使用される関数です。
buttonパラメーターが指定された場合にはオーバーレイ(オーバーレイボタンの場合)、またはバッファー位置やマーカー(テキストプロパティボタンの場合)いずれかという、特定のボタンを参照するオブジェクトを意味します。そのようなオブジェクトはボタンが関数を呼び出す際に1つ目の引数として渡されます。
buttonが開始される位置をリターンする。
buttonが終了する位置をリターンする。
ボタンbuttonのpropという名前のプロパティを取得する。
buttonのpropプロパティにvalをセットする。
buttonのaction
プロパティを呼び出す(単一の引数buttonを渡してプロパティの値である関数を呼び出す)。use-mouse-actionが非nil
なら、action
のかわりにそのボタンのmouse-action
プロパティの呼び出しを試みる。ボタンがmouse-action
プロパティをもたなければ通常どおりaction
を使用する。
buttonのテキストラベルをリターンする。
buttonのボタンタイプをリターンする。
buttonがボタンタイプtype、またはtypeのsubtypeのいずれかをもつならt
をリターンする。
カレントバッファー内の位置posにあるボタン、またはnil
をリターンする。posにあるボタンがテキストプロパティボタンならリターン値はposを指すマーカー。
ボタンタイプtypeのpropプロパティにvalをセットする。
ボタンタイプtypeのpropという名前のプロパティを取得する。
ボタンタイプtypeがsupertypeのsubtypeならt
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsバッファー内にボタンの配置や操作を行うコマンドや関数が存在します。
push-button
はユーザーが実際にボタンを押下(push)するために使用するコマンドであり、そのボタンのオーバーレイプロパティかテキストプロパティを使用することにより、そのボタンのRETとmouse-2にデフォルトでバインドされます。ボタン自身の外部で有用なforward-button
やbackward-button
のようなコマンドは、button-buffer-map
に格納されたキーマップ内で追加で利用可能です。ボタンを使用するモードはそのキーマップの親キーマップとしてbutton-buffer-map
の使用を望むかもしれません。
ボタンが非nil
のfollow-link
プロパティをもち、かつmouse-1-click-follows-link
がセットされている場合には、素早いmouse-1クリックによりpush-button
コマンドもアクティブになるでしょう。クリック可能なテキストの定義を参照してください。
位置posにあるボタンが指定するアクションを行う。posはバッファー位置、またはマウスイベントのいずれか。use-mouse-actionが非nil
、またはposがマウスイベントならaction
のかわりにそのボタンのmouse-action
プロパティの呼び出しを試みて、ボタンにmouse-action
プロパティがなければ通常のようにaction
を使用する。push-button
がマウスイベントの結果としてインタラクティブに呼び出されたときはそのマウスイベントの位置、それ以外ではポイントの位置がposのデフォルトになる。posにボタンがなければ何もせずにnil
をリターンして、それ以外ならt
をリターンする。
次のn番目、nが負なら前のn番目のボタンに移動する。nが0ならポイント位置にある任意のボタンの開始に移動する。wrapが非nil
ならバッファーの先頭または終端を超えてもう一方の端へ移動を継続する。display-messageが非nil
ならボタンのhelp-echo文字列が表示される。非nil
のskip
プロパティをもつボタンはすべてスキップされる。見つかったボタンをリターンする。
前のn番目、nが負なら次のn番目のボタンに移動する。nが0ならポイント位置にある任意のボタンの開始に移動する。wrapが非nil
ならバッファーの先頭または終端を超えて、もう一方の端へ移動を継続する。display-messageが非nil
ならボタンのhelp-echo文字列が表示される。非nil
のskip
プロパティをもつボタンはすべてスキップされる。見つかったボタンをリターンする。
カレントバッファー内の位置posの次(next-button
の場合)、または前(previous-button
の場合)のボタンをリターンする。count-currentが非nil
なら、次のボタンから検索を開始するかわりにposにある任意のボタンを考慮する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
EwocパッケージはLispオブジェクトの構造を表すバッファーテキストを構成して、その構造体の変更にしたがってテキストを更新します。これはデザインパラダイム“model–view–controller”内の“view”コンポーネントと似ています。Ewocは“Emacs’s Widget for Object Collections(オブジェクトコレクション用Emacsウィジェット)”を意味します。
ewocは特定のLispデータを表現するバッファーテキストの構築に要される情報を組織化します。ewocのバッファーテキストは順番に、まず固定されたheaderテキスト、次に一連のデータ要素のテキスト記述(あなたが指定するLispオブジェクト)、最後に固定されたfooterテキストという3つのパートをもっています。具体的にはewocは以下の情報を含んでいます:
通常はewoc-create
によりewocを定義して、その結果のewoc構造体内にノードを構築するためにEwocパッケージ内の別の関数に渡してバッファー内に表示します。バッファー内でこれが一度表示されれば、他の関数はバッファー位置とノードの対応を判断したり、あるノードのテキスト表現から別のノードのテキスト表現への移動等を行います。抽象ディスプレーの関数を参照してください。
ノードは変数が値を保持するのと同じ方法でデータ要素をカプセル化(encapsulate)します。カプセル化は通常はewocへのノード追加の一部として発生します。以下のようにデータ要素値を取得して、その場所に新たな値を配置することができます:
(ewoc-data node) ⇒ value (ewoc-set-data node new-value) ⇒ new-value
データ要素値として実際の値のコンテナーであるようなLispオブジェクト(リストまたはベクター)、または他の構造体へのインデックスも使用できます。例(抽象ディスプレーの例を参照)では後者のアプローチを使用しています。
データが変更された際にはバッファー内のテキストを更新したいでしょう。ewoc-refresh
呼び出しにより全ノード、ewoc-invalidate
を使用して特定のノード、またはewoc-map
を使用して述語を満足するすべてのノードを更新できます。あるいはewoc-delete
を使用して無効なノードを削除したり、その場所に新たなノードを追加できます。ewocからのノード削除はバッファーからそれに関連付けられたテキスト記述も同様に削除します。
37.20.1 抽象ディスプレーの関数 | Ewocパッケージ内の関数。 | |
37.20.2 抽象ディスプレーの例 | Ewocの使用例。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは、ewocとnodeは上述(抽象的なディスプレーを参照)の構造体を、dataはデータ要素として使用される任意のLispオブジェクトを意味します。
これはノード(とデータ要素)をもたない新たなewocを構築してリターンする。pretty-printerは1つの引数を受け取る関数であること。この引数は当該ewoc内で使用を計画する類のデータ要素であり、insert
を使用してポイント位置にそのテキスト記述を挿入する(Ewocパッケージの内部的メカニズムと干渉するためにinsert-before-markers
は決して使用しない)。
ヘッダー、フッター、およびすべてのノードのテキスト記述の後には、通常は自動的に改行が挿入される。nosepが非nil
なら改行は何も挿入されない。これはewoc全体を単一行に表示したり、これらのノードにたいして何も行わないようにpretty-printerをアレンジすることによりノードを不可視にするために有用かもしれない。
ewocは作成時にカレントだったバッファー内のテキストを保守するので、ewoc-create
呼び出し前に意図するバッファーへ切り替えること。
これは、ewocがそのテキストを保守するバッファーをリターンする。
これはewocのヘッダーとフッターから作成されたコンスセル(header
. footer)
をリターンする。
これはewocのヘッダーとフッターに文字列headerとfooterをセットする。
これらはそれぞれdataを新たなノードにカプセル化して、それをewocのチェーンノードの先頭または終端に配置する。
これらはそれぞれdataを新たなノードにカプセル化して、それをewocのnodeの前または後に追加する。
これらはそれぞれewoc内のnodeの前または次のノードをリターンする。
これはewoc内で0基準のインデックスnで見つかったノードをリターンする。負のnは終端から数えることを意味する。nが範囲外ならewoc-nth
はnil
をリターンする。
これはnodeにカプセル化されたデータを抽出してリターンする。
これはnodeにカプセル化されるデータとしてdataをセットする。
これはポイント(指定された場合はpos)を含むewoc内のノードを判断して、そのノードをリターンする。ewocがノードをもたなければ、nil
をリターンする。posが最初のノードの前なら最初のノード、最後のノードの後なら最後のノードをリターンする。オプションの3つ目の引数guessは、pos近傍にあると思われるノードであること。これは結果を変更しないが、関数の実行を高速にする。
これはnodeの開始位置をリターンする。
これらはそれぞれewoc内の前または次のarg番目のノードにポイントを移動する。すでに最初のノードにポイントがある場合、またはewocが空の場合にはewoc-goto-prev
は移動しない。またewoc-goto-next
が最後のノードを超えて移動すると結果はnil
。この特殊なケースを除き、これらの関数は移動先のノードをリターンする。
これはewoc内のnodeの開始にポイントを移動する。
この関数はewocのテキストを再生成する。これはヘッダーとフッターの間のテキスト、すなわちすべてのデータ要素の表現を削除して、各ノードにたいして1つずつ順にpretty-printer関数を呼び出すことによりすることにより機能する。
これはewoc-refresh
と似ているが、ewoc内のノードセット全体ではなくnodesだけを対象とする点が異なる。
これはewocからnodes内の各要素を削除する。
これはewoc内の各データ要素にたいしてpredicateを呼び出して、predicateがnil
をリターンしたノードを削除する。任意のargsをpredicateに渡すことができる。
これはewoc内の各データ要素にたいしてpredicateを呼び出して、predicateが非nil
をリターンしたノードのリストをリターンする。リスト内の要素はバッファー内での順序になる。任意のargsをpredicateに渡すことができる。
これはewoc内の各データ要素にたいしてmap-functionを呼び出して、map-functionが非nil
をリターンしたノードを更新する。任意のargsをmap-functionに渡すことができる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下は3つの整数からなるベクターを表すバッファー内の領域であるカラー構成(color components)表示をewocパッケージ内の関数を使用して、さまざまな方法で実装するシンプルな例です。
(setq colorcomp-ewoc nil colorcomp-data nil colorcomp-mode-map nil colorcomp-labels ["Red" "Green" "Blue"]) (defun colorcomp-pp (data) (if data (let ((comp (aref colorcomp-data data))) (insert (aref colorcomp-labels data) "\t: #x" (format "%02X" comp) " " (make-string (ash comp -2) ?#) "\n")) (let ((cstr (format "#%02X%02X%02X" (aref colorcomp-data 0) (aref colorcomp-data 1) (aref colorcomp-data 2))) (samp " (sample text) ")) (insert "Color\t: " (propertize samp 'face `(foreground-color . ,cstr)) (propertize samp 'face `(background-color . ,cstr)) "\n")))) (defun colorcomp (color) "新たなバッファー内でCOLORの編集を許可する。 そのバッファーはColor Componentsモードになる。" (interactive "sColor (name or #RGB or #RRGGBB): ") (when (string= "" color) (setq color "green")) (unless (color-values color) (error "No such color: %S" color)) (switch-to-buffer (generate-new-buffer (format "originally: %s" color))) (kill-all-local-variables) (setq major-mode 'colorcomp-mode mode-name "Color Components") (use-local-map colorcomp-mode-map) (erase-buffer) (buffer-disable-undo) (let ((data (apply 'vector (mapcar (lambda (n) (ash n -8)) (color-values color)))) (ewoc (ewoc-create 'colorcomp-pp "\nColor Components\n\n" (substitute-command-keys "\n\\{colorcomp-mode-map}")))) (set (make-local-variable 'colorcomp-data) data) (set (make-local-variable 'colorcomp-ewoc) ewoc) (ewoc-enter-last ewoc 0) (ewoc-enter-last ewoc 1) (ewoc-enter-last ewoc 2) (ewoc-enter-last ewoc nil)))
この例はcolorcomp-data
の変更して選択プロセスを“完了”して、それらを互いに簡便に結ぶキーマップを定義することにより(言い換えると“model/view/controller”デザインパラダイムのcontroller部分)、“color
selection widget”への拡張が可能です。
(defun colorcomp-mod (index limit delta) (let ((cur (aref colorcomp-data index))) (unless (= limit cur) (aset colorcomp-data index (+ cur delta))) (ewoc-invalidate colorcomp-ewoc (ewoc-nth colorcomp-ewoc index) (ewoc-nth colorcomp-ewoc -1)))) (defun colorcomp-R-more () (interactive) (colorcomp-mod 0 255 1)) (defun colorcomp-G-more () (interactive) (colorcomp-mod 1 255 1)) (defun colorcomp-B-more () (interactive) (colorcomp-mod 2 255 1)) (defun colorcomp-R-less () (interactive) (colorcomp-mod 0 0 -1)) (defun colorcomp-G-less () (interactive) (colorcomp-mod 1 0 -1)) (defun colorcomp-B-less () (interactive) (colorcomp-mod 2 0 -1)) (defun colorcomp-copy-as-kill-and-exit () "color componentsをkillリングにコピーしてバッファーをkill。 文字列は#RRGGBB(6桁16進が付加されたハッシュ)にフォーマットされる。" (interactive) (kill-new (format "#%02X%02X%02X" (aref colorcomp-data 0) (aref colorcomp-data 1) (aref colorcomp-data 2))) (kill-buffer nil)) (setq colorcomp-mode-map (let ((m (make-sparse-keymap))) (suppress-keymap m) (define-key m "i" 'colorcomp-R-less) (define-key m "o" 'colorcomp-R-more) (define-key m "k" 'colorcomp-G-less) (define-key m "l" 'colorcomp-G-more) (define-key m "," 'colorcomp-B-less) (define-key m "." 'colorcomp-B-more) (define-key m " " 'colorcomp-copy-as-kill-and-exit) m))
わたしたちが決して各ノード内のデータを変更していないことに注意してください。それらのデータはewoc作成時にnil
、または実際のカラーコンポーネントであるベクターcolorcomp-data
にたいするインデックスに固定されています。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではユーザーが閉カッコを挿入した際に、マッチする開カッコをEmacsが示すメカニズムを説明します。
この変数の値は閉カッコ構文(close parenthesis
syntax)の文字が挿入された際に常に呼び出される関数(引数なし)であること。blink-paren-function
の値はnil
も可能であり、この場合は何も行わない。
この変数がnil
ならblink-matching-open
は何も行わない。
この変数はギブアップする前にマッチするカッコをスキャンする最大の距離を指定する。
この変数はマッチするカッコを示し続ける秒数を指定する。分数の秒も良好な結果をもたらすことがあるが、デフォルトはすべてのシステムで機能する1である。
この関数はblink-paren-function
のデフォルト値である。この関数は閉カッコ構文の文字の後にポイントがあると仮定して、マッチする開カッコに瞬時適切な効果を適用する。その文字がまだスクリーン上になければ、エコーエリア内にその文字のコンテキストを表示する。長い遅延を避けるために、この関数は文字数blink-matching-paren-distance
より遠くを検索しない。
以下はこの関数を明示的に呼び出す例。
(defun interactive-blink-matching-open () "ポイント前のカッコによるsexp開始を瞬時示す" (interactive)
(let ((blink-matching-paren-distance (buffer-size)) (blink-matching-paren t)) (blink-matching-open)))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは文字がEmacsにより実際に表示される方法について説明します。文字は通常はグリフ(glyph)として表示されます。グリフとはスクリーン上で1文字の位置を占めるグラフィカルなシンボルであり、その外観はその文字自身に対応します。たとえば文字‘a’ (文字コード97)は‘a’と表示されます。しかしいくつかの文字は特別な方法で表示されます。たとえば改頁文字(文字コード12)は通常は2つのグリフのシーケンス‘^L’で表示されて、改行文字(文字コード10)は新たなスクリーン行を開始します。
ディスプレイテーブル(display table)を定義することにより、各文字が表示される方法を変更できます。これはそれぞれの文字をグリフのシーケンスにマップするテーブルです。ディスプレーテーブルを参照してください。
37.22.1 通常の表示の慣習 | 文字の表示にたいする通常の慣習。 | |
37.22.2 ディスプレーテーブル | ディスプレイテーブルの構成要素。 | |
37.22.3 アクティブなディスプレーテーブル | 使用するディスプレイテーブルをEmacsが選択する方法。 | |
37.22.4 グリフ | グリフの定義方法とグリフの意味。 | |
37.22.5 グリフ文字の表示 | グリフなしの文字の描画方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下は各文字コードの表示にたいする慣習です(ディスプレイテーブルが存在しなければこれらの慣習をオーバーライドできる 。ディスプレーテーブル)を参照)。
tab-width
はタブストップごとのスペース数を制御する(以下参照)。
ctl-arrow
に応じて2つの方法のいずれかで表示される。この変数が非nil
(デフォルト)なら、たとえばDELにたいしては‘^?’のように、これらの文字は1つ目のグリフが‘^’
(‘^’のかわりに使用する文字をディスプレイテーブルで指定できる)のような2つのグリフのシーケンスとして表示される。
ctl-arrow
がnil
なら、これらの文字は8進エスケープとして表示される(以下参照)。
このルールはバッファー内に復帰文字(CR: carriage return、文字コード13)があればそれにも適用される。しかし復帰文字は通常はバッファーテキスト内には存在しない。これらは行末変換(end-of-line conversion)の一部として除去される(コーディングシステムの基本概念を参照)。
上記の表示慣習はたとえディスプレイテーブルがあっても、アクティブディスプレイテーブル内のエントリーがnil
であるようなすべての文字にたいして適用されます。したがってディスプレイテーブルのセットアップ時に指定が必要なのは特別な振る舞いを望む文字だけです。
以下の変数はスクリーン上で特定の文字が表示される方法に影響します。これらはその文字が占める列数を変更するのでインデント関数にも影響を与えます。またモードラインが表示される方法にも影響があります。新たな値を使用してモードラインを強制的に再表示するには関数force-mode-line-update
を呼び出してください(モードラインのフォーマットを参照)。
このバッファーローカル変数はコントロール文字が表示される方法を制御する。非nil
なら‘^A’のようにカレットとその文字、nil
なら‘\001’のようにバックスラッシュと8進3桁のように8進エスケープとして表示される。
このバッファーローカル変数の値はEmacsバッファー内でのタブ文字表示で使用するタブストップ間のスペース数。値は列単位でデフォルトは8。この機能はコマンドtab-to-tab-stop
で使用されるユーザー設定可能なタブストップとは完全に無関係であることに注意。Adjustable Tab Stopsを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ディスプレイテーブルとはサブタイプとしてdisplay-table
をもつ特殊用途の文字テーブル(文字テーブルを参照)であり、文字の通常の表示慣習をオーバーライドするために使用されます。このセクションではディスプレイテーブルオブジェクトの作成と調査、および要素を割り当てる方法について説明します。
これはディスプレイテーブルを作成してリターンする。テーブルは初期状態ではすべての要素にnil
をもつ。
ディスプレイテーブルの通常の要素は文字コードによりインデックス付けされます。インデックスcの要素はコードcの表示方法を示します。値はnil
(これは通常の表示慣習に応じて文字cを表示することを意味する。通常の表示の慣習を参照)、またはグリフコードのベクター(これらのグリフとして文字cを表示することを意味する。グリフを参照)のいずれかです。
警告: 改行文字の表示を変更するためにディスプレイテーブルを使用すると、バッファー全体が1つの長い行として表示されるでしょう。
ディスプレイテーブルは特殊用途向け6つのエクストラスロット(extra
slots)をもつこともできます。以下はそれらの意味についてのテーブルです。nil
のスロットは以下で示すそのスロットにたいするデフォルトの使用を意味します。
切り詰められたスクリーン行終端のグリフ(デフォルトでは‘$’)。グリフを参照のこと。グラフィカルな端末ではEmacsは切り詰められたことをフリンジ内の矢印で示してディスプレイテーブルは使用しない。
継続行終端のグリフ(デフォルトは‘\’)。グラフィカルな端末ではEmacsは継続をフリンジ内の曲矢印で示してディスプレイテーブルは使用しない。
8進文字コードとして表示される文字を示すグリフ(デフォルトは‘\’)。
コントロール文字を示す(デフォルトは‘^’)。
不可視行があることを示すグリフのベクター(デフォルトは‘...’)。選択的な表示を参照のこと。
横並びのウィンドウ間のボーダー描画に使用されるグリフ(デフォルトは‘|’)。ウィンドウの分割を参照のこと。これはスクロールバーが存在するときだけ効果をもつ。スクロールバーがサポートされていて使用中ならスクロールバーが2つのウィンドウを分割する。
たとえば以下は関数make-glyph-code
にたいしてctl-arrow
に非nil
をセットして得られる効果を模倣するディスプレイテーブル(グリフを参照のこと)を構築する例です:
(setq disptab (make-display-table)) (dotimes (i 32) (or (= i ?\t) (= i ?\n) (aset disptab i (vector (make-glyph-code ?^ 'escape-glyph) (make-glyph-code (+ i 64) 'escape-glyph))))) (aset disptab 127 (vector (make-glyph-code ?^ 'escape-glyph) (make-glyph-code ?? 'escape-glyph)))))
この関数はdisplay-tableのエクストラスロットslotの値をリターンする。引数slotには0から5の数字(両端を含む)、またはスロット名(シンボル)を指定できる。有効なシンボルはtruncation
、wrap
、escape
、control
、selective-display
、vertical-border
。
この関数はdisplay-tableのエクストラスロットslotにvalueを格納する。引数slotには0から5の数字(両端を含む)、またはスロット名(シンボル)を指定できる。有効なシンボルはtruncation
、wrap
、escape
、control
、selective-display
、vertical-border
。
この関数はヘルプバッファーにディスプレイテーブルdisplay-tableの説明を表示する。
このコマンドはヘルプバッファーにカレントディスプレイテーブルの説明を表示する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウはそれぞれディスプレイテーブルを指定でき、各バッファーもディスプレイテーブルを指定できます。もしウィンドウにディスプレイテーブルがあれば、それはバッファーのディスプレイテーブルより優先されます。ウィンドウとバッファーがいずれもディスプレイテーブルをもたなければ、Emacsは標準的なディスプレイテーブルの使用を試みます。標準ディスプレイテーブルがnil
ならEmacsは通常の文字表示慣習を使用します(通常の表示の慣習を参照)。
ディスプレイテーブルはモードラインが表示される方法に影響を与えるので、新たなディスプレイテーブルを使用してモードラインを強制的に再表示するにはforce-mode-line-update
を使用することに注意してください(モードラインのフォーマットを参照)。
この関数はwindowのディスプレイテーブル、ディスプレイテーブルがなければnil
をリターンする。windowのデフォルトは選択されたウィンドウ。
この関数はwindowのディスプレイテーブルにtableをセットする。引数tableはディスプレイテーブルかnil
のいずれかであること。
この変数はすべてのバッファーにおいて自動的にバッファーローカルになる。変数の値はバッファーのディスプレイテーブルを指定する。これがnil
ならバッファーのディスプレイテーブルは存在しない。
この変数の値は、ウィンドウ内にバッファーを表示する際にウィンドウディスプレイテーブルとバッファーディスプレイテーブルのいずれも定義されていないときや、Emacsがテキストを標準出力やエラーストリームに出力中のときにEmacsが使用する標準ディスプレイテーブル(standard
display table)。変数のデフォルトは通常はnil
だが、対話的なセッションで端末がcurved
quotesを表示できなければ、そのデフォルトはcurved quotesをASCIIに近似的にマップする。ドキュメント内でのキーバインディングの置き換えを参照のこと。
disp-tableライブラリーでは、標準ディスプレイテーブルを変更するために、いくつかの関数を定義されています。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
グリフ(glyph)とはスクリーン上で1文字を占めるグラフィカルなシンボルです。各グリフはLisp内でグリフコード(glyph code)として表現されます。これは文字と、表示するフェイスをオプションで指定します(フェイスを参照)。ディスプレイテーブル内でのエントリーとしての使用がグリフコードの主な用途です(ディスプレーテーブルを参照)。以下の関数はグリフコードを操作するために使用されます:
この関数は文字charを表すグリフをフェイスfaceでリターンする。faceが省略かnil
ならグリフはデフォルトフェイスを使用して、その場合にはグリフコードは整数。faceが非nil
ならグリフコードが整数オブジェクトである必要はない。
この関数はグリフコードglyphの文字をリターンする。
この関数はグリフコードglyphのフェイス、またはglyphがデフォルトフェイスを使用する場合にはnil
をリターンする。
テキスト端末上で実際にどのようにグリフコードを表示するかを変更するためにglyph
tableをセットアップできる。この機能は半ば時代遅れであり、かわりにglyphless-char-display
を使用すること(グリフ文字の表示を参照)。
この変数の値が非nil
なら、それはカレントグリフテーブルである。これは文字端末上でのみ効果があり、グラフィカルディスプレイ上ではすべてのグリフはそのままliteralに表示される。グリフテーブルはg番目の要素がグリフコードgの表示方法を指定するようなベクターであること。ここでgはフェイス未指定なグリフにたいするグリフコード。要素はそれぞれ以下のいずれかであること:
nil
そのグリフをそのままliteralに表示する。
指定された文字列を端末に送信することによりグリフを表示する。
指定されたグリフコードをかわりに表示する。
グリフテーブルのテーブル長以上の整数グリフコードは、そのままliteralに表示される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
グリフ無し文字(glyphless characters)とはliteralに表示されるのではなく特別な方法、すなわち16進コードを中に含むボックスとして表示される文字です。これらの文字にはグリフが無いと明示的に定義された文字や、利用可能なフォントがない文字(グラフィカルなディスプレイ)、その端末のコーディングシステムではエンコードできない文字(テキスト端末)が同様に含まれます。
この変数の値はグリフ無し文字と表示方法を定義する文字テーブル。エントリーはそれぞれ以下の表示メソッドのいずれかでなければならない:
nil
通常の方法でその文字を表示する。
zero-width
その文字を表示しない。
thin-space
グラフィカルな端末では幅が1ピクセル、テキスト端末では幅が1文字の狭いスペース。
empty-box
空のボックスを表示する。
hex-code
その文字のUnicodeコードポイントの16進表記を含むボックスを表示する。
その文字列を含むボックスを表示する。文字列には最大で6文字が含まれること。
(graphical . text)
グラフィカルな端末ではgraphical、テキスト端末ではtextをで表示する。graphicalとtextはいずれも上述した表示メソッドのいずれかでなければならない。
thin-space
、empty-box
、hex-code
、およびASCII文字列はglyphless-char
フェイスで描画される。テキスト端末ではボックスはsquare
brackets ‘[]’でエミュレートされる。
文字テーブルには利用可能なすべてのフォントでも表示できない、またはその端末のコーディングシステムでエンコードできないすべての文字の表示方法を定義する余分なスロットが1つある。その値は上述した表示メソッドのうちzero-width
とコンスセル以外のいずれかでなければならない。
アクティブなディスプレイテーブル内に非nil
なエントリーをもつ文字では、そのディスプレイテーブルが効果をもつ。この場合にはEmacsはglyphless-char-display
をまったく参照しない。
このユーザーオプションは似かよった文字のグループにたいしてglyphless-char-display
をセットする便利な手段を提供する。Lispコードからこの値を直接セットしてはならない。glyphless-char-display
更新するカスタム関数:set
を通じた場合のみ値は効果をもつ。
この値は要素が(group
.
method)
であるようなalistであること。ここでgroupは文字のグループを指定するシンボル、methodはそれらを表示する方法を指定するシンボル。
groupは以下のいずれかであること:
c0-control
改行文字とタブ文字を除くU+0000
からU+001F
までのASCIIコントロール文字(通常は‘^A’のようなエスケープシーケンスとして表示される。How Text Is Displayed in The GNU Emacs Manualを参照)。
c1-control
U+0080
からU+009F
までの非ASCII、非プリント文字(通常は‘\230’のような8進エスケープシーケンスとして表示される)。
format-control
‘U+200E’のようなUnicode General Category [Cf]の文字だが、‘U+00AD’(Soft Hyphen)のようにグラフィックイメージをもつ文字を除く。
no-font
適切なフォントが存在しないか、その端末のコーディングシステムではエンコードできない文字。
methodシンボルはzero-width
、thin-space
、empty-box
、hex-code
のいずれかであること。これらは上述のglyphless-char-display
での場合と同様の意味をもつ。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではユーザーの注意を喚起するために、Emacsでベルを鳴らす方法を説明します。これを行う頻度は控え目にしてください。頻繁なベルは刺激過剰になる恐れがあります。同様にエラーのシグナル時に過度にビープ音を使用しないよう注意してください。
この関数はビープ音を鳴らす、またはスクリーンをフラッシュする(後述のvisible-bell
を参照)。do-not-terminateがnil
なら、この関数はカレントで実行中のキーボードマクロも終了する。
これはding
のシノニム。
この変数はベルを表すためにスクリーンをフラッシュすべきかどうかを決定する。非nil
ならフラッシュして、nil
ならフラッシュしない。これはグラフィカルなディスプレイで効果的であり、テキスト端末ではその端末のTermcapエントリーが可視ベル(visible
bell) ‘vb’の能力を定義する。
これが非nil
ならEmacsがどのようにベルを鳴らすかを定義すること。値は引数なしの関数であること。これが非nil
ならvisible-bell
より優先される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsは複数のウィンドウシステムで機能しますが、特にXウィンドウシステムにおいてもっとも機能します。EmacsとXはどちらも“ウィンドウ”を使用しますが異なる使い方をします。EmacsのフレームはXにおいては単一のウィンドウです。Emacsの個々のウィンドウについては、Xはまったく関知しません。
この端末ローカルな変数は、Emacsがフレームを表示するのに何のウィンドウシステムを使用しているかを示す。可能な値は、
x
EmacsはXを使用してフレームを表示している。
w32
EmacsはネイティブMS-Windows GUIを使用してフレームを表示している。
ns
EmacsはNextstepインターフェイスを使用してフレームを表示している(GNUstepとMac OS Xで使用)。
pc
EmacsはMS-DOSのスクリーン直接書き込みを使用してフレームを表示している。
nil
Emacsは文字ベース端末を使用してフレームを表示している。
この変数はスタートアップの間にEmacsが作成する最初のフレームにたいして使用されるwindow-system
の値を保持する(Emacsを--daemonオプションで呼び出し時には初期フレームを作成しないので、依然としてw32
であるMS-Windowsを除いてinitial-window-system
はnil
。daemon in The GNU Emacs Manualを参照)。
この関数はframeを表示するために使用されているウィンドウシステムを示す名前のシンボルをリターンする。この関数がリターンし得るシンボルのリストは変数window-system
の記述と同様。
テキスト端末とグラフィカルなディスプレイで異なる処理を行うコードを記述したいときは、window-system
とinitial-window-system
を述語やブーリーンフラグ変数として使用しないでください。これは与えられたディスプレイタイプでのEmacsの能力指標としてwindow-system
が適していないからです。かわりにdisplay-graphic-p
、またはディスプレー機能のテストで説明しているその他の述語display-*-p
を使用してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ツールチップ(Tooltips)はマウスポインターのカレント位置に関連するヘルプ的なヒント(別名“tips”)の表示に使用される特別なフレームです(フレームを参照)。Emacsはテキストのアクティブ範囲(特殊な意味をもつプロパティを参照)、およびメニューアイテム(拡張メニューアイテムを参照)やツールバーのボタン(ツールバーを参照)のような種々のUI要素に関するヘルプ文字列の表示にツールチップを使用します。
Tooltipモードはツールチップの表示を有効にするマイナーモード。このモードをオフにするとツールチップはエコーエリアに表示される。テキストモード(別名“TTY”)のフレームでは、ツールチップは常にエコーエリアに表示される。
GTK+サポート付きでEmacsがビルドされた際にはデフォルトでGTK+関数を使用してツールチップを表示して、ツールチップの外観はGTK+のセッティングにより制御されます。GTK+ツールチップは変数x-gtk-use-system-tooltips
の値をnil
に変更して無効にできます。このセクションの残りではEmacs自身が提供する非GTK+ツールチップを制御する方法を説明します。
ツールチップは特別なフレームなのでフレームパラメーターをもっています(フレームのパラメーターを参照)。他のフレームと異なりツールチップのフレームパラメーターは特別な変数に格納されます。
このカスタマイズ可能なオプションはツールチップ表示に使用するフレームパラメーターを保持する。すべてのフォントおよびカラーのパラメーターは無視して、かわりに対応するtooltip
フェイスの属性が使用される。left
やtop
のパラメーターが含まれていれば、ツールチップが表示されるフレームに相対的な絶対座標として使用される(Tooltips in The GNU Emacs
Manualで説明されている変数を使用してツールチップのマウスに相対的な位置をカスタマイズできる)。(left
とtop
が与えられるとマウスに相対的なオフセットの値はオーバーライドされる)。
tooltip
フェイスはツールチップ内に表示されるテキストの見栄えを決定します。デフォルトのフレームフォントより一般的にはサイズの小さい可変ピッチフォントの使用が必要になります。
これはEmacsがツールチップの表示を必要とする際に呼び出す関数のリストであるようなアブノーマルフック。関数はそれぞれ最後のマウス移動イベントであるeventを単一の引数として呼び出される。このリスト上の関数が実際にツールチップを表示するなら非nil
をリターンして、残りの関数は呼び出されない。この変数のデフォルト値はtooltip-help-tips
という1つの関数。
tooltip-functions
のリストに配置する関数を独自に記述する場合には、ツールチップの表示をトリガーしたマウスイベントのバッファーを知る必要があるかもしれません。以下はこの情報を提供する関数です。
この関数はeventが発生したバッファーをリターンする。テキストがツールチップをトリガーしたバッファーを取得するために、これをtooltip-functions
の関数の引数で呼び出す。イベントはバッファーではないところ(たとえばツールバー)で発生したかもしれず、そのような場合にはこの関数はnil
をリターンする。
ツールチップ表示に関する他の側面は、いくつかのカスタマイズ可能なセッティングにより制御されます。Tooltips in The GNU Emacs Manualを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはアラビア語、ペルシア語、ヘブライ語のような水平方向テキストの自然な表示順がR2L(right-to-left: 右から左)に実行されるようなスクリプトで記述されたテキストを表示できます。さらにL2R(right-to-left: 左から右)のテキストに埋め込まれたR2Lスクリプト(例: プログラムソースファイル内のアラビア語やヘブライ語のコメント)は適宜右から左にR2Lに表示される一方、ラテンスクリプト部やR2Lテキストに埋め込まれた数字はL2Rで表示されます。そのようなL2RとR2Lが混交されたテキストを、わたしたちは双方向テキスト(bidirectional text)と呼んでいます。このセクションでは双方向テキストの編集と表示にたいする機能とオプションについて説明します。
テキストはロジカルな順序(または読込順)、すなわち人間が各文字を読み込むであろう順序でEmacsバッファーや文字列に格納されます。R2Lおよび双方向テキストでは、スクリーン上で文字が表示される順序(ビジュアル順と呼ばれる)はロジカル順と同一ではありません。それら各文字のスクリーン位置は、文字列やバッファー位置により単調に増加しません。この双方向の並べ替え(bidirectional reordering)を処理を行うに際に、EmacsはUnicode双方向アルゴリズム(UBA: Unicode Bidirectional Algorithm)にしたがいます(http://www.unicode.org/reports/tr9/)。EmacsはUnicode Standard v8.0の要求に合致するUBAの“Full Bidirectionality”クラスの実装を提供します。
このバッファーローカル変数の値が非nil
(デフォルト)なら、Emacsは表示で双方向の並べ替えを行う。この並べ替えはバッファーテキスト、同様に文字列表示やバッファー内のテキストプロパティやオーバーレイプロパティ由来のオーバーレイ文字列に効果を及ぼす(オーバーレイのプロパティおよびdisplay
プロパティを参照)。値がnil
ならEmacsはバッファー内での双方向の並べ替えを行わない。
bidi-display-reordering
のデフォルト値は、モードライン内に表示されるテキスト(モードラインのフォーマットを参照)、およびヘッダー行(ウィンドウのヘッダーラインを参照)を含む、バッファーにより直接提供されない文字列の並べ替えを制御する。
たとえバッファーのbidi-display-reordering
が非nil
でも、Emacsがユニバイトバッファーのテキストの並べ替えを行うことはありません。これはユニバイトバッファーに含まれるのが文字ではなくrawバイトであり、並べ替えに要する方向的なプロパティを欠くからです。したがってあるバッファーのテキストが並べ替えられるかどうかテストするには、bidi-display-reordering
のテスト単独では不十分です。正しいテストは以下のようになります:
(if (and enable-multibyte-characters bidi-display-reordering) ;; 表示時にバッファーは並べ替えられるだろう )
とはいえ親バッファーが並べ替えられた際には、ユニバイト表示やオーバーレイ文字列は並べ替えられます。これはEmacsによりプレーンASCII文字列がユニバイト文字列に格納されるからです。ユニバイト表示やオーバーレイ文字列が非ASCII文字列を含むなら、それらの文字はL2Rの方向をもつとみなされます。
テキストプロパティdisplay
、値が文字列であるようなdisplay
プロパティによるオーバーレイ、バッファーテキストを置換するその他任意のプロパティにカバーされたテキストは表示時の並べ替えの際には単一の単位として扱われます。つまりこれらのプロパティにカバーされたテキストのchunk全体が一緒に並べ替えられます。さらにそのようなテキストchunk内の文字の双方向的なプロパティは無視されて、Emacsはあたかもそれらがオブジェクト置換文字(Object
Replacement
Character)として知られる単一文字で置換されたかのように並べ替えます。これはテキスト範囲上にdisplayプロパティを配置することにより、表示時に周辺テキストを並べ替える方法が変更され得ることを意味しています。このような予期せぬ効果を防ぐには、常に周辺テキストと等しい方向のテキストにたいしてそのようなプロパティを配置してください。
双方向テキストのパラグラフはそれぞれ、R2LかL2Rいずれかの基本方向(base direction)をもちます。L2Rパラグラフはウィンドウの左マージンを先頭に表示され、そのテキストが右マージンに達したら切り詰めや継続されます。R2Lパラグラフはウィンドウの右マージンを先頭に表示され、そのテキストが左マージンに達したら切り詰めや継続されます。
デフォルトではEmacsはテキスト先頭を調べることにより各パラグラフの基本方向を判断します。基本方向の精細な決定手法はUBAにより指定されており、簡潔に言うとその明示にな方向生をもつそのパラグラフ内の最初の文字がパラグラフの基本方向を決定します。とはいえ、あるバッファーが自身のパラグラフにたいして特定の基本方向の強制を要する場合もあります。たとえばプログラムソースコードを含むバッファーは、すべてのパラグラフがL2Rで表示されるよう強制されるべきでしょう。これを行うために以下の変数を使用できます:
このバッファーローカル変数の値がright-to-left
かleft-to-right
いずれかのシンボルなら、そのバッファー内のすべてのパラグラフがその指定された方向をもつとみなされる。その他すべての値はnil
(デフォルト)と等価であり、それは各パラグラフの基本方向が内容により判断されることを意味する。
プログラムソースコードにたいするモードは、これをleft-to-right
にセットすること。Progモードはデフォルトでこれを行うので、Progモードから派生したモードは明示的にセットする必要はない(基本的なメジャーモードを参照)。
この関数はbufferという名前のバッファーのポイント位置のパラグラフ方向をリターンする。リターンされる値はleft-to-right
かright-to-left
いずれかのシンボルである。bufferが省略またはnil
の場合のデフォルトはカレントバッファー。変数bidi-paragraph-direction
のバッファーローカル値が非nil
なら、リターンされる値はその値と等しくなるだろう。それ以外ならリターンされる値はEmacsにより動的に決定されたパラグラフの方向を反映する。bidi-display-reordering
の値がnil
のバッファー、同様にユニバイトバッファーにたいしては、この関数は常にleft-to-right
をリターンする。
バッファーのカレントのスクリーン位置にたいして、ビジュアル順にL2RかR2Lいずれかの方向に厳密なポイント移動を要す場合があります。Emacsはこれを行うためのプリミティブを提供します。
この関数は、カレントで選択されたウィンドウのバッファーにたいしてポイントを、スクリーン上ですぐ右か左のポイントへ移動する。directionが正ならスクリーン位置は右、それ以外ならスクリーン位置は左へ移動するだろう。周囲の双方向コンテキストに依存して、これは潜在的に多くのバッファーのポイントを移動し得ることに注意。スクリーン行終端で呼び出された場合には、この関数はdirectionに応じて適宜、次行か前行の右端か左端のスクリーン位置にポイントを移動する。
この関数は値として新たなバッファー位置をリターンする。
バッファー内で双方向の内容をもつ2つの文字列が並置されているときや、プログラムで1つのテキスト文字列に結合した場合には、双方向の並べ替えは以外かつ不快な効果を与える可能性があります。典型的な問題ケースはBuffer MenuモードやRmail Summaryモードのようにバッファーがスペースや区切り文字分割されたテキストのフィールドのシーケンスで構成されているときです。それはセパレーターとして使用されている区切り文字が弱い方向性をもち、周囲のテキストの方向を採用するためです。結果として双方向の内容のフィールドが後続する数値フィールドは、先行するフィールドヘ左方向に表示され、期待したレイアウトを破壊してしまいます。この問題を回避するための方法がいくつかあります:
U+200E
を付加する。後述の関数bidi-string-mark-left-to-right
はこの目的に手頃である(R2LパラグラフではかわりにRIGHT-TO-LEFT
MARK、略してRLMのU+200F
を使用する)。これはUBAにより推奨される解決策の1つ。
display
プロパティ、または(space . PROPS)
という形式の値をもつオーバーレイ(スペースの指定を参照)でフィールドを区切る。Emacsはこのdisplay仕様をパラグラフセパレーター(paragraph
separator)として扱い両側のテキストを個別に並べ替える。
この関数は結果を安全に他の文字列に結合できるよう、あるいはこの文字列とスクリーン上で次行となる行に関連するレイアウトを乱すことなくバッファー内の他の文字列に並置できるよう、自身への引数stringを恐らく変更してリターンする。この関数がリターンする文字列がR2Lパラグラフの一部として表示される文字列なら、それは常に後続するテキストの左に出現するだろう。この関数は自身の引数の文字を検証することにより機能して、もしそれらの文字のいずれかがディスプレイ上の並べ替えを発生し得るなら、この関数はその文字列にLRM文字を付加する。付加されたLRM文字はテキストプロパティinvisible
にt
を与えることにより不可視にできる(不可視のテキストを参照)。
並べ替えアルゴリズムはbidi-class
プロパティとして格納された文字の双方向プロパティを使用します(文字のプロパティを参照)。Lispプログラムはput-char-code-property
関数を呼び出すことにより、これらのプロパティを変更できます。しかしこれを行うにはUBAの完全な理解が要求されるので推奨しません。ある文字の双方向プロパティにたいする任意の変更はグローバルな効果をもちます。これらはEmacsのフレームのすべてのフレームとウィンドウに影響します。
同様にmirroring
プロパティは並べ替えられたテキスト内の適切にミラーされた文字の表示に使用されます。Lispプログラムはこのプロパティを変更することにより、ミラーされた表示に影響を与えることができます。繰り返しますがそのような変更はEmacsのすべての表示に影響を与えます。
スペシャル双方向制御文字LEFT-TO-RIGHT OVERRIDE (LRO)とRIGHT-TO-LEFT OVERRIDE (RLO)をテキストに挿入することにより、文字の双方向プロパティをオーバーライドできます。RLOと改行かPOP DIRECTIONAL FORMATTING (PDF)のいずれか先にある文字間のすべての文字は、それらが強いR2Lであるかのように表示されます(反転して表示される)。同様にLROとPDFか改行の間のすべての文字は、それらがたとえ強いR2Lであっても強いL2Rであるかのように反転して表示されません。
これらのオーバーライドは、あるテキストを並び替えアルゴリズムの影響を受けずに、直接表示順を制御したいときに有用です。しかしこれらはフィッシング(phishing)として知られるような悪意のある用途にも使用されます。特にウェブ上のURLやemailメッセージ内のリンクは真のリンク先はまったく異なるのに、ブラウザによる論理順で解釈される外観を認識不能に操作したり、何らかの著名で安全なリンク先に偽装される可能性があります。
Emacsはアプリケーションが使用するために、双方向プロパティでL2R文字をR2L、またはその逆にするようにオーバーライドされたテキストのインスタンスを検知するプリミティブを提供します。
この関数はobjectで指定されたテキストのfrom (含む)とto
(含まず)の間のテキストを調べてR2Lの文字であるかのように表示が強制されている双方向プロパティの強いL2R文字、L2Rの文字であるかのように表示が強制されている強いR2L文字の最初の位置をリターンする。指定されたテキストリージョンでそのような文字が見つからなければnil
をリターンする。
オプション引数objectは検索するテキストを指定して、デフォルトはカレントバッファー。objectが非nil
なら別のバッファーや文字列、またはウィンドウかもしれない。文字列ならこの関数はその文字列を検索する。ウィンドウならこの関数はそのウィンドウが表示するバッファーを検索する。検査したいテキストをもつバッファーが何らかのウィンドウに表示されていれば、この関数にバッファーを渡すのではなくそのウィンドウの指定を推奨する。これはウィンドウ固有のオーバーレイにカバーされたバッファーのテキストでは関数の結果が変化し得るが、関数にウィンドウ固有のオーバーレイを正しく考慮するように指示するからである。
テキストがR2L文字とL2R文字の混交を含み、かつ双方向制御が別の場所にコピーされる際には、その視覚的外見は変化するかもしれず、コピー先の周辺テキストの視覚的外見にも影響するかもしれません。これはUBAで指定される双方向テキストの並び替えでは、コピーされるテキストとそれを取り囲む周辺テキストの両方が非自明かつコンテキスト依存の効果をもつからです。
コピーされるテキストとコピー先周辺のテキストの視覚的外見をLispプロパティが保証することが必要なときがあるかもしれません。この効果を達成するためにLispプログラムは以下の関数を使用できます。
この関数はbuffer-substring
(バッファーのコンテンツを調べるを参照)と同様に機能するが、テキストが別の場所にコピーされる際に視覚的外見を保つために必要な双方向制御文字を前や後に付加する点が異なる。オプション引数no-propertiesが非nil
なら、それはテキストのコピーからテキストプロパティを削除することを意味する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
これはEmacsの開始と終了、オペレーティングシステム内の値へのアクセス、端末の入力と出力に関するチャプターです。
関連する情報はEmacsのビルドを参照してください。端末とスクリーンに関連するオペレーティングシステムの状態に関する追加情報はEmacsのディスプレー表示を参照してください。
38.1 Emacsのスタートアップ | Emacsのスタートアッププロセスのカスタマイズ。 | |
38.2 Emacsからの脱出 | (永久または一時的に)exitが機能する方法。 | |
38.3 オペレーティングシステムの環境 | システム名と種類の区別。 | |
38.4 ユーザーの識別 | ユーザーの名前とユーザーIDを調べる。 | |
38.5 時刻 | カレント時刻の取得。 | |
38.6 Time Zone Rules | タイムゾーンと夏時間のルール。 | |
38.7 時刻の変換 | 時刻の数値形式からカレンダーデータへの変換と逆変換。 | |
38.8 時刻のパースとフォーマット | 時刻の数値形式からテキストへの変換と逆変換。 | |
38.9 プロセッサーの実行時間 | Emacsによる実行時間の取得。 | |
38.10 時間の計算 | 時間の加減算、その他。 | |
38.11 遅延実行のためのタイマー | 特定時刻に関数を呼び出すためにターマーをセットする。 | |
38.12 アイドルタイマー | Emacsが特定の時間の間アイドル時に関数を呼び出すためにタイマーをセットする。 | |
38.13 端末の入力 | 端末入力へのアクセスと記録。 | |
38.14 端末の出力 | 端末出力の制御と記録。 | |
38.15 サウンドの出力 | コンピューターのスピーカーでのサウンド再生。 | |
38.16 X11キーシンボルの処理 | Xウィンドウにたいするキーシンボルの操作。 | |
38.17 batchモード | 端末との対話なしでEmacsを実行する。 | |
38.18 セッションマネージャー | Xセッション管理の保存とリストア。 | |
38.19 デスクトップ通知 | ||
38.20 ファイル変更による通知 | ファイル通知。 | |
38.21 動的にロードされるライブラリー | サポートライブラリーのオンデマンドロード。 | |
38.22 Security Considerations | 非有効的な環境でのEmacsの実行。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではEmacsが開始時に何を行うか、およびそれらのアクションのカスタマイズ方法を説明します。
38.1.1 要約: スタートアップ時のアクション順序 | スタートアップ時にEmacsが行うアクションの順序。 | |
38.1.2 initファイル | initファイル読み込みの詳細。 | |
38.1.3 端末固有の初期化 | 端末固有のLispファイルの読み込み方法。 | |
38.1.4 コマンドライン引数 | コマンドライン引数の処理とカスタマイズの方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsは起動時に以下の処理を行います(startup.el内のnormal-top-level
を参照):
load-path
の各ディレクトリー内にあるsubdirs.elという名前のファイルを実行してload-path
にサブディレクトリーを追加する。このファイルは通常はそのディレクトリー内にあるサブディレクトリーをこのリスト変数に追加して、それらを順次スキャンする。ファイルsubdirs.elは通常はEmacsインストール時に自動的に作成される。
load-path
のディレクトリー内で見つかったleim-list.elをすべてロードする。このファイルは入力メソッドの登録を意図している。この検索はユーザーが作成するかもしれない個人的なleim-list.elすべてにたいしてのみ行われる。標準的なEmacsライブラリーを含むディレクトリーはスキップされる(これらは単一のleim-list.elだけに含まれるべきでありEmacs実行形式にコンパイル済)。
before-init-time
にcurrent-time
の値をセットする(時刻を参照)。これはafter-init-time
にnil
をセットすることによりEmacs初期化時にLispプログラムへの合図も行う。
LANG
のような環境変数がそれを要するなら言語環境と端末のコーディングシステムをセットする。
initial-window-system
が指定するウィンドウシステムを初期化する(initial-window-systemを参照)。サポートされる各ウィンドウシステムにたいする初期化関数はwindow-system-initialization-alist
により指定される。initial-window-system
の値がwindowsystemならファイルterm/windowsystem-win.el内で適切な初期化関数が定義されている。このファイルはビルド時にEmacs実行可能形式にコンパイルされているべきである。
before-init-hook
を実行する。
custom-delayed-init-variables
内のメンバーを再初期化するためにcustom-reevaluate-setting
を使用する。これらのメンバーは、デフォルト値がビルド時ではなく実行時のコンテキストに依存する、すべての事前ロード済ユーザーオプションである。custom-initialize-delayを参照のこと。
inhibit-default-init
が非nil
、あるいはオプション‘-q’、‘-Q’、または‘--batch’指定された場合には行われない。
abbrev-file-name
で指定されるファイルからユーザーのabbrevをロードする(abbrev-file-nameを参照)。オプション‘--batch’が指定されていたら行われない。
package-initialize
を呼び出す。パッケージ化の基礎を参照のこと。しかしpackage-enable-at-startup
がnil
、または‘-q’、‘-Q’、‘--batch’のいずれかのオプションで開始時には、Emacsはパッケージの初期化をしない。後者のケースでパッケージを初期化するには、(たとえば‘--funcall’オプションを通じて)明示的にpackage-initialize
を呼び出すこと。
after-init-time
にcurrent-time
の値をセットする。この変数は事前にnil
にセットされている。これをカレント時刻にセットすることが初期化フェーズが終わったことの合図となり、かつbefore-init-time
と共に用いることにより初期化に要した時間の計測手段を提供する。
after-init-hook
を実行する。
initial-major-mode
に応じたメジャーモードをセットする。
tty-setup-hook
を実行する。これは--batch
モード、またはterm-file-prefix
がnil
なら実行されない。
inhibit-startup-echo-area-message
で抑制していなければエコーエリアに初期メッセージを表示する。
--batch
が指定されていたら、ここでexitする。
(substitute-command-keys
initial-scratch-message)
を挿入する。
initial-buffer-choice
が文字列ならその名前のファイル(かディレクトリー)をvisitする。関数なら引数なしでその関数を呼び出して、それがリターンしたバッファーを選択する。コマンドライン引数として単一のファイルが与えられた場合にはファイルをvisitして、そのバッファーをinitial-buffer-choice
のそばに表示する。複数のファイルが与えられた場合にはすべてのファイルをvisitして、initial-buffer-choice
のそばに*Buffer
List*バッファーを表示する。
emacs-startup-hook
を実行する。
frame-notice-user-settings
を呼び出す。
window-setup-hook
を実行する。このフックとemacs-startup-hook
の違いは前述したフレームパラメーターの変更後にこれが実行される点のみ。
inhibit-startup-screen
かinitial-buffer-choice
が非nil
、あるいはコマンドラインオプション‘--no-splash’か‘-Q’が指定されていたら行われない。
--daemon
が指定された場合、またはPosixシステムの場合にもserver-start
を呼び出して制御端末からデタッチする。Emacs
Server in The GNU Emacs Manualを参照のこと。
emacs-session-restore
を呼び出す。セッションマネージャーを参照のこと。
以下のオプションはスタートアップシーケンスにおけるいくつかの側面に影響を与えます。
この変数が非nil
ならスタートアップスクリーンを抑制する。この場合にはEmacsは通常は*scratch*バッファーを表示する。しかし以下のinitial-buffer-choice
を参照されたい。
新しいユーザーがcopyleftやEmacsの基本的な使い方に関する情報を入手するのを防げるので、新しいユーザーのinitファイル内や複数ユーザーに影響するような方法でこの変数をセットしてはならない。
inhibit-startup-message
とinhibit-splash-screen
はこの変数にたいするエイリアス。
非nil
ならこの変数はスタートアップ後にスタートアップスクリーンのかわりにEmacsが表示するファイルを指定する文字列であること。この変数が関数ならEmacsはその関数を呼び出して、その関数はその後に表示するバッファーをリターンしなければならない。値がt
ならEmacsは*scratch*バッファーを表示する。
この変数はエコーエリアのスタートアップメッセージの表示を制御する。ユーザーのinitファイル内に以下の形式のテキストを追加することによりエコーエリアのスタートアップメッセージを抑制できる:
(setq inhibit-startup-echo-area-message "your-login-name")
Emacsはユーザーのinitファイル内で上記のような式を明示的にチェックする。ユーザーのロフイン名はLispの文字列定数としてこの式内に記述されていなければならない。Customizeインターフェイスを使用することもできる。他の方法で同じ値にinhibit-startup-echo-area-message
をセットしてもスタートアップメッセージは抑制されない。この方法により望むならユーザー自身で簡単にメッセージを抑制できるが、単に自分用のiniファイルを別のユーザーにコピーしてもメッセージは抑制されないだろう。
この変数が非nil
ならEmacsスタートアップ時に*scratch*バッファーに挿入するドキュメントとして扱われる文字列であること。nil
なら*scratch*バッファーは空になる。
以下のコマンドラインオプションはスタートアップシーケンスにおけるいくつかの側面に影響を与えます。Initial Options in The GNU Emacs Manualを参照してください。
--no-splash
スプラッシュスクリーンを表示しない。
--batch
対話的な端末なしで実行する。batchモードを参照のこと。
--daemon
表示の初期化を何も行わず単にバックグラウンドでサーバーを開始する。
--no-init-file
-q
initファイルとdefaultライブラリーをいずれもロードしない。
--no-site-file
site-startライブラリーをロードしない。
--quick
-Q
‘-q --no-site-file --no-splash’と等価。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsの開始時は通常はユーザーのinitファイル(init file)のロードを試みます。これはユーザーのホームディレクトリー内にある.emacsか.emacs.elという名前のファイル、あるいはホームディレクトリーの.emacs.dという名前のサブディレクトリー内にあるinit.elという名前のファイルのいずれかのファイルです。
コマンドラインスイッチ‘-q’、‘-Q’、‘-u’はinitファイルを探すべきか、およびどこで探すべきかを制御します。‘-u
user’はそのユーザーではなくuserのinitファイルのロードを指示しますが、‘-q’
(‘-Q’のほうが強力)はinitファイルをロードしないことを指示します。Entering Emacs in The
GNU Emacs
Manualを参照してください。いずれのオプションも指定されていなければユーザーのホームディレクリーからinitファイルを探すために、Emacsは環境変数LOGNAME
、USER
(ほとんどのシステム)、またはUSERNAME
(MSシステム)を使用します。この方法によりたとえsuしていたとしても、依然としてEmacsはそのユーザー自身のinitファイルをロードできるのです。これらの環境変数が存在していなくてもEmacsはユーザーIDからユーザーのホームディレクトリーを探します。
インストールしたEmacsによってはdefault.elというLispライブラリーのデフォルトinitファイル(default
init file)が存在するかもしれません。Emacsはライブラリーの標準検索パスからこのファイルを探します(プログラムがロードを行う方法を参照)。このファイルはEmacsディストリビューション由来ではありません。このファイルはローカルなカスタマイズを意図しています。デフォルトinitファイルが存在する場合には常にこのファイルがEmacs開始時にロードされます。しかしユーザー自身のinitファイルが存在する場合にはそれが最初にロードされます。それによりinhibit-default-init
が非nil
値にセットされた場合には、Emacsは後続するdefault.elファイルのロードを行いません。batchモードまたは‘-q’
(または‘-Q’)を指定した場合には、Emacsは個人的なinitファイルトでデフォルトinitファイのいずれもロードしません。
サイトのカスタマイズのためのファイルはsite-start.elです。Emacsはユーザーのinitファイルの前にこれをロードします。オプション‘--no-site-file’により、このファイルのロードを抑制できます。
この変数はユーザーのinitファイルの前にロードするサイト用のカスタマイズファイルを指定する。通常の値は"site-start"
。実際に効果があるようにこれを変更するには、Emacsのdump前に変更するのが唯一の方法である。
一般的に必要とされる.emacsファイルのカスタマイズ方法についてはInit File Examples in The GNU Emacs Manualを参照のこと。
この変数が非nil
ならEmacsがデフォルトの初期化ライブラリーファイルをロードするのを防ぐ。デフォルト値はnil
。
このノーマルフックはすべてのinitファイル(site-start.el、ユーザーのinitファイル、およびdefault.el)のロード直前に一度実行される(実際に効果があるようにこれを変更するにはEmacsのdump前に変更するのが唯一の方法)。
このノーマルフックはすべてのinitファイル(site-start.el、ユーザーのinitファイル、およびdefault.el)のロード直後、端末固有ライブラリーのロードとコマンドラインアクション引数の処理の前に一度実行される。
このノーマルフックはコマンドライン引数の処理直後に一度実行される。batchモードではEmacsはこのフックを実行しない。
このノーマルフックはemacs-startup-hook
と非常に類似している。このフックは若干遅れてフレームパラメーターのセット後に実行されるのが唯一の違い。window-setup-hookを参照のこと。
この変数はユーザーのinitファイルの絶対ファイル名を保持する。実際にロードされたinitファイルが.emacs.elcのようにコンパイル済なら、値はそれに対応するソースファイルを参照する。
この変数は.emacs.dディレクトリーの名前を保持する。これはMS-DOS以外のプラットフォームでは~/.emacs.d。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
端末タイプはそれぞれ、その端末のタイプでEmacsが実行時にロードする独自のLispライブラリーをもつことができます。そのライブラリーの名前は変数term-file-prefix
の値と端末タイプ(環境変数TERM
により指定)を結合することにより構築されます。term-file-prefix
は通常は値"term/"
をもち変更は推奨しません。連想リストterm-file-aliases
内にTERM
にマッチするエントリーが存在する場合には、EmacsはTERM
のかわりにんその連想値を使用します。Emacsは通常の方法、つまりload-path
のディレクトリーから‘.elc’と‘.el’の拡張子のファイルを検索することにより、このファイルを探します。
端末固有ライブラリーの通常の役割は特殊キーによりEmacsが認識可能なシーケンスを送信可能にすることです。TermcapとTerminfoのエントリーがその端末のすべてのファンクションキーを指定していなければ、input-decode-map
へのセットや追加も必要になるかもしれません。端末の入力を参照してください。
端末タイプにハイフンとアンダースコアーが含まれて、その端末名に等しい名前のライブラリーが見つからないときには、Emacsはその端末名から最後のハイフンまたはアンダースコアー以降を取り除いて再試行します。このプロセスはEmacsがマッチするライブラリーを見つかるか、その名前にハイフンとアンダースコアーが含まれなくなる(つまりその端末固有ファイルが存在しない)まで繰り返されます。たとえば端末名が‘xterm-256color’でterm/xterm-256color.elというライブラリーが存在しなければEmacsはterm/xterm.elのロードを試みます。必要なら端末タイプの完全な名称を見つかるために端末ライブラリーは(getenv
"TERM")
を評価できます。
initファイルで変数term-file-prefix
をnil
にセットすることにより端末固有ライブラリーのロードを防ぐことができます。
tty-setup-hook
を使用することにより、端末固有ライブラリーのいくつかのアクションのアレンジやオーバーライドもできます。これは新たなテキスト端末の初期化後にEmacsが実行するノーマルフックです。自身のライブラリーをもたない端末にたいして初期化を定義するために、このフックを使用することのできるでしょう。フックを参照してください。
この変数の値が非nil
ならEmacsは以下のように端末固有初期化ファイルをロードする:
(load (concat term-file-prefix (getenv "TERM")))
端末初期化ファイルのロードを望まない場合には変数term-file-prefix
にnil
をセットできる。
MS-DOSではEmacsは環境変数TERM
に‘internal’をセットする。
この変数は端末タイプとそのエイリアスをマップする連想リスト。たとえば("vt102"
. "vt100")
という形式の要素はタイプ‘vt100’と同じようにタイプ‘vt102’の端末を扱うことを意味する。
この変数は新たなテキスト端末の初期化後にEmacsが実行するノーマルフック(これは非ウィンドウのモードでのEmacs開始時とemacsclient
のTTY接続作成時に適用される)。(適用可能なら)このフックはユーザーのinitファイルおよび端末固有Lispファイルのロード後に実行されるので、そのファイルにより行われた定義を調整するためにフックを使用できる。
関連する機能についてはwindow-setup-hookを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs開始時に種々のアクションをリクエストするためにコマンドライン引数を使用できます。Emacsを使う際にはログイン後に一度だけ起動して同一のEmacsセッション内ですべてを行うのが推奨される方法です(Entering Emacs in The GNU Emacs Manualを参照)。この理由によりコマンドライン引数を頻繁に使うことはないかもしれません。それでもセッションスクリプトからEmacsを呼び出すときやEmacsのデバッグ時にコマンドライン引数が有用になるかもしれません。このセクションではEmacsがコマンドライン引数を処理する方法を説明します。
この関数はEmacsが呼び出された際のコマンドライン引数を解析、処理、そして(とりわけ)ユーザーのinitファイルをロードしてスタートアップメッセージを表示する。
この変数の値は一度コマンドラインが処理されるとt
になる。
dump-emacs
(Emacsのビルドを参照)を呼び出すことによりEmacsを再dumpする場合には、新たにdumpされたEmacsに新たなコマンドライン引数を処理させるために最初にこの変数にnil
をセットしたいと思うかもしれない。
この変数はユーザー定義のコマンドライン引数とそれに関連付けられたハンドラー関数のalist。デフォルトでは空だが望むなら要素を追加できる。
コマンドラインオプション(command-line option)は以下の形式をもつコマンドライン上の引数である:
-option
command-switch-alist
の要素は以下のようになる:
(option . handler-function)
CARのoptionは文字列でコマンドラインオプションの名前(先頭のハイフンは含まない)。handler-functionはoptionを処理するために呼び出されて、単一の引数としてオプション名を受け取る。
このオプションはコマンドライン内で引数を併う場合がある。この場合には、handler-functionは残りのコマンドライン引数すべてを変数command-line-args-left
(以下参照)で見つけることができる(コマンドライン引数のリスト全体はcommand-line-args
)。
コマンドライン引数はstartup.elファイル内のcommand-line-1
により解析される。Command Line Arguments for Emacs Invocation in The GNU
Emacs Manualも参照のこと。
この変数の値はEmacsに渡されたコマンドライン引数のリスト。
この変数の値はまだ処理されていないコマンドライン引数のリスト。
この変数の値は認識されなかったコマンドライン引数を処理するための関数のリスト。次の引数が処理されてそれに特別な意味がないときは、その都度このリスト内の関数が非nil
をリターンするまでリスト内での出現順に呼び出される。
これらの関数は引数なしで呼び出される。関数はその時点で一時的にバインドされている変数argi
を通じて検討中のコマンドラインにアクセスできる。残りの引数(カレントの引数含まず)は変数command-line-args-left
内にあり。
関数がargi
内のその引数を認識して処理したときは引数を処理したと告げるために非nil
をリターンすること。後続の引数のいくつかを処理したときはcommand-line-args-left
からそれらを削除してそれを示すことができる。
これらの関数すべてがnil
をリターンした場合には引数はvisitすべきファイル名として扱われる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsから抜け出すには2つの方法があります: 1つ目は永遠にexitするEmacsジョブのkill、2つ目はサスペンドする方法でこれは後からEmacsプロセスに再エンターすることができます(もちろんグラフィカルな環境ではEmacsで特に何もせず単に他のアプリケーションにスイッチして後で望むときにEmacsに戻れる)。
38.2.1 Emacsのkill | Emacsからの不可逆的なexit。 | |
38.2.2 Emacsのサスペンド | Emacsからの可逆的なexit。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
EmacsのkillとはEmacsプロセスの終了を意味します。端末からEmacsを開始した場合には、通常は親プロセスの制御が再開されます。Emacsをkillする低レベルなプリミティブはkill-emacs
です。
このコマンドはフックkill-emacs-hook
を呼び出してからEmacsプロセスをexitしてkillする。
exit-dataが整数ならEmacsプロセスのexitステータスとして使用される(これは主にbatch処理で有用。batchモードを参照)。
exit-dataが文字列なら内容は端末の入力バッファーに詰め込まれるので、shell(や何であれ次の入力を読み込むプログラム)が読み込むことができる。
関数kill-emacs
は通常はより高レベルなコマンドC-x C-c
(save-buffers-kill-terminal
)を通じて呼び出される。Exiting in The GNU
Emacs
Manualを参照のこと。これはEmacsがオペレーティングシステムのシグナルSIGTERM
やSIGHUP
を受け取った場合(たとえば制御端末が切断されたとき)や、batchモードで実行中にSIGINT
を受け取った場合(batchモードを参照)にも自動的にこれが呼び出される。
このノーマルフックはEmacsのkillの前にkill-emacs
により実行される。
kill-emacs
はユーザーとの対話が不可能な状況(たとえば端末が切断されたとき)で呼び出されるかもしれないので、このフックの関数はユーザーとの対話を試みるべきではない。Emacsシャットダウン時にユーザーと対話したければ下記のkill-emacs-query-functions
を使用すること。
Emacsをkillしたときには保存されたファイルを除きEmacsプロセス内のすべての情報が失われます。うっかりEmacsをkillすることで大量の作業が失われるので、save-buffers-kill-terminal
コマンドは保存を要するバッファーがあったり実行中のサブプロセスがある場合には確認の問い合わせを行います。これはアブノーマルフックkill-emacs-query-functions
も実行します。
save-buffers-kill-terminal
がEmacsをkillする際には標準の質問を尋ねた後、kill-emacs
を呼び出す前にこのフック内の関数を呼び出す。関数は出現順に引数なしで呼び出される。関数はそれぞれ追加でユーザーから確認を求めることができる。それらのいずれかがnil
をリターンするとsave-buffers-kill-emacs
はEmacsをkillせずに、このフック内の残りの関数は実行されない。直接kill-emacs
を呼び出すとフックは実行されない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
テキスト端末ではEmacsのサスペンドができます。これはEmacsを一時的にストップして上位のプロセスに制御を返します。これは通常はshellです。これにより後で同じEmacsプロセス内の同じバッファー、同じkillリング、同じアンドゥヒストリー、...で編集を再開できます。Emacsを再開するには親shell内で適切なコマンド
— 恐らくはfg
— を使用します。
そのEmacsセッションが開始された端末デバイス上でのみサスペンドは機能します。そのデバイスのことをセッションの制御端末(controlling terminal)と呼びます。制御端末がグラフィカルな端末ならサスペンドは許されません。グラフィカルな端末ではEmacsで特別なことをせずに単に別のアプリケーションにスイッチできるのでサスペンドは通常は関係ありません。
いくつかのオペレーティングシステム(SIGTSTP
のないシステムやMS-DOS)ではジョブの停止はサポートされません。これらのシステムでの停止はEmacsのサブプロセスとして新たなshellを一時的に作成します。Emacsに戻るためにはshellをexitすればよいでしょう。
この関数はEmacsを停止して上位のプロセスに制御を返す。上位プロセスがEmacsを再開する際には、Lispでのsuspend-emacs
の呼び出し元にnil
をリターンする。
この関数はそのEmacsセッションの制御端末上でのみ機能する。他のTTYデバイスの制御を放棄するにはsuspend-tty
を使用する(下記参照)。そのEmacsセッションが複数の端末を使用する場合にはEmacsのサスペンド前に他のすべての端末からフレームを削除しなければならず、さもないとこの関数はエラーをシグナルする。複数の端末を参照のこと。
stringが非nil
なら、その各文字はEmacsの上位shellに端末入力として送信される。string内の文字は上位shellによりエコーされずに結果だけが表示される。
サスペンドする前にsuspend-emacs
はノーマルフックsuspend-hook
を実行する。ユーザーがEmacs再開後にsuspend-emacs
はノーマルフックsuspend-resume-hook
を実行する。フックを参照のこと。
再開後の次回再表示では変数no-redraw-on-reenter
がnil
ならスクリーン全体が再描画される。スクリーンのリフレッシュを参照のこと。
以下はこれらのフックの使用例:
(add-hook 'suspend-hook (lambda () (or (y-or-n-p "Really suspend? ") (error "Suspend canceled"))))
(add-hook 'suspend-resume-hook (lambda () (message "Resumed!") (sit-for 2)))
(suspend-emacs "pwd")
を評価すると以下を目にするだろう:
---------- Buffer: Minibuffer ---------- Really suspend? y ---------- Buffer: Minibuffer ----------
---------- Parent Shell ---------- bash$ /home/username bash$ fg
---------- Echo Area ---------- Resumed!
Emacsサスペンド後に‘pwd’がエコーされないことに注意。エコーはされないがshellにより読み取られて実行されている。
この変数はEmacsがサスペンド前に実行するノーマルフック。
この変数はサスペンド後の再開時にEmacsが実行するノーマルフック。
ttyにEmacsが使用する端末デバイスを指定すると、この関数はそのデバイスを放棄して以前の状態にリストアする。そのデバイスを使用していたフレームは存在を続けるが更新はされず、Emacsはそれらのフレームから入力を読み取らない。ttyには端末オブジェクト、フレーム(そのフレームの端末の意)、nil
(選択されたフレームの端末の意)を指定できる。複数の端末を参照のこと。
ttyがサスペンド済みなら何も行わない。
この関数は端末オブジェクトを各関数への引数としてフックsuspend-tty-functions
を実行する。
この関数は以前にサスペンドされたデバイスttyを再開する。ここでttyはsuspend-tty
に指定できる値と同じである。
この関数は端末デバイスの再オープンと再初期化を行い、その端末の選択されたフレームで端末を再描画する。それから端末ブジェクトを各関数への引数としてフックresume-tty-functions
を実行する。
同じデバイスが別のEmacs端末で使用済みなら、この関数はエラーをシグナルする。ttyがサスペンドされていなければ何もしない。
この関数はttyがそのEmacsセッションの制御端末なら非nil
をリターンする。ttyには端末オブジェクト、フレーム(そのフレームの端末の意)、nil
(選択されたフレームの端末の意)を指定できる。
このコマンドはフレームをサスペンドする。GUIフレームではiconify-frame
を呼び出す(フレームの可視性を参照)。テキスト端末上のフレームでは、そのフレームが制御端末デバイス上で表示されていればsuspend-emacs
、されていなければsuspend-tty
のいずれかを呼び出す。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはさまざまな変数を通じてオペレーティングシステム環境内の変数へのアクセスを提供します。これらの変数にはシステムの名前、ユーザーのUIDなどが含まれます。
この変数はユーザーのシステムのハードウェアとソフトウェアにたいするGNUの標準コンフィグレーション名(standard GNU configuration name)を保持する。たとえば64ビットGNU/Linuxシステムにたいする典型的な値は‘"x86_64-unknown-linux-gnu"’。
この変数の値はEmacs実行中のオペレーティングシステムのタイプを示すシンボル。可能な値は:
aix
IBMのAIX。
berkeley-unix
Berkeley BSDとその変種。
cygwin
MS-Windows上のPosixレイヤーであるCygwin。
darwin
Darwin (Mac OS X)。
gnu
(HURDとMachから構成される)GNUシステム。
gnu/linux
GNU/Linuxシステム — すなわちLinuxカーネルを使用するGNUシステムの変種(これらのシステムは人がしばしば“Linux”と呼ぶシステムだが実際にはLinuxは単なるカーネルであってシステム全体ではない)。
gnu/kfreebsd
FreeBSDカーネルによる(glibcベースの)GNUシステム。
hpux
ヒューレット・パッカードのHPUXオペレーティングシステム。
irix
シリコングラフィックスのIrixシステム。
nacl
Google Native Client(NaCl)サンドボックスシステム。
ms-dos
MicrosoftのDOS。MS-DOSにたいするDJGPPでコンパイルされたEmacsは、たとえMS-Windows上で実行されていてもsystem-type
がms-dos
にバインドされる。
usg-unix-v
AT&TのUnix System V。
windows-nt
MicrosoftのWindows NT、9X以降。たとえばWindows
10でもsystem-type
の値は常にwindows-nt
。
わたしたちは絶対に必要になるまでは、より細分化するために新たなシンボルを追加したくありません。実際のところ将来的にはこれらの候補のいくつかを取り除きたいと思っています。system-type
で許されているより細分化する必要がある場合には、たとえば正規表現にたいしてsystem-configuration
をテストできます。
この関数は実行中のマシン名を文字列としてリターンする。
この変数が非nil
なら、この変数がemailアドレスを生成するためにsystem-name
のかわりに使用される。たとえばこれはuser-mail-address
のデフォルト値の構築時に使用される。ユーザーの識別を参照のこと(これはEmacsスタートアップ時に行われるので実際に使用されるのはEmacsのdump時に保存されたもの。Emacsのビルドを参照)。
この関数は環境変数varの値を文字列としてリターンする。varは文字列であること。その環境内でvarが未定義ならgetenv
はnil
をリターンする。varがセットされているがnull(訳注:
空文字列)なら‘""’をリターンする。Emacs内では環境変数とそれらの値のリストは変数process-environment
内に保持されている。
(getenv "USER") ⇒ "lewis"
shellコマンドprintenv
は環境変数のすべて、または一部をプリントする:
bash$ printenv PATH=/usr/local/bin:/usr/bin:/bin USER=lewis
TERM=xterm SHELL=/bin/bash HOME=/home/lewis
…
このコマンドはvariableという名前の環境変数の値にvalueをセットする。variableは文字列であること。内部的にはEmacs
Lispは任意の文字列を扱える。しかしvariableは通常はshell識別子として有効、すなわちアルファベットかアンダースコアで始まり、アルファベットか数字またはアンダースコアのシーケンスであること。それ以外ならEmacsのサブプロセスがvariableの値にアクセスを試みるとエラーが発生するかもしれない。valueが省略かnil
の場合(またはプレフィクス引数とともにインタラクティブに呼び出された場合)には、setenv
はその環境からvariableを削除する。それ以外ならvariableは文字列であること。
オプション引数substituteが非nil
なら、value内のすべての環境変数を展開するためにEmacsは関数substitute-env-vars
を呼び出す。
setenv
はprocess-environment
を変更することにより機能する。この変数をlet
でバインドするのも合理的プラクティスである。
setenv
はvariableの新たな値、または環境からvariableが削除されていればnil
をリターンする。
この変数はそれぞれが1つの環境変数を記す文字列リスト。関数getenv
とsetenv
はこの変数により機能する。
process-environment ⇒ ("PATH=/usr/local/bin:/usr/bin:/bin" "USER=lewis"
"TERM=xterm" "SHELL=/bin/bash" "HOME=/home/lewis" …)
process-environment
に同じ環境変数を指定す複数の要素が含まれる場合には、それらの最初の要素が変数を指定して他は無視される。
この変数はEmacs開始時にその親プロセスからEmacsが継承した環境変数のリストを保持する。
この変数は、(環境変数で見つけた)検索パス内でディレクトリーを区切る文字を示す文字列を保持する。値はUnixとGNUシステムでは":"
、MSシステムでは";"
。
この関数は環境変数PATH
の値のような検索パス文字列を引数に受け取り、それをセパレーターで分割してディレクトリー名のリストをリターンする。このリスト内では、nil
はカレントディレクトリーを意味する。この関数の名前からはセパレーターは“コロン”となるが、実際に使用するのはpath-separator
の値。
(parse-colon-path ":/foo:/bar") ⇒ (nil "/foo/" "/bar/")
この変数はEmacsが呼び出された時のプログラム名を保持する。値は文字列でありディレクトリー名は含まれない。
この変数はEmacs実行可能形式が呼び出されたディレクトリー名、そのディレクトリーが判断できなければnil
をリターンする。
非nil
ならサブディレクトリーlib-srcとetcを探すディレクトリーである。インストールされたEmacsなら通常はnil
。Emacsが標準のインストール位置にそれらのディレクトリーを見つけられないものの、Emacs実行可能形式を含むディレクトリー(たとえばinvocation-directory
)に何らかの関連があるディレクトリーで見つかることができたら非nil
。
この関数はカレント、1分、5分、15分のロードアベレージ(load averages: 平均負荷)をリストでリターンする。このロードアベレージはシステム上で実行を試みているプロセス数を示す。
デフォルトでは値はシステムロードアベレージを100倍にした整数だが、use-floatが非nil
なら100を乗ずることなくこれらの値は浮動小数点数としてリターンされる。
ロードアベレージ入手が不可能ならこの関数はエラーをシグナルする。いくつかのプラットフォームではロードアベレージへのアクセスにカーネル情報を読み取れるように、通常は推奨されないsetuidかsetgidしたEmacsのインストールを要する。
1分のロードアベレージは利用できるが、5分と15分のアレージは利用できなければ、この関数は利用可能なアベレージを含んだ短縮されたリストをリターンする。
(load-average) ⇒ (169 48 36)
(load-average t) ⇒ (1.69 0.48 0.36)
shellコマンドのuptime
はこれと類似する情報をリターンする。
この関数はEmacsプロセスのプロセスIDを整数としてリターンする。
この変数はEmacs開始前にそのシステムの端末ドライバーで選択されていたerase文字を保持する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この変数はEmacsによりどのユーザーのinitが使用されるべきか —
なければnil
をリターンする。""
はログイン時のオリジナルのユーザーをリターンする。この値は‘-q’や‘-u
user’のようなコマンドラインオプションを反映する。
カスタマイズ関連のファイルや、他の類の短いユーザープロファイルをロードするLispパッケージは、それをどこで探すか判断するためにこの変数にしたがうこと。これらのLispパッケージはこの変数内で見つかったユーザー名のプロファイルをロードすること。init-file-user
がnil
なら‘-q’、‘-Q’、または‘-batch’オプションが使用されたことを意味しており、その場合にはLispパッケージはカスタマイズファイルやユーザープロファイルを何もロードするべきではない。
これはEmacs実行中ユーザーの公称emailアドレス(nominal email address)を保持する。Emacsは通常はinit読み込み後に、ユーザーがこれをまだセットしていなれば変数にデフォルト値をセットする。デフォルト値を使用したくなければinitファイル内でこの変数に他の何らかの値をセットすればよい。
この関数はユーザーのログイン名をリターンする。これはいずれかがセットされていれば環境変数LOGNAME
かUSER
を使用する。それ以外なら値は実UIDではなく実効UIDにもとづく。
uid (数字)を指定するとuidに対応するユーザー名、そのようなユーザーが存在しなければnil
が結果となる。
この関数はEmacsの実UIDに対応するユーザー名をリターンする。これは実効UID、および環境変数LOGNAME
とUSER
を無視する。
この関数はログインユーザーの完全名、環境変数NAME
がセットされていればその値をリターンする。
EmacsプロセスのユーザーIDが既知のユーザーに不一致(かつ与えられたNAME
が未セット)なら結果は"unknown"
。
uidが非nil
なら数字(ユーザーID)か文字列(ログイン名)であること。その場合にはuser-full-name
はそのユーザー名かログイン名に対応する完全名をリターンする。未定義のユーザー名かログイン名を指定するとnil
をリターンする。
シンボルuser-login-name
、user-real-login-name
、user-full-name
は変数であると同時に関数でもあります。関数の場合には、その名前の変数と同じ値をリターンします。これらの変数を使えば対応する関数が何をリターンするべきかを告げることによりEmacsを騙すことができます。またフレームタイトルの構築においても、これらの関数は有用です(フレームのタイトルを参照)。
この関数はユーザーの実UIDをリターンする。この値は、(非現実的だが)そのUIDがLisp整数の範囲を超える程大きいような場合には浮動小数点数になるかもしれない。
この関数はユーザーの実効UIDをリターンする。値は浮動小数点数かもしれない。
この関数はユーザーの実効GIDをリターンする。値は浮動小数点数かもしれない。
この関数はユーザーの実GIDをリターンする。値は浮動小数点数かもしれない。
この関数はシステム上のユーザー名をリストする文字列リストをリターンする。この情報をEmacsが取得できなければuser-real-login-name
の値だけを含んだリストをリターンする。
この関数はシステム上のグループ名をリストする文字列リストをリターンする。この情報をEmacsが取得できなければリターン値はnil
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではカレント時刻とタイムゾーンを決定する方法を説明します。
これらの関数のほとんどは時刻を4つの整数のリスト(sec-high sec-low microsec
picosec)
で表現します。これは式
high * 2**16 + low + micro * 10**-6 + pico *
10**-12を使用してepoch (January 1, 1970 at 00:00 UTC)からの経過秒数を表します。
current-time
のリターン値は、他のfile-attributes
のような関数(Definition of file-attributesを参照)のリターン値でのタイムスタンプのように、この形式を使用して表現されます。あるケースにおいては、関数はmicrosecやpicosecのコンポーネントを省略した2要素や3要素(省略時のデフォルトは0)のリストをリターンすることがあります。
current-time-string
にたいするtime引数等の関数引数は、上述のような整数のリスト、epochからの単一の経過秒数、カレント時刻を意味するnil
などの、より一般的なtime値(time
value)を受け付けます。current-time-string
やformat-time-string
を使用して可読性のある文字列、decode-time
やfloat-time
を使用して他の形式にtime値を変換できます。これらの関数は以降のセクションで説明します。
この関数はカレントの時刻と日付を可読形式の文字列でリターンする。この文字列の先頭部分には曜日、月、日付、時刻がこの順に含まれて、それらが可変長となることはない。これらのフィールドにたいして使用される文字数は常に同じなので、それらを切り出すために安心してsubstring
を使用できる。年の部分は正確に4桁とは限らず、いつか追加情報が終端に付加されるかもしれないので文字列終端からではなく先頭から文字を数えること。
引数timeが与えられたら、それはカレント時刻のかわりにフォーマットする時刻を指定する。オプション引数zoneのデフォルトはカレントのタイムゾーンルール。Time Zone Rulesを参照のこと。
(current-time-string) ⇒ "Wed Oct 14 22:21:05 1987"
この関数は4つの整数のリスト(sec-high sec-low microsec
picosec)
で表されたカレント時刻をリターンする。これらの整数うち後部は、低精度の時刻をリターンするシステムでは0。現在のすべてのマシンではpicosecは1000の倍数だが、より高精度のクロックが利用可能になったら変更されるかもしれない。
この関数はエポックからの経過秒数を浮動小数点数としてリターンする。オプション引数time-valueが与えられた場合には、カレント時刻ではなく変換する時刻を指定する。
警告: 結果は浮動小数点数なので正確ではないかもしれない。正確なタイムスタンプが必要なら使用しないこと。
time-to-seconds
はこの関数のエイリアス。
この関数はtime値を整数リスト形式に変換する。たとえばtimeが数値の場合にはオーバーフローや丸めエラーが発生しなければ、これは(time-to-seconds
(seconds-to-time time))
と等価。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
デフォルトのタイムゾーンは環境変数TZ
により判断されます。オペレーティングシステムの環境を参照してください。たとえば(setenv \"TZ\"
\"UTC0\")
とすれば万国標準時の使用をEmacsに指示できます。その環境にTZ
がなければ、Emacsはプラットフォーム依存のデフォルト時刻であるシステムの実時間(system
wall clock time)を使用します。
サポートされるTZ
のセットはシステム依存です。GNUと他の多くのシステムはtzdataデータベースをサポートします。これはたとえば‘"America/New_York"’はニューヨーク市周辺のタイムゾーンを夏時間ヒストリーを指定します。GNUと他の多くのシステムはPOSIXスタイルのTZ
セッティングをサポートします。これはたとえば‘"EST+5EDT,M4.1.0/2,M10.5.0/2"’は1987から2006にニューヨークで使用されたルールを指定します。すべてのシステムは万国標準時(Universal
Time)を意味する‘"UTC0"’文字列をサポートします。
地方時刻(local time)との間で変換を行う関数はタイムゾーンと夏時間ヒストリーを指定するタイムゾーンルール(time zone
rule)を受け付けます。このタイムゾーンルールが省略かnil
なら、変換にはEmacsのデフォルトのタイムゾーンが使用されます。t
なら変換には万国標準時を使用します。wall
ならシステムの実時間を変換に使用します。文字列なら変換にはその文字列と等しいTZ
のタイムゾーンルールのセッティングが使用されます。
この関数はユーザーが居るタイムゾーンを記すリストをリターンする。
値は(offset
abbr)
という形式をもつ。ここでoffsetは万国標準時刻より進んでいる秒数(グリニッジより東)を与える整数。負の値はグリニッジより西を意味する。2つ目の要素abbrはそのタイムゾーンのを与える省略名の文字列。たとえば‘"CST"’は中国標準時か米国中部標準時のタイムゾーン。夏時間の開始と終了時に、いずれの要素も変化し得る。ユーザーが季節時間調整を用いていないタイムゾーンを指定した場合には、値は時期を通して定数となる。
この値を計算するのに必要なすべての情報をオペレーティングシステムが提供しなければ、このリストの未知の要素はnil
になる。
引数timeが与えられたら、それはカレント時刻のかわりに分析するべきtime値を指定する。オプション引数zoneのデフォルトはカレントのタイムゾーンルール。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はtime値(時刻を参照)を暦情報に変換したり逆の変換を行います。
32ビットオペレーティングシステムの多くは、秒数コンポーネントに32ビット情報を含んだシステム時刻に制限されます。これらのシステムは通常は万国標準時の1901-12-13 20:45:52から2038-01-19 03:14:07までの時刻だけを処理します。しかし64ビット、およびいくつかの32ビットオペレーティングシステムは、より大きな秒数コンポーネント値をもち、より遠い過去や未来の時刻を表現できます。
時刻変換関数は、たとえグレゴリオ暦導入前の日付にたいしても常にグレゴリオ暦を使用します。年はB.C. 1年から年数を数えて伝統的なグレゴリオ年が行うように0年をスキップしません。たとえば年数-37はグレゴリオ年のB.C. 38年を表します。
この関数はtime値を暦情報に変換する。timeを指定しなければカレント時刻をデコードする。同様にzoneのデフォルトはカレントのタイムゾーンルール。Time Zone Rulesを参照のこと。リターン値は以下のような9要素のリスト:
(seconds minutes hour day month year dow dst utcoff)
以下は各要素の意味:
0から59までの整数で表した分を過ぎた時分秒の秒。いくつかのオペレーティングシステムでは閏秒にたいして60となる。
0から59までの整数で表した時を過ぎた時分秒の分。
0から23までの整数で表した時分秒の時。
1から31までの整数で表した年月日の日。
1から12までの整数で表した年月日の月。
通常は1900より大きい整数で表した年月日の年。
0から6までの整数で表した曜日であり0は日曜日を意味する。
夏時間が有効ならt
、それ以外はnil
。
万国標準時からの秒数、すなわち東グリニッジの秒数を示す整数。
Common Lispに関する注意: Common Lispではdowとutcoffの意味が異なる。
この関数はdecode-time
の逆バージョン。これは7アイテムの暦データを整数リストのtime値に変換する。引数の意味は上述decode-time
のテーブルを参照のこと。
100未満の年が特別に扱われることはない。これに1900や2000を超える年を意味させたい場合には、encode-time
を呼び出す前に自身でこれらを修正しなければならない。
オプション引数zoneのデフォルトは、カレントのタイムゾーンルール。Time Zone Rulesを参照のこと。通常のタイムゾーンルール値に加えて(decode-time
で得られるような)リスト、(decode-time
で得られるような)整数も夏時間による更なる変更を受けずに適用される。
encode-time
にたいして7個より多い引数を渡すと最初の6つはsecondsからyear、最後の引数がzoneとして使用されてその間の引数は無視される。これにより以下のようにdecode-time
がリターンしたリストの要素をencode-time
の引数として使用することが可能になる:
(apply 'encode-time (decode-time …))
seconds、minutes、hour、day、monthの引数に範囲外の値を使用することにより単純な日付計算ができる。たとえばdayが0なら与えられたmonthの前月末日になる。
オペレーティングシステムは可能なtime値の範囲に制限を設ける。範囲外の時刻のエンコードを試みると結果はエラーとなる。たとえばあるシステムでは1970年以前では機能せず、別のシステムではより以前の1901年以降から機能する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はtime値と文字列内のテキストの間で変換と逆変換を行います。time値は2つから4つの整数からなるリストです(時刻を参照)。
この関数はtime文字列stringをパースして対応するtime値をリターンする。
この関数はtime(省略時はカレント時刻)をformat-stringに応じて文字列に変換する。変換にはタイムゾーンルールzone(デフォルトはカレントのタイムゾーンルール)を使用する。Time Zone Rulesを参照のこと。引数format-stringには時刻を置換する‘%’シーケンスを含めることができる。以下のテーブルは‘%’シーケンスの意味:
曜日の短縮名を意味する。
曜日の完全名を意味する。
月の短縮名を意味する。
月の完全名を意味する。
‘%x %X’のシノニム。
これはlocale固有の意味をもつ。デフォルトlocale(Cという名前のlocale)では‘%A, %B %e, %Y’と等価。
0パディングされた年月日の日。
‘%m/%d/%y’のシノニム。
ブランクでパディングされた年月日の日。
‘%b’のシノニム。
時分秒の時(00から23)を意味する。
時分秒の時(01から12)を意味する。
年内の経過日(001から366)を意味する。
ブランクでパディングされた時分秒の時(0から23)を意味する。
ブランクでパディングされた時分秒の時(1から12)を意味する。
年月日の月(01から12)を意味する。
時分秒の分(00から59)を意味する。
改行を意味する。
ナノ秒(000000000–999999999)を意味する。より少ない桁数を求める場合にはミリ秒は‘%3N’、マイクロ秒は‘%6N’を使用する。余分な桁は丸めずに切り捨てられる。
必要に応じて‘AM’か‘PM’を意味する。
‘%I:%M:%S %p’のシノニム。
‘%H:%M’のシノニム。
時分秒の秒(00から59)を意味する。
タブ文字を意味する。
‘%H:%M:%S’のシノニム。
週の開始を日曜日とみなした年内の週(01から52)。
数字で表した曜日(0から6)で日曜日が0。
これは週の開始を月曜日とみなした年内の週(01から52)。
これはlocale固有の意味をもつ。デフォルトlocale(Cという名前のlocale)では‘%D’と等価。
これはlocale固有の意味をもつ。デフォルトlocale(Cという名前のlocale)では‘%T’と等価。
世紀を含まない年(00から99)を意味する。
世紀を併なう年を意味する。
タイムゾーンの短縮形(たとえば‘EST’)を意味する。
数値的オフセットによるタイムゾーン(たとえば‘-0500’)を意味する。
これら‘%’シーケンスのすべてにおいてフィールド幅とパディングのタイプを指定できる。これはprintf
での指定のように機能する。フィールド幅は桁数として‘%’シーケンスの中間に記述する。このフィールド幅を‘0’で開始すると0によるパディングを意味する。フィールド幅を‘_’で開始すればスペースによるパディングを意味する。
たとえば‘%S’は分内で経過した秒数を指定するが‘%03S’は3箇所の0、‘%_3S’は3箇所にスペースをパディングすることを意味する。ただの‘%3S’は0でパディングを行う。これは‘%S’が通常において2箇所にパディングする方法のため。
文字‘E’と‘O’は、‘%’と上記テーブルのアルファベットのいずれかの間に使用されたときには修飾子として作用する。‘E’は日付と時刻にカレントlocaleの代替バージョンの使用を指定する。たとえば日本のlocaleでは、%Ex
により日本の元号にもとづいた日付フォーマットを得られるだろう。‘E’は‘%Ec’、‘%EC’、‘%Ex’、‘%EX’、‘%Ey’、‘%EY’での使用が許されている。
‘O’は通常の10進数字(訳注: アラビア数字)ではなく、カレントlocaleの数字の代替表現を使用する。これは数字を出力する、ほとんどすべてのアルファベットで使用が許されている。
この関数は処理のほとんどを行うためにCライブラリー関数strftime
を使用している(Formatting Calendar
Time in The GNU C Library Reference
Manualを参照)。その関数とやり取りするためにlocale-coding-system
(localeを参照)で指定されたコーディングシステムを使用して最初に引数のエンコーディングを行う。strftime
が結果文字列をリターンした後に同じコーディングシステムを使用してformat-time-string
はデコードを行う。
この関数は引数secondsをformat-stringに応じた年、日、時、...の文字列に変換する。引数format-stringには変換を制御する‘%’シーケンスを指定することができる。以下のテーブルは‘%’の意味:
年間365日での年の整数。
年月日の日。
時分秒の時の整数。
時分秒の分の整数。
時分秒の秒の整数。
非プリント制御フラグ。これを使用する際には他の指定はサイズ減少順、すなわち年、日、時刻、分、...のように与えなければならない。最初の非0変換に遭遇するまで‘%z’の左側の結果文字列は生成されない。たとえばemacs-uptime
(emacs-uptimeを参照)で使用されるデフォルトフォーマットでは、秒数は常に生成されるが年、日、時、分はそれらが非0の場合のみ生成されるだろう。
リテラルの‘%’を生成する。
大文字のフォーマットシーケンスは数字に加えて単位を生成するが、小文字フォーマットは数字だけを生成する。
‘%’に続けてフィールド幅を指定できる。指定したフ幅より短ければブランクでパディングされる。この幅の前にオプションでピリオドを指定すれば、かわりに0パディングを要求する。たとえば"%.3Y"
は"004
years"
を生成するだろう。
警告:
この関数はmost-positive-fixnum
を超えないsecondsの値でのみ機能する(most-positive-fixnumを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
EmacsはEmacsプロセスにより使用された経過時間(elapsed time)とプロセッサー時間(processor time)の両方にたいして、それらをリターンする関数とプリミティブをいくつか提供します。
この関数はEmacsのuptime —
このEmacsインスタンスが実行してから経過した実世界における稼動時間を表す文字列をリターンする。この文字列はオプション引数formatに応じてformat-seconds
によりフォーマットされる。利用できるフォーマット記述子についてはformat-secondsを参照のこと。formatがnil
か省略された場合のデフォルトは"%Y, %D,
%H, %M, %z%S"
。
インタラクティブに呼び出されるとエコーエリアにuptimeをプリントする。
この関数はEmacsにより使用されたプロセッサーの実行時間を、current-time
の場合と同じフォーマット(時刻を参照)の4つの整数のリスト(sec-high sec-low microsec
picosec)
でリターンする。
この関数がリターンする値にはEmacsがプロセッサーを使用していない時間は含まれないこと、そしてEmacsプロセスが複数のスレッドをもつ場合には、すべてのEmacsスレッドにより使用されたプロセッサー時間の合計値がリターンされることに注意。
システムがプロセッサー実行時間を判断する方法を提供しなければget-internal-run-time
はcurrent-time
と同じ値をリターンする。
この関数はEmacsの初期化(要約: スタートアップ時のアクション順序を参照)にかかった秒数を文字列としてリターンする。インタラクティブに呼び出された場合にはエコーエリアにプリントする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はtime値(時刻を参照)を使用して暦計算を行います。
これはtime値t1がtime値t2より小ならt
をリターンする。
これは2つのtime値の間の差t1 - t2をtime値でリターンする。
これは2つのtime値の和をリターンする。引数のうち1つはある時点での時刻ではなく時間差を表すこと。以下はtime値に秒数を加算する方法:
(time-add time seconds)
この関数はA.C. 1年元日からtime-valueまでの間の日数をリターンする。
これはtime-valueに対応する年内の日数をリターンする。
この関数はyearが閏年ならt
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
将来の特定時刻や特定の長さのアイドル時間経過後に関数を呼び出すためにタイマー(timer)をセットアップできます。
EmacsはLispプログラム内では、任意の時点ではタイマーを実行できません。サブプロセスからの出力が受け入れ可能なときだけEmacsはタイマーを実行できます。つまり待機中や待機することが可能なsit-for
やread-event
のような特定のプリミティブ関数内部でのみタイマーを実行できます。したがってEmacsがbusyならタイマーの実行は遅延するかもしれません。しかしEmacsがidleなら実行される時刻は非常に正確になります。
quitにより多くのタイマー関数が物事を不整合な状態に放置し得るので、ターマー関数呼び出し前にEmacsはinhibit-quit
にt
をバインドします。ほとんどのタイマー関数は多くの作業を行わないので、これは通常は問題にはなりません。しかし実際には実行に長時間を要する関数を呼び出すタイマーが問題となる恐れがあります。タイマー関数がquitを許容する必要があるならwith-local-quit
を使用するべきです(quitを参照)。たとえば外部プロセスから出力を受け取るためにタイマー関数がaccept-process-output
を呼び出す場合には、外部プロセスのハング時のC-gを確実に機能させるために、その呼び出しをwith-local-quit
内部にラップすべきです。
バッファー内容の変更のためにタイマー関数を呼び出すのは通常は悪いアイデアです。これを行うときには単一のアンドゥエントリーが巨大になるのを防ぐために、通常はバッファーの変更前後でundo-boundary
を呼び出して、タイマーによる変更とユーザーのコマンドによる変更を分離するべきです。
タイマー関数はsit-for
のようなEmacsに待機を発生させるような関数(時間の経過や入力の待機を参照)の呼び出しも避けるべきです。その待機中に別のタイマー(同じタイマーとう可能性さえある)が実行され得るので、これは予測不可能な効果を導く恐れがあります。特定時間の経過後に処理される必要があるタイマー関数は、新たなタイマーをスケジュールしてこれを行うことができます。
マッチデータを変更するかもしれない関数を呼び出すタイマー関数はマッチデータの保存とリストアをするべきです。マッチデータの保存とリストアを参照してください。
これは時刻timeに引数argsで関数functionを呼び出すタイマーをセットアップする。repeatが数値(整数か浮動小数点数)ならタイマーはtime後の各repeat秒ごとに再実行されるようスケジュールされる。repeatがnil
ならタイマーは1回だけ実行される。
timeには絶対時刻と相対時刻を指定できる。
絶対時刻は限定された種々フォーマットの文字列を使用して指定でき、すでに経過後の時刻であっても当日の時刻とみなされる。認識される形式は‘xxxx’、‘x:xx’、または‘xx:xx’ (軍用時間)、および‘xxam’、‘xxAM’、‘xxpm’、‘xxPM’、‘xx:xxam’、‘xx:xxAM’、‘xx:xxpm’、‘xx:xxPM’のいずれか。時と分の部分の区切りはコロンのかわりにピリオドも使用できる。
相対時刻は単位を付加した数字を文字列として指定する。たとえば:
現在時刻から1分後を表す。
現在時刻から65秒後を表す。
現在時刻から丁度103ヵ月123日10862秒後を表す。
相対time値にたいしてEmacsは月を正確に30日、年を正確に365.25とみなす。
有用なフォーマットのすべてが文字列という訳ではない。timeが数字(整数か浮動小数点数)なら秒で数えた相対時刻を指定する。encode-time
の結果はtimeにたいする絶対時刻の指定にも使用できる。
ほとんどの場合には、repeatを最初に呼び出されている際には効果はなくtime単独で時刻を指定する。例外が1つありtimeがt
ならエポックからrepeatの倍数秒ごとに毎回そのタイマーが実行される。これはdisplay-time
のような関数にとって有用。
関数run-at-time
はスケジュール済みの将来の特定アクションを識別するtime値をリターンする。cancel-timer
(以下参照)の呼び出しにこの値を使用できる。
タイマーのリピートは名目上はrepeat秒ごとに毎回実行されますが、すべてのタイマー呼び出しは遅延する可能性があることを忘れないでください。1つの繰り返しの遅延が次の繰り返しに影響を与えることはありません。たとえば3回分のスケジュール済みのタイマー繰り返しをカバーするほどの計算等によりEmacsがbusyでも、それらは待機を開始して連続してそのタイマー関数が3回呼び出されることになります(それらの間の別のタイマー呼び出しは想定していない)。最後の呼び出しからn秒より短くならずにタイマーを再実行したい場合にはrepeat引数を使用しないでください。タイマー関数は、かわりにそのタイマーを明示的に再スケジュールするべきです。
この変数の値は以前スケジュールされていた呼び出しが止むを得ずに遅延された際に、タイマー関数がリピートによりまとめて呼び出される最大の回数を指定する
bodyを実行するがseconds秒後に実行を諦める。タイムアップ前にbodyが終了したら、with-timeout
はbody内の最後のフォームの値をリターンする。ただしタイムアウトによりbodyの実行が打ち切られた場合には、with-timeout
はtimeout-formsをすべて実行して最後のフォームの値をリターンする。
このマクロはseconds秒後に実行するタイマーをセットすることにより機能する。その時刻の前にbodyが終了したらそのタイマーを削除して、タイマーが実際に実行されたらbodyの実行を終了してからtimeout-formsを実行する。
Lispプログラムでは待機を行えるプリミティブをプログラムが呼び出している時のみタイマーを実行できるので、bodyが計算途中の間はwith-timeout
は実行を停止できない
—
そのプログラムがこれらのプリミティブのいずれかを呼び出したときのみ停止できる。そのためbodyで長時間の計算を行う場合ではなく、入力を待機する場合だけwith-timeout
を使用すること。
あまりに長時間応答を待機するのを避けるために、関数y-or-n-p-with-timeout
はタイマーを使用するシンプルな方法を提供します。Yes-or-Noによる問い合わせを参照してください。
これはtimerにたいして要求されたアクションをキャンセルする。ここでtimerはタイマーであること。これは通常は以前にrun-at-time
かrun-with-idle-timer
がリターンしたものである。この関数はこれらの関数の1つの呼び出しの効果をキャンセルする。指定した時刻が到来しても特に何も起きないだろう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はEmacsの特定の期間アイドル時に実行するタイマーをセットアップする方法です。それらをセットアップする方法とは別にすればアイドルタイマーは通常のタイマーと同様に機能します。
Emacsの次回secs秒間アイドル時に実行するタイマーをセットアップする。secsの値には数値、またはcurrent-idle-time
がリターンするタイプの値を指定できる。
repeatがnil
なら、Emacsが充分長い間アイドルになった初回の1回だけタイマーは実行される。これは大抵はrepeatが非nil
の場合であり、そのときはEmacsがsecs秒間アイドルになったときに毎回そのタイマーが実行される。
関数run-with-idle-timer
はcancel-timer
呼び出し時に使用できるタイマー値をリターンする。
ユーザー入力の待機時にEmacsはアイドル(idle)となり、ユーザーが何らかの入力を与えるまでアイドルのままとなります。あるタイマーを5秒間のアイドルにセットすると、Emacsが最初に約5秒間アイドルになったときにタイマーが実行されます。たとえrepeatが非nil
でもEmacsがアイドルであり続けるかぎりタイマーが再実行されることはありません。アイドル期間は増加を続けて再び5秒に減少することはないからです。
アイドル時にEmacsはガーベージコレクションや自動保存やサブプロセスからのデータ処理など、さまざまなことを行うことができます。しかしこれらの幕間劇がアイドルのクロックを0にリセットすることはないのでアイドルタイマーと干渉することはありません。600秒にセットされたアイドルタイマーはたとえその10分間にサブプロセスの出力が何回到達しても、たとえガーベージコレクションや自動保存が行われてもユーザーコマンドが最後に終了してから10分経過後に実行されるでしょう。
ユーザーが入力を与えるとEmacsは入力の実行の間は非アイドルになります。それから再びアイドルとなると、繰り返すようにセットアップされたすべてのアイドルタイマーは1つずつ異なる時刻に実行されるでしょう。
実行ごとに特定の量を処理するループを含んだり、(input-pending-p)
が非nil
のときにexitするアイドルタイマー関数を記述しないでください。このアプローチはとても自然に見えますが2つの問題があります:
同様にsecs引数がカレントのアイドル期間以下となるような、別のアイドルタイマー(同じアイドルタイマーも含む)をセットアップするアイドルタイマー関数を記述しないでください。そのようなタイマーはほとんど即座に実行されて、Emacsが次回アイドルになるのを待機するかわりに再現なく継続して実行されるでしょう。以下で説明するようにカレントのアイドル期間を適切に増加させて再スケジュールするのが正しいアプローチです。
この関数はEmacsがアイドルならEmacsがアイドルとなった期間をcurrent-time
で使用するのと同じ4つの整数リストのフォーマット(sec-high
sec-low microsec picosec)
でリターンする(時刻を参照)。
Emacsがアイドルでなければcurrent-idle-time
はnil
をリターンする。これはEmacsがアイドルかどうかテストする手軽な方法である。
current-idle-time
の主な用途はアイドルタイマー関数を少し“休憩”したいときです。そのアイドルタイマー関数はさらに数秒アイドル後に、同じ関数を再呼び出しするために別のタイマーをセットアップできます。以下はその例です:
(defvar my-resume-timer nil "Timer for `my-timer-function' to reschedule itself, or nil.") (defun my-timer-function () ;;my-resume-timer
アクティブの間にユーザーがコマンドをタイプ ;; したら、次回この関数はそれのメインアイドルタイマーから呼び出され ;;my-resume-timer
を非アクティブにする (when my-resume-timer (cancel-timer my-resume-timer)) ...do the work for a while... (when taking-a-break (setq my-resume-timer (run-with-idle-timer ;; カレント値より大きいアイドル ;; 期間break-lengthを計算 (time-add (current-idle-time) break-length) nil 'my-timer-function))))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは端末入力の記録や操作のための関数と変数を説明します。関連する関数についてはEmacsのディスプレー表示を参照してください。
38.13.1 入力のモード | 入力の処理方法にたいするオプション。 | |
38.13.2 入力の記録 | 直近またはすべての入力イベントのヒストリーの保存。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はキーボード入力の読み取りにたいしてモードをセットする。Emacsはinterruptが非nil
なら入力割り込み、nil
ならCBREAKモードを使用する。デフォルトのセッティングはシステムに依存する。いくつかのシステムでは指定に関わらずに常にCBREAKモードを使用する。
EmacsがXと直接通信する際にはこの引数を無視して、それがEmacsの知る通信手段であれば割り込みを使用する。
flowが非nil
なら、Emacsは端末への出力にたいしてXON/XOFFフロー制御(C-qとC-s)を使用する。これはCBREAK以外では効果がない。
引数metaは127より上の文字コード入力にたいするサポートを制御する。metaがt
ならEmacsは8番目のビットがセットされた文字をメタ文字に変換する。metaがnil
ならEmacsは8番目のビットを無視する。これは端末がそのビットをパリティビットとして使用する場合に必要となる。metaがt
とnil
のいずれでもなければ、Emacsは入力の8ビットすべてを変更せずに使用する。これは8ビット文字セットを使用する端末にたいして適している。
quit-charが非nil
ならquitに使用する文字を指定する。この文字は通常はC-g。quitを参照のこと。
current-input-mode
関数はEmacsがカレントで使用する入力モードのセッティングをリターンします。
この関数はキーボード入力読み取りにたいするカレントのモードをリターンする。これはset-input-mode
の引数に対応した(interrupt
flow meta quit)
という形式のリストをリターンする。
Emacsが割り込み駆動の入力(interrupt-driven
input)を使用時には非nil
。nil
ならEmacsはCBREAKモードを使用している。
Emacsが端末出力にXON/XOFFフロー制御(C-qとC-s)を使用していれば非nil
。この値はinterruptがnil
のときのみ意味がある。
Emacsが入力文字の8番目のビットをメタ文字として扱う場合にはt
。nil
はEmacsがすべての入力文字の8ビット目をクリアーすることを意味する。その他の値はEmacsが8ビットすべてを基本的な文字コードとして使用することを意味する。
カレントでEmacsがquitに使用する文字であり通常はC-g。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はキーボードかマウスからの最後の入力イベント300個を含んだベクターをリターンする。その入力イベントがキーシーケンスに含まれるか否かに関わらずすべての入力イベントが含まれる。つまりキーボードマクロにより生成されたイベントを含まない、最後の入力イベント300個を常に入手することになる(キーボードマクロは、デバッグにとってより興味深いとはいえないので除外されている。そのマクロを呼び出したイベントを確認するだけで充分であるはず)、
clear-this-command-keys
(コマンドループからの情報を参照)を呼び出すと、その直後はこの関数は空のベクターをリターンする。
この関数はfilenameという名前のdribbleファイル(dribble file)をオープンする。dribbleファイルがオープンされたとき、キーボードとマウス(ただしキーボードマクロ由来は除く)からのそれぞれの入力イベントはそのファイルに書き込まれる。非文字イベントは‘<…>’で囲まれたプリント表現で表される。(パスワードのような)機密情報はdribbleファイルへの記録を終了させることに注意。
引数nil
でこの関数を呼び出すことによりファイルはクローズされる。
端末の出力のopen-termscript
も参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
端末出力関数は出力をテキスト端末に送信したり、端末に送信した出力を追跡します。変数baud-rate
はEmacsが端末の出力スピードをどのように考慮すべきかを指示します。
この変数はEmacsの認識する端末の出力スピード。この変数をセットしても実際のデータ転送スピードは変化しないが、この値はパディングのような計算に使用される。
これはテキスト端末でスクリーンの一部をスクロールしたり再描画すべきかどうかについての判定にも影響する。グラフィカルな端末での対応する機能については強制的な再表示を参照のこと。
値の単位はボー(baud)。
ネットワークを介して実行中にネットワークの別の部分が違うボーレートで機能している場合には、Emacsがリターンする値はユーザーのローカル端末で使用される値と異なるかもしれません。いくつかのネットワークプロトコルはローカル端末のスピードでリモートマシンと対話するので、Emacsや他のプログラムは正しい値を得ることができますが相手側はそうではありません。Emacsが誤った値をもつ場合には最適よりも劣る判定をもたらします。この問題を訂正するためにはbaud-rate
をセットします。
この関数はstringを変更せずにterminalへ送信する。string内のコントロール文字は端末依存の効果をもつ(端末上に非ASCIIテキストを表示する必要があるなら明示的なエンコードとデコードに記述した関数のいずれかを使用してエンコードすること)。この関数はテキスト端末だけを操作する。terminalには端末オブジェクト、フレーム、または選択されたフレームの端末を意味するnil
を指定できる。batchモードではterminalがnil
なら、stringはstdout
に送信される。
この関数の1つの用途はダウンロード可能なファンクションキー定義をもつ端末上でファンクションキーを定義することである。たとえば以下は(特定の端末で)ファンクションキー4を前方へ4文字移動(そのコンピューターヘ文字C-u C-fを送信)するように定義する方法:
(send-string-to-terminal "\eF4\^U\^F") ⇒ nil
この関数はEmacsが端末へ送信したすべての文字を記録するtermscriptファイル(termscript
file)をオープンする。リターン値はnil
。termscriptファイルはEmacsのスクリーン文字化け問題、不正なTermcapエントリーや、実際のEmacsバグより頻繁に発生する望ましくない端末オプションのセッティングの調査に有用。どの文字が実際に出力されるか確信できれば、それらの文字が使用中のTermcap仕様に対応するかどうか確実に判断できる。
(open-termscript "../junk/termscript") ⇒ nil
引数nil
でこの関数を呼び出すことによりtermscriptファイルはクローズされる。
入力の記録のopen-dribble-file
も参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsを使用してサウンドを再生するためには関数play-sound
を使用します。特定のシステムだけがサポートされています。実際に処理を行うことができないシステムでplay-sound
を呼び出すとエラーが発生します。
サウンドはRIFF-WAVEフォーマット(‘.wav’)かSun Audioフォーマット(‘.au’)で格納されていなければなりません。
この関数は指定されたサウンドを再生する。引数soundは(sound
properties...)
という形式をもつ。ここでpropertiesはキーワード(特定のシンボルが特別に認識される)とそれに対応する値で交互に構成されている。
以下のテーブルは現在のところsound内で意味をもつキーワードとそれらの意味:
:file file
これは再生するサウンドを含んだファイルを指定する。絶対ファイル名でなければディレクトリーdata-directory
にたいして展開される。
:data data
これはファイルを参照する必要がないサウンドの再生を指定する。値dataはサウンドファイルと同じバイトを含む文字列であること。わたしたちはユニバイト文字列の使用を推奨する。
:volume volume
これはサウンド再生での音の大きさを指定する。0から1までの数値であること。どんな値であれ以前に指定されたボリュームがデフォルトとして使用される。
:device device
これはサウンドを再生するシステムデバイスを文字列で指定する。デフォルトのデバイスはシステム依存。
実際にサウンドを再生する前にplay-sound
はリストplay-sound-functions
内の関数を呼び出す。関数はそれぞれ1つの引数soundで呼び出される。
この関数はオプションでvolumeとdeviceを指定してサウンドfileを再生する代替インターフェイス。
リストの関数はサウンド再生前に呼び出される。関数はそれぞれサウンドを記述するプロパティリストを単一の引数として呼び出される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
システム固有のX11 keysym(key symbol:
キーシンボル)を定義するには変数system-key-alist
をセットします。
この変数の値はシステム固有のkeysymそれぞれにたいして1つの要素をもつようなalistであること。要素はそれぞれ(code
. symbol)
という形式をもつ。ここでcodeは数字のkeysymコード(ベンダー固有の
-2**28),
のビットは含まない)、symbolはそのファンクションキーの名前。
たとえば(168 . mute-acute)
は数字コード
-2**28
+ 168のシステム固有キーを定義する(HP Xサーバーで使用される)。
このalistから他のXサーバーのkeysymを除外することは重要ではない。実際に使用中のXサーバーが使用するkeysymが競合しないかぎり無害である。
この変数は常にカレント端末にたいしてローカルでありバッファーローカルにできない。複数の端末を参照のこと。
以下の変数をセットすればEmacsが修飾キーMeta、Alt、Hyper、Superにたいして何のkeysymを使用するべきかを指定できます。
keysymの名前はそれぞれ修飾子Alt、Meta、Hyper、Superを意味する名前であること。たとえば以下はMeta修飾キーとAlt修飾キーを交換する方法:
(setq x-alt-keysym 'meta) (setq x-meta-keysym 'alt)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コマンドラインオプション‘-batch’でEmacsを非対話的に実行できます。このモードではEmacsは端末からコマンドを読み取りません。また終端モード(terminal modes)を変更せず消去可能なスクリーンへの出力も待ち受けません。これはLispプログラムの実行を指示して終了したらEmacsが終了するというアイデアです。これを行うには‘-l file’によりfileという名前のライブラリーをロード、‘-f function’により引数なしでfunctionを呼び出す、または‘--eval form’で実行するプログラムを指定できます。
通常はエコーエリアに出力したりストリームとしてt
を指定するmessage
やprin1
等を使用したLispプログラムの出力はbatchモードではEmacsの標準記述子へと送られます(prin1
や他のプリント関数は標準記述子に書き込むがmessage
は標準エラー記述子に書き込む)。同様に通常はミニバッファーから読み取られる入力は標準入力から読み取られます。つまりEmacsは非インタラクティブなアプリケーションプログラムのように振る舞います(コマンドのエコーのようにEmacsが通常生成するエコーエリアへの出力はすべて抑制される)。
標準出力やエラー記述子に書き込まれる非ASCIIテキストは、locale-coding-system
が非nil
ならそれを使用してエンコードされます(localeを参照)。coding-system-for-write
を他のコーディングシステムにバインドすればこれをオーバーライドできます(明示的なエンコードとデコードを参照)。
Emacsがbatchモードで実行中ならこの変数は非nil
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはアプリケーションのサスペンドとリスタートに使用されるXセッション管理プロトコル(XSMP: X Session Management Protocol)をサポートしています。Xウィンドウシステムではセッションマネージャー(session manager)と呼ばれるプログラムが実行中アプリケーション追跡の責を負います。Xサーバーのシャットダウン時にセッションマネージャーはアプリケーションに状態を保存するか尋ねて、それらが応答するまでシャットダウンを遅延します。アプリケーションがそのシャットダウンをキャンセルすることもできます。
セッションマネージャーがサスペンドされたセッションをリスタートする際には、これらのアプリケーションにたいして保存された状態をリロードするように個別に指示します。これはリストアする保存済みセッションが何かを指定する特別なコマンドラインオプションを指定することにより行われます。これはEmacsでは‘--smid session’という引数です。
Emacsはemacs-save-session-functions
と呼ばれるフックを介した状態の保存をサポートする。セッションマネージャーがウィンドウシステムのシャットダウンを告げた際にEmacsはこのフックを実行する。これらの関数はカレントバッファーを一時バッファーにセットして引数なしで呼び出される。それぞれの関数はバッファーにLispコードを追加するためにinsert
を使用できる。最後にEmacsはセッションファイル(session
file)と呼ばれるファイル内にそのバッファーを保存する。
その後でセッションマネージャーがEmacsを再開する際に、Emacsはセッションファイルを自動的にロードする(ロードを参照)。これはスタートアップ中に呼び出されるemacs-session-restore
という名前の関数により処理される。要約: スタートアップ時のアクション順序を参照のこと。
emacs-save-session-functions
内の関数が非nil
をリターンすると、Emacsはセッションマネージャーにシャットダウンのキャンセルを要求します。
以下はセッションマネージャによりEmacsがリストアされる際に単に*scratch*にテキストを挿入する例です。
(add-hook 'emacs-save-session-functions 'save-yourself-test)
(defun save-yourself-test () (insert "(save-current-buffer (switch-to-buffer \"*scratch*\") (insert \"I am restored\"))") nil)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはfreedesktop.orgのDesktop Notifications
SpecificationをサポートするシステムとMS-Windowsでは通知(notifications)を送ることができます。Posixホストでこの機能を使用するには、EmacsがD-Busサポート付きでコンパイルされていてnotifications
ライブラリーがロードされていなければなりません。D-Bus in D-Bus integration in
Emacsを参照してください。以下の関数はD-Bus利用可能な際にサポートされます:
この関数は引数paramsで指定された構成したパラメーターによりD-Busを通じてデスクトップに通知を送信する。これらの引数は交互になったキーワードと値のペアーで構成されていること。以下はサポートされているキーワードと値:
:bus bus
D-Busのバス。この引数は:session
以外のバスを使用する場合のみ必要。
:title title
通知のタイトル。
:body text
通知のbodyのテキスト。通知サーバーの実装に依存して‘"<b>bold text</b>"’のようなHTMLマークアップ、ハイパーリンク、イメージをテキストに含むことができる。HTML特殊文字は‘"Contact <postmaster@localhost>!"’のようにエンコードしなければならない。
:app-name name
その通知を送信するアプリケーション名。デフォルトはnotifications-application-name
。
:replaces-id id
この通知が置換する通知のid。idはnotifications-notify
の以前の呼び出し結果でなければならない。
:app-icon icon-file
通知アイコンのファイル名。nil
ならアイコンは表示されない。デフォルトはnotifications-application-icon
。
:actions (key title key title ...)
適用されるアクションのリスト。keyとtitleはどちらも文字列。デフォルトのアクション(通常は通知クリックで呼び出される)は‘"default"’という名前であること。実装がそれを表示しないようにするには自由だがtitleは何でもよい。
:timeout timeout
timeoutは通知が表示されてからその通知が自動的にクローズされるまでのミリ秒での時間。-1なら通知の有効期限は通知サーバーのセッティングに依存して、通知のタイプにより異なるかもしれない。0なら通知は失効しない。デフォルト値は-1。
:urgency urgency
緊急レベル。low
、normal
、critical
のいずれか。
:action-items
このキーワードが与えられるとアクションのtitle文字列はアイコン名として解釈される。
:category category
通知の種類の文字列。標準のカテゴリーのリストはDesktop Notifications Specificationを参照のこと。
:desktop-entry filename
これは‘"emacs"’のようにプログラムを呼び出すデスクトップファイル名の名前を指定する。
:image-data (width height rowstride has-alpha bits channels data)
これはそれぞれwidth、height、rowstride、およびalpha channel、bits per sample、channels、image dataの有無を記述するrawデータのイメージフォーマット。
:image-path path
これはURI(現在サポートされているのはURIスキーマは‘file://’のみ)、または‘$XDG_DATA_DIRS/icons’にあるfreedesktop.org準拠のアイコンテーマ名のいずれかを表す。
:sound-file filename
通知ポップアップ時に再生するサウンドファイルのパス。
:sound-name name
通知ポップアップ時に再生するfreedesktop.orgサウンド命名仕様準拠のテーマに対応した‘$XDG_DATA_DIRS/sounds’にある名前付きサウンド。アイコン名と同様にサウンドにたいしてのみ。例としては‘"message-new-instant"’。
:suppress-sound
それが可能ならサーバーにすべてのサウンドの再生を抑制させる。
:resident
セットするとアクション呼び出し時にサーバーは通知を自動的に削除しない。ユーザーか送信者により明示的に削除されるまで通知はサーバー内に常駐し続ける。恐らくこのヒントはサーバーが:persistence
能力をもつときのみ有用。
:transient
セットするとサーバーはその通知を過渡的なものとして扱い、もしそれが永続的であるべきならサーバーのpersistence能力をバイパスする。
:x position
:y position
その通知がポイントすべきスクリーン上のXとYの座標を指定する。これらの引数は併せて使用しなければならない。
:on-action function
アクション呼び出し時に呼び出す関数。通知idとアクションのkeyは引数としてその関数に渡される。
:on-close function
タイムアウトかユーザーにより通知がクローズされたときに呼び出す関数。通知idとクローズ理由reasonは引数としてその関数に渡される。:
expired
。
dismissed
。
notifications-close-notification
呼び出しにより通知がクローズされたら
close-notification
undefined
。
通知サーバーがどのパラメーターを受け入れるかのチェックはnotifications-get-capabilities
を通じて行うことができる。
この関数は整数の通知idをリターンする。このidはnotifications-close-notification
や別のnotifications-notify
呼び出しの:replaces-id
引数で通知アイテムの操作に使用できる。たとえば:
(defun my-on-action-function (id key) (message "Message %d, key \"%s\" pressed" id key)) ⇒ my-on-action-function
(defun my-on-close-function (id reason) (message "Message %d, closed due to \"%s\"" id reason)) ⇒ my-on-close-function
(notifications-notify :title "Title" :body "This is <b>important</b>." :actions '("Confirm" "I agree" "Refuse" "I disagree") :on-action 'my-on-action-function :on-close 'my-on-close-function) ⇒ 22
A message window opens on the desktop. Press ``I agree''. ⇒ Message 22, key "Confirm" pressed Message 22, closed due to "dismissed"
この関数は識別子idの通知をクローズする。busはD-Bus接続を表す文字列でありデフォルトは:session
。
通知サーバーの能力をシンボルのリストでリターンする。busはD-Bus接続を表す文字列でありデフォルトは:session
。以下は期待できる能力:
:actions
サーバーはユーザーにたいする指定されたアクションを提供する。
:body
bodyのテキストをサポートする。
:body-hyperlinks
サーバーは通知内のハイパーリンクをサポートする。
:body-images
サーバーは通知内のイメージをサポートする。
:body-markup
サーバーは通知内のマークアップをサポートする。
:icon-multi
サーバーは与えられたイメージ配列内のすべてのフレームのアニメーションを描画できる。
:icon-static
与えられたイメージ配列内の正確に1フレームの表示をサポートする。この値は、:icon-multi
とは相互に排他。
:persistence
サーバーは通知の永続性をサポートする。
:sound
サーバーは通知のサウンドをサポートする。
これらに加えてベンダー固有の能力は:x-gnome-foo-cap
のように:x-vendor
で始まる。
通知サーバーの情報を文字列のリストでリターンする。busはD-Bus接続を表す文字列でありデフォルトは:session
。リターンされるリストは(name
vendor version spec-version)
。
サーバーのプロダクト名。
ベンダー名。たとえば‘"KDE"’や‘"GNOME"’。
サーバーのバージョン番号。
サーバーが準拠する仕様のバージョン。
spec_versionがnil
ならサーバーは‘"1.0"’以前の仕様をサポートする。
EmacsがMS-WindowsでGUIセッションとして実行時には、ネイティブのプリミティブを通じてD-Bus通知の小サブセットをサポートします:
この関数はparamsの指定にしたがってMS-Windowsのトレー通知(tray notification)を表示する。MS-Windowsトレー通知はタスクバーのの通知エリア内のアイコンからのバルーン内に表示される。
値は以下で説明するw32-notification-close
で通知の削除に使用できる一意な通知ID。関数が失敗するとリターン値はnil
。
引数paramsはkeyword/valueペアーで指定する。パラメーターはすべてオプションだが何もパラメーターを指定しなければ関数は何もせずにnil
をリターンする。
は以下はサポートされるパラメーター:
:icon icon
システムトレーにiconを表示する。iconが文字列ならアイコンをロードするファイル名(Windowsのアイコンファイル.ico)を指定すること。iconが文字列以外、またはこのパラメーターが指定されなければEmacsの標準アイコンが使用される。
:tip tip
通知のツールチップにtipを使用する。tipが文字列なら、通知により追加されたトレーアイコン上にマウスポインターを移動した際に表示されるツールチップのテキスト。tipが文字列以外またはこのパラメーターが指定されていなければ、ツールチップのデフォルトのテキストは‘Emacs notification’。ツールチップのテキストは127文字まで(Windows 2000以前は63文字)。それより長い文字列は切り捨てられる。
:level level
通知の重大度レベルでinfo
、warning
、error
のいずれか。値が与えられた場合には、:title
パラメーターも指定されて、かつ文字列の場合のみ通知アイコンの左に表示されるアイコンを決定する。
:title title
通知のタイトル。titleが文字列ならbodyテキストの直上に大きなフォントで表示される。タイトルのテキストは63文字まで。それより長い文字列は切り捨てられる。
:body body
通知のbody(本文)。bodyが文字列なら通知メッセージのテキストを指定する。テキストを行に分割する方法を制御するには埋め込みの改行を使用する。bodyのテキストは255文字までで、それより長ければ切り捨てられる。D-Busとは異なりbodyテキストはマークアップを含まないプレーンテキストであること。
Windows
2000以前のWindowsでは:icon
と:tip
だけがサポートされることに注意。他のパラメーターを渡すことは可能だが、それらの古いシステムでは無視されるだろう。
一度にアクティブな通知は最大でも常に1つ。新たな通知を表示できるようにするにはw32-notification-close
を呼び出してアクティブな通知を削除しなければならない。
タスクバーから通知とアイコンを削除するには以下の関数を使用します:
この関数は与えられた一意なidでトレー通知を削除する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
いくつかのオペレーティングシステムはファイル変更にたいするファイルシステムの監視をサポートします。正しく設定されていれば、Emacsはinotify、kqueue、gfilenotify、w32notifyのようなライブラリーを静的にリンクします。これらのライブラリーによりローカルマシン上でのファイルシステムの監視が有効になります。
リモートマシン上のファイルシステムの監視も可能です。Remote Files in The GNU Emacs Manualを参照してください。これはEmacsにリンク済みのライブラリーのいずれかに依存する訳ではありません。
通知されたファイル変更によりこれらすべてのライブラリーは異なるイベントを発行するので、Emacsは一意な参照を提供するライブラリーfilenotify
を提供しています。
fileに関するファイルシステムイベントの監視を追加する。これはfileに関するファイルシステムイベントがEmacsに報告されるように取り計らう。
リターン値は追加された監視ディスクリプター(descriptor)。タイプは背景にあるライブラリーに依存しており、以下の例に示すとおり整数とみなすことはできない。比較にはequal
を使用すること。
何らかの理由によりfileが監視不可能なら、この関数はエラーfile-notify-error
をシグナルする。
マウントされたファイルシステムでファイル変更を監視できないことがある。これはこの関数により検出されないので、非nil
のリターン値がfileの変更の通知を保証するものではない。
flagsは何を監視するかセットするためのコンディションのリスト。以下のシンボルを含めることができる:
change
ファイル変更を監視。
attribute-change
パーミッションや変更時刻のようなファイル属性の変更を監視。
fileがディレクトリーならディレクトリー内のすべてのファイルの変更が通知される。これは再帰的に機能しない。
Emacsは何らかのイベント発生時には以下の形式のeventを単一の引数として関数callbackを呼び出す:
(descriptor action file [file1])
descriptorはこの関数がリターンするオブジェクトと同じ。actionはイベントを示し、以下のシンボルのいずれか:
created
fileが作成された。
deleted
fileが削除された。
changed
fileの内容が変更された。w32notifyライブラリーでは属性の変更でも同様に報告される。
renamed
fileがfile1にリネームされた。
attribute-changed
fileの属性が変更された。
stopped
監視中のfileが削除された。
w32notifyライブラリーはattribute-changed
イベントを報告しないことに注意。このライブラリーはパーミッションや変更時刻のようなファイル属性が何か変更された際にはchanged
イベントを報告する。同じようにkqueueライブラリーでは、ディレクトリー監視時にはファイル属性変更の報告に信頼性がない。
stopped
イベントはファイル監視の停止を報告する。これはfile-notify-rm-watch
の呼び出された(以下参照)、監視中のファイルが削除された、または背後にあるライブラリーから別のエラーが報告された可能性がある。
fileとfile1はイベントが報告されたファイルの名前。たとえば:
(require 'filenotify) ⇒ filenotify
(defun my-notify-callback (event) (message "Event %S" event)) ⇒ my-notify-callback
(file-notify-add-watch "/tmp" '(change attribute-change) 'my-notify-callback) ⇒ 35025468
(write-region "foo" nil "/tmp/foo") ⇒ Event (35025468 created "/tmp/.#foo") Event (35025468 created "/tmp/foo") Event (35025468 changed "/tmp/foo") Event (35025468 deleted "/tmp/.#foo")
(write-region "bla" nil "/tmp/foo") ⇒ Event (35025468 created "/tmp/.#foo") Event (35025468 changed "/tmp/foo") Event (35025468 deleted "/tmp/.#foo")
(set-file-modes "/tmp/foo" (default-file-modes)) ⇒ Event (35025468 attribute-changed "/tmp/foo")
アクションrenamed
がリターンされるかどうかは使用する監視ライブラリーに依存する。それ以外ではdeleted
とcreated
のアクションがランダムな順にリターンされる。
(rename-file "/tmp/foo" "/tmp/bla") ⇒ Event (35025468 renamed "/tmp/foo" "/tmp/bla")
(delete-file "/tmp/bla") ⇒ Event (35025468 deleted "/tmp/bla")
descriptorに指定された既存のファイル監視を削除する。descriptorはfile-notify-add-watch
がリターンしたオブジェクトであること。
descriptorで指定された監視の有効性をチェックする。descriptorはfile-notify-add-watch
がリターンしたオブジェクトであること。
監視するファイルやディレクトリーの削除や別の理由による監視スレッドの異常exitにより監視が無効になる可能性がある。file-notify-rm-watch
の呼び出しで削除することにより監視も無効になる。
(make-directory "/tmp/foo") ⇒ Event (35025468 created "/tmp/foo")
(setq desc (file-notify-add-watch "/tmp/foo" '(change) 'my-notify-callback)) ⇒ 11359632
(file-notify-valid-p desc) ⇒ t
(write-region "bla" nil "/tmp/foo/bla") ⇒ Event (11359632 created "/tmp/foo/.#bla") Event (11359632 created "/tmp/foo/bla") Event (11359632 changed "/tmp/foo/bla") Event (11359632 deleted "/tmp/foo/.#bla")
;; ディレクトリーのファイル削除では監視は無効にならない (delete-file "/tmp/foo/bla") ⇒ Event (11359632 deleted "/tmp/foo/bla")
(write-region "bla" nil "/tmp/foo/bla") ⇒ Event (11359632 created "/tmp/foo/.#bla") Event (11359632 created "/tmp/foo/bla") Event (11359632 changed "/tmp/foo/bla") Event (11359632 deleted "/tmp/foo/.#bla")
;; ディレクトリー削除により監視は無効になる ;; 別の監視ディスクリプターからイベントが到着 (delete-directory "/tmp/foo" 'recursive) ⇒ Event (35025468 deleted "/tmp/foo") Event (11359632 deleted "/tmp/foo/bla") Event (11359632 deleted "/tmp/foo") Event (11359632 stopped "/tmp/foo")
(file-notify-valid-p desc) ⇒ nil
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ダイナミックにロードされるライブラリー(dynamically loaded library)とは機能が最初に必要になったときにオンデマンドでロードされるライブラリーです。Emacsは自身の機能をサポートするライブラリーのオンデマンドロードのように、それらをサポートします。
ダイナミックライブラリーとそれらを実装する外部ライブラリーファイルのalist。
要素はそれぞれ(library files…)
という形式のリスト。ここでcar
はサポートされた外部ライブラリーを表すシンボル、残りはそのライブラリーにたいして候補となるファイル名を与える文字列。
Emacsはリスト内のファイル出現順でライブラリーのロードを試みる。何も見つからなければEmacsセッションはライブラリーにアクセスできず、それが提供する機能は利用できない。
いくつかのプラットフォーム上におけるイメージのサポートはこの機能を使用している。以下は、S-Windows上でイメージをサポートするためにこの変数をセットする例:
(setq dynamic-library-alist '((xpm "libxpm.dll" "xpm4.dll" "libXpm-nox4.dll") (png "libpng12d.dll" "libpng12.dll" "libpng.dll" "libpng13d.dll" "libpng13.dll") (jpeg "jpeg62.dll" "libjpeg.dll" "jpeg-62.dll" "jpeg.dll") (tiff "libtiff3.dll" "libtiff.dll") (gif "giflib4.dll" "libungif4.dll" "libungif.dll") (svg "librsvg-2-2.dll") (gdk-pixbuf "libgdk_pixbuf-2.0-0.dll") (glib "libglib-2.0-0.dll") (gobject "libgobject-2.0-0.dll")))
イメージタイプpbm
とxbm
は外部ライブラリーに依存せずEmacsで常に利用可能なので、この変数内にエントリーがないことに注意。
これは外部ライブラリーへのアクセスにたいする一般的な機能を意図したものではないことにも注意。Emacsにとって既知のライブラリーだけがこれを通じてロードできる。
与えられたlibraryがEmacsに静的にリンクされていれば、この変数は無視される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
すべてのアプリケーションと同じように、アクセス等のルールを励行するオペレーティングシステムでは、Emacsを安全な環境で実行できます。注意を払えばEmacsベースのアプリケーションがそのようなルールをチェックするセキュリティ境界の一部になることもできます。Emacsのデフォルトのセッティングでは典型的なソフトウェア開発環境としても良好に機能しますが、アタッカーを含んだ信頼されないユーザーの存在する環境では調整を要します。以下はそのようなアプリケーションを開発する際に助けとなるセキュリティ問題の要覧です。これは完全なものではありません。これはセキュリティチェックリストではなく、セキュリティに関する問題にたいするアイデアを与えることを意図したものです。
Emacsがvisitするファイルは、ファイルをvisitするバッファーに影響を与える変数セッティングを含むことができる。ファイルローカル変数を参照のこと。同様にディレクトリーはディレクトリー内のすべてのファイルに共通なローカル変数値を指定できる。ディレクトリーローカル変数を参照のこと。これらの変数の悪用から守るためにEmacsはある程度の努力をしているにしても、過度に楽観してパッケージでsafe-local-variable
をセットすることにより単にセキュリティホールが作られてしまうというのは、あまりにも有りがちな問題である。ファイルとディレクトリーの両方でこの機能を無効にするには、enable-local-variables
にnil
をセットする。
Emacsが通常は背後にあるオペレーティングシステムのアクセス権限にしたがうとしても、アクセスを特別に扱うケースがある。たとえばファイル名は独自のアクセスチェックによりファイルを特別に扱うハンドラーをもつことができる。特定のファイル名の“Magic”の作成を参照のこと。また対応するファイルが書き込み可でもバッファーを読み取り専用にできるが逆も可能であり、その結果は‘File passwd is write-protected; try to save anyway? (yes or no)’のようなメッセージとなるかもしれない。読み取り専用のバッファーを参照のこと。
Emacsにはread-passwd
のようなパスワードを扱う関数がいくつかある。パスワードの読み取りを参照のこと。これらの関数はパスワードを公に喧伝しないにしても、Emacs内部にアクセスする猛者なアタッカーにたいする実装の証左はない。たとえばパスワード使用後にメモリーをクリアーするためにelispコードがclear-string
を使用しても、パスワードの残滓は依然としてガーベージコレクトされたフリーリスト内に存在する。文字列の変更を参照のこと。
Emacsは他の多くのアプリケーションにコマンドを送信でき、アプリケーションはコマンドの値として送信された文字列を命令と誤解しないように注意を払う必要がある。たとえばファイルをaからbにリネームするためにシェルコマンドを使用する際には単に文字列mv
a
b
を使用するべきではない。なぜならいずれかのファイル名が‘-’で始まったり、‘;’のようなシェルのメタ文字を含むかもしれない。この種の問題はshell-quote-argument
のような関数の使用で回避できるものの、POSIXプラットフォームではshell-quote-argument
はシェルのメタ文字はクォートするが先頭の‘-’はクォートしない。shell引数を参照のこと。call-process
を使用するほうが通常はサブシェルより安全である。同期プロセスの作成を参照のこと。同様に、たとえばmv
を呼び出すかわりに(rename-file "a"
"b" t)
を使用する等、Emacsのビルドイン関数を使用するほうが安全である。ファイルの名前と属性の変更を参照のこと。
Emacsはアクセスするファイルとネットワークのコーディングシステムを推察する。コーディングシステムを参照のこと。Emacsの推察が誤っていたりネットワークの相手先がEmacsの推察に不同意なら、結果となるコーディングシステムは信頼できないかもしれない。更にその推察が正しいときでさえ、他のプログラムが使用できないバイトをEmacsが使用できる場合がよくある。たとえばEmacsEmacsにとってはnullバイトは他と同じ単なる文字だとしても、他の多くのアプリケーションはnull文字を文字列終端として扱うので、nullバイトを含む文字列やファイルを誤って処理する。
POSIXはEmacsの挙動に影響し得る環境変数をいくつか指定する。ASCII英大文字、数字、アンダースコアだけから構成される名前をもつ任意の環境変数がEmacsの内部の動作に影響を及ぼし得る。Emacsはその種のEMACSLOADPATH
のような変数をいくつか使用する。See section ライブラリー検索を参照のこと。Emacsが呼び出すかもしれないユーティリティーすべてにたいして標準の挙動を得るためには、いくつかの環境変数(PATH
、POSIXLY_CORRECT
、SHELL
、TMPDIR
)が正しく設定されていることを要するシステムがいくつかある。TZ
のような一見は無害な変数でさえセキュリティに影響し得る。オペレーティングシステムの環境を参照のこと。
Emacsにはカスタマイズと同義な変数が他にある。たとえば変数shell-file-name
に非標準的な動作を行うシェルを指定すれば、Emacsベースのアプリケーションはご堂する可能性がある。
Emacsのインストールの際にインストール先のディレクトリー階層が信頼できないユーザーに変更可能なら、そのアプリケーションは信頼できない。これはEmacsが使用するプログラムや読み書きするファイルのディレクトリー階層にも適用される。
Emacsでは多くの場合にネットワークにアクセスするので、通常行うようなネットワークアクセスを回避したいと思うかもしれない。たとえばtramp-mode
をnil
にセットしていなければ、特定の構文を使用するファイル名はネットワークファイルとして解釈されて、ネットワーク越しに取得される。The Tramp Manual in The Tramp Manualを参照のこと。
Emacsアプリケーションには、他のアプリケーションが行う競合状態に関するものと同種の問題がある。たとえば(file-readable-p
"foo.txt")
がt
をリターンしたときでさえ、file-readable-p
の呼び出しからその時点の間に別のアプリケーションがファイルの権限を変更したために読み取りできないかもしれない。アクセシビリティのテストを参照のこと。
Emacsがメモリーや他のオペレーティングシステムのリソースを使い切ったときには、通常は完了まで実行される計算が異常終了でトップレベルに戻るかもしれないので挙動の信頼性が減少し得る。これにより通常は完了する操作をEmacsが放棄するかもしれない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispコードをユーザーに配布するために、Emacsは標準的な方法を提供します。パッケージ(package)はユーザーが簡単にダウンロード、インストール、アンインストール、および更新できるような方法でフォーマットと同梱された1つ以上のファイルのコレクションです。
以降のセクションではパッケージを作成する方法、およびそれを他の人がダウンロードできるようにパッケージアーカイブ(package archive)に配置する方法を説明します。パッケージングシステムのユーザーレベル機能の説明はPackages in The GNU Emacs Manualを参照してください。
39.1 パッケージ化の基礎 | Emacs Lispパッケージの基本的概念。 | |
39.2 単純なパッケージ | 単一.elファイルをパッケージする方法。 | |
39.3 複数ファイルのパッケージ | 複数ファイルをパッケージする方法。 | |
39.4 パッケージアーカイブの作成と保守 | パッケージアーカイブの保守。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
パッケージはシンプルパケージ(simple package)か複数ファイルパッケージ(multi-file package)のいずれかです。シンプルパッケージは単一のEmacs Lispファイル内に格納される一方、複数ファイルパッケージはtarファイル(複数のLispファイルとマニュアルのような非Lispファイルが含まれる可能性がある)に格納されます。
通常の使い方ではシンプルパッケージと複数ファイルパッケージとの違いは比較的重要ではありません。Package Menuインターフェースでは、それらの間に差異はありません。しかし以降のセクションで説明するように作成する手順は異なります。
パッケージ(シンプルか複数ファイル)はそれぞれ特定の属性(attributes)をもっています:
短い単語(たとえば‘auctex’)。これは通常はそのプログラム内でシンボルプレフィクスとしても使用される(Emacs Lispコーディングの慣習を参照)。
関数version-to-list
が理解できる形式のバージョン番号(たとえば‘11.86’)。パッケージの各リリースではバージョン番号もアップすること。
そのパッケージがPackage Menuにリストされる際にが表示される。理想的には36文字以内の単一行であること。
これはC-h P
(describe-package
)により作成されたバッファーに表示されて、その後にそのパッケージの簡単な説明(brief
description)とインストール状態(installation
status)が続く。これには通常はパッケージの能力とインストール後に使用を開始する方法を複数行に渡って完全に記述すること。
そのパッケージが依存する他のパッケージ(最低のバージョン番号を含むかもしれない)。このリストは空でもよく、その場合にはパッケージは依存パッケージがないことを意味する。それ以外ならパッケージをインストールすることにより依存パッケージも自動的にインストールされる。依存パッケージのいずれかが見つからなければパッケージをインストールすることはできない。
コマンドpackage-install-file
、またはPackage
Menuのいずれかを介したパッケージのインストールでは、package-user-dir
にname-versionという名前のサブディレクトリーが作成されます。ここでnameはパッケージ名、versionはバージョン番号です(たとえば~/.emacs.d/elpa/auctex-11.86/)。わたしたちはこれをパッケージのコンテンツディレクトリー(content
directory)と呼んでいます。これはEmacsがパッケージのコンテンツ(シンプルパッケージでは単一のLispファイル、または複数ファイルパッケージから抽出されたファイル)を配置する場所です。
その後にEmacsはautoloadマジックコメント(autoloadを参照)にたいしてコンテンツディレクトリー内のすべてのLispファイルを検索します。これらのautoload定義はコンテンツディレクトリーのname-autoloads.elという名前のファイルに保存されます。これらは通常はパッケージ内で定義された主要なユーザーコマンドのautoloadに使用されますが、auto-mode-alist
への要素の追加(Emacsがメジャーモードを選択する方法を参照)等の別のタスクを行うこともできます。パッケージは通常はその中で定義された関数と変数のすべてをautoloadしないことに注意してください
—
通常はそのパッケージの使用を開始するために呼び出される一握りのコマンドだけがautoloadされます。それからEmacsはそのパッケージ内のすべてのLispファイルをバイトコンパイルします。
インストール後はインストールされたパッケージはロード済み(loaded)になります。Emacsはload-path
にコンテンツディレクトリーを追加してname-autoloads.el内のautoload定義を評価します。
Emacsのスタートアップ時はインストール済みパッケージをロードするために、常に自動的に関数package-initialize
が呼び出されます。これはinitファイルと、(もしあれば)abbrevファイルのロード後、かつafter-init-hook
の実行前に行われます(要約: スタートアップ時のアクション順序を参照)。ユーザーオプションpackage-enable-at-startup
がnil
なら自動的なパッケージのロードは無効です。
この関数はインストール済みパッケージ、およびそれらがロード済みかどうかを記録するEmacsの内部レコードを初期化する。ユーザーオプションpackage-load-list
は何のパッケージをロードするかを指定する。デフォルトではすべてのインストール済みパッケージがロードされる。スタートアップ中に呼び出されると、この関数は意図せずパッケージを2重にロードすることを防ぐためにpackage-enable-at-startup
にnil
をセットする。Package
Installation in The GNU Emacs Manualを参照のこと。
オプション引数no-activateが非nil
なら、インストール済みパッケージを実際にロードせずにこのレコードを更新する。これは内部でのみ使用される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
シンプルパッケージは単一のEmacs Lispソースファイルで構成されます。このファイルはEmacs Lispライブラリーのヘッダー規約に準拠していなればなりません(Emacsライブラリーのヘッダーの慣習を参照)。以下の例に示すようにパッケージの属性は種々のヘッダーから取得されます:
;;; superfrobnicator.el --- Frobnicate and bifurcate flanges ;; Copyright (C) 2011 Free Software Foundation, Inc.
;; Author: J. R. Hacker <jrh@example.com> ;; Version: 1.3 ;; Package-Requires: ((flange "1.0")) ;; Keywords: multimedia, frobnicate ;; URL: http://example.com/jrhacker/superfrobnicate … ;;; Commentary: ;; This package provides a minor mode to frobnicate and/or ;; bifurcate any flanges you desire. To activate it, just type … ;;;###autoload (define-minor-mode superfrobnicator-mode …
そのパッケージの名前は1行目のファイル名の拡張子を除いた部分と同じです。ここでは‘superfrobnicator’です。
brief description(簡単な説明)も1行目から取得されます。ここでは‘Frobnicate and bifurcate flanges’です(訳注: ‘flangeをフロブニケートして二股化する’のフロブニケートとはある技術にたいする無目的で非生産的な具体的行為を意味する)。
バージョン番号は、もしあれば‘Package-Version’ヘッダー、それ以外は‘Version’ヘッダーから取得されます。これらのヘッダーのいずれかが提供されていなればなりません。ここでのバージョン番号は1.3です。
そのファイルに‘;;; Commentary:’セクションがあれば、そのセクションは長い説明(long description)として使用されます(その説明を表示する際にはEmacsは‘;;; Commentary:’の行とコメント内のコメント文字列を省略する)。
そのファイルに‘Package-Requires’ヘッダーがあればパッケージの依存関係(package dependencies)として使用されます。上の例ではパッケージはバージョン1.0以上の‘flange’パッケージに依存します。‘Package-Requires’ヘッダーの説明はEmacsライブラリーのヘッダーの慣習を参照してください。このヘッダーが省略された場合にはパッケージに依存関係はありません。
ヘッダー‘Keywords’と‘URL’はオプションですが含めることを推奨します。コマンドdescribe-package
は出力にリンクを追加するためにこれらを使用します。‘Keywords’ヘッダーにはfinder-known-keywords
リストからの標準的キーワードを少なくとも1つ含めるべきです。
ファイルにはパッケージ化の基礎で説明したように1つ以上のautoloadマジックコメントも含めるべきです。上の例ではマジックコメントによりsuperfrobnicator-mode
が自動ロードされます。
パッケージアーカイブに単一ファイルのパッケージを追加する方法はパッケージアーカイブの作成と保守を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
複数ファイルパッケージは単一ファイルパッケージより作成の手軽さが少し劣りますが、より多くの機能を提供します。複数ファイルパッケージには複数のEmacs Lispファイル、Infoマニュアル、および(イメージのような)他のファイルタイプを含めることができます。
インストールに先立ち複数パッケージはファイルとしてパッケージアーカイブに含まれます。このtarファイルはname-version.tarという名前でなければなりません。ここでnameはパッケージ名、versionはバージョン番号です。tarのコンテンツは一度解凍されたなら、コンテンツディレクトリcontent directory)であるname-versionという名前のディレクトリーにすべて解凍されなければなりません(パッケージ化の基礎を参照)。このコンテンツディレクトリーのサブディレクトリーにもファイルが抽出されるかもしれません。
このコンテンツディレクトリー内のファイルのうち、1つはname-pkg.elという名前のファイルでなければなりません。このファイルには以下で説明する関数define-package
の呼び出しから構成される単一のLispフォームを含まなければなりません。これはパッケージのバージョン、簡単な説明(brief
description)、必要条件(requirements)を定義します。
たとえば、複数ファイルパッケージとしてsuperfrobnicatorのバージョン1.3を配布する場合のtarファイルはsuperfrobnicator-1.3.tarになります。これのコンテンツはsuperfrobnicator-1.3に解凍されて、そのうちの1つはファイルsuperfrobnicator-pkg.elになるでしょう。
この関数はパッケージを定義する。nameはパッケージの名前(文字列)、versionは関数version-to-list
が理解できる形式のバージョン(文字列)、docstringは簡単な説明(brief
description)。
requirementsは必要となるパッケージとバージョン番号。このリスト内の各要素は(dep-name
dep-version)
という形式であること。ここでdep-nameはその依存するパッケージ名が名前であるようなシンボル、dep-versionは依存するパッケージのバージョン番号(文字列)。
コンテンツディレクトリーにREADMEという名前のファイルがあれば長い説明(long description)として使用されます。
コンテンツディレクトリーにdirという名前のファイルがあれば、install-info
で作成されるInfoディレクトリーファイル名とみなされます。Invoking install-info in Texinfoを参照してください。関係のあるInfoファイルもコンテンツディレクトリー内に解凍される必要があります。この場合には、パッケージがアクティブ化されたときにEmacsが自動的にInfo-directory-list
にコンテンツディレクトリーを追加します。
パッケージ内に.elcファイルを含めないでください。これらはパッケージのインストール時に作成されます。ファイルがバイトコンパイルされる順序を制御する方法は存在しないことに注意してください。
name-autoloads.elという名前のファイルを含めてはなりません。このファイルはパッケージのautoload定義のために予約済みです(パッケージ化の基礎を参照)。これはパッケージのインストール時にパッケージ内のすべてのLispファイルからautoloadマジックコメントを検索する際に自動的に作成されます。
複数パッケージファイルが、(イメージのような)補助的なデータファイルを含む場合には、パッケージ内のLispファイルは変数load-file-name
を通じてそれらのファイルを参照できます(ロードを参照)。以下は例です:
(defconst superfrobnicator-base (file-name-directory load-file-name)) (defun superfrobnicator-fetch-image (file) (expand-file-name file superfrobnicator-base))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Package Menuを通じてパッケージアーカイブ(package
archives)からユーザーはパッケージをダウンロードできます。そのようなアーカイブは変数package-archives
で指定されます。この変数のデフォルト値にhttp://elpa.gnu.orgでGNUプロジェクトがホストするアーカイブが単一のエントリーとして含まれています。このセクションではパッケージアーカイブのセットアップと保守の方法について説明します。
この変数の値はEmacsパッケージマネージャーが認識するパッケージアーカイブのリスト。
このalistの要素はそれぞれが1つのアーカイブに対応する(id
.
location)
という形式であること。ここでidはパッケージ名(文字列)、locationは文字列であるようなベースロケーション(base
location)。
ベースロケーションが‘http:’で始まればHTTPのURLとして扱われて、(デフォルトのGNUアーカイブのように)HTTPを介してこのアーカイブからパッケージがダウンロードされる。
それ以外ならベースロケーションはディレクトリー名であること。この場合にはEmacsは通常のファイルアクセスを通じて、そのアーカイブからパッケージを取得する。localのようなアーカイブは主としてテストに有用。
パッケージアーカイブはパッケージ、および関連するファイルが格納された単なるディレクトリーです。HTTPを介してそのアーカイブに到達できるようにしたければ、このディレクトリーがウェブサーバーにアクセスできなければなりません。これを達成する方法はマニュアルの範囲を超えます。
手軽なのはpackage-x
を通じてパッケージアーカイブのセットアップと更新を行う方法です。これはEmacsに含まれていますがデフォルトではロードされません。ロードするにはM-x
load-library RET package-x RET、または(require
'package-x)
をinitファイルに追加します。Lisp Libraries in The
GNU Emacs Manualを参照してください。一度ロードされれば以下を使用できます:
この変数の値はディレクトリー名としてのパッケージアーカイブのベースロケーション。package-x
ライブラリー内のコマンドはこのベースロケーションを使用することになる。
このディレクトリー名は絶対ファイル名であること。パッケージアーカイブが別マシン上にある場合には、/ssh:foo@example.com:/var/www/packages/のようなリモート名を指定できる。Remote Files in The GNU Emacs Manualを参照のこと。
このコマンドはファイル名filenameの入力を求めて、そのファイルをpackage-archive-upload-base
にアップロードする。このファイルはシンプルパッケージ(.elファイル)、または複数ファイルパッケージ(.tarファイル)のいずれかでなければならず、それ以外ならエラーが発生する。そのパッケージの属性は自動的に解凍されて、アーカイブのコンテンツリストはこの情報でアップロードされる。
package-archive-upload-base
が有効なディレクトリーを指定しない場合には、この関数はインタラクティブにそれの入力を求める。そのディレクトリーが存在しなければ作成する。このディレクトリーが初期コンテンツをもつ必要はない(最初に空のアーカイブを作成するためにこのコマンドを使用できる)。
このコマンドはpackage-upload-file
と似ているが、パッケージファイルの入力を求めずにカレントバッファーのコンテンツをアップロードする。カレントバッファーはシンプルパッケージ(.elファイル)か複数ファイルパッケージ(.tarファイル)をvisitしていなればならず、それ以外ならエラーが発生する。
アーカイブ作成後に、それがpackage-archives
内になければPackage
Menuインターフェースからアクセスできないことを忘れないでください。
公的なパッケージアーカイブの保守には責任が併ないます。アーカイブからEmacsユーザーがパッケージをインストールする際には、それらのパッケージはそのユーザーの権限において任意のコードを実行できるようになります(これはパッケージにたいしてだけでなく一般的なEmacsコードにたいしても真といえる)。そのためアーカイブの保守を保つとともにホスティングシステムが安全であるよう維持するべきです。
暗号化されたキーを使用してパッケージにサイン(sign)するのがパッケージのセキュリティーを向上する1つの方法です。gpgのprivateキーとpublicキーを生成してあれば以下のようにそのパッケージにサインするためにgpgを使用できます:
gpg -ba -o file.sig file
単一ファイルパッケージにたいしては、fileはそのパッケージのLispファイルです。複数ファイルパッケージではそのパッケージのtarファイルです。同じ方法によりアーカイブのコンテンツファイルにもサインできます。これを行うにはパッケージと同じディレクトリーで.sigファイルを利用可能できるようにしてください。ダウンロードする人にたいしても、http://pgp.mit.edu/のようなキーサーバーにアップロードすることによりpublicキーを利用できるようにするべきです。その人がアーカイブからパッケージをインストールする際には署名の検証にpublicキーを使用できます。
これらの方法についての完全な説明はマニュアルの範囲を超えます。暗号化キーとサインに関する詳細はGnuPG in The GNU Privacy Guard Manual、Emacsに付属するGNU Privacy GuardへのインターフェースについてはEasyPG in Emacs EasyPG Assistant Manualを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
時代に逆らって生きるユーザーのために以下はEmacsバージョン24。5へのダウングレードに関する情報です。Emacs 25.1機能の不在による結果としての偉大なる単純さを、ぜひ堪能してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
setq
とsetf
の要件は削除されました。これで奇数個の引数でこれらを呼び出すことが可能になり、欠落分にはEmacsがnil
を提供するでしょう。単純明快なルールです!
EMACS
をセットします。このセッティングに対処する方法を何年もかけて習得したパッケージは、対処コードの使用を継続できます。
save-excursion
フォームは期待どおりにマークの保存とリストアを行います。新しいsave-mark-and-excursion
は必要なくなったので削除しました。
text-quoting-style
変数および関連する機能は削除されました。これでEmacsはコードに記述したのと完全に同一なクォート文字を表示するようになりました!
同様にsubstitute-command-keys
はクォート文字を加工しません。時代を遡るにつれてUnicodeのサポートと重要性は減少するので、Unicode標準が考案したこれらのfancyな新クォートの表示は不必要になります。
[:alpha:]
と[:alnum:]
は単語構文をもつ任意の文字、[:graph:]
と[:print:]
は任意のマルチバイト文字にマッチして、それらには代替コードポイントと未割り当てのコードポイントが含まれます。繰り返しますが、これは時代の逆行によるUnicodeの重要性減少に沿っています。
quote
とapp
を削除することによりpcase
は大幅に簡略化されました。Lispプログラムに新たにUPatternを定義させる必要がないことも判明したにで、この機能をさらに簡略化するためにpcase-defmacro
も削除しました。
cursor-intangible
とcursor-sensor-functions
を、より単純なintangible
、point-entered
、point-left
プロパティに置き換えることにより削除しました。後者はより低レベルで実装されるので、ユーザーの期待により統合されるでしょう。同様の理由によりcursor-intangible-mode
とcursor-sensor-mode
は削除されました。フック変数inhibit-point-motion-hooks
の使用はもはや時代遅れではありません。
make-process
と接続タイプpipe
の削除により、プロセスの作成と管理を行う関数が大幅に改善、簡略化されました。サブプロセスのstderr
へのリダイレクトはEmacsではなくシェルの機能により行われるべきなのです。
inhibit-message
変数の削除を決定しました。
string-collate-lessp
とstring-collate-equalp
は削除されました。これらのlocale非依存なカウンターパートであるstring-lessp
とstring-equal
はよりシンプルであり、locale依存の照合がEmacsにおいて有用たりえる状況をわたしたちが確認できない予測可能な結果を得ることができます。結果としてls-lisp.elパッケージはlocale非依存な方法でソートを行います。
bidi-find-overridden-directionality
とbuffer-substring-with-bidi-context
の削除を開始しました。
current-time-string
のような時刻変換関数はオプション引数zoneを受け取らなくなりました。カレントタイムゾーンを変更する必要があるなら(何で?)、set-time-zone-rule
で明示的に行ってください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. http://fsf.org/ Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
The purpose of this License is to make a manual, textbook, or other functional and useful document free in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.
This License is a kind of “copyleft”, which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.
We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.
This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The “Document”, below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as “you”. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.
A “Modified Version” of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.
A “Secondary Section” is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document’s overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.
The “Invariant Sections” are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.
The “Cover Texts” are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.
A “Transparent” copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not “Transparent” is called “Opaque”.
Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.
The “Title Page” means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, “Title Page” means the text near the most prominent appearance of the work’s title, preceding the beginning of the body of the text.
The “publisher” means any person or entity that distributes copies of the Document to the public.
A section “Entitled XYZ” means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” of such a section when you modify the Document means that it remains a section “Entitled XYZ” according to this definition.
The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.
You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and you may publicly display copies.
If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document’s license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.
If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.
It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.
You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:
If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version’s license notice. These titles must be distinct from any other section titles.
You may add a section Entitled “Endorsements”, provided it contains nothing but endorsements of your Modified Version by various parties—for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.
You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.
You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.
The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.
In the combination, you must combine any sections Entitled “History” in the various original documents, forming one section Entitled “History”; likewise combine any sections Entitled “Acknowledgements”, and any sections Entitled “Dedications”. You must delete all sections Entitled “Endorsements.”
You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.
You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.
A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an “aggregate” if the copyright resulting from the compilation is not used to limit the legal rights of the compilation’s users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document’s Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.
Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.
If a section in the Document is Entitled “Acknowledgements”, “Dedications”, or “History”, the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.
You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights under this License.
However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it.
The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.
Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License “or any later version” applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. If the Document specifies that a proxy can decide which future versions of this License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Document.
“Massive Multiauthor Collaboration Site” (or “MMC Site”) means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example of such a server. A “Massive Multiauthor Collaboration” (or “MMC”) contained in the site means any set of copyrightable works thus published on the MMC site.
“CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization.
“Incorporate” means to publish or republish a Document, in whole or in part, as part of another Document.
An MMC is “eligible for relicensing” if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008.
The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing.
To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:
Copyright (C) year your name. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''.
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the “with…Texts.” line with this:
with the Invariant Sections being list their titles, with the Front-Cover Texts being list, and with the Back-Cover Texts being list.
If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation.
If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Copyright © 2007 Free Software Foundation, Inc. http://fsf.org/ Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
The GNU General Public License is a free, copyleft license for software and other kinds of works.
The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program—to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.
For the developers’ and authors’ protection, the GPL clearly explains that there is no warranty for this free software. For both users’ and authors’ sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.
Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users’ freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and modification follow.
“This License” refers to version 3 of the GNU General Public License.
“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.
“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.
To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.
A “covered work” means either the unmodified Program or a work based on the Program.
To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.
To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.
The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.
A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.
The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.
The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work’s System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.
The Corresponding Source for a work in source code form is that same work.
All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.
When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work’s users, your or third parties’ legal rights to forbid circumvention of technological measures.
You may convey verbatim copies of the Program’s source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.
You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:
A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation’s users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:
A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.
A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.
“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).
The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.
“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:
All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.
You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).
However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.
You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.
Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.
An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party’s predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.
A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor’s “contributor version”.
A contributor’s “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor’s essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.
In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.
If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient’s use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.
A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.
If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.
Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.
The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.
If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Program.
Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.
If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.
one line to give the program's name and a brief idea of what it does. Copyright (C) year name of author This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:
program Copyright (C) year name of author This program comes with ABSOLUTELY NO WARRANTY; for details type ‘show w’. This is free software, and you are welcome to redistribute it under certain conditions; type ‘show c’ for details.
The hypothetical commands ‘show w’ and ‘show c’ should show the appropriate parts of the General Public License. Of course, your program’s commands might be different; for a GUI interface, you would use an “about box”.
You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see http://www.gnu.org/licenses/.
The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read http://www.gnu.org/philosophy/why-not-lgpl.html.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このチャプターでではEmacs Lispの追加機能については説明しません。かわりに以前のチャプターで説明した機能を効果的に使う方法、およびEmacs Lispプログラマーがしたがうべき慣習を説明します。
以降で説明する慣習のいくつかはLispファイルのvisit時にコマンドM-x checkdoc
RETを実行することにより自動的にチェックできます。これはすべての慣習はチェックできませんし、与えられた警告すべてが必ずしも問題に対応する訳ではありませんが、それらすべてを検証することには価値があります。カレントバッファーの慣習のチェックにはコマンドM-x
checkdoc-current-buffer RET、M-x compile RETで実行するコマンド等でbatchモードでファイルをチェックするにはcheckdoc-file
をかわりに使用してください。
D.1 Emacs Lispコーディングの慣習 | 明快で堅牢なプログラムにたいする慣習。 | |
D.2 キーバインディングの慣習 | どのキーをどのプログラムにバインドすべきか。 | |
D.3 Emacsプログラミングのヒント | Emacsコードを円滑にEmacsに適合させる。 | |
D.4 コンパイル済みコードを高速化ためのヒント | コンパイル済みコードの実行を高速にする。 | |
D.5 コンパイラー警告を回避するためのヒント | コンパイラー警告をオフにする。 | |
D.6 ドキュメント文字列のヒント | 読みやすいドキュメント文字列の記述。 | |
D.7 コメント記述のヒント | コメント記述の慣習。 | |
D.8 Emacsライブラリーのヘッダーの慣習 | ライブラリーパッケージにたいする標準的なヘッダー。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下は幅広いユーザーを意図したEmacs Lispコードを記述する際にしたがうべき慣習です:
この慣習はカスタム定義を含むすべてのファイルに必須である。そのようなファイルを慣習にしたがうために修正するのが非互換の変更を要するなら、構うことはないから非互換の修正を行うこと。先送りにしてはならない。
ユーザーの使用を意図したコマンド名では、何らかの単語がそのパッケージ名のプレフィクスの前にあると便利なことがある。関数や変数等を定義する構文は‘defun’や‘defvar’で始まればより良く機能するので、名前内でそれらの後に名前プレフィクスを置くこと。
この勧告はcopy-list
のようなEmacs
Lisp内のプリミティブではなく、伝統的なLispプリミティブにさえ適用される。信じようと信じまいとcopy-list
を定義する尤もらしい方法は複数あるのだ。安全第一である。かわりにfoo-copy-list
やmylib-copy-list
のような名前を生成するために、あなたの名前プレフィクスを追加しよう。
twiddle-files
のような特定の名前でEmacsに追加されるべきだと考えている関数を記述する場合には、プログラム内でそれを名前で呼び出さないこと。プログラム内ではそれをmylib-twiddle-files
で呼び出して、わたしたちがそれをEmacsに追加するため提案メールを、‘bug-gnu-emacs@gnu.org’に送信すること。もし追加することになったときに、わたしたちは十分容易にその名前を変更できるだろう。
1つのプレフィクスで十分でなければ、それらに意味があるかぎり、あなたのパッケージは2つか3つの一般的なプレフィクス候補を使用できる。
provide
呼出を配置すること。名前つき機能を参照のこと。
require
を使用すること。名前つき機能を参照のこと。
(eval-when-compile (require 'bar))
これはfooのバイトコンパイル直前にbarをロードするようEmacsに告げるので、そのマクロはコンパイル中は利用可能になる。eval-when-compile
の使用によりコンパイル済みバージョンのfooが中古ならbarのロードを避けられる。これはファイル内の最初のマクロ呼び出しの前に呼び出すこと。マクロとバイトコンパイルを参照のこと。
require
してこれを行うこと。しかしあなたのファイルがいくつかの独立した機能を含み、それらの1つか2つだけが余分なライブラリーを要するなら、トップレベルではなく関連する関数内部へのrequire
の配置を考慮すること。または必要時に余分のライブラリーをロードするためにautoload
ステートメントを使用すること。この方法ではあなたのファイルの該当部分を使用しない人は、余分なライブラリーをロードする必要がなくなる。
cl
ライブラリーではなく、cl-lib
ライブラリーを使うこと。cl
ライブラリーはクリーンなネームスペースを使用しない(定義が‘cl-’で始まらない)。パッケージが実行時にcl
をロードする場合には、そのパッケージを使用しないユーザーにたいして名前の衝突を起こすかもしれない。
(eval-when-compile (require
'cl))
でコンパイル時にcl
を使用するのは問題ない。コンパイラーはバイトコードを生成する前にマクロを展開するのでcl
内のマクロを使用するには十分である。ただしこの場合においても現代的なcl-lib
を使用するほうが良い。
framep
やframe-live-p
。
feature-unload-hook
という関数を定義すること。ここでfeatureはパッケージが提供する機能の名前であり、そのような変更をアンドゥするためのフックにする。そのファイルのアンロードにunload-feature
を使用することにより、この関数が実行されるようになる。アンロードを参照のこと。
(defalias 'gnus-point-at-bol (if (fboundp 'point-at-bol) 'point-at-bol 'line-beginning-position))
eval-after-load
とwith-eval-after-load
の使用を避けること(ロードのためのフックを参照)。この機能は個人的なカスタマイズを意図している。Lispプログラム内でこれを使用すると別のLisp内ではそれが見えず、その挙動を変更するために不明瞭になる。これは別のパッケージ内の関数へのadviseと同様にデバッグの障害になる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
mouse-1-click-follows-link
にしたがうようにfollow-link
条件もセットアップすること。クリック可能なテキストの定義を参照のこと。そのようなクリック可能リンクを実装する簡便な手法についてはボタンを参照のこと。
すべてのメジャーモードがこの慣習を尊重するよう変更するには多大な作業を要する。この慣習を捨て去ればそのような作業は不要になりユーザーは不便になるだろう。この慣習を遵守してほしい。
このルールの理由は任意のコンテキストにおける非プレフィクスであるようなESCのバインディングは、そのコンテキストにおいてファンクションキーとなるようなエスケープシーケンスの認識を阻害するからである。
通常のEmacsコマンドを受け入れる状態、より一般的には後にファンクションキーか矢印キーが続くESC内のような状態は潜在的な意味をもつのでESC ESCを定義してはならない。なぜならそれはESCの後のエスケープシーケンスの認識を阻害するからである。これらの状態においては、エスケープ手段としてESC ESC ESCを定義すること。それ以外ならかわりにESC ESCを定義すること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の慣習にしたがうことによりあなたのプログラムが実行時によりEmacsに適合するようになります。
next-line
やprevious-line
を使用してはならない。ほとんど常にforward-line
のほうがより簡便であり、より予測可能かつ堅牢である。テキスト行単位の移動を参照のこと。
特に以下の関数は使用しないこと:
beginning-of-buffer
、end-of-buffer
replace-string
、replace-regexp
insert-file
、insert-buffer
インタラクティブなユーザーを意図した別の機能がないのにポイントの移動、特定の文字列の置換、またはファイルやバッファーのコンテンツを挿入したいだけなら単純な1、2行のLispコードでそれらの関数を置き換えられる。
要素の挿入や削除がなく(これはリストだけで可能)、ある程度のサイズがあって、(先頭か末尾から検索しない)ランダムアクセスがあるテーブルではベクターが有利。
princ
ではなくmessage
関数。エコーエリアを参照のこと。
error
(またはsignal
)を呼び出すこと。関数error
はリターンしない。エラーをシグナルする方法を参照のこと。
エラーの報告にmessage
、throw
、sleep-for
、beep
を使用しないこと。
yes-or-no-p
かy-or-n-p
で答えを求める質問を行う場合には大文字で始めて‘?
’で終わること。
Enter the answer (default 42):
interactive
で引数リストを生成するLisp式を使用する場合には、リージョンやポジションの引数にたいして正しいデフォルト値を生成しようと試みではならない。それらの引数が指定されていなければかわりにnil
を提供して、引数がnil
のときに関数のbodyでデフォルト値を計算すること。たとえば以下のように記述する:
(defun foo (pos) (interactive (list (if specified specified-pos))) (unless pos (setq pos default-pos)) ...)
以下のようにはしない:
(defun foo (pos) (interactive (list (if specified specified-pos default-pos))) ...)
これはそのコマンドを繰り返す場合に、そのときの状況にもとづいてデフォルト値が再計算されるからである。
interactiveの‘d’、‘m’、‘r’指定を使用する際にはコマンドを繰り返すときの引数値の再計算にたいして特別な段取りを行うので、このような注意事項を採用する必要はない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はバイトコンパイル済みLispプログラムの実行速度を改善する方法です。
memq
、member
、assq
、assoc
は明示的な繰り返しより更に高速である。これらの検索プリミティブを使用できるようにデータ構造を再配置することにも価値が有り得る。
byte-compile
プロパティを調べればよい。そのプロパティが非nil
ならその関数は特別に扱われる。
たとえば以下を入力するとaref
が特別にコンパイルされえることが示される(配列を操作する関数を参照):
(get 'aref 'byte-compile) ⇒ byte-compile-two-args
この場合(および他の多くの場合)には、最初にbyte-compile
プロパティを定義するbytecompライブラリーをロードしなければならない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
defvar
定義を追加して未定義のフリー変数に関するコンパイラーの警告の回避を試みる:
(defvar foo)
このような定義はファイル内での変数foo
の使用にたいしてコンパイラーが警告しないようにする以外に影響はない。
declare-function
ステートメントを使用して、定義されるこが既知な未定義関数に関するコンパイラーの警告の回避を試みる(コンパイラーへの定義済み関数の指示を参照)。
require
を追加できる。たとえば、
(eval-when-compile (require 'foo))
with-no-warnings
の内側に置くこと。コンパイラーのエラーを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はドキュメント文字列記述に関するいくつかのヒントと慣習です。コマンドM-x checkdoc-minor-modeを実行すれば慣習の多くをチェックできます。
apropos
の出力で見栄えが悪くなる。
見栄えがよくなるならそのテキストをフィルできる。Emacs
Lispモードはemacs-lisp-docstring-fill-column
で指定された幅にドキュメント文字列をフィルする。しかしドキュメント文字列の行ブレークを注意深く調整すればドキュメント文字列の可読性をより向上できることがある。ドキュメント文字列が長い場合にはセクション間に空行を使用すること。
関数では最初の行は“その関数は何を行うのか?”、変数にたいしては最初の行は“その値は何を意味するのか?”という問いに簡略に答えること。
ドキュメント文字列を1行に制限しないこと。その関数や変数の使用法の詳細を説明する必要に応じてその分の行数を使用すること。テキストの残りの部分にたいしても完全なセンテンスを使用してほしい。
eval
のドキュメント文字列では最初の引数の名前がform
なので‘FORM’で参照する:
Evaluate FORM and return its value.
同様にリストやベクターのサブユニットへの分解で、それらのいくつかを異なるように示すような際にはメタ構文変数(metasyntactic variables)を大文字で記述すること。以下の例の‘KEY’と‘VALUE’はこれの実践例:
The argument TABLE should be an alist whose elements have the form (KEY . VALUE). Here, KEY is ...
foo
なら“Foo”ではなく“foo”(“Foo”は違うシンボル)。
これは関数の引数の値の記述ポリシーと反するように見えるかもしれないが矛盾は実際には存在しない。引数のvalueはその関数が値の保持に使用するsymbolと同じではない。
これによりセンテンス先頭に小文字を置くことになり、それが煩しいならセンテンス開始がシンボルにならないようにセンテンスを書き換えること。
t
とnil
は区切り文字で括らない。たとえば‘CODE
can be ‘lambda’, nil, or t’。curved single quotesの入力方法はQuotation
Marks in The GNU Emacs Manualを参照のこと。
ドキュメント文字列には‘like-this’ではなく`like-this'のようにgrave accent `とapostrophe 'というクォートシンボルによる旧いシングルクォーテーションの慣習も使用できる。この旧い慣習はgrave accentとapostropheがミラーイメージであるような、現在では時代遅れとなったディスプレイ用にデザインされている。
いずれかの慣習を使用するドキュメントは、ヘルプバッファーにコピーされる際にはユーザーの好みに応じてフォーマットされる。ドキュメント内でのキーバインディングの置き換えを参照のこと。
Helpモードはシングルクォートされたシンボル名がドキュメント文字列で使用されている際には、それが関数と変数のいずれかの定義をもっていれば自動的にハイパーリンクを作成する。これらの機能を使用するために何か特別なことを行う必要はない。しかしあるシンボルが関数と変数の両方の定義をもち一方だけを参照したい場合には、そのシンボル名の直前に‘variable’、‘option’、‘function’、‘command’の単語のいずれかを記述してそれを指定できる(これらの指示語の識別では大文字小文字に差はない)。たとえば以下を記述すると
This function sets the variable `buffer-file-name'.
これのハイパーリンクはbuffer-file-name
の変数のドキュメントだけを参照して関数のドキュメントは参照しない。
あるシンボルが関数および/または変数の定義をもつがドキュメントしているシンボルの使用とそれらが無関係なら、すべてのハイパーリンク作成を防ぐためにシンボル名の前に単語‘symbol’か‘program’を記述できる。たとえば、
If the argument KIND-OF-RESULT is the symbol `list', this function returns a list of all the objects that satisfy the criterion.
これは無関係な関数list
のドキュメントにハイパーリンクを作成しない。
変数ドキュメントがない変数には、通常はハイパーリンクは作成されない。そのような変数の前に単語‘variable’と‘option’のいずれかを記述すればハイパーリンクの作成を強制できる。
フェイスにたいするハイパーリンクはフェイスの前か後に単語‘face’があれば作成される。この場合にはたとえそのシンボルが変数や関数として定義されていてもフェイスのドキュメントだけが表示される。
Infoドキュメントにハイパーリンクを作成するには、‘info node’、‘Info node’、‘info anchor’、‘Info anchor’のいずれかの後Infoのノード(かアンカー)をシングルクォートして記述する。Infoファイル名のデフォルトは‘emacs’。たとえば、
See Info node `Font Lock' and Info node `(elisp)Font Lock Basics'.
最後にURLのハイパーリンクを作成するには‘URL’の後にURLをシングルクォートして記述する。たとえば、
The home page for the GNU project has more information (see URL `http://www.gnu.org/').
forward-char
にバインドされたキーに置き換える(これは通常は‘C-f’だがユーザーがキーバインディングを変更していれば何か他の文字かもしれない)。ドキュメント内でのキーバインディングの置き換えを参照のこと。
ドキュメント文字列の表示が低速になるので非常に多数回の‘\\[…]’の使用は実用的ではない。メジャーモードのもっとも重要なコマンドの記述にこれを使用して、そのモードの残りのキーマップの表示には‘\\{…}’を使用する。
The argument FOO can be either a number \(a buffer position) or a string (a file name).
これはその開カッコがdefunの開始として扱われることを防ぐ(Defuns in The GNU Emacs Manualを参照)。
dired-find-file
のドキュメントは:
In Dired, visit the file or directory named on this line.
defcustom
を使用すること。グローバル変数の定義を参照のこと。
nil
値が等価であることを明確にして、nil
と非nil
が何を意味するかを明示的に示すために“Non-nil
means”のような単語で始めること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コメントにたいして以下の慣習を推奨します:
1つのセミコロン‘;’で始まるコメントはソースコードの右側の同じ列にすべて揃えられる。そのようなコメントは通常はその行のコードがどのように処理を行うかを説明する。たとえば:
(setq base-version-list ; There was a base (assoc (substring fn 0 start-vn) ; version to which file-version-assoc-list)) ; this looks like ; a subversion.
2つのセミコロン‘;;’で始まるコメントはコードと同じインデントレベルで揃えられる。そのようなコメントは通常はその後の行の目的や、その箇所でのプログラムの状態を説明する。たとえば:
(prog1 (setq auto-fill-function … … ;; Update mode line. (force-mode-line-update)))
わたしたちは通常は関数の外側のコメントにも2つのセミコロンを使用する。
;; This Lisp code is run in Emacs when it is to operate as ;; a server for other processes.
関数がドキュメント文字列をもたなければ、かわりにその関数の直前にその関数が何を行うかと、正しく呼び出す方法を説明する2つのセミコロンのコメントをもつこと。各引数の意味と引数で可能な値をその関数が解釈する方法を正確に説明すること。しかしそのようなコメントはドキュメント文字列に変換するほうがはるかに優れている。
3つのセミコロン‘;;;’デ始まるコメントは左マージンから始まる。わたしたちはOutlineマイナーモードのheading(ヘッダー)とみなされるべきコメントにそれらを使用している。デフォルトでは少なくとも(後に1つの空白文字と非空白文字が続く)3つのセミコロンはheadingとみなして、2つ以下のセミコロンで始まるものはheadingとみなさない。歴史的に3つのセミコロンのコメントは関数内での行のコメントアウトに使用されてきたがこの使用は推奨しない。
関数全体をコメントアウトするときは2つのセミコロンを使用する。
4つのセミコロン‘;;;;’で始まるコメントは左マージンに揃えられプログラムのメジャーセクションのheadingに使用される。たとえば:
;;;; The kill ring
一般的に言うとコマンドM-;
(comment-dwim
)は適切なタイプのコメントを自動的に開始するか、セミコロンの数に応じて既存のコメントを正しい位置にインデントします。Manipulating Comments in The GNU Emacs Manualを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsにはセクションに分割してそれの記述者のような情報を与えるために、Lispライブラリー内で特別なコメントを使用する慣習があります。それらのアイテムにたいして標準的なフォーマットを使用すれば、ツール(や人)が関連する情報を抽出するのが簡単になります。このセクションでは以下の例を出発点にこれらの慣習を説明します。
;;; foo.el --- Support for the Foo programming language ;; Copyright (C) 2010-2016 Your Name
;; Author: Your Name <yourname@example.com> ;; Maintainer: Someone Else <someone@example.com> ;; Created: 14 Jul 2010
;; Keywords: languages ;; Homepage: http://example.com/foo ;; This file is not part of GNU Emacs. ;; This file is free software… … ;; along with this file. If not, see <http://www.gnu.org/licenses/>.
一番最初の行は以下のフォーマットをもつべきです:
;;; filename --- description
この説明は1行に収まる必要があります。そのファイルに‘-*-’指定が必要ならdescriptionの後に配置してください。これにより最初の行が長くなりすぎるようなら、そのファイル終端でLocal Variablesセクションを使用してください。
著作権表示には、(あなたがそのファイルを記述したなら)通常はあなたの名前をリストします。あなたの作業の著作権を主張する雇用者がいる場合には、かわりに彼らをリストする必要があるかもしれません。Emacsディストリビューションにあなたのファイルが受け入れられていなければ、著作権者がFree Software Foundation(またはそのファイルがGNU Emacsの一部)だと告げないでください。著作権とライセンス通知の形式に関するより詳細な情報はthe guide on the GNU websiteを参照してください。
著作権表示の後は、それぞれが‘;; header-name:’で始まる複数のヘッダーコメント(header comment)を記述します。以下は慣習的に利用できるheader-nameのテーブルです:
この行は少なくともそのライブラリーの主要な作者の名前とemailアドレスを示す。複数の作者がいる場合には前に;;
とタブか少なくとも2つのスペースがある継続行で彼らをリストする。わたしたちは‘<…>’という形式で連絡用emailアドレスを含めることを推奨する。たとえば:
;; Author: Your Name <yourname@example.com> ;; Someone Else <someone@example.com> ;; Another Person <another@example.com>
このヘッダーはAuthorヘッダーと同じフォーマット。これは現在そのファイルを保守(バグレポートへの応答等)をする人(か人々)をリストする。
Maintainerの行がなければAuthorフィールドの人(人々)がMaintainerとみなされる。Emacs内のいくつかのファイルはMaintainerに‘FSF’を使用している。これはファイルにたいしてオリジナル作者がもはや責任をもっておらずEmacsの一部として保守されていることを意味する。
このオプションの行はファイルのオリジナルの作成日付を与えるもので歴史的な興味のためだけに存在する。
個々のLispプログラムにたいしてバージョン番号を記録したいならこの行に配置する。Emacsとともに配布されたLispファイルはEmacsのバージョン番号自体が同じ役割を果たすので一般的には‘Version’ヘッダーをもたない。複数ファイルのコレクションを配布する場合には、各ファイルではなく主となるファイルにバージョンを記述することを推奨する。
この行はヘルプコマンドfinder-by-keyword
にたいするキーワードをリストする。意味のあるキーワードのリストを確認するためにこのコマンドを使用してほしい。コマンドM-x
checkdoc-package-keywords
RETはfinder-known-keywords
にないすべてのキーワードを探して表示する。変数checkdoc-package-keywords-flag
に非nil
をセットするとcheckdocコマンドはチェックにキーワード検証を含める。
このフィールドはトピックでパッケージを探す人が、あなたのパッケージを見つける手段となる。キーワードを分割するにはスペースとカンマの両方を使用できる。
人はしばしばこのフィールドを単にFinder(訳注:
finder-by-keyword
がオープンするバッファー)に関連したキーワードではなくパッケージを説明する任意のキーワードを記述する箇所だとみなすのは不運なことだ。
この行はライブラリーのホームページを示す。
‘Version’がパッケージマネージャーによる使用に適切でなければ、パッケージは‘Package-Version’を定義でき、かわりにこれが使用される。これは‘Version’がRCSやversion-to-list
でパース不能な何かであるようなら手軽である。パッケージ化の基礎を参照のこと。
これが存在する場合にはカレントパッケージが正しく動作するために依存するパッケージを示す。パッケージ化の基礎を参照のこと。これは(パッケージの完全なセットがダウンロードされることを確実にするために)ダウンロード時と、(すべての依存パッケージがあるときだけパッケージがアクティブになることを確実にするために)アクティブ化の両方でパッケージマネージャーにより使用される。
これのフォーマットはリストのリスト。サブリストそれぞれのcar
はパッケージの名前(シンボル)、cadr
は許容できる最小のバージョン番号(文字列)。たとえば:
;; Package-Requires: ((gnus "1.0") (bubbles "2.7.2"))
パッケージのコードは自動的に、実行中のEmacsのカレントのバージョン番号をもつ‘emacs’という名前のパッケージを定義する。これはパッケージが要求するEmacsの最小のバージョンに使用できる。
ほぼすべてのLispライブラリーは‘Author’と‘Keywords’のヘッダーコメント行をもつべきです。適切なら他のものを使用してください。ヘッダー行内で別のヘッダー行の名前も使用できます。これらは標準的な意味をもたないので害になることを行うことはできません。
わたしたちはライブラリーファイルのコンテンツを分割するために追加の提携コメントを使用します。これらは空行で他のものと分離されている必要があります。以下はそれらのテーブルです:
これはライブラリーが機能する方法を説明する、概論コメントを開始する。これは複製許諾の直後にあり‘Change Log’、‘History’、‘Code’のコメント行で終端されていること。このテキストはFinderパッケージで使用されるのでそのコンテキスト内で有意であること。
これは時間とともにそのファイルに加えられたオプションの変更ログを開始する。このセクションに過剰な情報を配置してはならない。(Emacsが行うように)バージョンコントロールシステムの詳細ログや個別のChangeLogファイルに留めるほうがよい。‘History’は‘Change Log’の代替え。
これはプログラムの実際のコードを開始する。
これはフッター行(footer line)。これはそのファイルの終端にある。これの目的はフッター行の欠落から、人がファイルの切り詰められたバージョンを検知することを可能にする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このチャプターでは実行可能なEmacs実行可能形式を事前ロードされたLispライブラリーとともにダンプする方法、ストレージが割り当てられる方法、およびCプログラマーが興味をもつかもしれないGNU Emacsの内部的な側面のいくつかを説明します。
E.1 Emacsのビルド | ダンプ済みEmacsの作成方法。 | |
E.2 純粋ストレージ | その場かぎりの事前ロードされたLisp関数を共有する。 | |
E.3 ガーベージコレクション | Lispオブジェクトの使用されないスペースの回収。 | |
E.4 Stack-allocated Objects | Cスタック上の一時的なコンスと文字列。 | |
E.5 メモリー使用量 | これまでに作成されたLispオブジェクトの総サイズの情報。 | |
E.6 C方言 | Emacsを記述するC系言語は何か。 | |
E.7 Emacsプリミティブの記述 | Emacs用にCコードを記述する。 | |
E.8 オブジェクトの内部 | バッファー、ウィンドウ、プロセスのデータフォーマット。 | |
E.9 Cの整数型 | Emacs内部でCの整数型が使用される方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではEmacs実行可能形式のビルドに関するステップの説明をします。makefileがこれらすべてを自動的に行うので、Emacsをビルドやインストールをするためにこの題材を知る必要はありません。この情報はEmacs開発者に適しています。
EmacsのビルドにはGNU Makeのバージョン3.81以降が必要です。
srcディレクトリー内のCソースファイルをコンパイルすることにより、temacsと呼ばれる実行可能形式ファイルが生成されます。これはbare impure Emacs(裸で不純なEmacs)とも呼ばれます。これにはEmacs LispインタープリターとI/Oルーチンが含まれますが編集コマンドは含まれません。
コマンドtemacs -l loadup
はtemacsを実行してloadup.elをロードするように計らいます。loadup
ライブラリーは通常のEmacs編集環境をセットアップする追加のLispライブラリーをロードします。このステップの後にはEmacs実行可能形式はbare(裸)ではなくなります。
標準的なLispファイルのロードには若干の時間を要するので、ユーザーが直接temacs実行可能形式を実行することは通常はありません。そのかわり、Emacsビルドの最終ステップとしてコマンド‘temacs
-batch -l loadup
dump’が実行されます。特別な引数‘dump’によりtemacs
はemacsと呼ばれる実行可能形式のプログラムにダンプされます。これには標準的なLispファイルがすべて事前ロードされています(引数‘-batch’はtemacsがその端末上でデータの初期化を試みることを防げるので端末情報のテーブルはダンプされたEmacsでは空になる)。
ダンプされたemacs実行可能形式(純粋なEmacsとも呼ばれる)がインストールされるEmacsになります。変数preloaded-file-list
にはダンプ済みEmacsに事前ロードされるLispファイルのリストが格納されています。新たなオペレーティングシステムにEmacsをポートする際に、そのOSがダンプを実装していなければEmacsは起動時に毎回loadup.elをロードしなければなりません。
site-load.elという名前のライブラリーを記述することにより、事前ロードするファイルを追加指定できます。追加するファイルを保持するために純粋(pure)なスペースnバイトを追加するように、以下の定義
#define SITELOAD_PURESIZE_EXTRA n
でEmacsをリビルドする必要があるでしょう。src/puresize.hを参考にしてください(十分大きくなるまで20000ずつ増加させる)。しかし追加ファイルの事前ロードの優位はマシンの高速化により減少します。現代的なマシンでは通常はお勧めしません。
loadup.elがsite-load.elを読み込んだ後にSnarf-documentation
を呼び出すことにより、それらが格納された場所のファイルetc/DOC内にあるプリミティブと事前ロードされる関数(と変数)のドキュメント文字列を探します(Accessing Documentationを参照)。
site-init.elという名前のライブラリー名に配置することにより、ダンプ直前に実行する他のLisp式を指定できます。このファイルはドキュメント文字列を見つけた後に実行されます。
関数や変数の定義を事前ロードしたい場合には、それを行うために3つの方法があります。それらにより定義ロードしてその後のEmacs実行時にドキュメント文字列をアクセス可能にします:
byte-compile-dynamic-docstrings
にnil
値を指定してsite-load.elかsite-init.elでロードする(この手法にはEmacsが毎回そのドキュメント文字列用のスペースを確保するという欠点がある)。
通常の未変更のEmacsでユーザーが期待する何らかの機能を変更するような何かをsite-load.elやsite-init.el内に配置することはお勧めしません。あなたのサイトで通常の機能をオーバーライドしなければならないと感じた場合には、default.elでそれを行えばユーザーが望む場合にあなたの変更をオーバーライドできます。要約: スタートアップ時のアクション順序を参照してください。site-load.elかsite-init.elのいずれかがload-path
を変更する場合には変更はダンプ後に失われます。ライブラリー検索を参照してください。load-path
を永続的に変更するにはconfigure
の--enable-locallisppathオプションを指定してください。
事前ロード可能なパッケージでは、その後のEmacsスタートアップまで特定の評価の遅延が必要(または便利)なことがあります。そのようなケースの大半はカスタマイズ可能な変数の値に関するものです。たとえばtutorial-directory
は事前ロードされるstartup.el内で定義される変数です。これのデフォルト値はdata-directory
にもとづいてセットされます。この変数はEmacsダンプ時ではなくスタート時にdata-directory
の値を必要とします。なぜならEmacs実行可能形式はダンプされたものなので、恐らく異なる場所にインストールされるからです。
この関数は次回のEmacs開始までsymbolの初期化を遅延する。通常はカスタマイズ可能変数の:initialize
プロパティとしてこの関数を指定することにより使用する(引数valueはフォームCustom由来の互換性のためだけに提供されており使用しない)。
custom-initialize-delay
が提供するより一般的な機能を要する稀なケースではbefore-init-hook
を使用できます(要約: スタートアップ時のアクション順序を参照)。
この関数はEmacsのカレント状態を実行可能ファイルto-fileにダンプする。これはfrom-file (通常はファイルtemacs)からシンボルを取得する。
すでにダンプ済みのEmacs内でこの関数を使用する場合には‘-batch’でEmacsを実行しなければならない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispはユーザー作成Lispオブジェクトにたいして、通常ストレージ(normal storage)と純粋ストレージ(pure storage)という2種のストレージをもちます。通常ストレージはEmacsセッションが維持される間に新たにデータが作成される場所です。純粋ストレージは事前ロードされた標準Lispファイル内の特定のデータのために使用されます。このデータは実際のEmacs使用中に決して変更されるべきではないデータです。
純粋ストレージはtemacs
が標準的な事前ローLispライブラリーのロード中にのみ割り当てられます。ファイルemacsではこのメモリースペースは読み取り専用とマークされるのでマシン上で実行中のすべてのEmacsジョブで共有できます。純粋ストレージは拡張できません。Emacsのコンパイル時に固定された量が割り当てられて、それが事前ロードされるライブラリーにたいして不足ならtemacsはそれに収まらない部分を動的メモリーに割り当てます。結果イメージは動作するでしょうがこの状況ではメモリーリークとなるのでガーベージコレクション(ガーベージコレクションを参照)は無効です。そのような通常なら発生しないオーバーフローは、あなたが事前ロードライブラリの追加や標準的な事前ロードライブラリに追加を試みないかぎり発生しません。Emacsはオーバーロードの開始時にオーバーロードに関する警告を表示するでしょう。これが発生したらファイルsrc/puresize.h内のコンパイルパラメーターをSYSTEM_PURESIZE_EXTRA
を増やしてEmacsをリビルドする必要があります。
この関数は純粋ストレージにobjectのコピーを作成してリターンする。これは同じ文字で新たに文字列を作成することにより文字列をコピーするが、純粋ストレージではテキストプロパティはない。これはベクターとコンスセルのコンテンツを再帰的にコピーする。シンボルのような他のオブジェクトのコピーは作成しないが未変更でリターンする。マーカーのコピーを試みるとエラーをシグナルする。
この関数はEmacsのビルド中とダンプ中を除き何もしない。通常は事前ロードされるLispファイル内でのみ呼び出される。
この変数の値は、これまでに割り当てられた純粋ストレージのバイト数。ダンプされたEmacsでは通常は利用可能な純粋ストレージの総量とほとんど同じであり、もしそうでないならわたしたちは事前割り当てをもっと少なくするだろう。
この変数はdefun
が純粋ストレージにその関数定義のコピーを作成するべきか否かを判断する。これが非nil
ならその関数の定義は純粋ストレージにコピーされる。
このフラグはEmacsのビルド用の基本的な関数の初回ロード中はt
となる。実行可能形式としてEmacsをダンプすることにより、ダンプ前後の実際の値とは無関係に常にこの変数にnil
が書き込まれる。
実行中のEmacsでこのフラグを変更しないこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プログラムがリストを作成するときや、(ライブライのロード等により)ユーザーが新しい関数を定義する際には、そのデータは通常ストレージに配置されます。通常ストレージが少なくなるとEmacsはもっとメモリーを割り当てるようにオペレーティングシステムに要求します。シンボル、コンスセル、小さいベクター、マーカー等のような別のタイプのLispオブジェクトはメモリー内の個別のブロックに隔離されます(大きいベクター、長い文字列、バッファー、および他の特定の編集タイプは非常に巨大であり1つのオブジェクトにたいして個別のブロックが割り当てられて、小さな文字列は8kバイトのブロック、小さいベクターは4kバイトのブロックにパックされる)。
基本的なベクターではないウィンドウ、バッファー、フレームがあたかもベクターであるかのように管理されています。対応するCデータ構造体にはstruct
vectorlike_header
フィールドが含まれていて、そのメンバーsize
にはenum
pvec_type
で列挙されたサブタイプ、その構造体が含むLisp_Object
フィールドの数に関する情報、および残りのデータのサイズが含まれます。この情報はオブジェクトのメモリーフットプリントの計算に必要であり、ベクターブロックの繰り返し処理の際のベクター割り当てコードにより使用されます。
しばらくの間いくつかのストレージを使用して、(たとえば)バッファーのkillやあるオブジェクトを指す最後のポインターの削除によりそれを解放するのは非常に一般的です。この放棄されたストレージを再利用するためにEmacsはガーベージコレクター(garbage collector)を提供します。ガーベージコレクターは、いまだLispプログラムからアクセス可能なすべてのLispオブジェクトを検索、マークすることにより動作します。これを開始するにはすべてのシンボル、それらの値と関連付けられている関数定義、現在スタック上にあるすべてのデータをアクセス可能であると仮定します。別のアクセス可能オブジェクトを介して間接的に到達できるすべてのオブジェクトもアクセス可能とみなされます。
マーキングが終了してもマークされないオブジェクトはすべてガーベージ(garbage: ごみ)です。Lispプログラムかユーザーの行為かに関わらず、それらに到達する手段はもはや存在しないので参照することは不可能です。誰もそれを失うことはないので、それらのスペースは再利用されることになります。ガーベージコレクターの2つ目ののフェーズ(sweep: スイープ、一掃)ではそれらの再利用を計らいます。
スイープフェーズは将来の割り当て用に、シンボルやマーカーと同様に未使用のコンスセルをフリーリスト(free list)上に配置します。これはアクセス可能な文字列は少数の8kブロックを占有するように圧縮して、その後に他の8kブロックを解放します。ベクターブロックから到達不可能はベクターは可能なかぎり最大のフリーエリアを作成するために統合して、フリーエリアが完全な4kブロックに跨がるようならブロックは解放されます。それ以外ならフリーエリアはフリーリスト配列に記録されます。これは各エントリーが同サイズのエリアのフリーリストに対応します。巨大なベクター、バッファー、その他の巨大なオブジェクトは個別に割り当てと解放が行われます。
Common Lispに関する注意: 他のLispと異なりGNU Emacs Lispはフリーリストが空のときにガーベージコレクターを呼び出さない。かわりに単にオペレーティングシステムに更なるストレージの割り当てを要求して、
gc-cons-threshold
バイトを使い切るまで処理を継続する。これは特定のLispプログラムの範囲の実行直前に明示的にガーベージコレクターを呼び出せば、その範囲の実行中はガーベージコレクターが実行されないだろうと確信できることを意味する(そのプログラム範囲が2回目のガーベージコレクションを強制するほど多くのスペースを使用しないという前提)。
このコマンドはガーベージコレクションを実行して使用中のスペース量の情報をリターンする(前回のガーベージコレクション以降にgc-cons-threshold
バイトより多いLispデータを使用した場合には自然にガーベージコレクションが発生することもあり得る)。
garbage-collect
は使用中のスペース量の情報をリストでリターンする。これの各エントリーは‘(name
size
used)’という形式をもつ。このエントリーでnameはそのエントリーが対応するオブジェクトの種類を記述するシンボル、sizeはそれが使用するバイト数、usedはヒープ内で生きていることが解ったオブジェクトの数、オプションのfreeは生きていないがEmacsが将来の割り当て用に保持しているオブジェクトの数。全体的な結果は以下のようになる:
((conses
cons-size used-conses free-conses) (symbols
symbol-size used-symbols free-symbols) (miscs
misc-size used-miscs free-miscs) (strings
string-size used-strings free-strings) (string-bytes
byte-size used-bytes) (vectors
vector-size used-vectors) (vector-slots
slot-size used-slots free-slots) (floats
float-size used-floats free-floats) (intervals
interval-size used-intervals free-intervals) (buffers
buffer-size used-buffers) (heap
unit-size total-size free-size))
以下は例:
(garbage-collect) ⇒ ((conses 16 49126 8058) (symbols 48 14607 0) (miscs 40 34 56) (strings 32 2942 2607) (string-bytes 1 78607) (vectors 16 7247) (vector-slots 8 341609 29474) (floats 8 71 102) (intervals 56 27 26) (buffers 944 8) (heap 1024 11715 2678))
以下は各要素を説明するためのテーブル。最後のheap
エントリーはオプションであり、背景にあるmalloc
実装がmallinfo
関数を提供する場合のみ与えられることに注意。
コンスセルの内部的サイズ(sizeof (struct Lisp_Cons)
)。
使用中のコンスセルの数。
オペレーティングシステムから取得したスペースにあるがカレントで未使用のコンスセルの数。
シンボルの内部的サイズ(sizeof (struct Lisp_Symbol)
)。
使用中のシンボルの数。
オペレーティングシステムから取得したスペースにあるがカレントで未使用のシンボルの数。
雑多なエンティティーの内部的なサイズ。sizeof (union Lisp_Misc)
はenum
Lisp_Misc_Type
に列挙された最大タイプのサイズ。
使用中の雑多なエンティティーの数。これらのエンティティーにはマーカー、オーバーレイに加えて、ユーザーにとって不可視な特定のオブジェクトが含まれる。
オペレーティングシステムから取得したスペースにあるがカレントで未使用の雑多なオブジェクトの数。
文字列ヘッダーの内部的サイズ(sizeof (struct Lisp_String)
)。
使用中の文字列ヘッダーの数。
オペレーティングシステムから取得したスペースにあるがカレントで未使用の文字列ヘッダーの数。
これは利便性のために使用されるものでsizeof (char)
と同じ。
すべての文字列データの総バイト数。
ベクターヘッダーの内部的サイズ(sizeof (struct Lisp_Vector)
)。
ベクターブロックから割り当てられたベクターブロック数。
ベクタースロットの内部的なサイズで常にsizeof (Lisp_Object)
と等しい。
使用されているすべてのベクターのスロット数。
すべてのベクターブロックのフリースロットの数。
浮動小数点数オブジェクトの内部的なサイズ(sizeof (struct
Lisp_Float)
)。(ネイティブプラットフォームのfloat
やdouble
と混同しないこと。)
使用中の浮動小数点数の数。
オペレーティングシステムから取得したスペースにあるがカレントで未使用の浮動小数点数の数。
インターバルオブジェクト(interval object)の内部的なサイズ(sizeof (struct interval)
)。
使用中のインターバルの数。
オペレーティングシステムから取得したスペースにあるがカレントで未使用のインターバルの数。
バッファーの内部的なサイズ(sizeof (struct
buffer)
)。(buffer-size
関数がリターンする値と混同しないこと。)
使用中のバッファーオブジェクトの数。これにはユーザーからは不可視のkillされたバッファー、つまりリストall_buffers
内のバッファーすべてが含まれる。
ヒープスペースを計る単位であり常に1024バイトと等しい。
unit-size単位での総ヒープサイズ。
unit-size単位でのカレントで未使用のヒープスペース。
純粋スペース(純粋ストレージを参照)内にオーバーフローがあれば実際にガーベージコレクションを行うことは不可能なのでgarbage-collect
はnil
をリターンする。
この変数が非nil
ならEmacsはガーベージコレクションの最初と最後にメッセージを表示する。デフォルト値はnil
。
これはガーベージコレクションの終わりに実行されるノーマルフック。ガーベージコレクションはこのフックの関数の実行中は抑制されるので慎重に記述すること。
この変数の値は別のガーベージコレクションをトリガーするために、ガーベージコレクション後にLispオブジェクト用に割り当てなければならないストレージのバイト数。特定のオブジェクトタイプに関する情報を取得するために、garbage-collect
がリターンした結果を使用できる。バッファーのコンテンツに割り当てられたスペースは勘定に入らない。後続のガーベージコレクションはこのthreshold(閾値)が消費されても即座には実行されず、次回にLispインタープリターが呼び出されたときにのみ実行されることに注意。
thresholdの初期値はGC_DEFAULT_THRESHOLD
であり、これはalloc.c内で定義されている。これはword_size
単位で定義されているので、デフォルトの32ビット設定では400,000、64ビット設定では800,000になる。大きい値を指定するとガーベージコレクションの頻度が下る。これはガーベージコレクションにより費やされる時間を減少させるがメモリーの総使用量は増大する。大量のLispデータを作成するプログラムの実行時にはこれを行いたいと思うかもしれない。
GC_DEFAULT_THRESHOLD
の1/10まで下げた小さな値を指定することにより、より頻繁にガーベージコレクションを発生させることができる。この最小値より小さい値は後続のガーベージコレクションで、garbage-collect
がthresholdを最小値に戻すときまでしか効果をもたないだろう。
この変数の値はガーベージコレクション発生するまでのコンス(訳注:
これはgc-cons-threshold
やgc-cons-percentage
の‘-cons-’のことで、これらの変数が定義されているalloc.c内ではLisp方言での‘cons’をより一般化したメモリー割り当てプロセスのことを指す模様)の量をカレントヒープサイズにたいする割り合いで指定する。この条件とgc-cons-threshold
を並行して適用して、条件が両方満足されたときだけガーベージコレクションが発生する。
ヒープサイズ増加にともないガーベージコレクションの処理時間は増大する。したがってガーベージコレクションの頻度割合を減らすのが望ましいことがある。
garbage-collect
がリターンする値はデータ型に分類されたLispデータのメモリー使用量を記述します。それとは対照的に関数memory-limit
はEmacsがカレントで使用中の総メモリー量の情報を提供します。
この関数はEmacsが割り当てたメモリーの最後のバイトアドレスを1024で除した値をリターンする。値を1024で除しているのはLisp整数に収まるようにするため。
あなたのアクションがメモリー使用に与える影響について大まかなアイデアを得るためにこれを使用することができる。
この変数はLispオブジェクト用のメモリーが不足に近い状態ならt
、それ以外ならnil
。
これはそのEmacsセッションで作成されたオブジェクト数をカウントしたリスト。これらのカウンターはそれぞれ特定の種類のオブジェクトを数える。詳細はドキュメント文字列を参照のこと。
この関数はシステムメモリーのトータル量とフリーな量をリターンする。サポートされないシステムでは値はnil
かもしれない。
この変数はそのEmacsセッションでそれまでに行われたガーベージコレクションの合計回数。
この変数はそのEmacsセッションでガーベージコレクションの間に費やされた経過時間を浮動小数点数で表した総秒数。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
上述のガーベージコレクターはLispプログラムから可視なデータ、同様にLispインタープリターが内部的に使用するほとんどのデータの管理に使用されます。インタプリターのCスタックを使用して一時的に内部オブジェクトを割り当てることが有用なときがあります。割り当てとガーベージコレクターによる解放は、ヒープメモリーよりスタック割り当てを使用するほうが通常は高速なので、これはパフォーマンスの改善の助けになります。これには解放後にそのようなオブジェクトを使用することにより未定義の挙動を引き起こすという欠点があるので、使用においては熟考するとともにGC_CHECK_MARKED_OBJECTS
機能(src/alloc.cを参照)を使用して慎重にデバッグするべきです。特にスタックに割り当てられたオブジェクトはユーザーのLispコードからは決して可視にならないようにする必要があります。
現在のことろコンスセルと文字列をこの方法で割り当てできます。これはblock寿命をもつ名前つきLisp_Object
を定義するAUTO_CONS
やAUTO_STRING
のようなCマクロで実装されています。これらのオブジェクトはガーベージコレクターでは解放されません。かわりにこれらは自動記憶期間(automatic
storage
duration)をもちます。つまりそれらはすべてローカル変数のように割り当てられて、そのオブジェクトを定義するCブロックの実行の最後に自動的に解放されます。
性能的な理由によりスタックに割り当てられる文字列はASCII文字に限定されており、それらの多くが不変です。つまりそれらにたいしてASET
を呼び出すと未定義の挙動を引き起こします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数と変数はEmacsが行なったメモリー割り当ての総量に関する情報をデータ型ごとに分類して提供します。これらの関数や変数とgarbage-collect
がリターンする値との違いに注意してください。garbage-collect
はカレントで存在するオブジェクトを計数しますが、以下の関数や変数はすでに解放されたオブジェクトを含めて割り当てのすべての数やサイズを計数します。
そのEmacsセッションでそれまでに割り当てられたコンスセルの総数。
そのEmacsセッションでそれまでに割り当てられた浮動小数点数の総数。
そのEmacsセッションでそれまでに割り当てられたベクターセル
そのEmacsセッションでそれまでに割り当てられたシンボルの総数。
そのEmacsセッションでそれまでに割り当てられた文字列の文字の総数。
そのEmacsセッションでそれまでに割り当てられた雑多なオブジェクトの総数。これにはマーカー、オーバーレイに加えてユーザーには不可視な特定のオブジェクトが含まれる。
そのEmacsセッションでそれまでに割り当てられたインターバルの総数。
そのEmacsセッションでそれまでに割り当てられた文字列の総数。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
EmacsのC部分はC99にたいして可搬性があります。‘<stdalign.h>’や‘_Noreturn’のようなC11固有の機能は通常はconfigure時に行われるチェックなしでは使用しておらず、Emacsのビルド手順は必要なら代替えの実装を提供します。無名な構造体や共用体のようないくつかのC11機能はエミュレートが非常に困難なので完全に無視しています。
そう遠くない将来のある時点で基本となるC方言は間違いなくC11に変更されるでしょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
LispプリミティブとはCで実装されたLisp関数です。Lispから呼び出せるようにC関数インターフェースの詳細はCのマクロで処理されます。新たなCコードの記述のしかたを真に理解するにはソースを読むのが唯一の方法ですが、ここではいくつかの事項について説明します。
スペシャルフォームの例として以下はeval.cのor
です(通常の関数は同様の一般的な外観をもつ)。
DEFUN ("or", For, Sor, 0, UNEVALLED, 0, doc: /* Eval args until one of them yields non-nil, then return that value. The remaining args are not evalled at all. If all args return nil, return nil.
usage: (or CONDITIONS...) */) (Lisp_Object args) { Lisp_Object val = Qnil;
while (CONSP (args)) { val = eval_sub (XCAR (args)); if (!NILP (val)) break; args = XCDR (args); QUIT; }
return val; }
ではDEFUN
マクロの引数について詳細に説明しましょう。以下はそれらのテンプレートです:
DEFUN (lname, fname, sname, min, max, interactive, doc)
これは関数名として定義するLispシンボル名。上記例ではor
。
これは関数のC関数名。これはCコードでその関数を呼び出すために使用される名前。名前は慣習として‘F’の後にLisp名をつけて、Lisp名のすべてのダッシュ(‘-’)をアンダースコアに変更する。つまりCコードから呼び出す場合にはFor
を呼び出す。
これはLispでその関数を表すsubrオブジェクト用にデータ保持のための構造体に使用されるC変数名。この構造体はそのシンボルを作成してそれの定義にsubrオブジェクトを格納する初期化ルーチンでLispシンボル名を伝達する。慣習により常にfnameの‘F’を‘S’に置き換えた名前になる。
これは関数が要求する引数の最小個数。関数or
は最小で0個の引数を受け入れる。
これは関数が受け入れる引数の最大個数が定数なら引数の最大個数。あるいはUNEVALLED
なら未評価の引数を受け取るスペシャルフォーム、MANY
なら評価される引数の個数に制限がないことを意味する(&rest
と等価)。UNEVALLED
とMANY
はいずれもマクロ。maxが数字ならminより大きく8より小さいこと。
これはLisp関数でinteractive
の引数として使用されるようなインタラクティブ仕様(文字列)。or
の場合は0(nullポインター)であり、それはor
がインタラクティブに呼び出せないことを示す。値""
はインタラクティブに呼び出す際に関数が引数を引き受けるべきではないことを示す。値が‘"(’で始まる場合には、その文字列はLispフォームとして評価される。たとえば:
DEFUN ("foo", Ffoo, Sfoo, 0, UNEVALLED, "(list (read-char-by-name \"Insert character: \")\ (prefix-numeric-value current-prefix-arg)\ t))", doc: /* … /*)
これはドキュメント文字列。複数行を含むために特別なことを要しないので、これにはCの文字列構文ではなくCコメント構文を使用する。‘doc:’の後のコメントはドキュメント文字列として認識される。コメントの開始と終了の区切り文字‘/*’と‘*/’はドキュメント文字列の一部にはならない。
ドキュメント文字列の最後の行がキーワード‘usage:’で始まる場合には、その行の残りの部分は引数リストをドキュメント化するためのものとして扱われる。この方法によりCコード内で使用される引数名とは異なる引数名をドキュメント文字列内で使用することができる。その関数の引数の個数に制限がなければ‘usage:’は必須。
Lispコードでのドキュメント文字列にたいするすべての通常ルール(ドキュメント文字列のヒントを参照)はCコードのドキュメント文字列にも適用される。
DEFUN
マクロ呼び出しの後には、そのC関数にたいする引数リストを引数のタイプを含めて記述しなければなりません。そのプリミティブがLispで固定された最大個数をもつ引数を受け入れるならLisp引数それぞれにたいして1つのC引数をもち、各引数のタイプはLisp_Object
でなければなりません(ファイルlisp.hではタイプLisp_Object
の値を作成する種々のマクロと関数が宣言されている)。そのプリミティブのLispの最大引数個数に上限がなければ正確に2つのC引数をもたなければなりません。1つ目はLisp引数の個数で、2つ目はそれらの値を含むブロックのアドレスです。これらはそれぞれint
、Lisp_Object *
のタイプをもちます。Lisp_Object
は任意のデータ型と任意のLispオブジェクトを保持できるので実行時のみ実際のデータ型を判断できます。特定のタイプの引数だけを受け入れるプリミティブを記述したければ適切な述語を使用してタイプを明確にチェックしなければなりません(型のための述語を参照)。
関数For
自体ではローカル変数args
はEmacsのスタックマーキングによるガーベージコレクションで制御されるオブジェクトを参照します。たとえガーベージコレクターがCのLisp_Object
スタック変数から到達可能なオブジェクトは再利用しないとしても、文字列の内容のようなオブジェクトの非オブジェクトコンポーネントは移動するかもしれないので、非オブジェクトコンポーネントにアクセスする関数はLisp評価を処理した後にはそれらのアドレスを再取得するよう注意しなければなりません。Lisp評価は直接と間接を問わずeval_sub
かFeval
の呼び出しを通じて発生する可能性があります。
ループ内部でのQUIT
の呼び出しには注意してください。このマクロはユーザーがC-gを押下したかどうかをチェックして、もし押下していたら処理をabortします。潜在的に多数の繰り返しを要するすべてのループでこれを行う必要があります。この場合には引数のリストは非常に長くなる可能性があります。これはEmacsの応答性とユーザーエクスペリエンスを向上します。
Emacsが一度ダンプされた後に変数に何か書き込まれているときには、その静的変数やグローバル変数にCの初期化を使用してはなりません。初期化されたこれらの変数はEmacsのダンプの結果として、(特定のオペレーティングシステムでは)読み取り専用となるメモリーエリアに割り当てられます。純粋ストレージを参照してください。
C関数の定義だけではLispプリミティブを利用可能にするのに十分ではありません。そのプリミティブにたいしてLispシンボルを作成して関数セルに適切なsubrオブジェクトを格納しなければなりません。このコードは以下のようになるでしょう:
defsubr (&sname);
ここでsnameはDEFUN
の3つ目の引数として使用する名前です。
すでにLispプリミティブが定義されたファイルにプリミティブを追加する場合には、(そのファイル終端付近にある)syms_of_something
という名前の関数を探してdefsubr
の呼び出しを追加してください。ファイルにこの関数がない、または新たなファイルを作成する場合にはsyms_of_filename
(例:
syms_of_myfile
)を追加します。それからemacs.cでそれらの関数が呼び出されるすべての箇所を探してsyms_of_filename
の呼び出しを追加してください。
関数syms_of_filename
はLisp変数として可視となるすべてのC変数を定義する場所でもあります。DEFVAR_LISP
はタイプLisp_Object
のC変数をLispから可視にします。DEFVAR_INT
はタイプint
のC変数を常に整数となる値をもつようにしてLispから可視にします。DEFVAR_BOOL
はタイプint
のC変数を常にt
かnil
のいずれかとなる値をもつようにしてLispから可視にします。DEFVAR_BOOL
で定義された変数はバイトコンパイラーに使用されるリストbyte-boolean-vars
に自動的に追加されることに注意してください。
Cで定義されたLisp変数をdefcustom
で宣言された変数のように振る舞わせたければcus-start.elに適切なエントリーを追加してください。
タイプLisp_Object
のファイルをスコープとするC変数を定義する場合には、以下のようにsyms_of_filename
内でstaticpro
を呼び出してガーベージコレクションから保護しなければなりません:
staticpro (&variable);
以下はより複雑な引数をもつ別の関数例です。これはwindow.cからのコードであり、Lispオブジェクトを操作するためのマクロと関数の使用を示すものです。
DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p, Scoordinates_in_window_p, 2, 2, 0, doc: /* Return non-nil if COORDINATES are in WINDOW. ...
or `right-margin' is returned. */) (register Lisp_Object coordinates, Lisp_Object window) { struct window *w; struct frame *f; int x, y; Lisp_Object lx, ly;
CHECK_LIVE_WINDOW (window); w = XWINDOW (window); f = XFRAME (w->frame); CHECK_CONS (coordinates); lx = Fcar (coordinates); ly = Fcdr (coordinates); CHECK_NUMBER_OR_FLOAT (lx); CHECK_NUMBER_OR_FLOAT (ly); x = FRAME_PIXEL_X_FROM_CANON_X (f, lx) + FRAME_INTERNAL_BORDER_WIDTH(f); y = FRAME_PIXEL_Y_FROM_CANON_Y (f, ly) + FRAME_INTERNAL_BORDER_WIDTH(f);
switch (coordinates_in_window (w, x, y)) { case ON_NOTHING: /* NOT in window at all. */ return Qnil;
...
case ON_MODE_LINE: /* In mode line of window. */ return Qmode_line;
...
case ON_SCROLL_BAR: /* On scroll-bar of window. */ /* Historically we are supposed to return nil in this case. */ return Qnil;
default: abort (); } }
CコードはCで記述されていなければ名前で呼び出すことはできないことに注意してください。Lispで記述された関数を呼び出すには関数funcall
をCで具現化したFfuncall
を使用します。Lisp関数funcall
は個数制限なしの引数を受け付けるので、Cでの引数はLispレベルでの引数個数とそれらの値を含む1次元配列という2個の引数になります。Lispレベルでの1つ目の引数は呼び出す関数、残りはそれに渡す引数です。
C関数call0
、call1
、call2
、...は個数が固定された引数でLisp関数を手軽に呼び出す便利な方法を提供します。これらはFfuncall
を呼び出すことにより機能します。
eval.cは例を探すのに適したファイルです。lisp.hには重要なマクロと関数の定義がいくつか含まれています。
副作用をもたない関数を定義する場合には、コンパイラーのオプティマイザーに知らせるためにside-effect-free-fns
とside-effect-and-error-free-fns
をバインドするbyte-opt.el内のコードを更新してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispは豊富なデータタイプのセットを提供します。コンスセル、整数、文字列のようにこれらのいくつかは、ほとんどすべてのLisp方言で一般的です。マーカやバッファーのようなそれ以外のものはLisp内でエディターコマンドを記述するための基本的サポートを提供するために極めて特別かつ必要なものです。そのような種々のオブジェクトタイプを実装してインタープリターのサブシステムとの間でオブジェクトを渡す効果的な方法を提供するために、Cデータ構造体セットとそれらすべてにたいするポインターを表すタグ付きポインター(tagged pointer)と呼ばれる特別なタイプが存在します。
Cではタグ付きポインターはタイプLisp_Object
のオブジェクトです。そのようなタイプの初期化された変数は基本的なデータタイプである整数、シンボル、文字列、コンスセル、浮動小数点数、ベクター類似オブジェクトや、その他の雑多なオブジェクトのいずれかを値として常に保持します。これらのデータタイプのそれぞれは対応するタグ値をもちます。すべてのタグはenum
Lisp_Type
により列挙されており、Lisp_Object
の3ビットのビットフィールドに配置されます。残りのビットはそれ自身の値です。整数は即値(値ビットで直接表される)、他のすべてのオブジェクトはヒープに割り当てられた対応するオブジェクトへのCポインターで表されます。Lisp_Object
のサイズはプラットフォームと設定に依存します。これは通常は背景プラットフォームのポインターと同一(32ビットマシンなら32ビット、64ビットマシンなら64ビット)ですがLisp_Object
が64ビットでも、すべてのポインターが32ビットのような特別な構成もあります。後者はLisp_Object
にたいして64ビットのlong
long
タイプを使用することにより、32ビットシステム上のLisp整数にたいする値範囲の制限を乗り越えるためにデザインされたトリックです。
以下のCデータ構造体は整数ではない基本的なデータタイプを表すためにlisp.hで定義されています:
struct Lisp_Cons
コンスセル。リストを構築するために使用されるオブジェクト。
struct Lisp_String
文字列。文字シーケンスを表す基本的オブジェクト。
struct Lisp_Vector
配列。インデックスによりアクセスできる固定サイズのLispオブジェクトのセット。
struct Lisp_Symbol
シンボル。一般的に識別子として使用される一意な名前のエンティティ。
struct Lisp_Float
Floating-point value.
union Lisp_Misc
上記のいずれにも適合しない雑多な種類のオブジェクト。
これらのタイプは内部的タイプシステムのファーストクラスの市民です。タグスペースは限られているので他のすべてのタイプはLisp_Vectorlike
かLisp_Misc
のサブクラスです。サブタイプのベクターはenum
pvec_type
により列挙されておりウィンドウ、バッファー、フレーム、プロセスのようなほとんどすべての複雑なオブジェクトはこのカテゴリーに分類されます。マーカーとオーバーレイを含む残りのスペシャルタイプはenum
Lisp_Misc_Type
により列挙されており、Lisp_Misc
のサブタイプセットを形成します。
Lisp_Vectorlike
のいくつかのサブタイプを説明します。バッファーオブジェクトは表示と編集を行うテキストを表します。ウィンドウはバッファーを表示したり同一フレーム上で再帰的に他のウィンドウを配置するためのコンテナーに使用される表示構造の一部です(Emacs
LispのウィンドウオブジェクトとXのようなユーザーインターフェースシステムに管理されるエンティティとしてのウィンドウを混同しないこと。Emacsの用語では後者はフレームと呼ばれる)。最後にプロセスオブジェクトはサブプロセスの管理に使用されます。
E.8.1 バッファーの内部 | バッファー構造体の構成子。 | |
E.8.2 ウィンドウの内部 | ウィンドウ構造体の構成子。 | |
E.8.3 プロセスの内部 | プロセス構造体の構成子。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Cでバッファーを表すために2つの構造体(buffer.hを参照)が使用されます。buffer_text
構造体にはバッファーのテキストを記述するフィールドが含まれます。buffer
構造体は他のフィールドを保持します。インダイレクトバッファーの場合には、2つ以上のbuffer
構造体が同じbuffer_text
構造体を参照します。
以下にstruct buffer_text
内のフィールドをいくつか示します:
beg
バッファーコンテンツのアドレス。
gpt
gpt_byte
バッファーのギャップの文字位置とバイト位置。バッファーのギャップを参照のこと。
z
z_byte
バッファーテキストの終端の文字位置とバイト位置。
gap_size
バッファーのギャップのサイズ。バッファーのギャップを参照のこと。
modiff
save_modiff
chars_modiff
overlay_modiff
これらのフィールドはバッファーで行われたバッファー変更イベントの数をカウントする。modiff
はバッファー変更イベントのたびに増分されて、それ以外では決して変化しない。save_modiff
にはバッファーが最後にvisitまたは保存されたときのmodiff
の値が含まれる。chars_modiff
はバッファー内の文字にたいする変更だけをカウントして、その他すべての種類の変更を無視する。overlay_modiff
はオーバーレイにたいする変更だけをカウントする。
beg_unchanged
end_unchanged
最後の再表示完了以降に未変更だと解っているテキスト、開始と終了の箇所での文字数。
unchanged_modified
overlay_unchanged_modified
それぞれ最後に再表示が完了した後のmodiff
とoverlay_modiff
の値。これらのカレント値がmodiff
やoverlay_modiff
とマッチしたら、それはbeg_unchanged
とend_unchanged
に有用な情報が含まれないことを意味する。
markers
このバッファーを参照するマーカー。これは実際には単一のマーカーであり、自身のマーカー“チェーン”内の一連の要素がバッファー内のテキストを参照する他のマーカーになる。
intervals
そのバッファーのテキストプロパティを記録するインターバルツリー。
struct buffer
のいくつかのフィールドを以下に示します:
header
タイプstruct vectorlike_header
のヘッダーはベクター類似のすべてのオブジェクトに共通。
own_text
構造体struct
buffer_text
は通常はバッファーのコンテンツを保持する。このフィールドはインダイレクトバッファーでは使用されない。
text
そのバッファーのbuffer_text
構造体へのポインター。通常のバッファーでは上述のown_text
フィールド。インダイレクトバッファーではベースバッファーのown_text
フィールド。
next
killされたバッファーを含むすべてのバッファーのチェーン内において次のバッファーへのポインター。このチェーンはkillされたバッファーを正しく回収するために割り当てとガーベージコレクションのためだけに使用される。
pt
pt_byte
バッファー内のポイントの文字位置とバイト位置。
begv
begv_byte
そのバッファー内のアクセス可能範囲の先頭位置の文字位置とバイト位置。
zv
zv_byte
そのバッファー内のアクセス可能範囲の終端位置の文字位置とバイト位置。
base_buffer
インダイレクトバッファーではベースバッファーのポイント。通常のバッファーではnull。
local_flags
このフィールドはバッファー内でローカルな変数にたいしてそれを示すフラグを含む。そのような変数はCコードではDEFVAR_PER_BUFFER
を使用して宣言され、それらのバッファーローカルなバインディングはバッファー構造体自身内のフィールドに格納される(これらのフィールドのいくつかはこのテーブル内で説明している)。
modtime
visitされているファイルの変更時刻。これはファイルの書き込みと読み込み時にセットされる。そのバッファーをファイルに書き込む前にファイルがディスク上で変更されていないことを確認するために、このフィールドとそのファイルの変更時刻を比較する。バッファーの変更を参照のこと。
auto_save_modified
そのバッファーが最後に自動保存されたときの時刻。
last_window_start
そのバッファーが最後にウィンドウに表示されたときのバッファー内でのwindow-start
位置。
clip_changed
このフラグはバッファーでのナローイングが変更されているかを示す。ナローイングを参照のこと。
prevent_redisplay_optimizations_p
このフラグはバッファーの表示において再表示最適化が使用されるべきではないことを示す。
overlay_center
このフィールドはカレントオーバーレイの中心位置を保持する。オーバーレイの管理を参照のこと。
overlays_before
overlays_after
これらのフィールドはカレントオーバーレイ中心、またはその前で終わるオーバーレイのリスト、およびカレントオーバーレイの後で終わるオーバーレイのリスト。オーバーレイの管理を参照のこと。overlays_before
は終端位置の記述順、overlays_after
は先頭位置増加順で格納される。
name
そのバッファーを命名するLisp文字列。これは一意であることが保証されている。バッファーの名前を参照のこと。
save_length
そのバッファーがvisitしているファイルを最後に読み込みか保存したときの長さ。インダイレクトバッファーは決して保存されることはないので、保存に関してはこのフィールドとその他のフィールドはbuffer_text
構造体で維持されない。
directory
相対ファイル名を展開するディレクトリー。これはバッファーローカル変数default-directory
の値(ファイル名を展開する関数を参照)。
filename
そのバッファーがvisitしているファイルの名前。これはバッファーローカル変数buffer-file-name
の値(バッファーのファイル名を参照)。
undo_list
backed_up
auto_save_file_name
auto_save_file_format
read_only
file_format
file_truename
invisibility_spec
display_count
display_time
これらのフィールドは自動的にバッファーローカル(バッファーローカル変数を参照)になるLisp変数の値を格納する。これらに対応する変数は名前に追加のプレフィクスbuffer-
がつき、アンダースコアがダッシュで置換される。たとえばundo_list
はbuffer-undo-list
の値を格納する。
mark
そのバッファーにたいするマーク。マークはマーカーなのでリストmarkers
内にも含まれる。マークを参照のこと。
local_var_alist
この連想リストはバッファーのバッファーローカル変数のバインディングを記述する。これにはバッファーオブジェクト内に特別なスロットをもつ、ビルトインのバッファーローカルなバインディングは含まれない(このテーブルではそれらのスロットは省略している)。バッファーローカル変数を参照のこと。
major_mode
そのバッファーのメジャーモードを命名するシンボル(例: lisp-mode
)。
mode_name
そのメジャーモードの愛称(例: "Lisp"
)。
keymap
abbrev_table
syntax_table
category_table
display_table
これらのフィールドはバッファーのローカルキーマップ(キーマップを参照)、abbrevテーブル(abbrevテーブルを参照)、構文テーブル(構文テーブルを参照)、カテゴリーテーブル(カテゴリーを参照)、ディスプレーテーブル(ディスプレーテーブルを参照)を格納する。
downcase_table
upcase_table
case_canon_table
これらのフィールドはテキストを小文字、大文字、およびcase-fold検索でのテキストの正規化の変換テーブルを格納する。caseテーブルを参照のこと。
minor_modes
そのバッファーのマイナーモードのalist。
pt_marker
begv_marker
zv_marker
これらのフィールドはインダイレクトバッファー、またはインダイレクトバッファーのベースバッファーであるようなバッファーでのみ使用される。これらはそれぞれバッファーがカレントでないときにバッファーにたいするpt
、begv
、zv
を記録するマーカーを保持する。
mode_line_format
header_line_format
case_fold_search
tab_width
fill_column
left_margin
auto_fill_function
truncate_lines
word_wrap
ctl_arrow
bidi_display_reordering
bidi_paragraph_direction
selective_display
selective_display_ellipses
overwrite_mode
abbrev_mode
mark_active
enable_multibyte_characters
buffer_file_coding_system
cache_long_line_scans
point_before_scroll
left_fringe_width
right_fringe_width
fringes_outside_margins
scroll_bar_width
indicate_empty_lines
indicate_buffer_boundaries
fringe_indicator_alist
fringe_cursor_alist
scroll_up_aggressively
scroll_down_aggressively
cursor_type
cursor_in_non_selected_windows
これらのフィールドは自動的にバッファーローカル(バッファーローカル変数を参照)になるLisp変数の値を格納する。これらに対応する変数は名前のアンダースコアがダッシュで置換される。たとえばmode_line_format
はmode-line-format
の値を格納する。
last_selected_window
これは最後に選択されていたときにそのバッファーを表示していたウィンドウ、またはそのウィンドウがすでにそのバッファーを表示していなければnil
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウのフィールドには以下が含まれます(完全なリストはwindow.hのstruct window
を参照):
frame
そのウィンドウがあるフレーム。
mini_p
そのウィンドウがミニバッファーウィンドウなら非nil
。
parent
Emacsは内部的にウィンドウをツリーにアレンジする。ウィンドウの兄弟グループは、そのエリアがすべての兄弟を含むような親ウィンドウをもつ。このフィールドはウィンドウの親を指す。
親ウィンドウはバッファーを表示せず子ウィンドウ形成を除いて表示では少ししか役割を果たさない。Emacs Lispプログラムからは通常は親ウィンドウへのアクセスがない。Emacs Lispプログラムでは実際にバッファーを表示するツリーの子ノードのウィンドウにたいして操作を行う。
hchild
vchild
これらのフィールドはウィンドウの左端の子と上端の子を含む。子ウィンドウによりウィンドウが分割される場合にはhchild
、垂直に分割される場合にはvchild
が使用される。生きたウィンドウではhchild
、vchild
、buffer
のいずれか1つだけが非nil
になる。
next
prev
そのウィンドウの次の兄弟と前の兄弟。自身のグループ内でそのウィンドウが右端か下端ならnext
はnil
。自身のグループ内でそのウィンドウが左端か上端ならprev
はnil
。
left_col
そのウィンドウの左端をフレームの最左列(列0)から相対的に数えた列数。
top_line
そのウィンドウの上端をフレームの最上行(行0)から相対的に数えた行数。
total_cols
total_lines
列数と行数で数えたウィンドウの幅と高さ。幅にはスクロールバーとフリンジおよび/または(もしあれば)ウィンドウ右側のセパレーターラインが含まれる。
buffer
そのウィンドウが表示しているバッファー。
start
そのウィンドウ内に表示されるバッファーでウィンドウに最初に表示される文字の位置を指すマーカー。
pointm
これはウィンドウが選択されているときのカレントバッファーのポイント値。選択されていなければ前の値が保たれる。
force_start
このフラグが非nil
ならLispプログラムによりそのウィンドウが明示的にスクロールされたことを示す。これはポイントがスクリーン外にある場合の次回再表示に影響を与える。影響とはポイント周辺のテキストを表示するためにウィンドウをスクロールするかわりに、スクリーン上にある位置にポイントを移動するというものである。
frozen_window_start_p
このフィールドは再表示にたいして、たとえポイントが不可視になったとしてもウィンドウのstart
を変更するべきではないことを示すために一時的に1にセットされる。
start_at_line_beg
非nil
はstart
のカレント値がウィンドウ選択時に先頭行だったことを意味する。
use_time
これはウィンドウが最後に選択された時刻。関数get-lru-window
はこの値を使用する。
sequence_number
そのウィンドウ作成時に割り当てられた一意な番号。
last_modified
前回のそのウィンドウの再表示完了時のウィンドウのバッファーのmodiff
フィールド。
last_overlay_modified
前回のウィンドウの再表示完了時のウィンドウのバッファーのoverlay_modiff
フィールド。
last_point
前回のウィンドウの再表示完了時のウィンドウのバッファーのポイント値。
last_had_star
非nil
値はウィンドウが最後に更新されたときウィンドウのバッファーが変更されたことを意味する。
vertical_scroll_bar
そのウィンドウの垂直スクロールバー。
left_margin_cols
right_margin_cols
そのウィンドウの左マージンと右マージンの幅。値nil
はマージンがないことを意味する。
left_fringe_width
right_fringe_width
そのウィンドウの左フリンジと右フリンジの幅。値nil
とt
はフレームの値の使用を意味する。
fringes_outside_margins
非nil
値はディスプレーマージン外側のフリンジ、それ以外ならフリンジはマージンとテキストの間にあることを意味する。
window_end_pos
これはz
からウィンドウのカレントマトリクス内の最後のグリフのバッファー位置を減じて算出される。この値はwindow_end_valid
が非nil
のときだけ有効。
window_end_bytepos
window_end_pos
に対応するバイト位置。
window_end_vpos
window_end_pos
を含む行のウィンドウに相対的な垂直位置。
window_end_valid
このフィールドはwindow_end_pos
が真に有効なら非nil
値にセットされる。これは重要な再表示が先に割り込んだ場合には、window_end_pos
を算出した表示がスクリーン上に出現しなくなるのでnil
となる。
cursor
そのウィンドウ内でカーソルがどこにあるかを記述する構造体。
last_cursor
完了した最後の表示でのcursor
の値。
phys_cursor
そのウィンドウのカーソルが物理的にどこにあるかを記述する構造体。
phys_cursor_type
phys_cursor_height
phys_cursor_width
そのウィンドウの最後の表示でのカーソルのタイプ、高さ、幅。
phys_cursor_on_p
このフィールドはカーソルが物理的にオンなら非0。
cursor_off_p
非0はそのウィンドウのカーソルが論理的にオフであることを意味する。これはカーソルの点滅に使用される。
last_cursor_off_p
このフィールドは最後の再表示時のcursor_off_p
の値を含む。
must_be_updated_p
これはウィンドウを更新しなければならないとき、再表示の間は1にセットされる。
hscroll
これはウィンドウ内の表示が左へ水平スクロールされている列数。これは通常は0。
vscroll
ピクセル単位での垂直スクロール量。これは通常は0。
dedicated
そのウィンドウがそれのバッファー専用(dedicated)なら非nil
。
display_table
そのウィンドウのディスプレーテーブル、何も指定されていなければnil
。
update_mode_line
非nil
はウィンドウのモードラインの更新が必要なことを意味する。
base_line_number
そのバッファーの特定の位置の行番号かnil
。これはモードラインでポイントの行番号を表示するために使用される。
base_line_pos
行番号が既知であるバッファー位置、未知ならnil
。これがバッファーならウィンドウがバッファーを表示するかぎり行番号は表示されない。
column_number_displayed
そのウィンドウのモードラインに表示されているカレント列番号、列番号が表示されていなければnil
。
current_matrix
desired_matrix
そのウィンドウのカレント、および望まれる表示を記述するグリフ。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プロセスのフィールドには以下が含まれます(完全なリストはprocess.hのstruct
Lisp_Process
の定義を参照):
name
プロセス名(文字列)。
command
そのプロセスの開始に使用されたコマンド引数を含むリスト。ネットワークプロセスとシリアルプロセスではプロセスが実行中ならnil
、停止していたらt
。
filter
そのプロセスから出力を受け取るために使用される関数。
sentinel
そのプロセスの状態が変化したら常に呼び出される関数。
buffer
そのプロセスに関連付けられたバッファー。
pid
オペレーティングシステムのプロセスID (整数)。ネットワークプロセスやシリアルプロセスのような疑似プロセスでは値0を使用する。
childp
フラグ。実際に子プロセスならt
。ネットワークプロセスやシリアルプロセスではmake-network-process
やmake-serial-process
にもとづくplist。
mark
そのプロセスの出力からバッファーに挿入された終端位置を示すマーカー。常にではないがこれはバッファー終端であることが多い。
kill_without_query
これが非0ならプロセス実行中にEmacsをkillしてもプロセスのkillにたいして確認を求めない。
raw_status
システムコールwait
がリターンするrawプロセス状態。
status
process-status
がリターンするようなプロセス状態。
tick
update_tick
これら2つのフィールドが等しくないなら、センチネル実行かプロセスバッファーへのメッセージ挿入によりプロセスの状態変更が報告される必要がある。
pty_flag
そのサブプロセスがptyを使用して対話する場合には非nil
、パイプを使用する場合にはnil
。
infd
そのプロセスからの入力にたいするファイルディクリプター。
outfd
そのプロセスへの出力にたいするファイルディクリプター。
tty_name
そのサブプロセスが使用する端末の名前、パイプを使用する場合にはnil
。
decode_coding_system
そのプロセスからの入力のデコーディングにたいするコーディングシステム。
decoding_buf
デコーディング用の作業バッファー。
decoding_carryover
デコーディングでのキャリーオーバーのサイズ。
encode_coding_system
そのプロセスからの出力のエンコーディングにたいするコーディングシステム。
encoding_buf
エンコーディング用の作業バッファー。
inherit_coding_system_flag
プロセス出力のデコードに使用されるコーディングシステムからプロセスバッファーのcoding-system
をセットするフラグ。
type
プロセスのタイプを示すreal
、network
、serial
のいずれかのシンボル。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はEmacsのCソースコード内で整数タイプを使用する際のガイドラインです。これらのガイドラインはときに相反するアドバイスを与えることがありますが一般的な常識に沿ったものがアドバイスです。
s
の長さをint
の範囲に収めることが要求されるのでなければint len =
strlen (s);
を使用しないこと。
ptrdiff_t
のかわりにsize_t
、intptr_t
のかわりにuintptr_t
)にたいして同様のアドバイスを適用できる。
int
を優先すること。より一般的には、たとえばスクリーン列数のようにint
範囲と既知である整数にはint
を優先すること。
ptrdiff_t
を優先すること。これは符号付きタイプにたいするEmacsの一般的な優先事項である。ptrdiff_t
の使用によりオブジェクトはPTRDIFF_MAX
に制限されるが、より大きいオブジェクトはポインター減算を破壊するかもしれず結局のところ問題を起こす可能性があるので、これは一方的に制限を課すものではない。
ssize_t
関連の制限をもつ低レベルAPIト対話する際を除いてssize_t
を避けること。これは典型的なプラトフォームではptrdiff_t
と等価だとしても、ssize_t
は範囲が狭いときがあり使用によりサイズ関連の計算がオーバーフローするかもしれない。同じくptrdiff_t
はより一般的で標準化されており、標準的なprintf
フォーマットをもち、Emacsの内部的なサイズオーバーフローのチェックの基礎である。ssize_t
を使用する際にはPOSIXガ-からSSIZE_MAX
の範囲の値にたいするサポートだけを要求することに注意してほしい。
intptr_t
を優先すること。現在のことこEmacsはintptr_t
を使用したほうがよいときに別のタイプを使用する場合がある。現在のEmacsのカレント移植先にたいして未修正でコードが動作するので修正の優先度は低い。
EMACS_INT
にもとづくのでEmacsで定義されたタイプEMACS_INT
を優先すること。
off_t
やtime_t
等の)システムタイプを優先すること。安全だと解っていなければシステムタイプが符号付きだと仮定してはならない。たとえばoff_t
は常に符号付きだがtime_t
は符号付きである必要はない。
printf
族の関数を使用してプリントされ得る任意の符号付き整数かもしれない値を表す場合にはEmacsの定義タイプprintmax_t
を優先すること。
intmax_t
を優先すること。
bool
、false
、true
を使用すること。bool
の使用によりプログラムの可読性が増して、int
を使用するより若干高速になる。int
、0
、1
を使用しても大丈夫だが旧スタイルは段階的に廃止される。bool
を使用する際にはソースファイルlib/stdbool.in.hに文書化されているbool
の代替実装の制限を尊重すること。特にブーリーンのビットフィールドはbool
ではなくbool_bf
タイプであること。そうすれば標準のGCCでObjective
Cをコンパイルするときでさえ正しく機能する。
int
は可搬性に劣るので、int
よりunsigned int
かsigned
int
を優先すること。単一ビットのビットフィールドの値は0か1なのでunsigned
int
かbool_bf
を使用すること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下は標準的なEmacsにおける、より重要なエラーシンボルを概念別にグループ分けしたリストです。このリストには各シンボルのメッセージ、およびエラーを発生し得る方法へのクロスリファレンスが含まれています。
これらのエラーシンボルはそれぞれ親となるエラー条件のセットをシンボルのリストとして保持します。このリストには通常はエラーシンボル自身とシンボルerror
が含まれます。このリストはerror
より狭義ですが単一のエラーシンボルより広義であるような中間的なクラス分けのための追加シンボルを含む場合があります。たとえばファイルアクセスでのすべてのエラーは条件file-error
をもちます。ここでわたしたちが特定のエラーシンボルにたいする追加エラー条件に言及していなければ、それがないことを意味しています。
特別な例外としてエラーシンボルquit
は、quitはエラーとみなされないのでコンディションerror
をもっていません。
これらのエラーシンボルのほとんどはC(主にdata.c)で定義されていますが、いくつかはLispで定義されています。たとえばファイルuserlock.elではfile-locked
とfile-supersession
のエラーが定義されています。Emacsとともに配布される専門的なLispライブラリーのいくつかは、それら自身のエラーシンボルを定義しています。それらのすべてをここではリストしません。
エラーの発生とそれを処理する方法についてはエラーを参照してください。
error
メッセージは‘error’。エラーを参照のこと。
quit
メッセージは‘Quit’。quitを参照のこと。
args-out-of-range
メッセージは‘Args out of range’。これはシーケンス、バッファー、その他コンテナー類似オブジェクトにたいして範囲を超えた要素にアクセスを試みたときに発生する。シーケンス、配列、ベクターとテキストを参照のこと。
arith-error
メッセージは‘Arithmetic error’。これは0による整数除算を試みたときに発生する。数値の変換と算術演算を参照のこと。
beginning-of-buffer
メッセージは‘Beginning of buffer’。文字単位の移動を参照のこと。
buffer-read-only
メッセージは‘Buffer is read-only’。読み取り専用のバッファーを参照のこと。
circular-list
メッセージは‘List contains a loop’。これは循環構造に遭遇時に発生する。循環オブジェクトの読み取り構文を参照のこと。
cl-assertion-failed
メッセージは‘Assertion
failed’。これはcl-assert
マクロのテスト失敗時に発生する。Assertions in Common
Lisp Extensionsを参照のこと。
coding-system-error
メッセージは‘Invalid coding system’。Lispでのコーディングシステムを参照のこと。
cyclic-function-indirection
メッセージは‘Symbol's chain of function indirections contains a loop’。See section シンボル関数インダイレクションを参照のこと。
cyclic-variable-indirection
メッセージは‘Symbol's chain of variable indirections contains a loop’。See section 変数のエイリアスを参照のこと。
dbus-error
メッセージは‘D-Bus error’。これはEmacsがD-Busサポートつきでコンパイルされたときだけ定義される。Errors and Events in D-Bus integration in Emacsを参照のこと。
end-of-buffer
メッセージは‘End of buffer’。文字単位の移動を参照のこと。
end-of-file
メッセージは‘End of file during
parsing’。これはファイルI/OではなくLispリーダーに属するのでfile-error
のサブカテゴリーではないことに注意のこと。入力関数を参照のこと。
file-already-exists
これはfile-error
のサブカテゴリー。ファイルの書き込みを参照のこと。
file-date-error
これはfile-error
のサブカテゴリー。これはcopy-file
を試行して出力ファイルの最終変更時刻のセットに失敗したときに発生する。ファイルの名前と属性の変更を参照のこと。
file-error
このエラーメッセージは、通常はエラー条件file-error
が与えられたときはデータアイテムだけから構築されるので、エラー文字列とサブカテゴリーはここにリストしない。つまりエラー文字列は特に関連しない。しかしこれらのエラーシンボルはerror-message
プロパティをもち、何もデータが与えられなければerror-message
が使用される。ファイルを参照のこと。
compression-error
これは圧縮ファイルの処理の問題を起因とするfile-error
のサブカテゴリー。プログラムがロードを行う方法を参照のこと。
file-locked
これはfile-error
のサブカテゴリー。ファイルのロックを参照のこと。
file-supersession
これはfile-error
のサブカテゴリー。バッファーの変更 Timeを参照のこと。
file-notify-error
これはfile-error
のサブカテゴリー。ファイル変更による通知を参照のこと。
ftp-error
これはftpを使用したリモートファイルへのアクセスの問題を起因とするfile-error
のサブカテゴリー。Remote
Files in The GNU Emacs Manualを参照のこと。
invalid-function
メッセージは‘Invalid function’。シンボル関数インダイレクションを参照のこと。
invalid-read-syntax
メッセージは‘Invalid read syntax’。プリント表現と読み取り構文を参照のこと。
invalid-regexp
メッセージは‘Invalid regexp’。正規表現を参照のこと。
mark-inactive
メッセージは‘The mark is not active now’。マークを参照のこと。
no-catch
メッセージは‘No catch for tag’。明示的な非ローカル脱出: catch
とthrow
を参照のこと。
scan-error
メッセージは‘Scan error’。これは特定の構文解析関数が無効な構文やマッチしないカッコを見つけたときに発生する。慣習的に人間が可読なエラーメッセージ、移動を妨害する開始位置、妨害の終了位置という3つの引数でraiseされる。バランスのとれたカッコを越えた移動と式のパースを参照のこと。
search-failed
メッセージは‘Search failed’。検索とマッチングを参照のこと。
setting-constant
メッセージは‘Attempt to set a constant
symbol’。これはnil
、t
、およびキーワードシンボルへの値の割り当て時に発生する。Variables that Never Changeを参照のこと。
text-read-only
メッセージは‘Text is
read-only’。これはbuffer-read-only
のサブカテゴリー。特殊な意味をもつプロパティを参照のこと。
undefined-color
メッセージは‘Undefined color’。カラー名を参照のこと。
user-error
メッセージは空文字列。エラーをシグナルする方法を参照のこと。
void-function
メッセージは‘Symbol's function definition is void’。関数セルの内容へのアクセスを参照のこと。
void-variable
メッセージは‘Symbol's value as variable is void’。変数の値へのアクセスを参照のこと。
wrong-number-of-arguments
メッセージは‘Wrong number of arguments’。リストフォームの分類を参照のこと。
wrong-type-argument
メッセージは‘Wrong type argument’。型のための述語を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは、より一般的なキーマップをリストします。これらの多くはEmacsの初回起動時に存在しますが、それらのいくつかは各機能へのアクセス時にロードされます。
他にもより特化された多くのキーマップがあります。それらは特にメジャーモードやマイナーモードに関連付けられています。ミニバッファーはいくつかのキーマップを使用します(補完を行うミニバッファーコマンドを参照)。キーマップの詳細についてはキーマップを参照してください。
2C-mode-map
プレフィクスC-x 6のサブコマンドにたいするsparseキーマップ。
Two-Column
Editing in The GNU Emacs Manualを参照のこと。
abbrev-map
プレフィクスC-x aのサブコマンドにたいするsparseキーマップ。
Defining Abbrevs in The GNU Emacs Manualを参照のこと。
button-buffer-map
バッファーを含むバッファーに有用なsparseキーマップ。
これを親キーマップとして使用したいと思うかもしれない。ボタンを参照のこと。
button-map
ボタンにより使用されるsparseキーマップ。
ctl-x-4-map
プレフィックスC-x 4のサブコマンドのsparseキーマップ。
ctl-x-5-map
プレフィックスC-x 5のサブコマンドのsparseキーマップ。
ctl-x-map
C-xコマンドにたいする完全なキーマップ。
ctl-x-r-map
プレフィクスC-x rのサブコマンドにたいするsparseキーマップ。
Registers in The GNU
Emacs Manualを参照のこと。
esc-map
ESC (やMeta)コマンドにたいする完全なキーマップ。
facemenu-keymap
プレフィクスキーM-oにたいして使用されるsparseキーマップ。
function-key-map
すべてのlocal-function-key-map
のインスタンスの親キーマップ(local-function-key-map
を参照)。
global-map
デフォルトのグローバルキーバインディングを含む完全なキーマップ。
モードでこのグローバルマップを変更しないこと。
goto-map
プレフィクスキーM-gにたいして使用されるsparseキーマップ。
help-map
ヘルプ文字C-hに後続するキーにたいするsparseキーマップ。
ヘルプ関数を参照のこと。
Helper-help-map
ヘルプユーティリティパッケージにより使用される完全なキーマップ。
これは値セルと関数セルに同じキーマップをもつ。
input-decode-map
キーパッドとファンクションキーの変換にたいするキーマップ。
存在しなければ空のsparseキーマップを含む。イベントシーケンス変換のためのキーマップを参照のこと。
key-translation-map
キー変換にたいするキーマップ。local-function-key-map
と異なり通常のキーバインディングをオーバーライドする。イベントシーケンス変換のためのキーマップを参照のこと。
kmacro-keymap
プレフィクス検索C-x C-kに後続するキーにたいするsparseキーマップ。
Keyboard Macros in The GNU Emacs Manualを参照のこと。
local-function-key-map
キーシーケンスを優先する代替えに変換するキーマップ。
存在しなければ空のsparseキーマップが含まれる。イベントシーケンス変換のためのキーマップを参照のこと。
menu-bar-file-menu
menu-bar-edit-menu
menu-bar-options-menu
global-buffers-menu-map
menu-bar-tools-menu
menu-bar-help-menu
これらのキーマップはメニューバー内のメインとなるトップレベルメニューを表示する。
これらのいくつかはサブメニューを含む。たとえばEditメニューはmenu-bar-search-menu
を含む等。メニューバー Barを参照のこと。
minibuffer-inactive-mode-map
ミニバッファーが非アクティブ時に使用される完全なキーマップ。
Editing in the
Minibuffer in The GNU Emacs Manualを参照のこと。
mode-line-coding-system-map
mode-line-input-method-map
mode-line-column-line-number-mode-map
これらのキーマップはモードライン内の種々のエリアを制御する。
モードラインのフォーマットを参照のこと。
mode-specific-map
C-cに後続する文字にたいするキーマップ。これはグローバルキーマップ内にあることに注意。これは実際にはモード固有のものではない。プフィクスキーC-cの使用方法を主に記述するC-h
b (display-bindings
)内で有益なのでこの名前が選ばれた。
mouse-appearance-menu-map
S-mouse-1キーにたいして使用されるsparseキーマップ。
mule-keymap
プレフィクスキーC-x RETにたいして使用されるグローバルキーマップ。
narrow-map
プレフィクスC-x nのサブコマンドにたいするsparseキーマップ。
prog-mode-map
Progモードにより使用されるキーマップ。
基本的なメジャーモードを参照のこと。
query-replace-map
multi-query-replace-map
query-replace
での応答と関連するコマンド、y-or-n-p
とmap-y-or-n-p
にたいしても使用されるsparseキーマップ。このマップを使用する関数はプレフィクスキーを使用せず一度に1つのイベントを照会する。複数バッファーの置換ではmulti-query-replace-map
がquery-replace-map
を拡張する。query-replace-mapを参照のこと。
search-map
検索関連コマンドにたいしてグローバルバインディングを提供するsparseキーマップ。
special-mode-map
Specialモードにより使用されるキーマップ。
基本的なメジャーモードを参照のこと。
tool-bar-map
ツールバーのコンテンツを定義するキーマップ。
ツールバーを参照のこと。
universal-argument-map
C-u処理中に使用されるsparseキーマップ。
プレフィクスコマンド引数を参照のこと。
vc-prefix-map
プレフィクスキーC-x vにたいして使用されるグローバルキーマップ。
x-alternatives-map
グラフィカルなフレームでの特定キーのマップに使用されるsparseキーマップ。
関数x-setup-function-keys
はこれを使用する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はEmacsで適切なタイミングで呼び出す関数を提供するためのいくつかのフック関数のリストです。
これらの変数のほとんどは‘-hook’で終わる名前をもちます。これらはノーマルフック(normal
hooks)と呼ばれておりrun-hooks
により実行されます。そのようなフックの値は関数のリストです。これらの関数は引数なしで呼び出されて値は完全に無視されます。そのようなフック上に新たに関数を配置するためにはadd-hook
を呼び出す方法を推奨します。フック使用についての詳細はフックを参照してください。
‘-functions’で終わる名前の変数は通常はアブノーマルフック(abnormal hooks)です(古いコードの中には非推奨の‘-hooks’サフィクスを使用するものもある)。これらの値は関数のリストですが関数は特殊な方法で呼び出されます(引数を渡されたりリターン値が使用される)。‘-function’で終わる名前の変数は値として単一の関数をもちます。
以下のリストはすべてを網羅したリストではなく、より一般的なフックだけをカバーしています。たとえばメジャーモードはそれぞれ‘modename-mode-hook’という名前のフックを定義します。メジャーモードは自身が行う最後のこととしてrun-mode-hooks
でこのノーマルフックを実行します。モードフックを参照してください。ほとんどのマイナーモードにもフックがあります。
特別な機能によりファイルがロードされたときに評価する式を指定できます(ロードのためのフックを参照)。この機能は正確にはフックではありませんが同様のことを行います。
activate-mark-hook
deactivate-mark-hook
マークを参照のこと。
after-change-functions
before-change-functions
first-change-hook
フックの変更を参照のこと。
after-change-major-mode-hook
change-major-mode-after-body-hook
モードフックを参照のこと。
after-init-hook
before-init-hook
emacs-startup-hook
window-setup-hook
initファイルを参照のこと。
after-insert-file-functions
write-region-annotate-functions
write-region-post-annotation-function
ファイルのフォーマット変換を参照のこと。
after-make-frame-functions
before-make-frame-hook
フレームの作成を参照のこと。
after-save-hook
before-save-hook
write-contents-functions
write-file-functions
バッファーの保存を参照のこと。
after-setting-font-hook
フレームのフォント変更後に実行されるフック。
auto-save-hook
See section 自動保存を参照のこと。
before-hack-local-variables-hook
hack-local-variables-hook
ファイルローカル変数を参照のこと。
buffer-access-fontify-functions
テキストプロパティのlazyな計算を参照のこと。
buffer-list-update-hook
バッファーリスト変更時に実行されるフック(バッファーリストを参照)。
buffer-quit-function
カレントバッファーをquitするために呼び出されるフック。
change-major-mode-hook
バッファーローカルなバインディングの作成と削除を参照のこと。
command-line-functions
コマンドライン引数を参照のこと。
delayed-warnings-hook
コマンドループはpost-command-hook
(以下参照)の直後にこれを実行する。
focus-in-hook
focus-out-hook
入力のフォーカスを参照のこと。
delete-frame-functions
フレームの削除を参照のこと。
delete-terminal-functions
複数の端末を参照のこと。
pop-up-frame-function
split-window-preferred-function
バッファー表示の追加オプションを参照のこと。
echo-area-clear-hook
エコーエリアのカスタマイズを参照のこと。
find-file-hook
find-file-not-found-functions
ファイルをvisitする関数を参照のこと。
font-lock-extend-after-change-region-function
バッファー変更後のリージョンのフォント化を参照のこと。
font-lock-extend-region-functions
複数行のFont Lock構造を参照のこと。
font-lock-fontify-buffer-function
font-lock-fontify-region-function
font-lock-mark-block-function
font-lock-unfontify-buffer-function
font-lock-unfontify-region-function
Font Lockのその他の変数を参照のこと。
fontification-functions
Automatic Face Assignmentを参照のこと。
frame-auto-hide-function
ウィンドウのquitを参照のこと。
kill-buffer-hook
kill-buffer-query-functions
バッファーのkillを参照のこと。
kill-emacs-hook
kill-emacs-query-functions
Emacsのkillを参照のこと。
menu-bar-update-hook
メニューバー Barを参照のこと。
minibuffer-setup-hook
minibuffer-exit-hook
ミニバッファー、その他の事項を参照のこと。
mouse-leave-buffer-hook
マウスコマンドでのウィンドウ切り替え時に実行されるフック。
mouse-position-function
マウスの位置を参照のこと。
prefix-command-echo-keystrokes-functions
(C-uのような)プレフィクスコマンドにより実行されるアブノーマルフックであり、カレントのプレフィクス状態を記述する文字列をリターンすること。たとえばC-uは‘C-u-’や‘C-u
1 2
3-’を生成する。フック関数はそれぞれ引数なしで呼び出されてカレントのプレフィクス状態を記述する文字列、プレフィクス状態がなければnil
をリターンすること。プレフィクスコマンド引数を参照のこと。
prefix-command-preserve-state-hook
プレフィクスコマンドが次のコマンドにカレントのプレフィクスコマンドを渡すことによりプレフィクスを確保する必要はある際にフックが実行される。たとえばC-uはユーザーがC-u -やC-uの後に数字をタイプした際には、その状態を次のコマンドに渡す必要がある。
pre-redisplay-functions
フックはそれぞれのウィンドウで再表示の直前に実行される。強制的な再表示を参照のこと。
post-command-hook
pre-command-hook
コマンドループの概要を参照のこと。
post-gc-hook
ガーベージコレクションを参照のこと。
post-self-insert-hook
キーマップとマイナーモードを参照のこと。
suspend-hook
suspend-resume-hook
suspend-tty-functions
resume-tty-functions
Emacsのサスペンドを参照のこと。
syntax-begin-function
syntax-propertize-extend-region-functions
syntax-propertize-function
font-lock-syntactic-face-function
構文的なFont Lockと構文プロパティを参照のこと。
temp-buffer-setup-hook
temp-buffer-show-function
temp-buffer-show-hook
一時的な表示を参照のこと。
tty-setup-hook
端末固有の初期化を参照のこと。
window-configuration-change-hook
window-scroll-functions
window-size-change-functions
ウィンドウのスクロールと変更のためのフックを参照のこと。
window-text-change-functions
ウィンドウのテキスト変更時の再表示で呼び出す関数。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Jump to: | "
#
$
%
&
'
(
)
*
+
,
-
.
/
1
2
3
;
<
=
>
?
@
[
\
]
^
`
|
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z |
---|
Jump to: | "
#
$
%
&
'
(
)
*
+
,
-
.
/
1
2
3
;
<
=
>
?
@
[
\
]
^
`
|
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z |
---|
[Top] | [Contents] | [Index] | [ ? ] |
副文字テーブル(sub-char-tables)に使用される‘#^^’を目にすることがあるかもしれません。
リストの最後に要素を追加するための、これと完全に同等な方法はありません。listnameをコピーすることにより新しいリストを作成してから、neweltをそのリストの最後に追加する(append
listname (list
newelt))
を使用することができます。すべてのCDRを辿って終端のnil
を置き換える、(nconc
listname (list
newelt))
を使用することもできます。コピーも変更も行なわずにリストの先頭に要素を追加するcons
と比較してみてください。
ここでの“キー(key)”の使い方は、用語“キーシーケンス(key sequence)”とは関係ありません。キーはテーブルにあるアイテムを探すために使用される値という意味です。この場合、テーブルはalistでありalistはアイテムに関連付けられます。
S式(S-expression)、短くはsexpという言葉でも呼ばれることがありますが、わたしたちはこのマニュアル内では通常はこの用語は使用しません。
“環境”にたいするこの定義は、プログラムの結果に影響し得るすべてのデータを特に意図したものではありません。
正確に言うとデフォルトのダイナミックスコープ(dynamic scoping)のルールでは、値セルは常にその変数のカレント値を保持しますが、レキシカルスコープ(lexical scoping)では異なります。詳細は変数のバインディングのスコーピングルールを参照してください。
これにはいくつか例外があります。たとえばレキシカルバインディングは、Lispデバッガーからもアクセスできます。
MS-DOS版のEmacsはDOSファイルシステムの制限により、かわりに_dir-locals.elという名前を使用します。
これはカリー化(currying)と関連しますが異なる機能です。カーリングは複数の引数を受け取る関数を、関数チェーンとして呼び出せるような1つの引数を取る個々の関数に変換するような方法です。
いくつかの要素は実際に2つの引数を提供します。
ボタンダウンはドラッグの保守的なアンチテーゼです。
訳注:
原文は“Button-down is the conservative antithesis of
drag.”。
ちなみにIT用語で使用される前は"button-down"はボタンダウンシャツを表すとともに「保守的、堅苦しい」という意味もあり、一方の"drag"はIT用語として使用される前から「引っ張る、引きずる」という意味で用いられてきましたが「本来は異性が着る洋服」という意味もあります。
これはテキスト端末のようなツールキットを使用しないメニューにたいして要求されます。
MS-WindowsバージョンのEmacsはCygwin環境用にコンパイルされており、2つのファイル名構文の変換にcygwin-convert-file-name-to-windows
とcygwin-convert-file-name-from-windows
を使用できます。
RFC(Request for Commentsの略)とは標準を記述するナンバーが付与されたインターネット情報提供ドキュメントです。RFCは通常は自身が先駆的に活動する技術エキスパートによって記述され、伝統として現実的で経験主導で記述されます。
この内部表現は任意のUnicodeコードポイントを表すための、UTF-8と呼ばれるUnicode標準によるエンコーディングの1つにもとづいたものですが、8ビットrawバイトおよびUnicodeに統一されていない文字を使用する追加のコードポイントを表現するためにEmacsはUTF-8を拡張しています。
Unicode仕様ではこれらのタグ名を‘<..>’カッコ内に記述しますがEmacsでのタグ名にはカッコは含まれません。Unicodeでの‘<small>’指定はEmacsでは‘small’となります。
regexp-opt
の結果が絶対的にもっとも効率的であるという保証はないことに注意してください。手作業でチューニングした正規表現のほうがわずかに効率的なこともありますが、これに努力する価値はほとんどないでしょう。
他のシステムではEmacsはls
のLispエミュレーションを使用します。ディレクトリーのコンテンツを参照してください。
後方互換のため、フェイス名の指定に文字列も使用できます。これは同名のLispシンボルと等価です。
このコンテキストでは用語fontはFont Lock(Font Lockモードを参照)にたいして何も行いません。
Common Lispスタイルのパッケージシステムの恩恵はコストを上回るとは考えられない。
[Top] | [Contents] | [Index] | [ ? ] |
display-buffer
にたいするアクション関数display
プロパティ
[Top] | [Contents] | [Index] | [ ? ] |
[Top] | [Contents] | [Index] | [ ? ] |
This document was generated on March 5, 2020 using texi2any.
The buttons in the navigation panels have the following meaning:
Button | Name | Go to | From 1.2.3 go to |
---|---|---|---|
[ << ] | FastBack | Beginning of this chapter or previous chapter | 1 |
[ < ] | Back | Previous section in reading order | 1.2.2 |
[ Up ] | Up | Up section | 1.2 |
[ > ] | Forward | Next section in reading order | 1.2.4 |
[ >> ] | FastForward | Next chapter | 2 |
[Top] | Top | Cover (top) of document | |
[Contents] | Contents | Table of contents | |
[Index] | Index | Index | |
[ ? ] | About | About (help) |
where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:
This document was generated on March 5, 2020 using texi2any.