This is the GNU Emacs Lisp Reference Manual corresponding to Emacs version 29.1.
Copyright © 1990–1996, 1998–2023 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 29.1.
Copyright © 1990–1996, 1998–2023 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 レコード | Compound objects with programmer-defined types. | |
8 ハッシュテーブル | 非常に高速な照会テーブル。 | |
9 シンボル | 名前を一意に表すシンボル。 | |
10 評価 | Lisp式が評価される方法。 | |
11 制御構造 | 条件文、ループ、非ローカル脱出。 | |
12 変数 | プログラムで値を表すためにシンボルを使用する。 | |
13 関数 | 関数とは別の関数から呼び出せるLispプログラムである。 | |
14 マクロ | マクロとはLisp言語を拡張する手段である。 | |
15 カスタマイゼーション設定 | 変数やフェイスをカスタマイズ可能にする。 | |
16 ロード | LispコードのファイルをLispに読み込む。 | |
17 バイトコンパイル | プログラム実行を高速にするコンパイル。 | |
18 Lispからネイティブコードへのコンパイル | Compile Lisp into native machine code. | |
19 Lispプログラムのデバッグ | Lispプログラムのデバッグのためのツールとヒント。 | |
20 Lispオブジェクトの読み取りとプリント | Lispオブジェクトからテキストへの変換と逆変換。 | |
21 ミニバッファー | 入力を読み取るためにミニバッファーを使用する。 | |
22 コマンドループ | エディターコマンドループが機能する方法と、そのサブルーチンを呼び出す方法。 | |
23 キーマップ | キーをコマンドにバインドするための定義。 | |
24 メジャーモードとマイナーモード | メジャーモードとマイナーモードの定義。 | |
25 ドキュメント | ドキュメント文字列の記述と使用。 | |
26 ファイル | ファイルへのアクセス。 | |
27 バックアップと自動保存 | バックアップファイルト自動保存ファイルの作成方法の制御。 | |
28 バッファー | バッファーオブジェクトの作成と使用。 | |
29 ウィンドウ | ウィンドウの操作とバッファーの表示。 | |
30 フレーム | システムレベルウィンドウを複数作成する。 | |
31 ポジション | バッファー位置と移動関数。 | |
32 マーカー | マーカーは位置を表し、テキスト変更時に自動的に更新される。 | |
33 テキスト | バッファー内のテキストの調査と変更。 | |
34 非ASCII文字 | バッファーと文字列内の非ASCIIテキスト。 | |
35 検索とマッチング | バッファー内の文字列や正規表現の検索。 | |
36 構文テーブル | 単語やリストの解析を制御する構文テーブル。 | |
37 プログラムソースの解析 | Generate syntax tree for program sources. | |
38 abbrevとabbrev展開 | Abbrevモードが機能する方法と、そのデータ構造。 | |
39 スレッド | Concurrency in Emacs Lisp. | |
40 プロセス | サブプロセスの実行と対話。 | |
41 Emacsのディスプレイ表示 | スクリーン表示を制御するための機能。 | |
42 オペレーティングシステムのインターフェース | ユーザーID、システムタイプ、環境変数、その他類似項目の取得。 | |
43 配布用Lispコードの準備 | 配布用にLispコードを準備する。 | |
Appendices | ||
Appendix A Emacs 28 Antinews | Info for users downgrading to Emacs 28. | |
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 Lispの歴史 | このマニュアルのフォーマット方法。 | |
1.4 バージョンの情報 | 実行中のEmacsのバージョンは? | |
1.5 謝辞 | このマニュアルの著者、編集者、スポンサー。 | |
Conventions | ||
1.3.1 Lispの歴史 | このマニュアルで使用する用語の説明。 | |
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 特別な読み取り構文 | An overview of all the special sequences. | |
2.3 コメント | コメントとコメント書式の慣例。 | |
2.4 プログラミングの型 | すべてのLispシステムに存在する型。 | |
2.5 編集用の型 | Emacs固有の型。 | |
2.6 循環オブジェクトの読み取り構文 | 循環構造にたいする入力構文。 | |
2.7 型のための述語 | 型に関連するテスト。 | |
2.8 同等性のための述語 | 2つのオブジェクトが等しいかのテスト。 | |
2.9 可変性 | Some objects should not be modified. | |
Programming 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 文字列型 | (効率的な)文字の配列。 | |
2.4.9 ベクター型 | 1次元の配列。 | |
2.4.10 文字テーブル型 | 文字によりインデックスされる1次元の疎な配列。 | |
2.4.11 ブールベクター型 | t とnil からなる、1次元の配列。
| |
2.4.12 ハッシュテーブル型 | とても高速な参照用のテーブル。 | |
2.4.13 関数型 | 他の場所から呼び出せる実行可能なコードの断片。 | |
2.4.14 マクロ型 | より基本的だが少し見栄えの悪い、式を他の式に展開する手法。 | |
2.4.15 プリミティブ関数型 | Lispから呼び出せる、Cで記述された関数。 | |
2.4.16 バイトコード関数型 | Lispで記述されてからコンパイルされた関数。 | |
2.4.17 レコード型 | Compound objects with programmer-defined types. | |
2.4.18 型記述子 | Objects holding information about types. | |
2.4.19 autoload型 | 頻繁に使用されない関数を自動的にロードするために使用される型。 | |
2.4.20 ファイナライザー型 | Runs code when no longer reachable. | |
Character Type | ||
2.4.3.1 基本的な文字構文 | 標準的な文字の構文。 | |
2.4.3.2 一般的なエスケープ構文 | 文字をコードにより指定する方法。 | |
2.4.3.3 コントロール文字構文 | コントロール文字の構文。 | |
2.4.3.4 メタ文字構文 | メタ文字の構文。 | |
2.4.3.5 その他の文字修飾ビット | ハイパー、スーパー、アルト文字の構文。 | |
Cons Cell and List Types | ||
2.4.6.1 ボックスダイアグラムによるリストの描写 | リストを絵で書いたら。 | |
2.4.6.2 ドットペア表記 | コンスセルの一般的な構文。 | |
2.4.6.3 連想リスト型 | コンスセルの一般的な構文。 | |
String Type | ||
2.4.8.1 文字列の構文 | Lisp文字列を指定する方法。 | |
2.4.8.2 文字列内の非ASCII文字 | 文字列内の国際化文字。 | |
2.4.8.3 文字列内の非プリント文字 | 文字列内の印刷不可能なリテラル文字。 | |
2.4.8.4 文字列内のテキストプロパティ | テキストプロパティをともなう文字列。 | |
Editing Types | ||
2.5.1 バッファー型 | 編集のための基本オブジェクト。 | |
2.5.2 マーカー型 | バッファー内の位置。 | |
2.5.3 ウィンドウ型 | バッファーはウィンドウ内に表示する。 | |
2.5.4 フレーム型 | ウィンドウはフレームを細分化する。 | |
2.5.5 端末型 | フレームを表示する端末デバイス。 | |
2.5.6 ウィンドウ構成型 | フレームが細分化された方法を記録する。 | |
2.5.7 フレーム構成型 | すべてのフレームの状態を記録する。 | |
2.5.8 プロセス型 | 背後のOS上で実行されるEmacsのサブプロセス。 | |
2.5.9 スレッド型 | A thread of Emacs Lisp execution. | |
2.5.10 ミューテックス型 | An exclusive lock for thread synchronization. | |
2.5.11 状態変数型 | Condition variable for thread synchronization. | |
2.5.12 ストリーム型 | 文字の受信と送信。 | |
2.5.13 キーマップ型 | キーストロークがどの関数を呼び出すか。 | |
2.5.14 オーバーレイ型 | オーバーレイが表示される方法。 | |
2.5.15 フォント型 | テキストを表示するフォント。 | |
2.5.16 Xwidget型 | Embeddable widgets. | |
Numbers | ||
3.1 整数の基礎 | 整数の表現と範囲。 | |
3.2 浮動小数点数の基礎 | 浮動小数の表現と範囲。 | |
3.3 数値のための述語 | 数にたいするテスト。 | |
3.4 数値の比較 | 同一性と非同一性の述語。 | |
3.5 数値の変換 | 浮動小数点数から整数、またはその逆の変換。 | |
3.6 算術演算 | 加減乗除の方法。 | |
3.7 丸め処理 | 浮動小数点数の明示的な丸め。 | |
3.8 整数にたいするビット演算 | 論理的な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.9 Lispでの大文字小文字変換 | case変換関数。 | |
4.10 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 オブジェクト用固定長リングの管理 | オブジェクトの固定サイズのリングを管理する。 | |
Records | ||
7.1 レコード関数 | Functions for records. | |
7.2 後方互換 | Compatibility for cl-defstruct. | |
Hash Tables | ||
8.1 ハッシュテーブルの作成 | ハッシュテーブルを作成する関数。 | |
8.2 ハッシュテーブルへのアクセス | ハッシュテーブルの内容の読み書き。 | |
8.3 ハッシュの比較の定義 | 新たな比較方法の定義。 | |
8.4 ハッシュテーブルのためのその他関数 | その他。 | |
Symbols | ||
9.1 シンボルの構成要素 | シンボルは名前、値、関数定義、プロパティリストをもつ。 | |
9.2 シンボルの定義 | 定義は、シンボルが使用される方法を示す。 | |
9.3 シンボルの作成とintern | シンボルが一意に保たれる方法。 | |
9.4 シンボルのプロパティ | さまざまな情報を記録するために、各シンボルはプロパティリストをもつ。 | |
9.5 ショートハンド | Properly organize your symbol names but type less of them. | |
9.6 位置をもつシンボル | Symbol variants containing integer positions | |
Symbol Properties | ||
9.4.1 シンボルのプロパティへのアクセス | シンボルプロパティへのアクセス。 | |
9.4.2 シンボルの標準的なプロパティ | シンボルプロパティの標準的な意味。 | |
Evaluation | ||
10.1 評価の概要 | 事の在り方における評価。 | |
10.2 フォームの種類 | さまざまなオブジェクト類が評価される方法。 | |
10.3 クォート | (プログラム内に定数を配すための)評価の回避。 | |
10.4 バッククォート | リスト構造の、より簡単な構築。 | |
10.5 evalについて | Lispインタープリターを明示的に呼び出す方法。 | |
10.6 遅延されたLazy評価 | Deferred and lazy evaluation of forms. | |
Kinds of Forms | ||
10.2.1 自己評価を行うフォーム | 自分自身を評価するフォーム。 | |
10.2.2 シンボルのフォーム | 変数として評価されるシンボル。 | |
10.2.3 リストフォームの分類 | さまざまな種類のリストフォームを区別する方法。 | |
10.2.4 シンボル関数インダイレクション | シンボルがリストのcarにある場合、そのシンボルを通じて実際の関数を見つける。 | |
10.2.5 関数フォームの評価 | 関数を呼び出すフォーム。 | |
10.2.6 Lispマクロの評価 | マクロを呼び出すフォーム。 | |
10.2.7 スペシャルフォーム | Special forms are idiosyncratic primitives, most of them extremely important. | |
10.2.8 自動ロード | 実際の定義を含むファイルのロードをセットアップする関数。 | |
Control Structures | ||
11.1 順序 | テキスト順の評価。 | |
11.2 条件 | if 、cond 、when 、unless 。
| |
11.3 組み合わせ条件の構築 | and 、or 、not 。
| |
11.4 パターンマッチングによる条件 | How to use pcase and friends.
| |
11.5 繰り返し | while ループ。
| |
11.6 ジェネレーター | Generic sequences and coroutines. | |
11.7 非ローカル脱出 | シーケンスの外へジャンプ。 | |
Nonlocal Exits | ||
11.7.1 明示的な非ローカル脱出: catch とthrow | プログラム自身の目的による非ローカル脱出。 | |
11.7.2 catch とthrow の例 | このような非ローカル脱出が記述される方法。 | |
11.7.3 エラー | エラーがシグナル・処理される方法。 | |
11.7.4 非ローカル脱出のクリーンアップ | エラーが発生した場合のクリーンアップフォーム実行のアレンジ。 | |
Errors | ||
11.7.3.1 エラーをシグナルする方法 | エラーを報告する方法。 | |
11.7.3.2 Emacsがエラーを処理する方法 | エラーを報告するときEmacsが何を行なうか。 | |
11.7.3.3 エラーを処理するコードの記述 | エラーをトラップして実行を継続する方法。 | |
11.7.3.4 エラーシンボルとエラー条件 | エラートラッピングのために、エラーをクラス分けする方法。 | |
Variables | ||
12.1 グローバル変数 | どの場所でも永続的に存在する変数の値。 | |
12.2 変更不可な変数 | Variables that never change. | |
12.3 ローカル変数 | 一時的にのみ存在する存在する変数の値。 | |
12.4 変数がvoidのとき | 値を持たないシンボル。 | |
12.5 グローバル変数の定義 | シンボルが変数として使用されていることを宣言する定義。 | |
12.6 堅牢な変数定義のためのヒント | 変数を定義するときに考慮すべき事項。 | |
12.7 変数の値へのアクセス | 実行時に判明する名前をもつ変数の値を確認する。 | |
12.8 変数の値のセット | 変数に新しい値を格納する。 | |
12.9 変数が変更されたときに実行される関数。 | Running a function when a variable is changed. | |
12.10 変数のバインディングのスコーピングルール | Lispがローカル値とグローバル値を選択する方法。 | |
12.11 バッファーローカル変数 | 1つのバッファーないだけで効果をもつ変数の値。 | |
12.12 ファイルローカル変数 | ファイル内にリストされたローカル変数の処理。 | |
12.13 ディレクトリーローカル変数 | ディレクトリー内のすべてのファイルで共通のローカル変数。 | |
12.14 接続ローカル変数 | Local variables common for remote connections. | |
12.15 変数のエイリアス | 他の変数のエイリアスとなる変数。 | |
12.16 値を制限された変数 | 任意のLispオブジェクトを値とすることができない、定数ではない変数。 | |
12.17 ジェネリック変数 | 変数の概念の拡張。 | |
12.18 マルチセッション変数 | Variables that survive restarting Emacs. | |
Scoping Rules for Variable Bindings | ||
12.10.1 ダイナミックバインディング | Emacs内でのローカル変数にたいするデフォルトのバインディング。 | |
12.10.2 ダイナミックバインディングの正しい使用 | ダイナミックバインディングによる問題を回避する。 | |
12.10.3 レキシカルバインディング | ローカル変数にたいする他の種類のバインディング。 | |
12.10.4 レキシカルバインディングの使用 | レキシカルバインディングを有効にする方法。 | |
12.10.5 レキシカルバインディングへの変換 | Convert existing code to lexical binding. | |
Buffer-Local Variables | ||
12.11.1 バッファーローカル変数の概要 | イントロダクションと概念。 | |
12.11.2 バッファーローカルなバインディングの作成と削除 | ||
12.11.3 バッファーローカル変数のデフォルト値 | 自身ではバッファーローカルな値をもたないバッファーで参照されるデフォルト値。 | |
Generalized Variables | ||
12.17.1 setf マクロ | ||
12.17.2 新たなsetf フォーム | 新たなsetf フォームの定義。
| |
Multisession Variables | ||
12.18 マルチセッション変数 | Variables that survive restarting Emacs. | |
Functions | ||
13.1 関数とは? | Lisp関数 vs. プリミティブ。専門用語。 | |
13.2 ラムダ式 | 関数がLispオブジェクトとして表現される方法。 | |
13.3 関数の命名 | シンボルは関数を名づける役割を果たすことができる。 | |
13.4 関数の定義 | 関数定義のためのLisp式。 | |
13.5 関数の呼び出し | 既存の関数を使う方法。 | |
13.6 関数のマッピング | リストの各要素などに関数を適用する。 | |
13.7 無名関数 | ラムダ式、それは無名の関数。 | |
13.8 ジェネリック関数 | Polymorphism, Emacs-style. | |
13.9 関数セルの内容へのアクセス | シンボルの関数定義へのアクセスとセット。 | |
13.10 クロージャ | レキシカル環境に囲まれた関数。 | |
13.11 オープンクロージャ | Function objects with meta-data. | |
13.12 Emacs Lisp関数にたいするアドバイス | Adding to the definition of a function. | |
13.13 関数の陳腐化の宣言 | 関数を陳腐と宣言する。 | |
13.14 インライン関数Inli | コンパイラーによりインライン展開される関数。 | |
13.15 declare フォーム | 関数についての補足的な情報の追加。 | |
13.16 コンパイラーへの定義済み関数の指示 | 関数が定義されていることをコンパイラーに知らせる。 | |
13.17 安全に関数を呼び出せるかどうかの判断 | 呼び出しても安全な関数なのか判断する。 | |
13.18 関数に関するその他トピック | 関数が動作する方法において特別な意味をもつ、特定のLispプリミティブのクロスリファレンス。 | |
Lambda Expressions | ||
13.2.1 ラムダ式の構成要素 | ラムダ式のパーツ。 | |
13.2.2 単純なラムダ式の例 | シンプルな例。 | |
13.2.3 引数リストの機能 | 引数リストの詳細と特別な機能。 | |
13.2.4 関数のドキュメント文字列 | 関数内にドキュメントを記述する方法。 | |
Advising Emacs Lisp Functions | ||
13.12.1 アドバイスを操作するためのプリミティブ | Primitives to manipulate advice. | |
13.12.2 名前つき関数にたいするアドバイス | Advising named functions. | |
13.12.3 アドバイスの構築方法 | Ways to compose advice. | |
13.12.4 古いdefadviceを使用するコードの改良 | Adapting code using the old defadvice. | |
13.12.5 アドバイスとバイトコード | Not all functions can be advised. | |
Macros | ||
14.1 単純なマクロの例 | 基本的な例。 | |
14.2 マクロ呼び出しの展開 | いつ、なぜ、どのようにしてマクロが展開されるか。 | |
14.3 マクロとバイトコンパイル | コンパイラーによりマクロが展開される方法。 | |
14.4 マクロの定義 | マクロ定義を記述する方法。 | |
14.5 マクロ使用に関する一般的な問題 | マクロ引数を何回も評価しないこと。ユーザーの変数を隠さないこと。 | |
14.6 マクロのインデント | マクロ呼び出しのインデント方法の指定。 | |
Common Problems Using Macros | ||
14.5.1 タイミング間違い | マクロ内ではなく展開形で作業を行う。 | |
14.5.2 マクロ引数の多重評価 | 展開形は各マクロ引数を一度評価すること。 | |
14.5.3 マクロ展開でのローカル変数 | 展開形でのローカル変数バインディングには特に注意を要する。 | |
14.5.4 展開におけるマクロ引数の評価 | 評価せずに展開形の中に配置すること。 | |
14.5.5 マクロが展開される回数は? | 展開が行われる回数への依存を避ける。 | |
Customization Settings | ||
15.1 一般的なキーワードアイテム | すべての種類のカスタマイズ宣言に共通なキーワード引数。 | |
15.2 カスタマイゼーショングループの定義 | カスタマイズグループ定義の記述。 | |
15.3 カスタマイゼーション変数の定義 | ユーザーオプションの宣言。 | |
15.4 カスタマイゼーション型 | ユーザーオプションの型指定。 | |
15.5 カスタマイゼーションの適用 | カスタマイズセッティングを適用する関数。 | |
15.6 Customテーマ | カスタムテーマの記述。 | |
Customization Types | ||
15.4.1 単純型 | シンプルなカスタマイズ型(sexp、integerなど)。 | |
15.4.2 複合型 | 他の型やデータから新しい型を構築する。 | |
15.4.3 リストへのスプライス | :inline で要素をリストに結合する。
| |
15.4.4 型キーワード | カスタマイズ型でのキーワード/引数ペアー | |
15.4.5 新たな型の定義 | 型に名前をつける。 | |
Loading | ||
16.1 プログラムがロードを行う方法 | load ’関数、その他。
| |
16.2 ロードでの拡張子 | load ’が試みられるサフィックスについての詳細。
| |
16.3 ライブラリー検索 | ロードするライブラリーの検索。 | |
16.4 非ASCII文字のロード | Emacs Lispファイル内の非ASCII文字。 | |
16.5 autoload | オートロードのための関数のセットアップ。 | |
16.6 多重ロード | ファイルを2度ロードする場合の配慮。 | |
16.7 名前つき機能 | まだロードされていないライブラリーのロード。 | |
16.8 どのファイルで特定のシンボルが定義されているか | 特定のシンボルがどのファイルで定義されているかの検索。 | |
16.9 アンロード | ロードされたライブラリーをunloadする方法。 | |
16.10 ロードのためのフック | 特定のライブラリーがロードされたとき実行されるコードの提供。 | |
16.11 Emacsのダイナミックモジュール | Modules provide additional Lisp primitives. | |
Byte Compilation | ||
17.1 バイトコンパイル済みコードのパフォーマンス | バイトコンパイルによるスピードアップ例。 | |
17.2 バイトコンパイル関数 | ||
17.3 ドキュメント文字列とコンパイル | ドキュメント文字列のダイナミックロード。 | |
17.4 個々の関数のダイナミックロード | ||
17.5 コンパイル中の評価 | コンパイル時に評価されるコード。 | |
17.6 コンパイラーのエラー | コンパイラーのエラーメッセージの扱い。 | |
17.7 バイトコード関数オブジェクト | バイトコンパイル済み関数に使用されるデータ型。 | |
17.8 逆アセンブルされたバイトコード | バイトコードの逆アセンブル。バイトコードの読み方。 | |
Native Compilation | ||
18.1 ネイティブコンパイル関数 | Functions to natively-compile Lisp. | |
18.2 ネイティブコンパイル関数 | Variables controlling native compilation. | |
Debugging Lisp Programs | ||
19.1 Lispデバッガ | Emacs Lisp評価機能にたいするデバッガ。 | |
19.2 Edebug | Emacs Lispソースレベルデバッガ。 | |
19.3 無効なLisp構文のデバッグ | シンタックスエラーを見つける方法。 | |
19.4 カバレッジテスト | プログラムのすべての分岐を確実にテストする。 | |
19.5 プロファイリング | あなたのコードが使用するリソースの計測。 | |
The Lisp Debugger | ||
19.1.1 エラーによるデバッガへのエンター | エラー発生時にデバッガにエンターする。 | |
19.1.3 無限ループのデバッグ | exitしないプログラムの停止デバッグ。 | |
19.1.4 関数呼び出しによるデバッガへのエンター | 特定の関数が呼び出されたときにデバッガにエンターする。 | |
19.1.5 変数の変更時にデバッガにエンターする。 | Entering it when a variable is modified. | |
19.1.6 明示的なデバッガへのエントリー | プログラム内の特定箇所でデバッガにエンターする。 | |
19.1.7 デバッガの使用 | What the debugger does. | |
19.1.8 バックトレース | What you see while in the debugger. | |
19.1.9 デバッガのコマンド | デバッガで使用するコマンド。 | |
19.1.10 デバッガの呼び出し | 関数debug の呼び出し方。
| |
19.1.11 デバッガの内部 | デバッガのサブルーチン、およびグローバル変数。 | |
Edebug | ||
19.2.1 Edebugの使用 | Edebug使用のための手引き。 | |
19.2.2 Edebugのためのインストルメント | Edebugでデバッグするために、コードをインストルメント(計装)しなければならないe | |
19.2.3 Edebugの実行モード | 多かれ少なかれ、ストップする実行モード。 | |
19.2.4 ジャンプ | 特定の位置にジャンプするコマンド。 | |
19.2.5 その他のEdebugコマンド | さまざまなコマンド。 | |
19.2.6 ブレーク | プログラムをストップさせるbreakpointのセット。 | |
19.2.7 エラーのトラップ | Edebugでのエラーのトラップ。 | |
19.2.8 Edebugのビュー | Edebugの内側と外側のビュー。 | |
19.2.9 評価 | Edebugでの式の評価。 | |
19.2.10 評価リストバッファー | Edebugにエンターするたびに値が表示される式。 | |
19.2.11 Edebugでのプリント | プリントのカスタマイズ。 | |
19.2.12 トレースバッファー | バッファー内で採れを生成する方法。 | |
19.2.13 カバレッジテスト | 評価をカバレッジテストする方法。 | |
19.2.14 コンテキスト外部 | Edebugが保存およびリストアするデータ。 | |
19.2.15 Edebugとマクロ | マクロ呼び出しをハンドルする方法の指定。 | |
19.2.16 Edebugのオプション | Edebugをカスタマイズするオプション変数。 | |
Breaks | ||
19.2.6.1 Edebugのブレークポイント | ストップポイントのbreakpoint。 | |
19.2.6.2 グローバルなブレーク条件 | イベントによるbreak。 | |
19.2.6.3 ソースブレークポイント | ソースコードに埋め込まれたbreakpoint。 | |
The Outside Context | ||
19.2.14.1 停止するかどうかのチェック | 何を行うかをEdebugが決定するタイミング。 | |
19.2.14.2 Edebugの表示の更新 | Edebugがディスプレイを更新するタイミング。 | |
19.2.14.3 Edebugの再帰編集 | Edebugが実行をストップするタイミング。 | |
Edebug and Macros | ||
19.2.15.1 マクロ呼び出しのインストルメント | 基本的な問題点。 | |
19.2.15.2 仕様リスト | 式の複雑なパターンを指定する方法。 | |
19.2.15.3 仕様でのバックトレース | マッチに失敗したときEdebugが行なうこと。 | |
19.2.15.4 仕様の例 | Edebug仕様を理解するために。 | |
Debugging Invalid Lisp Syntax | ||
19.3.1 過剰な開カッコ | 誤った開カッコと閉カッコを探す方法。 | |
19.3.2 過剰な閉カッコ | 誤った閉カッコと開カッコを探す方法。 | |
Reading and Printing Lisp Objects | ||
20.1 読み取りとプリントの概念 | ストリーム、読み取り、プリントの概観。 | |
20.2 入力ストリーム | 入力ストリームとして使用できる、さまざまなデータ型。 | |
20.3 入力関数 | テキストからLispオブジェクトを読み取る関数。 | |
20.4 出力ストリーム | 出力ストリームとして使用できる、さまざまなデータ型。 | |
20.5 出力関数 | テキストとしてLispオブジェクトをプリントする関数。 | |
20.6 出力に影響する変数 | プリント関数が何を行うか制御する変数。 | |
20.7 出力変数のオーバーライド | Overriding output variables. | |
Minibuffers | ||
21.1 ミニバッファーの概要 | ミニバッファーに関する基本的な情報。 | |
21.2 ミニバッファーでのテキスト文字列の読み取り | そのままのテキスト文字列を読み取る方法。 | |
21.3 ミニバッファーでのLispオブジェクトの読み取り | Lispオブジェクトや式を読み取る方法。 | |
21.4 ミニバッファーのヒストリー | ユーザーが再利用できるように以前のミニバッファー入力は記録される。 | |
21.5 入力の初期値 | ミニバッファーにたいして初期内容を指定する。 | |
21.6 補完 | 補完の呼び出しとカスタマイズ方法。 | |
21.7 Yes-or-Noによる問い合わせ | 問いにたいし単純な答えを求める。 | |
21.8 複数の問いを尋ねる | 一連の似たような問いに答える。 | |
21.9 パスワードの読み取り | 端末からパスワードを読み取る。 | |
21.10 ミニバッファーのコマンド | ミニバッファー内でキーバインドとして使用されるコマンド。 | |
21.11 ミニバッファーのウィンドウ | 特殊なミニバッファーウィンドウを処理する。 | |
21.12 ミニバッファーのコンテンツ | どのようなコマンドがミニバッファーのテキストにアクセスするか。 | |
21.13 再帰的なミニバッファー | ミニバッファーへの再帰的なエントリーが許容されるかどうか。 | |
21.14 対話の抑止 | Running Emacs when no interaction is possible. | |
21.15 ミニバッファー、その他の事項 | カスタマイズ用のさまざまなフックや変数。 | |
Completion | ||
21.6.1 基本的な補完関数 | 文字列を補完する低レベル関数。 | |
21.6.2 補完とミニバッファー | 補完つきでミニバッファーを呼び出す。 | |
21.6.3 補完を行うミニバッファーコマンド | ||
21.6.4 高レベルの補完関数 | 特別なケースに有用な補完(バッファー名や変数名などの読み取り)。 | |
21.6.5 ファイル名の読み取り | ファイル名やシェルコマンドの読み取りに補完を使用する。 | |
21.6.6 補完変数 | 補完の挙動を制御する変数。 | |
21.6.7 プログラムされた補完 | 独自の補完関数を記述する。 | |
21.6.8 通常バッファーでの補完 | 通常バッファー内でのテキスト補完。 | |
Command Loop | ||
22.1 コマンドループの概要 | コマンドループがコマンドを読み取る方法。 | |
22.2 コマンドの定義 | 関数が引数を読み取る方法を指定する。 | |
22.3 インタラクティブな呼び出し | 引数を読み取るようにコマンドを呼び出す。 | |
22.4 インタラクティブな呼び出しの区別 | インタラクティブな呼び出しとコマンドを区別する。 | |
22.5 コマンドループからの情報 | 検証用にコマンドループによりセットされる変数。 | |
22.6 コマンド後のポイントの調整 | コマンドの後にポイント位置を調整する。 | |
22.7 入力イベント | 入力を読み取るとき、入力がどのように見えるか。 | |
22.8 入力の読み取り | キーボードやマウスからの入力イベントを読み取る方法。 | |
22.9 スペシャルイベント | 即座かつ個別に処理されるイベント。 | |
22.10 時間の経過や入力の待機 | ユーザー入力または経過時間の待機。 | |
22.11 quit | C-g’が機能する方法。quitをcatchまたは延期する方法。 | |
22.12 プレフィクスコマンド引数 | コマンドがプレフィクス引数が機能するようにセットするための方法。 | |
22.13 再帰編集 | 再帰編集へのエンター、なぜ通常は再帰編集を行うべきでないのか。 | |
22.14 コマンドの無効化 | コマンドループが無効なコマンドを扱う方法。 | |
22.15 コマンドのヒストリー | コマンドヒストリーがセットアップされる方法と、どのようにアクセスされるか。 | |
22.16 キーボードマクロ | キーボードマクロが実装される方法。 | |
Defining Commands | ||
22.2.1 interactive の使用 | interactive ’にたいする一般的なルール。
| |
22.2.2 interactive にたいするコード文字 | さまざまな方法で引数を読み取る標準的な文字のコード。 | |
22.2.3 interactive の使用例 | インタラクティブ引数を読み取る方法の例。 | |
22.2.4 コマンドにたいするモード指定 | Specifying that commands are for a specific mode. | |
22.2.5 コマンド候補からの選択 | ||
Input Events | ||
22.7.1 キーボードイベント | Ordinary characters – keys with symbols on them. | |
22.7.2 ファンクションキー | Function keys – keys with names, not symbols. | |
22.7.3 マウスイベント | マウスイベントの概観。 | |
22.7.4 クリックイベント | マウスボタンのプッシュとリリース。 | |
22.7.5 ドラッグイベント | ボタンをリリースする前のマウス移動。 | |
22.7.6 ボタンダウンイベント | ボタンがプッシュされて、まだリリースされていない状態。 | |
22.7.7 リピートイベント | ダブル、トリプルのクリック(またはドラッグ、ダウン) | |
22.7.8 モーションイベント | ボタンを押さずに、マウスだけを移動する。 | |
22.7.10 フォーカスイベント | フレーム間のマウス移動。 | |
22.7.12 その他のシステムイベント | システムが生成可能なその他のイベント。 | |
22.7.13 イベントの例 | マウスイベントの例。 | |
22.7.14 イベントの分類 | イベントシンボル内の修飾キーを見つける。イベント型。 | |
22.7.15 マウスイベントへのアクセス | マウスイベントから情報抽出する関数。 | |
22.7.16 スクロールバーイベントへのアクセス | スクロールバーイベントから情報取得する関数。 | |
22.7.17 文字列内へのキーボードイベントの配置 | 文字列内にキーボード文字イベントを配すための特別な配慮。 | |
Reading Input | ||
22.8.1 キーシーケンス入力 | キーシーケンスを読み取る方法。 | |
22.8.2 単一イベントの読み取り | イベントを1つだけ読み取る方法。 | |
22.8.3 入力イベントの変更と変換 | Emacsが読み取られたイベントを変更する方法。 | |
22.8.4 入力メソッドの呼び出し | 入力メソッドを使用するイベントを読み取る方法。 | |
22.8.5 クォートされた文字の入力 | 文字の指定をユーザーに問い合わせる。 | |
22.8.6 その他のイベント入力の機能 | 入力イベントの最読み取りや破棄の方法。 | |
Keymaps | ||
23.1 キーシーケンス | Lispオブジェクトとしてのキーシーケンス。 | |
23.2 キーマップの基礎 | キーマップの基本概念。 | |
23.3 キーマップのフォーマット | キーマップはLispオブジェクトとしてどのように見えるか。 | |
23.4 キーマップの作成 | キーマップを作成、コピーする関数。 | |
23.5 継承とキーマップ | キーマップが他のキーマップのバインディングを継承する方法。 | |
23.6 プレフィクスキー | キーマップの定義としてキーを定義する。 | |
23.7 アクティブなキーマップ | Emacsがアクティブなキーマップでキーバインディングを探す方法。 | |
23.8 アクティブなキーマップの検索 | アクティブなマップ検索のLisp処理概要。 | |
23.9 アクティブなキーマップの制御 | 各バッファーは標準(グローバル)のバインディングをオーバーライドするためのキーマップをもつ。マイナーモードもそれらをオーバーライドできる。 | |
23.10 キーの照合 | 1つのキーマップから、あるキーのバインディングを探す。 | |
23.11 キー照合のための関数 | キールックアップを要求する方法。 | |
23.12 キーバインディングの変更 | キーマップ内でのキーの再定義。 | |
23.13 低レベルなキーバインディング | Legacy key syntax description. | |
23.14 コマンドのリマップ | キーマップはあるコマンドを他のコマンドに変換できる。 | |
23.15 イベントシーケンス変換のためのキーマップ | イベントシーケンスを変換するキーマップ。 | |
23.16 キーのバインドのためのコマンド | キーの再定義にたいするインタラクティブなインターフェイス。 | |
23.17 キーマップのスキャン | ヘルプをプリントするためにすべてのキーマップを走査する。 | |
23.18 メニューキーアップ | キーマップとしてキーマップを定義する。 | |
Menu Keymaps | ||
23.18.1 メニューの定義 | メニューを定義するキーマップを作成する方法。 | |
23.18.2 メニューとマウス | ユーザーがマウスでメニューを操作する方法。 | |
23.18.3 メニューとキーボード | ユーザーがキーボードでメニューを操作する方法。 | |
23.18.4 メニューの例 | シンプルなメニューの作成。 | |
23.18.5 メニューバー | メニューバーのカスタマイズ方法。 | |
23.18.6 ツールバー | イメージ行のツールバー。 | |
23.18.7 メニューの変更 | メニューへ新たなアイテムを追加する方法。 | |
23.18.8 easy-menu | メニュー作成のための便利なマクロ。 | |
Defining Menus | ||
23.18.1.1 単純なメニューアイテム | 単純なメニューのキーバインディング。 | |
23.18.1.2 拡張メニューアイテム | 複雑なメニューアイテムの定義。 | |
23.18.1.3 メニューセパレーター | メニューに水平ラインを描画する。 | |
23.18.1.4 メニューアイテムのエイリアス | メニューアイテムにコマンドエイリアスを使用する。 | |
Major and Minor Modes | ||
24.1 フック | フックの使い方と、フックを提供するコードの記述方法。 | |
24.2 メジャーモード | メジャーモードの定義。 | |
24.3 マイナーモード | マイナーモードの定義。 | |
24.4 モードラインのフォーマット | モードラインに表示されるテキストのカスタマイズ。 | |
24.5 Imenu | バッファーで作成された定義のメニューを提供する。 | |
24.6 Font Lockモード | モードが構文に応じてテキストをハイライトする方法。 | |
24.7 コードの自動インデント | メジャーモードにたいするインデントをEmacsに伝える方法。 | |
24.8 Desktop Saveモード | Emacsセッション間でモードがバッファー状態を保存する方法。 | |
Hooks | ||
24.1.1 フックの実行 | フックの実行方法。 | |
24.1.2 フックのセット | 関数をフックに登録、削除する方法。 | |
Major Modes | ||
24.2.1 メジャーモードの慣習 | キーマップなどにたいするコーディング規約。 | |
24.2.2 Emacsがメジャーモードを選択する方法 | Emacsが自動的にメジャーモードを選択する方法。 | |
24.2.3 メジャーモードでのヘルプ入手 | モードの使用方法の探し方。 | |
24.2.4 派生モードの定義 | 他のメジャーモードにもとづき新たなメジャーモードを定義する。 | |
24.2.5 基本的なメジャーモード | 他のモードからよく派生元とされるモード。 | |
24.2.6 モードフック | メジャーモード関数の最後に実行されるフック。 | |
24.2.7 Tabulated Listモード | 表形式データを含むバッファーにたいする親モード。 | |
24.2.8 ジェネリックモード | コメント構文とFont | |
24.2.9 メジャーモードの例 | TextモードとLispモード。 | |
Minor Modes | ||
24.3.1 マイナーモード記述の規約 | マイナーモードを記述するためのTips。 | |
24.3.2 キーマップとマイナーモード | マイナーモードが自身のキーマップをもつための方法。 | |
24.3.3 マイナーモードの定義 | マイナーモードを定義するための便利な機能。 | |
Mode Line Format | ||
24.4.1 モードラインの基礎 | モードライン制御の基本概念。 | |
24.4.2 モードラインのデータ構造 | モードラインを制御するデータ構造。 | |
24.4.3 モードライン制御のトップレベル | トップレベル変数、mode-line-format。 | |
24.4.4 モードラインで使用される変数 | そのデータ構造で使用される変数。 | |
24.4.5 モードラインでの% 構文 | モードラインへの情報の配置。 | |
24.4.6 モードラインでのプロパティ | モードライン内でのテキストプロパティの使用。 | |
24.4.7 ウィンドウのヘッダーライン | モードラインに類似した最上部のライン。 | |
24.4.8 モードラインのフォーマットのエミュレート | モードラインのようにテキストをフォーマットする。 | |
Font Lock Mode | ||
24.6.1 Font Lockの基礎 | Font Lockカスタマイズの概要。 | |
24.6.2 検索ベースのフォント化 | 正規表現にもとづくフォント表示。 | |
24.6.3 検索ベースのフォント化のカスタマイズ | 検索ベースフォント表示のカスタマイズ。 | |
24.6.4 Font Lockのその他の変数 | 追加のカスタマイズ機能。 | |
24.6.5 Font Lockのレベル | 多なりとも少ユーザーが選択できるように、それぞれのモードは代替レベルを定義できる。 | |
24.6.6 事前計算されたフォント化 | バッファーコンテンツを生成するLispプログラムが、どのようにしてそれをフォント表示する方法も指定できるか。 | |
24.6.7 Font Lockのためのフェイス | Font Lockにたいする具体的な特殊フェイス。 | |
24.6.8 構文的なFont Lock | 構文テーブルにもとづくフォント表示。 | |
24.6.9 複数行のFont Lock構造 | Font Lockに複数行構成の正しいハイライトを強制する方法。 | |
24.6.10 パーサーベースのFont Lock | Use parse data for fontification. | |
Multiline Font Lock Constructs | ||
24.6.9.1 複数行のFont Lock | テキストプロパティで複数行塊をマークする。 | |
24.6.9.2 バッファー変更後のリージョンのフォント化 | バッファー変更後にどのリージョンを再フォント表示するかを制御する。 | |
Automatic Indentation of code | ||
24.7.1 SMIE: 無邪気なインデントエンジン | SMIE: Simple Minded Indentation Engine(純真なインデントエンジン)。 | |
24.7.2 パーサーベースのインデント | Parser-based indentation engine. | |
Simple Minded Indentation Engine | ||
24.7.1.1 SMIEのセットアップと機能 | ||
24.7.1.2 演算子順位文法 | 非常にシンプルなパース技術。 | |
24.7.1.3 言語の文法の定義 | 言語の文法を定義する。 | |
24.7.1.4 トークンの定義 | ||
24.7.1.5 非力なパーサーと歩む | パーサー制限の回避策。 | |
24.7.1.6 インデントルールの指定 | ||
24.7.1.7 インデントルールにたいするヘルパー関数 | ||
24.7.1.8 インデントルールの例 | ||
24.7.1.9 インデントのカスタマイズ | ||
Documentation | ||
25.1 ドキュメントの基礎 | ドキュメント文字列が定義、格納される場所。 | |
25.2 ドキュメント文字列へのアクセス | Lispプログラムがドキュメント文字列にアクセスする方法。 | |
25.3 ドキュメント内でのキーバインディングの置き換え | カレントキーバインディングの置き換え。 | |
25.4 テキストのクォートスタイル | Quotation marks in doc strings and messages. | |
25.5 ヘルプメッセージの文字記述 | 非プリント文字やキーシーケンスをプリント可能な記述にする。 | |
25.6 ヘルプ関数 | Emacsヘルプ機能により使用されるサブルーチン。 | |
Files | ||
26.1 ファイルのvisit | 編集のためにEmacsバッファーにファイルを読み込む。 | |
26.2 バッファーの保存 | 変更されたバッファーをファイルに書き戻す。 | |
26.3 ファイルからの読み込み | ファイルをvisitせずにバッファーに読み込む。 | |
26.4 ファイルへの書き込み | バッファーの一部から新たなファイルに書き込む。 | |
26.5 ファイルのロック | 複数名による同時編集を防ぐためにファイルをlockまたはunlockする。 | |
26.6 ファイルの情報 | ファイルの存在、アクセス権、サイズのテスト。 | |
26.7 ファイルの名前と属性の変更 | ファイル名のリネームやパーミッションの変更など。 | |
26.9 ファイルの名前 | ファイル名の分解と展開。 | |
26.10 ディレクトリーのコンテンツ | ディレクトリーないのファイルリストの取得。 | |
26.11 ディレクトリーの作成・コピー・削除 | ディレクトリーの作成と削除。 | |
26.12 特定のファイル名の“Magic”の作成 | 特定のファイル名にたいする特別な処理。 | |
26.13 ファイルのフォーマット変換 | さまざまなファイルフォーマットへ/からの変換。 | |
Visiting Files | ||
26.1.1 ファイルをvisitする関数 | visit用の通常のインターフェイス関数。 | |
26.1.2 visitのためのサブルーチン | 通常のvisit関数が使用する低レベルのサブルーチン。 | |
Information about Files | ||
26.6.1 アクセシビリティのテスト | そのファイルは読み取り可能か?書き込み可能か? | |
26.6.2 ファイル種別の区別 | それはディレクトリー?それともシンボリックリンク? | |
26.6.3 本当の名前 | シンボリックリンクが行き着くファイル名。 | |
26.6.4 ファイルの属性 | ファイルのサイズ?更新日時など。 | |
26.6.5 拡張されたファイル属性 | アクセス制御にたいするファイル属性の拡張。 | |
26.6.6 標準的な場所へのファイルの配置 | 標準的な場所でファイルを見つける方法。 | |
File Names | ||
26.9.1 ファイル名の構成要素 | ファイル名のディレクトリー部分と、それ以外。 | |
26.9.2 絶対ファイル名と相対ファイル名 | カレントディレクトリーにたいして相対的なファイル名。 | |
26.9.3 ディレクトリーの名前 | ディレクトリーとしてのディレクトリー名と、ファイルとしてのファイル名の違い。 | |
26.9.4 ファイル名を展開する関数 | 相対ファイル名から絶対ファイル名への変換。 | |
26.9.5 一意なファイル名の生成 | 一時ファイル用の名前の生成。 | |
26.9.6 ファイル名の補完 | 与えられたファイル名にたいする補完を探す。 | |
26.9.7 標準的なファイル名 | パッケージが固定されたファイル名を使用する際に、種々のオペレーティングシステムをシンプルに処理する方法。 | |
File Format Conversion | ||
26.13.1 概要 | insert-file-contents とwrite-region 。
| |
26.13.2 ラウンドトリップ仕様 | format-alist の使用。
| |
26.13.3 漸次仕様 | 非ペアー変換の指定。 | |
Backups and Auto-Saving | ||
27.1 ファイルのバックアップ | バックアップファイルの作成と名前選択の方法。 | |
27.2 自動保存 | auto-saveファイルの作成と名前選択の方法。 | |
27.3 リバート | revert-buffer とその動作のカスタマイズ方法。
| |
Backup Files | ||
27.1.1 バックアップファイルの作成 | Emacsがバックアップファイルを作成する方法とタイミング。 | |
27.1.2 リネームかコピーのどちらでバックアップするか? | 2つの選択肢: 古いファイルのリネームとコピー。 | |
27.1.3 番号つきバックアップファイルの作成と削除 | ソースファイルごとに複数のバックアップを保持する。 | |
27.1.4 バックアップファイルの命名 | バックアップファイル名の計算方法とカスタマイズ。 | |
Buffers | ||
28.1 バッファーの基礎 | バッファーとは? | |
28.2 カレントバッファー | バッファーをカレントに指定することにより、プリミティブはバッファーのコンテンツにアクセスする。 | |
28.3 バッファーの名前 | バッファー名にたいするアクセスと変更。 | |
28.4 バッファーのファイル名 | バッファーファイル名は、どのファイルをvisitしているかを示す。 | |
28.5 バッファーの変更 | 保存が必要なら、バッファーは“変更されている(modified)”。 | |
28.6 バッファーの変更時刻 | Determining whether the visited file was changed behind Emacs’s back. | |
28.7 読み取り専用のバッファー | 読み取り専用バッファーでのテキスト変更は許されない。 | |
28.8 バッファーリスト | すべての既存バッファーを閲覧する方法。 | |
28.9 バッファーの作成 | バッファーを作成する関数。 | |
28.10 バッファーのkill | 明示的にkillされるまで、バッファーは存在する。 | |
28.11 インダイレクトバッファー | インダイレクトバッファーは、他のバッファーとテキストを共有する。 | |
28.12 2つのバッファー間でのテキストの交換 | ||
28.13 バッファーのギャップ | バッファー内のギャップ。 | |
Windows | ||
29.1 Emacsウィンドウの基本概念 | ウィンドウ使用についての基本情報。 | |
29.2 ウィンドウとフレーム | ウィンドウとそれらが表示されるフレームとの関連。 | |
29.3 ウィンドウの選択 | 選択されたウィンドウとは、編集を行っているウィンドウである。 | |
29.4 ウィンドウのサイズ | ウィンドウのサイズへのアクセス。 | |
29.5 ウィンドウのリサイズ | ウィンドウのサイズの変更。 | |
29.6 ウィンドウサイズの保持 | Preserving the size of windows. | |
29.7 ウィンドウの分割 | 新たなウィンドウの作成。 | |
29.8 ウィンドウの削除 | フレームからのウィンドウの削除。 | |
29.9 ウィンドウの再結合 | ウィンドウの分割や削除時のフレームレイアウトの保存。 | |
29.10 ウィンドウのサイクル順 | 既存のウィンドウ間の移動。 | |
29.11 バッファーとウィンドウ | それぞれのウィンドウは、バッファーのコンテンツを表示する。 | |
29.12 ウィンドウ内のバッファーへの切り替え | バッファー切り替えのための、より高レベルな関数。 | |
29.13 適切なウィンドウへのバッファーの表示 | Displaying a buffer in a suitable window. | |
29.14 ウィンドウのヒストリー | それぞれのウィンドウは、表示されていたバッファーを記憶する。 | |
29.15 専用のウィンドウ | 特定のウィンドウ内で他のバッファーの表示を無効にする。 | |
29.16 ウィンドウのquit | 以前に表示していたバッファーの状態をリストアする方法。 | |
29.17 サイドウィンドウ | Special windows on a frame’s sides. | |
29.18 アトミックウィンドウ | Preserving parts of the window layout. | |
29.19 ウィンドウとポイント | それぞれのウィンドウは、自身の位置とポイントをもつ。 | |
29.20 ウィンドウの開始位置と終了位置 | ウィンドウ内でスクリーン表示されるテキストを表すバッファー位置。 | |
29.21 テキスト的なスクロール | ウィンドウを通じたテキストの上下移動。 | |
29.22 割り合いによる垂直スクロール | ウィンドウ上のコンテンツの上下移動。 | |
29.23 水平スクロール | ウィンドウ上のコンテンツの横移動。 | |
29.24 座標とウィンドウ | 座標からウィンドウへの変換。 | |
29.25 マウスによるウィンドウの自動選択 | Automatically selecting windows with the mouse. | |
29.26 ウィンドウの構成 | スクリーンの情報の保存とリストア。 | |
29.27 ウィンドウのパラメーター | ウィンドウへの追加情報の割り当て。 | |
29.28 ウィンドウのスクロールと変更のためのフック | スクロール、ウィンドウのサイズ変更、ある特定のしきい値を超えたときに行われる再表示、ウィンドウ構成の変更にたいするフック。 | |
Displaying Buffers | ||
29.13.1 バッファーを表示するウィンドウの選択 | バッファーを表示するウィンドウの選択方法。 | |
29.13.2 バッファー表示用のアクション関数 | Support functions for buffer display. | |
29.13.3 バッファー表示用のアクションalist | Alists for fine-tuning buffer display action functions. | |
29.13.4 バッファー表示の追加オプション | バッファー表示方法に影響する拡張オプション。 | |
29.13.5 アクション関数の優先順 | A tutorial explaining the precedence of buffer display action functions. | |
29.13.6 バッファー表示の思想 | How to avoid that buffers get lost in between windows. | |
Side Windows | ||
29.17.1 サイドウィンドウへのバッファーの表示 | An action function for displaying buffers in side windows. | |
29.17.2 サイドウィンドウのオプションと関数 | Further tuning of side windows. | |
29.17.3 サイドウィンドウによるフレームのレイアウト | Setting up frame layouts with side windows. | |
Frames | ||
30.1 フレームの作成 | 追加のフレームの作成。 | |
30.2 複数の端末 | 異なる複数デバイス上での表示。 | |
30.3 フレームのジオメトリー | Geometric properties of frames. | |
30.4 フレームのパラメーター | フレームのサイズ、位置、フォント等の制御。 | |
30.5 端末のパラメーター | 端末上のすべてのフレームにたいして一般的なパラメーター。 | |
30.6 フレームのタイトル | フレームタイトルの自動的な更新。 | |
30.7 フレームの削除 | 明示的に削除されるまでフレームは存続する。 | |
30.8 すべてのフレームを探す | すべての既存フレームを調べる方法。 | |
30.9 ミニバッファーとフレーム | フレームが使用するミニバッファーを見つける方法。 | |
30.10 入力のフォーカス | 選択されたフレームの指定。 | |
30.11 フレームの可視性 | フレームは可視、不可視、またはアイコン化されているかもしれない。 | |
30.12 フレームのraise、lower、re-stack | Raising, Lowering and Restacking Frames. | |
30.13 フレーム構成 | すべてのフレームの状態の保存。 | |
30.14 子フレーム | Making a frame the child of another. | |
30.15 マウスの追跡 | マウス移動時のイベントの取得。 | |
30.16 マウスの位置 | マウスの場所や移動を問い合わせる。 | |
30.17 ポップアップメニュー | ユーザーに選択させるためのメニューの表示。 | |
30.18 ダイアログボックス | yes/noを問い合わせるためのボックスの表示。 | |
30.19 ポインターの形状 | マウスポインターのシェイプの指定。 | |
30.20 ウィンドウシステムによる選択 | 他のXクライアントとのテキストの転送。 | |
30.21 メディアのyank | Yanking things that aren’t plain text. | |
30.22 ドラッグアンドドロップ | ドラッグアンドドロップの実装の内部。 | |
30.23 カラー名 | カラー名定義の取得。 | |
30.24 テキスト端末のカラー | テキスト端末のカラーの定義。 | |
30.25 Xリソース | サーバーからのリソース値の取得。 | |
30.26 ディスプレイ機能のテスト | 端末の機能の判定。 | |
Frame Geometry | ||
30.3.1 フレームのレイアウト | Basic layout of frames. | |
30.3.2 フレームのフォント | The default font of a frame and how to set it. | |
30.3.3 フレームの位置 | The position of a frame on its display. | |
30.3.4 フレームのサイズ | Specifying and retrieving a frame’s size. | |
30.3.5 フレームの暗黙的なリサイズ | Implied resizing of frames and how to prevent it. | |
Frame Parameters | ||
30.4.1 フレームパラメーターへのアクセス | フレームのパラメーターの変更方法。 | |
30.4.2 フレームの初期パラメーター | フレーム作成時に指定するフレームパラメーター。 | |
30.4.3 ウィンドウフレームパラメーター | ウィンドウシステムにたいするフレームパラメーターのリスト。 | |
30.4.4 ジオメトリー | ジオメトリー仕様の解析。 | |
Window Frame Parameters | ||
30.4.3.1 基本パラメーター | 基本的なパラメーター。 | |
30.4.3.2 位置のパラメーター | スクリーン上のフレームの位置。 | |
30.4.3.3 サイズのパラメーター | フレームのサイズ。 | |
30.4.3.4 レイアウトのパラメーター | フレームのパーツのサイズと、一部パーツの有効化と無効化。 | |
30.4.3.5 バッファーのパラメーター | 表示済みまたは表示されるべきバッファーはどれか。 | |
30.4.3.6 フレームとの相互作用のためのパラメーター | Parameters for interacting with other frames. | |
30.4.3.7 マウスドラッグのパラメーター | Parameters for resizing and moving frames with the mouse. | |
30.4.3.8 ウィンドウ管理のパラメーター | ウィンドウマネージャーとの対話。 | |
30.4.3.9 カーソルのパラメーター | カーソルの外見の制御。 | |
30.4.3.10 フォントとカラーのパラメーター | フレームテキストにたいするフォントとカラー。 | |
Positions | ||
31.1 ポイント | 編集タスクが行われる特別な位置。 | |
31.2 モーション | ポイントの変更。 | |
31.3 エクスカーション | 一時的な移動とバッファーの変更。 | |
31.4 ナローイング | バッファーの一部に編集を限定する。 | |
Motion | ||
31.2.1 文字単位の移動 | 文字単位での移動。 | |
31.2.2 単語単位の移動 | 単語単位での移動。 | |
31.2.3 バッファー終端への移動 | バッファー先頭または終端への移動。 | |
31.2.4 テキスト行単位の移動 | テキスト行単位での移動。 | |
31.2.5 スクリーン行単位の移動 | 表示される行単位での移動。 | |
31.2.6 釣り合いのとれたカッコを越えた移動 | リストやS式の解析による移動。 | |
31.2.7 文字のスキップ | 特定の集合に属す文字のスキップ。 | |
Markers | ||
32.1 マーカーの概要 | マーカー構成要素と再配置方法。 | |
32.2 マーカーのための述語 | オブジェクトがマーカーか否かのテスト。 | |
32.3 マーカーを作成する関数 | 空マーカーや特定箇所のマーカーの作成。 | |
32.4 マーカーからの情報 | マーカーのバッファーや文字位置を探す。 | |
32.5 マーカーの挿入タイプ | マーカーが指す位置への挿入時にマーカーを再配置する2つの方法。 | |
32.6 マーカー位置の移動 | 新たなバッファーや位置にマーカーを移動する。 | |
32.7 マーク | How the mark is implemented with a marker. | |
32.8 リージョン | How to access the region. | |
Text | ||
33.1 ポイント近傍のテキストを調べる | ポイント付近のテキストを調べる。 | |
33.2 バッファーのコンテンツを調べる | 一般的な方法によってテキストを調べる。 | |
33.3 テキストの比較 | バッファーの部分文字列を比較する。 | |
33.4 テキストの挿入 | バッファーへの新たなテキストの追加。 | |
33.5 ユーザーレベルの挿入コマンド | テキスト挿入のためのユーザーレベルコマンド。 | |
33.6 テキストの削除 | バッファーからテキストを削除する。 | |
33.7 ユーザーレベルの削除コマンド | テキスト削除のためのユーザーレベルコマンド。 | |
33.8 killリング | テキスト削除時にユーザーのためにそれを保存する場所。 | |
33.9 アンドゥ | バッファーのテキストにたいする変更の取り消し。 | |
33.10 アンドゥリストの保守 | undo情報の有効と無効。情報をどれだけ保持するか制御する方法。 | |
33.11 fill | 明示的にフィルを行う関数。 | |
33.12 fillのマージン | フィルコマンドにたいしてマージンを指定する方法。 | |
33.13 Adaptive Fillモード | コンテキストからフィルプレフィクスを選択するAdaptive | |
33.14 オートfill | 行ブレークにたいするauto-fillの実装方法。 | |
33.15 テキストのソート | バッファーの一部をソートする関数。 | |
33.16 列を数える | 水平位置の計算とその使用方法。 | |
33.17 インデント | インデントの挿入や調整のための関数。 | |
33.18 大文字小文字の変更 | バッファーの一部にたいするcase変換。 | |
33.19 テキストのプロパティ | テキスト文字にたいするLispプロパティリストの追加。 | |
33.20 文字コードの置き換え | 与ええられた文字の出現箇所を置換する。 | |
33.21 レジスター | レジスターの実装方法。レジスターに格納されたテキストや位置にアクセスする。 | |
33.22 テキストの交換 | バッファーの2つの部分を交換する。 | |
33.24 圧縮されたデータの処理 | 圧縮データの扱い。 | |
33.25 Base 64エンコーディング | Base64エンコーディングとの変換。 | |
33.26 チェックサムとハッシュ | 暗号ハッシュの計算。 | |
33.27 不審なテキスト | Determining whether a string is suspicious. | |
33.28 GnuTLS暗号化 | Cryptographic algorithms imported from GnuTLS. | |
33.29 データベース | Interacting with an SQL database. | |
33.30 HTMLとXMLの解析 | HTMLおよびXMLの解析。 | |
33.33 グループのアトミックな変更 | Installing several buffer changes atomically. | |
33.34 フックの変更 | テキスト変更時に実行する関数の指定。 | |
The Kill Ring | ||
33.8.1 killリングの概念 | killリング内のテキストがどのように見えるか。 | |
33.8.2 kill用の関数 | テキストをkillする関数。 | |
33.8.3 yank | yankが行われる方法。 | |
33.8.4 yank用の関数 | killリングにアクセスするコマンド。 | |
33.8.5 低レベルのkillリング | killリングアクセス用の関数および変数。 | |
33.8.6 killリングの内部 | killリングのデータを保持する変数。 | |
Indentation | ||
33.17.1 インデント用のプリミティブ | インデントのカウントと挿入に使用される関数。 | |
33.17.2 メジャーモードが制御するインデント | 異なるモード用にインデントをカスタマイズする。 | |
33.17.3 リージョン全体のインデント | リージョン内すべての行のインデント。 | |
33.17.4 前行に相対的なインデント | 前の行にもとづきカレント行をインデントする。 | |
33.17.5 調整可能なタブストップ | 調整可能なタイプライター形式のタブストップ。 | |
33.17.6 インデントにもとづくモーションコマンド | 最初の非ブランク文字への移動。 | |
Text Properties | ||
33.19.1 テキストプロパティを調べる | 単一の文字のプロパティを調べる。 | |
33.19.2 テキストプロパティの変更 | テキスト範囲のプロパティをセットする。 | |
33.19.3 テキストプロパティの検索関数 | プロパティが値を変更する場所の検索。 | |
33.19.4 特殊な意味をもつプロパティ | 特別な意味をもつ特定のプロパティ。 | |
33.19.5 フォーマットされたテキストのプロパティ | テキストのフォーマットを表すプロパティ。 | |
33.19.6 テキストプロパティの粘着性 | 挿入されたテキストが隣接するテキストからプロパティを取得する方法。 | |
33.19.7 テキストプロパティのlazyな計算 | テキストが調べられる際のみ、ものぐさな方法でテキストプロパティを計算する。 | |
33.19.8 クリック可能なテキストの定義 | テキストプロパティを使用して、テキストリージョンがクリック時に何か行うようにする。 | |
33.19.9 フィールドの定義と使用 | バッファー内にフィールドを定義するfield プロパティ。
| |
33.19.10 なぜテキストプロパティはインターバルではないのか | テキストプロパティがLispから可視なテキスト間隔をもたない理由。 | |
Parsing HTML and XML | ||
33.30.1 ドキュメントオブジェクトモデル | Access, manipulate and search the DOM. | |
Non-ASCII Characters | ||
34.1 テキストの表現方法 | Emacsがテキストを表す方法。 | |
34.2 マルチバイト文字の無効化 | マルチバイト使用を制御する。 | |
34.3 テキスト表現の変換 | ユニバイトとマルチバイトの相互変換。 | |
34.4 表現の選択 | バイトシーケンスをユニバイトやマルチバイトとして扱う。 | |
34.5 文字コード | ユニバイトやマルチバイトが個々の文字のコードと関わる方法。 | |
34.6 文字のプロパティ | 文字の挙動と処理を定義する文字属性。 | |
34.7 文字セット | 利用可能な文字コード空間はさまざまな文字セットに分割される。 | |
34.8 文字セットのスキャン | バッファーで使用されている文字セットは? | |
34.9 文字の変換 | 変換に使用される変換テーブル。 | |
34.10 コーディングシステム | コーディングシステムはファイル保存のための変換である。 | |
34.11 入力メソッド | 入力メソッドによりユーザーは特別なキーボードなしで非ASCII文字を入力できる。 | |
34.12 locale | POSIX localeとの対話。 | |
Coding Systems | ||
34.10.1 コーディングシステムの基本概念 | 基本的な概念。 | |
34.10.2 エンコーディングとI/O | ファイル入出力関数がコーディングシステムを扱う方法。 | |
34.10.3 Lispでのコーディングシステム | コーディングシステム名を処理する関数。 | |
34.10.4 ユーザーが選択したコーディングシステム | ユーザーにコーディングシステムの選択を求める。 | |
34.10.5 デフォルトのコーディングシステム | デフォルトの選択の制御。 | |
34.10.6 単一の操作にたいするコーディングシステムの指定 | 単一ファイル処理にたいして特定のコーディングシステムを要求する。 | |
34.10.7 明示的なエンコードとデコード | 入出力を伴わないテキストのエンコードおよびデコード。 | |
34.10.8 端末I/Oのエンコーディング | 端末入出力にたいするエンコーディングの使用。 | |
Searching and Matching | ||
35.1 文字列の検索 | 正確なマッチの検索。 | |
35.2 検索と大文字小文字 | case-independentまたはcase-significantな検索。 | |
35.3 正規表現 | 文字列クラスの記述。 | |
35.4 正規表現の検索 | regexpにたいするマッチの検索。 | |
35.5 POSIX正規表現の検索 | 最長マッチにたいするPOSIXスタイルのマッチ。 | |
35.6 マッチデータ | 文字列またはregexp検索後に、テキストがマッチした部分を見つける。 | |
35.7 検索と置換 | 検索と置換を繰り返すコマンド。 | |
35.8 編集で使用される標準的な正規表現 | センテンスやページ等を探すために有用なregexp。 | |
Regular Expressions | ||
35.3.1 正規表現の構文 | 正規表現の記述ルール。 | |
35.3.2 正規表現の複雑な例 | 正規表現構文の説明。 | |
35.3.3 rx 構造化Rgexp表記 | An alternative, structured regexp notation. | |
35.3.4 正規表現の関数 | 正規表現を操作する関数。 | |
35.3.5 正規表現にまつわるトラブル | Some problems and how they may be avoided. | |
Syntax of Regular Expressions | ||
35.3.1.1 正規表現内の特殊文字 | 正規表現内のスペシャル文字。 | |
35.3.1.2 文字クラス | 正規表現内で使用される文字クラス。 | |
35.3.1.3 正規表現内のバッククラッシュ構文 | 正規表現内のバックスラッシュシーケンス。 | |
The Match Data | ||
35.6.1 マッチしたテキストの置換 | マッチされた部分文字列の置換。 | |
35.6.2 単純なマッチデータへのアクセス | 特定の部分式開始箇所のような、マッチデータの単一アイテムへのアクセス。 | |
35.6.3 マッチデータ全体へのアクセス | リストとしてマッチデータ全体に一度にアクセスする。 | |
35.6.4 マッチデータの保存とリストア | ||
Syntax Tables | ||
36.1 構文テーブルの概念 | 構文テーブルの基本的概念。 | |
36.2 構文記述子 | 文字がクラス分けされる方法。 | |
36.3 構文テーブルの関数 | 構文テーブルを作成、調査、変更する方法。 | |
36.4 構文プロパティ | テキストプロパティによる構文テーブルのオーバーライド。 | |
36.5 モーションと構文 | 特定の構文による文字間の移動。 | |
36.6 式のパース | 構文テーブル使用による釣り合いのとれた式の解析。 | |
36.7 構文テーブルの内部 | 構文テーブルの情報が格納される方法。 | |
36.8 カテゴリー | 文字構文をクラス分けする別の手段。 | |
Parsing Program Source | ||
37.1 Tree-sitter Language Grammar | Loading tree-sitter language grammar. | |
37.2 tree-sitterパーサーの使用 | Introduction to parsers. | |
37.3 ノードの取得 | Retrieving nodes from a syntax tree. | |
37.4 ノード情報へのアクセス | Accessing node information. | |
37.5 tree-sitterノードにたいするパターンマッチング | Pattern matching with query patterns. | |
37.6 複数言語ののパース | Parse text written in multiple languages. | |
37.7 tree-sitterを用いるメジャーモードの開発 | Develop major modes using tree-sitter. | |
37.8 tree-sitterのC APIとの対応表 | Compare the C API and the ELisp API. | |
Syntax Descriptors | ||
36.2.1 構文クラスのテーブル | ||
36.2.2 構文フラグ | 各文字が所有できる追加のフラグ。 | |
Parsing Expressions | ||
36.6.1 パースにもとづくモーションコマンド | パースにより機能する移動関数。 | |
36.6.2 ある位置のパース状態を調べる | ある位置の構文状態を判断する。 | |
36.6.3 パーサー状態 | Emacsが構文状態を表す方法。 | |
36.6.4 低レベルのパース | 指定されたリージョンを横断するパース。 | |
36.6.5 パースを制御するためのパラメーター | パースに影響するパラメーター。 | |
Abbrevs and Abbrev Expansion | ||
38.1 abbrevテーブル | abbrevテーブルの作成と操作。 | |
38.2 abbrevの定義 | 略語の指定とそれらの展開。 | |
38.3 ファイルへのabbrevの保存 | ||
38.4 略語の照会と展開 | 展開の制御と展開サブルーチン。 | |
38.5 標準abbrevテーブル | 種々メジャーモードに使用されるabbrevテーブル。 | |
38.6 abbrevプロパティ | abbrevプロパティの読み取りとセットを行う方法。どのプロパティが何の効果をもつか。 | |
38.7 abbrevテーブルのプロパティ | abbrevテーブルプロパティの読み取りとセットを行う方法。どのプロパティが効果をもつか。 | |
Threads | ||
39.1 基本的なスレッド関数 | Basic thread functions. | |
39.2 ミューテックス | Mutexes allow exclusive access to data. | |
39.3 条件変数 | Inter-thread events. | |
39.4 スレッドリスト | Show the active threads. | |
Processes | ||
40.1 サブプロセスを作成する関数 | サブプロセスを開始する関数。 | |
40.2 shell引数 | shellに渡すために引数をクォートする。 | |
40.3 同期プロセスの作成 | 同期サブプロセス使用の詳細。 | |
40.4 非同期プロセスの作成 | 非同期サブプロセスの起動。 | |
40.5 プロセスの削除 | 非同期サブプロセスの削除。 | |
40.6 プロセスの情報 | 実行状態および他の属性へのアクセス。 | |
40.7 プロセスへの入力の送信 | 非同期サブプロセスへの入力の送信。 | |
40.8 プロセスへのシグナルの送信 | 非同期サブプロセスの停止、継続、割り込み。 | |
40.9 プロセスからの出力の受信 | 非同期サブプロセスからの出力の収集。 | |
40.10 センチネル: プロセス状態の変更の検知 | プロセスの実行状態変更時に実行されるセンチネル。 | |
40.11 exit前の問い合わせ | exitによりプロセスがkillされる場合に問い合わせるかどうか。 | |
40.12 別のプロセスへのアクセス | そのシステム上で実行中の別プロセスへのアクセス。 | |
40.13 トランザクションキュー | サブプロセスとのトランザクションベースのコミュニケション。 | |
40.14 ネットワーク接続 | ネットワーク接続のopen。 | |
40.15 ネットワークサーバー | Emacsによるネット接続のacceptを可能にするネットワークサーバー。 | |
40.16 データグラム | UDPネットワーク接続。 | |
40.17 低レベルのネットワークアクセス | 接続およびサーバーを作成するための、より低レベルだがより汎用的な関数。 | |
40.18 その他のネットワーク機能 | ネット接続用の追加の関連関数。 | |
40.19 シリアルポートとの対話 | シリアルポートでのやり取り。 | |
40.20 バイト配列のpackとunpack | bindatを使用したバイナリーデータのpackとunpack。 | |
Receiving Output from Processes | ||
40.9.1 プロセスのバッファー | デフォルトでは、出力はバッファーに送信される。 | |
40.9.2 プロセスのフィルター関数 | フィルター関数はプロセスからの出力を受け取る。 | |
40.9.3 プロセス出力のデコード | フィルターはユニバイトおよびマルチバイトの文字列を取得できる。 | |
40.9.4 プロセスの出力を受け取る | プロセスの出力到着まで待機する方法。 | |
Low-Level Network Access | ||
40.17.1 make-network-process | make-network-process ’の使用。
| |
40.17.2 ネットワークのオプション | 更なるネットワーク接続の制御。 | |
40.17.3 ネットワーク機能の可用性のテスト | 使用中マシン上で動作するネットワーク機能を判断する。 | |
Packing and Unpacking Byte Arrays | ||
40.20.1 データレイアウトの記述 | ||
40.20.2 バイトのunpackとpackを行う関数 | unpack化とpack化を行う。 | |
40.20.3 高度なデータレイアウト仕様 | Advanced data layout specifications. | |
Emacs Display | ||
41.1 スクリーンのリフレッシュ | スクリーン上にあるすべてのもののクリアーと再描画。 | |
41.2 強制的な再表示 | 再描画の強制。 | |
41.3 切り詰め | 長いテキストの折り畳みと折り返し。 | |
41.4 エコーエリア | スクリーン最下部へのメッセージ表示。 | |
41.5 警告のレポート | ユーザーへの警告メッセージの表示。 | |
41.6 不可視のテキスト | バッファーのテキストの一部を隠す。 | |
41.7 選択的な表示 | バッファーのテキストの一部を隠す(旧来の方式)。 | |
41.8 一時的な表示 | 自動的に消える表示。 | |
41.9 オーバーレイ | オーバーレイを使用したバッファーの一部のハイライト。 | |
41.10 表示されるテキストのサイズ | 表示されたテキストの大きさ。 | |
41.11 行の高さ | 行の高さの制御。 | |
41.12 フェイス | テキスト文字のグラフィカルスタイル(フォント、カラー等)を定義するフェイス。 | |
41.13 フリンジ | ウィンドウフリンジの制御。 | |
41.14 スクロールバー | Controlling scroll bars. | |
41.15 ウィンドウディバイダー | ウィンドウを視覚的に区別する。 | |
41.16 display プロパティ | 特別な表示機能の有効化。 | |
41.17 イメージ | Emacsバッファー内でのイメージ表示。 | |
41.20 ボタン | Emacsバッファー内へのイメージ表示クリック可能ボタン追加。 | |
41.21 抽象的なディスプレイ | オブジェクトコレクション用のEmacsウィジェット。 | |
41.22 カッコの点滅 | Emacsがマッチする開カッコを表示する方法。 | |
41.23 文字の表示 | Emacsがマッチする個々の文字を表示する方法。 | |
41.24 ビープ | ユーザーへの可聴シグナル。 | |
41.25 ウィンドウシステム | どのウィンドウシステムが使用されているか。 | |
41.26 ツールチップ | Tooltip display in Emacs. | |
41.27 双方向テキストの表示 | アラビア語やペルシア語のような、双方向スクリプトの表示。 | |
The Echo Area | ||
41.4.1 エコーエリアへのメッセージの表示 | エコーエリア内に明示的にテキストを表示する。 | |
41.4.2 処理の進捗レポート | 長時間の処理の進行状況をユーザーに知らせる。 | |
41.4.3 *Messages*へのメッセージのロギング | ユーザー用にログされるエコーエリアメッセージ。 | |
41.4.4 エコーエリアのカスタマイズ | エコーエリアの制御。 | |
Reporting Warnings | ||
41.5.1 警告の基礎 | 警告の概念と、それらを報告するための関数。 | |
41.5.2 警告のための変数 | プログラムが警告をカスタマイズするためにバインドする変数。 | |
41.5.3 警告のためのオプション | ユーザーが警告の表示を制御するためにセットする変数。 | |
41.5.4 遅延された警告 | コマンド終了まで警告を延期する。 | |
Overlays | ||
41.9.1 オーバーレイの管理 | オーバーレイの作成と変更。 | |
41.9.2 オーバーレイのプロパティ | プロパティ読み取りおよびセットの方法。どのプロパティがスクリーン表示に何を行うか。 | |
41.9.3 オーバーレイにたいする検索 | ||
Faces | ||
41.12.1 フェイスの属性 | フェイスとは? | |
41.12.2 フェイスの定義 | フェイスを定義する方法。 | |
41.12.3 フェイス属性のための関数 | フェイス属性の確認およびセットを行う関数。 | |
41.12.4 フェイスの表示 | ある文字にたいして指定されたフェイスをEmacsが組み合わせる方法。 | |
41.12.5 フェイスのリマップ | フェイスを別の定義にリマップする。 | |
41.12.6 フェイスを処理するための関数 | フェイスの定義、および確認する方法。 | |
41.12.7 フェイスの自動割り当て | 自動的にフェイスを割り当てるフック。 | |
41.12.8 基本的なフェイス | デフォルトで定義されるフェイス。 | |
41.12.9 フォントの選択 | あるフェイスに最適なフォントを見つける。 | |
41.12.10 フォントの照会 | 利用可能なフォント名とそれらの情報の照会。 | |
41.12.11 フォントセット | フォントセット、それは文字セットの範囲を処理するフォントコレクションである。 | |
41.12.12 低レベルのフォント表現 | 文字表示フォントのLisp表現。 | |
Fringes | ||
41.13.1 フリンジのサイズと位置 | ウィンドウフリンジを置く場所を指定する。 | |
41.13.2 フリンジのインジケーター | ウィンドウフリンジ内にインジケーターアイコンを表示する。 | |
41.13.3 フリンジのカーソルFrin | 右フリンジ内にカーソルを表示する。 | |
41.13.4 フリンジのビットマップ | フリンジインジケーターにたいしてビットマップを指定する。 | |
41.13.5 フリンジビットマップのカスタマイズ | フリンジ内で使用する独自ビットマップの指定。 | |
41.13.6 オーバーレイ矢印 | 位置を示す矢印の表示。 | |
The | ||
41.16.1 テキストを置換するディスプレイ仕様 | テキストを置換するディスプレイspec。 | |
41.16.2 スペースの指定 | 指定された幅に1つのスペースを表示する。 | |
41.16.3 スペースにたいするピクセル指定 | ピクセル単位でスペースの幅または高さを指定する。 | |
41.16.4 その他のディスプレイ仕様 | イメージの表示。高さ、スペーシング、その他のテキストプロパティの調整。 | |
41.16.5 マージン内への表示 | メインテキスト側面へのテキストまたはイメージの表示。 | |
Images | ||
41.17.1 イメージのフォーマット | サポートされるイメージフォーマット。 | |
41.17.2 イメージのディスクリプタ | :display 内で使用されるイメージの指定方法。
| |
41.17.3 XBMイメージ | XBMフォーマット用の特別な機能。 | |
41.17.4 XPMイメージ | XPMフォーマット用の特別な機能。 | |
41.17.5 ImageMagickイメージ | ImageMagickを通じて利用できる特別な機能。 | |
41.17.7 その他のイメージタイプ | サポートされるその他さまざまなフォーマット。 | |
41.17.8 イメージの定義 | 後で使用するためにイメージを定義する便利な方法。 | |
41.17.9 イメージの表示 | 一度定義されたイメージを表示するための便利な方法。 | |
41.17.10 マルチフレームのイメージ | 1つ以上のフレームを含むイメージ。 | |
41.17.11 イメージキャッシュ | イメージ表示の内部的メカニズム。 | |
Buttons | ||
41.20.1 ボタンのプロパティ | 特別な意味をもつボタンプロパティ。 | |
41.20.2 ボタンのタイプ | ボタンのクラスにたいして一般的なプロパティを定義する。 | |
41.20.3 ボタンの作成 | Emacsバッファーへのボタンの追加。 | |
41.20.4 ボタンの操作 | ボタンプロパティの取得とセット。 | |
41.20.5 ボタンのためのバッファーコマンド | ボタンにたいするバッファー規模のコマンドとバインディング。 | |
Abstract Display | ||
41.21.1 抽象ディスプレイの関数 | Ewocパッケージ内の関数。 | |
41.21.2 抽象ディスプレイの例 | Ewocの使用例。 | |
Character Display | ||
41.23.1 通常の表示の慣習 | 文字の表示にたいする通常の慣習。 | |
41.23.2 ディスプレイテーブル | ディスプレイテーブルの構成要素。 | |
41.23.3 アクティブなディスプレイテーブル | 使用するディスプレイテーブルをEmacsが選択する方法。 | |
41.23.4 グリフ | グリフの定義方法とグリフの意味。 | |
41.23.5 グリフなし文字の表示 | グリフなしの文字の描画方法。 | |
Operating System Interface | ||
42.1 Emacsのスタートアップ | Customizing Emacs startup processing. | |
42.2 Emacsからの脱出 | (永久または一時的に)exitが機能する方法。 | |
42.3 オペレーティングシステムの環境 | システム名と種類の区別。 | |
42.4 ユーザーの識別 | そのユーザーの名前とユーザーIDを調べる。 | |
42.5 時刻 | カレント時刻の取得。 | |
42.7 時刻の変換 | Converting among timestamp forms. | |
42.8 時刻のパースとフォーマット | Converting timestamps to text and vice versa. | |
42.9 プロセッサーの実行時間 | Emacsによる実行時間の取得。 | |
42.10 時間の計算 | 時間の加減算、その他。 | |
42.11 遅延実行のためのタイマー | 特定時刻に関数を呼び出すためにターマーをセットする。 | |
42.12 アイドルタイマー | Emacsが特定の時間の間アイドル時に関数を呼び出すためにタイマーをセットする。 | |
42.13 端末の入力 | 端末入力へのアクセスと記録。 | |
42.14 端末の出力 | 端末出力の制御と記録。 | |
42.15 サウンドの出力 | コンピューターのスピーカーでのサウンド再生。 | |
42.16 X11キーシンボルの処理 | Xウィンドウにたいするキーシンボルの操作。 | |
42.17 batchモード | 端末との対話なしでEmacsを実行する。 | |
42.18 セッションマネージャー | Xセッション管理の保存とリストア。 | |
42.19 デスクトップ通知 | ||
42.20 ファイル変更による通知 | ファイル通知。 | |
42.21 動的にロードされるライブラリー | サポートライブラリーのオンデマンドロード。 | |
42.22 セキュリティへの配慮 | Running Emacs in an unfriendly environment. | |
Emacsのスタートアップ | ||
42.1.1 要約: スタートアップ時のアクション順序 | スタートアップ時にEmacsが行うアクションの順序。 | |
42.1.2 initファイル | initファイル読み込みの詳細。 | |
42.1.3 端末固有の初期化 | 端末固有のLispファイルの読み込み方法。 | |
42.1.4 コマンドライン引数 | コマンドライン引数の処理とカスタマイズの方法。 | |
Getting Out of Emacs | ||
42.2.1 Emacsのkill | Emacsからの不可逆的なexit。 | |
42.2.2 Emacsのサスペンド | Emacsからの可逆的なexit。 | |
Terminal Input | ||
42.13.1 入力のモード | 入力の処理方法にたいするオプション。 | |
42.13.2 入力の記録 | 直近またはすべての入力イベントのヒストリーの保存。 | |
Preparing Lisp code for distribution | ||
43.1 パッケージ化の基礎 | Emacs Lispパッケージの基本的概念。 | |
43.2 単純なパッケージ | 単一.elファイルをパッケージする方法。 | |
43.3 複数ファイルのパッケージ | 複数ファイルをパッケージする方法。 | |
43.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 スタックに割り当てられたオブジェクト | 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 動的にロードされるモジュールの記述 | Writing loadable modules for Emacs. | |
E.9 オブジェクトの内部 | バッファー、ウィンドウ、プロセスのデーラフォーマット。 | |
E.10 Cの整数型 | How C integer types are used inside Emacs. | |
Writing Dynamic Modules | ||
E.8.1 モジュールの初期化コード | ||
E.8.2 モジュール関数の記述 | ||
E.8.3 Lisp・モジュール間の値変換 | ||
E.8.4 その他の便利なモジュール用関数 | ||
E.8.5 モジュールでの非ローカル脱出 | ||
Object Internals | ||
E.9.1 バッファーの内部 | バッファー構造体の構成子。 | |
E.9.2 ウィンドウの内部 | ウィンドウ構造体の構成子。 | |
E.9.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 29.1に対応したGNU Emacs Lisp Reference Manualです。
1.1 注意事項 | 不備な点と、助けを求める方法。 | |
1.2 Lispの歴史 | Maclispを後継するEmacs Lisp。 | |
1.3 Lispの歴史 | このマニュアルのフォーマット方法。 | |
1.4 バージョンの情報 | 実行中のEmacsのバージョンは? | |
1.5 謝辞 | このマニュアルの著者、編集者、スポンサー。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このマニュアルは幾多のドラフトを経てきました。ほとんど完璧ではありますが、不備がないとも言えません。(ほとんどの特定のモードのように)それらが副次的であるとか、まだ記述されていないという理由により、カバーされていないトピックもあります。わたしたちがそれらを完璧に扱うことはできないので、いくつかの部分は意図的に省略しました。
このマニュアルは、それがカバーしている事柄については完全に正しくあるべきあり、故に特定の説明テキスト、チャプターやセクションの順番にたいしての批判にオープンであるべきです。判りにくかったり、このマニュアルでカバーされていない何かを学ぶためにソースを見たり実地から学ぶ必要があるなら、このマニュアルはおそらく訂正されるべきなのかもしれません。どうかわたしたちにそれを教えてください。
このマニュアルを使用するときは、間違いを見つけたらすぐに訂正を送ってください。関数または関数グループの単純な現実例を考えたときは、ぜひそれを記述して送ってください。それが妥当ならコメントでノード名と関数名や変数名を参照してください。あなたが訂正を求めるエディションのバージョンも示してください。
コメントや訂正の送信には、M-x report-emacs-bugを使用するようお願いします。新たなコード(や問題訂正のパッチ)を寄贈するにはM-x submit-emacs-patchを使用してください。
[ << ] | [ < ] | [ 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 Lispの歴史 | このマニュアルで使用する用語の説明。 | |
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
エラーとなります。変更不可な変数を参照してください。
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バッファーで閉カッコの後でC-jをタイプすることによりコード例を実行する場合には、プリントされるテキストはそのバッファーに挿入されます。(関数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 26.1 (build 1, x86_64-unknown-linux-gnu, GTK+ Version 3.16) of 2017-06-01"
hereが非nil
ならテキストをバッファーのポイントの前に挿入して、nil
をリターンする。この関数がインタラクティブに呼び出すと、同じ情報をエコーエリアに出力する。プレフィクス引数を与えると、hereが非nil
になる。
この変数の値はEmacsがビルドされた日時を示す。値はcurrent-time
の形式(時刻を参照)、その情報が利用できなければnil
。
emacs-build-time ⇒ (25194 55894 8547 617000)
(Emacsのビルド時にcurrent-time-list
がnil
なら、タイムスタンプは(1651169878008547617
. 1000000000)
になる。)
この変数の値は実行中のEmacsのバージョンであり、"26.1"
のような文字列。"26.0.91"
のように3つの数値コンポーネントをもつ値はリリース版ではなくテストバージョンであることを示す(Emacs
26.1より前では"25.1.1"
のように文字列の最後に余分な整数コンポーネントが含まれていたが、これは現在はemacs-build-number
に格納される)。
Emacsのメジャーバージョン番号を示す整数。Emacs 23.1では値は23。
Emacsのマイナーバージョン番号を示す整数。Emacs 23.1では値は1。
これは同一のディレクトリーにおいてEmacsが(クリーニングなしで)ビルドされるたびに増分される整数。これはEmacsの開発時だけに関係のある変数。
Emacsがビルドされたレポジトリのリビジョン番号を与える文字列。Emacsがリビジョンコントロール外部でビルドされた場合の値はnil
。
Emacsがビルドされたレポジトリブランチを与える文字列。ほとんどの場合は"master"
。Emacsがリビジョンコントロール外部でビルドされた場合の値はnil
。
[ << ] | [ < ] | [ 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)、レコード(record)、および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 コメント | コメントとコメント書式の慣例。 | |
2.4 プログラミングの型 | すべてのLispシステムに存在する型。 | |
2.5 編集用の型 | Emacs固有の型。 | |
2.6 循環オブジェクトの読み取り構文 | 循環構造にたいする入力構文。 | |
2.7 型のための述語 | 型に関連するテスト。 | |
2.8 同等性のための述語 | 2つのオブジェクトが等しいかのテスト。 | |
2.9 可変性 | 変更されるべきではないオブジェクト。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
オブジェクトのプリント表現(printed
representation)とは、オブジェクトにたいしてLispプリンター(関数prin1
)が生成する出力のフォーマットです。すべてのデータ型は一意なプリント表現をもちます。オブジェクトの入力構文(read
syntax)とは、オブジェクトにたいしてLispリーダー(関数read
)が受け取る入力のフォーマットです。これは一意である必要はありません。多くの種類のオブジェクトが複数の構文をもちます。Lispオブジェクトの読み取りとプリントを参照してください。
ほとんどの場合、オブジェクトのプリント表現が、入力構文としても使用されます。しかしLispプログラム内の定数とすることに意味が無いいくつかの型には、入力構文がありません。これらのオブジェクトはハッシュ表記(hash notation)でプリントされ、‘#<’、説明的な文字列(典型的には型名にオブジェクトの名前を続けたもの)、‘>’で構成される文字列です。たとえば:
(current-buffer) ⇒ #<buffer objects-ja.texi>
ハッシュ表記は読み取ることができないので、Lispリーダーは‘#<’に遭遇すると常にエラーinvalid-read-syntax
をシグナルします。
他の言語では式はテキストであり、これ以外の形式はありません。Lispでは式は第一にまずLispオブジェクトであって、オブジェクトの入力構文であるテキストは副次的なものに過ぎません。たいていこの違いを強調する必要はありませんが、このことを心に留めておかないとたまに混乱することがあるでしょう。
インタラクティブに式を評価するとき、Lispインタープリターは最初にそれのテキスト表現を読み取り、Lispオブジェクトを生成してからそのオブジェクトを評価します(評価を参照)。しかし評価と読み取りは別の処理です。読み取りによりテキストにより表現されたLispオブジェクトを読み取り、Lispオブジェクトがリターンされます。後でオブジェクトは評価されるかもしれないし、評価されないかもしれません。オブジェクトを読み取るための基本的な関数read
の説明は、入力関数を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispでは特別なハッシュ表記を通じて多くの特別なオブジェクトと構文を表します。
入力構文がないオブジェクトはこのように表される(プリント表現と読み取り構文を参照)。
名前が空文字列であるようなインターン済みシンボルのプリント表現(シンボル型を参照)。
function
にたいするショートカット。無名関数を参照のこと。
名前がfooであるようなインターンされていないシンボルのプリント表現は‘#:foo’ (シンボル型を参照)。
循環構造のプリント時には構造が自身をループバックすることを表すためにこの構文が使用される。ここで‘N’リストの開始カウント。
(let ((a (list 1))) (setcdr a a)) => (1 . #0)
‘#N=’はオブジェクト名、‘#N#’はそのオブジェクトを表すので、これらはコピーではなく同一オブジェクトになる(循環オブジェクトの読み取り構文を参照)。
16進表現の‘N’ (‘#x2a’)。
8進表現の‘N’ (‘#o52’)。
2進表現の‘N’ (‘#b101010’)。
文字列のテキストプロパティ(文字列内のテキストプロパティを参照)。
文字テーブル(文字テーブル型を参照)。
ハッシュテーブル(ハッシュテーブル型を参照)。
文字(基本的な文字構文を参照)。
バイトコンパイル済みファイルのカレントファイル名(ドキュメント文字列とコンパイルを参照)。これはEmacs Lispソースファイルで使用するためのものではない。
次の‘N’文字をスキップする(コメントを参照)。バイトコンパイル済みファイル内で使用されるものであって、Emacs Lispソースファイル内で使用するためのものではない。
これに続くフォームがEmacs Lispリーダーで読み取れないことを示す。これは表示されることを意図したテキストだけに出現する読み取り構文(読み取れないフォームを示すための他の選択肢よりも見栄えがよくなると思われる場合)、でありLispファイル中に出現することは決してない。
[ << ] | [ < ] | [ 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.4.1 整数型 | 小数部のない数字。 | |
2.4.2 浮動小数点数型 | 広い範囲をもつ、小数部をもつ数字。 | |
2.4.3 文字型 | 文字、数字、コントロール文字にたいする表現。 | |
2.4.4 シンボル型 | 関数、変数、プロパティリストを参照する、一意に識別される多目的オブジェクト。 | |
2.4.5 シーケンス型 | リストと配列はどちらもシーケンスに分類される。 | |
2.4.6 コンスセルとリスト型 | コンスセル、および(コンスセルにより作られる)リスト。 | |
2.4.7 配列型 | 配列には文字列とベクターが含まれる。 | |
2.4.8 文字列型 | (効率的な)文字の配列。 | |
2.4.9 ベクター型 | 1次元の配列。 | |
2.4.10 文字テーブル型 | 文字によりインデックスされる1次元の疎な配列。 | |
2.4.11 ブールベクター型 | t とnil からなる1次元の配列。
| |
2.4.12 ハッシュテーブル型 | 非常に高速な参照用のテーブル。 | |
2.4.13 関数型 | 他の場所から呼び出せる実行可能なコード断片。 | |
2.4.14 マクロ型 | より基本的だが少し見栄えの悪い、式を他の式に展開する手法。 | |
2.4.15 プリミティブ関数型 | Lispから呼び出せるCで記述された関数。 | |
2.4.16 バイトコード関数型 | Lispで記述されてコンパイルされた関数。 | |
2.4.17 レコード型 | プログラーが定義する合成オブジェクト型。 | |
2.4.18 型記述子 | 型に関する情報を保持するオブジェクト。 | |
2.4.19 autoload型 | 頻繁に使用されない関数を自動的にロードするために使用される型。 | |
2.4.20 ファイナライザー型 | オブジェクトが到達不能になった際に実行するコード。 | |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
内部にはfixnumsと呼ばれる小さい整数、およびbignumsという大きい整数という2種類の整数が存在します。
fixnumの値の範囲はマシンに依存します、最小のレンジは-536,870,912から536,870,911(30ビットでは -2**29 から 2**29 - 1) しかし多くのマシンはより広い範囲を提供します。
bignumは任意の精度をもつことができます。fixnumのオーバーフローする処理では、かわりにbignumをリターンされます。
eql
や=
ですべての数値、fixnumならeq
で比較することができます。整数がfixnumかbignumをテストするにはmost-negative-fixnum
とmost-positive-fixnum
で比較するか、便利な述語fixnump
とbignump
を任意のオブジェクトに使用できます。
整数にたいする入力構文は、(10を基数とする)数字のシーケンスで、オプションで先頭に符号、最後にピリオドがつきます。Lispインタープリターにより生成されるプリント表現には、先頭の ‘+’や最後の‘.’はありません。
-1 ; 整数の-1 1 ; 整数の1 1. ; これも整数の1 +1 ; これも整数の1
詳細は数値を参照してください。
[ << ] | [ < ] | [ 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.4.3.1 基本的な文字構文 | 標準的な文字の構文。 | |
2.4.3.2 一般的なエスケープ構文 | 文字をコードにより指定する方法。 | |
2.4.3.3 コントロール文字構文 | コントロール文字の構文。 | |
2.4.3.4 メタ文字構文 | メタ文字の構文。 | |
2.4.3.5 その他の文字修飾ビット | ハイパー、スーパー、アルト文字の構文。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
文字は実際には整数なので、文字のプリント表現は10進数です。文字にたいする入力構文も利用可能ですが、Lispプログラムでこの方法により文字を記述するのは、明解なプログラミングではありません。文字にたいしては、Emacs Lispが提供する、特別な入力構文を常に使用するべきです。これらの構文フォーマットはクエスチョンマークで開始されます。
英数字にたいする通常の入力構文は、クエスチョンマークと、その後にその文字を記述します。したがって文字Aは‘?A’、文字Bは‘?B’、文字aは‘?a’となります。
たとえば:
?Q ⇒ 81 ?q ⇒ 113
区切り文字(punctuation characters)にも同じ構文を使用できますが、区切り文字がLispで特別な意味をもつ場合には‘\’でクォートしなければなりません。たとえば‘?\(’が開カッコを記述する方法であり、同様に文字が‘\’なら、‘?\\’のようにクォートするために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コマンドが混乱するのを避けるために‘|'`#.,’の前にもバックスラッシュを追加するべきです。コードを読む人の混乱を避けるために、前に言及したASCII文字と類似したUnicode文字の前にもバックスラッシュを追加する必要があります。これを奨励するために、‘‘’のような一般的には混乱を招くエスケープされていない文字をハイライトします。スペース、タブ、改行、フォームフィードのような空白文字の前にもバックスラッシュを追加できます。しかしタブやスペースspaceのような実際の空白文字のかわりに、‘\t’や‘\s’のような可読性のあるエスケープシーケンスを使用するほうが明解です(スペースを後にともなうバックスラッシュを記述する場合、後続のテキストと区別するために、文字定数の後に余分なスペースを記述すること)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
特に重要なコントロール文字にたいする特別なエスケープシーケンスに加えて、Emacsは非ASCIIテキスト文字の指定に使用できる、何種類かのエスケープ構文を提供します。
?\N{NAME}
はNAMEという名前のUnicode文字を表す。したがって‘?\N{LATIN
SMALL LETTER A WITH
GRAVE}’は?à
と等価でありUnicode文字のU+00E0を意味する。名前中のスペースを空白文字(改行)の非空のシーケンスにして複数行文字列の入力を簡略化できる。
?\N{U+X}
はUnicodeコードポイントX
(16進数値)を表す。また?\uxxxx
と?\Uxxxxxxxx
はそれぞれコードポイントxxxxとxxxxxxxxを表すxは(1つの16進数字)。たとえば?\N{U+E0}
、?\u00e0
、?\U000000E0
は?à
と‘?\N{LATIN
SMALL LETTER A WITH
GRAVE}’に等しい。Unicode標準は‘U+10ffff’以下のコードポイントだけを定義するので、これより大きいコードポイントではEmacsはエラーをシグナルする。
?\xe0
は文字à
(グレイブアクセントつきのa)になる。‘x’の後に1つ以上の16進数を使用できるので、この方法で任意の文字を表すことができる。
?\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 ビットが付加されます。したがって文字列に含めることができるメタ文字のコードは128から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上でのGUIディスプレイのようなグラフィカルディスプレイでのみ利用できます。通常のテキスト端末はこれらの違いを報告しません。シフトをあらわすビットのための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)と呼ばれます。これらのシンボルは自動的に定数として振る舞い、通常は未知のシンボルといくつかの特定の候補を比較することだけに使用されます。変更不可な変数を参照してください。
シンボル名にはどんな文字でも含めることができます。ほとんどのシンボル名は英字、数字、‘-+=*/’などの区切り文字で記述されます。このような名前には特別な区切り文字は必要ありません。名前が数字のように見えない限り、名前にはどのような文字も使用できます(名前が数字のように見える場合は、名前の先頭に‘\’を記述して強制的にシンボルとして解釈させる)。文字‘_~!@$%^&:<>{}?’はあまり使用されませんが、これらも特別な句読点文字を必要としません。他の文字も、バックスラッシュでエスケープすることにより、シンボル名に含めることができます。しかし文字列内でのバックスラッシュの使用とは対照的に、シンボル名でのバックスラッシュは、バックスラッシュの後の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.4.6.1 ボックスダイアグラムによるリストの描写 | リストの図解。 | |
2.4.6.2 ドットペア表記 | コンスセルの一般的な構文。 | |
2.4.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
だけを保持できます。この種の配列はシステムアーキテクチャー制限と利用可能なメモリーにしたがったもっとも大きいfixnumまでの任意の長さをもつことができます。文字テーブルは、任意の有効な文字コードによりインデックスづけされる疎な配列であり、任意のオブジェクトを保持することができます。
配列の最初の要素はインデックス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.4.8.1 文字列の構文 | Lisp文字列を指定する方法。 | |
2.4.8.2 文字列内の非ASCII文字 | 文字列内の国際化文字。 | |
2.4.8.3 文字列内の非プリント文字 | 文字列内の印刷不可能なリテラル文字。 | |
2.4.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] | [ ? ] |
Emacsの文字列内の非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.8125 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] | [ ? ] |
レコード(record)はvector
と似ていますが、最初の要素はtype-of
でリターンされる型を保持するために使用されます。レコードの主要目的はプログラマーがEmacsのビルトインではない新たな型を作成することを可能にすることです。
レコードに作用する関数についてはレコードを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
型記述子(type
descriptor)は型に関する情報を保持するrecord
です。レコードの1スロット目には型を命名するシンボルでなければならず、type-of
はrecord
オブジェクトの型をリターンするためにこれに依存しています。他の型記述子スロットをEmacsは使用しません。これらをLisp拡張が使用するのは自由です。
cl-structure-class
のインスタンスはすべて型記述子の例です。
[ << ] | [ < ] | [ 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.5.1 バッファー型 | 編集のための基本オブジェクト。 | |
2.5.2 マーカー型 | バッファー内の位置。 | |
2.5.3 ウィンドウ型 | バッファーはウィンドウ内に表示される。 | |
2.5.4 フレーム型 | ウィンドウはフレームを細分化する。 | |
2.5.5 端末型 | フレームを表示する端末デバイス。 | |
2.5.6 ウィンドウ構成型 | フレームが細分化された方法を記録する。 | |
2.5.7 フレーム構成型 | すべてのフレームの状態を記録する。 | |
2.5.8 プロセス型 | 背後のOS上で実行されるEmacsのサブプロセス。 | |
2.5.9 スレッド型 | Emacs Lispの実行スレッド。 | |
2.5.10 ミューテックス型 | スレッド同期のための排他ロック。 | |
2.5.11 状態変数型 | スレッド同期のための状態変数。 | |
2.5.12 ストリーム型 | 文字の受信と送信。 | |
2.5.13 キーマップ型 | どのキーストロークがどの関数を呼び出すか。 | |
2.5.14 オーバーレイ型 | オーバーレイが表示される方法。 | |
2.5.15 フォント型 | テキストを表示するフォント。 | |
2.5.16 Xwidget型 | 埋め込み可能なウィジェット。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファー(buffer)とは、編集されるテキストを保持するオブジェクトです(バッファーを参照)。ほとんどのバッファーはディスクファイル(ファイルを参照)の内容を保持するので編集できますが、他の目的のために使用されるものもいくつかあります。ほとんどのバッファーはユーザーにより閲覧されることも意図しているので、いつかはウィンドウ内(ウィンドウを参照)に表示されます。しかしバッファーはウィンドウに表示される必要はありません。バッファーはそれぞれ、ポイント(point)と呼ばれる位置指定をもちます(ポジションを参照)。ほとんどの編集コマンドは、カレントバッファー内のポイントに隣接する内容を処理します。常に1つのバッファーがカレントバッファー(current buffer)です。
バッファーの内容は文字列によく似ていますが、バッファーはEmacs Lispの文字列と同じようには使用されず、利用可能な操作は異なります。たとえば文字列にテキストを挿入するためには部分文字列の結合が必要であり、結果が完全に新しい文字列オブジェクトになるのにたいして。バッファーでは既存のバッファーに効率的にテキストを挿入してバッファーの内容を変更できます。
標準的なEmacs関数の多くは、カレントバッファー内の文字を操作したりテストするためのものです。このマニュアルはこれらの関数の説明のために、1つのチャプターを設けています(テキストを参照)。
他のデータ構造のいくつかは、各バッファーに関連付けられています:
ローカルキーマップと変数リストは、グローバルなバインディングや値を個別にオーバーライドするためのエントリーを含みます。これらは実際にプログラムを変更することなく、異なるバッファーでプログラムの振る舞いをカスタマイズするために使用されます。
バッファーはインダイレクト(indirect: 間接) — つまり他のバッファーとテキストを共有するがそれぞれ別に表示する — かもしれません。インダイレクトバッファーを参照してください。
バッファーに入力構文はありません。バッファーはバッファー名を含むハッシュ表記でプリントされます。
(current-buffer) ⇒ #<buffer objects-ja.texi>
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マーカー(marker)は特定のバッファー内の位置を表します。したがってマーカーには2つの内容 — 1つはバッファー、もう1つは位置 — をもちます。バッファーのテキストの変更では、マーカーが常にバッファー内の同じ2つの文字の間に位置することを確実にするために、必要に応じて自動的に位置の値が再配置されます。
マーカーは入力構文をもちません。マーカーはカレントの文字位置とそのバッファー名を与える、ハッシュ表記でプリントされます。
(point-marker) ⇒ #<marker at 10779 in objects-ja.texi>
マーカーのテスト、作成、コピー、移動の方法についての情報はマーカーを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウ(window)はEmacsがバッファーを表示するために使用するスクリーンの範囲を記述します。すべての生きたウィンドウ(Emacsウィンドウの基本概念を参照)には関連付けられた1つのバッファーがあり、バッファーの内容はそのウィンドウに表示されます。それとは対照的に、あるバッファーは1つのウィンドウに表示されるか表示されないか、それとも複数のウィンドウに表示されるかもしれません。ウィンドウはスクリーン上でフレームにグループ化されます。それらのウィンドウはただ1つのフレームに属します。フレーム型を参照してください。
同時に複数のウィンドウが存在するかもしれませんが、常に1つのウィンドウが選択されたウィンドウ(selected window)になります(ウィンドウの選択を参照)。Emacsがコマンドにたいして準備できているときは、(通常は)カーソルが表示されるウィンドウが選択されたウィンドウです。選択されたウィンドウは、通常はカレントバッファー(カレントバッファーを参照)を表示しますがこれは必須ではありません。
ウィンドウは入力構文をもちません。ウィンドウはウィンドウ番号と表示されているバッファー名を与える、ハッシュ表記でプリントされます。与えられたウィンドウに表示されるバッファーは頻繁に変更されるかもしれないので、一意にウィンドウを識別するためにウィンドウ番号が存在します。
(selected-window) ⇒ #<window 1 on objects-ja.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] | [ ? ] |
Emacsでのスレッド(thread)とはEmacs Lispの実行スレッドとは別のスレッドを表します。これは自身のLispプログラムを実行して、自身のカレントバッファーを所有して、そのスレッドにロックされたサブプロセスをもつことができます(サブプロセスの出力を受け取ることができるのはそのスレッドのみ)。スレッドを参照してください。
スレッドオブジェクトは入力構文をもちません。スレッドオブジェクトは(名前を与えられていれば)スレッド名を与えるハッシュ表記かメモリー内のアドレスでプリントされます。
(all-threads) ⇒ (#<thread 0176fc40>)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ミューテックス(mutex)とはスレッド間で同期をとるためにスレッドが所有と非所有することができる排他ロックです。ミューテックスを参照してください。
ミューテックスオブジェクトは入力構文をもちません。プロセスオブジェクトは(名前を与えられていれば)ミューテックス名を与えるハッシュ表記かメモリー内のアドレスでプリントされます。
(make-mutex "my-mutex") ⇒ #<mutex my-mutex> (make-mutex) ⇒ #<mutex 01c7e4e0>
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
状態変数(condition variable)はミューテックスがサポートするよりも複雑な非同期スレッドのためのデバイスです。スレッドは別のスレッドが状態を通知したときに再開するように状態変数を待機することができます。
状態変数オブジェクトは入力構文をもちません。プロセスオブジェクトは(名前が与えられていれば)状態変数の名前を与えるハッシュ表記かメモリー内のアドレスでプリントされます。
(make-condition-variable (make-mutex)) ⇒ #<condvar 01c45ae8>
[ << ] | [ < ] | [ 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] | [ ? ] |
xwidgetとはバッファー内に埋め込みができる、ウェブブラウザのような特別な表示要素のことです。xwidgetを表示しているウィンドウはそれぞれ、xwidgetビュー(xwidget view)ももつことができます。Xウィンドウにおいては、ウィジェットの表示に使用される単一のウィンドウに相当するのがxwidgetビューです。
これらのオブジェクトはいずれも読み取りができません。プリント構文はそれぞれ‘#<xwidget>’、‘#<xwidget-view>’のようになります。xwidgetに関する詳細については埋め込みネイティブウィジェットを参照してください。
[ << ] | [ < ] | [ 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を参照のこと。
bignump
floatpを参照のこと。
bool-vector-p
bool-vector-pを参照のこと。
booleanp
booleanpを参照のこと。
bufferp
bufferpを参照のこと。
byte-code-function-p
byte-code-function-pを参照のこと。
compiled-function-p
compiled-function-pを参照のこと。
case-table-p
case-table-pを参照のこと。
char-or-string-p
char-or-string-pを参照のこと。
char-table-p
char-table-pを参照のこと。
commandp
commandpを参照のこと。
condition-variable-p
condition-variable-pを参照のこと。
consp
conspを参照のこと。
custom-variable-p
custom-variable-pを参照のこと。
fixnump
floatpを参照のこと。
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
変更不可な変数を参照のこと。
listp
listpを参照のこと。
markerp
markerpを参照のこと。
mutexp
mutexpを参照のこと。
nlistp
nlistpを参照のこと。
number-or-marker-p
number-or-marker-pを参照のこと。
numberp
numberpを参照のこと。
overlayp
overlaypを参照のこと。
processp
processpを参照のこと。
recordp
recordpを参照のこと。
sequencep
sequencepを参照のこと。
string-or-null-p
string-or-null-pを参照のこと。
stringp
stringpを参照のこと。
subrp
subrpを参照のこと。
symbolp
symbolpを参照のこと。
syntax-table-p
syntax-table-pを参照のこと。
threadp
threadpを参照のこと。
vectorp
vectorpを参照のこと。
wholenump
wholenumpを参照のこと。
window-configuration-p
window-configuration-pを参照のこと。
window-live-p
window-live-pを参照のこと。
windowp
windowpを参照のこと。
あるオブジェクトがどの型かチェックするもっとも一般的な方法は、関数type-of
の呼び出しです。オブジェクトは、ただ1つだけの基本型に属することを思い出してください。type-of
は、それがどの型かを告げます(Lispのデータ型を参照)。しかしtype-of
は基本型以外の型については何も知りません。ほとんどの場合では、type-of
より型述語を使用するほうが便利でしょう。
この関数はobjectの基本型を名前とするシンボルをリターンする。リターン値はシンボルbool-vector
、buffer
、char-table
、compiled-function
、condition-variable
、cons
、finalizer
、float
、font-entity
、font-object
、font-spec
、frame
、hash-table
、integer
、marker
、mutex
、overlay
、process
、string
、subr
、symbol
、thread
、vector
、window
、window-configuration
のいずれか。ただしobjectがレコードなら最初のスロットで指定された型をリターンする。レコードを参照のこと。
(type-of 1) ⇒ integer
(type-of 'nil)
⇒ symbol
(type-of '()) ; ()
はnil
⇒ symbol
(type-of '(x))
⇒ cons
(type-of (record 'foo))
⇒ foo
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ここでは2つのオブジェクトの同一性をテストする関数を説明します。(たとえば文字列などの)特定の型のオブジェクト同士で内容の同一性をテストするには、別の関数を使用します。これらの述語にたいしては、そのデータ型を説明する適切なチャプターを参照してください。
この関数はobject1とobject2が同じオブジェクトならt
、それ以外はnil
をリターンする。
object1とobject2が同じ名前をもつシンボルなら、通常は同じオブジェクトだが例外もある。シンボルの作成とinternを参照のこと。他の非数値型(リストやベクター、文字列などの)にたいしては、同じ内容(または要素)の2つの引数が両者eq
である必要はない。これらが同じオブジェクトの場合だけeq
であり、その場合には一方の内容を変更するともう一方の内容にも同じ変更が反映される。
object1とobject2が異なるタイプや値をもつ数値なら同じオブジェクトではなく、eq
はnil
をリターンする。同じ値をもつfixnumなら同じオブジェクトであり、eq
はt
をリターンする。別個に計算されてたまたま同じ値をもち、かつ非fixnumタイプの同じ数値型なら、それらは同じかもしれないし違うかもしれず、Lispインタープリターが作成したオブジェクトが1つか2つかに依存してeq
はt
かnil
をリターンする。
(eq 'foo 'foo) ⇒ t
(eq ?A ?A) ⇒ t
(eq 3.0 3.0) ⇒ t または nil ;; 浮動小数にたいするeqではオブジェクト同じかもしれず違うかもしれない
(eq (make-string 3 ?A) (make-string 3 ?A)) ⇒ nil
(eq "asdf" "asdf") ⇒ t または nil ;; 文字列コンテンツにたいするeqではオブジェクト同じかもしれず違うかもしれない
(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
Emacs Lispバイトコンパイラーはリテラル文字列のような等価なリテラルオブジェクトを同一オブジェクトにたいする参照に落し込む(collapse
into)かもしれない。バイトコンパイルされたコードはそのようなオブジェクトをeq
で比較するだろうが、そうでないコードは異なるという効果がある。したがってコードではオブジェクトのリテラルコンテンツがeq
か否かではなく、以下に説明するequal
のような関数でオブジェクトの関数を使用すること。同様にコードではリテラルオブジェクトを変更(たとえばリテラル文字列へのテキストプロパティのput)しないこと。バイトコンパイラーがそれらの落し込みを行っていたら、同一コンテンツをもつ別のリテラルオブジェクトに影響があるかもしれない。
この関数は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)の場合に限りequal
となる(テキストの表現方法を参照)。
(equal "asdf" "ASDF") ⇒ nil
equal
関数はオブジェクトが整数、文字列、マーカー、ベクター、ブールベクター、バイトコード関数オブジェクト、文字テーブル、レコード、フォントオブジェクトなら、それらのコンテンツを再帰的に比較する。その他のオブジェクトは、それらがeq
の場合のみequal
とみなされる。たとえば個別の2つのバッファーは、たとえバッファーのテキスト的なコンテンツが同一であってもequal
とみなされることはない。
equal
では等価性は再帰的に定義されています。たとえば2つのコンスセルxとyを与えると、(equal
x y)
は、以下の式の両方がt
をリターンする場合だけt
をリターンします:
(equal (car x) (car y)) (equal (cdr x) (cdr y))
したがって循環リストの比較はエラーとなるような深い再帰を引き起こすかもしれず、(equal a
b)
はt
をリターンするにも関わらず(equal b
a)
はエラーをシグナルするといった直感に反する結果となることがあります。
この関数はすべてのケースにおいてequal
と同様に振る舞うが、2つの文字列がequal
になるためには、それらが同じテキストプロパティをもつ必要がある。
(equal "asdf" (propertize "asdf" 'asdf t)) ⇒ t
(equal-including-properties "asdf" (propertize "asdf" 'asdf t)) ⇒ nil
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
変更されるべきではないLispオブジェクトがいくつかあります。たとえばLisp式"aaa"
では文字列を生成しますが、そのコンテンツを変更するべきではありません。いくつかのオブジェクトは変更できません。たとえばある数値を計算して新たな数値を作成できたとしても、Lispは既存の数値を変更する操作を提供しません。
その他のLispオブジェクトはmutable(可変)オブジェクトで、副作用をともなう破壊的な操作を通じて値を変更しても安全です。たとえばマーカーを別のポイントを指すマーカーに移動することにより、既存のマーカーを変更することができます。
数値は変更不可でマーカーはすべてmutableだとしても、mutableと非mutableのメンバーをもつタイプがいくつかあります。これらのタイプにはコンス、ベクター、文字列が含まれます。たとえば"cons"
と(symbol-name
'cons)
は変更するべきではない文字列を生成しますが、(copy-sequence
"cons")
と(make-string 3
?a)
は後からaset
を呼び出すことを通じて変更可能なmutable文字列を生成します。
mutableオブジェクトは評価される式の一部となったときにmutableであることを止めます。たとえば:
(let* ((x (list 0.5)) (y (eval (list 'quote x)))) (setcar x 1.5) ;; プログラムはこれを行うべきではない y)
作成時にリスト(0.5)
がmutableでも、それはeval
に与えられたのでsetcar
を通じて変更するべきではありません。変更するべきではないオブジェクトが後からmutableになることは決してないので逆はあり得ません。
変更するべきではないオブジェクトの変更をプログラムが試みた際の動作は未定義です。Lispインタープリターがエラーをシグナルするかもしれず、クラッシュしたり他の方法で予測不能な振る舞いを引き起こすかもしれません2。
プログラムの一部として類似した定数が出現する際には、既存の定数やそのコンポーネントの再利用によってLispが時間やスペースを節約できるかもしれません。たとえば(eq
"abc"
"abc")
はインタープリターが文字列リテラル"abc"
の1つのインスタンスを作成したらt
、2つのインスタンスを作成したらnil
をリターンします。したがってこの最適化使用の有無に関わらず機能するようにLispプログラムを記述する必要があります。
[ << ] | [ < ] | [ 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 整数にたいするビット演算 | 論理的なand、or、not、shift。 | |
3.9 標準的な数学関数 | 三角関数、指数、対数関数。 | |
3.10 乱数 | 予測可能または不可能な乱数の取得。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispリーダーは、10進数字のシーケンス(オプションで最初の符号記号と最後のピリオドをともなう)として整数を読み取ります。
1 ; 整数1 1. ; 整数1 +1 ; これも整数1 -1 ; 整数-1 0 ; 整数0 -0 ; 整数0
10以外の基数をもつ整数の構文は‘#’、基数表示(radix indication)、その後の1つ以上の数字から構成されます。基数表示は2進数(binary)は‘b’、8進数(octal)は‘o’、16進数(hex)は‘x’、基数radixにたいしては‘radixr’になります。したがって‘#binteger’は2進数、‘#radixrinteger’は基数radixでintegerを読み取ります。radixの値として可能な値は2から36であり、最初のradix文字は‘0’–‘9’および‘A’–‘Z’から採択されます。英文字のcase(大文字小文字)は無視されて、最初の符号と最後のピリオドはありません。たとえば:
#b101100 ⇒ 44 #o54 ⇒ 44 #x2c ⇒ 44 #24r1k ⇒ 44
整数にたいして処理を行なうさまざまな関数、特にビット演算(整数にたいするビット演算を参照)を理解するためには、数を2進形式で見ることが助けになることがよくあります。
10進整数の5は2進数では以下のようになります:
…000101
(省略記号‘…’は概念的に先頭ビットにマッチする無限個数のビットを意味する。ここでは無限個の0ビット。後の例でも‘…’表記を使用する。)
整数の-1は以下のようになります:
…111111
-1はすべて1で表現されます(2の補数表記と呼ばれる)。
-1から4を減じることで負の整数-5が得られます。10進の整数4は2進では100です。したがって-5は以下のようになります:
…111011
このチャプターで説明する多くの関数は、数字の位置として引数にマーカー(マーカーを参照)を受け取ります。そのような関数にたいする実際の引数は数字かマーカーなので、わたしたちはこれらの引数にnumber-or-markerという名前を与えることがあります。引数の値がマーカーならマーカーの位置が使用され、マーカーのバッファーは無視されます。
Emacs
Lispでは、テキスト文字は整数により表現されます。0から(max-char)
までの整数は、有効な文字として判断されます。文字コードを参照してください。
Emacs
Lispの整数はマシンのワードサイズに制限されません。しかしその背後にはfixnumsと呼ばれる小さい整数と、bignumsと呼ばれる大きい整数という2種類の整数が存在します。Emacs
Lispコードは通常は整数がfixnumかbignumのいずれであるかに依存するべきではありませんが、Emacsの古いバージョンではfixnumだけがサポートされており、未だにfixnumだけを受け取るEmacs関数がいくつかあり、古いEmacs
Lispコードがbignumを受け取ると問題が起こるかもしれません。たとえば古いEmacs
Lispコードはeq
で整数にたいする数値の等価性を安全に比較できましたが、bignumの登場により整数の比較にはeql
や=
のような等価性にたいする述語を使うことが必要になりました。
bignumの値の範囲は主メモリー量、bignumの指数の表現に使用されるワードサイズのようなマシン特性、およびinteger-width
変数により制限されます。これらの制限は通常はfixnumにたいする制限よりは寛大です。bignumが数値的にfixnumと等しくなることはありません。Emacsはfixnum範囲内の整数を、bignumではなく常にfixnumとして表現します。
fixnumの値の範囲はマシンに依存します。最小の範囲は-536,870,912から536,870,911(30ビット長の -2**29 から 2**29 - 1) ですが、多くのマシンはより広い範囲を提供します。
この変数の値はEmacs Lispが扱える“小さい”整数の最大値。典型的な値は32ビットでは 2**29 - 1 、64ビットでは 2**61 - 1 。
この変数の値はEmacs Lispが扱える数値的に最小の“小さい”整数。これは負の整数。典型的な値は32ビットでは -2**29 、64ビットでは -2**61、 。
この変数の値は大きな整数の計算時にEmacsが範囲エラー(range error)をシグナルするかどうかを制御する負ではない整数。絶対値が 2**n (nはこの変数の値)より小さい整数の時は範囲エラーをシグナルしない。大きい整数を簡単に作成できればエラーがシグナルされない場合もあるが、通常は大きな整数の作成を試みると範囲エラーをシグナルする。この変数に大きな数値を設定すると、巨大な整数の計算にコストを要する可能性がある。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
浮動小数点数は整数以外の数値の表現に有用です。浮動小数点数の範囲は使用中マシンでのCのデータ型double
と同じ範囲です。EmacsがサポートするほとんどすべてのコンピューターではIEEEの64ビット浮動小数フォーマットであり、これはIEEE
Std 754-2019で標準化されたもので、David
Goldbergの論文“What Every Computer Scientist Should Know About Floating-Point
Arithmetic”で更に議論されています。モダンなプラットフォームでは浮動小数処理はIEEE-754標準に厳密にしたがいますが、特に32ビットX86のような一部のシステムでは丸めは常に正しい訳ではありません。
一部の古いコンピューターシステムでは、EmacsがIEEEの浮動小数点数を使わないかもしれません。わたしたちが把握している、Emacsが正しく実行されているにも関わらずIEEE-754にしたがわないようなシステムとして、GCC 10.4.0を使用してNetBSDを実行するVAXシステムが挙げられます。このシステムではVAXの‘D_Floating’フォーマットが使用されています。IBMのSystem/370系メインフレームとそのXL/Cコンパイラーも16進浮動小数点数を扱う能力がありますが、今のところEmacsはそのような構成でビルドされていません。
浮動小数点数にたいする入力構文は、小数点と指数のどちらか1つ、または両方を必要とします。オプションの符号(‘+’か‘-’)は、その数字と指数の前に記述します。たとえば‘1500.0’、‘+15e2’、‘15.0e+2’、‘+1500000e-3’、‘.15e4’は値が1500の浮動小数点数を記述する5つの方法です。これらはすべて等価です。Common Lispと同様に、Emacs Lispは指数のない浮動小数点数の小数点の後に少なくとも1つの数字を必要とします。‘1500.’は整数であって浮動小数点数ではありません。
Emacs
Lispは=
のような数学的な比較に関して、-0.0
を通常の0と数学的に同じものとして扱います。これは、(他の処理がこれらを区別するとしても-0.0
と0.0
は数学的に等しいとする)IEEE浮動小数点数規格にしたがっています。
IEEE浮動小数点数規格は浮動小数点数として、正の無限大と負の無限大をサポートします。この規格はNaNまたは“not a
number(数字ではない)”と呼ばれる値クラスも提供します。正しい答えが存在しないような場合に、数学関数はこのような値をリターンします。たとえば(/
0.0
0.0)
はNaNをリターンします。数値的にNaNはたとえ自身と比較してもすべての値にたいして数値的にイコールになることはありません。NaNは符号と仮数をもち、非数学関数は符号と仮数が一致すれば2つのNaNを等しいものと扱います。NaNの仮数は文字列表現の数字のようにマシン依存です。
NaNはIEEE浮動小数点演算を使用しないシステムでは利用できません。たとえばNaNにたいする読み取り構文をVAXで使用すると、リーダーがエラーをシグナルするでしょう。
NaNと符号つき0が関係する際にはeql
、equal
、sxhash-eql
、sxhash-equal
、gethash
のような非数学関数はそれらが数学的にイコールかではなく、値が区別できるかどうかを判断します。たとえばxとyが同じNaNなら数値比較を使用する(=
x y)
はnil
をリターンするのにたいして(equal x y)
はt
をリターンして、反対に(=
0.0 -0.0)
がt
をリターンするのにたいして(equal 0.0 -0.0)
はnil
をリターンします。
以下は、これらの特別な浮動小数点数にたいする入力構文です:
‘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が有限かつ非0なら|x|の2を底とする対数を整数に切り下げた値。xが0または無限なら値は無限大。xがNaNなら値はNaN。
(logb 10) ⇒ 3 (logb 10.0e20) ⇒ 69 (logb 0) ⇒ -1.0e+INF
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションの関数は数値や、特定の数値型にたいしてテストを行ないます。関数integerp
とfloatp
は、引数として任意のLispオブジェクト型をとることができます(でなければ、あまり使用する機会ない)。しかし述語zerop
は引数として数値を要求します。マーカーのための述語のinteger-or-marker-p
、number-or-marker-p
も参照してください。
この述語は引数が大きい整数かどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。小さい整数とは異なり大きい整数はeq
でなくても=
やeql
になり得る。
この述語は引数が小さい整数かどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。小さい整数はeq
で比較できる。
この述語は引数が浮動小数かどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。
この述語は引数が整数かどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。
この述語は引数が数(整数か浮動小数)かどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。
この述語は引数が正の整数かどうかをテストしてもしそうならt
、それ以外はnil
をリターンする(名前は“natural
number: 自然数”が由来)。0は負でないと判断される。
wholenump
はnatnump
のシノニム。
この述語は引数が0かどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。引数は数でなければならない。
(zerop x)
は(= x 0)
と等価。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
数値にたいして数学的な等価性をテストするには通常はeq
、eql
、equal
のような非数値的な比較述語のかわりに=
を使用するべきです。異なる浮動小数点オブジェクトと大きい整数オブジェクトを数値的に等しくすることができます。これらの比較にeq
を使用した場合にはそれらが同一のオブジェクトかどうかを、eql
やequal
を使用した場合にはそれらの値が区別不能かどうかをテストすることになります。対照的に=
は数値比較を使用して、非数値的な比較がnil
をリターンするような場合にt
をリターンしたり、その逆もあり得ます。浮動小数点数の基礎を参照してください。
Emacs
Lispでは2つのfixnumが数値的に等しければ同一のLispオブジェクトです。つまりfixnumではeq
は=
と同じです。値が未知のfixnumの比較にeq
を使用する方が便利な場合があります。なぜなら未知の値が数でない場合でもeq
はエラーを報告しないからです。これは任意のタイプの引数を受け付けます。対照的に引数が数でもマーカーでもなければ=
はエラーをシグナルします。しかし整数の比較においてさえ、使用できる場合には=
を使用するのがよいプログラミング習慣です。
数の比較において、2つの数が同じデータ型(どちらも整数であるかどちらも浮動小数であるか)で同じ値の場合は等しい数として扱うeql
や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)))
この関数はすべての引数が数値的に等しいかどうかをテストしてもしそうならt
、それ以外はnil
をリターンする。
この関数はeq
と同様に振る舞うが引数が両方とも数のときを除く。これは数を型と数値的な値により比較するので(eql 1.0
1)
はnil
をリターンするが、(eql 1.0 1.0)
と(eql 1
1)
はt
をリターンする。これは小さい整数と同様に大きい整数の比較に使用できる。符号、指数部、小数部が同じ浮動小数点数はeql
であり、これは数値の比較とは異なる。(eql
0.0 -0.0)
はnil
、(eql 0.0e+NaN
0.0e+NaN)
は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
この関数は最小の引数をリターンする。
(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の加算と減算を行う関数を提供します。%
を除き、これらの各関数は引き数として整数か浮動小数を受け取り、浮動小数の引数がある場合は浮動小数点数をリターンします。
この関数は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
エラー(エラーを参照)をシグナルする。IEEE-754の浮動小数点数を使用するシステムにおける浮動小数点数の除算では、非0の数を0で除することで正の無限大または負の無限大を得る(浮動小数点数の基礎を参照)。それ以外のシステムでは通常通りarith-error
エラーがシグナルされる。
この関数は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進数で表されます。ビットシーケンスは概念的には最上位ビットがすべて0か1であるような左側に無限なシーケンスです。ビット演算はそのようなシーケンスの中の個々のビットに作用します。たとえばシフト(shifting)はシーケンス全体を1つ以上左または右に移動して、移動されたのと同じパターンを再現します。
Emacs Lispのビット演算は整数だけに適用されます。
ash
(算術シフト(arithmetic
shift))は、integer1の中のビット位置を左にcountシフトする。countが負なら右にシフトする。左シフトでは右側に0が挿入されて、右シフトでは最右ビットが破棄される。整数処理として考えると、ash
はinteger1に
2**count
を乗じてから、負の無限大に向かって丸めることによりその結果を変換する。
以下はビットパターンを1ビット左にシフトしてから右にシフトする例。この例で2進数パターンの下位ビットだけを示している。先頭ビットはすべて表示されている最上位ビットと一致する。ご覧のとおり1ビットの左シフトは2を乗ずること、1ビットの右シフトは2で除してから負の無限大方向に丸められることと等価である。
(ash 7 1) ⇒ 14
;; 10進の7は10進の14になる
…000111
⇒
…001110
(ash 7 -1) ⇒ 3 …000111 ⇒ …000011
(ash -7 1) ⇒ -14 …111001 ⇒ …110010
(ash -7 -1) ⇒ -4 …111001 ⇒ …111100
以下は2ビット左にシフトしてから右に2ビットシフトする例:
; 2進数値 (ash 5 2) ; 5 = …000101 ⇒ 20 ; = …010100 (ash -5 2) ; -5 = …111011 ⇒ -20 ; = …101100
(ash 5 -2)
⇒ 1 ; = …000001
(ash -5 -2)
⇒ -2 ; = …111110
lsh
はlogical
shiftの略で、integer1のビットを左にcount回シフト(countが負なら右にシフト、空いたビットには0を補填)する。countが負ならinteger1はfixnumか正のbignumのいずれかでなければならず、lsh
はシフト前に負のfixnumをmost-negative-fixnum
で2回減算してあたかも符号なしであるかのように非負の結果を生成する。この奇妙な振る舞いはEmacsがfixnumsだけをサポートしていた頃の振る舞いであり、現在ではash
がより良い選択である。
integer1とcount1がいずれも負の場合を除いてlsh
はash
のように振る舞うので、以下の例ではこれらの例外ケースに焦点をあてている。これらの例は30ビットのfixnumsを想定している。
; 2進数値 (ash -7 -1) ; -7 = …111111111111111111111111111001 ⇒ -4 ; = …111111111111111111111111111100 (lsh -7 -1) ⇒ 536870908 ; = …011111111111111111111111111100
(ash -5 -2) ; -5 = …111111111111111111111111111011 ⇒ -2 ; = …111111111111111111111111111110 (lsh -5 -2) ⇒ 268435454 ; = …001111111111111111111111111110
この関数は引数のビットの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)である。logand
に渡す引数が1つだけならその引数がリターンされる。
; 2進数値 (logand 14 13) ; 14 = …001110 ; 13 = …001101 ⇒ 12 ; 12 = …001100
(logand 14 13 4) ; 14 = …001110 ; 13 = …001101 ; 4 = …000100 ⇒ 4 ; 4 = …000100
(logand)
⇒ -1 ; -1 = …111111
この関数は、引数のビット単位の包含的ORをリターンする。少なくとも1つの引数でn番目のビットが1なら、結果のn番目のビットが1になる。引数を与えなければ、結果はこの処理にたいする単位元である0となる。logior
に渡す引数が1つだけならその引数がリターンされる。
; 2進数値 (logior 12 5) ; 12 = …001100 ; 5 = …000101 ⇒ 13 ; 13 = …001101
(logior 12 5 7) ; 12 = …001100 ; 5 = …000101 ; 7 = …000111 ⇒ 15 ; 15 = …001111
この関数は、引数のビット単位の排他的ORをリターンする。n番目のビットが1であるような引数の数が奇数個の場合のみ、結果のn番目のビットが1となる。引数を与えなければ、結果はこの処理の単位元である0となる。logxor
に渡す引数が1つだけならその引数がリターンされる。
; 2進数値 (logxor 12 5) ; 12 = …001100 ; 5 = …000101 ⇒ 9 ; 9 = …001001
(logxor 12 5 7) ; 12 = …001100 ; 5 = …000101 ; 7 = …000111 ⇒ 14 ; 14 = …001110
この関数は引数のビット単位の補数(bitwise complement)をリターンする。integerのn番目のビットが0の場合に限り、結果のn番目のビットが1になり、その逆も成り立つ。結果は-1 - integerと等価。
(lognot 5) ⇒ -6 ;; 5 = …000101 ;; becomes ;; -6 = …111010
この関数はintegerのハミング重み (Hamming weight: integerの2進数表現での1の個数)をリターンする。integerが負なら、その2の補数の2進数表現での0ビットの個数をリターンする。結果は常に非負となる。
(logcount 43) ; 43 = …000101011 ⇒ 4 (logcount -43) ; -43 = …111010101 ⇒ 3
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の数学的関数は、引数として整数と同様に浮動小数点数も受け入れます。
(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未満の値から選択される。それ以外なら値はLispで表現可能な任意のfixnum(most-negative-fixnum
からmost-positive-fixnum
の間の任意の整数)となるだろう(整数の基礎を参照)。
limitが文字列なら、その文字列定数にもとづいた新しいシードを選択することを意味する。これにより後でrandom
を呼び出して再現可能な結果シーケンスをリターンさせることができる。
limitがt
なら、あたかもEmacsが再起動されたかのように新たなシードが選択されることを意味する。これにより後でrandom
を呼び出して予測不能な結果シーケンスをリターンさせることができる。
暗号化用に乱数ノンス(random nonce:
使い捨てのランダム値)が必要な場合にrandom
を使用するのは、いくつかの理由により適切ではありません:
(random
t)
を用いるのは可能とはいえ、あなたのプログラムのうち再現可能な結果から恩恵を受ける他の部分に悪影響を与えるかもしれない。
random
が使用するシステム依存の疑似乱数ジェネレーター(PRNG: pseudo-random number
generator)は、必ずしも暗号化に適している訳ではない。
(random
t)
は、システムエントロピーへの直接的アクセスを提供しない。このエントロピーはシステム依存のPRNGを通過するので、結果にバイアスがかかる可能性がある。
(random t)
の呼び出しによって、Emacsの内部状態が散在するノンス情報が残るので、内部的な攻撃面のサイズが増加する。
(random t)
が暗号化にたいして脆弱なソースからシードされる。
[ << ] | [ < ] | [ 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 カスタムフォーマット文字列 | カスタマイズしたformat 仕様によるフォーマット。
| |
4.9 Lispでの大文字小文字変換 | 大文字小文字の変換関数。 | |
4.10 caseテーブル | case変換のカスタマイズ。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
文字(character)とは、テキスト内の1つの文字を表すLispオブジェクトです。Emacs Lispでは文字は単なる整数です。ある整数が文字か文字でないかを区別するのは、それが使用される方法だけです。Emacsでの文字表現についての詳細は文字コードを参照してください。
文字列(string)とは固定された文字シーケンスです。これは配列(array)と呼ばれるシーケンス型であり、配列長が固定で一度作成したら変更できないことを意味します(シーケンス、配列、ベクターを参照)。Cとは異なり、Emacs Lispの文字列は文字コードを判断することにより終端されません。(訳注: 文字列の終端用の文字コードはない、ということ。)
文字列は配列であるということは同様にシーケンスでもあるので、シーケンス、配列、ベクターにドキュメントされている一般的な配列関数やシーケンス関数で文字列を処理できます。たとえば関数aref
を使用して文字列内の特定の文字にアクセスしたり変更することができます(配列を操作する関数を参照)。
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文字を参照してください。ディスプレイ上の文字列幅の計算にlength
を使用するべきではないことにも注意してください。かわりにstring-width
を使用してください(表示されるテキストのサイズを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
一般的なシーケンスや配列にたいする述語についての情報は、シーケンス、配列、ベクターと配列を参照してください。
この関数はobjectが文字列ならt
、それ以外はnil
をリターンする。
この関数はobjectが文字列かnil
ならt
、それ以外はnil
をリターンする。
この関数はobjectが文字列か文字(たとえば整数)ならt
、それ以外はnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はスクラッチ、文字列同士、またはその一部から文字列を作成します(string-replace
やreplace-regexp-in-string
のように他の文字列内容を変更して文字列を作成する関数については検索と置換を参照)。
この関数はcharacterをcount回繰り返すことにより作成された文字列をリターンする。countが負ならエラーをシグナルする。
(make-string 5 ?x) ⇒ "xxxxx" (make-string 0 ?x) ⇒ ""
characterがASCII文字なら、結果は通常はユニバイト文字列になる。しかしオプション引数multibyteが非nil
なら、この関数はかわりにマルチバイト文字列を生成する。これは結果を後で非ASCII文字列と結合したり、結果の中のいくつかの文字を非ASCII文字で置換する必要がある際に有用。
この関数に対応する他の関数には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
は空のシーケンス。
(concat "abc" nil "-def")
⇒ "abc-def"
(concat "The " "quick brown " "fox.")
⇒ "The quick brown fox."
(concat)
⇒ ""
この関数は常に新たな文字列の割り当てを行う訳ではない。呼び出し側は結果が新たな文字列であること、もしくは既存の文字列にたいしてeq
であることに依存しないよう推奨する。
特にリターン値を変更すると誤って別の文字列を変更したり、プログラム内の定数文字列の変更や、エラーをraiseすることさえあり得る。安全に変更できる文字列を取得するには、結果にcopy-sequence
を使用すること。
他の結合関数(concatenation functions)についての情報は関数のマッピングのmapconcat
、ベクターのための関数のvconcat
、コンスセルおよびリストの構築のappend
を参照のこと。シェルコマンドで使用される文字列の中に、個々のコマンドライン引数を結合するには、combine-and-quote-stringsを参照されたい。
この関数は正規表現separators(正規表現を参照)にもとづいて、stringを部分文字列に分解する。separatorsにたいする各マッチは分割位置を定義する。分割位置の間にある部分文字列をリストにまとめてリターンする。
separatorsがnil
(か省略)ならデフォルトはsplit-string-default-separators
の値となり、関数はomit-nullsがt
であるかのように振る舞う。
omit-nullsがnil
(または省略)なら、連続する2つのseparatorsへのマッチか、stringの最初か最後にマッチしたときの空文字列が結果に含まれる。omit-nullsがt
なら、これらの空文字列は結果から除外される。
オプションの引数trimが非nil
なら、その値は各部分文字列の最初と最後からトリム(trim:
除去)するテキストにマッチする正規表現を指定する。トリムによりその部分文字列が空になるようなら、それは空文字列として扱われる。
文字列を分割してcall-process
やstart-process
に適するような、個々のコマンドライン引数のリストにする必要がある場合はsplit-string-and-unquoteを参照のこと。
以下は例:
(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")
split-string
のseparatorsにたいするデフォルト値。通常の値は"[ \f\t\n\r\v]+"
。
string内の連続する空白文字を単一のスペースに、同様にstringの先頭と終端にあるすべての空白文字を取り除くことにより空白文字を整理する。
stringの先頭からregexpにマッチするテキストを削除する。regexpのデフォルトは‘[ \t\n\r]+’。
stringの末尾からregexpにマッチするテキストを削除する。regexpのデフォルトは‘[ \t\n\r]+’。
stringからtrim-leftにマッチする先頭のテキストと、trim-rightにマッチする末尾のテキストを削除する。いずれのregexpもデフォルトは‘[ \t\n\r]+’。
lengthより長い行が無くなるようにstringのワードラップを試みる。フィルは空白文字境界でのみ行われる。lengthより長い個別の単語は短くならない。
stringの文字数がlengthより短ければstringをそのままリターンする。それ以外なら最初のlength文字からなるstringの部分文字列をリターンする。オプションのパラメーターendが与えられた場合には、かわりに最後のlength文字からなる文字列をリターンする。
coding-systemが非nil
ならstringを切り詰める前にエンコードして、結果はlength
バイトより短いユニバイト文字列になる。stringにエンコードされると複数バイトになる文字(たとえばutf-8
使用時)が含まれる場合には、結果となるユニバイト文字列が文字表現の途中で切り詰められることはない。
この関数は文字列長を文字数かバイトで数えるので、文字列を表示用に短くする必要がある場合には一般的に適していない。かわりにtruncate-string-to-width
、window-text-pixel-size
、string-glyph-split
を使用すること(表示されるテキストのサイズを参照)。
改行を境界としてstringを文字列のリストに分割する。オプション引数omit-nullsが非nil
なら、結果から空行を除外する。オプション引数keep-newlinesが非nil
なら、結果文字列から末尾の改行を取り除かない。
paddingをパディング文字に使用して、与えられたlengthになるようにstringをパディングする。paddingのデフォルトはスペース文字。lengthよりstringが長ければパディングしない。startがnil
(または省略)ならパディングは文字列終端、非nil
なら文字列先頭に追加される。
stringからもしあれば最後の改行を削除する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションで説明する処理を介して変更可能な文字列のコンテンツを変更できます。可変性を参照してください。
既存の文字列の内容を変更するもっとも基本的な方法は、aset
(配列を操作する関数を参照)を使用する方法です。(aset string idx char)
は、stringの文字インデックスidxに、charを格納します。これはstringが純正なASCIIなら必要に応じてマルチバイト文字列(テキストの表現方法を参照)に変換しますが、charがrawバイトではなく非ASCII文字の場合には、たとえばstring-to-multibyte
(テキスト表現の変換を参照)を使う等により、stringがマルチバイトになるよう常に保証することをお勧めします。
より強力な関数はstore-substring
です:
この関数は文字インデックスidxで開始される位置にobjを格納することにより、指定されたstringの内容の一部を変更する。objは文字(この場合にはaset
とまったく同じように振る舞う)、または(stringより小さい)文字列。objがマルチバイト文字列の場合には、たとえstringが純正のASCII文字列であってもマルチバイト文字列に変更することを推奨する。
既存の文字列の文字数を変更するのは不可能なので、文字インデックスidxを開始位置としたときに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
ユニバイト文字列とマルチバイト文字列がstring=
において等しくなるのは、すべての文字が0から127の範囲(ASCII)にある同じ文字シーケンスを含む場合だけである。テキストの表現方法を参照のこと。
string-equal
はstring=
の別名である。
string-equal-ignore-case
はcase-fold-search
がt
の際のchar-equal
のように、case(大文字小文字)の違いを無視して文字列を比較する。
この関数はlocale (デフォルトはカレントのシステムlocale)で指定された照合ルール(collation
rule)にもとづいて、string1とstring2が等しければt
をリターンする。照合ルールはstring1とstring2に含まれる文字の辞書順だけではなく、それらの文字間の関係に関する他のルールにより判断される。これは通常はEmacs実行中のlocale環境、およびEmacsがリンクされた標準Cライブラリー3により決定される。
たとえばUnicode文字の異なるグレイブアクセントのように、コーディングポイントが異なっても意味が同じなら、一部のlocaleでは等しいとみなされるかもしれない。
(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
なら、文字を小文字に変換することによってcaseを区別せずに文字の比較を行う。ただし背景となるシステムライブラリーがlocale固有の照合ルールを提供していない場合には、この関数はstring-equal
にフォールバックする。この場合にはignore-case引数を無視して、常にcaseを区別した比較を行う。
MS-WindowsシステムでUnicode互換の照合をエミュレートする場合、MS-Windowsではlocaleのコードセット部分を"UTF-8"
にできないので、w32-collate-ignore-punctuation
に非nil
値をバインドすること。
あるlocale環境をシステムがサポートしなれければ、この関数はstring-equal
と同様に振る舞う。
一般的にファイルシステムは照合ルールが実装するような文字列の言語学的な等価性を尊重しないので、この関数をファイル名の等価性の比較に使用しないこと。
この関数は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)
を呼び出すのと等価である。
この関数は指定されたlocale
(デフォルトはカレントのシステムlocale)の照合順において、string1がstring2より小さければt
をリターンする。照合順はstring1とstring2に含まれる文字の辞書順だけではなく、それらの文字間の関係に関するルールによっても判断される。これは通常はEmacs実行中のlocale環境、およびEmacsとリンクされた標準Cライブラリーによって決定される。
たとえばソートでは区切り文字と空白文字は無視されるだろう(シーケンスを参照)。
(sort (list "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 (list "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
なら、文字を小文字に変換することによってcaseを区別せずに文字の比較を行う。ただし背景となるシステムライブラリーがlocale固有の照合ルールを提供していない場合には、この関数はstring-equal
にフォールバックする。この場合にはignore-case引数を無視して、常にcaseを区別した比較を行う。
MS-WindowsシステムでUnicode互換の照合をエミュレートする場合、MS-Windowsではlocaleのコードセット部分を"UTF-8"
にできないので、w32-collate-ignore-punctuation
に非nil
値をバインドすること。
locale環境をサポートしないシステムでは、この関数はstring-lessp
と同様に振る舞う。
この関数は文字列を辞書順で比較するが、数字のシーケンスを10進数で構成されているかのように扱い、その数値を比較する。つまりたとえ辞書順で‘12’が‘2’より“小”だとしても、この述語に応じて‘foo12.png’より‘foo2.png’が“小”になる。
この関数はstring1がstring2のプレフィクス(たとえばstring2がstring1で始まる)なら、非nil
をリターンする。オプションの引数ignore-caseが非nil
なら、比較においてcaseの違いは無視される。
この関数はsuffixがstringのサフィックス(たとえばstringがsuffixで終わる)なら、非nil
をリターンする。オプションの引数ignore-caseが非nil
なら、比較においてcaseの違いは無視される。
haystack内で最初にneedle
(いずれも文字列)が出現する位置をリターンする。start-posが非nil
なら、検索はneedle内のその位置から開始される。マッチ(一致するもの)が見つからなければnil
をリターンする。この関数は比較を行う際にはテキストプロパティは無視して、文字列内の文字だけを考慮する。マッチングでは常にcaseを区別する。
この関数はstring1の指定部分をとstring2指定部分を比較する。string1の指定部分とは、インデックスstart1(その文字を含む)から、インデックスend1(その文字を含まない)まで。start1にnil
を指定すると文字列の最初という意味になり、end1にnil
を指定すると文字列の長さを意味する。同様にstring2の指定部分とはインデックスstart2からインデックスend2まで。
文字列は文字列内の文字の数値により比較される。たとえばstr1とstr2は、最初に異なる文字でstr1の文字の数値が小さければ小さいと判断される。ignore-caseが非nil
なら比較を行なう前に、カレントバッファーのcaseテーブル(caseテーブルを参照)を使用して大文字に変換される。比較用にユニバイト文字列はマルチバイト文字列に変換されるので(テキストの表現方法を参照)、ユニバイト文字列とそれを変換したマルチバイト文字列は常に等しくなる。
2つの文字列の指定部分がマッチ(一致)した場合、値はt
になる。それ以外なら値は整数で、何文字が一致してどちらの文字が小さいかを示す。この値の絶対値は、2つの文字列の先頭から一致した文字数に1加えた値になる。string1(または指定部分)のほうが小さければ符号は負になる。
この関数はソース文字列string1とターゲット文字列string2の間のレーベンシュタイン距離(Levenshtein distance)をリターンする。レーベンシュタイン距離はソース文字列をターゲット文字列に変換(削除、挿入、置換)するために必要な単一文字の個数。これは文字列間の編集距離(edit distance)として使用可能な定義の1つである。
計算距離にとって文字列の英字のcase(大文字小文字)は意味をもつが、テキストプロパティは無視される。オプション引数bytecompareが非nil
なら、この関数は文字ではなくバイトで計算する。バイト単位での比較はEmacsの内部的な文字表現を使用するので、rawバイトを含むマルチバイト文字列では不正確な結果を生成するかもしれない(テキストの表現方法を参照)。rawで正確な結果が必要なら、エンコードして文字列をユニバイトにすること(明示的なエンコードとデコードを参照)。
この関数は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の先頭にあるスペースとタブはスキップして、与えられた基数で数字として解釈できるところまで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を復号化したものと置換したものと等しい文字列をリターンする。引数objectsはフォーマットされる計算値。
(もしあれば)string内のフォーマット仕様以外の文字はテキストプロパティを含めて出力に直接コピーされる。フォーマット仕様のすべてのテキストプロパティは引数objectsを表現する生成された文字列にコピーされる。
出力される文字列は新規に割り当てられる必要はない。たとえばx
が文字列"foo"
なら(eq x (format
x))
と(eq x (format "%s" x))
はいずれもt
となるだろう。
この関数はformat
と同様に機能するが、string内のすべてのグレイブアクセント(`)とアポストロフィー(')をtext-quoting-style
の各値に応じて変換する点が異なる。
フォーマット内のグレイブアクセントとアポストロフィーはマッチするcurved quotesに変換される("Missing `%s'"は"Missing ‘foo’"という結果になる)この変換の影響と回避についてはテキストのクォートスタイルを参照のこと。
フォーマット仕様(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コードが生成した文字列の場合に当てはまります。その文字列が決して文字‘%’を含まないと確信できないならば、以下で説明するように最初の引数に"%s"
を渡して、その不定な文字列を2番目の引数として渡します:
(format "%s" arbitrary-string)
ある種のフォーマット仕様は特定の型の値を要求します。その要求に適合しない値を与えた場合にはエラーがシグナルされます。
以下は有効なフォーマット仕様のテーブルです:
フォーマット仕様を、クォートなしのオブジェクトのプリント表現で置き換える(つまりprin1
ではなくprinc
を使用して置き換える。出力関数を参照されたい)。したがって文字列は‘"’文字なしの文字列内容だけが表示され、シンボルは‘\’文字なしで表される。
オブジェクトが文字列なら文字列のプロパティは出力にコピーされる。‘%s’のテキストプロパティ自身もコピーされるが、オブジェクトのテキストプロパティが優先される。
フォーマット仕様を、クォートありのオブジェクトのプリント表現で置き換える(つまりprin1
を使用して変換する。出力関数を参照されたい)。したがって文字列は‘"’文字で囲まれ、必要となる特別文字の前に‘\’文字が表示される。
フォーマット仕様を整数の8進表現に置き換える。負の整数はプラットフォーム依存の方法でフォーマットされる。オブジェクトは浮動小数点数(小数部分を切り捨てて整数にフォーマット)でもよい。
フォーマット仕様を10進表現の符号つき整数で置き換える。オブジェクトは浮動小数点数(小数部分を切り捨てて整数にフォーマット)でもよい。
フォーマット仕様を16進表現の整数で置き換える。負の整数はプラットフォーム依存の方法でフォーマットされる。‘%x’なら小文字、‘%X’なら大文字が使用される。オブジェクトは小数部分を切り捨てて整数にフォーマットされた浮動小数点数でもよい。
フォーマット仕様を与えられた値の文字で置き換える。
フォーマット仕様を浮動小数点数の指数表現で置き換える。
フォーマット仕様を浮動小数点数にたいする10進小数表記で置き換える。
指数表記か小数点表記のいずれかを使用してフォーマット仕様を浮動小数点数にたいする表記に置き換える。指数が-4未満または精度(デフォルトは6)以上なら指数表記を使用する。デフォルトでは結果の小数部の末尾の0は削除されて、小数点が現れるのは後に数字が続く場合のみ。
フォーマット仕様を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-ja.texi’." (format-message "The buffer object prints as `%s'." (current-buffer)) ⇒ "The buffer object prints as ‘strings-ja.texi’."
フォーマット仕様はデフォルトではobjectsから連続して値を引き当てます。つまりstring内の1番目のフォーマット仕様は1番目の値、2番目のフォーマット仕様は2番目の値、...を使用します。余分なフォーマット仕様(対応する値がない場合)にはエラーとなります。フォーマットされる値が余分にある場合には無視されます。
フォーマット仕様はフィールド番号(field number)をもつことができます。これは最初の‘%’の直後に10進数字、その後にドル記号‘$’が続きます。これにより次の引数ではなく与えられた番号の引数をフォーマット仕様に変換させることができます。フィールド番号は1から始まります。フォーマットのフォーマット仕様が番号を含むことも含まないことも可能ですが、両方を含むことはできません。ただし例外は‘%%’であり、これは番号付きのフォーマット仕様と混交できます。
(format "%2$s, %3$s, %%, %1$s" "x" "y" "z") ⇒ "y, z, %, x"
‘%’とすべてのフィールド番号の後にフラグ文字(flag characters)を配置できます。
フラグ‘+’は非負の数の前にプラス符号を挿入するので、数には常に符号がつきます。フラグとしてスペースを指定すると、非負の数の前に1つのスペースが挿入されます(それ以外は非負の数は最初の数字から開始される)。これらのフラグは非負の数と負数にたいして確実に同じ列数を使用させるために有用です。これらは‘%d’、‘%e’、‘%f’、‘%g’以外では無視され、両方が指定された場合は‘+’が優先されます。
フラグ‘#’は代替形式(alternate form)を指定します。これは使用するフォーマットに依存します。‘%o’にたいしては結果を‘0’で開始させます。‘%x’と‘%X’にたいしては非0の結果のプレフィクスは‘0x’または‘0X’になります。‘%e’、‘%f’にたいしての‘#’フラグは、小数部が0のときにも小数点が含まれることを意味します。‘%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."
フォーマット仕様はフィールド幅(width)をもつことができます。これはすべてのフィールド番号とフラグの後にある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."
すべてのフォーマット仕様文字にはフィールド番号、フラグ、フィールド幅の後にオプションで精度(precision)を指定できます。精度は小数点‘.’と、その後に桁文字列(digit-string)を指定します。浮動小数点数のフォーマット仕様(‘%e’と‘%f’)では、精度は表示する小数点以下の桁数を指定します。0なら小数点も省略されます。%gの精度が0か未指定なら1として扱われます。‘%s’と‘%S’では精度として与えられた幅に文字列が切り詰められるので、‘%.3s’ではobjectの表現の最初の3文字だけが表示されます。その他の仕様文字では、printf
ファミリーのローカルライブラリーが生成する精度の効果が表れます。
‘%s’と‘%S’にたいしては、文字列を精度で指定された幅に切り詰めます。したがって‘%.3s’では、objectにたいするプリント表現の最初の3文字だけが表示されます。他のフォーマット仕様文字にたいしては、精度の効果はローカルライブラリーのprintf
関数ファミリーが生成する効果となります。
フォーマット済みの値のコピーを取得するために後でread
を使用する予定なら、read
が値を再構築する仕様を使用してください。この逆手順で数値をフォーマットするには‘%s’と‘%S’、整数だけなら‘%d’、非負の整数なら‘#x%x’と‘#o%o’も使用できます。その他のフォーマットでは問題があるかもしれません。たとえば‘%d’と‘%g’はNaNを誤って処理したり精度や型を失うかもしれず、‘#x%x’と‘#o%o’は負の整数を誤って処理するかもしれません。入力関数を参照してください。
このセクションでは仕様文字の固定セットを受け取る関数を説明します。次のセクションでは‘%a’や‘%z’のようなカスタム仕様文字を受け取ることができる関数format-spec
を説明します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ユーザーやLispプログラムが、カスタムフォーマットの制御文字列を介して特定のテキストが生成される方法を制御できるようにすると便利な場合があります。たとえばフォーマット文字列は人の姓や名、emailアドレスを表示する方法を制御できます。前のセクションで説明した関数format
を使用することにより、フォーマット文字列は"%s %s <%s>"
のようになるかもしれません。しかしこのアプローチはどの仕様文字がどの情報に対応するかが不明瞭なのですぐに非実用的になります。
そのような場合には"%f %l <%e>"
のようなフォーマット文字列のほうが便利かもしれません。このフォーマット文字列では仕様文字それぞれがより意味的な情報をもち、他の仕様文字に関連して簡単に再配置できるので、このようなフォーマット文字列はユーザーにより簡単にカスタマイズできます。
このセクションで説明する関数format-spec
はformat
と同様の機能を処理しますが、任意の仕様文字を使用するフォーマットコントロール文字列を処理する点が異なります。
この関数はspec-alistで指定された変換にしたがってフォーマット文字列templateから生成された文字列をリターンする。spec-alistは(letter . replacement)
という形式のalist(連想リストを参照)。template内の仕様%letter
はそれぞれ結果文字列のフォーマット時に置換される。
(もしあれば)template内のフォーマット仕様以外の文字はテキストプロパティを含めて出力に直接コピーされる。フォーマット仕様のすべてのテキストプロパティは置換先にコピーされる。
変換の指定にalistを使用することによって有用な特性がいくつか生成される:
REPLACEMENTは引数なしで呼び出されて置換に用いる文字列をリターンする関数でもよい。この関数はTEMPLATEで対応するLETTERが使用された際にのみ呼び出される。これはたとえば必要なとき以外は入力を求めるプロンプトの表示を避ける場合に役に立つかもしれない。
オプション引数ignore-missingは、spec-alistで見つからないtemplate内の仕様文字の処理方法を示す。nil
か省略なら、関数はエラーをシグナルする。ignore
ならこれらのフォーマット仕様は(もしあれば)テキストプロパティも含めてそのまま出力する。delete
ならこれらのフォーマット仕様は出力から取り除かれる。これら以外の非nil
値はignore
と同様に処理されるが、出力中に‘%%’があればそのまま残される。
オプション引数splitが非nil
なら、format-spec
は単一文字列のかわりに置換場所を基準に結果を文字列リストに分割してリターンする。たとえば:
(format-spec "foo %b bar" '((?b . "zot")) nil t) ⇒ ("foo " "zot" " bar")
format-spec
が受け取るフォーマット仕様の構文はformat
が受け取るフォーマット仕様と似ていますが同一ではありません。いずれの場合でもフォーマット仕様は‘%’で始まり‘s’のようなアルファベット文字で終わる文字シーケンスです。
仕様文字の固定セットに特定の意味を割り当てるformat
とは異なり、format-spec
は任意の仕様文字を受け取ってそれらをすべて等しく扱います。たとえば:
(setq my-site-info (list (cons ?s system-name) (cons ?t (symbol-name system-type)) (cons ?c system-configuration) (cons ?v emacs-version) (cons ?e invocation-name) (cons ?p (number-to-string (emacs-pid))) (cons ?a user-mail-address) (cons ?n user-full-name))) (format-spec "%e %v (%c)" my-site-info) ⇒ "emacs 27.1 (x86_64-pc-linux-gnu)" (format-spec "%n <%a>" my-site-info) ⇒ "Emacs Developers <emacs-devel@gnu.org>"
フォーマット仕様には置換の様相を変更するために、‘%’の直後に任意個数のフラグ文字を含めることができます。
このフラグは指定された幅のパディングをスペースのかわりに‘0’で構成する。
このフラグは指定された幅のパディングを左側ではなく右側に挿入する。
このフラグはもし幅と精度が指定されたら置換の左側を切り捨てる。
このフラグはもし幅が指定されたら置換の右側を切り捨てる。
このフラグは置換されるテキストを大文字に変換する(Lispでの大文字小文字変換を参照)。
このフラグは置換されるテキストを小文字に変換する(Lispでの大文字小文字変換を参照)。
矛盾したフラグ(たとえば大文字と小文字)を使用した場合の結果は未定義です。
format
の場合と同様に幅(任意のフラグの後の10進数値)、精度(任意のフラグと幅の後の小数点‘.’に続く10進数)をフォーマット仕様に含めることができます。
指定した幅より置換の文字が少なければ左側がパディングされます。
(format-spec "%8a is padded on the left with spaces" '((?a . "alpha"))) ⇒ " alpha is padded on the left with spaces"
指定した精度より置換の文字が多ければ右側が切り詰められます。
(format-spec "%.2a is truncated on the right" '((?a . "alpha"))) ⇒ "al is truncated on the right"
以下は前述の機能をいくつか組み合わせたより複雑な例です:
(setq my-battery-info (list (cons ?p "73") ; パーセント表示 (cons ?L "Battery") ; 状態 (cons ?t "2:23") ; 残り時間 (cons ?c "24330") ; 容量 (cons ?r "10.6"))) ; 放電率 (format-spec "%>^-3L : %3p%% (%05t left)" my-battery-info) ⇒ "BAT : 73% (02:23 left)" (format-spec "%>^-3L : %3p%% (%05t left)" (cons (cons ?L "AC") my-battery-info)) ⇒ "AC : 73% (02:23 left)"
このセクションの例で示したように、format-spec
はさまざまな情報の断片を選択的にフォーマットするために頻繁に使用されます。これはプログラムが可能にする情報のサブセットだけをユーザーが通常の構文で望む順序で選択できるように、ユーザーにカスタマイズ可能なフォーマット文字列を提供するプログラムにとって有用です。
[ << ] | [ < ] | [ 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変換コードポイントを1対1でマップするものではなく、結果の文字列長は引数の文字列長と異なるかもしれません。さらに文字を渡すことによりリターンされる型にも文字が強制されるので、関数は正しい置換を行えずに1文字の文字列を処理する場合とは結果が異なるかもしれません。たとえば:
(upcase "fi") ; 注意: 1文字の合字 "fi" ⇒ "FI"
(upcase ?fi) ⇒ 64257 ; つまり ?fi
これを避けるためにはcase関数のいずれかに文字を渡す前にstring
関数を使用して文字列に変換しなければなりません。もちろん結果の長さについて仮定はできません。
このような特殊ケースのマッピングはspecial-uppercase
、special-lowercase
、special-titlecase
から取得されます。文字のプロパティを参照してください。
文字列を比較する関数(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
で終端された構造を正リスト(proper
list)と呼びます4。Emacs
Lispではシンボルnil
はシンボルであり、かつ要素なしのリストでもあります。便宜上、シンボルnil
はそのCDR(とCAR)にnil
をもつと考えます。
したがって正リストのCDRは常に正リストです。空でない正リストのCDRは1番目の要素以外を含む正リストです。
リストの最後のコンスセルのCDRがnil
以外の何らかの値の場合、このリストのプリント表現はドットペア表記(dotted pair
notation。ドットペア表記を参照のこと)を使用するので、わたしたちはこの構造をドットリスト(dotted
list)と呼びます。他の可能性もあります。あるコンスセルのCDRが、そのリストのそれより前にある要素を指すかもしれません。わたしたちは、この構造を循環リスト(circular
list)と呼びます。
ある目的においてはそのリストが正リストか循環リストなのか、あるいはドットリストなのかが問題にならない場合もあります。そのプログラムがリストを充分に辿って最後のコンスセルのCDRを確認しようとしないなら、これは問題になりません。しかしリストを処理する関数のいくつかは正リストを要求し、ドットリストの場合はエラーをシグナルします。リストの最後を探そうと試みる関数のほとんどは循環リストを与えると無限ループに突入します。リストが正リストかどうかを判断するためには、次セクションで説明する関数proper-list-p
(proper-list-pを参照)を使うことができます。
ほとんどのコンスセルはリストの一部として使用されるので、わたしたちはコンスセルで構成される任意の構造をリスト構造(list structure)と呼びます。
[ << ] | [ < ] | [ 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の最初のn個の要素をリターンする。要するにlistからnthcdr
をスキップした部分をリターンする。
listの要素の数がnより少なければlist、nが0か負ならnil
をリターンする。
(take 3 '(a b c d)) ⇒ (a b c)
(take 10 '(a b c d)) ⇒ (a b c d)
(take 0 '(a b c d)) ⇒ nil
これは引数であるリストの構造を破壊的に変更することによって機能するバージョンのtake
である。これにより高速になるが、listの元の値は失われるだろう。
ntake
は要素の数がnより少なければ変更せずにlistを、nが0か負ならnil
をリターンする。それ以外の場合には最初のn個の要素に切り詰められたlistをリターンする。
これはnが正だと判っていない場合には単純に切り詰め効果を信頼するのではなく、通常はリターン値を使うほうが賢明だということを意味している。
この関数は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)
と同じ。
上記に加えてcxxxr
やcxxxxr
のようなcar
とcdr
で構成される24の関数が定義されています。ここでx
はa
かd
のいずれかです。cadr
とcaddr
とcadddr
はそれぞれリストの2つ目、3つ目、4つ目の要素です。cl-libは同じものをcl-second
、cl-third
、cl-fourth
という名前で提供しています。List
Functions in Common Lisp Extensionsを参照してください。
この関数はリスト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
がよく使用される。これをリストに要素をコンスすると言います。5たとえば:
(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
なら、この関数はベクターでもコピーします(そしてベクターの要素を再帰的に処理する)。
この関数はtreeを“平坦化”したコピー(
treeをルートとするコンスセルのツリーのすべての非nil
な終端nodeとleave)をリターンする。リターンされたリストのleaveの順序はtreeでの順序と同じ。
(flatten-tree '(1 (2 . 3) nil (4 5 (6)) 7)) ⇒(1 2 3 4 5 6 7)
この関数はobjectをリストとしてリターンする。objectがすでにリストならそれをリターンし、それ以外ならobjectを含む1要素のリストをリターンする。
これは通常はリストのときもあればそうでないときもある変数を使用する場合に有用であり、たとえば以下のような記述ができる:
(dolist (elem (ensure-list foo)) (princ elem))
この関数は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番目の要素は、厳密に(+
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
のような通常の関数である。クォートしたい場合には自分で引数をクォートすること。
symbolがレキシカル変数を参照する際にはこの関数を使用しないこと。
以下に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)
と等価な式です:
(if (member value var) 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
プロパティにハッシュテーブルで保存される。symbolはレキシカル変数を参照できない。
以下に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のコンテンツを変更できます。これらは既存のリスト構造を変更するので破壊的な操作です。破壊的操作はmutable(変更可能)なリスト、すなわちcons
、list
、または類似の操作により構築される必要があります。クォートにより作成されたリストはプログラムの一部であり、破壊的な操作により変更するべきではありません。可変性を参照してください。
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 (list 1 2)) ⇒ (1 2)
(setcar x 4) ⇒ 4
x ⇒ (4 2)
コンスセルが複数のリストを共有する構造の一部なら、コンスに新しいCARを格納することにより、これら共有されたリストの各1つの要素を変更します。以下は例です:
;; 部分的に共有された2つのリストを作成
(setq x1 (list '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 (list 1 2 3)) ⇒ (1 2 3)
(setcdr x '(4)) ⇒ (4)
x ⇒ (1 4)
リスト内のコンスセルのCDRを変更することにより、リストの途中から要素を削除できます。たとえば以下では、1番目のコンスセルのCDRを変更することにより、2番目の要素b
をリスト(a
b c)
から削除します。
(setq x1 (list '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 (list '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 (list 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 (list 1 2 3)) ⇒ (1 2 3)
(nconc x 'z) ⇒ (1 2 3 . z)
x ⇒ (1 2 3 . z)
しかし他の(最後を除くすべての)引数はmutableリストでなければなければならない。
一般的な落とし穴としては、nconc
にたいしてリスト定数を最後以外の引数として使用した場合である。これを行なった場合の結果としての挙動は未定義である(自己評価を行うフォームを参照)。実行するごとにプログラムはリスト定数を変更する可能性がある! (必ず発生する保証はないが)以下のようなことが起こり得る:
(defun add-foo (x) ; この関数ではfoo
(nconc '(foo) x)) ; を引数の前に追加したい
(symbol-function 'add-foo) ⇒ (lambda (x) (nconc '(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 '(foo 1 2 3 4) x))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
リストは順序なしの数学的集合 — リスト内に要素があれば集合の要素の値としてリスト内の順序は無視される —
を表すことができます。2つの集合を結合(union)するには、(重複する要素を気にしなければ)append
を使用します。equal
である重複を取り除くにはdelete-dups
やseq-uniq
を使用します。集合にたいする他の有用な関数にはmemq
やdelq
や、それらのequal
バージョンであるmember
とdelete
が含まれます。
Common Lispに関する注意: 集合を処理するためにCommon Lispには関数
union
(要素の重複がない)とintersection
がある。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
か((2))
かも
この関数は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 (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
が比較しようとしている(list
4)
とsample-list
内の(4)
は、equal
ですがeq
ではありません:
(delq (list 4) sample-list) ⇒ (a c (4))
与えられた値とequal
な要素を削除したい場合には、delete
(以下参照)を使用してください。
この関数はobjectとeq
なすべての要素が除かれた、listのコピーをリターンする。remq
の文字‘q’は、この関数がobjectとリスト内の要素の比較にeq
を使用することを示す。
(setq sample-list (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)) ; 2つの1.2
がeq
である必要はない ⇒ 未定義;nil
か(1.2 1.3)
かもしれない
以下の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)
かもしれない
;; 同じ内容の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 (list '(2) '(1) '(2))) (delete '(2) l) ⇒ ((1)) l ⇒ ((2) (1)) ;;l
の変更に信頼性を要するときは ;;(setq l (delete '(2) l))
と記述する。
(setq l (list '(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
は最初の要素を残す。非破壊的な操作についてはseq-uniq
を参照してください(シーケンスを参照)。
変数に格納されたリストへの要素の追加や、それを集合として使用する方法については、リスト変数の変更の関数add-to-list
も参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
連想リスト(association list、短くはalist)は、キーと値のマッピングを記録します。これは連想(associations)と呼ばれるコンスセルのリストです。各コンスセルにおいてCARはキー(key)で、CDRは連想値(associated value)となります。6
以下はalistの例です。キーpine
は値cones
、キーoak
はacorns
、キーmaple
はseeds
に関連付けられます。
((pine . cones) (oak . acorns) (maple . seeds))
alist内の値とキーには、任意のLispオブジェクトを指定できます。たとえば以下のalistでは、シンボル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要素にたいしてtestfnが関数ならtestfn、それ以外ならequal
を使用して、alist内からkeyをもつ最初の連想をリターンする。testfnが関数の場合にはalistの要素のCARとkeyの2つの引数で呼び出される。testfnでテストした結果、CARがkeyと一致する連想が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
と同様だが、比較に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
か("simple leaves" . oak)
かもしれない
(assoc "simple leaves" leaves)
⇒ ("simple leaves" . oak)
この関数はassq
と似ている。これはalistの要素のkeyを比較して最初の連想(key . value)
を見つける。連想が見つからなければ、関数はdefaultをリターンする。alistにたいするkeyの比較にはtestfnで指定された関数を使用する(デフォルトはeq
)。
これは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 (list '(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))
この関数はassq-delete-all
と同様だが、オプション引数test (
alist内のキーを比較するための述語関数)を受け取る点が異なる。testが省略かnil
ならデフォルトはequal
。この関数はassq-delete-all
のように、多くの場合はalistの元のリスト構造を変更する。
この関数は、alistからCDRがvalueとeq
であるようなすべての要素を削除する。この関数は短くなったリストをリターンし、alistの元のリスト構造を変更することもよくある。rassq-delete-all
はassq-delete-all
と似ているが、CARではなくalistの各連想のCDRを比較する。
連想リストalistのキーとして使用される先頭にドットを付したシンボルそれぞれにたいしてバインディングを作成する。これは同じ連想リスト内の複数のアイテムにアクセスする際に有用かもしれない。理解するためにもっともよいのは以下のシンプルな例だろう:
(setq colors '((rose . red) (lily . white) (buttercup . yellow))) (let-alist colors (if (eq .rose 'red) .lily)) ⇒ white
bodyをコンパイル時に検査して、body内に出現する先頭文字として‘.’を付したシンボルだけがバインドされる。キーの検索はassq
、このassq
のリターン値のcdr
がそのバインディングにたいする値として割り当てられる。
ネストされた連想リストをサポートする:
(setq colors '((rose . red) (lily (belladonna . yellow) (brindisi . pink)))) (let-alist colors (if (eq .rose 'red) .lily.belladonna)) ⇒ yellow
互いに内部にlet-alist
をネストすることが可能だが、内側のlet-alist
は外側のlet-alist
がバインドする変数にはアクセスできない。
[ << ] | [ < ] | [ 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
はプロパティリストを引数にとり、文字列やバッファー内のテキストにたいして、テキストプロパティとテキストに適用するプロパティ値を指定します。テキストのプロパティを参照してください。
プロパティリストが頻繁に使用される他の例は、シンボルプロパティの保管です。すべてのシンボルはシンボルに関する様々な情報を記録するために、プロパティのリストを処理します。これらのプロパティはプロパティリストの形式で保管されます。シンボルのプロパティを参照してください。
この述語関数はobjectが有効なプロパティリストなら非nil
をリターンする。
5.9.1 プロパティリストと連想リスト | プロパティリストと連想リストの利点の比較。 | |
5.9.2 プロパティリストと外部シンボル | 他の場所に保管されたプロパティリストへのアクセス。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
連想リスト(連想リストを参照)は、プロパティリストとよく似ています。連想リストとは対照的にプロパティ名は一意でなければならないので、プロパティリスト内でペアの順序に意味はありません。
様々なLisp関数や変数に情報を付加するためには、連想リストよりプロパティリストの方が適しています。プログラムでこのような情報すべてを1つの連想リストに保持する場合は、特定のLisp関数や変数にたいする連想をチェックする度にリスト全体を検索する必要が生じ、それにより遅くなる可能性があります。対照的に関数名や変数自体のプロパティリストに同じ情報を保持すれば、検索ごとにそのプロパティリストの長さだけを検索するようになり、通常はこちらの方が短時間で済みます。変数のドキュメントがvariable-documentation
という名前のプロパティに記録されているのはこれが理由です。同様にバイトコンパイラーも、特別に扱う必要がある関数を記録するためにプロパティを使用します。
とはいえ連想リストにも独自の利点があります。アプリケーションに依存しますが、プロパティを更新するより連想リストの先頭に連想を追加する方が高速でしょう。シンボルにたいするすべてのプロパティは同じプロパティリストに保管されるので、プロパティ名を異なる用途のために使用すると衝突の可能性があります(この理由により、そのプログラムで通常の変数や関数の名前につけるプレフィクスをプロパティ名の先頭につけて、一意と思われるプロパティ名を選ぶのはよいアイデアだと言える)。連想リストは、連想をリストの先頭にpushして、その後にある連想は無視されるので、スタックと同様に使用できます。これはプロパティリストでは不可能です。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はプロパティリストを操作するために使用されます。これらの関数はすべて、デフォルトではプロパティ名の比較にeq
を使用します。
この関数はプロパティリストplistに保管された、プロパティpropertyの値をリターンする。比較はpredicate
(デフォルトはeq
)で行われる。この関数には不正な形式(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を保管する。比較はpredicate
(デフォルトはeq
)で行われる。この関数はplistを破壊的に変更するかもしれず、元のリスト構造を変更せずに新しいリストを構築することもある。この関数は変更されたプロパティリストをリターンするので、plistを取得した場所に書き戻すことができる。たとえば、
(setq my-plist (list '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
をリターンする。比較はpredicate
(デフォルトはeq
)で行われる。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
をリターンする。以下のseqp
も参照のこと。
この関数はsequence内の要素の数をリターンする。sequenceがシーケンス以外、またはドットリストならwrong-type-argument
エラーをシグナルする。引数が循環リストならcircular-list
エラーをシグナルする。文字テーブルでは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
(表示されるテキストのサイズを参照)を使用すること。
sequenceがlengthより短ければ非nil
をリターンする。これはsequenceが長いリストの場合にsequenceの長さを計算するより効率的かもしれない。
sequenceがlengthより長ければ非nil
をリターンする。
sequenceの長さがlengthなら非nil
をリターンする。
この関数は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を参照)を一般化したものである。
この関数はseqr (シーケンスかレコードであること)のコピーをリターンする。コピーはオリジナルと同じオブジェクト型であり、同じ要素を同じ順序でもつ。しかしseqrが空なら長さが0の文字列やベクターと同じように関数がリターンする値はコピーではないかもしれないが、seqrと同じ型の空のオブジェクトである。
コピーに新しい要素を格納するのは元のseqrに影響を与えずその逆も真である。しかし新しいシーケンス内の要素はコピーではなく、元のシーケンスの要素と同一(eq
)になる。したがってコピーされたシーケンスを介して見つかった要素を変更するとオリジナルでも変更を見ることができる。
引数がテキストプロパティをもつ文字列なら、コピー内のプロパティリスト自身もコピーとなり、元のシーケンスのプロパティリストと共有はされない。しかしプロパティリストの実際の値は共有される。テキストのプロパティを参照のこと。
この関数はドットリストでは機能しない。循環リストのコピーは無限ループを起こすだろう。
シーケンスをコピーする別の方法についてはコンスセルおよびリストの構築のappend
、文字列の作成のconcat
、ベクターのための関数のvconcat
も参照されたい。
(setq bar (list 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 (list '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 (copy-sequence [1 2 3 4])) ⇒ [1 2 3 4] (nreverse x) ⇒ [4 3 2 1] x ⇒ [4 3 2 1]
reverse
とは異なり、この関数は文字列では機能しない。aset
を使用して文字列データを変更できても、たとえmutableであったとしても文字列は不変として扱うことを強く推奨する。可変性を参照のこと。
この関数は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
のリストにたいする破壊的側面は、コンスセルによって形成されたsequenceの内容を、もしかしたら違う順序に再配置するような変更を施すことによって再利用することである。これは入力リストのソート後の値が未定義であることを意味する。定義された有効な値は、sort
によってリターンされるリストだけである。
(setq nums (list 2 1 4 3 0)) (sort nums #'<) ⇒ (0 1 2 3 4) ; この時点においてnumsは予測不可能
元のリストを保持していた変数に結果を書き戻す場合がほとんどだろう:
(setq nums (sort nums #'<))
元の値話破壊せずにソート済みのコピーが欲しければ、まずコピーしてからソートすること:
(setq nums (list 2 1 4 3 0)) (sort (copy-sequence nums) #'<) ⇒ (0 1 2 3 4)
nums ⇒ (2 1 4 3 0)
安定ソートの何たるかをより理解するには、以下のベクターのサンプルを考えてみよ。ソート後、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.elライブラリーは、シーケンシャルなデータ構造の追加型で機能するように拡張可能です。そのためにすべての関数はcl-defgeneric
を使用して定義されています。cl-defgeneric
を使用した拡張の追加に関する詳細は、ジェネリック関数を参照してください。
この関数は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を参照のこと。
この関数はobjectがシーケンス(リストか配列)、またはseq.elのジェネリック関数を通じて定義されたすべての追加シーケンス型なら非nil
をリターンする。これはsequencep
の拡張された変種である。
(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]
この関数は(最大で)長さlengthのsequenceの部分シーケンスから構成されるリストをリターンする(sequenceの長さがlengthの倍数でなければ最後の要素の長さはlengthより短くなるかもしれない)。
(seq-split [0 1 2 3 4] 2) ⇒ ([0 1] [2 3] [4])
この関数はsequenceの各要素にたいして、(恐らくは副作用を得るために)順番にfunctionを適用して、sequenceをリターンする。
この関数はsequenceの各要素にfunctionを適用した結果をリターンする。リターン値はリスト。
(seq-map #'1+ '(2 4 6)) ⇒ (3 5 7)
(seq-map #'symbol-name [foo bar]) ⇒ ("foo" "bar")
この関数はsequenceの各要素およびseqであるようなインデックスにfunctionを適用した結果をリターンする。リターン値はリスト。
(seq-map-indexed (lambda (elt idx) (list idx elt)) '(a b c)) ⇒ ((0 a) (1 b) (2 c))
この関数はsequencesの各要素にfunctionを適用した結果をリターンする。 functionのarity (関数が受け取れる引数の個数。subr-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
この関数はインデックスn (0基準)にある要素が削除されたsequenceのコピーをリターンする。結果のタイプはsequenceと同じ。
(seq-remove-at-position [1 -1 3 -3 5] 0) ⇒ [-1 3 -3 5]
(seq-remove-at-position [1 -1 3 -3 5] 3) ⇒ [1 -1 3 5]
この関数はsequenceの要素それぞれにたいしてfunctionを呼び出して、結果が非nil
だった要素すべてからなるリストをリターンする。
(seq-keep #'cl-digit-char-p '(?6 ?a ?7)) ⇒ (6 7)
この関数はinitial-valueとsequenceの1つ目の要素でfunctionを呼び出し、次にその結果とsequenceの2つ目の要素でfunctionを呼び出し、その次にその結果とsequenceの3つ目の要素で、...と呼び出した結果をリターンする。functionは引数が2つの関数であること。
functionは2つの引数で呼び出される。1つ目の引数としてinitial-value (その後は累積値)、2つ目の引数としてsequence内の要素が使用される。
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-every-p #'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
をリターンする。
この関数はseq-sort
と似ているがソート前にsequenceの要素にfunctionを適用して変換する点が異なる。functionは単一の引数を受け取る関数。
(seq-sort-by #'seq-length #'> ["a" "ab" "abc"]) ⇒ ["abc" "ab" "a"]
この関数はsequence内の少なくとも1つの要素がeltとequalなら非nil
をリターンする。オプション引数functionが非nil
なら、それはデフォルトのequal
のかわりに使用する2つの引数を受け取る関数であること。
(seq-contains-p '(symbol1 symbol2) 'symbol1) ⇒ t
(seq-contains-p '(symbol1 symbol2) 'symbol3) ⇒ nil
この関数は順序とは無関係にsequence1とsequence2が同じ要素を含むかどうかをチェックする。オプション引数testfnが非nil
なら、デフォルトのequal
のかわりに使用する2つの引数を受け取る関数であること。
(seq-set-equal-p '(a b c) '(c b a)) ⇒ t
(seq-set-equal-p '(a b c) '(c b)) ⇒ nil
(seq-set-equal-p '("a" "b" "c") '("c" "b" "a")) ⇒ t
(seq-set-equal-p '("a" "b" "c") '("c" "b" "a") #'eq) ⇒ nil
この関数はeltとequal
であるようなsequence内の最初の要素のインデックス(0基準)をリターンする。オプション引数functionが非nil
なら、それはデフォルトのequal
のかわりに使用する2つの引数を受け取る関数であること。
(seq-position '(a b c) 'b) ⇒ 1
(seq-position '(a b c) 'd) ⇒ nil
この関数はsequenceの要素それぞれにたいして、eltとともに引数としてtestfnを呼び出し、非nil
をリターンするような要素のインデックス(0基準)のリストをリターンする。testfnのデフォルトはequal
。
(seq-positions '(a b c a d) 'a) ⇒ (0 3)
(seq-positions '(a b c a d) 'z) ⇒ nil
(seq-positions '(11 5 7 12 9 15) 10 #'>=) ⇒ (0 3 5)
この関数は重複を削除したsequenceの要素のリストをリターンする。オプション引数functionが非nil
なら、それはデフォルトのequal
のかわりに使用する2つの引数を受け取る関数であること。
(seq-uniq '(1 2 2 1 3)) ⇒ (1 2 3)
(seq-uniq '(1 2 2.0 1.0) #'=) ⇒ (1 2)
この関数は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 4 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のいずれかに出現する要素のリストをリターンする。リターンされるリストの要素はすべて、2要素を比較してequalにならないという意味において一意である。オプション引数functionが非nil
なら、それはデフォルトのequal
のかわりに比較に使用する2つの引数を受け取る関数であること。
(seq-union [1 2 3] [3 5]) ⇒ (1 2 3 5)
この関数は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にリスト、ベクター、文字列のいずれかを指定できる点が異なる。これ主な利点は副作用である。
このマクロはvar-sequence内で定義される変数にval-sequenceの対応する要素をバインドする。これは分割代入(destructuring binding)として知られている。var-sequenceの要素は、ネストされた非構造化を許容することにより自身にシーケンスを含むことができる。
var-sequenceシーケンスには、val-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]
pcase
パターンは分割代入にたいする代替えの機能を提供する。pcase
パターンによる分解を参照のこと。
このマクロはseq-let
と同様に機能するが、let
ではなくあたかもsetq
で値が変数にバインドされる点が異なる。
(let ((a nil) (b nil)) (seq-setq (_ a _ b) '(1 2 3 4)) (list a b)) ⇒ (2 4)
この関数はsequenceの要素をランダムにリターンする。
(seq-random-elt [1 2 3 4]) ⇒ 3 (seq-random-elt [1 2 3 4]) ⇒ 2 (seq-random-elt [1 2 3 4]) ⇒ 4 (seq-random-elt [1 2 3 4]) ⇒ 2 (seq-random-elt [1 2 3 4]) ⇒ 1
sequenceが空ならこの関数はエラーをシグナルする。
[ << ] | [ < ] | [ 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
この関数はarr (配列かレコード)の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 (vector 'foo 'bar 'baz)) ⇒ [foo bar baz] (aset w 0 'fu) ⇒ fu w ⇒ [fu bar baz]
;; copy-sequence
は後で変更する文字列をコピーする
(setq x (copy-sequence "asdfasfd"))
⇒ "asdfasfd"
(aset x 3 ?Z)
⇒ 90
x
⇒ "asdZasfd"
arrayはmutableであること。可変性を参照のこと。
arrayが文字列でobjectが文字でなければ、結果はwrong-type-argument
エラーとなる。この関数は文字列の挿入で必要なら、ユニバイト文字列をマルチバイト文字列に変換する。
この関数は配列arrayをobjectで充填するので、arrayのすべての要素はobjectになる。この関数はarrayをリターンする。
(setq a (copy-sequence [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 (copy-sequence "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入力として同じ方法でベクターを記述できます。
文字列や数値と同様にベクターは定数として評価され、評価された結果は同じベクターになります。ベクターの要素は評価も確認もされません。自己評価を行うフォームを参照してください。角カッコ(square
brackets)で記述されたベクターをaset
や他の破壊的操作を通じて修正しないでください。可変性を参照してください。
以下はこれらの原理を表す例です:
(setq avector [1 two '(three) "four" [five]]) ⇒ [1 two '(three) "four" [five]] (eval avector) ⇒ [1 two '(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 '(three) "four" [five]] (append avector nil) ⇒ (1 two '(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
をリターンする。
リング内の一番新しい要素は常にインデックス0をもちます。より大きいインデックスは、より古い要素に対応します。インデックスはリング長のmoduloにより計算されます。インデックス-1は一番古い要素、-2は次に古い要素、...となります。
この関数はインデックスindexにあるring内のオブジェクトをリターンする。indexには負やリング長より大きい数を指定できる。ringが空ならring-ref
はエラーをシグナルする。
この関数は一番新しい要素としてobjectをringに挿入してobjectをリターンする。
リングが満杯なら新しい要素用の空きを作るために、挿入により一番古い要素が削除される。
ringからオブジェクトを削除してそのオブジェクトをリターンする。引数indexはどのアイテムを削除するかを指定する。これがnil
なら、それは一番古いアイテムを削除することを意味する。ringが空ならring-remove
はエラーをシグナルする。
この関数は一番古い要素としてobjectをringに挿入する。リターン値に意味はない。
リングが満杯なら、この関数は挿入される要素のための空きを作るために一番新しい要素を削除する。
ringのサイズをsizeにセットする。新たなサイズのほうが小さければリング内の古いアイテムは破棄される。
リングサイズを超過しないよう注意すれば、そのリングを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] | [ ? ] |
レコードの目的はEmacsにビルトインされていない新たな型のオブジェクトをプログラマーが作成できるようにすることです。これらはcl-defstruct
やdefclass
のインスタンスを表現する基礎として使用されています。
レコードオブジェクトは内部的にはベクターと似ています。レコードオブジェクトのスロットはaref
を使用してアクセス可能であり、copy-sequence
を使用してコピーできます。しかし最初のスロットはtype-of
がリターンする型を保持するために使用されます。更に現実装ではレコードは最大で4096スロットを所有できますが、ベクターはそれより多くのスロットを所有できます。レコードは配列と同じように0基準のインデックスを使用するので、最初のスロットはインデックスが0になります。
型スロット(type slot)はシンボルか型記述子であるべきです。型記述子なら型を命名するシンボルがリターンされます。型記述子を参照してください。その他の種類のオブジェクトはすべてそのままリターンされます。
レコードのプリント表現では‘#s’の後にコンテンツを指定するリストが続きます。リストの最初の要素はそのレコードの型である必要があります。後続の要素はレコードのスロットです。
レコードの型を新たに定義するLispプログラムは他の型名との衝突を避けるために、通常はレコード型を導入する部分では型名にパッケージの命名規約を使用するべきです。衝突する可能性がある型名は、パッケージが定義したレコード型のロード時には不明かもしれないことに注意してください。これらは将来のある時点でロードされる可能性があります。
レコードは評価にたいして定数とみなされます。評価すると結果は同じレコードになります。レコードは評価されずにスロットのチェックさえ行われません。自己評価を行うフォームを参照してください。
7.1 レコード関数 | レコード用の関数。 | |
7.2 後方互換 | cl-defstructにたいする後方互換について。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はobjectがレコードならt
をリターンする。
(recordp #s(a)) ⇒ t
この関数は型がtypeであり、残りのスロットが残りの引数objectsであるようなレコードを作成してリターンする。
(record 'foo 23 [bar baz] "rats") ⇒ #s(foo 23 [bar baz] "rats")
この関数は型がtype、objectで初期化されたスロット数がlengthの新たなレコードをリターンする。
(setq sleepy (make-record 'foo 9 'Z)) ⇒ #s(foo Z Z Z Z Z Z Z Z Z)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
レコードを使用しない古いバージョンのcl-defstruct
でコンパイルされたコードを新しいEmacsで実行したときに問題が発生するかもしれません。この魔問題を軽減するために、Emacsは古いcl-defstruct
の使用を検知した際に古い構造体オブジェクトがレコードであるかのように処理するモードを有効にします。
argが正なら旧スタイルの構造体にたいする後方互換を有効にする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ハッシュテーブル(hash table)は非常に高速なルックアップテーブルの一種で、キーに対応する値をマップするという点ではalist(連想リストを参照)に似ています。ハッシュテーブルは以下の点でalistと異なります:
Emacs Lispは一般的な用途のハッシュテーブルデータ型とともに、それらを処理する一連の関数を提供します。ハッシュテーブルは‘#s’、その後にハッシュテーブルのプロパティと内容を指定するリストが続く、特別なプリント表現をもちます。ハッシュテーブルの作成を参照してください(ハッシュ表記の最初に使用される‘#’文字は、読み取り表現をもたないオブジェクトのプリント表現であり、これはハッシュテーブルに何も行わない。プリント表現と読み取り構文を参照のこと)。
obarray(オブジェクト配列)もハッシュテーブルの一種ですが、これらは異なる型のオブジェクトであり、intern(インターン)されたシンボルを記録するためだけに使用されます(シンボルの作成とinternを参照)。
8.1 ハッシュテーブルの作成 | ハッシュテーブルを作成する関数。 | |
8.2 ハッシュテーブルへのアクセス | ハッシュテーブルの内容の読み書き。 | |
8.3 ハッシュの比較の定義 | 新たな比較方法の定義。 | |
8.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以下の正の浮動小数点数であること。実際のエントリー数が通常のサイズにたいする指定した割合に近い値を超えるとハッシュテーブルは一杯(full)になる。thresholdのデフォルトは0.8125。
ハッシュテーブルのプリント表現を使用してハッシュテーブルを作成することもできます。指定されたハッシュテーブル内の各要素が、有効な入力構文(プリント表現と読み取り構文を参照)をもっていれば、Lispリーダーはこのプリント表現を読み取ることができます。たとえば以下は値val1
(シンボル)と300
(数字)に関連づけられた、キーkey1
とkey2
(両方ともシンボル)をハッシュテーブルに指定します。
#s(hash-table size 30 data (key1 val1 key2 300))
しかしこれをEmacs
Lispコードで使用する際には、ハッシュテーブルを新たに作成するかどうかは未定義であることに注意してください。ハッシュテーブルを新たに作成したければ、常にmake-hash-table
を使う必要があります(自己評価を行うフォームを参照)。
ハッシュテーブルのプリント表現は‘#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で古い連想値を置き換える。この関数は常にvalueをリターンする。
この関数はtableにkeyの連想があればそれを削除する。keyが連想をもたなければremhash
は何も行なわない。
Common Lispに関する注意: Common
Lispではremhash
が実際に連想を削除したときは非nil
、それ以外はnil
をリターンする。Emacs
Lispではremhash
は常にnil
をリターンする。
この関数はハッシュテーブルtableからすべての連想を削除するので、そのハッシュテーブルは空になる。これはハッシュテーブルのクリーニング(clearing)とも呼ばれる。clrhash
は空のtableをリターンする。
この関数はtable内の各連想にたいして一度ずつfunctionを呼び出す。関数functionは2つの引数 —
tableにリストされたkeyと、それに関連づけられたvalue —
を受け取ること。maphash
はnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
define-hash-table-test
でキーを照合する新しい方法を定義できます。この機能を使用するにはハッシュテーブルの動作方法と、ハッシュコード(hash
code)の意味を理解する必要があります。
概念的にはハッシュテーブルを1つの連想を保持できるスロットがたくさんある巨大な配列として考えることができます。キーを照合するにはまず、gethash
がキーから整数(ハッシュコード)を計算します。配列の長さを法(modulo)としてこの整数を縮小して(訳注:配列の長さで割った余りの整数にして)、配列内のインデックスを生成することができます。それから探しているキーが見つかったかどうか確認するためにそのスロット、必要なら近くのスロットを調べます。
したがってキーを照合する新たな方法を定義するにはキーからハッシュコードを計算する関数、および2つのキーを直接比較する関数の両方を指定する必要があります。この2つの関数は互いに一貫性をもつ必要があります。すなわちキーを比較してequalなら、2つのキーのハッシュコードは同一であるべきです。さらに(ガーベージコレクターからの呼び出しのように)2つの関数は任意のタイミングで呼び出される可能性があるので、関数が副作用をもたないこと、すぐにリターンすること、そしてこれらの関数の挙動はそのキーの不変の性質だけに依存する必要があります。
この関数はnameという名前の新たなハッシュテーブルテストを定義します。
この方法でnameを定義した後は、make-hash-table
の引数testにこれを使用することができる。これを行なう際は、そのハッシュテーブルのキー値の比較にtest-fn、キー値からハッシュコードを計算するためにhash-fnを使用することになる。
関数test-fnは2つの引数(2つのキー)をとり、それらが同一と判断されたときは非nil
をリターンする。
関数hash-fnは1つの引数(キー)を受け取り、そのキーのハッシュコード(整数)をリターンすること。よい結果を得るために、その関数は負のfixnumを含むfixnumの全範囲をハッシュコードに使用すること。
指定された関数は、プロパティhash-table-test
の配下の、nameというプロパティリストに格納される。そのプロパティの値形式は(test-fn
hash-fn)
。
この関数はLispオブジェクトobjのハッシュコードをリターンする。リターン値はobjと、それが指す別のLispオブジェクトの内容を表す整数。
2つのオブジェクトobj1とobj2がequal
ならば(sxhash-equal
obj1)
と(sxhash-equal obj2)
は同じ整数になる。
2つのオブジェクトがequal
でなければ、通常ならsxhash-equal
がリターンする値は異なるが常に異なるとも限らない。sxhash-equal
はネストされた構造体を深く再帰しないことによって十分高速になるようデザインされている(ハッシュテーブルのインデックス作成に使用するため)。加えて稀に(運次第)ではあるがsxhash-equal
が同じ結果を与える、2つの異なって見えるシンプルなオブジェクトに出会うことがあるかもしれない。したがって一般的にはオブジェクトが変更されたかどうかのチェックにsxhash-equal
を用いることはできない。
Common Lispに関する注意: Common
Lispではこれに似た関数はsxhash
と呼ばれる。Emacsは互換性のためにsxhash-equal
にたいするエイリアスとしてこの名前を提供している。
この関数はLispオブジェクトobjにたいするハッシュコードをリターンする。結果はobjの識別値であり内容が反映されているわけではない。
2つのオブジェクトobj1とobj2がeq
なら(sxhash-eq
obj1)
と(sxhash-eq obj2)
は同じ整数になる。
この関数はeql
による比較に適したLispオブジェクトobjにたいするハッシュコードをリターンする。つまり浮動小数点数とbignum以外のobjなら、それにたいする識別値(浮動小数点数ならその値にたいするハッシュコード)を生成する。
2つのオブジェクトobj1とobj2がeql
なら(sxhash-eql
obj1)
と(sxhash-eql obj2)
は同じ整数になる。
以下はcaseを区別しない文字列のキーをもつハッシュテーブルを作成する例です。
(defun string-hash-ignore-case (a) (sxhash-equal (upcase a))) (define-hash-table-test 'ignore-case 'string-equal-ignore-case 'string-hash-ignore-case) (make-hash-table :test 'ignore-case)
以下は事前に定義されたテスト値equal
と等価なテストを行なうハッシュテーブルを定義できるという例です。キーは任意のLispオブジェクトで、equalに見えるオブジェクトは同じキーと判断されます。
(define-hash-table-test 'contents-hash 'equal 'sxhash-equal) (make-hash-table :test 'contents-hash)
ハッシュ関数の実装はセッション間や異なるアークテクチャー間で変わる可能性のあるオブジェクトストレージのいくつかの詳細を使用するので、LispプログラムはEmacsセッションの間はハッシュコードが保存されることに依存するべきではありません。
[ << ] | [ < ] | [ 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
をリターンする。
9.1 シンボルの構成要素 | シンボルは名前、値、関数定義、プロパティリストをもつ。 | |
9.2 シンボルの定義 | 定義はシンボルが使用される方法を示す。 | |
9.3 シンボルの作成とintern | シンボルが一意に保たれる方法。 | |
9.4 シンボルのプロパティ | さまざまな情報を記録するために各シンボルはプロパティリストをもつ。 | |
9.5 ショートハンド | シンボル名のタイプ量を少なくしつつ正しく組織化するには。 | |
9.6 位置をもつシンボル | 整数の位置を含んだシンボルの変種 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
各シンボルは4つの構成要素(もしくは“セル”)をもち、構成要素はそれぞれ別のオブジェクトを参照します:
そのシンボルの名前。
変数としてのそのシンボルの現在値。
そのシンボルの関数定義。シンボル、キーマップ、キーボードマクロも保持できる。
そのシンボルのプロパティリスト。
プリント名のセルは常に文字列を保持し、それを変更することはできません。他の3つのセルには、任意のLispオブジェクトをセットすることができます。
プリント名のセルはシンボルの名前となる文字列を保持します。シンボルはシンボル名によりテキストとして表されるので、2つのシンボルが同じ名前をもたないことが重要です。Lispリーダーはシンボルを読み取るごとに、それを新規作成する前に、指定されたシンボルがすでに存在するかを調べます。シンボルの名前を得るには関数symbol-name
(シンボルの作成とinternを参照)を使用します。しかしシンボルがそれぞれ一意なプリント名(print
name)を1つだけもつとしても、“ショートハンド(shorthand)”と呼ばれる違うエイリアス名を通じて同じシンボルを参照することは可能です(ショートハンドを参照)。
値セルは変数としてのシンボルの値(そのシンボル自身がLisp式として評価されたときに得る値)を保持します。ローカルバインディング(local
binding)やスコーピングルール(scoping
rules)等のような複雑なものを含めて、変数のセットや取得方法については変数を参照してください。ほとんどのシンボルは値として任意のLispオブジェクトをもつことができますが、一部の特別なシンボルは変更できない値をもちます。これらにはnil
、t
、および名前が‘:’で始まるすべてのシンボル(キーワード(keyword)と呼ばれる)が含まれます。変更不可な変数を参照してください。
関数セルはシンボルの関数定義を保持します。実際はには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-ja.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リーダーはその名前の文字すべてを読み取ります。それからプログラマーが意図したシンボルを見つけるために、obarray(オブジェクト配列)と呼ばれるテーブルでその名前を照合します。この照合に使用されるテクニックは“ハッシュ化(hashing)”と呼ばれています。これは照合を行う際に文字シーケンスを“ハッシュコード(hash code)”として知られる数値に変換する効率的な手法です。たとえばJan Jonesを見つけるときは、電話帳を表紙から1頁ずつ探すのではなくJの頁から探し始めます。これはハッシュ化の簡単なバージョンです。obarrayの各要素は与えられたハッシュコードとともに、すべてのシンボルを保持するバケット(bucket)です。与えられた名前を探すためには、バケットの中からハッシュコードがその名前であるような、すべてのシンボルを探すのが効果的です(同じアイデアは一般的なEmacsのハッシュテーブルでも使用されていがこれらはデータ型が異なる。ハッシュテーブルを参照されたい)。
Lispリーダーは名前の照合時には“ショートハンド(shorthands 速記、簡略表記)”も考慮します。プログラマーがショートハンドを提供した場合には、たとえソースコード内でシンボル名が完全な形式で与えられなくても、リーダーはシンボルを見つけることができます。もちろんリーダーはそのようなショートハンドに関して事前に既定されたコンテキストを認識する必要があり、同様に“Jan”という名前だけでJan Jonesを一意に参照できるコンテキストが必要です。これはJonesの中にいるときや、Janが最近言及されていれば問題はないでしょうが、他の状況下では非常に曖昧です。ショートハンドを参照してください。
探している名前のシンボルが見つかったら、リーダーはそのシンボルを使用します。obarrayにその名前のシンボルが含まれなければ、リーダーは新しいシンボルを作成してそれをobarrayに追加します。特定の名前のシンボルを探して追加することをインターン(intern)と言い、これが行なわれた後はそのシンボルはインターンされたシンボル(interned symbol)と呼ばれます。
インターンすることによりある特定の名前のシンボルは、各obarrayに1つだけであることが保証されます。同じ名前のシンボルが他に存在するかもしれませんが、同じobarrayには存在しません。したがってリーダーは、(同じobarrayを読みつづける限り)同じ名前にたいして同じシンボルを取得します。
インターンは通常はリーダー内で自動的に発生しますが、他のプログラムがこれを行ないたい場合もあるかもしれません。たとえばM-xコマンドはその後にミニバッファーを使用してコマンド名を文字列として取得して、その文字列をインターンしてからインターンされたその名前のシンボルを得ます。別の例として、照合する人名それぞれをシンボル名としてインターンする架空の電話帳プログラムは、たとえそれがobarrayに含まれていなくても、誰かが最後にそれを照合した際に情報をアタッチできるようにする場合などです。
すべてのシンボルを含むobarrayはありません。実際にどのobarrayにも含まれないシンボルがいくつかあります。これらはインターンされていないシンボル(uninterned symbols)と呼ばれます。インターンされていないシンボルも、他のシンボルと同じく4つのセルをもちます。しかしインターンされていないシンボルへのアクセスを得る唯一の方法は、他の何らかのオブジェクトとして探すか、変数の値として探す方法だけです。インターンされていないシンボルは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では複数の異なる“パッケージ”における同一の名前のインターンは提供されていないので、異なるパッケージごとに同じ名前のシンボルが複数作成される。Emacs Lispは“ショートハンド”と呼ばれる別の名前空間システムを提供する(ショートハンドを参照)。
以下の関数のほとんどは、引数に名前とobarrayをとります。名前が文字列以外、またはobarrayがベクター以外ならwrong-type-argument
エラーがシグナルされます。
この関数はsymbolの名前を文字列としてリターンする。たとえば:
(symbol-name 'foo) ⇒ "foo"
警告: この関数がリターンした文字列は絶対変更してはならない。これを行うことによってEmacsの機能が損なわれるかもしれず、Emacsのクラッシュすら招きかねない。
インターンされていないシンボルの作成は、Lispコードを生成するとき有用です。なぜなら作成されたコード内で変数として使用されているインターンされていないシンボルは、他のLispプログラムで使用されている任意の変数と競合することはありえないからです。
この関数は新たに割り当てられた、名前がname(文字列でなければならない)であるような、インターンされていないシンボルをリターンする。このシンボルの値と関数はvoidで、プロパティリストはnil
。以下の例ではsym
の値はfoo
とeq
ではない。なぜならこれは名前が‘foo’という、インターンされていないシンボルだからである。
(setq sym (make-symbol "foo")) ⇒ foo (eq sym 'foo) ⇒ nil
この関数はmake-symbol
を使用してprefixにgensym-counter
を付加した名前のシンボルをリターンする。更にこの関数を複数回呼び出しても同一名のシンボルが生成されないことを保証するためにカウンターを増加する。プレフィックスのデフォルトは"g"
。
意図せず生成したコードのプリント表現をインターンした際の問題を避けるために、make-symbol
ではなくgensym
の使用をお勧めします。(プリント表現と読み取り構文を参照)。
この関数は名前が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
なら、その変数の名前が危険なファイルローカル変数(ファイルローカル変数を参照)であることを意味します。
シンボルのプロパティとプロパティ値はそれぞれ、シンボルのプロパティリストセル(シンボルの構成要素を参照)に、プロパティリスト形式(プロパティリストを参照)で格納されます。
9.4.1 シンボルのプロパティへのアクセス | シンボルプロパティへのアクセス。 | |
9.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-face、customized-face、themed-faceを記録するために使用される。これらのプロパティを直接セットしないこと。これらのプロパティはdefface
と関連する関数により管理される。フェイスの定義を参照のこと。
customized-value
saved-value
standard-value
theme-value
これらのプロパティは、カスタマイズ可能な変数のstandard-value、saved-value、customized-value(しかし保存はされない)、themed-valueを記録するために使用される。これらのプロパティを直接セットしないこと。これらはdefcustom
と関連する関数により管理される。カスタマイゼーション変数の定義を参照のこと。
definition-name
このプロパティはソースファイルのテキスト検索ではシンボルの定義を見つけるのが困難な際に、ソースコードから定義を見つけるために使用される。たとえばdefine-derived-mode
(派生モードの定義を参照)によってモード固有の関数や変数が暗黙裡に定義されたのかもしれないし、Lispプログラム実行時にdefun
を呼び出して関数を定義したのかもしれない(関数の定義を参照)。このようなケースや類似したケースにおいては、そのシンボルのdefinition-name
プロパティはテキスト検索によって検索可能な定義をもち、そのコードによって元のシンボルを定義するような別のシンボルであることが必要になる。define-derived-mode
の例では、定義される関数および変数にたいするこのプロパティの値がモードシンボルであることが必要になる。C-h
f (Help in The GNU Emacs
Manualを参照)のようなEmacsのヘルプコマンドでは、そのシンボルのドキュメントを表示する*Help*バッファーのボタンを通じてシンボルの定義を表示するためにこのプロパティが使用されている。
disabled
値が非nil
なら命名される関数はコマンドとして無効になる。コマンドの無効化を参照のこと。
face-documentation
値には命名されるフェイスのドキュメント文字列が格納される。これはdefface
により自動的にセットされる。フェイスの定義を参照のこと。
history-length
値が非nil
なら、命名されるヒストリーリスト変数のミニバッファーヒストリーの最大長を指定する。ミニバッファーのヒストリーを参照のこと。
interactive-form
この値は命名される関数のインタラクティブ形式である。通常はこれを直接セットするべきではない。かわりにスペシャルフォームinteractive
を使用すること。インタラクティブな呼び出しを参照されたい。
menu-enable
この値は命名されるメニューアイテムが、メニュー内で有効であるべきか否かを決定するための式である。単純なメニューアイテムを参照のこと。
mode-class
値がspecial
なら命名されるメジャーモードはspecial(特別)である。メジャーモードの慣習を参照のこと。
permanent-local
値が非nil
なら命名される変数はバッファーローカル変数となり、メジャーモードの変更によって変数の値はリセットされない。バッファーローカルなバインディングの作成と削除を参照のこと。
permanent-local-hook
値が非nil
なら、命名される関数はメジャーモード変更時にフック変数のローカル値から削除されない。フックのセットを参照のこと。
pure
¶値が非nil
の場合には、名づけられた関数は純粋(pure)だとみなされる。定数の引数で呼び出された場合には、コンパイル時に評価することができる。これは実行時のエラーをコンパイル時へとシフトする。純粋ストレージ(pure
storage)と混同しないこと(純粋ストレージを参照)。
risky-local-variable
値が非nil
なら、命名される変数はファイルローカル変数としては危険だとみなされる。ファイルローカル変数を参照のこと。
safe-function
値が非nil
なら、命名される関数は評価において一般的に安全だとみなされます。安全に関数を呼び出せるかどうかの判断を参照のこと。
safe-local-eval-function
値が非nil
なら、命名される関数はファイルローカルの評価フォーム内で安全に呼び出すことができる。ファイルローカル変数を参照のこと。
safe-local-variable
この値は命名される変数にたいして、ファイルローカル値が安全かを判断する関数を指定する。ファイルローカル変数を参照のこと。この値はファイルのロード時に参照されるので、指定する関数は効率的かつ安全性判断のために理想的にはライブラリーを何もロードしない(autoload関数にしない)ようにする必要がある。
side-effect-free
¶非nil
値は命名される関数が副作用(関数とは?を参照)をもたないことを示すので、バイトコンパイラーは値が使用されない呼び出しを無視する。このプロパティの値がerror-free
なら、バイトコンパイラーはそのような呼び出しの削除すら行うかもしれない。バイトコンパイラーの最適化に加えて、このプロパティは関数の安全性を判断するためにも使用される(安全に関数を呼び出せるかどうかの判断を参照)。
undo-inhibit-region
非nil
の場合には、命名される関数の直後にundo
が呼び出されると、undo
操作をアクティブなリージョンに限定することを抑止する。アンドゥを参照のこと。
variable-documentation
非nil
なら、それは命名される変数のドキュメント文字列を指定する。ドキュメント文字列はdefvar
と関連する関数により自動的にセットされる。フェイスの定義を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
“名前変更シンボル(renamed symbols)”と呼ばれることもあるシンボルのショートハンド(shorthands: 速記、簡略表記)とは、Lispソースで目にする抽象形式です。これらは正規の抽象形式と類似していますが、Lispリーダーがそれらに遭遇した際に別の通常はもっと長いプリント名(print name)を生成する点が異なリます(シンボルの構成要素を参照)。
ショートハンドを意図するシンボルの完全名にたいする略語(abbreviating)と考えることは有益です。その点を除けばAbbrevシステム(abbrevとabbrev展開を参照)とショートハンドを混同しないでください。
ショートハンドによりEmacs Lispのネームスペース作法(namespacing
etiquette)にしたがうことが容易になります。すべてのシンボルは単一のobarray (シンボルの作成とinternを参照)に格納されるので、一般的にプログラマーはシンボル名それぞれにたいして出自ライブラリー名をプレフィクスとして付加します。たとえば関数text-property-search-forward
とtext-property-search-backward
はどちらもtext-property-search.elライブラリーに属しています(ロードを参照)。シンボル名に正しくプレフィクスを付加することによって、異なるライブラリーに属する別のことを行う同一名シンボル間でのクラッシュを効果的に回避できます。しかしこれを実践してしばらくすると、一般的にはタイプしにくく読み難い、非常に長いシンボル名となります。これらの問題をショートハンドは明快な方法により解決します。
この変数の値は要素が(shorthand-prefix
.
longhand-prefix)
という形式であるようなalist。それぞれの要素はLispリーダーにたいして、shorthand-prefixで始まるすべてのシンボルを、longhand-prefixで始まるシンボルとして読み取るよう指示する。
この変数はファイルローカル変数としてのみセットできる(Local Variables in Files in The GNU Emacs Manualを参照)。
以下は架空の文字列操作ライブラリーsome-nice-string-utils.elでショートハンドを使用する例です。
(defun some-nice-string-utils-split (separator s &optional omit-nulls) "match-dataを保存する`split-string'の変種" (save-match-data (split-string s separator omit-nulls))) (defun some-nice-string-utils-lines (s) "文字列Sを改行文字で分割して文字列リストにする" (some-nice-string-utils-split "\\(\r\n\\|[\n\r]\\)" s))
見ての通りタイプするシンボル名が非常に長いので、このコードを読んだり開発するのはとても退屈です。これの緩和にショートハンドが使用できます。
(defun snu-split (separator s &optional omit-nulls) "match-dataを保存する`split-string'の変種" (save-match-data (split-string s separator omit-nulls))) (defun snu-lines (s) "文字列Sを改行文字で分割して文字列リストにする" (snu-split "\\(\r\n\\|[\n\r]\\)" s)) ;; Local Variables: ;; read-symbol-shorthands: (("snu-" . "some-nice-string-utils-")) ;; End:
この2つの例が異なるように見えても、これらをLispリーダーが処理した後はまったく同じです。どちらもインターン(シンボルの作成とinternを参照)される同一のシンボルへと導かれます。したがって2つのファイルのどちらをバイトコンパイルしても、同じ結果が得られます。2つ目のバージョンのショートハンドsnu-split
とsnu-lines
はobarrayにインターンされません。これはショートハンド使用箇所にポイントを移動して、ポイント位置のシンボルの真のシンボル名のヒントをElDoc
(Local Variables in Files in The GNU
Emacs Manualを参照)がエコーエリアに表示するのを待つことで容易に確認できます。
read-symbol-shorthands
はファイルローカル変数なので、some-nice-string-utils-lines.elに依存する複数のライブラリーが同一のシンボルを異なるショートハンドで参照したり、あるいはショートハンドをまったく使用せずに参照することが可能になります。次の例ではmy-tricks.elライブラリーがsnu-
ではなく、sns-
というプレフィクスを使用してシンボルsome-nice-string-utils-lines
を参照しています。
(defun t-reverse-lines (s) (string-join (reverse (sns-lines s)) "\n") ;; Local Variables: ;; read-symbol-shorthands: (("t-" . "my-tricks-") ;; ("sns-" . "some-nice-string-utils-")) ;; End:
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
位置つきシンボル(symbol with position)とはbareシンボル(bare symbol: 裸のシンボル)と位置(position)と呼ばれる符号なし整数を合わせたシンボルのことです。これらのオブジェクトはバイトコンパイラーによって使用されます。バイトコンパイラーはシンボルそれぞれの出現位置を記録して、警告メッセージやエラーメッセージでそれらの位置を使用します。
位置つきシンボルのプリント表現には、プリント表現と読み取り構文で概説したハッシュ表記が使用されます。‘#<symbol foo at
12345>’のようなプリント表現であり、入力構文はありません。プリント操作の前後で変数print-symbols-bare
を非nil
にバインドすれば、bareシンボルだけをプリントさせることができます。バイトコンパイラーはコンパイル済みLispファイルへ書き込む前にこれを行っています。
フラグ変数symbols-with-pos-enabled
が非nil
であっても、ほとんどの用途にたいして位置つきシンボルはbareシンボルと同じように動作します。たとえばこの変数がセットされている場合には、‘(eq
#<symbol foo at 12345>
foo)’の値はt
になります(ただしセットされていなければnil
)。Emacsではほとんどの場合この変数はnil
ですが、バイトコンパイラーの実行時にはt
にバインドされます。
位置つきシンボルは通常はバイトコンパイラーがリーダー関数read-positioning-symbols
を呼び出すことによって作成されます(入力関数を参照)が、関数position-symbol
によって作成することもできます。
この変数が非nil
の際には、位置つきシンボルはそれに内包されているbareシンボルと同様に振る舞う。この場合にはEmacsの実行が少しだけ遅くなる。
非nil
にバインドされていると、Lispプリンターは位置つきシンボルの位置は無視してbareシンボルだけをプリントする。
この関数はsymbolがシンボルならt
、それ以外はnil
をリターンする。
この関数はsymbolに含まれるbareシンボル、symbolがすでにbareシンボルならsymbol自体をリターンする。それ以外のタイプのオブジェクトの場合にはエラーをシグナルする。
この関数は位置つきシンボルの位置(数値)をリターンする。それ以外のタイプのオブジェクトの場合にはエラーをシグナルする。
位置つきシンボルを新たに作成する。symはbareシンボルか位置つきシンボルで、これは新たなオブジェクトにたいしてシンボル部分を提供する。posは整数(新オブジェクトの数値部分となる)、あるいは位置つきシンボル(このシンボルの位置を使用)のいずれか。引数のいずれかが無効であればEmacsはエラーをシグナルする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispでの式の評価(evaluation)は、Lispインタープリター —
入力としてLispオブジェクトを受け取り、それの式としての値(value as an expression)を計算する —
により処理されます。評価を行なう方法はそのオブジェクトのデータ型に依存していて、それはこのチャプターで説明するルールにより行なわれます。インタープリターはプログラムの一部を評価するために自動的に実行されますが、Lispプリミティブ関数のeval
を通じて明示的に呼び出すこともできます。
10.1 評価の概要 | 事の在り方における評価。 | |
10.2 フォームの種類 | さまざまなオブジェクト類が評価される方法。 | |
10.3 クォート | (プログラム内に定数を配すことによる)評価の回避。 | |
10.4 バッククォート | リスト構文より簡単な構築。 | |
10.5 evalについて | Lispインタープリターを明示的に呼び出す方法。 | |
10.6 遅延されたLazy評価 | フォームのlazyな遅延評価。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispインタープリター(またはLispエバリュエーター)はEmacsの一部であり、与えられた式の値を計算します。Lispで記述された関数が呼び出されると、エバリュエーターはその関数のbody(本文)の中の式を評価してその関数の値を計算します。したがってLispプログラムを実行するとは、実際にはLispインタープリターを実行することを意味します。
評価を意図したLispオブジェクトはフォーム(form)、または式(expression)と呼ばれます7。フォームはデータオブジェクトであって単なるテキストではないという事実は、Lisp風の言語と通常のプログラミング言語との間にある基本的な相違点の1つです。任意のオブジェクトを評価できますが、実際に評価される事が非常に多いのは数字、シンボル、リスト、文字列です。
以降のセクションでは、各種フォームにたいしてそれを評価することが何を意味するかの詳細を説明します。
Lispフォームを読み取ってそのフォームを評価するのは、非常に一般的なアクティビティーですが、読み取りと評価は別のアクティビティーであって、どちらか一方を単独で処理することができます。読み取っただけでは何も評価されません。読み取りはLispオブジェクトのプリント表現をそのオブジェクト自体に変換します。そのオブジェクトが評価されるべきフォームなのか、それともまったく違う目的をもつかを指定するのは、read
の呼び出し元の役目です。入力関数を参照してください。
評価とは再帰的な処理であり、あるフォームを評価するとそのフォームの一部が評価されるといったことがよくあります。たとえば(car
x)
のような関数呼び出し(function call)のフォームを評価する場合、Emacsは最初にその引数(サブフォーム
x
)を評価します。引数を評価した後、Emacsはその関数(car
)を実行(executes)します。その関数がLispで記述されていれば、関数のbody(本文)を評価することによって実行が行なわれます(しかしこの例で使用しているcar
はLisp関数ではなくCで実装されたプリミティブ関数である)。関数と関数呼び出しについての情報は関数を参照してください。
評価は環境(environment)と呼ばれるコンテキストの内部で行なわれます。環境はすべてのLisp変数(変数を参照)のカレント値とバインディングにより構成されます。8フォームが新たなバインディングを作成せずに変数を参照する際、その変数はカレントの環境から与えられる値へと評価されます。フォームの評価は、変数のバインディングによって一時的にその環境を変更することもあります(ローカル変数を参照)。
フォームの評価が永続する変更を行なうこともあります。これらの変更は副作用(side
effects)と呼ばれます。副作用を生成するフォームの例は(setq foo 1)
です。
コマンドキー解釈での評価と混同しないでください。エディターのコマンドループはアクティブなキーマップを使用して、キーボード入力をコマンド(インタラクティブに呼び出すことができる関数)に変換してからそのコマンドを実行するために、call-interactively
を使用します。そのコマンドがLispで記述されていれば、そのコマンドの実行には通常は評価を伴います。しかしこのステップはコマンドキー解釈の一部とは考えません。コマンドループを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
評価される事を意図したLispオブジェクトはフォーム(form)、または式(expression))と呼ばれます。Emacsがフォームを評価する方法はフォームのデータ型に依存します。Emacsは3種の異なるフォーム — シンボル、リスト、およびその他すべての型 — をもち、それらが評価される方法は異なります。このセクションではまず最初に自己評価フォームのその他の型から開始して、3つの種類をすべて1つずつ説明します。
10.2.1 自己評価を行うフォーム | 自分自身を評価するフォーム。 | |
10.2.2 シンボルのフォーム | 変数として評価されるシンボル。 | |
10.2.3 リストフォームの分類 | さまざまな種類のリストフォームを区別する方法。 | |
10.2.4 シンボル関数インダイレクション | シンボルがリストのcarにあればそのシンボルを通じて実際の関数を見つける。 | |
10.2.5 関数フォームの評価 | 関数を呼び出すフォーム。 | |
10.2.6 Lispマクロの評価 | マクロを呼び出すフォーム。 | |
10.2.7 スペシャルフォーム | スペシャルフォームは特異なプリミティブであり、それらのほとんどがとても重要である。 | |
10.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
自己評価フォームはプログラムの一部となる値を生成します。これをsetcar
やaset
、その他の類似操作を通じて変更しようと試みるべきではありません。Lispインタープリターがプログラム中の自己評価フォームにより生成される定数を統合して、これらの定数が構造を共有するかもしれません。可変性を参照してください。
自己評価されるという事実による利点から数字、文字、文字列、そしてベクターでさえLispコード内で記述されるのが一般的です。しかし入力構文がない型にたいしてこれを行なうのは極めて異例です。なぜなら、これらをテキスト的に記述する方法がないからです。Lispプログラムを使用してこれらの型を含むLisp式を構築することは可能です。以下は例です:
;; バッファーオブジェクトを含む式を構築する。
(setq print-exp (list 'print (current-buffer)))
⇒ (print #<buffer eval-ja.texi>)
;; それを評価する。
(eval print-exp)
-| #<buffer eval-ja.texi>
⇒ #<buffer eval-ja.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
がそれらを他の任意のシンボルと同様に扱うとはいえ)自己評価フォームと同じように振る舞います。名前が‘:’で始まるシンボルも同じ方法で自己評価されます。そして、(通常は)値を変更できない点も同じです。変更不可な変数を参照してください。
[ << ] | [ < ] | [ 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 (and function (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
see 組み合わせ条件の構築
catch
cond
see 条件
condition-case
see エラーを処理するコードの記述
defconst
see グローバル変数の定義
defvar
see グローバル変数の定義
function
see 無名関数
if
see 条件
interactive
see インタラクティブな呼び出し
lambda
see ラムダ式
let
let*
see ローカル変数
or
see 組み合わせ条件の構築
prog1
prog2
progn
see 順序
quote
see クォート
save-current-buffer
see カレントバッファー
save-excursion
see エクスカーション
save-restriction
see ナローイング
setq
see 変数の値のセット
setq-default
unwind-protect
see 非ローカル脱出
while
see 繰り返し
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 ⇒ 'foo
'(quote foo) ⇒ 'foo
['foo] ⇒ ['foo]
(list '+ 1 2)
と'(+ 1 2)
の2つの式はいずれも(+ 1
2)
とequalなリストを生成しますが前者はmutableリストを新たに作成するのにたいして、後者は共有される可能性のある変更すべきではないコンスから構築したリストを作成します。自己評価を行うフォームを参照してください。
他のクォート構文としては、コンパイル用に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)
バッククォート構文の部分式に置換や継ぎ足し(splice)がなければ、これは共有される可能性があり変更するべきではないコンス、ベクター、文字列でのquote
のように振る舞います。自己評価を行うフォームを参照してください。
[ << ] | [ < ] | [ 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
可能な限りは文字列をユニコードに変換する。
この変数はエラー(エラーメッセージは"Lisp nesting exceeds
max-lisp-eval-depth"
)がシグナルされる前にeval
、apply
、funcall
の呼び出しで許容される最大の深さを定義する。
超過した際にエラーを起こすこの制限は、誤って定義された関数による無限再帰をEmacs
Lispが回避するための手段として用いられる。max-lisp-eval-depth
の値を過大に増加させると、そのようなコードはかわりにスタックオーバーフローを起こすだろう。オーバーフローを処理できるシステムがいくつかある。この場合には通常のLisp評価は割り込まれて、制御はトップレベルのコマンドループ(top-level
)に戻される。この状況ではEmacs
Lispデバッガにエンターする手段は存在しないことに注意されたい。エラーによるデバッガへのエンターを参照のこと。
Lisp式に記述された関数の呼び出し、関数呼び出しの引数と関数bodyフォームにたいする再帰評価、Lispコード内での明示的な呼び出し等では内部的にeval
、apply
、funcall
を使用して深さ制限を計数する。
この変数のデフォルト値は1600。この値を100未満にセットした場合には、値が与えられた値に達するとLispはそれを100にリセットする。空きが少なければデバッガー自身を実行するために空きが必要になるので、Lispデバッガーに入ったときは値が増加される。
この変数の値は読み取り、評価、プリントを行なった標準的なEmacsコマンドにより、バッファー(ミニバッファーを含む)からリターンされる値のリストである(これには*ielm*バッファーでの評価、lisp-interaction-mode
でのC-jやC-x
C-e、類似の評価コマンドを使用した評価は含まれないことに注意)。
この変数は時代遅れでありEmacsプロセスのメモリーフットプリントを常に増加させるため、将来のバージョンでは削除されるだろう。この理由により使用を推奨しない。
values
の要素の順序はもっとも最近の要素が最初になる。
(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] | [ ? ] |
たとえばプログラムの将来において計算結果が不要ということがわかった場合に時間を要する計算処理を回避したい等、式の評価を遅延させると便利な場合があります。そのような遅延評価(deferred evaluation)をサポートするために、thunkライブラリは以下の関数とマクロを提供します。
formsを評価するためのthunkをリターンする(訳注:
thunkとは、別のサブルーチンに計算を追加で挿入するために使用するサブルーチンであり、計算結果が必要になるまで計算を遅延したり、別のサブルーチンの先頭や最後に処理を挿入するために使用される。英語版Wikipediaより)。thunkはthunk-delay
呼び出しのlexical環境を継承するクロージャである(クロージャを参照)。このマクロの使用にはlexical-binding
が必要。
thunkを作成したthunk-delay
で指定されたフォームの評価をthunkに強制する。最後のフォームの評価結果をリターンする。thunkが強制されたことも“記憶”される。同一のthunkにたいする以降のthunk-force
呼び出しでは、フォームを再度評価せずに同じ結果をリターンする。
このマクロはlet
の類似だが“lazy(遅延された)”変数バインディングを作成する。すべてのバインディングは(symbol value-form)
という形式をもつ。let
とは異なり、すべてのvalue-formの評価はformsを最初に評価する際に、対応するsymbolのバインディングが使用されるまで遅延される。すべてのvalue-formは最大でも1回評価される。このマクロの使用にはlexical-binding
が必要。
例:
(defun f (number) (thunk-let ((derived-number (progn (message "Calculating 1 plus 2 times %d" number) (1+ (* 2 number))))) (if (> number 10) derived-number number)))
(f 5) ⇒ 5
(f 12) -| Calculating 1 plus 2 times 12 ⇒ 25
遅延バインドされた変数の特性として、それらにたいする(setq
による)セットはエラーになります。
これはthunk-let
と似ているが、bindings内の任意の式がこのthunk-let*
フォーム内の先行するバインディングの参照を許されている点が異なる。このマクロの使用にはlexical-binding
が必要。
(thunk-let* ((x (prog2 (message "Calculating x...") (+ 1 1) (message "Finished calculating x"))) (y (prog2 (message "Calculating y...") (+ x 1) (message "Finished calculating y"))) (z (prog2 (message "Calculating z...") (+ y 1) (message "Finished calculating z"))) (a (prog2 (message "Calculating a...") (+ z 1) (message "Finished calculating a")))) (* z x)) -| Calculating z... -| Calculating y... -| Calculating x... -| Finished calculating x -| Finished calculating y -| Finished calculating z ⇒ 8
thunk-let
とthunk-let*
はthunkを暗黙に使用します。これらの拡張はヘルパーシンボルを作成してバインディング式をラップするthunkにバインドします。forms本体中の元の変数にたいするすべての参照は、対応するヘルパー変数を引数とするthunk-force
呼び出し式に置き換えられます。したがってthunk-let
やthunk-let*
を使用するコードはthunkを使用するように書き換えが可能ですが、多くの場合には明示的にthunkを使用するよりこれらのマクロを使用するほうが優れたコードになるでしょう。
[ << ] | [ < ] | [ 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は他の様々な順序づけ、条件、繰り返し、(制御された)ジャンプを含む複数の種類の制御構造を提供しており、以下ではそれらのすべてを記述します。ビルトインの制御構造は制御構造のサブフォームが評価される必要がなかったり、順番に評価される必要がないのでスペシャルフォームです。独自の制御構造を構築するためにマクロを使用することができます(マクロを参照)。
11.1 順序 | テキスト順の評価。 | |
11.2 条件 | if 、cond 、when 、unless 。
| |
11.3 組み合わせ条件の構築 | and 、or 、not とその仲間達。
| |
11.4 パターンマッチングによる条件 | pcase 類の使用方法。
| |
11.5 繰り返し | while ループ。
| |
11.6 ジェネレーター | 汎用のシーケンスとコルーチン。 | |
11.7 非ローカル脱出 | シーケンスの外へのジャンプ。 |
[ << ] | [ < ] | [ 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は5つの条件フォームをもちます。if
は他の言語のものとほとんど同じです。when
とunless
はif
の変種です。cond
は一般化されたcase命令です。cond
を汎用化したものがpcase
です(パターンマッチングによる条件を参照)。
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))
変数のバインドとあわせて条件を使うと便利かもしれません。変数の計算を行って、その後もし値が非nil
なら何かしたいというのはよくあることです。これを行うには、たとえば以下のように単にそのまま記述すればよいのです:
(let ((result1 (do-computation))) (when result1 (let ((result2 (do-more result1))) (when result2 (do-something result2)))))
これはパターンとしては非常に一般的なのでEmacsではこれを簡単に行って、かつ可読性を向上させるためのマクロがいくつか提供されています。上記のコードは以下のように記述することができます:
(when-let ((result1 (do-computation)) (result2 (do-more result1))) (do-something result2))
このテーマにはバリエーションがいくつかあり、以下にそれらを概略します。
spec内のバインディングを、let*
(ローカル変数を参照)のようにそれぞれ順番に評価して、値がnil
になるバインディングがあれば停止する。すべて非nil
ならthen-form、それ以外ではelse-formsの最後のフォームの値をリターンする。
if-let
と同様だがelse-formsがない。
when-let
と同様だが、spec内のバインディングがnil
になるまで繰り返す。リターン値は常にnil
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは複雑な条件を表現するためにif
やcond
とともによく使用される構文を説明します。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回以上引数を評価することは決してない。
この関数はcondition1とcondition2の排他的論理和をリターンする。つまりxor
は引数がいずれもnil
あるいは非nil
ならnil
をリターンする。それ以外なら非nil
の引数の値をリターンする。
or
とは対照的に引数はどちらも常に評価されることに注意。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
4つの基本的な条件フォームとは別に、Emacs Lispにはcond
とcl-case
(Conditionals in Common Lisp
Extensionsを参照)の合成物とも言うべき、pcase
マクロというパターンマッチングによる条件フォームがあります。これはcond
とcl-case
の制限を克服して、パターンマッチングによるプログラミングスタイル(pattern
matching programming style)を導入するものです。そのpcase
が克服する制限とは:
cond
フォームはclauseそれぞれにたいして述語conditionを評価して候補から選択を行う(条件を参照)。condition内でのletバインドされた変数がclauseのbody-formsで利用できないのが主な制限。
もう1つの煩しい(制限というより不便な)点は一連のcondition述語が等価なテストを実装する際にはコードが多数回繰り返されること(cl-case
はこの不便さを解決している)。
cl-case
マクロは最初の引数と特定の値セットの等価性を評価することにより候補から選択を行う。
制限は2つ:
eql
を使用。
これらの制限は文字列や複合データ構造にたいしてcl-case
を不適格にする(このような制限はcond
にはないが上述のように別の制限をもつ)。
pcase
マクロはパターンマッチング(pattern
matching)の変種であるような等価性テストを汎化したものによるconditionの置き換え、clauseの述語を簡潔に表現できるような機能の追加、clauseの述語とbody-formsの間でletバインディングを共有するようなアレンジにより、概念的には最初の引数のフォーカスではcl-case
、clauseの処理フローではcond
を借用しています。
この述語の簡潔な表現はパターン(pattern)として知られています。最初の引数の値にたいして呼び出される述語が非nil
をリターンしたときには、“パターンが値にマッチした”といいます(“値がパターンにマッチした”ということもある)。
11.4.1 pcase マクロ | 例と注意を含む。 | |
11.4.2 pcase の拡張 | 新種パターンの定義。 | |
11.4.3 バッククォートスタイルパターン | 構造的パターンマッチング。 | |
11.4.4 pcase パターンによる分解 | pcaseパターンによるサブフィールド抽出。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
pcase
マクロ背景はパターンマッチングによる条件を参照してください。
clauses内のclauseは(pattern body-forms…)
という形式をもつ。
expressionの値( expval )を決定するために評価する。patternがexpvalにマッチするような最初のclauseを探して、そのclauseのbody-formsに制御を渡す。
マッチが存在すればpcase
の値はマッチが成功したclauseのbody-formsの最後の値、それ以外ならpcase
はnil
に評価される。
各patternはpcaseパターン(pcase
pattern)である必要があります。これは以下に定義されるコアパターンのいずれか、またはpcase-defmacro
(pcase
の拡張を参照)を通じて定義されるパターンの1つを使用できます。
このサブセクションの残りの部分ではコアパターンの異なるフォームをいくつかの例を交えて説明して、いくつかのパターンフォームが提供するletバイディング機能を使用する上で重要な注意点で締めくくります。コアパターンは以下のフォームをもつことができます:
_ (アンダースコア)
任意のexpvalにマッチ。これはdon’t care、あるいはワイルドカード(wildcard)としても知られる。
'val
expvalとvalが等しければマッチ。比較はequal
のように行われる(同等性のための述語を参照)。
keyword
integer
string
expvalがリテラルオブジェクトと等しければマッチ。これは上述の'val
の特殊なケースであり、これらのタイプのリテラルオブジェクトが自己クォート(self-quoting)を行うために可能となる。
symbol
任意のexpvalにマッチするとともに、追加でsymbolをexpvalにletバインドする。このようなバインディングはbody-forms内でも利用できる(ダイナミックバインディングを参照)。
symbolが(以下のand
を使用することにより)シーケンスパターンseqpatの一部なら、symbolに後続するseqpat部分でもバインディングは利用可能。この使用法にはいくつかの注意点がある。caveatsを参照のこと。
使用を避けるべき2つのシンボルは_
(上述)と同様に振る舞う非推奨のt
とnil
(エラーをシグナルする)。同様にキーワードシンボルへのバインドは無意味(変更不可な変数を参照)。
(cl-type type)
expvalがタイプtype ( cl-typep
が許す型記述子。 Type
Predicates in Common Lisp Extensionsを参照)ならマッチ。たとえば:
(cl-type integer) (cl-type (integer 0 10))
(pred function)
expvalにたいして述語functionが非nil
をリターンしたらマッチ。このテストは構文(pred
(not function))
で否定となる。述語functionは以下のフォームのいずれかが可能:
expvalを単一の引数として名前つきの関数を呼び出す。
例: integerp
expvalを単一の引数として無名関数を呼び出す(ラムダ式を参照)。
例: (lambda (n) (= 42 n))
関数(関数呼び出しの1つ目の要素)をn個の引数(残りの要素)、およびexpvalをn+1番目の追加の引数としてで呼び出す。
例: (= 42)
この例では関数が=
、nが1であり、実際の関数呼び出しは(= 42 expval)
になる。
(app function pattern)
expvalにたいして呼び出したfunctionがpatternにマッチする値をリターンすればマッチ。functionは上述のpred
で説明したフォームのいずれかが可能。しかしpred
とは異なり、app
はブーリーンの真値ではなくpatternにたいして結果をテストする点が異なる。
(guard boolean-expression)
boolean-expressionが非nil
に評価されればマッチ。
(let pattern expr)
exprvalを取得するためにexprを評価して、exprvalがpatternにマッチすればマッチ(patternはsymbolを使用することでシンボルに値をバインドできるのでlet
と呼ばれる)。
seqpatとしても知られるシーケンスパターン(sequencing
pattern)はサブパターンを順に処理するパターンです。pcase
にたいしてはand
とor
の2つが存在します。これらは同じ名前のスペシャルフォーム(組み合わせ条件の構築を参照)と同様の方式で振る舞いますが、値ではなくサブパターンを処理します。
(and pattern1…)
pattern1…のいずれかがマッチに失敗するまで順にマッチを試みる。この場合にはand
もマッチに失敗して、残りのサブパターンはテストしない。すべてのサブパターンがマッチすればand
はマッチする。
(or pattern1 pattern2…)
pattern1、pattern2、…のいずれかがマッチに成功するまで順にマッチを試みる。この場合にはor
もマッチして、残りのサブパターンはテストしない。
body-formsにたいして一貫した環境
(評価の概要を参照)
を与える(マッチでの評価エラーを回避できる)ために、パターンがバインドする変数セットは各サブパターンがバインドする変数を結合したものになる。ある変数がマッチしたサブパターンにバインドされない場合にはnil
にバインドされる。
(rx rx-expr…)
string-match
が行うようにrx
正規表現表記を使用して文字列を正規表現rx-expr…にマッチする(rx
構造化Rgexp表記を参照)。
通常のrx
構文に加えて、rx-expr…には以下の構文を含めることができる:
(let ref rx-expr…)
シンボルrefをrx-expr...にマッチする部分マッチにバインドする。refはbody-forms内で部分マッチの文字列かnil
にバインドされるが、backref
でも使用可能。
(backref ref)
標準のbackref
構文と同様だが、refは前の(let ref
…)
構文で導入された名前にもなる。
cl-case
にたいする利点以下はcl-case
(Conditionals in Common Lisp
Extensionsを参照)にたいするpcase
の利点のいくつかを強調する例です。
(pcase (get-return-code x) ;; 文字列 ((and (pred stringp) msg) (message "%s" msg))
;; シンボル ('success (message "完了!")) ('would-block (message "残念、今は実行できない")) ('read-only (message "shmliblickは読み取り専用")) ('access-denied (message "必要な権限がない"))
;; default (code (message "未知のリターンコード %S" code)))
cl-case
ではget-return-code
のリターン値を保持するためにローカル変数code
を宣言する必要があります。さらにcl-case
は比較にeql
を使用するので文字列の使用も難しくなります。
and
の使用後続のサブパターン(と同様にbodyフォーム)にバインディングを提供する1つ以上のsymbolサブパターンをもつand
で開始するのが、パターンを記述する際の一般的なイディオムです。たとえば以下のパターンは1桁の整数にマッチします。
(and
(pred integerp)
n ; n
にexpvalをバインド
(guard (<= -9 n 9)))
まずpred
は(integerp expval)
が非nil
に評価されればマッチになります。次にn
はすべてにマッチするsymbolパターンであり、n
にexpvalがバインドされます。最後にguard
はブーリーン式(<= -9 n 9)
が非nil
に評価されればマッチになります(n
への参照に注意)。これらすべてのサブパターンがマッチすればand
がマッチになります。
pcase
による書き換え以下はシンプルなマッチングタスクを伝統的な実装(関数grok/traditional
から、pcase
を使用する実装(関数grok/pcase
)に書き換える別の例です。これらの関数のdocstringはいずれも“If
OBJ is a string of the form "key:NUMBER", return NUMBER (a
string). Otherwise, return the list ("149"
default).”です。最初は伝統的な実装です(正規表現を参照):
(defun grok/traditional (obj) (if (and (stringp obj) (string-match "^key:\\([[:digit:]]+\\)$" obj)) (match-string 1 obj) (list "149" 'default)))
(grok/traditional "key:0") ⇒ "0" (grok/traditional "key:149") ⇒ "149" (grok/traditional 'monolith) ⇒ ("149" default)
この書き換えではsymbolバインディング、およびor
、and
、pred
、app
、let
を実演します。
(defun grok/pcase (obj) (pcase obj ((or ; L1 (and ; L2 (pred stringp) ; L3 (pred (string-match ; L4 "^key:\\([[:digit:]]+\\)$")) ; L5 (app (match-string 1) ; L6 val)) ; L7 (let val (list "149" 'default))) ; L8 val))) ; L9
(grok/pcase "key:0") ⇒ "0" (grok/pcase "key:149") ⇒ "149" (grok/pcase 'monolith) ⇒ ("149" default)
grok/pcase
は主に1つのpcase
フォームのclause、L1からL8のパターン、L9の(1つの)フォームからなります。パターンは引数であるサブパターンにたいして順にマッチを試みるor
です。これは最初にand
(L2からL7)、次にlet
(L8)のように、いずれかが成功するまで順にマッチを試みます。
前出の例(Example
1を参照)のように、and
は以降のサブパターンが正しいタイプのオブジェクト(この場合は文字列)に作用することを保証するためにpred
サブパターンで始まります。(stringp expval)
がnil
ならpred
は失敗となり、したがってand
も失敗となります。
次のpred
(L4からL5)は(string-match RX expval)
を評価して結果が非nil
(
expvalが期待するフォームkey:NUMBER
であることを意味する)ならマッチになります。これが失敗すると再びpred
は失敗となり、したがってand
も失敗となります。
(and
の一連のサブパターンでは)最後のapp
は一時的な値tmp (部分文字列
“NUMBER”)を取得するために(match-string 1 expval)
(L6)を評価して、パターンval
(L7)とtmpのマッチを試みます。これはsymbolパターンなので無条件でマッチして、val
にtmpを追加でバインドします。
ついにapp
がマッチしたので、and
のすべてのサブパターンがマッチして、and
がマッチとなります。同じように一度and
がマッチすればor
がマッチするので、サブパターンlet
(L8)の処理が試みられることはありません。
obj
が文字列以外、あるいは間違った形式の文字列の場合を考えてみましょう。この場合にはいずれかのpred
(L3からL5)がマッチに失敗するので、and
(L2)がマッチに失敗して、or
(L1)がサブパターンlet
(L8)の処理を試みます。
まずlet
は("149" default)
を取得するために(list "149" 'default)
を評価して、それからパターンval
にたいしてexprvalのマッチを試みます。これはsymbolパターンなので無条件にマッチして、追加でval
にexprvalをバインドします。これでlet
がマッチしたので、or
がマッチとなります。
and
とlet
のサブパターンはどちらも同じ方法、すなわちval
をバインドする過程でsymbolパターンのval
に(常に成功する)マッチを試みることにより完了することに注意してください。したがってor
は常にマッチして、常に制御をbodyフォーム(L9)に渡します。マッチが成功したpcase
のclauseとしては最後のbodyなので、これはpcase
の値となり、同様にgrok/pcase
のリターン値になります(関数とは?を参照)。
前出の例のすべてでは、何らかの方法によりsymbolサブパターンが含まれるシーケンスパターンが使用されています。以下に使用法に関する重要な詳細をいくつか挙げます。
eq
を使用した等価性テストに展開される。
以下の例には2つのclauseと2つのseqpat
(AとB)を使用している。AとBはいずれも最初に(pred
を使用することにより)expvalがペアであることをチェックして、それから(それぞれにたいしてapp
を使用することにより)
expvalのcar
とcdr
にシンボルをバインドする。
Aではシンボルst
が2回記述されているので、2つ目の記述はeq
を使用した等価性チェックになる。一方でBはs1
とs2
という別個のシンボルを使用するので、独立したバインディングになる。
(defun grok (object) (pcase object ((and (pred consp) ; seqpat A (app car st) ; st: 1回目 (app cdr st)) ; st: 2回目 (list 'eq st))
((and (pred consp) ; seqpat B (app car s1) ; s1: 1回目 (app cdr s2)) ; s2: 1回目 (list 'not-eq s1 s2))))
(let ((s "yow!")) (grok (cons s s))) ⇒ (eq "yow!") (grok (cons "yo!" "yo!")) ⇒ (not-eq "yo!" "yo!") (grok '(4 2)) ⇒ (not-eq 4 (2))
and
、symbol、guard
を使用する:
(defun square-double-digit-p/CLEAN (integer) (pcase (* integer integer) ((and n (guard (< 9 n 100))) (list 'yes n)) (sorry (list 'no sorry)))) (square-double-digit-p/CLEAN 9) ⇒ (yes 81) (square-double-digit-p/CLEAN 3) ⇒ (no 9)
(defun square-double-digit-p/MAYBE (integer)
(pcase (* integer integer)
((and n (guard (< 9 (incf n) 100))) (list 'yes n))
(sorry (list 'no sorry))))
(square-double-digit-p/MAYBE 9) ⇒ (yes 81)
(square-double-digit-p/MAYBE 3) ⇒ (yes 9) ; WRONG!
違いはguard
内のboolean-expressionである。CLEAN
は単に直接n
を参照するのにたいして、MAYBE
は式(incf
n)
の中で副作用によりn
を参照している。integer
の際には以下のようなことが発生している:
n
はexpval
(評価した結果である(* 3 3)
、つまり9)にバインドされる。
start: (< 9 (incf n) 100) becomes: (< 9 (setq n (1+ n)) 100) becomes: (< 9 (setq n (1+ 9)) 100)
becomes: (< 9 (setq n 10) 100)
; ここで副作用!
becomes: (< 9 n 100) ; n
は10にバインドされている
becomes: (< 9 10 100)
becomes: t
nil
なので
guard
がマッチしてand
がマッチとなり、制御はそのclauseのbodyフォームに渡される。
MAYBE
には9が2桁の整数だと判定してしまう数学的な誤り以外にも問題がある。bodyフォームはn
の更新された値(10)を確認せずに参照を複数回行う。するとどうなるか?
要約すると( guard
での) boolean-expressionだけではなく( let
での)
expr、( pred
とapp
での)
functionでも副作用をもつsymbolパターンにたいする参照は完全に避けることが最良である。
and
の際には、各サブパターンでletバインドされるすべてのシンボルそれぞれを結合したものになる。and
のマッチではすべてのサブパターンがマッチしなければならないので、これには意味がある。
seqpatがor
なら事情は異なる。or
は最初にマッチしたサブパターンでマッチとなり、残りのサブパターンは無視される。bodyフォームにはどのサブパターンがマッチして異なるセットの中からどれが選択されたかを知る術はないので、各シンボルが異なるシンボルセットをletバインドすることに意味はない。たとえば以下は無効:
(require 'cl-lib) (pcase (read-number "Enter an integer: ") ((or (and (pred cl-evenp) e-num) ;e-num
をexpvalにバインド o-num) ;o-num
をexpvalにバインド (list e-num o-num)))
Enter an integer: 42 error→ Symbol’s value as variable is void: o-num
Enter an integer: 149 error→ Symbol’s value as variable is void: e-num
bodyフォーム(list e-num o-num)
の評価によりエラーがシグナルされる。サブパターンを区別するために、すべてのサブパターンごとに異なる値をもつ同一名のシンボルを使用できる。上記の例を書き換えると:
(require 'cl-lib) (pcase (read-number "Enter an integer: ") ((and num ; L1 (or (and (pred cl-evenp) ; L2 (let spin 'even)) ; L3 (let spin 'odd))) ; L4 (list spin num))) ; L5
Enter an integer: 42 ⇒ (even 42)
Enter an integer: 149 ⇒ (odd 149)
L1ではexpvalのバインディング(この場合はnum
)をand
とsymbolで“分解”している。L2では前と同じ方法でor
は始まるが、異なるシンボルにバインドするかわりに、両方のサブパターン内で同一のシンボルspin
に回バインドするために2回let
を使用している(L3からL4)。spin
の値によりサブパターンは区別される。そしてbodyフォームでは両方のシンボルを参照している(L5)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
pcase
の拡張pcase
マクロは数種類のパターンをサポートします(パターンマッチングによる条件を参照)。pcase-defmacro
を使用すれば違う種類のパターンにたいするサポートを追加できます。
(name actual-args)
のように呼び出すために新たな種類のpcase
用のパターンを定義する。pcase
マクロはbodyを評価する呼び出しへと展開する。このマクロの役割はargsをactual-argsにバインドした環境下において、呼び出されたパターンを別の何らかのパターンに書き換えることである。
さらにpcase
のドキュメント文字列とともにdocが表示されるように計らう。docでは慣例によりexpressionの評価結果を示すためにEXPVAL
を使用すること。
bodyは通常はより基本的なパターンを使用して呼び出されたパターンを書き換える。最終的にはすべてのパターンはコアパターンに絞り込まれるが、body
がすぐにコアパターンを使用する必要はない。以下の例ではless-than
とinteger-less-than
という2つのパターンを定義している。
(pcase-defmacro less-than (n) "Matches if EXPVAL is a number less than N." `(pred (> ,n)))
(pcase-defmacro integer-less-than (n) "Matches if EXPVAL is an integer less than N." `(and (pred integerp) (less-than ,n)))
args
(このケースではn
の1つだけ)に言及するdocstringは通常の方法、EXPVAL
では慣例にもとづく方法であることに注意してください。1つ目の書き換え(
less-than
のbody
)ではpred
というコアパターンだけが使用されていて、2つ目では2つのコアパターンand
とpred
と新たに定義したパターンless-than
が使用されています。そしていずれの書き換えにおいてもシングルバッククォート構文が使用されています(バッククォートを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このサブセクションでは構造化マッチングを容易にするビルトインパターンであるバッククォートスタイルパターン(backquote-style patterns)について説明します。背景についてはパターンマッチングによる条件を参照してください。
バッククォートスタイルパターンは(pcase-defmacro
を使用して作成された)強力なpcase
パターン拡張であり、その構造(structure)の仕様にたいするexpvalのマッチを容易にします。
たとえば1つ目の要素が特定の文字列、2つ目の要素が任意の値であるような2要素リストのexpvalにたいするマッチはコアパターンを使用して記述できます:
(and (pred listp) ls
(guard (= 2 (length ls))) (guard (string= "first" (car ls))) (let second-elem (cadr ls)))
しかし等価なバッククォートスタイルパターンで記述することもできます:
`("first" ,second-elem)
バッククォートスタイルパターンはより簡潔かつexpvalの構造と似ており、ls
のバインドを要しません。
バッククォートスタイルパターンは`qpat
のような形式をもちます。ここでqpatは以下の形式をもつことができます:
(qpat1 . qpat2)
expvalが(
car
がqpat1、cdr
がqpat2にマッチする)コンスセルならマッチ。(qpat1 qpat2 …)
のように容易に一般化できる。
[qpat1 qpat2 … qpatm]
expvalが長さmの(0
から(m-1)
番目の要素がqpat1、qpat2、…、qpatmにマッチする)ベクターならマッチ。
symbol
keyword
number
string
expvalの対応する要素が指定されたリテラルオブジェクトとequal
ならマッチ。
,pattern
expvalの対応する要素がpatternにマッチすればマッチ。patternはpcase
がサポートするすべての種類のパターンであることに注意(上記の例ではsecond-elem
はsymbolコアパターンであり、これはすべてにマッチしてsecond-elem
をletでバインドする)。
対応する要素(corresponding
element)とはバッククォートスタイルパターンqpatにたいする構造的な位置に等しいようなexpvalの構造的な位置部分のことです(上記の例ではsecond-elem
の対応する要素はexpvalの2つ目の要素)。
以下は小さな式言語用の単純なインタープリターの実装用にpcase
を使用する例です(body
とarg
を正しくキャプチャーするにはfn
のclause内でlambda式にレキシカルバインディングが必要なことに注意):
(defun evaluate (form env) (pcase form (`(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) form) ((pred symbolp) (cdr (assq form env))) (_ (error "Syntax error: %S" form))))
最初の3つのclauseではバッククォートスタイルパターンが使用されています。`(add ,x
,y)
はform
がリテラルシンボルadd
から始まる3要素リストであることをチェックしてから2つ目と3つ目の要素を取り出してシンボルx
とy
にバインドします。clauseのbodyではx
とy
を評価して結果を加算します。同じようにcall
clauseは関数呼び出しを実装して、fn
clauseは無名関数定義を実装します。
残りのclauseではコアパターンが使用されています。(pred
numberp)
はform
が数値ならマッチします。マッチした場合にはbodyがそれを評価します。(pred
symbolp)
はform
がシンボルならマッチします。マッチした場合にはbodyはenv
内のシンボルを照合して、それの連想値をリターンします。最後の_
はすべてにマッチする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
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
pcase
パターンによる分解pcaseのパターンはあるオブジェクトがマッチ可能なフォーム上の条件を表現するだけではなく、それらのオブジェクトのサブフィールドの抽出もできます。たとえば以下のコードにより、変数my-list
の値であるリストから2つの要素を抽出できます:
(pcase my-list (`(add ,x ,y) (message "Contains %S and %S" x y)))
これはx
とy
を抽出するだけではなく、加えてmy-list
が正確に3つの要素を含むリストであり、最初の要素がシンボルadd
かどうかをテストします。これらのテストのいずれかが失敗したら、pcase
はmessage
を呼び出さずに即座にnil
をリターンします。
あるオブジェクトから格納された複数の値を抽出する処理は分割(destructuring)という処理としても知られています。pcase
パターンの使用によりバインディングの分割(destructuring
binding)を処理することが可能になります。これはローカルバインディング(ローカル変数を参照)と似ていますが、互換性のあるオブジェクトから値を抽出することにより、変数の複数要素に値を与えることができます。
このセクションで説明したマクロはバインディングを分割するためにpcase
パターンを使用しています。オブジェクト構造に互換性があるという条件は、そのオブジェクトがパターンにマッチしなければならないことを意味しています。なぜならマッチした場合のみオブジェクトのサブフィールドが抽出可能になるからです。たとえば:
(pcase-let ((`(add ,x ,y) my-list)) (message "Contains %S and %S" x y))
これは最初にmy-list
が正しい個数の要素をもつリストであり、かつ1つ目の要素がadd
か検証せずに、my-list
から直接x
とy
の抽出を行う点を除いて前の例と同じことを行います。実際にオブジェクトがパターンにマッチしない場合には、たとえbodyが暗黙にスキップされることはないとしても、その振る舞いは未定義でありエラーがシグナルされるか、あるいはいくつかの変数がnil
のような任意の値にバインドされた状況でbodyが実行されるかもしれません。
バインディングの分割に有用なpcaseパターンとしては、マッチされるオブジェクト構造の仕様を表現するバッククォートスタイルパターンで説明したパターンが一般的です。
バインディングの分割にたいする代替え機能についてはseq-letを参照してください。
bindingsに応じて変数のバインディング分割を行い、それからbodyを評価する。
bindingsは(pattern exp)
という形式のバインディングのリスト。ここでexpは評価する式、patternはpcase
パターン。
expはすべて最初に評価されて、その後で対応するpatternにマッチされて、bodyの内部で使用可能な変数バインディングが導入される。この変数バインディングはpatternの要素を、評価されたexpの対応する要素の値に分割してのバインディングすることにより生成される。
以下はその例:
(pcase-let ((`(,major ,minor) (split-string "image/png" "/"))) minor) ⇒ "png"
bindingsに応じて変数のバインディング分割を行い、それからbodyを評価する。
bindingsは(pattern
exp)
という形式のバインディングのリスト。ここでexpは評価する式、patternはpcase
パターン。この変数バインディングはpatternの要素を、評価されたexpの対応する要素の値に分割してバインディングすることにより生成される。
pcase-let
とは異なり(しかしlet*
と同じように)、各expはbindingsの次要素の処理前に対応するpatternにたいしてマッチされるので、各bindingsのいずれかによって導入される変数バインディングはbody内で利用可能になるのに加えて、その後に続くbindingsのexp内で利用可能になる。
繰り返しごとにpatternの変数をlistの要素の対応するサブフィールドに分割バインディングしながら、listの各要素ごとに一度bodyを実行する。このバインディングはpcase-let
の場合のように行われる。patternが単なる変数ならdolist
と等価(繰り返しを参照)。
patternに応じて各valueの分割を行い、setq
フォーム内の変数に値を割り当てる。
lambda
と同様だが、各引数はパターンでも良い。たとえば以下は引数としてコンスセルを受け取る単純な関数の例:
(setq fun (pcase-lambda (`(,key . ,val)) (vector key (* val 10)))) (funcall fun '(foo . 2)) ⇒ [foo 20]
[ << ] | [ < ] | [ 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
をリターンする。resultの使用は推奨しない。以下は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との連携における重要な原則を示すものです。
(require 'generator) (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ではエラーの結果として非ローカル脱出が発生することがあります。明示的な制御の下で非ローカル脱出を使用することもできます。非ローカル脱出は脱出しようとしている構文により作成された、すべての変数バインディングのバインドを解消します。
11.7.1 明示的な非ローカル脱出: catch とthrow | プログラム自身の目的による非ローカル脱出。 | |
11.7.2 catch とthrow の例 | このような非ローカル脱出が記述される方法。 | |
11.7.3 エラー | エラーのシグナルと処理される方法。 | |
11.7.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
とthrow
の例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
を参照してください。
11.7.3.1 エラーをシグナルする方法 | エラーを報告する方法。 | |
11.7.3.2 Emacsがエラーを処理する方法 | エラーを報告するときEmacsが何を行なうか。 | |
11.7.3.3 エラーを処理するコードの記述 | エラーをトラップして実行を継続する方法。 | |
11.7.3.4 エラーシンボルとエラー条件 | エラートラプのためにエラーをクラス分けする方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
エラーのシグナリング(signaling)とは、エラーの処理を開始することを意味します。エラー処理は通常は実行中のプログラムのすべて、または一部をアボート(abort)してエラーをハンドルするためにセットアップされた位置にリターンします。ここではエラーをシグナルする方法を記述します。
ほとんどのエラーは、たとえば整数にたいしてCARの取得を試みたり、バッファーの最後で1文字前方に移動したときなどのように、他の目的のために呼び出したLispプリミティブ関数の中で自動的にシグナルされます。関数error
とsignal
で明示的にエラーをシグナルすることもできます。
ユーザーがC-gをタイプしたときに発生するquitはエラーとは判断されませんが、ほとんどはエラーと同様に扱われます。quitを参照してください。
すべてのエラーメッセージはそれぞれ、何らかのエラーメッセージを指定します。そのメッセージはどうであるべきか(“File must exist”)ではなく、何が悪いのか(“File does not 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
は機能する。
"Missing `%s'"が"Missing ‘foo’"となるように、通常はフォーマット内のgrave accentとapostropheはマッチする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
を含む)。t
というコンディション名はすべてのコンディションにマッチする。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
なら、それはバインドされた変数がないことを意味する。この場合、エラーシンボルおよび関連するデータは、そのハンドラーでは利用できない。
特殊なケースとしてhandlersのいずれか1つが(:success
body…)
形式のリストの場合がある。ここでbodyはprotected-formがエラーなしで終了した際のリターン値(非nil
の場合)にバインドされたvarとともに実行される。
より外側のレベルのハンドラーに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
と同様だが、指定した特定のエラーコンディションだけを無視する点が異なる。
(ignore-error end-of-file (read ""))
conditionはエラーコンディションのリストでも可。
このマクロはいわば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
を配置して保護すること。
たとえば以下は一時的な使用のために不可視のバッファーを作成して、終了する前に確実にそのバッファーを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
は関数の作成者が予想できない多くの問題から非常に影響を受け易いので、失敗イベントでプロセスの削除を保証するフォームで保護されています。そうしないと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)に格納されます9。シンボルの構成要素を参照してください。Emacs Lispではシンボルを変数として使用することは、同じシンボルを関数名として使用することと関係ありません。
このマニュアルで前述したとおり、Lispプログラムはまず第1にLispオブジェクトとして表され、副次的にテキストとして表現されます。Lispプログラムのテキスト的な形式は、そのプログラムを構成するLispオブジェクトの入力構文により与えられます。したがってLispプログラム内の変数のテキスト的な形式は、その変数を表すシンボルの入力構文を使用して記述されます。
12.1 グローバル変数 | どの場所でも永続的に存在する変数の値。 | |
12.2 変更不可な変数 | Variables that never change. | |
12.3 ローカル変数 | 一時的にのみ存在する存在する変数の値。 | |
12.4 変数がvoidのとき | 値を持たないシンボル。 | |
12.5 グローバル変数の定義 | シンボルが変数として使用されていることを宣言する定義。 | |
12.6 堅牢な変数定義のためのヒント | 変数を定義するときに考慮すべき事項。 | |
12.7 変数の値へのアクセス | 実行時に判明する名前をもつ変数の値を確認する。 | |
12.8 変数の値のセット | 変数に新しい値を格納する。 | |
12.9 変数が変更されたときに実行される関数。 | ||
12.10 変数のバインディングのスコーピングルール | Lispがローカル値とグローバル値を選択する方法。 | |
12.11 バッファーローカル変数 | 1つのバッファーないだけで効果をもつ変数の値。 | |
12.12 ファイルローカル変数 | ファイル内にリストされたローカル変数の処理。 | |
12.13 ディレクトリーローカル変数 | ディレクトリー内のすべてのファイルで共通のローカル変数。 | |
12.14 接続ローカル変数 | リモート接続で共通なローカル変数。 | |
12.15 変数のエイリアス | 他の変数のエイリアスとなる変数。 | |
12.16 値を制限された変数 | 任意のLispオブジェクトを値とすることができない、定数ではない変数。 | |
12.17 ジェネリック変数 | 変数の概念の拡張。 | |
12.18 マルチセッション変数 | Emacsを再起動しても存続する変数。 |
[ << ] | [ < ] | [ 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はエラーを起こしません。
現実的な種々の理由により、追加で少数のシンボルが読み取り専用になります。これらにはenable-multibyte-characters
、most-positive-fixnum
、most-negative-fixnum
の他にいくつかのシンボルが含まれます。これらにたいしてセットやバインドを試みると、すべてsetting-constant
エラーがシグナルされます。
[ << ] | [ < ] | [ 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)と呼ばれるスコープルールについては、変数のバインディングのスコーピングルールを参照してください。Emacsの最近の動向として、レキシカルバインディングをデフォルトにするという最終ゴールに向けて、レキシカルバインディングがますます多くの場所で使用される方向に進んでいます。特にEmacs Lispのソースファイルすべてと*scratch*バッファーではレキシカルなスコープが使用されています。
スペシャルフォームlet
とlet*
は、ローカルバインディングを作成するために存在します:
このスペシャルフォームはbindingsにより指定される特定の変数セットにたいするローカルバインディングをセットアップしてから、formsのすべてをテキスト順に評価する。これはforms内の最後のフォームの値をリターンする。let
がセットアップしたローカルバインディングはformsのbody内でのみ効果をもつ。
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)
その一方でbindingsの順序は指定されない。以下の例では1か2のどちらかがプリントされる。
(let ((x 1) (x 2)) (print x))
したがって単一のlet
フォーム内で変数を複数回バインディングするのは避けること。
このスペシャルフォームはlet
と似ているが、次の変数値にたいするローカル値を計算する前に、ローカル値を計算してそれを変数にバインドする。したがてbindings内の式は、このlet*
フォーム内の前のシンボルのバインドを参照できる。以下の例を上記let
の例と比較されたい。
(setq y 2) ⇒ 2
(let* ((y 1)
(z y)) ; y
の値に今計算されたばかりの値を使用する
(list y z))
⇒ (1 1)
上記例におけるx
とy
のlet*
バインディングは、基本的には以下のようなネストされたlet
を使うのと同じ:
(let ((y 1)) (let ((z y)) (list y z)))
このスペシャルフォームはlet*
と同様だが、ローカル値を計算する前にすべての変数をバインドする。値はその後にバインドされた変数にローカルに割り当てられる。これはレキシカルバインディングが効力をもち、let*
の使用しても有効にならないバインディングを参照するクロージャを作成したい場合のみ有用。
たとえば以下は一度実行後にフックから自身を削除するクロージャ:
(letrec ((hookfun (lambda () (message "Run once") (remove-hook 'post-command-hook hookfun)))) (add-hook 'post-command-hook hookfun))
このスペシャルフォームはlet
と似ているが、すべての変数をダイナミックにバインドする。これが役に立つことは稀だろう —
通常ならノーマル変数はレキシカルに、スペシャル変数(defvar
で定義された変数)はダイナミックにバインドしたいと望むだろうし、これは正にlet
が行うことだからだ。
特定の変数がダイナミックにバインド(ダイナミックバインディングを参照)されていることを想定している古いコードとインターフェイスをとる際、それらの変数をdefvar
とするのは非現実的な場合にdlet
は有用かもしれない。dlet
はこれらの変数を一時的にスペシャルとしてバインドしてフォームを実行、それから再び変数を非スペシャルにする。
このスペシャルフォームはScheme言語からインスパイアされたロープ構文である。これはlet
のようにbindings内の変数をバインドしてからbodyを評価する。ただしnamed-let
は正規の引数がbindings内の変数で本体がbodyであるようなローカル関数にたいしてnameのバインドも行う。これによりnameを呼び出してbodyが自身を再帰的に呼び出すことができる。再帰呼び出しにおいては、バインドされる変数の新たな値としてnameに渡された引数が使用される。
数値にリストを加算するループの例:
(named-let sum ((numbers '(1 2 3 4)) (running-sum 0)) (if numbers (sum (cdr numbers) (+ running-sum (car numbers))) running-sum)) ⇒ 10
bodyの末尾位置(tail positions)におけるnameへの再帰呼び出しは、末尾呼び出し(tail calls)としての最適化が保証される。これは再帰の実行深さに関わらず追加のスタック空間を消費しないことを意味する。このような再帰呼び出しでは、変数にたいして新たな値でループ先頭に効果的にジャンプを行う。
一番最後に行うことが関数呼び出しならそれは末尾位置にあり、したがってその呼び出しのリターン値は上記sum
にたいする再帰呼び出しと同じようにbodyの値となる。
警告: named-let
が期待通り動作するのはレキシカルバインディングg有効な場合のみ。See レキシカルバインディングを参照のこと。
以下はローカルバインディングを作成する他の機能のリストです:
変数はバッファーローカルなバインディングを持つこともできます(バッファーローカル変数を参照)。数は多くありませんが、端末ローカル(terminal-local)なバインディングをもつ変数もあります(複数の端末を参照)。この種のバインディングは、通常のローカルバインディングのように機能することもありますが、これらはEmacs内のどこにいるかに依存してローカルになります。
[ << ] | [ < ] | [ 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の値は変更されない。
たとえnil
であっても値を指定することにより、その変数は特別だと永続的にマークされることに注意。一方でvalueが省略されると変数はローカル(カレントのレキシカルスコープまたはトップレベルにあればファイル)でのみ特別だとマークされる。これはバイトコンパイルの警告を抑止するために有用。コンパイラーのエラーを参照のこと。
symbolがカレントバッファー内でバッファーローカルなバインディングをもつ場合、defvar
はデフォルト値に作用する。デフォルト値はバッファーローカルなバインディングではなく、バッファーにたいして独立である。デフォルト値がvoidのときはデフォルト値をセットする。バッファーローカル変数を参照のこと。
すでにsymbolがletバインドされている(たとえばlet
フォーム内にdefvar
がある)場合には、set-default-toplevel-value
と同じようにdefvar
はトップレベルの値をセットする。letバインディングの構文を抜けるまでバインディングの効果は持続する。変数のバインディングのスコーピングルールを参照のこと。
C-M-x (eval-defun
)、またはEmacs LispモードでC-x C-e
(eval-last-sexp
)によりトップレベルのdefvar
を評価する際には、これら2つのコマンドの特別な機能はその値がvoidであるかテストすることなく、その変数を無条件にセットする。
引数doc-stringが与えられたら、それは変数にたいするドキュメント文字列を指定する(そのシンボルのvariable-documentation
プロパティに格納される)。ドキュメントを参照のこと。
以下にいくつか例を示す。これはfoo
を定義するが初期化は行わない:
(defvar foo) ⇒ foo
以下の例はbar
の値を23
に初期化してドキュメント文字列を与える:
(defvar bar 23 "The normal weight of a bar.") ⇒ bar
defvar
フォームはsymbolをリターンするが、これは通常は値が問題にならないファイル内のトップレベルで使用される。
値をもたないdefvar
のより詳細な使用例はLocal defvar exampleを参照のこと。
このスペシャルフォームはある値で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
か否かだけが意味をもつような値。結局そのような変数は、やがては多くの値をもつことが多いので、この慣習を強く推奨はしない。
値はプログラム名。
値は完全なシェルコマンド。
値はコマンドにたいして指定するオプション。
これは内部的な使用を意図した変数でありファイルprefix.el内で定義される(他の規約にしたがうかもしれない2018年以前に貢献されたEmacsコードは段階的に廃止される)。
これは内部的な使用を意図した変数でありファイルCコード内で定義される(他の規約にしたがうかもしれない2018年以前に貢献されたEmacsコードは段階的に廃止される)。
変数を定義するときは、その変数を安全(safe)とマークすべきか、それとも危険(risky)とマークすべきかを常に考慮してください。ファイルローカル変数を参照してください。
複雑な値を保持する変数(バインディングをもつkeymapなど)の定義や初期化を行う場合は、以下のように値の計算をすべてdefvar
の中に配置するのが最良です:
(defvar my-mode-map (let ((map (make-sparse-keymap))) (keymap-set map "C-c C-a" 'my-command) … map) docstring)
この方法にはいくつかの利点があります。1つ目はファールをロード中にユーザーが中断した場合、変数はまだ初期化されていないか、初期化されているかのどちらかであり、その中間ということはありません。まだ初期化されていなければ、ファイルをリロードすれば正しく初期化されます。2つ目は一度初期化された変数は、ファイルをリロードしても変更されないことです。コンテンツの一部を変更(たとえばキーのリバインド)するフックをユーザーが実行した場合などに、これは重要です。3つ目はC-M-xでdefvar
を評価すると、そのマップは完全に再初期化されることです。
[ << ] | [ < ] | [ 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)
これはsetq
(上記参照)と似ているがユーザーオプションを意図したマクロであり、変数(複数可)のセットにCustomizeの仕組みを使用している(カスタマイゼーション変数の定義を参照)。特にsetopt
はその変数に割り当てられたset用の関数を実行する。たとえば以下のような場合に:
(defcustom my-var 1 "My var." :type 'number :set (lambda (var val) (set-default var val) (message "We set %s to %s" var val)))
ここで次を実行するとmy-var
に‘2’がセットされるとともに、メッセージも発行されるだろう:
(setopt my-var 2)
ユーザーオプションにたいしてsetopt
は値が妥当かどうかのチェックも行う。たとえばsetopt
でnumber
タイプと定義されたユーザーオプションに文字列をセットするとエラーがシグナルされるだろう。
defcustom
やcustomize-variable
のようなCustomize関連コマンドとは異なり、setopt
は非インタラクティブな使用、特にユーザーのinitファイルでの使用を意図している。この理由により値がstandard、saved、user-setのいずれなのかは記録せず、customファイルへの保存用に変数をマークすることも行わない。
setopt
マクロはユーザーオプションではない通常の変数にも使用できるが、setq
に比べると効率において遥かに劣る。このマクロのユースケースは、主にinitファイル内でのユーザーオプションのセットである。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
変数の値が変化したときに何らかのアクションを行えれば便利なときがあります。変数watchpoint(variable watchpoint)機能はそのための機能を提供します。この機能の有効な利用方法としては変数セッティングと表示の同期、変数への予期せぬ変更を追跡するためのデバッガの呼び出しが含まれます(変数の変更時にデバッガにエンターする。を参照)。
以下の関数は関数にたいするwatch関数の操作や問い合わせに使用できます。
この関数はsymbolが変化したときは常にwatch-functionが呼び出されるようにアレンジする。エイリアスを介した変更にも同じ効果をもつ(変数のエイリアスを参照)。
watch-functionはsymbolの値の変更直前にsymbol、newval、operation、whereという4つの引数で呼び出される。symbolは変更される変数、newvalは変更後の値(watch-functionではnewvalに変更される前なので古い値はsymbolの値で利用可能)、operationは変更の種類を表すシンボルでありset
、let
、unlet
、makunbound
、defvaralias
のいずれか。whereは変数のバッファーローカルな値が変更される場合にはバッファー、それ以外はnil
。
この関数はsymbolのwatcherリストからwatch-functionを削除する。
この関数はsymbolのアクティブなwatcher関数のリストをリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
watchpointをトリガーせずに変数が変更される(または少なくとも変更されたように見える)方法がいくつかあります。
watchpointはシンボルにアタッチされるので変数内に含まれるオブジェクトの変更(リスト変更関数による変更。既存のリスト構造の変更を参照のこと)はこのメカニズムにより検出されません。
さらにCのコードはwatchpointメカニズムをバイパスして変数の値を直接変更できます。
繰り返しになりますがこれはシンボルをターゲットとするので、この機能のマイナーな制限はダイナミックなスコープをもつ変数だけをウォッチできるということです。レキシカル変数への変更は変数スコープ内のコードを調べれば容易に発見できるので、これが問題をもたらすことは稀でしょう(結局のところいかなるコードからも変更され得るダイナミック変数とは異なる。変数のバインディングのスコーピングルールを参照のこと)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ある変数にたいするローカルバインディングを作成するとき、そのバインディングはプログラムの限られた一部だけに効果をもちます(ローカル変数を参照)。このセクションでは、これが正確には何を意味するかについて説明します。
ローカルバインディングはそれぞれ、個別にスコープ(scope: 範囲という意味)とエクステント(extent: これも範囲を意味する)をもちます。スコープはそのバインディングにアクセスできるのが、テキストのソースコードのどこ(where)であるかを示します。エクステントはプログラムの実行中に、そのバインディングが存在するのがいつ(when)であるかを示します。
デフォルトではEmacsが作成したローカルバインディングは、ダイナミックバインディング(dynamic
binding)です。このようなバインディングはダイナミックスコープ(dynamic
scope)をもち、それはプログラムの任意の範囲が、その変数バインディングにアクセスするかもしれないことを意味します。これはダイナミックエクステント(dynamic
extent)ももっています。これはそのバインディング構造(let
フォームのbodyなど)が実行される間だけ、そのバインディングが存続することを意味します。
Emacsはオプションでレキシカルバインディング(lexical binding)を作成することができます。レキシカルバインディングはレキシカルスコープ(lexical scope)をもち、これはその変数にたいするすべての参照が、バインディング構文内にテキスト的に配置されなければならないことを意味します10。レキシカルバインディングは不定エクステント(indefinite extent)ももっています。これはある状況下において、クロージャ(closures)と呼ばれるスペシャルオブジェクトにより、バインディング構造が実行を終えた後でさえも、存続し続けることを意味します。
Emacsでは長年に渡り(そして現在でも)ダイナミックバインディングがデフォルトでしたが、最近の動向としてはレキシカルバインディングをデフォルトにするという最終ゴールに向けて、レキシカルバインディングがますます多くの場所で使用される方向に進んでいます。
以降のサブセクションでは、ダイナミックバインディングとレキシカルバインディング、およびEmacs Lispプログラムでレキシカルバインディングを有効にする方法についてより詳細に説明します。
12.10.1 ダイナミックバインディング | Emacs内でのローカル変数にたいするデフォルトのバインディング。 | |
12.10.2 ダイナミックバインディングの正しい使用 | ダイナミックバインディングによる問題を回避する。 | |
12.10.3 レキシカルバインディング | ローカル変数にたいする他の種類のバインディング。 | |
12.10.4 レキシカルバインディングの使用 | レキシカルバインディングを有効にする方法。 | |
12.10.5 レキシカルバインディングへの変換 | 既存コードからレキシカルバインディングへの変換。 |
[ << ] | [ < ] | [ 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して値セルにそれを配置します。
ダイナミックバインディングを使用したコードのネイティブコンパイル時には、ネイティブコンパイラーはLisp固有の最適化を何も行わないことに注意してください。
[ << ] | [ < ] | [ 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 t)) (re-search-forward "abc")))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsのバージョン24.1からオプションの機能としてレキシカルバインディングが導入されました。わたしたちはこの機能の重要性が時とともに増加することを期待します。レキシカルバインディングは最適化の機会をより広げるので、この機能を使用するプログラムはおそらく将来のEmacsバージョンで高速に実行されるようになるでしょう。レキシカルバインディングは、バージョン26.1の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)が、ある変数のカレント値を得たいときは、最初にレキシカル環境内を探します。そこで変数が指定されていなければ、ダイナミック値が格納されるシンボルの値セルを探します。
(レキシカル環境は内部的には、通常はシンボルと値のペアーによるコンスセルをメンバーとするリストだが、一部のメンバーはコンスセルではなくシンボルでもよい。このリストにおけるシンボルは、そのシンボルの変数はローカルではダイナミックにバインドされているとみなすよう宣言されたレキシカル環境を意味している。このリストはフォームを評価するためのレキシカル環境を指定するために、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)) () (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についてを参照してください。
レキシカルバインディングは*scratch*バッファーで使用されるLisp
Interactionモード、および*ielm*バッファーで使用されるIELMモードでも有効であり、M-:
(eval-expression
)を通じた式の評価や、Emacsとemacsclient
(emacsclient Options in The GNU Emacs
Manualを参照)の--evalコマンドラインオプション(Action Arguments in The
GNU Emacs Manualを参照)を処理する際にも有効です。
レキシカルバインディングが有効な場合でも、特定の変数はダイナミックにバインドされたままです。これらはスペシャル変数(special
variable)と呼ばれます。defvar
、defcustom
、defconst
で定義されたすべての変数はスペシャル変数です(グローバル変数の定義を参照)。その他のすべての変数はレキシカルバインディングの対象になります。
値なしでdefvar
を使用することにより、他の場所ではレキシカルにバインドされている状態のまま、単一ファイルやファイルの一部だけで変数をダイナミックにバインドすることが可能になります。たとえば:
(let (_) (defvar x) ;x
へのletバインドはこのlet内ではダイナミック (let ((x -99)) ; これはx
のダイナミックバインド (defun get-dynamic-x () x))) (let ((x 'lexical)) ; これはx
のレキシカルバインド (defun get-lexical-x () x)) (let (_) (defvar x) (let ((x 'dynamic)) (list (get-lexical-x) (get-dynamic-x)))) ⇒ (lexical dynamic)
この関数はsymbolがスペシャル変数(つまり変数がdefvar
、defcustom
、defconst
による定義をもつ)なら非nil
をリターンする。、それ以外ならリターン値はnil
。
これは関数なので永続的にスペシャルな変数には非nil
をリターンできるが、カレントレキシカルスコープでのみスペシャルな変数では異なることに注意。
関数内の正式な引数としてのスペシャル変数の使用はサポートされていません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispプログラムをレキシカルバインディングに変換するのは簡単です。最初にEmacs
Lispソースファイルのヘッダー行でlexical-binding
をt
にして、ファイルローカル変数を追加します(ファイルローカル変数を参照)。次に意図せずレキシカルにバインドしてしまわないように、ダイナミックなバインドをもつ必要がある変数が変数定義をもつことを各変数ごとにチェックします。
どの変数が変数定義をもつ必要があるか見つけるシンプルな方法は、ソースファイルをバイトコンパイルすることです。バイトコンパイルを参照してください。let
フォームの外側で非スペシャル変数が使用されていれば、バイトコンパイラーはフリーな変数にたいする参照や割り当てについて警告するでしょう。非スペシャル変数がバインドされているがlet
フォーム内で使用されていなければ、バイトコンパイラーは使用されないレキシカル変数に関して警告するでしょう。バイトコンパイラーは、スペシャル変数を関数の引数として使用している場合も問題を警告します。
フリー変換にたいする参照や割り当てに関する警告は、通常はその変数をダイナミックスコープにすべきだという明解なサインなので、その変数を最初に使用する前に適切なdefvar
を追加する必要があります。
使用されない変数についての警告は、それが(実際には別の関数で使用されているので)ダイナミックスコープを意図した変数だという良いヒントかもしれませんが、その変数が実際に未使用であり、単に削除可能であることを示しているのかもしれません。そのために、あなたはこれがいずれのケースなのかを調べて、それにもとづいてdefvar
を追加するか、あるいはその変数を完全に削除する必要があります。削除が不可能、あるいは望ましくない場合(典型的にはそれが正規の引数であり、呼び出し側すべての変更が不可能だったり望ましくない場合)には、それが使用されないと判っている変数であることをコンパイラーに示すために、変数名の先頭にアンダースコアを追加することもできます。
警告: これは事前通知なしに変更あるいは消滅するかもしれない実験的な機能です。
バイトコンパイラーは別のEmacs
Lispファイル内ではスペシャルであるようなレキシカル変数についても警告するかもしれません。これはしばしばdefvar
宣言の欠落を示しています。これは便利ですが3つのステップを要する幾分特殊なチェックを行います:
EMACS_GENERATE_DYNVARS
に非空の文字列をセットして、対象となりそうなスペシャル変数宣言をもつすべてのファイルをバイトコンパイルする。これは通常は同一パッケージ、関連するパッケージ、Emacsサブシステム内のすべてのファイルが該当する。この処理によりコンパイル済みEmacs
Lispファイルそれぞれにたいして、名前が.dynvarsで終わるファイルが生成される。
EMACS_DYNVARS_FILE
にはステップ2で作成した集約済みファイルがセットされる。
以下はUnixシェル上でmake
を使用してバイトコンパイルしたら何が行われるかを示した例です:
$ rm *.elc # 再コンパイルを強制 $ EMACS_GENERATE_DYNVARS=1 make # .dynvarsを生成 $ cat *.dynvars > ~/my-dynvars # .dynvarsを結合 $ rm *.elc # 再コンパイルを強制 $ EMACS_DYNVARS_FILE=~/my-dynvars make # チェック実施
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
グローバルおよびローカルな変数バインディングは、いずれかの形式をほとんどのプログラミング言語で見つけることができます。しかしEmacsは1つのバッファーだけに適用されるバッファーローカル(buffer-local)なバインディング用に、普通には存在しない類の変数バインディングもサポートしています。ある変数にたいして異なるバッファーごとに別の値をもつのは、カスタマイズでの重要な手法です(変数は端末ごとにローカルなバインディングをもつこともできる。複数の端末を参照)。
12.11.1 バッファーローカル変数の概要 | イントロダクションと概念。 | |
12.11.2 バッファーローカルなバインディングの作成と削除 | ||
12.11.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引数を使用すると、必要に応じて自動でバッファーローカルになる。
pairsは変数と値のペアからなるリスト。このマクロはカレントバッファー内で変数それぞれにたいしてバッファーローカルなバインディングを作成して、それにバッファーローカルな値を与える。このマクロは各変数にたいしてmake-local-variable
の後にsetq
を呼び出すのと等価。変数はクォートされていないシンボルであること。
(setq-local var1 "value1" var2 "value2")
このコマンドは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のデフォルト値(バッファーローカル変数のデフォルト値を参照)をリターンする。
これはvariableがバッファーbufferでバッファーローカルにバインドされているか、あるいはグローバルにバインドされていれば非nil
をリターンする。
この関数はバッファー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(永続的)とマークされた変数、および非nil
のpermanent-local-hook
プロパティをもつローカルフック関数(フックのセットを参照)は除外されるが、オプションのkill-permanent引数が非nil
ならこれらの変数をもkillされる。
この関数はそのバッファーに関連する他の特定の情報もリセットする。これはローカルキーマップをnil
、構文テーブルを(standard-syntax-table)
の値、caseテーブルを(standard-case-table)
、abbrevテーブルをfundamental-mode-abbrev-table
の値にセットする。
この関数が一番最初に行うのはノーマルフックchange-major-mode-hook
(以下参照)の実行である。
すべてのメジャーモードコマンドはこの関数を呼び出すことによって開始され、これによりFundamentalモードにスイッチし、以前のメジャーモードの影響のほとんどを消去する効果があります。この関数が処理を行うのを確実にするために、メジャーモードがセットする変数はpermanentとマークすべきではない。
kill-all-local-variables
はnil
をreturnします。
関数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
は、boundp
がsymbol-value
に対応するように、default-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
ある変数に値をletバインドできます(ローカル変数を参照)。このバインディングにより変数のグローバル値はシャドーされます。default-value
はグローバル値ではなくそのバインディングの値をリターンして、set-default
によるグローバル値のセットは防がれます(かわりにletバインドされた値が変更される)。以下の2つの関数によりletバインドでグローバル値がシャドーされていてもグローバル値を参照できます。
この関数はsymbolにたいするすべてのletバインディングの外部の値としてトップレベルのデフォルト値をリターンする。
(defvar variable 'global-value) ⇒ variable
(let ((variable 'let-binding)) (default-value 'variable)) ⇒ let-binding
(let ((variable 'let-binding)) (default-toplevel-value 'variable)) ⇒ global-value
この関数はsymbolのトップレベルのデフォルト値に指定されたvalueをセットする。これはコードがsymbolのletバインディングのコンテキスト下で実行中かどうかとは無関係にsymbolのグローバル値をセットしたいときに便利。
[ << ] | [ < ] | [ 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
がnil
であっても、いくつかのローカル変数セッティングは、デフォルトでは注意する必要があるだろう。これはデフォルトにおいてローカル変数lexical-binding
のセッティングの場合だけだが、この変数(シンボルのリスト)を使用して制御できる。
この関数はカレントバッファーの内容により指定された任意のローカル変数にたいしてパースを行い、適切にバインドと評価を行う。変数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’要素を無視する。
オプションの引数handle-modeがt
なら、この関数が行うのはメジャーモードを指定するシンボルをリターンすることだけであり、‘-*-’行やローカル変数リストがメジャーモードを指定していればそのモード、それ以外はnil
をリターンする。この関数はモードや他のファイルローカル変数をセットしない。handle-modeの値がnil
とt
のいずれでもなければ‘-*-’行の‘mode’に関するすべてのセッティングとローカル変数リストは無視されて、別のセッティングが適用される。handle-modeが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
を使用します。
Cソースコード内で定義された変数にsafe-local-variable
プロパティを定義したければ、それらの変数の名前とプロパティをfiles.elのセクション“Safe
local variables”のリストに追加してください。
defcustom
を使用してユーザーオプションを定義する際には、defcustom
に引数:safe
function
を追加してsafe-local-variable
プロパティをセットできます(カスタマイゼーション変数の定義を参照)。しかし:safe
を使用して定義された安全性の述語は、そのdefcustom
を含むパッケージのロード時の一度だけ認識されるものであり、それでは遅すぎることがしばしばあります。代替策としては、以下のようにオプションに安全性の述語を割り当てるためにautoloadクッキー(autoloadを参照)を使用できます:
;;;###autoload (put 'var 'safe-local-variable 'pred)
autoload
で指定された安全な値の定義は、そのパッケージのautoloadファイル(Emacsに同梱されたパッケージのほとんどではloaddefs.el)にコピーされて、セッションの開始からEmacsにより認識されます。
この変数はある変数の値が安全であることをマークする、別の方法を提供する。これはコンスセル(var
. val)
のリストでありvarは変数名、valはその変数にたいして安全な値である。
Emacsが一連のファイルローカル変数にしたがうかどうかユーザーに尋ねるとき、ユーザーはそれらの変数が安全だとマークすることができる。安全とマークするとsafe-local-variable-values
にこれらのvariable/valueペアーが追加されて、ユーザーのカスタムファイルに保存する。
特定のローカル変数にたいして常に完全に無視したい値がいくつかある場合には、この変数を使用できる。値はsafe-local-variable-values
と同じ形式であり、ファイルが指定するローカル変数の処理時にこのリストに現れる値にセットされるファイルローカル変数は常に無視される。safe-local-variable-values
の場合のように、ファイルローカル変数にしたがうべきかEmacsがユーザーに尋ねる際に、ユーザーは特定の値を恒久的に無視することを選択でき、この選択によってこの変数は変更されてユーザーのcustomファイルに保存される。この変数にある変数/値ペアーは、safe-local-variable-values
内にある同一ペアーより優先される。
この関数は上記の条件に基づき、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.el11。ディレクトリー内でその名前をもつファイルによりEmacsはディレクトリー内の任意のファイル、または任意のサブディレクトリー(オプションでサブディレクトリーを除外できる。以下参照し)にセッティングを適用する。独自に.dir-locals.elをもつサブディレクトリーがある場合には、Emacsはサブディレクトリーで見つかったもっとも深いファイルのディレクトリーからディレクトリーツリーを上方に移動しながら、もっとも深いファイルのセッティングを使用する。この定数は2番目のdir-localsファイル.dir-locals-2.elの名前を導出するためにも使用される。この2番目のdir-localsファイルが与えられた場合には、そのファイルが.dir-locals.elに加えてロードされる。これは.dir-locals.elがバージョンコントロールの共有レポジトリの配下にあって個人のカスタマイズ用に使用できないときに有用。このファイルはローカル変数をフォーマットされたリストとして指定する。詳細は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] | [ ? ] |
接続ローカル変数(connection-local variable)はリモート接続をもつバッファーにおいて、異なる変数セッティングにたいする汎用のメカニズムを提供します(Remote Files in The GNU Emacs Manualを参照)。これはそのリモート接続に専用のバッファーに応じてバインドおよびセットされる変数です。
12.14.1 接続ローカルなプロファイル | 接続に適用する変数セッティングの保存。 | |
12.14.2 接続ローカル変数の適用 | コード内での接続ローカル変数の使用。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
接続ローカルプロファイルとは、特定の接続にたいして適用する変数のセッティングを保存するためにEmacsが使用するプロファイルのことです。connection-local-set-profiles
を使用してプロファイルを適用すべき条件を定義することで、プロファイルとリモート接続を関連付けることができます。
この関数は接続profile
(シンボル)にたいする一連の変数セッティングを定義する。この接続プロファイルに後から1つ以上のリモート接続を割り当てることができ、Emacsはそれらの接続にたいするすべてのプロセスバッファーにそれらの変数セッティングを適用するだろう。variables内のリストは(name . value)
という形式のalist。たとえば:
(connection-local-set-profile-variables 'remote-bash '((shell-file-name . "/bin/bash") (shell-command-switch . "-c") (shell-interactive-switch . "-i") (shell-login-switch . "-l")))
(connection-local-set-profile-variables 'remote-ksh '((shell-file-name . "/bin/ksh") (shell-command-switch . "-c") (shell-interactive-switch . "-i") (shell-login-switch . "-l")))
(connection-local-set-profile-variables 'remote-null-device '((null-device . "/dev/null")))
既存のプロファイルにたいして変数セッティングを追加したい場合には、以下のように関数connection-local-get-profile-variables
を使って既存のセッティングを取得できる
(connection-local-set-profile-variables 'remote-bash (append (connection-local-get-profile-variables 'remote-bash) '((shell-command-dont-erase-buffer . t))))
このalistは接続プロファイルシンボルと連想変数セッティングを保持する。これはconnection-local-set-profile-variables
により更新される。
この関数はcriteriaで識別されるすべてのリモート接続にprofiles
(シンボル)を割り当てる。criteriaは接続を識別するplistであり、アプリケーションはその接続を使用する。プロパティ名は:application
、:protocol
、:user
、:machine
のいずれか。:application
のプロパティ値はシンボル、それ以外のプロパティ値は文字列。プロパティはすべてオプション。criteriaがnil
なら常に適用される。たとえば:
(connection-local-set-profiles '(:application tramp :protocol "ssh" :machine "localhost") 'remote-bash 'remote-null-device)
(connection-local-set-profiles '(:application tramp :protocol "sudo" :user "root" :machine "localhost") 'remote-ksh 'remote-null-device)
criteriaがnil
ならすべてのリモート接続に適用される。したがって上記の例は以下と等価
(connection-local-set-profiles '(:application tramp :protocol "ssh" :machine "localhost") 'remote-bash)
(connection-local-set-profiles '(:application tramp :protocol "sudo" :user "root" :machine "localhost") 'remote-ksh)
(connection-local-set-profiles nil 'remote-null-device)
profilesのすべてのプロファイルはconnection-local-set-profile-variables
で定義済みでなければならない。
このalistは接続のcriteria(判断基準)それに割り当てられたとprofileの名前を含む。関数connection-local-set-profiles
はこのリストを更新する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
接続を認識するコードの記述時には接続ローカル変数を収集して、もしかしたらそれらを適用する必要があるでしょう。これを行うには以下のようにいくつかの方法があります。
この関数はconnection-local-variables-alist
内のcriteriaに関連する適用可能な接続ローカル変数を適用することなく収集する。たとえば:
(hack-connection-local-variables '(:application tramp :protocol "ssh" :machine "localhost"))
connection-local-variables-alist ⇒ ((null-device . "/dev/null") (shell-login-switch . "-l") (shell-interactive-switch . "-i") (shell-command-switch . "-c") (shell-file-name . "/bin/bash"))
この関数はcriteriaに対応する接続ローカル変数を探してカレントバッファーに即座に適用する。
default-directory
によって指定されるすべての接続ローカル変数をapplication
に適用する。
その後にbodyを実行して接続ローカル変数を非バインド化する。たとえば:
(connection-local-set-profile-variables 'my-remote-perl '((perl-command-name . "/usr/local/bin/perl5") (perl-command-switch . "-e %s")))
(connection-local-set-profiles '(:application my-app :protocol "ssh" :machine "remotehost") 'my-remote-perl)
(let ((default-directory "/ssh:remotehost:/working/dir/")) (with-connection-local-application-variables 'my-app do something useful))
with-connection-local-variables
が適用されるデフォルトのアプリケーション(シンボル)。デフォルトはtramp
だが、letバインドによって一時的にアプリケーションを変更できる(ローカル変数を参照)。
この変数をグローバルに変更してはならない。
これはwith-connection-local-application-variables
と同じだが、そのアプリケーションにたいしてconnection-local-default-application
を使用する。
このマクロはconnection-local-profile-name-for-setq
で指定された接続ローカルプロファイルを用いて、それぞれのsymbolを対応するformを評価した結果に接続ローカルでバインドする。接続ローカルプロファイルの名前がnil
の場合には、このマクロはsetq
が行うような通常の方法によって変数をセットする(変数の値のセットを参照)。
たとえば接続ローカルなセッティングの初期化を遅延させるには、このマクロを以下のようにwith-connection-local-variables
やwith-connection-local-application-variables
と組み合わせて使用する:
(defvar my-app-variable nil) (connection-local-set-profile-variables 'my-app-connection-default-profile '((my-app-variable . nil))) (connection-local-set-profiles '(:application my-app) 'my-app-connection-default-profile)
(defun my-app-get-variable () (with-connection-local-application-variables 'my-app (or my-app-variable (setq-connection-local my-app-variable do something useful))))
setq-connection-local
を通じて変数をセットする際に使用する接続ローカルプロファイル名(シンボル)。これはwith-connection-local-variables
のbody内でletバインドされているが、別のプロファイルで変数をセットしたければ自分でletバインドすることもできる。
この変数をグローバルに変更してはならない。
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)
このマクロはすべてのパラメーターを評価する。obsolete-nameとcurrent-nameはいずれもシンボルのはずなので、通常は以下のような使用方法になる:
(define-obsolete-variable-alias 'foo-thing 'bar-thing "27.1")
この関数は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
formはsetf
マクロ(setf
マクロを参照)を使用して値が格納される、Lispメモリー内の多くの場所のうちの1つです。一番シンプルなplace
formは通常のLisp変数です。しかしリストのCARとCDR、配列の要素、シンボルのプロパティ、その他多くのロケーション(location)もLisp値が格納される場所です。
ジェネリック変数は、C言語のlvalues(左辺値)と類似しています。C言語のlvalueでは‘x =
a[i]’で配列から要素を取得し、同じ表記を使用して‘a[i] =
x’で要素を格納します。Cではa[i]
のような特定のフォームがlvalueになれるように、Lispでジェネリック変数になることができる一連のフォームが存在します。
12.17.1 setf マクロ | ||
12.17.2 新たなsetf フォーム | 新たなsetf フォームの定義。
|
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
setf
マクロsetf
マクロはジェネリック変数を操作するもっとも基本的な方法です。setf
フォームはsetq
と似ていますが、シンボルだけでなくそれぞれのペアーの1つ目(左)の任意のplace
formを受け入れます。たとえば(setf (car a)
b)
はa
のcarをb
にセットして(setcar a
b)
と同じ操作を行いますが、このタイプのplaceにセットやアクセスするために2つの関数を個別に覚える必要はありません。
このマクロはformを評価して、その値をplaceに格納する。placeは有効なジェネリック変数フォームでなければならない。複数のplace/formペアーがある場合の割り当てについてはsetq
の場合と同様。setf
は最後のformの値をリターンする。
以下のLispフォームはEmacsではジェネリック変数として機能するフォームなので、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 overlay-start default-value overlay-get face-background process-buffer face-font process-filter face-foreground process-get face-stipple process-sentinel face-underline-p terminal-parameter file-modes window-buffer frame-parameter window-dedicated-p frame-parameters window-display-table get-register window-hscroll getenv window-parameter keymap-parent window-point match-data window-start overlay-end
(substring subplace n
[m])
という形式の呼び出し。ここでsubplaceはそれ自体がカレント値として文字列をもち、それに格納される値も文字列であるような有効なジェネリック変数。新たな文字列は目的となる文字列の指定した箇所につなぎ合わされる。たとえば:
(setq a (list "hello" "world")) ⇒ ("hello" "world") (cadr a) ⇒ "world" (substring (cadr a) 2 4) ⇒ "rl" (setf (substring (cadr a) 2 4) "o") ⇒ "o" (cadr a) ⇒ "wood" a ⇒ ("hello" "wood")
if
やcond
というコンディションも機能する。たとえば以下はfoo
かbar
いずれかの変数をzot
にセットする例:
(setf (if (zerop (random 2)) foo bar) 'zot)
どのように処理すれば良いか未知な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内に格納されたリストの一番前に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
マクロが使用できる。たとえばセット可能なsubstring
は以下の方法で実装できる:
(gv-define-expander substring (lambda (do place from &optional to) (gv-letplace (getter setter) place (macroexp-let2* (from to) (funcall do `(substring ,getter ,from ,to) (lambda (v) (macroexp-let2* (v) `(progn ,(funcall setter `(cl--set-substring ,getter ,from ,to ,v)) ,v))))))))
マクロgv-letplace
はsetf
のような処理を行うマクロを定義するのに有用。たとえばCommon
Lispのincf
マクロは以下の方法で実装できる:
(defmacro incf (place &optional n) (gv-letplace (getter setter) place (macroexp-let2* ((v (or n 1))) (funcall setter `(+ ,v ,getter)))))
getterはplaceの値をリターンするコピー可能な式にバインドされる。setterは式vを受け取り、placeにvをセットする新たな式をリターンする関数にセットされる。bodyはgetterとsetterを介してplaceを操作するEmacs Lisp式をリターンすること。
詳細はgv.elのソースファイルを参照。
この関数はバイトコンパイラーにジェネリック変数obsolete-nameが陳腐化していると警告させる。current-nameがシンボルなら、obsolete-nameのかわりにcurrent-nameを使用するよう告げるメッセージにより警告が行われる。current-nameが文字列なら、それはメッセージであること。whenはその変数が最初に陳腐化するのがいつかを示す文字列(通常はバージョン番号文字列)。
Common Lispに関する注意: Common Lispは関数としての
setf
、すなわち関数名がシンボルではなくリスト(setf name)
であるようなsetf
関数の挙動を指定するために別の方法を定義する。たとえば(defun (setf foo) …)
は、setf
がfoo
に適用されるときに使用される関数を定義する。Emacsはこれをサポートしない。適切な展開が定義されていないフォームにsetf
を使用するとコンパイル時エラーとなる。Common Lispでは後で関数(setf func)
が定義されるのでエラーにならない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ある変数に値をセットしてからEmacsを終了すると、その後に再起動してもその値が自動的に復元されることはありません。ユーザーが値を永続的にセットする場合には、通常の変数であればスタートアップファイル、ユーザーオプションであればCustomize(カスタマイゼーション設定を参照)を用いるのが普通です。更にデータを格納するためにさまざまなファイルをもつパッケージが沢山あります(例: Gnusはデータを.newsrc.eld、URLライブラリーはcookieを~/.emacs.d/url/cookiesに格納する)。
これらの2つの対極的な事項(スタートアップファイルに書き込まれる構成、あるいは大規模なアプリケーションが個別のファイルへ書き込む状態)にたいして、Emacsはセッションに跨がるデータを複製(replicate)するためのマルチセッション変数(multisession variables)と呼ばれる機能を提供しています(この機能はすべてのシステムで利用できる訳ではない)。これらがどのような利用を意図しているかヒントを与えるために、以下に小さな例を示しましょう:
(define-multisession-variable foo-var 0) (defun my-adder (num) (interactive "nAdd number: ") (setf (multisession-value foo) (+ (multisession-value foo) num)) (message "The new number is: %s" (multisession-value foo)))
これは変数foo-var
を定義して、(この変数が以前のセッション以降に存在していなければ)値‘0’に初期化された特別なマルチセッションオブジェクトにバインドしています。my-adder
コマンドはユーザーに数値の入力を求めて、それを(もしかしたら保存されていた)古い値に加算してから新しい値へと保存します。
この機能は巨大なデータ構造にたいする使用を意図したものではありませんが、ほとんどの値にたいしてパフォーマンスは高いはずです。
このマクロはマルチセッション変数としてnameを定義して、その変数に以前に値が割り当てられていなければinitial-valueを与える。docはdoc文字列、argsにはいくつかのキーワード引数を使用できる:
:package package-symbol
マルチセッション変数がpackage-symbolで指定されたパッケージに属することを告げるキーワード。package-symbolとnameは一意な組み合わせであること。package-symbolが与えられない場合には、nameのシンボル名の1つ目の“セグメント”(シンボル名の最初の‘-’の手前までの部分)がデフォルトになる。たとえばnameがfoo-var
でpackage-symbolを与えなければ、package-symbolのデフォルトはfoo
。
:synchronized bool
boolが非nil
であればマルチセッション変数を同期(synchronized)できる。同時に2つのEmacsインスタンスが実行中に、別のEmacsがマルチセッション変数foo-var
を変更すると、カレントのEmacsインスタンスがその値にアクセスした際には変更済みのデータが取得されることを意味する。これはsynchronizedがnil
あるいは未指定の場合には発生せず、この変数を使用するすべてのEmacsセッションそれぞれにたいして独立した値となる。
:storage storage
storageで指定されたメソッドを使用する。sqlite
(SQLiteサポートつきでコンパイルされたEmacsの場合)、あるいはfiles
のいずれか。与えられない場合には、後述のmultisession-storage
変数の値がデフォルトになる。
この関数はvariableのカレント値をリターンする。そのEmacsセッションにおいて変数にこれまでアクセスしていない、あるいは変数が外部から変更されていた場合には外部ストレージから読み込まれる。それ以外の場合にはそのセッションでのカレント値がそのままリターンされる。マルチセッション変数ではないvariableにたいしてこの関数を呼び出すとエラーとなる。
multisession-value
を通じて取得した値は互いにeq
のときもあれば異なるときもあるが、常にequal
である。
これはジェネリック化された変数(ジェネリック変数を参照)なので、そのような変数はたとえば以下のような方法によって更新される:
(setf (multisession-value foo-bar) 'zot)
この方法によって保存できるのは読み取り可能なプリント構文(プリント表現と読み取り構文を参照)をもつEmacs Lisp値のみ。
そのマルチセッション変数が同期化されている場合にセットすると、最初に値が更新されるかもしれない。たとえば:
(cl-incf (multisession-value foo-bar))
ここではまず別のEmacsセッションによって値が変更されているかどうかをチェックして、その後に値に1を加算して格納している。これはロックなしでおこなわれために、多くのセッションが同時に値を変更する場合にどのセッションが“勝利”するか予想できないことに注意。
この関数はobjectとその値を永続化されたストレージから削除する。
特定の変数ではなく明示的なパッケージとキーに結びつけられらた永続的な値を作成することもできる。
(setq foo (make-multisession :package "mail" :key "friends")) (setf (multisession-value foo) 'everybody)
この関数はdefine-multisession-variable
と同じキーワードに加えて、:initial-value
キーワード(デフォルト値を指定する)もサポートする。
この変数はマルチセッション変数をどのように格納するかを制御する。デフォルト値のfiles
はmultisession-directory
で指定されたディレクトリー内に変数1つにたいしてファイル1つという構造で値が格納されることを意味する。これがsqlite
なら値はSQLiteデータベースに格納される(SQLiteサポートつきでビルドされたEmacsでのみ利用可能)。
このディレクトリー配下にマルチセッション変数は格納される。デフォルトはuser-emacs-directory
のサブディレクトリーmultisession/
(通常なら~/.emacs.d/multisession/)。
このコマンドはすべてのマルチセッション変数をリストするバッファーをポップアップして、それらの値の削除や編集が行える特別なモードmultisession-edit-mode
にエンターする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispプログラムは主にLisp関数で構成されます。このチャプターはで関数とは何か、引数を受け取る方法、そして関数を定義する方法を説明します。
13.1 関数とは? | Lisp関数 vs. プリミティブ。専門用語。 | |
13.2 ラムダ式 | 関数がLispオブジェクトとして表現される方法。 | |
13.3 関数の命名 | シンボルは関数を命名できる。 | |
13.4 関数の定義 | 関数定義のためのLisp式。 | |
13.5 関数の呼び出し | 既存の関数を使う方法。 | |
13.6 関数のマッピング | リストの各要素などに関数を適用する。 | |
13.7 無名関数 | ラムダ式、それは無名の関数。 | |
13.8 ジェネリック関数 | Emacsスタイルのポリモーフィズム。 | |
13.9 関数セルの内容へのアクセス | シンボルの関数定義へのアクセスとセット。 | |
13.10 クロージャ | レキシカル環境に囲まれた関数。 | |
13.11 オープンクロージャ | Function objects with meta-data. | |
13.12 Emacs Lisp関数にたいするアドバイス | 関数の定義への追加。 | |
13.13 関数の陳腐化の宣言 | 関数を陳腐と宣言する。 | |
13.14 インライン関数Inli | コンパイラーによりインライン展開される関数。 | |
13.15 declare フォーム | 関数についての補足的な情報の追加。 | |
13.16 コンパイラーへの定義済み関数の指示 | 関数が定義されていることをコンパイラーに知らせる。 | |
13.17 安全に関数を呼び出せるかどうかの判断 | 呼び出しても安全な関数なのか判断する。 | |
13.18 関数に関するその他トピック | 関数が動作する方法において特別な意味をもつ、特定のLispプリミティブのクロスリファレンス。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
一般的な意味では関数とは引数(arguments)と呼ばれる与えられた入力値の計算を担うルールです。計算の結果は関数の値(value)、またはreturn値(return value)と呼ばれます。計算は変数の値やデータ構造の内容を変更する等の副作用をもつこともできます(Definition of side effectを参照)。純粋関数(pure function)とは、それらに加えて副作用をもたず、機種別やシステム状態のような外部要因とは無関係に同じ条件の引数にたいして常に同一の値をリターンする関数のことです。
ほとんどのコンピューター言語では、関数はそれぞれ名前をもちます。しかし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
を通じて呼び出すことができるオブジェクトで、通常はそのコマンドにバインドされたキーシーケンスをユーザーがタイプすることにより呼び出される。インタラクティブな呼び出しを参照のこと。コマンドは通常は関数である。その関数がLispで記述されていれば、関数の定義内のinteractive
フォームによってコマンドとなる(コマンドの定義を参照)。関数であるコマンドは他の関数と同様、Lisp式から呼び出すこともできる。
キーボードマクロ(文字列かベクター)は関数ではないが、これらもコマンドである。キーボードマクロを参照のこと。シンボルの関数セルにコマンドが含まれてれば、わたしたちはそのシンボルをコマンドと言う(シンボルの構成要素を参照)。そのような名前つきコマンド(named command)はM-xで呼び出すことができる。
ラムダ式とよく似た関数オブジェクトだが、クロージャはレキシカル変数バインディングの環境にも囲われている。クロージャを参照のこと。
バイトコンパイラーによりコンパイル済みの関数。バイトコード関数型を参照のこと。
実際の関数のプレースホルダー。autoloadオブジェクトが呼び出されると、Emacsは実際の関数の定義を含むファイルをロードした後に実際の関数を呼び出す。autoloadを参照のこと。
関数functionp
を使用して、あるオブジェクトが関数かどうかテストできます:
この関数はobjectが任意の種類の関数(funcall
に渡すことができる)ならt
をリターンする。functionp
は関数を名づけるシンボルにたいしてはt
、マクロやスペシャルフォームにたいしてはnil
をリターンすることに注意。
objectは関数でなければ、この関数は通常はnil
をリターンする。ただし関数オブジェクトの表現は複雑なので、効率上の理由によりobjectがたとえ関数でなくてもこの関数がt
をリターンするときが稀にある。
任意の関数が期待する引数の個数を調べることもできます:
この関数は指定されたfunctionの引数リストに関する情報を提供する。リターン値は(min . max)
という形式のコンスセル。ここでminは引数の最小個数、maxは引数の最大個数、または&rest
引数をもつ関数ではmany
、functionがスペシャルフォームならシンボルunevalled
。
以下のようにある状況下ではこの関数は不正確な結果をリターンすることに注意:
apply-partially
を使用して定義された関数(apply-partiallyを参照)。
advice-add
を使用して定義された関数(名前つき関数にたいするアドバイスを参照)。
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
この関数はobjectがELispソースコード形式ではなくても、何らかのマシンコードやバイトコードならt
をリターンする。より正しくは、ビルドイン関数(別名“プリミティブ(primitive)”。関数とは?を参照)、バイトコンパイル済み関数(バイトコンパイルを参照)、ネイティブコンパイル済み関数(Lispからネイティブコードへのコンパイルを参照)、またはダイナミックモジュールからロードされた関数(Emacsのダイナミックモジュールを参照)の場合にt
をリターンする。
これはfunc-arity
と同様だがシンボルインダイレクションなしのビルトイン関数にたいしてのみ機能する。非ビルトイン関数にたいしてはエラーをシグナルする。かわりにfunc-arity
の使用を推奨する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ラムダ式(lambda expression)はLispで記述された関数オブジェクトです。以下は例です:
(lambda (x) "Xの双曲線コサインをreturnする" (* 0.5 (+ (exp x) (exp (- x)))))
Emacs Lispではこのようなリストは、関数オブジェクトに評価される有効な式です。
ラムダ式自身は名前をもたない無名関数(anonymous function)です。ラムダ式をこの方法で使用できますが(無名関数を参照)、名前付き関数(named functions)を作成するためにシンボルに関連付けられる方が一般的です(関数の命名を参照)。これらの詳細に触れる前に以下のサブセクションではラムダ式の構成要素と、それらが行うことについて説明します。
13.2.1 ラムダ式の構成要素 | ラムダ式のパーツ。 | |
13.2.2 単純なラムダ式の例 | シンプルな例。 | |
13.2.3 引数リストの機能 | 引数リストの詳細と特別な機能。 | |
13.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
、d
、e
はnil
になります。2つまたは3つの引数の場合にはd
とe
はnil
です。引数が4つ以下の場合には、e
はnil
になります。正確に5つの引数に明示的にnil
が指定された場合には、e
にたいして他の単一値が与えられたときのように、引数のnil
が1要素のリスト(nil)
としてe
に与えられます。
オプションの引数の後ろに必須の引数を指定する方法はありません —
これは意味を成さないからです。なぜそうなるかは、この例で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の移動コマンドが混乱するのを避けるために使用する)。この方法で指定された呼び出し規約は、ヘルプメッセージ内で関数の実引数から生成される呼び出し例と同じ場所に表示されます。
マクロ定義内に記述された引数は、ユーザーがマクロ呼び出しの一部だと考える方法とは合致しない場合がしばしばあるので、この機能はマクロ定義で特に有用です。
呼び出し規約を廃止して上記の仕様で示す規約を公開したければ、この機能を使用してはなりません。かわりに廃止された呼び出し規約を使用するLispプログラムのバイトコンパイル時に警告メッセージを発する宣言advertised-calling-convention
(declare
フォームを参照)かset-advertised-calling-convention
(関数の陳腐化の宣言を参照)を使用してください。
ドキュメント文字列は通常だと静的ですが、動的な生成を要するときもあるかもしれません。コンパイル時にドキュメント文字列と一緒に関数コードを生成するマクロを記述することでこれを達成できる場合もあります。しかしドキュメント文字列のかわりに(:documentation
form)
を記述することで、doc文字列を動的に生成することもできます。これは実行時に関数が定義されるとformを評価して、それをドキュメント文字列として使用します12。関数のシンボルのfunction-documentation
プロパティに文字列に評価されるLispフォームをセットすれば、オンザフライでドキュメント文字列を算出することもできます。
たとえば:
(defun adder (x) (lambda (y) (:documentation (format "Add %S to the argument Y." x)) (+ x y))) (defalias 'adder5 (adder 5)) (documentation 'adder5) ⇒ "Add 5 to the argument Y."
(put 'adder5 'function-documentation '(concat (documentation (symbol-function 'adder5) 'raw) " Consulted at " (format-time-string "%H:%M:%S"))) (documentation 'adder5) ⇒ "Add 5 to the argument Y. Consulted at 15:52:13" (documentation 'adder5) ⇒ "Add 5 to the argument Y. Consulted at 15:52:18"
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
シンボルは関数の名前となることができます。これはそのシンボルの関数セル(function cell: シンボルの構成要素を参照)が、関数オブジェクト(たとえばラムダ式)を含むときに起こります。するとそのシンボル自身が呼び出し可能な有効な関数、つまりそのシンボルの関数セルの関数と等価になります。
関数セルの内容はそのシンボルの関数定義(function definition)と呼ぶこともできます。そのシンボルのかわりにシンボルの関数定義を使う手続きのことをシンボル関数インダイレクション(symbol function indirection)と呼びます。シンボル関数インダイレクションを参照。与えられたシンボルに関数定義がなければシンボルの関数セルはvoidと呼ばれ、それを関数として使用することはできません。
実際のところほとんどすべての関数は名前をもち、その名前により参照されます。ラムダ式を定義することで名前つきのLisp関数を作成、それを関数セル(関数セルの内容へのアクセスを参照)に置くことができます。しかしより一般的なのはdefun
マクロ(次のセクションで説明)を使う方法です。
関数の定義を参照してください。
わたしたちが関数に名前を与えるのは、Lisp式内で関数を名前で参照するのが便利だからです。また名前つきの関数は簡単に自分自身を — 再帰的(recursive)に参照することができます。さらにプリミティブはテキスト的な名前だけで参照することができます。なぜならプリミティブ関数は入力構文(read syntax)をもたないオブジェクトだからです(プリミティブ関数型を参照)。
関数が一意な名前をもつ必要はありません。与えられた関数オブジェクトは通常は1つのシンボルの関数セルだけに存在しますが、これは単に慣習的なものです。fset
を使用すれば関数を複数のシンボルに格納するのは簡単です。それらのシンボルはそれぞれ、同じ関数にたいする有効な名前となります。
関数として使用しているシンボルを、変数としても利用できることに注意してください。シンボルのこれら2つの利用法は独立しており、競合はしません(これはSchemaのような他のいくつかのLisp方言には当てはまらない)。
慣例により関数のシンボルが‘--’で分割される2つの名前で構成される場合には、その関数は内部的な使用を意図しており、名前の最初の部分は関数を定義するファイルです。たとえばvc-git--rev-parse
という名前の関数はvc-git.elで定義される内部関数です。Cで記述された内部関数はbury-buffer-internal
のように名前が‘-internal’で終わります。2018年より前に貢献されたEmacsコードは内部的な使用にたいして別の命名規約を使用するかもしれませんが、これらは徐々に廃止されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
わたしたちは通常は関数を最初に作成したときに名前を与えます。これは関数の定義(defining a
function)と呼ばれており、通常はdefun
マクロにより行われます。このセクションでは関数を定義する別の方法も説明します。
defun
は新たなLisp関数を定義する通常の方法である。これは引数リストargs、およびbodyにより与えられるbodyフォームとともに、シンボルnameを関数として定義する(引数リストの機能を参照)。nameとargsをクォートする必要はない。
docが与えられたら、それはその関数のドキュメント文字列を指定する文字列であること(関数のドキュメント文字列を参照)。declareが与えられたら、それは関数のメタデータを指定するdeclare
フォームであること(declare
フォームを参照)。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))
Emacsの関数のほとんどはLispプログラムのソースコードの一部であり、実行前にEmacs
Lispリーダーがプログラムソースを読み込んだ際に定義される。しかし実行時にダイナミックに関数を定義することもできる(プログラムのコード実行時にdefun
呼び出しを生成する)。関数の定義にジャンプするボタンを*Help*バッファーに表示するC-h
fのようなEmacsのヘルプコマンドが、ソースコードを発見できないかもしれないので、これを行う際には注意を要する。なぜなら関数のダイナミックな生成は、defun
にたいする通常の静的な呼び出しと比べて普通は非常に異なって見えるからである。このような関数を生成するコードを見つける作業を容易にするためにdefinition-name
プロパティを用いることができる。シンボルの標準的なプロパティを参照のこと。
意図せず既存の関数を再定義しないように注意されたい。defun
はcar
のようなプリミティブ関数でさえ、問い合わせせずに躊躇なく再定義する。Emacsがこれを妨げることはない。なぜなら関数の再定義は故意に行われることがあり、そのような意図した再定義を、意図しない再定義と見分ける方法はがないからである。
この関数は定義がdefinitionであるような関数としてシンボルnameを定義する。definitionには有効な任意のLisp関数、マクロ、スペシャルフォーム(スペシャルフォームを参照)、キーマップ(キーマップを参照)、ベクター、文字列(キーボードマクロ)を指定できる。defalias
のリターン値は未定義。
docが非nil
なら、それは関数nameのドキュメントとなる。それ以外ならdefinitionにより提供されるドキュメントが使用される。
内部的にはdefalias
は、通常は定義のセットにfset
を使用する。しかしnameがdefalias-fset-function
プロパティをもつなら、fset
を呼び出すかわりにそれに割り当てられた値を使用する。
defalias
を使う正しい場所は、特定の関数やマクロの名前が正に定義される場所 —
特にソースファイルがロードされるときに明示的にその名前が出現する場所である。これはdefalias
がdefun
と同じように、どれが関数を定義するファイルなのか記録するからである(アンロードを参照)。
それとは対象的に他の目的のために関数を操作するプログラムでは、そのような記録を保持しないfset
を使用するほうがよいだろう。関数セルの内容へのアクセスを参照のこと。
objectが関数のエイリアス(alias: 別名)かどうかをチェックする。エイリアスならその関数のエイリアスのチェーン(chain:
連鎖)を表すシンボルのリスト、エイリアスでなければnil
をリターンする。たとえばa
がb
のエイリアスで、b
がc
のエイリアスなら:
(function-alias-p 'a) ⇒ (b c)
定義中にループがあるとエラーをシグナルする。noerrorが非nil
の場合には、ループしていないチェーン部分をリターンする。
defun
やdefalias
で新たなプリミティブ関数を作成することはできませんが、任意の関数定義を変更するのに使用することができ、通常の定義がプリミティブであるcar
やx-popup-menu
のような関数でさえ変更することができます。しかしこれは危険なことです。たとえばLispの完全性を損なうことなく、car
を再定義するのはほとんど不可能だからです。それほど有名ではないx-popup-menu
のような関数の再定義では、危険は減少しますが、それでも期待したとおりに機能しないかもしれません。Cコードにそのプリミティブの呼び出しがあれば、それは直接そのプリミティブのC定義を呼び出すので、シンボル定義を変更してもそれらに影響はありません。
defsubst
も参照してください。これはdefun
のように関数を定義して、それのインライン展開を処理するようLispコンパイラーに指示します。インライン関数Inliを参照してください。
関数名を未定義にするにはfmakunbound
を使用します。関数セルの内容へのアクセスを参照してください。
[ << ] | [ < ] | [ 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
を使用すること(インタラクティブな呼び出しを参照)。
(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
は特別である。引数(非空のリスト)の最初の要素は、残りの要素を個別の引数に関数として呼び出される。2つ以上の引数を渡すほうが早くなるだろう。
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 '(+ 3 4)) ⇒ 7
apply
を使用した興味深い例はDefinition of mapcarを参照のこと。
ある関数にたいして、その関数のある引数を特定の値に固定して、他の引数は実際に呼びだされたときの値にできれば便利なことがあります。関数のいくつかの引数を固定することは、その関数の部分適用(partial application)と呼ばれます13。これの結果は残りの引数をとる新たな関数で、すべての引数を合わせて元の関数を呼び出します。
Emacs Lispで部分適用を行う方法を示します:
この関数は新たな関数をリターンする。この新しい関数は呼びだされたときにargs、および呼び出し時に指定された追加の引数から成る引数リストでfuncを呼び出す関数である。funcにn個の引数を指定できる場合、m < n
個の引数でapply-partially
を呼び出すと、n - m
個の新たな関数を生成する14。
以下はビルトイン関数1+
が存在しないものとして、apply-partially
と他のビルトイン関数+
を使用して1+
を定義する例である15:
(defalias '1+ (apply-partially '+ 1) "Increment argument by one.")
(1+ 10) ⇒ 11
引数として関数を受け取ったり、データ構造(特にフック変数やプロパティリスト)から関数を探す関数はLispでは一般的で、それらはfuncall
やapply
を使用してそれらの関数を呼び出します。引数として関数をとる関数は、ファンクショナル(functional)と呼ばれるときもあります。
ファンクショナルを呼び出すとき、引数としてno-op関数(何も行わない関数)を指定できると便利なときがあります。以下に2つの異なるno-op関数を示します:
この関数はargumentをリターンする。副作用はない。
この関数はすべてのargumentsを無視してnil
をリターンする。
この関数はすべてのargumentsを無視してt
をリターンする。
関数のいくつかはユーザーに可視なコマンドで、これらは(通常はキーシーケンスを介して)対話的に呼び出すことができます。そのようなコマンドは、call-interactively
関数を使用することにより、対話的に呼びだされたときと同様に呼び出すことができます。インタラクティブな呼び出しを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マップ関数(mapping
function)は与えられた関数(スペシャルフォームやマクロではない)をリストや他のコレクションの各要素に適用します。Emacs
Lispにはそのような関数がいくつかあります。このセクションではリストにたいしてマッピングを行うmapcar
、mapc
、mapconcat
、mapcan
を説明します。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))
この関数はmapcar
のようにsequenceの各要素にfunctionを適用するが、結果をリストに収集するかわりに結果を変更(nconc
を使用。see リストを再配置する関数を参照)して結果のすべての要素を単一のリストでリターンする。mapcar
と同様にsequenceには文字テーブルを除く任意のタイプのシーケンスを指定できる。
;; 以下と: (mapcar #'list '(a b c d)) ⇒ ((a) (b) (c) (d)) ;; 以下を比較してみよ: (mapcan #'list '(a b c d)) ⇒ (a b c d)
mapc
はmapcar
と似ているが、functionは副作用のためだけに使用される —
つまりfunctionがリターンする値は無視されてリストに収集されない。mapc
は常にsequenceをリターンする。
mapconcat
はsequenceのそれぞれの要素にfunctionを適用する。結果は文字のシーケンス(文字列、ベクター、リスト)でなければならず、単一の文字列に結合されてリターン値となる。mapconcat
は結果シーケーンスの各ペアの間にseparatorの文字を挿入する。これも文字列、または文字のベクターかリストでなければならない。nil
値は空文字列として扱われる。シーケンス、配列、ベクターを参照のこと。
引数functionは1つの引数を受け取り文字のシーケンス、すなわち文字列、ベクター、リストのいずれかをリターンする。引数sequenceは文字テーブル以外の任意の種類のシーケンス、すなわちリスト、ベクター、ブールベクター、または文字列を指定できる。
(mapconcat #'symbol-name '(The cat in the hat) " ") ⇒ "The cat in the hat"
(mapconcat (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-objectがシンボルかつバイトコンパイル済みコードの場合には、その関数が未定義、あるいは実行時に認識されていなければバイトコンパイラーは警告を発する。
入力構文#'
は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-type
引数はcl-defstruct
(Structures in Common Lisp Extensions for
GNU Emacs
Lispを参照)で定義されたstruct-typeという名前のクラス、またはその子クラスのインスタンスでなければならない。
メソッド定義は新たな引数リストのキーワード&context
を使用できる。これはメソッド実行時に環境をテストする余分なスペシャライザーを導入する。このキーワードは必須の引数リストの後、かつすべての&rest
と&optional
キーワードの前に記述すること。&context
スペシャライザーは正規の引数スペシャライザー(expr
spec)と非常によく似ているが、exprはカレントコンテキストで評価される式であり、specは比較対象となる値となる。たとえば&context
(overwrite-mode (eql
t))
は、メソッドをoverwrite-mode
がオンのとだけ適用可能にする。&context
キーワードの後には任意個数のコンテキストスペシャライザーを続けることができる。コンテキストスペシャライザーはジェネリック関数の引数signatureの一部ではないので、これらを必要としないメソッドでは省略できる。
型スペシャライザー(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
として表されるオプション要素extraによって、同一のspecializerとqualifierにたいして、stringで区別されるメソッドを追加できる。
オプションのqualifierは複数の適用可能なメソッドの合成を許容する。与えられなければ定義されるメソッドはprimary(主)メソッドとなり、スペシャライズされた引数にたいする主要な実装の提供に責任を有する。qualifierとして以下の値のいずれかを使用してauxiliary(副)メソッドも定義できる:
:before
このauxiliaryメソッドはprimaryメソッドの前に実行される。より正確にはすべての:before
メソッドは、より特化したメソッドが最初になる順で、primaryメソッドの前に実行される。
:after
このauxiliaryメソッドはprimaryメソッドの後に実行される。より正確にはすべてのこの類のメソッドは、より特化したメソッドが最後になる順で、primaryメソッドの後に実行される。
:around
このauxiliaryメソッドはprimaryメソッドの代替えとして実行される。この類のメソッドでもっとも特化したものが他のメソッドより前に実行される。このようなメソッドは他のauxiliaryメソッドやprimaryメソッドを呼び出すために、通常は以下で説明するcl-call-next-method
を使用する。
cl-defmethod
を使用して定義した関数をインタラクティブにすることはできない。つまりinteractive
フォームを追加してコマンドにすることはできない(コマンドの定義を参照)。多相型コマンド(polymorphic
command)が必要なら、cl-defgeneric
とcl-defmethod
を通じて定義した多相型関数(polymorphic
function)を呼び出す通常のコマンドを定義することを推奨する。
ジェネリック関数が呼び出されると、毎回その関数にたいして定義された適用可能なメソッドを合成することによってその呼び出しを処理する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
は有効な関数足り得る)。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] | [ ? ] |
関数とは伝統的には呼び出し以外の機能を提供しない不透明なオブジェクトです。(Emacs Lisp関数はdoc文字列や引数リスト、interactive仕様のようないくつかの情報を抽出できるので完全に不透明という訳ではないが、そのほとんどは依然として不透明である)。これはわたしたちの要望を通常は満たしていますが、関数自体に関する情報をもう少し公開する必要がある場合もあるでしょう。
オープンクロージャ(Open closure)、略してOClosureは追加のタイプ情報をもった関数オブジェクトであり、アクセッサ関数を通じてアクセス可能なスロット形式で自身の情報の一部を公開します。
OClosureは2つのステップから定義されます。まずoclosure-define
を使ってそのタイプのOClosuresがもつスロットを指定することにより新たなOClosureタイプを定義します。それからoclosure-lambda
を使用して与えられたタイプのOClosureオブジェクトを作成するのです。
たとえばキーボードマクロ、すなわちキーイベントのシーケンスを再実行するインタラクティブな関数を定義したいとします(キーボードマクロを参照)。これは以下のような普通の関数で行うことができます:
(defun kbd-macro (key-sequence) (lambda (&optional arg) (interactive "P") (execute-kbd-macro key-sequence arg)))
しかしこのような定義では関数からkey-sequenceを抽出して、たとえばプリントするといったようなことを簡単に行う方法はありません。
この問題は以下のようなOClosureを使えば解決できます。まずはキーボードマクロのタイプを定義します(ついでにcounter
スロットを追加することにします):
(oclosure-define kbd-macro "Keyboard macro." keys (counter :mutable t))
その後にkbd-macro
関数の定義を書き換えることができます:
(defun kbd-macro (key-sequence) (oclosure-lambda (kbd-macro (keys key-sequence) (counter 0)) (&optional arg) (interactive "P") (execute-kbd-macro keys arg) (setq counter (1+ counter))))
ご覧のとおり、このOClosureのスロットkeys
とcounter
には、OClosureのbodyからローカル変数としてアクセスすることができます。しかしOClosureのbody外部からもアクセスできるようになったのです。たとえばキーボードマクロをdescribeする関数は:
(defun describe-kbd-macro (km) (if (not (eq 'kbd-macro (oclosure-type km))) (message "Not a keyboard macro") (let ((keys (kbd-macro--keys km)) (counter (kbd-macro--counter km))) (message "Keys=%S, called %d times" keys counter))))
ここでkbd-macro--keys
とkbd-macro--counter
はタイプがkbd-macro
であるようなoclosureのために、oclosure-define
マクロによって生成されたアクセッサ関数です。
このマクロはslotsのアクセッサ関数とともに、新たなOClosureタイプを定義する。onameはシンボル(新たなタイプの名前)、または(oname . type-props)
という形式のリスト。この場合のtype-propsはこのoclosureタイプの追加プロパティのリストである。slotsはスロットを記述するリストであり、スロットはそれぞれシンボル(スロットの名前)、または(slot-name . slot-props)
という形式を指定できる。ここでslot-propsは対応するスロットslot-nameのプロパティリストである。type-propsで指定するOClosureタイプのプロパティには以下を含めることができる:
(:predicate pred-name)
pred-nameという名前の述語関数の作成をリクエストする。その関数はタイプonameのOClosureの識別に使用される。このタイプのプロパティが未指定なら、oclosure-define
はその述語にたいするデフォルト名を生成する。
(:parent otype)
タイプotypeのOClosureをタイプonameの親にする。タイプonameのOClosureは親タイプで定義されたslotsを継承する。
(:copier copier-name copier-args)
copierと呼ばれる機能更新関数を定義する。1つ目の引数にタイプonameのOClosureを受け取り、copier-argsという名前のスロット(copier-nameの実際の呼び出し時には対応するはそれぞれ引数に渡された値が含まれるように変更される)をもつコピーをリターンする。
oclosure-define
マクロがslots内のスロットそれぞれにたいして、oname--slot-name
という名前で、スロットの値へのアクセスに使用できるアクセッサ関数を定義する。slotsでのそれぞれのスロットの定義では、以下のスロットのプロパティを指定できる:
:mutable val
デフォルトではスロットはimmutable(変更不可、不変)だが、:mutable
プロパティに非nil
を指定すれば、たとえばsetf
(setf
マクロを参照)でスロットを変更できるようにmutable(変更可能)になる。
:type val-type
そのスロットに期待される値のタイプを指定する。
このマクロはタイプtypeの無名OClosureを作成する。typeはoclosure-define
によって定義されていること。slotsは(slot-name expr)
という形式の要素からなるリスト。実行時にはexprが順に評価された後に、その結果の値によってスロットが初期化されたOClosureが作成される。
関数として呼び出された場合には(関数の呼び出しを参照)、このマクロによって作成されたOClosureはarglistに応じた引数を受け取り、bodyのコードを実行する。bodyからはあたかも静的スコープにキャプチャされたローカル変数のように任意のスロットの値を直接参照できる。
この関数はobjectがOClosureであればそのOClosureタイプ(シンボル)そうでなければnil
をリターンする。
他にもOClosureに関連する関数としてoclosure-interactive-form
があります。これは一部のOClosureタイプにたいしてダイナミックなinteractiveフォームの算出を可能にする関数です。oclosure-interactive-formを参照してください。
[ << ] | [ < ] | [ 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
)。
簡単な例として、以下は関数の呼び出し時に毎回リターン値を変更するアドバイスを追加する方法です:
(defun my-double (x) (* x 2)) (defun my-increase (x) (+ x 1)) (advice-add 'my-double :filter-return #'my-increase)
このアドバイスの追加後に‘3’でmy-double
を呼び出すとリターン値は‘7’になるでしょう。このアドバイスを削除するには、以下のようにします
(advice-remove 'my-double #'my-increase)
より高度な例として、以下はプロセス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)と呼ばれます。
13.12.1 アドバイスを操作するためのプリミティブ | アドバイスを扱うプリミティブ。 | |
13.12.2 名前つき関数にたいするアドバイス | 名前つき関数のアドバイス。 | |
13.12.3 アドバイスの構築方法 | アドバイスを構成する方法。 | |
13.12.4 古いdefadviceを使用するコードの改良 | 古いdefadviceを使用したコードの改良。 | |
13.12.5 アドバイスとバイトコード | アドバイスできない関数。 |
[ << ] | [ < ] | [ 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のインタラクティブ仕様が関数(式や文字列ではないlambda
式やfbound
シンボル)なら、合成される関数のインタラクティブ仕様は、元の関数のインタラクティブ仕様を唯一の引数とする、その関数の呼び出しとなります。引数として受け取ったインタラクティブ仕様を解釈するためにはadvice-eval-interactive-spec
を使用します。
注意:
functionのインタラクティブ指定は結合された関数に適用されるべきであり、functionではなく結合された関数の呼び出し規約にしたがうこと。これらは多くの場合には等しいので差異は生じないが、placeに格納されたオリジナルの関数とは異なる引数を受け取る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つの要素からなるリストをリターンする。
たとえばC-x m
(compose-mail
)コマンドに‘From:’ヘッダーの入力を求めるさせるようにするには、以下のようにすればよい:
(defun my-compose-mail-advice (orig &rest args) "Read From: address interactively." (interactive (lambda (spec) (let* ((user-mail-address (completing-read "From: " '("one.address@example.net" "alternative.address@example.net"))) (from (message-make-from user-full-name user-mail-address)) (spec (advice-eval-interactive-spec spec))) ;; Put the From header into the OTHER-HEADERS argument. (push (cons 'From from) (nth 2 spec)) spec))) (apply orig args)) (advice-add 'compose-mail :around #'my-compose-mail-advice)
[ << ] | [ < ] | [ 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自身のソースファイルでは、Emacs関数にアドバイスを配置するべきではありません(現在のところこの慣習にたいするいくつかの例外があるが修正する予定)。一般的にはfoo
にアドバイスとしてbar
を配置するよりも、foo
内に新たなフックを作成してbar
にそのフックを使用させるほうが明快です。
スペシャルフォーム(スペシャルフォームを参照)はアドバイスできませんが、マクロは関数と同じ方法でアドバイスできます。もちろんこれはすでにマクロ展開されたコードには影響しないため、マクロ展開前にアドバイスが確実にインストールされる必要があります。
プリミティブ(関数とは?を参照)にアドバイスするのは可能ですが、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] | [ ? ] |
すべての関数にたいして信頼性をもってアドバイスできる訳ではありません。バイトコンパイラーが関数の呼び出しを、あなたが変更したい関数を呼び出さない命令シーケンスに置き換えることを選択するかもしれないからです。
これは通常は以下の3つのメカニズムのいずれかのために発生します:
byte-compile
プロパティある関数のシンボルにbyte-compile
プロパティがあると、シンボルの関数定義のかわりにそのプロパティが使用される。バイトコンパイル関数を参照のこと。
byte-optimize
プロパティある関数のシンボルにbyte-optimize
プロパティがあると、バイトコンパイラーが関数の引数を書き換えたり、まったく別の関数の使用を決断するかもしれない。
compiler-macro
関数は定義内に特別なdeclare
フォームであるcompiler-macro
をもつことができる(declare
フォームを参照)。これは関数のコンパイル時に呼び出すexpanderを定義する。その場合にはexpanderが元の関数を呼び出さないバイトコードを生成するかもしれない。
[ << ] | [ < ] | [ 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")
この関数の代替えとなるのがadvertised-calling-convention
におけるspecのdeclare
です。declare
フォームを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
インライン関数(inline function)は関数と同様に機能しますが、1つ例外があります。その関数の呼び出しがバイトコンパイルされると(バイトコンパイルを参照)、その関数の定義が呼び出し側に展開されます。
インライン関数を定義するには、defun
のかわりにdefsubst
を記述するのがシンプルに方法です。定義の残りの部分は同一に見えますが、defsubst
の使用によりバイトコンパイルにそれをインラインにするように指示します。
このマクロはインライン関数を定義する。マクロの構文はdefun
とまったく同じ(関数の定義を参照)。
関数をインラインにすることにより、その関数の呼び出しが高速になる場合があります、が欠点もありその1つは柔軟性の減少です。その関数の定義を変更すると、すでにインライン化された呼び出しは、リコンパイルを行うまで古い定義を使用することになります。
もう1つの欠点は、大きな関数をインライン化することにより、コンパイルされたコードのファイル上およびメモリー上のサイズが増大することです。スピード面でのインライン化の有利性は小さい関数で顕著なので、一般的に大きな関数をインライン化するべきではありません。
インライン関数はデバッグ、トレース、アドバイス(Emacs Lisp関数にたいするアドバイスを参照)に際してうまく機能しません。デバッグの容易さと関数の再定義の柔軟さはEmacsの重要な機能なので、スピードがとても重要であってdefun
の使用が実際に性能の面で問題となるのか検証するためにすでにコードをチューニングしたのでなければ、たとえその関数が小さくてもインライン化するべきではありません。
インライン関数を定義した後そのインライン展開はマクロ同様、同じファイル内の後の部分で処理されます。
インライン関数が実行するのと同じコードに展開されるマクロ(マクロを参照してください)を定義するためにdefmacro
を使用できます。しかし式内でのマクロの直接の使用には制限があります
—
apply
、mapcar
などでマクロを呼び出すことはできません。通常の関数からマクロへの変換には余分な作業が必要になります。通常の関数をインライン関数に変換するのは簡単です。defun
をdefsubst
に置き換えるだけです。インライン関数の引数はそれぞれ正確に1回評価されるので、マクロのときのようにbodyで引数を何回使用するかを心配する必要はありません。
かわりにコンパイラーマクロとしてインライン展開されるコードを記述することにより関数を定義できます(declare
フォームを参照)。以下のマクロがこれを可能にします。
自身をインライン化するコードを提供することにより、コンパイラーマクロとして関数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の要素がシンボルvarだけなら、varの評価結果はvarに再バインドされる(これはlet
の挙動と大きく異なる)。
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] | [ ? ] |
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フォームなら、((lambda (arg)
body)
のように)単一の引数をもつフォームとして記述すること。関数の正規引数はlambdaの引数リストに自動的に追加されるため。
(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
に渡される。
extra
M-xでの補完にたいして入力を求める際に、関数のシンボルを関数リストに含めるかどうかを決定する関数としてcompletion-predicateを宣言する。この述語関数はread-extended-command-predicate
がcommand-completion-default-include-p
にカスタマイズされているときだけ呼び出される。read-extended-command-predicate
のデフォルトの値はnil
(execute-extended-commandを参照)。述語completion-predicateは関数のシンボル、カレントバッファーという2つの引数で呼び出される。
(modes modes)
指定されたmodesにのみ適用されることを意図したコマンドであることを指定する。
(interactive-args arg ...)
repeat-command
用に格納されるべき引数を指定する。argはそれぞれargument-name
form
という形式。
(pure val)
valが非nil
なら、その関数は純粋(pure)である(関数とは?を参照)。これは関数のシンボルのpure
プロパティと同じ(シンボルの標準的なプロパティを参照)。
(side-effect-free val)
valが非nil
ならこの関数には副作用がないので、関数の値を無視するような呼び出しをバイトコンパイラーは無視できる。これは関数のシンボルのside-effect-free
プロパティと同じ。シンボルの標準的なプロパティを参照のこと。
(speed n)
この関数のネイティブコンパイルにたいして有効なnative-comp-speed
の値を指定する(ネイティブコンパイル関数を参照)。これによりその関数に発行されるネイティブコードに用いる最適化レベルを関数レベルで制御できるようになる。特にnが-1の場合には、その関数のネイティブコンパイルによってその関数にたいするネイティブコードではなくバイトコードが発行される。
no-font-lock-keyword
これはマクロにたいしてのみ有効。この宣言をもつマクロは特にマクロとしてではなく、通常の関数としてfont-lockによりハイライトされる(Font Lockモードを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
あるファイルをバイトコンパイルするとき、コンパイラーが知らない関数について警告が生成されるときがあります(コンパイラーのエラーを参照してください)。実際に問題がある場合もありますが、問題となっている関数がそのコードの実行時にロードされる他のファイルで定義されている場合が通常です。たとえば以前はsimple.elをバイトコンパイルすると以下のような警告が出ていました:
simple.el:8727:1:Warning: the function ‘shell-mode’ is not known to be defined.
実際のところshell-mode
は(require
'shell)
を実行する関数内のshell-mode
を呼び出す前でのみ使用されるので、shell-mode
は実行時に正しく定義されるでしょう。そのような警告が実際には問題を示さないことを知っているときには警告を抑制したほうがよいでしょう。そうすれば実際に問題があることを示す新しい警告の識別性が良くなります。これはdeclare-function
を使用して行うことができます。
必要なのは問題となっている関数を最初に使用する前にdeclare-function
命令を追加するだけです:
(declare-function shell-mode "shell" ())
これはshell-mode
がshell.el
(‘.el’は省略可)の中で定義していることを告げます。コンパイラーは関数がそのファイルで実際に定義されているとみなしてチェックを行いません。
3つ目の引数はオプションでありshell-mode
の引数リストを指定します。この例では引数はありません(nil
と値を指定しないのは異なる)。それ以外の場合には(file
&optional
overwrite)
のようになります。引数リストを指定する必要はありませんが、指定すればコンパイラーはその呼び出しが宣言と合致するかチェックできます。
ファイルfile内でfunctionが定義されているとみなすようにバイトコンパイラーに告げる。オプションの3つ目の引数arglistはt
(引数リストが未指定という意味)、またはdefun
と同スタイルな正式パラメーターリスト(カッコを含む)のいずれか。arglistを省略した際のデフォルトはnil
ではなくt
。これは引数省略時の非定形な挙動であり、3つ目の引数を指定せずに4つ目引数を与える場合には通常のnil
のかわりに3つ目の引数のプレースホルダーにt
を指定しなければならないことを意味する。オプションの4つ目の引数fileonlyが非nil
なら実際にfunctionが定義されているかではなくfileの存在だけをチェックすることを意味する。
これらの関数が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の詳細は(ses)Simple Emacs Spreadsheetを参照)。 ユーザーファイルは素性があやふやな場合があります — 初対面の人から受け取ったスプレッドシートかもしれず、会ったことのない誰かから受け取ったeメールかもしれません。そのためユーザーファイルに格納されたソースコードの関数を呼び出すのは、それが安全だと決定されるすまでは危険です。
formが安全(safe)なLisp式ならnil
、危険ならなぜその式が危険かもしれないのか説明するリストをリターンする。引数unsafep-varsは、この時点で一時的なバインドだと判っているシンボルのリスト。これは主に内部的な再帰呼び出しで使用される。カレントバッファーは暗黙の引数になり、これはバッファーローカルなバインディングのリストを提供する。
高速かつシンプルにするために、unsafep
は非常に軽量な分析を行うので、実際には安全な多くのLisp式を拒絶します。安全ではない式にたいしてunsafep
がnil
をリターンするケースは確認されていません。しかし安全なLisp式はdisplay
プロパティと一緒に文字列をリターンでき、これはその文字列がバッファーに挿入された後に実行される、割り当てられたLisp式を含むことができます。割り当てられた式はウィルスかもしれません。安全であるためにはバッファーへ挿入する前に、ユーザーコードで計算されたすべての文字列からプロパティを削除しなければなりません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のテーブルは関数呼び出しと関数定義に関連したことを行ういくつかの関数です。これらは別の場所で説明されているので、ここではクロスリファレンスを提供します。
apply
関数の呼び出しを参照のこと。
autoload
autoloadを参照のこと。
call-interactively
インタラクティブな呼び出しを参照のこと。
called-interactively-p
インタラクティブな呼び出しの区別を参照のこと。
commandp
インタラクティブな呼び出しを参照のこと。
documentation
ドキュメント文字列へのアクセスを参照のこと。
eval
evalについてを参照のこと。
funcall
関数の呼び出しを参照のこと。
function
無名関数を参照のこと。
ignore
関数の呼び出しを参照のこと。
indirect-function
シンボル関数インダイレクションを参照のこと。
interactive
interactive
の使用を参照のこと。
interactive-p
インタラクティブな呼び出しの区別を参照のこと。
mapatoms
シンボルの作成とinternを参照のこと。
mapcar
関数のマッピングを参照のこと。
map-char-table
文字テーブルを参照のこと。
mapconcat
関数のマッピングを参照のこと。
undefined
キー照合のための関数を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マクロ(macros)により新たな制御構造や、他の言語機能の定義を可能にします。マクロは関数のように定義されますが、値の計算方法を指定するかわりに、値を計算する別のLisp式を計算する方法を指示します。わたしたちはこの式のことをマクロの展開(expansion)と呼んでいます。
マクロは関数が行うように引数の値を処理するのではなく、引数にたいする未評価の式を処理することによって、これを行うことができます。したがってマクロは、これらの引数式かその一部を含む式を構築することができます。
て通常の関数が行えることをマクロを使用して行う場合、単にそれが速度面の理由ならばかわりにインライン関数の使用を考慮してください。インライン関数Inliを参照してください。
14.1 単純なマクロの例 | 基本的な例。 | |
14.2 マクロ呼び出しの展開 | いつ、なぜ、どのようにマクロが展開されるか。 | |
14.3 マクロとバイトコンパイル | コンパイラーによりマクロが展開される方法。 | |
14.4 マクロの定義 | マクロ定義を記述する方法。 | |
14.5 マクロ使用に関する一般的な問題 | マクロ引数を何回も評価しないこと。ユーザーの変数を隠さないこと。 | |
14.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))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マクロ展開が直感に反する結果となることがあり得ます。このセクションでは問題になりやすい重要な結果と、問題を避けるためにしたがうべきルールをいくつか説明します。
14.5.1 タイミング間違い | マクロ内ではなく展開形で作業を行う。 | |
14.5.2 マクロ引数の多重評価 | 展開形は各マクロ引数を一度評価すること。 | |
14.5.3 マクロ展開でのローカル変数 | 展開形でのローカル変数バインディングには特に注意を要する。 | |
14.5.4 展開におけるマクロ引数の評価 | 評価せずに展開形の中に配置すること。 | |
14.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についてを参照)の呼び出しなどによりマクロ引数式を評価した場合には別の問題が発生します。まだ呼び出し側のコンテキスト(マクロ展開が評価される場所)にアクセスできない場合には、コード実行の遥か前にマクロが展開されることを考慮する必要があります。
更にマクロ定義でlexical-binding
バインディングを使用していなければ、ユーザーの同じ名前の変数ををマクロの正規引数が隠してしまうかもしれません。マクロの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
と競合しているからです。
更に上記の(foo x)
の展開は、コードがコンパイル済みの際には(setq x
'b)
の実行は後刻そのコードが実行されるときだけ発生するのに、(foo
x)
はコンパイル時に展開されるので、異なる結果をリターンしたりエラーをシグナルするでしょう。
この問題を避けるためには、マクロ展開形の計算では引数式を評価しないでください。かわりにその式をマクロ展開形の中に置き換えれば、その値は展開形の実行の一部として計算されます。これは、このチャプターの他の例が機能する方法です。
[ << ] | [ < ] | [ 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)が含まれ、これは関連するカスタマイゼーションアイテムのコンテナとして振る舞います。
15.1 一般的なキーワードアイテム | すべての種類のカスタマイゼーション宣言に共通なキーワード引数。 | |
15.2 カスタマイゼーショングループの定義 | カスタマイゼーショングループ定義の記述。 | |
15.3 カスタマイゼーション変数の定義 | ユーザーオプションの宣言。 | |
15.4 カスタマイゼーション型 | ユーザーオプションの型指定。 | |
15.5 カスタマイゼーションの適用 | カスタマイゼーションセッティングを適用する関数。 | |
15.6 Customテーマ | Customテーマの記述。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以降のセクションで説明するカスタマイゼーション宣言(customization declaration) —
defcustom
、defgroup
などはすべてさまざまな情報を指定するためのキーワード引数(変更不可な変数を参照)を受け取ります。このセクションではカスタマイゼーション宣言のすべての種類に適用されるキーワードを説明します。
: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
で説明を表示する変数の名前を指定する文字列である。
(face-link face)
フェイスのドキュメントへのリンク。faceはユーザーがこのリンクを呼び出したときにdescribe-face
で説明を表示する関数の名前を指定する文字列である。
(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が省略される。グループは任意の数のプレフィクスをもつことができる。
変数およびグループのサブグループはグループのシンボルのcustom-group
プロパティに格納される。シンボルのプロパティへのアクセスを参照のこと。このプロパティの値はcar
が変数、フェイスまたはサブグループのシンボル、cdr
はそれぞれcustom-variable
、custom-face
、またはcustom-group
のうちいずれかに対応するシンボルであるようなリスト。
この変数が非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
を使用する方法は個別の型の定義を参照のこと。
異なる:options
値によるdefcustom
フォームの再評価では以前の評価で追加された値や、custom-add-frequent-value
(以下参照)呼び出しで追加された値はクリアーされない。
:set setfunction
¶Customizeインターフェースを使用してこのオプションの値を変更する方法としてsetfunctionを指定する。関数setfunctionは2つの引数
— シンボル(オプション名)と新しい値 —
を受け取り、このオプションにたいして正しく値を更新するために必要なことは何であれ行うこと(これはおそらくLisp変数として単にオプションをセットすることを意味しない)。この関数は引数の値を破壊的に変更しないことが望ましい。setfunctionのデフォルトはset-default-toplevel-value
。
定義された場合にはEmacs
LispモードからC-M-xによりdefcustom
が評価されたとき、あるいはsetopt
マクロ(setoptを参照)を介してoptionの値が変更された際にもsetfunctionが呼び出される。
このキーワードを指定すると、その変数のドキュメント文字列にはsetfunctionを直接呼び出すか、setopt
を用いることによって手入力のLispコードで同じことを行う方法が記載されていること。
:get getfunction
¶このオプションの値を抽出する方法としてgetfunctionを指定する。関数getfunctionは1つの引数(シンボル)を受け取り、カスタマイズがそのシンボル(シンボルのLisp値である必要はない)にたいするカレント値としてそれを使うべきかどうかをリターンすること。デフォルトはdefault-toplevel-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-toplevel-value
を使用して変数をセットする。これは変数の:set
関数がマイナーモードを有効または無効にする場合の通常の選択である。この選択により変数の定義ではマイナーモード関数を呼び出しは行わないが、変数をカスタマイズしたときはマイナーモード関数を呼び出すだろう。
custom-initialize-reset
変数の初期化に常に:set
関数を使用する。変数がすでに非voidなら、(:get
メソッドでリターンされる)カレント値を使用して:set
関数を呼び出して変数をリセットする。これはデフォルトの:initialize
関数である。
custom-initialize-changed
変数がすでにセットされている、またはカスタマイズされていれば:set
関数、それ以外なら単にset-default-toplevel-value
を使用して変数の初期化を行う。
custom-initialize-delay
この関数はcustom-initialize-set
と同様に振る舞うが、実際の初期化をEmacsの次回起動時に遅延させる。これはビルド時ではなく実行時のコンテキストで初期化を行わせるように、事前ロードされるファイル(やautoloadされる変数)で使用すること。これは(遅延された)初期化が:set
関数で処理されるという副作用ももつ。Emacsのビルドを参照のこと。
:local value
¶valueがt
ならoptionをバッファーローカルと自動的にマークする。値がpermanent
ならoptionのpermanent-local
プロパティもt
にセットする。バッファーローカルなバインディングの作成と削除を参照のこと。
:risky value
¶その変数のrisky-local-variable
プロパティをvalueにセットする(ファイルローカル変数を参照)。
:safe function
¶その変数のsafe-local-variable
プロパティをfunctionにセットします(ファイルローカル変数を参照)。
:set-after variables
¶保存されたカスタマイゼーションに合わせて変数をセッティングするときは、その前に変数variables確実にセット —
つまりこれら他のものが処理される後までセッティングを遅延 —
すること。これら他の変数が意図された値をもっていない場合に、この変数のセッティングが正しく機能しなければ:set-after
を使用すること。
特定の機能をオンに切り替えるオプションには、:require
キーワードを指定すると便利です。これはその機能がまだロードされていないときには、そのオプションがセットされればEmacsがその機能をロードするようにします。一般的なキーワードアイテムを参照してください。以下は例です:
(defcustom frobnicate-automatically nil "Non-nil means automatically frobnicate all buffers." :type 'boolean :require 'frobnicate-mode :group 'frobnicate)
あるカスタマイゼーションアイテムが: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
フォームの評価ではクリアーされないので、Lispプログラムは未定義のユーザーおっしゃるへの値追加にこの関数を使用できる。
defcustom
は内部的に、標準値にたいする式の記録にシンボルプロパティstandard-value
、カスタマイゼーションバッファーでユーザーが保存した値の記録にsaved-value
、カスタマイゼーションバッファーでユーザーがセットして未保存の値の記録にcustomized-value
を使用します。シンボルのプロパティを参照してください。加えてテーマによりセットされた値の記録に使用されるthemed-value
も存在します(Customテーマを参照)。これらのプロパティは、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を参照してください。
15.4.1 単純型 | シンプルなカスタマイゼーション型(sexp、integerなど)。 | |
15.4.2 複合型 | 他の型やデータから新しい型を構築する。 | |
15.4.3 リストへのスプライス | :inline で要素をリストに結合する。
| |
15.4.4 型キーワード | カスタマイゼーション型でのキーワード/引数ペアー | |
15.4.5 新たな型の定義 | 型に名前をつける。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではすべてのシンプルデータ型を説明します。これらのカスタマイゼーション型のうちのいくつかにたいして、カスタマイゼーションウィジェットはC-M-iかM-TABによるインライン補完を提供します。
sexp
値はプリントと読み込みができる任意のLispオブジェクト。より特化した型を使用するために時間をとりたくなければ、すべてのオプションにたいするフォールバックとしてsexp
を使用することができる。
integer
値は整数でなければならない。
natnum
値は非負の整数でなければならない。
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
key-valid-pに照らして有効となるような、たとえばkeymap-set
に用いるのに適した値。
key-sequence
値はキーシーケンス。カスタマイゼーションバッファーはkbd関数と同じ構文を使用してキーシーケンスを表示する。このタイプは過去の遺物であり、かわりにkbd関数を使うこと。キーシーケンスを参照されたい。
coding-system
値はコーディングシステム名でなければならず、M-TABで補完することができる。
color
値は有効なカラー名でなければならない。ウィジェットはカラー名にたいする補完と、同様に*Colors*バッファーに表示されるカラーサンプルとカラー名のリストからカラー名を選択するボタンを提供する。
fringe-bitmap
値はフリンジビットマップ名でなければならない。ウィジェットは補完を提供する。
[ << ] | [ < ] | [ 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つ目の要素は文字列でなければなりません。
ウィジェットは:match-inline
要素でインライン値がウィジェットにマッチするかどうかを告げる述語を指定できます。
[ << ] | [ < ] | [ 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を実行する。
‘%[…%]’で表示されたボタンテキストにたいして、フェイスface(フェイス名、またはフェイス名のリスト)を使用する。
: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
をリターンすること。
:match-inline function
¶インライン値がその型にマッチするか判断する方法を指定する。対応する値functionは2つの引数(ウィジェットとインライン値)を受け取る関数であり、値が適切なら非nil
をリターンすること。インライン値に関する詳細な情報はリストへのスプライスを参照のこと。
:validate function
入力にたいして検証を行う関数を指定する。functionは引数としてウィジェットを受け取り、そのウィジェットのカレント値がウィジェットにたいして有効ならnil
をリターンすること。それ以外なら無効なデータを含むウィジェットをリターンして、そのウィジェットの:error
プロパティに、そのエラーを記述する文字列をセットすること。
:type-error string
¶stringは値がなぜ:match
関数で判定されるような値にマッチしないかを説明する文字列であること。:match
関数がnil
をリターンした際には、ウィジェットの:error
プロパティがstringにセットされる。
[ << ] | [ < ] | [ 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*’バッファーで?をタイプしたときに表示される。残りの引数propertiesテーマの属性を含んだプロパティリストを渡すために使用される。
サポートされている属性は以下のとおり:
:family
テーマがどの“ファミリー(family)”に属すかを示すシンボル。テーマのファミリーとは、フレームのバックグラウンドのライト(light: 明るい)とダーク(dark: 暗い)を意図したフェイスカラーのように、似ているがマイナーな側面は異なるテーマセットのこと。
:kind
シンボル。テーマが有効かつこのプロパティの値がcolor-scheme
なら、テーマを切り替えるためにコマンドtheme-choose-variant
は同じファミリーに属する他のの利用可能なテーマを探す。現在のところ他の値は指定されておらず、使用するべきではない。
:background-mode
light
かdark
いずれかのシンボル。この属性は現在のところ使用されていないが依然として指定はする必要がある。
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はソースファイルを表示してユーザーに確認を求めます。このようにテーマは通常のバイトコンパイルは行わずに、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
なら、そのテーマをロードする前にユーザーに確認を求める。
この関数はfeatureをprovideするファイルをcustom-theme-load-path
から検索してロードする。これは関数require
(名前つき機能を参照)と似ているが、load-path
(ライブラリー検索を参照)ではなくcustom-theme-load-path
を検索する点が異なるこれはLispサポートファイルおロードを要するCustomテーマにおいて、require
が不適切な際に有用かもしれない。
カレントのEmacsセッションにおいてfeaturep
に照らしてfeature
(シンボル)がまだ与えられていなければ、require-theme
はcustom-theme-load-path
で指定されたディレクトリー内から、featureに‘.elc’、次に‘.el’のサフィックスを追加した名前をもつファイルを検索する。
featureをprovideするファイルが見つかりロードに成功すると、require-theme
はfeatureをリターンする。オプション引数noerrorは検索やロードの失敗時に何が発生するかを決定する。nil
ならこの関数はエラーをシグナルして、それ以外ならnil
をリターンする。ファイルのロードには成功してもfeatureをlprovideしない場合には、require-theme
はエラーをシグナルする(これは抑止不可)。
この関数は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プリミティブで必要となるとあらかじめ判明している外部ライブラリーのオンデマンドローディングについては、動的にロードされるライブラリーを参照してください。
16.1 プログラムがロードを行う方法 | load 関数、その他。
| |
16.2 ロードでの拡張子 | load が試みられるサフィックスについての詳細。
| |
16.3 ライブラリー検索 | ロードするライブラリーの検索。 | |
16.4 非ASCII文字のロード | Emacs Lispファイル内の非ASCII文字。 | |
16.5 autoload | オートロードのための関数のセットアップ。 | |
16.6 多重ロード | ファイルを2度ロードする場合の配慮。 | |
16.7 名前つき機能 | まだロードされていないライブラリーのロード。 | |
16.8 どのファイルで特定のシンボルが定義されているか | 特定のシンボルがどのファイルで定義されているかの検索。 | |
16.9 アンロード | ロードされたライブラリーをunloadする方法。 | |
16.10 ロードのためのフック | 特定のライブラリーがロードされたとき実行されるコードの提供。 | |
16.11 Emacsのダイナミックモジュール | 追加のLispプリミティブを提供するモジュール。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs
Lispにはロードのためのインターフェイスがいくつかあります。たとえばautoload
はファイル内で定義された関数にたいしてプレースホルダーとなるオブジェクトを作成します。この関数はオートロードされる関数を呼び出すために、ファイルからその関数の実際の定義の取得を試みます(autoloadを参照)。require
はファイルがまだロードされていない場合にファイルをロードします(名前つき機能を参照)。これらすべての関数は処理を行うために最終的にload
を呼び出します。
この関数はLispコードのファイルを見つけてオープンして、その中のすべてのフォームを評価してそのファイルをクローズする。
load
はまずファイルを見つけるために、filename.elcという名前、つまりfilenameに拡張子‘.elc’を足した名前のファイルを探す。このようなファイルが存在して、かつネイティブコンパイル(Lispからネイティブコードへのコンパイルを参照)のサポートつきでEmacsがコンパイルされていれば、load
は対応する‘.eln’を探して、見つかったらfilename.elcのかわりにそのファイルを、見つからなければfilename.elcをロードする(そして見つからなかった‘.eln’を生成するためにバックグラウンドでネイティブコンパイルを開始してコンパイルしたファイルをロードする)。filename.elcというファイルが存在しなければ、load
はfilename.elという名前のファイルを探す。このファイルが存在したらそれをロードする。Emacsがダイナミックモジュール(Emacsのダイナミックモジュールを参照)のサポートつきでコンパイルされていれば、、次にload
はfilename.extという名前のファイルを探す。ここでextは共有ライブラリーのシステム依存のファイル名拡張子である(GNUおよびUnixシステムでは‘.so’)。最後に、もしこれらの名前がいずれも見つからなければ、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’等)であっても、もっとも最近変更されたファイルのバージョンを選択する。この場合には、ネイティブコンパイルされた‘.eln’があっても、load
はそれをロードしない。
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…’)というエラーを報告するだろう。これが起こらないようにするためには、コードのリストラクチャリング(restructuring: 再構築)が必要となる。コンパイル済みのファイルのロードではマクロの展開は行われない(コンパイル時に既に行われているため)。マクロとバイトコンパイルを参照のこと。
nomessageが非nil
でなければ、エコーエリアに‘Loading foo...’や‘Loading
foo...done’のようなメッセージがロードの間に表示される。ネイティブコンパイルされた‘.eln’ファイルをロードしたら、メッセージでその旨を伝える。
ファイルをロードする間のハンドルされないエラーはロードを終了させる。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のコンパイル時にセットされたデフォルトの場所から、自身のLispファイルを含むディレクトリーを探します。Emacsはこのディレクトリーをlisp-directory
に保存します。このディレクトリーには、通常なら*.elcやその種のファイルがインストールされています。
"/usr/local/share/emacs/version/lisp"
ここでversionとはEmacsのバージョンのことです(以降の例では/usr/localをあなたがインストールしたEmacsに合わせてインストール先に置き換えること)。これらのディレクトリーとサブディレクトリーには、Emacsに付属している標準Lispファイルが含まれています。Emacsが自身のLispファイルを見つけられなければ、正常に起動しないでしょう。
EmacsをビルドしたディレクトリーのEmacs(つまりまだインストールしていない実行可能ファイル)を起動した場合には、そのファイルをビルドしたソースを含むディレクトリーにあるサブディレクトリーlispをかわりに用いてlisp-directory
を初期化します。
Emacsはその後このlisp-directory
でload-path
を初期化します。ソースとは別のディレクトリーでEmacsをビルドした場合にも、そのビルドしたディレクトリーのサブディレクトリーlispを追加します。
これらのディレクトリーは上記2つの変数に絶対ファイル名として格納されています。
--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のカレントのversion用にローカルにインストールされたファイル、2つ目はEmacsのすべてのバージョンの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)
push
の説明についてはpushを参照してください。
Emacsのダンプにはload-path
の特別な値を使用する。ダンプされたEmacsをカスタマイズするためにsite-load.elかsite-init.elを使用する場合、これらのファイルが行ったload-path
にたいする変更はすべてダンプ後に失われる。
この変数にはEmacsが自身の*.elおよび*.elcファイルを保持するディレクトリーを命名する文字列が格納されている。これは通常ならEmacsのインストールツリーにおいてこれらのファイルが配置される場所になるが、ビルドディレクトリーからEmacsを実行した場合にはそのEmacsをビルドしたソースディレクトリーのサブディレクトリーlispを指す文字列になる。
このコマンドはライブラリー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/29.1/lisp")
そして両方のディレクトリーにfoo.elという名前のファイルがあるとする。この場合、(require
'foo)
は決して2つ目のディレクトリーのファイルをロードしない。このような状況はEmacsがインストールされた方法に問題があることを示唆する。
Lispから呼び出されたると、この関数はシャドーされたファイルリストをバッファー内に表示するかわりに、それのメッセージをプリントする。オプション引数stringp
が非nil
なら、かわりにシャドーされたファイルを文字列としてリターンする。
ネイティブコンパイルのサポート付きでLispからネイティブコードへのコンパイルを参照がコンパイルされている場合には、Emacsはload-path
の検索時にバイトコンパイル済みの‘.elc’ファイルを見つけた際に、それに対応するネイティブコンパイル済みコードを保持する‘.eln’を探します。ネイティブコンパイル済みファイルはnative-comp-eln-load-path
にリストされたディレクトリーから検索されます。
この変数はEmacsがネイティブコンパイル済み‘.eln’ファイルを探すディレクトリーのリストを保持する。絶対ファイル名ではないリスト内のファイル名は、invocation-directory
(オペレーティングシステムの環境を参照)と相対的なファイル名に解釈される。このリストの最後のディレクトリーはシステムディレクトリー(Emacsのビルドおよびインストール手続きで‘.eln’がインストールされるディレクトリー)である。このリストの各ディレクトリーにたいして、EmacsのバージョンとカレントのネイティブコンパイルのABIに応じた8文字のハッシュから構成される名前のサブディレクトリーで、Emacsは‘.eln’ファイルを探す。このサブディレクトリー名は変数comp-native-version-dir
に格納されている。
[ << ] | [ < ] | [ 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: 自動ロード)の機能により、定義されているファイルをロードすることなく関数やマクロの存在を登録できます。関数の最初の呼び出しで実際の定義およびその他の関連するコードをインストールするために適切なライブラリーを自動的にロードして、すべてがすでにロードされていたかのように実際の定義を実行します。関数やマクロのドキュメントの参照(ドキュメントの基礎を参照)、変数名や関数名の補完(以下のプレフィックスによるautoloadを参照)によってもオートロードが発生します。
16.5.1 プレフィックスによるautoload | プレフィクスによるautoload。 | |
16.5.2 autoloadを使用するケース | autoloadを使用するべきとき。 |
オートロードされた関数をセットアップするには2つの方法があります。それはautoload
を呼び出す方法と、ソースの実際の定義の前に“マジック”コメントを記述する方法です。autoload
はオートロードのための低レベルのプリミティブです。任意のLispプログラムが、任意のタイミングでautoload
を呼び出すことができます。Emacsとともにインストールされるパッケージにとって、マジックコメントは関数をオートロードできるようににするための一番便利な方法です。そのコメント自身は何も行いませんが、コマンドloaddefs-generate
にたいするガイドの役目を果たします。このコマンドはautoload
の呼び出しを構築して、Emacsビルド時に実行されるようにアレンジします。
この関数はfilenameから自動的にロードされるように、functionという名前の関数(かマクロ)を定義する。文字列filenameにはfunctionの実際の定義を取得するファイルを指定する。
filenameがディレクトリー名、またはサフィックス.el
と.elc
のいずれも含まなければ、この関数はこれらのサフィックスのいずれかを強制的に追加して、サフィックスがないただのfilenameという名前のファイルはロードしない(変数load-suffixes
により要求される正確なサフィックスが指定される)。
引数docstringはその関数のドキュメント文字列である。autoload
の呼び出しでドキュメント文字列を指定することにより、その関数の実際の定義をロードせずにドキュメントを見ることが可能になる。この引数の値は通常は関数定義のドキュメント文字列と等しいこと。もし等しくなければ、その関数定義のドキュメント文字列がロード時に有効になる。
interactiveが非nil
なら、その関数はインタラクティブに呼び出すことが可能になる。これによりfunctionの実際の定義をロードせずに、M-xによる補完が機能するようになる。ここでは完全なインタラクティブ仕様は与えられない。完全な仕様はユーザーが実際にfunctionを呼び出すまで必要ない。ユーザーが実際に呼び出したときに、実際の定義がロードされる。
interactiveがリストなら、そのコマンドを適用可能なモードのリストとして解釈される。
普通の関数と同様、マクロとキーマップをオートロードできる。functionが実際にはマクロならtypeにmacro
、キーマップのならtypeにkeymap
を指定する。Emacsのさまざまな部分では、実際の定義をロードせずにこれらの情報を知ることが必要とされる。
オートロードされたキーマップは、あるプレフィクスキーがシンボルfunctionにバインドされているとき、キーを探す間に自動的にロードされる。そのキーマップにたいする他の類のアクセスではオートロードは発生しない。特にLispプログラムが変数の値からそのキーマップを取得してkeymap-set
を呼び出した場合には、たとえその変数の名前がシンボル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’だけの行から構成されます。関数loaddefs-generate
は、対応するautoload
呼び出しをloaddefs.el内に書き込みます(autoload
cookieとなる文字列とloaddefs-generate
で生成されるファイルの名前は、上述のデフォルトから変更可能です。以下参照)。Emacsのビルドではloaddefs.elをロードするためにautoload
を呼び出します。
このマジックコメントは任意の種類のフォームを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
、deftheme
、defclass
(EIEIO in EIEIOを参照)、およびdefine-skeleton
(Autotyping in Autotypingを参照)。
ビルド時にそのファイル自身をロードするときにフォームを実行しないようにするためにマジックコメントを使用することもできます。これを行なうにはマジックコメントと同じ行にフォームを記述します。これはコメントなのでソースファイルをロードするときには何も行いません。ただしビルド時に実行されたEmacsでは、loaddefs-generate
がloaddefs.elにコピーします。
以下はマジックコメントによるオートロードのためにdoctor
を準備する例です:
;;;###autoload (defun doctor () "Switch to *doctor* buffer and start giving psychotherapy." (interactive) (switch-to-buffer "*doctor*") (doctor-mode))
これにより以下がloaddefs.el内に書き込まれます:
(autoload 'doctor "doctor" "\ Switch to *doctor* buffer and start giving psychotherapy. \(fn)" t nil)
ダブルクォートの直後のバックスラッシュと改行は、loaddefs.elのように事前ロードされる未コンパイルのLispファイルだけに用いられる慣習です。これらはetc/DOCファイルにドキュメント文字列を配置するよう指示する文字です。Emacsのビルド、およびlib-src/make-docfile.cのコメントも参照してください。loaddefs.elは編集用ではありませんが、ある程度は人が読みやすいように保とうと努めています。たとえばdefvar
の値の中のコントロール文字をエスケープしたり、行が長くならないようにdoc文字列のダブルクォーテーションの直後にはバックスラッシュと改行を挿入するようにしています。ドキュメント文字列の使い方(usage
part)の中の‘(fn)’は、種々のヘルプ関数(ヘルプ関数を参照)が表示するときにその関数の名前に置き換えられます。
関数定義手法として既知ではなく、認められてもいないような、通常とは異なるマクロにより関数定義を記述した場合、通常のオートロードのマジックコメントの使用によって定義全体がloaddefs.el
内にコピーされるでしょう。これは期待した動作ではありません。かわりに以下を記述することにより、意図したautoload
呼び出しをloaddefs.el
内に配置することができます。
;;;###autoload (autoload 'foo "myfile") (mydefunmacro foo ...)
autoload cookieとしてデフォルト以外の文字列を使用して、デフォルトのloaddefs.elとは異なるファイル内に対応するオートロード呼び出しを記述できます。これを制御するためにEmacsは2つの変数を提供します:
この定数の値はautoload
cookieにマッチさせるregexp。loaddefs-generate
はそのcookieの後に続くLispフォームを、生成したautoloadファイルにコピーする。これは‘;;;###autoload’や‘;;;###calc-autoload’のようなコメントにマッチするだろう。
この変数の値は、オートロード呼び出しが書き込まれるEmacs Lispファイルを命名する。デフォルト値はloaddefs.elだが、(たとえば.elファイル内のセクションLocal Variables))をオーバーライドできる。オートロードファイルは、フォームフィード文字で開始される終端を含んでいると仮定される。
以下の関数はオートロードオブジェクトにより指定されたライブラリーを明示的にロードするために使用されるかもしれません:
この関数はオートロードオブジェクトautoloadにより指定されたロードを処理する。オプション引数nameに非nil
を指定するなら、関数値がautoloadとなるシンボルを指定すること。この場合、この関数のリターン値がそのシンボルの新しい関数値になる。オプション引数macro-onlyの値がmacro
なら、この関数は関数ではなくマクロのロードだけを有効にする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コマンドdescribe-variable
とdescribe-function
の補完の間に、Emacsは補完されるプレフィクスにマッチする定義を含むファイルのロードを試みます。変数definition-prefixes
にはプレフィクスとそれをロードするファイルのリストをマップするハッシュテーブルが保持されています。このマッピングのエントリーは、loaddefs-generate
(autoloadを参照)が生成するregister-definition-prefixes
を呼び出すことによって追加されます。ロードする価値のある定義を含んでいないファイル(たとえばテストファイル)ではファイルローカル変数としてautoload-compute-prefixes
をnil
にセットする必要があります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
本当に必要でなければautoloadコメントを追加しないでください。コードをautoloadすることは、それが常にグローバルに可視になることを意味しています。一度あるアイテムがautoloadされれば、autoload以前の状態(autoload後には明示的なロードなしで通常のように使用できる)に戻るための互換性のある手段はありません。
python-mode
関数の定義をautoloadすればユーザーは単にM-x
python-modeを使用してライブラリーをロードできる。
find-exec-terminator
のようなものが該当するだろう)。
(defvar
foo)
、未定義の関数にたいする警告の抑制にはdeclare-function
(コンパイラーへの定義済み関数の指示を参照)を使用するか、あるいは使用する関連ライブラリーをrequireしたり明示的にautoloadの命令文を使用すること。
[ << ] | [ < ] | [ 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
は欠落している機能に関するエラーをシグナルする。
この関数はカレントEmacsセッションでfeatureがプロバイドされていれば(たとえばfeatureがfeatures
のメンバーなら)t
をリターンする。subfeatureが非nil
なら、この関数はサブフィーチャも同様にプロバイドされているとき(たとえばsubfeatureがシンボルfeatureのプロパティsubfeature
のメンバーのとき)だけt
をリターンする。
この変数の値はシンボルのリストであり、そのシンボルはカレントEmacsセッションにロードされたフィーチャである。シンボルはそれぞれprovide
を呼び出すことにより、このリストにputされたものである。リストfeatures
内の要素の順番に意味はない。
use-package
は機能のロードやそれを使うための構成にたいして便利な手段を提供するためのマクロです。require
が行うような機能のrequire、それにロード時のフック(see ロードのためのフック)のようにその機能が既にロード済みならコードを実行するという処理を組み合わせる手段を提供するのです。use-package
の宣言的な構文によって、ユーザーのinitファイルで非常に簡単に使うことができます。
このマクロはfeatureという名前の機能をロードする方法、およびどのようにそれを構成、カスタマイズして使用するかを指定する。引数argsはキーワード/値のペアー。重要なキーワードと値の一部を以下に記す:
:init forms
featureのロード前に実行するformsを指定する。
:config forms
featureのロード後に実行するformsを指定する。
:defer condition
conditionが非nil
なら、featureのautoloadされるコマンドか変数のいずれかが最初に使用されるまで、featureのロードを遅延するように指定する。conditionが数値nの場合には、アイドル後n秒経過後にfeatureをロードするよう指定する。
:commands commands…
autoloadするfeatureのコマンドを指定する。
:bind keybindings…
featureのコマンドのkeybindingsを指定する。バインドはそれぞれ以下の形式をもつ
(key-sequence . command)
または
(:map keymap (key-sequence . command))
ここでkey-sequenceはkbd
マクロが受け付けるような形式であること(キーシーケンスを参照)。
use-package
に関する詳細はTop in use-package User
Manualを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はsymbolを定義しているファイルの名前をリターンする。typeがnil
なら、どのようなタイプの定義も受け入れる。typeがdefun
なら関数定義、defvar
は変数定義、defface
はフェイス定義だけを指定する。
値は通常は絶対ファイル名である。定義がどのファイルにも関係しなければnil
になることもある。symbolがオートロード関数を指定するなら、値が拡張子なしの相対ファイル名になることもある。
オプションの3番目の引数native-pが非nil
、かつネイティブコンパイルのサポートつき(Lispからネイティブコードへのコンパイルを参照)でビルドされたEmacsの場合には、この関数は.elcや.elといったファイルではなく、.elnファイルで定義されたsymbolを探そうと試みる。そのような.elnファイルが見つかり古くなっていなければ、この関数は絶対ファイル名をリターンする。それ以外の場合にはソースファイルかバイトコンパイル済みファイルのいずれかの名前をリターンする。
symbol-file
は変数load-history
の値にもとづく。
この変数の値はロードされたライブラリーファイルの名前を、それらが定義する関数と変数の名前、およびそれらがプロバイドまたはリクワイアするフィーチャに関連付けるalistである。
このalist内の各要素は、1つのロード済みライブラリー(スタートアップ時にプリロードされたライブラリーを含む)を記述する。要素はCARがライブラリーの絶対ファイル名(文字列)であるようなリストである。残りのリスト要素は以下の形式をもつ:
var
シンボルvarが変数として定義された。
(defun . fun)
関数funは定義済み。(defun . 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についてを参照してください。
load-history
に加えて、関数はそれぞれシンボルプロパティfunction-history
で自身のヒストリーを追跡します。この点において関数が特別扱いされる理由は、関数は2つの異なるファイルにおいて2段階で定義されることがよくある(典型的にはそのうちの一方がautoloadされる)ので、ファイルを正しいunloadを可能にするために、そのファイルが関数定義に何を行ったかをより正確に知る必要があるのです。
シンボルプロパティfunction-history
には(file1 def2 file2 def3 ...)
という形式のリストが保持されています。ここでfile1は定義を最後に変更したファイル、def2はfile1の前にfile2によってセットされた定義、...となります。論理的にはこのリストの最後はその関数を最初に定義したファイルですが、容量削減のために通常は最後の要素は省略されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
他のLispオブジェクト用にメモリーを回収するために、ライブラリーによりロードされた関数や変数を破棄することができます。これを行うには関数unload-feature
を使用します:
このコマンドはフィーチャfeatureをプロバイドしていたライブラリーをアンロードする。そのライブラリー内のdefun
、defalias
、defsubst
、defmacro
、defconst
、defvar
、defcustom
によって定義されたすべての関数、マクロ、変数は未定義になる。その後に、それらのシンボルにたいして事前に関連付けられていたオートロードをリストアする(ロードはシンボルのfunction-history
プロパティにこれらを保存している)。
以前の定義をリストアする前に、特定のフックからライブラリーが定義した関数を取り除くために、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 "js" (keymap-set js-mode-map "C-c C-c" 'js-eval))
どのファイルが評価をトリガーするか制限するには、ディレクトリーか拡張子、またはその両方を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モジュール)とは、Emacs Lispで記述されたパッケージのように、Emacs Lispプログラムで使用するための追加機能を提供する共有ライブラリーです。
Emacs Lispパッケージをロードする関数は、ダイナミックモジュールのロードもできます。これらの関数はファイル名の拡張子、いわゆる“サフィックス”を調べることによってダイナミックモジュールを認識します。
この変数はモジュールファイルにたいするシステム依存なファイル名拡張子を保持する。POSIXホストでは.so、macOSでは.dylib 、MS-Windowsでは.dll。
macOSではダイナミックモジュールは.dylibに加えて、サフィックス.soをもつこともできます。
すべてのダイナミックモジュールはemacs_module_init
という名前のCから呼び出し可能な関数をエクスポートする必要があります。Emacsはそのモジュールをロードするload
やrequire
の呼び出しの一部として、その関数を呼び出します。自身のコードがGPLまたは互換ライセンスの下にリリースされていることを示すために、plugin_is_GPL_compatible
という名前のシンボルもエクスポートするべきです。このようなシンボルをエクスポートしないモジュールをプログラムがロードしようとすると、Emacsはエラーをシグナルするでしょう。
あるモジュールがEmacsの関数の呼び出しを必要とするなら、Emacsディストリビューションに同梱されているヘッダーファイルemacs-module.hで定義および文書化されたAPI (Application Programming Interface)を介して行う必要があります。独自モジュールを記述する際におけるこのAPI使用の詳細は動的にロードされるモジュールの記述を参照してください。
モジュールはモジュールが定義するC構造体への埋め込みポインターとなるLispオブジェクトuser-ptr
を作成できます。これはモジュールが作成する複雑なデータ構造を維持してモジュールの関数に渡して戻す場合に有用です。user-ptrオブジェクトはそれに関連付けられるファイナライザー(finalizer:
オブジェクトがガーベージコレクトされる際に呼び出される関数)をもつこともできます。これはメモリー、オープンしたファイル記述子等のデータ構造の背後に割り当てられたリソースの解放に有用です。Lisp・モジュール間の値変換を参照してください。
この関数は引数がuser-ptr
オブジェクトならt
をリターンする。
Emacsは指定されたfileからモジュールをロードして、そのモジュールに必要な初期化えを行うために、この低レベルのプリミティブを呼び出す。これはモジュールがシンボルplugin_is_GPL_compatible
をエクスポートすることを保証して、モジュールのemacs_module_init
関数を呼び出し、その関数のリターン値がエラーを示したりユーザーが初期化中にC-gをタイプしたらエラーをシグナルする。初期化が成功するとmodule-load
はt
をリターンする。この関数はload
とは異なり既知の拡張子をもつファイルの検索を試みないので、fileは正確なファイル名拡張子をもたなければならないことに注意。
load
とは異なり、module-load
はload-history
にモジュールを記録せず、何もメッセージをプリントしないし、再帰ロードにたいする保護も行わない。したがってほとんどのユーザーはmodule-load
のかわりにload
、load-file
、load-library
、require
を使用するべきである。
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; -*-
17.1 バイトコンパイル済みコードのパフォーマンス | バイトコンパイルによるスピードアップ例。 | |
17.2 バイトコンパイル関数 | ||
17.3 ドキュメント文字列とコンパイル | ドキュメント文字列のダイナミックロード。 | |
17.4 個々の関数のダイナミックロード | ||
17.5 コンパイル中の評価 | コンパイル時に評価されるコード。 | |
17.6 コンパイラーのエラー | コンパイラーのエラーメッセージの扱い。 | |
17.7 バイトコード関数オブジェクト | バイトコンパイル済み関数に使用されるデータ型。 | |
17.8 逆アセンブルされたバイトコード | バイトコードの逆アセンブル; バイトコードの読み方。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バイトコンパイルされた関数はCで記述されたプリミティブ関数ほど効率的ではありませんが、Lispで記述されたバージョンよりは高速に実行されます。以下は例です:
(defun silly-loop (n) "ループをN回繰り返し実行して時間を秒でリターンする" (let ((t1 (float-time))) (while (> (setq n (1- n)) 0)) (- (float-time) t1))) ⇒ silly-loop
(silly-loop 50000000) ⇒ 5.200886011123657
(byte-compile 'silly-loop)
⇒ [コンパイルされたコードは表示されない]
(silly-loop 50000000) ⇒ 0.6239290237426758
この例ではインタープリターによる実行には5秒以上を要しますが、バイトコンパイルされたコードは1秒未満です。これは典型的な結果例ですが、実際の結果はさまざまでしょう。
[ << ] | [ < ] | [ 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を参照してください。しかし変数byte-compile-debug
が非nil
ならエラーメッセージはLispエラーとしてシグナルされます(エラーを参照)。
バイトコンパイルを意図したファイル内にマクロ呼び出しを記述する際には注意が必要です。マクロ呼び出しはコンパイル時に展開されるので、そのマクロは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) ⇒ #[257 "\211\300U\203^H^@\300\207\211\301^BS!_\207" [1 factorial] 4 "Compute factorial of INTEGER.\n\n(fn 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
をリターンする。インタラクティブに呼び出されたときは、ファイル名の入力をもとめる。
$ 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’ファイルをリコンパイルする。
このコマンドは通常はシンボリックリンクであるような‘.el’ファイルをコンパイルしない。オプションのfollow-symlinkパラメーターが非nil
なら、シンボリックリンクされた‘.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ファイルでは発生し得ます。それぞれのファイルをリコンパイルしたらすぐに新たなコンパイル済みファイルをリロードするのが、これらの問題を回避する一番簡単な方法です。
ダイナミックな関数ロードの使用により提供される利点がほとんど計測できないという経験から、この機能はEmacs 27.1以降は廃止されます。
コンパイル時に変数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-suppressed-warnings
マクロを使用して特定の式にたいするコンパイラーの警告を抑制することもできます:
これは実行においては(progn
body...)
と等価だが、コンパイラーはbody内の指定したコンディションにたいする警告を発しない。warningsは警告シンボルと、それらを適用する関数/変数シンボルの連想リスト。たとえばfoo
という時代遅れ(obsolete)の関数を呼び出したいがコンパイル時の警告を抑止したければ、以下のようにする:
(with-suppressed-warnings ((obsolete foo)) (foo ...))
コンパイラー警告の抑制をより粗く行うにはwith-no-warnings
構文を使用できます:
これは実行時には(progn
body...)
と等価だが、コンパイラーはbodyの中で起こるいかなる事項にたいしても警告を発しない。
わたしたちはかわりにwith-suppressed-warnings
の使用を推奨するが、この構文を使用する場合には、あなたが抑制したいと意図する警告以外の警告を失わないようにするために、可能な限り小さいコード断片にたいしてこの構文を使用すること。
変数byte-compile-warnings
をセットすることにより、コンパイラーの警告をより詳細に制御できます。詳細は変数のドキュメント文字列を参照してください。
error
を使用してバイトコンパイラーの警告が報告されることを望む場合があるかもしれません。そのような場合にはbyte-compile-error-on-warn
を非nil
値にセットしてください。
[ << ] | [ < ] | [ 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: (arg1)
0 dup ; 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 dup ;integer
の値をスタック上にpushする 9 constant factorial ;factorial
をスタック上にpushする 10 stack-ref 2 ;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: (arg1)
0 constant current-time-string ; current-time-string
を
; スタック上のトップにpushする
1 call 0 ; 引数なしでcurrent-time-string
を呼び出して ; 結果をt1
のようにスタック上にpushする
2:1 stack-ref 1 ; 引数n
の値を取得して
; その値をスタック上にpushする
3 sub1 ; スタックのトップから1を減ずる
4 dup ; スタックのトップを複製する ; つまりスタックのトップをコピーしてスタック上にpushする 5 stack-set 3 ; ; スタックのトップをpopして ;n
にその値をセットする ;; (要はシーケンスdup stack-set
は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 dup ;t1
の値をスタック上にpushする 13 constant current-time-string ;current-time-string
を ; スタックのトップにpushする 14 call 0 ; 再度current-time-string
を呼び出す
15 list2 ; スタックのトップ2要素をpopして取り出し ; それらのリストを作りスタック上にpushする 16 return ; スタックのトップの値をリターンする
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
the previous chapterで述べたバイトコンパイルに加えて、EmacsではオプションでLisp関数定義をネイティブコード(native code)として知られている真のコンパイル済みコードにコンパイルすることもできます。この機能はGCCディストリビューションの一部であるlibgccjitを使用しており、そのライブラリー使用のサポートと共にEmacsがビルドされている必要があります。更にLispコードをネイティブコンパイルするために、システムにGCCとBinutils(アセンブラとリンカ)がインストールされている必要があります。
Emacsのカレントプロセスでネイティブコンパイル済みLispコードの生成およびロードが可能かどうか判断するには、native-comp-available-p
(ネイティブコンパイル関数を参照)を呼び出してください。
バイトコンパイル済みコードとは異なり、ネイティブコンパイル済みLispコードはマシンのハードウェアにより直接実行されるので、ホストCPUが提供できる最高スピードで実行されます。このスピードアップの結果は一般的にはそのLispコードが何を行うかに依りますが、対応するバイトコンパイル済みコードに比べて、通常は2.5から5倍高速になります。
一般的に異なるシステム間ではネイティブコードに互換性はないので、あるマシンから別のマシンへのネイティブコンパイル済みコードの可搬性はありません。ネイティブコンパイル済みコードはそれを生成したのと同じマシン、もしくは類似のマシン(同一のCPUおよびランタイムライブラリー)でのみ使用できます。ネイティブコンパイル済みコードの可搬性は、共有ライブラリー(.soや.dllのファイル)の可搬性と同様です。
ネイティブコンパイル済みコードのライブラリーにはEmacs Lispプリミティブ(関数とは?を参照)とそれらの呼び出し規約に関して重大な依存性が含まれているので、Emacsは通常はバージョンの異なるEmacsが生成したネイティブコンパイル済みコードをロードしません。同一のLispコードで異なるバージョンのEmacsがネイティブコンパイルしたコードは、ネイティブコンパイル済みライブラリーをそのバージョンのEmacsだけがロードできる一意なファイル名で生成します。しかし一意なファイル名の使用により、複数の異なるバージョンのEmacsによりネイティブコンパイルされた同一ライブラリーが、同一ディレクトリーに存在することになります。
ファイルローカル変数としてno-byte-compile
に非nil
をバインドしても、そのファイルのネイティブコンパイルが無効になります。加えて同様の変数no-native-compile
は、ファイルのネイティブコンパイルだけを無効にします。no-byte-compile
とno-native-compile
の両方が指定された場合には、前者が優先されます。
ネイティブコンパイルによるuser-emacs-directory
のサブディレクトリー内の*.elnファイルへの結果の書き込みを防がなければならない場合もあるかもしれません。これはnative-comp-eln-load-path
の値を変更するか(ネイティブコンパイル関数を参照)、あるいは環境変数HOME
が一時的に既存ディレクトリー以外を指すようにすることで行うことができます。後者のテクニックはEmacsがトランポリン(trampolines)を生成する必要がある場合(Lispコード内においてLispプリミティブをネイティブにコンパイルするためにアドバイスまたは再定義する際に用いられる)には、依然として少数の*.elnファイルを生成するかもしれないことに注意が必要です。trampolinesを参照してください。かわりにstartup-redirect-eln-cache
関数を使用してデフォルト以外のディレクトリーに*.elnファイルを書き込むよう指定できます。ネイティブコンパイル関数を参照してください。
18.1 ネイティブコンパイル関数 | Lispをネイティブコンパイルする関数。 | |
18.2 ネイティブコンパイル関数 | ネイティブコンパイルを制御する変数。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ネイティブコンパイルはバイトコンパイル(バイトコンパイルを参照)の副作用として実装されています。したがってLispコードをネイティブコンパイルすると、同様にバイトコードが常に生成されるため、バイトコンパイル用にLispコードを準備する際の規則や注意事項(バイトコンパイル関数を参照)は、ネイティブコンパイルでも同じようにすべて有効です。
native-compile
関数により単一の関数やマクロ、あるいはLispコードのファイル全体をネイティブコンパイルできます。ファイルをネイティブコンパイルすると、それに対応するバイトコードの.elcファイルと、ネイティブコードの.elnファイルの両方が生成されます。
ネイティブコンパイルでは警告やエラーが生成されるかもしれません。これらは通常は*Native-compile-Log*と呼ばれるバッファーに記録されます。このバッファーではインタラクティブなセッションではLIMPLEという特別なモードが使用されます。このモードではログにたいして適切なfont-lock
ロックをセットアップされて、それ以外はFundamentalモードと同じです。ネイティブコンパイルの結果メッセージのロギングは変数native-comp-verbose
で制御できます(ネイティブコンパイル関数を参照)。
Emacsが非インタラクティブに実行されている際には、ネイティブコンパイルによって生成されたメッセージはmessage
(エコーエリアへのメッセージの表示を参照)の呼び出しによって報告されます。これは通常はEmacsを呼び出した端末の標準エラーストリームに表示されます。
この関数はfunction-or-fileをネイティブコードにコンパイルする。引数function-or-fileにはコンパイルする関数シンボル、Lispフォーム、またはEmacs Lispソースコードを含むファイル名(文字列)を指定できる。オプション引数outputが与えられた場合には、コンパイル済みコードを書き込むファイルの名前を指定する文字列でなければならない。それ以外の場合には、function-or-fileが関数かLispフォームならコンパイル済みオブジェクト、ファイル名ならコンパイル済みコード用に作成したファイルの完全な絶対ファイル名をリターンする。出力ファイルにはデフォルトで拡張子.elnが与えられる。
この関数はlibgccjitを通じて別のサブプロセス内でGCCを呼び出すネイティブコンパイルの最終フェーズを実行する。これはこの関数を呼び出したプロセスとして、同じEmacs実行可能形式を呼び出す。
この関数はbatchモードでEmacsのコマンドラインで指定されたファイルにたいしてネイティブコンパイルを実行する。これはコンパイル完了によりEmacsをkillするので、Emacsのバッチ実行でのみ使用しなければならない。1つ以上のファイルでコンパイルが失敗すると、Emacsプロセスはそれ以外のすべてのファイルのコンパイルを試みて、非0のexitステータスで終了する。オプション引数for-tarballが非nil
なら、この関数はコンパイルした結果の.elnファイルをnative-comp-eln-load-path
に記述された最後のディレクトリーに配置する(ライブラリー検索を参照)。これは初回にEmacsソースtarballをビルドするときに、ソースtarballに含まれていないネイティブコンパイル済みファイルをユーザーのキャッシュディレクトリーではなくビルドツリー内に生成する必要がある際に使用されることを意図している。
ネイティブコンパイルはメインのEmacsプロセスのサブプロセス中で、全体を非同期に実行できます。これによりバックグラウンドでコンパイルを実行する間、メインのEmacsプロセスをフリーにできます。これはEmacsにロードされた任意のLispファイルやバイトコンパイル済みLispファイルを、Emacsがネイティブコンパイルするために使用する手法です。サブプロセスをこのように使用することによって、ネイティブコンパイルではバイトコンパイルでは発生しない警告やエラーが生成されるかもしれず、それ故に正しく機能するようにLispコードの修整が必要かもしれないことに注意してください。詳細はネイティブコンパイル関数のnative-comp-async-report-warnings-errors
を参照してください。
この関数はfilesという名前のファイルを非同期にコンパイルする。引数filesは単一のファイル名(文字列)、または1つ以上のファイルおよび/またはディレクトリー名のリストであること。このリスト中にディレクトリーが与えられた場合には、それらのディレクトリー内で再帰的にコンパイルするように、オプション引数recursivelyは非nil
であること。loadが非nil
なら、Emacsはコンパイルが成功したそれぞれのファイルをロードする。オプション引数selectorによりfilesのどれをコンパイルするか制御できる。これには以下のいずれかの値を指定できる:
nil
または省略files内のすべてのファイルとディレクトリーを選択。
このregexpに名前がマッチするファイルとディレクトリーを選択。
files内のファイルおよびディレクトリーそれぞれにたいして呼び出される述語関数。そのファイルまたはディレクトリーを選択する必要があるなら非nil
をリターンすること。
複数のCPU実行ユニットをもつシステムでは、この関数はfilesが複数のファイル名の際には、通常はnative-comp-async-jobs-number
(ネイティブコンパイル関数を参照)の制御の下で複数のコンパイル用サブプロセスを並行で開始する。
以下の関数により、実行時にネイティブコンパイルが利用可能かどうかをLispプログラムがテストできます。
この関数は実行中のEmacsにネイティブコンパイルのサポートがコンパイルされていれば非nil
をリターンする。libgccjitを動的にロードするシステムでは、ライブラリーg利用できロードできることも確認する。ネイティブコンパイルが利用可能か事前に知る必要があるLispプログラムはこの述語を使用すること。
非同期なネイティブコンパイルはnative-comp-eln-load-path
変数(ネイティブコンパイル関数を参照)で指定された最初の書き込み可能なディレクトリーのサブディレクトリーに生成した*.elnファイルを書き込む。スタートアップファイルで以下の関数を使用してこれを変更できる:
この関数は非同期なネイティブコンパイルがcache-directory
(単一のディレクトリーを表す文字列)に生成した*.elnファイルを書き込むように手配する。更にnative-comp-eln-load-path
の最初の要素がcache-directoryになるように破壊的な変更も行う。cache-directoryが絶対ファイル名でなければ、user-emacs-directory
(initファイル)。を参照から相対的なファイル名と解釈する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではネイティブコンパイルを制御する変数について述べます。
この変数はネイティブコンパイルの最適化レベルを指定する。値は-1から3の数値であること。値0から3はコンパイラーの対応する最適化レベル-O0、-O1、...のコマンドラインオプションと等しい。値-1はネイティブコンパイルの無効化を意味する。この場合には関数およびファイルはバイトコンパイルされる。ただしバイトコード形式でコンパイルされたコードだけを含む*.elnファイルは依然として生成される((declare (speed -1))
を使えばこれを関数単位で行うこともできる。declare
フォームを参照)。デフォルト値は2。
この変数はネイティブコンパイルが生成するデバッグ情報のレベルを指定する。値は0から3の数値で、以下のような意味をもつ:
デバッグ出力なし。これがデフォルト。
ネイティブコードでデバッグシンボルを発行する。これはgdb
のようなデバッガによるネイティブコードの電話を容易にする。
1と同様だが、更に疑似Cコードをダンプする。
2と同様、更にGCC中間パス(GCC intermediate passes)とlibgccjitログファイルをダンプする。
この変数はネイティブコンパイルが発行する一部またはすべてのログメッセージを抑制することにより、ネイティブコンパイルの冗長性(verbosity)を制御する。値が0(デフォルト)なら、ログメッセージはすべて抑制される。1から3の値をセットすることにより、レベルが上述の値であるようなメッセージのロギングを可能にする。値には以下のような解釈がある:
ログなし。これがデフォルト。
コードの最終的なLIMPLE表現をログ。
LAP、最終的なLIMPLE、および追加のパス情報をログ。
最大の冗長性。すべてをログ。
この変数は同時に開始するネイティブコンパイルのサブプロセスの最大数を決定する。非負の数値であること。デフォルト値0はCPU実行ユニットの半数の使用、1は単一の実行ユニットの使用を意味する。
この変数の値が非nil
なら、ネイティブコンパイルの非同期サブプロセスからの警告とエラーは、メインのEmacsセッションの*Warnings*という名前のバッファーに報告される。デフォルト値のt
はそのバッファーへの表示を意味する。*Warnings*バッファーをポップアップせずに警告をログするには、この変数にsilent
をセットすればよい。
非同期ネイティブコンパイルで警告が生成されるのは、必要な機能にたいするrequire
が欠落したファイルのコンパイルが原因であることが多い。この機能はメインのEmacsにロードされるかもしれないが、ネイティブコンパイルは常にサブプロセスから初期状態の環境で開始されるので、サブプロセスではロードされないかもしれない。
この変数の値が非nil
なら、Emacsはexitに際して実行中のネイティブコンパイルの非同期サブプロセスをすべてkillしてexitするかどうかを尋ねる(対応する.elnファイルへの書き込みを防ぐため)。値がnil
(デフォルト)なら、Emacsは問い合わせを行わずにそれらのサブプロセスをkillする。
変数native-comp-eln-load-path
はEmacsが*.elnファイルを探すディレクトリーのリストを保持します(ライブラリー検索を参照)。これは役割りの面では*.elや*.elcのファイルを探すために使用されるload-path
と同じです。このリストにあるディレクトリーは非同期のネイティブコンパイルによって生成された*.elnファイルの書き込みにも使用されます。特にEmacsはこのリスト中の最初に書き込み可能なディレクトリーにファイルを書き込むでしょう。したがってこの変数の値を変更することで、ネイティブコンパイルが結果を格納する場所を制御することができます。
この変数が非nil
であれば、対応する*.elnがまだ存在しないEmacsにロード済みの*.elcの非同期(別名just-in-time、あるいはJIT)なネイティブコンパイルを有効にする。このJITコンパイルはnative-comp-async-jobs-number
の値に応じて、batchモードで走行する別個のEmacsサブプロセスを使用する。LispファイルのJITコンパイルが、成功裏に終了した際にはコンパイル結果の.elnファイルがロードされて、.elcファイルによって提供されていた関数定義をコンパイルしたコードで置き換える。
native-comp-jit-compilation
の値をnil
にセットすることによって、JITネイティブコンパイルが無効になります。ただしたとえJITネイティブコンパイルを無効にしても、トランポリン(trampolines)を生成するために依然としてEmacsは非同期ネイティブコンパイルを開始する必要があるかもしれません。これを制御するためには、以下で説明する別の変数を使用します。
この変数はトランポリンの生成を制御する。トランポリンとはnative-comp-speed
が2以上でネイティブコンパイルされたLispコードから、アドバイスまたは再定義されたLispプリミティブの呼び出しを許すために必要な小さいネイティブコード片のこと。Emacsは生成されたトランポリンを別の*.elnファイルに格納する。この変数のデフォルトの値はトランポリンファイルの生成を有効にするt
だが、値をnil
にセットすることでトランポリンの生成が無効になる。プリミティブにたいするアドバイスや再定義に必要となるトランポリンが利用できなければ、ネイティブコンパイルされたLispからのプリミティブ呼び出しでは再定義とアドバイスは無視されて、プリミティブは直接Cから呼び出されたかのように振る舞うことに注意。したがってあなたのLispプログラムに必要なトランポリンすべてがコンパイル済みでEmacsからアクセス可能であることが不明なら、トランポリン生成の無効化は推奨しない。
この変数の値は文字列でもよく、その場合には生成されたトランポリンである*.elnファイルを格納するディレクトリー名を指定する。このディレクトリー名はnative-comp-eln-load-path
のディレクトリーをオーバーライドする。これは必要に応じてトランポリンを生成したいものの、ユーザーのHOME
ディレクトリーや*.elnが保持されるその他のパブリックディレクトリーの配下には格納したくない場合に役に立つ。ただしnative-comp-eln-load-path
内のディレクトリーとは異なり、トランポリンはバージョン固有のサブディレクトリーではなくこの変数で与えられたディレクトリーに格納されることになる。このディレクトリーが絶対名でなければ、invocation-directory
(オペレーティングシステムの環境を参照)に相対的なディレクトリー名と解釈される。
この変数が非nil
、かつEmacsがトランポリンの生成を要するもののトランポリンを格納するための書き込み可能ディレクトリーが見つからない場合には、トランポリンをtemporary-file-directory
(一意なファイル名の生成を参照)の内部に格納する。
格納するための書き込み可能ディレクトリーが見つからない、あるいはこの変数の値が文字列の際に生成されたトランポリンは、Emacsのカレントセッションの間のみ利用できる。なぜならEmacsはいずれの場所からもトランポリンを探さないからである。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispプログラム内の問題を見つけて詳細に調べる方法がいくつかあります。
trace-function-foreground
とtrace-function-background
、値をトレースする変数の追加用にtrace-values
という関数を提供する。詳細はtrace.elにあるこれらの機能のドキュメントを参照のと。
入出力の問題をデバックする便利なその他のツールとして、ドリブルファイル(dribble file: 端末の入力を参照)と、open-termscript
関数(端末の出力)があります。
19.1 Lispデバッガ | Emacs Lisp評価機能にたいするデバッガ。 | |
19.2 Edebug | Emacs Lispソースレベルデバッガ。 | |
19.3 無効なLisp構文のデバッグ | シンタックスエラーを見つける方法。 | |
19.4 カバレッジテスト | プログラムのすべての分岐を確実にテストする。 | |
19.5 プロファイリング | あなたのコードが使用するリソースの計測。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
普通のLispデバッガは、フォーム評価のサスペンド機能を提供します。評価がサスペンド(一般的にはbreakの状態として知られる)されている間、実行時スタックを調べたり、ローカル変数やグローバル変数の値を調べたり変更することができます。breakは再帰編集(recursive edit)なので、Emacsの通常の編集機能が利用可能です。デバッガにエンターするようにプログラムを実行することさえ可能です。再帰編集を参照してください。
19.1.1 エラーによるデバッガへのエンター | エラー発生時にデバッガにエンターする。 | |
19.1.2 再表示エラーのデバッグ | 再表示エラーからのバックトレース取得。 | |
19.1.3 無限ループのデバッグ | exitしないプログラムの停止デバッグ。 | |
19.1.4 関数呼び出しによるデバッガへのエンター | 特定の関数が呼び出されたときにデバッガにエンターする。 | |
19.1.5 変数の変更時にデバッガにエンターする。 | 変数が変更されたときにデバッガにエンターする。 | |
19.1.6 明示的なデバッガへのエントリー | プログラム内の特定箇所でデバッガにエンターする。 | |
19.1.7 デバッガの使用 | デバッガが行なうこと。 | |
19.1.8 バックトレース | デバッガ内で何を目にするか。 | |
19.1.9 デバッガのコマンド | デバッガで使用するコマンド。 | |
19.1.10 デバッガの呼び出し | 関数debug の呼び出し方。
| |
19.1.11 デバッガの内部 | デバッガのサブルーチンとグローバル変数。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
デバッガに入るタイミングとして一番重要なのは、Lispエラーが発生したときです。デバッガではエラーの直接原因を調査できます。
しかしデバッガへのエンターは、エラーによる通常の結末ではありません。多くのコマンドは不適切に呼び出されたときにLispエラーをシグナルするので、通常の編集の間にこれが発生するたびデバッガにエンターするのは、とても不便でしょう。したがってエラーの際にデバッガにエンターしたいなら、変数debug-on-error
に非nil
をセットします(コマンドtoggle-debug-on-error
はこれを簡単に行う方法を提供する)。
再表示コードによって呼び出されたLispエラーは、技術的な理由によりこのサブセクションで定義されている機能ではデバッグできないことに注意してください。これらについてのヘルプについては再表示エラーのデバッグを参照してください。
この変数はエラーがシグナルされて、それがハンドルされていないときにデバッガを呼び出すかどうかを決定する。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
で指定された条件を満たさなければならない)。
たとえばemacsclientの--evalオプションによるコードの評価からバックトレースを取得するためにはこの変数をセットすると便利。この変数が非nil
のときにemacsclientで評価されたLispコードがエラーをシグナルすると、バックトレースは実行中のEmacsにポップアップされる。
警告:
この変数を非nil
にセットすると、芳しくない効果があるかもしれない。Emacsのさまざまな部分で処理の通常の過程としてエラーがキャッチされており、そのエラーが発生したことに気づかないことさえあるかもしれない。condition-case
でラップされたコードをデバッグする必要があるなら、condition-case-unless-debug
(see エラーを処理するコードの記述を参照)の使用を考慮されたい。
debug-on-event
をスペシャルイベント(スペシャルイベントを参照)にセットすると、Emacsはspecial-event-map
をバイパスしてこのイベントを受け取ると即座にデバッガへのエンターを試みる。現在のところサポートされる値は、シグナルSIGUSR1
とSIGUSR2
に対応する値のみ(これがデフォルト)。これはinhibit-quit
がセットされていて、それ以外はEmacsが応答しない場合に有用かもしれない。
debug-on-message
に正規表現をセットした場合は、それにマッチするメッセージがエコーエリアに表示されると、Emacsはデバッガにエンターする。たとえばこれは特定のメッセージの原因を探すのに有用かもしれない。
‘*Backtrace*’バッファーのカレントスタックフレーム内のフォームはeコマンドで評価できる。またedebug中ならeやC-x
C-eのコマンドを使用すれば、同様のことを行うことができる。デフォルトではこれらのコマンドによってデバッガは抑制される(この時点でデバッガに(再)エンターすると、デバッグ中のコンテキストから抜け出してしまうので)。しかしdebug-allow-recursive-debug
を非nil
値にセットすると、これらのコマンドが再帰的にデバッガにエンターできるようになる。
initファイルロード中に発生したエラーをデバッグするには、オプション‘--debug-init’を使用する。これはinitファイルロードの間にdebug-on-error
をt
にバインドして、通常はinitファイル内のエラーをキャッチするcondition-case
をバイパスする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
再表示によって呼び出されたLispコード内でエラーが発生した際には、技術的な理由によりEmacsでの通常時のデバッグメカニズムが使えなくなります。このサブセクションではそのようなエラーからどのようにしてバックトレースを取得するかを説明します。デバッグ中に役に立つはずです。
これらの説明はたとえばモードライン構文:eval
(モードラインのデータ構造を参照)のように、再表示から呼び出される以下のようなすべてのフック内で使用されているLispフォームに適用されます。
fontification-functions
(フェイスの自動割り当てを参照)
window-scroll-functions
(ウィンドウのスクロールと変更のためのフックを参照)
再表示から呼び出されたフック関数でエラーが発生すると、エラー処理によってその関数がフックから削除されているかもしれないことに注意してください。したがってそのバグを再現するためにそのフックを何らかの手段、恐らくはadd-hook
を使って再初期化する必要があるでしょう。
これらのような状況下でバックトレースを生成するには、変数backtrace-on-redisplay-error
に非nil
をセットします。エラーが発生するとEmacsはバッファー*Redisplay-trace*にバックトレースをダンプしますが、そのバッファーを自動的にウィンドウには表示しません。これはデバッグ中の再表示弐不必要な破壊を避けるためです。したがってswitch-to-buffer-other-frame
C-x 5 bのようなコマンドによって、このバッファーを自分で表示する必要があります。
再表示から呼び出されたすべてのLispにたいしてエラー発生時のバックトレース生成を有効にするには、この変数に非nil
をセットする。
[ << ] | [ < ] | [ 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] | [ ? ] |
不正な変数のセッティングが関数に問題をもたらすときがあります。元のセッティングを調べるためには、変数の変更時に常にデバッガがトリガーされるようにセットアップするのが手軽な方法です。
この関数はvariableの変更時に常にデバッガが呼び出されるようにアレンジする。
これはwatchpointメカニズムを使用して実装されているので同じような特徴と制限を継承する。つまりvariableのすべてのエイリアスは一緒にwatchされて、watch対象はダイナミック変数のみであり変数から参照されるオブジェクトの変更は検出されない。詳細は変数が変更されたときに実行される関数。を参照のこと。
この関数はvariableにたいするdebug-on-variable-change
の効果をアンドゥする。インタラクティブに呼び出されたときはミニバッファーでvariableの入力をもとめる。variableが省略かnil
ならすべての変数にたいする変更時のブレークを取り消す。カレントで変更時にブレークするようにセットアップされていない変数にたいしてcancel-debug-on-variable-change
の呼び出しは何も行わない。
[ << ] | [ < ] | [ 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
にセットされます。ただしデバッグ中に更にエラーが発生しても、(デフォルトでは)別のデバッガをトリガーすることはありません。それはinhibit-debugger
も非nil
にバインドされているからです。
デバッガはLispインタープリターの状態について想定を行うので、バイトコンパイルされて実行されなければなりません。デバッガがインタープリターに解釈されて実行されているときは、これらの想定は正しくなくなります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
DebuggerモードはEdebugとERT(Edebugとthe ERT manual in ERT: Emacs Lisp Regression Testingを参照)がbacktrace表示にも使用するBacktraceモードから派生したモードです。
backtraceバッファーは実行されている関数と、その関数の引数の値を示します。backtraceバッファー作成時には1つのスタックフレームにたいして1行(非常に長い可能性がある)を表示します(スタックフレームとはLispインタープリターが特定の関数呼び出しに関する情報を記録する場所のこと)。もっとも最近の呼び出しが最上行になります。
backtraceではフレームを記述する行にポイントを移動してフタックフレームを指定できます。ポイントのある行のフレームがカレントフレーム(current frame)とみなされます。
関数名に下線が引かれている場合には、Emacsがソースコードの場所を知っていることを意味します。その関数名をマウスでクリックするか、そこに移動してRETをタイプすることにより、ソースコードをvisitできます。下線のない関数名や変数名にポイントがあるときにRETをタイプした場合には、もしあればそのシンボルにたいするヘルプ情報をhelpバッファーで確認することもできます。M-.にバインドされているxref-find-definitions
コマンドはbacktrace内の任意の識別子にも使用できます(Looking
Up Identifiers in The GNU Emacs Manualを参照)。
backtraceでは長いリストの末尾およびベクターや構造、同じように深くネストされたオブジェクトの終端は下線つきの“...”でプリントされます。“...”上でマウスをクリックするか、その上にポイントがある状態でRETをタイプすることにより、オブジェクトの隠蔽されている部分を表示できます。省略を行う量の制御はbacktrace-line-length
をカスタマイズしてください。
以下はbacktraceの操作と閲覧を行うコマンドのリストです:
カレントスタックフレームのローカル変数の表示を切り替える。
フレームまたは前のフレームの先頭に移動する。
次のフレームの先頭に移動する。
可読性向上のためにポイント位置に行ブレークを追加してトップレベルLispフォームにインデントする。
ポイント位置のトップレベルLispフォームを1行に折り畳む。
ポイント位置のフレームのprint-circle
を切り替える。
ポイント位置のフレームのprint-gensym
を切り替える。
ポイント位置のフレームの“...”で省略されたすべてのフォームを展開する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
(Debuggerモードの)debuggerバッファーでは通常のEmacsコマンドに加えて特別なコマンド、および前セクションで説明したBacktraceモードのコマンドが提供されます。デバッガでもっとも重要な使い方をするのは、制御フローを見ることができるコードをステップ実行するコマンドです。デバッガはインタープリターによって解釈された制御構造のステップ実行はできますが、バイトコンパイル済みの関数ではできません。バイトコンパイル済み関数をステップ実行したいなら、同じ関数の解釈された定義に置き換えてください(これを行なうにはその関数のソースをvisitして、関数の定義でC-M-xとタイプする)。プリミティブ関数のステップ実行にLispデバッガは使用できません。
デバッガのコマンドのいくつかはカレントフレームを処理します。フレームが星印で開始される場合には、そのフレームをexitすることにより再びデバッガが呼び出されることを意味します。これは関数のリターン値の検証に有用です。
以下はDebuggerモードのコマンドのリストです:
デバッガをexitして実行を継続する。これはあたかもデバッガにエンターしなかったかのようにプログラムの実行を再開する(デバッガ内で行った変数値やデータ構造の変更などの副作用は除外)。
実行を継続するが、次にLisp関数が何か呼び出されたときはデバッガにエンターする。これによりある式の下位の式をステップ実行して、下位の式が計算する値や行うことを確認できる。
デバッガにエンターした関数呼び出しにたいして、この方法で作成されたスタックフレームには自動的にフラグがつくため、そのフレームをexitすると再びデバッガが呼び出される。このフラグはuコマンドを使用してキャンセルできる。
カレントフレームにフラグをつけるので、そのフレームをexitするときデバッガにエンターする。この方法でフラグがつけられたフレームは、backtraceバッファーでスターのマークがつく。
カレントフレームをexitしたときデバッガにエンターしない。これはそのフレームのbコマンドをキャンセルする。目に見える効果としてはbacktraceバッファーの行からスターが削除される。
bと同じようにカレントフレームにフラグをつける。その後にcのように実行を継続するが、debug-on-entry
によりセットアップされたすべての関数にたいするbreak-on-entryを一時的に無効にする。
ミニバッファーのLisp式を読み取り、(関連するlexical環境が適切なら)それを評価してエコーエリアに値をプリントする。デバッガは特定の重要な変数とバッファーを処理の一部として変更する。eは一時的にデバッガの外部からそれらの値をリストアするので、それらを調べて変更できる。これによりデバッガはより透過的になる。対照的にデバッガ内でM-:は特別なことを行わず、デバッガ内での変数の値を表示する。このコマンドは既存のエラーの最上位の上に新たなエラーとして式の評価によるエラーを追加しないように、デフォルトでは評価の間はデバッガを抑止する。これはユーザーオプションdebug-allow-recursive-debug
を非nil
値にセットすることによってオーバーライドできる。
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*バッファーで表示するものと等しい。リターン値は常に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 'testing (backtrace))
(progn ...) eval((progn (1+ var) (list '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
ならバックトレースのすべてのスタックフレームはリストとして表示される。これは通常の関数呼び出しとバックトレースの特殊形式の視覚的な違いによるコストをなくして、バックトレースの可読性を向上することが目的。
debugger-stack-frame-as-list
が非nil
なら上記の例は以下のようになる:
----------- Buffer: backtrace-output ------------ (backtrace) (list 'testing (backtrace))
(progn ...) (eval (progn (1+ var) (list '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の末尾に示される。
baseを指定するとframe-numberはfunctionがbaseであるようなフレームの上端から相対的に数えられる。
frame-numberが範囲外ならbacktrace-frame
はnil
をリターンする。
関数mapbacktrace
はバックトレース上の関数がbaseであるようなフレーム(baseが省略かnil
なら先頭)から順に各フレームにたいして一度functionを呼び出す。
functionはevald、func、args、flagsという4つの引数で呼び出される。
そのフレームがまだ引数を評価していない、またはそのフレームがスペシャルフォームならevaldはnil
、argsはフォームのリスト。
フレームが引数を評価して関数を呼び出し済みならevaldはt
、argsは値リスト。flagsはカレントフレームのプロパティのplist。サポートされるプロパティは現在のところ:debug-on-exit
のみであり、そのスタックフレームのdebug-on-exit
フラグがセットされていればt
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
EdebugはEmacs Lispプログラムにたいするソースレベルデバッガです。これにより以下のことができます:
以下の初めの3つのセクションは、Edebugの使用を開始するために十分な説明を行います。
19.2.1 Edebugの使用 | Edebug使用のための手引き。 | |
19.2.2 Edebugのためのインストルメント | Edebugでデバッグするために、コードをインストルメント(計装)しなければならないe | |
19.2.3 Edebugの実行モード | 多かれ少なかれ、ストップする実行モード。 | |
19.2.4 ジャンプ | 特定の位置にジャンプするコマンド。 | |
19.2.5 その他のEdebugコマンド | さまざまなコマンド。 | |
19.2.6 ブレーク | プログラムをストップさせるbreakpointのセット。 | |
19.2.7 エラーのトラップ | Edebugでのエラーのトラップ。 | |
19.2.8 Edebugのビュー | Edebugの内側と外側のビュー。 | |
19.2.9 評価 | Edebugでの式の評価。 | |
19.2.10 評価リストバッファー | Edebugにエンターするたびに値が表示される式。 | |
19.2.11 Edebugでのプリント | プリントのカスタマイズ。 | |
19.2.12 トレースバッファー | バッファー内で採れを生成する方法。 | |
19.2.13 カバレッジテスト | 評価をカバレッジテストする方法。 | |
19.2.14 コンテキスト外部 | Edebugが保存およびリストアするデータ。 | |
19.2.15 Edebugとマクロ | マクロ呼び出しをハンドルする方法の指定。 | |
19.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-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を使用するときだけ機能します。
Edebugがインストルメント中にシンタックスエラー(syntax error:
構文エラー)を検知した場合には、以下のように間違ったコードの箇所にポイントを残してinvalid-read-syntax
エラーをシグナルします:
error→ Invalid read syntax: "Expected lambda expression"
このようにインストルメントに失敗する可能性の1つとして、いくつかのマクロ定義をEmacsが把握していない場合があります。これに対処するためには、インストルメントしようとしている関数を定義しているファイルをロードしてください。
定義からインストルメントを削除するには、単にインストルメントを行わない方法でその定義を再評価するだけです。フォームを絶対にインストルメントせずに評価するには2つの方法があります。それはファイルからのload
による評価と、ミニバッファーからのeval-expression
(M-:)による評価です。
定義からインストルメントを削除する別の方法はedebug-remove-instrumentation
コマンドの使用です。これはインストルメントしたすべてからインストルメントを削除することもできます。
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しません。
コマンドh、f、oは通常は“Break”を表示して、正に評価した結果を表示する前にedebug-sit-for-seconds
の間、一時停止します。edebug-sit-on-break
をnil
にセットすることによりこの一時停止を回避できます。Edebugのオプションを参照してください。
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-pop-to-backtrace
)。
backtraceとbacktraceに作用するコマンドの説明はバックトレースを参照のこと。
backtrace内でEdebugの関数を確認したければM-x edebug-backtrace-show-instrumentation、それらを再び隠すにはM-x edebug-backtrace-hide-instrumentationを使用する。
backtraceのフレームの先頭が‘>’なら、そのフレームにたいするソースコードの場所をEdebugが知っていることを意味する。カレントフレームのソースコードにジャンプするにはsを使用する。
実行を継続したときにbacktraceバッファーは自動的にkillされる。
Edebugから再帰的にEdebugをアクティブにするコマンドを呼び出すことができます。Edebugがアクティブなときは常にqによトップレベルの終了、またはC-]による再帰編集1レベルの中断ができます。dによってすべての未解決な評価のbacktraceを表示できます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Edebugのstepモードは、次のストップポイントに達したときに実行をストップします。一度開始されたEdebugの実行をストップするには、他に3つの方法があります。それはbreakpoint、グローバルbreak条件、およびソースbreakpointです。
19.2.6.1 Edebugのブレークポイント | ストップポイントのbreakpoint。 | |
19.2.6.2 グローバルなブレーク条件 | イベントによるbreak。 | |
19.2.6.3 ソースブレークポイント | ソースコードに埋め込まれたbreakpoint。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Edebugを使用しているときは、テスト中のプログラム内にbreakpointを指定できます。breakpointとは実行がストップされる場所のことです。Edebugの使用で定義されている任意のストップポイントにbreakpointをセットできます。breakpointのセットと解除で影響を受けるストップポイントは、ソースコードバッファー内でポイント位置、またはポイント位置の後の最初のストップポイントです。以下はEdebugのbreakpoint用のコマンドです:
ポイント位置、またはポイント位置の後のストップポイントにbreakpointをセットする(edebug-set-breakpoint
)。プレフィクス引数を使用すると、それは一時的なbreakpointとなり、プログラムが最初にそこで停止したときに解除される。breakpoint位置にはedebug-enabled-breakpoint
またはedebug-disabled-breakpoint
フェイスのオーバーレイが配置される。
(もしあれば)ポイント位置、またはポイント位置の後のストップポイントにあるbreakpointを解除(unset)する(edebug-unset-breakpoint
)。
カレントフォーム内のすべてのbreakpointにポイントのセットを解除する(edebug-unset-breakpoints
)。
ポイント付近のbreakpointの有効と無効を切り替える(edebug-toggle-disable-breakpoint
)。このコマンドは主に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はその式への干渉を最小限にしようと努める。評価した結果はエコーエリア、プレフィックス引数を与えられた場合には新たにバッファーをポップアップしてそこに結果を見栄えよくプリントする。
このコマンドはデフォルトでは評価の間はデバッガを抑制する。これにより評価される式内のエラーが新たなエラーとして既存のエラーの最上位に追加されることはなくなる。ユーザーオプションdebug-allow-recursive-debug
を非nil
にセットすれば、これをオーバーライドできる。
Edebug自身のコンテキスト内で式expを評価する(eval-expression
)。
ポイントの前の式をEdebugのコンテキスト外で評価する(edebug-eval-last-sexp
)。プレフィックス引数が0(C-u
0 C-x C-e)なら、(文字列やリストのような)長いアイテムを短縮しない。それ以外のプレフィックスなら別のバッファーに値を見栄えよくプリントする。
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
)。プレフィクス引数が0(C-u
0 C-j)なら、(文字列やリストのような)長いアイテムを短縮しない。
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 (list 'x 'y)) (setcar a a)
print-circle
が非nil
なら、プリント関数(prin1
等)はa
を‘#1=(#1#
y)’のようにプリントします。‘#1=’という表記はその後の構造をラベル‘1’とラベル付けして、‘#1#’表記はその前にラベル付けされた構造を参照しています。この表記はリストとベクターの任意の共有要素に使用されます。
非nil
なら結果をプリントするときEdebugはprint-circle
をこの値にバインドする。デフォルト値はt
。
プリントをどのようにカスタマイズできるかに関する詳細は出力関数を参照してください。
[ << ] | [ < ] | [ 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が完全に透過的になるのに失敗する理由を正確に説明します。
19.2.14.1 停止するかどうかのチェック | 何を行うかをEdebugが決定するタイミング。 | |
19.2.14.2 Edebugの表示の更新 | Edebugがディスプレイを更新するタイミング。 | |
19.2.14.3 Edebugの再帰編集 | Edebugが実行をストップするタイミング。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Edebugにエンターするときは常に特定のデータの保存とリストアを行なう必要があり、それはトレース情報を作成するか、あるいはプログラムを停止するかを決定する前に行なう必要があります。
max-lisp-eval-depth
(evalについてを参照)はEdebugがスタックに与える影響の低減効果を高める。しかしそれでもEdebug使用時にスタック空間を使い切ってしまうことがあり得る。非常に大きいクォートされたリストを含むコードをインストルメントすることによってEdebugが再帰深さの制限に達してしまうようなら、edebug-max-depth
の値を大きくすることもできる。
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のオプションを参照)。edebug-save-windows
の値がリストの場合には、保存とリストアはリストされたウィンドウにたいしてのみ行われる。
エラーやquitではウィンドウ構成はリストアされないが、save-excursion
がアクティブなら、たとえエラーやquitのときでも外部の選択されたウィンドウが再選択される。
ただしソースコードバッファーのウィンドウの開始位置と水平スクロールはリストアされないので、表示はEdebug内で整合性が保たれたままとなる。
外部のウィンドウ構成の保存やリストアによってデバッグ中のLispプログラムが作用するバッファーのポイントが変更されてしまうときがある(特にプログラムがポイントを移動する場合)。もしこれが発生してデバッグに干渉するようなら、edebug-save-windows
にnil
をセットすることをお勧めする(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が正しくマクロを呼び出す式をインストルメントするには、いくつかの特定な配慮が必要になります。このサブセクションでは、その詳細を説明します。
19.2.15.1 マクロ呼び出しのインストルメント | 基本的な問題点。 | |
19.2.15.2 仕様リスト | 式の複雑なパターンを指定する方法。 | |
19.2.15.3 仕様でのバックトレース | マッチに失敗したときEdebugが行なうこと。 | |
19.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に仕様が確実に解るように留意してください。別ファイルで定義されたマクロを使用する関数をインストルメントする場合には、関数を含むファイル内のrequire
フォームを評価するか、あるいはマクロを含むファイルを明示的にロードする必要があるかもしれません。マクロの定義がeval-when-compile
でラップされていれば、それを評価する必要があるでしょう。
def-edebug-spec
によりマクロ定義から個々のマクロにたいしてEdebug仕様を定義することもできます。Lispで記述されたマクロ定義にたいしてはdebug
宣言を追加するほうが好ましく便利でもありますが、def-edebug-spec
ではCで実装されたスペシャルフォームにたいしてEdebug仕様を定義することが可能になります。
マクロmacro呼び出しのどの式が評価される式かを指定する。specificationはEdebug仕様である。どちらの引数も評価されない。
引数macroには単なるマクロ名ではない、任意の実シンボルを指定できる。
以下はspecificationに指定できるシンボルと、引数を処理する方法のテーブルです。
t
すべての引数は評価のためにインストルメントされる。(body)
の省略形。
そのシンボルはかわりに使用される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
評価される単一の式。インストルメントされる。評価前にマクロが式のをlambda
でラップしていれば、かわりにdef-form
を使用すること(以下のdef-form
を参照)。
place
汎変数(generalized variable)。ジェネリック変数を参照のこと。
body
&rest
form
の短縮形(以下の&rest
を参照)。評価前にマクロが式のをlambda
でラップしていれば、かわりにdef-form
を使用すること(以下のdef-form
を参照)。
lambda-expr
クォートされないラムダ式。
&optional
仕様リスト内の後続の要素はオプション。マッチしない要素が出現するとEdebugはこのレベルのマッチングを停止する。
後続が非オプションの要素であるような数個の要素をオプションにするだけなら、[&optional
specs…]
を使用する。複数の要素すべてのマッチや非マッチを指定するには、&optional
[specs…]
を使用する。defun
の例を参照のこと。
&rest
仕様リスト内の後続のすべての要素は0回以上繰り返される。しかし最後の繰り返しでは、仕様リスト内のすべての要素にたいするマッチングの前に式が終了しても問題はない。
数個の要素を繰り返すには[&rest
specs…]
を使用する。各繰り返しにおいてすべてマッチしなければならない複数要素を指定するには、&rest
[specs…]
を使用する。
&or
仕様リスト内の後続の各要素は選択肢である。選択肢の1つがマッチしなければならず、マッチしなければ&or
仕様は失敗する。
&or
に続く各リスト要素は単一の選択肢である。複数のリスト要素を単一の選択肢にグループ化するには、それらを[…]
で括る。
¬
後続の各要素は&or
が使用されたときのように選択肢にマッチするが、要素がマッチしたら失敗となる。マッチする要素がなければ何もマッチされないが¬
仕様は成功となる。
&define
フォームを定義する仕様であることを示す。フォームを定義するEdebugの定義は、後刻(フォーム定義の実行後に)保存および実行される1つ以上のコードを含んだフォーム。
フォーム定義自体はインストルメントされない(つまりEdebugはフォーム定義の前後でストップしない)が、フォーム内部は通常はインストルメントされるであろう。&define
キーワードはリスト仕様の最初の要素であること。
nil
カレント引数レベルでマッチさせる引数が存在しなければ成功し、それ以外は失敗する。部分リスト仕様とバッククォートの例を参照のこと。
gate
¶引数はマッチされないがgateを通じたバックトラックは、このレベルの仕様の残りをマッチングする間は無効にされる。これは主に特定の構文エラーメッセージを一般化するために使用される。詳細は仕様でのバックトレース、およびlet
の例も参照のこと。
&error
&error
の後にはedebug仕様のエラーメッセージ(文字列)が続くこと。これはインストルメントをabortして、メッセージをミニバッファーに表示する。
&interpose
残りのコードのパースを関数に制御させる。これは&interpose spec fun
args...
のような形式をとり、Edebugがコードにたいして最初にspecをマッチして、それからspec
にマッチしたコードとともにfun、パース関数pf、最後にargs...を呼び出すことを意味する。パース関数は、残りのコードのパースに使用するための仕様リストを単一の引数として期待する。これは正確に1回呼び出されて、funがリターンすることを期待されるインストルメント済みコードをリターンすること。たとえば(&interpose
symbolp
pcase--match-pat-args)
は最初の要素がシンボルであるようなsexpにマッチしてから、pcase--match-pat-args
はpcase--match-pat-args
に照らしてheadとなるシンボルに対応するspecを照合、その後にそれらを引数として受け取るpfに渡す。
other-symbol
¶仕様リスト内のその他の要素は、述語(predicate)かインダイレクト仕様(indirect specification)である。
シンボルがEdebug仕様をもつなら、インダイレクト仕様(indirect
specification)はシンボル位置に使用されるリスト仕様か、引数を処理するための関数のいずれかである。この仕様はdef-edebug-spec
で定義できる。
シンボルelementの箇所で使用するspecificationを定義する。specificationはリストでなければ鳴らす。
それ以外ならシンボルは述語(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 [prestring] spec
[poststring] fun
args...
という形式をとり、Edebugがコードにたいしてspecをマッチしてから結合したカレント名、args...、prestring、spec
にマッチしたコード、poststringとともにfunを呼び出すことを意味する。funが未指定なら、、デフォルトは引数を(前の名前と新しい名前の間に@
を置いて)結合する関数。
name
引数(シンボル)は定義フォームの名前。[&name symbolp]
の省略形。
定義フォームは名前フィールドをもつ必要はなく、複数の名前フィールドをもつかもしれない。
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
)をマッチングする間、バックトラックは無効になっています。これらの仕様は任意のフォームにマッチするので、何らかのエラーが発生するとしたらそれは高位レベルではなく、そのフォーム自体の内部でなければなりません。
バックトラックはクォートされたシンボル、文字列仕様、または&define
キーワードとのマッチに成功した後にも無効になります。なぜなら通常これは構文が認識されたことを示すからです。しかし同じシンボルで始まる一連の選択肢構文がある場合には、たとえば["foo"
&or [first case] [second case]
...]
のように、通常は選択肢の外部にそのシンボルをファクタリングすることによりこの制約に対処できます。
ほとんどのニーズは、バックトラックを自動的に無効にする、これら2つの方法で満足させることができますが、gate
仕様を使用して明示的にバックトラックを無効にするほうが便利なときもあります。これは高位に適用可能な選択肢が存在しないことが分かっている場合に有用です。let
仕様の例を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下で提供する例から学ぶことにより、Edebug仕様の理解が容易になるでしょう。
与えられたデータりすとにテストを実行する架空nマクロmy-test-generator
を考えてみましょう。edebug-eval-macro-args
(マクロ呼び出しのインストルメントを参照)によって制御されるようにEdebugのデフォルトの振る舞いでは引数をコードとしてインストルメントしませんが、引数がデータであることをドキュメントするのは役に立つかもしれません。
(def-edebug-spec my-test-generator (&rest sexp))
スペシャルフォーム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-elem-spec 'lambda-list
'(([&rest arg]
[&optional ["&optional" arg &rest arg]]
&optional ["&rest" arg]
)))
(def-edebug-elem-spec 'interactive
'(&optional &or stringp def-form)) ; def-form
に注目
以下のバッククォートにたいする仕様はドットリストにマッチさせる方法と、nil
を使用して再帰を終了させる方法を説明するための例です。またベクターのコンポーネントをマッチさせる方法も示しています(Edebugにより定義される実際の仕様は少し異なり、失敗するかもしれない非常に深い再帰を引き起こすためドットリストについてはサポートしない)。
(def-edebug-spec \` (backquote-form)) ; 単なる明確化用エイリアス
(def-edebug-elem-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
に適用される。
このオプションの切り替えにはコマンドM-x edebug-all-defsを使用する。Edebugのためのインストルメントを参照のこと。
これが非nil
の場合にはeval-defun
、eval-region
、eval-buffer
はたとえフォームが何も定義していなくても、すべてのフォームをインストルメントする。これはロードとミニバッファー内の評価には適用されない。
このオプションの切り替えにはコマンドM-x edebug-all-formsを使用する。Edebugのためのインストルメントを参照のこと。
これが非nil
なら、すべてのマクロ引数が生成されるコード内にインストルメントされる。debug
宣言はこのオプションをオーバーライドする。ある引数を評価して他の引数は評価しないマクロにたいする例外を指定するためには、debug
宣言を指定するためはEdebugフォーム仕様を使用すること。
このオプションが非nil
なら、Edebugはウィンドウ構成の保存とリストアを行う。これには幾分時間を要するので、あなたのプログラムがウィンドウ構成に何が起こったかを気にしないようなら、この変数にはnil
をセットしたほうがよい。このオプションがデフォルト値のままだとウィンドウ構成の保存やリストアの結果として、デバッグ中のプログラムに含まれるバッファーのポイント位置がEdebugに上書きされてしまう場合もnil
にセットすることをお勧めする。これはあなたのプログラムがこのようなバッファーの1つ以上でポイントを移動した場合に起こり得る。他にも後述のedebug-save-displayed-buffer-points
のカスタマイズを試してみるという手もある。
edebug-save-windows
の値がリストなら、リストされたウィンドウだけが保存およびリストアされる。
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外部で実行されている任意のキーボードマクロの定義または実行を継続する。これはデバッグされないので慎重に使用すること。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する。エラーは無視される。グローバルなブレーク条件を参照のこと。
実行モードがtraceかcontinueでbreakpointに達した際に一時停止する秒数。Edebugの実行モードを参照のこと。
breakpointに達したときにedebug-sit-for-seconds
の間、一時停止するかどうか。nil
で一時停止の抑止、非nil
なら一時停止を許可。
デフォルトでは、このalistにはキーがedebug
で3つの関数edebug-enter
、edebug-before
、edebug-after
からなるリストという1つのエントリーが含まれる。これらの関数はインストルメントされるコードに挿入される関数のデフォルト実装である。Edebugの全般的な挙動を変更するためには、このデフォルトエントリーを変更する。
Edebugの挙動はこのalistにエントリーにユーザーが選択したキーと3つの関数を追加することにより、定義ごとにもとづいて変更もできる。それからインストルメントされた定義のシンボルプロパティedebug-behavior
に新たなエントリーのキーをセットすれば、Edebugはその定義にたいして自身の関数を呼び出す箇所で新たな関数を呼び出す。
定義やクロージャのbodyをラップした後にEdebugが実行する関数。Edebugが自身のデータを初期化後に、この関数は定義に関連付けられたシンボル(Edebugが定義または生成した実際のシンボルかもしれない)を単一の引数として呼び出される。この関数はEdebugによりインストルメントされる各定義のシンボルプロパティedebug-behavior
をセットするために使用されるかもしれない。
使用前にEdebugのインストルメントの検査や修正を行うには、インストルメントするトップレベルのフォームを単一の引数として受け取り、その後にEdebugがインストルメントの最終結果として使用することになる同一フォームあるいは置換フォームをリターンする関数をこの変数にセットする。
[ << ] | [ < ] | [ 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 (
end-of-defun
。Moving by Defuns in The GNU Emacs
Manualを参照)とタイプして、そのdefunの最後と思われる箇所に移動するか確認する方法です。もし移動しなければ、問題はそのdefunの内部にあります。
マッチしないカッコがLispにおいてもっとも一般的な構文エラーなので、これらのケースにたいしてさらにアドバイスすることができます(Show Parenモードを有効にしてコードにポイントを移動するだけでカッコの不一致を探しやすくなるだろう)。
19.3.1 過剰な開カッコ | 誤った開カッコと閉カッコの欠落を探す方法。 | |
19.3.2 過剰な閉カッコ | 誤った閉カッコと開カッコの欠落を探す方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
カッコがマッチしないdefunを探すのが、最初のステップです。過剰な開カッコが存在する場合は、ファイルの終端に移動してC-u C-M-u (
backward-up-list
。Moving by Parens in The GNU Emacs
Manualを参照)とタイプします。これにより、カッコがマッチしない最初のdefunの先頭に移動するでしょう。
何が間違っているのか正確に判断するのが次のステップです。これを確実に行なうにはプログラムを詳しく調べる以外に方法はありませんが、カッコがあるべき箇所を探すのに既存のインデントが手掛かりになることが多々あります。C-M-q
(indent-pp-sexp
。Multi-line Indent in The GNU Emacs
Manualを参照)で再インデントして何が移動されるか確認するのが、この手掛かりを使用するもっとも簡単な方法です。しかし、行うのはちょっと待ってください!
まず続きを読んでからにしましょう。
これを行なう前にdefunに十分な閉カッコがあるか確認します。十分な閉カッコがなければ
C-M-qがエラーとなるか、そのdefunからファイル終端までの残りすべてが再インデントされます。その場合にはdefunの最後に移動して、そこに閉カッコを挿入します。そのdefunのカッコの釣り合いがとれるまでは、defunの最後に移動するのにC-M-e
(end-of-defun
)は使用できません(失敗する)。
これでdefunの先頭に移動してC-M-qとタイプすることができます。通常は一定のポイントからその関数の最後までのすべての行が、右へとシフトされるでしょう。これはおそらくそのポイント付近で閉カッコが欠落していたり不要な開カッコがあります(しかしこれを真実と仮定せずコードを詳しく調べること)。不一致箇所を見つけたら、元のインデントはおそらく意図されたカッコに適しているはずなので、C-_
(undo
)でC-M-qをアンドゥしてください。
問題をfixできたと思った後に、再度C-M-qを使用します。実際に元のインデントが意図したカッコのネストに適合していて、足りないカッコを追加していたら、C-M-qは何も変更しないはずです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
過剰な閉カッコへの対処は、まずファイルの先頭に移動してからカッコのマッチしないdefunを探すためにC-u -1 C-M-u
(引数-1でbackward-up-list
)をタイプします。
それからdefunの先頭でC-M-f (forward-sexp
。Expressions in The
GNU Emacs
Manualを参照)をタイプして、実際にマッチする閉カッコを探します。これによりdefunの終端より幾分手前の箇所に移動するでしょう。その付近に間違った閉カッコが見つかるはずです。
そのポイントに問題が見つからない場合には、そのdefunの先頭でC-M-q
(indent-pp-sexp
)をタイプするのが次のステップです。ある行範囲はおそらく左へシフトするでしょう。その場合には欠落している開カッコや間違った閉カッコは、おそらくそれらの行の1行目の近くにあるでしょう(しかしこれを真実と仮定せずコードを詳しく調べること)。不一致箇所が見つけたら、元のインデントはおそらく意図されたカッコに適しているはずなのでC-_
(undo
)で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をタイプします。CPU使用率の定期的なサンプリング(cpu
、かメモリー割り当て時(memory
)、またはその両方を選択できます。それから高速化したいコードを実行します。その後にM-x
profiler-reportとタイプすると、プロファイルに選択した各タイプ(cpuとmemory)によりサンプリングされたCPU使用率がsummaryバッファーに表示されます。reportバッファーの名前にはレポートが生成された時刻が含まれるので、前の結果を消去せずに後で他のレポートを生成できます。プロファイリングが終了したらM-x
profiler-stopとタイプしてください(プロファイリングに関連したオーバーヘッドが若干あるので実際に調査したいコードの実行中以外にアクティブのままに放置することは推奨しない)。
profiler reportバッファーでは、各行に呼び出された関数、その前にプロファイリングが開始されてから使用したCPUリソースの絶対時間とパーセンテージが表示されます。関数名の左にシンボル‘+’のある行ではRETをタイプして行を展開して高位レベルの関数に呼び出された関数を確認できます。関数ツリー配下全体の呼び出しを確認するにはプレフィクス引数を使用します(C-u RET)。もう一度RETをタイプすれば元の状態へと行が折り畳まれます。
jかmouse-2を押下するとポイント位置の関数の定義にジャンプします。dを押下すると関数のドキュメントを閲覧できます。C-x C-wを使用してプロファイルをファイルに保存できます。=を使用すれば2つのプロファイルを比較することができます。
elpライブラリーはプロファイルしたいLisp関数が事前に解っているときに有用な別のアプローチを選択肢として提供します。このライブラリーの使用するには、まずelp-function-list
に関数シンボルのリスト(プロファイルしたい関数)をセットします。それから関数をプロファイル用にアレンジするためにM-x elp-instrument-list RET nil RETとタイプします。プロファイルしたいコードの実行後にM-x elp-resultsを呼び出してカレント結果を表示します。処理手順の詳細についてはelp.elファイルを参照してください。このアプローチはLispで記述された関数のプロファイリングに限定されており、Emacsプリミティブのプロファイルはできません。
benchmarkライブラリーを使用して個々のEmacs
Lispフォームの評価に消費される時間を計測できます。benchmark.el内の関数benchmark-call
、同様にマクロbenchmark-run
とbenchmark-run-compiled
、benchmark-progn
を参照してください。フォームをインタラクティブに時間計測するためにbenchmark
コマンドも使用できます。
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)についても説明します。ストリームとは、(読み取りでは)テキストがどこから取得されるか、(プリントでは)テキストをどこに出力するかを指定します。
20.1 読み取りとプリントの概念 | ストリーム、読み取り、プリントの概観。 | |
20.2 入力ストリーム | 入力ストリームとして使用できる、さまざまなデータ型。 | |
20.3 入力関数 | テキストからLispオブジェクトを読み取る関数。 | |
20.4 出力ストリーム | 出力ストリームとして使用できる、さまざまなデータ型。 | |
20.5 出力関数 | テキストとしてLispオブジェクトをプリントする関数。 | |
20.6 出力に影響する変数 | プリント関数が何を行うか制御する変数。 | |
20.7 出力変数のオーバーライド |
[ << ] | [ < ] | [ 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モード(batchモードを参照)で実行されている場合には、ミニバッファーのかわりに標準入力が使用される。たとえば、
(message "%s" (read t))
batchモードでは標準入力から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)
この関数はread
が行うようにstreamからテキストとして1つの式を読み取るが、読み込んだシンボルにたいしてそのシンボルがstreamで出現した位置を読み込んだシンボルに付加する。効率上の理由によりシンボルnil
だけは位置を付加しない。位置をもつシンボルを参照のこと。これはバイトコンパイラーによって使用される関数である。
この変数はデフォルト入力ストリーム(引数streamがnil
のときにread
が使用するストリーム)を保持する。デフォルトはt
で、これはミニバッファーを使用することを意味する。
非nil
なら、この変数は循環構造(circular structure)と共有構造(shared
structures)の読み取りを有効にする。循環オブジェクトの読み取り構文を参照のこと。デフォルト値はt
。
batchモードのEmacsプロセスの標準入力や標準出力のストリームにたいして読み取りや書き込みを行う際には、任意のバイナリーデータにたいしてそのまま読み取りや書き込みを行うことや、改行とCR-LFの変換を何も行わないことを保証することが要求される場合があります。この問題はMS-WindowsとMS-DOSだけに存在する問題であり、POSIXではそのような問題はありません。以下の関数によりEmacsプロセスのすべての標準ストリームのI/Oモードを制御することができます。
streamのI/Oモードのバイナリーとテキストを切り替える。modeが非nil
ならバイナリーモード、それ以外ならテキストモードに切り替える。streamの値はstdin
、stdout
、stderr
のいずれか。この関数は副作用としてstreamの保留中の出力データをすべてフラッシュして、streamの以前のI/Oモードの値をリターンする。POSIXでは常に非nil
値をリターンして、保留中の出力のフラッシュ以外は何も行わない。
この述語はobjectが読み取り可能構文(readable syntax)かどうか、つまり書き込んでからEmacs
Lispリーダーによって読み戻せるかどうかを判定する。読み取り可能でなければnil
、読み取り可能であればこの関数はobjectのプリント表現をリターンする(prin1
を通じて;
出力関数を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
出力ストリームはプリントによって生成された文字に何を行うかを指定します。ほとんどのプリント関数は引数としてオプションで出力ストリームを受け取ります。以下は利用できる出力ストリーム型です:
出力文字はbufferのポイント位置に挿入される。文字が挿入された分だけポイントが進む。
出力文字はmarkerがあるバッファーのマーカー位置に挿入される。文字が挿入された分だけマーカー位置が進む。ストリームがマーカーのときは、そのバッファー内のポイント位置にプリントは影響せず、この種のプリントでポイントは移動しない(マーカー位置がポイント位置かポイント位置より前の場合は除く。通常はテキストの周囲にポイントが進む)。
出力文字は文字を格納する役目をもつfunctionに渡される。この関数は1つの文字を引数に出力される文字の回数呼び出され、格納したい場所にその文字を格納する役目をもつ。
t
¶出力文字はエコーエリアに表示される。Emacsがbatchモード(batchモードを参照)で実行中なら、出力はかわりに標準出力デスクリプターに書き込まれる。
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
を呼び出してリストを文字列に変換すれば、内容をより明解に確認できます。
この関数はデバッグ時の出力ストリームとして有用。これは標準エラーストリームにcharacterを書き込む。
たとえば
(print "This is the output" #'external-debugging-output) -| This is the output ⇒ "This is the output"
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではオブジェクトをオブジェクトのプリント表現に変換して、LispオブジェクトをプリントするLisp関数を説明します。
Emacsプリント関数には、正しく読み取れるように必要なとき出力にクォート文字を追加するものがあります。使用されるクォート文字は‘"’と‘\’です。これらは文字列をシンボルと区別するとともに、文字列とシンボル内の区切り文字が読み取りの際に区切り文字として扱われることを防ぎます。完全な詳細はプリント表現と読み取り構文を参照してください。クォートするかしないかはプリント関数の選択によって指定できます。
そのテキストがLispに読み戻す場合、またはLispプログラマーにLispオブジェクトを明解に説明するのが目的の場合は、曖昧さを避けるためにクォート文字をプリントするべきです。しかしプログラマー以外の人間にたいして出力の見栄えを良くするのが目的なら、通常はクォートなしでプリントしたほうがよいでしょう。
Lispオブジェクトは自己参照ができます。通常の方法で自己参照オブジェクトをプリントするにはテキストが無限に必要であり、その試みにより無限再帰が発生する恐れがあります。Emacsはそのような再帰を検知して、すでにプリントされたオブジェクトを再帰的にプリントするかわりに、‘#level’をプリントします。たとえば以下はカレントのプリント処理において、レベル0のオブジェクトを再帰的に参照することを示しています:
(setq foo (list nil)) ⇒ (nil) (setcar foo foo) ⇒ (#0)
以下の関数ではstreamは出力ストリームを意味します(出力ストリームの説明は前のセクションを参照。デバッグではストリーム値としてexternal-debugging-outputも有用)
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"
overridesが非nil
なら、それはt
(すべてのプリンター関連変数にたいしてデフォルトとしてprin1
を使うよう指示する)、あるいはセッティングのリストであること。詳細については出力変数のオーバーライドを参照のこと。
この関数は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をリターンする。
端末に出力を送信するようなEmacsベースのバッチスクリプトでは、standard-output
に改行文字を書き込むたびにEmacsが自動的に出力を表示する。この関数を使えば最初に改行文字を送信せずにstandard-output
をフラッシュ(flush)できるので、不完全な行を表示することができる。
この関数は同じ引数でprin1
がプリントするテキストを含む文字列をリターンする。
(prin1-to-string 'foo) ⇒ "foo"
(prin1-to-string (mark-marker)) ⇒ "#<marker at 2773 in strings-ja.texi>"
If overrides is non-nil
, it should either bet
(which tellsprin1
to use the defaults for all printer related variables), or a list of settings. See 出力変数のオーバーライド, for details.
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)な方法でこれを行う。すなわちこの関数は人間がより読みやすいようにオブジェクトのインデントとパディングを行う。
任意のバイナリーデータを書き込んだり非POSIXホストで改行変換を回避するためにこのセクションで説明した関数を使用してbatchモードでバイナリーI/Oモードを使用する必要がある場合にはset-binary-modeを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この変数の値はデフォルト出力ストリーム(stream引数がnil
のときプリント関数が使用するストリーム)である。デフォルトはt
で、これはエコーエリアに表示することを意味する。
これが非nil
なら、省略されたリーダー構文(たとえば(quote
foo)
を'foo
、(function
foo)
を#'foo
のように)を使用してクォートされたフォームをプリントすることを意味する。デフォルトはt
。
この変数が非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
は、文字列内のコントロール文字をバックスラッシュシーケンスとしてプリントする。この変数とprint-escape-newlines
がいずれも非nil
なら改行と改頁には後者が優先される。
この変数が非nil
なら、クォートつきでプリントするプリント関数prin1
とprint
は文字列内のユニバイトの非ASCII文字を無条件でバックスラッシュシーケンスとしてプリントする。
これらの関数は出力ストリームがマルチバイトバッファー、あるいはマーカーがマルチバイトバッファーをポイントするときは、この変数の値に関わらずユニバイト非ASCII文字にたいしてバックスラッシュシーケンスを使用する。
この変数が非nil
なら、クォートつきでプリントするプリント関数prin1
とprint
は、文字列内のマルチバイトの非ASCII文字を無条件でバックスラッシュシーケンスとしてプリントする。
これらの関数は出力ストリームがユニバイトバッファー、あるいはマーカーがユニバイトバッファーをポイントするときは、この変数の値に関わらずマルチバイト非ASCII文字にたいしてバックスラッシュシーケンスを使用する。
この変数は文字列のプリントにおいてテキストプロパティ‘charset’のプリントを制御する。値はnil
、t
、またはdefault
のいずれか。
値がnil
ならcharset
テキストプロパティを決してプリントせず、t
なら常にプリントする。
値がdefault
なら“予期せぬ(unexpected)”charset
プロパティがある場合だけcharset
テキストプロパティをプリントする。ASCII文字ではすべてのcharsetが“期待された(expected)”ものとみなされる。それ以外なら文字の期待されるcharset
プロパティはchar-charset
により与えられる。
この変数の値は任意のリスト、ベクター、ブールベクターをプリントする際の最大要素数である。プリントされるオブジェクトがこれより多くの要素をもつ場合は、省略記号(“...”)で省略される。
値が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
なら、この変数はプリント時の循環構造と共有構造の検出を有効にする。循環オブジェクトの読み取り構文を参照のこと。
デフォルトではEmacsは読み取り可能ではないオブジェクトを‘#<...>"’のようにプリントする。たとえば:
(prin1-to-string (make-marker)) ⇒ "#<marker in no buffer>"
この変数が非nil
なら、これらのオブジェクトにたいするプリントを処理するために呼び出される関数であること。この関数はそのオブジェクト、およびプリント関数(出力関数を参照)によって使用されるnoescapeフラグという2つの引数で呼び出される。
この関数はnil
(通常のようにオブジェクトをプリント)、文字列(プリントする文字列)、あるいは他のオブジェクト(そのオブジェクトをプリントしない)のいずれかをリターンすること。たとえば:
(let ((print-unreadable-function (lambda (object escape) "hello"))) (prin1-to-string (make-marker))) ⇒ "hello"
非nil
なら、この変数はプリント時のインターンされていないシンボル(シンボルの作成とinternを参照)の検出を有効にする。これが有効なら、インターンされていないシンボルはプレフィックス‘#:’とともにプリントされる。このプレフィックスは、Lispリーダーにたいしてインターンされていないシンボルを生成するよう告げる。
非nil
なら、複数のプリント呼び出しを通じて通番が振られることを意味する。これは‘#n=’ラベルと‘#m#’参照にたいしてプリントされる数字に影響する。この変数をsetq
でセットしてはならない。let
を使用して一時的にt
にバインドすること。これを行う場合はprint-number-table
もnil
にバインドすること。
この変数はprint-circle
機能を実装するために、プリント処理で内部的に使用されるベクターを保持する。print-continuous-numbering
をバインドするときにこの変数をnil
にバインドする以外は、この変数を使用するべきではない。
この変数は浮動小数点数をプリントする方法を指定する。デフォルトはnil
で、これは情報を失わずにその数値を表せるもっとも短い出力を使用することを意味する。
出力フォーマットをより精密に制御するために、この変数に文字列をセットできる。この文字列にはCのsprintf
関数で使用される‘%’指定子をセットする。この変数で使用することのできる制限についての詳細は、この変数のドキュメント文字列を参照のこと。
この変数が非nil
ならグラフィックベース文字を表す整数はLispの文字構文を用いてプリントされる(基本的な文字構文を参照)。それ以外の数は通常の方法でプリントされる。たとえばリスト(4 65 -1 10)
は‘(4 ?A -1
?\n)’のようにプリントされるだろう。
正確にはUnicode一般カテゴリーLetter、Number、Punctuation、Symbol、Private-useに属する文字(文字のプロパティを参照)を表す文字、同じように改行のようなエスケープシーケンスを独自にもつコントロール文字にたいする値は、文字構文を使用してプリントされる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
前のセクション(出力関数を参照)では、Emacs
Lispプリンターが出力用にデータをどのようにフォーマットするかを制御するさまざまな変数を説明しました。これらは一般的には変更用にユーザーが利用できますが、デフォルトのフォーマットでデータを出力したり、あるいは他の手段でユーザーセッティングをオーバーライドしたい場合があるかもしれません。たとえばEmacs
Lispのデータをファイルに格納したい場合には、そのデータがprint-length
のセッティングによって短縮されたくはないでしょう。
そのためにprin1
およびprin1-to-string
という関数にはオプションとしてoverrides引数があります。この引数にはt
(すべてのプリント用変数をデフォルト値にリセット)、あるいはいくつかの変数にたいするセッティングのリストのいずれかを指定できます。このリストの要素はそれぞれt
(“デフォルトへのリセット”を意味しており、通常はリストの最初の要素)、あるいはcar
が出力変数を意味するシンボルでcdr
がその変数にたいする値であるようなペアーを指定できます。
たとえば以下はデフォルトだけを用いてプリントします:
(prin1 object nil t)
以下はカレントのプリントセッティングを用いてobjectをプリントしますが、print-length
の値を5にオーバーライドします:
(prin1 object nil '((length . 5)))
そして最後はprint-length
を5にバインドする以外はデフォルトセッティングを用いてobjectをプリントする例です:
(prin1 object nil '(t (length . 5)))
以下は使用できるシンボルと、それらのシンボルがマップされる変数のリストです:
length
print-length
をオーバーライドする。
level
print-level
をオーバーライドする。
circle
print-circle
をオーバーライドする。
quoted
print-quoted
をオーバーライドする。
escape-newlines
print-escape-newlines
をオーバーライドする。
escape-control-characters
print-escape-control-characters
をオーバーライドする。
escape-nonascii
print-escape-nonascii
をオーバーライドする。
escape-multibyte
print-escape-multibyte
をオーバーライドする。
charset-text-property
print-charset-text-property
をオーバーライドする。
unreadeable-function
print-unreadable-function
をオーバーライドする。
gensym
print-gensym
をオーバーライドする。
continuous-numbering
print-continuous-numbering
をオーバーライドする。
number-table
print-number-table
をオーバーライドする。
float-format
float-output-format
をオーバーライドする。
integers-as-characters
print-integers-as-characters
をオーバーライドする。
将来的には変数に直接マップされない、このパラメーターだけを介してのみ使用できるオーバーライドが更に提供されるかもしれません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ミニバッファー(minibuffer)とは、単一の数プレフィックス引数(numeric prefix argument)より複雑な引数を読み取るためにEmacsコマンドが使用する特別なバッファーのことです。これらの引数にはファイル名、バッファー名、(M-xでの)コマンド名が含まれます。ミニバッファーはフレームの最下行、エコーエリア(エコーエリアを参照)と同じ場所に表示されますが、引数を読み取るときだけ使用されます。
21.1 ミニバッファーの概要 | ミニバッファーに関する基本的な情報。 | |
21.2 ミニバッファーでのテキスト文字列の読み取り | そのままのテキスト文字列を読み取る方法。 | |
21.3 ミニバッファーでのLispオブジェクトの読み取り | Lispオブジェクトや式を読み取る方法。 | |
21.4 ミニバッファーのヒストリー | ユーザーが再利用できるように以前のミニバッファー入力は記録される。 | |
21.5 入力の初期値 | ミニバッファーにたいして初期内容を指定する。 | |
21.6 補完 | 補完の呼び出しとカスタマイズ方法。 | |
21.7 Yes-or-Noによる問い合わせ | 問いにたいし単純な答えを求める。 | |
21.8 複数の問いを尋ねる | 複雑な問い合わせ。 | |
21.9 パスワードの読み取り | 端末からパスワードを読み取る。 | |
21.10 ミニバッファーのコマンド | ミニバッファー内でキーバインドとして使用されるコマンド。 | |
21.11 ミニバッファーのウィンドウ | 特殊なミニバッファーウィンドウを処理する。 | |
21.12 ミニバッファーのコンテンツ | どのようなコマンドがミニバッファーのテキストにアクセスするか。 | |
21.13 再帰的なミニバッファー | ミニバッファーへの再帰的なエントリーが許容されるかどうか。 | |
21.14 対話の抑止 | 対話が不可能な際のEmacsの実行。 | |
21.15 ミニバッファー、その他の事項 | カスタマイズ用のさまざまなフックや変数。 |
[ << ] | [ < ] | [ 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*’という名前になります。再帰ミニバッファーはミニバッファー名の最後の数字を増加することにより命名されます(名前はスペースで始まるので通常のバッファーリストには表示されない)。再帰ミニバッファーが複数ある場合は、最内の(もっとも最近にエンターされた)ミニバッファーがアクティブミニバッファー(active
minibuffer)です( RET
(exit-minibuffer
)をタイプして終了できるミニバッファー)。わたしたちは通常はこれを、所謂
ミニバッファーと呼んでいます。変数enable-recursive-minibuffers
、またはコマンドシンボルのその名前のプロパティをセットすることにより再帰ミニバッファーを許可したり禁止できます(再帰的なミニバッファーを参照)。
他のバッファーと同様、ミニバッファーは特別なキーバインドを指定するためにローカルキーマップ(キーマップを参照)を使用します。ミニバッファーを呼び出す関数も、処理を行うためにローカルマップをセットアップします。補完なしのミニバッファーローカルマップについてはミニバッファーでのテキスト文字列の読み取りを参照してください。補完つきのミニバッファーローカルマップについては補完を行うミニバッファーコマンドを参照してください。
アクティブミニバッファーのメジャーモードは、通常はminibuffer-mode
です。これは特別な機能をもたない、Emacsの内部モードです。ミニバッファーのセットアップをカスタマイズするには、minibuffer-mode-hook
よりminibuffer-setup-hook
(ミニバッファー、その他の事項を参照)の使用を推奨します。なぜならminibuffer-mode-hook
はセットアップの後、ミニバッファーが完全に初期化された後に実行されるからです。
ミニバッファーが非アクティブのときのメジャーモードは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 入力関数を参照)。
引数defaultはヒストリーコマンドを通じて利用できるデフォルト値を指定する。値には文字列、文字列リスト、またはnil
を指定する。文字列と文字列リストは、ユーザーがM-nで利用可能な“未来のヒストリー(future
history)”になる。更に(keymap引数を通じて)呼び出しで補完が提供された場合には、defaultの値をM-nで使い果たすと、その補完候補が“未来のヒストリー”に追加される。minibuffer-default-add-functionを参照のこと。
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
。historyがシンボルt
なら、ヒストリーを記録しない。同様にオプションでヒストリーリスト内の開始位置を指定できる。ミニバッファーのヒストリーを参照のこと。
変数minibuffer-allow-text-properties
が非nil
なら、リターンされる文字列にはミニバッファーでのすべてのテキストプロパティが含まれる。それ以外なら、値がリターンされるときすべてのテキストプロパティが取り除かれる。
minibuffer-prompt-properties
内のテキストプロパティはプロンプトに適用される。このプロパティリストはデフォルトではプロンプトに使用するフェイスを定義する。このフェイスが与えられるとフェイスリストの最後に適用されて表示前にマージされる。
ユーザーがプロンプトの外観を完全に制御したければすべてのフェイスリストの最後にdefault
フェイスを指定するのがもっとも簡便な方法である。たとえば:
(read-from-minibuffer (concat (propertize "Bold" 'face '(bold default)) (propertize " and normal: " 'face '(default))))
引数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))
長い文字列(たとえば複数行に跨がるような文字列)を編集したい場合にread-string
を使うのは理想的ではないかもしれない。そのような場合にはその文字列をユーザーが編集できる通常のバッファーを新たにポップアップしたほうが便利かもしれない。これはread-string-from-buffer
を使用して行うことができる。
この関数はミニバッファーから文字列として正規表現を読み取ってそれをリターンする。ミニバッファーのプロンプト文字列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
となる。
ユーザーはcase foldingをオンまたはオフにするかどうかを示すために、M-s
cコマンドを使うことができる。ユーザーがこのコマンドを使うと、リターンされる文字列のテキストプロパティcase-fold
にはfold
またはinhibit-fold
のいずれかがセットされる。この値を実際に使うかどうかはread-regexp
の呼び出し側に任されており、そのための利便的関数としてread-regexp-case-fold-search
が提供されている。典型的な使い方は以下のようになるだろう:
(let* ((regexp (read-regexp "Search for: ")) (case-fold-search (read-regexp-case-fold-search regexp))) (re-search-forward regexp))
関数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を参照)は、この変数の値に関わらず、無条件でface
プロパティを破棄する。
この変数が非nil
なら、補完テーブル由来の文字列(ただし補完された文字列部分のみ)のほとんどのテキストプロパティは保持される。
(let ((minibuffer-allow-text-properties t)) (completing-read "String: " (list (propertize "foobar" 'data 'zot)))) => #("foobar" 3 6 (data zot))
この例ではユーザーが‘foo’とタイプしてからTABキーを押下しており、最後の3文字のテキストプロパティだけが保持される。
これはミニバッファーからの読み取りにたいするデフォルトローカルキーマップである。デフォルトでは以下のバインディングをもつ:
exit-minibuffer
exit-minibuffer
minibuffer-beginning-of-buffer
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
のバインディングに加えて、以下のバインディングが有効になる:
minibuffer-default-prompt-format
変数に応じたデフォルト値defaultでpromptをフォーマットする。
minibuffer-default-prompt-format
はフォーマット文字列(デフォルトは‘" (default
%s)"’)であり、これは‘"Local filename (default somefile):
"’のようなプロンプトの“default”部分をどのようにフォーマットするかを指示する。
これをどのように表示させるかをユーザーがカスタマイズできるようにするには、ユーザーに(デフォルト値をもつ)値の入力を求めるコードが、そのコードスニペット行に沿って何らかを調べる必要がある:
(read-file-name (format-prompt "Local filename" file) nil file)
format-argsがnil
なら、promptはリテラル文字列として使用される。format-argsが非nil
ならpromptはフォーマットコントロール文字列として使用され、promptとformat-argsがformat
に渡される(文字列のフォーマットを参照)。
minibuffer-default-prompt-format
は‘""’でもよく、その場合には何のデフォルト値も表示されない。
defaultがnil
ならデフォルト値はなく、したがって結果となる値には“default
value”文字列は含まれない。defaultが非nil
のリストなら、プロンプトでリストの最初の要素が使用される。
promptとminibuffer-default-prompt-format
はいずれもsubstitute-command-keys
を通じて実行される(ドキュメント内でのキーバインディングの置き換えを参照)。
このオプションが非nil
(デフォルト)の場合には、ミニバッファーからの入力を取得してexitする際に、ミニバッファーにエンターしたフレーム、それが別のフレームならミニバッファーウィンドウを所有するフレームのウィンドウ構成をリストアする。これはたとえば同じフレームにあるミニバッファーから入力を所得中にユーザーがウィンドウを分割した場合には、ミニバッファーのexit時にその分割が取り消されることを意味する。
このオプションがnil
なら、そのようなリストアは行われない。したがって上記のような分割はミニバッファー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
は、どちらも新たな要素を自動的にヒストリーリストに追加して、ユーザーがそのリストのアイテムを再使用するためのコマンドを提供します(ミニバッファーのコマンドを参照)。ヒストリーリストを使用するためにプログラムが行う必要があるのはリストの初期化と、使用するときに入力関数にリストの名前を渡すだけです。しかしミニバッファー入力関数がリストを使用していないときに手動でリストを変更しても問題はありません。
デフォルトではM-n (next-history-element
, next-history-elementを参照)によってミニバッファーから入力の読み取りを開始したコマンドが提供デフォルト値の終端に達すると、minibuffer-completion-table
(補完を行うミニバッファーコマンドを参照)で指定されている補完候補すべてがデフォルトのリストに追加されるので、これらの候補がすべて“未来のヒストリー(future
history)”として利用できます。あなたのプログラムは変数minibuffer-default-add-function
を通じてこれを制御することができます。値が関数以外ならこの自動的な追加は無効になります。またはこの変数に独自に関数をセットして一部の候補だけを、あるいは何か他の値を“未来のヒストリー”に追加することもできます。
新たな要素をヒストリーリストに追加するEmacs関数は、リストが長くなりすぎたときに古い要素の削除を行うこともできます。変数history-length
は、ほとんどのヒストリーリストの最大長を指定する変数です。特定のヒストリーリストにたいして異なる最大長を指定するには、そのヒストリーリストのシンボルのhistory-length
プロパティにその最大長をセットします。変数history-delete-duplicates
にはヒストリー内の重複を削除するかどうかを指定します。
この関数はneweltが空文字列でなければ、それを新たな要素として変数history-varに格納されたヒストリーリストに追加して、更新されたヒストリーリストをリターンする。これはmaxeltかhistory-length
がが非nil
なら、リストの長さをその変数の値に制限する(以下参照)。maxeltに指定できる値の意味はhistory-length
の値と同様。history-varはレキシカル変数を参照できない。
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式引数にたいするヒストリーリスト。
フェイス引数にたいするヒストリーリスト。
read-variable
が読み取る変数名引数にたいするヒストリーリスト。
read-number
が読み取る数値にたいするヒストリーリスト。
goto-line
の引数にたいするヒストリーリスト。ユーザーオプションgoto-line-history-local
をカスタマイズすれば、各バッファーにたいしてこの変数をローカルにできる。
[ << ] | [ < ] | [ 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
の呼び出しによって有効な名前リストの判定方法が指定されます。その後にこの関数は補完にたいして有用ないくつかのコマンドにキーバインドするローカルキーマップとともに、ミニバッファーをアクティブ化します。その他の関数は特定の種類の名前を補完つきで読み取る、簡便なインターフェイスを提供します。
21.6.1 基本的な補完関数 | 文字列を補完する低レベル関数。 | |
21.6.2 補完とミニバッファー | 補完つきでミニバッファーを呼び出す。 | |
21.6.3 補完を行うミニバッファーコマンド | ||
21.6.4 高レベルの補完関数 | 特別なケースに有用な補完(バッファー名や変数名などの読み取り)。 | |
21.6.5 ファイル名の読み取り | ファイル名やシェルコマンドの読み取りに補完を使用する。 | |
21.6.6 補完変数 | 補完の挙動を制御する変数。 | |
21.6.7 プログラムされた補完 | 独自の補完関数を記述する。 | |
21.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"
の前にある領域に関する補完情報だけをリターンするであろうことを告げている。try-completion
は意味のある境界に影響されない。すなわち"/usr/sh"
にたいしてtry-completion
は"share/"
ではなく、依然として"/usr/share/"
をリターンする。
補完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
の値にバインドされる。
この変数にグローバルに非nil
をセットしてはならない。安全ではないし恐らく補完コマンドでエラーが発生するだろう。この変数への非nil
値のバインドはtry-completion
、test-completion
、all-completions
といった基本的な補完コマンド呼び出しの前後においてletでのみバインドを行う必要がある。
この変数は変数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の要素でなければ確認を求められる。補完を行うミニバッファーコマンドを参照のこと。
nil
をリターンすること。
t
と同じだが、exitコマンドは補完処理中はexitしない。
しかしrequire-matchの値に関わらず、空の入力は常に許容される。この場合completing-read
はdefaultがリストなら最初の要素、defaultがnil
なら""
、またはdefaultをリターンする。文字列とdefault内の文字列はヒストリーコマンドを通じてユーザーが利用できる(ミニバッファーのコマンドを参照)。更にdefaultの値をM-nで使い果たすと、その補完候補が“未来のヒストリー”に追加される。minibuffer-default-add-functionを参照のこと。
関数completing-read
はrequire-matchがnil
ならキーマップとしてminibuffer-local-completion-map
を、require-matchが非nil
ならminibuffer-local-must-match-map
を使用する。補完を行うミニバッファーコマンドを参照のこと。
引数historyは入力の保存とミニバッファーヒストリーコマンドに、どのヒストリーリスト変数を使用するか指定する。デフォルトはminibuffer-history
。historyがシンボルt
なら、ヒストリーを記録しない。ミニバッファーのヒストリーを参照のこと。
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
のようなミニバッファー補完コマンドにより使用される。
この変数の値は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
のいずれかを組み合わせる。
非nil
の場合には、M-<コマンドはポイントがプロンプト終端の後ならポイントをプロンプト終端に移動する。ポイントがプロンプト終端またはプロンプト終端より前ならバッファーの先頭に移動する。この変数がnil
ならM-<はbeginning-of-buffer
のように振る舞う。
[ << ] | [ < ] | [ 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
をリターンするシンボルだということを思い出してほしい。インタラクティブな呼び出しを参照のこと。
引数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
、または補完の隣に表示する文字列をリターンしなければならない。この関数が自身で注釈サフィックス文字列にフェイスをputしなければ、その文字列にはデフォルトでcompletions-annotations
フェイスが追加される。
:affixation-function
値は補完にプレフィックスとサフィックスを追加する関数であること。この関数は単一の引数として補完リストを受け取り、注釈付きの補完リストをリターンすること。リターンされるリストは補完、プレフィックス文字列、サフィックス文字列の3要素からなるリストを要素とするリストでなければならない。この関数は:annotation-function
より優先される。
: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
を指定する。マッチがなければ関数はnil
をリターンすること。指定された文字列が一意でかつ正確にマッチしたらt
をリターンすること。それ以外ならすべてのマッチに共通な最長の前置部分文字列をリターンすること。
t
all-completions
を指定する。関数は指定された文字列の利用可能なすべての補完のリストをリターンする。
lambda
test-completion
を指定する。関数は指定された文字列がいくつかの補完候補に完全一致するならt
、それ以外はnil
をリターンする。
(boundaries . suffix)
completion-boundaries
を指定する。関数は(boundaries start
.
end)
をリターンする。ここでstartは指定された文字列内の境界の開始位置、endはsuffix内の境界の終了位置。
Lispプログラムが些細とは言えない境界をリターンする場合には、それらとall-completions
操作との整合を確認すること。all-completions
がリターンする補完は、補完境界がカバーするプレフィックスとサフィックスだけに関係していること。補完境界に期待される正確なセマンティックスについては基本的な補完関数を参照のこと。
metadata
カレント補完の状態に関する情報の要求を指定する。リターン値は(metadata
. alist)
の形式をもち、alistは以下で説明する要素をもつ連想リスト。
フラグに他の値が指定されたら、補完関数はnil
をリターンする。
以下はmetadata
フラグ引数への応答として補完関数がリターンするかもしれないmetadataエントリーのリストです:
category
値は補完関数が補完を試みているテキストの種類を説明するシンボル。シンボルがcompletion-category-overrides
内のキーの1つにマッチする場合、通常の補完動作はオーバーライドされる。補完変数を参照のこと。
annotation-function
値は補完に注釈(annotation)を付ける関数。この関数は1つの引数stringを受け取り、これは利用可能な補完である。リターン値は文字列で、*Completions*バッファー内の補完stringの後に表示される。この関数が自身で注釈サフィックス文字列にフェイスをputしなければ、その文字列にはデフォルトでcompletions-annotations
フェイスが追加される。
affixation-function
値は補完にプレフィックスとサフィックスを追加する関数であること。この関数は単一の引数としてcompletions
(可能な補完のリスト)を受け取り、それぞれの要素が3要素(補完、*Completions*バッファーにおいて補完文字列の前に表示するプレフィックス、補完文字列の後に表示するサフィックス)のリストであるようなcompletionsリストをリターンすること。この関数はannotation-function
より優先される。
group-function
値は補完候補をグループ化するための関数であること。この関数はcompletion (補完候補)、transform
(ブーリーンフラグ)という2つの引数を受け取らなければならない。transformがnil
なら、その関数は補完候補が属するグループのグループタイトルをリターンしなければならない。リターンされるタイトルはnil
でもよい。それ以外なら、その関数は変換された候補をリターンしなければならない。この変換はたとえば、グループタイトルに表示される冗長なプレフィックスの削除などが考えられる。
display-sort-function
値は補完をソートする関数。関数は1つの引数をとる。これは補完文字列のリストで、ソートされた補完文字列リストがリターンされる。その入力のリストは破壊的に変更することが許容される。
cycle-sort-function
値はcompletion-cycle-threshold
が非nil
、かつユーザーが補完候補を巡回するときに補完をソートする関数。引数のリストとリターン値はdisplay-sort-function
と同様。
この関数はプログラムされた補完関数として動作可能な関数を記述する便利な方法である。引数functionは1つの引数(文字列)をとる関数であり、利用可能な補完すべてを含む補完テーブル(基本的な補完関数を参照)をリターンする。functionがリターンするテーブルには文字列引数にマッチしない要素を含めることもできる。これらはcompletion-table-dynamic
によって自動的にフィルターされる。特にfunctionは引数を無視して利用可能なすべての補完の完全なリストをリターンできる。completion-table-dynamic
をfunctionとプログラムされた補完関数との間の変換器として考えることができる。
オプション引数switch-bufferが非nil
、かつ補完がミニバッファーで行われた場合、functionはそのミニバッファーにエンターしたときのバッファーをカレントバッファーにセットして呼び出される。
completion-table-dynamic
のリターン値はtry-completion
およびall-completions
の2つ目の引数として使用できる。この関数は常に空のメタデータと無意味な境界をリターンすることに注意。
これは前回の引数/結果ペアーを保存する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
内の次の関数へ移動する。
このフック上の関数は(たとえばpost-command-hook
から)頻繁に呼び出され得るので一般的には素早くリターンすること。補完リストの生成が高価な処理なら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)))))
さらに一般的にはcollectionはstartとendの間のカレントのテキストにもとづいて事前にフィルターされるべきではない。なぜなら使用を判断した補完スタイルに応じてこれを行うのはcompletion-at-point-functions
の呼び出し側の責任だからである。
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文字の答えを要求するので、より重大な問いに適しています。
マウスやその他ウィンドウシステムのジェスチャーを使って呼び出されたコマンド、あるいはメニュー経由で呼び出されたコマンドからこれらの関数のいずれかが呼び出されると、ダイアログボックスがサポートされていればダイアログボックスかポップアップメニューを使って質問にたいする答えを求めます。それ以外の場合にはキーボード入力を使用します。呼び出しの前後でlast-nonmenu-event
に適切な値をバインドすることによってマウス、あるいはキーボード入力のいずれかの使用を強制できます。t
ならキーボードによる対話、リストにバインドすればダイアログボックスの使用が強制されます。
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にバインドされている)のような特殊な応答をエンターした場合、この関数はは指定されたウィンドウの再センタリングやスクロール操作を処理してから再度答えを求める。
y-or-n-p
の呼び出し中にhelp-form
(ヘルプ関数を参照)を非nil
値にバインドすると、help-char
の押下によりhelp-form
を評価して結果を表示する。help-char
はpromptに自動的に追加される。
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から得られる)質問する次のオブジェクトである。format
についての詳細は文字列のフォーマットを参照のこと。
prompterが文字列でなければ、1つの引数(質問する次のオブジェクト)をとる関数であり、そのオブジェクトにたいする質問テキストをリターンすること。値が文字列ならユーザーに問う質問であること。関数はt
(ユーザーに尋ねずこのオブジェクトを処理する)、またはnil
(ユーザーに尋ねずこのオブジェクトを無視する)をリターンすることもできる。
引数actorはユーザーがyesと答えにたいして、どのように作処理するかを指定する。これはlistから取得したそれぞれのオブジェクトであるを単一の引数として呼び出される関数であること。
引数helpが与えられたら、それは以下の形式のリストである:
(singular plural action)
singularは処理するオブジェクトを説明する単数形の名詞を含む文字列、pluralはそれに対応する複数形の名詞、actionはactorがオブジェクトに何を行うかを説明する他動詞である。
helpを指定しない場合のリストのデフォルトは("object" "objects" "act on")
。
尋ねられる質問ごとにユーザーは以下のように答えることができる:
そのオブジェクトを処理する
そのオブジェクトをスキップ
以降のオブジェクトをすべて処理する
exit(以降のオブジェクトすべてをスキップ)する
そのオブジェクトを処理してからexitする
ヘルプを表示する
これらはquery-replace
が受け入れる応答と同じである。キーマップquery-replace-map
がmap-y-or-n-p
やquery-replace
にたいして、これらの応答の意味を定義する。検索と置換を参照のこと。
action-alistを使用して、利用できる追加の答えとそれらが何を意味するかを指定できる。action-alistが与えられた場合には、要素が(char function help)
という形式のalistであること。alistの要素はそれぞれ追加の答えを1つ定義する。各要素のcharは文字(応答)、functionは単一の引数(
listのオブジェクト)、helpは文字列。ユーザーがcharで応答した際には、map-y-or-n-p
はfunctionを呼び出す。非nil
をリターンすると、オブジェクトを処理対象とみなして、map-y-or-n-p
はlistの次オブジェクトに処理を進める。nil
をリターンした場合には、同じオブジェクトにたいして繰り返し入力を求める。ユーザーがヘルプを要求した場合には、これらの追加質問を説明するためにhelpのテキストを使用する。
確認を求める間、map-y-or-n-p
は通常はcursor-in-echo-area
をバインドする。しかしno-cursor-in-echo-areaが非nil
ならバインドしない。
マウスやその他ウィンドウシステムのジェスチャー、あるいはメニュー経由で呼び出されたコマンドからmap-y-or-n-p
が呼び出された場合には、ダイアログボックスがサポートされていれば質問の答えを求めるためにダイアログボックスかポップアップメニューが使用される。この場合にはキーボード入力やエコーエリアは使用されない。呼び出しの前後でlast-nonmenu-event
を適切な値にバインドすることによって、マウスあるいはキーボード入力を強制できる。t
ならキーボードによる対話、リストにバインドすればダイアログボックスの使用が強制される。
map-y-or-n-p
のリターン値は処理したオブジェクトの個数である。
3つ以上の答えをもつかもしれない質問をユーザーに尋ねる必要がある場合にはread-answer
を使用してください。
この関数はquestionのテキスト( ‘SPC’文字で終端されていること)とともにユーザーに入力を求める。この関数はquestionにanswersを追加することにより、プロンプト内に可能な応答を含めることができる。この可能な応答は以下の形式の要素をもつalistとしてanswers内に提供される。
(long-answer short-answer help-message)
long-answerはユーザーの応答の完全なテキスト(文字列)、short-answerは同じ応答の短い形式(単一文字かファンクションキー)、help-messageはその応答の意味を説明するテキスト。変数read-answer-short
が非nil
なら可能な応答の短いバージョンをプロンプトに表示して、ユーザーがプロンプトに表示された1文字をタイプすることを期待する。それ以外なら可能な応答の長いバージョンをプロンプトに表示して、ユーザーにはプロンプトに表示された完全なテキストのいずれかを入力してから、入力完了でRETを押下することが期待される。RETが非nil
かつこの関数がマウスイベントから呼び出された場合には問いと答えはGUIのダイアログボックス内に表示される。
この関数はプロンプトに表示された応答の長短やユーザーがタイプした応答とは無関係に、ユーザーがセンタクしたlong-answerのテキストをリターンする。
以下はこの関数の使用例:
(let ((read-answer-short t)) (read-answer "Foo " '(("yes" ?y "perform the action") ("no" ?n "skip to the next") ("all" ?! "perform for the rest without more questions") ("help" ?h "show help") ("quit" ?q "exit"))))
この関数はミニバッファーを使用して単一文字を読み取りリターンする。オプションで許容する文字のリストchars以外のメンバーはすべて無視する。history引数は使用するヒストリーリストシンボルを指定する。これが省略かnil
なら、この関数はヒストリーを使用しない。
read-char-from-minibuffer
の呼び出し中にhelp-form
(ヘルプ関数を参照)を非nil
値にバインドすると、help-char
の押下によりhelp-form
を評価して結果を表示する。
[ << ] | [ < ] | [ 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する。これは通常はミニバッファー内のローカルキーマップのキーにバインドされる。カレントバッファーがミニバッファーだがアクティブミニバッファーでなければ、このコマンドはエラーをthrowする。
このコマンドはキーボードでタイプされた最後の文字を挿入した後にアクティブなミニバッファーをexitする。コマンドループからの情報)を参照のこと。
このコマンドはn個前(古い)のヒストリー要素の値でミニバッファー内のコンテンツを置換する。
このコマンドはミニバッファー内のポイントの前のカレントコンテンツを、n個分のより最近のヒストリー要素の値で置換する。現在位置を超えたヒストリー内の位置への移動も可能であり、それは“未来のヒストリー(future history)”を呼び出す(ミニバッファーでのテキスト文字列の読み取りを参照)。
このコマンドはpattern(正規表現)にマッチするn個前(古い)のヒストリー要素でミニバッファー内のコンテンツを置換する。
このコマンドはpattern(正規表現)にマッチするn個先(新しい)のヒストリー要素でミニバッファー内のコンテンツを置換する。
このコマンドはミニバッファー内のポイントの前のカレントコンテンツを、n個前(古い)ヒストリー要素の値で置換する。
このコマンドはミニバッファー内のポイントの前のカレントコンテンツを、n個先(新しい)ヒストリー要素の値で置換する。
この関数はミニバッファーにミニバッファーヒストリーの要素を配置する。引数nabsは絶対ヒストリー位置(absolute history
position)を降順で指定する。0ならカレント要素、正の数nはn個前の要素を意味する。負の数-nはn番目の“未来のヒストリー”を意味する。この関数はread-from-minibuffer
(ミニバッファーでのテキスト文字列の読み取りを参照)およびcompleting-read
(補完とミニバッファーを参照)によって提供されるデフォルト値の終端に達すると、補完候補を“未来のヒストリー”に追加する。minibuffer-default-add-functionを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はミニバッファーウィンドウにアクセスと選択を行い、それがアクティブかどうかテストしてリサイズされる方法を制御します。
この関数はフレームframeにたいして使用されるミニバッファーウィンドウをリターンする。frameがnil
ならそれは選択されたフレームを意味する。
フレームが使用するミニバッファーウィンドウがフレームの一部である必要はないことに注意(ミニバッファーをもたないフレームは必要に応じて別のフレームのミニバッファーウィンドウを使用する)。ミニバッファーのないフレームのミニバッファーウィンドウは、そのフレームのminibuffer
フレームパラメーターをセットすることにより変更できる(バッファーのパラメーターを参照)。
この関数はミニバッファーウィンドウとしてwindowを使用するよう指定する。これは通常のミニバッファーコマンドを呼び出さずにミニバッファーにテキストを入力する場合には、ミニバッファーをどこに表示するかに影響を及ぼす。通常のミニバッファー入力関数はすべて選択されたフレームに対応するミニバッファーを選択して開始されるので影響はない。
この関数はwindowがミニバッファーウィンドウならt
をリターンする。windowのデフォルトは選択されたウィンドウ。
以下の関数はカレントでアクティブなミニバッファーを表示しているウィンドウをリターンします。
この関数はカレントでアクティブなミニバッファーのウィンドウ、アクティブなミニバッファーがなければnil
をリターンする。
(minibuffer-window)
の結果の比較だけでは、与えられたウィンドウがカレントでアクティブなミニバッファーを表示するかどうかを判断するのは不十分である。なぜなら複数のフレームがある場合にはミニバッファーウィンドウも複数あり得る。
この関数はwindowがカレントでアクティブなミニバッファーを表示するウィンドウなら非nil
をリターンする。
以下の2つのオプションはミニバッファーウィンドウが自動的にリサイズされるか否か、およびその処理でミニバッファーが大きくなり得るサイズを制御します。
このオプションはミニバッファーウィンドウが自動的にリサイズされるかどうかを指定する。デフォルト値はgrow-only
で、これはミニバッファーが表示するテキストを収容するために、ミニバッファーウィンドウがデフォルトにより自動的に拡張されて、ミニバッファーが空になれば即座に1行に縮小されることを意味する。値がt
ならEmacsは常にミニバッファーが表示するテキストにミニバッファーウィンドウの高さをフィットさせるように試みる。値がnil
ならミニバッファーウィンドウのサイズが自動的に変更されることは決してない。この場合には、ミニバッファーウィンドウの高さの調節のために、ウィンドウリサイズコマンドを使用できる(ウィンドウのリサイズを参照)。
このオプションはミニバッファーウィンドウの自動的なリサイズにたいする最大高さを提供する。浮動小数点数はフレーム高さにたいする割合として最大高さを指定する。整数はフレームの正規文字高さの単位で最大高さを指定する(フレームのフォントを参照)。デフォルト値は0.25。
上記の2つの変数の値は表示時に効果を発揮するので、エコーエリアのメッセージを生成するコードの前後でこれらの変数をletバインドしても機能しないことに注意してください。長いメッセージを表示する際にミニバッファーウィンドウのリサイズを抑止したければ、かわりにmessage-truncate-lines
変数をバインドしてください(エコーエリアのカスタマイズを参照)。
オプションresize-mini-windows
はミニバッファーのみのフレームの振る舞いには影響を与えません(フレームのレイアウトを参照)。以下のオプションによりそのようなフレームも同じように自動的にリサイズすることが可能になります。
これがnil
ならミニバッファーのみのフレームは決して自動的にリサイズされない。
これが関数なら、その関数はリサイズするミニバッファーのみフレームを単一の引数として呼び出される。この関数が呼び出されるときは、そのフレームのミニバッファーウィンドウのバッファーは、そのウィンドウの次回再表示時にコンテンツが表示されるバッファーである。この関数には何らかの適切な方法によりフレームをバッファーにフィットさせることが期待される。
それ以外の非nil
値はfit-mini-frame-to-buffer
を呼び出すことによりミニバッファーのみのフレームをリサイズすることを意味する。この関数はfit-frame-to-buffer
と似ているが、バッファーテキストから先頭や末尾の空行を取り除かない(ウィンドウのリサイズを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はミニバッファーのプロンプトとコンテンツにアクセスします。
この関数はカレントでアクティブなミニバッファーのプロンプト文字列をリターンする。アクティブなミニバッファーがなければnil
をリターンする。
この関数はミニバッファーがカレントならミニバッファープロンプトの終端のカレント位置をリターンする。それ以外はバッファーの有効な最小位置をリターンする。
この関数はミニバッファーがカレントならミニバッファープロンプトのカレントの表示幅をリターンする。それ以外は0をリターンする。
この関数はミニバッファーがカレントなら、ミニバッファーの編集可能なコンテンツ(つまりプロンプト以外のすべて)を文字列でリターンする。それ以外はカレントバッファーのコンテンツ全体をリターンする。
これはminibuffer-contents
と同様だが、テキストプロパティをコピーせずに文字自身だけをリターンする。テキストのプロパティを参照のこと。
このコマンドはミニバッファーがカレントなら、ミニバッファーの編集可能なコンテンツ(つまりプロンプト以外のすべて)を削除する。それ以外はカレントバッファー全体を削除する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数と変数は再帰ミニバッファーを処理します(再帰編集を参照):
この関数はアクティブなミニバッファーのカレント再帰深さを正の整数でリターンする。アクティブなミニバッファーが存在しなければ0をリターンする。
この変数が非nil
ならミニバッファーがアクティブでも、(find-file
のような)ミニバッファーを使用するコマンドを呼び出すことができる。このような呼び出しは新たなミニバッファーにたいして再帰編集レベル(recursive
editing
level)を生成する。内側レベルの編集中は、デフォルトでは、外側レベルのミニバッファーは非表示になる。minibuffer-follows-selected-frame
をnil
をセットしていれば、複数フレームで同時にミニバッファーを可視にできる。(emacs)Basic
Minibufferを参照のこと。
この変数がnil
ならミニバッファーがアクティブなときは、たとえ他のウィンドウに切り替えてもミニバッファーコマンドの呼び出しはできない。
コマンド名が非nil
のプロパティenable-recursive-minibuffers
をもつ場合には、たとえミニバッファーから呼び出された場合でも、そのコマンドは引数の読み取りにミニバッファーを使用できる。コマンドのinteractive宣言内でenable-recursive-minibuffers
をt
にしても、これを行うことができる(interactive
の使用を参照)。ミニバッファーコマンドnext-matching-history-element
(ミニバッファー内では通常M-s)は後者を行う。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ネットワーク越しに与えたコマンドに応答するヘッドレスサーバープロセスとしてEmacsを実行できると便利な場合があります。とはいえEmacsは主として対話的に使用するためのプラットフォームなので、特定の例外的な状況ではユーザーに入力を求めるコマンドが沢山あります。ユーザー入力の待機によりサーバーは単にハングしてしまうでしょうから、この使用方法はより困難になります。
inhibit-interaction
をnil
以外の何らかにバインドすることによって、Emacsに入力を求めさせるのではなく、そのような状況をサーバーが処理するために使用可能なinhibited-interaction
エラーをシグナルさせることができます。
以下は典型的な使用例です:
(let ((inhibit-interaction t)) (respond-to-client (condition-case err (my-client-handling-function) (inhibited-interaction err))))
(y-or-n-p
やread-from-minibuffer
等を通じて)ユーザーに入力を求める何かをmy-client-handling-function
が呼び出すことになると、かわりにinhibited-interaction
エラーをシグナルします。それからサーバーコードはそのエラーをcatchしてクライアントに報告します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はbuffer-or-nameがミニバッファーなら非nil
をリターンする。buffer-or-nameがnil
か省略なら、カレントバッファーをテストする。liveが非nil
なら、この関数はbuffer-or-nameがアクティブミニバッファーのときだけ非nil
をリターンする。
このマクロは指定されたfunctionがminibuffer-setup-hook
を通じて呼び出されるように計らった後にbodyを実行する。デフォルトではfunctionはminibuffer-setup-hook
リストの他の関数の前に呼び出されるが、functionが(:append func)
というフォームなら、funcは他のフック関数の後に呼び出される。
bodyはミニバッファーを複数回使用しないこと。ミニバッファーが再帰的に再エンターされると、functionは最外のミニバッファーの使用にたいして1回だけ呼び出されるだろう。
これはミニバッファーがexitされたときは常に実行されるノーマルフックである。
この変数の値が非nil
なら、それはウィンドウオブジェクトである。ミニバッファー内で関数scroll-other-window
が呼び出されたときは、このウィンドウをスクロールする(テキスト的なスクロールを参照)。
この関数はミニバッファーウィンドウが選択される直前に選択されていたウィンドウをリターンする。選択されたウィンドウがミニバッファーウィンドウ以外ならnil
をリターンする。
この関数はmessage
(see エコーエリアへのメッセージの表示を参照)と似ているが、(典型的にはEmacsがユーザーに何らかの入力を求めたことによって)ユーザーがミニバッファー内でタイプする際にメッセージを特別な方法で表示する。ミニバッファーがカレントバッファーの際には、この関数はメッセージをエコーエリアに表示することによってミニバッファーのテキストが隠されることを避けるために、stringで指定されたメッセージを一時的にミニバッファーのテキストの終端に表示する。このメッセージは数秒経過するか、あるいは次の入力イベントが到達するまで表示される。
ミニバッファーがカレントバッファーでないときに呼び出されるとこの関数は単にmessage
を呼び出すので、stringはエコーエリアに表示される。
これはインタラクティブなミニバッファー内で使用されるメジャーモードである。キーマップminibuffer-inactive-mode-map
を使用する。ミニバッファーが別のフレームにある場合には有用かもしれない。ミニバッファーとフレームを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsを実行すると、ほぼ即座にエディターコマンドループ(editor command loop)に移行します。このループはキーシーケンスを読み取り、それらの定義を実行して結果を表示します。このチャプターではこれらが行われる方法と、Lispプログラムがこれらを行えるようにするサブルーチンを説明します。
22.1 コマンドループの概要 | コマンドループがコマンドを読み取る方法。 | |
22.2 コマンドの定義 | 関数が引数を読み取る方法を指定する。 | |
22.3 インタラクティブな呼び出し | 引数を読み取るようにコマンドを呼び出す。 | |
22.4 インタラクティブな呼び出しの区別 | インタラクティブな呼び出しとコマンドを区別する。 | |
22.5 コマンドループからの情報 | 検証用にコマンドループによりセットされる変数。 | |
22.6 コマンド後のポイントの調整 | コマンドの後にポイント位置を調整する。 | |
22.7 入力イベント | 入力を読み取るとき、入力がどのように見えるか。 | |
22.8 入力の読み取り | キーボードやマウスからの入力イベントを読み取る方法。 | |
22.9 スペシャルイベント | 即座かつ個別に処理されるイベント。 | |
22.10 時間の経過や入力の待機 | ユーザー入力または経過時間の待機。 | |
22.11 quit | C-gが機能する方法。quitのcatchや延期する方法。 | |
22.12 プレフィクスコマンド引数 | コマンドがプレフィクス引数が機能するようにセットするための方法。 | |
22.13 再帰編集 | 再帰編集への移行と、なぜ通常は再帰編集を行うべきでないのか。 | |
22.14 コマンドの無効化 | コマンドループが無効なコマンドを扱う方法。 | |
22.15 コマンドのヒストリー | コマンドヒストリーがセットアップされる方法と、どのようにアクセスされるか。 | |
22.16 キーボードマクロ | キーボードマクロが実装される方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コマンドループが最初に行わなければならないのはキーシーケンスの読み取りです。キーシーケンスはコマンドに変換される入力イベントのシーケンスです。これは関数read-key-sequence
を呼び出すことによって行われます。Lispプログラムもこの関数を呼び出すことができます(キーシーケンス入力を参照)。これらはより低レベルのread-key
やread-event
(単一イベントの読み取り)で入力を読み取ったり、discard-input
(その他のイベント入力の機能を参照)で保留中の入力を無視することもできます。
キーシーケンスはカレントでアクティブなキーマップを通じてコマンドに変換されます。これが行われる方法についてはキーの照合を参照してください。結果はキーボードマクロかインタラクティブに呼び出し可能な関数になります。キーがM-xなら他のコマンドの名前を読み取って、それを呼び出します。これはコマンドexecute-extended-command
(インタラクティブな呼び出しを参照)により行われます。
コマンドの実行に先立ち、Emacsはアンドゥ境界(undo
boundary)を作成するためにundo-boundary
を実行します。アンドゥリストの保守を参照してください。
コマンドを実行するために、Emacsはまずcommand-execute
を呼び出してコマンドの引数を読み取ります(インタラクティブな呼び出しを参照)。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つのフックを実行します。
バッファーのテキストに非常に長い行が含まれている場合には、これら2つのフックはあたかもポイント周辺の一部にナローイングされて、long-line-optimizations-in-command-hooks
のラベルが付されたwith-restriction
フォーム(ナローイングを参照)の内部であるかのように呼び出されることに注意してください。
[ << ] | [ < ] | [ 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コード内で使用されるかわりの関数です。
ジェネリック関数(ジェネリック関数を参照)にinteractive
フォームを追加してコマンドにすることはできません。
22.2.1 interactive の使用 | interactive にたいする一般的なルール。
| |
22.2.2 interactive にたいするコード文字 | さまざまな方法で引数を読み取る標準的な文字のコード。 | |
22.2.3 interactive の使用例 | インタラクティブ引数を読み取る方法の例。 | |
22.2.4 コマンドにたいするモード指定 | 特定モード用コマンドの指定。 | |
22.2.5 コマンド候補からの選択 | コマンド選択肢からの選択。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
interactive
の使用このセクションでは、Lisp関数をインタラクティブに呼び出し可能なコマンドにするinteractive
フォームの記述方法と、コマンドのinteractive
フォームの検証方法について説明します。
このスペシャルフォームは関数がコマンドであり、したがって(M-xを通じて、またはそのコマンドにバインドされたキーシーケンスをエンターすることにより)インタラクティブに呼び出すことができることを宣言する。引数arg-descriptorは、そのコマンドがインタラクティブに呼び出されたときに引数を計算する方法を宣言する。
コマンドは他の関数と同じようにLisp関数から呼び出されるかもしれないが、その場合には呼び出し側は引数を提供して、arg-descriptorは効果をもたない。
interactive
フォームは関数body内のトップレベルに置くか、関数シンボルのinteractive-form
プロパティ((シンボルのプロパティ)を参照)になければならない。これはコマンドループが関数を呼び出す前にinteractiveフォームを調べることにより効果をもつ(インタラクティブな呼び出しを参照)。一度関数が呼び出されると関数body内のすべてのフォームが実行される。このときbody内にinteractive
フォームが出現しても、そのフォームは引数の評価さえされず単にnil
をリターンする。
modesリストではコマンドの使用を意図したモードを指定できる。modes指定の効果と使用するタイミングに関する詳細はコマンドにたいするモード指定を参照のこと。
慣例により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
spec)
)である。それ以外なら値はnil
。functionがシンボルなら、そのシンボルの関数定義が使用される。OClosureで呼び出された場合には、処理はジェネリック関数oclosure-interactive-form
に委譲される。
この関数はinteractive-form
と同様にコマンドを受け取り、そのインタラクティブなフォームをリターンする。これがジェネリック関数であること、そしてfunctionがOClosureのときだけ呼び出される点が異なる。この関数の目的は一部のOClosureタイプ(オープンクロージャを参照)にたいしてそれらのスロットの1つにインタラクティブフォームを格納するのではなく、動的なインタラクティブフォームの計算を可能にすることにある。
これはたとえばすべてのkmacro
は同じインタラクティブフォームを共有するので、kmacro
に用いることでメモリーサイズを削減できる。インタラクティブフォームが関数のコンポーネントのインタラクティブフォームから計算されるadvice
関数においても、いずれかのコンポーネントが再定義された際の計算を更に遅延でき、かつインタラクティブフォームをより正確に調整できる。
[ << ] | [ < ] | [ 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’に関連するイベントとしてカウントされない。
既存ファイルのファイル名(ファイルの名前を参照)。デフォルト値の詳細についてはファイル名の読み取りを参照のこと。[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
やkeymap-global-set
のようなコマンドにより使用される。
keymap-set
のような関数の入力として使用されるフォーム上のキーシーケンス。これは‘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つの引数を指定する唯一のコード文字である。コマンド呼び出し時にカレントなバッファーにマークがセットされていなければエラーをシグナルする。Transient
Markモード(マークを参照)がオン(デフォルト)かつユーザーオプションmark-even-if-inactive
がnil
の場合には、たとえマークがセットされていても非アクティブならEmacsはエラーをシグナルする。[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] | [ ? ] |
Emacsのコマンドの多くは汎用であり、特定のモードに関連付けられていません。たとえばM-x kill-regionは編集可能テキストをもつほとんどのモード、(M-x list-buffersのような)情報表示コマンドはほとんどのコンテキストで使用できます。
しかしそれ以外の多くのコマンドはモードに具体的に関連付けられており、そのコンテキスト外部では意味をなしません。たとえばDiredバッファーの外部でM-x
dired-diff
を使用すると、単にエラーをシグナルするでしょう。
したがってEmacsにはコマンドが“所属する”モードが何かを指定するためのメカニズムがあります:
(defun dired-diff (...) ... (interactive "p" dired-mode) ...)
これはそのコマンドをdired-mode
(やdired-mode
から派生したモード)だけに適用されるようにマークします。interactive
フォームには任意個数のモードを追加できます。
モードの指定は、M-S-x
(execute-extended-command-for-buffer
)でのコマンド補完に影響を与えます(インタラクティブな呼び出しを参照)。read-extended-command-predicate
の値に応じて、モード指定がM-xでの補完にも影響を与えるかもしれません。
たとえばread-extended-command-predicate
の値としてcommand-completion-default-include-p
述語を使用する際には、特定モードに適用されるとマークされたコマンドはM-xでリストされないでしょう(もちろんそのモードを使用するバッファーにいない場合)。これはメジャーモードとマイナーモードの両方に言えることです(対照的にM-S-xは適用されないコマンドを補完候補から常に省略する)。
read-extended-command-predicate
はデフォルトではnil
であり、M-xでの補完ではカレントバッファーのモードに適用されるとマークされているか否かに関わらず、ユーザーがタイプしたものにマッチするすべてのコマンドがリストされます。
あるモードにたいして適用されるものとしてコマンドをマークすると、(何らかのキーにバインドされていなければ)それらはC-h mでもリストされるようになります。
(拡張interactive
フォームをサポートしない古いバージョンのEmacsでは動作すると思われるコードがある等で)この拡張interactive
フォームの使用が不便なら、かわりに等価な以下の宣言(declare
フォームを参照)を使用できます:
(declare (modes dired-mode))
コマンドのモードへのタグ付けはある意味好みの問題ですが、そのモードの外部では動作しないことが明確なコマンドはタグ付けするべきです。これにはどこか別の場所で呼び出すとエラーをシグナルするだけではなく、期待しないモードからの呼び出しが破壊的なコマンドも含まれます(これは通常はスペシャルモード、すなわち編集不可なモード用に記述されたコマンドのほとんどが含まれる)。
別モードから呼び出した際にも害がなく、“機能する”コマンドもありますが、それでも別の場所使用することが実際に無意味なコマンドには、依然としてタグ付けする必要があります。たとえば多くのスペシャルモードはバッファーのexitコマンドにqをバインドしており、これは"Goodbye
from this
mode"のようなメッセージを発行してkill-buffer
を呼び出す以外は何も行わないかもしれません。このコマンドは別のモードでも“機能する”でしょうが、そのスペシャルモードのコンテキスト外部でこのコマンドを実際に使いたいと思う人が居るようには思えません。
多くのモードには、そのモードを異なる方法で開始するために、一連の異なるコマンドがあります (例:
eww-open-in-new-buffer
とeww-open-file
)。このようなコマンドはユーザーがさまざまなコンテキストから発行し得るので、モード固有とタグ付けするべきでは決してありません。
[ << ] | [ < ] | [ 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
このコマンドはカレントメジャーモード(や有効なマイナーモード)に不適切なコマンドを除外するread-extended-command-predicate
変数を考慮する。この変数の値はデフォルトではnil
であり、除外されるコマンドはない。しかし関数command-completion-default-include-p
を呼び出すようにカスタマイズすることで、モードに応じたフィルタリングを行うようになる。read-extended-command-predicate
には任意の述語関数を指定できる。これはそのコマンドのシンボル、およびカレントバッファーという2つのパラメーターで呼び出される。そのバッファーニオイそのコマンドを補完に含めるなら非nil
をリターンすること。
これはexecute-extended-command
と似ているが、補完にたいしてカレントバッファー(や有効なマイナーモード)と特に関連するものに限定してコマンドを提案する。これらにはそのモードにタグ付けされたコマンド(interactive
の使用を参照)、およびローカルでアクティブなキーマップにバインドされたコマンドも含まれる。このコマンドはM-S-x
(すなわち“meta shift x”)の通常の定義である。
これらのコマンドはいずれもコマンド名の入力を求めますが、補完ルールは異なります。入力を求められた際にM-S-xコマンドを使用することで、2つの補完モードを切り替えることができます。
[ << ] | [ < ] | [ 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
は実行を指定されたが他のコマンドにリマップされたコマンドを与える。
これはthis-command
と同じ値をもつが、ミニバッファーへエンター時2再帰的にバインドされる。この変数はカレントミニバッファーセッションをオープンしたコマンドが何かを判定するために、ミニバッファーフック等から使用されるかもしれない。
この関数は現在のコマンドを呼び出したキーシーケンスを含む文字列かベクターをリターンする。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
(どの文字が挿入されたか判断するため)、およびpost-self-insert-hook
(挿入された文字にアクセスするため)の内部で使用されている(ユーザーレベルの挿入コマンドを参照)。
last-command-event
;; これを評価するためにC-u C-x C-eを使用すると
⇒ 5
C-eのASCIIコードの5が値になる。
この変数は最後の入力イベントが送られたフレームを記録する。これは通常はそのイベントが生成されたときに選択されていたフレームだが、そのフレームの入力が他のフレームにリダイレクトされていたら、そのリダイレクトされていたフレームが値となる。入力のフォーカスを参照のこと。
最後のイベントがキーボードマクロに由来する場合、値はmacro
になる。
入力イベントには、その発生元となるどこかから送られてこなければなりません。それがキーボードマクロ、シグナル、あるいは‘unread-command-events’のときもありますが、通常はコンピューターに接続されたユーザーの制御する物理的な入力デバイスからでしょう。これらのデバイスは入力デバイス(input device)と呼ばれており、Emacsは入力イベントそれぞれを発生元である入力デバイスに関連付けています。これらのデバイスは入力デバイスそれぞれにたいして一意な名前によって識別されます。
使用された入力デバイスを正確に判別できる能力は、各システムの詳細に依存します。その情報が利用できなければ、Emacsはキーボードイベントの発生元を‘"Virtual core keyboard"’、その他のイベントの発生元を‘"Virtual core pointer"’のように報告します(これらは詳細なデバイス情報が不明なときにXサーバーが報告するデバイス名なので、すべてのプラットフォームでこれらの値をデバイス名として使用する)。
この変数は最後に読み取られた入力イベントの発生元となる入力デバイス名を記録する。そのようなデバイスが存在しなければnil
(たとえば最後の入力イベントをunread-command-events
から読み取ったときや、キーボードマクロが発生元のとき)。
XウィンドウでXInput拡張(X Input Extension)が使用される際のデバイス名はXサーバーに接続された物理キーボード、ポインティングデバイス、タッチスクリーンそれぞれにたいして一意な文字列となる。それ以外の場合には‘"Virtual core pointer"’か‘"Virtual core keyboard"’という文字列のいずれかであり、それはそのイベントが(マウスのような)ポインティングデバイス、あるいはキーボードのいずれによって生成されたかに依存する。
異なるさまざまなタイプのデバイスがあり、それらのデバイスは名前によって判別できる。この関数はframeで発生したイベントにたいして、デバイスnameの正しいタイプを決定するために使用できる。
リターン値は以下のシンボル(“デバイスクラス”)のいずれか:
core-keyboard
コアキーボード(core keyboard)。そのデバイスがキーボードのようなデバイスだが、その他の特徴が不明なことを意味する。
core-pointer
コアキーボード(core pointer)。そのデバイスがポインティングデバイスのようなデバイスだが、その他の特徴が不明なことを意味する。
mouse
コンピューターマウス。
trackpoint
トラックポイントやジョイスティック(または同種のコントローラー)。
eraser
グラフィックタブレットのスタイラス(タッチペン)の反対側やスタンドアロンのイレイサー(消しゴム)。
pen
グラフィックタブレットのペン、スタイラス、または同種デバイスのペン先端。
puck
コンピュータのマウスのように見えるが、他の何かの面にたいする絶対座標を報告するデバイス。
power-button
電源ボタンやボリュームボタン(または同種のコントローラー)。
keyboard
コンピューターキーボード。
touchscreen
コンピュータータッチパッド。
pad
描画タブレットの周辺機器で一般的なセンシティブボタン(sensitive button)、リング(ring)、ストリップ(strip)のコレクション。
touchpad
タッチパッドのような二次的タッチデバイス。
piano
電子キーボードのような音楽器。
test
入力を報告するためにXTEST拡張が使用するデバイス。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プロパティdisplay
やcomposition
をもつテキストや非表示のテキストシーケンスの中間では、Emacsはポイント値を表示できません。したがってコマンドが終了した後にコマンドループにリターンした後にそのようなシーケンス中にポイントがある場合には、そのシーケンスを効果的に不可触にするために、コマンドループは通常ポイントをそのようなシーケンスの端へと移動します。
変数disable-point-adjustment
をセットすることにより、コマンドはこの機能を抑制できます:
この変数が非nil
ならコマンドがコマンドループにリターンするとき、コマンドループはこれらのテキストプロパティをチェックせず、これらのプロパティをもつシーケンスの外にポイントを移動しない。
コマンドループは各コマンドを実行する前にこの変数をnil
にセットするので、あるコマンドがこれをセットしても効果が適用されるのはそのコマンドにたいしてだけである。
この変数を非nil
にセットするとシーケンス外にポイントを移動する、これらの機能は完全にオフになる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsコマンドループは入力イベント(input events)のシーケンスを読み取ります。入力イベントとはキーボードやマウスのアクティビティ、またはEmacsに送られるシステムイベントを表します。キーボードアクティビティにたいするイベントは文字かシンボルです。それ以外のイベントは常にリストになります。このセクションでは入力イベントの表現と意味について詳細を説明します。
この関数はobjectが入力イベントかイベント型なら非nil
をリターンする。
イベントまたはイベント型として非nil
の任意のシンボルが使用されるかもしれないことに注意。eventp
はLispコードによりイベントとして使用されることを意図したシンボルかどうかは区別できない。
22.7.1 キーボードイベント | 通常の文字 — 自身にシンボルされるキー。 | |
22.7.2 ファンクションキー | ファンクションキー — 名前をもつがシンボルではない。 | |
22.7.3 マウスイベント | マウスイベントの概観。 | |
22.7.4 クリックイベント | マウスボタンのプッシュとリリース。 | |
22.7.5 ドラッグイベント | ボタンをリリースする前のマウス移動。 | |
22.7.6 ボタンダウンイベント | ボタンがプッシュされて、まだリリースされていない状態。 | |
22.7.7 リピートイベント | ダブル、トリプルのクリック(またはドラッグ、ダウン) | |
22.7.8 モーションイベント | ボタンを押さずに、マウスだけを移動する。 | |
22.7.9 タッチスクリーンのイベント | タッチスクリーン上での指によるタップや移動。 | |
22.7.10 フォーカスイベント | フレーム間のマウス移動。 | |
22.7.11 Xwidgetイベント | Xwidgetが生成したイベント。. | |
22.7.12 その他のシステムイベント | システムが生成可能なその他のイベント。 | |
22.7.13 イベントの例 | マウスイベントの例。 | |
22.7.14 イベントの分類 | イベントシンボル内の修飾キーを見つける。イベント型。 | |
22.7.15 マウスイベントへのアクセス | マウスイベントから情報抽出する関数。 | |
22.7.16 スクロールバーイベントへのアクセス | スクロールバーイベントから情報取得する関数。 | |
22.7.17 文字列内へのキーボードイベントの配置 | 文字列内にキーボード文字イベントを配すための特別な配慮。 |
[ << ] | [ < ] | [ 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コントロール文字、すなわち27番目のビットがセットされた文字をサポートすると仮定する)。
文字イベントコードのビット 2**25 (26番目のビット)はシフトキーが押下された状態で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
(イベントの分類を参照)を使用してください。keymap-set
でキーバインディングを作成する際には、‘C-H-x’
(“control hyper x”)のような文字列を使ってこれらのイベントを指定できます(キーバインディングの変更を参照)。
[ << ] | [ < ] | [ 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
、…のうちのいずれかで、マウスボタンは左から右に番号が付される。マウスホイールイベントならwheel-up
やwheel-down
かもしれない。
ファンクションキーにたいして行うのと同様にアルト、コントロール、ハイパー、メタ、シフト、スーパーの修飾にたいしてプレフィクス‘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
、tab-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はヘッダーライン、タブラインももてば行1はタブラインとなり、それ以外ならテキストエリアの上端ラインが行0となる。ウィンドウのテキストエリアのクリックにたいしては、テキストエリアの左端列が列0となり、モードラインまたはヘッダーラインのクリックにたいしてはそのラインの左端が列0となる。フリンジまたは垂直ボーダーのクリックにたいしては、これらは有意なデータをもたない。マージンのクリックにたいしては、colはマージンエリアの左端、rowはマージンエリアの上端から測られる。
クリック箇所にイメージがあればfind-image
がリターンするようなイメージオブジェクト(イメージの定義を参照)、それ以外はnil
。
クリック位置からもっとも近いobjectのグリフ左上隅からクリック位置への相対オフセット(ピクセル)。関係のあるobjectはバッファー、文字列、またはイメージ(上記参照)。objectがnil
か文字列なら、クリックされた文字グリフの左上隅からの相対座標。テキストモードのフレームではすべてのグリフのピクセルサイズは正確に1x1とみなされるので、objectがnil
ならオフセットは常に0になることに注意。
クリックがバッファーテキスト、あるいはオーバーレイ文字列やディスプレイ文字列の文字上の場合には、その文字のグリフのピクセル単位での幅と高さ。それ以外の場合にはクリックされたobjectのサイズ。
スクロールバーへのクリックにたいして、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
(スクロールバー端の下矢印)のいずれか。
フレームのインターナルボーダー(フレームのレイアウトを参照)、フレームのツールバー(ツールバーを参照)やタブバーにたいするクリックではpositionは以下の形式をもちます:
(frame part (X . Y) timestamp)
インターナルボーダー、ツールバー、またはタブバーがクリックされたフレーム。
クリックされたフレームの部分。以下のいずれか:
tool-bar
フレームにはツールバーがあり、イベントはツールバー領域。
tab-bar
フレームにはタブバーがあり、イベントはタブバー領域。
left-edge
top-edge
right-edge
bottom-edge
対応するボーダーの直近のコーナーから少なくとも1正規文字の範囲内がクリックされた。
top-left-corner
top-right-corner
bottom-right-corner
bottom-left-corner
インターナルボーダーの対応するコーナーがクリックされた。
nil
フレームにインターナルボーダーがなく、イベントがツールバーやタブバー上ではない。これは通常はテキストモードフレームで発生する。これは非nil
値にセットされたdrag-internal-border
パラメーター(マウスドラッグのパラメーターを参照)をもたないGUIフレームのインターナルボーダーでも発生し得る。
[ << ] | [ < ] | [ 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)イベントを処理する必要があります17。これらは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
のbodyの外側では、Emacsはマウスの単なるモーションにたいするイベントは生成せず、これらのイベントは発生しません。マウスの追跡を参照してください。
非nil
ならたとえ非常に小さい移動でもマウスモーションイベントを生成する。それ以外ならテキスト内の同一グリフをマウスカーソルがポイントし続けるかぎりモーションイベントは生成されない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
一部のウィンドウシステムではユーザーがスクリーンにタッチしたり、タッチしながら指を動かすことで反応する入力デバイスがサポートされています。Emacsはこれらのタッチスクリーンと呼ばれる入力デバイスが生成したイベントをタッチスクリーンイベント(touchscreen event)として報告します。
タッチスクリーンが生成した個々のイベントのほとんどは、他のイベントのより大きなシーケンスの一部としての意味しかもっていません。たとえばタッチスクリーンをタップするという単純な操作はユーザーがタッチスクリーンに指を置いて離すという操作、ディスプレイをスクロールためのスワイプはタッチスクリーンに指を置いて何度も上(下)に動かしてから指を離すという操作を引き起こすのです。
タップやスクロールにたいしては一本の指で構成される単純なモデルで十分ですが、より複雑なジェスチャーには複数の指を追跡するためのサポートが要求されまづ。指が複数の場合には、それぞれの指の位置はタッチポイント(touch point)によって表されることになります。たとえば“ズームするためのピンチアウト”というジェスチャーは、ユーザーが指を2本置いて、それらの指を別個に反対方向へ動かすことから構成されます。ここでこれら2本の指による個別のポイント位置の間の距離によってディスプレイのズーム量、これらの位置を結ぶ想像上の線の中央位置によってズーム後にどこにディスプレイをパンする(振る)かが決まります。
下記の低レベルなタッチスクリーンイベントを使って、上述したタッチシーケンスすべてを実装できます。これらのイベントでは、ポイントはそれぞれポイントを識別する任意の番号、およびイベント発生時の指の位置を指定するマウス位置リスト(クリックイベントを参照)のコンスセルによって表現されます。
(touchscreen-begin point)
これはユーザーがタッチスクリーンにたいして指を押すことでpointが作成されたときに送信されるイベント。
(touchscreen-update points)
これはタッチスクリーン上のポイントの位置が変更されたときに送信されるイベント。pointsはカレントでタッチスクリーン上にあるタッチポイントの最新位置を含んだタッチポイントのリスト。
(touchscreen-end point)
これは他のプログラムにより奪われたりユーザーがタッチスクリーンから指を離したことによってpointがディスプレイ上に存在しなくなった際に送信されるイベント。
[ << ] | [ < ] | [ 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] | [ ? ] |
Xwidgetsは自身の状態によってLispプログラムを更新するためにイベントを送信することができます。(埋め込みネイティブウィジェットを参照)。これらのイベントはxwidget-events
という、変更の性質を説明するさまざまなデータを含んだイベントに置き換えられます。
(xwidget-event kind xwidget arg)
これはxwidgetである種の更新が発生した際は常に送信されるイベント。更新には複数の種類があり、それらはkindによって識別される。
これはxwidgetにたいするxwidgetイベントを受信した際は常に呼び出されるようなコールバック(callback)をxwidgetに追加することによって処理する必要があるスペシャルイベントである(スペシャルイベントを参照)。
コールバックは引数としてxwidgetとkindを受け取る関数であること。コールバックはwidgetのプロパティリストのcallback
をセットすることによって追加できる。
load-changed
これはxwidgetがページローディングプロセスの特定のポイントに達したことを示すxwidgetイベント。argにはこれらのイベントが送信される際には、widgetの状態が更に記述された文字列が含められる。
これはそのwidgetがページローディング操作を開始したことを意味する。
これはxwidgetが前に処理していたページローディング操作が何であれ処理が終了したことを意味する。
これはxwidgetがページローディング操作中にリダイレクトに遭遇して、それをフォローしたことを意味する。
これはxwidgetがページローディング操作中に与えられたURLにコミット(つまりそのURLがカレントのページローディング操作中にレンダリングする最終URL)したことを意味する。
download-callback
このイベントはある種のダウンロードが完了したことを示す。
上記イベントではargの後に引数があるかもしれない。その引数自体はダウンロードしたファイルを取得したURLを示す。argの後の1つ目の引数はそのダウンロードのMIMEタイプ(文字列)を示し、2つ目の引数はダウンロードしたファイルの完全なファイル名が含まれる。
download-started
このイベントはダウンロードが開始したことを示す。これらのイベントにおいて、argにはカレントでダウンロードされるファイルのURLが含まれる。
javascript-callback
このイベントにはJavaScriptのコールバックデータが含まれる。これらのイベントはxwidget-webkit-execute-script
によって内部的に使用される。
(xwidget-display-event xwidget source)
このイベントはxwidgetが他のxwidgetの表示をリクエストした際は常に送信される。xwidgetは表示されることになるxwidget、sourceはxwidgetの表示を要求したxwidget。
これはコールバックを通じて処理を要するスペシャルイベントでもある。そのようなコールバックは引数としてxwidgetとsourceを受け取る関数であり、sourceのプロパティリストのdisplay-callback
にセットして追加できる。
xwidgetのバッファーは一時バッファーにセットされる。widget表示の際には、set-xwidget-buffer
(埋め込みネイティブウィジェットを参照)を使用してバッファーをxwidgetが表示されるバッファーに置き換えるよう注意すること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
他にもシステム内での出来事を表現するイベント型がいくつかあります。
(delete-frame (frame))
このイベントの種類はユーザーがウィンドウマネージャーに特定のウィンドウを削除するコマンドを与えたことを示し、Emacsのフレームにたいして発生する。
フレーム削除(delete-frame)
イベントの標準的な定義ではframeが削除される。
(iconify-frame (frame))
このイベントの種類はウィンドウマネージャーを使用してユーザーがframeをアイコン化したことを示す。標準的な定義はignore
。これはそのフレームがすでにアイコン化されているので、Emacsが行う必要のことは何もないからである。このイベント型の目的は、望むならこのようなイベントの追跡を可能にしておくためである。
(make-frame-visible (frame))
このイベントの種類はウィンドウマネージャーを使用してユーザーがframeを非アイコン化したことを示す。標準的な定義はignore
。これは、そのフレームがすでに可視化されているので、Emacsが行う必要のことは何もないからである。
(touch-end (position))
この種のイベントはユーザーの指がマウスホイールやタッチパッドから離れたことを示す。マウス位置リストのposition要素(クリックイベントを参照)は、マウスホイールから指が離れた際のマウスカーソルの位置を指定する。
(wheel-up position clicks lines pixel-delta)
(wheel-down position clicks lines pixel-delta)
この種類のイベントはマウスホイールを動かすことによって発生する。position要素はそのイベント発生時のマウスカーソル位置を指定するマウス位置リスト(クリックイベントを参照)。
clicksが与えられた場合には、ホイールが連続して素早く動いた回数を示す。リピートイベントを参照のこと。linesが与えられて、それがnil
でなければ、それはスクロールされるべきスクリーン行の行数である。pixel-deltaが与えられた場合には、それが(x . y)
という形式のコンスセルであれば、xとyはそれぞれの軸方向にたいしてスクロールされたピクセル数、いわゆるピクセル単位デルタ(pixelwise
delta)である。
これらのピクセル単位デルタxとyを用いれば、マウスホイールがピクセル解像度で実際にどれだけ動いたかを判断できる。たとえばピクセル単位デルタを使うことによって、ユーザーが回したマウスホイールとまったく同じようにディスプレイをスクロールできるだろう。
この種類のイベントはある種のシステムでのみ発生する。いくつかのシステムでは、かわりにmouse-4
とmouse-5
が使用される。可搬性のあるコードとするためには、マウスホイールにたいしてどのイベント型が期待されるかを決定するために、mwheel.el内で定義されている変数mouse-wheel-up-event
、mouse-wheel-up-alternate-event
、mouse-wheel-down-event
、mouse-wheel-down-alternate-event
を使用すること。
同様にmouse-wheel-left-event
とmouse-wheel-right-event
を生成できる一部のマウスでは、mouse-wheel-tilt-scroll
が非mouse-wheel-tilt-scroll
ならこれらをスクロールに使用できる。ただしこれらのスクロールイベントと同時に別のイベントをも生成するマウスもいくつかあり、邪魔をするかもしれない。この問題を解決するにはこれらのイベントにたいするバインドを削除する方法が一般的である(たとえばmouse-6
やmouse-7
等を削除するがバインドはハードウェアとオペレーティングシステムに大きく依存する)。
(pinch position dx dy scale angle)
この種のイベントはタッチパッドに指を2本置いてそれらを互いに近づけたり離したりする、“ピンチ(pinch)”というジェスチャーをユーザーが行った際に生成される。positionはイベント発生時のマウスポインターの位置を提供するマウス位置リスト(クリックイベントを参照)、dxは同一シーケンス内の最後のイベントから2本の指の間の水平距離の変分、dyは同じく垂直距離の変分、scaleはこのシーケンス開始時の2本の指の間の距離とカレント距離の比率、angleはこのイベントで指と指をつなぐ線分の方向と同一シーケンスの最後のイベントにおける同線分方向との間の角度差(degree)である。
ピンチイベントが送信されるのはピンチシーケンスの開始かその間だけであり、ユーザーがタッチパッド置いた2本の指をピンチではなく回転(rotate)させるように動かすジェスチャーは報告されない。
positionの後の引数はすべて浮動小数点数。
これはユーザーがタッチパッドに2本の指を置いたときが開始、指を離したときに終了するイベントであり、通常はあるシーケンスの一部として送信される。先頭のイベントではdx、dy、angleは0.0
になる。後続するイベントではこのイベント構造のこれらのメンバーにたいしては非0値が報告されるだろう。
dxとdyは1.0
がそれぞれタッチパッドの幅と高さに相当するような想像上の相対的単位として報告される。これらは通常はジェスチャーの下にあるイメージやウィンドウ等のオブジェクトサイズに相対的なものと解釈される。
(preedit-text arg)
これは何が挿入されるかをユーザーに示すために、システムのインプットメソッドがEmacsに何らかのテキストを表示するよう伝える際に送信されるイベント。argの内容は使用中のウィンドウシステムに依存する。
Xではargはカーソルの向こうに配置するテキストを記述する文字列。nil
なら前に表示していたすべてのテキストの削除を意味する。
PGTKフレーム(フレームを参照)では、argはカラーとアンダーラインの属性に関する情報をもつ文字列リスト。以下の形式をもつ:
((string1 (ul . underline-color) (bg . background-color) (fg . foreground-color)) (string2 (ul . underline-color) (bg . background-color) (fg . foreground-color)) … )
文字列に関するテキストを残してカラーの情報は省略可。underline-colorがt
ならテキストのアンダーラインがデフォルトのアンダーラインカラーになること、文字列ならそのカラー名によってアンダーラインが描画されることを意味する。
これは通常ならユーザーがコマンドにバインドするべきではないスペシャルイベントである(スペシャルイベントを参照)。Emacsは通常はこのイベントを受信すると、ポインター背後にあるオーバーレイにイベントに含まれるテキストを表示する。
(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)) (keymap-set 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)
end-session
このイベントはMS-Windowsにおいてユーザーがインタラクティブなセッションを終了したとき、またはシステムがシャットダウンすることをオペレーティングシステムがEmacsに知らせる際に生成される。このイベントの標準的な定義では、秩序に則ってEmacsをシャットダウンできるようにkill-emacs
コマンドを呼び出す(Emacsのkillを参照)。未保存の変更が存在する場合には、ユーザーが後で未保存の変更をリストアするセッションの再起動に使用できるauto-saveファイルを生成する(自動保存を参照)。
キーシーケンスの途中、つまりプレフィクスキーの後にこれらのイベントの1つが到着すると、複数イベントキー内ではなくその前か後にそのイベントが到着するようにEmacsはそのイベントを記録する。
いくつかのdelete-frame
のようなスペシャルイベントは、デフォルトではEmacsコマンドを呼び出します(他のイベントはバインドされない)。special-event-map
を通じて、あるスペシャルイベントがコマンドを呼び出すようにすることができます。このマップでファンクションキーにバインドしたコマンドは、last-input-event
内でそれが呼び出された完全なイベントを調べることができます。スペシャルイベントを参照してください。
[ << ] | [ < ] | [ 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")) (keymap-global-set "<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’が含まれない。同じように‘C-a’のようなASCIIコントロール文字にたいする修飾子リストでは、たとえ‘C-a’の修飾ビットを取り除いて値1をリターンするread-char
を通じて読み取られたイベントであってもcontrol
が含まれる。
この関数は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
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではマウスボタンやモーションイベント内のデータアクセスに役立つ関数を説明します。同じ関数を使用してキーボードイベントデータにもアクセスできますが、キーボードイベントに不適切なデータ要素は0かnil
になります。
以下の2つの関数は、マウスイベントの位置を指定するマウス位置リスト(クリックイベントを参照)をリターンします。
これはeventの開始位置をリターンする。
eventがクリックイベントかボタンダウンイベントなら、この関数はそのイベントの位置をリターンする。eventがドラッグイベントなら、そのドラッグの開始位置をリターンする。
これはeventの終了位置をリターンする。
eventがドラッグイベントなら、この関数はユーザーがマウスボタンをリリースした位置をリターンする。eventがクリックイベントかボタンダウンイベントなら、値はそのイベント固有の開始位置となる。
以下の関数は引数にマウス位置リストを受け取り、そのリストのさまざまな部分をリターンします:
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の値より計算され、そのフレームのデフォルト文字幅とデフォルト行高(行間スペースを含む)の単位で与えられる(そのため実際の文字サイズが非デフォルト値の場合には、実際の行と列は計算された値とは異なるかもしれない)オプションの。window引数が非nil
の場合には、フレームではなくpositionで示されるウィンドウのデフォルト文字幅を使用する(これはたとえば非デフォルトのズームレベルでバッファーを表示しているウィンドウで違いが生じる)。
rowはそのテキストエリアの上端から数えられることに注意。positionにより与えられるウィンドウがヘッダーライン(ウィンドウのヘッダーラインを参照)やタブラインをもつなら、それらはrowの数に含まれない。
position内の実際の行と列をコンスセル(col . row)
でリターンする。値はposition与えられるウィンドウの実際の行と列。クリックイベントを参照のこと。positionが実際のポジション値を含まなければ、この関数はnil
をリターンする。この場合にはおおよその値を取得するためにposn-col-row
を使用できる。
この関数はタブ文字やイメージによるビジュアル列数のように、ディスプレイ上の文字のビジュアル幅を意味しない。標準的な文字単位の座標が必要なら、かわりにposn-col-row
を使用すること。
positionに記述された文字列オブジェクトをリターンする。nil
(positionがバッファーテキストを記述することを意味する)、またはコンスセル(string . string-pos)
のいずれか。
positionにあるイメージオブジェクトをリターンする。nil
(positionにイメージがない)、またはイメージspec (image …)
のいずれか。
positionにより記述されるイメージオブジェクトか文字列オブジェクトをリターンする。nil
(positionがバッファーテキストを記述することを意味する)、イメージ(image …)
、またはコンスセル(string . string-pos)
のいずれか。
positionで記述されるオブジェクトの左上隅からのピクセル単位のxy座標を、コンスセル(dx . dy)
でリターンする。positionがバッファーテキストを記述する場合には、その位置にもっとも近いバッファーテキストの相対位置をリターンする。
positionで記述されるオブジェクトのピクセル幅とピクセル高さを、コンスセル(width
. height)
でリターンする。positionがバッファー位置を記述する場合には、その位置の文字のサイズをリターンする。
positionのタイムスタンプをリターンする。これはミリ秒で表したイベント発生時刻である。このようなタイムスタンプは使用しているウィンドウシステムに応じてさまざまに異なる任意の開始時刻からの相対時刻として報告される。たとえばXウィンドウシステムでは、そのXサーバー開始から経過したミリ秒数となる。
以下の関数は与えられた特定のバッファー、またはスクリーン位置によって位置リストを計算します。上述の関数でこの位置リスト内のデータにアクセスできます。
この関数はwindow内の位置posにたいする位置リストをリターンする。posのデフォルトはwindow内のポイント、windowのデフォルトは選択されたウィンドウ。
window内でposが不可視なら、posn-at-point
はnil
をリターンする。
この関数は指定されたフレームかウィンドウframe-or-window(デフォルトは選択されたウィンドウ)内のピクセル座標xとyに対応する位置情報をリターンする。xとyは、選択されたウィンドウのテキストエリアにたいする相対座標である。wholeが非nil
なら、x座標はスクロールバー、マージン、フリンジを含むウィンドウエリア全体にたいする相対座標。
[ << ] | [ < ] | [ 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プログラムはときおりキーボード文字、たとえばキーシーケンスやキーボードマクロ定義かもしれないキーボード文字を概念的に含んだ文字列を使用します。しかし文字列内へのキーボード文字の格納は、歴史的な互換性の理由から複雑な問題であり、常に可能なわけではありません。
新たに記述するプログラムでは文字列内にコントロール文字類を含むキーボードイベントを格納せずに、key-valid-p
が理解できるEmacsの一般形式で格納することを推奨する。
read-key-sequence-vector
(あるいはread-key-sequence
)でキーシーケンスを読み取ったり、this-command-keys-vector
(あるいはthis-command-keys
)でキーシーケンスにアクセスする場合には、key-description
を使用することでキーシーケンスを推奨フォーマットに変換することができます。
複雑さはキーボード入力に含まれるかもしれない修飾ビットに起因します。メタ修飾以外の修飾ビットは文字列に含めることができず、メタ文字も特別な場合だけ許容されます。
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
も参照してください。端末の入力モードの制御、および端末入力のデバッグに関する関数と変数については、端末の入力を参照してください。
高レベル入力機能についてはミニバッファーを参照してください。
22.8.1 キーシーケンス入力 | キーシーケンスを読み取る方法。 | |
22.8.2 単一イベントの読み取り | イベントを1つだけ読み取る方法。 | |
22.8.3 入力イベントの変更と変換 | Emacsが読み取られたイベントを変更する方法。 | |
22.8.4 入力メソッドの呼び出し | 入力メソッドを使用するイベントを読み取る方法。 | |
22.8.5 クォートされた文字の入力 | 文字の指定をユーザーに問い合わせる。 | |
22.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
はその文字を小文字に変換します(この挙動はユーザーオプションtranslate-upper-case-key-bindings
をnil
にセットして無効にできる)。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
はこの情報を仮想的なプレフィクスキーに変換します。これらはすべてシンボルでありtab-line
、header-line
、horizontal-scroll-bar
、menu-bar
、tab-bar
、mode-line
、vertical-line
、vertical-scroll-bar
、left-margin
、right-margin
、left-fringe
、right-fringe
、right-divider
、bottom-divider
です。これらの仮想的なプレフィクスキーを使用してキーシーケンスを定義することにより、ウィンドウの特別な部分でのカウスクリックにたいして意味を定義できます。
たとえば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
はコマンド入力にたいするもっとも低レベルの関数です。
ミニバッファーを使用して1文字を読み取る関数が必要ならread-char-from-minibuffer
を使用してください(複数の問いを尋ねるを参照)。
この関数はコマンド入力の次のイベントを読み取ってリターンする。必要ならイベントが利用可能になるまで待機する。
リターンされるイベントはユーザーからの直接のイベントかもしれないし、キーボードマクロからのイベントかもしれない。イベントはキーボードの入力コーディングシステム(端末I/Oのエンコーディングを参照)によりデコードされていない。
オプション引数promptが非nil
なら、それはエコーエリアにプロンプトとして表示される文字列。
promptが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
と同じように機能する。
イベントが修飾子をもつ場合には、Emacsはそれらの解決を試みて対応する文字のコードをリターンする。たとえばユーザーがC-aをタイプすると、関数は文字‘C-a’のASCIIコードである1をリターンする。いくつかの修飾子を文字コードに反映できない場合には、read-char
は未解決の修飾子ビットをセットしたままイベントをリターンする。たとえばユーザーがC-M-aをタイプすると、関数は134217729(16進の8000001であり、これはメタ修飾子がセットされた‘C-a’)をリターンする。この値は有効な文字コードではないので、characterp
のテストに失敗する(文字コードを参照)。修飾子ビットが削除された文字の復元にはevent-basic-type
(イベントの分類を参照)、read-char
がリターンした文字イベント内の修飾子をテストするにはevent-modifiers
を使用すること。
以下の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
と同じように機能する。リターン値にはread-char
のように修飾ビットが含まれるかもしれない。
上記の関数でquitを抑制するものはありません。
この変数は端末から受信した入力イベント(キーボードマクロにより生成されたイベントは勘定しない)の総数を保持する。
read-key-sequence
と異なり関数read-event
、read-char
、read-char-exclusive
はイベントシーケンス変換のためのキーマップで説明した変換を行わないことを強調しておきます。単一キー読み取りでこれらの変換を行う —
たとえば端末からファンクションキー(ファンクションキーを参照)、xterm-mouse-mode
からマウスイベント(マウスイベントを参照)を読み取る場合 —
には関数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
はプロンプトを表示しないことを意味する。
引数disable-fallbacksが非nil
なら、read-key-sequence
でバインドされないキーにたいする通常のフォールバックロジックは適用されない。これはbutton-downちmulti-clickのイベントは棄却されず、local-function-key-map
とkey-translation-map
が適用されないことを意味する。nil
または指定されなければ、フォールバックの無効化は最後のイベントのダウンキャスト(訳注:
基本イベントから継承イベントへの型変換)となる。
この関数はcharsのメンバーであるような文字を読み取って1文字をリターンするためにread-from-minibuffer
を使用する。charsのメンバーではない文字が入力されると、その旨を伝えるメッセージして入力を破棄する。
オプション引数inhibit-quitはデフォルトでは無視されるが、変数read-char-choice-use-read-key
が非nil
ならこの関数はread-from-minibuffer
ではなくread-key
を使用する。この場合にはinhibit-quitが非nil
だと、有効な入力待機中のkeyboard-quitイベントを無視することを意味する。加えてread-char-choice-use-read-key
が非nil
の場合には、この関数の呼び出し中にhelp-form
に非nil
値をバインドすることによって、ユーザーがhelp-char
文字を押下した際にhelp-form
を評価してその結果を表示、その後は有効な入力文字、あるいはkeyboard-quitの待機を継続する。
複数の選択肢のある問いをユーザーに尋ねる。promptはプロンプトとして表示する文字列であること。
choicesは各エントリーの1つ目の要素が入力される文字、2つ目の要素がプロンプトを表示する際にそのエントリーにたいして表示する短い名前であるようなalist(スペースがあれば短縮され得る)であり、3つ目のオプションのエントリーはユーザーがより多くのヘルプを要求した際にヘルプバッファーに表示する長い説明。
オプション引数help-stringが非nil
なら、すべてのchoiceをより詳細に記述する文字列であること。これはユーザーが?をタイプした際に、自動生成されたデフォルトの説明のかわりとしてヘルプバッファーに表示される。
オプション引数show-helpが非nil
なら、ユーザーが入力する前に即座にヘルプバッファーが表示される。文字列ならそれがヘルプバッファーの名前として用いられる。
オプション引数long-formが非nil
なら、ユーザーは単一キーではなく(completing-read
を使用して)長い形式をタイプして応答する必要がある。この応答はリストchoicesの2つ目の要素内に存在しなければならない。
リターン値はchoicesのマッチする値。
(read-multiple-choice "Continue connecting?" '((?a "always" "Accept certificate for this and future sessions.") (?s "session only" "Accept certificate this session only.") (?n "no" "Refuse to use certificate, close connection.")))
グラフィカル端末で名前文字列にマッチする文字をハイライトするためにread-multiple-choice-face
フェイスが使用される。
[ << ] | [ < ] | [ 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
を使用する例:
(key-translate "C-x" "<control-x>") (key-translate "C-c" "<control-c>") (key-translate "C-v" "<control-v>") (keymap-global-set "<control-x>" 'kill-region) (keymap-global-set "<control-c>" 'kill-ring-save) (keymap-global-set "<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を強制的に追加する。
このリストから読み取った要素は通常は記録保持機能(入力の記録を参照)により記録されるとともに、キーボードマクロ定義の間(キーボードマクロを参照)は記録される。しかし(no-record . 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)))
この変数はwhile-no-input
が無視するべきスペシャルイベントのセッティングを可能にする。これはイベントシンボルのリスト(イベントの例を参照)。
この関数は端末入力バッファーの内容を破棄して定義処理中かもしれないキーボードマクロをキャンセルする。この関数は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
にバイドされている場所で役に立つ。
キーボードマクロの定義や実行をabortさせることなくquitするために、minibuffer-quit
条件をシグナルすることができます。これはキーボードマクロの定義や実行をexitせずに、コマンド内のエラーハンドラーがこの条件を処理することを除き、quit
とほとんど同じ効果をもつ。
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
を参照)。コマンドC-M-c
(exit-recursive-edit
)がこれを行います。値t
をthrowすることによってrecursive-edit
がquitされるので、1レベル上位のコマンドループに制御がリターンされます。これはabortと呼ばれ、C-](abort-recursive-edit
)がこれを行います。同様にrecursive-edit
にエラーをシグナルさせるために文字列値をthrowできます。この文字列はメッセージとしてプリントされます。関数値をthrowすると。recursive-edit
はリターンする前に引数なしでそれを呼び出します。それ以外の値をthrowすると、recursive-edit
は自身を呼び出した関数に正常にリターンします。コマンドC-M-c
(exit-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プログラムから関数として呼び出したときは効果がありません。
disabled
プロパティの値には、1つ目の要素がシンボルquery
であるようなリストも指定できます。この場合には、ユーザーはそのコマンドを実行するかどうか問い合わせられることになります。このリストの2つ目の要素にはy-or-n-p
を使用するならnil
、yes-or-no-p
なら非nil
を指定する必要があり、3つ目に要素は質問として使用されます。コマンドにたいする問い合わせを有効にするには、利便性のための関数command-query
を使う必要があります。
その時点から特別な確認なしで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: キーの照合)と呼びます。
23.1 キーシーケンス | Lispオブジェクトとしてのキーシーケンス。 | |
23.2 キーマップの基礎 | キーマップの基本概念。 | |
23.3 キーマップのフォーマット | キーマップはLispオブジェクトとしてどのように見えるか。 | |
23.4 キーマップの作成 | キーマップの作成やコピーを行う関数。 | |
23.5 継承とキーマップ | キーマップが他のキーマップのバインディングを継承する方法。 | |
23.6 プレフィクスキー | キーマップの定義としてキーを定義する。 | |
23.7 アクティブなキーマップ | Emacsがアクティブなキーマップでキーバインディングを探す方法。 | |
23.8 アクティブなキーマップの検索 | アクティブなマップ検索のLisp処理概要。 | |
23.9 アクティブなキーマップの制御 | 各バッファーは標準(グローバル)のバインディングをオーバーライドするためのキーマップをもつ。マイナーモードもそれらをオーバーライドできる。 | |
23.10 キーの照合 | 1つのキーマップから、あるキーのバインディングを探す。 | |
23.11 キー照合のための関数 | キールックアップを要求する方法。 | |
23.12 キーバインディングの変更 | キーマップ内でのキーの再定義。 | |
23.13 低レベルなキーバインディング | 従来のキー構文について。 | |
23.14 コマンドのリマップ | キーマップはあるコマンドを他のコマンドに変換できる。 | |
23.15 イベントシーケンス変換のためのキーマップ | イベントシーケンスを変換するキーマップ。 | |
23.16 キーのバインドのためのコマンド | キーの再定義にたいするインタラクティブなインターフェイス。 | |
23.17 キーマップのスキャン | ヘルプをプリントするためにすべてのキーマップを走査する。 | |
23.18 メニューキーアップ | キーマップとしてキーマップを定義する。 |
[ << ] | [ < ] | [ 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]
kbd
は非常に融通の効く関数であり、完全には準拠していない構文が使用されたとしても適切な何かをリターンしようと試みる。構文が実際に有効か否かをチェックするにはkey-valid-p
関数を使用すること。
[ << ] | [ < ] | [ 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-set
(キーバインディングの変更を参照)を使用してそのマップ内のキーバインディングを指定する。ただしモードを記述する際には一度に大量のキーのバインドを要することが頻繁にあるため、keymap-set
を使用してそれらすべてをバインドするのは面倒かもしれないしエラーも起きやすいだろう。かわりにキーマップの作成と複数のキーのバインドを行うdefine-keymap
を使うことができる。基本的な例を以下に示す:
(define-keymap "n" #'forward-line "f" #'previous-line "C-c C-c" #'quit-window)
この関数はpairs内のキーストロークを定義するsparseキーマップを新たに作成して、そのキーマップをリターンする。pairs内に重複したキーバインディングがあればエラーをシグナルする。
pairsはkeymap-set
が受け入れるようなキーバインディングとキー定義が交互に指定されたリスト。更にキーは特別なシンボル:menu
でもよい。この場合には、定義easy-menu-define
(easy-menuを参照)が許容するようなメニュー定義であること。以下は使い方を示す簡単な例:
(define-keymap :full t "g" #'eww-reload :menu '("Eww" ["Exit" quit-window t] ["Reload" eww-reload t]))
新たなキーマップの機能を変更するために、キー/定義のペアーの前にいくつかのキーワードを使うことができる。define-keymap
の呼び出しに含まれていないキーワードの機能にたいするデフォルト値はnil
。利用可能な機能キーワードは以下のとおり:
:full
非nil
なら(make-sparse-keymap
が作成するような)sparseキーマップのかわりに、(make-keymap
が作成するような)文字テーブルキーマップを作成する(キーマップの作成を参照)。デフォルトはsparseキーマップ。
:parent
非nil
なら値は親として使用するキーマップであること(継承とキーマップを参照)。
:keymap
非nil
なら、値はキーマップであること。新たにキーマップを作成するかわりに指定されたキーマップを変更する。
:suppress
非nil
なら、そのキーマップはsuppress-keymap
によって抑制される(キーバインディングの変更を参照)。デフォルトでは数字とマイナス記号は抑制から除外されるが、値がnodigits
なら他の文字と同様に数字とマイナス記号も抑制する。
:name
非nil
、かつx-popup-menu
(ポップアップメニューを参照)によるメニューとして使用する場合には、値をメニューとして使用するような文字列にする必要がある。
:prefix
非nil
なら、値はプレフィックスコマンドとして使用するシンボルであること(プレフィクスキーを参照)。この場合にはマップ自体ではなく、このシンボルがdefine-keymap
によってリターンされる。
キーマップでもっとも一般的に行われるのは専ら変数へのバインドであろう。これはほぼすべてのモードが行っていることであり、foo
と呼ばれるモードにはほとんど常にfoo-mode-map
と呼ばれる変数が存在する。
このマクロはnameを変数として定義して、optionsとpairsをdefine-keymap
に渡した結果をその変数のデフォルト値として使用する。pairs内に重複したキーバインディングがあればエラーをシグナルする。
optionsはdefine-keymap
におけるキーワードと同様だが、定義される変数にたいしてdoc文字列を提供するためのキーワード:doc
が追加されている。
以下は例:
(defvar-keymap eww-textarea-map :parent text-mode-map :doc "Keymap for the eww text area." "RET" #'forward-line "TAB" #'shr-next-link)
キーマップ内のコマンドはそれぞれrepeat-map
プロパティを配置することによって、(repeat-mode
で便利なように)‘repeatable(繰り返し可能)’とマークすることができる、たとえば
(put 'undo 'repeat-map 'undo-repeat-map)
repeat-mode
によって使用されるマップがこのプロパティになる。
put
を繰り返し呼び出すことを避けるためのキーワードとして、defvar-keymap
には:repeat
がある。このキーワードを使えばキーマップのどのコマンドがrepeat-mode
で使用可能かを指定できる。使用できる値は以下のとおり:
t
キーマップのすべてのコマンドが繰り返し可能ということを意味する。もっとも一般的な使い方。
(:enter (commands ...) :exit (commands ...))
:enter
リストにあるコマンドでrepeat-mode
にエンター、:exit
リストにあるコマンドでrepeatモードからexitすることを指定する。
:enter
リストが空の場合には、そのマップのすべてのコマンドがrepeat-mode
にエンターする。このリストに1つ以上のコマンドを指定しておけば、定義しているマップには存在しないものの、repeat-map
プロパティをもつべきコマンドがある場合に役に立つだろう。
:exit
リストが空なら、そのマップにおいてrepeat-mode
をexitするコマンドは存在しない。このリストに1つ以上のコマンドを指定しておけば、定義しているマップにrepeat-map
プロパティをもつべきではないコマンドが含まれる場合に役に立つだろう。
たとえばuでundo
コマンドを繰り返す場合には、以下の2節は等価である:
(defvar-keymap undo-repeat-map "u" #'undo) (put 'undo 'repeat-map 'undo-repeat-map)
または
(defvar-keymap undo-repeat-map :repeat t "u" #'undo)
マップに多くのコマンドがあり、それらすべてを繰り返し可能にする必要がある場合には後者を使うほうがよいだろう。
この関数はkeymapのコピーをリターンする。これはほとんど必要ないだろう。ほとんど差のないキーマップが必要なら、コピーより以下のように継承を使用するべきである:
(let ((map (make-sparse-keymap))) (set-keymap-parent map <theirmap>) (keymap-set map ...) ...)
copy-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でオーバーライドできるという効果があります。
keymap-set
や他のキーバインディング関数を使用してparent-keymap内のバインディングを変更すると、変更されたバインディングはelementsで作られたバインディングにshadowされない限り継承されたキーマップ内で可視になります。逆は成り立ちません。keymap-set
を使用して継承されたキーマップ内のバインディングを変更すると、これらの変更は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
なバインディングはオーバーライドしない。
For example, here is how Emacs sets the parent of
たとえば以下はbutton-buffer-map
とspecial-mode-map
の両方を継承するhelp-mode-map
のようなキーマップの親キーマップをEmacsがセットする方法です:
(defvar-keymap help-mode-map :parent (make-composed-keymap button-buffer-map special-mode-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にたいして使用されるグローバルキーマップである。
tab-prefix-map
はプレフィクスキーC-x tにたいして使用されるグローバルキーマップである。
vc-prefix-map
はプレフィクスキーC-x vにたいして使用されるグローバルキーマップである。
goto-map
はプレフィクスキーM-gにたいして使用されるグローバルキーマップである。
search-map
はプレフィクスキーM-sにたいして使用されるグローバルキーマップである。
プレフィクスキーのキーマップバインディングは、プレフィクスキーに続くイベントをルックアップするために使用されます(これは関数定義がキーマップであるようなシンボルかもしれない。効果は同じだがシンボルはプレフィクスキーにたいする名前の役割を果たす)。したがって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
9はすべてのアクティブなキーマップで見つけることができません。
(use-local-map (make-sparse-keymap)) ⇒ nil
(keymap-local-set "C-p" ctl-x-map) ⇒ (keymap #^[nil nil keymap …
(keymap-lookup nil "C-p C-f") ⇒ find-file
(keymap-lookup nil "C-p 9") ⇒ 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プロパティがあるなら、それはバッファーのデフォルトローカルキーマップのかわりに使用するローカルキーマップを指定します。
ローカルキーマップは通常はそのバッファーのメジャーモードによってセットされます。同じメジャーモードをもつすべてのバッファーは、同じローカルキーマップを共有します。したがってあるバッファーでローカルキーマップを変更するためにkeymap-local-set
(キーのバインドのためのコマンドを参照)を呼び出すと、それは同じメジャーモードをもつ他のバッファーのローカルキーマップにも影響を与えます。
最後は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
によってリターンされるイベント位置、またはバッファー位置を指定でき、keymap-lookup
(keymap-lookupを参照)で説明されているようにキーマップを変更するかもしれない。
[ << ] | [ < ] | [ 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-char-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
と同じ値。リターン値はコピーではなく参照である。これにkeymap-set
などの関数を使用すると、グローバルバインディングが変更されるだろう。
(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
はローカルキーマップのコピーではなく参照をリターンします。これにkeymap-set
などの関数を使用するとローカルバインディングが変更されるでしょう。
この関数はカレントで有効なメジャーモードのキーマップリストをリターンする。
この関数は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が非アクティブになった後に引数なしで呼び出される関数を指定する。
オプション引数messageには一時的なマップをアクティブ化後に表示するメッセージを指定する。messageが文字列ならメッセージ用のフォーマット文字列であり、文字列中のすべての‘%k’指定子は一時的マップのキーのリストに置き換えられる。messageの値としては、それ以外の非nil
値はデフォルトのメッセージフォーマット‘Repeat
with %k’を意味する。
オプション引数timeoutが非nil
なら、それはkeymapを非アクティブにするまでに待機するアイドル時間を秒数で指定する数値であること。変数set-transient-map-timeout
の値が非nil
なら、この引数の値をオーバーライドする。
この関数は他のすべてのアクティブなキーマップに優先される変数overriding-terminal-local-map
にたいして、keymapを追加または削除することによって機能する(アクティブなキーマップの検索を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
キールックアップ(key lookup: キー照合)とは与えられたキーマップからキーシーケンスのバインディングを見つけ出すことです。そのバインディングの使用や実行はキールックアップの一部ではありません。
キールックアップはキーシーケンス内の各イベントのイベント型だけを使用して、そのイベントの残りは無視します。実際のところキールックアップに使用されるキーシーケンスは、マウスイベントをイベント全体(リスト)のかわりにイベント型のみ(シンボル)を用いるでしょう。入力イベントを参照してください。そのようなキーシーケンスはcommand-execute
による実行には不十分ですが、キーのルックアップやリバインドには十分です。
キーシーケンスが複数イベントから構成されるとき、キールックアップはイベントを順に処理します。最初のイベントのバインディングが見つかったとき、それはキーマップでなければなりません。そのキーマップ内で2つ目のイベントを見つけ出して、そのキーシーケンス内のすべてのイベントが消費されるまで、このプロセスを続けます(故に最後のイベントにたいして見つかったイベントはキーマップかどうかはわからない)。したがってキールックアッププロセスはキーマップ内で単一イベントを見つけ出す、よりシンプルなプロセスで定義されます。これが行なわれる方法はキーマップ内でそのイベントに関連するオブジェクトの型に依存します。
キーマップ内のイベント型ルックアップによる値の発見を説明するために、キーマップエントリー(keymap
entry)という用語を導入しましょう(これにはメニューアイテムにたいするキーマップ内のアイテム文字列や他の余計な要素は含まれない。なぜならkeymap-lookup
や他のキーマップルックアップ関数がリターン値にそれらを含まないから)。任意のLispオブジェクトがキーマップエントリーとしてキーマップに格納されるかもしれませんが、すべてがキールックアップに意味をもつわけではありません。以下のテーブルはキーマップエントリーで重要な型です:
nil
¶nil
はそれまでにルックアップに使用されたイベントが未定義キーを形成することを意味する。最終的にキーマップがイベント型を調べるのに失敗してデフォルトバインディングも存在しないときは、そのイベント型のバインディングがnil
であるのと同じである。
それまでにルックアップに使用されたイベントがコンプリートキーを形成して、commandがそのバインディングである。関数とは?を参照のこと。
array(文字列かベクター)はキーボードマクロである。それまでにルックアップに使用されたイベントはコンプリートキーを形成して、arrayがそのバインディングである。詳細はキーボードマクロを参照のこと。
それまでにルックアップに使用されたイベントはプレフィクスキーを形成する。そのキーシーケンスの次のイベントはkeymap内でルックアップされる。
listの意味はそのリストが何を含んでいるかに依存する:
keymap
なら、そのリストはキーマップでありキーマップとして扱われる(上記参照)。
lambda
なら、そのリストはラムダ式である。これは関数とみなされてそのように扱われる(上記参照)。キーバインディングとして正しく実行されるために、この関数はコマンドでなければならずinteractive
指定をもたなければならない。コマンドの定義を参照のこと。
symbolの関数定義がsymbolのかわりに使用される。もし関数定義もシンボルなら、任意の回数このプロセスが繰り返される。これは最終的にキーマップであるようなオブジェクト、コマンド、またはキーボードマクロに行き着くはずである。
キーマップとキーボードマクロ(文字列かベクター)は有効な関数ではないので関数定義にキーマップ、文字列、ベクターをもつシンボルは関数としては無効であることに注意。しかしキーバインディングとしては有効である。その定義がキーボードマクロなら、そのシンボルはcommand-execute
(インタラクティブな呼び出しを参照)の引数としても有効である。
シンボルundefined
は特記するに値する。これはそのキーを未定義として扱うことを意味する。厳密に言うとそのキーは定義されているが、そのバインディングがコマンドundefined
なのである。しかしこのコマンドは未定義キーにたいして自動的に行われるのと同じことを行う。これは(ding
を呼び出して)bellを鳴らすがエラーはシグナルしない。
undefined
はグローバルキーバインディングをオーバーライドして、そのキーをローカルに未定義とするために使用される。nil
にローカルにバインドしてもグローバルバインディングをオーバーライドしないであろうから、これを行うのに失敗するだろう。
オブジェクトの他の型が見つかったら、それまでにルックアップで使用されたイベントはコンプリートキーを形成してそのオブジェクトがバインディングになるが、そのバインディングはコマンドとして実行不可能である。
要約するとキーマップエントリーはキーマップ、コマンド、キーボードマクロ、あるいはそれらに導出されるシンボル、あるいはnil
のいずれかです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はキールックアップに関連する関数および変数です。
この関数はkeymap内のkeyの定義をリターンする。このチャプターで説明されているキーをルックアップする他のすべての関数がkeymap-lookup
を使用する。以下は例:
(keymap-lookup (current-global-map) "C-x C-f") ⇒ find-file
(keymap-lookup (current-global-map) "C-x C-f 1 2 3 4 5") ⇒ 2
文字列かベクターのkeyがkeymap内で指定されるプレフィクスキーとして有効なキーシーケンスでなければ、それは最後に余計なイベントをもった、単一のキーシーケンスに適合しない長過ぎるキーのはずである。その場合のリターン値は数となり、この数はコンプリートキーを構成するkeyの前にあるイベントの数である。
accept-defaultsが非nil
なら、keymap-lookup
はkey内の特定のイベントにたいするバインディングと同様にデフォルトバインディングも考慮する。それ以外ではkeymap-lookup
は特定のkeyのシーケンスにたいするバインディングだけを報告して、明示的に指定したとき以外はデフォルトバインディングを無視する(これを行うにはkeyの要素としてt
を与える。キーマップのフォーマットを参照)。
keyがメタ文字(ファンクションキーではない)を含むなら、その文字は暗黙にmeta-prefix-char
の値と対応する非メタ文字からなる2文字シーケンスに置き換えられる。したがって以下の1つ目の例は2つ目の例に変換されて処理される。
(keymap-lookup (current-global-map) "M-f") ⇒ forward-word
(keymap-lookup (current-global-map) "ESC f") ⇒ forward-word
keymap引数はnil
でもよい。これはカレントキーマップ(current-active-maps
によってリターンされるキーマップ;
アクティブなキーマップを参照)でkeyを探すことを意味する。またはキーマップやキーマップのリストでもよく、この場合には指定されたキーマップからのみキーを探すことを意味する。
read-key-sequence
とは異なり、この関数は指定されたイベントの情報を破棄する変更(キーシーケンス入力を参照)を行わない。特にこの関数はアルファベット文字を小文字に変更せず、ドラッグイベントをクリックイベントに変更しない。
keymap-lookup
は通常のコマンドループが行うように、カレントキーマップ内のコマンドを調べることによってkeyを見つけ出し、その結果によってコマンドのリマップを行う。ただしオプションの第3引数no-remapが非nil
なら。keymap-lookup
はリマップをせずにそのコマンドをリターンする。
オプション引数positionが非nil
なら、それはevent-start
やevent-end
がリターンするようなマウス位置を指定する。そしてルックアップはkeymapではなく、その位置に関連付けられているキーマップにたいして行われる。positionは数値かマーカーでもよく、その場合にはバッファー位置として解釈されて、この関数はポイント位置ではなく指定した位置のキーマッププロパティを使用する。
キーを未定義にするためにキーマップ内で使用される。これはding
を呼び出すがエラーを発生ささない。
この関数はカレントのローカルキーマップ内のkeyにたいするバインディングをリターンする。カレントのローカルキーマップ内で未定義ならnil
をリターンする。
引数accept-defaultsはkeymap-lookup
(上記)と同じようにデフォルトバインディングのチェックを制御する。
この関数はカレントのグローバルキーマップ内でコマンドkeyにたいするバインディングをリターンする。カレントのグローバルキーマップ内で未定義ならnil
をリターンする。
引数accept-defaultsはkeymap-lookup
(上記)と同じようにデフォルトバインディングのチェックを制御する。
この関数はアクティブなマイナーモードのkeyのバインディングをリストでリターンする。より正確にはこの関数は(modename
.
binding)
のようなペアのalistをリターンする。ここでmodenameなそのマイナーモードを有効にする変数、bindingはそのモードでのkeyのバインディングである。keyがマイナーモードバインディングをもたなければ値はnil
。
最初に見つかったバインディングがプレフィクス定義(キーマップ、またはキーマップとして定義されたシンボル)でなければ、他のマイナーモードに由来するすべての後続するバインディングは完全にshadowされて省略される。同様にこのリストはプレフィクスバインディングに後続する非プレフィクスバインディングは省略される。
引数accept-defaultsはkeymap-lookup
(上記)と同じようにデフォルトバインディングのチェックを制御する。
この変数はメタ/プレフィクス文字コードである。これはメタ文字をキーマップ内でルックアップできるように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しているバッファーでは直接影響しないとしても)すべてのバッファーに影響します。カレントバッファーのローカルマップを変更すると、通常は同じメジャーモードを使用するすべてのバッファーに影響します。関数keymap-global-set
とkeymap-local-set
は、これらの操作のための使いやすいインターフェイスです(キーのバインドのためのコマンドを参照)。より汎用的な関数keymap-set
を使用することもできます。その場合には変更するマップを明示的に指定しなければなりません。
Lispプログラムでリバインドするキーシーケンスを選択するときは、さまざまなキーの使用についてのEmacsの慣習にしたがってください(キーバインディング規約を参照)。
以下の関数はkeymapがキーマップではない、あるいはkeyが有効なキーでなければエラーをシグナルします。
keyは単一のキーを表す文字列、あるいは一連のキーストロークであり、key-valid-p
を満足しなければなりません。キーストロークは1つのスペース文字によって区切られています。
キーストロークはそれぞれ単一の文字、あるいは山カッコ(angle brackets)で括られたイベント名です。更にすべてのキーストロークにたいして1つ以上の修飾キーが前置されているかもしれません。最後に数は限られますが特別な短縮構文をもつ文字があります。以下に例としてキーシーケンスの例を示します:
キーのf。
S、o、mの3文字からなるキーシーケンス。
controlで修飾されたキーc、その後にキーo。
hyperで修飾されたleftという名前のキー。
metaで修飾されたreturnキー。
controlとmetaで修飾されたspaceキー。
特別な短縮構文をもつキーはNUL、RET、TAB、LFD、ESC、SPC、DELだけです。
修飾キーは‘Alt-Control-Hyper-Meta-Shift-super’、すなわち‘A-C-H-M-S-s’のアルファベット順に指定する必要があります。
この関数はkeymap内でkeyにたいするバインディングをセットする(keyが長さ2以上のイベントなら、その変更は実際はkeymapから辿られる他のキーマップで行なわれる)。引数bindingには任意のLispオブジェクトを指定できるが、意味があるのは特定のオブジェクトだけである(意味のある型のリストはキーの照合を参照)。keymap-set
のリターン値はbindingである。
keyが<t>なら、それはkeymap内でデフォルトバインディングをセットする。イベントが自身のバインディングをもたないとき、そのキーマップ内にデフォルトバインディングが存在すればEmacsコマンドループはそれを使用する。
keyのすべてのプレフィクスはプレフィクスキー(キーマップにバインドされる)か未定義のいずれかでなけらばならず、それ以外ならエラーがシグナルされる。keyのいくつかのプレフィクスが未定義ならkeymap-set
はそれをプレフィクスキーとして定義するので、残りのkeyは指定されたように定義できる。
前にkeymap内でkeyにたいするバインディングが存在しなければ、新たなバインディングがkeymapの先頭に追加される。キーマップ内のバインディングの順序はキーボード入力にたいし影響を与えないが、メニューキーマップにたいしては問題となる(メニューキーアップを参照)。
これはkeymap-set
の逆バージョンの関数。keymap内のkeyのバインディングを解除(unset)する(nil
にセットするのと同じ)。バインディングを完全に削除する場合には、removeに非nil
を指定すればよい。これに違いが生じるのは、keymapに親キーマップがある場合のみ。子マップでキーのバインディングを解除しただけでは、依然としてそれが親マップの同じキーをシャドーし続けるだろう。removeを使うことによって、親キーマップのキーが用いられることになる。
注意:
removeに非nil
を指定してのkeymap-unset
の使用は、ユーザーがinitファイルに記述する場合を想定したものです。Emacsパッケージは他のパッケージのキーマップを変更するべきではなく、いずれにせよ自身のキーマップにたいして完全な制御を有しているので、可能であれば使用を避けてください。
以下はsparseキーマップを作成してその中にバインディングをいくつか作成する例:
(setq map (make-sparse-keymap)) ⇒ (keymap)
(keymap-set map "C-f" 'forward-char) ⇒ forward-char
map ⇒ (keymap (6 . forward-char))
;; C-xにたいしsparseサブマップを作成して
;; その中でfをバインドする
(keymap-set map "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
にバインド (keymap-set map "C-p" ctl-x-map) ;;ctl-x-map
⇒ [nil … find-file … backward-kill-sentence]
;; ctl-x-map
内でC-fをfoo
にバインド
(keymap-set map "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の両方のバインディングを変更する効果をもつことに注意。
一般的にキーマップ内でキーを定義する際に主に作業を担うのがkeymap-set
です。ただしモードを記述する際には一度に大量のキーのバインドを要することが多々あり、それらすべてにたいしてkeymap-set
を使うのは煩雑ですし、エラーも起こりやすくなります。かわりにdefine-keymap
を使えばキーマップを作成して複数のキーのバインドを行うことができます。詳細についてははキーマップの作成を参照してください。
関数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 (list 'keymap (cons ?1 olddef-1) (cons ?2 olddef-2) (cons ?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) (keymap-set map "q" 'quit-window) … map))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
歴史的にEmacsはキーを定義するために、異なる複数の構文を複数サポートしてきました。現時点ではキーをバインドする方法として文書化されているのは、key-valid-p
がサポートしている構文を使用する方法です。これはkeymap-set
やkeymap-lookup
のような関数がサポートするすべてのことを行うことができます。このセクションでは旧スタイルの構文とインターフェイス関数について記述しました。これらを新しいコードで使用するべきではありません。
define-key
(およびキーのリバインドに用いられるその他の低レベル関数)は、キーにたいして複数の異なる構文を理解します。
修飾名に基本イベント(文字かファンクションキー名)を1つを加えたものをリストに含めることができる。たとえば[(control ?a)
(meta b)]
はC-a M-b、[(hyper control left)]
はC-H-leftと等価。
キーシーケンスは内部的にはshift、control、metaといった修飾キー用の特別なエスケープシーケンス(文字列型を参照)を用いた文字列として表現されていることがよくあるが、この表現はユーザーがキーのリバインドを行う際にも使うことができる。"\M-x"
や"\C-f"
のような文字列はそれぞれ単一のM-xやC-f、"\M-\C-x"
と"\C-\M-x"
はいずれも単一のC-M-xを含んだキーシーケンスとして読み取られる。
これはキーシーケンスを表す別の内部表現である。文字列表現よりも幅広い範囲の修飾をサポートしており、ファンクションキーもサポートしている。‘[?\C-\H-x home]’を例とすると、これはC-H-x homeというキーシーケンスを表している。文字型を参照のこと。
これはkeymap-set
(キーバインディングの変更を参照)と似ているが、旧来のキー構文だけを理解する。
この関数には更にremove引数もある。これが非nil
だと、その定義は削除される。これは概ね定義にnil
をセットするのと同義だが、keymapに親があってkeyが親の同一バインディングをシャドーしている場合に違いが生じる。removeの場合にはそれ以降のルックアップで親のバインディングがリターンされるが、nil
の定義ではルックアップにたいしてnil
がリターンされるだろう。
他にも以下のような旧来のキー定義関数とコマンドがありますが、新しいコードでは等価な新式の関数を使用してください。
この関数はカレントグローバルマップ内でkeyのバインディングをbindingにセットする。かわりにkeymap-global-set
を使うこと。
この関数はカレントグローバルマップからkeyのバインディングを削除する。かわりにkeymap-global-unset
を使うこと。
この関数はカレントローカルキーマップ内のkeyのバインディングをbindingにセットする。かわりにkeymap-local-set
を使うこと。
この関数はカレントローカルキーマップからkeyのバインディングを削除する。かわりにkeymap-local-unset
を使うこと。
この関数はkeymap内でolddefにバインドされるすべてのキーについてolddefをnewdefに置き換える。言い換えるとolddefが出現する箇所のすべてをnewdefに置き換える。この関数はnil
をリターンする。かわりにkeymap-substitute
を使うこと。
define-key
と同じようにmap内にkeyにたいする値bindingのバインディングを定義するが、map内でのバインディング位置はイベントafterのバインディングの後になる。引数keyは長さ1
— 1要素だけのベクターか文字列にすること。しかしafterは単一のイベント型 —
シーケンスではないシンボルか文字にすること。新たなバインディングはafterのバインディングの後に追加される。afterがt
または省略された場合には、新たなバインディングはそのキーマップの最後に追加される。しかし新たなバインディングは継承されたすべてのキーマップの前に追加される。この関数ではなくkeymap-set-after
を使うこと。
この関数は文字コードをfromからtoに変換することによってkeyboard-translate-table
話変更する。かわりにkey-translate
を使うこと。
この関数はカレントでアクティブなキーマップに応じて、keyにたいするバインディングをリターンする。そのキーマップでkeyが未定義なら結果はnil
になる。引数accept-defaultsはlookup-key
(キー照合のための関数を参照)の場合と同じように、デフォルトのバインディングのチェックを行うかどうかを制御する。no-remapが非nil
ならkey-binding
はコマンドのリマップ(コマンドのリマップを参照)を無視して、keyに直接指定されているバインディングをリターンする。オプション引数positionはバッファー位置、あるいはevent-start
の値のようなイベント位置のいずれかであること。これによりpositionにもとづいて照会するマップを判断するように告げる。
keyが文字列とベクターのいずれでもなければEmacsはエラーをシグナルする。
この関数ではなくかわりにkeymap-lookup
を使うこと。
この関数はkeymapからkeyの定義をリターンする。文字列かベクターのkeyがkeymap内で指定されるプレフィクスキーとして有効なキーシーケンスでなければ、それは最後に余計なイベントをもった、単一のキーシーケンスに適合しない長過ぎるキーのはずである。その場合のリターン値は数となり、この数はコンプリートキーを構成するkeyの前にあるイベントの数である。
accept-defaultsが非nil
なら、lookup-key
はkey内の特定のイベントにたいするバインディングと同様にデフォルトバインディングも考慮する。それ以外ではlookup-key
は特定のkeyのシーケンスにたいするバインディングだけを報告して、明示的に指定したとき以外はデフォルトバインディングを無視する。
この関数ではなくかわりにkeymap-lookup
を使うこと。
この関数はカレントのローカルキーマップ内のkeyにたいするバインディングをリターンする。カレントのローカルキーマップ内で未定義ならnil
をリターンする。
引数accept-defaultsはlookup-key
(上記)と同じようにデフォルトバインディングのチェックを制御する。
この関数はカレントのグローバルキーマップ内でコマンドkeyにたいするバインディングをリターンする。カレントのグローバルキーマップ内で未定義ならnil
をリターンする。
引数accept-defaultsはlookup-key
(上記)と同じようにデフォルトバインディングのチェックを制御する。
この修飾名のリストと基本的なイベントタイプを、それらすべてを指定するイベントタイプに変換する。基本的なイベントタイプはリストの最後の要素でなければならない。たとえば、
(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] | [ ? ] |
あるコマンドから他のコマンドへのリマップ(remap)には、特別な種類のキーバインディングが使用できます。この機能を使用するためには、ダミーイベントremap
で始まり、その後にリマップしたいコマンド名が続くようなキーシーケンスにたいするキーバインディングを作成します。そしてそのバインディングにたいしては、新たな定義(通常はコマンド名だがキーバインディングにたいして有効な他の任意の定義を指定可能)を指定します。
たとえばMyモードというモードが、kill-line
のかわりに呼び出されるmy-kill-line
という特別なコマンドを提供するとします。これを設定するには、このモードのキーマップに以下のようなリマッピングが含まれるはずです:
(keymap-set my-mode-map "<remap> <kill-line>" 'my-kill-line)
その後はmy-mode-map
がアクティブなときは常に、ユーザーがC-k
(kill-line
にたいするデフォルトのグローバルキーシーケンス)をタイプするとEmacsはかわりにmy-kill-line
を実行するでしょう。
リマップはアクティブなキーマップでのみ行なわれることに注意してください。たとえばctl-x-map
のようなプレフィクスキーマップ内にリマッピングを置いても、そのようなキーマップはそれ自体がアクティブでないので通常は効果がありません。それに加えてリマップは1レベルを通じてのみ機能します。以下の例では、
(keymap-set my-mode-map "<remap> <kill-line>" 'my-kill-line) (keymap-set 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
にリマップします:
(keymap-set 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
を継承する。後者はすべての端末にバインディングを適用したい場合のみ修正するべきなので、ほとんど常に前者の使用が望ましい。
この変数は入力イベントを他のイベントに変換するために、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 (ash 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))))) (keymap-set local-function-key-map "C-c h" '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-c
ESCの直後に読み取りを停止して、O Pが読み取られずに残るからです。この場合にはユーザーが実際にC-c
ESCをタイプすると、ユーザーが実際にESCを押下したのか、あるいはPF1を押下したのか判断するためにEmacsが待つべきではないのです。
この理由によりキーシーケンスの終わりがキー変換のプレフィクスであるようなキーシーケンスをコマンドにバインドするのは、避けたほうがよいでしょう。そのような問題を起こす主なサフィックス、およびプレフィクスはESC、M-O (実際はESC O)、M-[ (実際はESC [)です。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではキーバインディングを変更するために役に立つ、インタラクティブなインターフェイスをいくつか説明します。これらのインターフェイスはkeymap-set
(キーバインディングの変更を参照)を呼び出すことによって機能します。これらのコマンドはインタラクティブに使用すると引数keyの入力を求めて、ユーザーが有効なキーシーケンスをタイプすることを期待します。更にそのキーシーケンスにたいするbindingの入力も求めて、ユーザーがコマンド名(commandp
を満足するシンボル;
インタラクティブな呼び出しを参照)を入力することを期待します。これらのコマンドはLispから呼び出されるとkeyにはkey-valid-p
(see キーシーケンス)を満足するような文字列、bindingにはキーマップにおいて意味をもつ任意のLispオブジェクト(キーの照合を参照)を期待します。
ユーザーはinitファイルにたいしてシンプルなカスタマイズを行うとき、しばしばkeymap-global-set
を使用します。たとえば、
(keymap-global-set "C-x C-\\" 'next-line)
は、次の行に移動するようにC-x C-\を再定義します。
(keymap-global-set "M-<mouse-1>" 'mouse-set-point)
は、メタキーを押してマウスの第一ボタン(左ボタン)をクリックすると、クリックした箇所にポイントをセットするように再定義します。
バインドするキーのLisp指定に非ASCII文字のテキストを使用するときには注意してください。マルチバイトとして読み取られたテキストがあるなら、Lispファイル内でマルチバイトテキストが読み取られるときのように(非ASCII文字のロードを参照)、マルチバイトとしてキーをタイプしなければなりません。たとえば、
(keymap-global-set "ö" 'my-function) ; bind o-umlaut
をLatin-1のマルチバイト環境で使用すると、これらのコマンドはLatin-1端末から送信されたバイトコード246(M-v)ではなく、コード246のマルチバイト文字に実際にはバインドされます。このバインディングを使用するためには適切な入力メソッド(Input Methods in The GNU Emacs Manualを参照)を使用して、キーボードをデコードする方法をEmacsに教える必要があります。
この関数はカレントグローバルマップ内でkeyのバインディングをbindingにセットする。
(keymap-global-set key binding) ≡ (keymap-set (current-global-map) key binding)
この関数はカレントグローバルマップからkeyのバインディングを削除する。
プレフィクスとしてkeyを使用する長いキーの定義の準備に使用するのもこの関数の1つの用途である。keyが非プレフィクスのようなバインディングをもつならこの使い方は許容されないだろう。たとえば、
(keymap-global-unset "C-l") ⇒ nil
(keymap-global-set "C-l C-l" 'redraw-display) ⇒ nil
この関数はカレントローカルキーマップ内のkeyのバインディングをbindingにセットする。
(keymap-local-set key binding) ≡ (keymap-set (current-local-map) key binding)
この関数はカレントローカルキーマップからkeyのバインディングを削除する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではヘルプ情報のプリントのために、すべてのカレントキーマップのスキャンに使用される関数を説明します。特定のキーマップのバインディングを表示するにはdescribe-keymap
コマンドを使用してください(Other Help Commands in The GNU Emacs Manualを参照)。
この関数は、(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にたいするバインディングをリターンする。
[some-event]
のようなキーバインディングをマップするコマンドがあり、some-event
には非nil
のnon-key-event
プロパティを含んだシンボルplistがある場合には、そのバインディングはwhere-is-internal
によって無視される。
この関数はすべてのカレントキーバインディングのリストを作成して、*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] | [ ? ] |
キーマップはキーボードキーやマウスボタンにたいするバインディング定義と同様に、メニューとして操作することができます。メニューは通常はマウスにより操作されますが、キーボードでも機能させことができます。次の入力イベントにたいしてメニューキーマップがアクティブならキーボードメニュー機能がアクティブになります。
23.18.1 メニューの定義 | メニューを定義するキーマップを作成する方法。 | |
23.18.2 メニューとマウス | ユーザーがマウスでメニューを操作する方法。 | |
23.18.3 メニューとキーボード | ユーザーがキーボードでメニューを操作する方法。 | |
23.18.4 メニューの例 | シンプルなメニューの作成。 | |
23.18.5 メニューバー | メニューバーのカスタマイズ方法。 | |
23.18.6 ツールバー | イメージ行のツールバー。 | |
23.18.7 メニューの変更 | メニューへ新たなアイテムを追加する方法。 | |
23.18.8 easy-menu | メニュー作成のための便利なマクロ。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
キーマップがoverallプロンプト文字列(overall prompt string)をもつ場合には、そのキーマップはメニューとして動作します。overallプロンプト文字列はキーマップの要素として表される文字列です(キーマップのフォーマットを参照)。この文字列にはメニューコマンドの目的を記述します。(もしあれば)Emacsはメニュー表示に使用されるツールキットに応じて、メニュータイトルにoverallメニュー文字列を表示します18。キーボードメニューもoverallプロンプト文字列を表示します。
プロンプト文字列をもつキーマップを構築するもっとも簡単な方法はmake-keymap
、make-sparse-keymap
(キーマップの作成を参照)、define-prefix-command
(Definition of define-prefix-commandを参照)を呼び出すときに引数として文字列を指定する方法です。キーマップをメニューとして操作したくなければ、これらの関数にたいしてプロンプト文字列を指定しないでください。
この関数はkeymapのoverallプロンプト文字列、もしなければnil
をリターンする。
メニューのアイテムは、そのキーマップ内のバインディングです。各バインディングはイベント型と定義を関連付けますが、イベント型はメニューの外見には何の意味ももっていません(通常はイベント型としてキーボードが生成できない擬似イベントのシンボルをメニューアイテムのバインディングに使用する)。メニュー全体はこれらのイベントにたいするキーマップ内のバインディングから生成されます。
メニュー内のアイテムの順序はキーマップ内のバインディングの順序と同じです。define-key
は新たなバインディングを先頭に配置するので、メニューアイテムの順序が重要ならメニューの最後から先頭へメニューアイテムを定義する必要があります。既存のメニューにアイテムを追加するときには、keymap-set-after
を使用してメニュー内の位置を指定できます(メニューの変更を参照)。
23.18.1.1 単純なメニューアイテム | 単純なメニューのキーバインディング。 | |
23.18.1.2 拡張メニューアイテム | 複雑なメニューアイテムの定義。 | |
23.18.1.3 メニューセパレーター | メニューに水平ラインを描画する。 | |
23.18.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-nameはサブメニュー名として使用される。最後にnil
でもよく、この場合には選択不可なメニューアイテ厶を取得する。これは主に区切り線のようなものの作成時に有用。
リスト末尾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
の指定は:key-sequence
属性が存在しないことに等しい。
: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" multifile-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だけです。
一部のツールキットにおいては、イメージとテキストの両方がツールバーに表示されます。イメージの使用だけを強制したければ、非nil
の:vert-only
プロパティを使用してください。
メニューバーと同様、ツールバーはセパレーター(メニューセパレーターを参照)を表示できます。ツールバーのセパレーターは水平ラインではなく垂直ラインであり、1つのスタイルだけがサポートされます。これらはツールバーキーマップ内では(menu-item
"--")
エントリーで表されます。ツールバーのセパレーターでは、:visible
のようなプロパティはサポートされません。GTK+とNextstepのツールバーでは、セパレーターはネイティブに描画されます。それ以外ではセパレーターは垂直ラインイメージを使用して描画されます。
デフォルトツールバーはコマンドシンボルのmode-class
プロパティにspecial
をもつメジャーモードにたいしては、編集に特化したアイテムは表示しないよう定義されています(メジャーモードの慣習を参照)。メジャーモードは、ローカルマップ内でバインディング[tool-bar
foo]
によって、グローバルバーにアイテムを追加するかもしれません。デフォルトツールバーの多くを適宜流用するのができないかもしれないので、デフォルトツールバーを完全に置き換えることは、いくつかのメジャーモードにとっては有意義です。デフォルトバインディングでtool-bar-map
を通じてインダイレクトすることにより、これを簡単に行うことができます。
デフォルトではグローバルマップは[tool-bar]
を以下のようにバインドする:
(keymap-global-set "<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)
ファンクションキーに修飾を追加する方法についての詳細な情報は、ファンクションキーを参照してください。
ツールバーアイテムを有効または無効に変更する関数があるとしても、その状態を必ずしも視覚的に即座に更新される訳ではありません。ツールバーの再計算を強制するにはforce-mode-line-update
を呼び出してください(モードラインのフォーマットを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
既存のメニューに新たなアイテムを挿入するときは、そのメニューの既存のアイテムの中の特定の位置にアイテムを追加したいと思うかもしれません。define-key
を使用してアイテムを追加すると、そのアイテムは通常はメニューの先頭に追加されます。メニュー内の他の位置にアイテムを追加するにはkeymap-set-after
を使用します:
keymap-set
(キーバインディングの変更を参照)と同じようにmapにおいてkeyの値としてbindingを定義するが、バインディングの位置はイベントafterにたいするバインディングの後になる。引数keyは単一のメニューアイテムかキーを表し、key-valid-p
(キーシーケンスを参照)を満足すること。afterは単一のイベントタイプ(シンボルか文字、シーケンスではない)であること。新たなバインディングはafterのバインディングの後に追加される。afterがt
または省略された場合には、新たなバインディングはそのキーマップの最後に追加される。しかし新たなバインディングは継承されたすべてのキーマップの前に追加される。
以下は例:
(keymap-set-after my-menu "<drink>" '("Drink" . drink-command) 'eat)
これは偽ファンクションキーDRINKのバインディングを作成して、EATのバインディングの直後に追加する。
以下はShellモードの‘Signals’メニュー内のアイテムbreak
の後に‘Work’と呼ばれるアイテムを追加する方法:
(keymap-set-after shell-mode-map "<menu-bar> <signals> <work>" '("Work" . work-command) 'break)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のマクロはポップアップメニューおよび/またはメニューバーメニューを定義する便利な方法を提供します。
このマクロはmenuにより与えるコンテンツのポップアップメニューおよび/またはメニューバーサブメニューを定義する。
symbolが非nil
なら、それはシンボルである。その場合、このマクロはドキュメント文字列docをもつ、メニューをポップアップ(ポップアップメニューを参照)する関数としてsymbolを定義する。symbolはクォートしないこと。
symbolの値とは関係なく、mapsがキーマップならメニューはメニューバーのトップレベルのメニュー(メニューバーを参照)として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はコナドが複数のキーシーケンスにバインドされている場合に、等価なキーボード入力としてどのキーシーケンスを表示するかを示すためのヒント。このメニューアイテムとしてkeysが同じコマンドがバインドされていなければ効果はない。
: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
を使用してメニューバー内で定義したメニューと同等なメニューを定義する例:
(easy-menu-define words-menu global-map "単語単位コマンドにたいするメニュー" '("Words" ["Forward word" forward-word] ["Backward word" backward-word]))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
モード(mode)とはEmacsの挙動を簡便な方法でカスタマイズする定義のセットです。モードは2種類あります。マイナーモード(minor modes)は編集時にユーザーがオンとオフを切り替えられる機能を提供します。メジャーモード(major modes)は特定の種類のテキストにたいする編集や相互作用に使用します。ある時点においてバッファーはそれぞれ正確に1つのメジャーモードをもちます。
このチャプターではメジャーモードとマイナーモードを記述する方法、それらをモードラインに示す方法、そしてそれらのモードがユーザーが提供するフックを実行する方法を説明します。キーマップ(keymaps)や構文テーブル(syntax tables)のような関連するトピックについてはキーマップと構文テーブルを参照してください。
24.1 フック | フックの使用法とフックを提供するコードの記述方法。 | |
24.2 メジャーモード | メジャーモードの定義。 | |
24.3 マイナーモード | マイナーモードの定義。 | |
24.4 モードラインのフォーマット | モードラインに表示されるテキストのカスタマイズ。 | |
24.5 Imenu | バッファーで作成された定義のメニューを提供する。 | |
24.6 Font Lockモード | モードが構文に応じてテキストをハイライトする方法。 | |
24.7 コードの自動インデント | メジャーモードにたいするインデントをEmacsに伝える方法。 | |
24.8 Desktop Saveモード | Emacsセッション間でモードがバッファー状態を保存する方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フック(hook)とは既存のプログラムから特定のタイミングで呼び出される関数(複数可)を格納できる変数のことです(関数とは?を参照)。Emacsはカスタマイズ用にフックを提供します。ほとんどの場合にはinitファイル内(initファイルを参照)でフックをセットアップしますが、Lispプログラムもフックをセットできます。標準的なフック変数のリストは標準的なフックを参照してください。
Emacsのほとんどのフックはノーマルフック(normal hooks)です。これらの変数は、引数なしで呼び出される関数のリストを含んでいます。慣習により名前が‘-hook’で終わるフックは、そのフックがノーマルフックであることを意味します。わたしたちは一貫した方法でフックを使用できるように、すべてのフックが可能な限りノーマルフックとなるよう努力しています。
すべてのメジャーモードコマンドは、初期化の最終ステップの1つとして、モードフック(mode
hook)と呼ばれるノーマルフックを実行するとみなされます。これによってそのモードですでに作成されたバッファーローカル変数割り当てをオーバーライドすることにより、ユーザーがそのモードの動作をカスタマイズするのが簡単になります。ほとんどのマイナーモード関数も最後にモードフックを実行します。しかしフックは他のコンテキストでも使用されます。たとえばフックsuspend-hook
は、Emacsが自身をサスペンド(Emacsのサスペンドを参照)する直前に実行されます。
フック変数の名前が‘-hook’で終わらなければ、それが恐らくアブノーマルフック(abnormal hook)であることを示しています。これらとノーマルフック違うのはフック関数が1つ以上の引数とともに呼ぶ出されること、何らかの方法によってそのリターン値が使用されることという2つの点です。その関数の呼び出し方や引数の使われ方はそのフックのドキュメントに記載されています。アブノーマルフックに追加する関数は、フックの呼び出し規約にしたがって関数を記述しなければなりません。慣習によりアブノーマルフックの名前の最後は‘-functions’です。
変数名の最後が‘-predicate’や‘-function’ (単数形)なら、値は関数のリストではなく単一の関数でなければなりません。このような単一関数フック(single function hook)が期待する引数やリターン値の意味はアブノーマルフックと同様さまざまです。それらの詳細については、各変数のdocstringで説明されています。
フック(単一関数と複数関数の両方)とは変数なので、値はsetq
、または一時的にlet
で変更できます。しかしフックがもつ他の関数を保持しつつ、特定の関数の追加や削除ができると便利なことがあります。複数関数フックでこれを行う推奨方法はadd-hook
とremove-hook
です(フックのセットを参照)。ほとんどのノーマルフック変数の初期値はvoidであり、add-hook
はこれを扱う方法を理解しています。フックへのグローバルまたはバッファーローカルな追加はadd-hook
で行うことができます。単一の関数だけを保持するフックではadd-hook
は不適切ですが、フックに新たな関数を組み合わせるためにadd-function
(Emacs Lisp関数にたいするアドバイスを参照)を使用できます。いくつかの単一関数フックはadd-function
が扱えないnil
かもしれないので、add-function
の呼び出し前にそれをチェックしなければならないことに注意してください。
24.1.1 フックの実行 | フックの実行方法。 | |
24.1.2 フックのセット | 関数をフックに登録、削除する方法。 |
[ << ] | [ < ] | [ 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)
フック変数の値は関数のリストにする必要があります。通常のLisp機能を使用してこのリストを操作できますが、モジュール方式では以下で説明する関数add-hook
とremove-hook
を使用します。これらの関数はいくつかの異常な状況を処理して問題を回避します。
フックにlambda
式を配置しても機能しますが、これは混乱を招くので避けることを推奨します。2回目は記述を微妙に変えて同じlambda
式を追加すると、そのフックは等価な2つの別々の関数をもつことになります。それから一方を削除しても、もう一方は残り続けるでしょう。
この関数はフック変数に関数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
呼び出しがなければ)それは最初に実行される。
いくつかのケースではフック上の相対順序の制御が重要になる。オプション引数によりリストのどこに関数を挿入するべきかを指定できる。値は-100から100の数値であり、より大きい値では関数はリストの終端に近づく。depthのデフォルトは0であり、後方互換のために非nil
ならdepthを90と解釈する。さらにdepthが厳密に0より大なら、関数は同じdepthの関数の前ではなく後に追加される。あなたの関数の前(や後)に他の関数を配置する必要が絶対ないとは限らないので、100(や-100)のをdepthは決して使用しないこと。
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モードにたいするメジャーモードコマンドである。他のモードコマンドと異なり、このモードはカスタマイズしてはならないことになっているので、モードフックは何も実行されない(メジャーモードの慣習を参照)。
この関数はすべてのバッファーローカル変数をkillする点においてfundamental-mode
のように機能するが、これは後でリストアできるように効力をもつメジャーモードを記録する。この関数とmajor-mode-restore
(以下参照)は、Emacsがそのバッファー用に自動的に選択したモード(Emacsがメジャーモードを選択する方法を参照)ではない何らかの特化したモードにバッファーを置く必要があり、なおかつ後で元のモードに戻れるようにしたい場合に有用。
この関数はmajor-mode-suspend
が記録したメジャーモードをリストアする。メジャーモードが何も記録されていなければ、この関数はnormal-mode
(normal-modeを参照)を呼び出すが、avoided-modes引数が非nil
ならこの引数内のモードを選択させないように試みる。
メジャーモード変更によってほとんどのローカル変数はクリアーされるが、バッファー内に残された残置物(テキストプロパティやオーバーレイなど)がすべて削除される訳ではない。あるバッファーのメジャーモードを別のモードに変更することは稀であり、これは通常なら問題にならない(fundamental-mode
からそれ以外のメジャーモードへの変更は除く)。バッファーの“完全リセット”を行うことができれば、(主としてバッファーでの問題をデバッグ中には)便利なときがあるかもしれず、正にそれがメジャーモードclean-mode
の提供する機能である。これはすべてのローカル変数(永続的なローカル変数さえも)をkillするとともに、すべてのオーバーレイおよびテキストプロパティを削除する。
メジャーモードを記述するもっとも簡単な方法はマクロ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モードになる(メジャーモードの慣習を参照)。
24.2.1 メジャーモードの慣習 | キーマップなどにたいするコーディング規約。 | |
24.2.2 Emacsがメジャーモードを選択する方法 | Emacsが自動的にメジャーモードを選択する方法。 | |
24.2.3 メジャーモードでのヘルプ入手 | モードの使用方法の探し方。 | |
24.2.4 派生モードの定義 | 他のメジャーモードにもとづき新たなメジャーモードを定義する。 | |
24.2.5 基本的なメジャーモード | 他のモードからよく派生元とされるモード。 | |
24.2.6 モードフック | メジャーモード関数の最後に実行されるフック。 | |
24.2.7 Tabulated Listモード | 表形式データを含むバッファーにたいする親モード。 | |
24.2.8 ジェネリックモード | コメント構文とFont Lockモードをサポートするシンプルなメジャーモードの定義。 | |
24.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を再定義するかもしれない。メジャーモードにニーズに応じてC-M-aを構成するための推奨方法は、そのモード固有の関数を呼び出すためにbeginning-of-defun-function
をセットすること(釣り合いのとれたカッコを越えた移動を参照)。
ある標準的なキーシーケンスの標準的な意味がそのモードではほとんど役に立たないような場合にも、メジャーモードが標準的なキーシーケンスをリバインドする正当性がある。たとえば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モードを参照)。
context-menu-mode
(Menu Mouse Clicks in The Emacs
Manualを参照)をアクティブにした際に使用されるモード固有のコンテキストメニューの追加を検討すること。これを達成するにはバッファー内でmouse-3がクリックされた位置に応じて1つ以上のメニューを構築するモード固有関数の定義して、context-menu-functions
のバッファーローカル値にその関数を追加すればよい。
imenu-generic-expression
、imenu-prev-index-position-function
とimenu-extract-index-name-function
の2つの変数、または変数imenu-create-index-function
にバッファーローカルな値をセットすることによってImenuがバッファー内の定義やセクションを探す方法を指定すること(Imenuを参照)。
eldoc-documentation-functions
に1つ以上のバッファーローカルエントリーを追加することにより、ポイント位置にあるものにたいして異なるタイプのドキュメントを取得する方法を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
、モードフック、(バッファーがファイルをvisitしていれば)関数hack-local-variables
、その後にノーマルフック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
(以下参照)を呼び出す。Emacs
26.1ではもはやhack-local-variables
を呼び出さずに、メジャーモードの初期化時のrun-mode-hooks
でこれが行われる(モードフックを参照)。
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’抜きのファイル名の解凍されたファイルを適切なモードに置く。
regexpがファイル名にマッチする要素がauto-mode-alist
に複数ある場合には、Emacsは最初のマッチを使用する。
以下は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
をもつ。これはフックを実行した後に:after-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はキーワードと値のペアー。:after-hook
のものを除いて値は評価される。現在のところ以下のキーワードがサポートされる:
:syntax-table
新たなモードにたいする構文テーブルを明示的に指定するためにこれを使用できる。nil
値を指定すると新たなモードはparentと同じ構文テーブル、parentもnil
なら標準的な構文テーブルを使用する(これはnil
値の非キーワード引数は引数を指定しないのと同じという通常の慣習にはしたがわないことに注意)。
:abbrev-table
新たなモードにたいするabbrevテーブルを明示的に指定するためにこれを使用できる。nil
値を指定すると新たなモードはparentと同じabbrevテーブル、parentもnil
ならfundamental-mode-abbrev-table
を使用する(繰り返すがnil
値はこのキーワードを指定しないことではない)。
:interactive
モードはデフォルトではインタラクティブコマンド。nil
値を指定すると、ここで指定したモードはインタラクティブにならない。これはユーザーが手動でアクティブにされることはないが、特別にフォーマットされたバッファーでのみ使用されることを意図したモードで有用。
:group
これが指定する場合、値はそのモードにたいするカスタマイズグループ(customization
group)であること(すべてのメジャーモードがカスタマイズグループをもつ訳ではない)。customize-mode
コマンドはこれを使用する。define-derived-mode
は指定されたカスタマイズグループを自動的に定義しない。
:after-hook
このオプションのkeyはモードフック実行後にモード関数の最後の活動として評価される単一のLispフォームを指定する。クォートしないこと。モードにが終了した後にフォーが評価されるので、モード関数のローカル状態のすべての要素にアクセスするべきではない。:after-hook
フォームはモードフックで変更されているかもしれないユーザーのセッティングに依存するモードの様相をセットアップするために有用。
以下は架空の例:
(defvar-keymap hypertext-mode-map "<down-mouse-3>" #'do-hyper-link) (define-derived-mode hypertext-mode text-mode "Hypertext" "ハイパーテキスト用のメジャーモード" (setq-local case-fold-search nil))
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
、(バッファーがファイルをvisitしていれば)hack-local-variables
(ファイルローカル変数を参照)、after-change-major-mode-hook
も実行する。これは最後に親モード(派生モードの定義を参照)で宣言されている:after-hook
フォームをすべて評価する。
この関数がdelay-mode-hooks
フォーム実行中に呼び出されたときはフックやhack-local-variables
の実行、およびフォームの評価を即座には行わない。かわりに次の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モードは単一のフォントとテキストサイズによりモノスペースフォントを使用してテキストを表示するように調整されています。可変ピッチフォントやイメージを使用したテーブルが表示したければ、かわりにmake-vtable
を使うことができます。vtableでは1つのバッファーに複数のテーブルをもったり、テーブルと追加のテキストの両方を含んだバッファーをもつことができます。詳細については(vtable)Introductionを参照してください。
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
を呼び出すべきです。
この変数はGUIフレームにおいて列が昇順でソートされていることを示すために使用する文字を指定する。
Tabulated Listバッファーでソート方向を変更するたびに、このインジケーターの昇順(“asc”)と降順(“desc”)が切り替わる。
tabulated-list-gui-sort-indicator-asc
と同様だが列が降順でソートされている際に使用される。
tabulated-list-gui-sort-indicator-asc
と同様だがテキストモードのフレームに使用される。
tabulated-list-tty-sort-indicator-asc
と同様だが列が降順でソートされている際に使用される。
このバッファーローカル変数は表形式データのフォーマットを指定する。値はベクターであり、ベクターの各要素はデータ列を表すリスト(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
を通じて配置されたタグが変更されていないエントリーから削除されないことだけである(通常はすべてのタグが削除される)。
この関数はポイント位置のエントリーを削除する。
リスト(id
cols)
をリターンする。ここでidは削除したエントリーのID、colsは列修飾子(column
descriptors)のベクター。カレント行の先頭にポイントを移動する。ポイント位置にエントリーがなければnil
をリターンする。
この関数はバッファーのコンテンツだけを変更することに注意。tabulated-list-entries
は変更しない。
このdefsubst
はtabulated-list-entries
がリストならIDオブジェクト、関数ならtabulated-list-entries
がリターンするリストからIDオブジェクトをリターンする。posが省略かnil
の場合のデフォルトはポイント位置。
このdefsubst
はtabulated-list-entries
がリストならエントリーオブジェクト、関数ならtabulated-list-entries
がリターンするリストからエントリーオブジェクトをリターンする。これはposにあるIDにたいするベクターになるだろう。posにエントリーがなければ、この関数はnil
をリターンする。
このdefsubst
はposに偽ヘッダーがあれば非nil
をリターンする。偽ヘッダー(fake
header)はバッファー先頭に列名を配置するためにtabulated-list-use-header-line
がnil
にセットされている場合に使用される。posが省略かnil
の場合のデフォルトはpoint-min
。
この関数はレント行のパディングエリアにtagを配置する。パディングエリアはその行の先頭にある空スペースであり、幅はtabulated-list-padding
により制御される。tagは長さがtabulated-list-padding
以下の文字列であること。advanceが非nil
なら、この関数は1行分ポイントを前方に移動する。
この関数はカレントバッファーのパディングエリアからすべてのタグをクリアーする。
この関数はcolをdescにセットしてポイント位置にあるTabulated
Listのエントリーを変更する。colは変更する列番号か列名、descは新たな列記述子であり、tabulated-list-print-col
を通じて挿入される。
change-entry-dataが非nil
なら、この関数は列記述子のベクターをdesc
にセットすることにより、背後のデータ(通常はリストtabulated-list-entries
内の列記述子)を変更する。
[ << ] | [ < ] | [ 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の抜粋を示します:
;; Create the syntax table for this mode.
(defvar text-mode-syntax-table
(let ((st (make-syntax-table)))
(modify-syntax-entry ?\" ". " st)
(modify-syntax-entry ?\\ ". " st)
;; Add 'p' so M-c on 'hello' leads to 'Hello', not 'hello'.
(modify-syntax-entry ?' "w p" st)
…
st)
"Syntax table used while in `text-mode'.")
;; このモード用にキーマップを作成
(defvar text-mode-map (let ((map (make-sparse-keymap))) (define-key map "\e\t" 'ispell-complete-word) … map) "Keymap for `text-mode'. Many other modes, such as `mail-mode', `outline-mode' and `indented-text-mode', inherit all the commands defined in this map.")
そして実際にモードコマンドが定義される方法が以下になります:
(define-derived-mode text-mode nil "Text" "人間が読むために記述されたテキストを編集するためのメジャーモード このモードではパラグラフを区切るのはブランク行か空白行だけである したがって適応型フィル(adaptive filling)の全恩恵を受けられる (変数`adaptive-fill-mode'を参照のこと) \\{text-mode-map} Textモードのオンによりノーマルフック`text-mode-hook'が実行される"
(setq-local text-mode-variant t) (setq-local require-final-newline mode-require-final-newline))
3つのLisp用モード(Lispモード、Emacs Lispモード、Lisp Interactionモード)はTextモードより多くの機能をもち、それにふさわしくコードもより複雑です。そのようなモードの記述方法を説明するためにlisp-mode.elの抜粋を示します。
以下はLispモードの構文テーブルとabbrevテーブルを定義する方法です:
;; モード固有のテーブル変数の作成
(define-abbrev-table 'lisp-mode-abbrev-table ()
"Abbrev table for Lisp mode.")
(defvar lisp-mode-syntax-table
(let ((table (make-syntax-table 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つのモードは多くのコードを共有します。たとえばLispモードとEmacs LispモードはLisp Dataモード、Lisp InteractionモードはEmacs Lispモードから派生したモードです。
その中でも特にLisp Dataモードは、Lispコメントを処理するために変数comment-start
をセットアップします:
(setq-local comment-start ";") …
これらの異なるLisp用モードは、微妙に異なるキーマップをもちます。たとえばLispモードはC-c
C-zをrun-lisp
にバインドしますが、他のLisp用モードはこれを行いません。とはいえすべてのLisp用モードに共通なコマンドがいくつかあります。以下のコードはそれらの共通コマンドをセットアップします:
(defvar-keymap lisp-mode-shared-map :parent prog-mode-map :doc "Keymap for commands shared by all sorts of Lisp modes." "C-M-q" #'indent-sexp "DEL" #'backward-delete-char-untabify)
そして以下がLispモードのためのキーマップをセットアップするコードです:
(defvar-keymap lisp-mode-map :doc "Keymap for ordinary Lisp mode. All commands in `lisp-mode-shared-map' are inherited by this map." :parent lisp-mode-shared-map "C-M-x" #'lisp-eval-defun "C-c C-z" #'run-lisp)
最後はLispモードのためのメジャーモードコマンドです:
(define-derived-mode lisp-mode lisp-data-mode "Lisp" "GNU Emacs Lisp以外のLispコードを編集するためのメジャーモード コマンド: あたかも後方に移動するようにタブをスペースに削除変換する パラグラフ区切りはブランク行でコメント開始はセミコロン \\{lisp-mode-map} `run-lisp'はinferior Lispジョブの開始と既存ジョブ から戻るための両方に使われるかもしれないことに注意"
(setq-local find-tag-default-function 'lisp-find-tag-default) (setq-local comment-start-skip "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *") (setq imenu-case-fold-search t))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マイナーモード(minor mode)はメジャーモードの選択とは無関係にユーザーが有効や無効にできるオプション機能の使用を提供します。マイナーモードは個別、あるいは組み合わせて有効にできます。
ほとんどのマイナーモードはメジャーモードとは独立した機能を実装するので、ほとんどのメジャーモードと一緒に使用することができます。たとえばAuto Fillモードはテキスト挿入を許容する任意のメジャーモードとともに機能します。しかし少数ながら特定のメジャーモードに特化したマイナーモードもあります。たとえばDiff Auto RefineモードはDiffモードとの使用だけを意図したマイナーモードです。
理想的にはマイナーモードは他のマイナーモードの効果と無関係に期待した効果をもつべきです。任意の順序でマイナーモードをアクティブや非アクティブにすることも可能であるべきです。
このバッファーローカル変数はカレントバッファーで有効なマイナーモード(シンボル)のリスト。
このバッファーローカル変数はカレントで有効なマイナーグローバルモード(シンボル)のリスト。
この変数の値はすべてのマイナーモードコマンドのリスト。
24.3.1 マイナーモード記述の規約 | マイナーモードを記述するためのTips。 | |
24.3.2 キーマップとマイナーモード | マイナーモードが自身のキーマップをもつための方法。 | |
24.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)))
しかしこれは頻繁には行われない。
マイナーモードを2回連続で直接有効(や無効)にしても失敗せずに、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という名前の変数も定義する。
keyword-argsはキーワードとその後の対応する値により構成され、いくつかのキーワードは特別な意味をもつ:
:global global
非nil
ならそのマイナーモードがバッファーローカルでなくグローバルであることを指定する。デフォルトはnil
。
マイナーモードをグローバルにしたときの効果の1つは、mode変数がカスタマイズ変数になることである。Customizeインターフェイスを通じてこの変数をトグルするとモードがオンやオフになり、変数の値は将来のEmacsセッション用に保存できるようになる(Saving
Customizations in The GNU Emacs
Manualを参照)。保存された変数が機能するためには、Emacsが開始されるたびにマイナーモード関数が利用できるようにする必要がある。これは通常はdefine-minor-mode
フォームをautoloadすることにより行われる。
:init-value init-value
これはmode変数を初期化するための値。特殊な状況(以下参照)を除き、この値はnil
でなければならない。
:lighter lighter
文字列lighterはモード有効時にモードライン内に何を表示するか指定する。これがnil
ならこのモードはモードライン内に表示されない。
:keymap keymap
オプション引数keymapはそのマイナーモードにたいするキーマップを指定する。非nil
なら、それは(値がキーマップであるような)変数の名前かキーマップ、または以下の形式のalistであること
(key-sequence . definition)
ここでkey-sequenceとdefinitionはdefine-key
に渡すのに適した引数である(キーバインディングの変更を参照)。keymapはキーマップかalistであり、これは変数mode-map
も定義する。
:variable place
これはそのモードの状態を格納するために使用されるデフォルトの変数modeを置き換える。これを指定するとmode変数は定義されず、すべてのinit-value引数は使用されない。placeは異なる名前の変数(あなた自身が定義しなければならない)、またはsetf
関数とともに使用され得るすべてのもの(ジェネリック変数を参照)。placeにはコンス(get
.
set)
も指定できる。ここでgetはカレント状態をリターンする式であり、setはそれをセットする1つの引数(placeに割り当てられる状態)をとる関数。
:after-hook after-hook
これはモードフック実行後に評価される単一のLispフォームを定義する。これをクォートしないこと。
:interactive value
デフォルトではインタラクティブコマンドであるようなマイナーモード。nil
値を指定するとこれを抑制。valueがシンボルのリストなら、そのマイナーモードが有用なメジャーモードを指定するために使用される。
その他のすべてのキーワード引数は変数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)))
これは“Hungry
mode”という名前のマイナーモード、モードをトグルするhungry-mode
という名前のコマンド、モードが有効かどうかを示すhungry-mode
という名前の変数、モードが有効なときそのキーマップを保持するhungry-mode-map
という名前の変数を定義します。これはC-DELにたいするキーバインディングでキーマップを初期化します。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)))))
これはglobal-modeという名前をグローバルにトグルする。これはmodeという名前のバッファーローカルなマイナーモードをすべてのバッファー(または一部のバッファー。以下参照)で有効か無効にするということを意味する。bodyフォームの実行も行う。あるバッファー内でそのマイナーモードをオンにするには関数turn-onを使用する。マイナーモードをオフにするには-1を引数としてmodeを呼び出す(turn-onは別の関数なのでそのマイナーモードを有効にすべきか先験的に明確でない場合でも有効にするかどうかを決定できる)。
モードをグローバルに有効にすると、それ以降ファイルをvisitすることによって作成されるバッファーやFundamental以外のメジャーモードを使用するバッファーにも影響がある。しかしFundamentalで作成される新たなバッファーは検知しない。
これはCustomizeインターフェイスを通じて、そのマイナーモードのオン/オフを切り替えるカスタムオプションglobal-mode
(カスタマイゼーション設定を参照)を定義するマクロ。define-minor-mode
と同様に、たとえば:require
を与える等によってEmacs開始時に毎回確実にdefine-globalized-minor-mode
フォームが評価されるようにすること。
グローバルマイナーモードのモード変数にたいしてカスタムグループを指定するにはkeyword-args内で:group
group
を使用する。
モードのオンかオフかを示すバッファーローカルなマイナーモード変数は、デフォルトではモード自身の名前なまと同じ。これが該当しない場合(状態情報を異なる変数に格納するいくつかのモード)には、:variable
variable
を使用すること。
一般的にはグローバル化されたマイナーモードを定義するときは、ユーザーがバッファーごとにモードを使用(または無効に)できるように非グローバル版も定義すること。これにより特定のメジャーモード内でそのモードのフックを使用すればグローバルに有効化されたマイナーモードを無効にすることができるようになる。
キーワード:predicate
が与えられると、このマクロはグローバルモード変数と似ているが-mode
ではなく-modes
で終わるユーザーオプションを作成する(つまりglobal-modes
ということ)。この変数は特定のメジャーモードにおいてそのメジャーモードをアクティブにするかどうかを判断する述語関数で使用される。ユーザーは変数の値をカスタマイズして、そのマイナーモードをオンに切り替えるモードを制御できる。:predicate
にたいする有効な値
(つまりこれが作成するユーザーオプションの有効な値)にはt
(すべてのメジャーモードで使用)、nil
(どのメジャーモードでも使用しない)、あるいはモード名のリスト(オプションで(not mode-name …)
のようにnot
を前置して否定)が含まれる。以下の例のようにこれらの要素を混合させることもできる。
(c-mode (not mail-mode message-mode) text-mode)
これは“c-mode
の派生モードで使用、message-mode
やmail-mode
の派生モードでは使用せず、text-mode
の派生モードでは使用,それ以外に使用するモードはない”ことを意味する。
((not c-mode) t)
“c-mode
の派生モードでは使用しないが、それ以外なら使用する”ことを意味する。
(text-mode)
これは“text-mode
の派生モードでは使用するが他では使用しない”ことを意味する(終端にnil
要素が暗に存在する)。
Emacsの一部機能に影響を与えるようなバッファーローカル変数をマイナーモードがセットすることがよくある。あるモードをオフに切り替えた際には、これらの変数の元の状態へのリストアがモードには求められる。これはそれらのことを行う助けとなる利便的なマクロである。これはsetq-local
と同じように機能するが、(相方となる関数buffer-local-restore-state
を使って)これらの変数を以前の値や状態をリストアするために使用できるオブジェクトをリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsの各ウィンドウ(ミニバッファーウィンドウを除く)には、通常は最下部にモードラインがあってそのウィンドウ内に表示されたバッファーに関するステータス情報がモードラインに表示されます。モードラインにはバッファー名、関連するファイル、再帰編集の深さ、およびメジャーモードやマイナーモードなどのようなそのバッファーに関する情報が含まれています。ウィンドウはヘッダーライン(header line)をもつこともでき、これはモードラインによく似ていますがウィンドウの最上部に表示されます。
このセクションではモードラインおよびヘッダーラインのコンテンツの制御の仕方について説明します。このチャプターにモードラインを含めた理由は、モードラインに表示される情報の多くが有効化されたメジャーモードとマイナーモードに関連があるからです。
24.4.1 モードラインの基礎 | モードライン制御の基本概念。 | |
24.4.2 モードラインのデータ構造 | モードラインを制御するデータ構造。 | |
24.4.3 モードライン制御のトップレベル | トップレベル変数、mode-line-format。 | |
24.4.4 モードラインで使用される変数 | そのデータ構造で使用される変数。 | |
24.4.5 モードラインでの% 構文 | モードラインへの情報の配置。 | |
24.4.6 モードラインでのプロパティ | モードライン内でのテキストプロパティの使用。 | |
24.4.7 ウィンドウのヘッダーライン | モードラインに類似した最上部のライン。 | |
24.4.8 モードラインのフォーマットのエミュレート | モードラインのようにテキストをフォーマットする。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
各モードラインのコンテンツはバッファーローカル変数mode-line-format
により指定されます(モードライン制御のトップレベルを参照)。この変数はモードライン構文(mode line
construct)を保持します。これはバッファーのモードラインに何を表示するかを制御するテンプレートです。header-line-format
の値は同じ方法によりバッファーのヘッダーラインを指定します。同一のバッファーにたいするすべてのウィンドウは、mode-line-format
や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-active
を使用して異なるカラーで表示されます。かわりに他のウィンドウのモードラインはフェイスmode-line-inactive
で表示されます。フェイスを参照してください。
モードラインのウィンドウの選択/非選択の間にもっと大きな差異をもたせたければ、:eval
構文内でこの述語を使うことができる。たとえば選択されているウィンドウのバッファー名をボールド(bold:
太字)、他のウィンドウはイタリック(italic: 斜体)で表示したければ以下のように記述できる:
(setq-default mode-line-buffer-identification '(:eval (propertize "%12b" 'face (if (mode-line-window-selected-p) 'bold 'italic))))
モードラインに大量のデータを出力して、モードラインの最後にある要素を右側へ押し出すモードがあります。mode-line-compact
変数が非nil
なら、Emacsは連続する複数のスペースを単一のスペースにして、モードラインを“圧縮する”ことができます。この変数がlong
なら、モードラインがカレントで選択されたウィンドウより広いときだけこれを行います(これは文字の表示幅ではなく文字数にもとづく近似により計算される)。この変数は特定バッファーでのみモードラインを圧縮するために、バッファーローカルにすることができます。
[ << ] | [ < ] | [ 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…)
最初の要素が文字列、またはすべての要素を再帰的に処理して結果を結合することを意図したリスト。これはもっとも一般的なモードライン構文である(モードラインへの文字列表示時には、テキストプロパティは(効率的理由により)特別に処理されることに注意。文字列の最初の文字のテキストプロパティだけを考慮して、それを文字列全体に使用する。別のテキストプロパティをもつ文字列が必要なら、特別モードライン構文:propertize
を使う必要がある)。
(:eval form)
最初の要素がシンボル:eval
であるようなリストは、formを評価してその結果を表示する文字列として使用するよう指示する。この評価が任意のファイルをロードできないことを確認すること。ファイルをロードすると無限再帰が発生するかもしれない。
(:propertize elt props…)
最初の要素がシンボル:propertize
であるようなリストはモードライン構文eltを再帰的に処理して、propsにより指定されるテキストプロパティに結果を加えるよう指示する。引数propsは0個以上のtext-propertyとvalueのペアーで構成されること。eltがテキストプロパティをもつ文字列、またはテキストプロパティをもつ文字列を生成する場合には、その文字列内のすべての文字は同一のプロパティをもつこと。さもなければ:propertize
によっていくつかのプロパティは削除されるかもしれない。
(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 (format-time-string "%F")) 'mode-line-process 'minor-mode-alist "%n" ")%]--"
'(which-function-mode ("" which-func-format "--")) '(line-number-mode "L%l--") '(column-number-mode "C%c--") '(-3 "%p")))
(変数line-number-mode
、column-number-mode
、which-function-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列になるようスペースパディングされたバッファー名を表示する。
この変数はバッファー内での位置を表示する。デフォルト値ではバッファーのパーセント位置、オプションでバッファーサイズ、行番号、列番号を表示する。
このオプションはmode-line-position
の中で使用される。これの値はバッファーのパーセンテージ(nil
、"%o"
、"%p"
、"%P"
、"%q"
のいずれか。モードラインでの%
構文を参照)とフィルするスペースか切り詰めの幅の両方を指定する。このオプションはcustomize-variable
機能でセットすることを推奨する。
変数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
で指定される情報を表示する。
line-number-mode
(Optional Mode Line in The GNU Emacs
Manualを参照)がオンの際に行番号表示に使用するフォーマット。フォーマット内の‘%l’は行番号に置き換えられる。
column-number-mode
(Optional Mode Line in The GNU Emacs
Manualを参照)をオンに切り替えた際に列番号の表示に使用するフォーマット。フォーマット内の‘%c’は0基準、‘%C’は1基準の列番号に置き換えられる。
line-number-mode
とcolumn-number-mode
の両方がオンの際に列番号表示に使用するフォーマット。フォーマットspecsの‘%l’、‘%c’、‘%C’の意味については、前出の2つの変数を参照のこと。
この変数はアクティブなマイナーモードをモードラインに示す方法を指定する要素をもった連想リスト(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内で参照される各変数は、そのマイナーモードをバッファーごとに個別に有効にできるならバッファーローカルであること。
この変数は、デフォルトではmode-line-misc-info
の一部としてモードラインに表示されるモードライン構文が保持されている。マイナーモードwhich-function-mode
が有効ならこのモード情報の直後、有効でなければmode-line-modes
の後に表示される。この構文に追加する要素は通常はスペース内に収まること(後続のglobal-mode-string
要素が正しく表示されるために)。
‘%M’構文はglobal-mode-string
の値を置き換える。この変数自体はmode-line-misc-info
で使用されているので、この構文はデフォルトのモードライン使用されない。
以下は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-function-mode ("" which-func-format "--")) (global-mode-string ("--" global-mode-string)) "-%-")
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
%
構文モードライン構文として使用される文字列では、さまざまな種類のデータを置き換えるために%
構文を使用できます。以下は定義済みの%
構文と意味のリストです。
‘%%’以外の構文では、フィールドの最小幅を指定するために‘%’の後に10進整数を追加できます。幅がそれより小さければそのフィールドは最小幅にパディングされます。純粋に数値的な構文(‘c’、‘i’、‘I’、‘l’)は左側、それ以外は右側にスペースを追加してパディングされます。
%b
buffer-name
関数により取得されるカレントバッファー名。バッファーの名前を参照のこと。
%c
ポイント位置のカレント列番号。そのウィンドウの左マージンより0からカウントされる。
%C
ポイント位置のカレント列番号。そのウィンドウの左マージンより1からカウントされる。
%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
ポイント位置のカレント行番号。そのバッファーのアクセス可能な範囲内でカウントされる。
%M
global-mode-string
の値(デフォルトではmode-line-misc-info
の一部)。
%n
ナローイングが有効なときは‘Narrow’、それ以外は何も表示しない(ナローイングのnarrow-to-region
を参照)。
%o
バッファー(の可視な範囲)を通じてウィンドウがtravel した割合(ウィンドウ外部にあるすべてのテキストにたいしてウィンドウ上端の上にあるテキストのサイズのパーセンテージまたは‘Top’、‘Bottom’、‘All’)。
%p
ウィンドウの最上部より上にあるバッファーテキストのパーセント表示、または‘Top’、‘Bottom’、‘All’のいずれか。デフォルトのモードライン構文は、これを3文字に切り詰めることに注意。
%P
ウィンドウの最下部より上にあるバッファーテキスト(ウィンドウ内の可視なテキストと最上部の上にあるテキスト)のパーセント表示、およびバッファーの最上部がスクリーン上で可視なら、それに加えて‘Top’。または‘Bottom’か‘All’。
%q
‘-’で区切ったウィンドウの上端および下端より上にあるテキストのパーセンテージ、または‘All’。
%s
process-status
により取得されるカレントバッファーに属するサブプロセスの状態。プロセスの情報を参照のこと。
%z
キーボード、端末、およびバッファーコーディングシステムのニーモニック。
%Z
‘%z’と同様だが、EOL形式(end-of-line format: 改行形式)を含む。
%*
バッファーが読み取り専用(buffer-read-only
を参照)なら‘%’、
変更(buffer-modified-p
を参照)されていればは‘*’、
それ以外は‘-’。バッファーの変更を参照のこと。
%+
バッファーが変更(buffer-modified-p
を参照)されていれば‘*’
バッファーが読み取り専用(buffer-read-only
を参照)なら‘%’、
それ以外は‘-’。これは読み取り専用バッファーの変更にたいしてのみ‘%*’と異なる。バッファーの変更を参照のこと。
%&
バッファーが変更されてれば‘*’、それ以外は‘-’。
%@
バッファーのdefault-directory
(ファイル名を展開する関数を参照)がリモートマシンなら‘@’、それ以外なら‘-’。
%[
再帰編集レベルの深さを表示する(ミニバッファーレベルは勘定しない)編集レベル1つが‘[’。再帰編集を参照のこと。
%]
編集レベル1つが‘]’(ミニバッファーレベルは勘定しない)。
%-
モードラインの残りを充填するのに十分なダッシュ。
%%
文字‘%’。%
構文が許される文字列内にリテラル‘%’を含めるにはこの方法を使用する。
%
-構文以下の構文は今後使用するべきではありません。
%m
廃止;
かわりにmode-name
変数を使うこと。mode-name
の値が(たとえばemacs-lisp-mode
の値のように)非文字列のモードライン構文の場合には、%m
構文は空文字列を生成するので不十分である。
[ << ] | [ < ] | [ 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
なので、通常のバッファーはヘッダーラインをもたない。
バッファーでdisplay-line-numbers-mode
(display-line-numbers-mode in The GNU Emacs
Manualを参照)がオンになっていると、バッファーのテキストは行番号の表示に必要なスクリーンスペース分インデントされて表示されます。それとは対照的にヘッダーラインのテキストは自動的にインデントされません。ヘッダーラインに行番号が表示されることはありませんし、ヘッダーラインとその下にあるバッファーのテキストが直接関連する必要はないからです。バッファーのテキストに合わせてヘッダーラインのテキストを位置揃えする必要があるLispプログラムや、tabulated-list-mode
(Tabulated Listモードを参照)のように列形式データを表示するバッファーは、マイナーモードheader-line-indent-mode
をオンにする必要があります。
このバッファーローカルなマイナーモードはスクリーン上で表示されている行番号の幅(そのウィンドウで表示されている行番号範囲に応じて大きく異なる可能性あり)の変更を追跡して、行番号の幅が変更された際にヘッダーラインとバッファーラインのテキストを常に位置揃えさせる手段をLispプログラムに提供する。このようなLispプログラムはバッファーでこのモードをオンにして、常時テキストのインデントを確実に調節するために、header-line-format
の中でheader-line-indent
およびheader-line-indent-width
という変数を使う必要がある。
そのウィンドウで表示されているバッファーでheader-line-indent-mode
の場合には、表示中の行番号のカレント幅と同じ幅をもつ空白文字列がこの変数の値となる。空白の個数はヘッダーラインのテキストのフェイスにおいて、サイズも含めてフレームのデフォルトフォントと同じフォントが使用されている前提で計算される。この前提が成り立たない場合には、かわりに下記のheader-line-indent-width
を使うこと。これは値をヘッダーラインのテキストの先頭に追加することによって、バッファーのテキストに合わせてヘッダーラインのテキスト全体のインデントを再調整するというシンプルな状況で使用されることを意図した変数である。たとえば以下のheader-line-format
の定義では:
(setq header-line-format `("" header-line-indent ,my-header-line))
ここでmy-header-line
はヘッダーラインの実際のテキストを生成するフォーマット文字列。これによりヘッダーラインのテキストはその下にあるバッファーと同じように常にインデントされることが保証される。
そのウィンドウで表示されているバッファーでheader-line-indent-mode
の場合には、この変数の値は行番号の表示に用いられるフレームの正規文字幅単位でカレント幅を提供するよう最新に保たれる。バッファーのテキストに合わせてヘッダーラインのテキストを位置揃えするにあたり、header-line-indent
では柔軟性に欠けるような際に用いることができる。たとえばヘッダーラインでデフォルトフェイスのフォントと異なるメトリクス(訳注:
個々の文字や全体の文字の平均について様々な値を定義する測定情報のこと)のフォントを使用している場合には、frame-char-width
(フレームのフォントを参照)のリターン値にこの変数の値を乗じて表示されている行番号のピクセル幅を計算、その結果をheader-line-frormat
の関連する部分にピクセル単位で適用するためにディスプレイプロパティ仕様:align-to
(スペースの指定を参照)を用いてヘッダーラインのテキストの位置合わせをを行えばよい。
この関数は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] | [ ? ] |
Font Lockモードとはバッファーの特定の部分にたいして、それらの構文的役割(syntactic
role)にもとづき自動的にface
プロパティをアタッチするバッファーローカルなマイナーモードです。このモードがバッファーをパースする方法はそのメジャーモードに依存します。ほとんどのメジャーモードは、どのコンテキストでどのフェイスを使用するかにたいして構文的条件(syntactic
criteria)を定義します。このセクションでは特定のメジャーモードにたいしてFont Lockをカスタマイズする方法を説明します。
Font Lockモードは(通常は外部のライブラリーやプログラムを介した)本格的なパーサー、Emacs組み込みの構文テーブルにもとづく構文解析、(通常は正規表現にたいする)検索という3つの手法によりハイライトするテキストを見つけます。有効になっていればまずパーサーベース(パーサーベースのFont Lockを参照)のフォント表示、次にコメントと文字列定数を見つけてハイライトする構文的なフォント表示、最後に検索ベースのフォント表示が行われます。
24.6.1 Font Lockの基礎 | Font Lockカスタマイズの概要。 | |
24.6.2 検索ベースのフォント化 | 正規表現にもとづくフォント表示。 | |
24.6.3 検索ベースのフォント化のカスタマイズ | 検索ベースフォント表示のカスタマイズ。 | |
24.6.4 Font Lockのその他の変数 | 追加のカスタマイズ機能。 | |
24.6.5 Font Lockのレベル | 多なりとも少ユーザーが選択できるように、それぞれのモードは代替レベルを定義できる。 | |
24.6.6 事前計算されたフォント化 | バッファーコンテンツを生成するLispプログラムが、どのようにしてそれをフォント表示する方法も指定できるか。 | |
24.6.7 Font Lockのためのフェイス | Font Lockにたいする具体的な特殊フェイス。 | |
24.6.8 構文的なFont Lock | 構文テーブルにもとづくフォント表示。 | |
24.6.9 複数行のFont Lock構造 | Font Lockに複数行構文の正しいハイライトを強制する方法。 | |
24.6.10 パーサーベースの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-debug-fontify
¶これはモード用のFont
Lock開発時の使用を意図した利便的なコマンドであり、Lispコードから呼び出すべきではありません。これは関連するすべての変数を再計算してから、バッファー全体にたいしてfont-lock-fontify-region
を呼び出します。
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 . facespec)
この種の要素ではfacespecの値がハイライトに使用するフェイスを指定する。もっともシンプルな例ではfacespecは値がフェイス名であるようなはLisp変数(シンボル)。
;; fubar-face
の値のフェイスを使用して
;; ‘fubar’をハイライトする
("fubar" . fubar-face)
しかしfacespecは以下のような形式のリストに評価されてもよい:
(subexp (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
を使用することができます。特定の条件にマッチするキーワードにたいして選択的にフォント表示を無効にするよう、font-lock-ignore
オプションをカスタマイズすることもできます。
この関数はカレントバッファー、またはメジャーモード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
にたいするすべての制約と条件が適用される。引数keywordsは対応する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)))))
このオプションは特定のFont
Lockキーワードによってフォント表示を選択的に無効にするための条件を定義する。非nil
なら、値は以下のような形式の要素からなるリストであること:
(symbol condition …)
ここでsymbolはシンボル(通常はメジャーモードかマイナーモード)。symbolの後のリスト要素conditionはsymbolがバインドされていて、なおかつ値が非nil
なら効力をもつ。あるモードのシンボルについて考えると、カレントのメジャーモードがそのモードの派生モードであること、あるいはバッファーでそのマイナーモードが有効であることを意味する。conditionが効力をもつ間は要素font-lock-keywords
に因をなすすべてのフォント表示は、conditionがマッチした場合には無効化される。
conditionにはそれぞれ以下のいずれかを指定できる:
この条件はそのシンボルを参照するFont
Lockキーワード要素すべてにマッチする。通常はフェイスだが、font-lock-keywords
リストの要素によって参照される任意のシンボルを指定できる。シンボルにはワイルドカードを含めることができる。*
はシンボルの名前に含まれる任意の文字列にマッチ、?
は1文字にマッチ、そして[char-set]
(char-setは1文字以上の文字列はその文字セットの1文字にマッチする。
この条件はmatcherが文字列にマッチするregexpであるようなFont Lockキーワード要素すべてにマッチする。言い換えると、これはその文字列をハイライトさせるようなFont Lockルールにマッチする条件である。したがってこの文字列に、ハイライトを無効にしたい特定のプログラムキーワードを指定できるかもしれない。
(pred function)
この条件は、その要素を引数としてfunctionを呼び出した際に非nil
がリターンされるようなFont
Lockキーワード要素すべてにマッチする。
(not condition)
これはconditionが成り立たなければマッチする。
(and condition …)
これはすべてのconditionがマッチすればマッチする。
(or condition …)
これは少なくとも1つのconditionがマッチすればマッチする。
(except condition)
この条件はトップレベルかor
節内だけで使用できる。同一レベルにおいて前にマッチした条件の効果を取り消す。
セッティングの例として以下を考えてみましょう:
(setq font-lock-ignore '((prog-mode font-lock-*-face (except help-echo)) (emacs-lisp-mode (except ";;;###autoload)") (whitespace-mode whitespace-empty-at-bob-regexp) (makefile-mode (except *))))
これは1行ごとに以下のことを行っています:
help-echo
に追加を行うキーワードはすべて保持。
whitespace-mode
(マイナーモード)が有効なら、バッファー先頭の空行もハイライトさせない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではfont-lock-defaults
内のother-varsを用いて、メジャーモードがセットできる追加の変数について説明します(Font Lockの基礎を参照)。
この変数が非nil
なら、それはコマンドM-x
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を呼び出す。functionがフォント表示を行う場合には、フォント表示したリージョン領域を示すためにフォーム(jit-lock-bounds beg . end)
のリストをリターンできる。後続する再表示サイクルおよび将来functionに渡されるバッファーテキストの最適化に、Just-In-Time(いわゆる“JIT”)なfont-lockがこの情報を使用するだろう。
オプション引数contextualが非nil
なら、行が更新されたときに限らずそのバッファーの構文的に関連する部分を常にフォント表示するようFont
Lockモードに強制する。この引数は通常は省略できる。
バッファーでFont Lockがアクティブのときには、もしfont-lock-keywords-only
(構文的なFont Lockを参照)の値がnil
なら、非nil
値のcontextualでこの関数を呼び出す。
以前にjit-lock-register
を使用してフォント表示関数としてfunctionを登録した場合は、その関数を未登録にする。
これはJIT
font-lockが実行するコードのデバッグを支援するためのマイナーモード。このモードが有効だと、(Lispエラーが抑制される)再表示サイクル中にJIT
font-lockが実行する通常のコードのほとんどがタイマーによって実行される。したがってこのモードではfont-lockやJIT
font-lockが実行するその他のコード内の問題を見つけて訂正するために、debug-on-error
(エラーによるデバッガへのエンターを参照)やEdebug (Edebugを参照)のようなデバッグ支援機能を使用することができる。
[ << ] | [ < ] | [ 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-face
を使用するモードや、通常のFont
Lock機構を使用するモードでも問題はありません。しかし通常のFont
Lock機構を使用しないモードでは、変数font-lock-defaults
をセットするべきではありません。この場合にはface
プロパティはオーバーライドされないので、face
プロパティの使用も機能します。しかしfont-lock-mode
の切り替えによりユーザーがフォント化を制御でき、かつモードの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
¶特有な構文(たとえば‘‘foo’のようにEmacs Lispシンボルにおけるエスケープされていない判りにくいクォート)や、Emacs Lispの‘;;;###autoload’、Cの‘#error’のような他のテキストの意味を大きく変更する構文にたいして使用される。
font-lock-function-name-face
¶定義、または宣言される関数の名前にたいして使用される。
font-lock-function-call-face
¶呼び出される関数の名前にたいして使用される。このフェイスはデフォルトではfont-lock-function-name-face
を継承する。
font-lock-variable-name-face
¶定義、または宣言される変数の名前にたいして使用される。
font-lock-variable-use-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-doc-markup-face
¶font-lock-doc-face
を使用するテキスト内のmark-up要素にたいして使用される。これは通常はHaddock、Javadoc、Doxygenなどの慣例にしたがってプログラムコード内に埋め込まれた、ドキュメント内のマークアップ構文にたいして使用される。このフェイスは、デフォルトではfont-lock-constant-face
を継承する。
font-lock-negation-char-face
¶見逃しやすい否定文字にたいして使用される。
font-lock-escape-face
¶文字列内のエスケープシーケンスにたいして使用される。このフェイスはデフォルトではfont-lock-regexp-grouping-backslash
を継承する。
以下はPythonでエスケープシーケンス\n
が使用されている例:
print('Hello world!\n')
font-lock-number-face
¶数値にたいして。
font-lock-operator-face
¶演算子にたいして。
font-lock-property-name-face
¶構造体におけるフィールド定義のようなオブジェクトのプロパティにたいして使用される。このフェイスはデフォルトではfont-lock-variable-name-face
を継承する。
font-lock-property-use-face
¶構造体のフィールドの使用のように、オブジェクトのプロパティにたいして使用される。このフェイスはデフォルトではfont-lock-property-name-face
を継承する。
たとえば、
typedef struct { int prop; // ^ property } obj; int main() { obj o; o.prop = 3; // ^ property }
font-lock-punctuation-face
¶カッコや区切り文字などの句読点文字。
font-lock-bracket-face
¶カッコ(()
、[]
、{}
)にたいして使用される。このフェイスはデフォルトではfont-lock-punctuation-face
を継承する。
font-lock-delimiter-face
¶区切り文字(;
、:
、,
)にたいして使用される。このフェイスはデフォルトではfont-lock-punctuation-face
を継承する。
font-lock-misc-punctuation-face
¶カッコや区切り文字以外の句読点文字にたいして使用される。このフェイスはデフォルトではfont-lock-builtin-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モードによりセットされる。値がnil
ならFont Lockはjit-lock-register
(Font Lockのその他の変数を参照)を呼び出して、変更行以降のバッファーテキストに変更による新たな構文コンテキストを反映するために、自動的な再フォント表示をセットアップする。
構文的なフォント表示だけを使用するにはこの変数に非nil
、そしてfont-lock-keywords
にnil
をセットする必要がある(Font Lockの基礎を参照)。
この変数はコメントと文字列のフォント表示に使用するための構文テーブルを保持する。これは通常はfont-lock-defaults
内のsyntax-alist要素にもとづいてFont
Lockモードによりセットされる。この値がnil
なら、構文的フォント表示はバッファーの構文テーブル(関数syntax-table
がリターンする構文テーブル。構文テーブルの関数を参照)を使用する。
この変数が非nil
なら、それは与えられた構文的要素(文字列かコメント)にどのフェイスを使用するかを決定する関数であること。
この関数は1つの引数で呼び出され、parse-partial-sexp
がリターンするポイントの状態をパースしてフェイスをリターンすること。リターンされるデフォルト値はコメントにたいしてはfont-lock-comment-face
、文字列にたいしてはfont-lock-string-face
(Font Lockのためのフェイスを参照)。
この変数は通常はfont-lock-defaults
内の“他”の要素を通じてセットされる:
(setq-local font-lock-defaults `(,python-font-lock-keywords nil nil nil nil (font-lock-syntactic-face-function . python-font-lock-syntactic-face-function)))
[ << ] | [ < ] | [ 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
でそれをマークする。
複数行構造の再ハイライトを行うにはいくつかの方法があります:
font-lock-multiline
を配置する。これによりその構造の一部が変更されると構造全体が再ハイライトされるだろう。あるケースにおいてはそれを参照するfont-lock-multiline
変数をセットすることにより自動的にこれを行うことができる。
jit-lock-contextually
を確実にセットしてそれが行う処理に委ねる。これにより、実際の変更に続いて構造の一部だけが若干の遅延の後に再ハイライトされるだろう。これは複数行構造のさまざまな箇所のハイライトが後続行のテキストに依存しない場合のみ機能する。jit-lock-contextually
はデフォルトでアクティブなので、これは魅力的な解決策になり得る。
jit-lock-defer-multiline
を配置する。これはjit-lock-contextually
が使用された場合のみ機能し、再ハイライト前に同様の遅延を伴うが、font-lock-multiline
のように後続行に依存する箇所のハイライトも処理する。
syntax-multiline
を追加できる。これのもっとも一般的な用途は、‘FOO’に適用する構文プロパティ(syntax
property)が後出するテキスト‘BAR’に依存する場合である。このテキストプロパティを‘FOO...BAR’全体に配置することによって、‘BAR’にたいする任意の変更が‘FOO’の構文プロパティに影響を与えて再計算されることが保証される。これが機能するためには、モードがsyntax-propertize-extend-region-functions
にsyntax-propertize-multiline
を追加する必要があることに注意。
24.6.9.1 複数行のFont Lock | テキストプロパティで複数行塊をマークする。 | |
24.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] | [ ? ] |
シンプルな構文的Font LockやregexpベースのFont Lockに加えて、Emacsはパーサーを用いた完全な構文的Font Lockも提供します。Emacsでは現在のところは、この目的のためにtree-sitterライブラリーを使用しています(プログラムソースの解析を参照)。
パーサーベースのFont Lockそれ以外のFont Lockのメカニズムは互いに排他ではありません。もしパーサーベースのFont Lockが有効なら、最初に構文的Font Lock置き換わり実行されて、その後にregexpベースのFont Lockが実行されます。
パーサーベースのFont LockがregexpベースのFont
Lockと同じカスタマイズ変数を共有しないとしても、カスタマイズでは類似したスキームを使用します。tree-sitterにおいてfont-lock-keywords
のカウンターパートとなるのがtreesit-font-lock-settings
です。
tree-sitterのフォント表示は一般的には以下のように機能します:
font-lock-keyword
とタグ付けされたノードなら、font-lock-keyword
フェイスによってハイライトされることになるだろう。
クエリー、パターン、キャプチャ名n関する詳細についてはtree-sitterノードにたいするパターンマッチングを参照してください。
tree-sitterのフォント表示をセットアップするためには、まずメジャーモードがtreesit-font-lock-rules
の出力をtreesit-font-lock-settings
にセットしてからtreesit-major-mode-setup
を呼び出す必要があります。
これはtreesit-font-lock-settings
のセットに使用される関数である。この関数はクエリーのコンパイルやその他の後処理を受けもち、treesit-font-lock-settings
が受け入れる値を出力する。以下は例:
(treesit-font-lock-rules :language 'javascript :feature 'constant :override t '((true) @font-lock-constant-face (false) @font-lock-constant-face) :language 'html :feature 'script "(script_element) @font-lock-builtin-face")
この関数は一連のquery-spec (query-specとは1つ以上のkeyword/valueが前置されたqueryのこと)を受け取る。queryとはそれぞれ文字列、S式、あるいはコンパイル済みフォームのいずれかによるtree-sitterクエリーのこと。
queryそれぞれの前にはクエリーにメタ情報を付加するkeyword/valueペアーが前置される。キーワード:language
はqueryの言語を宣言、キーワード:feature
はqueryのfeature名をセットする。ユーザーhtreesit-font-lock-level
とtreesit-font-lock-feature-list
によって、どのfeatureを有効にするかを制御できる(後述)。いずれのキーワードも必須。
その他のキーワードはオプションである:
キーワード | 値 | 意味 |
---|---|---|
:override | nil | そのリージョンにすでにフェイスがセットされていれば新たなフェイスを破棄 |
t | 常に新たなフェイスを適用する | |
append | 既存フェイスの後に新たなフェイスを追加 | |
prepend | 既存フェイスの前に新たなフェイスを追加 | |
keep | 既存フェイスなしでリージョンをフィルする |
Lispプログラムはquery内のパターンをキャプチャ名(@
で始まる名前)でマークする。そしてtree-sitterは同じキャプチャ名でタグ付けされたノードをリターンする。フォント表示という目的のために、queryのキャプチャ名はfont-lock-keyword-face
のようなフェイス名であること。キャプチャされたノードはそのフェイスによってフォント表示されることになる。
キャプチャ名は関数でもよい。この場合にはnode and
override、start、endという4つの引数で呼び出される関数であること。ここでnodeはそのノード自身、overrideはそのノードにキャプチャされたルールの:override
プロパティ、startとendはこの関数がフォント表示するべきリージョンを制限する(この関数がoverrideを尊重したければtreesit-fontify-with-override
を使用できる)。
機能拡張を可能にするために、その関数は5つ以上の引数が与えられた場合にはそれらをオプションの引数として受け入れる必要がある。
キャプチャ名がフェイスと関数のどちらにも当てはまる場合にはフェイスが優先される。フェイスにも関数にも当てはまらないキャプチャ名は無視される。
これはfeatureシンボル(feature symbol:
機能シンボル)のリストのリスト。このリストの要素はそれぞれ装飾レベルを表すためのリストである。どのレベルをアクティブにするかを制御するのがtreesit-font-lock-level
。
リストの要素はそれぞれ(feature …)
という形式のリスト。ここでfeatureはそれぞれtreesit-font-lock-rules
内で定義されるクエリーで対応する:feature
の値。このリストからfeatureシンボルを削除することによって、font-lockの間に対応するクエリーが無効なる。
多くのプログラミング言語にとって一般的なfeature名にはdefinition
、type
、assignment
、builtin
、constant
、keyword
、string-interpolation
、comment
、doc
、string
、operator
、preprocessor
、escape-sequence
、key
が含まれる。メジャーモードはこれらの一般的なfeatureを自由に分割あるいは拡張ができる。
これらのfeatureのうちいくつかは説明が必要だろう。definition
は何であれ定義されつつあるものをハイライトする(関数定義の関数名、構造体定義構造体名、変数定義の変数など)。assignment
は何であれ割り当てされつつあるものをハイライトする(割り当て命令の変数やフィールドなど)。key
はキー/値ペアーのキーをハイライトする(JSONオブジェクトのキーやPythonのdictionaryなど)。doc
はdoc文字列やdocコメントをハイライトする。
この変数の値はたとえば以下のようになるかもしれない:
((comment string doc) ; level 1 (function-name keyword type builtin constant) ; level 2 (variable-name string-interpolation key)) ; level 3
メジャーモードはtreesit-major-mode-setup
の呼び出し前にこの変数をセットすること。
この変数が効力をもつためには、Lispプログラムが(適宜treesit-font-lock-settings
をリセットする)treesit-font-lock-recompute-features
、または(treesit-font-lock-recompute-features
を呼び出す)treesit-major-mode-setup
を呼び出す必要がある。
tree-sitterベースのfont
lock用のセッティングのリスト。セッティングそれぞれの正確なフォーマットは内部的なフォーマットとみなされる。この変数のセットには、常にtreesit-font-lock-rules
を使うこと。
複数言語用のメジャーモードはtreesit-range-functions
でrange関数(range function:
範囲関数)を提供する必要があり、Emacsはリージョンのフォント表示を行う前にrangeを適宜セットします(複数言語ののパースを参照)。
[ << ] | [ < ] | [ 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言語に適応します。他にもたとえばtree-sitterライブラリーのような本格的なパーサーに頼る方法もあります。
24.7.1 SMIE: 無邪気なインデントエンジン | SMIE: Simple Minded Indentation Engine(純真なインデントエンジン) | |
24.7.2 パーサーベースのインデント | パーサーベースのインデントエンジン |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SMIEは一般的な操作とインデントを提供するエンジンです。これは演算子順位文法(operator precedence grammar)を使用する非常にシンプルなパーサーにもとづいたエンジンであり、メジャーモードがLispのS式ベースの操作を非Lisp言語に拡張するのを助けるとともにシンプルに使用できるにも関わらず、信頼できる自動インデントを提供します。
演算子順位文法はコンパイラー内で使用されるより一般的なパーサーと比較すると非常に原始的なパーステクノロジーです。このパーサーには次のような特徴があります。このパーサーのパース能力は非常に限定的で構文エラーを大概は検出できません。しかしアルゴリズム的に前方パースと同様に後方パースを効果的に行うことが可能です。実際にそれはSMIEが後方パースにもとづくインデントを使用でき、forward-sexp
とbackward-sexp
の両方の機能を提供できるとともに、特別な努力を要さずに構文的に不正なコードにたいして自然に機能するであろうことを意味します。欠点はほとんどのプログラミング言語は、少なくとも何らかの特別なトリック(非力なパーサーと歩むを参照)で再分類しなければSMIEを使用して正しくパースできないことをも意味することです。
24.7.1.1 SMIEのセットアップと機能 | ||
24.7.1.2 演算子順位文法 | 非常にシンプルなパース技術。 | |
24.7.1.3 言語の文法の定義 | 言語の文法を定義する。 | |
24.7.1.4 トークンの定義 | ||
24.7.1.5 非力なパーサーと歩む | パーサー制限の回避策。 | |
24.7.1.6 インデントルールの指定 | ||
24.7.1.7 インデントルールにたいするヘルパー関数 | ||
24.7.1.8 インデントルールの例 | ||
24.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
の呼び出しはbegin...end
のような要素に適用するためにblink-matching-paren
を拡張してTABによるインデントを期待通り機能させるとともに、メジャーモードのキーマップ内でバインドできるいくつかのコマンドの提供を満足します。
このコマンドは、もっとも最近オープンされた(まだクローズされていない)ブロックをクローズする。
このコマンドは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] | [ ? ] |
tree-sitterライブラリー(プログラムソースの解析を参照)とともにEmacsをビルドした場合には、Emacsによるプログラムソースのパースと構文ツリー(syntax tree)の生成が可能になります。プログラムソースのインデントコマンドにたいするガイド役としてこの構文ツリーを使用することができます。柔軟性を最大限発揮できるように構文ツリーに問い合わせを行うインデント用のカスタマイズ関数を記述して、それぞれの言語に応じたインデントを行うことも可能ですが、これには多くの作業が伴います。より使いやすいのは、この後に説明するシンプルなインデント用エンジンでしょう。そうすればメジャーモードに要求されるのはいくつかのインデントルールの記述だけとなり、残りはこのエンジンが面倒を見てくれます。
パーサーベースのインデントエンジンを有効にするにはtreesit-simple-indent-rules
をセットしてtreesit-major-mode-setup
を呼び出すか、indent-line-function
の値をtreesit-indent
にセットしてください(どちらを選んでも同じ)。
この変数はtreesit-indent
によって呼び出される実際の関数が格納される。デフォルトの値はtreesit-simple-indent
。将来より複雑なエンジンが追加されるかもしれない。
このローカル変数にはすべての言語用のインデントルールが格納される。値は(language . rules)
というフォームのalist。ここでlanguageは言語シンボル、rulesは(matcher anchor offset)
という形式の要素をもつリスト。
最初にEmacsはカレント行の先頭にある最小のtree-sitterノードをmatcherに渡して、非nil
がリターンされればそのルールが適用できる。その後にEmacsはそのノードをanchorに渡して、バッファーの位置がリターンされる。Emacsがその位置の列番号を取得してoffsetを追加すると、、その結果がカレント行のインデント列となる。
matcherとanchorは関数。これらにたいしてEmacsは便利なデフォルトを提供している。
matcherおよびanchorはそれぞれnode、parent、bolという3つの引数を受け取る関数。引数bolはインデントが要求されるバッファー位置(行頭の後の最初の非空白文字の位置)、引数nodeはその位置から開始されるもっとも大きい(かつルートではない)ノード、parentはnodeの親ノードである。ただしその位置にあるのが空白だったり、あるいは複数行文字列の内部の場合には、その位置から開始可能なノードは存在しないので、nodeはnil
となる。このような場合には、その位置を跨ぐもっとも小さいノードがparentとなる。
ルールが適用可能ならmatcherは非nil
、anchorはバッファー位置をリターンすること。
offsetは整数、値が整数であるような変数、あるいは整数をリターンする関数を指定できる。関数の場合にはmatcherやanchorと同様にnode、parent、bolが渡される。
これはtreesit-simple-indent-rules
のmatcherとanchorにたいするデフォルトのリスト。これらはそれぞれnode、parent、bolという3つの引数を受け取る関数である。利用できるデフォルト関数は以下のとおり:
no-node
¶このmatcherはnode、parent、bolという3つの引数で呼び出される。nodeがnil
(bolで始まるノードが存在せず、bolが空行や複数行の内部にbolがある場合などが該当)の場合には、マッチを表す非nil
をリターンする。
parent-is
¶このmatcherはtypeという1つの引数で呼び出される関数をリターンする。この関数はnode、parent、bolという3つの引数とともに呼び出されて、parentのタイプがregexpのtypeとマッチすれば非nil
(マッチしたことを意味する)をリターンする。
node-is
¶このmatcherはtypeという1つの引数を受け取る関数。この関数はnode、parent、bolという3つの引数とともに呼び出されて、nodeのタイプがregexpのtypeとマッチすれば非nil
をリターンする。
field-is
¶このmatcherはnameという1つの引数を受け取る関数。この関数はnode、parent、bolという3つの引数とともに呼び出されて、parentのnodeのフィールド名がregexpのnameとマッチすれば非nil
をリターンする。
query
¶このmatcherはqueryという1つの引数を受け取る関数。この関数はnode、parent、bolという3つの引数とともに呼び出されて、queryでparentに問い合わせた場合にnodeをキャプチャすれば非nil
をリターンする(tree-sitterノードにたいするパターンマッチングを参照)。
match
¶このmatcherはnode-type、parent-type、node-field、node-index-min、node-index-maxという5つの引数とともに呼び出される関数。ここでリターンされた関数はnode、parent、bolという3つの引数で呼び出される関数をリターンする。ここでリターンされた関数はnodeのタイプがregexpのnode-type、parentのタイプがregexpのparent-type、parentのnodeのフィールド名がregexpのnode-field、nodeのインデックスが兄弟ノードnode-index-minとnode-index-maxの間にあれば非nil
をリターンする。このmatcherは引数の値がnil
であれば、その引数はチェックしない。たとえば親ノードとしてargument_list
をもつ最初の子ノードにマッチさせるには、以下のようにすればよい
(match nil "argument_list" nil nil 0 0)
更にnode-typeは特別な値null
でもよく、これはnodeの値がnil
のときにマッチする。
n-p-gp
¶“node-parent-grandparent(ノード-親-祖父母)”の略。このmatcherはnode-type、parent-type、grandparent-typeという3つの引数を受け取る関数。これはnode、parent、bolという3つの引数で呼び出されて(1)
node-typeがnode’のタイプとマッチ、(2)
parent-typeがparentのタイプとマッチ (3)
grandparent-typeがparentの親のタイプという3つのマッチがすべて成り立てば非nil
をリターンする関数をリターンする。この関数はnode-type、parent-type、grandparent-typeのいずれかがnil
ならチェックを行わない。
comment-end
¶このmatcherはnode、parent、bolという3つの引数で呼び出されて、コメント終了トークンn前にポイントがあれば非nil
をリターンする関数。コメント終了トークンはcomment-end-skip
のregexpによって定義される。
catch-all
¶このmatcherはnode、parent、bolという3つの引数で呼び出される関数。この関数はマッチを示すために常に非nil
をリターンする。
first-sibling
¶このanchorはnode、parent、bolという3つの引数とともに呼び出されて、parentの最初の子ノードの開始をリターンする関数。
nth-sibling
¶このanchorはn、オプションとしてnamedという2つの引数を受け取る関数。node、parent、bolという3つn引数で呼び出されて、parentのn番目の開始をリターンする関数をリターンする。namedが非nil
なら、名前付きの子だけを考慮する(named nodeを参照)。
parent
¶このanchorはnode、parent、bolという3つの引数とともに呼び出されて、parentの開始をリターンする関数。
grand-parent
¶このanchorはnode、parent、bolという3つの引数とともに呼び出されて、parentの親の開始をリターンする関数。
great-grand-parent
¶このanchorはnode、parent、bolという3つの引数とともに呼び出されて、parentの親の親の開始をリターンする関数。
parent-bol
¶このanchorはnode、parent、bolという3つの引数とともに呼び出されて、parentの開始位置にある行の最初の非スペース文字をリターンする関数。
standalone-parent
¶このanchorはnode、parent、bolという3つの引数で呼び出される関数。この関数は独自の行で始まるようなnodeの最初の祖先(親、祖父母、etc)を探して、そのノードの開始をリターンする。“独自の行で始まる”とはそのノードが開始する行において、ノードの前に空白文字しか存在しないことを意味する。
prev-sibling
¶このanchorはnode、parent、bolという3つの引数とともに呼び出されて、nodeの前の兄弟ノードの開始をリターンする関数。
no-indent
¶このanchorはnode、parent、bolという3つの引数とともに呼び出されて、nodeの開始をリターンする関数。
prev-line
¶このanchorはnode、parent、bolという3つの引数とともに呼び出されて、前の行の最初の必要空白文字をリターンする関数。
column-0
¶このanchorはnode、parent、bolという3つの引数とともに呼び出されて、列0にあるカレント行先端をリターンする。
comment-start
¶このanchorはnode、parent、bolという3つの引数とともに呼び出されて、コメント開始トークンの後の位置をリターンする。コメント開始トークンは正規表現comment-start-skip
によって定義される。この関数はparentがコメントノードであるとみなす。
prev-adaptive-prefix
¶このanchorはnode、parent、bolという3つの引数で呼び出される関数。前にある空ではない行の先頭にあるテキストにたいして、adaptive-fill-regexp
とのマッチを試みる。マッチが存在すればマッチの終端、存在しなければnil
をリターンする。ただしカレント行がプレフィックス(例:
‘-’)で始まる場合には、前の行のプレフィックスと位置が揃うように、前の行のプレフィックスの開始をリターンする。このanchorはブロックコメントにたいして、indent-relative
-*のような挙動のインデントを行う際に役に立つ。
以下にパーサーベースのインデントルールを記述する助けとなるユーティリティー関数をいくつか挙げます。
このコマンドはメジャーモードmodeにたいするカレントバッファーのインデントをチェックする。この関数はmodeに応じてカレントバッファーをインデントして、その結果をカレントのインデントと比較、その後に差分を表示するバッファーをポップアップする。(インデント対象の)正しいインデントはグリーン、カレントのインデントは赤のカラーで示される。
インデントのルールを記述する際には、treesit-inspect-mode
を使用するのも助けとなるでしょう(Tree-sitter Language Grammarを参照)。
[ << ] | [ < ] | [ 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を参照してください。
25.1 ドキュメントの基礎 | ドキュメント文字列が定義、格納される場所。 | |
25.2 ドキュメント文字列へのアクセス | Lispプログラムがドキュメント文字列にアクセスする方法。 | |
25.3 ドキュメント内でのキーバインディングの置き換え | カレントキーバインディングの置き換え。 | |
25.4 テキストのクォートスタイル | ドキュメント文字列やメッセージの中のクォーテーションマーク。 | |
25.5 ヘルプメッセージの文字記述 | 非プリント文字やキーシーケンスをプリント可能な記述にする。 | |
25.6 ヘルプ関数 | Emacsヘルプ機能により使用されるサブルーチン。 | |
25.7 ドキュメントのグループ | グループごとに関数をリストする。 |
[ << ] | [ < ] | [ 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
をリターンする。
documentation
が関数オブジェクトから生のdoc文字列を抽出するために用いるジェネリック関数。対応するメソッドを追加することによって、特定の関数タイプのdoc文字列を取得する方法を指定できる。
この関数は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 (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)
;; パターンにマッチするシンボルのリストを構築
(mapatoms (lambda (sym)
(if (string-match pattern (symbol-name sym))
(setq sym-list (cons sym sym-list)))))
;; データを表示
(help-setup-xref (list 'describe-symbols pattern)
(called-interactively-p 'interactive))
(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の値を指定する。
\`KEYSEQ'
これはキーシーケンスKEYSEQを表し、コマンド置き換えと同じフェイスが使用される。これはキーシーケンスがたとえばread-key-sequence
によって直接読み取られた場合のように、対応するコマンドがない場合のみ使用すること。キーシーケンスはkey-valid-p
に照らして有効なキーシーケンスでなければならない。これは‘\`M-x
foo'’のようなコマンド名にたいして、キーボードシーケンスのようにフォント表示したいものの、‘\[foo]’が行うようなキーシーケンスへの変換を抑止したい場合にも使用できる。
`
グレイブアクセント(grave
accent)は左クォートを意味する。これはtext-quoting-style
の値に応じて左シングルクォーテーションマーク、アポストロフィ、グレイブアクセントのいずれかを生成する。テキストのクォートスタイルを参照のこと。
'
アポストロフィ(apostrophe)は右クォートを意味する。これはtext-quoting-style
の値に応じて右シングルクォーテーションマーク、アポストロフィのいずれかを生成する。テキストのクォートスタイルを参照のこと。
\=
これは後続の文字をクォートして無効にする。したがって‘\=`’は‘`’、‘\=\[’は‘\[’、‘\=\=’は‘\=’を出力する。
\+
これは直後のシンボルを*Help*バッファーでリンクとしてマークするべきではないことを示す。
注意してください: Emacs Lisp内の文字列として記述する際は‘\’を2つ記述しなければなりません。
この関数は上述の特別なシーケンスをstringからスキャンして、それらが意味するもので置き換えてその結果を文字列としてリターンする。これによりそのユーザー自身がカスタマイズした実際のキーシーケンスを参照するドキュメントが表示できる。そのキーバインディングにはデフォルトでは特別なフェイスhelp-key-binding
が与えられるが、オプション引数no-faceが非nil
なら、この関数は生成した文字列にこのフェイスを追加しない。
この関数はsubstitute-command-keys
と同じように機能するが、クォート文字だけを置き換える。
あるコマンドが複数のバインディングをもつ場合、通常この関数は最初に見つかったバインディングを使用する。以下のようにしてコマンドのシンボルプロパティ:advertised-binding
に割り当てることにより、特定のキーバインディングを指定できる:
(put 'undo :advertised-binding [?\C-/])
:advertised-binding
プロパティはメニューアイテム(メニューバーを参照)に表示されるバインディングにも影響する。コマンドが実際にもたないキーバインディングを指定するとこのプロパティは無視される。
以下は特別なキーシーケンスの例:
(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
"
The keymap description will normally exclude menu items, but if
include-menus is non-nil
, include them.
(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] | [ ? ] |
ドキュメント文字列や診断メッセージの中では、グレイブアクセント(grave
accent)とアポストロフィ(apostrophe)は通常は特別に扱われてマッチするシングルクォーテーションマーク(“curved
quotes”とも呼ばれる)に変換されます。たとえばドキュメント文字列"Alias for
`foo'."と関数呼び出し(message "Alias for `foo'.")
はどちらも"Alias for
‘foo’."に変換されます。あまり一般的ではありませんが、Emacsがグレイブアクセントとアポストロフィをそのまま表示したり、アポストロフィだけ("Alias
for
'foo'.")を表示する場合もあります。ドキュメント文字列やメッセージフォーマットは、これらのスタイルすべてで良好に表示されるように記述する必要があります。たとえば通常の英語スタイル"Alias
for ’foo’."で表示できるのならば、ドキュメント文字列"Alias for 'foo'."はあなたが望むスタイルではないでしょう。
テキストのクォートスタイルとは無関係に変換なしでグレイブアクセントやアポストロフィの表示を要するときがあるかもしれません。ドキュメント文字列ではエスケープでこれを行うことができます。たとえばドキュメント文字列"\\=`(a
,(sin 0)) ==> (a
0.0)"では、グレイブアクセントはLispコードの表現を意図しているので、グレイブアクセントエスケープしてクォートスタイルとは無関係にそれ自身を表示します。message
やerror
の呼び出しでは、フォーマット"%s"とformat
呼び出しを引数として変換を回避できます。たとえば(message
"%s" (format "`(a ,(sin %S)) ==> (a %S)" x (sin
x)))
はテキストのクォートスタイルに関わらず、グレイブアクセントで始まるメッセージを表示します。
このユーザーオプションの値はヘルプやメッセージの文言中のシングルクォートにたいして、Emacsが使用するべきスタイルを指定するシンボル。このオプションの値がcurve
なら‘like
this’のようなcurved single quotesスタイル。値がstraight
なら'like
this'のような素のアポストロフィスタイル。値がgrave
ならクォートは変換せずに、`like
this'のようなEmacsバージョン25以前の標準スタイルであるグレイブアクセントとアポストロフィのスタイル。デフォルト値のnil
はcurved
single quotesが表示可能なようならcurve
、それ以外ならgrave
のように機能する。
このオプションはcurved quotesに問題があるプラットフォームで有用。個人の好みに応じてこれを自由にカスタマイズできる。
変数text-quoting-style
の値を直接読み取るべきではない。カレント端末においてこの変数にnil
がセットされている際の正しいクォートスタイルを動的に算出するために、この同名の関数を使用すること。
[ << ] | [ < ] | [ 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
と似ているが、引数がcharacterp
によるテスト(文字コードを参照)をパスする有効な文字コードでなければならない点が異なる。この関数は先頭のカレットによりコントロール文字の記述を生成する(Emacsがバッファー内にコントロール文字を表示する通常の方法)。修飾ビットをもつ文字にたいして、この関数はエラーをシグナルする(コントロール修飾されたASCII文字は例外であり、これらはコントロール文字として表現される)。
(text-char-description ?\C-c) ⇒ "^C"
(text-char-description ?\M-m) error→ Wrong type argument: characterp, 134217837
この関数は主にキーボードマクロを操作するために使用されるが、大雑把な意味で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内で以下のように定義されている:
(keymap-set global-map (key-description (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
、read-char-from-minibuffer
、y-or-n-p
を呼び出すコマンドは、それが入力を行う間は恐らく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は種々のグループにもとづいて関数をリストできます。たとえばstring-trim
やmapconcat
などは“string(文字列)”の関数ですが、M-x
shortdoc RET string RETによって文字列を操作する関数の概要を得ることができます。
ドキュメンテーショングループはdefine-short-documentation-group
マクロにより作成されます。
関数グループとしてgroupを定義して、それらの関数の使用に関する短いサマリーを提供する。オプション引数functionsは要素が以下の形式であるようなリスト:
(func [keyword val]…)
以下のキーワードが認識される:
:eval
値は評価時の副作用をもたないフォームであること。このフォームはドキュメント内でprin1
でプリントして使用されることになる(出力関数を参照)。しかしこのフォームが文字列ならそのまま挿入されてから、フォームを生成するためにread
される。いずれのケースでも、その後にフォームは評価されて結果が使用される。たとえば:
:eval (concat "foo" "bar" "zot") :eval "(make-string 5 ?x)"
は以下の結果になる:
(concat "foo" "bar" "zot") ⇒ "foobarzot" (make-string 5 ?x) ⇒ "xxxxx"
(Lispフォームと文字列の両方を受け付けるのは、特定のフォーム表現が望まれるいくつかのケースにおいてプリントのコントロールを可能にするのが理由。この例では‘?x’が文字列に含まれていなければ‘120’としてプリントされるだろう。)
:no-eval
これは:eval
と似ているが、フォームを評価しない点が異なる。この場合では何らかの類の:result
要素が含まれている必要がある。
:no-eval (file-symlink-p "/tmp/foo") :eg-result t
:no-eval*
:no-eval
と同様だが、常に‘[it depends]’を結果として挿入する。たとえば:
:no-eval* (buffer-string)
は以下の結果になる:
(buffer-string) → [it depends]
:no-value
:no-eval
と同様だが、対象となっている関数が明確に定義されたリターン値をもち、副作用のためだけに使用される際に用いられる。
:result
評価されないフォーム例の結果を出力するために使用される。
:no-eval (setcar list 'c) :result c
:eg-result
評価されないフォーム例の結果例を出力するために使用される。たとえば:
:no-eval (looking-at "f[0-9]") :eg-result t
は以下の結果になる:
(looking-at "f[0-9]") eg. → t
:result-string
:eg-result-string
これら2つはそれぞれ:result
や:eg-result
と同じだが、そのまま挿入される。これは結果が読めなかったり、特定の形式が要求される際に有用:
:no-eval (find-file "/tmp/foo") :eg-result-string "#<buffer foo>" :no-eval (default-file-modes) :eg-result-string "#o755"
:no-manual
その関数がマニュアルにドキュメントされていないことを示す。
:args
デフォルトではその関数の実際の引数リストが表示される。:args
が与えられたら、かわりにそれらが使用される。
:args (regexp string)
以下に非常に短い例を示す:
(define-short-documentation-group string "Creating Strings" (substring :eval (substring "foobar" 0 3) :eval (substring "foobar" 3)) (concat :eval (concat "foo" "bar" "zot")))
1つ目の引数は定義するグループ名、その後に任意個数の関数説明が続く。
関数は任意個数のドキュメンテーショングループに所属できます。
このリストは関数説明に加えて、ドキュメントからセクションへの分割に使用される文字列要素ももつことができます。
この関数によりLispパッケージは関数をグループに追加できる。elemはそれぞれ上述したような関数説明であること。groupは関数グループ、sectionは関数を挿入する関数グループのセクション。
groupが存在しなければ作成する。sectionが存在しなければ、その関数グループの最後に追加される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このチャプターでは検索、作成、閲覧、保存、その他ファイルとディレクトリーにたいして機能するEmacs Lispの関数と変数について説明します。その他のいくつかのファイルに関する関数についてはバッファー、バックアップとauto-save(自動保存)に関する関数についてはバックアップと自動保存で説明されています。
ファイル関数の多くはファイル名であるような引数を1つ以上受け取ります。このファイル名は文字列です。これらの関数のほとんどは関数expand-file-name
を使用してファイル名引数を展開するので、~は相対ファイル名(../と空文字列を含む)として正しく処理されます。ファイル名を展開する関数を参照してください。
加えて特定のmagicファイル名は特別に扱われます。たとえばリモートファイル名が指定された際、Emacsは適切なプロトコルを通じてネットワーク越しにファイルにアクセスします。Remote Files in The GNU Emacs Manualを参照してください。この処理は非常に低レベルで行われるので、特に注記されたものを除いて、このチャプターで説明するすべての関数がファイル名引数としてmagicファイル名を受け入れると想定しても良いでしょう。詳細はSee 特定のファイル名の“Magic”の作成を参照してください。
ファイルI/O関数がLispエラーをシグナルする際、通常はコンディションfile-error
を使用します(エラーを処理するコードの記述を参照)。ほとんどの場合にはオペレーティングシステムからロケールsystem-messages-locale
に応じたエラーメッセージが取得されて、コーディングシステムlocale-coding-system
を使用してデコードされます(localeを参照)。
26.1 ファイルのvisit | 編集のためにEmacsバッファーにファイルを読み込む。 | |
26.2 バッファーの保存 | 変更されたバッファーをファイルに書き戻す。 | |
26.3 ファイルからの読み込み | ファイルをvisitせずにバッファーに読み込む。 | |
26.4 ファイルへの書き込み | バッファーの一部から新たなファイルに書き込む。 | |
26.5 ファイルのロック | 複数名による同時編集を防ぐためにファイルをlockまたはunlockする。 | |
26.6 ファイルの情報 | ファイルの存在、アクセス権、サイズのテスト。 | |
26.7 ファイルの名前と属性の変更 | ファイル名のリネームやパーミッションの変更など。 | |
26.8 ファイルと二次媒体 | 電源喪失とメディアエラーへの対処 | |
26.9 ファイルの名前 | ファイル名の分解と展開。 | |
26.10 ディレクトリーのコンテンツ | ディレクトリーないのファイルリストの取得。 | |
26.11 ディレクトリーの作成・コピー・削除 | ディレクトリーの作成と削除。 | |
26.12 特定のファイル名の“Magic”の作成 | 特定のファイル名にたいする特別な処理。 | |
26.13 ファイルのフォーマット変換 | さまざまなファイルフォーマットへ/からの変換。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ファイルのvisitとはファイルをバッファーに読み込むことを意味します。一度これを行うと、わたしたちはバッファーがファイルをvisit(訪問)していると言い、ファイルのことをバッファーのvisitされたファイルと呼んでいます。
ファイルとバッファーは2つの異なる事柄です。ファイルとは、(削除しない限り)コンピューター内に永続的に記録された情報です。一方バッファーとは編集セッションの終了(またはバッファーのkill)とともに消滅する、Emacs内部の情報です。あるバッファーがファイルをvistしているとき、バッファーにはファイルからコピーされた情報が含まれます。編集コマンドにより変更されるのはバッファー内のコピーです。バッファーへの変更によってファイルは変更されません。その変更を永続化するためにはバッファーを保存(save)しなければなりません。これは変更されたバッファーのコンテンツをファイルにコピーして書き戻すことを意味します。
ファイルとバッファーは異なるにも関わらず、人はバッファーという意味でファイルを呼んだり、その逆を行うことが多々あります。実際のところ、“わたしはまもなく同じ名前のファイルに保存するためのバッファーを編集している”ではなく、“わたしはファイルを編集している”と言います。人間がこの違いを明確にする必要は通常はありません。しかしコンピュータープログラムで対処する際には、この違いを心に留めておくのが良いでしょう。
26.1.1 ファイルをvisitする関数 | visit用の通常のインターフェイス関数。 | |
26.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していないバッファーでも、バッファーローカルんqwrite-contents-functions
の関数を使用することにより“saved(保存済み)”にすることができます。
この関数はバッファーが最後に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
ならどのバッファーで確認せずに保存するか)を制御する。
predがnil
なら、predのかわりにsave-some-buffers-default-predicate
の値を使用することを意味する。その結果がnil
ならファイルをvisitしているバッファーにたいしてのみ確認を求めることを意味する。t
ならbuffer-offer-save
のバッファーローカル値がnil
であるような非ファイルバッファー以外の特定のバッファーの保存も提案することを意味する(バッファーのkillを参照)。ユーザーが非ファイルバッファーの保存にたいして‘yes’と応えると保存に使用するファイル名の指定を求める。save-buffers-kill-emacs
関数はpredにたいして値t
を渡す。
述語がt
とnil
のいずれでもなければ引数なしの関数であること。その関数はバッファーの保存を提案するか否かを決定するためにバッファーごとに呼び出される。これが特定のバッファーで非nil
値をリターンすればバッファー保存の提案を行うことを意味する。
この関数はカレントバッファーをファイルfilenameに書き込んで、バッファーがそのファイルをvisitしていることにして未変更とマークする。次にfilenameにもとづいてバッファー名をリネームする。バッファー名を一意にするため、必要なら‘<2>’のような文字列を付加する。処理のほとんどはset-visited-file-name
(バッファーのファイル名を参照)、およびsave-buffer
を呼び出すことにより行われる。
confirmが非nil
なら、それは既存のファイルを上書きする前に確認を求めることを意味する。ユーザーがプレフィックス引数を与えなければinteractiveに確認が求められる。
filenameがディレクトリー名(ディレクトリーの名前を参照)、または既存のディレクトリーへのシンボリックリンクなら、write-file
はディレクトリーfilename内でvisitされているファイルの名前を使用する。そのバッファーがファイルをvisitしていなければ、かわりにバッファーの名前を使用する。
バッファーの保存によりフックがいくつか実行されます。これによりフォーマット変換も処理されます(ファイルのフォーマット変換を参照)。以下で説明するこれらのフックはバッファーのテキストをファイルに書き込むsave-buffer
以外の他のプリミティブや関数、とりわけauto-saving
(自動保存を参照)では実行されないことに注意してください。
この変数の値は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している特定のファイルやファイルの場所ではなくバッファーのコンテンツに関連するフックを意図しており、実際にはファイルをvisitしていないバッファーにたいして任意の保存処理を作成するために使用できる。そのようなフックは、この変数にたいするバッファーローカルなバインディングとして、通常はメジャーモードにより作成される。この変数はセットされた際には常に自動的にバッファーローカルになる。新たなメジャーモードへの切り替えは常にこの変数をリセットするが、set-visited-file-name
の呼び出しではリセットされない。
このフック内の関数のいずれかが非nil
をリターンすると、そのファイルはすでに書き込み済みとみなされて、残りの関数は呼び出されずwrite-file-functions
内の関数も呼び出されない。
(スペシャルモードのバッファーのような)ファイルをvisitしていないバッファーを保存するためにこのフックを利用する際には、その関数が正常に保存することに失敗してnil
値をリターンすると、save-buffer
がユーザーにたいしてバッファーを保存するファイルの入力を求めることに留意。これが望ましくなければエラーのレイズによる関数の失敗を考慮されたい。
このノーマルフックはvisitしているファイルにバッファーが保存される前に実行される。保存が通常の方法で行われるか、あるいは上述のフックのいずれかで行われたかは問題ではない。たとえばcopyright.elプログラムは、ファイルの保存においてそれの著作権表示が今年であることを確認するためにこのフックを使用する。
これはバッファーをvisitするファイルに保存後に実行されるノーマルフック。
この変数が非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文字(バイト)でコードされた文字を挿入する。
begかendが偶然マルチバイトシーケンス文字の中間だった場合には、Emacsお文字コード規約によりバッファーに1つ以上の8ビット文字(いわゆる“rawバイト”)が挿入されるだろう(文字セットを参照)。この方法でバッファーの一部にたいして読み取りを行いたければ、この関数の呼び出し前後に適切な値をcoding-system-for-read
にバインドして(単一の操作にたいするコーディングシステムの指定を参照)、境界にあるrawバイトをチェックするとともに、これらのバイトシーケンス全体を読み取り有効な文字に変換して戻すLisp関数を記述することをお勧めする。
引数replaceが非nil
なら、それはバッファーのコンテンツ(実際にはアクセス可能な範囲)をファイルのコンテンツで置き換えることを意味する。これは単にバッファーのコンテンツを削除してファイル全体を挿入するより優れている。なぜなら、(1)マーカー位置を維持して、(2)undoリストに配置するデータも少ないからである。
replace、visit、begがnil
ならinsert-file-contents
で(FIFOやI/Oデバイスのような)スペシャルファイルの読み取りが可能。とはいえバッファーに(潜在的には)無制限のデータが挿入されることを防ぐために(たとえば/dev/urandomからのデータ挿入時)、これらのファイルにたいしては通常はend引数を使用するべきだろう。
この関数はinsert-file-contents
のように機能するが、ファイル内の各バイトを必要なら8ビット文字へ変換するために個別に処理する点が異なる。またafter-insert-file-functions
を実行せずフォーマットのデコード、文字コード変換、自動解凍、...などを行わない。
他のプログラムがファイルを読めるように他プロセスにファイル名を渡したければ関数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
をシグナルする。たとえwrite-region
が通常はシンボリックリンクをフォローして、もしシンボリックリンクが壊れていればpointed-toファイル(訳注:
ファイルへのハードリンクにたいするポインター)を作成するとしても、mustbenewがexcl
ならシンボリックリンクをフォローしない。
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モードで処理中に有用である。
この変数の値がnil
ならwrite-region
はファイル書き込み後にシステムコールfsync
を使用する。これはたとえEmacsを低速化するとしても、電源喪失時のデータ損失リスクを軽減する。値がt
ならEmacsはfsync
を使用しない。デフォルト値はEmacsが対話的に実行されていればnil
、batchモードで実行時にはt
。ファイルと二次媒体を参照のこと。
with-temp-file
マクロは一時バッファー(temporary
buffer)をカレントバッファーとしてbodyフォームを評価して、最後にそのバッファーのコンテンツをfileに書き込む。これは終了時に一時バッファーをkillして、with-temp-file
フォームの前にカレントだったバッファーをリストアする。その後にbody内の最後のフォームの値をリターンする。
throw
やエラーによる異常なexit(abnormal exit)でも、カレントバッファーはリストアされる(非ローカル脱出を参照)。
with-temp-buffer
(Current
Bufferを参照)と同様に、このマクロが使用する一時バッファーではフックkill-buffer-hook
、kill-buffer-query-functions
(バッファーのkillを参照)、buffer-list-update-hook
(バッファーリストを参照)は実行されない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
2人のユーザーが同時に同じファイルを編集する際には、彼らはおそらく互いに干渉しあうでしょう。Emacsはファイルが変更される際にファイルロック(file
lock)を記録することにより、このような状況の発生を防ぎます。そしてEmacsは他のEmacsジョブにロックされているファイルをvisitしているバッファーへの変更の最初の試みを検知して、ユーザーに何を行うべきかを尋ねます。このファイルロックの実態は、編集中のファイルと同じディレクトリーに格納される特別な名前をもつシンボリックリンクです。この名前はバッファーのファイル名に.#を前置することにより構築されます。シンボリックリンクのターゲットはuser@host.pid:boot
という形式になります。ここでuserはカレントのユーザー名(
user-login-name
かより得)、hostはEmacsを実行中のホスト(
system-name
より取得)、pidはEmacsのプロセスID、bootは最後のブートからの経過時間です。ブート時刻が利用できなければ:boot
は省略されます。(シンボリックリンクをサポートしないファイルシステムでは、user@host.pid:boot
という形式を構築するか割りに通常のファイルが使用される)。
ファイルのアクセスにNFSを使用する際には、可能性は小さいものの他のユーザーと同じファイルを同時にロックするかもしれません。これが発生すると2人のユーザーが同時にファイルを変更することが可能になりますが、それでもEmacsは2番目に保存するユーザーにたいして警告を発するでしょう。たファイルをvisitしているバッファーでディスク上でファイルの変更を検知することにより、ある種の同時編集を捕捉できます。バッファーの変更時刻を参照してください。
この関数はファイルfilenameがロックされていなければnil
をリターンする。このEmacsプロセスによりロックされていればt
、他のEmacsジョブによりロックされている場合はロックしたユーザーの名前をリターンする。
(file-locked-p "foo") ⇒ nil
この関数はカレントバッファーが変更されていればファイルfilenameをロックする。引数filenameのデフォルトはカレントバッファーがvisitしているファイル。カレントバッファーがファイルをvisitしていない、バッファーが変更されていない、またはcreate-lockfiles
がnil
なら何もしない。
この関数はカレントバッファーが変更されていればバッファーによりvisitされているファイルをアンロックする。バッファーが変更されていなければ、そのファイルをロックしてはならないのでこの関数は何もしない。カレントバッファーがファイルをvisitしていない、またはファイルがロックされていなければこの関数は何もしない。この関数はdisplay-warning
呼び出しによってファイルシステムエラーを処理して、それ以外の場合にはエラーを無視する。
この変数がnil
ならEmacsはファイルをロックしない。
デフォルトでは、Emacsはロックするファイルと同じディレクトリーにロックファイルを作成する。この変数をカスタマイズしてこれを変更できる。これはauto-save-file-name-transforms
と同じ構文をもつ(自動保存を参照)。たとえばEmacsにすべてのロックファイルを/var/tmp/に書き込ませるには、以下のようにすればよい:
(setq lock-file-name-transforms '(("\\`/.*/\\([^/]+\\)\\'" "/var/tmp/\\1" t)))
この関数はユーザーがfileの変更を試みたが、それが名前other-userのユーザーにロックされていたとき呼び出される。この関数のデフォルト定義は何を行うかユーザーに尋ねる関数。この関数がリターンする値はEmacsが次に何を行うかを決定する:
t
はそのファイルのロックを奪うことを意味する。その場合にはother-userはロックを失い、そのユーザーがファイルを編集することができる。
nil
はロックを無視して、とにかくユーザーがファイルを編集できるようにすることを意味する。
file-locked
をシグナルする。この場合には、ユーザーが行おうとしていた変更は行われない。
このエラーにたいするエラーメッセージは以下のようになる:
error→ File is locked: file other-user
ここでfile
はファイル名、other-userはそのファイルのロックを所有するユーザーの名前。
望むなら他の方法で判定を行う独自バージョンでask-user-about-lock
関数を置き換えることができる。
変数remote-file-name-inhibit-locks
にt
をセットして、リモートロックファイルの作成を抑止できる。
これはインタラクティブに呼び出されるコマンドであり、カレントバッファーでcreate-lockfiles
のローカル値を切り替える。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではファイル(またはディレクトリーやシンボリックリンク)に関してファイルが読み込み可能か、書き込み可能か、あるいはファイルのサイズのようなさまざまなタイプの情報を取得する関数を説明します。これらの関数はすべて引数にファイルの名前を受け取ります。特に注記した場合を除きこれらの引数には既存のファイルを指定する必要があり、ファイルが存在しなければエラーをシグナルします。
スペースで終わるファイル名には気をつけてください。いくつかのファイルシステム(特にMS-Windows)では、ファイル名の末尾の空白文字は暗黙かつ自動的に無視されます。
26.6.1 アクセシビリティのテスト | そのファイルは読み取り可能か? 書き込み可能か? | |
26.6.2 ファイル種別の区別 | それはディレクトリー? それともシンボリックリンク? | |
26.6.3 本当の名前 | シンボリックリンクの最終的なファイル名。 | |
26.6.4 ファイルの属性 | ファイルのサイズや更新日時など。 | |
26.6.5 拡張されたファイル属性 | アクセス制御にたいするファイル属性の拡張。 | |
26.6.6 標準的な場所へのファイルの配置 | 標準的な場所でファイルを見つける方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はファイルにたいする読み取り、書き込み、実行のパーミッションをテストします。これらの関数は明示しない限りボリックリンクをフォローします。ファイル種別の区別を参照してください。
いくつかのオペレーティングシステムではACL(Access Control Lists: アクセス制御リスト)のような機構を通じて、より複雑なアクセスパーミッションセットが指定できます。それらのパーミッションにたいする問い合わせやセットの方法については拡張されたファイル属性を参照してください。
この関数はファイル名filenameが存在しているようならt
をリターンする。これはファイルが読み取り可能である必要はなく、ファイルの属性を調べることが恐らく可能なこと意味する(Unixやその他のPOSIXシステム類ではファイルが存在してファイルを含むディレクトリーの実行パーミッションをもつ場合にはファイル自体のパーミッションに関わらずt
)。
ファイルが存在しない、またはファイルが存在するかどうかの判断に問題があるようなら、この関数はnil
をリターンする。
空文字列であるようなファイル名はカレントバッファーのデフォルトディレクトリーから相対的なファイル(絶対ファイル名と相対ファイル名を参照)と解釈されるので、引数に空文字列を指定してfile-exists-p
を呼び出すとそのバッファーのデフォルトディレクトリーについてレポートされることになる。
ディレクトリーはファイルなので、ディレクトリーが与えられるとfile-exists-p
はt
をリターンするかもしれない。しかしfile-exists-p
はシンボリックリンクをフォローするので、リンクのターゲットが存在する場合のみシンボリックリンク名にたいしてt
をリターンする。Lispプログラムにおいて既存のファイルとしてターゲットが存在しない壊れたシンボリックリンク(dangling
symlinks)を考慮する必要がある場合には、file-exists-p
ではなくfile-attributes
(ファイルの属性を参照)を使うこと。
この関数はfilenameという名前のファイルが存在して、それを読み取ることが可能ならt
、それ以外はnil
をリターンする。
この関数は、filenameという名前のファイルが存在して、それを実行することが可能ならt
をリターンする。それ以外はnil
をリターンする。Unixやその他のPOSIXシステム類ではファイルがディレクトリーなら実行パーミッションはディレクトリー内のファイルの存在と属性をチェックできるので、ファイルのモードが許せばオープンできることを意味する。
この関数は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
このマクロはbody実行前にdefault-directory
が存在するディレクトリーにバインドされていることを保証する。すでにdefault-directory
が存在していれば優先し、存在していなければ何処か別のディレクトリーを使用する。このマクロはたとえば存在するディレクトリー内での実行を要する外部コマンド呼び出し時に有用かもしれない。選択されるディレクトリーへの書き込み権限は保証しない。
この関数はfilenameが読み取り可能ならnil
、それ以外ならstringをエラーメッセージのテキストに使用してエラーをシグナルする。
この関数はファイルfilenameを削除後に新たに作成してもファイルの所有者が変更されずに維持されるようならt
をリターンする。これは存在しないファイルにたいしてもt
をリターンする。
オプション引数groupが非nil
なら、この関数はファイルのグループが変更されないこともチェックする。
この関数はシンボリックリンクをフォローしない。
この関数はfilenameのモードビット(mode
bits)をリターンする。これは読み取り、書き込み、実行パーミッションを要約する整数。この関数はシンボリックリンクを許容する。ファイルが存在しなければリターン値はnil
。
モードビットの説明はFile permissions in The GNU Coreutils
Manualを参照のこと。たとえば最下位ビットが1ならそのファイルは実行可能、2ビット目が1なら書き込み可能、...となる。設定できる最大の値は4095(8進の7777)であり、これはすべてのユーザーが読み取り、書き込み、実行のパーミッションをもち、他のユーザーとグループにたいしてSUIDビット、およびstickyビットがセットされる。
デフォルトでは、この関数はシンボリックリンクをフォローする。しかしオプション引数flagがシンボルnofollow
なら、この関数はシンボリックリンクのfilenameをフォローしない。これはどこか別の場所でうっかりモードビットを取得してしまうことを防ぎ、file-attributes
との整合性を保つ助けとなり得る(ファイルの属性を参照)。
これらのパーミッションのセットに使用されるset-file-modes
関数についてはファイルの名前と属性の変更を参照のこと。
(file-modes "~/junk/diffs" 'nofollow)
⇒ 492 ; 10進整数
(format "%o" 492)
⇒ "754" ; 8進に変換した値
(set-file-modes "~/junk/diffs" #o666 'nofollow) ⇒ 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などのような標準的な実行可能な拡張子のいずれかで終わる場合にはファイルを実行可能であると判断する。POSIX標準の‘#!’署名で始まるshellスクリプトやPerlスクリプトも実行可能と判断される。POSIXとの互換性のためにディレクトリーも実行可能と報告される。file-attributes
(ファイルの属性を参照)もこれらの慣習にしたがう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではディレクトリー、シンボリックリンク、および通常ファイルのようなさまざまな種類のファイルを区別する方法を説明します。
シンボリックリンクは通常はそれが出現した場合には常にフォローされます。たとえばファイル名a/b/cを解釈するためにシンボリックリンクかもしれないa、a/b、a/b/cはすべてフォローされて、リンクターゲット自身がシンボリックリンクなら再帰的にフォローされるかもしれません。しかしいくつかの関数は最後のファイル名(この例ではa/b/c)ではシンボリックリンクをフォローしません。そのような関数のことをシンボリックリンク非フォロー(not follow symbolic links)と呼びます。
ファイルfilenameがシンボリックリンクならfile-symlink-p
関数はリンクをフォローせずに、かわりにリンクターゲットを文字列としてリターンする(リンクターゲット文字列はターゲットの完全な絶対ファイル名である必要はない。リンクが指すのが完全なファイル名かどうかを判断するのは簡単な処理ではない。以下参照)。
file-symlink-p
はファイルfilenameがシンボリックリンクではないか、あるいは存在しなかったりシンボリックリンクかどうか判断するのに問題がある場合には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をリターンするが、たとえそれ自体がシンボリックリンクであってもリンク先の解決を行わないことに注意。これは関数がシンボリックリンクをフォローしない、すなわちシンボリックリンクをフォローする処理はファイル名の最後のコンポーネントには適用されないからである。
この関数がリターンするのはそのシンボリックリンクに何が記録されているかを示す文字列であり、それにディレクトリー部分が含まれているかどうかは構わない。この関数は完全修飾されたファイル名を生成するためにリンクターゲットを展開しないし、リンクターゲットが絶対ファイル名でなければ、(もしあっても)filename引数のディレクトリー部分は使用しない。以下に例を示す:
(file-symlink-p "/foo/bar/baz") ⇒ "some-file"
ここでは、たとえ与えられた/foo/bar/bazが完全修飾されたファイル名であるにも関わらずその結果は異なり、実際には何のディレクトリー部分ももたない。some-file自体がシンボリックリンクかもしれないので、単にその前に先行ディレクトリーを追加することはできず、絶対ファイル名を生成するために単にexpand-file-name
(ファイル名を展開する関数を参照)を使用することもできないからである。
この理由により、あるファイルがシンボリックリンクか否かという単一の事実よりも多くを判定する必要がある場合にこの関数が有用であることは稀である。実際にリンクターゲットのファイル名が必要なら、本当の名前で説明するfile-chase-links
やfile-truename
を使用すること。
この関数はfilenameが既存のディレクトリー名ならt
。filenameがディレクトリー名ではない、あるいはディレクトリーかどうかの判断に問題がある場合にはnil
をリターンする。この関数はシンボリックリンクをフォローする。
(file-directory-p "~rms") ⇒ t
(file-directory-p "~rms/lewis/files-ja.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
をリターンする。filenameが存在しない、通常ファイルではない、あるいは通常ファイルかどうかの判断に問題がある場合にはnil
をリターンする。この関数はシンボリックリンクをフォローする。
[ << ] | [ < ] | [ 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を参照のこと。
シンボリックリンクのターゲットがリモートファイル名の構文をもつ場合には、file-truename
はそれをクォートしてリターンする。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が存在しなければリターン値は不定。
ファイル名やその一部にたいして文字列としての比較を要する場合には、背景にあるファイルシステムが非caseセンシティブ(case-insensitive:
大文字小文字を区別しない)かどうかを知ることが重要になる。この関数はファイルfilenameが非caseセンシティブなファイルシステムにあればt
をリターンする。MS-DOSとMS-Windowsでは常にt
をリターンする。CygwinとmacOSでは非caseセンシティブかもしれないので、実行時テストによりcaseセンシティブ性の判定を試みる。テストで決定されなければCygwinならt
、macOSならnil
をリターンする。
この関数は現在のところMS-DOS、MS-Windows、Cygwin、macOS以外のプラットフォームでは常にnil
をリターンする。これはSamba共有やNFSマウントされたWindowsボリュームのようにマウントされたファイルシステムのcaseセンシティブ性は検知しない。リモートホストでは‘smb’メソッドにたいしてはt
とみなす。
この関数は与えられたfileにたいしてVCバックエンドが責任を負うかどうかを判断する。たとえばemacs.cがGitでトラック(track:
追跡)されていれば(vc-responsible-backend "emacs.c")
は‘Git’をリターンする。fileがシンボリックリンクならvc-responsible-backend
はシンボリックリンクを解決せずに、シンボリックリンクにたいするバックエンドが報告されることに注意。fileが参照するファイルのバックエンドVCを取得するには、file-chase-links
のようなシンボリックリンク解決用の関数でfileをラップすること。
(vc-responsible-backend (file-chase-links "emacs.c"))
[ << ] | [ < ] | [ 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
この関数は最後に呼び出されて以降にfilenameのタイムスタンプが変更されていれば非nil
をリターンする。何らかのfilenameにたいして初めて呼び出された際には、そのファイルの最終修整時刻とサイズを記録して、filenameが存在すれば非nil
をリターンする。これ以降に同じfilenameで呼び出されると、カレントのタイムスタンプとサイズを記録されたものと比較してタイムスタンプかサイズのいずれか(あるいは両方)が異なる場合のみ非nil
をリターンする。これはあるファイルが変更されたら常に再読み込みするようなLispプログラムで役に立つ。オプション引数tag
(シンボル)を指定して呼び出すと、サイズと最終修整時刻の比較は同一tagにたいする呼び出しに限定される。
この関数はファイルfilenameの属性(attributes)のリストをリターンする。オープンできないファイルが指定された場合は、nil
をリターンする。指定されたファイルが存在しなければnil
をリターンする。この関数はシンボリックリンクをフォローしない。オプション引数id-formatは属性UIDとGID(以下参照)にたいして望ましいフォーマットを指定する。有効な値は'string
と'integer
。デフォルトは'integer
だが、わたしたちはこれの変更を計画しているので、リターンされるUIDやGIDを使用する場合にはid-formatにたいして非nil
値を指定すること。
GNUプラットフォームではこの関数はロックファイル処理時はアトミックである。別のプロセスによりファイルシステムが同時に変更された場合には、この関数は変更の前か後のいずれかのファイル属性をリターンする。それ以外ならこの関数はアトミックではなく競合状態を検知したらnil
、または以前とカレントが混ざったファイル属性をリターンするかもしれない。
このリスト内の要素にアクセスするためにアクセッサ関数が提供される。このアクセッサ以下の要素の記述とともに示される。
リストの要素は順に:
t
、シンボリックリンクにたいしては文字列(リンクされる名前)、テキストファイル(file-attribute-type
)にたいしてはnil
。
file-attribute-link-number
)。ハードリンクとして知られる代替え名は関数add-name-to-file
を使用して作成できる(ファイルの名前と属性の変更を参照)。
file-attribute-user-id
。しかし名前をもつユーザーに対応しなければ値は整数。
file-attribute-group-id
)。
file-attribute-access-time
)。タイムスタンプはcurrent-time
(時刻を参照)の形式であり、ファイルシステムのタイムスタンプの精度に切り詰められる。たとえばFATベースのいくつかのファイルシステムでは最終アクセスの日付だけが記録されるので、この時刻には常に最終アクセス日の真夜中が保持されることに注意。
file-attribute-modification-time
)。これはファイルのコンテンツが変更された最終時刻。
file-attribute-status-change-time
。上記参照)。これはファイルのアクセスモードビット、所有者とグループ、およびファイルにたいしてファイルのコンテンツ以外にファイルシステムが記録するその他の情報にたいする最終変更時刻。
file-attribute-size
)。
file-attribute-modes
)。
file-attribute-inode-number
)。
file-attribute-device-number
)を表す整数、あるいは2つの整数からなるコンスセル。後者のコンスセルはリモートとローカルのファイルシステムを区別するために、リモートファイルにたいして使われる場合がある。
ファイルのinodeとデバイスを合わせれば、そのシステム上の2つの任意のファイルを区別するために十分な情報が得られる(この2つの属性の両方に等しい値を2つのファイルがもつことはできない)。ファイルを一意に識別するこのタプル(tuple:
組)は、file-attribute-file-identifier
によってリターンされる。
たとえば以下はfiles-ja.texiのファイル属性:
(file-attributes "files-ja.texi" 'string) ⇒ (nil 1 "lh" "users" (20614 64019 50040 152000) (20000 23 0 0) (20614 64555 902289 872000) 122295 "-rw-rw-rw-" t 6473924464520138 1014478468)
この結果を解釈すると:
nil
ディレクトリーでもシンボリックリンクでもない。
1
(カレントデフォルトディレクトリー内で名前files-ja.texiは)単一の名前をもつ。
"lh"
名前"lh"のユーザーにより所有される。
"users"
名前"users"のグループ。
(20614 64019 50040 152000)
最終アクセス時刻は2012年10月23日のUTC(協定世界時)で20:12:03.050040152(current-time-list
がnil
ならタイムスタンプは(1351023123050040152
. 1000000000)
になる)。
(20000 23 0 0)
最終修整時刻は2001年7月15日のUTCで08:53:43.000000000(current-time-list
がnil
ならタイムスタンプは(1310720023000000000
. 1000000000)
になる)。
(20614 64555 902289 872000)
最後のステータス変更時刻は2012年10月23日のUTCで20:20:59.902289872(current-time-list
がnil
ならタイムスタンプは(1351023659902289872
. 1000000000)
になる)。
122295
バイト長は122295バイト(しかしマルチバイトシーケンスが含まれていたり、EOLフォーマットがCRLFなら122295文字は含まれないかもしれない)。
"-rw-rw-rw-"
所有者、グループ、その他にたいして読み取り、書き込みアクセスのモードをもつ。
t
単なるプレースホルダーであり何の情報ももたない。
6473924464520138
inode番号は6473924464520138。
1014478468
ファイルシステムのデバイス番号は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がサポートされていない、あるいはファイルが存在しなければリターン値はnil
。
この関数はファイルfilenameのSELinuxコンテキストを(user role
type
range)
という形式のリストでリターンする。リストの要素はそのコンテキストのユーザー、ロール、タイプ、レンジを文字列として表す値である。これらの実際の意味についての詳細はSELinuxのドキュメントを参照のこと。リターン値はset-file-selinux-context
がcontext引数で受け取るのと同じ形式(ファイルの名前と属性の変更を参照)。
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関数がディレクトリーにたいして確実にdir-ok
をリターンすること。たとえば:
(locate-file "html" '("/var/www" "/srv") nil (lambda (f) (if (file-directory-p f) 'dir-ok)))
互換性のためにpredicateにはexecutable
、readable
、writable
、exists
、またはこれらシンボルの1つ以上のリストも指定できる。
この関数はprogramという名前の実行可能ファイルを検索して、その実行可能ファイルの絶対ファイル名と、もしあればファイル名の拡張子も含めてリターンする。ファイルが見つからなければnil
をリターンする。この関数はexec-path
内のすべてのディレクトリーを検索して、exec-suffixes
内のすべてのファイル名拡張子の検索も試みる(サブプロセスを作成する関数を参照)。
remoteがnil
、かつ非default-directory
がリモートディレクトリーなら、programは各リモートホスト上で検索される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションの関数はファイルのリネーム、コピー、削除やリンク、モードをセットします。これらの関数は処理に失敗すると、通常は失敗の理由を記述するシステム依存のエラーメッセージを報告するfile-error
エラーをシグナルします。ファイルが存在しないために失敗すると、かわりにfile-missing
エラーをシグナルします。
性能的な理由によりオペレーティングシステムはこれらの関数により行われた変更を2次記憶装置に書き込むかわりに、キャッシュしたりエイリアスするかもしれません。ファイルと二次媒体を参照してください。
引数newnameをもつ関数では、それがディレクトリー名ならsource名の非ディレクトリー部分が追加されたかのように扱われます。ディレクトリー名は通常は‘/’で終端されます(ディレクトリーの名前を参照)。たとえばoldnameがa/b/cでnewnameがd/e/f/ならd/e/f/cであるかのように処理されます。newnameがディレクトリー名ではなくディレクトリーであるような名前なら、この特別な扱いは適用されません。たとえばnewnameのd/e/fがディレクトリーでも、そのまま処理されます。
newnameという引数をもつ関数では、newnameという名前のファイルが既に存在する場合には、その挙動が引数ok-if-already-existsの値に依存します。
nil
ならfile-already-exists
エラーがシグナルされる。
この関数は、oldnameという名前のファイルにnewnameという名前を追加で与える。これはnewnameという名前がoldnameにたいする新たなハードリンクになることを意味する。
newnameがシンボリックリンクなら、リンクが指すディレクトリーエントリーではなく、シンボリックリンクリンクのディレクトリーエントリーが置き換えられる。oldnameがシンボリックリンクなら、この関数はリンクをフォローする可能性があるが、GNUプラットフォームではリンクをフォローしない。oldnameがディレクトリーなら、たとえ処理を正常に行ってツリー構造ではないファイルシステムを作成できる古い様式の非GNUプラットフォームのスーパーユーザーでも、この関数は通常は失敗する。
以下の例の最初の部分では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を削除するのは、瞬間的な遷移状態とエラーの処理、ディレクトリーとシンボリックリンクを別とすればリネームと同じ効果がある。
このコマンドはシンボリックリンクをフォローしない。filenameがシンボリックリンクなら、このコマンドはリンクが指すファイルではなくシンボリックリンクをリネームする。newnameがシンボリックリンクなら、リンクが指すディレクトリーエントリーではなくリンクのディレクトリーエントリーを置き換える。
filenameとnewnameが同じディレクトリーエントリー(親ディレクトリーが同じでありそのディレクトリー内で同じ名前を与える)なら、このコマンドは何もしない。それ以外ならfilenameとnewnameが同一のファイルを命名する場合には、このコマンドはPOSIX準拠システムでは何も行わなず、いくつかの非POSIXシステムではfilenameを削除する。
newnameがすでに存在する場合にはoldnameがディレクトリーなら空のディレクトリー、非ディレクトリーなら非ディレクトリーでなければならない。
このコマンドはファイルoldnameをnewnameにコピーする。oldnameが通常のファイルでなければエラーをシグナルする。newnameがディレクトリーなら最後の名前コンポーネントを保持するようにディレクトリーの中にoldnameをコピーする。
この関数はnewnameを作成するために壊れたシンボリックリンクをフォローしない点を除いて、シンボリックリンクをフォローする。
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コンテキストはコピーされない。
このコマンドはlinknameという名前でtargetにたいするシンボリックリンクを作成する。これはシェルコマンドと‘ln -s target linkname’と似ている。targetは文字列としてのみ扱われる。既存ファイルの名前である必要はない。ok-if-already-existsが整数ならインタラクティブな使用を意味しており、target文字列内の先頭の‘~’は展開されて、先頭の‘/:’は取り除かれる。
targetが相対ファイル名なら結果となるシンボリックリンクはシンボリックリンクを含むディレクトリーにたいして相対的に解釈される。絶対ファイル名と相対ファイル名を参照のこと。
targetとlinknameの両方がリモートファイル構文をもち、かつ両者のリモート識別が等価なら、シンボリックリンクはtargetのローカルファイル名部分を指す。
この関数はシンボリックリンクをサポートしないシステムでは利用できない。
このコマンドはファイルfilenameを削除する。ファイルが複数の名前をもつ場合には他の名前で存在し続ける。filenameがシンボリックリンクならdelete-file
はシンボリックリンクだけを削除してターゲットは削除しない。
ファイルが存在しない、または削除できない場合には適切な種類のfile-error
エラーがシグナルされる(GNU/およびその他のPOSIX準拠システムではファイルのディレクトリーが書き込み可能ならファイルは削除可能)。
オプション引数trashが非nil
、かつ変数delete-by-moving-to-trash
が非nil
なら、このコマンドはファイルを削除するかわりにシステムのTrash(ゴミ箱)にファイルを移動する。Miscellaneous File Operations in The GNU Emacs
Manualを参照のこと。インタラクティブに呼び出された際には、プレフィックス引数がなければtrashはt
、それ以外はnil
。
ディレクトリーの作成・コピー・削除のdelete-directory
も参照のこと。
この関数は、filenameのファイルモード (またはパーミッション)をmodeにセットする。
この関数はデフォルトではシンボリックリンクをフォローする。しかしオプション引数flagがシンボルnofollow
の場合には、filenameがシンボリックリンクでもこの関数はシンボリックリンクをフォローしない。これによりどこか別の場所で意図せずモードビットを変更してしまうことを防げるかもしれない。シンボリックリンクでのモードビット変更をサポートしないプラットフォームでは、この関数はfilenameがシンボリックリンクかつflagがnofollow
の際にエラーをシグナルする。
非インタラクティブに呼び出された場合には、modeは整数でなければならない。その整数の下位12ビットだけが使用される。ほとんどのシステムでは意味があるのは下位9ビットのみ。modeを入力するLisp構文を使用できる。たとえば、
(set-file-modes "myfile" #o644 'nofollow)
これはそのファイルにたいして所有者による読み取りと書き込み、グループメンバーによる読み取り、その他のユーザーによる読み取り可能であることを指定する。モードビットの仕様の説明はFile
permissions in The GNU Coreutils
Manualを参照のこと。
インタラクティブに呼び出されると、modeはread-file-modes
(以下参照)を使用してミニバッファーから読み取られる。この場合にはユーザーは整数、またはパーミッションをシンボルで表現する文字列をタイプできる。
ファイルのパーミッションをリターンする関数file-modes
についてはアクセシビリティのテストを参照のこと。
この関数はEmacsおよびEmacsのサブプロセスが新たに作成するファイルにデフォルトのパーミッションをセットする。Emacsにより作成されたすべてのファイルはこれらのパーミッション、およびそれらのサブセットとなるパーミッションをもつ(デフォルトファイルパーミッションが実行を許可しても、write-region
は実行パーミッションを付与しないだろう)。GNUやその他のPOSIX準拠システムでは、デフォルトのパーミッションは‘umask’の値のビット単位の補数で与えられる。すなわち引数modeでセットされた各ビットはEmacsが作成するファイルのデフォルトパーミッション内ではリセットされる。
引数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(すべてのアクセスが許可されない)がデフォルトになる。
この関数はmodes内の数値ファイルモード指定を等価な文字列形式に変換する。
This function converts a numeric file mode specification in modes into
the equivalent string form.
この関数がリターンする文字列はシェルコマンドのls
-lやfile-attributes
が生成する文字列と同じであり、file-modes-symbolic-to-number
やシェルコマンドのchmod
が受け付けるシンボリックフォーマットとは異なる。
この関数はfilenameのアクセス時刻と変更時刻をtimeにセットする。時刻が正しくセットされればt
、それ以外はnil
がリターン値となる。timeのデフォルトはカレント時刻でありtime値でなければならない(時刻を参照)。
この関数はデフォルトではシンボリックリンクをフォローする。しかしオプション引数flagがシンボルnofollow
の場合には、filenameがシンボリックリンクでもフォローしない。これはどこか別の場所でファイル時刻をうっかり変更してしまうことを防ぐのに役立つかもしれない。シンボリックリンクの時刻変更をサポートしないプラットフォームでは、この関数はfilenameがシンボリックリンクかつflagがnofollow
の際にはエラーをシグナルする。
この関数は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がファイルを変更した後、その後に生じた電源喪失と媒体エラーにより行った変更が保存されないことには2つの理由があります。1つ目は一方または他方のファイルが後で変更されるまで、オペレーティングシステムは書き込まれたデータを2次ストレージのどこかに格納済みのデータにエイリアスすることです。媒体エラーにより2次ストレージ上のコピーだけが失われると、ファイルは両方とも失われるでしょう。2つ目はオペレーティングシステムがデータを2次ストレージに即座に書き込まないかもしれないので、電源喪失時にはデータが失われます。
これらはいずれも適切なファイルシステムの設定により回避され得る類のエラーですが、そのようなシステムは通常はより高価であるか非効率的です。より典型的なシステムでは媒体エラーに備えて異なるデバイスにファイルをコピーでき、電源喪失にたいしては変数write-region-inhibit-fsync
にnil
をセットしてwrite-region
を使用できます。ファイルへの書き込みを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ファイルは一般的に名前で参照され、これはEmacsでも他と同様です。Emacsではファイル名は文字列で表現されます。ファイルを操作する関数はすべてファイル名引数に文字列を期待します。
ファイル自体の操作に加えて、Emacs Lispプログラムでファイル名を処理する必要(ファイル名の一部を取得して関連するファイル名構築にその一部を使用する等)がしばしばあります。このセクションではファイル名を扱う方法を説明します。
このセクションの関数は実際にファイルにアクセスする訳ではないので、既存のファイルやディレクトリーを参照しないファイル名を処理できます。
MS-DOSやMS-Windowsでは、(実際にファイルを操作する関数と同様)これらの関数はMS-DOSとMS-Windowsのファイル名構文を受け入れます。この構文はPOSIX構文のようにバックスラッシュでコンポーネントを区切りますが、これらの関数は常にPOSIX構文をリターンします。これによりPOSIX構文でファイル名を指定するLispプログラムが変更なしですべてのシステムで正しく機能することが可能になります19。
26.9.1 ファイル名の構成要素 | ファイル名のディレクトリー部分と、それ以外。 | |
26.9.2 絶対ファイル名と相対ファイル名 | カレントディレクトリーにたいして相対的なファイル名。 | |
26.9.3 ディレクトリーの名前 | ディレクトリーとしてのディレクトリー名と、ファイルとしてのファイル名の違い。 | |
26.9.4 ファイル名を展開する関数 | 相対ファイル名から絶対ファイル名への変換。 | |
26.9.5 一意なファイル名の生成 | 一時ファイル用の名前の生成。 | |
26.9.6 ファイル名の補完 | 与えられたファイル名にたいする補完を探す。 | |
26.9.7 標準的なファイル名 | パッケージが固定されたファイル名を使用する際に、種々のオペレーティングシステムをシンプルに処理する方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
オペレーティングシステムはファイルをディレクトリーにグループ化します。あるファイルを指定するためには、ディレクトリーとそのディレクトリー内でのファイルの名前を指定しなければなりません。それゆえEmacsはファイル名をディレクトリー名パートと非ディレクトリー(またはディレクトリー内ファイル名)パートという、2つの主要パートから判断します。どちらのパートも空の場合があり得ます。これら2つのパートを結合することによって元のファイル名が再構築されます。20
ほとんどのシステムでは最後のスラッシュ(MS-DOSとMS-Windowsではバックスラッシュも許される)までのすべてがディレクトリーパートです。残りが非ディレクトリーパートです。
ある目的のために、非ディレクトリーパートはさらに正式名称(the name proper)とバージョン番号に細分されます。ほとんどのシステムでは、名前にバージョン番号をもつのはバックアップファイルだけです。
この関数はfilenameのディレクトリーパートをディレクトリー名(ディレクトリーの名前を参照)としてリターンする。filenameがディレクトリーパートを含まなければnil
をリターンする。
GNUや他のPOSIX準拠ixシステムでは、この関数がリターンする文字列は常にスラッシュで終わる。MS-DOSではコロンで終わることもあり得る。
(file-name-directory "lewis/foo") ; GNUの例
⇒ "lewis/"
(file-name-directory "foo") ; GNUの例
⇒ 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が拡張子をもたなければリターン値は""
。
この関数は拡張子にextensionをセットしたfilenameをリターンする。すでにドットがあればextensionの先頭のドットは取り除く。たとえば:
(file-name-with-extension "file" "el") ⇒ "file.el" (file-name-with-extension "file" ".el") ⇒ "file.el" (file-name-with-extension "file.c" "el") ⇒ "file.el"
filenameかextensionが空、あるいはfilenameがディレクトリー(つまりdirectory-name-p
が非nil
をリターンする)のようなら、この関数はエラーとなることに注意。
この関数は、もしあれば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"
この関数はファイル名をコンポーネントに分割する。これを適切なディレクトリー区切りを用いてstring-join
の逆を行う関数とみなすことができる。たとえば、
(file-name-split "/tmp/foo.txt") ⇒ ("" "tmp" "foo.txt") (string-join (file-name-split "/tmp/foo.txt") "/") ⇒ "/tmp/foo.txt"
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ファイルシステム内のすべてのディレクトリーはルートディレクトリーから開始されるツリーを形成します。このツリーのルートから開始されるすべてのディレクトリー名によりファイル名を指定でき、それを絶対(absolute)ファイル名と呼びます。デフォルトディレクトリーからの相対的なツリー中の位置でファイルを指定することもでき、それらは相対(relative)ファイル名と呼ばれます。GNUや他のPOSIX準拠システムでは‘~’で開始されるすべてのファイル名は‘/’で始まる絶対ファイル名(abbreviate-file-nameを参照)に展開されますが、相対ファイル名は展開されません。。MS-DOSとMS-Windowsでは絶対ファイル名はスラッシュ、バックスラッシュ、またはドライブ指定‘x:/’で始まります。ここでxはドライブ文字(drive letter)です。
この関数はファイルfilenameが絶対ファイル名ならt
、それ以外はnil
をリターンする。ファイル名の最初のコンポーネントが‘~’か‘~user’
(userは有効なログイン名)なら絶対ファイル名とみなす。以下の例では‘rms’という名前のユーザーは存在するが、‘nosuchuser’という名前のユーザーは存在しないものとする。
(file-name-absolute-p "~rms/foo") ⇒ t
(file-name-absolute-p "~nosuchuser/foo") ⇒ nil
(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)とは、ある文字列が何らかのファイルを命名する場合にはディレクトリーを命名する文字列のことです。ディレクトリーは実際にはファイルの一種なので、ファイル名(ディレクトリーファイル名と呼ばれる)をもち、これはディレクトリー名と関係はあるものの通常は等価ではありません(これはPOSIXの通常の用語と完全に同一ではない)。同じ実体にたいするこれら2つの異なる名前は構文的な変換により関連付けられます。GNUや他のPOSIXシステムではことは単純です。ディレクトリー名の最後が‘/’でなければ、ディレクトリーファイル名に‘/’を追加してディレクトリー名を取得できます。MS-DOSではこの関連付けはより複雑です。
ディレクトリー名とディレクトリーファイル名の違いは些細ですが重要です。Emacsの変数や関数の引数を記述する際には、それがディレクトリー名であるとしており、ディレクトリーファイル名は許容されません。file-name-directory
が文字列をリターンするときには常にディレクトリー名をリターンします。
以下の2つの関数は、ディレクトリー名とディレクトリーファイル名の間で変換を行います。これらの関数は‘$HOME’のような環境変数や‘~’、‘.’、‘..’などの構文にたいして、特別なことは何も行いません。
この関数はオペレーティングシステムがディレクトリーの名前(ディレクトリー名)と解釈する形式でfilenameを表す文字列をリターンする。これはほとんどのシステムでは、(もし終端にそれがなければ)これは文字列にスラッシュを追加することを意味する。
(file-name-as-directory "~rms/lewis") ⇒ "~rms/lewis/"
この関数はfilenameの終端がディレクトリー区切り文字なら非nil
をリターンする。これはGNUや他のPOSIX準拠システムではスラッシュ‘/’、MS-WindowsとMS-DOSではスラッシュとバックスラッシュ‘\’がディレクトリー区切りとして認識される。
この関数はオペレーティングシステムがファイルの名前と解釈する形式(ディレクトリーファイル名)でdirnameを表す文字列をリターンする。ほとんどのシステムではこれは文字列すべてがディレクトリー区切り文字で構成されている場合を除き、文字列から最後のディレクトリー区切り文字を削除することを意味する。
(directory-file-name "~lewis/") ⇒ "~lewis"
directoryまたは前置されるコンポーネントがスラッシュで終端されていなければコンポーネントの前にスラッシュを挿入して、directoryにcomponentsを結合する。
(file-name-concat "/tmp" "foo") ⇒ "/tmp/foo"
componentsや空文字列のdirectoryやコンポーネントは無視する。これらは最初に除外されて、結果に影響することはない。
この関数はconcat
を使用するのとほとんど同じだが、dirname(と最後のコンポーネント)がスラッシュで終端されているか否かに関わらずスラッシュ文字を2重に連結することはない点が異なる。
ディレクトリー名をディレクトリーの省略名に変換するには以下の関数を使用します:
この関数はfilenameの省略された形式をリターンする。
これはdirectory-abbrev-alist
(File Aliases in The GNU Emacs
Manualを参照)で指定される省略名を適用して、引数で与えられるファイル名ががホームディレクトリーかそのサブディレクトリーにあれば、ユーザーのホームディレクトリーを‘~’に置換する。ホームディレクトリーがルートディレクトリーなの場合には、多くのシステムでは結果が短縮されないので‘~’で置き換えない。
これは名前の一部であるような省略形さえも認識するので、ディレクトリー名とファイル名にも使用できる。
この関数はfilenameの親ディレクトリーのディレクトリー名をリターンする。filenameがソンファイルシステムのルートディレクトリーにある場合にはnil
をリターンする。相対的なfilenameの場合にはdefault-directory
から相対的なディレクトリーとみなし、リターンされる値も相対的なディレクトリー名となる。リターン値が非nil
ならスラッシュで終端される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ファイル名の展開(expanding)と、相対ファイル名を絶対ファイル名に変換することを意味します。これはデフォルトディレクトリーから相対的に行われるため、展開されるファイル名と同様にデフォルトディレクトリーも指定しなければなりません。これは~/のような省略形 (abbreviate-file-nameを参照)、 の展開、および./やname/../のような冗長さの排除も行います。
この関数はfilenameを絶対ファイル名に変換する。directoryが与えられた場合にはfilenameが相対的であり先頭が‘~’でなければ、それが開始点となるデフォルトディレクトリーになる(directoryの値はそれ自体が絶対ディレクトリー名かディレクトリーファイル名であるべきで、それは‘~’で始まるかもしれない)。それ以外ではカレントバッファーの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"
filenameの最初のスラッシュの前が‘~’ならユーザーのホームディレクトリー(通常は環境変数HOME
の値で指定される)に展開される(General
Variables in The GNU Emacs
Manualを参照)。最初のスラッシュの前が‘~user’でuserが有効なログイン名ならuserのホームディレクトリーに展開される。リテラル‘~’で始まるかもしれない相対的なfilenameにたいして展開を望まない場合には(expand-file-name
filename directory)
のかわりに(concat (file-name-as-directory directory)
filename)
を使用できる。
File names containing ‘.’ or ‘..’ are simplified to their canonical form:
(expand-file-name "bar/../foo") ⇒ "/xcssun/users/rms/lewis/foo"
出力に‘..’部分が残り得る場合もある:
(expand-file-name "../home" "/") ⇒ "/../home"
これはルートディレクトリー/の上位のスーパールート(superroot)という概念をもつファイルシステムのためのものである。その他のファイルシステムでは/../は/とまったく同じに解釈される。
.や空文字列を展開するとデフォルトディレクトリーがリターンされる:
(expand-file-name "." "/usr/spool/") ⇒ "/usr/spool" (expand-file-name "" "/usr/spool/") ⇒ "/usr/spool"
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/は破棄された
ファイル名の展開が望ましくない場合もあります。そのような場合には展開を抑制するためにファイル名をクォートしてファイル名をそのままリテラルとして処理することができます。ファイル名の前に‘/:’を前置することによりクォートが行われます。
このマクロはファイルnameにクォーテーションプレフィクス‘/:’を付加する。ローカルファイルnameにはnameの前にプレフィクス‘/:’を付加する。nameがリモートファイル名ならnameのローカル部分がクォートされる(特定のファイル名の“Magic”の作成を参照)。nameがクォート済みのファイル名なら、nameは変更せずにリターンする。
(substitute-in-file-name (file-name-quote "bar/~/foo")) ⇒ "/:bar/~/foo"
(substitute-in-file-name (file-name-quote "/ssh:host:bar/~/foo")) ⇒ "/ssh:host:/:bar/~/foo"
マジックファイル名によるファイル名ハンドラーを抑制するためにこのマクロは使用できない(特定のファイル名の“Magic”の作成を参照)。
このマクロはファイルnameにクォーテーションプレフィクス‘/:’があれば削除する。nameがリモートファイル名ならnameのローカル部分を非クォート化する。
このマクロはnameがプレフィクス‘/:’でクォートされていれば非nil
をリターンする。nameがリモートファイル名ならnameのローカル部分をチェックする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
一時ファイルに書き込む必要があるプログラムがいくつかあります。以下は、そのようなファイルを構築する便利な方法です:
(make-temp-file name-of-application)
make-temp-file
の役目は、2人の異なるユーザーやジョブが完全に一致する名前のファイルの使用を防ぐことです。
この関数は一時ファイルを作成して、その名前をリターンする。EmacsはEmacsの各ジョブごとに異なるランダムないくつかの文字をprefixに追加することにより一時ファイルの名前を作成する。結果として文字列としてtextが与えられた場合にはそれを含むファイル、それ以外は空ファイルが新たに作成されることが保障される。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
はそれをファイル名の最後に追加する。
textが文字列なら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はマジックファイル名ではない絶対ファイル名であること、(iii)リターンされるファイル名がマジックファイル名なら既存のファイルかもしれない、という点が異なる(MS-DOSシステムでは8+3ファイル名制限に適合するようにbase-nameが切り詰められる)。
警告: この関数を使用するべきではない。かわりにmake-temp-file
を使用すること!
この関数は競合状態の影響を受けやすい。make-temp-name
呼び出しと一時ファイル作成のタイムラグはセキュリティーホールとなり得る。
リモートホストやマウントされたディレクトリーで一時ファイルの作成を要する場合があります。以下の2つの関数はそれをサポートします。
この関数はmake-temp-file
と同様だができ得るかぎりdefault-directory
に近接した一時ファイルを作成する点が異なる。prefixが相対ファイル名でdefault-directory
がリモートファイル名かマウントされたファイルシステムに配置されていれば、一時ファイルは関数temporary-file-directory
がリターンするディレクトリー内に作成される。それ以外なら関数make-temp-file
を使用する。prefix、dir-flag、suffixの意味はmake-temp-file
の場合と同様。
(let ((default-directory "/ssh:remotehost:")) (make-nearby-temp-file "foo")) ⇒ "/ssh:remotehost:/tmp/foo232J6v"
make-nearby-temp-file
を通じて一時ファイルを書き込むディレクトリー。default-directory
がリモートの場合にはリモートホスト上の一時ファイル用のディレクトリー。そのようなディレクトリーが存在しない、またはdefault-directory
がマウントされるファイルシステム上に配置される場合(mounted-file-systems
を参照)には、この関数はdefault-directory
をリターンする。リモートでもマウントされたファイルシステムでもないdefault-directory
ではtemporary-file-directory
の値がリターンされる。
一時ファイルのファイル名のローカル部分を抽出するためにはfile-local-name
を使用してください(特定のファイル名の“Magic”の作成を参照)。
[ << ] | [ < ] | [ 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
で指定されるディレクトリーに配置されて、
デフォルトでは通常は~/.config/emacs/か~/.emacs.d/です(How
Emacs Finds Your Init File in The GNU Emacs
Manualを参照)。たとえばabbrev(abbreviation:
省略形)の定義は、デフォルトでは~/.config/emacs/abbrev_defsか~/.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や他のPOSIX準拠システムでは単に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
はリストをソートしないので、取得するファイル名に特定の順序はない。最大限の可能なスピードを得る必要がありファイル処理順を気にしなければこれを使用する。ユーザーから処理順が可視なら、名前をソートすれば多分ユーザーはより幸せになるだろう。
countが非nil
なら最初のcount個のファイル名、またはすべてのファイル名のいずれか早いほうをリターンする。countは0より大な整数であること。
(directory-files "~lewis") ⇒ ("#foo#" "#foo.el#" "." ".." "dired-mods.el" "files-ja.texi" "files-ja.texi.~1~")
directoryが読み取り可能なディレクトリー名でなければエラーがシグナルされる。
このユーティリティー関数は与えられたdirectoryがアクセス可能なディレクトリーかつ何のファイルも含まない(空ディレクトリー)場合にはt
をリターンする。ディレクトリー内のファイルとして‘.’や‘..’をリターンするシステムでは、それらは無視される。
ディレクトリーへのシンボリックリンクはディレクトリーとみなされる。シンボリックリンクと区別する方法についてはfile-symlink-pを参照のこと。
regexpにマッチする名前をもつdirectory配下のすべてのファイルをリターンする。この関数はベースネーム(basename:
先行するディレクトリー部分を除外したファイル名)がregexpにマッチするファイルを、directoryとそのサブディレクトリーを再帰的に検索して、マッチしたファイルの絶対ファイル名(absolute file
namesを参照)のリストをリターンする。ファイル名は深さ優先順でリターンされ、それは親ディレクトリーの前に任意のサブディレクトリー内のファイルが配置されることを意味する。加えて各ディレクトリー内で見つかったファイルはベースネームにもとづいてソートされる。デフォルトではregexpにマッチする名前のディレクトリーはリストから省略されるが、オプション引数include-directoriesが非nil
ならそれらも含まれる。
デフォルトではすべてのサブディレクトリーが含まれる。predicateがt
ならサブディレクトリーを含める際のエラー(たとえばそのユーザーでは読み取り不可の場合)は無視される。nil
やt
以外なら、1つのパラメーター(サブディレクトリー名)を受け取り、そのディレクトリーを含める場合には非nil
をリターンする関数であること。
デフォルトではサブディレクトリーへのシンボリックリンクはフォローしないが、follow-symlinksが非nil
ならフォローする。
fileから開始してディレクトリーツリー階層を上方にname
(文字列)というディレクトリーを検索して、最初に見つけたディレクトリーをリターンする。fileがファイルならファイルのディレクトリーが検索の開始位置、それ以外ならfileは検索を開始するディレクトリーであること。この関数は開始ディレクトリーを調べて、それからその親ディレクトリー、更にその親ディレクトリー、...のようにnameというディレクトリーを見つけるか、あるいはnameが見つけることなくファイルシステムのロートディレクトリーに到達するまで検索を行う。後者の場合にはnil
をリターンする。
引数name
は述語関数でもよい。この述語は関数により検査される、file
(fileがディレクトリーでない場合でも)から開始されるすべてのディレクトリーにたいして呼び出される。この述語は1つの引数(ファイルかディレクトリー)で呼び出されて、それが検索しているディレクトリーなら非nil
をリターンすること。
この関数は、fileがディレクトリーdir内のファイルかサブディレクトリーならt
をリターンする。またfileとdirが同じディレクトリーの場合もt
をリターンする。この関数は2つのディレクトリーの実名を比較する。dirが既存のディレクトリーの名前でなければリターン値はnil
。
これはどのファイルを報告するか、およびファイル名を報告する方法においてdirectory-files
と似ている。しかしこの関数はファイル名のリストをリターンするかわりに、各ファイルごとにリスト(filename
.
attributes)
をリターンする。ここでattributesは、そのファイルにたいしてfile-attributes
がリターンする値。オプション引数id-formatは、file-attributes
の対応する引数と同じ意味をもつ(Definition of file-attributesを参照)。
この正規表現は‘.’と‘..’を除いたすべてのファイル名にマッチする。より正確にはこれら2つを除いたすべての空文字列以外の部分にマッチする。これはdirectory-files
およびdirectory-files-and-attributes
のmatch-regexp引数として有用。
(directory-files "/foo" nil directory-files-no-dot-files-regexp)
ディレクトリー‘/foo’が空ならnil
をリターンする。
この関数はワイルドカードパターンpatternを展開して、それにマッチするファイル名のリストをリターンする。
patternはデフォルトでは‘"/tmp/*.png"’や‘"/*/*/foo.png"’のような“glob”あるいはワイルドカード文字列だが、オプションのregexpパラメーターが非nil
なら正規表現でもよい。いずれの場合でもマッチが親ディレクトリーとサブディレクトリーにまたがらないように、サブディレクトリーごとに適用される。
絶対ファイル名として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
)には、その親ディレクトリーがまだ存在しなければ最初にそれを作成することを意味する。関数としてのmake-directory
はdirnameがディレクトリーとして既に存在していてparentsが非nil
なら非nil
、dirnameを成功裏に作成できたらnil
をリターンする。mkdir
はこのコマンドにたいするエイリアス。
このコマンドはfilenameという名前の空のファイルを作成する。このコマンドはmake-directory
と同様に、parentsが非filenameがすでに存在する場合には、このコマンドはエラーをシグナルする。
このコマンドは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
はエラーをシグナルする。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ファイル名ハンドラーが処理する操作です:
abbreviate-file-name
、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
、exec-path
、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-locked-p
、file-modes
、file-name-all-completions
、file-name-as-directory
、file-name-case-insensitive-p
、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-system-info
、file-truename
、file-writable-p
、find-backup-file-name
、
get-file-buffer
、insert-directory
、insert-file-contents
、
list-system-processes
、load
、lock-file
、make-auto-save-file-name
、make-directory
、make-lock-file-name
、make-nearby-temp-file
、make-process
、make-symbolic-link
、
memory-info
、process-attributes
、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
、
temporary-file-directory
、unhandled-file-name-directory
、unlock-file
、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ディレクトリーをもたなければならず、この関数はそれを導出するよい手段である。
この関数はfilenameのローカル部分(local part)をリターンする。これはリモートホスト上でファイル名を識別する部分であり、通常はリモートファイル名からリモートホストを指定する部分とアクセス方法を取り除いた部分である。たとえば:
(file-local-name "/ssh:user@host:/foo/bar") ⇒ "/foo/bar"
この関数はリモートのfilenameにたいして、リモートプロセス(非同期プロセスの作成と同期プロセスの作成を参照)やリモートホスト上で実行されるプログラムの引数として直接使用可能なファイル名をリターンする。filenameがローカルなら、この関数はそれを変更せずにリターンする。
リモートファイルの属性は、よりよいパフォーマンスのためにキャッシュすることができる。キャッシュが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 (file-attribute-size (file-attributes (file-chase-links file)))))))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはバッファー内のデータ(テキスト、テキストプロパティ、あるいはその他の情報)とファイルへの格納に適した表現との間で双方向の変換をするために複数のステップを処理します。このセクションでは、このフォーマット変換(format
conversion)を行う基本的な関数、すなわちファイルをバッファーに読み込むinsert-file-contents
と、バッファーをファイルに書き込むwrite-region
を説明します。
26.13.1 概要 | insert-file-contents とwrite-region
| |
26.13.2 ラウンドトリップ仕様 | format-alist の使用。
| |
26.13.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つである。そうでないとおそらく再度変換が呼び出される。さらにfrom-fnはデコードされるバッファーやバッファーではないこと。さもなければフォーマット用の内部バッファーが上書きされるかもしれない。
このフォーマットのデータをエンコード、すなわち通常のEmacsデータ表現をこのフォーマットに変換するためのシェルコマンドか関数。
to-fnが文字列ならそれはシェルコマンドである。Emacsは変換処理のためのフィルターとしてこのコマンドを実行する。
to-fnが関数なら、それは3つの引数で呼び出される。beginとendは変換されるべきバッファー部分、bufferでそれがどのバッファーかを指定する。変換を行うには2つの方法がある:
(position
.
string)
という形式の要素をもつリストで、positionは書き込まれるテキスト内での相対位置を指定する整数、stringはそこに追加される注釈である。このリストはto-fnがそれをリターンする際には、位置順でソートされていなければならない。
write-region
が実際にバッファーからファイルにテキストを書き込む際には、指定された注釈を対応する位置に混合する。これはすべてバッファーを変更せずに行われる。
from-fnはデコードされるバッファーやバッファーではないこと。さもなければフォーマット用の内部バッファーが上書きされるかもしれない。
フラグ。エンコード関数がバッファーを変更するなら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)はカレントの編集セッションを開始した以降のテキストを保存します。一方バックアップファイルはカレントセッションの前のファイルコンテンツを保存します。
27.1 ファイルのバックアップ | バックアップファイルの作成と名前選択の方法。 | |
27.2 自動保存 | auto-saveファイルの作成と名前選択の方法。 | |
27.3 リバート | revert-buffer とその動作のカスタマイズ方法。
|
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バックアップファイル(backup file)とは編集中ファイルの古いコンテンツのコピーです。Emacsはvisitされているファイルにバッファーを最初に保存するときにバックアップファイルを作成します。したがってバックアップファイルには、通常はカレント編集セッションの前にあったファイルのコンテンツが含まれています。バックアップファイルを一度存在したら、そのコンテンツは変更されずに残ります。
バックアップは通常はvisitされているファイルを新たな名前にリネームすることによって作成されます。オプションでバックアップファイルがvisitされているファイルをコピーすることにより作成されるように指定できます。この選択により、複数の名前をもつファイルの場合に違いが生じます。また編集中のファイルの所有者が元のオーナーのままか、それとも編集ユーザーになるかにも影響し得ます。
デフォルトではEmacsは編集中のファイルごとに単一のバックアップファイルを作成します。かわりに番号付きバックアップ(numbered backup)を要求することもできます。その場合には新たなバックアップファイルそれぞれが新たな名前を得ます。必要なくなったときには古い番号付きバックアップを削除したり、Emacsにそれらを自動的に削除させることもできます。
性能的な理由によりオペレーティングシステムはバックアップファイルのコンテンツを二次ストレージに即座に書き込まないかもしれず、オリジナルデータとバックアップデータのいずれかが変更されるまでバックアップデータをエイリアスするかもしれません。ファイルと二次媒体を参照してください。
27.1.1 バックアップファイルの作成 | Emacsがバックアップファイルを作成する方法とタイミング。 | |
27.1.2 リネームかコピーのどちらでバックアップするか? | 2つの選択肢: 古いファイルのリネームとコピー。 | |
27.1.3 番号つきバックアップファイルの作成と削除 | ソースファイルごとに複数のバックアップを保持する。 | |
27.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の値(具体的には特定の値以下のID数値)にたいしてのみ、backup-by-copying-when-mismatch
と同じように振る舞うことを指定する。変数にはその数値をセットする。
したがってファイル所有者の変更を防ぐ必要がある際には、backup-by-copying-when-privileged-mismatch
を0にセットすればスーパーユーザーとグループ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-ja.texi") ⇒ ".backups-ja.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
をリターンする。ファイルは更新日時(modification
time)にたいして降順でソートされるので、もっとも最近に更新されたファイルが最初になる。
この関数はfile-backup-file-names
がリターンするリストの最初の要素をリターンする。
ファイル比較関数のいくつかは、自動的にもっとも最近のバックアップを比較できるようにこの関数を使用している。
[ << ] | [ < ] | [ 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-ja.texi#"
これはバッファーローカルなマイナーモードであるAuto Saveモードにたいするモードコマンド。Auto Saveモードが有効なときはそのバッファーで自動保存が有効。呼び出し方法は他のマイナーモードと同様(マイナーモード記述の規約を参照)。
ほとんどのマイナーモードと異なりauto-save-mode
変数は存在しない。buffer-auto-save-file-name
が非nil
でbuffer-saved-size
(以下参照)が非0ならAuto
Saveモードが有効。
この変数はバッファーにたいしてauto-saveファイル名を作成する前にバッファーのファイル名に適用する変換(transform)をリストする。
この変換はそれぞれ(regexp replacement [uniquify])
という形式のリスト。regexpはファイル名にたいしてマッチを行う正規表現であり、マッチしたらマッチ部分をreplacementで置き換えるためにreplace-match
が使用される。オプション要素uniquifyが非nil
なら、クラッシュを回避するために変換ファイルのディレクトリー部分(クラッシュ回避のためにディレクトリー区切り文字はすべて‘!’に変更)とバッファーのファイル名を結合してauto-saveファイル名を構築する(ファイルシステムが結果となるファイルを切り詰める場合には正しく機能しないだろう)。
uniquifyがsecure-hash-algorithms
のメンバーのいずれかなら、バッファーのファイル名にsecure-hash
を適用することによって、Emacsはauto-saveファイルのディレクトリー部分以外を構築する。これは極端に長いファイル名というリスクを回避する。
リストにあるすべての変換をリスト順に試行する。いずれかの変換が適用されたらそれが最終結果となり、それ以上の変換は試みられない。
デフォルト値ではリモートファイルのauto-saveファイルは一時ディレクトリーに置くようセットアップされている(一意なファイル名の生成を参照)。
長いファイル名がないMS-DOSファイルシステムでは、この変数は常に無視される。
この関数はfilenameがauto-saveファイルのような文字列なら非nil
をリターンする。先頭と末尾がハッシュマーク(‘#’)であるような名前はauto-saveファイルの可能性があるという、auto-saveファイルにたいする通常の命名規則を想定する。引数filenameはディレクトリーパートを含まないこと。
(make-auto-save-file-name) ⇒ "/xcssun/users/rms/lewis/#backups-ja.texi#"
(auto-save-file-name-p "#backups-ja.texi#") ⇒ 0
(auto-save-file-name-p "backups-ja.texi") ⇒ nil
この関数はカレントバッファーの自動保存に使用されるファイル名をリターンする。これはファイル名の先頭と末尾にハッシュマーク(‘#’)を単に追加する。この関数は変数auto-save-visited-file-name
(以下参照)を調べない。呼び出し側はまずその変数をチェックすること。
(make-auto-save-file-name) ⇒ "/xcssun/users/rms/lewis/#backups-ja.texi#"
この変数が非nil
ならEmacsはvisit中のファイルにバッファーを自動保存する。つまり自動保存は編集中ファイルと同じファイルにたいして行われる。この変数は通常はnil
なので、auto-saveファイルはmake-auto-save-file-name
で作成された別の名前をもつ。
この変数の値を変更した際、バッファー内でauto-saveモードを再度有効にするまで、既存バッファーにたいして新たな値は効果をもたない。すでにauto-saveモードが有効なら、再度auto-save-mode
が呼び出されるまで同じファイルに自動保存が行われる。
この変数を非nil
にセットしても自動保存とバッファーの保存は異なるという事実は変わらないことに注意(バッファーの保存で説明したフックはバッファーが自動保存された際には実行されない)。
この関数はカレントバッファーが最後に読み込み、または保存されて以降に自動保存されていれば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-function
の個別の実装次第である。
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
は、このフックを実行するかどうか判らない。
Emacsはバッファーを自動的にリバートできます。これはファイルをvisitしているバッファーにはデフォルトで行われます。以下では新たなタイプのバッファーにたいして自動リバートのサポートを追加する方法を説明します。
そのようなバッファーはまず適切に定義されたrevert-buffer-function
とbuffer-stale-function
をもたなければなりません。
この変数の値はバッファーがリバートを要するかどうかをチェックするために呼び出される関数を指定する。デフォルト値では、修正時刻をチェックすることによりファイルをvisitするバッファーだけを処理する。ファイルをvisitしないバッファーにはオプション引数を1つ受け取るカスタム関数が必要になる。この関数はバッファーをリバートする必要があれば非nil
をリターンする。関数の呼び出し時にはそのバッファーがカレントになる。
この関数は主として自動リバートを意図しているが、他の用途にも使用できる。たとえば自動リバートが有効でなければ、ユーザーにバッファーのリバートが必要なバッファーを警告するために使用できる。noconfirm引数の背景にあるアイデアは、ユーザーへの確認なしでバッファーがリバートされるようならt
、関数がバッファーの期限切れをユーザーに警告する。特に自動リバートにおける使用ではnoconfirmはt
になる。関数が自動リバートにたいしてのみ使用されるようならnoconfirm引数は無視できる。
(Buffer Menuのように) auto-revert-interval
秒ごとに自動リバートをしたければバッファーのモード関数で:
(setq-local buffer-stale-function (lambda (&optional noconfirm) 'fast))
を使用する。
特別なリターン値‘fast’はリバートの必要性はチェックしていないがバッファーのリバートは高速であることを告げる。さらにauto-revert-verbose
が非nil
でもリバートメッセージを何もプリントしないようにAuto
Revertに指示する。auto-revert-interval
秒ごとのリバートメッセージが非常に煩雑になり得ることから、これは重要である。自動リバート以外の目的でこの関数が考慮される場合には、リターン値が提供する情報は有用になるかもしれない。
バッファーが適切なrevert-buffer-function
とbuffer-stale-function
をもった後にも、通常はいくつかの問題が残ります。
未変更とマークされた場合のみバッファーは自動リバートされます。したがって種々の関数はリバートにより失われるかもしれない情報をバッファーが含む場合や、ユーザーがバッファーにたいして作業を行っていて自動リバートがユーザーにとって不便だと確信できる理由がある場合にのみバッファーを変更済みとマークすることを保証する必要があるでしょう。バッファーの変更状態を手動で調整することによりユーザーは常にこれをオーバーライドできます。これをサポートするために、未変更とマークされたバッファーでのrevert-buffer-function
呼び出しでは、常にバッファーの未変更とマークされた状態を保つ必要があります。
自動リバートの結果としてその前後で連続してポイントがジャンプしないことを保証することが重要です。もちろんバッファーが根本的に変更されればポイントの移動は必然的かもしれません。
revert-buffer-function
がauto-revert-verbose
がt
の場合に表示されるAuto
Revert自身のメッセージを不必要に重複してプリントしないことと、auto-revert-verbose
にたいするnil
値を効果的にオーバーライドすることを保証する必要があります。したがって自動リバートにたいするモードの調整には、このようなメッセージを取り除くことを要する場合が多々あります。とりわけこれはauto-revert-interval
秒ごとに自動的にリバートされるバッファーにおいて重要です。
新しい自動リバートがEmacsの一部であるなら、global-auto-revert-non-file-buffers
のドキュメント文字列でそれに言及するべきです。
同様にEmacsマニュアル内に追加でドキュメントするべきです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファー(buffer)とは編集されるテキストを含んだLispオブジェクトのことです。バッファーはvisitされるファイルのコンテンツを保持するために使用されます。しかしファイルをvisitしないバッファーも存在します。一度に複数のバッファーが存在するかもしれませんが、カレントバッファー(current buffer)に指定できるのは常に1つのバッファーだけです。ほとんどの編集コマンドはカレントバッファーのコンテンツにたいして作用します。カレントバッファーを含むすべてのバッファーは任意のウィンドウ内に表示されるときもあれば、表示されない場合もあります。
28.1 バッファーの基礎 | バッファーとは? | |
28.2 カレントバッファー | バッファーをカレントに指定することにより、プリミティブはバッファーのコンテンツにアクセスする。 | |
28.3 バッファーの名前 | バッファー名にたいするアクセスと変更。 | |
28.4 バッファーのファイル名 | バッファーファイル名は、どのファイルをvisitしているかを示す。 | |
28.5 バッファーの変更 | 保存が必要ならバッファーは変更されている(modified)。 | |
28.6 バッファーの変更時刻 | Emacsの背後でvisitされているファイルが変更されたかどうかを判断する。 | |
28.7 読み取り専用のバッファー | 読み取り専用バッファーでのテキスト変更は許されない。 | |
28.8 バッファーリスト | すべての既存バッファーを閲覧する方法。 | |
28.9 バッファーの作成 | バッファーを作成する関数。 | |
28.10 バッファーのkill | 明示的にkillされるまで、バッファーは存在する。 | |
28.11 インダイレクトバッファー | インダイレクトバッファーは他のバッファーとテキストを共有する。 | |
28.12 2つのバッファー間でのテキストの交換 | ||
28.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-ja.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で有効にできる)。また一時バッファーはkill-buffer-hook
、kill-buffer-query-functions
(バッファーのkillを参照)、buffer-list-update-hook
(バッファーリストを参照)のフックも実行しない。
リターン値は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-ja.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-ja.texi"
このバッファーローカル変数はカレントバッファーにvisitされているファイルの名前、ファイルをvisitしていなければnil
。これは永続的なローカル変数でありkill-all-local-variables
の影響を受けない。
buffer-file-name ⇒ "/usr/user/lewis/manual/buffers-ja.texi"
他のさまざまな事項を変更せずにこの変数を変更するのは危険である。通常はset-visited-file-name
を使用するほうがよい(以下参照)。バッファー名の変更などのような、そこで行われることのいくつかは絶対必要という訳ではないが、その他の事項はEmacsが混乱するのを防ぐために必要不可欠である。
このバッファーローカル変数はカレントバッファーにvisitされているファイルの省略された形式の実名(truename)、ファイルをvisitしていなければnil
を保持する。これは永続的にローカルでありkill-all-local-variables
の影響を受けない。See 本当の名前とabbreviate-file-nameを参照のこと。
このバッファーローカル変数はカレントバッファーにvisitされているファイルのinode番号とディレクトリーデバイス識別子、ファイルをvisitしていなければnil
を保持する。これは永続的にローカルでありkill-all-local-variables
の影響を受けない。
値は通常は(inodenum device)
のような形式のリスト。このタプル(tuple:
組)はシステム上でアクセス可能なすべてのファイルの中からファイルを一意に識別する。より詳細な情報はファイルの属性のfile-attributes
を参照のこと。
buffer-file-name
がシンボリックリンク名なら、inodenumとdeviceの両方がリンクのターゲットを再帰的に参照する。
この関数はファイルfilenameをvisitしているバッファーをリターンする。そのようなバッファーが存在しなければnil
をリターンする。引数filenameは文字列でなければならず、展開(ファイル名を展開する関数を参照)された後に、killされていないすべてのバッファーがvisitしているファイル名と比較される。バッファーのbuffer-file-name
はfilenameの展開形と正確にマッチしなければならないことに注意。この関数は同じファイルにたいする他の名前は認識しないだろう。
(get-file-buffer "buffers-ja.texi") ⇒ #<buffer buffers-ja.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
が報告する時刻(バッファーの変更時刻を参照)で変更することもしない。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が最後に読み込まれた、あるいは保存されて以降に変更されていれば非nil
、そうでなければnil
をリターンする。bufferが最後に変更されて以降に自動保存されていれば、この関数はシンボルautosaved
をリターンする。bufferがbufferか省略の際のデフォルトはカレントバッファー。
この関数はflagが非nil
ならカレントバッファーを変更済みとして、nil
なら未変更としてマークする。
この関数を呼び出すことによる別の効果は、それがカレントバッファーのモードラインの無条件な再表示を引き起こすことである。実際のところ関数force-mode-line-update
は以下を行うことにより機能する:
(set-buffer-modified-p (buffer-modified-p))
set-buffer-modified-p
と同様だがモードラインの再表示を強制しない。この関数のflagの値にシンボルautosaved
も指定できる。これによりバッファーは変更されていること、そして最後に変更された後にauto-saveされているものとしてマークされる。
このコマンドはカレントバッファーが変更されておらず保存する必要がないとマークする。argが非nil
なら変更されているとマークするので、次回の適切なタイミングでバッファーは保存されるだろう。interactiveに呼び出された場合には、argはプレフィックス引数。
この関数はエコーエリア内にメッセージをプリントするのでプログラム内で使用してはならない。かわりにset-buffer-modified-p
(上述)を使用すること。
この関数はbufferの変更カウント(modification-count)をリターンする。これはバッファーが変更されるたびに増加されるカウンター。bufferがnil
(または省略)ならカレントバッファーが使用される。
この関数はbufferの文字変更に関わる変更カウントをリターンする。テキストプロパティを変更してもこのカウンターは変化しない。しかしそのバッファーにテキストが挿入または削除されるたびに、このカウンターはbuffer-modified-tick
によりリターンされるであろう値にリセットされる。buffer-chars-modified-tick
を2回呼び出してリターンされる値を比較することにより、その呼び出しの間にバッファー内で文字変更があったかどうかを知ることができる。bufferがnil
(または省略)ならカレントバッファーが使用される。
テキストプロパティの変更の等、バッファーのテキストを実際には変更しない方法でバッファーを変更することを要する場合があります。プログラムがフックやバッファー変更にたいするリアクションを何もトリガーせずにバッファーを変更する必要がある場合には、with-silent-modifications
マクロを使用します。
バッファーを変更しないように装ってbodyを実行する。これにはバッファーのファイルがロックされているかどうかのチェック(ファイルのロックを参照)、バッファーの変更フック(フックの変更を参照)等が含まれる。(バッファーのテキストプロパティとは対照的に)bodyが実際にバッファーテキストを変更する場合にはアンドゥするデータが破損するかもしれないことに注意。
[ << ] | [ < ] | [ 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
、および変更済みファイルの上書きを防ぐための通常テストを行わない例外的な箇所で呼び出される。
この関数はカレントバッファーにたいして記録された最終ファイル変更時刻をLispタイムスタンプ(時刻を参照)としてリターンする。
バッファーが最終変更時刻の記録をもたなければこの関数は0をリターンする。これが発生するのは、たとえばバッファーがファイルをvisitしていなかったり、clear-visited-file-modtime
で最終変更時刻が明示的にクリアーされた場合。しかしvisited-file-modtime
は、いくつかの非ファイルバッファーにたいするタイムスタンプをリターンすることに注意。たとえばディレクトリーをリストするDiredバッファーでは、Diredが記録するそのディレクトリーの最終変更時刻がリターンされる。
バッファーが存在しないファイルをvisitしている場合には、この関数は-1をリターンする。
この関数はバッファーがvisitしているファイルの最終変更時刻の記録を、timeが非nil
ならtime、それ以外はvisitしているファイルの最終変更時刻に更新する。
timeがnil
やvisited-file-modtime
がリターンする整数フラグでなければ、それはLispのtime値であること(時刻を参照)。
この関数はバッファーが通常のようにファイルから読み取られたものでない場合や、ファイル自身が害のない既知の理由により変更されている場合に有用。
これは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-ja.texi> #<buffer *Minibuf-1*> #<buffer buffer.c> #<buffer *Help*> #<buffer TAGS>)
;; ミニバッファーの名前が ;; スペースで始まることに注意! (mapcar #'buffer-name (buffer-list)) ⇒ ("buffers-ja.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 専用のウィンドウ)であり、かつそのフレーム上に他のウィンドウが存在する場合には専用ウィンドウは削除される。それがフレーム上で唯一のウィンドウであり、かつそのフレームが端末上で唯一のフレームでなければ、そのフレームは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
(ウィンドウの選択を参照)。このフックはget-buffer-create
やgenerate-new-buffer
でinhibit-buffer-hooks引数に非nil
を指定して作成した内部バッファーや一時バッファーには実行されない。
このフックが実行する関数は無限再帰を引き起こすので、nil
のnorecord引数によるselect-window
の呼び出しは避けること。
この関数はbuffer-or-name
で指定されたバッファーがcondition
の指定を満足するかチェックする。3つ目のオプション引数argはconditionの述語関数に渡される。有効なcondition
は以下のいずれか:
nil
をリターンすること。1つの引数を期待する関数の場合は引数としてbuffer-or-name、2つの引数を期待する関数の場合には1つ目の引数がbuffer-or-name、2つ目の引数がarg(argの省略時はnil
)で呼び出される。
(oper . expr)
。operは以下のいずれか
(not cond)
そのバッファーとarg
ではbuffer-match-p
が偽となるようなcondなら真。
(or conds…)
conds内のいずれかの条件にたいして、そのバッファーとarg
ならばbuffer-match-p
が真になれば真。
(and conds…)
conds内のすべての条件にたいして、そのバッファーとarg
ならばbuffer-match-p
が真になれば真。
derived-mode
そのバッファーのメジャーモードがexprを継承していれば真。
major-mode
そのバッファーのメジャーモードがexprなら真。どちらでも機能するのならderived-mode
の使用を推奨する。
""
(空文字列)、(and)
(empty conjunction: 空論理積)を使いやすくした代替え。
この関数はcondition
を満たすすべてのバッファーのリスト、マッチするバッファーがなければnil
をリターンする。引数conditionは上述のbuffer-match-p
と同様に定義される。デフォルトではすべてのバッファーを考慮するが、オプション引数buffer-list
(考慮すべきバッファーのリスト)を通じて制限できる。オプションの3つ目の引数argは、buffer-match-p
と同じ方法によってconditionに渡される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではバッファーを作成する2つのプリミティブについて説明します。get-buffer-create
は指定された名前の既存バッファーが見つからなければ作成します。generate-new-buffer
は常に新たにバッファーを作成してそれに一意な名前を与えます。
どちらの関数もオプション引数inhibit-buffer-hooksを受け取ります。これが非nil
なら、これらの関数が作成したバッファーはkill-buffer-hook
、kill-buffer-query-functions
(バッファーのkillを参照)、buffer-list-update-hook
(バッファーリストを参照)のフックを実行しません。これはユーザーに提示されたり他のアプリケーションに渡されることが決してない、内部バッファーや一時バッファーの速度低下を避けるためです。
バッファーを作成するために使用できる他の関数には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
はそのバッファーを殺さない。
このフックは非nil
のinhibit-buffer-hooks引数のget-buffer-create
またはgenerate-new-buffer
で作成された内部バッファーや一時バッファーにたいしては実行されない。
これは尋ねることになっている質問をすべて終えた後、実際にバッファーをkillする直前にkill-buffer
により実行されるノーマルフック。この変数は永続的にローカルであり、メジャーモードの変更により、そのローカルバインディングはクリアーされない。
このフックは非nil
のinhibit-buffer-hooks引数のget-buffer-create
またはgenerate-new-buffer
で作成された内部バッファーや一時バッファーにたいしては実行されない。
特定のバッファーにおいてこの変数が非nil
なら、あたかもファイルをvisitするバッファーにたいして提案するときのように、バッファーの保存を提案するようにsave-buffers-kill-emacs
に指示する。2つ目のオプション引数をt
にセットしてsave-some-buffers
を呼び出せばバッファーの保存も提案する。最後にこの変数をシンボルalways
にセットすると、save-buffers-kill-emacs
とsave-some-buffers
は常に保存を提案する。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ではなく実際のベースバッファーからコピーされる。
inhibit-buffer-hooksの意味についてはバッファーの作成を参照のこと。
この関数はカレントバッファーのベースバッファーを共有するインダイレクトバッファーを新たに作成して、カレントバッファーの残りの属性をコピーしてリターンする(カレントバッファーがインダイレクトバッファーでなければそれがベースバッファーとして使用される)。
display-flagが非nil
(インタラクティブな呼び出しでは常に非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のディスプレイ表示を参照してください。
29.1 Emacsウィンドウの基本概念 | ウィンドウ使用についての基本情報。 | |
29.2 ウィンドウとフレーム | ウィンドウとそれらが表示されるフレームとの関連。 | |
29.3 ウィンドウの選択 | 選択されたウィンドウとは編集を行っているウィンドウである。 | |
29.4 ウィンドウのサイズ | ウィンドウのサイズへのアクセス。 | |
29.5 ウィンドウのリサイズ | ウィンドウのサイズの変更。 | |
29.6 ウィンドウサイズの保持 | ウィンドウのサイズ維持。 | |
29.7 ウィンドウの分割 | 新たなウィンドウの作成。 | |
29.8 ウィンドウの削除 | フレームからのウィンドウの削除。 | |
29.9 ウィンドウの再結合 | ウィンドウの分割や削除時のフレームレイアウトの保存。 | |
29.10 ウィンドウのサイクル順 | 既存のウィンドウ間の移動。 | |
29.11 バッファーとウィンドウ | それぞれのウィンドウはバッファーのコンテンツを表示する。 | |
29.12 ウィンドウ内のバッファーへの切り替え | バッファー切り替えのためのより高レベルな関数。 | |
29.13 適切なウィンドウへのバッファーの表示 | 適切なウィンドウでのバッファーの表示。 | |
29.14 ウィンドウのヒストリー | それぞれのウィンドウは表示されていたバッファーを記憶する。 | |
29.15 専用のウィンドウ | 特定のウィンドウ内で他のバッファーの表示を無効にする。 | |
29.16 ウィンドウのquit | 以前に表示していたバッファーの状態をリストアする方法。 | |
29.17 サイドウィンドウ | フレーム側端の特別なウィンドウ。 | |
29.18 アトミックウィンドウ | ウィンドウレイアウトの一部を保存する。 | |
29.19 ウィンドウとポイント | それぞれのウィンドウは自身の位置とポイントをもつ。 | |
29.20 ウィンドウの開始位置と終了位置 | ウィンドウ内でスクリーン表示されるテキストを表すバッファー位置。 | |
29.21 テキスト的なスクロール | ウィンドウを通じたテキストの上下移動。 | |
29.22 割り合いによる垂直スクロール | ウィンドウ上のコンテンツの上下移動。 | |
29.23 水平スクロール | ウィンドウ上のコンテンツの横移動。 | |
29.24 座標とウィンドウ | 座標からウィンドウへの変換。 | |
29.25 マウスによるウィンドウの自動選択 | マウスによる自動的なウィンドウ選択。 | |
29.26 ウィンドウの構成 | スクリーンの情報の保存とリストア。 | |
29.27 ウィンドウのパラメーター | ウィンドウへの追加情報の割り当て。 | |
29.28 ウィンドウのスクロールと変更のためのフック | スクロール、ウィンドウのサイズ変更、ある特定のしきい値を超えたときに行われる再表示、ウィンドウ構成の変更にたいするフック。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウ(window)とはバッファー(バッファーを参照)の表示に使用されるスクリーン領域です。ウィンドウはフレームへとグループ化されます(フレームを参照)。それぞれのフレームは最低でも1つのウィンドウを含みます。ユーザーは複数のバッファーを一度に閲覧するために、フレームを複数のオーバーラップしないウィンドウに分割することができます。Lispプログラムはさまざまな目的にたいして複数のウィンドウを使用できます。たとえばRmailでは1つのウィンドウでメッセージタイトル、もう一方のウィンドウで選択したメッセージのコンテンツを閲覧できます。
EmacsはX Window Systemのようなグラフィカルなデスクトップ環境やウィンドウシステムとは異なる意味で“ウィンドウ(window)”という用語を使用します。EmacsがX上で実行されているときはEmacsに所有されるグラフィカルなXウィンドウは、Emacsでのフレームに相当します。Emacsがテキスト端末上で実行されているときには、Emacsフレームそれぞれが1つの端末スクリーン全体を占有します。いずれの場合においても、フレームには1つ以上のEmacsウィンドウが含まれます。曖昧さをなくすために、Emacsフレームに相当するウィンドウシステムのウィンドウを指す際には、ウィンドウシステムのウィンドウ(window-system window)という用語を使うことにします。
Xのウィンドウとは異なり、Emacsのウィンドウはタイル表示(tiled)されるので、それらのフレーム領域内でオーバーラップされることは決してありません。あるウィンドウが作成、リサイズ、削除されるとき変更されたウィンドウスペースの変更は他のウィンドウから取得・譲与されるので、そのフレームの総領域に変化はありません。
Emacs Lispではウィンドウは特別なLispオブジェクトタイプで表されます(ウィンドウ型を参照)。
この関数は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
をリターンする。
以下の図は生きたウィンドウの構造を示しています:
____________________________________________ |________________ Tab Line _______________|RD| ^ |______________ Header Line ______________| | | ^ |LS|LM|LF| |RF|RM|RS| | | | | | | | | | | | | | Window | | | | | | | | | Window Body | | | | | Window Body | | | | | Total Height | | | | | | | | | Height | | | | |<- Window Body Width ->| | | | | | v |__|__|__|_______________________|__|__|__| | | |_________ Horizontal Scroll Bar _________| | | |_______________ Mode Line _______________|__| | |_____________ Bottom Divider _______________| v <---------- Window Total Width ------------>
ウィンドウの中央はボディー(body: 本体、本文)と呼ばれるバッファーテキストが表示される場所です。テキストエリアは、ウィンドウ装飾(window decorations)と呼ばれる一連のオプションエリアで囲まれている可能性があります。左右には内側から外側に向かって図中にLFとRFで示される左右のフリンジ(フリンジを参照)、LMとRMで示される左右のマージン(マージン内への表示を参照)、そしてLSとRSはスクロールバー(スクロールバーを参照)で、これは常に表示されるのはいずれか一方だけです。さらにRDで示されるのが右ディバイダー(ウィンドウディバイダーを参照)です。ウィンドウ上端にはヘッダーライン(ウィンドウのヘッダーラインを参照)、ウィンドウ下端には水平スクロールバー(スクロールバーを参照)、モードライン(モードラインのフォーマットを参照)、下端ディバイダー(ウィンドウディバイダーを参照)があります。これらを合わせて、ウィンドウの左や右の装飾(left and right decorations)と呼びます。
ウィンドウの上端にあるのがタブラインとヘッダーライン(ウィンドウのヘッダーラインを参照)です。ウィンドウにヘッダーラインやタブラインがある場合には、それらはウィンドウのテキストエリア(text area: テキスト領域)に含まれます。ウィンドウの下端にあるのが水平スクロールバー(スクロールバーを参照)とモードライン(モードラインのフォーマットを参照)、そして下ディバイダー(ウィンドウディバイダーを参照)です。これらを合わせてウィンドウの上や下の装飾(top and bottom decorations)と呼びます。
図には省略した特別なエリアが2つあります。
いずれのケースでも、たとえ結果となる構造のスクリーンスペースがバッファーテキストの表示に使用されなくても、そのウィンドウのボディーとみなされます。
行番号(と周囲の空白)display-line-numbers-mode
(Display Custom in The GNU Emacs Manualを参照)によって表示されるので装飾ではなく、そのウィンドウのボディー部分とみなされます。
内部ウィンドウがテキストを表示したり装飾をもつことはありません。したがってこれらにたいして“body”という概念は意味をもちません。実際にウィンドウのbodyを操作するほとんどの関数は、内部ウィンドウに適用するとエラーとなります。
デフォルトではEmacsフレームはメッセージ表示やユーザー入力受け取りに使用される1つの特別な生きたウィンドウ — ミニバッファーウィンドウ(minibuffer window)を表示します(ミニバッファーのウィンドウを参照)。ミニバッファーウィンドウはテキストの表示に使用されるのでbodyがありますが、タブライン、ヘッダーライン、それにマージンはありません。最後にツールチップフレームでツールチップを表示するのに使用されるツールチップウィンドウ(tooltip window)には、ボディーはありますが装飾は何もありません(ツールチップを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
それぞれのウィンドウは正確に1つのフレームに属します(フレームを参照)。ある特定のフレームに属するすべてのウィンドウにたいして、それらのウィンドウがそのフレームに所有されている(owned)、あるいは単にそのフレーム上にあるというときもあります。
この関数は指定されたwindowのフレーム(windowが属するフレーム)をリターンする。windowがnil
の場合のデフォルトは選択されたウィンドウ(ウィンドウの選択を参照)。
この関数は指定されたframeに所有されるすべての生きたウィンドウのリストをリターンする。frameが省略またはnil
の場合のデフォルトは選択されたフレーム(入力のフォーカスを参照)。
オプション引数minibufferはそのリストにミニバッファーウィンドウ(ミニバッファーのウィンドウを参照)を含めるべきかどうかを指定する。minibufferがt
ならミニバッファーウィンドウが含まれ、nil
または省略された場合にはミニバッファーウィンドウがアクティブのときだけ含まれる。minibufferがnil
とt
以外ならミニバッファーウィンドウは含まれない。
オプション引数windowが非nil
なら、それは指定されたフレーム上の生きたウィンドウでなければならない。その場合にはwindowがリターンされるリストの最初の要素になる。windowが省略またはnil
なら、frameの選択されたウィンドウ(ウィンドウの選択を参照)が最初の要素になる。
同一フレーム内のウィンドウは、リーフノード(leaf nodes)が生きたウィンドウであるようなウィンドウツリー(window tree)内に組織化されます。ウィンドウツリーの内部ノード(internal nodes)は生きたウィンドウではありません。これらのウィンドウは生きたウィンドウ間の関係を組織化するという目的のために存在します。ウィンドウツリーのルートノード(root node)はルートウィンドウ(root window)と呼ばれます。ルートノードは生きたウィンドウ、または内部ウィンドウのいずれかです。生きたウィンドウの場合には、ミニバッファーウィンドウ以外にウィンドウが1つだけあるフレーム、あるいはミニバッファーだけのフレームです。フレームのレイアウトを参照してください。
フレーム内で唯一ではないミニバッファーウィンドウ(ミニバッファーのウィンドウを参照)は親ウィンドウをもたないので、厳密に言えばフレームのウィンドウツリーの一部ではありません。それでもフレームのルートウィンドウの兄弟ウィンドウなので、ルートウィンドウからwindow-next-sibling
(以下参照)を通じて到達することができます。さらにこのセクションの最後に説明する関数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は自動的に親ウィンドウも削除して、その1つだけ残った子ウィンドウがウィンドウツリー内のその位置に配置されます。
子ウィンドウは生きたウィンドウ、または(次に自身の子ウィンドウをもつであろう)内部ウィンドウのいずれかです。したがって各内部ウィンドウは、最終的にはその内部ウィンドウの子孫であるような生きたウィンドウにより占有される領域を結合した、特定の矩形スクリーン領域(screen area)を占有すると考えることができます。
内部ウィンドウそれぞれにたいして、近接する子たちのスクリーン領域は垂直(vertically)か水平(horizontally)のいずれかにより整列されます(両方で整列されることはない)。子ウィンドウが他の子ウィンドウと上下に整列される場合、それらは垂直コンビネーション(vertical combination)、左右に整列される場合は水平コンビネーション(horizontal combination)を形成すると表現されます。以下の例で考えてみましょう:
______________________________________ | ______ ____________________________ | || || __________________________ || || ||| ||| || ||| ||| || ||| ||| || |||____________W4____________||| || || __________________________ || || ||| ||| || ||| ||| || |||____________W5____________||| ||__W2__||_____________W3_____________ | |__________________W1__________________|
このフレームのルートウィンドウは内部ウィンドウW1です。これの子ウィンドウは、生きたウィンドウW2と内部ウィンドウW3からなる水平コンビネーションを形成します。W3の子ウィンドウは、生きたウィンドウW4とW5からなる垂直コンビネーションを形成します。したがって、このウィンドウツリー内の生きたウィンドウはW2、W4、およびW5です。
以下の関数は内部ウィンドウの子ウィンドウ、および子ウィンドウの兄弟を取得するために使用できます。これらの関数のwindow引数のデフォルトは常に選択されたウィンドウです(ウィンドウの選択を参照)。
この関数は内部ウィンドウwindowの子ウィンドウが垂直コンビネーションを形成する場合には、windowの一番上の子ウィンドウをリターンする。他のタイプのウィンドウにたいするリターン値はnil
。
この関数は内部ウィンドウwindowの子ウィンドウが水平コンビネーションを形成する場合には、windowの一番左の子ウィンドウをリターンする。他のタイプのウィンドウにたいするリターン値はnil
。
この関数は内部ウィンドウwindowの最初の子ウィンドウをリターンする。これは垂直コンビネーションにたいしては一番上、水平コンビネーションにたいしては一番左の子ウィンドウ。windowが生きたウィンドウならリターン値はnil
。
この関数はwindowが垂直コンビネーションの一部である場合のみ非nil
をリターンする。
オプション引数horizontalが非nil
なら、windowが水平コンビネーションの一部である場合のみ非nil
をリターンすることを意味する。
この関数は指定されたwindowの次の兄弟をリターンする。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がsideに配置されていればt
をリターンする。引数windowは有効なウィンドウでなければならず、デフォルトは選択されたウィンドウ。引数sideはシンボルleft
、top
、right
、bottom
のいずれか。デフォルト値のnil
はbottom
として扱われる。
この関数はミニバッファーウィンドウを無視することに注意(ミニバッファーのウィンドウを参照)。したがってsideがbottom
なら、windowの右下にミニバッファーウィンドウがある際にもt
をリターンするかもしれない。
この関数はウィンドウ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
なら、そのフレームのミニバッファーウィンドウがアクティブでそれがフレームの他のウィンドウの最下にある場合には、この関数は通常はミニバッファーウィンドウをリターンする。
オプション引数minibufがt
なら、ミニバッファーウィンドウが非アクティブでもこの関数はそれをリターンするかもしれない。nil
ならカレントでアクティブな場合のみミニバッファーウィンドウをリターンすることを意味する。nil
とt
のいずれでもなければ、この関数がミニバッファーウィンドウをリターンすることはない。しかしwrapが非nil
なら、常にminibufがnil
であるかのように振る舞う。
適切なウィンドウが見つからなければ、この関数はnil
をリターンする。
この関数をdirectionにウィンドウが存在しないかどうかをチェックするために使用しないこと。それを行うには上述のwindow-at-side-p
を呼び出すほうが効果的である。
以下の関数はフレームのウィンドウツリー全体を取得します:
この関数はフレーム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] | [ ? ] |
それぞれのフレーム内において、常にただ1つのEmacsウィンドウがそのフレームで選択されている(selected within the
frame)として指定されます。選択されたフレームにたいしてそのウィンドウは選択されたウィンドウ(selected
window)と呼ばれます。選択されたウィンドウは編集のほとんどが行われるウィンドウであり、選択されたウィンドウに表示されるカーソルがあるウィンドウです(カーソルのパラメーターを参照)。テキストの挿入や削除を行うキーボード入力もそのウィンドウにたいして行われます。選択されたウィンドウのバッファーは、通常はset-buffer
が使用された場合を除いてカレントバッファーでもあります(カレントバッファーを参照)。選択されていないフレームでは、そのフレームが選択されたときはフレームで選択されていたウィンドウが選択されたウィンドウになります。
この関数は選択されたウィンドウをリターンする(これは常に生きたウィンドウ)。
以下の関数はウィンドウとそのフレームを明示的に選択します。
この関数はwindowを選択されたウィンドウにすることによりそのフレーム内で選択されたウィンドウとして、そのフレームを選択する。またwindowのバッファー(バッファーとウィンドウを参照)をカレントにして、そのバッファーのpoint
の値(ウィンドウとポイントを参照)をwindowのwindow-point
の値にセットする。windowは生きたウィンドウでなければならない。リターン値はwindow。
デフォルトではこの関数はwindowのバッファーをバッファーリストの先頭(バッファーリストを参照)に移動して、windowをもっとも最近選択されたウィンドウにする。オプション引数norecordが非nil
なら、これらの追加処理は省略される。
加えてこの関数はデフォルトではwindowのフレームの次回再表示の際にwindowを更新するようにディスプレイエンジンに指示する。norecordが非nil
なら、そのような更新は通常は行わない。しかしnorecordが特別なシンボルmark-for-redisplay
と等しければ上述の追加アクションは省略されるが、それにも関わらずwindowの表示は更新される。
ウィンドウを選択することではウィンドウの表示やそのフレームをディスプレイ上の最上フレームにすることを満足しない場合があることに注意。さらにそのフレームのレイズやフレームにフォーカスが当たることを確実にする必要もあるだろう。入力のフォーカスを参照のこと。
歴史的な理由によりウィンドウ選択時にEmacsが個別にフックを実行することはありません。アプリケーションや内部ルーチンがあるウィンドウ上でいくつかの処理を行うために一時的にウィンドウを選択することはよくあります。これらはwindow引数が何も指定されていなければデフォルトでは選択されたウィンドウを処理する関数が多数存在するのでコーディングを単純化するために、あるいは引数としてウィンドウを受け取らないために常に選択されたウィンドウを処理する関数がいくつか存在した(そして今も存在する)ためにこれを行います。あるウィンドウが短時間選択されたときと、以前に選択されていたウィンドウがリストアされるたびに毎回フックを実行するのは有用ではありません。
しかしnorecord引数がnil
の際にはselect-window
がバッファーリストを更新するので、間接的にノーマルフックbuffer-list-update-hook
が実行されます(バッファーリストを参照)。結果としてこのフックは、あるウィンドウがより“永続的”に選択された際に関数を実行する1つの手段を提供します。
buffer-list-update-hook
はウィンドウ管理とは無関係な関数によっても実行されるので、選択されたウィンドウの値を何かに保存しておいて、このフックの実行中にselected-window
の値と比較することには意味があります。buffer-list-update-hook
を使用する際の誤検出を防ぐためにも、一時的にのみウィンドウの選択を意図するselect-window
の呼び出しごとにnorecord引数に非nil
を渡すことはよい習慣です。そのような場合にはマクロwith-selected-window
(以下参照)を使用するべきです。
最後の再表示以降に別ウィンドウが選択されたことを再表示ルーチンが検知した際には、常にEmacsはフックwindow-selection-change-functions
も実行します。詳細な説明はウィンドウのスクロールと変更のためのフックを参照してください。(同じセクションに記載されている)
window-state-change-functions
は別ウィンドウ選択後に実行される別のアブノーマルフックですが、これは他のウィンドウの変更時にも同様にトリガーされます。
引数norecordに非nil
を指定したselect-window
の連続呼び出しは、ウィンドウの並び順を選択または使用時刻により決定します(以下参照)。関数get-lru-window
はたとえば、もっとも昔に選択されたウィンドウ(ウィンドウのサイクル順を参照)を取得するために使用できます。
この関数はフレームframe内で選択されているウィンドウをリターンする。frameは生きたフレームであること。省略またはnil
の場合のデフォルトは選択されたフレーム。
この関数はwindowをフレームframe内で選択されたウィンドウにする。frameは生きたフレームであること。省略またはnil
の場合のデフォルトは選択されたフレーム。windowは生きたウィンドウでなければならない
frameが選択されたフレームなら、windowを選択されたウィンドウにする。
オプション引数norecordが非nil
なら、この関数はもっとも最近に選択されたウィンドウやバッファーリストのいずれの順序も変更はしない。
以下のマクロはもっとも最近選択されたウィンドウやバッファーリストの順序に影響を与えずにウィンドウを一時的に選択するのに有用です。
このマクロは選択されたフレーム、同様に各フレームの選択されたウィンドウを記録して、formsを順に実行してから以前に選択されていたフレームとウィンドウをリストアする。これはカレントバッファーの保存とリストアも行う。リターン値はforms内の最後のフォームの値。
このマクロはウィンドウのサイズ、コンテンツ、配置についての保存やリストアは何も行わない。したがってformsがそれらを変更すると、その変更は永続化される。あるフレームにおいて以前に選択されていたウィンドウがformsのexit時にすでに生きていなければ、そのフレームの選択されたウィンドウはそのまま放置される。以前に選択されていたウィンドウがすでに生きていなければformsの最後に選択されていたウィンドウが何であれ、それが選択されたままになる。カレントバッファーformsのexit時にそれが生きている場合のみリストアされる。
このマクロは、もっとも最近に選択されたウィンドウとバッファーリストの順番をいずれも変更しない。
このマクロはwindowを選択してformsを順に実行してから、以前に選択されていたウィンドウとカレントバッファーをリストアする。たとえば引数norecordをnil
でselect-window
を呼び出す等、forms内で故意に変更しない限り、もっとも最近に選択されたウィンドウとバッファーリストの順番は変更されない。したがってこのマクロは不要なbuffer-list-update-hook
の実行なしに、windowを選択されたウィンドウとして一時的に作業するために好ましい手段である。
このマクロはウィンドウ管理コードを一時的に不安定な状態に置くことに注意。特にもっとも最近使用されたウィンドウ(下記参照)が、選択されたウィンドウと一致する必要はなくなる。したがってこのマクロのbodyでget-lru-window
やget-mru-window
のような関数を呼び出すと、予期せぬ結果を得ることになるかもしれない。
このマクロはframeを選択したフレームとしてformsを実行する。リターン値はformsの最後のフォームの値。このマクロは選択されたフレームの保存とリストアを行い、もっとも最近に選択されたフレーム、およびバッファーリスト内のバッファーのどちらの順序も変更しない。
この関数はウィンドウwindowの使用回数をリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。
ウィンドウの使用回数(use
time)は実際にはtime値ではなく、nil
のnorecord引数によるselect-window
の呼び出しごとに毎回単調に増加する整数。通常は最小の使用回数をもつウィンドウは、もっとも最近使用されていないウィンドウ(the
least recently used window)と呼ばれる。最大の使用回数をもつウィンドウはもっとも最近使用されたウィンドウ(the most
recently used window)と呼ばれる(ウィンドウのサイクル順を参照)。これはwith-selected-window
を使用していなければ、通常は選択されたウィンドウである。
この関数はwindowを2番目に最近使われたウィンドウ(選択されたウィンドウの次)としてマークする。windowが選択されたウィンドウ、あるいは選択されたウィンドウの使用時間がすべてのウィンドウの中で最長ではない場合(with-selected-window
のスコープ内で発生し得る)には何もしない。
たとえばFollowモード((emacs)Follow Modeを参照)の管理下では、あるウィンドウが単独で表示可能な部分より大きい部分をそのウィンドウにまとめて表示するように、複数のウィンドウが集合かつ協調してバッファーを表示することがあります。そのようなウィンドウグループ(window
group)を1つのエンティティーとしてとらえると便利なことがよくあります。window-group-start
(ウィンドウの開始位置と終了位置を参照)のようないくつかの関数では、グループ全体の代表としてウィンドウの1つを引数に与えることにより、これを行うことができます。
選択されたウィンドウがウィンドウグループのメンバーなら、この関数はそのバッファーの最前箇所を表示するウィンドウが先頭になる順序で、グループ内のウィンドウのリストをリターンする。それ以外なら、この関数は選択されたウィンドウだけを含むリストをリターンする。
バッファーローカル変数selected-window-group-function
が関数にセットされているときは、選択されたウィンドウはグループの一部とみなされる。この場合には、selected-window-group
はその関数を引数なしで呼び出し、その結果をリターンする(これはそのグループ内のウィンドウのリストであること)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはウィンドウの高さと幅を求めるためのさまざまな関数を提供します。これらの関数がリターンする値の多くはピクセル単位、または行単位と列単位のいずれかにより指定できます。グラフィカルなディスプレイでは後者は実際にはframe-char-height
とframe-char-width
(フレームのフォントを参照)によりリターンされる、そのフレームのデフォルトフォントが指定するデフォルト文字の高さと幅に対応します。したがってあるウィンドウが異なるフォントやサイズでテキストを表示していると、そのウィンドウにたいして報告される行高さと列幅は、実際にウィンドウ内で表示されるテキスト行数と列数とは異なるかもしれません。
トータル高さ(total height)とは、そのウィンドウのボディー、上下の装飾(Emacsウィンドウの基本概念を参照)を構成する行数です。
この関数はウィンドウwindowのトータル高さを行数でリターンする。windowが省略nil
の場合のデフォルトは選択されたウィンドウ。windowが内部ウィンドウなら、リターン値はそのウィンドウの子孫となるウィンドウにより占有されるトータル高さになる。
ウィンドウのピクセル高さがそのウィンドウがあるフレームのデフォルト文字高さの整数倍でなければ、そのウィンドウが占有する行数が内部で丸められる。これはそのウィンドウが親ウィンドウの場合には、すべての子ウィンドウのトータル高さの合計が、親ウィンドウのトータル高さと内部的に等しくなるような方法により行われる。これはたとえ2つのウィンドウのピクセル高さが等しくでも、内部的なトータル高さは1行分異なるかもしれないことを意味する。さらにこれはそのウィンドウが垂直コンビネーションされていて、かつ次の兄弟をもつ場合には、その兄弟の上端行は、このウィンドウの上端行とトータル高さから計算されるかもしれないことも意味する(座標とウィンドウを参照)。
オプション引数roundがceiling
なら、この関数はwindowのピクセル高さをそのフレームの文字高さで除した数より大であるような最小の整数、floor
なら除した数より小であるような最大の整数、それ以外のroundにたいしてはwindowsのトータル高さの内部値をリターンする。
トータル幅(total width)とはそのウィンドウのボディー、左右の装飾(Emacsウィンドウの基本概念を参照)を構成する列数です。
この関数はウィンドウ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の上下に他のウィンドウがなければ非nil
をリターンする。より正確には、windowのトータル高さがそのフレームのルートウィンドウの高さに等しいことを意味する。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。
この関数はフレーム内でwindowの左右に他のウィンドウがなければ非nil
をリターンする(トータル幅がそのフレーム上のルートウィンドウと等しい)。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。
ウィンドウのボディー高さ(body height)とは上下の装飾(Emacsウィンドウの基本概念を参照)を含まないbodyの高さです。
この関数はウィンドウwindowのボディーの高さを行数でリターンする。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ、それ以外なら生きたウィンドウでなければならない。
オプション引数pixelwiseは高さにたいして用いる単位を定義する。nil
なら、必要に応じて文字で計ったwindowのbody高さはもっとも近い整数に切り下げられる。これはテキスト領域の下端行が部分的に可視の場合にその行は計数されないこと、さらに任意のウィンドウのボディー高さはwindow-total-height
によりリターンされるそのウィンドウのトータル高さ決して超過し得ないことも意味する。
pixelwiseがremap
、かつデフォルトフェイスがリマップ(フェイスのリマップを参照)されている場合には、文字の高さの判定にリマップされたフェイスを使用する。それ以外の非nil
値にたいしてはピクセル単位で高さをリターンする。
ウィンドウのボディー幅(body width)とは左右の装飾を何も含まないbodyとテキスト領域の幅です。
(幅を0にセットすることにより)一方または両方のフリンジが削除されたときには、継続と切り詰めのグリフを表示するためにディスプレイエンジンが文字セル2つを予約するので、テキスト表示にたいして2列少なくなることに注意してください(以下で説明するwindow-max-chars-per-line
はこの特性を考慮する)。
この関数はウィンドウwindowのボディーの幅を列数でリターンする。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ、それ以外なら生きたウィンドウでなければならない。
オプション引数pixelwiseは幅にたいして用いる単位を定義する。nil
なら、必要に応じて文字で計ったwindowのbody幅はもっとも近い整数に切り下げられる。これはテキスト領域の右端の列が部分的に可視な場合にその列が計数されないことを意味する。さらにこれはウィンドウのボディーの幅がwindow-total-width
によりリターンされるウィンドウのトータル幅を決して超過し得ないことをも意味する。
pixelwiseがremap
、かつデフォルトフェイスがリマップ(フェイスのリマップを参照)されている場合には、文字の幅の判定にリマップされたフェイスを使用する。それ以外の非nil
値にたいしてはピクセル単位で幅をリターンする。
この関数はwindowのボディーの高さか幅をリターンする。horizontalが省略またはnil
ならwindowにたいしてwindow-body-height
、それ以外ならwindow-body-width
を呼び出すのと同じ。いずれの場合もオプション引数pixelwiseは呼び出された関数に渡される。
ウィンドウのモードライン、タブライン、ヘッダーラインのピクセル高さは以下の関数により取得できます。それらのリターン値は、そのウィンドウが以前に表示されていない場合を除いて通常は加算されます。その場合のリターン値はそのウィンドウのフレームにたいして使用を予想されるフォントが元になります。
この関数はwindowモードラインの高さをピクセルでリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。windowにモードラインがなければリターン値は0。
この関数は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
にもしたがう(ウィンドウサイズの保持を参照)。
このオプションは任意のウィンドウの最小のトータル高さを行で指定する。この値は最低でも1つのテキスト行、および上下のすべての装飾が含まれている必要がある。
このオプションはすべてのウィンドウの最小のトータル幅を列で指定する。この値は2つのテキスト列、および左右のすべての装飾が含まれている必要がある。
以下の関数は、ある特定の大きさのウィンドウにたいして、それのwindow-min-height
とwindow-min-width
、およびwindow-size-fixed
(ウィンドウサイズの保持を参照)の値と領域のサイズを示す。
この関数はwindowの最小のサイズをリターンする。windowは有効なウィンドウでなければならず、デフォルトは選択されたウィンドウ。オプション引数horizontalが非nil
ならwindowの最小の列数、それ以外はwindowの最小の行数をリターンすることを意味する。
このリターン値によってwindowのサイズが実際にその値にセットされた場合にwindowのすべてのコンポーネントが完全に可視にとどまることが保証される。horizontalがnil
なら上下のすべての装飾が含まれる。horizontalが非nil
なら、windowの左右のすべての装飾が含まれる。
オプション引数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つ以上のウィンドウを含む関数上でのみ意味があります(ウィンドウのリサイズにより他の少なくとも1つのウィンドウのサイズも変更される)。フレーム上に単一のウィンドウしか存在しない場合には、フレームの変更以外でウィンドウのサイズ変更はできません(フレームのサイズを参照)。
注記した場合を除き、これらの関数は引数として内部ウィンドウも許容します。内部ウィンドウのリサイズにより、同じスペースにフィットするように子ウィンドウもリサイズされます。
この関数は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行分の高さのテキストの合計をウィンドウの最小高さ、左右の装飾と2列分を占めるのテキストの合計をウィンドウの最小幅と判断する。
オプション引数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上下のすべての装飾を含んだ行数で指定する。
windowが水平コンビネーションの一部で、かつオプションfit-window-to-buffer-horizontally
(以下参照)の値が非nil
なら、この関数はwindowの幅を調整する。新たな幅はwindowのカレントのスタート位置以降のバッファーの最長の行から計算される。オプション引数max-widthは最大幅を指定して、デフォルトはwindowのフレーム幅。オプション引数min-widthは最小幅を指定して、デフォルトはwindow-min-width
。max-widthとmin-widthはどちらもwindowの左右のすべての装飾を含んだ列数で指定する。
オプション引数preserve-sizeが非nil
なら、将来のリサイズ操作の間のwindowのサイズを予約するパラメーターをインストールする(ウィンドウサイズの保持を参照)。
オプション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が非nil
の場合にはframeのルートウィンドウの新たなボディーサイズの境界を指定する。これらの引数いずれかに非nil
値を指定した場合には、後述のfit-frame-to-buffer-sizes
オプションで指定された対応する値をオーバーライドする。
この関数はオプション引数onlyがvertically
なら垂直方向のみ、onlyがhorizontally
なら水平方向のみフレームをリサイズする。
fit-frame-to-buffer
の振る舞いは次にリストする2つのオプションで制御可能です。
このオプションはフレーム周辺のマージンを指定してfit-frame-to-buffer
でフィットさせるために使用できる。このようなマージンはたとえばタスクバーや親フレームの一部とオーバーラップするフレームのリサイズを防ぐために有用かもしれない。
これはフィットされるフレームの左右上下にフリーとして残されるピクセル数を指定する。デフォルトのnil
はそれぞれにたいしてマージンを使用しないことを指定する。ここで指定した値は、特定のフレームにたいしてもしそのフレームのfit-frame-to-buffer-margins
が与えられればオーバーライドされ得る。
このオプションはfit-frame-to-buffer
にたいするサイズ境界を指定する。これはすべてのフレームにおいてバッファーにフィットされるルートウィンドウのbodyの行の最大と最小、列の最大と最小の合計を指定する。指定された値が非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] | [ ? ] |
前セクションのいずれかの関数を使用してウィンドウを明示的にリサイズしたり、たとえば隣接するウィンドウのリサイズ時、ウィンドウの分割や削除(ウィンドウの分割とsee ウィンドウの削除を参照)、あるいはそのウィンドウのフレームをリサイズ(フレームのサイズを参照)する際に暗黙的にリサイズできます。
同一フレーム上に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
はウィンドウリサイズ関数から参照されるwindow-preserved-size
と呼ばれるウィンドウパラメーターをインストールします(ウィンドウのパラメーターを参照)。このパラメーターはウィンドウがwindow-preserve-size
が呼び出されたときと異なるバッファーを表示していたり、呼び出し以降にウィンドウのサイズが変化していたらウィンドウのリサイズを妨げません。
以下の関数は特定のウィンドウの高さが予約済みかどうかチェックするために使用できます:
この関数はウィンドウwindowの予約済み高さをピクセル単位でリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。オプション引数horizontalが非nil
ならwindowの予約済み幅をリターンする。windowのサイズが予約されていなければnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは既存のウィンドウを分割(splitting)することによりウィンドウを新たに作成する関数を説明します。ここで説明する理由により関数が失敗するという意味において、特別なウィンドウがいくつかあることに注意してください。このようなウィンドウの例としてサイドウィンドウ(サイドウィンドウを参照)やアトミックウィンドウ(アトミックウィンドウを参照)があります。
この関数はウィンドウ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
を呼び出しています。
この関数はウィンドウwindow-to-splitが左側になるように、ウィンドウwindow-to-splitを2つの横並びのウィンドウに分割する。window-to-splitのデフォルトは選択されたウィンドウ。sizeが正ならば左のウィンドウがsize列、負ならば右のウィンドウが-size列を与えられる。
この関数はウィンドウwindow-to-splitが上側になるように、ウィンドウwindow-to-splitを2つの縦並びのウィンドウに分割する。window-to-splitのデフォルトは選択されたウィンドウ。sizeが正ならば上のウィンドウがsize行、負ならば下のウィンドウが-size行を与えられる。
この関数はフレーム全体を2つに分割する。カレントのウィンドウ構成は上側に留まり、フレーム全体の幅を占めるような新たなウィンドウを下側に作成する。sizeはsplit-window-below
の場合と同様に扱われる。
この関数はフレーム全体を2つに分割する。カレントのウィンドウ構成は左側に留まり、フレーム全体の高さを占めるような新たなウィンドウを右側に作成する。sizeはsplit-window-below
の場合と同様に扱われる。
この変数の値が非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のフレーム上の残りすべてのウィンドウがサイドウィンドウ(サイドウィンドウを参照)ならエラーがシグナルされる。windowがアトミックウィンドウ(アトミックウィンドウを参照)の一部なら、この関数はかわりにアトミックウィンドウのルートウィンドウの削除を試みる。
デフォルトではwindowが占めていたスペースは、(もしあれば)隣接する兄弟ウィンドウのうちの1つに与えられる。しかし変数window-combination-resize
が非nil
なら、そのスペースは同一ウィンドウコンビネーション内の残りのすべてのウィンドウに比例的に分配される。See ウィンドウの再結合を参照のこと。
変数ignore-window-parameters
がnil
の場合に限り、この関数の振る舞いはwindowのウィンドウパラメーターにより変更される可能性がある。ウィンドウパラメーターdelete-window
の値がt
なら、この関数はその他すべてのウィンドウパラメーターを無視する。ウィンドウパラメーターdelete-window
が関数なら、通常のdelete-window
のかわりに引数windowでその関数が呼び出される。ウィンドウのパラメーターを参照のこと。
フレームの選択されたウィンドウをdelete-window
で削除したときは、別のウィンドウをそのフレームの新たな選択されたウィンドウにする必要があります。このとき選択されるウィンドウを以下のオプションで設定できます。
このオプションでdelete-window
が選択されたウィンドウを削除した後に、かわりの選択するウィンドウを指定できる。可能な選択肢は
mru
そのフレームでもっとも最近に使用したウィンドウを選択する(デフォルト)。
pos
そのフレームで前に選択されていたポイントのフレーム座標を含むウィンドウを選択する。
nil
そのフレームの最初のウィンドウ(frame-first-window
がリターンするウィンドウ)を選択する。
非nil
のno-other-window
パラメーターをもつウィンドウは、そのフレームの他のすべてのウィンドウもこのパラメーターが非nil
値をもつ場合しか選択されることはない。
この関数は必要に応じて他のウィンドウを削除することにより、windowでフレームを充填する。windowが省略またはnil
の場合のデフォルトは選択されたウィンドウ。windowがサイドウィンドウならエラーをシグナルする(サイドウィンドウを参照)。windowがアトミックウィンドウの一部なら、この関数はアトミックウィンドウのルートウィンドウによるフレームの重点を試みる(アトミックウィンドウを参照)。リターン値はnil
。
変数ignore-window-parameters
がnil
の場合に限り、この関数の振る舞いは変更される可能性がある。ウィンドウパラメーターdelete-other-windows
の値がt
なら、この関数は他のすべてのウィンドウパラメーターを無視する。ウィンドウパラメーターdelete-other-windows
の値が関数なら、delete-other-windows
の通常の動作のかわりに引数windowでその関数が呼び出される。ウィンドウのパラメーターを参照のこと。
さらにignore-window-parameters
がnil
なら、この関数はno-delete-other-windows
パラメーターが非nil
のウィンドウを削除しない。
この関数は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
エントリーに渡すことを意味する(バッファー表示用のアクション関数を参照)。それ以外の場合にはウィンドウの分割は値がnil
のときのように振る舞う。
temp-buffer-resize
この場合にはwith-temp-buffer-window
がウィンドウを分割して、かつtemp-buffer-resize-mode
が有効なら新たに親ウィンドウを作成する(一時的な表示を参照)。それ以外ならウィンドウ分割はnil
の場合のように振る舞う。
temp-buffer
この場合にはwith-temp-buffer-window
は既存のウィンドウの分割時に常に新たな親ウィンドウを作成する(一時的な表示を参照)。それ以外ならウィンドウ分割はnil
の場合のように振る舞う。
display-buffer
これはdisplay-buffer
(バッファーを表示するウィンドウの選択を参照)がウィンドウを分割する際に、常に親ウィンドウを新たに作成することを意味する。それ以外ならウィンドウ分割はnil
の場合のように振る舞う。
t
これはウィンドウを分割することによって常に親ウィンドウが新たに作成されることを意味する。したがってこの変数の値が常にt
なら、すべてのウィンドウツリーは常に2分木(ルートウィンドウ以外のすべてのウィンドウが正確に1つの兄弟をもつようなツリー)になる。
デフォルトはwindow-size
であり、それ以外の値は将来のために予約済み。
この変数のセッティングの結果として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] | [ ? ] |
他のウィンドウを選択するためにコマンド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
の場合と同じ意味をもつ。
この関数はignore-window-parameters
がnil
なら非nil
のウィンドウパラメーターno-other-window
をもつウィンドウを選択しない。
選択されたウィンドウのother-window
パラメーターが関数でignore-window-parameters
がnil
なら、この関数の通常の処理のかわりに、other-window
パラメーターの関数が引数countとall-framesで呼び出される。
この関数は生きたウィンドウそれぞれにたいしてウィンドウを引数に関数funを呼び出す。
これはウィンドウのサイクル順にしたがう。オプション引数minibufとall-framesには、含まれるウィンドウセットを指定する。これらはnext-window
の引数の場合と同じ意味をもつ。all-framesがフレームを指定する場合には、最初に処理されるのはそのフレームの最初のウィンドウ(frame-first-window
がリターンするウィンドウ)であり、選択されたウィンドウである必要はない。
funがウィンドウの分割や削除によりウィンドウ構成を変更する場合でも、処理するウィンドウセットは初回のfun呼び出しに先立ち決定されるため変更されない。
この関数は選択されたウィンドウが唯一の生きたウィンドウならt
、それ以外はnil
をリターンする。
ミニバッファーウィンドウがアクティブなら、ミニバッファーウィンドウは通常は考慮される(そのためこの関数はnil
をリターンする)。しかしオプション引数no-miniが非nil
なら、たとえアクティブであってもミニバッファーウィンドウは無視される。オプション引数all-framesはnext-window
の場合と同じ意味をもつ。
以下は何らかの条件を満足するウィンドウを、それらを選択することなくリターンする関数です:
この関数は発見的に最近もっとも使用されていない生きたウィンドウをリターンする。最近もっとも使用されていないウィンドウ(least
recently used
window)とは最近選択されたのがもっとも少ない、すなわち他のすべての生きたウィンドウより使用時間が少ないウィンドウのこと。オプション引数all-framesはnext-window
の場合と同じ意味をもつ。
フル幅のウィンドウが存在する場合には、それらのウィンドウだけが考慮される。ミニバッファーが候補になることは決してない。オプション引数dedicatedがnil
なら、専用バッファー(専用のウィンドウを参照)が候補になることは決してない。唯一の候補が選択されたウィンドウである場合以外は選択されたウィンドウを決してリターンしない。しかしオプション引数not-selectedが非nil
なら、そのような場合でもこの関数はnil
をリターンする。オプション引数no-otherが非nil
なら、no-other-window
パラメーターが非nil
のウィンドウをリターンすることは決してないことを意味する。
この関数はget-lru-window
と同様だが、かわりにもっとも最近使用されたウィンドウをリターンする。最近もっとも使用されたウィンドウ(most
recently used
window)とは最近選択されたのがもっとも多い、すなわち他のすべての生きたウィンドウより使用時間が多いウィンドウのこと。引数の意味はget-lru-window
と同様。
もっとも最近使用されたウィンドウは実際には常に選択されたウィンドウになるので、非nil
のnot-selected引数でこの関数を呼び出すことには通常は道理がある。
この関数はもっとも広い領域(高さ掛ける幅)のウィンドウをリターンする。同サイズの候補ウィンドウが2つある場合には、ウィンドウのサイクル順で選択されたウィンドウから数えて最初にあるウィンドウを優先する。引数の意味はget-lru-window
と同じ。
この関数はウィンドウのサイクル順内の各ウィンドウにたいして、そのウィンドウを引数として関数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
なら、windowのディスプレイマージンおよびフリンジとスクロールバーのセッティングは未変更のままにする。
アプリケーションを記述する際には直接set-window-buffer
を呼び出すのではなく、通常はdisplay-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
を呼び出した場合には無視される。
この変数が非nil
ならswitch-to-buffer
はdisplay-buffer-overriding-action
やdisplay-buffer-alist
、およびその他の表示に関係する変数で指定されるディスプレイアクションにしたがいます。
以下の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] | [ ? ] |
このセクションでは特定のバッファーの表示にたいしてEmacsが検索や作成に使用する低レベルの関数を説明します。これらの関数の共通点は、受け取ったすべてのバッファー表示要求を最終的に処理するdisplay-buffer
(バッファーを表示するウィンドウの選択を参照)を主に用いるという点です。
display-buffer
は適切なウィンドウを見つけるタスクを、いわゆるアクション関数に委譲します(バッファー表示用のアクション関数を参照)。まずdisplay-buffer
は、いわゆるアクションalist
(アクション関数が振る舞いを微調整するために使用可能な連想リスト)をコンパイルします。それから呼び出す関数それぞれにたいして、そのalistを渡します(バッファー表示用のアクションalistを参照)。
display-buffer
の動作は高度にカスタマイズ可能です。実際にカスタマイゼーションが使用される方法を理解するためには、display-buffer
がアクション関数を呼び出す際に使用する優先順を示す例を学びたいと思うかもしれません(アクション関数の優先順を参照)。display-buffer
を呼び出すLispプログラムや、display-buffer
の動作にたいするユーザーのカスタマイズとの間の競合を避けるためには、このセクションの最後に示すいくつかのガイドラインにしたがうのが合理的かもしれません(バッファー表示の思想を参照)。
29.13.1 バッファーを表示するウィンドウの選択 | バッファーを表示するウィンドウの選択方法。 | |
29.13.2 バッファー表示用のアクション関数 | バッファー表示用のサポート関数。 | |
29.13.3 バッファー表示用のアクションalist | バッファー表示微調整用のalist。 | |
29.13.4 バッファー表示の追加オプション | バッファー表示方法に影響する拡張オプション。 | |
29.13.5 アクション関数の優先順 | アクション関数の優先順の例。 | |
29.13.6 バッファー表示の思想 | ウィンドウ間でバッファーが失われることを避けるには。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コマンドdisplay-buffer
は表示のために柔軟にウィンドウを選択して、そのウィンドウ内に指定されたバッファーを表示します。これはキーバインディングC-x
4
C-oを通じてインタラクティブに呼び出すことができます。またswitch-to-buffer
やpop-to-buffer
を含む多くの関数やコマンドにからサブルーチンとしても使用されます(ウィンドウ内のバッファーへの切り替えを参照)。
このコマンドは表示するウィンドウを探すために、いくつかの複雑なステップを実行します。これらのステップはディスプレイアクション(display
actions)を用いて記述されます。ディスプレイアクションは(functions
.
alist)
という形式をもちます。ここでfunctionsは“アクション関数”と呼ばれる単一の関数か関数のリスト(バッファー表示用のアクション関数を参照)、alistは“アクションalist”と呼ばれる連想リストです(バッファー表示用のアクションalistを参照)。ディスプレイアクションの例についてはバッファー表示の思想を参照してください。
アクション関数は、表示するバッファーと、アクションalistという、2つの引数を受け取ります。これは、自身の条件にしたがってウィンドウを選択、または作成して、バッファーをウィンドウ内に表示します。成功した場合はそのウィンドウ、それ以外はnil
をリターンします。
display-buffer
は複数ソースからのディスプレイアクションを組み合わせて、アクション関数のいずれか1つがバッファーの表示を管理して非nil
値をリターンするまでアクション関数を順に呼び出します。
このコマンドは、ウィンドウを選択したり、そのバッファーをカレントにすることなく、buffer-or-nameをウィンドウに表示させる。引数buffer-or-nameはバッファー、または既存のバッファーの名前でなければならない。リターン値はバッファーを表示するために選ばれたウィンドウ、適切なウィンドウが見つからなければnil
。
オプション引数actionが非nil
なら、それは通常はディスプレイアクション(上述)であること。display-buffer
は以下のソース(優先度の高位順)からディスプレイアクションを集約してアクション関数リストとアクションalistを構築する:
display-buffer-overriding-action
。
display-buffer-alist
。
display-buffer-base-action
。
display-buffer-fallback-action
。
これはこれらのディプレイアクションにより指定されるアクション関数すべてのリストを、実際にはdisplay-buffer
が構築することを意味する。このリストの最初の要素は(もしあれば)
display-buffer-overriding-action
が指定する最初のアクション関数、最後の要素はdisplay-buffer-pop-up-frame
(display-buffer-fallback-action
が指定する最後のアクション関数)。このリストから重複要素は削除されないので、1回のdisplay-buffer
呼び出しの間に同一のアクション関数が複数回呼び出されるかもしれない。
display-buffer
はバッファーを1つ目の引数、組み合わされたalistを2つ目の引数として、いずれかの関数が非nil
をリターンするまで、このリスト内で指定されたアクション関数を順に呼び出す。異なるソースから指定されたディスプレイアクションをdisplay-buffer
がどのように処理するかの例はアクション関数の優先順を参照のこと。
2つ目の引数は常に、上記に挙げたソースが指定するすべてのアクションalistエントリーのリストであることに注意。したがってこのリストの最初の要素は(もしあれば)
display-buffer-overriding-action
が指定する最初のアクションalistエントリー、最後の要素はもしあれば
display-buffer-base-action
の最後のalistエントリーとなる(display-buffer-fallback-action
のアクションalistが空の場合)。
組み合わされたアクションalistは重複したエントリーを含むかもしれず、同じキーのエントリーが異なる値をもつかもしれないことにも注意。アクション関数はルールとして見つかった最初のキーの連想値を常に使用する。したがってアクション関数が使用する連想値が、そのアクション関数に指定されたディスプレイアクションが提供する連想値である必要はない。
引数actionにはリストではない非nil
値も指定できる。これはたとえ選択されたウィンドウがすでにそのバッファーを表示していても、選択されたウィンドウではない別のウィンドウにバッファーが表示されるべきという特別な意味をもつ。プレフィックス引数とともにインタラクティブに呼び出された場合には、actionはt
である。Lispプログラムは値として常にリストを提供すること。
オプション引数frameが非nil
の場合は、そのバッファーがすでに表示されているか判断する際、どのフレームをチェックするかを指定する。これはactionのアクションalistに要素(reusable-frames . frame)
を追加するのと等価(バッファー表示用のアクションalistを参照)。frameは互換性のために提供される引数であり、Lispプログラムは使用するべきではない。
この変数の値はdisplay-buffer
により最高の優先順で扱われるディスプレイアクションであること。デフォルト値は空のディスプレイアクション(つまり(nil . nil)
)。
このオプションの値はディスプレイアクションにコンディション(condition:
状態)をマップするalist。各コンディションはバッファー名、display-buffer
に渡されたaction引数とともにbuffer-match-p
に渡される。これが非nil
値をリターンしたら、display-buffer
は対応するディスプレイアクションをそのバッファーの表示に使用する。
このオプションの値はディスプレイアクションであること。このオプションはdisplay-buffer
呼び出しにたいする標準のディスプレイアクションを定義するために使用できる。
このディスプレイアクションはdisplay-buffer
にたいして、他のディスプレイアクションが与えられなかった場合の代替え処理を指定する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
アクション関数(action
function)とはバッファーを表示するウィンドウを選択するためにdisplay-buffer
が呼び出す関数です。アクション関数はbuffer
(表示するバッファー)、およびalist (アクションalist、バッファー表示用のアクションalistを参照)という2つの引数を受け取ります。これらの関数は成功時にはbufferを表示するウィンドウ、失敗時にはnil
をリターンします。
以下の基本的なアクション関数がEmacsで定義されています。
この関数は選択されたウィンドウ内にbufferの表示を試みる。選択されたウィンドウがミニバッファーウィンドウや他のバッファー専用(専用のウィンドウを参照)の場合には失敗する。alistに非nil
のinhibit-same-window
エントリーがある場合にも失敗する。
この関数はすでにbufferを表示しているウィンドウを探すことによりバッファーの表示を試みる。選択されたフレーム上のウィンドウは別フレーム上のウィンドウより優先される。
alistに非nil
のinhibit-same-window
エントリーがある場合には、選択されたウィンドウは再利用に適さない。bufferをすでに表示しているウィンドウを検索するフレームセットは、アクションalistのreusable-frames
エントリーで指定できる。alistにreusable-frames
エントリーが含まれる場合には、この関数は選択されたフレームだけを検索する。
この関数が他のフレーム上のウィンドウを選択した場合には、そのフレームを可視にするとともに、alistがinhibit-switch-frame
エントリーを含んでいなければ、必要ならそのフレームを最前面に移動(raise)する。
この関数は与えられたモードですでにbufferを表示しているウィンドウを探すことによりバッファーの表示を試みる。
alistがmode
エントリーを含んでいれば、その値がメジャーモード(シンボル)、またはメジャーモードのリストを指定する。alistにmode
エントリーが含まれていなければ、かわりにbufferのカレントのメジャーモードが使用される。このように指定されたモードのいずれかから継承されたモードでバッファーを表示しているウィンドウは候補となる。
display-buffer-reuse-window
のように関数の挙動はinhibit-same-window
、reusable-frames
、inhibit-switch-frame
にたいするalistエントリーによっても制御される。
この関数は、最大もしくはもっとも長い間参照されていないウィンドウ(通常は選択されたフレームに配置されている)を分割することによりbufferの表示を試みる。これは実際には、split-window-preferred-function
(バッファー表示の追加オプションを参照)内で指定された関数を呼び出すことにより分割を行う。
新たなウィンドウのサイズはalistにエントリーwindow-height
とwindow-width
を与えることにより調整できる。alistにpreserve-size
エントリーが含まれていれば、Emacsは将来のリサイズ操作の間に新たなウィンドウのサイズの維持も試みる(ウィンドウサイズの保持を参照)。
この関数は分割可能なウィンドウがなければ失敗する。これの多くは、分割を許容するのに十分大きいウィンドウがない場合に発生する。この問題にたいしてはsplit-height-threshold
やsplit-width-threshold
に小さい値をセットすることが助けになるかもしれない。選択されたフレームがフレームパラメーターunsplittable
をもつ場合にも分割は失敗する。バッファーのパラメーターを参照のこと。
この関数はbufferを以前に表示したウィンドウにbufferの表示を試みる。
alistに非nil
のinhibit-same-window
エントリーが含まれる場合には、選択されたウィンドウは使用に適さない。専用ウィンドウ(dedicated
window)は、すでにbufferを表示済みの場合のみ使用可能。alistにprevious-window
エントリーが含まれる場合には、そのエントリーで指定されるウィンドウが以前にbufferを表示したことがなくても、そのウィンドウが使用される。
alistにreusable-frames
エントリー(バッファー表示用のアクションalistを参照)が含まれる場合には、その値が適切なウィンドウを検索するフレームを決定する。この関数はalistにreusable-frames
エントリーが含まれず、display-buffer-reuse-frames
とpop-up-frames
がいずれもnil
なら選択されたフレームのみ、いずれかが非nil
ならカレント端末上のすべてのフレームを検索する。
これらのルールに照らして1つ以上のウィンドウが使用に適している場合には、この関数は以下の優先順にしたがって選択を行う:
previous-window
エントリーで指定されるウィンドウが選択されたウィンドウでなければそのウィンドウ。
previous-window
エントリーで指定されているか、あるいは以前にbufferを表示していれば選択されたウィンドウ。
この関数は既存のウィンドウを選んでそのウィンドウにバッファーを表示することによってbufferの表示を試みる。まずalistのlru-frames
エントリーによって指定されたすべてのフレームにおいて最近使用されていないウィンドウ(ウィンドウのサイクル順を参照)を探す(そのようなエントリーが存在しなければ選択されたウィンドウにフォールバック)。alistのwindow-min-width
エントリーとwindow-min-height
エントリーに指定された制約を満足するようなウィンドウも優先される(window-min-width
エントリーがなければfull-widthのウィンドウを優先)。最後にalistのlru-time
エントリーで指定された値より長い使用時間のウィンドウは除外する。
最近使用されていないウィンドウが見つからなければ、この関数は別のウィンドウ(可視なフレーム上のなるべく大きいウィンドウを優先)の使用を試みる。ウィンドウがすべて別のバッファー専用(専用のウィンドウを参照)の場合には失敗するかもしれない。
この関数はdisplay-buffer-use-some-window
と似ているが、より厳格に最近使用されたウィンドウを使用しないよう試みる。特に選択されたウィンドウを使用することはない。更に加えてまず既にbufferを表示しているウィンドウの再利用を試み、次に別のバッファーを表示しているウィンドウの使用時間だけにもとづいてそのウィンドウを使用すべきかどうかを判断、それでも利用可能なウィンドウが見つからなければ新たなウィンドウをポップアップする。
最後にこの関数は以降の呼び出しでそのウィンドウに別のバッファーを表示することを避けるために、リターンするウィンドウの使用時間(ウィンドウの選択を参照)を増加させる。この関数を使って複数のバッファーを順に表示したいアプリケーションは、alistのlru-time
に初期値として選択されたウィンドウの使用時間をセットして提供することによって、この関数を支援することができる。この関数は呼び出されるごとにリターンするウィンドウの使用時間をより長い使用時間に増加することによって、以降の呼び出しでは以前にリターンしたウィンドウの使用を回避する。
この関数はalistで指定した位置でbufferの表示を試みる。この目的のために、alistには値がleft
、above
(かup
)、right
、below
(かdown
)のいずれかであるようなdirection
エントリーを含めること。それ以外の値は通常はbelow
と解釈される。
alistにwindow
エントリーも含まれている場合には、その値は参照ウィンドウ(reference
window)を指定する。値には選択されたフレームのメインウィンドウ(サイドウィンドウのオプションと関数を参照)を意味するmain
、選択されたフレームのルートウィンドウ(ウィンドウとフレームを参照)を意味するroot
のような特別なシンボルを指定できる。任意の有効なウィンドウの指定も可能。それ以外の値(またはwindow
エントリーを完全に省略)は参照ウィンドウとして選択されたウィンドウを使用することを意味する。
この関数は、指定方向ですでにbufferを表示しているウィンドウの再利用を試みる。そのようなウィンドウが存在しなければ、指定方向に新たなウィンドウを生成するために参照ウィンドウの分割を試みる。これも同様に失敗したら指定方向にある既存ウィンドウにbufferの表示を試みる。いずれの場合でもdirection
エントリーで指定された参照ウィンドウ側に、少なくとも1辺を参照ウィンドウと共有したウィンドウが選ばれることになる。
参照ウィンドウが生きたウィンドウなら、選択されるウィンドウのエッジはdirection
エントリーで指定された方向と反対側が共有される。たとえばdirection
エントリーの値がleft
なら、選択されるウィンドウの右エッジ座標は、参照ウィンドウの左エッジ座標と等しくなる(座標とウィンドウを参照)。
参照ウィンドウが内部ウィンドウなら、再利用されるウィンドウはdirection
エントリーで指定されるエッジが共有されなければならない。したがって、たとえば参照ウィンドウがフレームのルートウィンドウ、direction
エントリーの値がleft
なら、再利用されるウィンドウはフレームの左側でなければならない。これは選択されるウィンドウと参照ウィンドウの左エッジ座標が等しいことを意味する。
しかし新たなウィンドウは選択したウィンドウが参照ウィンドウの反対側エッジを共有するように参照ウィンドウを分割して作成される。上記の例では参照ウィンドウを子ウィンドウとして、新たな生きたウィンドウと共にルートウィンドウが新たに作成される。選択されたウィンドウの右エッジ座標は、参照ウィンドウの左エッジ座標、左エッジ座標はフレームのルートウィンドウの左エッジ座標と等しくなる。
direction
エントリーにたいする特別な4つの値leftmost
、top
、rightmost
、bottom
では参照ウィンドウとして選択されたフレームのメインウィンドウを暗黙に指定できる。これはたとえば(direction . left) (window . main)
のかわりに、単に(direction . leftmost)
と指定することができることを意味する。このような場合ではalistの既存のwindow
エントリーは無視される。
この関数は選択されたウィンドウの下のウィンドウ内にbufferの表示を試みる。選択されたウィンドウの下にすでにそのバッファーを表示するウィンドウがあれば、そのウィンドウを再利用する。
そのようなウィンドウが存在しなければ、この関数は選択されたウィンドウを分割することにより新たなウィンドウを作成してbufferの表示を試みる。alistに適切なwindow-height
かwindow-width
のエントリーが含まれていれば、ウィンドウのサイズ調整も試みる(上記参照)。
選択されたウィンドウの分割に失敗、かつ選択されたウィンドウの下に別のバッファーを表示中の非専用ウィンドウがある場合には、この関数はbufferの表示にそのウィンドウの使用を試みる。
alistにwindow-min-height
エントリーが含まれていると、この関数は少なくとも使用するウィンドウの高さがこのエントリーで指定された値になることを保証する。これは単なる保証であることに注意。使用するウィンドウを実際にリサイズするためには、alistで適切なwindow-height
エントリーも提供しなければならない。
この関数は選択されたフレームの最下にあるウィンドウ内にbufferの表示を試みる。
これはフレーム最下のウィンドウまたはフレームのルートウィンドウを分割、または選択されたフレーム最下の既存ウィンドウを試みる。
この関数は新たにフレームを作成して、そのフレームのウィンドウ内にバッファーを表示する。これは実際にはpop-up-frame-function
(バッファー表示の追加オプションを参照)内で指定された関数を呼び出すことによりフレーム作成の処理を行う。alistがpop-up-frame-parameters
エントリーを含む場合には、その連想値(associated
value)が新たに作成されたフレームのパラメーターに追加される。
この関数はカレントフレームの他のウィンドウをすべて削除して、フレーム全体を占めるようにバッファーを表示する。
この関数は選択されたフレームの既存の子フレーム、または子フレームを新たに作成してbufferの表示を試みる(子フレームを参照)。alistに非nil
のchild-frame-parameters
エントリーがあれば、対応する値が新たなフレームのフレームパラメーターのalistとして与えられる。デフォルトとして選択されたフレームを指定するparent-frame
パラメーターが提供される。その子フレームが別のフレームの子になる場合には、対応するエントリーをalistに追加しなければならない。
子フレームの外観はalistを通じて提供されるパラメーターに大きく依存する。子フレームが可視のままでいることを保証するために、少なくとも子フレームのサイズ(サイズのパラメーターを参照)と位置(位置のパラメーターを参照)を指定して比率(ratio)を使用すること、およびkeep-ratio
パラメーター(フレームとの相互作用のためのパラメーターを参照)の追加を推奨する。他に考慮すべきパラメーターについては子フレームを参照のこと。
この関数は述語を満足するフレーム(デフォルトは選択されたフレーム以外のフレーム)を探してbufferの表示を試みる。
この関数が他のフレーム上のウィンドウを選択した場合には、そのフレームを可視にするとともに、alistがinhibit-switch-frame
エントリーを含んでいなければ、必要ならそのフレームを最前面に移動(raise)する。
alistに非nil
のframe-predicate
エントリーがあれば、その値は1つの引数(フレーム)を受け取ってそのフレームが候補なら非nil
をリターンする、デフォルトの述語を置き換える関数。
alistに非nil
のinhibit-same-window
エントリーがある場合には選択されたウィンドウは使用しない。したがって選択されたフレームに単一のウィンドウしかなければ使用しない。
この関数はalistに非nil
のallow-no-window
エントリーがあればbufferを表示せずにシンボルfail
をリターンする。この構成はアクション関数がnil
かbufferを表示するウィンドウをリターンするという慣習の唯一の例外である。alistにそのようなallow-no-window
エントリーがなければ、この関数はnil
をリターンする。
この関数がfail
をリターンした場合には、display-buffer
はそれ以上のディスプレイアクションをスキップして即座にnil
をリターンする。この関数がnil
をリターンした場合には、display-buffer
はもしあれば次のディスプレイアクションを継続する。
display-buffer
の呼び出し側が非nil
のallow-no-window
エントリーを指定した場合には、nil
のリターン値の処理も可能とみなされる。
他の2つのアクション関数display-buffer-in-side-window
とdisplay-buffer-in-atom-window
については、それぞれ適正なセクションで説明します(サイドウィンドウへのバッファーの表示とアトミックウィンドウを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
アクションalist(action
alist)とはアクション関数が認識可能な事前定義されたシンボルと、それに応じてそれらの関数が解釈することを意図した値をマップする連想リストです。各呼び出しにおいてdisplay-buffer
は新たなアクションalist(空の場合もある)を作成して、呼び出すすべてのアクション関数にそのリスト全体を渡します。
仕様によりアクション関数はアクションalist全体を自由に解釈できます。実際のところallow-no-window
やprevious-window
のようないくつかのエントリーはいくつかのアクション関数にとってのみ意味があり、他のアクション関数では無視されます。それ以外のinhibit-same-window
やwindow-parameters
のようなエントリーは、アプシケーションプログラムや外部パッケージから提供されるものも含めて、ほとんどのアクション関数がしたがいます。
前のサブセクションでは、個別のアクション関数がアクションエントリーを処理する方法の詳細を説明しました。ここでは既知のアクションalistエントリーに対応するすべてのシンボル、およびそれらの値とそれらを認識するアクション関数(バッファー表示用のアクション関数を参照)とともに示すリファレンスリストを提供します。このリストにおいて用語“バッファー”はdisplay-buffer
が表示しようとするバッファー、“値”はそのエントリーの値を意味しています。
inhibit-same-window
値が非nil
なら、バッファーの表示に選択されたウィンドウを使用してはならないことを告げる。既存のウィンドウを(再)使用するすべてのアクション関数は、このエントリーにしたがう必要がある。
previous-window
値には以前にバッファーを表示した可能性のあるウィンドウを指定しなければならない。そのようなウィンドウがまだ生きていて他のバッファー専用でなれば、display-buffer-in-previous-window
はそのウィンドウを優先する。
mode
値はメジャーモードかメジャーモードのリスト。このエントリーが指定する値がウィンドウのバッファーのメジャーモードにマッチすれば、display-buffer-reuse-mode-window
は常にそのウィンドウを再利用する。これ以外のアクション関数はこのエントリーを無視する。
frame-predicate
値はそのフレームがバッファーを表示する候補なら非nil
をリターンする単一の引数(フレーム)を受け取る関数でなければならない。このエントリーはdisplay-buffer-use-some-frame
が使用する。
reusable-frames
値はバッファーをすでに表示していたことにより再利用可能なウィンドウを検索するためのフレームセットを指定する。以下をセット可能:
nil
は選択されたフレーム(実際にはミニバッファーフレーム以外の最後に使用されたフレーム)上のウィンドウだけを考慮することを意味する。
visible
はすべての可視フレーム上のウィンドウを考慮することを意味する。
t
はすべてのフレームのウィンドウを考慮することを意味する(ツールチップフレームがリターンされるかもしれないので、この値が使用に耐えることは稀であることに注意)。
nil
の意味はnext-window
にたいするall-frames引数の場合の意味とは若干異なることに注意(ウィンドウのサイクル順を参照)。
これの主要クライアントはdisplay-buffer-reuse-window
だが、ウィンドウの再利用を試みる他のすべてのアクション関数も同様に影響を受ける。display-buffer-in-previous-window
はバッファーを以前に表示していたウィンドウを別フレーム上で検索する際にこれを参照する。
inhibit-switch-frame
非nil
値の場合には、display-buffer
により選択されたウィンドウがすでに表示されていれば別のフレームのraiseや選択を抑制する。これにより主に影響を受けるのはdisplay-buffer-use-some-frame
とdisplay-buffer-reuse-window
。理想的にはdisplay-buffer-pop-up-frame
も同様に影響を受けるべきだが、ウィンドウマネージャーがこれに準拠する保証はない。
window-parameters
値は選択したウィンドウに与えるウィンドウパラメーターのalist。ウィンドウを選択するすべてのアクション関数は、このエントリーを処理する必要がある。
window-min-width
値は使用するウィンドウの最小幅をフレームの正準列で指定する。特別な値full-width
は、そのフレームにおいて左右に他のウィンドウがないウィンドウを選択することを意味する。
このエントリーに影響を受けるのは現在のところdisplay-buffer-use-some-window
、およびdisplay-buffer-use-least-recent-window
(最近使用されていないウィンドウのリターンにおいてこのエントリーを満足しないようなウィンドウのリターンをより厳格に回避する)。
このようなエントリーを単独で提供しても、ウィンドウがその値で指定した幅になるとは限らないことに注意。既存ウィンドウを実際にリサイズしたり新たなウィンドウの幅を指定した値にするためには、同様にこの値を指定するwindow-width
エントリーを提供する必要がある。しかしこのようなwindow-width
エントリーでまったく異なる値を指定したり、ウィンドウ幅をバッファーにフィットするように要請することができる。そのような場合にはwindow-width
使用するウィンドウの最小幅にたいする保証を与える。
window-min-height
値は使用するウィンドウの最小高さをフレームの正準行で指定する。特別な値full-height
は、そのフレームにおいて上下に他のウィンドウがないウィンドウを選択することを意味する。
このエントリーは現在のところdisplay-buffer-below-selected
(このエントリーで指定された高さより低いウィンドウは使用しない)に影響を与える。更にdisplay-buffer-use-some-window
、およびdisplay-buffer-use-least-recent-window
(最近使用されていないウィンドウのリターンにおいてこの制約を満足しないようなウィンドウのリターンをより厳格に回避する)にも影響を与える。
このようなエントリーを単独で提供しても、ウィンドウがその値で指定した高さになるとは限らないことに注意。既存ウィンドウを実際にリサイズしたり新たなウィンドウの高さを指定した値にするためには、同様にこの値を指定するwindow-height
エントリーを提供する必要がある。しかしこのようなwindow-height
エントリーでまったく異なる値を指定したり、ウィンドウ高さをバッファーにフィットするように要請することができる。そのような場合にはwindow-min-height
使用するウィンドウの最小高さにたいする保証を与える。
window-height
値は選択したウィンドウの高さを調節するかとその方法を指定する。以下のいずれか:
nil
は選択したウィンドウの高さを変更しないことを意味する。
body-lines
、CDRが選択されたウィンドウのボディー高さをフレーム行数で指定する整数であるようなコンスセル。
fit-window-to-buffer
とshrink-window-if-larger-than-buffer
。ウィンドウのリサイズを参照のこと。
慣例により選択したウィンドウの高さは、そのウィンドウが垂直コンビネーション(ウィンドウとフレームを参照)の一部であり、他の無関係のウィンドウの高さの変更を避ける場合のみ調整される。さらにこのエントリーはこのリストの後に指定する特定の条件下でのみ処理される必要がある。
window-width
これは上述のwindow-height
と同様だが、かわりに選択したウィンドウの幅の調節に使用される。値は以下のいずれか:
nil
は選択したウィンドウの幅を変更しないことを意味する。
body-columns
、CDRが選択されたウィンドウのボディー幅をフレーム列数で指定する整数であるようなコンスセル。
window-size
これは前の2つを組み合わせたエントリーであり、選択したウィンドウの高さと幅の両方の調節に用いることができる。他のウィンドウに影響を与えずにウィンドウをリサイズできる方向は1つだけなので、window-size
はフレーム上に単独で表示されるウィンドウのサイズのセットアップでのみ効果的である。値は以下のいずれか:
nil
は選択したウィンドウのサイズを変更しないことを意味する。
body-chars
、CDRが2つの整数からなるコンスセル(選択したウィンドウの望ましい幅と高さをフレームの行数と列数で指定)であるようなコンスセル。これに応じてフレームのサイズを調節する効果がある。
このエントリーはこのリストのすぐ下で指定されている特定の条件の下で処理される必要がある。
dedicated
このようなエントリーが非nil
なら、display-buffer
は作成するすべてのウィンドウをそのバッファー専用であるとマークする(専用のウィンドウを参照)。これは最初の引数に選択したウィンドウ、2つ目の引数にエントリーの値を指定してset-window-dedicated-p
を呼び出すことにより行われる。サイドウィンドウはデフォルトでは値side
で専用となる(サイドウィンドウのオプションと関数を参照)。
preserve-size
このようなエントリーが非nil
なら、選択したウィンドウのサイズを維持するようにEmacsに指示する(ウィンドウサイズの保持を参照)。値は(t . nil)
(ウィンドウの幅を維持)、(nil . t)
(高さを維持)、または(t . t)
(幅と高さの両方を維持)のいずれか。このエントリーはこのリストの後に指定する特定の条件下でのみ処理される必要がある。
lru-frames
値はバッファーの表示に使用可能なウィンドウを検索するフレームを指定する。display-buffer-use-some-window
、およびdisplay-buffer-use-least-recent-window
が最近使用されていない別のバッファーを表示中のウィンドウを探す際に参照される。値は上述のreusable-frames
エントリーと同様。
lru-time
値には使用時間(use time)の指定が求められる(ウィンドウの選択を参照)。このエントリーはdisplay-buffer-use-some-window
、およびdisplay-buffer-use-least-recent-window
が最近使用されていない別のバッファーを表示中のウィンドウを探す際に参照される。これらの関数はバッファーの表示において、このオプションで指定された値より長い使用時間をもつウィンドウを勘定に入れない。
bump-use-time
このエントリーが非nil
なら、display-buffer
が使用するウィンドウの使用時間(ウィンドウの選択を参照)を増加させる。これにより後刻display-buffer-use-some-window
やdisplay-buffer-use-least-recent-window
のようなアクション関数が別のバッファーを表示する際に、このウィンドウが使用されることが回避される筈である。
このエントリーの使用とアクション関数display-buffer-use-least-recent-window
の使用の間には僅かな違いが存在する。後者の呼び出しは、この関数がバッファーの表示に使用するウィンドウの使用時間だけを増加させることを意味する。ここで説明しているエントリーには、display-buffer
がバッファーの表示に使用するすべてのウィンドウの使用時間を増加させるという意味をもつ。
pop-up-frame-parameters
この値は新たにフレームが作成された場合に与えるフレームパラメーターのalist。display-buffer-pop-up-frame
がけが参照する。
parent-frame
値は子フレームにバッファーを表示時に使用する親フレームを指定する。このエントリーを使用するのはdisplay-buffer-in-child-frame
のみ。
child-frame-parameters
値は子フレームにバッファー表示時に使用するフレームパラメーターのalistを指定する。このエントリーを使用するのはdisplay-buffer-in-child-frame
のみ。
side
値はバッファーを表示する新たなウィンドウを、フレームやバッファーのどのサイドに作成するかを示す。このエントリーは新たなサイドウィンドウをフレームのどのサイドに配置するかを示すためにdisplay-buffer-in-side-window
が使用する(サイドウィンドウへのバッファーの表示を参照)。さらに新たなサイドウィンドウを既存ウィンドウのどのサイドに配置するかを示すためにdisplay-buffer-in-atom-window
にも使用される(アトミックウィンドウを参照)。
slot
値が非nil
ならバッファーを表示するサイドウィンドウのスロットを指定する。このエントリーを使用するのはdisplay-buffer-in-side-window
のみ。
direction
この値はwindow
エントリーとともに、display-buffer-in-direction
がバッファーを表示するウィンドウ位置を決定するための方向を指定する。
window
値はdisplay-buffer
で選択されたウィンドウと何らかの関連があるウィンドウを指定する。このエントリーは現在のところ新たなウィンドウが作成されるサイドのウィンドウを示すためにdisplay-buffer-in-atom-window
が使用する。これは結果のウィンドウが出現する側の参照ウィンドウを指定するためにdisplay-buffer-in-direction
も使用する。
allow-no-window
値が非nil
ならdisplay-buffer
は必ずしもバッファーを表示する必要はなく、呼び出し側はそれを受け入れる準備がある。display-buffer
の任意の呼び出し手がバッファーを表示するウィンドウが存在しないケースを処理できる保証がないので、、このエントリーはユーザーのカスタマイゼーションを意図したものではない。このエントリーを考慮するアクション関数はdisplay-buffer-no-window
のみ。
body-function
値は1つの引数(表示されるウィンドウ)を受け取る関数でなければならない。この関数は表示されるウィンドウのサイズに応じて、表示されるウィンドウのbodyを何らかのコンテンツで充填するために使用できるかもしれない。これはバッファー表示の後、かつ挿入したコンテンツに適合するようにリサイズを適用できるwindow-height
、window-width
、preserve-size
の開始の前に呼び出される。
慣例によりエントリーwindow-height
、window-width
、preserve-size
は選択したウィンドウのバッファーのセットアップ後、かつそのウィンドウが以前に他のバッファーを表示していない場合のみ適用されます。後者はより正確にはカレントのdisplay-buffer
呼び出しによりウィンドウが作成されたか、以前にそのバッファーを表示するためにdisplay-buffer
によりウィンドウが作成されて、カレントのdisplay-buffer
呼び出しによる再利用まで他のバッファーの表示に使用されたことがないことを意味します。
window-height
、window-width
、あるいはwindow-size
のエントリーが何も指定されていない場合でも、そのバッファーが一時的なバッファーであり、かつtemp-buffer-resize-mode
有効ならウィンドウは依然としてリサイズされる可能性があります。一時的な表示を参照してください。このような場合には特定のバッファーやdisplay-buffer
呼び出しにたいするtemp-buffer-resize-mode
のデフォルトの挙動の抑制やオーバーライドにwindow-height
、window-width
、あるいはwindow-size
といったエントリーのCDRを用いることができます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のユーザーオプションでバッファーのディスプレイアクション(バッファーを表示するウィンドウの選択を参照)の振る舞いをさらに変更することができます。
この変数の値が非nil
なら、display-buffer
は表示のために既存のバッファーを分割して新たなウィンドウを作成できる。
この変数は後方互換のためだけに提供される。このオプションの値が非nil
のときはアクション関数display-buffer-pop-up-window
(バッファー表示用のアクション関数を参照)を呼び出すだけのdisplay-buffer-fallback-action
内の特別なメカニズムを経由してdisplay-buffer
にしたがう。この変数はdisplay-buffer-alist
等により直接指定できるdisplay-buffer-pop-up-window
自体からは参照されない。
この変数は、バッファーを表示する新たなウィンドウを作成するための、ウィンドウを分割する関数を指定する。これは、実際にウィンドウを分割するために、アクション関数display-buffer-pop-up-window
により使用される。
値はウィンドウを単一の引数とする関数でなければならず、(要求されたバッファーを表示するために使用される)新たなウィンドウ、またはnil
(分割の失敗を意味する)をリターンしなければならない。デフォルト値はsplit-window-sensibly
(次に説明)。
この関数は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-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
により使用される。
値はフレーム、またはフレームを作成できなかったらnil
をリターンする引数をとらない関数であること。デフォルト値はpop-up-frame-alist
(以下参照)により指定されるパラメーターを使用してフレームを作成する関数。
この変数はフレームを新たに作成するためのpop-up-frame-function
で指定される関数が使用するフレームパラメーター(フレームのパラメーターを参照)のalistを保持する。デフォルトはnil
。
このオプションは後方互換のためだけに提供される。これはdisplay-buffer-pop-up-frame
がpop-up-frame-function
の指定する関数を呼び出す際に、すべてのアクションalistのpop-up-frame-parameters
エントリーの値に前置されるので、アクションalistのエントリーが指定する値がpop-up-frame-alist
の対応する値を効果的にオーバーライドすることに注意。
したがってユーザーはpop-up-frame-alist
をカスタマイズするのではなく、display-buffer-alist
noアクションalistのpop-up-frame-parameters
エントリーをセットアップするべきである。ユーザーが指定したパラメーターの値だけが、display-buffer
の呼び出し手が指定したパラメーターの値をオーバーライドするこが保証されている。
display-buffer
のデザインではpop-up-windows
、pop-up-frames
、pop-up-frame-alist
、same-window-buffer-names
、same-window-regexps
のような古いオプションを使用するコードにたいする保守に互換性を与えるために多くの努力が払われています。Lispプログラムやユーザーはこれらのオプションの使用は控えるべきです。上述のようにpop-up-frame-alist
のカスタマイズにたいしては警告済みです。ここでは残りのオプションではなくディスプレイアクションを使用するように変換する方法を説明します。
pop-up-windows
¶この変数のデフォルトはt
。これをnil
にカスタマイズしてdisplay-buffer
に何を行うべきではないかを指示するよりも、かわりに試みるべきアクション関数をdisplay-buffer-base-action
内にリストするほうがよい。たとえば:
(setopt display-buffer-base-action '((display-buffer-reuse-window display-buffer-same-window display-buffer-in-previous-window display-buffer-use-some-window)))
pop-up-frames
¶この変数をt
にカスタマイズするのではなく、たとえば以下のようにdisplay-buffer-base-action
をカスタマイズすること:
(setopt display-buffer-base-action '((display-buffer-reuse-window display-buffer-pop-up-frame) (reusable-frames . 0)))
same-window-buffer-names
¶same-window-regexps
これらのオプションのいずれかにたいしてバッファー名や正規表現を追加するかわりに、そのバッファーにたいしてアクション関数display-buffer-same-window
を指定するdisplay-buffer-alist
エントリーを使用すること。
(setopt display-buffer-alist (cons '("\\*foo\\*" (display-buffer-same-window)) display-buffer-alist))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
これまでのサブセクションによってバッファーを表示するためには、display-buffer
にいくつかのディスプレイアクションを提供しなければならないことがわかりました(バッファーを表示するウィンドウの選択を参照)。まったくカスタマイズしていないEmacsでは、これらのアクションはdisplay-buffer-fallback-action
によってウィンドウの再利用、同一フレーム上での新たなウィンドウのポップアップ、そのバッファーを以前に表示したウィンドウの使用、新たなフレームをポップアップして何らかのウィンドウを使用するという優先順で指定されます(display-buffer-fallback-action
いより命名される残りのアクションは未カスタマイズのEmacsではvoidであることに注意)。
以下のフォームを考えてください:
(display-buffer (get-buffer-create "*foo*"))
このフォームをカスタマイズされていないEmacsの*scratch*バッファーで評価すると、通常はすでに*foo*を表示しているウィンドウの再利用は失敗しますが、新たなウィンドウのポップアップは成功するでしょう。そこで同じフォームを再度評価すると、今度はdisplay-buffer
はすでに*foo*を表示しているウィンドウを再利用して視覚的な変化は生じません。なぜならそれは許容され得るアクションであるとともに、すべての許容され得るアクションの中でもっとも高い優先度をもつからです。
選択されたフレームに十分なスペースがなければ、新たなウィンドウのポップアップは失敗します。カスタマイズされていないEmacsでは、通常はフレームに2つのウィンドウがすでに存在すれば失敗します。たとえば今度はC-x 1の後にC-x 2をタイプしてからもう一度フォームを評価すると、*foo*は下側のウィンドウに表示されるはずです(
display-buffer
は単に“何らか”のウィンドウを使用した)。C-x 2をタイプする前にC-x oをタイプしていれば、*foo*は上側のウィンドウに表示されるでしょう。なぜなら“何らか”のウィンドウとは“最近もっとも使用されていない”ウィンドウという意味であり、選択されたウィンドウが最近もっとも使用されていないウィンドウになるのは、それがフレームで唯一のウィンドウの場合だけだからです。
C-x oをタイプせずに*foo*が下側のウィンドウに表示されているとしましょう。下側のウィンドウに移動するためにC-x oの後にC-x leftをタイプして、再びフォームを評価してみます。すると*foo*は同じ下側のウィンドウに表示されるはずです。なぜなら*foo*は以前にそのウィンドウで表示されているので何らかのウィンドウのかわりにそのウィンドウが選択されるからです。
ここまではカスタマイズしていないEmacsのデフォルトの動作を観察してきました。この動作のカスタマイズの仕方を確認するために、オプションdisplay-buffer-base-action
について考えてみましょう。これは概念的に任意のバッファーの表示に影響を与える、非常に大まかなカスタマイズを提供します。これはdisplay-buffer-fallback-action
により提供されるアクションの並び替えや、提供されていないもののユーザーの編集方法により密接に適合するアクションを追加することにより、display-buffer-fallback-action
の補強に使用することができます。しかしデフォルトの動作をより深く変更するためにも使用できます。
ルールとして別フレームにバッファーを表示することを好むユーザーを考えてみましょう。そのようなユーザーなら以下のようなカスタマイズを行うかもしれません:
(setopt display-buffer-base-action '((display-buffer-reuse-window display-buffer-pop-up-frame) (reusable-frames . 0)))
このセッティングによりdisplay-buffer
はバッファーを表示するウィンドウを探すために、まず可視のフレームとアイコン化されたフレームを探して、そのようなフレームが存在しなければ新たなフレームをポップアップします。グラフィカルなシステム上で*scratch*を表示しているウィンドウでC-x 1をタイプして例のdisplay-buffer
フォームを評価して動作を観察できます。これは通常はルートウィンドウに*foo*を表示するフレームを新たに作成(およびフォーカスを付与)します。このフレームをアイコン化して例のフォームを再度評価すると、display-buffer
は新たなフレーム(通常はフレームをraiseしてフォーカスを付与)のウィンドウを再利用するでしょう。
display-buffer
は新たなフレームの作成に失敗した場合のみdisplay-buffer-fallback-action
が提供するアクション(ウィンドウ再利用の再試行、新たなウィンドウのポップアップ等)を適用します。以下のフォームでフレーム作成を簡単に失敗させることができます:
(let ((pop-up-frame-function 'ignore)) (display-buffer (get-buffer-create "*foo*")))
新たなフレーム作成に失敗してかわりにフォールバックアクションの使用を観察した直後にこのフォームを忘れてしまうでしょう。
display-buffer-base-action
のカスタマイズにおいてdisplay-buffer-reuse-window
は冗長に思えることに注意してください。なぜならすでにdisplay-buffer-reuse-window
はdisplay-buffer-fallback-action
の一部であり、いずれにせよフォールバックアクションで試みられるはずだからです。しかしこれはdisplay-buffer-pop-up-frame
が優先順ですでに優っていた時点で、display-buffer-base-action
がdisplay-buffer-fallback-action
より優先されることにより失敗するでしょう。実際のところ:
(setopt display-buffer-base-action '(display-buffer-pop-up-frame (reusable-frames . 0)))
はdisplay-buffer
が常に新たなフレームをポップアップして、これはおそらくユーザーが望んでいない動作です。
ここまではユーザーがdisplay-buffer
のデフォルト動作をカスタマイズする方法だけを示しました。今度はアプリケーションがdisplay-buffer
の動作を変更する方法について見てみましょう。これを行う正規の手順はdisplay-buffer
やpop-to-buffer
のようなdisplay-buffer
を呼び出す関数のaction引数を使用する方法です(ウィンドウ内のバッファーへの切り替えを参照)。
あるアプリケーションが(新たなウィンドウにユーザーを即座に注目させるために)可能なら選択されたウィンドウの下、それが失敗したらフレームの最下ウィンドウにに*foo*を表示したいと仮定してみましょう。これは以下のような呼び出しで行うことができます:
(display-buffer (get-buffer-create "*foo*") '((display-buffer-below-selected display-buffer-at-bottom)))
この新しい変更されたフォームがどのように機能するか確認するために*foo*を表示しているすべてのフレームを削除してから、*scratch*を表示中のウィンドウでC-x 1の後にC-x 2をタイプしてから、続けてそのフォームを評価してみてください。display-buffer
は上側のウィンドウを分割して、新たなウィンドウに*foo*を表示するはずです。C-x 2の後にC-x oをタイプした場合には、display-buffer
はかわりに最下にあるウィンドウを分割するでしょう。
今度は新たなフォームを評価する前に、(たとえば選択されたウィンドウで(fit-window-to-buffer)
を評価して)選択されたウィンドウを可能なかぎり小さくしたとします。この場合にはdisplay-buffer
は選択されたウィンドウの分割に失敗して、フレームの最下に効果的に*foo*を表示するために、かわりにフレームのルートウィンドウを分割するでしょう。
いずれの場合においても新たなフォームの2回目の評価では、すでに*foo*を表示しているウィンドウの再利用を試みるはずです。これはaction引数が提供するどちらの関数も、そのようなウィンドウの使用を最初に試みるからです。
action引数をセットすることにより、アプリケーションはdisplay-buffer-base-action
のすべてのカスタマイゼーションを効果的に無効にします。今度はユーザーはアプリケーションの選択を受け入れるか、以下のようにオプションdisplay-buffer-alist
をさらにカスタマイズすることができます:
(setopt display-buffer-alist '(("\\*foo\\*" (display-buffer-reuse-window display-buffer-pop-up-frame))))
*foo*がどこにも表示されていない設定で新たな変更版のフォームを試みると、display-buffer
のactionを完全に無視して別フレームに*foo*が表示されます。
display-buffer-alist
の仕様において,reusable-frames
アクションalistの指定を気にしていない点に注意してください。display-buffer
は常に最初に見つかったウィンドウ、この場合ではdisplay-buffer-base-action
で指定されたウィンドウを採用します。しかし異なる仕様を使用したいとき、たとえば再利用可能なウィンドウから*foo*を表示中のアイコン化されたフレームを除外したければ個別にそれを指定する必要があります:
(setopt display-buffer-alist '(("\\*foo\\*" (display-buffer-reuse-window display-buffer-pop-up-frame) (reusable-frames . visible))))
これを試せば繰り返し*foo*の表示を試みた場合に、フレームが可視のときだけフレームの再利用に成功することに気がつくでしょう。
上記の例によりアプリケーションが選択したaction引数を無視するという単一の目的にたいしてユーザーがdisplay-buffer-alist
をカスタマイズできるという結論が導かれるかもしれません。そのような結論は正しくありません。display-buffer-alist
は表示がaction引数によってもガイドされるかどうかに関わらず、ユーザーが好む方法で特定のバッファーの表示方法を指示するための標準オプションです。
しかし2つの主要な観点から、display-buffer-alist
のカスタマイズはdisplay-buffer-base-action
のカスタマイズとは異なると合理的に結論づけることができます。display-buffer-alist
のカスタマイズはdisplay-buffer
のaction引数をオーバーライドして、影響を受けるバッファーを明示的に指定できることからより強力です。実際のところ*foo*のカスタマイズによって他のバッファーの表示には何も影響がありません。たとえば、
(display-buffer (get-buffer-create "*bar*"))
はdisplay-buffer-base-action
とdisplay-buffer-fallback-action
のセッティングだけに管理されます。
ここで例を止めることもできますが、Lispプログラムにはdisplay-buffer-alist
にたいする任意のカスタマイズの無効化に使用できる取って置きの切り札があります。その切り札display-buffer-overriding-action
は以下のようにdisplay-buffer
呼び出しの前後でバインドすることができます:
(let ((display-buffer-overriding-action '((display-buffer-same-window)))) (display-buffer (get-buffer-create "*foo*") '((display-buffer-below-selected display-buffer-at-bottom))))
このフォームの評価により通常はaction引数や任意のユーザーカスタマイゼーションとは無関係に、選択されたウィンドウに*foo*が表示されます(通常はアプリケーションがactionを提供する必要もないが、ここではオーバーライドされる事実を示すために提供されている)。
ここで提供したカスタマイゼーションで*foo*の表示を試みたアクション関数のリストを調べれば、それが実例になるかもしれません。そのリスト(何がそれを追加したかと後続の要素を含む)は:
(display-buffer-same-window ;; `display-buffer-overriding-action' display-buffer-reuse-window ;; `display-buffer-alist' display-buffer-pop-up-frame display-buffer-below-selected ;; ACTION argument display-buffer-at-bottom display-buffer-reuse-window ;; `display-buffer-base-action' display-buffer-pop-up-frame display-buffer--maybe-same-window ;; `display-buffer-fallback-action' display-buffer-reuse-window display-buffer--maybe-pop-up-frame-or-window display-buffer-in-previous-window display-buffer-use-some-window display-buffer-pop-up-frame)
ここで列挙した内部関数の中でdisplay-buffer--maybe-pop-up-frame-or-window
が実際にdisplay-buffer-pop-up-window
を実行しているにも関わらず、display-buffer--maybe-same-window
が効果的に無視されていることに注意してください。
アクション関数の各呼び出しにおいて渡されるアクションalistは:
((reusable-frames . visible) (reusable-frames . 0))
これは上述のdisplay-buffer-alist
の2つ目の仕様を使用して、display-buffer-base-action
が提供する仕様をオーバーライドすることを示しています。これをユーザーが以下のように記述したと考えてみましょう
(setopt display-buffer-alist '(("\\*foo\\*" (display-buffer-reuse-window display-buffer-pop-up-frame) (inhibit-same-window . t) (reusable-frames . visible))))
この場合にはalistのinhibit-same-window
エントリーはdisplay-buffer-overriding-action
からdisplay-buffer-same-window
仕様を成功裏に無効化して、display-buffer
は別フレームに*foo*を表示するでしょう。この点においてdisplay-buffer-overriding-action
をより堅牢にするためには、アプリケーションはたとえば以下のように適切なinhibit-same-window
エントリーも指定する必要があるでしょう:
(let ((display-buffer-overriding-action '(display-buffer-same-window (inhibit-same-window . nil)))) (display-buffer (get-buffer-create "*foo*")))
最後の例ではバッファーを表示するウィンドウの選択で説明したようにアクション関数の優先順は固定ではあるものの、優先順で低位のディスプレイアクションが指定したアクションalistのエントリーが、より高位のディスプレイアクションの実行に影響を与えれれることを示しています。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレームのもっとも単純な形式では常にバッファー表示に使用可能な単一のウィンドウが収容されています。結果としてdisplay-buffer
のもっとも最近の呼び出しは、常にそのウィンドウへのバッファーの配置に成功した呼び出しとなります。
そのようなフレームを処理することは実際的ではないので、デフォルトではEmacsはフレームサイズのデフォルト値、split-height-threshold
やsplit-width-threshold
のオプションにより制御される、より複雑なレイアウトを許容しています。そのフレームでまだ表示されていないバッファーを表示すると、フレーム上の単一ウィンドウを分割するか、2つのウィンドウのいずれかを(再)利用します。
これらのしきい値のいずれかをカスタマイズしたり手動でフレームのレイアウトを変更するとデフォルトの動作は棄却されます。非nil
のaction引数でdisplay-buffer
を呼び出したり、前のサブセクションに示したオプションのいずれかをユーザーがカスタマイズした際にもデフォルト動作は棄却されます。display-buffer
を習得次第、表示可能なディスプレイアクションとフレイムレイアウト結果の膨大さにフラストレーションを覚えるかもしれません。
しかしバッファー表示関数の使用を控えてウィンドウのウィンドウの分割と削除のメタファーに逆行するのは良い考えではありません。Lispプログラムやユーザーにたいしてバッファー表示関数は、異なるニーズを調整するフレームワークを提供します。ウィンドウの分割と削除にたいする同等なフレームワークは存在しません。バッファー表示関数ではフレームからバッファーを削除する際に、少なくともフレームレイアウトを部分的に後からリストアすることが可能です(ウィンドウのquitを参照)。
上述したフラストレーションを埋め合わせるとともに、文字通りフレームのウィンドウ間でバッファーが失われることを避けるために、以下にいくつのガイダンスを示します。
ディスプレイアクションの記述はアクション関数とアクションalistを1つの巨大なリストにまとめる必要があるので多大な苦痛をともなう恐れがある(歴史的な理由によってdisplay-buffer
の引数として個別にサポートすることができなかった)。以下のリストのような基本形式を覚えておくと便利かもしれない:
'(nil (inhibit-same-window . t))
アクション関数なしのアクションalistエントリーだけを指定する。これの唯一の目的は、どこかで指定されたdisplay-buffer-same-window
関数が同一ウィンドウ内でのバッファー表示を抑制すること。前のサブセクションの最後の例も参照のこと。
'(display-buffer-below-selected)
一方こちらは1つのアクション関数と空のアクションalistを指定する。上記2つの指定の効果を1つ組み合わせるためには以下のようなフォームを記述
'(display-buffer-below-selected (inhibit-same-window . t))
別のアクション関数の追加は以下のように記述
'((display-buffer-below-selected display-buffer-at-bottom) (inhibit-same-window . t))
別のアクションalistを追加するには以下のように記述
'((display-buffer-below-selected display-buffer-at-bottom) (inhibit-same-window . t) (window-height . fit-window-to-buffer))
最後のフォームは以下の方法によりdisplay-buffer
のaction関数に使用できる:
(display-buffer (get-buffer-create "*foo*") '((display-buffer-below-selected display-buffer-at-bottom) (inhibit-same-window . t) (window-height . fit-window-to-buffer)))
display-buffer-alist
のカスタマイズでは以下のように使用できる:
(setopt display-buffer-alist '(("\\*foo\\*" (display-buffer-below-selected display-buffer-at-bottom) (inhibit-same-window . t) (window-height . fit-window-to-buffer))))
2つ目のバッファーへのカスタマイズを追加するには以下のように記述:
(setopt display-buffer-alist '(("\\*foo\\*" (display-buffer-below-selected display-buffer-at-bottom) (inhibit-same-window . t) (window-height . fit-window-to-buffer)) ("\\*bar\\*" (display-buffer-reuse-window display-buffer-pop-up-frame) (reusable-frames . visible))))
display-buffer-alist
とdisplay-buffer-base-action
はユーザーオプションであって、Lispプログラムはそれらのセットやリバインドを行ってはならない。一方でdisplay-buffer-overriding-action
はアプリケーション用に予約されていて滅多に使用されず、使用する場合には細心の注意を払うこと。
display-buffer
の旧実装では、pop-up-frames
やpop-up-windows
のようなユーザーオプションのセッティングをめぐってユーザーとアプリケーションの競合が頻発した(バッファー表示の追加オプションを参照)。これがdisplay-buffer
を再デザイン(ユーザーおよびアプリケーションにたいして何を行うことが許容されているかを指定する明快なフレームワークを提供する)した主な理由である。
Lispプログラムはユーザーのカスタマイゼーションによって予期せぬ方法でバッファーが表示されるかもしれないことに備えなければならない。display-buffer
の後続の振る舞いにおいてaction引数で要求した方法でバッファーが正確に表示されていると仮定しないこと。
ユーザーは任意のバッファーが表示される方法について厳しすぎる制限を過度に多く設けるべきではない。さもないと特定の目的でバッファーを表示する際の特性を失うリスクがある。横並びの2つのウィンドウでバッファーの異なるバージョンを比較するLispプログラムを記述するとしよう。display-buffer-alist
のカスタマイズによりそのようなすべてのバッファーは常に選択されたウィンドウの下に表示されるように定められていたら、display-buffer
を通じて望ましいウィンドウ構成を構成するのはプログラムにとって困難だろう。
任意のバッファーを表示するための設定を指定するためには、ユーザーはdisplay-buffer-base-action
をカスタマイズする必要がある。複数のフレームで作業を行うことを好むユーザーについての例は前のサブセクションを参照のこと。display-buffer-alist
は特定のバッファーを特定の方法で表示するために予約済みである。
一般的にユーザーとLispプログラムにとって、ウィンドウがすでに対象となるバッファーを表示していて、それを再利用するのは常に良いアイデアである。前のサブセクションではバッファーを表示しているフレームがすでに存在していても、正しく行うことに失敗するとdisplay-buffer
が継続的に新たなフレームをポップアップすることを示した。たとえばバッファーの異なる部分をそのウィンドウで表示する必要がある際のように、少数のケースにおいてはウィンドウの再利用は望ましくないかもしれない。
したがってdisplay-buffer-reuse-window
はaction引数とカスタマイゼーションの両方で可能なかぎり使用するべきアクション関数の1つである。action引数のinhibit-same-window
エントリーは、通常はバッファーをを表示中のウィンドウ、つまり対象となるウィンドウが選択されたウィンドウならそのウィンドウの再利用を避けるような、一般的なケースのほとんどを考慮する。
これは複数フレームで作業を行う人にとっては思考を要しない。バッファーを表示中のフレームは自動的にraiseされてinhibit-switch-frame
が禁じていなければフォーカスを取得する。単一フレームのユーザーにとっては、このタスクは顕著に困難になり得る。この点において特にdisplay-buffer-pop-up-window
とdisplay-buffer-use-some-window
が厄介になる可能性がある。これらは表面上は任意に見えるウィンドウ(最大のウィンドウか最近もっとも使用されていないウィンドウ)を分割または使用してユーザーの注意を逸らす。
したがってLispプログラムのいくつかは、たとえば新たなウィンドウに関して問いに答える場所として期待されるミニバッファーウィンドウの近傍にバッファーを表示するためにフレーム最下のウィンドウの選択を試みる。選択されたウィンドウは通常はすでにユーーザーの注意を喚起済みなので、入力とは無関係なアクションであるdisplay-buffer-below-selected
が好ましいかもしれない。
アプリケーションの多くは引数norecordに非nil
を指定してwith-selected-window
やselect-window
を呼び出すことによって生成されたウィンドウエクスカーション内部からdisplay-buffer
を呼び出す。これはほとんど常に間違った考えである。なぜならそのようなエクスカーション内部で選択されたウィンドウは、ユーザーに提示されているウィンドウ構成で選択されているウィンドウと通常は異なるから。
たとえばユーザーがalistにエントリーinhibit-same-window
を追加していたとすると、そのエントリーによってエクスカーションのスコープ内で選択されたウィンドウを回避するが、結果となる構成において選択されたウィンドウは回避しないだろう。たとえそのようなエントリーが追加されていなくても、結果として奇妙に振る舞うかもしれない。1つの生きたウィンドウを含んだフレームで以下のフォームを評価すると
(progn (split-window) (display-buffer "*Messages*"))
これは他のウィンドウが選択されたまま最下に*Messages*バッファーを表示する。次のフォームを評価すると
(with-selected-window (split-window) (display-buffer "*Messages*"))
これは最上ウィンドウに*Messages*を表示してそれを選択する(display-buffer
の場合は通常は選択しない)。
一方、以下のフォームを評価すると
(progn (split-window) (pop-to-buffer "*Messages*"))
これは*Messages*バッファーを正しく選択するが、次のフォーム
(progn (split-window) (with-selected-window (selected-window) (pop-to-buffer "*Messages*")))
こちらは異なる。
更に選択されたウィンドウの使用時間がすべてのウィンドウの中でもっとも長いことを期待するdisplay-buffer-use-some-window
やdisplay-buffer-use-least-recent-window
のようなアクション関数の呼び出しは、その仕様にしたがったウィンドウの生成に失敗するかもしれない。
したがってウィンドウ
エクスカーションの使用に依存するアプリケーションは、そのエクスカーションが終了するまでdisplay-buffer
の呼び出しの延期を試みるべきである。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウはそれぞれ、リスト内に以前表示されていたバッファーと、それらのバッファーがウィンドウから削除された順序を記憶しています。このヒストリーが、たとえばreplace-buffer-in-windows
(バッファーとウィンドウを参照)やウィンドウのquit (ウィンドウのquitを参照)の際に使用されます。このリストは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が表示されているフレームのバッファーリスト(バッファーリストを参照)からバッファーを表示する。
特定のバッファー、たとえば別ウィンドウに表示済みのバッファーへの切り替えを抑制するために、以下で説明するオプションswitch-to-prev-buffer-skip
を使用できる。同様にwindowのフレームがbuffer-predicate
パラメーター(バッファーのパラメーターを参照)をもつ場合には、この述語は特定のバッファーへの切り替えを抑制する。
このコマンドはwindow内の次バッファーに切り替える。つまりwindow内での最後のswitch-to-prev-buffer
コマンドの効果をアンドゥする。引数windowは生きたウィンドウであること。デフォルトは選択されたウィンドウ。
アンドゥ可能なswitch-to-prev-buffer
の直近の呼び出しが存在しなければ、この関数はwindowが表示されているフレームのバッファーリスト(バッファーリストを参照)からバッファーの表示を試みる。
windowのフレームのオプションswitch-to-prev-buffer-skip
とbuffer-predicate
(バッファーのパラメーターを参照)はswitch-to-prev-buffer
の場合のように、このコマンドに影響を与える。
デフォルトでは、switch-to-prev-buffer
とswitch-to-next-buffer
は他のウィンドウで表示済みのバッファーに切り替えることができます。この挙動をオーバーライドするために以下のオプションを使用できます。
この変数がnil
なら、switch-to-prev-buffer
は別のウィンドウに表示済みのバッファーを含むすべてのバッファーに切り替えることができる。
この変数が非nil
なら、switch-to-prev-buffer
は特定のバッファーへの切り替えを抑制する。以下の値を使用できる:
this
はswitch-to-prev-buffer
が動作するウィンドウをホストするフレームで表示中のバッファーに切り替えないことを意味する。
visible
は可視フレームで表示中のバッファーに切り替えないことを意味する。
t
は生きたフレームで表示中のバッファーに切り替えないことを意味する。
switch-to-prev-buffer
のwindow引数、switch-to-prev-buffer
が切り替えようとするバッファー、switch-to-prev-buffer
のbury-or-kill引数という3つの引数を受け取る関数。この関数が非nil
をリターンすると、switch-to-prev-buffer
は2つ目の引数で指定されたバッファーからの切り替えを抑制する。
コマンドswitch-to-next-buffer
は同様の方法でこのオプションにしたがう。このオプションに関数が指定されると、switch-to-next-buffer
は3つ目の引数を常にnil
にしてその関数を呼び出す。
switch-to-prev-buffer
はbury-buffer
、同じくreplace-buffer-in-windows
やquit-restore-window
が呼び出すので、このオプションをカスタマイズすることによりウィンドウのquitやバッファーがバリーやkillされる際のEmacsの挙動にも影響することに注意。
更にswitch-to-prev-buffer
やswitch-to-next-buffer
は特定の状況下、たとえばこれらの関数が切り替え可能なバッファーが1つしか残っていないときには、このオプションが無視されるかもしれないことにも注意。
このユーザーオプションは正規表現、または正規表現のリストであること。名前がこれらの正規表現にマッチするバッファーを、switch-to-prev-buffer
およびswitch-to-next-buffer
は無視する(切り替えるバッファーが他に存在しない場合を除く)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
特定のウィンドウがそのウィンドウのバッファーにたいして専用(dedicated)であるとマークすることにより、バッファーを表示する関数にそのウィンドウを使用しないように告げることができます。display-buffer
(バッファーを表示するウィンドウの選択を参照)は、他のバッファーの表示に専用バッファーを決して使用しません。
get-lru-window
とget-largest-window
(ウィンドウのサイクル順を参照)は、dedicated引数が非nil
のときは専用ウィンドウを候補とはみなしません。専用ウィンドウにたいする配慮に関してset-window-buffer
(バッファーとウィンドウを参照)の挙動は若干異なります。以下を参照してください。
ウィンドウからのバッファー削除、およびフレームからのウィンドウ削除を意図した関数は、処理するウィンドウが専用ウィンドウのときは特別な挙動を示す可能性があります。ここでは4つの基本ケース、すなわち(1)そのウィンドウがフレーム上で唯一のウィンドウの場合、(2)ウィンドウはフレーム上で唯一のウィンドウだが同一端末上に別のフレームがある場合、(3)そのウィンドウが同一端末上で唯一のフレームの唯一のウィンドウの場合、(4)
dedicated(専用ウィンドウ)の値がside
(サイドウィンドウへのバッファーの表示を参照)の場合を明確に区別することにします。
特にdelete-windows-on
(ウィンドウの削除を参照)は関連するフレームを削除する際にケース(2)を、フレーム上で唯一のウィンドウに他のバッファーを表示する際にケース(3)と(4)を処理します。バッファーが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
値と区別して扱わない。
適切なdedicated
アクションalistエントリー(バッファー表示用のアクションalistを参照)を与えることにより、display-buffer
が作成するウィンドウにたいしてそのバッファー専用であるとマークするよう指示することもできます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コマンドがスクリーンにバッファーを配置するためにdisplay-buffer
を使用した後に、ユーザーはそれを隠してEmacsディスプレイの以前の構成をリターンすることを選択できます。わたしたちはこれをウィンドウのquit(quitting
the
window)と呼びます。これを行うにはdisplay-buffer
が使用中のウィンドウが選択されたウィンドウである間にquit-window
を呼び出してください。
以前の表示の構成を正しくリストアする方法は、そのときバッファーが表示されているウィンドウにたいして何が行われたのかに依存します。ウィンドウの削除が正しいかもしれないし、フレームの削除やそのウィンドウに別のバッファーを単に表示することが正しいことなのかもしれません。難しいのは、そのバッファーを表示するという行為の後でユーザーがウィンドウ構成を変更しているかもしれず、ユーザーが明示的に要求したその変更をアンドゥするのは望ましくないということも1つの理由です。
quit-window
が正しく事を行うことができるように、display-buffer
はそのウィンドウのquit-restore
パラメーター(ウィンドウのパラメーターを参照)に行ったことに関する情報を保存します。
このコマンドはwindowをquitしてそのバッファーをバリーする。引数windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。プレフィックス引数killが非nil
ならバッファーをバリーするかわりにkillする。
まず関数quit-window
はquit-window-hook
を実行する。その後にウィンドウとそのバッファーを処理するために、厄介な処理をこなす関数quit-restore-window
(次に説明)を呼び出す。
かわりにquit-restore-window
を呼び出すことで、より多くの制御を得ることができます。
この関数はwindowのquit後にウィンドウとウィンドウのバッファーを処理する。オプション引数windowは生きたウィンドウでなければならず、デフォルトは選択されたウィンドウ。この関数はwindowのquit-restore
パラメーターを考慮する。
オプション引数bury-or-killにはwindowを処理する方法を指定し、以下の値が意味をもつ。
nil
これはバッファーを特別な方法で処理しないことを意味する。その結果としてwindowが削除されない場合には、switch-to-prev-buffer
の呼び出しにより通常はそのバッファーが再び表示されるだろう。
append
これはwindowが削除されない場合には、そのバッファーをwindowの前のバッファーのリスト(ウィンドウのヒストリーを参照)の最後に移動するので、将来のswitch-to-prev-buffer
呼び出しでこのバッファーには切り替わることは少なくなる。これはそのバッファーをフレームのバッファーリストの最後への移動も行う(バッファーリストを参照)。
bury
これはwindowが削除されない場合には、そのバッファーをwindowの前のバッファーリストから削除する。これはそのバッファーをフレームのバッファーリストの最後への移動も行う。これはswitch-to-prev-buffer
がそのバッファーをkillすることなく、このバッファーに再び切り替えさせないようにするもっとも信頼できる方法である。
kill
これはwindowのバッファーをkillすることを意味する。
引数bury-or-killはwindowがそのフレームで唯一のウィンドウであり、かつそのフレームの端末上に他のフレームが存在する場合には、windowを削除するべき際にはそのフレームに何を行うかも指定する。bury-or-killがkill
はフレームの削除を意味する。それ以外ではフレームの処遇はそのフレームを単一の引数とするframe-auto-hide-function
(以下参照)の呼び出しにより決定される。
この関数はウィンドウを削除しない場合には、windowのquit-restore
パラメーターに常にnil
をセットする。
ウィンドウwindowのquit-restore
パラメーター(ウィンドウのパラメーターを参照)はnil
、あるいは4要素のリストである必要があります:
(method obuffer owindow this-buffer)
1つ目の要素methodはwindow
、frame
、same
、other
の4つのシンボルのうちのいずれかです。frame
とwindow
はwindowを削除する方法、same
とother
はwindowへの別バッファーの表示を制御します。
具体的には、window
はそのウィンドウが特にdisplay-buffer
によって作成されたこと、frame
は別のフレームが作成されたこと、same
はこのウィンドウにはそのバッファーしか表示されていないこと、other
は以前は別のバッファーを表示していたことを意味します。
2つ目の要素obufferはwindow
、frame
のシンボルのいずれか、あるいは以下の形式のリストです
(prev-buffer prev-window-start prev-window-point height)
これはそれぞれ以前windowにどのバッファーが表示されていたか、その時点でのバッファーのウィンドウ開始(ウィンドウの開始位置と終了位置を参照)とウィンドウポイント(ウィンドウとポイントを参照)の位置、そしてwindowのその時点での高さです。windowのquit時にまだprev-bufferが生きていれば、ウィンドウのquitによってprev-bufferの表示にwindowが再利用されるかもしれません。
3つ目の要素owindowは表示が行われる直前に選択されていたウィンドウです。quitによってwindowが削除された場合にはowindowの選択を試みます。
4つ目の要素this-bufferは表示によってquit-restore
パラメーターをセットしたバッファーです。windowのquitではまだそのバッファーを表示している場合のみウィンドウを削除します。
windowのquitにおいては、(1) methodがwindow
かframe
のいずれかで、(2)
そのウィンドウに以前表示されていたバッファー履歴がなく、(3)
windowにカレントで表示されているバッファーがthis-bufferと等しい場合のみウィンドウの削除を試みます。windowがアトミックウィンドウ(アトミックウィンドウを参照)の一部の場合には、quitはかわりにそのアトミックウィンドウのルートウィンドウの削除を試みます。いずれのケースにおいてもwindowが削除できない場合は、エラーのシグナルの回避を試みます。
obufferがリストでprev-bufferがまだ生きていたら、quitすることによってobufferの残りの要素に応じたwindowにprev-bufferが表示されます。これにはthis-bufferを表示するために一時的にリサイズされていた場合にウィンドウをheightにリサイズすることが含まれます。
それ以外の場合には、以前に別のバッファーの表示にwindowが使用されていれば(ウィンドウのヒストリーを参照)、その履歴中でもっとも最近のバッファーが表示される。
以下のオプションはウィンドウを1つ含むフレームで、そのウィンドウをquitする際に正しく事を行うための関数を指定します。
このオプションで指定された関数は自動的にフレームを隠すために呼び出される。この関数はフレームを唯一の引数として呼び出される。
ここで指定される関数は選択されたウィンドウが専用(dedicated)であり、かつバリーされるバッファーを表示しているときにbury-buffer
(バッファーリストを参照)から呼び出される。またquitされるウィンドウのフレームがそのウィンドウのバッファーを表示するために特別に作成されたフレームで、かつそのバッファーがkillされないときにもquit-restore-window
(上記)から呼び出される。
デフォルトではiconify-frame
(フレームの可視性を参照)を呼び出す。かわりにフレームをディスプレイから削除するdelete-frame
(フレームの削除を参照)、フレームを不可視にするmake-frame-invisible
、フレームを変更せずに残すignore
、またはフレームを唯一の引数とする任意の関数のいずれかを指定できる。
このオプションで指定された関数は指定されたフレームが生きたウィンドウただ1つを含み、かつ同一端末上に少なくとも1つ他のフレームが存在する場合のみ呼び出されることに注意。
特定のフレームにたいしてここで指定した値は、そのフレームのフレームパラメーターauto-hide-function
でオーバーライドされるかもしれない(フレームとの相互作用のためのパラメーターを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
サイドウィンドウ(side window)とは、フレームのルートウィンドウ(ウィンドウとフレームを参照)の4辺のいずれかに位置する特別なウィンドウです。これは実際にはフレームのルートウィンドウ領域は、メインウィンドウとメインウィンドウ周囲のいくつかのサイドウィンドウに分割されることを意味します。メインウィンドウは“通常”の生きたウィンドウ、またはすべての通常ウィンドウを含んだ領域を指定します。
この形式のもっともシンプルな使用では、サイドウィンドウによって特定のバッファーを常にフレームの同一領域に表示することが可能です。したがってこれはdisplay-buffer-at-bottom
(バッファー表示用のアクション関数を参照)によって提供される概念を残りのサイド(訳注:
下辺以外)に一般化したものとみなすことができます。しかし適切にカスタマイズすることにより、いわゆる統合開発環境(IDE)で見い出されるようなフレームレイアウトを提供するためにも、サイドウィンドウを使用できます。
29.17.1 サイドウィンドウへのバッファーの表示 | サイドウィンドウへのバッファー表示のためのアクション関数。 | |
29.17.2 サイドウィンドウのオプションと関数 | サイドウィンドウの更なる調整。 | |
29.17.3 サイドウィンドウによるフレームのレイアウト | サイドウィンドウによるフレームレイアウトのセットアップ。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のdisplay-buffer
(バッファー表示用のアクション関数を参照)用のアクション関数は特定のバッファーを表示するためにサイドウィンドウの作成や再利用を行います。
この関数は選択されたフレームのサイドウィンドウにbufferを表示する。bufferの表示に使用したウィンドウをリターンする。そのようなウィンドウが見つからない、または作成できなければnil
をリターンする。
alistはdisplay-buffer
の場合と同様のシンボルと値からなる連想リスト。alist内で以下のシンボルはこの関数では特別な意味をもつ:
side
ウィンドウを配置するフレームのサイド(側面)を表す。有効な値はleft
、top
、right
、bottom
。未指定ならウィンドウはフレームの底部(bottom)に配置される。
slot
指定したウィンドウを配置するサイドのスロットを表す。値0は指定したサイドのおおよそ中央にウィンドウを配置する。負の値は中央スロットの前(上方か左方)、正の値は中央スロットの後(下方か右方)を意味する。つまり特定のサイド上にあるすべてのウィンドウはslot
の値の順になる。未指定ならウィンドウは指定したサイドの中央に配置される。
dedicated
サイドウィンドウにたいしては、dedicatedフラグ(専用のウィンドウを参照)は若干異なる意味をもつ。他のアクション関数によりdisplay-buffer
がそのウィンドウを使用することを防ぐために、サイドウィンドウ作成時にそのフラグは値side
にセットされる。この値はquit-window
、kill-buffer
、previous-buffer
、next-buffer
呼び出しの間保たれる。
一度セットアップされれば、サイドウィンドウにたいするswitch-to-prev-buffer
とswitch-to-next-buffer
(ウィンドウのヒストリーを参照)の挙動も変更されます。特にサイドウィンドウでは、これらのコマンドは以前にそのウィンドウに表示されたことのないバッファーの表示を抑制します。さらにすでにサイドウィンドウに表示されているバッファーの、通常の非サイドウィンドウでの表示も抑制します。後者ルールの明記するべき例外は、アプリケーションがバッファー表示後にバッファーのローカル変数をリセットしたときに発生します。quit-window
やkill-buffer
が常に削除して、最終的にprevious-buffer
とnext-buffer
の使用を防ぐためにこれらの規則をオーバーライドするには、この値にt
をセットするか、display-buffer-mark-dedicated
を通じて値を指定してください。
同一サイドの同一スロットに2つ以上の異なるバッファーすると、最後に表示されたバッファーが対応するウィンドウに表示される。したがってバッファー間で同じサイドウィンドウを共有するためにスロットを使用できる。
この関数はパラメーターwindow-side
とwindow-slot
をインストールして永続化する(ウィンドウのパラメーターを参照)。alist内のwindow-parameters
エントリーを通じて明示的に提供されない限り、他のウィンドウパラメーターは何もインストールしない。
デフォルトではサイドウィンドウはsplit-window
(ウィンドウの分割を参照)で分割できません。さらにサイドウィンドウはアクションのターゲットとして明示的に指定されていなければ、バッファーディスプレイアクション(バッファー表示用のアクション関数を参照)によって再利用や分割されることはありません。delete-other-windows
はサイドウィンドウをフレーム上で唯一ののウィンドウにできないことにも注意してください(ウィンドウの削除を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のオプションはサイドウィンドウ配置において更なる制御を提供します。
非nil
ならフレームの左右のサイドウィンドウはフレームの全高さを占有する。それ以外ならフレームの上下のサイドウィンドウはフレームの全幅を占有する。
このオプションはフレーム各サイドのサイドウィンドウの最大数を指定する。値は各フレームのサイドウィンドウのスロット数を左辺、上辺、右辺、下辺の順で指定する4要素のリスト。要素が数値なら対応するサイドで表示できる最大のウィンドウ数を意味する。要素がnil
ならそのサイドのスロット数に制限がないことを意味する。
指定された値のいずれかが0なら、対応するサイドへのウィンドウは作成できない。この場合にはdisplay-buffer-in-side-window
はエラーをシグナルしないがnil
をリターンする。指定した値が単にサイドウィンドウの追加作成を禁止する場合には、そのサイド上にあるもっとも適したウィンドウが再利用されて、それに応じてウィンドウのwindow-slot
も変更される。
このオプションは上や下のサイドウィンドウが逆順で表示されるかどうかを指定する。nil
ならフレームの上や下にあるサイドウィンドウはスロット値の増加にともない常に左から右に描画される。t
なら描画順は反転してフレームの上や下にあるサイドウィンドウはスロット値の増加にともない右から左に描画される。
これがbidi
なら描画順はフレームのメインウィンドウ内でもっとも最近選択されたウィンドウに表示されるバッファーのbidi-paragraph-direction
(双方向テキストの表示を参照)の値がright-to-left
の場合のみ逆順になる。このウィンドウを見つけるのが困難なときがあるかもしれないので、別のウィンドウ選択時に意図せず描画順が変更されることを避けるために経験則が使用される。
フレームの左右にあるサイドウィンドウのレイアウトは、この変数の値から影響を受けない。
以下の関数はサイドウィンドウをもつフレームのメインウィンドウをリターンします。
この関数は指定したframeのメインウィンドウをリターンする。オプション引数frameは生きたフレームでなければならず、デフォルトは選択されたフレーム。
frameにサイドウィンドウがなければframeのルートウィンドウをリターンする。それ以外ならframe上にある他のすべての非サイドウィンドウの系統元であるようなサイドウィンドウではない内部ウィンドウ、またはframeの単一の生きた非サイドウィンドウのいずれか。フレームのメインウィンドウはdelete-window
で削除できないことに注意。
以下のコマンドは指定したフレーム上にあるすべてのサイドウィンドウの外観を手軽にトグル(toggle: オンとオフを切り替える)できます。
この関数は指定されたframeのサイドウィンドウをトグルする。オプション引数frameは生きたフレームでなければならずデフォルトは選択されたframe。
frameに少なくとも1つのサイドウィンドウがあれば、このコマンドはframeのルートウィンドウの状態をframeのwindow-state
パラメーターに保存して、その後にframeのサイドウィンドウをすべて削除する。
frameにサイドウィンドウがなく、しかしwindow-state
パラメーターがあれば、このコマンドはパラメーターの値を使用してframeのメインウィンドウを残しつつframeのサイドウィンドウをリストアする。
frameにサイドウィンドウがなく保存した状態も見つからなければエラーをシグナルする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
サイドウィンドウは統合開発環境(IDE)が提供するような、より複雑なフレームレイアウトの作成に使用できます。そのようなレイアウトでは通常の編集アクティビティが行われるのはメインウィンドウ領域になります。サイドウィンドウは通常の意味においての編集は意図していません。それよりはカレント編集アクティビティを補足するためのファイルやタグやバッファーのリスト、ヘルプ情報、検索やgrepの結果、シェル出力などの情報の表示を意図しています。
そのようなフレームのレイアウトは以下のような外観になるでしょう:
___________________________________ | *Buffer List* | |___________________________________| | | | | | * | | * | | d | | T | | i | | a | | r | Main Window Area | g | | e | | s | | d | | * | | * | | | |_____|_______________________|_____| | *help*/*grep*/ | *shell*/ | | *Completions* | *compilation* | |_________________|_________________| | Echo Area | |___________________________________|
以下は上図フレームレイアウトを作成するコードをセットアップするためにdisplay-buffer-in-side-window
とともにウィンドウパラメーター(see ウィンドウのパラメーター) を使用する方法を説明するための例です。
(defvar parameters '(window-parameters . ((no-other-window . t) (no-delete-other-windows . t)))) (setq fit-window-to-buffer-horizontally t) (setq window-resize-pixelwise t) (setq display-buffer-alist `(("\\*Buffer List\\*" display-buffer-in-side-window (side . top) (slot . 0) (window-height . fit-window-to-buffer) (preserve-size . (nil . t)) ,parameters) ("\\*Tags List\\*" display-buffer-in-side-window (side . right) (slot . 0) (window-width . fit-window-to-buffer) (preserve-size . (t . nil)) ,parameters) ("\\*\\(?:help\\|grep\\|Completions\\)\\*" display-buffer-in-side-window (side . bottom) (slot . -1) (preserve-size . (nil . t)) ,parameters) ("\\*\\(?:shell\\|compilation\\)\\*" display-buffer-in-side-window (side . bottom) (slot . 1) (preserve-size . (nil . t)) ,parameters)))
これは固定化された名前をもつバッファーにたいしてdisplay-buffer-alist
エントリー(バッファーを表示するウィンドウの選択を参照)を指定します。特にフレーム上辺に高さ調節可能な*Buffer
List*と、フレーム右辺に幅調節可能な*Tags
List*の表示を要求します。さらにフレーム下辺左側のウィンドウでバッファー*help*と*grep*と*Completions*の共有、フレーム下辺右側のウィンドウではバッファー*shell*と*compilation*の表示を要求します。
ウィンドウの水平調節を可能にするためにオプションfit-window-to-buffer-horizontally
が非nil
値をもたなければならないことに注意してください。フレームの上下にあるサイドウィンドウの高さとフレームの左右にあるサイドウィンドウの幅を保持するためのエントリーも追加しています。フレーム最大化時にサイドウィンドウがそれに応じたサイズを維持することを保証するために、変数window-resize-pixelwise
に非nil
値をセットしています。ウィンドウのリサイズを参照してください。
最後のフォームではこれらの各ウィンドウにno-other-window
パラメーターをインストールすることによって、作成したサイドウィンドウにたいするC-x oを介してアクセスできないことも保証しています。さらにこれらの各ウィンドウにno-delete-other-windows
パラメーターをインストールして、C-x 1によるサイドウィンドウの削除ができないことを保証しています。
dired
バッファーは固定化された名前をもたないので、フレーム左辺の細いディレクトリーバッファーを表示するためにスペシャル関数dired-default-directory-on-left
を使用しています。
(defun dired-default-directory-on-left () "左側サイドウィンドウに詳細を隠して`default-directory'を表示する。" (interactive) (let ((buffer (dired-noselect default-directory))) (with-current-buffer buffer (dired-hide-details-mode t)) (display-buffer-in-side-window buffer `((side . left) (slot . 0) (window-width . fit-window-to-buffer) (preserve-size . (t . nil)) ,parameters))))
これまでのフォームを評価して任意の順序でM-x list-buffers、C-h f、M-x shell、M-x list-tags、M-x dired-default-directory-on-leftを評価すれば上図のフレームレイアウトが再作成されるはずです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
アトミックウィンドウ(atomic window)とは少なくとも2つ以上の生きたウィンドウから組成された矩形領域であり以下のような特性をもちます:
split-window
(ウィンドウの分割を参照)を適用するとアトミックウィンドウ外部に新たなウィンドウの作成を試みる。
delete-window
(ウィンドウの削除を参照)を適用するとアトミックウィンドウ全体の削除を試みる。
delete-other-windows
(ウィンドウの削除を参照)を適用するとアトミックウィンドウによるフレームの充填、またはメインウィンドウ化を試みる(サイドウィンドウを参照)。
これはウィンドウ構造を変更する基本的な関数グループはアトミックウィンドウを生きたウィンドウのように扱い、それゆえアトミックウィンドウ内部の構造を保持することを意味しています。
アトミックウィンドウはファイルのリビジョン間の差異、異なる言語やマークアップでの同一テキストの表示のように、関連するバッファーを特定のマナーにしたがって同時に表示する際にのみ有意義なウィンドウレイアウトの構築と保持に有用です。特定のウィンドウの側面上のバーでウィンドウの情報を永続的に表示するためにも使用できます。
アトミックウィンドウは予約済みのウィンドウパラメーターwindow-atom
(ウィンドウのパラメーターを参照)の助けを借りて実装されていて、内部ウィンドウ(Emacsウィンドウの基本概念を参照)はアトミックウィンドウのルートウィンドウと呼ばれます。同じアトミックウィンドウの一部であるようなすべてのウィンドウは共通の祖先としてこのルートウィンドウをもち、window-atom
パラメーターに非nil
が割り当てられます。
以下の関数は指定したウィンドウを一部とするアトミックウィンドウのルートをリターンします:
この関数はwindowを一部とするようなアトミックウィンドウのルートウィンドウをリターンする。windowには有効なウィンドウを指定しなければならず、デフォルトは選択されたウィンドウ。windowがアトミックウィンドウの一部でなければnil
をリターンする。
アトミックウィンドウを新たに作成するには既存の内部ウィンドウを選んで以下の関数を適用するのがもっともシンプルなアプローチです:
この関数はwindowをアトミックウィンドウに変換する。windowには内部ウィンドウを指定しなければならない。この関数が行うのはwindowの子孫それぞれのwindow-atom
パラメーターにt
をセットすることだけである。
既存の生きたウィンドウから新たにアトミックウィンドウを作成したり、既存のアトミックウィンドウに新たにウィンドウを追加するには、以下のバッファーディスプレイアクション関数を使用できます(バッファー表示用のアクション関数を参照):
この関数は既存のウィンドウと組み合わせてアトミックウィンドウを形成することになる新たなウィンドウ内でbufferを表示する。既存のウィンドウがすでにアトミックウィンドウの一部なら、そのアトミックウィンドウに新たなウィンドウを追加する。
alistにはシンボルと値からなる連想リストを指定する。以下は特別な意味をもつシンボル:
window
このような要素は新たなウィンドウを組み合わせる既存のウィンドウを指定する。内部ウィンドウを指定すると、そのウィンドウのすべての子ウィンドウもアトミックウィンドウの一部になる。ウィンドウを何も指定しなければ新たなウィンドウは選択されたウィンドウの兄弟ウィンドウになる。既存ウィンドウのwindow-atom
パラメーターはそれが生きたウィンドウであり、かつwindow-atom
がすでにセット済みでなければmain
にセットされる。
side
このような要素は既存ウィンドウで新たなウィンドウが配置されるサイドを表す。有効な値はbelow
、right
、above
、left
。デフォルトはbelow
。この値は新たなウィンドウのwindow-atom
パラメーターにセットされる。
リターン値は新たなウィンドウ、ウィンドウ作成に失敗するとnil
。
非nil
である限りwindow-atom
パラメーターの値は問題ではないことに注意してください。display-buffer-in-atom-window
が割り当てる値は、関数の適用後に元のウィンドウと新たなウィンドウを簡単に取得することだけが目的です。display-buffer-in-atom-window
が割り当てるウィンドウパラメーターはwindow-atom
パラメーターだけであることにも注意してください。それ以外のパラメーターはalist内のwindow-parameters
エントリーを介してアプリケーションがセットする必要があります。
アトミックウィンドウはそれを構成するウィンドウのいずれかが削除された際には存在を終えます。アトミックウィンドウを手動で分解するためには、それを構成するウィンドウ(アトミックウィンドウのルートウィンドウと子孫)のwindow-atom
パラメーターをリセットしてください。
以下のスニペットコードを単一ウィンドウのフレームに適用すると、最初に選択されたウィンドウを分割して選択されたウィンドウと新たなウィンドウの親をルートとしてアトミックウィンドウを構成します。それからフレーム下辺にある新たなウィンドウでバッファー*Messages*を表示して、新たなウィンドウを作成したアトミックウィンドウの一部にします。
(let ((window (split-window-right))) (window-make-atom (window-parent window)) (display-buffer-in-atom-window (get-buffer-create "*Messages*") `((window . ,(window-parent window)) (window-height . 5))))
この時点においてフレーム内の任意のウィンドウでC-x 2をタイプすると、フレーム下辺に新たなウィンドウが作成されます。かわりにC-x 3をタイプすれば新たなウィンドウはフレーム右辺に配置されるでしょう。いずれのケースでもここでアトミックウィンドウ内の任意のウィンドウでC-x 1をタイプすると、新たなウィンドウだけが削除されます。アトミックウィンドウ内の任意のウィンドウでC-x 0をタイプすればフレームは新たなウィンドウで充填されるでしょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
それぞれのウィンドウは独自のポイント値(ポイントを参照)をもち、同じバッファーを表示する他のウィンドウの間でも、ポイント値はそれぞれ独立しています。これは1つのバッファーを複数ウィンドウで表示するのに有用です。
デフォルトではEmacsは塗りつぶした矩形ブロックで各ウィンドウのポイント位置にカーソルを表示します。あるウィンドウでユーザーが別のバッファーに切り替えた際には、そのウィンドウのカーソルはそのバッファーのポイント位置に移動します。display文字列やイメージ等の何らかのディスプレイ要素により正確な位置が隠れている場合には、Emacsはそのdisplay要素の直前か直後にカーソルを表示する。
この関数はwindow内のカレントのポイント位置をリターンする。選択されていないウィンドウでは、そのウィンドウが選択された場合の、(そのウィンドウのバッファーの)ポイント値である。windowにたいするデフォルトは選択されたウィンドウ。
windowが選択されたウィンドウのときのリターン値は、そのウィンドウのバッファーのポイント値。厳密にはすべてのsave-excursion
フォームの外側のトップレベルのポイント値のほうがより正確であろう。しかしこの値は見つけるのが困難である。
この関数はwindow内のポイントをwindowのバッファー内の位置positionに配置する。リターン値はposition。
windowが選択されていれば単にwindow内でgoto-char
を行う。
この変数はwindow-point
のマーカー挿入型(マーカーの挿入タイプを参照)を指定する。デフォルトは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 ----------
ポイントを可視(つまり完全に可視なスクリーン行内にポイントを配置)にする試みが失敗すると、表示ルーチンは要求されたwindow-start位置を無視して、とにかく新しい位置を計算する。したがってこの関数を呼び出すLispプログラムが信頼できる結果を得るためには、表示がpositionで始まるウィンドウ内部に常にポイントを移動すること。
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を参照のこと。
この関数は他のウィンドウ内のテキストを下方にcount行スクロールする。countが負かnil
ならscroll-down
のように処理される。それ以外の点においてはscroll-other-window
と同様の方法で振る舞う。
この変数が非nil
なら、それはscroll-other-window
がどのバッファーのウィンドウをスクロールするかを指定する。
このオプションはスクロールマージン(ポイントとウィンドウの上端/下端との最小行数)のサイズを指定する。ポイントがウィンドウの上端/下端からその行数になったとき、(可能なら)再表示はポイントをそのマージン外のウィンドウ中央付近に移動するためにテキストを自動的にスクロールする。
この変数はscroll-margin
の実効値をカレントウィンドウの行高さの割合に制限する。たとえばカレントウィンドウが20行でmaximum-scroll-margin
が0.1なら、scroll-margin
がどれほど大きくてもスクロールマージンが2より大きくなることはない。
maximum-scroll-margin
自体は最大値として0.5という値をもち、これはウィンドウの中央行(ウィンドウが偶数行なら中央の2行)までカーソルを維持するためにマージンを大きくセットすることを可能にする。大きな値(または0.0から0.5までの浮動小数点数以外の値)をセットするとデフォルト値0.25がかわりに使用される。
この変数はポイントがスクリーン外(またはスクロールマージン内)に移動したときに自動的にスクロールを行う方法を指定する。値が正の整数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とredisplayが非nil
なら、この関数はrecenter-redisplay
の値に応じてフレームを再描画するかもしれない。recenter-redisplay
が非nil
の場合の効果を打ち消すために、したがって2つ目の引数の省略を使用できる。インタラクティブな呼び出しではredisplayに非nil
が渡される。
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
なら引数redisplayをnil
、引数countを非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)とは、指定された値を行に乗ずるることによりウィンドウ内のテキストを上下にシフトすることを意味します。たとえばEmacsはウィンドウより高さが大きいイメージやスクリーン行でこれを使用します。ウィンドウはそれぞれ決して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。
vscrollは通常はminibuffer-scroll-window
、あるいはミニバッファーウィンドウのリサイズ時に選択されているウィンドウ(ミニバッファーのウィンドウを参照)のいずれでもないウィンドウには効果がない。この“凍結された挙動”は、preserve-vscroll-pパラメーターが非nil
の場合には無効になる。これはvscrollを通常のようにセットすることを意味する。
この変数が非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
がセットされている場合には、再表示はポイントが常に可視となることを保証するために必要に応じて水平スクロールを自動的に変更する。とはいえ依然として水平スクロール位置を明示的に指定するのは可能である。指定した値は自動スクロールの下限値としての役目を果たす(自動スクロールは指定された値より小さい列にウィンドウをスクロールしない)。
auto-hscroll-mode
のデフォルト値はt
です。これをcurrent-line
にセットするとカーソルのある行だけがポイントが可視になるように水平スクロールされて、ウィンドウの残りはスクロールされないかscroll-left
とscroll-right
(以下参照)にセットされた最小量だけスクロールされる自動水平スクロールの変種がアクティブになります。
この関数は選択されたウィンドウを左( 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] | [ ? ] |
このセクションでは位置とそのウィンドウを報告する関数を説明します。これらの関数のほとんどはウィンドウのフレームのネイティブ位置の原点から相対的な位置を報告します(フレームのジオメトリーを参照)。いくつかの関数はウィンドウのフレームのディスプレイの原点から相対的な位置を報告します。いずれのケースにおいても原点は座標 (0, 0)をもち、X座標とY座標はそれぞれ右方向と下方向で増加します。
以下の関数ではX座標とY座標は整数の文字単位(行数と列数)で報告されます。グラフィカルなディスプレイ上での“行”と“列”はそれぞれ、そのフレームのデフォルトフォントにより指定されるデフォルト文字の高さと幅に対応します(フレームのフォントを参照)。
この関数は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のネイティブ位置(フレームのジオメトリーを参照)から相対的に、デフォルト文字単位(フレームのフォントを参照)で与えられる座標xとyにある生きたウィンドウをリターンする。
その位置にウィンドウがなければリターン値はnil
。frameが省略またはnil
の場合のデフォルトは選択されたフレーム。
この関数はウィンドウwindowがフレーム相対座標coordinatesを占有するかどうかをチェックして、もしそうならウィンドウのどの部分かをチェックする。windowは生きたウィンドウであること。
coordinatesは(x
.
y)
という形式のコンスセルであること。ここでxとyはwindowのフレームのネイティブ位置(フレームのジオメトリーを参照)から相対的に、デフォルト文字サイズ(フレームのフォントを参照)の単位で与えられる。
指定された位置にウィンドウが存在しなければリターン値はnil
。それ以外ではリターン値は以下のいずれか:
(relx . rely)
その座標はwindow内にある。数値relxとrelyは指定された位置にたいする、ウィンドウ左上隅を原点に0から数えたウィンドウ相対座標と等価。
mode-line
その座標はwindowのモードライン内にある。
header-line
その座標はwindowのヘッダーライン内にある。
tab-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のbodyのピクセル座標のリストをリターンする。(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)))
以下の関数はそのウィンドウに表示するテキストを変換することなくウィンドウに内接する最大の矩形をリターンします。
この関数は指定死windowに内接する空の最大の矩形のディメンションをリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。
リターン値はwindowのテキスト領域の空スペース(テキストを何も表示していないスペース)に内接可能な最大矩形の幅、Y座標の開始と終了からなる3要素のリスト。このような矩形はwindowのテキスト領域の右エッジで終端されるとみなされるので、この関数はX座標をリターンしない。空のスペースが見つからなければリターン値はnil
。
オプション引数countが非nil
なら、それはリターンする矩形の最大数を指定する。これはリターン値が最大の矩形が1つ目になるような矩形(3要素のリスト)のリストであることを意味する。countはコンスセルでもよく、この場合にはCARがリターンする矩形数、CDRが非nil
ならリターンされるすべての矩形が互いに素でなければならないことを示す。
オプション引数min-widthとmin-heightが非nil
なら、リターンされる矩形の最小の幅と高さを指定する。
オプション引数positions非nil
なら、それはリターンされる矩形がカバーしなければならない最上のピクセル位置がCAR、最下のピクセル位置がCDRであるようなコンスセル。これらの位置はwindowのテキスト領域の開始から計測される。
オプション引数leftが非nil
なら、それはリターン値がテキストを右から左に表示するバッファーに適していることを意味する。この場合にはリターンされる矩形はすべてwindowのテキスト領域の左端から開始するとみなされる。
この関数はwindow-lines-pixel-dimensions
(表示されるテキストのサイズを参照)を通じてwindowのグリフマトリクスの各行のディメンションを取得する必要があることに注意。したがってこの関数はwindowのグリフマトリクスが最新でなければnil
をリターンするかもしれない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のオプションによりマウスポインターの下のウィンドウを自動的に選択することができます。これはウィンドウシステムのウィンドウにマウスポインターがエンターした際は常にフレームにフォーカスを与える(それゆえ以降の選択をトリガーする)ウィンドウマネージャーと同様なポリシーを実現します(入力のフォーカスを参照)。
この変数が非nil
なら、Emacsはマウスポインターの下のウィンドウの自動的な選択を試みる。有意な値は以下のとおり:
これは自動選択トリガー後の遅延秒数を指定する。マウスポインター下のウィンドウはこの遅延秒数の間マウスが留まった後に選択される。
負の数値は正の数値と同様の効果をもつが、数値の絶対数の遅延秒数の間マウスポインターがウィンドウ内に留まり加えて移動を停止した後にウィンドウを選択する点が異なる。
その他の非nil
値はマウスポインターがウィンドウ上にエンターすると即座にウィンドウを選択することを意味する。
いずれのケースでもウィンドウの選択をトリガーするために、マウスポインターはウィンドウのテキスト領域にエンターしなければならない。スクロールバーのスライダーのドラッグやウィンドウのモードラインではコンセプト的には自動選択を発生させるべきではない。
マウスによる自動選択はミニバッファーウィンドウがアクティブなときのみ選択を行い、アクティブなミニバッファーウィンドウの選択解除は決して行わない。
マウスによる自動選択はウィンドウマネージャーが追跡しない子フレーム(子フレームを参照)にたいしてマウスフォーカス追従ポリシーをエミュレートするために使用できます。これを行うためにはfocus-follows-mouse
(入力のフォーカスを参照)に非nil
値をセットすることが必要です。focus-follows-mouse
の値がauto-raise
なら、マウスで子フレームにエンターすることにより親フレームの他のすべての子フレームの前面にその子フレームが自動的にレイズされます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウ構成(window configuration)とは1つのフレーム上全体のレイアウト —
すべてのウィンドウとサイズ、どんなバッファーを含んでいるか、それらのバッファーがスクロールされる方法、およびポイント値を記録して、更に装飾も記録します。これにはminibuffer-scroll-window
の値も含まれます。特別な例外としてウィンドウ構成には選択されたウィンドウのカレントバッファーのポイント値は記録されません。
以前に保存されたウィンドウ構成をリストアすることにより、フレーム全体のレイアウトをリストアすることができます。1つだけではなくすべてのフレームのレイアウトを記録したければ、ウィンドウ構成のかわりにフレーム構成(frame configuration)を使用します。フレーム構成を参照してください。
この関数はframeのカレントのウィンドウ構成を表す新たなオブジェクトをリターンする。frameのデフォルトは選択されたフレーム。変数window-persistent-parameters
はこの関数により保存されるウィンドウパラメーター(もしあれば)を指定する。ウィンドウのパラメーターを参照のこと。
この関数はconfigurationが作成されたフレームにたいして、そのフレームが選択されているかどうかに関わらず、ウィンドウとバッファーの構成をconfigurationで指定された構成にリストアする。引数configurationはそのフレームにたいして以前にcurrent-window-configuration
がリターンした値でなければならない。この関数は通常は構成に記録されているフレームも選択するが、dont-set-frameが非nil
なら関数の開始にすでに選択されていたフレームを選択したままにする。
この関数は通常はミニバッファー(もしあれば)のリストアと保存を行うが、dont-set-miniwindowが非nil
なら関数の開始でカレントだったミニバッファー(もしあれば)はミニウィンドウ内に残る。
configurationが保存されたフレームが死んでいる(生きていない)場合には、この関数が行うのは変数minibuffer-scroll-window
の値のリストア、minibuffer-selected-window
がリターンした値の調整のみ。この場合には関数はnil
、それ以外はt
をリターンする。
configurationのウィンドウのバッファーがconfiguration作成後にkillされていたら、そのウィンドウは規則としてリストアされる構成から削除される。しかしリストアされる構成内でそのウィンドウが最後に残ったウィンドウなら、そのウィンドウに別の生きたバッファーが表示される。
以下は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
が保存とリストアするのはカレントフレーム上のウィンドウ構成だけだからである。
この関数はobjectがウィンドウ構成ならt
をリターンする。
この関数は2つのウィンドウ構成のウィンドウレイアウトが同じかどうかを判断するが、ポイント値および保存されたスクロール位置は無視される(つまりこれらの点では異なるウィンドウ構成であってもt
をリターンし得る)。
この関数はウィンドウ構成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する前に生きたウィンドウに置き換える。windowが生きたウィンドウでなければ、それにstateをputする前に同一フレーム上に作成された新たな生きたウィンドウに置き換えられる。windowがnil
ならウィンドウの状態を新たなウィンドウにputする。
オプション引数ignoreが非nil
なら、それは最小ウィンドウサイズと固定サイズの制限を無視することを意味する。ignoreがsafe
なら、それは1行および/または2列までできる限り小さくできることを意味する。
関数window-state-get
とwindow-state-put
では2つの生きたウィンドウ間でのコンテンツの交換も可能です。以下の関数はこれを正確に行います:
このコマンドは2つの生きたウィンドウwindow-1とwindow-2の状態を交換する。window-1には生きたウィンドウを指定しなければならずデフォルトは選択されたウィンドウ。window-2には生きたウィンドウを指定しなければならず、デフォルトはミニバッファーウィンドウを除き、すべての可視なフレーム上の生きたウィンドウを含むウィンドウサイクル順においてwindow-1の次のウィンドウ。
オプション引数sizeが非nil
なら、それはwindow-1とwindow-2のサイズも同様に交換を試みることを意味する。値height
は高さのみ、値width
は幅のみ、t
は幅と高さの両方を可能なら交換することを意味する。この関数はフレームをリサイズしない。
[ << ] | [ < ] | [ 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
のボディー内でパラメーターの値を変更したときは、そのマクロの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
の実行に影響する(ウィンドウの削除を参照)。
no-delete-other-windows
¶このパラメーターはそのウィンドウをdelete-other-windows
により削除できないことをマークする(ウィンドウの削除を参照)。
split-window
¶このパラメーターはsplit-window
の実行に影響する(ウィンドウの分割を参照)。
other-window
¶このパラメーターはother-window
の実行に影響する(ウィンドウのサイクル順を参照)。
no-other-window
¶このパラメーターはそのウィンドウをother-window
による選択が不可だとマークする(ウィンドウのサイクル順を参照)。
clone-of
¶このパラメーターはそのウィンドウがクローンされたことを指定する。これはwindow-state-get
によりインストールされる(ウィンドウの構成を参照)。
window-preserved-size
¶このパラメーターはバッファー、方向(nil
は垂直でt
は水平)、ピクセル単位のサイズを指定する。そのウィンドウが指定されたバッファーを表示していて、かつ指示された方向のサイズがこのパラメーターで指定されたサイズと等しければ、Emacsはそのウィンドウの指示された方向のサイズを予約する。関数window-preserve-size
によりこのパラメーターのインストールと更新が行われる(ウィンドウサイズの保持を参照)。
quit-restore
¶このパラメーターはバッファー表示関数によりインストールされて、quit-restore-window
により参照される(ウィンドウのquitを参照)。これは4つの要素をもつリストであり、詳細はウィンドウのquitのquit-restore-window
の説明を参照のこと。
window-side
¶window-slot
これらはサイドウィンドウを実装するために内部的に使用される(サイドウィンドウを参照)。
window-atom
¶このパラメーターはアトミックウィンドウを実装するために内部的に使用される(アトミックウィンドウを参照)。
mode-line-format
¶このパラメーターはウィンドウが表示されるたびにそのウィンドウのバッファーのバッファーローカル変数mode-line-format
(モードラインの基礎を参照)の値を置き換える。シンボルnone
はそのウィンドウのモードライン表示の抑制を意味する。そのバッファーを表示する他のウィンドウのモードラインの表示とコンテンツは影響を受けない。
header-line-format
¶このパラメーターはウィンドウが表示されるたびにそのウィンドウのバッファーのバッファーローカル変数header-line-format
(モードラインの基礎を参照)の値を置き換える。シンボルnone
はそのウィンドウのヘッダーライン表示の抑制を意味する。そのバッファーを表示する他のウィンドウのヘッダーラインの表示とコンテンツは影響を受けない。
tab-line-format
¶このパラメーターはウィンドウが表示されるたびにそのウィンドウのバッファーのバッファーローカル変数tab-line-format
(モードラインの基礎を参照)の値を置き換える。シンボルnone
はそのウィンドウのタブライン表示の抑制を意味する。そのバッファーを表示する他のウィンドウのタブラインの表示とコンテンツは影響を受けない。
min-margins
¶このパラメーターの値はCARとCDRが非nil
のコンスセルなら、そのウィンドウの左ージンと右マージンの最小値を列数で指定する(マージン内への表示を参照)。与えられた場合には、Emacsはウィンドウを分割するか水平方向に縮小するかの判断にたいして、実際のマージン幅のかわりにこれらの値を使用する。
すべてのウィンドウにたいして、分割やリサイズ後にEmacsがマージンの自動調整をすることは決してない。これはそのウィンドウト分割のためにこのウィンドウのマージンを継承する新たなウィンドウニタイシテ、マージンを調整するためにこのパラメーターをセットするすべてのアプリケーション単独の責任である。window-configuration-change-hook
とwindow-size-change-functions
はいずれもこの用途に使用すること(ウィンドウのスクロールと変更のためのフックを参照)。
これはウィンドウ内でバッファーをセンタリングするために大きなマージンを使用するアプリケーションのサポート用にEmacsのバージョン25.1から導入されたパラメーターであり、それらのアプリケーションと排他となるよう留意して使用すること。Emacsの将来のバージョンで改善策により置換され得る。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではLispプログラムがウィンドウのスクロール後や、その他のウィンドウ変更が発生した際にどのようにしてアクションを起こすことができるかを説明します。最初はウィンドウがバッファーの異なる部分を表示するケースについて考えてみます。
この変数はウィンドウのスクロールによりEmacsが再表示前に呼び出すべき関数のリストを保持する。そのウィンドウ内への異なるバッファーの表示や新たなウィンドウの作成でもこれらの関数が実行される。
この変数はそれぞれの関数がウィンドウとウィンドウのdisplay-start位置という2つの引数を受け取るのでノーマルフックではない。呼び出し時にはwindow引数のdisplay-start位置は新たな値、そのウィンドウに表示されるバッファーがカレントバッファーとしてセットされる。
これらの関数はwindow-end
(ウィンドウの開始位置と終了位置を参照)を使用する際には気をつけなければならない。最新の値が必要なら、それを確実に入力するためにupdate引数を使用しなければならない。
警告: ウィンドウのスクロール方法を変更するためにこの機能を使用してはならない。これはそのような用途のためにデザインされておらず、そのような使用では機能しないだろう。
加えてFont Lockフォント表示関数(Font Lock fontification
function)を登録するためにjit-lock-register
を使用できる。バッファーの一部が(再)フォント表示されたときは、ウィンドウがスクロールまたはサイズ変更されたという理由で、これが常に呼び出されるだろう。Font Lockのその他の変数を参照のこと。
このセクションの残りの部分ではウィンドウのスクロールをともなわないウィンドウの有意な変更を検知した際の再表示の間に呼び出される6つのフックについて補足します。単純化するために、これらのフックおよびそれらが呼び出す関数をまとめてウィンドウ変更関数(window
change
functions)と呼ぶことにします。他のフックと同様に、これらのフックはインストール時にadd-hook
のlocal引数(フックのセットを参照)を通じてグローバル、またはバッファーローカルにセットできます。
これらのフックのうち最初のフックはウィンドウバッファー変更(window buffer change)を検知した後に実行されます。ウィンドウバッファー変更とはウィンドウの作成や削除、他のバッファーの割り当てを意味します。
この変数はウィンドウバッファー変更時の再表示の間に呼び出す関数を指定する。値は1つの引数を受け取る関数のリストであること。
バッファーローカルに指定された関数は、対応するバッファーを表示するすべてのウィンドウにたいして、最後にウィンドウ変更関数が実行されて以降にウィンドウが作成されたり、そのバッファーが割り当てられた場合に呼び出される。この場合にはそのウィンドウが引数として渡される。
デフォルト値として指定された関数はフレームにたいして、最後にウィンドウ変更関数が実行されて以降にそのフレームに少なくとも1つのウィンドウの追加か削除が行われるか、別のバッファーが割り当てられた場合に呼び出される。この場合にはフレームが引数として渡される。
2つ目のフックはウィンドウサイズ変更(window size change)の検出時に実行されます。ウィンドウサイズ変更とはウィンドウ作成、別バッファーの割り当て、合計サイズやテキストエリアの合計サイズの変更を意味します。
この変数はウィンドウサイズ変更発生時の再表示の間に呼び出される関数を指定する。値は1つの引数を受け取る関数のリストであること。
バッファーローカルに指定された関数は、対応するバッファーを表示するすべてのウィンドウにたいして、最後にウィンドウ変更関数が実行されて以降にウィンドウの追加や別バッファーの割り当て、合計サイズやボディーサイズが変更された場合に呼び出される。この場合にはそのウィンドウが引数として渡される。
デフォルト値として指定された関数は、最後にフレームにたいしてウィンドウ変更関数が実行されて以降に、そのフレーム上の少なくとも1つのウィンドウ追加や別バッファーの割り当て、または合計サイズやボディーサイズが変更された場合に呼び出される。この場合にはフレームが引数として渡される。
3つ目のフックは前回の再表示以降にウィンドウ選択変更(window selection change)により別のウィンドウが選択された際に実行されます。
この変数は選択されたウィンドウやフレームの選択されたウィンドウの変更時の再表示の間に実行される関数を指定する。値は1つの引数を受け取る関数のリストであること。
バッファーローカルに指定された関数は、対応するバッファーを表示するすべてのウィンドウにたいして、最後にウィンドウ変更関数が実行されて以降に(すべてのウィンドウあるいはウィンドウのフレーム上のすべてのウィンドウの中から)ウィンドウが選択されたり選択解除された場合に呼び出される。この場合にはそのウィンドウが引数として渡される。
デフォルト値として指定された関数はフレームにたいして、最後にウィンドウ変更関数が実行されて以降のそのフレームの選択や非選択、あるいはフレームの選択されたウィンドウが変更された場合に呼び出される。この場合にはフレームが引数として渡される。
4つ目のフックはウィンドウ状態変更(window state change)の検出時に実行されます。ウィンドウ状態変更とは上述の3つのウィンドウ変更のうち少なくとも1つが発生したことを意味します。
この変数はウィンドウのバッファーかサイズの変更発生時、または選択されたウィンドウやフレームの選択されたウィンドウの変更時の再表示の間に呼び出される関数を指定する。値は1つの引数を受け取る関数のリストであること。
バッファーローカルに指定された関数は、対応するバッファーを表示するすべてのウィンドウにたいして、最後にウィンドウ変更関数が実行されて以降にそのウィンドウの追加や別バッファーの割り当て、合計サイズやボディーサイズが変更されたり、(すべてのウィンドウあるいはウィンドウのフレーム上のすべてのウィンドウの中から)ウィンドウが選択されたり選択解除された場合に呼び出される。この場合にはそのウィンドウが引数として渡される。
デフォルト値として指定された関数はフレームにたいして、最後にウィンドウ変更関数が実行されて以降にそのフレームの少なくとも1つのウィンドウが追加や削除、別バッファーを割り当てられるか、合計サイズやボディーサイズの変更、またはフレームの選択または選択されていないウィンドウが変更された場合に呼び出される。この場合にはフレームが引数として渡される。
デフォルト値として指定された関数は、最後の再表示以降にそのフレームのウィンドウ状態変更フラグ(以下参照)がセットされた場合にもフレームにたいして実行される。
5つ目のフックはウィンドウ構成変更(window configuration change)の検出時に実行されます。ウィンドウ構成変更とはバッファーやウィンドウサイズの変更を意味します。このフックは実行方向において前記4つのフックとは異なります。
この変数はウィンドウのバッファーかサイズの変更時の再表示の間に呼び出される関数を指定する。値は引数を受け取らない関数のリストであること。
バッファーローカルに指定された関数は、対応するバッファーを表示するすべてのウィンドウにたいして、最後にウィンドウ変更関数が実行されて以降に、そのフレームの少なくとも1つのウィンドウの追加や削除、別バッファーの割り当て、あるいは合計サイズやボディーサイズが変更された場合に呼び出される。各呼び出しは一時的にそのバッファーを表示するウィンドウを選択して、そのバッファーをカレントにして行われる。
デフォルト値として指定された関数は各フレームにたいして、最後にウィンドウ変更関数が実行されて以降に、そのフレームに少なくとも1つのウィンドウの追加や削除、別バッファーの割り当て、あるいは合計サイズやボディーサイズが変更された場合に呼び出される。各呼び出しは一時的にそのフレームを選択して、その選択されたウィンドウのバッファーをカレントにして行われる。
最後にEmacsはwindow-state-change-functions
の振る舞いを一般化したノーマルフックを実行します。
この変数のデフォルト値はウィンドウ状態変更、または少なくとも1つのフレームでウィンドウ状態変更フラグのセットを検出した際の再表示の間に呼び出される関数を指定する。値は引数を受け取らない関数のリストであること。
アプリケーションは最後の再表示以降に複数のフレームで発生した(またはシグナルされた)変更に対処したい場合のみ、このフックに関数を配置すること。他のすべてのケースにたいしてはwindow-state-change-functions
に関数を配置するほうが好ましい。
ウィンドウ変更関数は各フレームにたいする再表示の間に次のように呼び出されます。まずすべてのバッファーローカルなウィンドウバッファー変更関数、ウィンドウサイズ変更関数、ウィンドウ選択変更関数、ウィンドウ状態変更関数を順番に呼び出します。次にこれらの関数のデフォルト値を同じ順番で呼び出します。これらの関数のデフォルト値で指定された関数の呼び出した後に、すべてのバッファーローカルなウィンドウ構成変更関数を呼び出します。そして最後にwindow-state-change-hook
の関数が実行されます。
ウィンドウ変更関数は対応する変更が前に登録されている特定のフレームにたいしてのみ実行されます。そのような変更にはウィンドウの作成や削除、ウィンドウへの別バッファーやサイズの割り当てが含まれます。そのような変更が登録されていたとしても、それは上述したフックのいずれかが実行されることを意味しないことに注意してください。たとえばある変更がウィンドウエクスカーション(ウィンドウの構成を参照)のスコープ内で登録されると、ウィンドウ変更関数呼び出しはウィンドウ変更関数実行時にそのエクスカーションがまだ持続している場合のみトリガーされるでしょう。それ以前にエクスカーションがexitされていれば、そのエクスカーションのスコープ外で登録された変更の場合のみフックが実行されます。
フレームのウィンドウ状態変更フラグ(window state change
flag)をセットすることにより、そのフレームにたいしてウィンドウ状態変更が実際に発生したかどうかに関わらず、次回の再表示の間に(そのフレームにたいする)
window-state-change-functions
とwindow-state-change-hook
のデフォルト値が実行されます。これらのフックのすべての関数を実行した後に、各フレームにたいしてフラグをリセットを行います。アプリケーションは以下の関数を使用してこのフラグのセットや検査を行うことができます。
この関数はargが非nil
ならframeのウィンドウ状態変更フラグをセット、それ以外はリセットする。frameは生きたフレームでなければならず、デフォルトは選択されたフレーム。
この関数はframeのウィンドウ状態変更フラグがセットされていればt
、それ以外はnil
をリターンする。frameは生きたフレームでなければならず、デフォルトは選択されたフレーム。
ウィンドウ変更関数の実行中に下記の関数を呼び出すことにより、最後の再表示以降に特定のウィンドウやフレームにたいして何が変更されたかについてより詳細な知見を得ることができます。これらの関数はすべて生きたウィンドウを単一かつオプションの引数として受け取ります(デフォルトは選択されたウィンドウ)。
この関数はwindowのフレームにたいして最後にウィンドウ変更関数が実行された時点において、windowに表示されていたバッファーをリターンする。その時点より後にwindowが作成された場合にはnil
をリターンする。その時点ではwindowは表示されていなかったが、後から以前に保存されたウィンドウ構成がリストアされた場合にはt
をリターンする。それ以外ならリターン値はその時点でwindowが表示していたバッファー。
この関数はウィンドウ変更関数がフレーム上でwindowが生きていることを確認した最終時点におけるwindowのトータルピクセル幅をリターンする。その後にwindowが作成された場合は0。
この関数はウィンドウ変更関数がフレーム上でwindowが生きていることを確認した最終時点におけるwindowのトータルピクセル高さをリターンする。その後にwindowが作成された場合は0。
この関数はウィンドウ変更関数がフレーム上でwindowが生きていることを確認した最終時点におけるwindowのテキストエリアのピクセル幅をリターンする。その後にwindowが作成された場合は0。
この関数はウィンドウ変更関数がフレーム上でwindowが生きていることを確認した最終時点におけるwindowのテキストエリアのピクセル高さをリターンする。その後にwindowが作成された場合は0。
ウィンドウ変更関数が最後に実行された時点でどのウィンドウまたはフレームが選択されていたかを調べるために以下の関数を使用できます:
この関数はウィンドウ変更関数が最後に実行された時点におけるframeの選択されていたウィンドウをリターンする。frameが省略またはnil
の場合のデフォルトは選択されたフレーム。
この関数はウィンドウ変更関数が最後に実行された時点において選択されていたウィンドウをリターンする。
この関数はウィンドウ変更関数が最後に実行された時点において選択されていたフレームをリターンする。
ウィンドウ変更関数は最後に実行されて以降に削除されたウィンドウに関する情報は提供しないことに注意してください。アプリケーションがそれを必要とする場合には、特定のバッファーを表示するすべてのウィンドウをバッファーのローカル変数に記憶するとともに、それをウィンドウバッファー変更の検出時に実行されるすべてのフックのデフォルト値の関数で更新する必要があります。
ウィンドウ変更関数に関数を追加する際には、以下の点を考慮する必要があります:
window-state-change-hook
のデフォルト値の最後にリストされる関数で行うこと。
save-window-excursion
、with-selected-window
、with-current-buffer
のようなマクロを使用できる。
window-configuration-change-hook
の実行以外では選択されたウィンドウやフレーム、カレントバッファーの保存やリストアは行われない。
[ << ] | [ < ] | [ 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端末上で表示されている。
pgtk
そのフレームはpure GTK機能を使って表示されている。
この関数はframeを表示する端末オブジェクトをリターンする。frameがnil
または未指定の場合のデフォルトは選択されたフレーム。
この述語はobjectが生きた(削除されていない)端末なら非nil
、それ以外はnil
をリターンする。生きた端末にたいしては、リターン値はその端末上で表示されているフレームの種類を示す。可能な値は上述のframep
と同様。
グラフィカルな端末ではフレームを2つのタイプに区別しています。通常のトップレベルフレーム(top-level frame)は、ウィンドウ(ウィンドウシステム)としては端末にたいするルートウィンドウ(ウィンドウシステム)の子であるようなフレームです。子フレーム(child frame)は、ウィンドウ(ウィンドウシステム)としてはEmacsの別フレームのウィンドウ(ウィンドウシステム)の子であるようなフレームです。子フレームを参照してください。
30.1 フレームの作成 | 追加のフレームの作成。 | |
30.2 複数の端末 | 異なる複数デバイス上での表示。 | |
30.3 フレームのジオメトリー | Geometric properties of frames. | |
30.4 フレームのパラメーター | フレームのサイズと位置、フォント等の制御。 | |
30.5 端末のパラメーター | 端末上のすべてのフレームにたいして一般的なパラメーター。 | |
30.6 フレームのタイトル | フレームタイトルの自動的な更新。 | |
30.7 フレームの削除 | 明示的に削除されるまでフレームは存続する。 | |
30.8 すべてのフレームを探す | すべての既存フレームを調べる方法。 | |
30.9 ミニバッファーとフレーム | フレームが使用するミニバッファーを見つける方法。 | |
30.10 入力のフォーカス | 選択されたフレームの指定。 | |
30.11 フレームの可視性 | フレームは可視や不可視、またはアイコン化されているかもしれない。 | |
30.12 フレームのraise、lower、re-stack | フレームの前面や背面への移動。 | |
30.13 フレーム構成 | すべてのフレームの状態の保存。 | |
30.14 子フレーム | フレームを他のフレームの子供にする。 | |
30.15 マウスの追跡 | マウス移動時のイベントの取得。 | |
30.16 マウスの位置 | マウスの場所や移動を問い合わせる。 | |
30.17 ポップアップメニュー | ユーザーに選択させるためのメニューの表示。 | |
30.18 ダイアログボックス | yes/noを問い合わせるためのボックスの表示。 | |
30.19 ポインターの形状 | マウスポインターのシェイプの指定。 | |
30.20 ウィンドウシステムによる選択 | 他のXクライアントとのテキストの転送。 | |
30.21 メディアのyank | 平文テキスト以外のオブジェクトのyank。 | |
30.22 ドラッグアンドドロップ | ドラッグアンドドロップの実装の内部。 | |
30.23 カラー名 | カラー名定義の取得。 | |
30.24 テキスト端末のカラー | テキスト端末のカラーの定義。 | |
30.25 Xリソース | サーバーからのリソース値の取得。 | |
30.26 ディスプレイ機能のテスト | 端末の機能の判定。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
新たにフレームを作成するためには関数make-frame
を呼び出します。
この関数はカレントバッファーを表示するフレームを作成してそれをリターンする。
parameters引数は新たなフレームのフレームパラメーターを指定するalist。フレームのパラメーターを参照のこと。alist内でterminal
パラメーターを指定すると新たなフレームはその端末上で作成される。それ以外の場合には、alist内でwindow-system
フレームパラメーターを指定すると、それはフレームがテキスト端末とグラフィカル端末のどちらで表示されるべきかを決定する。ウィンドウシステムを参照のこと。どちらも指定しなければ新たなフレームは選択されたフレームと同じ端末上に作成される。
parametersで指定されなかったパラメーターのデフォルトは連想リストdefault-frame-alist
内の値となる。そこでも指定されないパラメーターのデフォルトはXリソース、またはそのオペレーティングシステムで同等なものの値(X Resources in The GNU Emacs
Manualを参照)。フレームが作成された後に、この関数はframe-inherited-parameters
(以下参照)内で指定されたパラメーターのうち未割り当てのパラメーターにたいして、make-frame
呼び出し時に選択されていたフレームから値を取得して適用する。
マルチモニターディスプレイ(複数の端末を参照)では、ウィンドウマネージャーがparameters内の位置パラメーター(位置のパラメーターを参照)の指定とは異なる位置にフレームを配置するかもしれないことに注意。たとえばウィンドウの大きな部分、いわゆる支配モニター(dominating monitor)上のフレームを表示するポリシーをもつウィンドウマネージャーがいくつかある。
この関数自体が新たなフレームを選択されたフレームにする訳ではない。入力のフォーカスを参照のこと。以前に選択されていたフレームは選択されたままである。しかしグラフィカル端末上ではウィンドウシステム自身の理由によって新たなフレームが選択されるかもしれない。
make-frame
がフレームを作成する前に、それにより実行されるノーマルフック。
make-frame
がフレームを作成した後に実行するアブノーマルフック。after-make-frame-functions
内の各関数は作成された直後のフレームを単一の引数として受け取る。
initファイルでこれらのフックに追加した関数は、初期フレームの作成後にEmacsがinitファイルを読み込むために、通常は初期フレームにたいして実行されないことに注意してください。しかし別のミニバッファーフレーム(ミニバッファーとフレームを参照)を使用して初期フレームを指定すれば、これらの関数はミニバッファーなしのフレームとミニバッファーフレームの両方にたいして実行されます。かわりに“早期initファイル(early init file)”でこれらのフックに関数を追加することができます(initファイルを参照)。この場合には初期フレームにも同じように効果があります。
この変数はカレントで選択されているフレームから継承して新たに作成されたフレームのフレームパラメーターのリストを指定する。リスト内の各要素はmake-frame
の処理において前に割り当てられていないパラメーター(シンボル)であり、make-frame
は新たに作成されたフレームのそのパラメーターに選択されたフレームの値をセットする。
Emacsサーバーがクライアントフレームを作成する際に実行されるノーマルフック。このフックの呼び出し時には作成されたフレームが選択されたフレームとなる。Emacs Server in The GNU Emacs Manualを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはそれぞれの端末を端末オブジェクト(terminal object)というデータ型で表します(端末型を参照)。GNUおよびUnixシステムではEmacsはそれぞれのセッション内で複数の端末を同時に実行できます。その他のシステムでは単一の端末だけが使用できます。端末オブジェクトはそれぞれ以下の属性をもちます:
terminal-live-p
によりリターンされるシンボル(たとえばx
、t
、w32
、ns
、pc
、haiku
、pgtk
)。フレームを参照のこと。
端末オブジェクトを作成するプリミティブはありません。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 1.5’、‘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のデフォルトは選択されたフレーム。
マルチモニターディスプレイではフレームを指定したモニター上にするためにコマンドmake-frame-on-monitor
を使用することが可能です。
この関数はdisplay上に配置されるmonitorに新たにフレームを作成してそれをリターンする。その他のフレームパラメーターは、parametersというalistから取得する。monitorは物理モニター名であり、display-monitor-attributes-list
関数のリターン値の属性name
の文字列と同一の文字列であること。displayはXディスプレイの名前(文字列)であること。
この変数はモニター構成が変更された際に実行されるアブノーマルフック。モニター構成の変更はモニターのローテート(rotate:
回転)、移動、マルチモニターセットアップへの追加や削除、プライマリーモニターの変更、モニター解像度の変更によって起こり得る。フックの関数はモニター構成が変更された端末で構成された単一の引数とともに呼び出される。プログラムは端末の新たなモニター構成を取得するために、その端末を引数としてdisplay-monitor-attributes-list
を呼び出すこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレームのジオメトリー(geometry)は、そのEmacsインスタンスのビルドに使用されたツールキット、およびそのフレームを表示する端末に依存します。このチャプターではこれらの依存関係とそれらを処理するいくつかの関数を説明します。これらの関数すべてにたいして、frame引数には生きたフレームを指定する必要があることに注意してください(フレームの削除を参照)。省略またはnil
なら選択されたフレーム(入力のフォーカスを参照)が指定されます。
30.3.1 フレームのレイアウト | フレームの基本的なレイアウト。 | |
30.3.2 フレームのフォント | フレームのデフォルトフォントとセット方法。 | |
30.3.3 フレームの位置 | ディスプレイ上のフレームの位置。 | |
30.3.4 フレームのサイズ | フレームサイズの指定と取得。 | |
30.3.5 フレームの暗黙的なリサイズ | フレームの暗黙なリサイズと予約方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
可視なフレームは端末のディスプレイの矩形(rectangular)の領域を占有します。この領域にはそれぞれが異なる用途をサービスする、いくつかのネストされた矩形を含むことができます。以下のスケッチはグラフィカル端末上でのレイアウトを描いたものです:
<------------ Outer Frame Width -----------> ____________________________________________ ^(0) ________ External/Outer Border _______ | | | |_____________ Title Bar ______________| | | | (1)_____________ Menu Bar ______________| | ^ | | (2)_____________ Tool Bar ______________| | ^ | | (3)_____________ Tab Bar _______________| | ^ | | | _________ Internal Border ________ | | ^ | | | | ^ | | | | | | | | | | | | | Outer | | | Inner | | | Native Frame | | | Frame | | | Frame Height | | | Height | | | Height | | | | | | | | | | | | |<--+--- Inner Frame Width ------->| | | | | | | | | | | | | | | | |___v______________________________| | | | | | |___________ Internal Border __________| | v v |___________ External/Outer Border __________| <-------- Native Frame Width -------->
実際のところ上図で示した領域すべてが存在するわけではありません。これらの領域については以下で説明します。
アウターフレーム(outer frame)とは上図で示すすべての領域を網羅する矩形。この矩形の端はそのフレームのアウターエッジ(outer edges)と呼ばれる。フレームのアウター幅(outer width)とアウター高さ(outer height)は併せて矩形のアウターサイズ(outer size)を指定する。
フレームのアウターサイズを把握することはフレームのディスプレイの作業領域にフレームをフィットさせたり、スクリーンで2つのフレームを隣接して配置するのに有用である(複数の端末を参照)。アウターサイズは通常はフレームが少なくとも1回マップ(可視にすること。フレームの可視性を参照)された後でなければ利用できない。初期フレームやまだ作成されていないフレームにたいするアウターサイズは予想するかウィンドウシステムやウィンドウマネージャーのデフォルトから計算しなければならない。回避策としてはマップ済みフレームのアウターサイズとネイティブサイズを取得して、新たなフレームのアウターサイズの計算に使用すればよい。
(上図‘(0)’で示される)アウターフレームの左上隅の位置はフレームのアウター位置(outer position)と呼ばれる。グラフィカルなフレームのアウター位置は、ディスプレイではフレームのリサイズやレイアウト変更では未変更のままなので、そのフレームの“位置”としても参照される。
アウター位置はフレームパラメーターleft
とtop
を通じて指定とセットができる(位置のパラメーターを参照)。これらのパラメーターは通常のトップレベルのフレームにたいして、通常はフレームのディスプレイの原点からみた絶対位置(以下参照)を表す。子フレーム(子フレームを参照)にたいしては親フレームのネイティブ位置(以下参照)から相対的な位置を表す。これらのパラメーターの値はテキスト端末のフレームでは意味がなく常に0である。
エクスターナルボーダー(external border)はウィンドウマネージャーにより提供される装飾の一部。典型的にはマウスによるフレームのリサイズで典型的に使用される。そのため“全画面化(fullboth)”や最大化されたフレームでは表示されない(サイズのパラメーターを参照)。エクスターナルボーダーの幅はウィンドウマネージャーにより決定されて、Emacsの関数では変更できない。
テキスト端末のフレームではエクスターナルボーダーは存在しない。グラフィカルなフレームではフレームパラメーターoverride-redirect
とundecorated
をセットすることにより表示を抑制できる(ウィンドウ管理のパラメーターを参照)。
アウターボーダー(outer border)はフレームパラメーターborder-width
(レイアウトのパラメーターを参照)で指定可能な分割線。実際にはエクスターナルボーダーとアウターボーダーのいずれかが表示されるが、両方が同時に表示されることはない。アウターボーダーはツールチップフレーム(ツールチップを参照)、子フレーム(子フレームを参照)、およびundecorated
やoverride-redirect
をセットされたフレーム(ウィンドウ管理のパラメーターを参照)のようにウィンドウマネージャーにより(完全に)制御される特別なフレームでは通常は表示されない。
アウターボーダーはテキスト端末のフレームとGTK+ルーチンが生成したフレームでは表示されない。MS-Windowsではアウターボーダーはピクセル幅が1のエクスターナルボーダーの助けを借りてエミュレートされる。X上でのツールキットによらないビルドではフレームパラメーターborder-color
をセットすることによりアウターボーダーのカラーを変更できる(レイアウトのパラメーターを参照)。
タイトルバー(title bar)、いわゆるキャプションバー(caption
bar)もウィンドウマネージャーの装飾の一部であり通常はフレームのタイトル(フレームのタイトルを参照)、同様に最小化や最大化、削除のボタンを表示する。これはマウスによるフレームのドラッグにも使用できる。タイトルバーは通常は全画面化(fullboth)されたフレーム(サイズのパラメーターを参照)、ツールチップフレーム(ツールチップを参照)、子フレーム(see 子フレームを参照)では表示されず、端末フレームでは存在しない。タイトルバーの表示はフレームパラメーターoverride-redirect
やundecorated
をセットすることにより抑制できる(ウィンドウ管理のパラメーターを参照)。
メニューバー(メニューバーを参照)にはインターナル(Emacs自身が描画)とエクスターナル(ツールキトが描画)がある。ほとんどのビルド(GTK+、Lucid、Motif、MS-Windows)ではエクスターナルメニューバーを依拠とする。NSもエクスターナルメニューバーを使用するが、これはアウターフレームの一部ではない。非ツールキットのビルドはインターナルメニューバーを提供できる。テキスト端末フレームではメニューバーはフレームのルートウィンドウの一部である(ウィンドウとフレームを参照)。ルールとして子フレームでメニューバーが表示されることはない(子フレームを参照)。パラメーターmenu-bar-lines
(レイアウトのパラメーターを参照)をセットすることによりメニューバーの表示は抑制できる。
メニューバーの幅がフレームにフィットするには大きくなりすぎた際に折り返されるか(wrapped)、それとも切り詰められるか(truncated)はツールキットに依存する。通常はMotifとMS-Windowsのビルドだけがニューバーを折り返すことができる。これらはメニューバーの折り返し、またはそれを解除する際にフレームのアウター高さの保持を試みるの、でかわりにフレームのネイティブ高さ(以下参照)が変更される。
メニューバーと同じように、ツールバーにはインターナルツールバー(Emacsが描画)とエクスターナルツールバー(ツールキットが描画)がある。GTK+とNSのビルドにはそれらのツールキットが描画するツールバーがある。その他のビルドはインターナルツールバーを使用する。GTK+ではフレームのインタナルボーダー(以下参照)のすぐ外側のいずれかのサイドにツールバーを配置できる。子フレームは通常はツールバーを表示しない(子フレームを参照)。パラメーターtool-bar-lines
(レイアウトのパラメーターを参照)に0をセットすることでツールバーの表示を抑制できる。
変数auto-resize-tool-bars
が非nil
なら、フレームに収まらないほど幅が大きくなるとEmacsはツールバーを折り返す。Emacsがインターナルツールバーの折り返しや折り返しの解除を行う場合には、デフォルトではフレームのアウター高さを未変更に保つので、かわりにフレームのネイティブ高さ(以下参照)が変更される。一方GTK+とともにビルドされたEmacsではツールバーの折り返しは決して行われないが、長くなりすぎたツールバーが収まるようにフレームのアウター幅が自動的に増加される。
タブバー(Tab Bars in The GNU Emacs
Manualを参照)は常にEmacs自身によって描画される。タブバーはインターナルツールバーとともビルドされたEmacsのツールバーの上、エクスターナルツールバーとともにビルドされたEmacsではツールバーの下に表示される。tab-bar-lines
パラメーターを0に設定すればタブバーの表示を抑止できる(レイアウトのパラメーターを参照)。
ネイティブフレーム(native frame)は全体的にアウターフレーム内に配置される。ネイティブフレームにはエクスターナルボーダーとアウターボーダー、タイトルバーとエクスターナルメニューバーとツールバーが占有する領域は含まれない。ネイティブフレームのエッジ(edge: 端)はフレームのネイティブエッジ(native edges)と呼ばれる。フレームのネイティブサイズ(native size)ハ、フレームのネイティブ幅(native width)とネイティブ高さ(native height)で指定される。
フレームのネイティブサイズはEmacs内のフレームの作成やリサイズをEmacsが行う際にウィンドウシステムやウィンドウマネージャーに渡すサイズである。これはたとえばタイトルバーの対応するボタンのクリックによりフレームを最大化した後やマウスでエクスターナルボーダーをドラッグした際等、フレームの(ウィンドウシステムの)ウィンドウをリサイズする際にウィンドウシステムやウィンドウマネージャーに渡すサイズでもある。
ネイティブフレームの左上隅の位置はフレームのネイティブ位置(native position)を指定する。上図の(1)から(3)は種々のビルドにたいするネイティブ位置を示す。
したがってLucid、Motif、MS-Windowsではネイティブ高さにツールバーの高さは含まれるがメニューバーの高さは含まれず、非ツールキットおよび端末のフレームではメニューバーとツールバーの高さは含まれない。
フレームのネイティブ位置はマウスのカレント位置(マウスの位置を参照)のセットやリターンを行う関数やwindow-edges
、window-at
、coordinates-in-window-p
のようにウィンドウ位置(座標とウィンドウを参照)を扱う関数にたいして参照位置となる。これはフレームの子フレームの配置や位置にたいする原点(0, 0)も指定する。
フレームパラメーターoverride-redirect
やundecorated
(ウィンドウ管理のパラメーターを参照)を変更してウィンドウマネージャーの装飾の削除や追加を行う際にも、フレームのネイティブ位置は未変更のままであることにも注意。
インターナルボーダーはインナーフレーム周囲にEmacsが描画するボーダー(以下参照)。その外観仕様は与えられたフレームが子フレームかどうかによる(子フレームを参照)。
通常のフレームでは、フレームの幅はフレームパラメーターinternal-border-width
(レイアウトのパラメーターを参照)、カラーはinternal-border
フェイスのバックグラウンドで指定される。
子フレームでは、フレームの幅はフレームパラメーターchild-frame-border-width
(ただしフォールバックとしてinternal-border-width
パラメーターを使用)、カラーはchild-frame-border
フェイスのバックグラウンドで指定される。
インナーフレーム(inner frame)はフレームのウィンドウにたいして予約された矩形のこと。インナーフレームはインターナルボーダー(これはインナーフレームの一部ではない)に囲われている。インナーフレームのエッジはフレームのインナーエッジ(inner edges)と呼ばれる。この矩形のインナーサイズ(inner size)はインアー幅(inner width)とインナー高さ(inner height)により指定される。このインナーフレームはフレームのディスプレイエリア(display area)として参照されることもある。
ルールとしてインナーフレームはフレームのルートウィンドウ(ウィンドウとフレームを参照)とミニバッファーウィンドウ(ミニバッファーのウィンドウを参照)に細分される。この2つには注目すべき2つの例外がある。それはミニバッファーウィンドウをもたないルートウィンドウのみのミニバッファーlessフレーム(minibuffer-less frame)と、ミニバッファーウィンドウだけをもち、それがフレームのルートウィンドウの役目も果たすミニバッファーonlyウィンドウ(minibuffer-only frame)である。そのようなフレーム構成を作成する方法はフレームの初期パラメーターを参照のこと。
フレームのテキストエリア(text area)はネイティブフレームに埋め込み可能な一種の架空領域である。テキストエリアの位置は指定されない。テキストエリアの幅はネイティブ幅からインターナルボーダーの幅、そのフレームに指定されていれば(レイアウトのパラメーターを参照)1つの垂直スクロールバーの幅、左右のフリンジ各1の幅を取り除くことにより取得できる。テキストエリアの高さはネイティブ高さからインターナルボーダーの幅、そのフレームに指定されていればフレームのインターナルのメニューバー、ツールバー、タブバーの高さ、1つの水平スロールバーの高さを取り除くことにより取得できる。
フレームの絶対位置(absolute position)は(X, Y)というペア、またはフレームのディスプレイの原点(0, 0)から相対的な水平および垂直のピクセル単位のオフセットにより与えられる。これに対応してフレームの絶対エッジ(absolute edges)はこの原点からのピクセル単位のオフセットにより与えられる。
マルチモニターではディスプレイの原点が端末の利用可能な表示エリア全体の左上隅と一致する必要はない。したがってそのような環境では、たとえそのフレームが完全に可視であってもフレームの絶対位置は負の値になり得る。
慣例により垂直方向のオフセットは“下方向”にたいして増加する。これはフレームの下エッジから上エッジのオフセットを減ずることによりフレームの高さが得られることを意味する。期待されるように水平方向のオフセットは“右方向”にたいして増加するので、フレームの右エッジから左エッジのオフセットを減ずることによりフレームの幅を計算できる。
以下の関数はグラフィカル端末上のフレームにたいして上述したエリアのサイズをリターンします:
この関数はframeの幾何学的な属性をリターンする。リタ^ン値は以下のような属性のリストの連想リスト。すべての座標、高さや幅の値はピクセル単位の整数。まだframeがマップされていなければ(フレームの可視性を参照)、いくつかのリターン値は実際の値の近似値しか表していないかもしれない(それらの値はフレームのマップ後に確認可能になる)。
outer-position
frameのアウターフレームの絶対位置を表すコンスであり、frameのディスプレイの原点(0, 0)から相対的な位置。
outer-size
frameのアウター幅とアウター高さを表すコンス。
external-border-size
ウィンドウマネージャーにより与えられる、frameエクスターナルボーダーの水平幅と垂直幅を表すコンス。ウィンドウマネージャーによりこれらの値が提供されなければ、Emacsはアウターフレームとインナーフレームの座標からそれらの推測を試みる。
outer-border-width
frameのアウターボーダーの幅。この値は非GTK+のXビルドでのみ意味がある。
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のディスプレイの原点から相対的なピクセル単位の値。端末フレームではleftとtopにたいしてリターンされる値は常に0。
オプション引数typeはリターンするエッジのタイプを指定する。outer-edges
はframeのアウターエッジ、native-edges
(かnil
)はネイティブエッジ、inner-edges
はインナーエッジをリターンすることを意味する。
慣例によりleftとtopにたいしてリターンされたディスプレイのピクセル位置はframeの内部(一部)とみなされる。したがってleftとtopがいずれも0なら、ディスプレイの原点のピクセル位置はframeの一部となる。その一方でbottomとrightのピクセル位置はframeのすぐ外側にあるとみなされる。これはたとえば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
(位置のパラメーターを参照)を使用すれば変更やアクセスができます。既存の可視なフレームの位置を処理するために追加で2つの関数が存在します。いずれの関数でも引数frameは生きたフレームでなければならず、デフォルトは選択されたフレームです。
この関数は子フレームではない通常のフレームにたいしてフレームのアウター位置(フレームのレイアウトを参照)を、フレームのディスプレイの原点(0,
0)
からのピクセル座標をコンスセルでリターンする。子フレーム(子フレームを参照)にたいしてはフレームのアウター位置を、frameのネイティブ位置を原点(0,
0)
として、そこからのピクセル座標をリターンする。
負の値はframeのディスプレイまたは親フレームの右エッジか下エッジからのオフセットではない。これらはframeのアウター位置が、フレームのデイスプレイの原点または親フレームのネイティブ位置の左および/または上にあることを意味する。これは通常はframeの一部だけが可視(または完全に不可視)であることを意味している。しかしディスプレイの原点がディスプレイの左上隅と一致しないシステムではセカンダリーモニター上ではフレームは可視かもしれない。
てきすと端末ではいずれの値も0。
この関数はframeのアウターフレームの位置を(x, y)にセットする。後の引数は通常はframeのディスプレイの位置(0, 0)にある原点からのピクセル数、子フレームではframeの親フレームのネイティブ位置からのピクセル数。
負のパラメーター値はアウターフレームの右エッジをスクリーンの右エッジ(または親フレームのネイティブ矩形位置)から左に-xピクセル、または下エッジをスクリーンの下エッジ(または親フレームのネイティブ矩形位置)から上に-yピクセルの位置にセットする。
負の値ではframeの右エッジや下エッジを性格にディスプレイや親フレームの右エッジや下エッジには揃えられないことに注意。負の値ではディスプレイや親フレーム内にあるエッジにある位置は指定できない。フレームパラメーターleft
とtop
(位置のパラメーターを参照)でこれを行うことはできるものの、初期フレームや新たなフレームでは依然として良好な結果は得られないかもしれない。
この関数はテキスト端末フレームでは効果がない。
このフックはウィンドウシステムやウィンドウマネージャーがフレームを(新たな位置を割り当てて)移動した際に実行される関数を指定する。関数は移動されたフレームを単一の引数として実行される。子フレーム(子フレームを参照)では親フレームとの関連性においてのフレーム位置が変更されたときだけ関数が実行される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs内からフレームサイズ(size of a frame)を指定する正規の方法はテキストサイズ(text size)の指定による方法です(フレームのテキストエリアの幅と高さの組み合わせ。フレームのレイアウトを参照)。これはピクセルやフレームの標準の文字サイズ(フレームのフォントを参照)で計ることができます。
インターナルメニューやインターナルツールバーのあるフレームでは実際にフレームが描画されるまでフレームのネイティブ高さを告げることはできません。一般的にこれはフレームの初期サイズの指定にネイティブサイズを使用できないことを意味しています。可視フレームのネイティブフレームが解り次第、frame-geometry
のリターン値から残りのコンポーネントを追加してアウターサイズ(フレームのレイアウトを参照)を計算できます。しかし不可視のフレームやまだ作成されていないフレームにたいするアウターサイズは推定しかできません。これはスクリーンの右エッジや下エッジからのオフセットの指定ではフレームの正確な初期位置を計算することが不可能であることも意味しています(フレームの位置を参照)。
フレームのテキストサイズはフレームパラメーターheight
とwidth
を使用してセットや取得が可能です(サイズのパラメーターを参照)。初期フレームのテキストサイズはX様式のジオメトリー仕様でもセットや取得が可能です。Command Line Arguments for Emacs Invocation in The GNU
Emacs
Manualを参照してください。以下に既存で可視なフレーム(デフォルトは選択されたフレーム)のサイズにたいしてセットやアクセスを行う関数をいくつかリストします。
これらの関数はframeのテキストエリアの高さと幅を、frameのデフォルトフォントの高さと幅を単位に計測してリターンする。これらの関数は単に(frame-parameter
frame 'height)
と(frame-parameter frame 'width)
を略記したもの。
ピクセルで計測したframeのテキストエリアがデフォルトフォントサイズの倍数でなければ、これらの関数がリターンする値はテキストエリアに完全に収まるデフォルトフォントの文字数に切り捨てられる。
以下の関数は与えられたフレームのネイティブフレーム、アウターフレーム、インナーフレーム、テキストエリアのピクセル幅とピクセル高さをリターンします(フレームのレイアウトを参照)。テキスト端末では結果はピクセルではなく文字単位になります。
これらの関数はframeのアウター幅やアウター高さをピクセル単位でリターンする。
これらの関数はframeのネイティブ幅やネイティブ高さをピクセル単位でリターンする。
これらの関数はframeのインナー幅やインナー高さをピクセル単位でリターンする。
これらの関数はframeのテキストエリアの幅や高さをピクセル単位でリターンする。
ウィンドウシステムがサポートしていれば、Emacsはデフォルトでフレームのピクセル単位でのテキストサイズをフレームの文字サイズの倍数にしようと試みます。しかし通常これはエクスターナルボーダーのドラッグ時にフレームが文字サイズの増減だけでリサイズできることを意味しています。さらにこれはフレームの下および/または右に空のスペースが残ることにより、フレームを最大化したり“fullheight”や“fullwidth”にする試みを阻害するかもしれません。このような場合には以下のオプションが助けになるでしょう。
このオプションがnil
(デフォルト)ならフレームのテキストのピクセルサイズは、フレームのリサイズの際に通常はframe-char-height
とframe-char-width
のカレント値の倍数に丸められる。非nil
なら丸めは行われず、フレームのサイズはピクセル単位で増加/減少が可能になる。
この変数をセットすることにより次回のリサイズ処理では、通常はウィンドウマネージャーにこれに相当するサイズのヒントを渡す。これはユーザーの初期ファイル内でのみこの変数をセットすべきで、アプリケーションが一時的にこれをバインドすべきではないことを意味する。
このオプションにたいしてnil
値がもつ正確な意味は使用されるツールキットに依存する。マウスによるエクスターナルボーダーのドラッグは、ウィンドウマネージャーが対応するサイズヒントを処理する意思があれば文字単位で行われる。文字サイズの整数倍ではないフレームサイズを引数としてset-frame-size
(以下参照)を呼び出すと、もしかしたら丸められたり(GTK+)、あるいは受容される(Lucid、Motif、MS-Windows)かもしれない。
いくつかのウィンドウマネージャーでは、フレームを本当に最大化や全画面で表示させるために、これを非nil
にセットする必要があるかもしれない。
この関数はframeのテキストエリアのサイズを、frameの文字の正準高さと正準幅で計測した単位でセトする(フレームのフォントを参照)。
オプション引数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つの関数はスクロールバー、フリンジ、マージン、ディバイダー、モードラインやヘッダーラインと一緒にすべてのウィンドウを表示するために必要な最小よりフレームを小さくしません。これはたとえばマウスによるフレームのエクスターナルボーダーのドラッグなどによるウィンドウマネージャーがトリガーとなる要求と対照的です。このような要求は、もし必要なら表示できないフレームの右下隅の部分をクリッピングすることにより常に尊重されます。Emacs内からのフレームサイズの変更時に同様の振る舞いを得るには、パラメーターmin-width
とmin-height
を使用できます(サイズのパラメーターを参照)。
アブノーマルフックwindow-size-change-functions
(ウィンドウのスクロールと変更のためのフックを参照)はウィンドウシステムやウィンドウマネージャーに起因するのもを含む、フレームのインナーサイズの変更のすべてを追跡します。実際にインナーフレームのサイズを変更せずにフレームのウィンドウのサイズだけを変更した際に発生するかもしれない誤検出を除外するために以下の関数を使用できます。
この関数はframeにたいして最後にwindow-size-change-functions
が実行されて以降にframeのインナー幅かインナー高さが変更されていれば非nil
をリターンする。これはframeにたいするwindow-size-change-functions
の実行直後は常にnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
たとえばメニューバーやツールバーの表示切り替え、デフォルトフォントの変更、フレームのスクロールバーの幅のセットの際には、Emacsはデフォルトではフレームのテキストエリアの行数と列数を未変更に保つように試みます。しかしこれはそのような場合のサイズ変更を調停するために、Emacsがウィンドウマネージャーにフレームのウィンドウのリサイズを依頼しなければならないことを意味します。
たとえばフレームの最大化や全画面化の際のように、そのような暗黙なフレームのリサイズ(implied frame resizing)がおそらく望ましくないケースもあります(デフォルトではオフになっている)。一般的には以下のオプションで暗黙のリサイズを無効にできます。
このオプションがnil
ならフレームのフォント、メニューバー、ツールバー、インターナルボーダー、フリンジ、スクロールバーを変更においてフレームのテキストエリアの列数と行数を維持するために、アウターフレームがリサイズされるかもしれない。このオプションがt
ならそのようなリサイズは行われない。
このオプションの値はフレームパラメーターのリストでもよい。この場合にはリスト内に出現するパラメーター変更にたいする暗黙のリサイズは抑制される。このオプションで処理されるフレームパラメーターは現在のところ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、MS-Windowsのデフォルト値は(tab-bar-lines
tool-bar-lines)
であり、これはツールバーやタブバーの追加や削除でアウターフレーム高さが変更されないことを意味する。GTK+を含むその他すべてのウィンドウシステムでは(tab-bar-lines)
であり、これは上記リストのtab-bar-lines
以外のパラメーターのいずれかを変更するとアウターフレームのサイズは変更されるかもしれないことを意味する。それ以外ではt
であり、これはウィンドウシステムのサポートがなければ暗黙にアウターフレームのサイズが変更されることはないことを意味する。
フレームが上述のいずれかのパラメーターにたいする変更の調停に不十分な際には、たとえこのオプションが非nil
でもEmacsがフレームの拡大を試みるかもしれないことに注意。
ウィンドウマネージャーは通常はエクスターナルメニューバーやエクスターナルツールバーが占有する行数の変更時にフレームのリサイズを要求しないことにも注意。典型的にはこのような“折り返し(wrappings)”はユーザーがフレームのメニューバーやツールバーのすべての要素を表示できないほどフレームを水平方向に縮小しや際に発生する。これはメニューバーやツールバーのアイテム数を変化させるようなメジャーモードの変更によっても発生し得る。このような折り返しはフレームのテキストエリアの行数を暗黙に変更するかもしれ、このオプションのセットによる影響を受けない。
[ << ] | [ < ] | [ 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
にも意味があります。
デフォルトでは変数desktop-restore-frames
が非nil
のときには、フレームパラメーターはデスクトップライブラリー関数(Desktop Saveモードを参照)が保存とリストアを行います。リストアされたセッションでは無意味や有害になることを避けるためにパラメーターをframeset-persistent-filter-alist
に含めるのはアプリケーションの責任です。
30.4.1 フレームパラメーターへのアクセス | フレームのパラメーターの変更方法。 | |
30.4.2 フレームの初期パラメーター | フレーム作成時に指定するフレームパラメーター。 | |
30.4.3 ウィンドウフレームパラメーター | ウィンドウシステムにたいするフレームパラメーターのリスト。 | |
30.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
(フレームの暗黙的なリサイズを参照)を非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
はテキスト端末上のフレームにたいしてのみ意味があります。
30.4.3.1 基本パラメーター | 基本的なパラメーター。 | |
30.4.3.2 位置のパラメーター | スクリーン上のフレームの位置。 | |
30.4.3.3 サイズのパラメーター | フレームのサイズ。 | |
30.4.3.4 レイアウトのパラメーター | フレームのパーツのサイズ、一部パーツの有効化と無効化。 | |
30.4.3.5 バッファーのパラメーター | 表示済みまたは表示されるべきバッファーはどれか。 | |
30.4.3.6 フレームとの相互作用のためのパラメーター | 別フレームと相互作用するためのパラーター。 | |
30.4.3.7 マウスドラッグのパラメーター | マウスによるフレームのリサイズや移動のためのパラメーター。 | |
30.4.3.8 ウィンドウ管理のパラメーター | ウィンドウマネージャーとの対話。 | |
30.4.3.9 カーソルのパラメーター | カーソルの外見の制御。 | |
30.4.3.10 フォントとカラーのパラメーター | フレームテキストにたいするフォントとカラー。 |
[ << ] | [ < ] | [ 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つのフレームのみ表示可能なケースが該当する。フレームのタイトルを参照のこと。Emacsがウィンドウシステムを使用している際にこのパラメーターが非nil
だと、name
によって決定されたタイトルがオーバーライドされて、frame-title-format
に応じて暗黙裡にタイトルが計算される。更にicon-title-format
によって決定されたアイコン化されたフレームのタイトルもオーバーライドする。フレームのタイトルを参照のこと。
name
フレームの名前。このパラメーターを通じて名前を指定しなければ、Emacsがframe-title-format
とicon-title-format
で指定されたフレーム名を自動的にセットする。そしてEmacsがウィンドウシステムを使用している際には、(title
パラメーターによってオーバーライドされていなければ)これがフレームのタイトルとして表示される。
フレーム作成時に明示的にフレーム名を指定すると、そのフレームにたいしてXリソースを照合する際にも、(Emacs実行可能形式名のかわりに)その名前が使用される。
explicit-name
フレーム作成時にフレーム名が明示的に指定されると、このパラメーターはその名前。明示的に名付けられなかったら、このパラメーターはnil
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレームのXY方向のオフセットを記述するパラメーターは常にピクセル単位です。子フレームではない通常のフレームでは、フレームのアウター位置(フレームのジオメトリーを参照)はディスプレイの原点から相対的に指定されます子フレーム(子フレームを参照)では、フレームのアウター位置は親フレームのネイティブ位置から相対的に指定されます(これらのパラメーターにTTYフレームで意味のあるものはないことに注意)。
left
フレームのディスプレイ(か親フレーム)の左エッジからフレームの左アウターエッジまでのピクセル単位での位置。以下のいずれかの方法で指定できる。
正の整数はフレームの左エッジをディスプレイ(か親フレーム)の左エッジ、負の整数はフレームの右エッジをディスプレイ(か親フレーム)の右エッジに相対的に指定する。
(+ pos)
これはディスプレイ(か親フレーム)の左エッジにたいしフレームの左エッジの相対的位置を指定する。整数posは正と負の値をとり得る。負の値はスクリーン(か親フレーム)の外側、または(マルチモニターディスプレイにたいしては)プライマリーモニター以外のモニター上の位置を指定する。
(- pos)
これはディスプレイ(か親フレーム)ノ右エッジにたいしフレームノ右エッジの相対的位置を指定する。整数posは正ト負の値をとり得る。負の値はスクリーン外側、または(マルチモニターディスプレイにたいしては)プライマリーモニター以外のモニター上の位置を指定する。
0.0から1.0の範囲の浮動小数点数はフレームの左位置比率(left position ratio)を通じて左エッジのオフレットを指定する。これはアウターフレームの左エッジの位置にたいする、フレームのワークエリア(複数の端末を参照)または親のネイティブフレーム(子フレームを参照)からアウターフレームの幅を減じた値との比率。したがって左位置比率0.0はディスプレイ(か親フレーム)の左、比率0.5は中央、1.0は右に揃える。同様に上位置比率(top position ratio)はアウターフレームの上エッジの位置にたいする、フレームのワークエリア(か親のネイティブフレーム)からフレームの高さを減じた値との比率。
Emacsは子フレームのパラメーターkeep-ratio
(フレームとの相互作用のためのパラメーターを参照)が非nil
なら、親フレームがリサイズされた場合に子フレームの位置比率を未変更のままにしようと試みる。
通常はフレームが可視になるまでフレームのアウターサイズ(フレームのジオメトリーを参照)は利用できないので、装飾つきのフレーム作成時には浮動小数点値の一般的には使用はできない。浮動小数点値は親フレームの領域内で子フレームの適切な配置を保証したい場合により適している。
プログラム指定の位置を無視するウィンドウマネージャーがいくつかある。指定した位置が無視されない保証を望む場合には、パラメーターuser-position
にも以下の例のように非nil
値を指定すること。
(modify-frame-parameters nil '((user-position . t) (left . (+ -4))))
一般的にフレームをディスプレイの右エッジや下エッジから相対的に配置するのは良いアイデアではない。初期フレームや新たなフレームの配置は不正確になる(フレームが可視になるまでアウターフレームのサイズは完全には解らない)か、または(可視になった後にフレームが再配置されると)追加のちらつき(flickering)をもたらすだろう。
さらにディスプレイ(やワークエリア、親フレーム)の右エッジや下エッジから相対的に指定された位置、同様に浮動小数点数のオフセットは内部的にはディスプレイ(やワークエリア、親フレーム)の左エッジや上エッジから相対的な整数のオフセットとして格納されることに注意。これらの値はframe-parameters
のような関数によるリターン値やデスクトップ保存ルーチンのリストアにも使用される。
top
ディスプレイ(か親フレーム)の上エッジ(下エッジ)にたいして、上エッジ(下エッジ)のスクリーン位置をピクセル単位で指定する。方向が水平ではなく垂直である点を除イテ、これはleft
と同様に機能する。
icon-left
スクリーン左エッジから数えた、フレームアイコン左エッジのピクセル単位のスクリーン位置。ウィンドウマネージャーがこの機能をサポートすれば、これはフレームをアイコン化したとき効果を発揮する。このパラメーターに値を指定する場合にはicon-top
にも値を指定しなければならず、その逆も真。
icon-top
スクリーン上端から数えたフレームアイコン上端のピクセル単位のスクリーン位置。ウィンドウマネージャーがこの機能をサポートすれば、これはフレームをアイコン化したときに効果を発揮する。
user-position
フレームを作成してパラメーターleft
とtop
で位置を指定する際は、指定した位置がユーザー指定(人間であるユーザーにより明示的に要求された位置)なのか、それとも単なるプログラム指定(プログラムにより選択された位置)なのかを告げるためにこのパラメーターを使用する。非nil
値はそれがユーザー指定の位置であることを告げる。
ウィンドウマネージャーは一般的にユーザー指定位置に留意するとともに、プログラム指定位置にも幾分か留意する。しかし多くのウィンドウマネージャーはプログラム指定位置を無視して、ウィンドウをウィンドウマネージャーのデフォルトの方法で配置するかユーザーのマウスによる配置に任せる。twm
を含むウィンドウマネージャーのいくつかは、プログラム指定位置にしたがうか無視するかをユーザーの指定に任せる。
make-frame
を呼び出す際にパラメーターleft
やtop
の値がそのユーザーにより示される嗜好を表すなら、このパラメーターに非nil
値、それ以外はnil
を指定すること。
z-group
このんパラメーターはフレームのウィンドウシステム的なウィンドウの相対位置を、フレームのディスプレイのスタック順(Zオーダー)で指定する。
これがabove
ならウィンドウシステムは、above
プロパティがセットされていない他のすべてのウィンドウシステムのウィンドウの前面にフレームに対応するウィンドウを表示する。nil
ならフレームのウィンドウはabove
プロパティがセットされたすべてのウィンドウの背後、かつbelow
プロパティがセットされたすべてのウィンドウの前面に表示される。below
ならフレームのウィンドウはbelow
プロパティがセットされていないすべてのウィンドウの背後に表示される。
特定のフレームの前面や背後にフレームを配置するためには関数frame-restack
を使用すること(フレームのraise、lower、re-stackを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレームパラメーターは通常はフレームのサイズを文字単位で指定します。グラフィカルなディスプレイ上ではdefault
フェイスがこれら文字単位の実際のピクセルサイズを決定します(フェイスの属性を参照)。
width
このパラメーターはフレームの幅を指定する。これは以下の方法でも指定できる:
フレームのテキストエリア(フレームのジオメトリーを参照)の幅を文字単位で指定する正の整数。
これがCARにシンボルtext-pixels
をもつコンスセルなら、CDRはフレームのテキストエリアの幅をピクセル単位で指定する。
0.0から1.0の範囲の浮動小数点数はフレームの幅比率(width ratio)を通じてフレームの幅の指定に使用できる。これはアウター幅(フレームのジオメトリーを参照)にたいする、フレームのワークエリア(複数の端末を参照)または親フレームのネイティブフレーム(子フレームを参照)からアウターフレームの幅を減じた値との比率。したがって値0.5はワークエリア(か親フレーム)の半分の幅、値1は全幅をフレームに占有させる。同様に高さ比率(height ratio)はアウターフ高さにたいする、フレームのワークエリア(か親のネイティブフレーム)からフレームの高さとの比率。
Emacsは子フレームのパラメーターkeep-ratio
(フレームとの相互作用のためのパラメーターを参照)が非nil
なら、親フレームがリサイズされた場合に子フレームの幅と高さの比率を未変更のままにしようと試みる。
通常はフレームが可視になるまでフレームのアウターサイズ(フレームのジオメトリーを参照)は利用できないので、装飾つきのフレーム作成時には浮動小数点値の一般的には使用はできない。浮動小数点値は、たとえばdisplay-buffer-in-child-frame
を通じてdisplay-buffer-alist
(バッファーを表示するウィンドウの選択を参照)をカスタマイズする際に親フレームの領域内へ常に子フレームを確実にフィットさせたい場合により適している。
パラメーターの指定方法にかかわらず、このパラメーターの値を報告するframe-parameters
のような関数は、常にフレームのデフォルトの文字幅の倍数にするために必要に応じて丸めを行いフレームのテキストエリアの幅を整数でリターンする。この値はデスクトップ保存ルーチンでも使用される。
height
このパラメーターはフレームの高さを指定する。これは水平ではなく垂直であるという点を除きwidth
のように機能する。
user-size
これはサイズパラメーターheight
とwidth
にたいして、user-position
(user-positionを参照)がtop
とleft
が行うのと同じことを行う。
min-width
このパラメーターはフレームの最小ネイティブ幅(フレームのジオメトリーを参照)を文字単位で指定する。フレームの初期幅やフレームを水平方向にリサイズする関数は、通常はフレームのすべてのウィンドウ、垂直スクロールバー、フリンジ、マージン、垂直ディバイダーが表示できるよう保証する。このパラメーターが非nil
なら、収まりきらないコンポーネントが結果としてウィンドウマネージャーにクリップされてしまうようなフレームより小さいフレームを作成できる。
min-height
このパラメーターはフレームの最小ネイティブ高さ(フレームのジオメトリーを参照)を文字単位で指定する。フレームの初期幅やフレームを水平方向にリサイズする関数は、通常はフレームのすべてのウィンドウ、水平スクロールバー、水平ディバイダー、モードライン、ヘッダーライン、エコーエリアー、インターナルメニューバー、インターナルツールバーが表示できるよう保証する。このパラメーターが非nil
なら、収まりきらないコンポーネントが結果としてウィンドウマネージャーにクリップされてしまうようなフレームより小さいフレームを作成できる。
fullscreen
このパラメータはフレームの幅、高さ、またはその両方を最大化するかどうかを指定する。値はfullwidth
、fullheight
、fullboth
、またはmaximized
のいずれか。21フレームがfullwidthなら幅、fullheightなら高さ、fullbothまら幅と高さが可能なかぎり大きくなる。maximizedは“fullboth”と同様だが、通常はタイトルバーとフレームのリサイズやクローズ用のボタンが維持される点が異なる。同様に最大化されたフレームでは、デスクトップ上に表示されているタスクバーやパネルが見えなくなること通常はない。一方で“fullboth(全画面)”のフレームは、通常はタイトルバーは省略されて、利用可能なスクリーンスペース全体を占有する。
この点ではfullheightやfullwidthのフレームは最大化されたフレームと類似している。しかしこれらは通常は最大化フレームでは存在しないエクスターナルボーダーを表示する。したがって最大化されたフレームの高さと幅は、fullheightのフレームの高さやfullwidthのフレームの幅とあ数ピクセル異なることがある。
いくつかのウィンドウマネージャーではフレームを真に最大化やフルスクリーンで表示させるために、変数frame-resize-pixelwise
(フレームのサイズを参照)をカスタマイズする必要があるかもしれない。さらにフルスクリーンや最大化の種々の状態間でスムーズな遷移をサポートしないウィンドウマネージャーもいくつかある。これの回避には変数x-frame-normalize-before-maximize
のカスタマイズが助けになるかもしれない。
macOSのフルスクリーンではツールバーとメニューバーの両方が非表示になるが、マウスポインターがスクリーン上端に移動すればどちらも表示される。
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を与えるだろう。
fit-frame-to-buffer-margins
このパラメーターはfit-frame-to-buffer
(ウィンドウのリサイズを参照)でフレームをルートウィンドウのバッファーにフィットさせる際に、オプションfit-frame-to-buffer-margins
の値のオーバーライドを可能にする。
fit-frame-to-buffer-sizes
このパラメーターはfit-frame-to-buffer
(ウィンドウのリサイズを参照)でフレームをルートウィンドウのバッファーにフィットさせる際に、オプションfit-frame-to-buffer-sizes
の値のオーバーライドを可能にする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のフレームパラメーターによりフレームのさまざまなパーツを有効または無効にしたりサイズを制御できます。
border-width
ピクセル単位でのフレームのアウターボーダー幅(フレームのジオメトリーを参照)。
internal-border-width
ピクセル単位でのフレームのインターナルボーダー幅(フレームのジオメトリーを参照)。
child-frame-border-width
与えられたフレームが子フレーム(子フレームを参照)なら、フレームのインターナルボーダーのピクセル幅。nil
ならかわりに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を参照のこと。エクスターナルメニューバー(フレームのレイアウトを参照)では、メニューバーが複数行に折り返されても値は変更されない。この場合にはframe-geometry
がリターンするmenu-bar-size
の値で実際にメニューバーが占有する行数を導出できる(フレームのジオメトリーを参照)。
tool-bar-lines
ツールバー用に使用する行数(ツールバーを参照)。デフォルトはTool Barモードが有効なら1、それ以外は0。Tool Bars in The GNU Emacs Manualを参照のこと。ツールバーが折り返されているかどうかで値は変化するかもしれない(フレームのレイアウトを参照)。
tool-bar-position
EmacsがGTK+とともにビルドされた際のツールバーの位置。値はtop
、bottom
、left
、right
のいずれか(デフォルトはtop
)。
tab-bar-lines
タブバー用に使用する行数(Tab Bars in The GNU Emacs Manualを参照)。デフォルトはTab Barモードが有効なら1、それ以外は0。ツールバーが折り返されているかどうかで値は変化するかもしれない(フレームのレイアウトを参照)。
line-spacing
各テキスト行の下に残すピクセル単位の追加スペース(正の整数)。詳細は行の高さを参照のこと。
no-special-glyphs
非nil
ならそのフレームで表示するすべてのバッファーにたいする切り詰めと継続のグリフ(切り詰めを参照)の表示をすべて抑制する。これはfit-frame-to-buffer
(ウィンドウのリサイズを参照)を通じてフレームをバッファーにフィットさせる際のグリフ排除に有用。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はフレーム内でどのバッファーが表示されているか、表示されるべきかを扱うためのフレームパラメーターであり、すべての種類の端末上で意味があります。
minibuffer
そのフレームが自身のミニバッファーをもつか否か。もつ場合にはt
、もたない場合はnil
、only
ならそのフレームが正にミニバッファーであることを意味する。値が(別フレーム内の)ミニバッファーウィンドウなら、そのフレームはそのミニバッファーを使用する。
このパラメーターはフレームの作成時に効果をもつ。nil
を指定するとEmacsはdefault-minibuffer-frame
のミニバッファーウィンドウ(ミニバッファーとフレームを参照)にそのフレームをセットしようと試みる。このパラメーターは既存のフレームでは別のミニバッファーウィンドウを指定するためにのみ使用できる。nil
からt
、およびその逆の変更も許されていない。このパラメーターがすでにミニバッファーウィンドウを指定していれば、これをnil
にセットしても効果はない。
特別な値child-frame
は作成されるフレームが親となるようなミニバッファーのみの子フレーム(子フレームを参照)を作成することを意味する。Emacsはnil
が指定されたかのように子フレームのイニバッファーウィンドウにこのパラメーターをセットするが、作成後に子フレームを選択しない。
buffer-predicate
このフレームにたいするバッファー述語関数。関数other-buffer
はこの述語が非nil
なら、(選択されたフレームから)どのバッファーを考慮すべきか決定するためにこれを使用する。これは各バッファーにたいして、そのバッファーを唯一の引数としてこの述語を1回呼び出す。この述語が非nil
値をリターンしたら、そのバッファーは考慮される。
buffer-list
そのフレーム内で選択されたことのあるバッファーにたいする、もっとも最近選択されたバッファーが先頭になるような順のリスト。
unsplittable
非nil
なら、このフレームのウィンドウは決して自動的に分割されることはない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のパラメーターは別のフレームとの間での相互作用するためのフォームを提供します。
parent-frame
非nil
ならそのフレームが子フレーム(子フレームを参照)であることを意味しており、そのパラメーターは親フレームを指定する。nil
ならそのフレームが通常のトップレベルのフレームであることを意味する。
delete-before
このパラメーターが非nil
なら、それは削除によってこのウレームも自動的にトリガーされるようなフレームを指定する。フレームの削除を参照のこと。
mouse-wheel-frame
このパラメーターが非nil
ならフレーム上でマウスホイールをスクロールするたびにウィンドウがスクロールされるようなフレームを指定する。Mouse
Commands in The GNU Emacs Manualを参照のこと。
no-other-frame
非nil
ならそのフレームは関数next-frame
、previous-frame
(すべてのフレームを探すを参照)、other-frame
の候補として適格ではない。Frame Commands in The GNU Emacs Manualを参照のこと。
auto-hide-function
このパラメーターが関数を指定する場合には、他のフレームが存在しないときにフレーム唯一のウィンドウをquit(ウィンドウのquitを参照)した際に変数frame-auto-hide-function
で指定された関数のかわりに呼び出される関数を指定する。
minibuffer-exit
このパラメーターが非nil
なら、Emacsはミニバッファーのexit(ミニバッファーを参照)の際は常にそのフレームを不可視にする。かわりに関数iconify-frame
とdelete-frame
も指定できる。このパラメーターはミニバッファーのexit時に(Emacsがウィンドウを処理する際のように)自動的に子フレームを非表示にするために有用。
keep-ratio
このパラメーターは現在のところ子フレーム(子フレームを参照)にたいしてのみ意味がある。非nil
なら親フレームのリサイズ時に、Emacsはフレームのサイズ比率(幅と高さ。サイズのパラメーターを参照)と位置比率(左と右。位置のパラメーターを参照のこと)を変更しないよう試みる。
このパラメーターの値がnil
なら親フレームのリサイズ時にフレームのサイズと位置は変更されないので、位置とサイズの比率は変更されるかもしれない。パラメーターの値がt
なら、Emacsはフレームのサイズと位置の比率を維持しようと試みるので、親フレームから相対的なフレームのサイズと位置は変更されるかもしれない。
コンスセルを使用することにより、さらに特化した制御が可能になる。この場合にはコンスセルのCARがt
かwidth-only
ならフレームの幅比率、CARがt
かheight-only
なら高さ比率、CDRがt
かleft-only
なら左位置比率、CDRがt
かtop-only
なら上位置比率が維持される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下のパラメーターはマウスでのインターナルボーダーのドラッグによるフレームのリサイズにたいするサポートを提供します。これらは最上ウィンドウのヘッダーラインやタブライン、最下ウィンドウのモードラインのマウスドラッグによるフレームの移動も可能にします。
これらのパラメーターはウィンドウマネージャーによる装飾がない子フレーム(子フレームを参照)にたいしてもっとも有用です。もし必要なら未装飾のトップレベルのフレームにたいしても使用できます。
drag-internal-border
非nil
なら、(もしあれば)マウスでインターナルボーダーをドラッグしてフレームをリサイズできる。
drag-with-header-line
非nil
なら、マウスで最上ウィンドウのヘッダーラインをドラッグしてフレームを移動できる。
drag-with-tab-line
非nil
なら、マウスで最上ウィンドウのタブラインをドラッグしてフレームを移動できる。
drag-with-mode-line
非nil
なら、マウスで最下ウィンドウのモードラインをドラッグしてフレームを移動できる。このようなフレームは自身のミニバッファーウィンドウをもつことが許されないことに注意。
snap-width
マウスで移動されるフレームはディスプレイ(か親ウィンドウ)のいずれかのエッジにこのパラメーターで指定されたピクセル数までドラッグされるとディスプレイ(か親ウィンドウ)のボーダーに“snapする(とびつく)”。
top-visible
このパラメーターが数値ならフレームの上エッジがディスプレイ(か親フレーム)の上エッジより上に表示されることは決してない。さらにディスプレイ(か親フレーム)の他のエッジにたいしてフレームが移動された際には、フレームの指定されたピクセル数分が可視に留まる。このパラメーターのセットは非nil
のdrag-with-header-line
パラメーターをもつ子フレームが、ドラッグにより完全に親フレームのエリア外になることを防ぐために有用。
bottom-visible
このパラメーターが数値ならフレームの下エッジがディスプレイ(か親フレーム)の下エッジより下に表示されることは決してない。さらにディスプレイ(か親フレーム)の他のエッジにたいしてフレームが移動された際には、フレームの指定されたピクセル数分が可視に留まる。このパラメーターのセットは非nil
のdrag-with-mode-line
パラメーターをもつ子フレームが、ドラッグにより完全に親フレームのエリア外になることを防ぐために有用。
[ << ] | [ < ] | [ 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
なら仮想デスクトップを伴うシステム上のすべての仮想デスクトップ上でそのフレームが可視になる。
shaded
非nil
ならウィンドウマネージャーにたいして、タイトルバーを残しコンテンツが隠れるようにフレームを表示するよう指示する。
use-frame-synchronization
非nil
ならグラフィックのティアリングを防ぐために、フレームの再表示とモニターのリフレッシュレートを同期させる。これは現時点ではHaiku、および非ツールキットとXツールキットとともにビルドされたXウィンドウシステムでのみ実際されており、ツールキットのスクロールバーでは正しく動作しない。更に関連するディスプレイ同期プロトコルをサポートするコンポジット型ウィンドウマネージャーを要求する。XリソースのsynchronizeResize
にも文字列"extended"
がセットされていなければならない。
inhibit-double-buffering
非nil
ならフレームはダブルバッファリングなしでスクリーンに描画される。通常はちらつきを減少させるために、利用可能ならEmacsはダブルバッファリングの使用を試みる。ディスプレイのバグや昔のようにちらつく感覚があるようならこのプロパティをセットすること。
skip-taskbar
非nil
ならウィンドウマネージャーならフレームのディスプレイに関連するタスクバーからフレームのアイコンを削除して、Alt-TABのコンビネーションキーを通じたフレームへの切り替えを抑制するようにウィンドウマネージャーに指示する。MS-Windowsではこのようなフレームをアイコン化するとデスクトップ下部にある、フレームにたいするウィンドウシステムのウィンドウに"ロールイン(roll
in)"される。いくつかのウィンドウマネージャーはこのパラメーターにしたがわない。
no-focus-on-map
非nil
ならフレームはマップ時に入力フォーカスの受け取りを希望しないことを意味する。いくつかのウィンドウマネージャーはこのパラメーターにしたがわない。
no-accept-focus
非nil
ならフレームは明示的なマウスクリックやfocus-follows-mouse
(入力のフォーカスを参照)、mouse-autoselect-window
(マウスによるウィンドウの自動選択を参照)によりマウスがフレーム内に移動した際に入力フォーカスの受け取りを希望しないことを意味する。これはユーザーが選択されていないフレームをマウスでスクロールできないという、望ましくない副作用をもたらすかもしれない。いくつかのウィンドウマネージャーはこのパラメーターにしたがわない。HaikuでもたとえユーザーがAlt-TABというキー組み合わせでそのフレームに切り替えた場合であっても、ウィンドウがユーザーからのキーボード入力を何も受け取ることができないという副作用があるだろう。
undecorated
非nil
ならフレームのウィンドウシステムのウィンドウはタイトル、最小化ボックスや最大化ボックス、エクスターナルボーダーのような装飾なしで描画される。これは通常はマウスによるそのウィンドウシステムのウィンドウのドラッグ、リサイズ、アイコン化、最大化、削除ができないことを意味する。nil
の場合にはウィンドウマネージャーのセッティングでディスプレイがサスペンドされていなければ、フレームのウィンドウは上述のすべての要素とともに描画される。
Xでは装飾をオフに切り替えるために、EmacsはMotifウィンドウマネージャーのヒントを使用する。いくつかのウィンドウマネージャーはこれらのヒントにしたがわない。
NSビルドはツールバーを装飾とみなすので未装飾のフレームでは表示されない。
override-redirect
¶非nil
ならオーバーライド・リダイレクト(override
redirect)のフレームであることを意味する。これはフレームがX配下のウィンドウマネージャーで処理されないことを意味する。オーバーライド・リダイレクト・フレームはウィンドウマネージャーの装飾をもたず、Emacsの配置関数やリサイズ関数でしか配置やリサイズができない。また他のすべてのフレームの最上位に通常は描画される。このパラメーターをセットしてもMS-Windowsでは効果がない。
ns-appearance
macOSのみ利用可能でありdark
にセットすると“vibrant
dark”テーマ、light
にセットすると“aqua”テーマ、それ以外ならシステムのデフォルトを使用してフレームのウィンドウシステムのウィンドウを描画する。暗色(dark)のバックグラウンドのEmacsテーマ使用時にツールバーやスクロールバーに暗色の外観をセットするために“vibrant
dark”テーマを使用できる。
ns-transparent-titlebar
macOSでのみ利用可能であり非nil
ならタイトルバーとツールバーをトランスペアレント(transparent:
透明)にセットする。これはEmacsのバックグラウンドカラーにマッチするようにタイトルバーとツールバーのバックグラウンドカラーを効果的にセットする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このフレームパラメーターはカーソルの外見を制御します。
cursor-type
カーソルの表示方法。適正な値は:
box
塗りつぶされた四角形(filled box)を表示する(デフォルト)。
(box . size)
塗りつぶされた四角形(filled box)を表示する。しかしポイントがいずれかの次元がsizeピクセルより大きいマスクされたイメージ配下にあれば中抜きの四角形(hollow 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)を優先順に指定するシンボルのリスト。CairoなしでビルドされたEmacsのXでの描画では現在のところx
(Xのコアフォントドライバー)、xft
(Xftフォントドライバー)、xfthb
(HarfBuzzテキストシェイピングをもつXftフォントドライバー)という3つのフォントバックエンドが潜在的に利用できる。Cairo描画つきでビルドされた場合にもX上のフォントバックエンドとしてx
、ftcr
(CairoのFreeTypeフォントドライバー)、ftcrhb
(HarfBuzzテキストシェイピングをもつCairo上のFreeTypeフォントドライバー)の3つが潜在的に利用できる。HarfBuzzつきでEmacsをビルドした場合には、非推奨のftcr
ドライバーの使用が可能であっても、デフォルトのフォントドライバーはftcrhb
となる。MS-Windowsでは現在のところgdi
(MS-Windowsのコアフォントドライバー)、uniscribe
(OTFフォントとTTFフォントにたいするUniscribeエンジンによるテキストシェイピングをもつフォントドライバー)、harfbuzz
(OTFフォントとTTFフォントにたいするHarfBuzzテキストシェイピングをもつフォントドライバー)という3つのフォントバックエンドが利用できる(Windows
Fonts in The GNU Emacs
Manualを参照)。同様にharfbuzz
も推奨される。Haikuでは複数のフォントドライバーが存在する可能性がある(Haiku
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
は未選択時の透明度。
いくつかのウィンドウシステムは子フレーム(子フレームを参照)にたいしてalpha
パラメーターをサポートしない。
alpha-background
¶フレームのバックグラウンドの透明度をセットする。フレームパラメーターalpha
とは異なり、テキストは完全に不透明のままといったようにフォアグラウンド要素は保ちつつ、バックグラウンドの透明度だけを制御する。値は0から100の整数であり0は完全に透明、100(デフォルト)は完全に不透明を意味する。
以下は特定のフェイスの特定のフェイス属性と自動的に等しくなるので、ほぼ時代遅れとなったフレームパラメーターです(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
をリターンする。
この関数はterminalのパラメーターparameterに指定されたvalueをセットしてパラメーターの以前の値をリターンする。
以下は特別な意味をもついくつかの端末パラメーターのリストです:
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’、‘%C’、‘%l’の構文は無視される。モードラインのデータ構造を参照のこと。
これはフレームのパラメーターを通じてフレームの名前を明示的に指定していない際に、アイコン化されたフレームの名前を計算する方法を指定する変数である。計算の結果得られたタイトルが、そのフレームのアイコン自体に表示される。値が文字列であれば、frame-title-format
のようなモードライン構文であること。値はt
でもよく、この場合にはかわりにframe-title-format
を使用することを意味する。これによって(フレームがアイコン化されているときに)フレームのタイトルを変更すると、そのフレームのraiseおよび/または入力フォーカスの要求と解釈する、一部のウィンドウマネージャーやデスクトップ環境における問題を避けることができる。この値はフレームがアイコン化されているかどうかに関わらず、フレームのタイトルを同じにしたい場合にも役に立つ。デフォルト値はframe-title-format
のデフォルト値と同じ文字列。
この変数はEmacsにより自動的にセットされる。フレームが2つ以上(ミニバッファーのみのフレームと不可視のフレームは勘定に入らない)のとき、値はt
となる。frame-title-format
のデフォルト値はフレームが複数存在する場合のみ、フレーム名にバッファー名を入れるためにmultiple-frames
を使用する。
この変数の値はframe-title-format
とicon-title-format
の処理中を除き正確である保証はない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
生きたフレーム(live frame)とは削除されていないフレームのことです。フレームが削除される際には、たとえそれへの参照元がなくなるまでLispオブジェクトとして存在し続けるとしても端末ディスプレイからは削除されます。
この関数はフレームframeを削除する。引数frameは生きたフレーム(以下参照)を指定しなければならず、デフォルトは選択されたフレーム。
この関数はまずframeのすべての子フレーム(子フレームを参照)とフレームパラメーターdelete-before
(フレームとの相互作用のためのパラメーターを参照)がframeを指定するすべてのフレームを削除する。祖先としてframeをもつフレームが他に存在しないことを保証するために、このような削除はすべて再帰的に行われる。その後にframeがツールチップを指定していなければ、実際にフレームをkillする前にフックdelete-frame-functions
を実行する(フックの各関数は単一の引数としてframeを受け取る)。delete-frame
は実際にフレームをkillしてフレームリストからフレームを削除した後にafter-delete-frame-functions
を実行する。
フレームのミニバッファーが別のフレームの代替えミニバッファー(ミニバッファーとフレームを参照)の役割をもつかぎりフレームを削除できないことに注意。他のフレームすべてが不可視なら通常はフレームは削除できないが、forceが非nil
なら削除が可能になる。
この関数はフレームframeが削除されていなければ非nil
をリターンする。リターンされ得る非nil
の値はframep
と同様。フレームを参照のこと。
いくつかのウィンドウマネージャーはウィンドウを削除するコマンドを提供します。これらはそのウィンドウを操作するプログラムに特別なメッセージを送ることにより機能します。Emacsがそれらメッセージのいずれかを受け取ったときはdelete-frame
イベントを生成します。このイベントの通常の定義は関数delete-frame
を呼び出すコマンドです。その他のシステムイベントを参照してください。
このコマンドはframeの端末上からframe以外のすべてのフレームを削除する。frameが別のフレームのミニバッファーを使用している場合には、そのミニバッファーフレームは処理せずに残る。引数frameは生きたフレームを指定しなければならず、デフォルトは選択されたフレーム。このコマンドは内部的には削除するすべてのフレームにたいして、forceにnil
を指定してdelete-frame
を呼び出すことにより機能する。
この関数はframeの子フレームは削除しない(子フレームを削除)。frameが子フレームならframeの兄弟だけを削除する。
プレフィックス引数iconifyを指定するとフレームを削除せずにアイコン化する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はすべての生きたフレーム(削除されていないフレーム)のリストをリターンする。これはバッファーにたいするbuffer-list
に類似しており、すべての端末上のフレームが含まれる。リターンされるリストは新たに作成されたものであり、このリストを変更してもEmacs内部への影響はない。
この関数はカレントで可視なフレームだけのリストをリターンする。See フレームの可視性を参照のこと。テキスト端末上のフレームは、実際に表示されるのが選択されたフレームだけだとしても常に可視であるとみなされる。
この関数はZオーダー(重なり)の順でEmacsのフレームのリストをリターンする(フレームのraise、lower、re-stackを参照)。オプション引数displayは調査するディスプレイを指定する。displayはフレームかディスプレイ名(文字列)であること。省略かnil
なら選択されたフレームのディスプレイを意味する。displayにEmacsフレームが含まれていなければnil
をリターンする。
フレームは最前面(最初)から最背面(最後)の順にリストされる。特別なケースとしてdisplayが非nil
で生きたフレームを指定する場合には、そのフレームの子フレームをZオーダー(重なり順)でリターンする。
この関数はテキスト端末では意味がない。
この関数により特定の端末上のすべてのフレームを任意の開始位置から簡単に巡回できる。これはframeの端末上のすべての生きたフレームのリストからframeの後のフレームをリターンする。引数frameは生きたフレームを指定しなければならず、デフォルトは選択されたフレーム。no-other-frame
パラメーター(フレームとの相互作用のためのパラメーターを参照)が非nil
であるようなフレームをリターンすることは決してない。
2つ目の引数minibufは、次フレームを決定する際にどのフレームを考慮するかを示す:
nil
ミニバッファーのみのフレームを除いたすべてのフレームを考慮する。
visible
可視フレームだけを考慮する。
可視フレームとアイコン化されたフレームだけを考慮する。
特定のウィンドウをミニバッファーウィンドウとして使用するフレームだけを考慮する。
すべてのフレームを考慮する。
next-frame
と同様だがすべてのフレームを逆方向に巡回する。
ウィンドウのサイクル順のnext-window
とprevious-window
も参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
それぞれのフレームは通常は下端に自身のミニバッファーウィンドウをもち、フレームが選択された際は常にそれを使用します。このウィンドウは関数minibuffer-window
で取得できます(ミニバッファーのウィンドウを参照)。
しかしミニバッファーをもたないフレームも作成できます。そのようなフレームは、別のフレームのミニバッファーを使用しなければなりません。この別フレームはそのフレームにたいする代替えミニバッファーフレーム(surrogate
minibuffer
frame)としての役目を果たし、そのフレームが生きているかぎりdelete-frame
で削除することはできなくなります(フレームの削除を参照)。
フレームパラメーターminibuffer
により、フレーム作成時に(別フレーム上にある)使用するミニバッファーを明示的に指定できます(バッファーのパラメーターを参照)。これを行わない場合には変数default-minibuffer-frame
の値であるようなフレーム内でミニバッファーを探します。この値はミニバッファーをもつフレームである必要があります。
ミニバッファーのみのフレームを使用する場合には、ミニバッファーにエンター時にそのフレームを前面に移動(raise)したいと思うかもしれません。その場合には変数minibuffer-auto-raise
にt
をセットします。フレームのraise、lower、re-stackを参照してください。
この変数はデフォルトでミニバッファーウィンドウとして使用するフレームを指定する。これは既存のフレームには影響しない。これはカレント端末にたいして常にローカルであり、バッファーローカルにはできない。複数の端末を参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
どんなときでもEmacs内のただ1つのフレームが選択されたフレーム(selected frame)です。選択されたウィンドウ(ウィンドウの選択を参照)は常に選択されたフレーム上にあります。
Emacsがフレームを複数端末(複数の端末を参照)上に表示する際には、各端末は自身の選択されたフレームをもちます。しかしそれらのうち1つだけが、いわゆる選択されたフレームであり、それはもっとも最近に入力があった端末に属すフレームです。つまり特定の端末からのコマンドをEmacsが実行する際には、その端末上の1つが選択されたフレームです。Emacsが実行するコマンドは常に1つだけなので、選択されたフレームは常に1つだけだと考える必要があります。このフレームこそが、このマニュアルで選択されたフレームと呼ぶフレームです。選択されたフレームを表示するディスプレイは、選択されたフレームのディスプレイ(selected frame’s display)です。
この関数は選択されたフレームをリターンする。
いくつかのウィンドウシステムおよびウィンドウマネージャーは、マウスがあるウィンドウオブジェクトにキーボード入力をダイレクトします。それ以外は、さまざまなウィンドウオブジェクトにフォーカスをシフト(shift
the
focus)するために、明示的なクリックやコマンドを要求します。どちらの方法でもEmacsはフォーカスをもつフレーム(複数形のframes)を自動的に追跡します。Lisp関数から別フレームに明示的に切り替えるためには、select-frame-set-input-focus
を呼び出します。
前のパラグラフ中の“複数形のframes”は意図したものです。Emacs自身は選択されたフレームを1つしかもたないのにたいして、Emacsは多くの異なる端末上にフレームをもつことができ(ウィンドウシステムへの接続は端末とみなされることを思い出してほしい)、各端末は入力フォーカスをもつフレームにたいして独自のアイデアをもっています。Xウィンドウシステムの下ではユーザー入力は個別に入力の“指定席”に組織化されていて、それらの指定席それぞれが独自に特定の入力フォーカスを順に得ることができるのです。あるフレームに入力フォーカスをセットすると、Emacsが最後に相互作用を行った指定席のフレームの端末にフォーカスがセットされますが、他の端末上のフレームや指定席に依然としてフォーカスが残るかもしれません。
入力フォーカスをセットする前に指定された端末上でユーザーと何らかの相互作用が発生した場合には、Xサーバーが指定席をランダムに選んで(通常はもっとも小さい番号の指定席)、そこに入力フォーカスをセットします。
関数select-frame
を呼び出すことにより、Lispプログラムが一時的にフレームを切り替えることができます。これはそのウィンドウシステムのフォーカス概念を変更はしません。変更ではなく何らかの方法により制御が再確認(reasserted)されるまで、ウィンドウマネージャーの制御から抜け出す(escape)のです。
テキスト端末使用時はその端末上で一度に表示できるフレームは1つだけなので、select-frame
呼び出し後に次回の再表示で新たに選択されたフレームが実際に表示されます。このフレームは次のselect-frame
呼び出しまで選択されたままです。テキスト端末上の各フレームはバッファー名の前に表示される番号をもちます(モードラインで使用される変数を参照)。
この関数はframeを選択して、(他のフレームのせいで不明瞭な場合には)それを前面に移動(raise)してウィンドウシステムのフォーカス授与を試みる。テキスト端末上では、次回再表示時に端末スクリーン全体に新たにフレームが表示される。オプション引数norecordはselect-frame
(下記参照)のときと同じ意味をもつ。この関数のリターン値に意味はない。
以下で説明する関数は理想的には他のフレームを前面にレイズすることなくフレームにフォーカスするべきです。残念ながらウィンドウシステムやウィンドウマネージャーの多くはこの要求を拒絶するかもしれません。
この関数はframeのレイズを要さずにframeにXサーバーのフォーカスを与える。frameがnil
なら選択されたフレームを意味する。Xの配下ではオプション引数noactivateが非nil
なら、frameのウィンドウシステムのウィンドウが“アクティブ”なウィンドウになることを防ぐことを意味する。これはframeが他のフレームの前面にならないようさらに強く主張する。
MS-Windowsではnoactivate引数に効果はない。しかしframeが子フレーム(子フレームを参照)なら、この関数は通常は他の子レームの前面にレイズすることなくframeにフォーカスする。
この関数はウィンドウシステムのサポートがなければ何もしない。
この関数はフレームframeを選択して、Xサーバーのフォーカスがあればそれを一時的に無視する。frameにたいする選択は次回ユーザーが別フレームに何かを行うか、この関数の次回呼び出しまで継続する(ウィンドウシステムを使用する場合には以前に選択されていたフレームに依然としてウィンドウシステムの入力フォーカスがあるかもしれないので、コマンドループからリターン後にそのフレームが選択されたフレームとしてリストアされるかもしれない)。
指定されたframeは選択されたフレームとなり、その端末が選択された端末になる。この関数はその後にframe内で選択されていたウィンドウを第1引数、norecordを第2引数にしてselect-window
をサブルーチンとして呼び出す(したがってnorecordが非nil
なら、もっとも最近に選択されたウィンドウとバッファーリストの変更を避ける)。ウィンドウの選択を参照のこと。
この関数はframe、frameが削除されていればnil
をリターンする。
一般的には実行後に端末を戻すよう切り替えることなく、別の端末に切り替えるのが可能な手段としてselect-frame
を決して使用しないこと。
Emacsは選択されたフレームをサーバーとしてアレンジしてウィンドウシステムに要求することによりウィンドウシステムと協調します。Emacsのいずれかのフレームが選択されたことをあるウィンドウシステムが通知すると、Emacsは内部的にfocus-inイベントを生成します。Emacsフレームをフォーカス変更イベントの通知をサポートするxterm
のようなテキスト端末エミュレーター上で表示している際には、テキストモードのフレームでもfocus-inとfocus-outのイベントを利用できます。フォーカスイベントは通常はhandle-focus-in
で処理されます。
この関数は明示的なフォーカス通知をサポートするウィンドウシステムと端末からのfocus-inイベントを処理する。これはframe-focus-state
が問い合わせてafter-focus-change-function
を呼び出すフレームごとのフォーカスフラグを更新する。加えてEmacsが認識する選択されたフレームを、いくつかの端末でもっとも最近フォーカスされたフレームに切り替えるためにswitch-frame
イベントを生成する。Emacsの選択されたフレームをもっとも最近フォーカスされたフレームに切り替えることは、それぞれの端末にある他のフレームがフォーカスをもち続けることを意味しないことに注意することが大事。自分でこの関数を呼び出してはならない。かわりにロジックをafter-focus-change-function
につけ加えること。
この関数はフォーカス通知や最後のイベントとは異なるフレームから到着した入力イベントを含むさまざまな状況においてEmacsが自身のために生成するswitch-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
が呼び出されるまで継続する。
この関数はframeの既知の最後のフォーカス状態を取得する。
フレームにフォーカスがないと解っていればnil
、フォーカスがあると解っていればt
、フレームのフォーカス状態をEmacsが知らなければunknown
をリターンする(この最後の状態は明示的なフォーカス通知をサポートしない端末で実行中のTTYフレームで見ることがあるかもしれない)。
これはEmacsがフレームへのフォーカスを取得あるいは喪失する可能性に気づいた際に引数なしで呼び出される関数である。フォーカスイベントの配信は非同期であり、期待する順に配信されないかもしれないので、フレームのフォーカス状態に応じて何かを行いたいコードはすべてのフレームをチェックする必要がある。
たとえばフレームへのフォーカス有無にもとづきバックグラウンドカラーをセットするシンプルな関数例を以下に示す:
(add-function :after after-focus-change-function #'my-change-background) (defun my-change-background () (dolist (frame (frame-list)) (pcase (frame-focus-state frame) (`t (set-face-background 'default "black" frame)) (`nil (set-face-background 'default "#404040" frame)))))
フォーカスイベント配信の差異や別の要因のせいで、複数フレームが入力イベントをもつように見える場合があるので、このような状況に直面しても大丈夫なように堅牢なコードを記述するべきである。
ウィンドウシステムによってはフォーカスイベントが繰り返し配信されて、期待した値にセットする前に異なるフォーカス状態が配信されるかもしれない。フォーカス通知にもとづくコードはおそらく再表示まで処理を遅延することにより、フォーカス変更から生じるユーザーに可視の更新を“デバウンス(debounce)”する必要がある。
この関数はread-event
の内部を含む任意のコンテキストで呼び出されるかもしれないので、プロセスフィルター記述時と同様の注意を払うこと。
このオプションはフレーム内にマウスポインターを移動した際にウィンドウマネージャーがフォーカスを転送するかどうかと、その方法についてEmacsに知らせる。意味がある値は以下の3つ:
nil
デフォルト値nil
はウィンドウマネージャーが“click-to-focus(フレームがフォーカスを取得するためにフレーム内部でマウスをクリックする必要がある)”のポリシーにしたがう際に使用すること。
t
値t
はマウスポインターの位置にしたがってウィンドウマネージャーが自動的にフォーカスするが、フォーカスを得たフレームは自動的にレイズされず別のウィンドウシステムのウィンドウに隠されたままかもしれないときに使用すること。
auto-raise
値auto-raise
はマウスポインターの位置にしたがってウィンドウマネージャーが自動的にフォーカスして、フォーカスを得たフレームは自動的にレイズされる際に使用すること。
このオプションが非nil
なら、Emacsはselect-frame-set-input-focus
が選択したフレームにマウスポインターを移動する。この関数はother-frame
やpop-to-buffer
などいくつかのコマンドで使用される。
ウィンドウマネージャーは“通常”のフレームのレイズには通常は配慮するので、値t
とauto-raise
を区別する必要はない。これはmouse-autoselect-window
(マウスによるウィンドウの自動選択を参照)を通じて子フレームをレイズするために有用。
このオオプションは“sloppy”なフォーカス(ウィンドウシステムの別ウィンドウにマウスポインターが移動しないかぎり以前にフォーカスのあったフレームがフォーカスを保持する)と“strict”なフォーカス(マウスポインターが去るとフレームは即座にフォーカスを失う)を区別しないことに注意。ウィンドウマネージャーがフォーカスや自動レイズの遅延をサポートしていなくても、新たなフレームがフォーカスを取得(あるいは自動レイズ)するまでの時間を明示的に指定できる。
変数mouse-autoselect-window
(マウスによるウィンドウの自動選択を参照)をカスタマイズすることにより、個別のEmacsウィンドウにたいして“focus follows
mouse”ポリシーを提供できる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
グラフィカルなディスプレイ上のフレームは可視(visible)、不可視(invisible)、またはアイコン化(iconified)されているかもしれません。可視ならそのコンテンツは通常の方法により表示されます。アイコン化されている場合にはそのコンテンツは表示されませんが、ビュー内にフレームを戻すための小さいアイコンがどこかにあります(いくつかのウィンドウマネージャーはこの状態をアイコン化ではなく最小化と呼ぶがEmacsの見地ではこれらは同等である)。フレームが不可視ならまったく表示されません。
可視性の概念はマップ(または非マップ)されたフレームと強い関連性があります。フレーム(より正確にはウィンドウシステムのウィンドウ)は最初に表示されるときにマップ済み(mapped)となり、状態がiconified
やinvisible
からvisible
に変化します。それとは逆に状態がvisible
からiconified
やinvisible
に変化したときは、フレームは常に非マップ済み(unmapped)になります。
テキスト端末では実際に表示されるのは常に選択されたフレームだけなので可視性に意味はありません。
この関数はフレームframeの可視性の状態をリターンする。値はframeが可視ならt
、不可視ならnil
、アイコン化されていればicon
。
テキスト端末上ではたとえ1つのフレームだけが表示されているとしても、この関数の目的にたいしてはすべてのフレームが可視とみなされる。フレームのraise、lower、re-stackを参照のこと。
この関数はフレームframeをアイコン化する。frameを省略すると選択されたフレームをアイコン化する。これにより通常はframeのすべての子フレーム(と子孫)は不可視になる(子フレームを参照)。
この関数はフレームframeを可視にする。frameを省略すると選択されたフレームを可視にする。これはフレームを前面に移動しないが、望むならraise-frame
でこれを行うことができる(フレームのraise、lower、re-stackを参照)。
通常はフレームを可視とすることにより、すべての子フレーム(と子孫)も同様に可視になる(子フレームを参照)。
この関数はフレームframeを不可視にする。frameを省略すると選択されたフレームを不可視にする。これにより通常はframeのすべての子フレーム(と子孫)も不可視になる(子フレームを参照)。
この関数はforceがnil
の場合には、他のすべてのフレームが不可視ならframeを不可視にすることを拒絶する。
フレームの可視性の状態はフレームパラメーターとしても利用可能である。つまりフレームパラメーターとして読み取りと変更ができる。ウィンドウ管理のパラメーターを参照のこと。ウィンドウマネージャーによりユーザーがフレームのアイコン化や非アイコン化を行うこともできる。これはEmacsが何らかの制御を及ぼすのが可能なレベルより下のレベルにおいて発生するが、Emacsはそのような変化を追跡するために使用するイベントを提供する。その他のシステムイベントを参照のこと。
この関数はframeがカレントでダブルバッファリングで描画されていれば非nil
をリターンする。frameのデフォルトは選択されたフレーム。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ほとんどのウィンドウシステムではデスクトップというメタファー(metaphor: 比喩的概念)が使用されています。このメタファーの一部はシステムレベルのウィンドウ(Emacsではフレーム)がスクリーン表面に向かって、概念的3次元の垂直方向にスタッキングされる(重ねて表示される)というアイデアにもとづいています。スタッキングによる順序は合計であり、通常はスタッキングの順序(またはZオーダー)として参照されます。2つのゥィンドウがオーバーラップする領域では、このオーダーにおいて高位のウィンドウが、下位のウィンドウ(の一部)をカバーします。
関数raise-frame
とlower-frame
を使用してフレームのZオーダーの一番上にraiseしたり一番下にlowerすることができます。関数frame-restack
を使用すれば別のフレームの上や下にフレームを直接restackできます。
以下で説明するすべての関数はフレーム(および他のウィンドウシステムのウィンドウすべて)の対応するZグループを尊重することに注意してください(位置のパラメーターを参照)。たとえば通常はフレームをデスクトップウィンドウよりlower(下位)にすることや、z-group
パラメータ0が非nil
のフレームをウィンドウシステムのタスクバーやツールチップウィンドウよりraise(上位)にすることはできません。
この関数はをframeのz-groupと同じかlower(下位)にある他のすべのフレームの上位にフレームframe (デフォルトは選択されたフレーム)をraiseする。frameが不可視やアイコン化されていたら可視になる。frameが子フレーム(子フレームを参照)なら、親フレームの他のすべての子フレームの上位にframeをraiseする。
この関数はをframeのz-groupと同じか上位にある他のすべのフレームの下位へフレームframe (デフォルトは選択されたフレーム)をlowerにする。frameが子フレーム(子フレームを参照)なら、親フレームの他のすべての子フレームの下位にframeをlowerする。
この関数はframe2の下にframe1を再スタックする(restack:
再び重ねる)。いずれのフレームも可視で表示エリアがオーバーラップしていたら、frame2がframe1を(部分的に)隠すことを暗に示している。オプションの3つ目の引数aboveが非nil
なら、この関数はframe2の上にframe1を再スタックする。これはいずれのフレームも可視で表示エリアがオーバーラップしていたら、frame1がframe2を(部分的に)隠すことを意味している。
この関数は最初のステップではディスプレイからframe1のウィンドウシステムのウィンドウを削除して、2つ目のステップで( aboveが真なら)frame2のウィンドウの下にframe1のウィンドウを再挿入を行う、2つのステップによりアトミックなアクションを処理すると技術的に考えることができる。したがってframe1を除く他のすべてのフレームに相対的なframe2のディスプレイ内でのZオーダー(スタッキングオーダー)は変更されない。
いくつかのウィンドウマネージャーはウィンドウの再スタックを拒絶する。
再スタックの効果は関連するフレームがアイコン化されたり不可視になったりしないかぎり継続することに注意してください。フレームを他のフレームの上位(や下位)に永続的に表示されるフレームグループに追加するためにフレームパラメーターz-group
(位置のパラメーターを参照)を使用できます。これらのグループのいずれかにフレームが所属するかぎり、再スタックはそのグループ内での相対的なスタッキング位置にのみ効果があります。異なるZグループに所属するフレームにたいする再スタックの効果は未定義です。関数frame-list-z-order
でカレントのフレームスタッキングオーダーをリストできます(すべてのフレームを探すを参照)。
これが非nil
ならミニバッファーをアクティブにすることにより、ミニバッファーウィンドウのあるフレームが前面に移動される。
ウィンドウシステム上ではフレームパラメーターを使用して、(フレーム選択時に)auto-raising、(フレーム選択解除時に)auto-loweringを有効にできます。ウィンドウ管理のパラメーターを参照してください。
フレームを前面や背面に移動するという概念は、テキスト端末のフレームにも適用できます。各テキスト端末上では一度に表示されるのは常に最前面のフレームだけです。
この関数はterminal上の最前面のフレームをリターンする。terminalは端末オブジェクト、フレーム(そのフレームの端末を意味する)、またはnil
(選択されたフレームの端末を意味する)であること。これがテキスト端末を参照しなければリターン値はnil
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フレーム構成(frame configuration)はフレームのカレント配置、すべてのプロパティ、および各ウィンドウのウィンドウ構成(ウィンドウの構成を参照)を記録します。
この関数はフレームのカレント配置とそのコンテンツを記述するフレーム構成のリストをリターンする。
この関数はフレームの状態をconfigurationの記述にリストアする。ただしこの関数は削除されたフレームはリストアしない。
この関数は通常はconfiguration内にリストされない既存フレームすべてを削除する。しかしnodeleteが非nil
なら、それらのフレームはかわりにアイコン化される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
子フレームはウィンドウ(ウィンドウを参照)と“通常”のフレームとの中間にあるオブジェクトです。ウィンドウのよように所属するフレームにアタッチされますが、ウィンドウとは異なり互いにオーバーラップすることができます。子フレームの1つのサイズや位置を変更しても兄弟となる他の子フレームのサイズや位置は変化しません。
仕様により子フレームの作成や変更を行う操作は特別な関数やカスタマイズ可能な変数ではなくフレームパラメーター(フレームのパラメーターを参照)の助けを借りて実装されています。子フレームはグラフィカル端末でのみ意味があることに注意してください。
子フレームを新たに作成したり通常のフレームを子フレームに変換するためには、そのフレームのparent-frame
パラメーター(フレームとの相互作用のためのパラメーターを参照)にすでに存在するフレームをセットします。このパラメーターで指定されたフレームは、パラメーターが変更やリセットされるまでフレームの親フレームになります。これにより技術的には子フレームのウィンドウシステムのウィンドウは、親フレームのウィンドウシステムのウィンドウの子ウィンドウになります。
parent-frame
パラメーターはいつでも変更できます。これを他のフレームにセットすれば子フレームがreparent(親を変更)されます。別の子フレームにセットすればフレームをネストされた(nested)子フレームにします。にセットすればフレームの状態をトップレベルのフレーム(ウィンドウシステムのウィンドウがディスプレイーのルートウィンドウの子であるようなフレーム)にリストアします。22
子フレームは任意にネスト(入れ子)させることができるので、フレームは子フレームと親フレームの両方になることができます。また子フレームと親フレームの相対的な役割はいつでも逆転させることができます(たとえ子フレームを親フレームより十分小さいサイズに保つことが通常はよいアイデアであるとしても)。フレームをそのフレームの祖先にしようと試みるとエラーがシグナルされます。
ほとんどのウィンドウシステムは親フレームのネイティブエッジ(フレームのジオメトリーを参照)で子フレームをクリップします(これらのエッジの外側は通常は不可視になる)。子フレームのパラメーターleft
とtop
は親のネイティブフレームの左上隅から相対的な位置を指定します。親フレームがリサイズされたとき、この位置は概念的には変更されません。
NSビルドは親フレームのエッジで子フレームをクリップしないので、子フレーム自身が可視であっても親フレームを隠さないように配置することができます。
通常は親フレームを移動することにより、すべての子フレームとその子孫も相対的な位置が変化しないように一緒に移動されます。フックmove-frame-functions
(フレームの位置を参照)は子フレームの親フレームにたいする相対的な位置が変化したときだけ実行されます。
親フレームがリサイズされた際には、子フレームは概念的には以前のサイズと親フレームの左上隅からの相対的な位置を保ちます。これは親フレームが縮小されると子フレームが(部分的に)不可視になるかもしれないことを意味しています。親フレームのリサイズ時に常に子フレームを比例してリサイズおよび再配置するためにパラメーターkeep-ratio
を使用できます(フレームとの相互作用のためのパラメーターを参照)。これにより親フレームが縮小された際にフレームの一部が隠されることを防ぐことができます。
可視な子フレームは常に親フレームの最上位に表示されるので、親フレームの下位に表示可能なNSビルド以外では親フレームの一部を隠すことになります。これは常に親ウィンドウであるデスクトップのルートウィンドウの最上位に表示されるトップレベルフレームのウィンドウシステムのウィンドウに相当します。親フレームがアイコン化されたり不可視(フレームの可視性を参照)になったときには子フレームは不可視になります。親フレームが非アイコン化されたり可視になると子フレームは可視になります。
親フレームが削除される際には、その前に子フレームが再帰的に削除されます(フレームの削除を参照)。この規則には1つの例外があります。子フレームが他のフレームの代理ミニバッファーフレーム(ミニバッファーとフレームを参照)を果たす際には、親フレームが削除されるまで削除されずに留まります。。この時点でその子フレームをミニバッファーとして使用するフレームが残っていなければ、Emacsは子フレームの削除も試みます。理由は何であれこの削除が失敗すると、その子フレームがトップレベルのフレームになります。
子フレームがメニューバーやツールバーをもてるかどうかはウィンドウシステムやウィンドウマネージャーに依存します。ほとんどのウィンドウシステムは子フレームのメニューバーを明示的に許可していません。フレームの初期パラメーターのセッティングでメニューバーとツールバーの両方を無効にすることを推奨します。
子フレームは通常はタイトルバーやエクスターナルボーダー(フレームのジオメトリーを参照)のようなウィンドウマネージャーの装飾を表示しません。子フレームがメニューバーやツールバーを表示しないときには他の種類のフレームのボーダーをエクスターナルボーダーのかわりに使用できます(レイアウトのパラメーターを参照)。
特にX(ただしGTK+ビルド以外)ではフレームのアウターボーダーを使用できます。MS-Windowsでは非0のアウターボ^ダーを指定することにより、幅が1ピクセルのエクスターナルボーダーが表示されます。すべてのウィンドウシステムにおいてインターナルボーダーを使用できます。いずれのケースでもフレームパラメーターundecorated
(ウィンドウ管理のパラメーターを参照)で子フレームにたいするウィンドウマネージャーの装飾を無効にすることを推奨します。
マウスで装飾されていない子フレームのリサイズや移動を行うためには、特別なフレームパラメーターを使う必要があります(マウスドラッグのパラメーターを参照)。子フレームのインターナルボーダーが存在する場合には、そのフレームが非nil
のdrag-internal-border
パラメーターをもっていればマウスによるフレームのリサイズに使用できます。snap-width
がセットされていれば、それは親フレームのエッジやコーナーそれぞれでフレームをスナップ(snaps)するピクセル数を表します。
マウスで子フレーム全体をドラッグするためには2つの方法があります。drag-with-mode-line
パラメーターが非nil
なら、ミニバッファーウィンドウのないフレーム(ミニバッファーのウィンドウを参照)の最下ウィンドウのモードラインエリアを通じてドラッグできます。drag-with-header-line
パラメーターが非nil
なら、フレームの最上ウィンドウのヘッダーラインを通じたドラッグが可能です。
子フレームにドラッグ可能なヘッダーラインやモードラインを与えるためには、ウィンドウパラメーターmode-line-format
とheader-line-format
(ウィンドウのパラメーターを参照)を使用するのが手軽です。これらにより(drag-with-header-line
の選択時に)不要なモードラインを削除したり、フレームのドラッグと干渉するマウス感応エリアを削除できます。
ユーザーが親フレームの外へフレームをマウスでドラッグすれば、親フレームのスクリーン領域外へ簡単にドラッグできます。マウスボタンを一度離してしまうと、そのようなフレームを取得するのは難しくなります。そのような状況を避けるために、フレームのパラメーターtop-visible
およびbottom-visible
(マウスドラッグのパラメーターを参照)をセットすることをお勧めします。
ヘッダーラインでユーザーにフレームをドラッグさせたければ、子フレームのtop-visible
パラメーターに数値をセットします。top-visible
に数値をセットすることによって、親フレームの上エッジを超えて子フレームの上エッジをドラッグすることが抑制されます。モードラインを介してフレームをドラッグさせたければ、bottom-visible
に数値をセットしてください。これは親フレームの下エッジを超えて子フレームの下エッジをドラッグすることを抑制します。いずれの場合でも、セットした数値は同時にドラッグの間に可視に留まる子フレーム領域の幅および高さをピクセルで指定します。
display-buffer-in-child-frame
(バッファー表示用のアクション関数を参照)を介してバッファー表示に子フレームが使用されている際には、バッファーを表示中のウィンドウがquitされる際にフレームを適切に処理するために、フレームのauto-hide-function
パラメーターに関数をセットできます(フレームとの相互作用のためのパラメーターを参照)。
たとえば別のウィンドウに補完を表示する等でミニバッファーとの相互作用中子フレームを使用する際には、ミニバッファーのexit時にフレームを適切に処理するためにminibuffer-exit
パラメーター(フレームとの相互作用のためのパラメーターを参照)が便利です。
子フレームの振る舞いは他のいくつかの点においても、トップレベルのフレームから逸脱しています。それらのいくつかを以下に挙げます:
iconify-frame
を呼び出すと子フレームにに対応するトップレベルのフレームにたいしてアイコン化を試みる。異なる挙動を得るためには、以下で説明するオプションiconify-child-frame
をカスタマイズできる。
z-group
(位置のパラメーターを参照)の変更では、同じ親をもつ子フレームのstack順だけが変更される。
mouse-autoselect-window
のカスタマイズが助けになるかもしれない(マウスによるウィンドウの自動選択を参照)。
以下の2つの関数は子フレームと親フレームで処理を行う際に役に立つかもしれません:
この関数はframeの親フレームをリターンする。frameの親フレームはウィンドウシステムのウィンドウがframeのウィンドウシステムのウィンドウの親ウィンドウであるようなEmacsフレーウである。そのようなフレームが存在すれば、frameはそのフレームの子フレームとみなされる。
この関数はframeに親フレームがなければnil
をリターンする。
この関数はancestorがdescendantの祖先なら非nil
をリターンする。ancestorがdescendantの親フレームかdescendantの親フレームの祖先なら、ancestorはdescendantの祖先である。ancestorとdescendantにはいずれも生きたフレームを指定しなければならない。
既存ウィンドウの最大の空エリア内への子フレームの描画に使用できる関数window-largest-empty-rectangle
にも注意してください(座標とウィンドウを参照)。これは子フレームがウィンドウ内に表示されているテキストを隠さないようにするために有用です。
子フレームにたいするiconify-frame
の挙動の調整に以下のオプションのカスタマイズが役に立つかもしれません。
このオプションはEmacsにたいして子フレームのアイコン化を要求された際に処理を行う方法を指定する。nil
ならiconify-frame
が子フレームに呼び出された際には何も行わない。iconify-top-level
なら子フレームの祖先であるトップレベルのフレームをアイコン化する。make-invisible
ならアイコン化せずに子フレームを不可視にしようと試みる。
その他の値は子フレームのアイコン化を試みることを意味する。そのような試みはすべてのウィンドウマネージャーで許容されるとはかぎらず、子フレームがユーザーのアクションに無応答になることさえあり得るので、デフォルトではトップレベルのフレームをアイコン化する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マウスをトラック(track: 追跡)するのが有用なことが時折あります。マウスのトラックとはマウスの位置を示す何かを表示して、マウス移動とともにそのインジケーターを移動するという意味です。効果的にマウスをトラックするためには、マウスが実際に移動するまで待機する手段が必要になります。
マウスをトラックするためには、マウスのモーション(motion: 移動)を表すイベントを問い合わせるのが便利な方法です。その後はそのイベントを待機することによりモーションを待機できます。それに加えて発生し得る他の類のイベントも簡単に処理できます。ボタンのリリースのような何か他のイベントだけを待機してマウスを永久にトラックすることは、通常は望ましくないのでこれは有用です。
このマクロはマウスモーションイベントの生成を有効にしてbodyを実行する。bodyはモーションイベントを読み取るために、通常はread-event
を使用してそれに対応して表示を変更する。マウスモーションイベントのフォーマットについてはモーションイベントを参照のこと。
body内の最後のフォームの値がtrack-mouse
の値となる。ボタンのリリースを示すup-eventや、何であれトラッキングを停止すべきタイミングを意味するイベントを確認したらbodyからリターンするようデザインすること。この変数の値はマウスボタンが押されたときに、そのマウスイベントがどのように報告されるかも制御する。値がdropping
かdrag-source
なら、ポインター下にあるフレームに関連するモーションイベントが報告される。そのようなフレームがなければ、そのイベントはマウスボタンが最初に押されたフレームと関連のあるイベントとして報告される。加えて値がdrag-source
なら、マウス位置リストのposn-window
はnil
になる。これはマウスポインター下にあるフレームが直接見えないときに有用。
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のデフォルト文字サイズ(フレームのフォントを参照)の単位で位置を与える整数(丸められている可能性あり)。
この変数の値は非nil
ならmouse-position
にたいして呼び出される関数。mouse-position
はリターン直前に、自身の通常のリターン値を唯一の引数としてこの関数を呼び出して、それが何であれその関数がリターンした値をリターンする。
このアブノーマルフックはxt-mouse.elのようにLispレベルでマウス処理を行う必要があるパッケージのために存在する。
非nil
なら、上述のようにTTYメニューはmouse-position-function
を呼び出す。これは再表示をトリガーする等、TTYメニューからのmouse-position-function
呼び出しが安全ではない場合のために存在する。
この関数はフレームframe内の位置x、yにマウスをワープ(warps the mouse)する。引数xとyはframeのネイティブ位置(フレームのジオメトリーを参照)から相対的に、frameのデフォルト文字サイズ(フレームのフォントを参照)の単位で位置を与える整数(丸められている可能性あり)。
結果となるマウス位置は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
で実装されないのはこれが理由です。メニューバーを参照してください。
メニューバーのサブメニューのコンテンツを変化させたい場合にも、その実装には依然としてメニューキーマップを使用するべきです。コンテンツを変化させるためには、必要に応じてメニューキーマップのコンテンツを更新するためにフック関数をmenu-bar-update-hook
に追加してください。
x-popup-menu
の呼び出しから直接、またはメニューキーマップを通して表示されるポップアップメニューの表示直前に実行されるノーマルフック。何らかの理由によりポップアップメニューを表示せずにx-popup-menu
がリターンしたら呼び出されない。
[ << ] | [ < ] | [ 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
テキスト上にあるときの通常のマウスポインタースタイル(“I”のようなシェイプ)。
arrow
vdrag
modeline
北西向き矢印。
hand
上向きの手。
hdrag
左右の矢印。
nhdrag
上下の矢印。
hourglass
回転する輪。
ウィンドウの空部分(void parts:
バッファーコンテンツのどの部分にも対応しない部分)の上では、マウスポインターは通常arrow
スタイルを使用しますが、void-text-area-pointer
をセットすることにより異なるスタイルを指定できます。
この変数は空テキストエリアにたいするマウスポインタースタイルを指定する。このエリアには行末の後やバッファー終端行の下が含まれる。デフォルトではarrow
(non-text)ポインタースタイルを使用する。
一部のウィンドウシステムを使用する際には、変数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つのマーカーのコンスを指定できる。オーバーレイとマーカーのペアは、そのオーバーレイまたはマーカー間のテキストを意味する。引数dataには有効な非ベクターの選択のベクターも指定できる。
dataが文字列なら、そのテキストプロパティによって個々のデータタイプに使用する値を指定できる。たとえばdataがtext/uri-list
という名前のテキストプロパティを保有していれば、データタイプtext/uri-list
とともにgui-get-selection
を呼び出すことによって、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] | [ ? ] |
たとえばあなたがウェブブラウザで“Copy
Image(イメージをコピー)”を選択したとすると、そのイメージはクリップボードに配置されて、Emacsはgui-get-selection
を通じてそのイメージにアクセスすることができます。ただし一般的にはイメージデータを任意のバッファーに挿入してもあまり役には立ちません。デフォルトのままでは実際のところ大したことはできないのです。
そのためにEmacsでは、これらの“複雑”な選択にたいしてモードがハンドラーを登録できるようになっています。
typesはMIMEメディアタイプのシンボルやそれらにマッチするregexp、またはシンボルとregexpのリスト。たとえば:
(yank-media-handler 'text/html #'my-html-handler) (yank-media-handler "image/.*" #'my-image-handler)
モードは必要な数のハンドラーを登録できる。
関数handlerはメディアタイプシンボルMIMEとデータ(文字列)という2つのパラメーターで呼び出される。このハンドラーはそのオブジェクトのバッファーへの挿入や保存、あるいはそれが何であれそのモードにとって適切な処理を行うこと。
yank-media
コマンドはカレントバッファーで登録されたハンドラーを照会するとともに、クリップボード上の利用可能なメディアタイプと比較を行い、(もしあれば)マッチした選択をそのハンドラーに渡します。マッチする選択が複数あれば、まずユーザーに問い合わせを行います。
クリップボード/プライマリー選択を調べるためにyank-media-types
コマンドを使うことができます。これはカレントで利用可能なメディアタイプすべてをリストします。これは実際に利用可能なデータは何なのかを確認できるので、ハンドラーの作成時に便利でしょう。一部のアプリケーションは、驚くほど多くの異なるデータタイプをクリップボードに配置します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
他のアプリケーションからユーザーが何かをEmacsの上にドロップすると、Emacsはドロップされたテキストの挿入、あるいはドロップされたURLのオープンを試みます。Emacsは常にテキストがドロップされると、そのドロップ発生時のマウスポインター位置にテキストを挿入するか、挿入が失敗した場合には(そのバッファーが読み取り専用の場合に発生し得る)そのテキストをkillリングに保存します。URLがドロップされた場合には、EmacsはそのURLと変数dnd-protocol-alist
に定義されたregexp、その後は変数browse-url-handlers
、browse-url-default-handlers
に定義されたregexpをマッチして適切なハンドラー関数の呼び出しを試みます。もし適切なハンドラーが見つからなければ、EmacsはそのURLを平文テキストとして挿入するというフォールバック処理を行います。
この変数は(pattern . action)
という形式のコンスセルのリストである。ここでpatternはドロップされた後にそのURLにたいしてマッチされるregexp、actionはドロップされたURLがpatternにマッチした場合に2つの引数で呼び出される関数で、1つ目の引数はドロップされたURL、2つ目の引数はcopy
、move
、link
、private
、ask
というシンボルのいずれか。
actionがprivateなら、それはドロップ操作を開始したプログラムが、そのURLでは指定されていないアクションをEmacsに行って欲しいことを意味する。この場合に行うべき妥当なアクションはそのURLのオープン、あるいはカレントバッファーへのそのURLのコンテンツのコピーとなる。それ以外のactionは、dnd-begin-file-drag
にたいするaction引数と同じ意味合いとなる。
Emacsはウィンドウシステムそれぞれにたいして個別にテキストとURLの受信を実装しており、他の種別のドロップによる受信はデフォルトではサポートしていません。他の種別のデータの受信をサポートするためには、以下のX固有のインターフェイスを使用してください。
Xウィンドウシステムにおいてユーザーが別のアプリケーションからEmacsに何かをドラッグすると、そのアプリケーションはEmacsがドラッグされたデータを理解しているかどうかを告げることを期待します。このような問いにたいして何を応答するか決定するためにEmacsが用いるのが、変数x-dnd-test-function
内の関数です。デフォルト値はx-dnd-default-test-function
で、これはドロップされたデータのタイプがx-dnd-known-types
内に存在すればドロップを受け入れます。何か別の条件にもとづいてEmacsにドロップを許容または拒絶させたければ、x-dnd-test-function
およびx-dnd-known-types
を変更してください。
Emacsが別のデータタイプのドロップを受け取る方法を変更したり、新たなタイプを理解するためにドロップを有効にしたい場合にはx-dnd-types-alist
を変更してください。これを正しく行うためには他のアプリケーションがドラッグアンドドロップに使用するデータタイプが何なのかに関する詳細な知識が要求されます。
これらのデータタイプは通常は他のアプリケーションから提供されたX選択から入手できるスペシャルデータタイプとして実装されています。ほとんどのケースにおいて、これらはgui-set-selection
が通常許容するのと同じデータタイプかMIMEタイプのいずれかであり、それは使用される固有のドラッグアンドドロップのプロトコルに依存します。たとえば平文テキストに用いられるのは"STRING"
か"STRING"
のいずれかでしょう。
XウィンドウシステムでEmacsを実行する際には、XDS (X Direct
Save)というプロトコルがサポートされます。このプロトコルによってユーザーがファイルをDiredウィンドウのようなEmacsウィンドウにドラッグアンドドロップして保存ができるようになります。XDSに独特な要件に準拠するために、これらのドラッグアンドドロップの要求は特別に処理されます。つまりx-dnd-types-alist
に応じて処理されるのではなく、変数x-dnd-direct-save-function
の値であるdirect-save関数(direct-save
function)によって処理されるのです。これはneed-nameおよびfilenameという2つの引数を受け取る関数である必要があります。XDSプロトコルではファイルのドラッグにたいして2段階の手続きが用いられます:
nil
、2つ目の引数filenameに保存するファイルのディレクトリー部分を除いた名前をセットしてdirect-save関数が呼び出される。この関数はファイルを保存するための完全に展開された絶対ファイル名をリターンする必要がある。たとえばDiredウィンドウにファイルがドラッグされれば、そのファイルのディレクトリーは当然ドロップされた場所に表示されているファイルのディレクトリーになるだろう。何らかの理由によりファイルの保存が不可能な場合には、この関数はドラッグアンドドロップ操作をキャンセルするnil
をリターンする必要がある。
nil
、2つ目の引数filenameに保存したファイルの完全な絶対ファイル名をセットして、もう一度direct-save関数を呼び出す。この関数にはファイルが保存されたという事実に鑑み、何であれ必要な処理を行うことが期待される。たとえばDiredならそこに新たなファイルを表示して、ディスプレイ上のディレクトリーを更新する必要があるだろう。
x-dnd-direct-save-function
のデフォルト値はx-dnd-save-direct
です。
引数need-nameが非nil
で呼び出されると、この関数はファイルを保存するためにユーザーに絶対ファイル名の入力を求める。指定されたファイルがすでに存在する場合には、上書きするかどうかの入力をユーザーに追加で求めて、ユーザーが上書きに同意した場合のみ絶対ファイル名をリターンする。
引数need-nameがnil
で呼び出された際には、カレントバッファーがDiredモード、あるいはDiredを継承する子孫の場合にはDiredの一覧リストをリバート、それ以外の場合にはfind-file
(ファイルをvisitする関数を参照)を呼び出してそのファイルをvisitする。
この関数はx-dnd-save-direct
と同様に機能するが、引数need-nameが非nil
で呼び出されても、ファイルを保存するための完全なファイル名の入力をユーザーに求めずに、カレントバッファーのデフォルトディレクトリーにたいしてfilename引数を展開してリターンする(デフォルトディレクトリーにその名前のファイルが既に存在する場合に確認を求めるのは変わらず)。
ウィンドウシステムが対応していれば、Emacsのフレームから他のアプリケーションウィンドウへのコンテンツのドラッグもEmacsはサポートします。
この関数はframeから別のプログラム(ドロップターゲット(drop target)と呼ばれるへのテキストのドラッグを開始して、テキストがドロップされた際のドラッグアンドドロップ操作の結果、またはドラッグアンドドロップ操作がキャンセルされたという結果をリターンする。textはドロップターゲットによって挿入されることになるテキスト。
actionはcopy
かmove
というシンボルのいずれかでなければならない。ここでcopy
はドロップターゲットによってtextが挿入されるべきであることを意味する。move
はcopy
と同様だが、後述するように呼び出し元は更にソースからtextを削除する必要があるかもしれないことを意味する。
frameはマウスボタンをカレントで押下したフレーム。nil
は選択されているフレームを意味する。どのマウスボタンも押されていなければ即座にリターンするかもしれないので、down-mouse-1
やそれに類するイベント(マウスイベントを参照)の直後のみ、そのイベントが発生したフレーム(クリックイベントを参照)をframeにセットして呼び出すこと。
allow-same-frameはframe自体の上へのドロップを無視するかどうかを指定する。
リターン値はドロップターゲットが実際に行ったアクション、オプションで呼び出し元が何を行うべきかを指定する。リターン値は以下のうちのシンボルのいずれか:
copy
ドロップターゲットはドロップされたテキストを挿入した。
move
ドロップターゲットはドロップされたテキストを挿入したが、呼び出し元はそのドロップ元(たとえばバッファー)からtextを削除する必要がある。
private
ドロップターゲットは指定されていない何らかのアクションを行った。
nil
ドラッグアンドドロップの操作はキャンセルされた。
この関数はframeから別のアプリケーションへのfileのドラッグを開始して、そのファイルがドロップされた際のドラッグアンドドロップ操作の結果、あるいはドラッグアンドドロップ操作がキャンセルされたという結果をリターンする。
fileがリモートファイルなら、一時的なコピーを作成する。
actionはcopy
、move
、またはlink
,のいずれかでなければならない。ここでcopy
はドロップターゲットによってfileがオープンまたはコピーされるべきことを、move
はドロップターゲットがファイルを別の場所に移動すべきことを、そしてlink
はドロップターゲットがfileへのシンボリックリンクを作成するべきであることを意味する。fileがリモートファイルの場合にアクションとしてlink
を指定するとエラーになる。
frameとallow-same-frameの意味はdnd-begin-text-drag
の場合と同様。
リターン値はドロップターゲットが実際に行ったアクションで、以下のうちのシンボルのいずれか:
copy
ドロップターゲットはfileをオープンした、または別の場所へコピーした。
move
ドロップターゲットはfileを別の場所に移動した。
link
ドロップターゲット(通常はファイルマネージャー)はfileへのシンボリックリンクを作成した。
private
ドロップターゲットは指定されていない何らかのアクションを行った。
nil
ドラッグアンドドロップの操作はキャンセルされた。
この関数はdnd-begin-file-drag
と同様だが、filesがファイルのリストである点が異なる。ドロップターゲットが複数ファイルのドロップをサポートしていなければ、かわりに1つ目のファイルが使用される。
この関数はdnd-begin-file-drag
と似ているが、アクションのかわりにname
を指定することによって、ターゲットプログラムがその名前のコピーを作成する点が異なる(デフォルトのアクションとしてコピーを行う関数)。
上述した高レベルのインターフェイスは、低レベルなプリミティブの上位に実装されています。ファイルやテキスト以外のコンテンツのドラッグを使用が必要なら、x-begin-drag
のかわりに低レベルのインターフェイスを使用してください。ただしこれらの低レベルなインターフェイスの使用にはデータタイプ、それにあなたがサポートしたいプラットフォームそれぞれにおいて、プログラムがドラッグアンドドロップを通じたコンテンツ転送に用いるアクションに関する詳細な知識が必要となるでしょう。
この関数はframeからのドラッグを開始して、そのドラッグアンドドロップがドロップに成功するか、あるいは拒絶されたかのいずれにより操作終了したらリターンする。ドロップはframe以外のトップレベルのXウィンドウ(ドロップターゲット、allow-current-frameが非nil
なら任意のXウィンドウ)の上でマウスボタンがリリースされた際に発生する。そのドラッグアンドドロップ操作の開始時にどのマウスボタンも押されていなければ、この関数は即座にnil
をリターンする。
targetsはgui-get-selection
のdata-type引数のような、選択されているターゲットを記述した文字列のリストであり、ドロップターゲットがEmacsに要求する可能性がある(ウィンドウシステムによる選択を参照)。
actionはターゲットに推奨されているアクションを記述したシンボル。XdndActionCopy
(選択されているXdndSelection
のコンテンツをドロップターゲットにコピー)、XdndActionMove
(XdndActionCopy
のようにコピーを行い更にコピー後は選択に格納されていたものが何であれ削除が必要)のいずれか。
利用可能なアクションが記述されたシンボルと、ドロップターゲットが利用可能なアクションを選択する際にユーザーへの提示を期待する文字列を関連付けるalistでもよい。
return-frameが非nil
、および最初にマウスがframeの外に移動してからEmacsフレームに移動した場合には、マウスが移動したフレームを即座にリターンする。return-frameがシンボルnow
なら、最初にマウスがframeの外に移動するのを待機せずに、フレームが何であれマウスポインター配下にあればそのフレームをリターンする。return-frameは特にあるフレームから別のフレームへのコンテンツのドラッグを扱いたい際に役に立つだろう。他のプログラムへのコンテンツのドラッグも扱えるものの、すべてのシステムやウィンドウマネージャーで動作する保証はない。
follow-tooltipが非nil
の場合には、ドラッグアンドドロップ操作の間にマウスポインターが移動するたびに、(tooltip-show
によって表示されるような)ツールチップの位置がマウスポインターの位置にしたがうようになる。マウスボタンがリリースされるとツールチップは非表示になる。
ドロップが拒絶されるかドロップターゲットが見つからなければ、この関数はnil
をリターンする。それ以外の場合には、ターゲットが行うことを選択したアクション(ドロップターゲットがサポートしていなければactionとは異なるかもしれない)を記述するシンボルをリターンする。XdndActionCopy
とXdndActionMove
に加えてXdndActionPrivate
も有効なリターンである。これはドロップターゲットが指定されていないアクションを選択したことを意味しており、呼び出し元はそれ以上の処理を要求されない。
呼び出し元はターゲットによって選択された処理を完遂するために、ターゲットと協力しなければならない。たとえばこの関数がXdndActionMove
をリターンしたら、呼び出し元はドラッグされたバッファーのテキストを削除すること。
Xウィンドウではx-begin-drag
は、複数の異なるドラッグアンドドロップのプロトコルをサポートします。ある特定のドラッグアンドドロップのプロトコルによってサポートされているか不明なコンテンツをドラッグする際には、以下の変数の値を変更してそのプロトコルをオフに切り替えることが望ましい場合があります:
この変数が非nil
ならMotifのドラッグアンドドロップのプロトコルは無効化となり、それらのプロトコルしか理解していないプログラムへのドロップは機能しない。
この変数がnil
ならOffiX(旧KDE)のドラッグアンドドロップのプロトコルは無効となる。シンボルfiles
なら、x-begin-drag
によって与えられたターゲットのいずれかが"FILE_NAME"
の場合のみOffiXプロトコルが使用される。それ以外の値の場合には、サポートされているコンテンツのドロップにOffiXプロトコルが使用される。
x-begin-drag
によって与えられたリスト内に"STRING"
、"UTF8_STRING"
、"COMPOUND_TEXT"
、"TEXT"
のいずれかのターゲットがあれば、ドロップターゲットが何もドラッグアンドドロップのプロトコルをサポートしていなくても、Emacsは合成されたマウスイベントとプライマリー選択を用いてテキストの挿入を試みる。
そのようなドロップにおいては、Emacsがそのプライマリー選択の所有者になるという副作用がある。これが望ましくなければ、この変数をnil
にセットされたドロップエミュレーションを無効にできる。
[ << ] | [ < ] | [ 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") ⇒ (65535 65535 65535) (color-values "red") ⇒ (65535 0 0) (color-values "pink") ⇒ (65535 49344 52171) (color-values "hungry") ⇒ nil
カラーの値はframeのディスプレイにたいしてリターンされる。frameが省略またはnil
の場合には、この情報は選択されたフレームのディスプレイにたいしてリターンされる。このフレームがカラーを表示できなければ値はnil
。
この関数は以前はx-color-values
と呼ばれており、その名前は今でもエイリアスとしてサポートされている。
この関数はcolor-values
と同じことを行うが、0.0から1.0(両端を含む)の浮動小数点数としてカラー値をリターンする。
この関数はRGBトリプレットで示されるカラーrgbが、暗いバックグラウンド(dark
background)のときより明るいバックグラウンド(white
background)のときの方が可読性に優れる場合には非nil
をリターンする。引数rgbは(r g b)
という形式のリストであること。リストの要素はそれぞれ0.0から1.0(両端を含む)の浮動小数点数。カラー名をこのようなリストに変換するためにはcolor-name-to-rgb
を使うことができる。
[ << ] | [ < ] | [ 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)機能も参照してください(フィールドの定義と使用を参照)。
31.1 ポイント | 編集タスクが行われる特別な位置。 | |
31.2 モーション | ポイントの変更。 | |
31.3 エクスカーション | 一時的な移動とバッファーの変更。 | |
31.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] | [ ? ] |
モーション関数はポイントのカレント値、バッファーの先頭か終端、または選択されたウィンドウ端のいずれかより相対的にポイントの値を変更します。ポイントを参照してください。
31.2.1 文字単位の移動 | 文字単位での移動。 | |
31.2.2 単語単位の移動 | 単語単位での移動。 | |
31.2.3 バッファー終端への移動 | バッファー先頭や終端への移動。 | |
31.2.4 テキスト行単位の移動 | テキスト行単位での移動。 | |
31.2.5 スクリーン行単位の移動 | 表示される行単位での移動。 | |
31.2.6 釣り合いのとれたカッコを越えた移動 | リストやS式の解析による移動。 | |
31.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-script-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)
が移動するであろう位置をリターンする。
line-beginning-position
と似ているがフィールドを無視する(そしてより効率的である)。
line-end-position
と似ているがフィールドを無視する(そしてより効率的である)。
この関数は後続行へ前方に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行を含まなければならないからである。
オプションのignore-invisible-linesが非nil
なら、不可視の行は行数に含まれない。
この関数はカレントバッファー内の位置startとendの間にある単語の数をリターンする。
この関数はインタラクティブに呼び出すこともできる。その場合はバッファー、またはリージョンがアクティブならリージョン内の行数、単語数、文字数を報告するメッセージをプリントする。
この関数はカレントバッファーのバッファー位置posに対応する行番号をリターンする。posがnil
か省略ならカレントのバッファー位置を使用する。absoluteがnil
(デフォルト)なら(point-min)
から数え始めるので、値は(ナローイングされているかもしれない)バッファーのアクセス可能範囲を参照する。absoluteが非nil
ならすべてのナローイングを無視して行の絶対番号をリターンする。
ポイント近傍のテキストを調べるの関数bolp
とeolp
も参照してください。これらの関数はポイントを移動しませんが、ポイントがすでに行頭または行末にあるかどうかをテストします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
前のセクションの行関数は、改行文字で区切られたテキスト行だけを数えました。それらとは対照的に以下の関数はスクリーン行を数えます。スクリーン行はスクリーン上でテキストが表示される方法にしたがって定義されます。あるテキスト行1行が選択されたウィンドウの幅にフィット可能な程に十分短ければそれはスクリーン行で1行になりますが、それ以外は複数のスクリーン行になり得ます。
テキスト行が追加スクリーン行に継続されずに、そのスクリーンで切り詰められる(truncated)場合があります。そのような場合にはvertical-motion
でforward-line
のようにポイントを移動します。切り詰めを参照してください。
文字列が与えられると、その幅は文字の外見を制御するフラグに依存するために与えられたテキスト断片にたいして、たとえそれが選択されたウィンドウ上でさえも(幅、切り詰めの有無、ディスプレイテーブルはウィンドウごとに異なり得るので)、そのテキストがあるバッファーに応じてvertical-motion
の挙動は異なります。通常の表示の慣習を参照してください。
以下の関数はスクリーン行のブレーク位置を判断するためにテキストをスキャンするために、スキャンする長さに比例して時間を要します。
この関数はポイントのあるスクリーン行からスクリーン行でcount行下方に移動して、そのスクリーン行の先頭にポイントを移動する。countが負ならかわりに上方に移動する。countが0の場合には、カレントスクリーン行の視覚的な先頭にポイントを移動する。
count引数には整数のかわりにコンスセル(cols . lines)
を指定できる。その場合には関数はcountで上述したように、スクリーン行でlines行移動して、そのスクリーン行の視覚的な行頭(visual
start)からcols列目にポイントを配置する。colsの値は浮動小数点数でもよく、この場合にはそのフレームの正規文字幅(フレームのフォントを参照)の単位として解釈される。これにより目標となるスクリーン行で可変幅フォントが使用されている際に、正確な水平位置を指定することが可能になる。colsはその行の視覚的(visual)な開始から数えられることに注意。そのウィンドウが水平スクロール(水平スクロールを参照)されていれば、ポイントが配置される列は、スクロールされたテキストの列数が加えられるだろう。更に目標となる行が継続行の場合には一番左の列を列0とみなす(列指向の関数とは異なる;
列を数えるを参照)。
リターン値はポイントが移動したスクリーン行の行数。バッファーの先頭か終端に到達していたら、この値は絶対値では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行目(0は最上行を意味する)の先頭にポイントを移動する。countが負ならバッファー下端(バッファーが指定されたスクリーン位置の上で終わる場合にはバッファーの最終行)から-count行目の位置を指定する。したがってcountが-1ならウィンドウの最後の完全に可視なスクリーン行を指定する。
countがnil
ならポイントはウィンドウ中央の行の先頭に移動する。countの絶対値がウィンドウサイズより大の場合には、ウィンドウが十分に高かったらそのスクリーン行は表示されていたであろう位置にポイントを移動する。これはおそらく次回の再表示の際に、その箇所がスクリーン上になるようなスクロールを発生させるだろう。
インタラクティブな呼び出しでは数プレフィクス引数がcountとなる。
リターン値はポイントが移動した先の、ウィンドウ上端行から相対的なスクリーン行番号。
この関数は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
。リテラル文字列の列0にカッコがあるような場合には偽陽性を回避するためにバックスラッシュでエスケープすること。
この変数は非nil
ならdefunの開始を見つける関数を保持する。関数beginning-of-defun
は通常の手法を使うかわりに、この関数に自身のオプション引数を渡して呼び出す。引数が非nil
なら、その関数はその回数分の関数呼び出しによってbeginning-of-defun
が行うように後方に移動すること。
この変数は非nil
ならdefunの終端を見つける関数を保持する。関数end-of-defun
は、通常の手法を使うかわりにその関数を呼び出す。
tree-sitterとともにEmacsがビルドされていれば、構文構造(syntax
construct)を横断して移動するためにtree-sitterのパーサー情報を使うことができます。正確に何がdefunとみなされるかは言語によってさまざまなので、それを判断するためにメジャーモードはtreesit-defun-type-regexp
をセットする必要があります。そうすればtreesit-beginning-of-defun
とtreesit-end-of-defun
を使うことによって、モードはdefun単位でのナビゲーション機能を労せず手に入れられるのです。
この変数はEmacsがどのノードをdefunとみなすかを決定する。defunノードのタイプにマッチするregexpを指定できる(“ノード”および “ノードタイプ”についてはプログラムソースの解析を参照)。
たとえばpython-mode
はこの変数に‘function_definition’か‘class_definition’のいずれかにマッチするregexpをセットする。
このregexpによってマッチしたノードすべてが有効なdefunという訳ではないときもある。したがってこの変数の値は(regexp . pred)という形式のコンスセルでもよい。ここでpredはノードを引数として受け取りそのノードが有効なdefunであれば非nil
、有効でなければnil
をリターンする関数であること。
この変数はEmacsがどのようにネスト(nest:
入れ子)されたdefunを扱うかを決定する。値がtop-level
なら、ナビゲーション関数はトップレベルのdefun間だけを移動、nested
ならナビゲーション関数はネストされたdefunを認識する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の2つの関数は指定された文字セットを超えてポイントを移動します。これらの関数は、たとえば空白文字をスキップするためによく使用されます。関連する関数についてはモーションと構文を参照してください。
これらの関数は検索関数(検索とマッチングを参照)が行うように、そのバッファーがマルチバイト(multibyte)ならマルチバイトに、ユニバイト(unibyte)ならユニバイトにその文字列セットを変換します。
この関数は与えられた文字セットをスキップしてカレントバッファー内のポイント前方に移動する。これはポイントの後の文字を調べて、その文字がcharacter-setにマッチすればポイントを進める。そしてマッチしない文字に到達するまでこれを継続する。この関数は飛び超えて移動した文字数をリターンする。
引数character-setが正規表現での‘[…]’内部と同じだが、‘]’で終端されず‘\’が‘^’、‘-’、‘\’をクォートする点が異なる。つまり"a-zA-Z"
はすべての英字をスキップして最初の非英字の前で停止して、"^a-zA-Z"
はすべての非英字をスキップして最初の英字の前で停止する(正規表現を参照)"[:alnum:]"
のような文字クラスも使用できる(文字クラスを参照)。
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
のマーカーです。マーカーの挿入タイプを参照してください。したがって保存されたポイント値は、リストア時には通常は挿入されたテキストの直前になります。
このマクロはsave-excursion
と同様だが、マークの位置とmark-active
の保存とリストアも行う点が異なる。このマクロはEmacsのバージョン25.1以前にsave-excursion
が行っていたことを行う。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ナローイング(narrowing)とはEmacs編集コマンドがアドレス指定可能なテキストを、あるバッファー内の制限された文字範囲に限定することを意味します。アドレス可能なテキストは、そのバッファーのアクセス可能範囲(accessible portion)と呼ばれます。
ナローイングは2つのバッファー位置により指定されるもので、それらの位置がアクセス可能範囲の開始と終了になります。ほとんどの編集コマンドやプリミティブにたいして、これらの位置はそれぞれそのバッファーの先頭と終端に置き換えられます。ナローイングが効果をもつ間にはアクセス可能範囲外のテキストは表示されず、その外部にポイントを移動することはできません。ナローイングは実際のバッファー位置(ポイントを参照)を変更しないことに注意してください。ほとんどの関数はアクセス可能範囲外のテキストにたいする操作を受け入れません。
バッファーを保存するコマンドはナローイングの影響を受けません。どんなナローイングであろうと、それらはバッファー全体を保存します。
単一バッファー内にタイプが大きく異なるテキストを複数表示する必要がある場合には、2つのバッファー間でのテキストの交換で説明する代替機能の使用を考慮してください。
この関数はアクセス可能範囲の開始と終了にカレントバッファーのstartとendをセットする。どちらの引数も文字位置で指定すること。
インタラクティブな呼び出しでは、startとendはカレントリージョンにセットされる(ポイントとマークで小さいほうが前者)。
ただしlabel引数(以下参照)を指定したwith-restriction
によってナローイングがセットされている際には、そのナローイングの制限の範囲内にたいしてのみnarrow-to-region
を使用できる。startかendがこの制限の範囲外であれば、with-restriction
によってセットされた対応する制限がかわりに使用される。バッファーのそれ以外の部分へのアクセスを取得するには、同じlabelを指定してwithout-restriction
を使えばよい。
この関数はカレントページだけを含むようにカレントバッファーのアクセス可能範囲をセットする。1つ目のオプション引数move-countが非nil
なら、move-countで前方か後方へ移動後に1ページにナローすることを意味する。変数page-delimiter
はページの開始と終了の位置を指定する(編集で使用される標準的な正規表現を参照)。
インタラクティブな呼び出しではmove-countには数プレフィクス引数がセットされる。
この関数はカレントバッファーにたいするすべてのナローイングをキャンセルする。これはワイドニング(widening)と呼ばれる。これは以下の式と等価:
(narrow-to-region 1 (1+ (buffer-size)))
ただしlabel引数(以下参照)を指定したwith-restriction
によってナローイングがセットされている際には、ナローイングをキャンセルするかわりにwith-restriction
でセットした制限がリストアされる。バッファーのそれ以外の部分へのアクセスを取得するには、同じlabelを指定してwithout-restriction
を使えばよい。
この関数はそのバッファーがナローされていれば非nil
、それ以外はnil
をリターンする。
このスペシャルフォームはアクセス可能範囲のカレントのバインドを保存してbodyを評価、その後に以前有効だったナローイング(またはナローイングがない状態)と同じ状態になるように、最後に保存された境界をリストアする。ナローイングの状態は、throw
やエラーを通じたアブノーマルexit(非ローカル脱出を参照)イベント内においてもリストアされる。したがってこの構文は一時的にバッファーをナローする明快な手段である。
この構文はlabel引数(以下参照)とともにwith-restriction
によってセットされたナローイングの保存とリストアも行う。
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 ----------
このスペシャルフォームはバッファーのアクセス可能範囲のカレント境界を保存、startで始まりendで終わるアクセス可能範囲をセットしてbodyフォームを評価、それから保存してある境界をリストアする。この場合は以下と等しい
(save-restriction (narrow-to-region start end) body)
オプション引数label (使用するラベルを取得するために評価される;
非nil
値が生成されなければならない)が与えられた場合には、そのナローイングはラベル付け(labeled)される。ラベル付けされたナローイングは、ラベル付けされていないナローイングといくつかの点で異なる:
narrow-to-region
とwiden
が使えるのはstartからendまでの制限の内部のみ。
with-restriction
でセットされた制限を解除してバッファーの他の部分へのアクセスを取得するためには、同じlabel引数を使ってwithout-restriction
を呼び出す(バッファーの他の部分へのアクセスを取得する別の方法としてインダイレクトバッファーの使用がある;
インダイレクトバッファーを参照)。
オプション引数labelとともにwith-restriction
を使う場合には、あなたのコードを呼び出す他のLispプログラムが必要に応じてナローイングを解除できるように、これを使う関数のdoc文字列でそのlabelのドキュメントを記述することを推奨する。
このスペシャルフォームはバッファーのアクセス可能範囲のカレント境界を保存、そのバッファーをワイドニングしてからbodyフォームを評価、それから保存した境界をリストアする。この場合は以下と等しい
(save-restriction (widen) body)
オプション引数labelが与えられた場合には、同じlabel引数のwith-restriction
でセットされたナローイングが解除される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マーカー(marker)とは、あるバッファー内で取り囲んでいるテキストにたいして相対的な位置を指定するために使用されるオブジェクトです。テキストが挿入や削除される際には、常にマーカーは自動的にそのバッファーの先頭からのオフセットを自動的に変更して自身の左右にある文字の間に留まります。
32.1 マーカーの概要 | マーカー構成要素と再配置方法。 | |
32.2 マーカーのための述語 | オブジェクトがマーカーか否かのテスト。 | |
32.3 マーカーを作成する関数 | 空マーカーや特定箇所のマーカーの作成。 | |
32.4 マーカーからの情報 | マーカーのバッファーや文字位置を探す。 | |
32.5 マーカーの挿入タイプ | マーカーが指す位置への挿入時にマーカーを再配置する2つの方法。 | |
32.6 マーカー位置の移動 | 新たなバッファーや位置にマーカーを移動する。 | |
32.7 マーク | マーカーによるマークの実装方法。 | |
32.8 リージョン | リージョンへのアクセス方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
マーカーはバッファーとそのバッファー内の位置を指定します。マーカーは位置を要求する関数内において、整数と同じように位置を表すために使用することができます。その場合には、そのマーカーのバッファーは通常は無視されます。この方法で使用されるマーカーは、通常はその関数が処理するバッファー内の位置を指しますが、それは完全にプログラマーの責任です。位置についての完全な説明はポジションを参照してください。
マーカーはマーカー位置(marker position)、マーカーバッファー(marker buffer)、挿入タイプ(insertion type)という3つの属性をもちます。マーカー位置はそのバッファー内の位置としてのマーカーと(その時点において)等しい整数です。しかしマーカー位置はマーカーの生存期間中に変化し得るものであり頻繁に変更されます。バッファー内でのテキストの挿入や削除によってマーカーは再配置されます。マーカー前後の2文字以外の場所で挿入や削除がおこなわれても、マーカー位置はその2文字間に留まるというのがこのアイデアです。再配置によってマーカーと等価な整数は変更されます。
マーカー位置周辺のテキストを削除することにより、そのマーカーは削除されたテキストの直前と直後にある文字の間に残されます。マーカー位置へのテキスト挿入では、マーカーは通常は新たなテキストの前か後のいずれかに配置されます。その挿入がinsert-before-markers
(テキストの挿入を参照)で行われたものでなければ、どちらに配置されるかはマーカーの挿入タイプ(マーカーの挿入タイプを参照)に依存します。
バッファーでの挿入と削除では、すべてのマーカーをチェックして必要ならそれらを再配置しなければなりません。これは多数のマーカーをもつバッファーでの処理を低速にします。この理由によりそれ以上マーカーが不必要なことが確信できるなら、存在しない場所を指さないようにマーカーを設定することはよいアイデアといえるでしょう。それ以上アクセスされる可能性がないマーカーは最終的には削除されます(ガーベージコレクションを参照)。
マーカー位置にたいして算術演算を行うことは一般的なので、それらの演算子のほとんど(+
や-
を含む)が引数としてマーカーに渡すことができます。そのような場合でのマーカーはカレント位置を意味します。
以下ではマーカーの作成とセットを行ってポイントをマーカーに移動しています:
;; 最初はどこも指さない新たなマーカーを作成:
(setq m1 (make-marker))
⇒ #<marker in no buffer>
;; カレントバッファーの99と100番目の
;; 文字間を指すようm1
をセット:
(set-marker m1 100)
⇒ #<marker at 100 in markers-ja.texi>
;; ここでバッファー先頭に1文字挿入:
(goto-char (point-min))
⇒ 1
(insert "Q")
⇒ nil
;; m1
は適切に更新された
m1
⇒ #<marker at 101 in markers-ja.texi>
;; 同じ位置を指す2つのマーカーは ;;equal
だがeq
に非ず (setq m2 (copy-marker m1)) ⇒ #<marker at 101 in markers-ja.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
のマーカーをリターンします。マーカーの挿入タイプを参照してください。
この関数はどこも指さないマーカーを新たに作成してリターンする。
(make-marker) ⇒ #<marker in no buffer>
この関数はカレントバッファーのポイント現在位置を指すマーカーを新たに作成してリターンする。ポイントを参照のこと。例は以下のcopy-marker
を参照のこと。
この関数はバッファーのアクセス可能範囲の先頭を指すマーカーを新たに作成してリターンする。ナローイングが効力をもたなければ、これはバッファーの先頭になるだろう。ナローイングを参照のこと。
この関数はバッファーのアクセス可能範囲の終端を指すマーカーを新たに作成してリターンする。ナローイングが効力をもたなければ、これはバッファーの終端になるだろう。ナローイングを参照のこと。
以下はこのチャプターのテキストのソースファイルのバージョンを含むバッファーにたいして、この関数とpoint-min-marker
を使用する例。
(point-min-marker) ⇒ #<marker at 1 in markers-ja.texi> (point-max-marker) ⇒ #<marker at 24080 in markers-ja.texi>
(narrow-to-region 100 200) ⇒ nil
(point-min-marker) ⇒ #<marker at 100 in markers-ja.texi>
(point-max-marker) ⇒ #<marker at 200 in markers-ja.texi>
引数としてマーカーを渡されると、copy-marker
はmarker-or-integerが行うように同じバッファーの同じ位置を指すマーカーを新たに作成してリターンする。整数を渡されると、copy-marker
はカレントバッファーの位置marker-or-integerを指すマーカーを新たに作成してリターンする。
新たなマーカーの挿入タイプは引数insertion-typeにより指定される。マーカーの挿入タイプを参照のこと。
(copy-marker 0) ⇒ #<marker at 1 in markers-ja.texi>
(copy-marker 90000) ⇒ #<marker at 24080 in markers-ja.texi>
markerがマーカーと整数のいずれでもなければエラーがシグナルされる。
2つのマーカーはそれらが同じバッファーの同じ位置、またはどちらも存在しない場所を指す場合には、(eq
ではないが)equal
とみなされます。
(setq p (point-marker)) ⇒ #<marker at 2139 in markers-ja.texi>
(setq q (copy-marker p)) ⇒ #<marker at 2139 in markers-ja.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-ja.texi>
(marker-buffer m) ⇒ #<buffer markers-ja.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-ja.texi>
(set-marker m 55) ⇒ #<marker at 55 in markers-ja.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-ja.texi>
(set-marker m 100) ⇒ #<marker at 100 in markers-ja.texi>
(mark-marker) ⇒ #<marker at 100 in markers-ja.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をセットする(マウスでリージョンをマークした際には、、この方法によって一時的にtransient-mark-mode
がオンになる)。
これが非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-ja.texi> #<marker at 10832 in markers-ja.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つの文字の間にあり、カーソルはポイントの後の文字上に表示されることを覚えておいてください。
33.1 ポイント近傍のテキストを調べる | ポイント付近のテキストを調べる。 | |
33.2 バッファーのコンテンツを調べる | 一般的な方法によってテキストを調べる。 | |
33.3 テキストの比較 | バッファーの部分文字列を比較する。 | |
33.4 テキストの挿入 | バッファーへの新たなテキストの追加。 | |
33.5 ユーザーレベルの挿入コマンド | テキスト挿入のためのユーザーレベルコマンド。 | |
33.6 テキストの削除 | バッファーからテキストを削除する。 | |
33.7 ユーザーレベルの削除コマンド | テキスト削除のためのユーザーレベルコマンド。 | |
33.8 killリング | テキスト削除時にユーザーのためにそれを保存する場所。 | |
33.9 アンドゥ | バッファーのテキストにたいする変更の取り消し。 | |
33.10 アンドゥリストの保守 | undo情報の有効と無効。情報をどれだけ保持するか制御する方法。 | |
33.11 fill | 明示的にフィルを行う関数。 | |
33.12 fillのマージン | フィルコマンドにたいしてマージンを指定する方法。 | |
33.13 Adaptive Fillモード | コンテキストからフィルプレフィクスを選択するAdaptive Fillモード。 | |
33.14 オートfill | 行ブレークにたいするauto-fillの実装方法。 | |
33.15 テキストのソート | バッファーの一部をソートする関数。 | |
33.16 列を数える | 水平位置の計算とその使用方法。 | |
33.17 インデント | インデントの挿入や調整のための関数。 | |
33.18 大文字小文字の変更 | バッファーの一部にたいする大文字小文字変換。 | |
33.19 テキストのプロパティ | テキスト文字にたいするLispプロパティリストの追加。 | |
33.20 文字コードの置き換え | 与ええられた文字の出現箇所を置換する。 | |
33.21 レジスター | レジスターの実装方法。レジスターに格納されたテキストや位置にアクセスする。 | |
33.22 テキストの交換 | バッファーの2つの部分を交換する。 | |
33.23 バッファーテキストの置換 | 他のバッファーのテキストによるバッファーテキストの置換。 | |
33.24 圧縮されたデータの処理 | 圧縮データの扱い。 | |
33.25 Base 64エンコーディング | Base64エンコーディングとの変換。 | |
33.26 チェックサムとハッシュ | 暗号ハッシュの計算。 | |
33.27 不審なテキスト | 文字列の不信度の判定。 | |
33.28 GnuTLS暗号化 | GnuTLSからインポートされた暗号化アルゴリズム。 | |
33.29 データベース | SQLデータベースとの相互作用。 | |
33.30 HTMLとXMLの解析 | HTMLおよびXMLの解析。 | |
33.31 JSON値の解析と生成 | JSON値のパースと生成。 | |
33.32 JSONRPCによる対話 | JSONのRPCプロトコル(リモートプロシージャコントロールプロトコル) | |
33.33 グループのアトミックな変更 | 複数バッファーへの変更をアトミックにインストールする。 | |
33.34 フックの変更 | テキスト変更時に実行する関数の指定。 |
[ << ] | [ < ] | [ 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
(この時代遅れの機能に関する詳細はマクロwith-wrapper-hook
のドキュメント文字列を参照)が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
にドキュメントされているように扱うこと。関数はフィルターされたテキストをリターン(およびオプションでソーステキストを削除)すること。
The following two variables are obsoleted by
以下の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の間のバッファー部分文字列をリターン(オプションでバッファーから元テキストを削除)する関数であり、それがfunに渡される。ほとんどの場合にはフック関数はfunを1回だけ呼び出してから、その結果にたいして自身の処理を行う。次のフック関数はこれと等しいfunを受け取って、それが順次繰り返されていく。実際のリターン値はすべてのフック関数が順次処理した結果。
この関数はポイント位置またはその付近のシンボル(または単語)を文字列としてリターンする。リターン値にテキストプロパティは含まれない。
オプション引数really-wordが非nil
なら単語、それ以外はシンボル(単語文字とシンボル構成文字の両方を含む)を探す。
オプション引数strictが非nil
のならポイントは単語(またはシンボル)の内部にあるか隣接しなければならない。そこに単語(またはシンボル)がなければ、この関数はnil
をリターンする。strictがnil
ならポイントと同一行にある近接する単語(またはシンボル)を許容する。
ポイントに隣接または周辺にあるthingを文字列としてリターンする。
引数thingは構文エンティティの種別を指定するシンボルである。可能なシンボルとしてはsymbol
、list
、sexp
、defun
、filename
、existing-filename
、url
、word
、sentence
、whitespace
、line
、page
、string
、および他が含まれる。
オプション引数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
ユーザーおよびモードは、この変数によってthing-at-point
が機能する方法を調節できる。これはthing、およびそれ(thing)をリターンする関数(パラメーターなしで呼び出される)の連想リストである。thingのエントリーは非nil
の結果がリターンされるまで順に評価される。
たとえばメジャーモードは以下のように指定できる:
(setq-local thing-at-point-provider-alist (append thing-at-point-provider-alist '((url . my-mode--url-at-point))))
非nil
をリターンするproviderがなければ、標準的な方法によってthingを計算する。
[ << ] | [ < ] | [ 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)と呼びます。
挿入により挿入位置の後にあったマーカーは、テキストを取り囲むように移動されます(マーカーを参照)。マーカーが挿入箇所をさしている際には、挿入によるマーカーの再配置の有無はそのマーカーの挿入タイプに依存します(マーカーの挿入タイプを参照)。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
と似ているが、テキストプロパティをコピーしない点が異なる。
これはinsert-buffer-substring
と同様だが、反対方向に機能する。テキストはカレントバッファーからto-bufferにコピーされる。テキストブロックはto-bufferのカレントポイントにコピーされて、(そのバッファーの)ポイントはコピーしたテキスト終端に進められる。start
/end
がnil
なら、カレントバッファーのテキスト全体をコピーする。
テキスト挿入に加えて、隣接するテキストからテキストプロパティを継承する他の関数についてはテキストプロパティの粘着性を参照のこと。インデント関数により挿入された空白文字もテキストプロパティを継承する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではテキスト挿入のための高レベルコマンド、ユーザーによる使用を意図しているがLispプログラムでも有用なコマンドについて説明します。
このコマンドはfrom-buffer-or-name
(存在しなければならない)のアクセス可能範囲全体をカレントバッファーのポイントの後に挿入する。マークは挿入されたテキストの後に残される。値はnil
。
このコマンドは文字charを挿入する。これをポイント前で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
を実行する。これを使えば、テキストのタイプ時に自動的に再インデントを行うことができる。このフックにセットした関数はlast-command-event
(コマンドループからの情報を参照)を使うことにより、挿入したばかりの文字にアクセスすることができる。
このフックのいずれかの関数がリージョン(リージョンを参照)にたいして作用する必要があるなら、post-self-insert-hook
の関数が呼び出される前にDelete
Selectionモード(Delete Selection in The GNU Emacs
Manualを参照)がリージョンを削除しないようにする必要がある。これを行うにはDelete
Selectionモードにリージョンを削除しないように告げる特別なフックself-insert-uses-region-functions
にnil
をリターンする関数を追加すること。
self-insert-command
の標準的な定義にたいして、独自の定義による置き換えを試みてはならない。エディターコマンドループはこのコマンドを特別に扱うからだ。
このコマンドはカレントバッファーのポイントの前に改行を挿入する。number-of-newlinesが与えられたら、その個数の改行文字が挿入される。インタラクティブな呼び出しでは、number-of-newlinesはプレフィクス数引数。
この関数はカレント列数がfill-column
より大、かつnumber-of-newlinesがnil
ならauto-fill-function
を呼び出す。このコマンドは改行を挿入するためにself-insert-command
を呼び出して、続けてauto-fill-function
を呼び出すことにより前の行をブレークする(オートfillを参照)。auto-fill-function
が通常行うのは改行の挿入であり、最終的な結果としてはポイント位置と、その行のより前方の位置という2つの異なる箇所に改行を挿入する。number-of-newlinesが非nil
ならnewline
はauto-fillを行わない。
このコマンドはインタラクティブな呼び出し、またはinteractiveが非nil
ならフックpost-self-insert-hook
を実行する。
このコマンドは左マージンが0でなければ、左マージンにインデントする。fillのマージンを参照のこと。
リターン値はnil
。
このコマンドはポイントの前に特定の行数の空行を確保するために用いることができる(ここで言う“空行”とは文字が何もない行のことを指し、空白文字があればそれは空行ではない)。デフォルトではポイントの前に1行の空行を確保する。
ポイントが行頭になければ、まず改行文字を挿入する。指定したより多くの空行がポイントの前にある場合には空行の行数を減らす。それ以外の場合には指定した行数に増やす。
この変数は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
はかわりに後続行と結合を行う。それ以外の場合にはbegとendが非nil
なら、この関数はbegとendで定義されるリージョン内のすべての行を結合する。
インタラクティブな呼び出しではjoin-following-pはプレフィクス引数、begとendはリージョンがアクティブならリージョンの開始と終了、それ以外はnil
。この関数は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)”という用語は、コンピューター誕生前に原稿を再配置するためにハサミで切り取って貼り付けていたような人に意味があるでしょう。しかし今となってはこの用語を変更するのは困難です。
33.8.1 killリングの概念 | killリング内のテキストがどのように見えるか。 | |
33.8.2 kill用の関数 | テキストをkillする関数。 | |
33.8.3 yank | yankが行われる方法。 | |
33.8.4 yank用の関数 | killリングにアクセスするコマンド。 | |
33.8.5 低レベルのkillリング | killリングアクセス用の関数と変数。 | |
33.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内のテキストを処理する点が異なる。
stringを挿入する前にyank-transform-functions
(以下参照)が実行される。
この関数は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
の後に効果を発揮する。
この変数は関数のリストである。関数はそれぞれyankする文字列を引数として(順番に)呼び出されて、(恐らくは変換後の)文字列をリターンすること。この変数をグローバルにセットすることもできるが、yank
の変種として新たなコマンドの作成にも用いることができる。たとえばyank
のように機能するが、挿入前に空白文字を整理するようなコマンドを作成するには以下のように記述すればよい:
(defun yank-with-clean-whitespace () (interactive) (let ((yank-transform-functions '(string-clean-whitespace))) (call-interactively #'yank)))
[ << ] | [ < ] | [ 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
をリターンする。
yank
や別のyank-pop
の直後に呼び出されると、このコマンドはkillリングからyankしたばかりのエントリーを、killリングの別のエントリーに置き換える。このようにコマンドが呼び出されたときは、リージョンには別のyankコマンドが挿入したばかりのテキストが含まれる。yank-pop
はそのテキストを削除して、killされた別のテキスト片をその位置に挿入する。そのテキスト片はすでにkillリング内のどこか別の箇所にあるので、これは削除されたテキストをkillリングに追加しない。しかし新たにyankされたテキストが先頭になるように、killリングの転回は行う。
argがnil
なら置換テキストはkillリングの1つ前の要素。argが数字なら置換テキストはkillリングのarg個前の要素である。argが負なら、より最近のkillが置換される。
killリング内のkillされたエントリーの順序はラップするので、繰り返しyank-pop
を呼び出してもっとも古いkillに達すると、その後はもっとも新しいkillとなり、もっとも新しいkillの前がもっとも古いkillとなる。
このコマンドはyank以外のコマンドの後でも呼び出せる。この場合にはミニバッファーで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-paste-function
interprogram-paste-function
(ユーザーオプションsave-interprogram-paste-before-kill
にしたがう)とinterprogram-cut-function
(以下参照)の値の呼び出しも行う。
replaceが非nil
ならkill-new
はkillリング上にstringをpushせずに、killリングの1つ目の要素をstringに置き換える。
この関数はkillリング内の最初のエントリーにテキストstringを追加して、その結合されたエントリーを指すようにyankポインターをセットする。通常はそのエントリーの終端にstringが追加されるが、before-pが非nil
ならエントリーの先頭に追加される。この関数はサブルーチンとしてkill-new
も呼び出すのでinterprogram-cut-function
とおそらくinterprogram-paste-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
のデフォルト値は120。
[ << ] | [ < ] | [ 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)
この種の要素は未変更のバッファーが変更されたことを示す。time-flag
(非整数のLispタイムスタンプ)は、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
は削除される。
融合可能な最大の変更数はamalgamating-undo-limit
変数で制御される。この変数が1なら変更は融合されない。
Lispプログラムはundo-amalgamate-change-group
を呼び出すことによって、一連の変更を単一の変更グループにまとめることができます(グループのアトミックな変更を参照)。この関数で生成したグループにたいしてamalgamating-undo-limit
は効果がないことに注意してください。
プロセスバッファーのようないくつかのバッファーでは、何もコマンドを実行していなくても変更が発生し得る。このような場合には、通常は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
をバインドしない。
このマクロはbodyの実行中に挿入されたundo境界を削除して、一度にまとめてundoできるようにする。
いくつかのコマンは、コマンドの選択的なアンドゥを妨害する方法により、実行後にリージョンをアクティブなままにします。undo
をそのようなコマンドの直後に呼び出した際にアクティブなリージョンを無視するには、コマンドの関数シンボルのundo-inhibit-region
プロパティに非nil
値をセットします。シンボルの標準的なプロパティを参照してください。
[ << ] | [ < ] | [ 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
はパラグラフを分割する方法を制御する。編集で使用される標準的な正規表現を参照のこと。
Emacsのほとんどのバッファーでは文字数とchar-width
にもとづいて(fill-region
のような)fill関数が機能するように、等幅(monospace)のテキストを使用する。しかしEmacsは可変幅フォント(proportional
font)を使ったイメージを含むテキストのような、他のタイプのオブジェクトを描画でき、正にこれを処理するために存在するのがpixel-fill-region
である。これはstartとendの間にあるリージョンのテキストをピクセル単位の粒度でfillするので、可変ピッチのフォントや異なるいくつかのフォントはサイズに関わらずfillされるようになる。引数pixel-widthはfill後に線に許容される最大のピクセル幅を指定する。これはfill-region
におけるfill-column
のピクセル解像度に相当する。以下のLispコードはプロポーショナルフォントを用いてテキストを挿入してから、300ピクセルを超えない幅になるようにfillする例である:
(insert (propertize "This is a sentence that's ends here." 'face 'variable-pitch)) (pixel-fill-region (point) (point-max) 300)
startが行頭にある場合には、後続行のインデントのプレックスとしてstartの水平位置をピクセル単位に変換した値が用いられる。
pixel-fill-width
はピクセル幅を計算するために使用できるヘルパー関数である。引数なしならカレントウィンドウの幅より若干小さい値をリターンする。1つ目のオプションcolumnsの値には、fill-column
が用いる標準的なモノスペースフォントによる列数を指定する。2つ目のオプションの値は使用するウィンドウである。典型的には以下のように使用する:
(pixel-fill-region start end (pixel-fill-width fill-column))
このコマンドはリージョン内の各パラグラフを、それの固有なフィルプレフィクスに応じてフィルする。したがってパラグラフの行がスペースでインデントされていれば、フィルされたパラグラフは同じ様式でインデントされた状態に保たれるだろう。
最初の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
なら異種(たとえば英語のCJK)の2つの単語は一方が行末にあり、もう一方が次行の先頭にある場合にはフィルでの結合時にスペースで分割される。
この変数はパラグラフのフィルをオーバーライドする手段を提供する。この値が非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。特定のモードでAuto Fillモードを無効にするには以下のように記述できる:
(add-hook 'foo-mode-hook (lambda () (auto-fill-mode -1))
これは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 in The GNU Emacs Manualを参照してください。このセクションでは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
を呼び出す文字からなる文字テーブル(ほとんどの言語環境においてはスペースと改行)。
この変数が非nil
なら行のフィルは自動的にコメントだけになる。より正確にはカレントバッファーにたいしてコメント構文が定義されていれば、コメントの外側の自己挿入文字がauto-fill-function
を呼び出さないことを意味する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションで説明するソート関数は、すべてバッファー内のテキストを再配置します。これはリスト要素を再配置するsort
関数とは対照的です(see リストを再配置する関数)。これらの関数がリターンする値に意味はありません。
この関数はバッファーをレコードに細分してそれらをソートする一般的なテキストソートルーチン。このセクションのコマンドのほとんどは、この関数を使用する。
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はキーの比較に使用する関数。この関数は引数として比較する2つのキーを受け取り、1つ目のキーが2つ目のキーよりソート順で前なら非nil
をリターンすること。引数のキーが正確に何であるかはstartkeyfunとendkeyfunがリターンする値に依存する。predicateが省略またはnil
の場合のデフォルトはキーが数値なら<
、キーがコンスセル(car
がキーのバッファー位置の開始でcdr
が終了)ならcompare-buffer-substrings
、それ以外なら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 (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と数えられます。列値は不可視性を別としてオーバーレイとテキストプロパティを無視します。buffer-invisibility-spec
で不可視のテキストを省略記号(ellipsis)として表示するように指定していないかぎり(不可視のテキストを参照)、不可視のテキストは幅が0であるとみなされます。
この関数は左マージンを0として列単位で数えたポイントの水平位置をリターンする。列の位置はカレント行の開始からポイントまでの間の文字の表示上の表現すべての幅の和。
この関数はカレント行のcolumnにポイントを移動する。columnの計算には行の開始からポイントまでの文字の表示上の表現の幅が考慮される。
インタラクティブに呼び出された際には、columnはプレフィクス数引数の値。columnが整数でなければエラーがシグナルされる。
列columnがタブのような複数列を占める文字の中間にあるために列を移動することが不可能な場合には、ポイントはその文字の終端に移動される。しかしforceが非nil
、かつcolumnがタブの中間にあるなら、(indent-tabs-mode
がnil
なら)move-to-column
はタブをスペースに変換するか、(それ以外なら)その前に十分なスペースを挿入するので正確に列columnに移動することができる。それ以外の複数列文字については分割する手段がないので、force指定に関わらず異常を引き起こす恐れがある。
その行が列columnに達するほど長くない場合にも引数forceは効果をもつ。columnがt
ならその列に達するよう行端に空白を追加することを意味する。
リターン値は実際に移動した列番号。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
インデント関数は行の先頭にある空白文字の調査、移動、変更に使用されます。行の他の箇所にある空白文字を変更できる関数もいくつかあります。列とインデントは左マージンを0として数えられます。
33.17.1 インデント用のプリミティブ | インデントのカウントと挿入に使用される関数。 | |
33.17.2 メジャーモードが制御するインデント | 異なるモード用にインデントをカスタマイズする。 | |
33.17.3 リージョン全体のインデント | リージョン内すべての行のインデント。 | |
33.17.4 前行に相対的なインデント | 前の行にもとづきカレント行をインデントする。 | |
33.17.5 調整可能なタブストップ | 調整可能なタイプライター形式のタブストップ。 | |
33.17.6 インデントにもとづくモーションコマンド | 最初の非ブランク文字への移動。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではインデントのカウントと挿入に使用されるプリミティブ関数について説明します。以降のセクションの関数はこれらのプリミティブを使用します。関連する関数については表示されるテキストのサイズを参照してください。
この関数はカレント行のインデント、すなわち最初の非ブランク文字の水平位置をリターンする。行のコンテンツ全体がブランクなら、それは行終端の水平位置である。
buffer-invisibility-spec
で不可視のテキストを省略記号(ellipsis)として表示するように指定していないかぎり、この関数は不可視のテキストの幅を0とみなす。不可視のテキストを参照のこと。
この関数はポイントから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
を呼び出す(通常バッファーでの補完を参照)。
tab-always-indent
がcomplete
なら、tab-first-completion
変数を介して拡張するか、それともインデントするかを更にカスタマイズできる。以下の値を使用できる:
eol
ポイントが行末にあれば補完のみ。
word
次の文字が単語構文をもたなければ補完。
word-or-paren
次の文字が単語構文やカッコでなければ補完。
word-or-paren-or-punct
次の文字が単語構文やカッコや句読点でなければ補完。
いずれの場合でも、2回目のTABの結果は常に補完となる。
いくつかのメジャーモードでは、異なるメジャーモードに所属する構文をもつ埋め込みのテキストリージョンをサポートする必要があります。これらの例にはドキュメントとソースコード断片の組み合わせである文芸的プログラミング(literate
programming)のソースファイル、PythonやJSのコード断片を含んだYacc/Bisonプログラムが含まれます。埋め込みチャンクをを正しくインデントするためには、主モードがインデントをガイドする何らかのコンテキストを提供しつつ、他のモードのインデントエンジン(JSではjs-indent-line
、Pythonではpython-indent-line
の呼び出し)にインデントを委譲する必要があります。メジャーモードはインデントコードでwiden
の呼び出しを避けてprog-first-column
にしたがうべきです。
この変数が非nil
なら副モードのインデントエンジンにたいして上位モードが提供するインデントのコンテキストを保持する。値は(first-column
. rest)
という形式のリストであること。リストのメンバーは以下の意味をもつ:
トップレベルの構文にたいして使用する列。これは副モードが使用するトップレベルの列のデフォルト値(通常は0)を置き換える。
現在のところ使用しない。
以下は他のメジャーモードの副モードとしての呼び出しをサポートする際に、そのメジャーモードのインデントエンジンが使用するべき便宜用の関数です。
トップレベルのプログラム上のコンテキストの列値にたいしてリテラル値(通常は0)を使用するかわりにこの関数を呼び出す。関数の値はトップレベルに使用する列数。上位モードの影響下になければ関数は0をリターンする。
[ << ] | [ < ] | [ 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
を呼び出す。したがってポイントが短いテキスト行の最後の列の下と右にある場合には、このコマンドは通常は空白文字を挿入することにより次のタブストップにポイントを移動する。
first-onlyが非nil
なら、最初のインデント位置だけを考慮する。
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.
このコマンドは引数first-onlyに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
のようなさまざまな関数が含まれます。
33.19.1 テキストプロパティを調べる | 単一の文字のプロパティを調べる。 | |
33.19.2 テキストプロパティの変更 | テキスト範囲のプロパティをセットする。 | |
33.19.3 テキストプロパティの検索関数 | プロパティが値を変更する場所の検索。 | |
33.19.4 特殊な意味をもつプロパティ | 特別な意味をもつ特定のプロパティ。 | |
33.19.5 フォーマットされたテキストのプロパティ | テキストのフォーマットを表すプロパティ。 | |
33.19.6 テキストプロパティの粘着性 | 挿入されたテキストが隣接するテキストからプロパティを取得する方法。 | |
33.19.7 テキストプロパティのlazyな計算 | テキストが調べられる際のみ、ものぐさな方法でテキストプロパティを計算する。 | |
33.19.8 クリック可能なテキストの定義 | テキストプロパティを使用して、テキストリージョンがクリック時に何か行うようにする。 | |
33.19.9 フィールドの定義と使用 | バッファー内にフィールドを定義するfield プロパティ。
| |
33.19.10 なぜテキストプロパティはインターバルではないのか | テキストプロパティがLispから可視なテキストインターバルをもたない理由。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
テキストプロパティを調べるもっともシンプルな方法は、特定の文字の特定のプロパティの値を尋ねる方法です。これを行うにはget-text-property
を使用します。ある文字のプロパティリスト全体を取得するにはtext-properties-at
を使用します。複数の文字のプロパティを一度に調べる関数についてはテキストプロパティの検索関数を参照してください。
以下の関数は文字列とバッファーの両方を処理します。バッファー内の位置は1から始まりますが、文字列内の位置は0から始まることに留意してください。カレントバッファー以外のバッファーのパースは低速になるかもしれません。
この関数はobject (バッファーか文字列)内の位置posの後にある文字のプロパティpropの値をリターンする。引数objectはオプションでありデフォルトはカレントバッファー。
positionがobjectの終端にあれば値はnil
になるが、バッファーのナローイングは値に影響しないことに注意。つまりobjectがバッファーかnil
の場合には、そのバッファーがナローイングされていて、かつobjectがナローイングされたバッファーの終端にあれば結果は非nil
になるだろう。
厳密な意味で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
ならデフォルトはカレントバッファー。
positionがobjectの終端にあれば値はnil
になるが、バッファーのナローイングは値に影響しないことに注意。つまりobjectがバッファーかnil
の場合には、そのバッファーがナローイングされていて、かつ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
この関数はobject内のインターバル(テキストプロパティ)をインターバルのリストとしてリターンする。objectは文字列かバッファーでなければならない。このリストの構造を変更しても、オブジェクト内のインターバルは変更されない。
(object-intervals (propertize "foo" 'face 'bold)) ⇒ ((0 3 (face bold)))
リターンされたリストの各要素は1つのインターバルを表す。インターバルはそれぞれ3つのパーツをもつ。1つ目は開始、2つ目は終了、3つ目はそのインターバル自身のテキストプロパティ。
[ << ] | [ < ] | [ 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、以前に存在していたフェイスが残りの要素であるようなフェイスのリストをセットする。オプション引数appendpが非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のデフォルトはカレントバッファー。
predicateにしたがい、値がvalue
(デフォルトはnil
)にマッチするようなプロパティpropをもつ次のテキストリージョンを検索する。
この関数はポイントを移動するという点においてsearch-forward
(文字列の検索を参照)や類似関数をモデルとするが、match-beginning
や類似関数とは異なりマッチを記述する構造もリターンする。
値がマッチするようなテキストプロパティが見つからなければ、この関数はnil
をリターンする。見つかった場合にはマッチしたテキストプロパティをもつリージョン終端にポイントを置いて、そのマッチに関する情報とともにprop-match
構造体をリターンする。
predicateはt
( equal
のシノニム)、nil
( “not
equal”を意味する)、または2つの引数(value、およびマッチ候補のバッファー位置のテキストプロパティpropの値)で呼び出される述語関数のいずれかを指定できる。その述語関数はマッチがあれば非nil
、なければnil
をリターンすること。
not-currentが非nil
の場合には、もしプロパティがマッチしたリージョン内に既にポイントがあればそのリージョンをスキップして、次のリージョンを探す。
prop-match
構造はprop-match-beginning
(マッチ先頭)、prop-match-end
(マッチ終端)、prop-match-value
(マッチ先頭のpropertyの値)というアクセサ関数をもつ。
以下の例では下記のような内容をもつバッファーを使用する:
This is a bold and here’s bolditalic and this is the end.
すなわち単語“bold”はbold
フェイス、単語“italic”はitalic
フェイスをもつものとする。
まず最初は:
(while (setq match (text-property-search-forward 'face 'bold t)) (push (buffer-substring (prop-match-beginning match) (prop-match-end match)) words))
これはbold
フェイスを使用するすべての単語を選択する。
(while (setq match (text-property-search-forward 'face nil t)) (push (buffer-substring (prop-match-beginning match) (prop-match-end match)) words))
これはフェイスプロパティをもたないすべての断片を選択する。結果としてリスト‘("This is a " "and here's " "and this is the end")’が得られるだろう(push
を使用しているので逆順になる; リスト変数の変更を参照)。
(while (setq match (text-property-search-forward 'face nil nil)) (push (buffer-substring (prop-match-beginning match) (prop-match-end match)) words))
これはface
に何らかがセットされているすべてのリージョンを選択するがプロパティが変化する箇所で分割するので結果は‘("bold"
"bold" "italic")’になるだろう。
これを使用するかもしれないより現実的な例してURLを表す特定のセクションがあり、それらがshr-url
でタグ付けされているバッファーがあると仮定してみる。
(while (setq match (text-property-search-forward 'shr-url nil nil)) (push (prop-match-value match) urls))
これはそれらすべてのURLのリストを与えるだろう。
これはtext-property-search-forward
と同様だが、後方に検索する。マッチが見つかったらポイントはマッチしたリージョンの終端ではなく先頭に配置される。
[ << ] | [ < ] | [ 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)
と同じようにフォアグラウンドやバックグラウンドを指定する。この形式は後方互換のためだけにサポートされており無視すること。
(:filtered filter face-spec)
という形式のコンスセル。これはface-specで与えられたフェイスを指定するが、フェイスを表示に使用する際にfilterがマッチした場合のみ。face-specには上述した任意のフォームを使用できる。filterは(:window param value)
という形式であること。これはパラメーターparamがvalueにeq
であるようなウィンドウにマッチする。変数face-filters-always-match
が非nil
なら、すべてのフェイスフィルターがマッチしたとみなす。
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
プロパティ由来の属性すべてを無視する。これらの属性はハイライトされていないテキストと常に等しい。
cursor-face
¶これはmouse-face
と似ているが、このプロパティをもつテキスト内にポイント(マウスではない)がある際に使用されるプロパティである。ハイライトはモードcursor-face-highlight-mode
が有効な場合のみ行われる。変数cursor-face-highlight-nonselected-window
が非nil
ならば、たとえウィンドウが選択されていなくてもhighlight-nonselected-windows
がリージョンにたいして行うのと同様(The Mark and the Region in The GNU Emacs
Manualを参照)に、このフェイスをもつテキストがハイライトされる。
fontified
¶このプロパティはそのテキストの表示準備が整っているかどうかを告げる。nil
ならEmacsの再表示ルーチンはバッファーの該当部分を表示する前に、準備のためにfontification-functions
(フェイスの自動割り当てを参照)の中の関数を呼び出す。これはフォントロックのコードのjust-in-timeにより内部的に使用される。
display
このプロパティはテキストが表示される方法を変更するさまざまな機能をアクティブ化する。たとえばこれによりテキスト外観を縦長(taller)または縦短(short)したり、高く(higher)または低く(lower)、太く(wider)または細く(narrower)したり、あるいはイメージに置き換えることができる。display
プロパティを参照のこと。
help-echo
¶テキストがhelp-echo
プロパティに文字列をもつ場合には、そのテキスト上にマウスを移動した際には、substitute-command-keys
を通じて文字列を渡した後にEmacsはエコーエリアかツールチップウィンドウ(ツールチップを参照)にその文字列を表示する。
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を参照)。
この機能はモードライン内、およびその他のアクティブテキストにたいして使用される。
help-echo-inhibit-substitution
¶help-echo
文字列の最初の文字が非nil
のhelp-echo-inhibit-substitution
プロパティをもつ場合には、substitute-command-keys
を通じて渡すことなくshow-help-function
が行うように表示される。
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
プロパティにより、スクリーン上で文字を不可視にできる。詳細は不可視のテキストを参照のこと。
inhibit-isearch
inhibit-isearch
プロパティが非nil
なら、isearchはそのテキストをスキップする。
intangible
¶連続する文字のグループが非nil
の等しいintangible
プロパティをもつなら、それらの文字の間にポイントを置くことは不可能。そのグループ内に前方へポイントの移動を試みると、ポイントは実際にはそのグループの終端に移動する。そのグループ内に後方へポイントの移動を試みると、ポイントは実際にはそのグループの先頭に移動する。
連続する文字のグループが非nil
の等しくないintangible
プロパティをもつなら、それらの文字は個別のグループに属して、各グループは上述のように別のグループとして扱われる。
変数inhibit-point-motion-hooks
が非nil
(デフォルト)ならintangible
プロパティは無視される。
注意せよ:
このプロパティは非常に低レベルで処理されて、予想外の方法により多くのコードに影響する。そのため使用に際しては特別な注意を要する。誤った使用方法としては不可視のテキストにintangibleプロパティをputするのが一般的な誤りであり、コマンドループは各コマンドの終わりに不可視テキストの外部へポイントを移動するだろうから、これは実際には必要ない。コマンド後のポイントの調整を参照のこと。これらの理由によりこのプロパティは時代遅れであり、かわりにcursor-intangible
プロパティを使用すること。
cursor-intangible
¶マイナーモードcursor-intangible-mode
がオンになっている際には、再表示が発生する直前に非nil
のcursor-intangible
プロパティをもつすべての位置からポイントが移動させられる。許容されるカーソル位置の計算時にはこのプロパティの“粘着性(stickiness)”が考慮される(テキストプロパティの粘着性を参照)ので、たとえばカーソルがエンターできないような連続する5つの‘x’を挿入するためには、以下のような何かしらを行う必要がある:
(insert (propertize "xxxx" 'cursor-intangible t) (propertize "x" 'cursor-intangible t 'rear-nonsticky t))
変数cursor-sensor-inhibit
が非nil
なら、cursor-intangible
プロパティとcursor-sensor-functions
プロパティ(以下参照)は無視される。
field
¶同じfield
プロパティをもつ連続する文字はフィールドを構成する。forward-word
やbeginning-of-line
を含むいくつかの移動関数はフィールド境界で移動を停止する。フィールドの定義と使用を参照のこと。
cursor
¶カーソルは通常はカレントバッファー位置を“隠している”(つまりかわりに表示されている)オーバーレイ、およびテキストプロパティ文字列の先頭か終端に表示される。Emacsに指示するかわりに文字に非nil
のcursor
テキストプロパティを与えることにより、それら文字列内の任意の望む文字にカーソルを置くことができる。加えてcursor
プロパティの値が整数なら、それはカーソルがその文字上に表示されるようにオーバーレイまたはdisplay
プロパティが始まる位置から数えたバッファーの文字位置の数字を指定する。特にある文字のcursor
プロパティの値が数字nなら、カーソルは範囲[ovpos..ovpos+n)
内の任意のバッファー位置にあるその文字上に表示されるだろう。ここでovposはoverlay-start
(オーバーレイの管理を参照)により与えられるオーバーレイ開始位置、またはそのバッファー内でdisplay
プロパティが始まる位置である。
言い換えると文字列の非nil
値のcursor
プロパティをもつ文字はカーソルが表示される文字である。このプロパティの値はオーバーレイまたはディスプレイ文字列が表示上でポイントを不可視にしている際に、カーソルを表示するバッファーの位置を告げる。値が整数nならオーバーレイまたはdisplay
プロパティの始まりからn後ろの位置までの間にポイントがあるとき、カーソルはそこに表示される。値がそれ以外の非nil
ならポイントがdisplay
プロパティの先頭となるバッファー位置にあるとき、あるいはディスプレイ上でその位置が不可視ならoverlay-start
となるバッファー位置でのみカーソルが表示される。cursor
プロパティの整数値は、たとえそのポイントがディスプレイ上可視でなくとも、その文字上でカーソルが表示されることを意味し得ることに注意。
このプロパティの微妙なのは、ディスプレイまたはオーバーレイ文字列の一部であるような改行にはこのプロパティが機能しない点である。これはEmacsがディスプレイ上の文字にたいしてソンcursor
プロパティを探す際に、検索するスクリーン上で改行文字がグラフィック表現をもたないからである。
バッファーのテキストを網羅するオーバーレイ文字列(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フック関数が単一のプリミティブにより変更されつつある複数の文字に出現する場合は、その関数が呼び出される回数を予測することはできない。さらに挿入は既存の文字を変更しないので、このフックは文字の削除、他の文字への置換、またはそれらのテキストプロパティ変更時のみ実行されるだろう。
他の同類フックとは異なり、Emacsはこれらの関数を呼び出し時にinhibit-modification-hooks
を非nil
にバインドしない。関数がバッファーを変更するようなら、バッファー変更による変更フックの実行を防ぐために、この変数を非nil
にバインドすることを考慮する必要がある。そうでなければ再帰呼び出しに備えなければならない。フックの変更を参照のこと。
オーバーレイもmodification-hooks
プロパティをサポートするが詳細は若干異なる(オーバーレイのプロパティを参照)。
insert-in-front-hooks
¶insert-behind-hooks
あるバッファーへの挿入操作は後続文字のinsert-in-front-hooks
プロパティ、および先行文字のinsert-behind-hooks
プロパティにリストされる関数の呼び出しも行う。これらの関数は挿入されるテキストの先頭と終端という2つの引数を受け取る。関数は優先される実際の挿入が行われた後に呼び出される。
これらの関数を呼び出す際にはinhibit-modification-hooks
は非nil
にバインドされる。関数がバッファーを変更する場合には、これらの変更にたいして変更フックが実行されるように、inhibit-modification-hooks
をnil
にバインドしたいと思うかもしれない。しかしこれを行うことによって、あなたの変更フックが再帰的に呼び出されるかもしれないので、確実にそれに備えること。
バッファー内のテキスト変更時にに呼び出される他のフックについてはフックの変更も参照のこと。
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
がオンのときのみ呼び出される。
変数cursor-sensor-inhibit
が非nil
ならcursor-sensor-functions
プロパティは無視される。
composition
¶このテキストプロパティは文字シーケンスをコンポーネントから構成される単一グリフ(single
glyph)として表示するために使用される。しかしこのプロパティの値自身は完全にEmacsの内部的なものであり、たとえばput-text-property
などで直接操作しないこと。
minibuffer-message
¶このテキストプロパティは、アクティブミニバッファーの一時的なメッセージを表示する場所を指定する。具体的にはこのプロパティをもつミニバッファーテキストの最初の文字が、その前に表示する一時的なメッセージを所有する。デフォルトではミニバッファーテキスト終端に一時的なメッセージが表示される。このテキストプロパティはset-message-function
のデフォルト値の関数が使用する(エコーエリアへのメッセージの表示を参照)。
この時代遅れの変数が非nil
のときは、point-left
とpoint-entered
のフックは実行されずintangible
プロパティは効果をもたない。この変数はグローバルにセットせずlet
でバインドすること。この変数の影響を受けるプロパティは時代遅れなので、それらを効果的に無効にするためにデフォルト値はt
。
この変数が非nil
なら、それはヘルプ文字列を表示するために呼び出される関数を指定する。これらはhelp-echo
プロパティ、メニューヘルプ文字列(単純なメニューアイテムと拡張メニューアイテムを参照)、ツールバーヘルプ文字列(ツールバーを参照)かもしれない。指定された関数は、ヘルプ文字列の最初の文字が非nil
のhelp-echo-inhibit-substitution
をもっていなければ、表示するためのヘルプ文字列(関数に与えられる前にsubstitute-command-keys
を通じて渡される)を単一の引数として呼び出される。ドキュメント内でのキーバインディングの置き換えを参照のこと。show-help-function
を使用するモードの例は、Tooltipモード(Tooltips in The GNU Emacs Manualを参照)のコード例を参照のこと。
この変数が非nil
なら、特定の条件が合致された際のみ適用される属性を指定するフェイスフィルターは常にマッチするとみなされる。
[ << ] | [ < ] | [ 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を処理する例:
(keymap-set Info-mode-map "<follow-link>" 'mouse-face)
コンディションが関数funcの場合には、(func
pos)
が非nil
に評価されれば、位置posはリンクの内側。funcがリターンする値はアクションコードとして機能する。
以下はpcvsがファイル名の上でのみmouse-1によるリンクのフォローを有効にする方法の例:
(keymap-set 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] | [ ? ] |
バッファー内のテキストへの属性の追加をサポートする一部のエディターの中には、ユーザーにテキスト内のインターバルを指定させて、そのインターバルにプロパティを追加することによって属性の追加をサポートするものがあります(訳注: 日本語のカタカナ英語として通用しているインターバルは「間隔」、「距離」、「合間」のようにインターバルの両端に実体がありインターバル自体は隔たりだけを表す疎な実体という日常会話でのinterval訳を連想しますが、Emacs Lispリファレンスにおけるインターバルは計算幾何学におけるインターバル木のように開始と終了をもった数学分野におけるinterval訳である「区間」の意味で用いられています; object-intervalsを参照してください)。それらのエディターではユーザーやプログラマーが個別にインターバルの開始と終了を決定することが許されています。わたしたちはテキスト変更に関連する逆説的な特定の振る舞いを避けるために、故意に異なる種類のインターフェイスを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に置き換える。これら2つの文字はマルチバイト形式で同じ長さでなければならない。
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 ----------
この関数はstring内のすべての文字fromcharをtocharに置き換える。デフォルトではstringのコピーで置き換えは発生するが、オプション引数inplaceが非nil
なら、この関数はstring自体を変更する。いずれの場合でも、この関数は結果となる文字列をリターンする。
この関数はバッファー内の位置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)
これはリストア用のフレーム構成とカレントバッファー内のジャンプ先の位置。フレーム構成はフレームセット(frameset)とも呼ばれる。
(file filename)
これはvisitするファイルを表し、この値にジャンプすることによりファイルfilenameをvisitする。
(file-query filename position)
これはvisitするファイルとファイル内の位置を表す。この値にジャンプすることによりファイルfilenameをvisitしてバッファー位置positionに移動する。このタイプの位置をリストアすると、まずユーザーにたいして確認を求める。
(buffer buffer-name)
これはvisitするバッファーを表し、この値にジャンプすることによりバッファーbuffer-nameに切り替える。
このセクションの関数は特に明記しない限り予期せぬ値をリターンします。
この関数はレジスター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] | [ ? ] |
以下の関数を使用して、あるバッファーのテキストを他のバッファーのテキストで置き換えることができます:
この関数はバファーsourceのアクセス可能範囲でカレントバッファーのアクセス可能範囲を置き換える。sourceはバッファーオブジェクトかバッファー名のいずれか。replace-buffer-contents
が成功するとカレントバッファーのアクセス可能範囲のテキストは、バッファーsourceのアクセス可能範囲のテキストと等しくなる。
この関数はバファーsourceのアクセス可能範囲でカこの関数はカレントバッファーのポイント、マーカー、テキストプロパティ、オーバーレイをそのまま維持しようと試みる。この挙動が好都合であるような潜在的なケースは外部コードをフォーマットするプログラムだろう。これらは通常は再フォーマットしたテキストを一時的なバッファーかファイルに書き込んで、delete-region
やinsert-buffer-substring
を使用することによりそれらのプロパティを削除する。しかし後者の組み合わせのほうが通常は高速である(テキストの削除とテキストの挿入を参照)。
これが機能するためにはreplace-buffer-contents
が元バッファーとsourceのコンテンツを比較する必要があり、これはバッファーが巨大で多数の差異が存在する場合にはコストがかかる処理となる。replace-buffer-contents
の実行時間を制限するために、2つのオプション引数がある。
max-secsは秒単位のハードリミットを定義する。これが与えられて超過した場合には、delete-region
およびinsert-buffer-substring
にフォールバックする。
max-costsは差分計算の品質を定義する。このリミットを実際のコストが超過したら、次善だがより高速な発見的手法を使用する。デフォルト値は1000000。
replace-buffer-contents
は非破壊的な置換ができればt
をリターンする。それ以外の場合にはmax-secsを超過したらnil
をリターンする。
この関数は与えられたreplace-fnを使用して、begとendの間のリージョンを置換する。関数replace-fnはカレントバッファーを指定されたリージョンにナローして実行される。リージョンを置換する文字列またはバッファーのいずれかをリターンすること。
置換は上述のreplace-buffer-contents
(引数max-secs、max-costs、リターン値についても記述あり)を使用して行われる。
注意:
置換物が文字列なら一時バッファーに配置されるのでreplace-buffer-contents
が処理することができる。したがってすでにバッファーに置換物がある場合には、buffer-substring
の類を使用して文字列に変換することは無意味である。
[ << ] | [ < ] | [ 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で圧縮されたデータが含まれていなければならない。この関数は成功したらリージョンのコンテンツを解凍されたデータに置き換える。allow-partialがnil
か省略の場合に失敗すると、この関数はリージョンを変更せずにnil
をリターンする。それ以外の場合には解凍されなかったバイト数をリターンして、正常に解凍されたデータが何であれ、それによりリージョンのテキストを置き換える。この関数はユニバイトバッファーでのみ呼び出すことができる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Base64コードは8ビットシーケンスをより長いASCIIグラフィック文字シーケンスにエンコードするためにemail内で使用されます。これはインターネットRFC2045およびRFC4648でも定義されます23。このセクションでは、このコードへの変換および逆変換を行う関数について説明します。
この関数はbegからendのリージョンをBase64コードに変換する。これはエンコードされたテキストの長さをリターンする。リージョン内の文字がマルチバイトならエラーをシグナルする(マルチバイトバッファーではリージョンにはASCIIとrawバイト以外の文字が含まれてはならない)。
この関数は通常は行が長くなりすぎるのを防ぐために、エンコードされたテキストに改行を挿入する。しかしオプション引数no-line-breakが非nil
なら、これらの改行は追加されず出力は長い単一の行となる。
この関数はbase64-encode-region
と同様だがRFC4648にしたがいBase64エンコーディングのURLバリアントを実装する。エンコードされたテキストに改行を挿入しないので、出力は1行だけの長い行となる。
オプション引数no-padは非nil
なら、この関数はパディング(=
)を生成しない。
この関数は文字列stringをBase64コードに変換する。これはエンコードされたテキストを含む文字列をリターンする。base64-encode-region
と同じように文字列内の文字がマルチバイトならエラーをシグナルする。
この関数は通常は行が長くなりすぎるのを防ぐためにエンコードされたテキストに改行を挿入する。しかしオプション引数no-line-breakが非nil
なら、これらの改行は追加されず結果となる文字列は長い単一の行となる。
base64-encode-string
と同様だがBase64のURLバリアントを生成する。エンコードされたテキストに改行を挿入しないので、結果は1行だけの長い行となる。
オプション引数no-padは非nil
なら、この関数はパディングを生成しない。
この関数はbegからendのリージョンのBase64コードを対応するデコードされたテキストに変換する。これはデコードされたテキストの長さをリターンする。
デコード関数はエンコード済みテキスト内の改行文字を無視する。
オプション引数base64urlが非nil
ならパディングはオプションであり、Base64エンコーディングのURLバリアントが使用される。オプション引数ignore-invalidが非nil
の場合には、認識できない文字はすべて無視される。
この関数は文字列stringを、Base64コードから対応するデコード済みテキストに変換する。これはデコード済みテキストを含むユニバイトをリターンする。
デコード関数はエンコード済みテキスト内の改行文字を無視する。
オプション引数base64urlが非nil
ならパディングはオプションであり、Base64エンコーディングのURLバリアントが使用される。オプション引数ignore-invalidが非nil
の場合には、認識できない文字はすべて無視される。
[ << ] | [ < ] | [ 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とSHA-1は‘衝突耐性(collision
resistant)をもたない(同じMD5またはSHA-1のハッシュをもつ異なるデータ片を故意にデザインすることが可能)ので、セキュリティに関連することに使用するべきではありません。セキュリティーに関するアプリケーションではSHA-2
(sha256
やsha512
)のような他のハッシュタイプを使用するべきです。
この関数はsecure-hash
が使用可能なアルゴリズムを表すシンボルのリストをリターンする。
この関数はobjectにたいするハッシュをリターンする。引数algorithmはどのハッシュを計算するかを示すシンボルでmd5
、sha1
、sha224
、sha256
、sha384
、sha512
のいずれか。引数objectはバッファーまたは文字列であること。
オプション引数startとendは、メッセージダイジェストを計算するobject部分を指定する文字位置。これらがnil
か省略なら、object全体にたいしてハッシュを計算する。
引数binaryが省略かnil
なら、通常のLisp文字列としてハッシュのテキスト形式(text
form)をリターンする。binaryが非nil
なら、ユニバイト文字列に格納されたバイトシーケンスとしてハッシュのバイナリー形式(binary
form)をリターンする。リターンされる文字列の長さはalgorithmに依存する:
md5
: 32文字(binaryが非nil
なら32バイト)
sha1
: 40文字(binaryが非nil
なら40バイト)
sha224
: 56文字(binaryが非nil
なら56バイト)
sha256
: 64文字(binaryが非nil
なら64バイト)
sha384
: 96文字(binaryが非nil
なら96バイト)"
sha512
: 128文字(binaryが非nil
なら128バイト)"
この関数はobjectのテキストの内部表現(テキストの表現方法を参照)からハッシュを直接計算しない。かわりにコーディングシステム(コーディングシステムを参照)を使用してテキストをエンコードして、そのエンコード済みテキストからハッシュを計算する。objectがバッファーなら使用されているコーディングが、バッファーのテキストをファイルに書き込むためのデフォルトとして選択される。objectが文字列ならユーザーの好むコーディングシステムが使用される(Recognize Coding in GNU Emacs Manualを参照)。
この関数はMD5ハッシュをリターンする。これはほとんどの目的において、algorithm引数にmd5
を指定してsecure-hash
を呼び出すのと等価であり半ば時代遅れである。引数のobject、start、endはsecure-hash
のときと同じ意味をもつ。この関数は32文字の文字列をリターンする。
coding-systemが非nil
なら、それはテキストをエンコードするために使用するコーディングシステムを指定する。省略またはnil
なら、secure-hash
と同様にデフォルトコーディングシステムが使用される。
md5
は通常は指定や選択されたコーディングシステムを使用してテキストをエンコードできなければエラーをシグナルする。しかしnoerrorが非nil
なら、かわりに黙ってraw-text
コーディングシステムを使用する。
buffer-or-nameのハッシュをリターンする。nil
の場合のデフォルトはカレントバッファー。この関数はsecure-hash
とは対照的にコーディングシステムとは無関係にバッファーの内部表現にもとづいてハッシュを計算する。したがって同一のEmacs上で実行中の2つのバッファーを比較する際にのみ有用であり、異なるバージョンのEmacs間で同じハッシュをリターンする保証はない。これは巨大なバッファーにたいしてsecure-hash
より幾分効果的であり、secure-hash
ほど多くのメモリーを割り当てないはずである。
この関数は以下のようにsecure-hash
を呼び出すことと同じ:
(secure-hash 'sha1 object start end binary)
これはbinaryがnil
なら40文字の文字列、それ以外の場合には40バイトのユニバイト文字列をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsでは電子メールやWebサイトのような多くの外部ソースを表示することができます。アタッカー(攻撃者)は難読化したURLや電子メールアドレスを使い、それらのテキストを読むユーザーを混乱させて、意図していないウェブページに誘導したり、誤ったアドレスにメールを送信するようユーザーを欺くのです。
これには通常だとASCII文字と似た外観をもつスクリプトの文字(homographs、すなわち綴りは同じでも意味の違う文字)が必要ですが、bdo(bidirectional override: 双方向オーバーライド)や、何かを示すHTMLの背後に別のどこかを指し示すURLを仕込むといった別のテクニックも存在します。
これら不審なテキスト文字列(suspicious text strings)の識別を助けるために、Emacsはテキストにたいしていくつかのチェックを行うライブラリーを提供します(利用可能なチェックの背景となる根拠に関する詳細についてはUTS #39: Unicode Security Mechanismsを参照)。疑わしい恐れのあるデータを提供するパッケージは、表示に際して不審なテキストにフラグを立てるためにこんなライブラリーを使う必要があります。
この関数はパッケージが使用すべき高レベルのインターフェイス関数である。チェックの無効化をユーザーに許すユーザーオプションtextsec-check
を考慮する。
この関数はtypeのオブジェクトとしてobject(データのタイプはtypeに依存)を評価した際に疑わしいかどうかをチェックする。利用できるタイプおよび対応するobjectのデータタイプは以下のとおり:
domain
不審なドメイン(例: ‘www.gnu.org’)かどうかをチェック。objectはドメイン名(文字列)。
url
不審なURL(例: ‘http://gnu.org/foo/bar’)かどうかをチェック。objectはチェックするURL(文字列)。
link
不審なHTMLリンク(例: ‘<a
href='http://gnu.org'>fsf.org</a>’)かどうかをチェック。この場合にはobjectはcar
がURL文字列、cdr
がリンクテキストであるようなcons
セルであること。リンクテキストにドメイン名が含まれていて、それがURLと異なるドメイン名を指す場合には不審なリンクとみなされる。
email-address
不審な電子メールアドレス(例: ‘foo@example.org’)かどうかをチェック。objectは文字列であること。
local-address
電子メールアドレスのローカル部分(‘@’記号の前の部分が疑わしいかどうかをチェック。objectは文字列であること。
name
名前(電子メールアドレスのヘッダーに使用される)が疑わしいかどうかをチェック。objectは文字列であること。
email-address-header
RFC2822に完全準拠した電子メールアドレス(例: ‘=?utf-8?Q?=C3=81?= <foo@example.com>’)が疑わしいかどうかをチェック。objectは文字列であること。
この関数はobjectが疑わしい場合には、なぜそれが疑わしいかを説明する文字列をリターンする。objectに不審な点がなければ、この関数はnil
をリターンする。
テキストが疑わしい場合には、アプリケーションはtextsec-suspicious
フェイスで疑わしいテキストファイルをマークするとともに、textsec-suspicious-p
がリターンした説明を、何らかの手段(たとえばツールチップなど)でユーザーが利用できるようにする必要があります。疑わしい文字列にもとづいて何らかのアクション(たとえば疑わしい電子メールアドレスへのメール送信)を実行する前に、アプリケーションがユーザーに確認を求める場合もあります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GnuTLSとともにコンパイルされていれば、Emacsはビルトインの暗号化サポートを提供します。GnuTLSのAPI用語にしたがいダイジェスト(digests)、MAC(メッセージ認証符号)、共通鍵暗号(symmetric ciphers)、認証付き暗号(AEAD ciphers)のツールが利用できます。
ここで使用するIV(Initialization Vector: 初期化ベクトル)のような暗号化にある程度親しんでいる必要のある用語は詳細には定義しません。GnuTLSライブラリーの用語や構造を理解する助けとなる特定のドキュメントについてはhttps://www.gnutls.org/を参照してください。
33.28.1 GnuTLS暗号化入力のフォーマット | GnuTLS暗号入力のフォーマット。 | |
33.28.2 GnuTLS暗号化関数 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GnuTLS暗号化関数への入力はEmacs Lispのプリミティブかリストのいずれかにより、複数の方法で指定できます。
現在のところリストの形式はmd5
とsecure-hash
が動作する方法に似ています。
バッファー
入力として単にバッファーを渡すとバッファー全体が使用されることを意味する。
文字列
文字列は入力として直接使用される。(他のほとんどのEmacs Lisp関数とは異なり)関数の処理後に機密データ漏洩の機会を減少させるために関数が文字列を変更するかもしれない。
(buffer-or-string start end coding-system noerror)
これは上述のようにバッファーか文字列を指定するが、オプションでstartとendで範囲を指定できる。
加えて必要ならオプションでcoding-systemを指定できる。
最後のオプションのアイテムnoerrorは指定もしくは選択されたコーディングシステムを使用してテキストをエンコードできない際の通常のエラーをオーバーライドする。noerrorが非nil
なら関数は暗黙にraw-text
コーディングシステムをかわりに使用する。
(iv-auto
length)
これは指定した長さのランダムなIV(Initialization Vector: 初期化ベクトル)を生成して関数に渡す。これによってIVが予測不可能となり、かつ同一セッション内での再利用があり得なくなることが保証される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はGnuTLSダイジェストアルゴリズムのalistをリターンする。
各エントリーはアルゴリズムを表すキーとアルゴリズムの内部的な詳細を表すplistをもつ。plistは結果となるダイジェストのバイトサイズを示す:type
gnutls-digest-algorithm
、および:digest-algorithm-length 64
のキーももつだろう。
GnuTLS MACとダイジェストアルゴリズムの間には類似した名前が存在するが、これらは内部的には別物であり混在させるべきではない。
digest-methodはgnutls-digests
由来の完全なplist、単なるシンボルキー、またはシンボル名の文字列でもよい。
inputはバッファー、文字列、もしくは他の方法(GnuTLS暗号化入力のフォーマットを参照)でも指定できる。
この関数はエラー時にはnil
、digest-methodかinputが無効ならLispエラーをシグナルする。成功時にはバイナリー文字列(出力)と使用されるIVのリストをリターンする。
この関数はGnuTLS MACアルゴリズムのalistをリターンする。
各エントリーはアルゴリズムを表すキーとアルゴリズムの内部的な詳細を表すplistをもつ。このplistは結果となるハッシュ、キー、ナンスのバイトサイズを示すキー:type
gnutls-mac-algorithm
、:mac-algorithm-length
、:mac-algorithm-keysize
、:mac-algorithm-noncesize
現在のところナンスは使用されておらず、いくつかのMACでのみサポートされる。
GnuTLS MACとダイジェストアルゴリズムの間には類似した名前が存在するが、これらは内部的には別物であり混在させるべきではない。
hash-methodはgnutls-macs
由来の完全なplist、単なるシンボルキー、またはシンボル名の文字列でもよい。
keyはバッファー、文字列、あるいは他の方法(GnuTLS暗号化入力のフォーマットを参照)でも指定できる。keyが文字列なら使用後に消去される。
inputはバッファー、文字列、もしくは他の方法(GnuTLS暗号化入力のフォーマットを参照)でも指定できる。
この関数はエラー時にはnil
、hash-methodやkey、inputが無効ならLispエラーをシグナルする。
成功時にはバイナリー文字列(出力)と使用されるIVをリターンする。
この関数はGnuTLS暗号のリストをリターンする。
各エントリーは暗号を表すキーとそのアルゴリズムに関する内部的な詳細を表すplistをもつ。このplistは:type
gnutls-symmetric-cipher
、およびAEAD機能を示すためにnil
かt
にセットされたキー:cipher-aead-capable
、さらにタグ、結果データのブロックサイズ、キー、IVのバイトサイズを示すキー:cipher-tagsize
、:cipher-blocksize
、:cipher-keysize
:cipher-ivsize
ももつ。
cipherはgnutls-ciphers
由来の完全なplist、単なるシンボルキー、またはシンボル名の文字列でもよい。
keyはバッファー、文字列、あるいは他の方法(GnuTLS暗号化入力のフォーマットを参照)でも指定できる。keyが文字列なら使用後に消去される。
iv、input、およびオプションのaead_authはバッファー、文字列、または他の方法(GnuTLS暗号化入力のフォーマットを参照)でも指定できる。
aead_authはAEAD暗号、すなわちplistが:cipher-aead-capable
t
をもつ暗号でのみチェックされて、他では無視される。
この関数エラー時にはnil
、cipherやkey、ivやinputが無効だったり、AEAD暗号でaead_authが指定されてそれが無効な場合にはLispエラーをシグナルする。
成功時にはバイナリー文字列(出力)と使用されるIVをリターンする。
cipherはgnutls-ciphers
由来の完全なplist、単なるシンボルキー、またはシンボル名の文字列でもよい。
keyはバッファー、文字列、あるいは他の方法(GnuTLS暗号化入力のフォーマットを参照)でも指定できる。keyが文字列なら使用後に消去される。
iv、input、およびオプションのaead_authはバッファー、文字列、または他の方法(GnuTLS暗号化入力のフォーマットを参照)でも指定できる。
aead_authはAEAD暗号、すなわちplistが:cipher-aead-capable
t
をもつ暗号でのみチェックされて、他では無視される。
この関数は解読エラー時にはnil
、cipherやkey、ivやinputが無効だったり、AEAD暗号で指定されたaead_authが無効な場合にはLispエラーをシグナルする。
成功時にはバイナリー文字列(出力)と使用されるIVをリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SQLiteデータベースへのアクセスにたいする組み込みサポートとともにEmacsをコンパイルできます。このセクションではLispプログラムからSQLiteデータベースへアクセスするために利用できる機能について説明します。
この関数はビルトインSQLiteサポートが利用可能なら非nil
をリターンする。
SQLiteサポートが利用可能なら、以下の関数を利用できます。
この関数はfileをSQLiteのデータベースファイルとしてオープンする。fileが存在しなければ、新たなデータベースを作成して指定されたファイルに格納する。fileが省略またはnil
なら、かわりにインメモリーのデータベースを作成する。
リターン値はデータベースオブジェクト(database object)。これは以下に挙げるほとんどの関数の引数として利用できる。
この述語関数はobjectがSQLiteデータベースオブジェクトなら非nil
をリターンする。sqlite-open
がリターンしたデータベースオブジェクトは、この述語を満足する。
データベースdbを閉じる。通常はこの関数を明示的に呼び出す必要はない(Emacsのシャットダウンやデータベースオブジェクトがガーベージコレクトされればデータベースは自動的に閉じられる)。
SQLの命令文statementを実行時する。たとえば:
(sqlite-execute db "insert into foo values ('bar', 2)")
オプション引数valuesを与える場合には、それは命令を実行する際に値としてバインドされるリストかベクターのいずれかであること。
(sqlite-execute db "insert into foo values (?, ?)" '("bar" 2))
これは前の例とまったく同じ効果をもつが、より効率的かつ安全である(文字列の解析や挿入を何も行わないので)。
sqlite-execute
は通常は影響を受ける行数をリターンする。たとえば‘insert’文は通常だと‘1’をリターンするが、‘update’文は0、あるいはそれより大きい値をリターンするかもしれない。ただし‘insert into … returning …’やその類いのSQL文を使った際には、かわりに‘returning …’によって指定された値がリターンされる。
SQLiteでの文字列は、デフォルトではutf-8
として格納されて、テキストの列をselectした場合にはその文字セット(charset)を使って文字列をデコードする。blobの列をselectした場合には、何もデコードせずにrawデータをリターンする(データベースに格納されているバイトを含んだユニバイトをリターンする)。バイナリーデータをblob列にinsertする場合には、デフォルトではsqlite-execute
はすべての文字列をutf-8
と解釈するため注意を要する。
したがってたとえばgifと呼ばれるユニバイト文字列としてGIFデータをもっている場合には、sqlite-execute
にそれが判るように特別にマークする必要がある:
(put-text-property 0 1 'coding-system 'binary gif) (sqlite-execute db "insert into foo values (?, ?)" (list gif 2))
dbからデータをselectしてそれをリターンする。たとえば:
(sqlite-select db "select * from foo where key = 2") ⇒ (("bar" 2))
sqlite-execute
の場合と同様に、selectの実行前にバインドする値としてリストまたはベクターをオプションとして渡すことができる:
(sqlite-select db "select * from foo where key = ?" [2]) ⇒ (("bar" 2))
これは前の例で用いた手法に比べて、通常はより効果的かつ安全である。
この関数はデフォルトではマッチした行のリストをリターンする(行は列の値のリスト)。return-typeがfull
の場合には、リターン値の1つ目の要素として列の名前(文字列のリスト)をリターンする。
return-typeがset
なら、この関数はかわりにステートメントオブジェクト(statement
object)をリターンする。このオブジェクトはsqlite-next
、sqlite-columns
、sqlite-more-p
といった関数を用いて調べることができる。結果セットが小さければ単に直接データをリターンするほうが便利な場合が多いが、結果セットが大きい場合(あるいはそのセットのデータすべてを使いたい場合)には、割り当てられるメモリーが大幅に小さくメモリー効率に優れたset
メソッドを使用すること。
この関数は結果セットstatement(通常はsqlite-select
がリターンしたオブジェクト)の次の行をリターンする。
(sqlite-next stmt) ⇒ ("bar" 2)
この関数は結果セットstatement (通常はsqlite-select
がリターンしたオブジェクト)の列名をリターンする。
(sqlite-columns stmt) ⇒ ("name" "issue")
結果セットstatement(通常はsqlite-select
がリターンしたオブジェクト)からfetchできるデータがまだあるかどうかを調べる述語である。
これ以上statementを使わない場合には、この関数を呼び出すことによってstatementが使用していたリソースが解放される。この関数の呼び出しは通常は必要ない(statementオブジェクトがガーベージコレクトされれば、Emacsがそのオブジェクトのリソースを自動的に解放する)。
dbでトランザクションを開始する。トランザクションにおいてはsqlite-commit
によってそのトランザクションがコミットされるまでは、そのデータベースの他の読み取り手は結果にアクセスできない。
dbのトランザクションを終了して、データベースのファイルにデータを書き込む。
dbのトランザクションを終了して、そのトランザクションによって行われたすべての変更を破棄する。
progn
(順序を参照)と同様だが、トランザクションとともにbodyを実行して、最後にそのトランザクションをコミットする。
dbにおいてpragmaを実行する。pragmaとは特定のテーブルではなく、通常はデータベース全体に効果を及ぼすコマンドのこと。たとえば不要になったデータのガーベージコレクトをSQLiteに自動的に行わせるには、以下のようにすればよい:
(sqlite-pragma db "auto_vacuum = FULL")
この関数はpragmaが成功すれば非nil
、失敗するとnil
をリターンする。pragmaの多くは空の新規データベースでのみ発行できる。
名前つきエクステンション(拡張)であるmoduleをデータベースdbにロードする。エクステンションは通常は共有ライブラリーであり、GNUおよびUnixのシステムではファイル名の拡張子として.soがつけられている。
使用中のSQLiteライブラリーのバージョンを表す文字列をリターンする。
SQLiteファイルの内容を一覧したければ、sqlite-mode-open-file
コマンドを使うことができます。これはSQLiteデータベースの調査(と変更)が可能なsqlite-mode
のバッファーをポップアップします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ビルトインのlibxml2サポートつきでEmacsをコンパイルできます。
この関数はビルトインlibxml2サポートが利用可能なら非nil
をリターンする。
libxml2サポートが利用可能なら、HTMLやXMLのテキストをLispオブジェクトツリーにパースするために以下の関数を利用できます。
この関数はstartとendの間のテキストをHTMLとしてパースして、HTMLパースツリー(parse tree)を表すリストをリターンする。これは構文誤りにたいして強力に対処することにより、現実世界のHTMLの処理を試みる。
startまたはendがnil
の場合のデフォルト値は、それぞれpoint-min
とpoint-max
になる。
オプション引数base-urlが非nil
なら、それはlibxml2がレポートする警告とエラーに使用されるべきだが、現在のところEmacsはエラーと警告を無効にしてこのライブラリーを呼び出すのでこの引数は使用されていない。
オプション引数discard-commentsが非nil
なら、すべてのトップレベルのコメントを破棄する(この引数は時代遅れでありEmacsの将来のバージョンで削除されるだろう。コメントの削除にはパース関数の呼び出し前にデータにユーティリティ関数xml-remove-comments
を使用すること)。
パースツリー内では各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(構文についてより厳格)としてテキストをパースする点が異なる。
33.30.1 ドキュメントオブジェクトモデル | 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) => "https://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-remove dom node
domからnodeを削除する。
以下はDOMを変更するための関数です。
dom-set-attribute node attribute value
ノードのattributeにvalueをセットする。
dom-remove-attribute node attribute
nodeからattributeを削除する。
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-search dom predicate
predicateが非nil
値をリターンしたdom内のすべてのノードをリターンする。predicateはテストされるノードをパラメーターとして呼び出される。
dom-strings dom
dom内のすべての文字列をリターンする。
ユーティリティ関数:
dom-pp dom &optional remove-empty
ポイント位置のdomにたいしてプリティプリント(pp: 優雅なプリント)を行う。remove-emptyなら空白文字だけを含むテキスト的ノードはプリントしない。
dom-print dom &optional pretty xml
ポイント位置のdomをプリントする。xmlが非nil
ならXML、それ以外ならHTMLとしてプリントする。prettyが非nil
なら、HTML/XMLを論理的にプリントする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
JSON (JavaScript Object Notation)のサポートつきでEmacsをコンパイルした場合には、LispオブジェクトとJSON値との間で変換を行う関数がいくつか提供されます。任意のJSON値をLispオブジェクトに変換できますが、その逆は成り立ちません。具体的には:
true
、null
、false
という3つのキーワードを使用する。true
はシンボルt
を表す。デフォルトでは残り2つのキーワードはそれぞれシンボル:null
、:false
で表される。
assq
の挙動にしたがいシリアライズに最初の要素だけを使用する。
alistとplistの両方で有効なnil
は、空のJSONオブジェクト{}
を表すことに注意してください。null
やfalse
、空の配列はJSONではすべて異なる値です。
この述語はJSONサポート付きでEmacsがビルドされていて、そのライブラリーがカレントシステムで利用可能なら非nil
をリターンする。
JSONで何らかのLispオブジェクトを表現できなければ、シリアライゼーション関数はタイプwrong-type-argument
のエラーをシグナルします。パース関数も以下のエラーをシグナルする可能性があります:
json-unavailable
パース用ライブラリーが利用できない際にシグナルされる。
json-end-of-file
入力テキストの早すぎる終端に遭遇した際にシグナルされる。
json-trailing-content
パース済みの最初のJSONオブジェクトの後で予期せぬ入力に遭遇した際にシグナルされる。
json-parse-error
無効なJSON構文に遭遇した際にシグナルされる。
トップレベルの値、およびそれらトップレベル値のサブオブジェクトをJSONにシリアライズできます。同様にパース関数は上述の利用可能なタイプをリターンします。
この関数はobjectのJSON表現を含むLisp文字列を新たにリターンする。引数argsはキーワード/引数のペアからなるリスト。以下のキーワードが可能:
:null-object
値はJSONキーワードのnull
を表すために使用するLispオブジェクトを決定する。デフォルトはシンボル:null
。
:false-object
値はJSONキーワードのfalse
を表すために使用するLispオブジェクトを決定する。デフォルトはシンボル:false
。
このコマンドはカレントバッファーのポイントの前にobjectのJSON表現を挿入する。引数argsはjson-parse-string
の場合と同様に扱われる。
この関数はstring
(Lisp文字列でなければならない)内のJSON値をパースする。stringに有効なJSONオブジェクトが含まれていなければ、この関数はjson-parse-error
エラーをシグナルする。
引数argsはキーワード/引数のペアのリスト。以下のキーワードが許されている:
:object-type
値はJSONオブジェクトのキーと値のマッピングを表現するために使用するLispオブジェクトを決定する。文字列をキーとするハッシュテーブルhash-table
(デフォルト)、シンボルをキーとするalistを使用するalist
、キーワードシンボルをキーとするplistを使用するplist
のいずれかが可能。
:array-type
値はJSON配列の表現に使用するLispオブジェクトを決定する。Lisp配列を使用するarray
(デフォルト)、またはリストを使用するlist
のいずれかが可能。
:null-object
値はJSONキーワードのnull
を表すために使用するLispオブジェクトを決定する。デフォルトはシンボル:null
。
:false-object
値はJSONキーワードのfalse
を表すために使用するLispオブジェクトを決定する。デフォルトはシンボル:false
。
この関数はカレントバッファーのポイント位置の文字列から、次のJSON値を読み取る。値に有効なJSONオブジェクトが含まれていれば値の直後にポイントを移動、それ以外ならjson-parse-error
エラーをシグナルしてポイントは移動しない。引数argsはjson-parse-string
の場合と同様に解釈される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
jsonrpc
ライブラリーはhttps://www.jsonrpc.org/に記載されたJSONRPC仕様を実装します。JSONRPCはその名前が示すように、Lispとの間で相互に変換可能なJSONオブジェクトを中心に設計された、遠隔手続呼出(Remote
Procedure Call)のための汎用プロトコルです。
33.32.1 概観 | ||
33.32.2 プロセスベースのJSONRPC接続 | ||
33.32.3 JSONRPCのJSONオブジェクトフォーマット | ||
33.32.4 遅延されたJSONRPCリクエスト |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
specから引用するとJSONRPCは、"同一プロセス、ソケットやhttp、多くのさまざまなメッセージパッシング環境において使用可能という概念においてトランスポート非依存"です。
この非依存性をモデル化するために、jsonrpc
ライブラリーはリモートのJSONのエンドポイントへの接続の表現にjsonrpc-connection
クラスのオブジェクトを使用します(Emacsのオブジェクトシステムの詳細はEIEIO in EIEIOを参照)。これはオブジェクト指向の現代的な用語では“抽象的(abstract)”なクラス、すなわち有用な接続オブジェクトの実クラスは常にjsonrpc-connection
のサブクラスになります。それにも関わらず、jsonrpc-connection
クラスを中心に2つのAPIを個別に定義できます。
このシナリオではJSONRPCアプリケーションはjsonrpc-connection
の具象サブクラスを選択して、make-instance
を使用することによりサブクラスのオブジェクト作成を行う。JSONRPCアプリケーションはリモートのエンドポイントとの対話を開始するために、関数jsonrpc-notify
、jsonrpc-request
、および/またはjsonrpc-async-request
にこのオブジェクトを渡す。一般的には非同期に到達するリモートで開始された対話を処理するために、インスタンス化には:request-dispatcher
と:notification-dispatcher
の初期化引数(initarg)を含める必要があり、これらはいずれも接続オブジェクト、リモートで呼び出されたJSONRPCメソッドを命名するシンボル、JSONRPCのparams
オブジェクトという3つの引数を受け取る関数である。
:request-dispatcher
として渡された関数は、ローカルのエンドポイントからのリプライ(この場合では構築するプログラム)を除いた、リモートのエンドポイントのリクエストを処理する役目を担う。その関数の内部では局所的なリターン(通常のリターン)と非局所的なリターン(エラーによるリターン)が起こり得る。局所的なリターン値はJSONとしてシリアライズ可能なLispオブジェクトでなければならない(JSON値の解析と生成を参照)。これは成功レスポンスを決定するとともに、オブジェクトはJSONRPCのresult
オブジェクトとしてサーバーにフォワードされる。関数jsonrpc-error
の呼び出しにより達成される非局所的なリターンは、エラーレスポンスをサーバーに送信する。JSONRPCのerror
に付随する詳細には、jsonrpc-error
に渡されるものすべてが含まれる。他のタイプの予期せぬエラーからトリガーされた非局所的なリターンでも、(
debug-on-error
をセットしていなければ)エラーレスポンスを送信して、この場合にはLispデバッガが呼び出される。エラーによるデバッガへのエンターを参照のこと。
このシナリオでは基盤として異なるトランスポートストラテジーを実装するためにjsonrpc-connection
をサブクラス化する(サブクラス化する方法についての詳細は(eieio)Inheritanceを参照)。その後にアプリケーション構築インターフェースのユーザーは、(
make-instance
関数を使用して)その具象クラスのオブジェクトをインスタンス化して、そのストラテジーを使用してJSONRPCエンドポイントに接続できる。
このAPIには必須部分とオプション部分がある。
ユーザーがJSONRPCコンタクト(通知やリクエスト)を開始したり、エンドポイントにリプライできるようにするためには、そのサブクラスはjsonrpc-connection-send
メソッドを実装しなければならない。
同様に3種類のリモートコンタクト(リクエスト、通知、ローカルリクエストへの応答)を処理するために、トランスポート実装はワイヤー(wire:
通信ライン)上への新たなJSONRPCメッセージの通知後に、(その"ワイヤー"が何であれ)関数jsonrpc-connection-receive
が呼び出されるように計らわなければならない。
最後にオプジョンとしてjsonrpc-shutdown
メソッドとjsonrpc-running-p
メソッドの概念をトランスポートに適用する場合には、jsonrpc-connection
サブクラスはそれらのメソッドを実装する必要がある。それらを行う場合には、ワイヤー上でメッセージをリッスン(listen)するために使用するシステムリソース(プロセス、タイマー等)はjsonrpc-shutdown
で解放する必要がある(それらのリソースはjsonrpc-running-p
が非nil
の間だけ必要なはずなので)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
jsonrpc
ライブラリーには利便性のために、ローカルサブプロセス(標準入力と標準出力を使用)やTCPホスト(ソケットを使用)、またはEmacsのプロセスオブジェクトが表現可能な他のリモートのエンドポイント(プロセスを参照)と対話可能なビルトインのjsonrpc-process-connection
トランスポート実装が付属しています。
このトランスポートを使用することによりJSONRPCメッセージはワイヤー上にプレーンテキストとしてエンコードされて、“Content-Length”のように何らかの基本的なHTTPスタイルのエンベロープヘッダーが前置されます。
このJSONRPC最上層のトランスポートスキームを使用したアプリケーションの例は、Language Server Protocolを参照してください。
:request-dispatcher
と:notification-dispatcher
という必須の初期化引数(initarg)に加えて、jsonrpc-process-connection
クラスのユーザーはmake-instance
へのキーワード/値ペアとして以下の初期化引数を渡す必要があります:
:process
値は生きたプロセスオブジェクト、またはそのようなオブジェクトを生成する引数のない関数でなければならない。プロセスオブジェクトを渡された場合には、そのオブジェクトには事前に確立された接続が含まれていることが期待される。それ以外の場合には、オブジェクトの作成直後に関数が呼び出される。
:on-shutdown
値はjsonrpc-process-connection
オブジェクトを単一の引数とする関数でなければならない。この関数は背後にあるプロセスオブジェクトの削除(jsonrpc-shutdown
による故意の削除、または何らかの外部要因による予期せぬ削除)の後に呼び出される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
JSONRPCのJSONとLispのplist(プロパティリストを参照)は交換することができます。JSON互換のplistをディスパッチャ関数に渡したり、同様にJSON互換のplistをjsonrpc-notify
、jsonrpc-request
、jsonrpc-async-request
に渡すことができます。
plist処理を容易にするために、このライブラリーはcl-lib
ライブラリー(cl-lib in Common
Lisp Extensions for GNU Emacs
Lispを参照)の積極的に使用しており、そのクライアントにたいしてもこれを同じように提案します(強制ではない)。以下の例のようにJSONオブジェクトの非構造化用lambdaの作成にはマクロjsonrpc-lambda
を使用できます:
(jsonrpc-async-request myproc :frobnicate `(:foo "trix") :success-fn (jsonrpc-lambda (&key bar baz &allow-other-keys) (message "Server replied back with %s and %s!" bar baz)) :error-fn (jsonrpc-lambda (&key code message _data) (message "Sadly, server reports %s: %s" code message)))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
多くのRPC状況下において、対話中の2つのエンドポイント間での同期は、RPCアプリケーションを正しくデザインするために問題となります。同期が必要な際にはリクエスト(ブロックする)、不必要なら通知で十分です。しかしこれらのエンドポイントのいずれかでEmacsが動作している際にはリモートエンドポイントの状態に不確実性が依然として残っているので、(タイマーやプロセスに関連する)非同期イベントがトリガーされる可能性があります。さらにこれらのイベントへの対応では、イベント固有の性質により、同期の要求が限定されるかもしれません。
jsonrpc-request
やjsonrpc-async-request
にたいするキーワード引数:deferred
は特定のリクエストに同期が必要なことを呼び出し側が示せるようにして、リクエストの実際の発行は何らかの条件が満足されるまで遅延できるようにデザインされています。あるリクエストへの:deferred
指定はリクエストが遅延されるのではなく、遅延される可能性があることを意味します。リクエストが即座に送信されなければ、エンドポイントにたいして他のメッセージの受信や送信を行う際のように、通信中の特定タイミングでjsonrpc
はリクエストを送る新たな試みを行います。
リクエストを送信するすべての試みの前にアプリケーション固有の条件がチェックされます。jsonrpc
ライブラリーがこれらの条件を知ることはできないので、それらを指定するためにプログラムはジェネリック関数jsonrpc-connection-ready-p
を使用できます(ジェネリック関数を参照)。この関数のデフォルトメソッドはt
をリターンしますが、これをオーバーライドして渡された引数(
jsonrpc-connection
オブジェクト。概観を参照)とキーワード引数:deferred
として渡されたすべて値にもとづいてnil
をリターンするメソッドを追加できます。
[ << ] | [ < ] | [ 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する。
undo-amalgamate-change-group
を使用すれば、いくつか、あるいはすべての変更をundo
コマンド(アンドゥを参照)の対象として単一の単位とみなせる変更グループにすることができます。
handleにより識別される状態以降にお子なわれた変更グループへの変更をすべてまとめる。この関数はhandleにより記述された状態以降の変更にたいするアンドゥレコード間のアンドゥ境界すべてを削除する。handleは通常はprepare-change-group
がリターンしたハンドルであり、この場合には変更先頭以降のすべての変更は、単一のアンドゥ単位にまとめられる。
グループが常に確実に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-functions
とafter-change-functions
を1回呼び出し、これらのフックにたいする引数は行われた変更を正確に区切ります。しかしフック関数は常にこのように行われると信頼すべきではありません。なぜなら複雑なプリミティブのいくつかは変更を行う前にbefore-change-functions
を呼び出してから、プリミティブが行なった個別の変更の数にもとづいてafter-change-functions
を0回以上呼び出すからです。これが発生した場合には、before-change-functions
の引数は個別の変更が行われたリージョンを囲むでしょうが、そのようなリージョンが最小である必要はなく、連続したafter-change-functions
呼び出しそれぞれにたいする引数は変更されたテキスト部分を正確に区切るでしょう。一般的には、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
の値を変更してはならない。
警告: 組み合わされた変更がバッファーの広い範囲に点在してに出現する場合でも、これは依然として機能するが推奨できない。なぜならこれは、ある変更フック関数を非効率的な挙動へと導くかもしれないからである。
これは通常のようにbodyを実行するが、before-change-functions
およびafter-change-functions
の呼び出しをトリガーしないすべてのバッファー変更を除く。かわりにbegとendで囲まれるリージョンにたいしてこれらのフックそれぞれを1回呼び出し、bodyが変更するサイズを反映したパラメーターをafter-change-functions
に与える。
このマクロの結果はbodyのリターンした結果。
このマクロはある関数がバッファーにたいして繰り返し多数の変更を行う可能性があり、このマクロ以外では個別のバッファー変更ごとにそれらの変更フックを実行するために実行に長時間を要する際に有用。Emacs自身は、たとえばコマンドcomment-region
やuncomment-region
の中でこのマクロを使用している。
警告:
body内でbefore-change-functions
やafter-change-function
の値を変更してはならない。
警告: begとendで指定したリージョン外部でのバッファー変更は何も行ってはならない。
この変数は以前は未変更の状態だったバッファーが変更された際は常に実行されるノーマルフック。
この変数が非nil
ならすべての変更フックは無効。それらは何も実行されない。これはこのセクションで説明したすべてのフック変数、同様に特定のスペシャルテキストプロパティ(特殊な意味をもつプロパティを参照)とオーバーレイプロパティ(オーバーレイのプロパティを参照)にアタッチされたフックに影響を与える。
これらの同一フック変数上の関数の実行の間、バッファー変更によるデフォルトの変更フックが他の変更フック実行中に実行されないように、この変数は非nil
にバインドされる。それ自体が変更フックから実行される特定のコード断片内で変更フックを実行したければ、inhibit-modification-hooks
をnil
にローカルに再バインドすること。しかしこれを行うことで変更フックが再帰的に呼び出されるかもしれないのでそれに備えること(たとえばフックが何も行わないようにいくつかの変数をバインドする)。
バッファーのテキストコンテンツに永続的な変更をもたらさない変更(たとえばフェイス変更や一時的な変更)だけにこの変数をバインドすることを推奨する。一連の変更の間は変更フックを遅延させる必要がある(通常は性能上な理由による)なら、かわりにcombine-change-calls
やcombine-after-change-calls
を使用すること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このチャプターは文字に関する特別な問題と、それらが文字列やバッファーに格納される方法について網羅しています。
34.1 テキストの表現方法 | Emacsがテキストを表す方法。 | |
34.2 マルチバイト文字の無効化 | マルチバイト使用を制御する。 | |
34.3 テキスト表現の変換 | ユニバイトとマルチバイトの相互変換。 | |
34.4 表現の選択 | バイトシーケンスをユニバイトやマルチバイトとして扱う。 | |
34.5 文字コード | ユニバイトやマルチバイトが個々の文字のコードと関わる方法。 | |
34.6 文字のプロパティ | 文字の挙動と処理を定義する文字属性。 | |
34.7 文字セット | 利用可能な文字コード空間はさまざまな文字セットに分割される。 | |
34.8 文字セットのスキャン | バッファーで使用されている文字セットは? | |
34.9 文字の変換 | 変換に使用される変換テーブル。 | |
34.10 コーディングシステム | コーディングシステムはファイル保存のための変換である。 | |
34.11 入力メソッド | 入力メソッドによりユーザーは特別なキーボードなしで非ASCII文字を入力できる。 | |
34.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ビットのバイトシーケンスとして格納するものです24。たとえばすべての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文字とeight-bit
文字セットの文字を、それらに応じたバイト値に変換する。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
この関数はEmacsにおいて有効な文字コードポイントとしてもつことができる最大値をリターンする。オプション引数unicodeが非nil
の場合には、Unicode標準(Unicode
Standard)によって定義される文字コードポイントの最大値をリターンする。
(characterp (max-char)) ⇒ t
(characterp (1+ (max-char))) ⇒ nil
この関数はUnicode名がstringであるような文字をリターンする。ignore-caseが非nil
ならstringのcase(大文字小文字)は無視する。stringが文字の名前でなければ、この関数はnil
をリターンする。
;; U+03A3 (= (char-from-name "GREEK CAPITAL LETTER SIGMA") #x03A3) ⇒ t
この関数はカレントバッファー内の文字位置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)であるかもしれないリスト25。分割シーケンス(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
であり、これはその文字自身を意味する。
special-uppercase
Unicodeの言語やコンテキストに依存しない特別な大文字caseルールに対応する。このプロパティの値は文字列(空も可)。たとえばU+00DF
LATIN SMALL LETTER SHARP
Sにたいするマッピングは"SS"
。特別なマッピングのない文字にたいする値はnil
(かわりにuppercase
プロパティの照会が必要なことを意味する)。
special-lowercase
Unicodeの言語やコンテキストに依存しない特別な小文字caseルールに対応する。このプロパティの値は文字列(空も可)。たとえばU+0130
LATIN CAPITAL LETTER I WITH DOT ABOVEにたいするマッピングは\"i\\u0307\"
(すなわちLATIN SMALL LETTER Iの後にU+0307 COMBINING DOT
ABOVEが続くことによって構成される2文字の文字列)。特別なマッピングのない文字にたいする値はnil
(かわりにlowercase
プロパティの照会が必要なことを意味する)。
special-titlecase
Unicodeの無条件の特別なタイトルcaseルールに対応する。このプロパティの値は文字列(空も可)。たとえばU+FB01 LATIN
SMALL LIGATURE FIにたいするマッピングは"Fi"
。特別なマッピングのない文字にたいする値はnil
(かわりにtitlecase
プロパティの照会が必要なことを意味する)。
この関数はcharのプロパティpropnameの値をリターンする。
(get-char-code-property ?\s 'general-category) ⇒ Zs
(get-char-code-property ?1 'general-category) ⇒ Nd
;; U+2084 (get-char-code-property ?\N{SUBSCRIPT FOUR} 'digit-value) ⇒ 4
;; U+2155 (get-char-code-property ?\N{VULGAR FRACTION ONE FIFTH} 'numeric-value) ⇒ 0.2
;; U+2163 (get-char-code-property ?\N{ROMAN NUMERAL FOUR} '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つもち、値はすべてのスクリプトシンボルのリスト。Emacsの文字からスクリプトへのクラス分けはUnicode標準と1対1で対応しないことに注意(たとえばUnicodeには‘symbol’スクリプトはない)。
この変数の値は、それぞれの文字がスクリーン上で占めるであろう幅を列単位で指定する文字テーブル。
この変数の値は、それぞれの文字にたいしてそれがプリント可能かどうかを指定する文字テーブル。すなわち(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のfixnum (most-positive-fixnumを参照)に収まらなければ、コンスセル(high
.
low)
として指定できる。ここでlowは値の下位16ビット、highは高位16ビット。この使用方法は時代遅れである。
この関数はcharset内で文字charに割り当てられたコードポイントをリターンする。charsetがcharにたいするコードポイントをもたなければ値はnil
。
以下の関数は文字セット内の文字の一部、またはすべてにたいして特定の関数を適用するのに有用です。
charset内の文字にたいしてfunctionを呼び出す。functionは2つの引数で呼び出される。1つ目はコンスセル(from
.
to)
であり、fromとtoはcharset内に含まれる文字の範囲。argは2つ目の引数としてfunctionに渡される。argが省略された際にはnil
が渡される。
デフォルトではfunctionに渡されるコードポイントの範囲にはcharset内のすべての文字が含まれるが、オプションの引数from-codeおよびto-codeは、charsetのこれら2つのコードポイント間の文字に範囲をする。これらのいずれかがnil
の場合のデフォルトは、それぞれcharsetの最初または最後のコードポイント。from-codeとto-codeはcharsetのコードポイントであって、Emacsの文字のコードではないことに注意。
対照的に、functionに渡されるコンスセルにおけるfrom-codeとto-codeの値は、Emacsの文字コードである。
これらのEmacs文字コードはUnicodeコードポイント、あるいはUnicode文字の範囲0..#x10FFFF
を超えて拡張されたEmacs内部コードポイントのいずれか(テキストの表現方法を参照)。後者はUnicodeに未統合の文字を指定する文字セットにたいするコードポイント用の過去のCJK文字セットであり滅多に使用されない。
[ << ] | [ < ] | [ 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)の指定にしたがって文字コード変換や行末変換を行います。
コーディングシステムの定義は難解な問題であり、ここには記述しません。
34.10.1 コーディングシステムの基本概念 | 基本的な概念。 | |
34.10.2 エンコーディングとI/O | ファイル入出力関数がコーディングシステムを扱う方法。 | |
34.10.3 Lispでのコーディングシステム | コーディングシステム名を処理する関数。 | |
34.10.4 ユーザーが選択したコーディングシステム | ユーザーにコーディングシステムの選択を求める。 | |
34.10.5 デフォルトのコーディングシステム | デフォルトの選択の制御。 | |
34.10.6 単一の操作にたいするコーディングシステムの指定 | 単一ファイル処理にたいして特定のコーディングシステムを要求する。 | |
34.10.7 明示的なエンコードとデコード | 入出力を伴わないテキストのエンコードおよびデコード。 | |
34.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
というコーディングシステムは特別です。これはファイル(や文字列)にたいしてデコードやエンコードを行う際に、そのファイル(や文字列)のデータにもとづいて発見的に選択が行われるように、選択を未指定のままにします。コーディングシステムprefer-utf-8
はundecided
と似ていますが、可能ならutf-8
を優先的に選択します。
一般的にコーディングシステムは可逆的な同一性を保証しません。あるコーディングシステムを使用してバイトシーケンスをデコードしてから、同じコーディングシステムで結果テキストをエンコードしても、異なるバイトシーケンスが生成される可能性があります。しかしデコードされたオリジナルのバイトシーケンスとなることを保証するコーディングシステムもいくつかあります。以下にいくつかの例を挙げます:
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文字だけが使用されます(これはクラシックなMac OSで使用されていた慣例)。
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-unix
にたいするエイリアスです(そのため3種類すべての行末変換をデコードする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
はバッファーコンテンツのエンコードにコーディングシステムを使用します。
使用するコーディングシステムは明示的(単一の操作にたいするコーディングシステムの指定を参照)、またはデフォルトメカニズム(デフォルトのコーディングシステムを参照)を使用により暗黙的に指定できます。しかしこれらの手法は何を行うかを完全には指定しないかもしれません。たとえば、これらはデータから文字コード変換を行わないundecided
のようなコーディングシステムを選択するかもしれません。このような場合、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
なら、そのような暗黙の選択は常に許容される。非nil
なら関数であること。select-safe-coding-system
は選択するコーディングシステムのベースとなるコーディングシステムを単一の引数としてその関数を呼び出す。関数が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
はそのコーディングシステムを選択する前にユーザーに問い合わせる。
この変数は出力処理がテキストを安全にエンコードできないときに、テキストをエンコードするための正しいコーディングシステムの選択をユーザーに求めるために呼び出される関数。この変数のデフォルト値はselect-safe-coding-system
。write-region
のようにテキストをファイルに書き込んだり、process-send-region
のように別プロセスにテキストを送信するEmacsプリミティブは、coding-system-for-write
がnil
にバインドされていれば、通常はこの変数の値を呼び出す(単一の操作にたいするコーディングシステムの指定を参照)。
以下の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はサブプロセスへの出力に適用される。
この変数はファイルのデコードされていないコンテンツにもとづいて、ファイルにたいするコーディングシステムの判断を試みる関数のリストを保持する。
このリスト内の各関数はカレントバッファー内のテキストを調べるように、ただしいかなる方法にせよそれを変更しないよう記述されるべきである。そのバッファーはファイルの一部であるデコードされていないUnicodeテキストを含むだろう。各関数はポイントを始点に何文字を調べる可を告げる唯一の引数sizeをとること。そのファイルにたいするコーディングシステムの決定に関数が成功したら、そのコーディングシステムをリターンすること。それ以外はnil
をリターンするべきである。
このリスト内の関数はファイルがvisitされる際にEmacsがファイルのコンテンツのデコードをしようとする場合、および/またはそのファイルのバッファーを保存しようとする際にEmacsがファイルのコンテンツのエンコード方法を決定しようと場合に呼び出されるかもしれない。
ファイルに‘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
と同じように機能するが、入力ではなく出力に適用される点が異なる。これはファイルへの書き込み、同様にサブプロセスやネットワークストリームへの出力の送信にも適用される。これはEmacsがサブプロセスを呼び出す際のコマンドライン引数のエンコーディングにも適用される。
単一の操作がcall-process-region
やstart-process
のように入力と出力の両方を行う際には、coding-system-for-read
とcoding-system-for-write
の両方がそれに影響する。
coding-system-for-write
に非nil
値をバインドすることにより、select-safe-coding-system-function
が指定する関数の呼び出しによる出力プリミティブを抑制する(ユーザーが選択したコーディングシステムを参照)。これはC-x RET c
(universal-coding-system-argument
)がcoding-system-for-write
をバインドすることにより機能して、かつEmacsはユーザーの選択にしたがう必要があるからである。Lispプログラムが書き込むテキストのエンコーディングに安全ではないかもしれない値をcoding-system-for-write
にバインドする場合には、coding-system-require-warning
にも非nil
値をバインドできる。これはたとえcoding-system-for-write
が非nil
でもselect-safe-coding-system-function
の値の呼び出しによる出力プリミティブにエンコードのチェックを強制する。または指定されたエンコーディングを使用する前に、明示的にselect-safe-coding-system
を呼び出すこと。
この変数が非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がundecided
ならコマンドはテキスト内に見出されたバイトシーケンスにもとづいてテキストのエンコーディングを検出するとともに、そのテキストが使用している行末変換のタイプ(eol
typeを参照)も検出する。coding-systemがundecided-eol-type
(eol-typeはunix
、dos
、mac
のいずれか)なら、コマンドが検出するのはテキストのエンコーディングのみ。utf-8
のようにeol-typeを指定しないすべてのcoding-systemにたいして、このコマンドは行末変換を検出する。そのテキストが使用している行末変換が事前に判っている場合には、余計な自動検出を防ぐために、utf-8-unix
のようにエンコーディングを完全に指定すること。
この関数はcoding-systemでstring内のテキストをデコードする。これはデコードされたテキストを含む新たな文字列をリターンするが、nocopyが非nil
の場合には、それが些細なデコード処理ならstring自体をリターンするかもしれない。明示的なデコードを使いやすくするために、stringのコンテンツはバイトシーケンス値をもつユニバイト文字列であるべきだが、マルチバイト文字列も許すようになっている(マルチバイト形式で8ビットバイトを含むと仮定する)。
この関数は必要ならdecode-coding-region
が行うようにエンコーディングを検出する。
オプション引数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
ならそれはカレントで選択されたフレームの端末を意味する。複数の端末を参照のこと。EmacsはMS-Windowsシステムではキーボード入力のデコード時は常にUnicodeを使用するので、このコマンドでエンコーディングをセットしてもWindowsでは効果がないことに注意。
この関数は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)
という2つの整数のリストで、デフォルト用紙サイズをmm単位でリターンする(localeアイテム_NL_PAPER_WIDTH
と_NL_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)を調べることができます。
35.1 文字列の検索 | 正確なマッチの検索。 | |
35.2 検索と大文字小文字 | case-independentまたはcase-significantな検索。 | |
35.3 正規表現 | 文字列クラスの記述。 | |
35.4 正規表現の検索 | regexpにたいするマッチの検索。 | |
35.5 POSIX正規表現の検索 | 最長マッチにたいするPOSIXスタイルのマッチ。 | |
35.6 マッチデータ | 文字列またはregexp検索後にテキストがマッチした部分を見つける。 | |
35.7 検索と置換 | 検索と置換を繰り返すコマンド。 | |
35.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とは無関係にエラーとなる。
countが正の数nなら、それは繰り返し回数の役目をもつ。検索はn回繰り返され、前回のマッチの終端から毎回検索が開始される。これらの連続する検索が成功した場合、関数は成功となりポイントを移動して新たな値をリターンする。それ以外は検索失敗となり、上述したように結果はnoerrorの値に依存する。countが負の数 -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を簡単に検証することが可能になります。
Emacsの検索はデフォルトではcase(大文字小文字)を区別しないことに注意してください(検索と大文字小文字を参照)。caseを区別したregexpの検索とマッチを有効にするには、区別したいコードの前後でcase-fold-search
にnil
をバインドしてください。
35.3.1 正規表現の構文 | 正規表現の記述ルール。 | |
35.3.2 正規表現の複雑な例 | 正規表現構文の説明。 | |
35.3.3 rx 構造化Rgexp表記 | 構造化regexpによる代替表記。 | |
35.3.4 正規表現の関数 | 正規表現を操作する関数。 | |
35.3.5 正規表現にまつわるトラブル | いくつかの問題点とその回避策。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
正規表現は少数の文字が特別な構成要素であり、残りは通常の文字であるような構文をもちます。通常の文字はその文字自身だけにマッチするシンプルな正規表現です。特別な文字は‘.’、‘*’、‘+’、‘?’、‘[’、‘^’、‘$’、および‘\’です。将来に新たなスペシャル文字が定義されることはないでしょう。文字候補で終わる場合には‘]’はスペシャル文字です。文字候補の間では‘-’はスペシャル文字です。‘[:’と対応する‘:]’は文字候補内の文字クラスです。正規表現内に出現する他の文字は‘\’が前置されていない限り通常の文字です。
たとえば‘f’はスペシャル文字ではなく通常文字なので、‘f’は文字列‘f’にマッチして他の文字にはマッチしない正規表現です(これは文字列‘fg’にはマッチしないが、その文字列の部分にマッチする)。同様に‘o’は‘o’だけにマッチします。
任意の2つの正規表現aとbを結合することができます。結合した結果は文字列の先頭からある長さの文字列がaにマッチして、残りの文字列がbにマッチするような文字列にマッチする正規表現になります。
単純な例として文字列‘fo’だけにマッチする正規表現の構成要素‘fo’を取得するために正規表現‘f’と‘o’を結合できます。
35.3.1.1 正規表現内の特殊文字 | 正規表現内のスペシャル文字。 | |
35.3.1.2 文字クラス | 正規表現内で使用される文字クラス。 | |
35.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のマッチは成功する。
これは‘*’のような後置演算子だが前置された表現に少なくとも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小文字アルファベットと‘$’、‘%’、またはピリオドとマッチする。しかし1つの範囲の終端文字が別の範囲の開始文字ではないこと。たとえば‘[a-m-z]’は使用しないこと。
文字候補には名前付き文字クラスも指定できる(文字クラスを参照)。たとえば‘[[:ascii:]]’は任意のASCII文字にマッチする。文字クラスの使用は、そのクラス内すべての文字を記述するのと等しい。しかし異なる文字数千を含むクラスもあるので後者は実際は実現不可能。文字クラス範囲の上側や下側の境界に出現するべきではない。
文字候補の内部では、通常のregexpスペシャル文字ではスペシャルではない。完全に異なる文字セット‘]’、‘-’、‘^’がスペシャルになる。文字候補に‘]’を含めるには、それを先頭に配置する。‘^’を含めるには、それを先頭以外の場所に配置する。‘-’を含めるには、それを最後に配置する。したがって‘[]^-]’は、これら3つのスペシャル文字すべてにマッチする。ここでは‘\’はスペシャルではないので、これら3つの文字のエスケープに‘\’は使用できない。
以下の範囲にたいする側面はEmacs固有であり、POSIXはこの振る舞いを許容はするが必須ではなく、Emacs以外のプログラムは異なる振る舞いをするかもしれない。
case-fold-search
が非nil
なら‘[a-z]’は大文字にもマッチする。
ある種の文字候補は、たとえそれらがEmacs内において明確に定義された意味をもっているとしても最良のスタイルとならない。これらには以下が含まれる:
‘[^’は補完文字候補(complemented character alternative)を開始する。これは指定された以外の任意の文字とマッチする。つまり‘[^a-z0-9A-Z]’はASCII文字と数字以外の、すべての文字にマッチする。
‘^’は文字クラス内では先頭に記述されない限り特別ではない。‘^’に続く文字は、あたかもそれが先頭にあるかのように扱われる(言い換えると‘-’や‘]’はここでは特別ではない)。
マッチしない文字の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] | [ ? ] |
以下は文字候補内で使用できるクラスと意味のテーブルです。クラス名を囲む‘[’と‘]’の文字は名前の一部なので、これらのクラスを使用する正規表現では1つ余分にカッコ(brackets)が必要になります。たとえば1つ以上のアルファベットか数字のシーケンスにマッチする正規表現は、‘[:alnum:]+’ではなく‘[[:alnum:]]+’です。
これは任意のASCII文字(コード0 – 127)にマッチする。
これは任意の英数字にマッチする。マルチバイト文字では、アルファベット文字か数字であることを示すUnicodeプロパティ‘general-category’ (文字のプロパティを参照)をもつ文字にマッチする。
これは任意のアルファベットにマッチする。マルチバイト文字では、アルファベット文字であることを示すUnicodeプロパティ‘general-category’ (文字のプロパティを参照)をもつ文字にマッチする。
これは Unicode Technical Standard #18のAnnex Cで定義される水平の空白文字(horizontal whitespace)にマッチする。特にスペース、タブ、およびスペース区切りであることをUnicodeの‘general-category’プロパティ(文字のプロパティを参照)が示す他の文字にマッチする。
これはコードが1から31の範囲にあるすべての文字にマッチする。
これは‘0’から‘9’までにマッチする。つまり‘[-+[:digit:]]’は‘+’と‘-’、同様に任意の数にマッチする。
これはUnicodeの‘general-category’プロパティで示されるようなグラフィック文字(スペース文字、ASCIIと非ASCIIの制御文字、サロゲートコードポイント、Unicodeで未割り当てのコードポイントを除くすべて)にマッチする(文字のプロパティを参照)。
これはカレントのcaseテーブル(caseテーブルを参照)で小文字と判断される文字すべてにマッチする。case-fold-search
が非nil
なら大文字にもマッチする。バッファーはデフォルトとは異なるローカルのcaseテーブルを独自にもてることに注意。
これは任意のマルチバイト文字にマッチする(テキストの表現方法を参照)。
これは非ASCII文字にマッチする。
これは任意のプリント文字(スペース文字か‘[:graph:]’でマッチされるグラフィック文字のいずれか)にマッチする。
これは任意の句読点文字(punctuation character)にマッチする(現在のところマルチバイト文字では単語構文以外のすべてにマッチするが、文字の構文はメジャーモード次第なのでメジャーモードごとに正確な定義は様々である)。
空白文字の構文(構文クラスのテーブルを参照)をもつ任意の文字にマッチする。文字の構文、すなわち何の文字を“空白”とみなすかはメジャーモード次第だということに注意。
これは任意のユニバイト文字(テキストの表現方法を参照)にマッチする。
これはカレントのcaseテーブル(caseテーブルを参照)で大文字と判断される文字すべてにマッチする。case-fold-search
が非nil
ならこれは小文字にもマッチする。バッファーはデフォルトとは異なるローカルのcaseテーブルを独自にもてることに注意。
単語の構文(構文クラスのテーブルを参照)をもつ任意の文字にマッチする。文字の構文、すなわち何の文字を“単語の構成文字”とみなすかはメジャーモード次第だということに注意。
これは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省略時の最大は存在しない。いずれの形式でもmやnが指定された場合には、 2**16 - 1 より大きくなることはない。
たとえば‘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でないような任意の文字にマッチする。
これはカテゴリーがcodeであるような任意の文字にマッチする。ここでcodeはカテゴリーを表す文字。たとえば標準カテゴリーテーブルでは‘c’はChinese(中国語)、‘g’はGreek(ギリシャ語)の文字を表す。M-x describe-categories RETで現在定義済みの全カテゴリーのリストを確認できる。define-category
関数を使用すれば、標準カテゴリーに加えて独自カテゴリーを定義することもできる(カテゴリーを参照)。
これはカテゴリーがcodeではない任意の文字にマッチする。
以下は空文字列にマッチします(つまり文字を何も消費しない)が、マッチするかどうかがコンテキストに依存するような正規表現を構築します。これらすべてにたいして、そのバッファーのアクセス可能範囲の先頭と終端は、あたかもそのバッファーの実際の先頭と終端のように扱われます。
これは空文字列、ただしバッファー先頭またはマッチ対象の文字列の先頭だけにマッチする。
これは空文字列、ただしバッファー終端またはマッチ対象の文字列の終端だけにマッチする。
これは空文字列、ただしポイント位置だけにマッチする(この構成要素はマッチ対象が文字列なら定義されない)。
これは空文字列、ただし単語の先頭だけにマッチする。つまり‘\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]*
最後にパターンの最終パートはセンテンスを終端させるために必要とされる以上の、余分な空白文字にマッチする。
rx
(rx
構造化Rgexp表記を参照)表記では以下のようにregexpを記述できます
(rx (any ".?!") ; センテンスを終端する区切り文字 (zero-or-more (any "\"')]}")) ; 終わりのクォートやカッコ (or line-end (seq " " line-end) "\t" " ") ; 2つのスペース (zero-or-more (any "\t\n "))) ; オプションの余分な空白文字
rx
によるregexpsは単なるS式なので、このように整形してコメントを付することができるのです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
rx
構造化Rgexp表記文字ベースの構文にたいする代替えとして、EmacsはLispのS式にもとづく構造化されたrx
表記を提供します。この表記により通常はregexp文字列をより簡単に読解、記述、保守することができ、自由にインデントしてコメントを記述できます。regexp関数が期待するのは文字列形式なので変換が必要になりますが、この変換はregexpを使用するLispコードの実行時ではなく、通常はバイトコンパイルの間に行われます。
以下はCプログラム言語のブロックコメントにマッチするrx
のregexpです26。
(rx "/*" ; 始まりの/* (zero-or-more (or (not (any "*")) ; 非* (seq "*" ; または (not (any "/"))))) ; /が後置されていない* (one-or-more "*") ; 少なくとも1つの* "/") ; と終わりの/
短いシノニムを使用してより簡潔に記述すると、
(rx "/*" (* (| (not "*") (: "*" (not "/")))) (+ "*") "/")
従来の文字列構文では以下のような記述になります
"/\\*\\(?:[^*]\\|\\*[^/]\\)*\\*+/"
rx
表記は主にLispコード内で有用です。query-replace-regexp
の実行時や変数のカスタマイゼーションのように、regexpが要求されるインタラクティブな状況下では使用することができません。
35.3.3.1 rx によるregexpの構築 | rxフォームで有効な構成。 | |
35.3.3.2 rx のregexpを使用する関数とマクロ | rxフォームを使用する関数とマクロ。 | |
35.3.3.3 新たなrx フォームの定義 | 独自のrxフォームを定義する方法。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
rx
によるregexpの構築rx
のregexpsにおける種々のフォームを以下で説明します。省略形式として使用するrxは任意のrxフォームを表します。rx…は0個以上のrxフォームを表し、特に明記しないかぎりこれらのフォームは(seq
…)
というサブフォームで括られているかのように順にマッチします。
以下はすべてrx
マクロにたいする有効な引数です。これらのフォームはすべて記述のされ方によって定義されます。それぞれに記述されている文字列regexpは、単に理解を容易にするために提供されています。(適切なカッコで括られた)A、B、…は、それらの部分式における文字列regexpを意味します。
"some-string"
文字列‘some-string’にリテラル(文字通り)にマッチする。文字列regexpsとは異なり特別な意味をもつ文字はない。
?C
文字‘C’にリテラルにマッチする。
(seq rx…)
¶(sequence rx…)
(: rx…)
(and rx…)
順にrxをマッチする。引数なしなら、その式は空文字列にマッチする。
対応する文字列regexpは‘AB…’
(シーケンス内の部分式)。
(or rx…)
¶(| rx…)
rxのうちのいずれか1つに正確にマッチする。すべての引数が文字列か文字、またはそのようなor
フォームなら、可能な最長マッチを常に使用する。それ以外なら最長のマッチ、または(L2R順で)最初のマッチのいずれかを使用する。引数なしなら、その式は何にもマッチすることはない。
対応する文字列regexpは‘A\|B\|…’。
unmatchable
¶すべてのマッチを拒絶する。(or)
と等価。regexp-unmatchableを参照のこと。
繰り返しフォームは通常は可能なかぎり多数回のマッチを試みるので欲張り(greedy)です。いくつかのフォームは可能なかぎり少数回のマッチを試みるので非欲張り(non-greedy)です(Non-greedy repetitionを参照)。
(zero-or-more rx…)
¶(0+ rx…)
rxに0回以上マッチする。デフォルトでは欲張り。
対応する文字列regexpは‘A*’
(欲張り)、‘A*?’ (非欲張り)。
(one-or-more rx…)
¶(1+ rx…)
rxに1回以上マッチする。デフォルトでは欲張り。
対応する文字列regexpは‘A+’
(欲張り)、‘A+?’ (非欲張り)。
(zero-or-one rx…)
¶(optional rx…)
(opt rx…)
rxに1回、または空文字列にマッチする。デフォルトでは欲張り。
対応する文字列regexpは‘A?’
(欲張り)、‘A??’ (非欲張り)。
(* rx…)
¶rxに0回以上マッチする。欲張り。
対応する文字列regexpは‘A*’。
(+ rx…)
¶rxに1回以上マッチする。欲張り。
対応する文字列regexpは‘A+’。
(? rx…)
¶rxに1回、または空文字列にマッチする。欲張り。
対応する文字列regexpは‘A?’。
(*? rx…)
¶rxに0回以上マッチする。非欲張り。
対応する文字列regexpは‘A*?’。
(+? rx…)
¶rxに1回以上マッチする。非欲張り。
対応する文字列regexpは‘A+?’。
(?? rx…)
¶rx、または空文字列にマッチする。非欲張り。
対応する文字列regexpは‘A??’。
(= n rx…)
(repeat n rx)
rxに正確にn回マッチする。
対応する文字列regexpは‘A\{n\}’。
(>= n rx…)
¶rxにn回以上マッチする。欲張り。
対応する文字列regexpは‘A\{n,\}’。
(** n m rx…)
¶(repeat n m rx…)
rxに少なくともn回、ただしm回を超えない回数マッチする。欲張り。
対応する文字列regexpは‘A\{n,m\}’。
いくつかの繰り返しフォームの欲張りの度合いは以下の構文を使用して制御できます。しかしそのようなマッチングが要求される際には、通常は上述した明示的な非欲張りフォームを使用するほうがよいでしょう。
(minimal-match rx)
¶非欲張りなマッチングを使用してzero-or-more
、0+
、one-or-more
、1+
、zero-or-one
、opt
、optional
によりrxをマッチする。
(maximal-match rx)
¶欲張りなマッチングを使用してzero-or-more
、0+
、one-or-more
、1+
、zero-or-one
、opt
、optional
によりrxをマッチする。これがデフォルト。
(any set…)
¶(char set…)
(in set…)
setのいずれかより1文字をマッチする。setはそれぞれ文字、それ自身が文字セットを表す文字列、範囲、または文字クラス(以下参照)。範囲は"A-Z"
のようにハイフンで区切られた文字列、または(?A
. ?Z)
のようなコンスセル。
この構文における文字列内のハイフン(-
)は範囲区切りとして振る舞うのでスペシャル。ハイフンを含めるには区切り文字か単一文字の文字列として追加する。
対応する文字列regexpは‘[…]’。
(not charspec)
¶charspecに含まれない文字にマッチする。charspecは文字、単一文字の文字列、フォームany
、not
、or
、intersection
、syntax
、category
、または文字クラス。charspecがor
フォームなら、その引数にはintersection
の引数と同じ制限がある。以下参照。
対応する文字列regexpは‘[^…]’、‘\Scode’、‘\Ccode’。
(intersection charset…)
¶charsetに含まれるすべての文字にマッチする。charsetはそれぞれ文字、単一文字の文字列、文字クラスなしのany
フォーム、または引数がcharsetであるようなintersection
、or
、not
フォーム。
not-newline
、nonl
¶改行を除くすべての文字にマッチする。
対応する文字列regexpは‘.’ (ドット)。
anychar
、anything
¶すべての文字にマッチする。
対応する文字列regexpはたとえば‘.\|\n’。
以下の名前つき文字クラスの文字にマッチする:
alpha
、alphabetic
、letter
アルファベット文字にマッチする。より正確には、Unicodeの‘general-category’プロパティがアルファベット文字であることを示すような文字にマッチする。
alnum
、alphanumeric
アルファベット文字と数字にマッチする。より正確には、Unicodeの‘general-category’プロパティがアルファベット文字か10進数字であることを示すような文字にマッチする。
digit
、numeric
、num
‘0’から‘9’の数字にマッチする。
xdigit
、hex-digit
、hex
‘0’から‘9’、‘A’から‘F’および‘a’から‘f’の16進数字にマッチする。
cntrl
、control
コードが0から31の範囲の任意の文字にマッチする。
blank
水平空白文字(horizontal whitespace)にマッチする。より正確には、Unicodeの‘general-category’プロパティがスペース区切り文字(spacing separators)であることを示すような文字にマッチする。
space
、whitespace
、white
空白文字構文をもつすべての文字にマッチする(構文クラスのテーブルを参照)。
lower
、lower-case
カレントのcaseテーブルで小文字として判断されるすべての文字にマッチする。case-fold-search
が非nil
ならすべての大文字にもマッチする。
upper
、upper-case
カレントのcaseテーブルで大文字として判断されるすべての文字にマッチする。case-fold-search
が非nil
ならすべての小文字にもマッチする。
graph
、graphic
Unicodeの‘general-category’プロパティで示されるような空白文字、ASCIIと非ASCIIの制御文字、サロゲートコードポイント、Unicodeで未割り当てのコードポイントを除くすべての文字にマッチする。
print
、printing
空白文字かgraph
にマッチする文字にマッチする。
punct
、punctuation
任意の句読点文字(punctuation character)にマッチする(現在のところマルチバイト文字では非単語構文のすべてにマッチする)。
word
、wordchar
単語構文(構文クラスのテーブルを参照)をもつ任意の文字にマッチする。
ascii
任意のASCII文字(コード0から127)にマッチする。
nonascii
非ASCII文字(ただしrawバイト以外)にマッチする。
対応する文字列regexpは‘[[:class:]]’。
(syntax syntax)
¶以下の名前のいずれかの構文syntaxの文字にマッチする。
構文名 | 構文文字 |
---|---|
whitespace | - |
punctuation | . |
word | w |
symbol | _ |
open-parenthesis | ( |
close-parenthesis | ) |
expression-prefix | ' |
string-quote | " |
paired-delimiter | $ |
escape | \ |
character-quote | / |
comment-start | < |
comment-end | > |
string-delimiter | | |
comment-delimiter | ! |
詳細は構文クラスのテーブルを参照のこと。(syntax
punctuation)
は文字クラスpunctuation
と等価ではないことに注意してほしい。
対応する文字列regexpは‘\schar’
(charは構文文字)。
(category category)
¶以下のカテゴリー名かカテゴリー文字のいずれかであるようなカテゴリーcategoryの文字にマッチする.
カテゴリー名 | カテゴリー文字 |
---|---|
space-for-indent | スペース |
base | . |
consonant | 0 |
base-vowel | 1 |
upper-diacritical-mark | 2 |
lower-diacritical-mark | 3 |
tone-mark | 4 |
symbol | 5 |
digit | 6 |
vowel-modifying-diacritical-mark | 7 |
vowel-sign | 8 |
semivowel-lower | 9 |
not-at-end-of-line | < |
not-at-beginning-of-line | > |
alpha-numeric-two-byte | A |
chinese-two-byte | C |
greek-two-byte | G |
japanese-hiragana-two-byte | H |
indian-two-byte | I |
japanese-katakana-two-byte | K |
strong-left-to-right | L |
korean-hangul-two-byte | N |
strong-right-to-left | R |
cyrillic-two-byte | Y |
combining-diacritic | ^ |
ascii | a |
arabic | b |
chinese | c |
ethiopic | e |
greek | g |
korean | h |
indian | i |
japanese | j |
japanese-katakana | k |
latin | l |
lao | o |
tibetan | q |
japanese-roman | r |
thai | t |
vietnamese | v |
hebrew | w |
cyrillic | y |
can-break | | |
カレントで定義されているカテゴリーに関する情報は、コマンドM-x describe-categories
RETを実行する。新たなカテゴリーを定義する方法についてはカテゴリーを参照のこと。
対応する文字列regexpは‘\cchar’
(charはカテゴリー文字)。
これらはすべて空文字列、ただし特定箇所箇所だけにマッチします。
line-start
、bol
¶行の先頭にマッチする。
対応する文字列regexpは‘^’。
line-end
、eol
¶行の終端にマッチする。
対応する文字列regexpは‘$’。
string-start
、bos
、buffer-start
、bot
¶マッチする文字列かバッファーの先頭にマッチする。
対応する文字列regexpは‘\`’。
string-end
、eos
、buffer-end
、eot
¶マッチする文字列かバッファーの終端にマッチする。
対応する文字列regexpは‘\'’。
point
¶ポイントにマッチする。
対応する文字列regexpは‘\=’。
word-start
、bow
¶単語の先頭にマッチする。
対応する文字列regexpは‘\<’。
word-end
、eow
¶単語の終端にマッチする。
対応する文字列regexpは‘\>’。
word-boundary
¶単語の先頭か終端にマッチする。
対応する文字列regexpは‘\b’。
not-word-boundary
¶単語の先頭と終端以外のすべての箇所にマッチする。
対応する文字列regexpは‘\B’。
symbol-start
¶シンボルの先頭にマッチする。
対応する文字列regexpは‘\_<’。
symbol-end
¶シンボルの終端にマッチする。
対応する文字列regexpは‘\_>’。
(group rx…)
¶(submatch rx…)
マッチデータ内でマッチしたテキストと位置にアクセスできるようにrxをマッチする。regexpの1つ目のグループは番号1、それ以降のグループはパターン内でそれ以前に最大の番号が付与されたグループより1つ大きい番号が付与される。
対応する文字列regexpは‘\(…\)’。
(group-n n rx…)
¶(submatch-n n rx…)
group
と同様だがグループ番号nを明示的に割り当てる。nは正でなければならない。
対応する文字列regexpは‘\(?n:…\)’。
(backref n)
¶前にグループ番号nでマッチされたテキストにマッチする。nは1から9の範囲になければならない。
対応する文字列regexpは‘\n’。
(literal expr)
¶Lisp式exprを評価した結果であるリテラル文字列とマッチする。評価はカレントのレキシカル環境で呼び出し時に行われる。
(regexp expr)
¶(regex expr)
Lisp式exprを評価した結果であるregexpとマッチする。評価はカレントのレキシカル環境で呼び出し時に行われる。
(eval expr)
¶Lisp式exprを評価した結果であるrxとマッチする。評価はrx-to-string
呼び出しの際のマクロ展開時に、カレントのグローバル環境で行われる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
rx
のregexpを使用する関数とマクロrx-formがあたかも(seq
…)
フォームのbodyであるかのように文字列regexpに変換する。rx
マクロは文字列定数、またはliteral
かregexp
フォームが使用されていたら文字列に評価されるLisp式に展開される。たとえば:
(rx (+ alpha) "=" (+ digit)) ⇒ "[[:alpha:]]+=[[:digit:]]+"
rx-exprをリターンされる文字列regexpに変換する。no-groupが省略またはnil
の場合には、後に付加する後置演算子が式全体に適用されるために、必要なら結果を非キャプチャリンググループ‘\(?:…\)’としてカッコで括る。たとえば:
(rx-to-string '(seq (+ alpha) "=" (+ digit)) t) ⇒ "[[:alpha:]]+=[[:digit:]]+"
rx-expr内のフォームliteral
およびregexp
にたいする引数は、文字列リテラルでなければならない。
pcase
マクロはパターンとして直接rx
式を使用できます。rx in pcaseを参照してください。
rx
表記へのユーザー定義の拡張メカニズムについては、新たなrx
フォームの定義を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
rx
フォームの定義新たなシンボル他のrx
式にたいしてパラメーター化されたフォームを定義することにより、rx
表記を拡張できます。これにより手軽にパーツを複数のregexp間で共有して、より小さな断片を互いに組み合わせて、複雑なregexpをより簡単に構築、理解することができます。
たとえば(one-or-more letter)
を意味するname
や、任意のxにたいして(seq
?' x ?')
を意味する(quoted
x)
を定義できます。これらのフォームは他のrx
式と同様に使用できます。(rx (quoted
name))
はシングルクォート内の非空の文字シーケンスにマッチするでしょう。
以下のLispマクロは定義にたいして名前を構築する別の手段を提供します。以下のルールはこれらすべてにたいして共通です:
digit
やgroup
のようなビルトインのrx
フォームは再定義不可。
-regexp
のようなサフィックスを付加する必要はない。これらが他と衝突することはあり得ない。
rx
やrx-to-string
の呼び出し内でのみ展開される。これはたとえ定義が互いを参照している際でも定義の順序は問題ではなく、定義の構文エラーは定義時ではなく使用時のみ顕現することを意味する。
rx
式が期待される任意の箇所でユーザー定義フォームが許される。たとえばzero-or-one
フォームのbody内では許されるが、any
やcategory
のフォーム内では許されない。これらはnot
およびintersection
のフォーム内でも許される。
すべての後続するrx
およびrx-to-string
呼び出しにおいて、グローバルにnameを定義する。arglistを省略すると、nameはrx-formで置き換えられるプレーンシンボルとして定義される。たとえば:
(rx-define haskell-comment (seq "--" (zero-or-more nonl))) (rx haskell-comment) ⇒ "--.*"
arglistが与えられた場合には0個以上の引数名のリストでなければならず、その場合にはnameはパラメーター化されたフォームとして定義される。(name
arg…)
としてrx
式内で使用時には、argはそれぞれrx-form内部の対応する引数名に置き換えられる。
arglistは&rest
と残りのパラメーターを示す最後の引数名で終わる場合がある。残りのパラメーターはarglist内の他のパラメーターにマッチしないすべての追加引数の実際の値に展開されて、rx-formの出現箇所へとスプライスされる。たとえば:
(rx-define moan (x y &rest r) (seq x (one-or-more y) r "!")) (rx (moan "MOO" "A" "MEE" "OW")) ⇒ "MOOA+MEEOW!"
定義はグローバルなので、nameには非ローカルな変数や関数を通常命名する際のように、別の場所の定義名との競合を避けるためにパッケージプレフィックスを付与することを推奨する。
この方法で定義したフォームは単純なテンプレート置換だけを行う。計算を任意で行うにはrx
フォームのeval
、regexp
、literal
とともに使用すること。たとえば:
(defun n-tuple-rx (n element) `(seq "<" (group-n 1 ,element) ,@(mapcar (lambda (i) `(seq ?, (group-n ,i ,element))) (number-sequence 2 n)) ">")) (rx-define n-tuple (n element) (eval (n-tuple-rx n 'element))) (rx (n-tuple 3 (+ (in "0-9")))) ⇒ "<\\(?1:[0-9]+\\),\\(?2:[0-9]+\\),\\(?3:[0-9]+\\)>"
body内のrx
マクロ呼び出しでbindings内のrx
をローカルに使用可能にしてから評価する。
bindingsの各要素は(name [arglist] rx-form)
という形式をもち、各パーツは上述のrx-define
の場合と同じ意味をもつ。たとえば:
(rx-let ((comma-separated (item) (seq item (0+ "," item))) (number (1+ digit)) (numbers (comma-separated number))) (re-search-forward (rx "(" numbers ")")))
定義はbodyのマクロ展開の間だけ利用可能であり、したがってコンパイル済みコードの実行の間は存在しない。
rx-let
は関数内部だけではなく、rx
フォームの共通セットの共有を要するグローバルな変数および関数に含めるためにトップレベルでも使用できる。名前はbody内部でローカルなので、何のパッケージプレフィックスも必要としない。たとえば:
(rx-let ((phone-number (seq (opt ?+) (1+ (any digit ?-))))) (defun find-next-phone-number () (re-search-forward (rx phone-number))) (defun phone-number-p (string) (string-match-p (rx bos phone-number eos) string)))
rx-let
のスコープはレキシカルであり、これはたとえbodyから呼び出される関数であってみ、body自身の外部からは不可視であることを意味する。
rx-let
のようにbindingsをバインディングのリストに評価して、rx-to-string
呼び出しに有効なこれらバインディングによってbodyを評価する。
このマクロはrx-let
と同様だが、bindingsを評価して(したがってリストリテラルならクォート要)、定義が実行時(rx-to-string
が機能するために必要)に置換される点が異なる。たとえば:
(rx-let-eval '((ponder (x) (seq "Where have all the " x " gone?"))) (looking-at (rx-to-string '(ponder (or "flowers" "young girls" "left socks")))))
他にrx-let
と異なるのは、bindingsはダイナミックにスコープされるので、bodyから呼び出される関数内でも利用可能なことである。しかしbody内で定義される関数の内部では不可視。
[ << ] | [ < ] | [ 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-"))
スペシャル文字を何も含まなければ、リターンされる文字列はstring自身となるだろう。
この関数はリストstringsの文字列だけにマッチする効果的な正規表現をリターンする。これはマッチングや検索を可能な限り高速にする必要があるとき、たとえばFont Lockモードで有用である27。
stringsが空リストなら、リターン値は何にもマッチすることはないregexpとなる。
オプション引数parenには以下のいずれかを指定できる:
結果となるregexpの前にparen、後に‘\)’が付加される。たとえば‘"\\(?1:"’を使用すると番号付きのグループを明示的に生成する。
words
結果となるregexpは‘\<\(’と‘\)\>’で括られる。
symbols
結果となるregexpは‘\_<\(’と‘\)\_>’で括られる(これはプログラミング言語のキーワードの類のマッチング時にしばしば適している)。
nil
結果となるregexpは‘\(’と‘\)’で括られる。
nil
後に付加する後置演算子が式全体に適用されるために必要なら、結果となるregexpは‘\(?:’と‘\)’で括られる。
リターンされる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 parens) (mapconcat 'regexp-quote strings "\\|") (cdr parens))))
この関数はregexp内のグループ化された構成要素(カッコで囲まれた正規表現)の総数をリターンする。これには内気なグループは含まれない(正規表現内のバッククラッシュ構文を参照)。
この関数は文字リストchars内の文字にマッチする正規表現をリターンする。
(regexp-opt-charset '(?a ?b ?c ?d ?e)) ⇒ "[a-e]"
この変数はすべての文字列にマッチしないことが保証されたregexpを含む。これは実際に何かとマッチするようにセットされ得る変数用のデフォルト値として特に有用。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsのregexp実装は他の多くの類似する実装と同じように概ね堅牢ですが、2つの問題のいずれかを引き起こすことがあります。それはマッチングが内部スタックスペースを使い果たしてエラーをシグナルしたり、完了まで長時間を要するかもしれないという問題です。以下のアドバイスはこれらの症状を軽減して、発生する問題を緩和する助けとなるでしょう。
\`
)の使用による行、文字列、あるいはバッファー先頭のアンカーregexp。これは実装内部の高速パスを利用して、無駄なマッチングの試行を回避できる。これら以外のゼロ幅アサーションでも、早期にマッチを失敗させることによる利益が得られるかもしれない。
(これはトレードオフである。マッチに成功するorパターンは、もっとも頻繁にマッチするパターンを最初にすると実行が高速になる。)
ネストした繰り返しには特に注意。曖昧さが存在すると、それらのマッチングが非常に低速になるのは容易である。たとえば‘\(?:a*b*\)+c’は‘a’からなる適切な長さの文字列にたいするマッチ試行でも、失敗までに長時間を要するだろう。これと等価な‘\(?:a\|b\)*c’はより高速であり、‘[ab]*c’は更に良い。
rx
の使用を検討する(rx
構造化Rgexp表記を参照)。これはいくつかのorパターンを自動的に最適化するとともに、明示的に要求されなければキャプチャリンググループを決して導入しない。
上記アドバイスにしたがってなおregexpがスタックオーバーフローするようなら、ためらうことなくマッチングを複数の関数呼び出しで行い、それぞれの関数呼び出しではバックトラッキングが容易に含まれるように単純なregexpを使ってください。
[ << ] | [ < ] | [ 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とは無関係にエラーとなる。
countが正の数nなら、それは繰り返し回数の役目をもつ。検索はn回繰り返され、前回のマッチの終端から毎回検索が開始される。これらの連続する検索が成功した場合、関数は成功となりポイントを移動して新たな値をリターンする。それ以外は検索失敗となり、上述したように結果はnoerrorの値に依存する。countが負の数 -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)
で利用できる。マッチデータを参照のこと。inhibit-modifyが非nil
なら、マッチデータを変更しない。
(string-match "quick" "The quick brown fox jumped quickly." 8) ⇒ 27
(match-end 0) ⇒ 32
この述語関数はstring-match
と同じことを行うが、マッチデータの変更を避ける。
この関数はカレントバッファー内のポイント直後のテキストが正規表現regexpにマッチするかどうかを判断する。“直後”の正確な意味は、その検索が“固定”されていて、ポイントの後の最初の文字からマッチが開始する場合のみ成功するということ。成功なら結果はt
、それ以外はnil
。
この関数はポイントを移動しないが、inhibit-modifyがnil
か省略(デフォルト)ならマッチデータは更新する。マッチデータを参照のこと。利便性のために、inhibit-modify引数のかわりに、下記の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)と呼ばれます。このマッチデータのおかげで、メールメッセージ内のデータのような複雑なパターンを検索した後に、そのパターンの制御下でマッチ部分を抽出できるのです。
マッチデータには通常はもっとも最近の検索だけが記述されるので、後で参照したい検索とそのマッチデータの使用の間に誤って別の検索を行わないように注意しなければなりません。誤って別の検索を避けるのが不可能な場合には、マッチデータの上書きを防ぐために前後でマッチデータの保存とリストアを行わなければなりません。
上書きを行わないと明記されていない限り、すべての関数は上書きを許されていることに注意してください。結果としてバックグラウンド(遅延実行のためのタイマーとアイドルタイマーを参照)で暗黙に実行される関数は、おそらく明示的にマッチデータの保存とリストアを行うべきでしょう。
35.6.1 マッチしたテキストの置換 | マッチされた部分文字列の置換。 | |
35.6.2 単純なマッチデータへのアクセス | 特定の部分式開始箇所のようなマッチデータの単一アイテムへのアクセス。 | |
35.6.3 マッチデータ全体へのアクセス | リストとしてマッチデータ全体に一度にアクセスする。 | |
35.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を参照してください。
特定のリージョンに置換を限定すれば、より便利かもしれません。関数replace-regexp-in-region
はこれを行います。
この関数はバッファーのstartからendのテキストリージョンにあるすべてのregexpをreplacementに置換する。startのデフォルトはポイント位置、endのデフォルトはバッファーのアクセス可能範囲の終端。regexpにたいする検索はcase(大文字小文字)を区別し、replacementは文字のcaseを変更せずに挿入される。replacement文字列にはreplace-match
で使用するような、同じ‘\’で始まる特殊要素を使用できる。この関数は置換した個数、regexpが見つからなければnil
をリターンする。この関数はポイント位置を維持する。
(replace-regexp-in-region "foo[ \t]+bar" "foobar")
この関数はreplace-regexp-in-region
と同様に機能するが、正規表現のかわりにリテラルのstringの検索と置換を行う。
Emacsには文字列内でマッチを置換する特別な関数もあります。
この関数はstringをコピーしてregexpにたいするマッチを検索、それらをrepに置き換える。これは変更されたコピーをリターンする。startが非nil
ならマッチにたいする検索はstring内のそのインデックスから開始されて、リターン値にはstringの最初のstart文字は含まれない。置き換え後の文字列全体を取得するには、stringの最初のstart文字とリターン値を結合すること。
この関数は置換を行うためにオプション引数fixedcase、literal、subexpを渡してreplace-match
を使用する。
repは文字列のかわりに関数でもよい。この場合にはreplace-regexp-in-string
はそれぞれのマッチにたいして、そのテキストを単一の引数としてrepを呼び出す。これはrepがリターンする値を収集して、それを置換文字列としてreplace-match
に渡す。この時点でのマッチデータはstringの部分文字列にたいするregexpのマッチ結果。
この関数はin-string内に出現するすべてのfrom-stringをto-stringに置換して、その結果をリターンする。引数のいずれかを変更せずに、文字列定数が新たな文字列をリターンするかもしれない。case(大文字小文字)には意味があるが、テキストプロパティは無視する。
query-replace
の行に関するコマンドを記述したい場合には、perform-replace
を使用してこれを行うことができます。
これはquery-replace
および関連するコマンドの根幹となる関数である。これは位置startとendの間にあるテキスト内に出現するfrom-stringの一部またはすべてを置換する。startがnil
(または省略)ならかわりにポイントを、endにはそのバッファーのアクセス可能範囲の終端が使用される(オピション引数backwardが非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
のかわりに使用するキーマップを指定する。
region-noncontiguous-pが非nil
なら、startとendの間のリージョンは非連続部分から構成されることを意味する。これのもっとも一般的な例は部分が開業文字で区切られた矩形リージョンである。
この関数は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
前に問い合わせた以前の場所に戻る。
undo
最後の置換をアンドゥして置換が行われた位置に戻る。
undo-all
すべての置換をアンドゥして最初に置換が行われた位置に戻る。
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機能により使用されます。
36.1 構文テーブルの概念 | 構文テーブルの基本的概念。 | |
36.2 構文記述子 | 文字がクラス分けされる方法。 | |
36.3 構文テーブルの関数 | 構文テーブルを作成、調査、変更する方法。 | |
36.4 構文プロパティ | テキストプロパティによる構文テーブルのオーバーライド。 | |
36.5 モーションと構文 | 特定の構文による文字間の移動。 | |
36.6 式のパース | 構文テーブル使用による釣り合いのとれた式の解析。 | |
36.7 構文テーブルの内部 | 構文テーブルの情報が格納される方法。 | |
36.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)も定義しています。構文テーブルの内部を参照してください。
36.2.1 構文クラスのテーブル | ||
36.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ではセミコロン(‘;’)がコメントの開始、改行かフォームフィードで終了する。
この構文クラスは特定の構文を指定しない。これはその文字の構文を探すために親構文テーブルを照合するよう告げる。
特殊なコメントを開始または終了させる文字(この構文クラスは“comment-fence”としても知られる)。任意の汎用コメント区切りは任意の汎用コメント区切りにマッチするが、コメント開始とコメント終了はマッチできない。汎用コメント区切りは汎用コメント区切り同士としかマッチできない。
この構文クラスは主としてsyntax-table
テキストプロパティ(構文プロパティを参照)とともに使用することを意図している。任意の文字範囲の最初と最後の文字にたいして、それらが汎用コメント区切りであることを示すsyntax-table
プロパティを付与することにより、その範囲がコメントを形成するとマークすることができる。
文字列を開始や終了させる文字(この構文クラスは“string-fence”としても知られる)。任意の汎用文字列区切りは任意の汎用文字列区切りにマッチするが、通常の文字列クォート文字とはマッチできない。
この構文クラスは主として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”のコメント終了シーケンスにマッチするまで拡張されるだろう。フラグセットが‘b’と‘c’のいずれでもなければ、結果となるスタイルは“a”スタイルと呼ばれる。
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つの引数で呼び出される。startとendで区切られたリージョン内でポイントを任意に移動でき、そのような移動にsave-excursion
(エクスカーションを参照)を使う必要はない。endの前の任意の位置でsyntax-ppss
を呼び出すこともできるが、Lispプログラムがどこかでsyntax-ppss
を呼び出して、その後にそこより前の位置でバッファーを変更する場合には、もはや古くなってしまった情報をキャッシュからフラッシュするためにsyntax-ppss-flush-cache
を呼び出すのは、そのプログラムの責任である。
警告:
この変数が非nil
なら、Emacsはsyntax-table
テキストプロパティを任意に削除して、それらの再適用はsyntax-propertize-function
に依存する。つまりこの機能が使用される場合には、関数はメジャーモードが使用するすべてのsyntax-table
テキストプロパティを適用しなければならない。特にCCモードはこれらのテキストプロパティの削除と適用に別の手段を使用するので、CCモードから派生したモードはこの変数を使用してはならない。
このアブノーマルフックは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つの空文字列定数として扱います。
36.6.1 パースにもとづくモーションコマンド | パースにより機能する移動関数。 | |
36.6.2 ある位置のパース状態を調べる | ある位置の構文状態を判断する。 | |
36.6.3 パーサー状態 | Emacsが構文状態を表す方法。 | |
36.6.4 低レベルのパース | 指定されたリージョンを横断するパース。 | |
36.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)とはparse-partial-sexp
(低レベルのパースを参照)を使用してバッファー内の指定された開始位置と終了位置の間のテキストをパースした後の構文パーサーの状態を記述する(現在のところは)11要素のリストです。syntax-ppss
のようなパース関数
(ある位置のパース状態を調べるを参照)
も値としてパーサー状態をリターンします。 parse-partial-sexp
can
はパースを再開するために引数としてパーサー状態を受け取ります。
以下はパーサー状態の要素の意味です:
nil
。
nil
。
nil
。より正確には文字列を終端させるであろう文字、または汎用文字列区切りが終端すべきような場合にはt
。
t
、ネスト可なコメントの内部ならコメントのネストレベル。
t
。
nil
、スタイル‘b’のコメントなら1、スタイル‘c’のコメントなら2、汎用コメント区切り文字で終端されるべきコメントならsyntax-table
。
nil
。
nil
。
パース継続のための引数としてparse-partial-sexp
に渡す場合には要素1、2、6は無視されます。要素9と10は主にパーサーコードにより内部的に使用されます。
以下の関数を使用することにより追加でパーサー状態からいくつかの有用な情報を利用できます:
この関数はパーサー状態stateから文法構造上トップレベルでのパースでのスキャンした最後の位置をリターンする。“トップレベル”とはすべてのカッコ、コメント、文字列の外部であることを意味する。
stateがトップレベルの位置に到達したパースを表す場合には値はnil
。
stateをリターンするスキャン終了位置が文字列内にあればstring
、コメント内にあればcomment
、それ以外は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文字をシンボル構成要素として扱う(とはいえ依然としてsyntax-table
テキストプロパティは構文をオーバーラードできる)。
この値が非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つ目の文字と同様)を指定します。
raw構文記述子の文字を取得するには(aref (syntax-table) ch)
のようにaref
(配列を操作する関数を参照)を使用してください。
以下はさまざまな構文クラスに対応する構文コードです。
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’ | (ash 1 16) | ‘p’ | (ash 1 20) |
‘2’ | (ash 1 17) | ‘b’ | (ash 1 21) |
‘3’ | (ash 1 18) | ‘n’ | (ash 1 22) |
‘4’ | (ash 1 19) | ‘c’ | (ash 1 23) |
与えられた構文記述子desc(文字列)にたいして、この関数は対応するraw構文記述子をリターンする。
与えられた構文記述子syntax (整数)にたいして、この関数は対応する構文記述子(文字)をリターンする。
この関数はバッファー内の位置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 ;; 空のcategory-tableを作成 (let ((category-table (make-category-table)) ;; Create a char-table which gives the 'bidi-class' Unicode ;; 各文字のプロパティ (uniprop-table (unicode-property-table-internal 'bidi-class))) (define-category ?R "Characters of bidi-class R, AL, or RLO" category-table) ;; Unicodeの'bidi-class'プロパティが ;; R、AL、RLOであるような(R2Lの方向性をもつ)文字の ;; カテゴリーエントリーを変更する (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] | [ ? ] |
Emacsではプログラムソースのテキストのパース(parse: 解析)や構文ツリーまたは構文木(syntax tree)を生成するためにさまざまな方法が提供されています。構文ツリーにおけるテキストはもはや1次元の文字ストリームではなく、ノードというそれぞれがテキストの一部を表現するようなものを構造化したツリーとみなされます。つまり構文ツリーによって正確なフォント表示(fontification)、インデント、ナビゲーション、構造化された編集等といった興味深い機能を有効にできるのです。
Emacsには釣り合いのとれた式をパースするシンプルな機能があります(式のパースを参照)。一般的なナビゲーションとインデントにたいするSMIEというライブラリーもあります(SMIE: 無邪気なインデントエンジンを参照)。
これらに加えてtree-sitterライブラリーにたいするサポートがコンパイルされていれば、Emacsはtree-sitterとの統合も提供します。tree-sitterライブラリーはインクリメンタルパーサー(incremental parser: 増分解析ライブラリー)であり、幅広いプログラミング言語をサポートしています。
この関数はカレントのEmacsセッションにおいてtree-sitter機能が利用可能なら非nil
をリターンする。
tree-sitterライブラリーを用いたプログラムソースのパースとプログラムの構文ツリーへのアクセスを可能にするためには、Lispプログラムがその言語のグラマーライブラリーをロードするとともにその言語とカレントバッファーにたいするパーサーを作成する必要があります。Lispプログラムがこれを行った後に、構文ツリーの特定のノードに関してパーサーへの問い合わせを行うことができるのです。その後はそれぞれのノードに関するさまざまな種類の情報にアクセスして、強力なパターンマッチングを用いたノードの検索が可能になります。このチャプターではこれらすべてをどのように行うのか、そして複数のプログラミング言語がミックスされているソースファイルにたいしてLispプログラムが処理する方法についても説明します。
37.1 Tree-sitter Language Grammar | tree-sitter言語グラマーのロード。 | |
37.2 tree-sitterパーサーの使用 | パーサー入門。 | |
37.3 ノードの取得 | 構文ツリーからのノードの取得。 | |
37.4 ノード情報へのアクセス | ||
37.5 tree-sitterノードにたいするパターンマッチング | パターン問い合わせによるパターンマッチング。 | |
37.6 複数言語ののパース | 複数言語で記述されたテキストのパース。 | |
37.7 tree-sitterを用いるメジャーモードの開発 | tree-sitterを使用するメジャーモードの開発。 | |
37.8 tree-sitterのC APIとの対応表 | C用APIとELisp用APIの比較。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ある言語で記述されたテキストをパースするために、tree-sitterはその言語のグラマー(grammar:
文法)に依存します。Emacsにおける言語グラマーはシンボルによって表現されます。たとえばC言語のグラマーはシンボルc
として表現されます。このc
というシンボルはtree-sitter関数のlanguage引数として渡すことができます。
tree-sitterの言語グラマーはダイナミックライブラリーとして配布されています。ある言語のグラマーをEmacsで使用するためには、そのダイナミックライブラリーがシステム上にインストール済みかを確認する必要があります。Emacsは以下の順序で複数の場所から言語グラマーを探します:
treesit-extra-load-path
で指定されたディレクトリーのリストから;
user-emacs-directory
で指定されるディレクトリーのサブディレクトリーtree-sitterから(initファイルを参照);
これらのディレクトリーそれぞれにおいて、Emacsは変数dynamic-library-suffixes
が指定するファイル名拡張子をもつファイルを探すのです。
Emacsがライブラリーを見つけられなかったりロードに問題がある場合には、Emacsがtreesit-load-language-error
エラーをシグナルします。このシグナルのデータは以下のいずれかです:
(not-found error-msg …)
その言語のグラマーライブラリーをEmacsが見つけられなかったという意味。
(symbol-error error-msg)
すべての言語のグラマーライブラリーでエクスポートされているべき関数を、そのライブラリーではEmacsが見つけられなかったという意味。
(version-mismatch error-msg)
その言語のグラマーライブラリーとtree-sitterライブラリーのバージョンに互換性がないという意味。
上記すべてのケースにおいて、error-msgにより失敗に関する追加の詳細が提供されるかもしれません。
この関数はlanguageにたいする言語グラマーが存在して、それがロード可能であれば非nil
をリターンする。
detailが非nil
の場合には、languageが利用可能なら(t
. nil)
、利用不可なら(nil
. data)
をリターンする。dataはtreesit-load-language-error
のシグナルデータ。
慣例によりlanguage用ダイナミックライブラリーのファイル名はlibtree-sitter-language.extです。ここでextはダイナミックライブラリー用のシステム固有な拡張子です。同じく慣例により、そのライブラリーが提供する関数の名前はtree_sitter_language
です。この慣例にしたがっていない言語グラマーライブラリーの場合には、
(language library-base-name function-name)
上記エントリーを変数treesit-load-name-override-list
のリストに追加する必要があります。ここでlibrary-base-nameはダイナミックライブラリーのファイル名のベースネーム(basename:
先行するディレクトリー部分を除外したファイル名のことで、通常だとlibtree-sitter-language)、function-nameはそのライブラリーが提供する関数(通常だとtree_sitter_language
)です。たとえば、
(cool-lang "libtree-sitter-coool" "tree_sitter_cooool")
これは慣例に屈するには自分があまりにも“cool”に過ぎると考える言語の例です。
この関数はtree-sitterライブラリーがサポートしている言語グラマーのABI (Application Binary
Interface:
アプリケーションバイナリーインターフェイス)のバージョンをリターンする。デフォルトではそのライブラリーがサポートする最新のABIバージョンをリターンするが、min-compatibleが非nil
の場合にはそのライブラリーでまだサポートできる最古のABIバージョンをリターンする。言語グラマーライブラリーはtree-sitterライブラリーがサポートする最古と最新の間にあるABIバージョンにたいしてビルドしなければ、tree-sitterライブラリーがそれらをロードできなくなる。
この関数はEmacsがロードしたlanguage用の言語グラマーライブラリーのABIバージョンをリターンする。languageが利用できなければnil
をリターンする。
構文ツリーはパーサーによって生成されます。構文ツリーにおけるノードはそれぞれがテキストのある部分を表し、お互いが親子関係というリレーションシップによって接続されています。たとえば以下のようなソーステキストがあるとします
1 + 2
これは以下のような構文ツリーになるかもしれません
+--------------+ | root "1 + 2" | +--------------+ | +--------------------------------+ | expression "1 + 2" | +--------------------------------+ | | | +------------+ +--------------+ +------------+ | number "1" | | operator "+" | | number "2" | +------------+ +--------------+ +------------+
これを以下のようにS式で表すことも可能です:
(root (expression (number) (operator) (number)))
root
、expression
、number
、operator
のような名前はノードのタイプ(type:
型)を指定します。ただし構文ツリーのすべてのノードがタイプをもつ訳ではありません。タイプをもっていないノードは無名ノード(anonymous
nodes)、タイプをもつノードは名前つきノード(named
nodes)と呼ばれています。無名ノードは角カッコ‘]’のような区切り文字やreturn
のようなキーワードを含む、固定化された綴りのトークン(token:
字句単位)です。
構文ツリーの分析を容易にするために、多くの言語グラマーは子ノードにフィールド名(field
names)を割り当てています。たとえばfunction_definition
ノードはdeclarator
とbody
のフィールド名をもつかもしれません:
(function_definition declarator: (declaration) body: (compound_statement))
言語の構文の理解、および構文ツリー割り当て使用するLispプログラムのデバッグ支援のために、Emacsはカレントバッファーのソースの構文ツリーをリアルタイムで表示する“explore”モードを提供しています。更にEmacsにはポイント位置にあるノードの情報をモードラインに表示する“inspect”モードも付属しています。
このモードはカレントバッファーのソースの構文ツリーを表示するウィンドウをポップアップする。ソースバッファーでテキストを選択することによって、表示されている構文ツリーの対応する部分がハイライトされる。構文ツリーでノードをクリックすれば、ソースバッファーの対応するテキストがハイライトされる。
このマイナーモードはポイント位置で始まるノードをモードラインに表示する。たとえばモードラインに以下のように表示されるかもしれない
parent field: (node (child (…)))
ここでnode、child、...等はポイント位置で始まるノード、parentはnodeの親である。nodeはbold書体で表示される。field-nameはnode、child、...等のフィールド名である。
ポイント位置で始まるノードがない(ポイントがノードの中間にある)場合には、ポイントを跨ぐ(span)もっとも前のノード、およびそのノードの直近の親ノードがモードラインに表示される。
このマイナーモード自身はパーサーを作成せず、(treesit-parser-list)
の最初のパーサーを使用する(tree-sitterパーサーの使用を参照)。
言語グラマーの製作者はプログラミング言語のグラマー(grammar: 文法)を定義します。パーサーがどのようにしてプログラムテキストから具体的な構文ツリーを構築するかを決めるのがグラマーです。構文ツリーを効果的に使用するためには、グラマーファイル(grammar file)を調べる必要があります。
グラマーファイルは通常だと言語グラマーのプロジェクトレポジトリにあるgrammar.jsです。言語グラマーのホームページへのリンクはtree-sitter’s homepageで見つけることができるでしょう。
グラマー定義はJavaScriptによって記述されます。たとえばfunction_definition
ノードにマッチするようなルールは以下のようなものかもしれません
function_definition: $ => seq( $.declaration_specifiers, field('declarator', $.declaration), field('body', $.compound_statement) )
ルールは単一の引数$を受け取る関数によって表現されます。この関数がグラマー全体を表すのです。この関数自体は他の関数によって構築されています。一連の子ノードをまとめるのがseq
関数、子ノードにフィールド名の注釈をつけるのがfield
関数です。上記の定義を俗にBNF
(Backus-Naur Form: バッカス・ナウア記法)と呼ばれる構文で表せば以下のようになるでしょう
function_definition := <declaration_specifiers> <declaration> <compound_statement>
そしてパーサーがリターンするノードは以下のようになります
(function_definition (declaration_specifier) declarator: (declaration) body: (compound_statement))
以下はグラマー定義で目にするかもしれない関数のリストです。これらの関数はいずれも引数として他のルールを受け取り新たなルールをリターンします。
seq(rule1, rule2, …)
すべてのルールに逐一マッチする。
choice(rule1, rule2, …)
引数のルールいずれかにマッチする。
repeat(rule)
ruleに0回以上マッチする。正規表現の演算子‘*’に似ている。
repeat1(rule)
ruleに1回以上マッチする。正規表現の演算子‘+’に似ている。
optional(rule)
ruleに0回または1回マッチする。正規表現の演算子‘?’に似ている。
field(name, rule)
ruleにマッチする子ノードにフィールド名nameを割り当てる。
alias(rule, alias)
ruleにマッチしたノードをパーサーが生成する構文ツリーでaliasとして表示する。たとえば、
alias(preprocessor_call_exp, call_expression)
これによりpreprocessor_call_exp
がマッチしたノードがcall_expression
と表示される。
以下は言語グラマーを読むにあたってそれほど重要ではないグラマー関数です。
token(rule)
単一の葉ノード(leaf node)としてruleをマークする。つまり個別の子ノードをもつ親ノードではなく、その単一の葉ノードにすべてが収斂されるようなノードを生成する。ノードの取得を参照のこと。
token.immediate(rule)
通常のグラマールールは先行する空白を無視するが、これは空白が前置されていないruleだけにマッチするよう変更する。
prec(n, rule)
ruleにたいしてレベルnの優先度を与える。
prec.left([n,] rule)
ruleにたいしてオプションとしてレベルnを付与して左結合(left-associative)とマークする。
prec.right([n,] rule)
ruleにたいしてオプションとしてレベルnを付与して右結合(right-associative)とマークする。
prec.dynamic(n, rule)
prec
と似ているが優先度は実行時に適用される。
tree-sitterプロジェクトにはmore about writing a grammarというドキュメントがあります。特に“The Grammar DSL”というセクションを読んでください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではtree-sitterパーサーをどのようにして作成して構成するかについて説明します。Emacsにおけるtree-sitterパーサーはそれぞれバッファーに関連付けられます。ユーザーによるバッファーの編集にしたがって、関連付けられているパーサーと構文ツリーは自動的に最新に保たれるのです。
この変数にはtree-sitterをアクティブにし得るバッファーの最大サイズが含まれる。メジャーモードはtree-sitter機能を有効にするかどうかを判断する際にはこの変数をチェックすること。
指定されたbufferおよびlanguage (Tree-sitter Language Grammarを参照)にたいしてパーサーを作成する。バッファーが省略またはnil
の場合にはカレントバッファーを意味する。
この関数はbufferのlanguageにたいするパーサーがすでに存在していれば、デフォルトではそれを再利用するがno-reuseが非nil
の場合には常に新たなパーサーを作成する。
そのバッファーがインダイレクトバッファーなら、かわりにベースバッファーを使用する。つまりインダイレクトバッファーではそのベースバッファーのパーサーが使用される。ベースバッファーがナローイングされていると、インダイレクトバッファーがベースバッファーで不可視なバッファーテキスト部分の情報を取得できないかもしれない。Lispプログラムがインダイレクトバッファーでパーサーを使用するためには、必要に応じてwiden(訳注: カレントバッファーからナローイングによる制限を取り去る関数)する必要がある。
パーサーが与えられれば、それに関する情報を問い合わせることができます。
この関数はparserに関連付けられているバッファーをリターンする。
この関数はparserが使用する言語をリターンする。
この関数はobjectをチェックしてtree-sitterパーサーなら非nil
、そうでなければnil
をリターンする。
パースは自動的かつ遅延して行われるので、明示的にバッファーをパースする必要はありません。パーサーがパースを行うのは、Lispプログラムがパーサーの構文ツリーのノードにたいして問い合わせを行ったときだけです。したがって最初にパーサーが作成された際にはバッファーのパースは行われず、Lispプログラムがノードにたいする問い合わせを最初に行うまで待機します。同様に何らかの変更をバッファーに行った際にも、パーサーが即座に再パースする訳ではありません。
パーサーがパースを行う際にはバッファーのサイズをチェックします。tree-sitterが処理できるのはおよそ4GBまでです。サイズがそれを超えると、Emacsはそのバッファーサイズをシグナルデータとしてtreesit-buffer-too-large
エラーをシグナルするでしょう。
一度パーサーを作成すると、Emacsが自動的にそれを内部のパーサーリストに追加します。バッファーにたいして変更が行われるたびに、パーサーがインクリメンタルに構文ツリーを更新できるように、Emacsがこのリストにあるパーサーを更新するのです。
この関数はbufferのパーサーリストをリターンする。bufferがnil
または省略の場合のデフォルトはカレントバッファー。そのバッファーがインダイレクトバッファーなら、かわりにベースバッファーを使用する。つまりインダイレクトバッファーではそのベースバッファーのパーサーが使用される。
この関数はparserを削除する。
パーサーは通常はバッファー全体を“見ている”ものですが、バッファーがナローイング(ナローイングを参照)されているとパーサーが見るのはバッファーのアクセス可能範囲だけになります。パーサーが見る限りでは、隠されているリージョンは削除されたことになります。後刻バッファーがワイドニングされた際には、先頭と終端にテキストが挿入されたとパーサーは考えるでしょう。パーサーがナローイングを尊重するにしても、複数言語のバッファーを処理するという意味合いでモードはナローイングを使用するべきではありません。そのかわりにパーサーが処理する必要がある範囲をセットするべきです。複数言語ののパースを参照してください。
パーサーはパースを遅延させるので、ユーザーやLispプログラムがバッファーをナローイングしてもパーサーはすぐに影響を受けないのです。バッファーをナローイングしていても、モードがノードについて問い合わせをするまでパーサーはナローイングを認識しません。
バッファーにたいしてパーサーを作成するだけではなく、Lispプログラムが文字列のパースを行うことも可能です。バッファーと違い文字列のパースは一度かぎりの操作であり、結果を更新する手段はありません。
この関数はlanguageを使用してstringのパースを行い、生成された構文ツリーのルートノードをリターンする。
Lispプログラムはインクリメンタルなパースによって影響を受けるテキストにたいして通知してほしい場合があるかもしれません。たとえばコメントを閉じるtokenの挿入によって、そのtokenの手前にあるテキストを変換する場合です。たとえテキストが直接変更されなくても、それは“変更”とみなされるのです。
Emacsではこれらの類いの変更にたいして、Lispプログラムにコールバック関数(別名notifier)を登録できます。notifier関数はranges、parserという2つの引数を受け取ります。rangesは(start . end)
という形式をもつコンスセルのリストです。ここでstart、endは範囲の開始と終了をマークします。parserは通知を発行するパーサーです。
パーサーはバッファーを再パースするたびに構文ツリーの新旧を比較して、変更されたノード範囲の計算を行いその範囲をnotifier関数に引き渡します。最初のパースも“変更”とみなされるので、最初のパースではバッファー全体を範囲としてnotifier関数が呼び出されることに注意してください。
この関数はparserのnotifier関数のafter-changeリストにfunctionを追加する。functionはlambda関数ではなく、関数シンボルでなければならない(無名関数を参照)。
この関数はparserのnotifier関数のafter-changeリストからfunctionを削除する。functionはlambda関数ではなく、関数シンボルでなければならない(無名関数を参照)。
この関数はparserのnotifier関数のリストをリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下はわたしたちがtree-sitter関数を文書化する際に用いる用語と慣習についてです。
構文ツリーのノードは、バッファーのプログラムテキストのある部分に跨ります(span)。あるノードの跨ぐバッファーテキスト部分が、他のノードのそれより小さい(または大きい)場合には、わたしたちはそのノードが他のノードより“小さい”(または“大きい”)と表現します。ツリーにおいてより深い(“下位”の)ノードは、そのツリーのより“上位”ノードの子となるので、そのノード階層において下位のノードは常に上位のノードより小さくなります。構文ツリーの上位のノードには、その子として1つ以上の小さいノードが含まれており、したがってバッファーテキストのより大きい部分を跨ぐことになるのです。
関数がノードを見つけられなかった場合にはnil
をリターンします。利便性のために、引数としてノードを受け取ってノードをリターンするすべての関数もnil
の引数を許し、そのような場合には単にnil
をリターンするようになっています。
関連付けられているバッファーが更新された際にノードが自動的に更新されることはなく、一度取得したノードを更新する術は存在しません。古くなってしまったノードを使用するとtreesit-node-outdated
エラーがシグナルされるでしょう。
この関数はバッファー位置posにある葉ノード(leaf node)をリターンする。葉ノードとは子ノードを何ももたないノードのこと。
この関数はposを跨がって覆う(cover)ようなノードのリターンを試みる。これは開始位置がpos以下、かつ終了位置がpos以上であるノードのこと。
posを跨いで覆うような葉ノードがない(たとえばposが2つの葉ノードの間にある空白にある)場合には、この関数はposの後にある最初の葉ノードをリターンする。
最後にもしposの後に葉ノードがなければ、posの前にある最初の葉ノードをリターンする。
parser-or-langがパーサーオブジェクトなら、この関数はそのパーサーを使用する。parser-or-langが言語の場合には、この関数はカレントバッファーにおいてその言語用の最初のパーサー、もし存在しなければパーサーを作成してそれを使用する。parser-or-langがnil
なら、この関数はtreesit-language-at
(複数言語ののパースを参照)を呼び出して、posの言語の推測を試みる。
リターンする適切なノードが見つけられなかった場合には、この関数はnil
をリターンする。
namedが非nil
の場合には、この関数は名前つきのノードだけを探す(named nodeを参照)。
例:
;; Cパーサーの構文ツリーでポイント位置のノードを探す (treesit-node-at (point) 'c) ⇒ #<treesit-node (primitive_type) in 23-27>
この関数はbegとendの間にあるバッファーテキストのリージョンを覆うような、もっとも小さいノードをリターンする。言い換えると開始がbeg以前、かつ終了がend以降であるようなノードのこと。
注意せよ:
トップレベル構文(関数定義等)の内部ではない空行でこの関数を呼び出すと、恐らくルートノードが取得される場合がほとんどだろう。その空行を覆うもっとも小さいノードがルートノードだというのがその理由だが、あなたが使いたいと望んでいる機能は、ほとんどの場合はtreesit-node-at
のほうだろう。
parser-or-langがパーサーオブジェクトなら、この関数はそのパーサーを使用する。parser-or-langが言語の場合には、この関数はカレントバッファーにおいてその言語用の最初のパーサー、もし存在しなければパーサーを作成してそれを使用する。parser-or-langがnil
なら、この関数はtreesit-language-at
(複数言語ののパースを参照)を呼び出して、begの言語の推測を試みる。
namedが非nil
の場合には、この関数は名前つきのノードだけを探す(named nodeを参照)。
この関数はparserが生成した構文ツリーのルートノードをリターンする。
この関数はカレントバッファーでlanguage用の最初のパーサー、パーサーが存在しなければ作成して、そのパーサーが生成したルートノードをリターンする。languageが省略された場合にはパーサーリストの最初のパーサーを使用する。適切なパーサーが見つからなければnil
をリターンする。
Lispプログラムはノードが与えられれば、そこから始まる他のノードを取得したり、そのノードに関する情報を問い合わせることができます。
この関数はnodeの直近の親をリターンする。
パースツリー(parse tree:
解析木)においてnodeが1000を超える深さのレベルにある場合のリターン値は未定義。現在のところnil
をリターンするが、将来変更されるかもしれない。
この関数はnodeのn番目の子をリターンする。namedが非nil
なら名前つきのノードだけを考慮する(named nodeを参照)。
たとえば文字列"text"
を表すノードの場合には開クォート"
、文字列テキストのtext
、それに閉クォート"
という3つの子ノードが存在する。これら3つのノードの中で最初の子は開クォート"
、最初の名前つきの子は文字列テキストとなる。
この関数はn番目の子が存在しなければnil
をリターンする。nは負でも可(-1は最後の子を表す)。
この関数はnodeのすべての子をリストでリターンする。namedが非nil
なら名前つきのノードだけを取得する。
この関数はnodeの次の兄弟を探す。namedが非nil
なら次の名前つきの兄弟を探す。
この関数はnodeの前の兄弟を探す。namedが非nil
なら前の名前つきの兄弟を探す。
構文ツリーの分析をより容易にするために、多くの言語ではグラマーで子ノードにフィールド名(field
names)を割り当てています(field
nameを参照)。たとえばfunction_definition
ノードにはdeclarator
やbody
というノードがあるかもしれません。
この関数はフィールド名がfield-name(文字列)であるようなnodeの子を探す。
;; フィールド名が"body"という子を取得 (treesit-node-child-by-field-name node "body") ⇒ #<treesit-node (compound_statement) in 45-89>
この関数はバッファー位置posを超えて広がるようなnodeの最初の子をリターンする。“超えて広がる(extends
beyond)”とは子ノードの終端がpos以降であることを意味する。この関数はnodeの直接の子だけを調べる(孫は調べない)。namedが非nil
の場合には最初の名前つきの子を探す(named nodeを参照)。
これは位置begとendの間にあるテキストリージョンを跨ぐような、もっとも小さいnodeの子孫ノードを探す、treesit-node-at
と似た関数。namedが非nil
の場合には、もっとも小さい名前つきの子を探す。
この関数はnodeのサブツリー(node自体を含む)を横断(traverse)して、predicateが非nil
をリターンするようなノードを探す。predicateはノードそれぞれのタイプにたいしてマッチさせるregexp、あるいはノードを受け取りそのノードがマッチしたら非nil
をリターンするような述語関数。この関数はマッチした最初のノード、何もマッチしなければnil
をリターンする。
この関数が検索するのはデフォルトでは名前つきノードだけだが、allが非nil
ならすべてのノードを横断して検索を行う。backwardが非nil
の場合には後方に横断して検索する(ツリーを下降して横断していく際に最後の子を最初に調べる)。depthが非nil
なら、それはツリーを横断して下降できるレベル数を制限する数値でなければならない。depthがnil
の場合のデフォルトは1000。
この関数は(startを除けば)treesit-search-subtree
と同じようにパースツリーを横断して、predicateによりそれぞれのノードをマッチする(predicateはregexpまたは関数)。以下のようなツリー(‘S’マークはstart)の場合には、この関数は1から12の順に横断していく:
12 | S--------3----------11 | | | o--o-+--o 1--+--2 6--+-----10 | | | | o o +-+-+ +--+--+ | | | | | 4 5 7 8 9
この関数はstartのサブツリーを横断せず、常に上方に移動する前にまず葉ノードを横断することに注意。
この関数が検索するのはtreesit-search-subtree
と同じようにデフォルトでは名前つきノードだけだが、allが非nil
ならすべてのノードを検索する。backwardが非nil
の場合には後方に検索する。
treesit-search-subtree
はノードのサブツリーを横断するが、この関数はノードstartから開始してバッファーの位置順でその後にあるすべてのノード(開始位置がstartの終了位置より大きいノード)を横断する。
上図で示すツリーにおいて、treesit-search-subtree
はノード‘S’
(start)およびo
のマークがついたノードを横断するが、この関数は数字のマークがついたノードを横断する。この関数は“バッファーでstartの後にあり何らかの条件を満足する最初のノードはどれ?”、のような問いの答えを求めるのに役に立つ。
この関数はバッファーでnodeの後にありpredicateにマッチする次のノードの開始または終了にポイントを移動する。startが非nil
なら、ノードの終了ではなく開始で停止する。
この関数がリターンするマッチしたノードは、バッファー位置という点において進行方向にある(リターンされたノードの開始/終了はnodeのそれより常に大きい)ことが保証されている。
引数predicate、backward、allはtreesit-search-forward
の場合と同じ。
この関数はrootのサブツリーからsparseツリー(疎らなツリー)を作成する。
この関数はroot配下のサブツリーを受け取って、predicateにマッチするノードだけが残るように間引く。前の関数と同じようにpredicateはノードそれぞれのタイプにマッチさせるためのregexp文字列、またはノードを受け取ってマッチした場合には非nil
をリターンする。
たとえば数字と文字の両方で構成される左側のサブツリーが与えられた場合に、“文字のみ”というpredicateでリターンされるのが右側のツリー。
a a a | | | +---+---+ +---+---+ +---+---+ | | | | | | | | | b 1 2 b | | b c d | | => | | => | c +--+ c + e | | | | | +--+ d 4 +--+ d | | | e 5 e
この関数はprocess-fnが非nil
の場合には、マッチしたノードではなくノードをそれぞれprocess-fnに渡してリターン値を使用する。depthが非nil
なら、それはrootから下降できるレベル数制限であること。depthがnil
の場合のデフォルトは1000。
リターンされるツリーのノードはそれぞれ(tree-sitter-node . (child …))
のようになる。このツリーのルートであるtree-sitter-nodeは、rootがpredicateにマッチしなければnil
になる。predicateにマッチするノードがなければ、この関数はnil
をリターンする。
この関数はpredicateを満足するnodeの直接の子を探す。
predicateは引数としてノードを受け取り、そのノードを候補に残すべきなら非nil
をリターンする関数であること。namedが非nil
なら、この関数は名前つきのノードだけを調べる。
この関数はnodeの親を順繰りに探して、pred
(引数としてノードを受け取りマッチを示すブーリーン値をリターンする関数)を満足する親をリターンする。predを満足する親がいなければ、この関数はnil
をリターンする。
この関数は通常だとnode自体ではなくnodeの親だけを調べる。しかし、include-nodeが非nil
の場合には、nodeがpredを満足すればnodeをリターンする。
この関数はnodeを開始点としてノードがpred (引数としてノードを受け取る関数)を満足するかぎりツリーを上方に移動する。つまりこの関数はpredを満足するもっとも高位にあるnodeの親をリターンする。nodeがpredを満足して、かつ直近の親はpredを満足しなければ、node自体がリターンされることに注意。
この関数はnodeと同じタイプをもつ、もっとも高くにある親をリターンする。そのような親がいなければnil
をリターンする。したがってこの関数はnodeがトップレベルかどうかをテストするためにも役に立つ。
typeが非nil
の場合には、この関数はnodeのタイプではなく、regexpとしてtypeを用いてそれぞれの親のタイプをマッチする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
すべてのノードはパーサーに関連付けられていて、そのパーサーが関連付けられているのがバッファーです。以下はそれらを取得する関数です。
この関数はnodeに関連付けられているパーサーをリターンする。
この関数はnodeのパーサーに関連付けられているバッファーをリターンする。
この関数はnodeに関連付けられている言語をリターンする。
それぞれのノードはバッファー内のテキストのある範囲を表しています。そのテキストに関する情報を探すのが以下の関数です。
nodeの開始位置をリターンする。
nodeの終了位置をリターンする。
nodeが表しているバッファーテキストを文字列としてリターンする(nodeが文字列をパースすることによって取得されたものであれば、その文字列のテキストをリターンする)。
以下はtree-sitterのノード用の述語の一部です:
objectがtree-sitterの構文ノードかをチェックする。
tree-sitterの構文ツリーにおいてnode1とnode2が同じノードを参照しているかをチェックする。この関数はequal
と等価なメトリックを用いる。equal
を使用してノードを比較することも可能(同等性のための述語を参照)。
具体的な構文ツリーにおけるノードは一般的に名前つきノード(named nodes)と無名ノード(anonymous nodes)という2つのカテゴリーに大別されます。あるノードが名前つきか、それとも無名なのかは言語グラマーによって判断されます(named nodeを参照)。
ノードが名前つきか、あるいは無名かというプロパティに加えて、ノードは他のプロパティをもつことができます。ノードが“欠落(missing)”していることもあり得ます。このようなノードは特定の類の構文エラー(たとえばグラマーに照らせば恐らくそこにあるべき何らかが存在しない)から復帰するためにパーサーによって挿入されます。これはプログラムソースの編集中において、そのソースがまだ最終形になっていないときに発生し得るエラーです。
“余分(extra)”というノードもあります。このようなノードはテキスト内の任意の場所に出現し得る、コメントのようなオブジェクトを表しています。
パーサーがノードを作成した後に少なくとも1回再パースされた場合には、“期限切れ(outdated)”のノードになることがあります。
ノードが跨ぐテキストに構文エラーが含まれていれば、“エラーあり(has error)”のノードです。ノード自体にエラーがあったり、子孫のいずれかのノードにエラーがあるのかもしれません。
ノードはそのノードのパーサーが削除されておらず、更にそのノードが生きているバッファー(バッファーのkillを参照)であれば生きている(live)とみなされます。
この関数はnodeが指定されたpropertyをもっていれば非nil
をリターンする。propertyはnamed
、missing
、extra
、outdated
、has-error
、live
のいずれか。
名前つきノードは“タイプ(type)”をもつことができる(node
typeを参照)。たとえば名前つきノードstring_literal
のタイプをstring_literal
にすることができる。無名ノードは、単にそのノードが表すテキストがタイプとなる(たとえば‘,’ノードのタイプは単に‘,’)。
この関数はnodeのタイプを文字列としてリターンする。
この関数は親からnodeを子ノードとして見た場合のインデックスをリターンする。namedが非nil
の場合には名前つきノードだけを考慮する(named nodeを参照)。
親をもつ子ノードはフィールド名をもつことができる(field nameを参照)。この関数は親からnodeを子ノードとして見た場合のフィールド名をリターンする。
この関数はnodeのn番目の子のフィールド名をリターンする。n番目の子がいない、またはn番目の子にフィールド名がなければnil
をリターンする。
nは名前つきの子と無名の子の両方を考慮することに注意。またnは負でもよい(-1は最後の子を表す)。
この関数はnodeの子の数をリターンする。namedが非nil
の場合には名前つきの子だけを考慮する(named nodeを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
tree-sitterでは小さな宣言型言語を用いてLispプログラムによるパターンのマッチングができます。このパターンマッチングは2つのステップから構成されています。まずtree-sitterが構文ツリーのノードにたいするパターン(pattern)のマッチを行い、その後にパターンにマッチした特定のノードをキャプチャー(capture)してそのノードをリターンするのです。
まずはもっとも基本的なクエリーパターンを記述してパターン内のノードをキャプチャーする方法、それからパターンマッチング関数、そして最後により上級のパターン構文について説明していきます。
クエリー(query:
問い合わせ)は複数のパターン(patterns)によって構成されます。パターンはそれぞれ構文ノード内の特定ノードにマッチするS式です。パターンは(type (child…))
という形式をもっています。
たとえば子ノードを含んだノードbinary_expression
にマッチするのは以下のようなパターンでしょう
(binary_expression (number_literal))
上記のクエリーパターンを用いてノードをキャプチャー(capture)するためには、キャプチャーしたいノードパターンの後に@capture-name
を追加します。たとえば、
(binary_expression (number_literal) @number-in-exp)
これはノードbinary_expression
にあるノードnumber_literal
をキャプチャー名でキャプチャーします。
同じようにして、たとえばキャプチャー名biexp
でノードbinary_expression
をキャプチャーできます:
(binary_expression (number_literal) @number-in-exp) @biexp
これでクエリー関数(query functions)を説明する準備ができました。
この関数はqueryのパターンをnodeとマッチする。引数queryはS式、文字列、またはコンパイル済みクエリーオブジェクトのいずれか。ここではS式構文に焦点を当てる。文字列構文およびコンパイル済みクエリーについては、このセクションの最後で説明しよう。
引数nodeはパーサー、あるいは言語シンボルでもよい。パーサーの場合にはそのルートノードを、言語シンボルならまずカレントバッファーでその言語用のパーサーを探すか作成してそのルートノードを使用する。
この関数はキャプチャーしたすべてのノードを、(capture_name . node)
という要素をもつalistでリターンする。node-onlyが非nil
の場合には、かわりにnodeのリストをリターンする。デフォルトではnodeのテキスト全体を検索するが、begとendがいずれも非nil
であれば、それはこの関数がノードをマッチするべきバッファーテキストのリージョンを指定する。begとendの間のリージョンを跨いで重なるようなノードがマッチすればすべてキャプチャーされる(完全にそのリージョンに含まれている必要はない)。
この関数はqueryが不正な形式であればtreesit-query-error
エラーraiseする。シグナルデータには、その特定。エラーに関する説明が含まれている。クエリーの検証とデバッグにはtreesit-query-validate
を使うことができる。
たとえばnodeのテキストが1 + 2
で、以下のクエリーを考えてみましょう
(setq query '((binary_expression (number_literal) @number-in-exp) @biexp)
このクエリーをマッチングすると以下がリターンされます
(treesit-query-capture node query) ⇒ ((biexp . <node for "1 + 2">) (number-in-exp . <node for "1">) (number-in-exp . <node for "2">))
前に言及したように、queryに複数のパターンを含めることができます。たとえば以下のようにトップレベルのパターンを2つもつことができます:
(setq query '((binary_expression) @biexp (number_literal) @number @biexp)
この関数はlanguageとしてstringをパースして、そのルートノードにたいしてqueryをマッチ、その結果をリターンする。
ノードのタイプとキャプチャー名以外にも、tree-sitterのパターン構文により無名ノード、フィールド名、ワイルドカード、量化、グルーピング、選択、アンカー、述語を表現することができます。
無名ノードはクォートで括ることで逐語的に記述されます。キーワードreturn
にマッチ(してキャプチャー)するパターンは以下のようになるでしょう
"return" @keyword
パターンにおいて‘(_)’は任意の名前つきノード、‘_’は名前つきノードや無名ノードのすべてにマッチします。たとえばbinary_expression
ノードの名前つきの子をすべてキャプチャーするパターンは以下のようになるでしょう
(binary_expression (_) @in-biexp)
特定のフィールド名をもつ子ノードをキャプチャーすることは可能です。以下のパターンでは、フィールド名であることを示すコロンが後置されているdeclarator
とbody
がフィールド名です。
(function_definition declarator: (_) @func-declarator body: (_) @func-body)
特定のフィールドをもたないノード、たとえばbody
フィールドのないfunction_definition
をキャプチャーすることも可能です:
(function_definition !body) @func-no-body
tree-sitterは量化演算子(quantification operator)の‘:*’、‘:+’,‘:?’を認識します。これらの演算子の意味は正規表現の場合と同じです。‘:*’と‘:+’はそれぞれ前にあるパターンの0個以またはは1個以上の繰り返し、‘:?’は前のパターンの0個または1個の繰り返しにマッチします。
たとえば以下はlong
というキーワードの0個以上の繰り返しにマッチするパターンです。
(type_declaration "long" :*) @long-type
こちらはlong
というキーワードをもつか、あるいはもたないかというタイプ宣言用のパターンです:
(type_declaration "long" :?) @long-type
正規表現におけるグループと同じように、パターンをグループにまとめたり量化演算子を適用することができます。たとえばカンマで区切られた識別子を表現するには、以下のように記述できるでしょう
(identifier) ("," (identifier)) :*
繰り返しになりますが正規表現と同じように、パターンにおいて“これらのパターンのいずれかにマッチ”と表現することができます。この構文はパターンのベクターです。たとえばCのいくつかのキーワードをキャプチャーするパターンは、以下のように記述できるでしょう
[ "return" "break" "if" "else" ] @keyword
たとえば2つのオブジェクトを隣接させるといったように、アンカー演算子:anchor
を用いて並置させることができます。2つの“オブジェクト”には2つのノードや子ノードと最後の親などを指定できます。たとえば最初最後の子、あるいは2つの隣接した子をキャプチャーするには:
;; 子と最後で親をアンカー (compound_expression (_) @last-child :anchor)
;; 子と最初の親をアンカー (compound_expression :anchor (_) @first-child)
;; 隣接する2つの子をアンカー (compound_expression (_) @prev-child :anchor (_) @next-child)
並置させる際には無名ノードは無視されることに注意してください。
パターンに述語による制約を追加することができます。たとえば以下のパターンでは:
( (array :anchor (_) @first (_) @last :anchor) (:equal @first @last) )
tree-sitterは配列の最初と最後の要素が等しい場合だけマッチします。パターンに述語を付加するためには、それらをグループにまとめる必要があります。現在のところ:equal
、:match
、:pred
という3つの述語があります。
arg1とarg2が等しければマッチ。引数は文字列またはキャプチャー名のいずれか。キャプチャー名とは、バッファーにおいてキャプチャーされたノードが跨ぐテキストを表す。
バッファーにおいてcapture-nameのノードが跨ぐテキストと、文字列リテラルとして与えられた正規表現regexpがマッチすればマッチ。マッチは大文字小文字を区別する。
関数fnにnodes内のノードそれぞれを渡して非nil
がリターンされたらマッチ。
述語が参照できるのは、同じパターン内に出現するキャプチャー名だけであることに注意してください。実際問題として別のパターンからキャプチャー名を参照しても、意味はほとんどありません。
S式の他にも、Emacsでは使用するtree-sitterのネイティブクエリー構文を文字列として記述することができます。これはS式の構文とよく似ています。たとえば以下のクエリーは
(treesit-query-capture node '((addition_expression left: (_) @left "+" @plus-sign right: (_) @right) @addition ["return" "break"] @keyword))
以下と等価です
(treesit-query-capture node "(addition_expression left: (_) @left \"+\" @plus-sign right: (_) @right) @addition [\"return\" \"break\"] @keyword")
ほとんどのパターンは文字列内部のS式として直接記述できます。変更が必要になるのはごく少数のパターンだけです:
:anchor
は‘.’と記述。
:equal
、:match
、:pred
はそれぞれ#equal
、#match
、#pred
と記述。一般的には述語の‘:’を‘#’に変更する。
たとえば、
'(( (compound_expression :anchor (_) @first (_) :* @rest) (:match "love" @first) ))
文字列形式では以下のように記述します
"( (compound_expression . (_) @first (_)* @rest) (#match \"love\" @first) )"
繰り返し使うことを意図したクエリー、とりわけタイトなループ(訳注 :少ない命令を含み多数回実行されるループ)では、クエリーのコンパイルが重要になります。なぜならコンパイル済みのクエリーは、コンパイルされていないものと比較して非常に高速だからです。クエリーの使用が許されている場所ならどこでもコンパイル済みクエリーを使うことができます。
この関数はlanguageのqueryをコンパイル済みクエリーオブジェクトにコンパイルして、それをリターンする。
この関数はqueryが不正な形式であればtreesit-query-error
エラーraiseする。シグナルデータには、その特定。エラーに関する説明が含まれている。クエリーの検証とデバッグにはtreesit-query-validate
を使うことができる。
この関数はqueryの言語をリターンする。
この関数はS式のqueryを文字列フォーマットに変換する。
この関数はS式のpatternを文字列フォーマットに変換する。
パターンマッチングに関する詳細については、https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queriesにあるtree-sitterプロジェクトのドキュメントを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プログラミング言語のソースの一部に他の言語のソースが含まれているときがあります。一例としてはHTML + CSS + JavaScriptが挙げられます。このような場合には、別の言語によって記述されたテキストセグメントには別のパーサーを割り当てる必要があります。伝統的にこれはナローイングの使用によって達成されてきました。tree-sitterはナローイング(narrowingを参照)とともに機能しますが、推奨される方法はバッファーテキストのリージョン(範囲)にそれを操作するパーサーを指定する方法です。このセクションではパーサーにたいして範囲のセットや取得を行う関数について説明します。
Lispプログラムがバッファーでパーサーを使う前には、treesit-update-ranges
の呼び出しによってパーサーそれぞれにたいする範囲が正しいか確認して、その位置にあるテキストにたいして任を負うパーサーを解決する必要があります。この2つの関数自身は作業を行わず、実際に作業を行うにはメジャーモードがtreesit-language-at-point-function
およびtreesit-language-at-point-function
をセットする必要があります。これらの関数および変数については、このセクションの終わり近くで詳細に説明しましょう。
この関数はrangesにたいして処理を行なうためにparserをセットアップする。parserが読み込むのは指定された範囲のテキストのみ。ranges内の範囲はそれぞれ(beg . end)
という形式のペアーである。
rangesの範囲は、以下の疑似コードのように重複せず順番に並んでいなければならない。
(cl-loop for idx from 1 to (1- (length ranges)) for prev = (nth (1- idx) ranges) for next = (nth idx ranges) should (<= (car prev) (cdr prev) (car next) (cdr next)))
rangesがこの制約に違反したり、何か他の問題が発生した場合には、この関数はtreesit-range-invalid
エラーをシグナルする。シグナルデータには特定のエラーメッセージ、セットを試みた範囲が含まれている。
この関数は範囲を無効にするためにも使うことができる。rangesがnil
の場合には、パーサーはバッファー全体をパースするようにセットされる。
例:
(treesit-parser-set-included-ranges parser '((1 . 9) (16 . 24) (24 . 25)))
この関数はparserにセットされている範囲をリターンする。リターン値はtreesit-parser-included-ranges
のranges引数と同じく(beg . end)
という形式のコンスセルのリスト。parserが範囲を何ももっていなければリターン値はnil
。
(treesit-parser-included-ranges parser) ⇒ ((1 . 9) (16 . 24) (24 . 25))
この関数はsourceをqueryでマッチングしてキャプチャーされたノードをリターンする。リターン値は(beg . end)
という形式のコンスセルのリスト。ここでbegとendはそれぞれテキスト範囲の開始と終了をする。
利便性のためにsourceは言語シンボル、パーサー、あるいはノードでもよい。この関数はそれが言語シンボルならその言語を使用する最初のパーサーのルートノード、パーサーならそのパーサーのルートノード、ノードならそのノードでマッチを行なう。
引数queryはノードのキャプチャーに用いるクエリー(tree-sitterノードにたいするパターンマッチングを参照)。引数begとendがどちらも非nil
なら、それはこの関数がクエリーを行なう範囲を制限する。
他のクエリー関数と同じように、この関数はqueryが不正であればtreesit-query-error
エラーをraiseする。
一般的なLispプログラムにおいて言語が複数ミックスされたプログラムをサポートするには、以下の2つの関数を呼び出すだけで十分です。
この関数はバッファーのパーサーの範囲を更新する。この関数はパーサーの範囲がbegとendの間に正しくセットされているかをtreesit-range-settings
に照らして確認する。省略された場合のデフォルトはbegがバッファー先頭、endがバッファー終端となる。
たとえばフォント表示(fontification)を行なう関数は、リージョン内のノードにクエリーを行う前にこの関数を使用する。
この関数はバッファー位置posにあるテキストの言語をリターンする。その背後ではtreesit-language-at-point-function
を呼び出して、そのリターンされた値をリターンしている。treesit-language-at-point-function
がnil
の場合には、この関数はtreesit-parser-list
のリターン値から最初のパーサーの言語をリターンする。バッファーにパーサーがなければnil
をリターンする。
ミックスされているかもしれない一連の言語では、ホスト言語(host language)と1つ以上の埋め込み言語(embedded languages)が存在することが珍しくありません。Lispプログラムはまずホスト言語のパーサーでドキュメント全体をパースすることで情報を得てから、それを用いて埋め込み言語の範囲をセット、その後に埋め込み言語をパースするのです。
HTML、CSS、それにJavaScriptを含むバッファーを例にとります。LispプログラムはまずHTMLパーサーでバッファー全体をパースして、それからパーサーにCSSとJavaScriptに相当するstyle_element
とscript_element
のノードをクエリーするのです。その後にCSSとJavaScriptそれぞれにたいして、対応するノードが跨がる範囲をセットします。
シンプルなHTMLドキュメントが与えられると:
<html> <script>1 + 2</script> <style>body { color: "blue"; }</style> </html>
LispプログラムはまずHTMLパーサーでパースを行い、それからCSSとJavaScriptそれぞれのパーサーにたいして範囲をセットします:
;; パーサーの作成 (setq html (treesit-parser-create 'html)) (setq css (treesit-parser-create 'css)) (setq js (treesit-parser-create 'javascript))
;; CSSの範囲をセット (setq css-range (treesit-query-range 'html '((style_element (raw_text) @capture)))) (treesit-parser-set-included-ranges css css-range)
;; JavaScriptの範囲をセット (setq js-range (treesit-query-range 'html '((script_element (raw_text) @capture)))) (treesit-parser-set-included-ranges js js-range)
treesit-update-ranges
によってEmacsがこのプロセスを自動化します。treesit-update-ranges
がプロセスを自動化する方法を解決するためには、複数言語のメジャーモードがtreesit-range-settings
をセットする必要があります。treesit-range-settings
に割り当てられる値を生成するためには、メジャーモードがヘルパー関数treesit-range-rules
を使う必要があります。この操作を直接コード化したのが以下のセッティング例になります。
(setq treesit-range-settings (treesit-range-rules :embed 'javascript :host 'html '((script_element (raw_text) @capture))
:embed 'css :host 'html '((style_element (raw_text) @capture))))
この関数はtreesit-range-settings
をセットするために用いる。クエリーのコンパイルやその他の後処理に注意を払い、treesit-range-settings
にセットできるような値を出力する。
この関数は引数として一連のquery-specを受け取る。ここでquery-specとは0個以上のkeyword/valueペアーが前置されたqueryのこと。queryはそれぞれ文字列、S式、コンパイル済みフォーム、あるいは関数のいずれかによるtree-sitterクエリーである。
queryがtree-sitterクエリーなら:keyword/valueのペアーを2つを前置すること(:keywordが:embed
は埋め込み言語、:host
はホスト言語)。
treesit-update-ranges
は埋め込み言語用のパーサーにたいして範囲をセットする方法の解決にqueryを使用する。ホスト言語パーサーにqueryを問い合わせてキャプチャーされたノードが跨ぐ範囲を計算、それらの範囲を埋め込み言語パーサーに適用するのである。
queryが関数の場合にはkeywordとvalueのペアーは必要ない。関数の場合にはstart、endという2つの引数を受け取り、カレントバッファーでstartとendの間にあるリージョンでパーサー用の範囲をセットすること。その関数がstartとendの間のリージョンを包むような広いリージョンに範囲をセットしても問題はない。
これはバッファーでtreesit-update-ranges
がパーサーにたいする範囲を更新する際の助けとなる変数である。settingのリストであり、その正確なフォーマットは内部的な使用を意図している。この変数が保持できる値を生成するにはtreesit-range-rules
を使うこと。
この変数の値はバッファー位置posを単一の引数として受け取り、posにあるテキストの言語をリターンする関数であること。この変数はtreesit-language-at
により使用される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではメジャーモード用にtree-sitterを統合した開発における一般的なガイドラインの一部について説明します。
tree-sitter機能をサポートするメジャーモードは、大枠では以下のようなパターンにしたがう必要があります:
(define-derived-mode woomy-mode prog-mode "Woomy" "A mode for Woomy programming language." (when (treesit-ready-p 'woomy) (setq-local treesit-variables ...) ... (treesit-major-mode-setup)))
treesit-ready-p
はtree-sitterを有効にする条件が揃っていなければ、自動的に警告を発します。
tree-sitterを使うメジャーモードは、その“ネイティブ”な相手先モードとセットアップを共有する場合には、以下のように共通のセットアップを含んだ“ベースモード”を作成することができます:
(define-derived-mode woomy--base-mode prog-mode "Woomy" "An internal mode for Woomy programming language." (common-setup) ...)
(define-derived-mode woomy-mode woomy--base-mode "Woomy" "A mode for Woomy programming language." (native-setup) ...)
(define-derived-mode woomy-ts-mode woomy--base-mode "Woomy" "A mode for Woomy programming language." (when (treesit-ready-p 'woomy) (setq-local treesit-variables ...) ... (treesit-major-mode-setup)))
この関数はtree-sitterをアクティブにするための条件をチェックする。tree-sitterとともにEmacsがビルドされているか、tree-sitterが処理するにあたってカレントバッファーのサイズが大き過ぎないか、そのシステムでlanguageにたいするグラマー(Tree-sitter Language Grammarを参照)が利用できるかどうかをチェックする。
この関数はtree-sitterをアクティブにできなければ警告を発する。quietがmessage
なら、警告をメッセージに変更する。quietがt
の場合には警告やメッセージは何も表示されない。
この関数は必要とされる条件すべてが適えば非nil
、そうでなければnil
をリターンする。
この関数はメジャーモードにたいしてtree-sitterに一部機能をアクティブにする。
現在のところ以下の機能のセットアップを行う:
treesit-font-lock-settings
(パーサーベースのFont Lockを参照)が非nil
ならフォント表示(fontification)をセットアップ。
treesit-simple-indent-rules
(パーサーベースのインデントを参照)が非nil
ならインデントをセットアップ。
treesit-defun-type-regexp
が非nil
なら、beginning-of-defun
とend-of-defun
にたいしてナビゲーション関数をセットアップ。
treesit-defun-name-function
が非nil
なら、add-log-current-defun
によって使用されるadd-log関数をセットアップ。
treesit-simple-imenu-settings
が非nil
ならImenuをセットアップ。
これらtree-sitter組み込み機能の詳細についてはパーサーベースのFont Lock、パーサーベースのインデント、釣り合いのとれたカッコを越えた移動を参照してください。
メジャーモードにおける複数言語のミックスのサポートについては複数言語ののパースを参照してください。
beginning-of-defun
やend-of-defun
の他にも、Emacsはdefunにたいして処理を行う追加の関数をいくつか提供します。treesit-defun-at-point
はポイント位置のdefunノード、treesit-defun-name
はdefunノードの名前をリターンする関数です。
この関数はポイント位置のdefunノードを、defunが見つからなければnil
をリターンする。この関数はtreesit-defun-tactic
に注意を払う。この変数の値がtop-level
ならトップレベルのdefunを、値がnested
ならすぐ外側のdefunをリターンする。
この関数が機能するためにはtreesit-defun-type-regexp
が必要となる。この変数の値がnil
であれば、この関数は単にnil
をリターンする。
この関数はnodeのdefun名をリターンする。nodeにたいするdefun名が存在しない、nodeがdefunノードではない、あるいはnodeがnil
の場合はnil
をリターンする。
言語とメジャーモードに応じて関数、クラス、構造体等の名前がdefun名となる。
treesit-defun-name-function
がnil
の場合には、この関数は常にnil
をリターンする。
この変数の値が非nil
の場合には、ノードを引数として呼び出されてそのノードの名前をリターンする関数であること。この関数は意味合いとしてはtreesit-defun-name
と同じである必要がある。つまりそのノードがdefunノードではない、defunノードだが名前がない、あるいはノードがnil
の場合にはnil
をリターンすること。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsのtree-sitter統合では、tree-sitterのCのAPIによって提供されるすべての機能が公開されている訳ではありません。欠落している機能には以下が含まれます:
更にEmacsでは、APIがより使いやすく慣れ親しんだ用語を用いるようにCのAPIの一部を変更しています:
nil
に変換。
CのすべてのAPIとELisp側での相方の対応を以下にまとめました。1つのElispがCの複数の関数に対応する場合もあるし、Elisp側の相方がいないC関数も沢山あります。
ts_parser_new treesit-parser-create ts_parser_delete ts_parser_set_language ts_parser_language treesit-parser-language ts_parser_set_included_ranges treesit-parser-set-included-ranges ts_parser_included_ranges treesit-parser-included-ranges ts_parser_parse ts_parser_parse_string treesit-parse-string ts_parser_parse_string_encoding ts_parser_reset ts_parser_set_timeout_micros ts_parser_timeout_micros ts_parser_set_cancellation_flag ts_parser_cancellation_flag ts_parser_set_logger ts_parser_logger ts_parser_print_dot_graphs ts_tree_copy ts_tree_delete ts_tree_root_node ts_tree_language ts_tree_edit ts_tree_get_changed_ranges ts_tree_print_dot_graph ts_node_type treesit-node-type ts_node_symbol ts_node_start_byte treesit-node-start ts_node_start_point ts_node_end_byte treesit-node-end ts_node_end_point ts_node_string treesit-node-string ts_node_is_null ts_node_is_named treesit-node-check ts_node_is_missing treesit-node-check ts_node_is_extra treesit-node-check ts_node_has_changes ts_node_has_error treesit-node-check ts_node_parent treesit-node-parent ts_node_child treesit-node-child ts_node_field_name_for_child treesit-node-field-name-for-child ts_node_child_count treesit-node-child-count ts_node_named_child treesit-node-child ts_node_named_child_count treesit-node-child-count ts_node_child_by_field_name treesit-node-child-by-field-name ts_node_child_by_field_id ts_node_next_sibling treesit-node-next-sibling ts_node_prev_sibling treesit-node-prev-sibling ts_node_next_named_sibling treesit-node-next-sibling ts_node_prev_named_sibling treesit-node-prev-sibling ts_node_first_child_for_byte treesit-node-first-child-for-pos ts_node_first_named_child_for_byte treesit-node-first-child-for-pos ts_node_descendant_for_byte_range treesit-node-descendant-for-range ts_node_descendant_for_point_range ts_node_named_descendant_for_byte_range treesit-node-descendant-for-range ts_node_named_descendant_for_point_range ts_node_edit ts_node_eq treesit-node-eq ts_tree_cursor_new ts_tree_cursor_delete ts_tree_cursor_reset ts_tree_cursor_current_node ts_tree_cursor_current_field_name ts_tree_cursor_current_field_id ts_tree_cursor_goto_parent ts_tree_cursor_goto_next_sibling ts_tree_cursor_goto_first_child ts_tree_cursor_goto_first_child_for_byte ts_tree_cursor_goto_first_child_for_point ts_tree_cursor_copy ts_query_new ts_query_delete ts_query_pattern_count ts_query_capture_count ts_query_string_count ts_query_start_byte_for_pattern ts_query_predicates_for_pattern ts_query_step_is_definite ts_query_capture_name_for_id ts_query_string_value_for_id ts_query_disable_capture ts_query_disable_pattern ts_query_cursor_new ts_query_cursor_delete ts_query_cursor_exec treesit-query-capture ts_query_cursor_did_exceed_match_limit ts_query_cursor_match_limit ts_query_cursor_set_match_limit ts_query_cursor_set_byte_range ts_query_cursor_set_point_range ts_query_cursor_next_match ts_query_cursor_remove_match ts_query_cursor_next_capture ts_language_symbol_count ts_language_symbol_name ts_language_symbol_for_name ts_language_field_count ts_language_field_name_for_id ts_language_field_id_for_name ts_language_symbol_type ts_language_version
[ << ] | [ < ] | [ 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を参照してください。
38.1 abbrevテーブル | abbrevテーブルの作成と操作。 | |
38.2 abbrevの定義 | 略語の指定とそれらの展開。 | |
38.3 ファイルへのabbrevの保存 | ||
38.4 略語の照会と展開 | 展開の制御と展開サブルーチン。 | |
38.5 標準abbrevテーブル | 種々メジャーモードに使用されるabbrevテーブル。 | |
38.6 abbrevプロパティ | abbrevプロパティの読み取りとセットを行う方法。どのプロパティが何の効果をもつか。 | |
38.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内に保存する。保存すべきabbrevがないテーブルは省略する。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テーブルtableがそのようなをプロパティもたなければ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] | [ ? ] |
Emacs Lispはスレッド(thread)と呼ばれる限定的な並行性(concurrency)の形式を提供します。Emacsの与えられたインターフェース内のすべてのスレッドは同じメモリーを共有します。Emacs Lisp内の並行性は“概ね協調的(mostly cooperative)”であり、これはEmacsがスレッド間の実効を明確に定義された時間にだけ切り替えることを意味しています。しかしEmacsでのスレッドのサポートは将来よりきめの細かい並行性が可能な方法でデザインされており、正しいプログラムは協調的なスレッドに依存するべきではありません。
現在のところスレッドの切り替えはキーボード入力や非同期プロセスからの出力の待機中(つまりaccept-process-output
の間)、ミューテックスのロックやthread-join
のようなスレッドに関連するブロッキング処理の間での、thread-yield
を介した明示的な要求時に発生します。
Emacs Lispはスレッドの作成や制御、さらにスレッドの同期に有用なミューテックスや条件変数の作成や制御を行うプリミティブを提供します。
グローバル変数はEmacs
Lispのすべてのスレッドの間で共有されますがローカル変数(let
によるダイナミックなバインドはローカル)は異なります。スレッドはそれぞれ自身のカレントバッファー(カレントバッファーを参照)と自身のマッチデータ(マッチデータを参照)を所有します。
let
によるバイディングはEmacs
Lisp実装により特別に処理されることに注意してください。let
の使う以外にこのunwind(巻き戻し)とrewind(巻き戻すための巻き取り)の振る舞いを複製する方法はありません。たとえばunwind-protect
を使用してlet
の独自実装で記述しても変数値をスレッド固有にアレンジすることはできません。
レキシカルバインディング(変数のバインディングのスコーピングルールを参照)の場合には他のEmacs Lispオブジェクト類似するものはクロージ(closure)です。クロージャ内のバインディングはクロージャを呼び出したすべてのスレッド間で共有されます。
39.1 基本的なスレッド関数 | ||
39.2 ミューテックス | データへの排他アクセスを可能にするミューテックス。 | |
39.3 条件変数 | スレッド間のイベント。 | |
39.4 スレッドリスト | アクティブなスレッドの表示。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
スレッドを作成したり待機することができます。スレッドを直接exitすることはできませんがカンレントスレッドは暗黙にexitでき、他のスレッドはシグナルを受け取ることができます。
functionを呼び出す新たなスレッドの実行を作成する。functionのリターン時にスレッドはexitする。
新たなスレッドは効力をもつローカル変数のバインディングが何もない状態で作成される。新たなスレッドのカレントバッファーはカレントスレッドから継承される。
nameでスレッドに名前を与えることができる。これはデバッグと情報的な用途だけに使用される名前であり、Emacsにとって意味はない。nameを与える場合には文字列でなければならない。
この関数は新たなスレッドをリターンする。
この関数はobjectがEmacsスレッドを表すならt
、それ以外はnil
をリターンする。
threadがexitするかカレントスレッドがシグナルされるまでブロックする。これはthread関数の結果をリターンする。threadがexit済みなら即座にリターンする。
signal
(エラーをシグナルする方法を参照)と同様だがシグナルはスレッドthreadに送信される。threadがカレントスレッドなら、即座にsignal
を呼び出す。それ以外ならthreadがカレントになり次第、シグナルを受信する。mutex-lock
、condition-wait
、thread-join
の呼び出しによりthreadがブロックされていたらthread-signal
がロックを解除する。
threadがメインスレッドならシグナルは伝播されない。かわりにメインスレッド内のメッセージとして表れる。
実行可能な次のスレッドに実行を譲り渡す。
make-thread
で指定されたthreadの名前をリターンする。
threadが生きていればt
、それ以外はnil
をリターンする。スレッドは自身の関数がまだ実行中なら生きている。
threadが待機中のオブジェクトをリターンする。これは主にデバッグを糸した関数であり、それを示すために“2重ハイフン”の名前を付与してある。
threadがthread-join
内でブロックされていたら待機対象のスレッドをリターンする。
threadがmutex-lock
内でブロックされていたらミューテックスをリターンする。
threadがcondition-wait
内でブロックされていたら条件変数をリターンする。
それ以外ならnil
をリターンする。
カレントスレッドをリターンする。
すべての生きたスレッドオブジェクトのリストをリターンする。呼び出しそれぞれにたいして新たなリストをリターンする。
この変数はEmacs実行中のメインスレッド、スレッドサポートなしでEmacsコンパイル時にはnil
を保持する。
スレッドが実行したコードがハンドルされないエラーをシグナルすると、そのスレッドはexitします。それ以外のスレッドは以下の関数を使用してスレッドのexitを誘発したエラーフォームにアクセスできます。
この関数はエラーによりスレッドがexitした際に記録された最後のエラーフォームをリターンする。異常終了(abnormal
exit)した各スレッドが、以前にスレッドエラーで格納されたフォームを新たな値に上書きするので、アクセスできるのは最後のフォームのみ。cleanupが非nil
なら格納されたフォームをnil
にリセットする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ミューテックス(mutex)は排他的なロックです。任意のタイミングにおいて0、または1つのスレッドがミューテックスを所有できます。スレッドがミューテックスの取得を試みたときに別スレッドがすでにそのミューテックスを所有していたら、ミューテックスが利用可能になるまで取得を試みたスレッドはブロックされます。
Emacs Lispのミューテックスは再帰的(recursive)と呼ばれるタイプです。これはスレッドがミューテックスを何回も再帰的に所有できることを意味します。ミューテックスは所有された回数を保持していて、それら所有のそれぞれがリリースとペアになっていなければなりません。スレッドによるミューテックスの最後のリリースによりミューテックスは他のスレッドが潜在的に所有可能である非所有な状態へとリバートされます。
この関数はobjectがEmacsのミューテックスを表していればt
、それ以外はnil
をリターンする。
新たなミューテックスを作成してリターンする。nameが指定されたらミューテックスの名前として与えられる(文字列でなければならない)。これはデバッグにたいする用途のみの名前でありEmacsにとって意味はない。
make-mutex
で指定されたmutexの名前をリターンする。
これはスレッドがmutexを所有するか、スレッドがthread-signal
の使用によりシグナルされるまでブロックする。スレッドがmutexをすでに所有していたら単にリターンする。
mutexをリリースする。そのスレッドがmutexを所有していなければエラーをシグナルする。
このマクロはもっともシンプルかつ安全にミューテックスを保持しつつフォームを評価する方法である。これはmutexを取得してbodyを呼び出してからmutexをリリースする。bodyの結果をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
条件変数(condition variable)は何らかのイベントが発生するまでスレッドをブロックするための手段です。スレッドは別のスレッドが条件を通知した際に目覚めるように条件変数を待機できます。
条件変数はミューテックス、および概念的に何らかの条件に関連付けられます。正しく操作するために、ミューテックスを所有してから待機スレッドはループして、条件のテストを行い条件変数を待機しなければなりません。たとえば:
(with-mutex mutex (while (not global-variable) (condition-wait cond-var)))
ミューテックスはアトミック操作のために、ループは堅牢性のためのものです。これは偽の通知があるかもしれないからです。
同様にミューテックスは条件の通知前に所持されていなければなりません。ミューテックスを所有して条件に関連する変更を行い、それを通知するのが典型的かつ最良なアプローチです:
(with-mutex mutex (setq global-variable (some-computation)) (condition-notify cond-var))
mutexに関連付けられた条件変数を作成する。nameが指定されたら条件変数の名前として与えられる(文字列でなければならない)。これはデバッグにたいする用途のみの名前でありEmacsにとって意味はない。
この関数はobjectが条件変数を表していればt
、それ以外はnil
をリターンする。
他のスレッドによる条件変数condの通知を待機する。この関数は条件変数の通知、またはthread-signal
の使用によりシグナルが送信されるまでブロックする。
ミューテックスに関連付けられた条件を所持しないcondition-wait
の呼び出しはエラーとなる。
condition-wait
は待機中に関連付けられたミューテックスをリリースする。これは別スレッドによる条件通知するためのミューテックス所有を可能にする。
condを通知する。呼び出し前にcondに関連付けられるミューテックスを所有しなければならない。通常はcondition-notify
により単一の待機中スレッドが目覚めさせられる。しかしallが非nil
ならcondを待機中のすべてのスレッドに通知される。
condition-notify
は関連付けられたミューテックスを待機中はリリースする。これによりスレッドが条件を待機するためにミューテックスを所有することが可能になる。
make-condition-variable
に渡されたcondの名前をリターンする。
condに関連付けられたミューテックスをリターンする。関連付けられたミューテックスは変更できないことに注意。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
list-threads
コマンドはカレントでアクティブなすべてのスレッドをリストします。その結果となるバッファー内では、それぞれのスレッドはmake-thread
(基本的なスレッド関数を参照)に渡された名前、または名前つきで作成されていなければ一意な内部識別子により識別される。バッファーの作成時(または最終更新時)の各スレッドの状態、さらにその時点でスレッドがブロックされていたらブロックしているオブジェクトが表示されます。
*Threads*バッファーは自動的に毎秒2回更新される。この変数をカスタマイズしてリフレッシュ間隔を加減できる。
以下はレッドリストバッファーで利用できるコマンドです:
ポイント位置のスレッドのバックトレースを表示する。これはbを押下した時点でスレッドが生成またはブロックされたコードを表示する。このバックトレースはスナップショットであることに注意。それ以降にスレッドが実行を再開して異なる状態になったりexitしているかもしれない。
バックトレースバッファーは自動的に更新されないので、スレッドのバックトレースバッファーでは、更新されたバックトレースを取得するためにgを使用できる。バックトレースおよびそれらに機能する他のコマンドの説明はバックトレースを参照のこと。
ポイント位置のスレッドにシグナルを送信する。sの後にqをタイプするとquit、eをタイプするとエラーをシグナルする。スレッドはシグナルを処理するように実装されているかもしれないが、デフォルトではすべてのシグナルにたいしてexitする。したがってターゲットとなるスレッドの再開方法を理解している場合のみこのコマンドを使用すること(必要なスレッドがkillされるとEmacsセッションは不正に振る舞うかもしれない)。
スレッドのリストと状態を更新する。
[ << ] | [ < ] | [ 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セッションのサブプロセスに加えて、そのマシン上で実行中の他のプロセスにアクセスすることもできます。別のプロセスへのアクセスを参照してください。
40.1 サブプロセスを作成する関数 | サブプロセスを開始する関数。 | |
40.2 shell引数 | shellに渡すために引数をクォートする。 | |
40.3 同期プロセスの作成 | 同期サブプロセス使用の詳細。 | |
40.4 非同期プロセスの作成 | 非同期サブプロセスの起動。 | |
40.5 プロセスの削除 | 非同期サブプロセスの削除。 | |
40.6 プロセスの情報 | 実行状態および他の属性へのアクセス。 | |
40.7 プロセスへの入力の送信 | 非同期サブプロセスへの入力の送信。 | |
40.8 プロセスへのシグナルの送信 | 非同期サブプロセスの停止、継続、割り込み。 | |
40.9 プロセスからの出力の受信 | 非同期サブプロセスからの出力の収集。 | |
40.10 センチネル: プロセス状態の変更の検知 | プロセスの実行状態変更時に実行されるセンチネル。 | |
40.11 exit前の問い合わせ | exitによりプロセスがkillされる場合に問い合わせるかどうか。 | |
40.12 別のプロセスへのアクセス | そのシステム上で実行中の別プロセスへのアクセス。 | |
40.13 トランザクションキュー | サブプロセスとのトランザクションベースのコミュニケション。 | |
40.14 ネットワーク接続 | ネットワーク接続のopen。 | |
40.15 ネットワークサーバー | Emacsによるネット接続のacceptを可能にするネットワークサーバー。 | |
40.16 データグラム | UDPネットワーク接続。 | |
40.17 低レベルのネットワークアクセス | 接続およびサーバーを作成するための、より低レベルだがより汎用的な関数。 | |
40.18 その他のネットワーク機能 | ネット接続用の追加の関連する関数。 | |
40.19 シリアルポートとの対話 | シリアルポートでのやり取り。 | |
40.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
の変更を試みると混乱した結果へと導かれ得る。
この関数は変数exec-path
の拡張である。default-directory
がリモートパスを示す場合には、この関数は対応するリモートホスト上でプログラム検索に使用するデジレクトリーのリストをリターンする。default-directory
がローカルにあれば、この関数は単に変数exec-path
の値をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispプログラムがshellを実行して、ユーザーが指定したファイル名を含むコマンドを与える必要がある場合が時折あります。これらのプログラムは任意の有効なファイル名をサポート可能であるはずです。しかしshellは特定の文字を特別に扱い、それらの文字がファイル名に含まれているとshellを混乱させるでしょう。これらの文字を処理するためには関数shell-quote-argument
を使用します。
この関数は実際のコンテンツがargumentであるような引数を表す文字列をshellの構文でリターンする。リターン値をshellコマンドに結合して実行のためにそれをshellに渡すことにより、信頼性をもって機能するはずである。
この関数が正確に何を行うかはオペレーティングシステムに依存する。この関数はそのシステムの標準shellの構文で機能するようデザインされている。非標準のshellを使用する場合には、この関数を再定義する必要があるだろう。セキュリティへの配慮を参照のこと。
;; この例は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))
オプションのposix引数が非nil
の場合には、そのシステムのシェルに関わらず、argumentはPOSIXシェルのクォート規制によってクォートされる。これは一般的にはPOSIXシェルが要求されるリモートホスト上でシェルを実行する際に役に立つだろう。
(shell-quote-argument "foo > bar" (file-remote-p default-directory))
以下の2つの関数はコマンドライン引数の文字列のリストを単一の文字列に結合したり、単一の文字列を個別のコマンドライン引数のリストへ分割するために有用です。これらの関数は主にミニバッファーでのユーザー入力であるLisp文字列をmake-process
、call-process
やstart-process
に渡す文字列引数のリストへ変換したり、そのような引数のリストをミニバッファーやエコーエリアに表示するためのLisp文字列に変換することを意図しています。(call-process-shell-command
を使用して)shellが呼び出される場合には、引数を依然としてshell-quote-argument
で保護する必要があることに注意。combine-and-quote-strings
はshellの評価から特殊文字を保護することを意図していない。
この関数はダブルクォート、シングルクォートと同様にバックスラッシュによるクォートにも注意を払い、stringを部分文字列に分割する。
(split-string-shell-command "ls /tmp/'foo bar'") ⇒ ("ls" "/tmp/foo bar")
この関数は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やUnix28でのDiredの起動が例です。プロセスは同期的なので、Emacsがそれにたいして何か行おうと試みる前にディレクトリーのリスト全体がバッファーに到着します。
同期サブプロセス終了をEmacsが待機する間に、ユーザーはC-gをタイプすることでquitが可能です。最初のC-gはSIGINT
シグナルによりサブプロセスのkillを試みます。しかしこれはquitする前に実際にそのサブプロセスが終了されるまで待機します。その間にユーザーがさらにC-gをタイプするとそれはSIGKILL
で即座にサブプロセスをkillしてquitします(別プロセスにたいするkillが機能しないMS-DOSを除く)。quitを参照してください。
同期サブプロセス関数はプロセスがどのように終了したかの識別をリターンします。
同期サブプロセスからの出力はファイルからのテキスト読み込みと同じように、一般的にはコーディングシステムを使用してデコードされます。call-process-region
によりサブプロセスに送信された入力は、ファイルへのテキスト書き込みと同じようにコーディングシステムを使用してエンコードされます。コーディングシステムを参照してください。
この関数はprogramを呼び出して完了するまで待機する。
サブプロセスのカレント作業ディレクトリー(CWD: current working
directory)はカレントバッファーのdefault-directory
がローカル(unhandled-file-name-directory
により判断される)ならその値、それ以外は"~"。リモートディレクトリーでプロセスを実行したければprocess-file
を使用すること。
新たなプロセスの標準入力は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
が有用。かわりにリモートホスト視点から見た絶対ファイル名を取得するためにfile-local-name
も使用できる(特定のファイル名の“Magic”の作成を参照)。
この変数はprocess-file
呼び出しがリモートファイルを変更するかどうかを示す。
この変数はデフォルトではprocess-file
呼び出しがリモートホスト上の任意のファイルを潜在的に変更し得ることを意味するt
に常にセットされる。nil
にセットされた際には、リモートファイル属性のキャッシュにしたがうことによりファイル名ハンドラーの挙動を最適化できる可能性がある。
この変数は決してsetq
ではなく、常にletバインディングでのみ変更すること。
このユーザーオプションは、リモートプロセスに割り込んだシグナルを記述する文字列をprocess-file
呼び出しがリターンするかどうかを示す。
プロセスが128より大なexitコードをリターンしたら、それはシグナルとして解釈される。process-file
はこのシグナルを説明する文字列のリターンを求められる。
この規約に違反するプロセスが存在するために、シグナルにバインドされない128より大なexitコードのリターンでは、常にprocess-file
はリモートプロセスにたいする自然数としてexitコードをリターンする。このユーザーオプションを非nil
にセットすることによって、そのようなexitコードをシグナルとして解釈して、それに対応する文字列をリターンするようにprocess-file
に強制することができる。
この関数は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-shell-region
を使用する:
(call-shell-region
start end
command ; shellコマンド
nil ; regionを削除しない
buffer) ; 出力をbuffer
に出力
この関数はshellコマンドcommandを非同期に実行する。他の引数はcall-process
の場合と同様に処理される。古い呼び出し規約はdisplayの後に任意個数の追加引数を許容して、これはcommandに結合される。これはまだサポートされるものの使用しないことを強く推奨する。
この関数はcall-process-shell-command
と同様だが内部的にprocess-file
を使用する点が異なる。default-directory
に依存してcommandはリモートホスト上でも実行可能。古い呼び出し規約はdisplayの後に任意個数の追加引数を許容して、これはcommandに結合される。これはまだサポートされるものの使用しないことを強く推奨する。
この関数はstartとendの間のテキストを、commandを実行するシェルの標準入力として送信する。これはプロセスがシェルであるようなcall-process-region
と類似している。引数delete
、destination
、およびリターン値はcall-process-region
と同様。この関数は追加の引数を受け付けないことに注意。
この関数はshellコマンドとしてcommand (文字列)を実行してコマンドの出力を文字列としてリターンする。
この関数はprogramを実行して完了を待機して、出力を文字列のリストとしてリターンする。リスト内の各文字列はプログラムのテキスト出力の1つの行を保持する。各行のEOL文字(行末文字)は取り除かれる。programの後の引数argsはそのプログラム実行に際して、コマンドライン引数を指定する文字列。
programが非0のexitステータスでexitすると、この関数はエラーをシグナルする。
この関数はcall-process
を呼び出すことにより機能して、プログラムの出力はcall-process
の場合と同じ方法でデコードされる。
この関数はprocess-lines
と同様だが、programが非0のexitステータスでexitした場合にエラーをシグナルしない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは非同期プロセス(asynchronous process)を作成する方法について説明します。非同期プロセスは作成後にEmacsと並列して実行され、Emacsは以降のセクション(プロセスへの入力の送信とプロセスからの出力の受信を参照)で説明する関数を使用してプロセスとコミュニケーションができます。プロセスコミュニケーションは部分的に非同期なだけであることに注意してください。Emacsはこれらの関数を呼び出したときだけプロセスとのデータを送受信できます。
非同期プロセスはpty(pseudo-terminal:
疑似端末)、またはpipeのいずれかを通じて制御されます。ptyかpipeの選択はデフォルトでは変数process-connection-type
(以下参照)の値にもとづいてプロセス作成時に行われます。Shellモードのように利用可能ならユーザーから可視なプロセスには、プロセスと子プロセス間でジョブ制御(C-c、C-z等)が可能であり、インタラクティブなプログラムではptyを端末デバイスとして扱いますがpipeはそのような機能をサポートしないのでptyが通常は好まれます。しかし内部的な目的のためにLispプログラムが使用する(サブプロセスとユーザーの相互作用が要求されない)サブプロセスでは、サブプロセスとLispプログラム間で大量データのやり取りが要求される場合には、pipeがより効率的なのでpipeの使用が最良な場合がままあります。さらに多くのシステムでは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
を指定できる。typeがコンスセル(input . output)
の場合には、標準入力にinput、標準出力(および:stderr
がnil
なら標準エラーも)にoutputが使用される。
ptyが利用できないシステム(MS-Windows)ではこのパラメーターを無視して、無条件でpipeが使用される。
プロセスqueryフラグをquery-flagに初期化する。exit前の問い合わせを参照のこと。
stoppedが与えられた場合にはnil
でなければならない。非nil
値の使用はすべてエラーとなる。それ以外の場合には:stop
は無視される。これはpipeプロセスのような他のプロセスタイプへの互換性のために維持されている。非同期サブプロセスがstopped状態で開始されることはあり得ない。
プロセスフィルターをfilterに初期化する。未指定ならデフォルトフィルターが提供されるが、これは後からオーバーライドできる。プロセスのフィルター関数を参照のこと。
プロセスセンチネルをsentinelに初期化する。未指定ならデフォルトセンチネルが使用されるが、これは後からオーバーライドできる。センチネル: プロセス状態の変更の検知を参照のこと。
プロセスの標準エラーにstderrを割り当てる。値が非nil
ならバッファー、または以下で説明するmake-pipe-process
で作成されたpipeのいずれかであること。stderrがnil
なら標準エラーを標準出力と合成して、両者をbufferかfilterに送信する。
stderrがバッファーならEmacsはpipeプロセス、標準エラープロセス(standard error
process)を作成する。このプロセスはデフォルトフィルター(プロセスのフィルター関数を参照)、センチネル(センチネル: プロセス状態の変更の検知を参照)、コーディングシステム(デフォルトのコーディングシステムを参照)をもつ。その一方で、自身のquery-on-exitフラグとしてquery-flagを使用する(exit前の問い合わせを参照)。このプロセスはstderrバッファーに関連づけられて、そこに出力(メインプロセスの標準エラー)を送信する(プロセスのバッファーを参照)。標準エラープロセスにたいするプロセスオブジェクトを取得するには、get-buffer-process
にstderrバッファーを渡せばよい。
stderrがpipeプロセスなら、Emacsはそれを新たなプロセス用の標準エラープロセスとして使用する。
file-handlerが非nil
なら、カレントバッファーのdefault-directory
にたいするファイル名ハンドラーを探して、プロセスを作成するためにそのファイル名ハンドラーを呼び出す。そのようなハンドラーがなければ、file-handlerがnil
であるかのように処理する。
実際の接続情報で修正されたオリジナルの引数リストはprocess-contact
を通じて利用できる。
サブプロセスのカレント作業ディレクトリー(CWD: current working
directory)はカレントバッファーのdefault-directory
がローカル(unhandled-file-name-directory
により判断される)ならその値、それ以外は~。リモートディレクトリーでプロセスを実行したければ、make-process
に:file-handler
t
を渡せばよい。この場合には、カレントのワーキングディレクトリー(CWD)はdefault-directory
の(file-local-name
で決定される)ローカル部分となる。
ファイル名ハンドラーの実装に依存して、結果となるプロセスオブジェクトへのfilterやsentinelの適用が不可能かもしれない。:stderr
引数はpipeプロセスではあり得ないので、ファイル名ハンドラーはこれにたいしてpipeプロセスをサポートしない。:stderr
引数としてバッファーは許されており、バッファーのコンテンツはpipeプロセスを使用することなく表示される。プロセスのフィルター関数およびプロセスの出力を受け取るを参照のこと。
いくつかのファイルハンドラーはmake-process
をサポートしないかもしれない。そのような場合には、この関数は何も行わずにnil
をリターンする。
この関数は子プロセスにアタッチ可能な双方向の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
なら停止状態でプロセスを開始する。停止状態ではpipeプロセスは入力データを受け取らないが出力データは送信できる。停止状態はstop-process
でセットしてcontinue-process
でクリアーされる(プロセスへのシグナルの送信を参照)。
プロセスフィルターを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の残りにたいしてファイル名ハンドラーの呼び出しを試みない。programはargsのいずれかがリモートファイル構文(特定のファイル名の“Magic”の作成を参照)を使用する場合には、file-local-name
を通じて実行することにより、それらの名前をdefault-directory
に相対的な名前やリモートホスト上でローカルにファイルを識別する名前に変換しなければならないことが理由。
そのファイル名ハンドラーの実装によっては、リターン結果のプロセスオブジェクトに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
の呼び出し時に効果を発揮する。そのためにこれらの関数の呼び出し前後でこの変数をバインドすることにより、サブプロセスとやり取りする方法を指定できる。
この変数の値は非nil
値の:stderr
パラメーターでmake-process
が呼び出された際には無視される。この場合にはEmacsはpipeを使用してプロセスと対話する。ptyが利用不能(MS-Windows)な場合にも無視される。
(let ((process-connection-type nil)) ; pipeを使用
(start-process …))
与えられたサブプロセスが実際にはpipeとptyのどちらを取得したかを判断するには関数process-tty-name
を使用する(プロセスの情報を参照)。
もしプロセスのセンチネルやフィルターの関数にエラーがあると、Emacsはそのエラーを表示した後に、ユーザーが問題となっているエラーを確認できるように(デフォルトでは)process-error-pause-time
に設定された秒数の間一時停止する。ただしEmacsが応答しなくなる状況に導かれる可能性もある(あまりに大量のエラーが発生した場合など)ので、process-error-pause-time
を0にセットして無効にできる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プロセス削除(deleting a process)とはEmacsをサブプロセスから即座に切断することです。プロセスは終了後に自動的に削除されますが即座に削除される必要はありません。任意のタイミングで明示的にプロセスを削除できます。終了したプロセスが自動的に削除される前に明示的に削除しても害はありません。実行中のプロセスの削除はプロセス(もしあれば子プロセスにも)を終了するためにシグナルを送信してプロセスセンチネルを呼び出します。センチネル: プロセス状態の変更の検知を参照してください。
プロセスが削除される際、そのプロセスオブジェクト自体はそれを参照する別のLispオブジェクトが存在する限り継続し続けます。プロセスオブジェクトに作用するすべてのLispプリミティブはプロセスの削除を受け入れますが、I/Oを行ったりシグナルを送信するプリミティブはエラーを報告するでしょう。プロセスマークは通常はプロセスからの出力がバッファーに挿入される箇所となる、以前と同じ箇所をポイントし続けます。
この変数は、(exit
呼び出しやシグナルにより)終了したプロセスの自動的な削除を制御する。これがnil
ならユーザーがlist-processes
を実行するまでプロセスは存在し続けて、それ以外ならexit後に即座に削除される。
この関数はプロセスがプログラムを実行していたらSIGKILL
シグナルでkillすることによりプロセスを削除する。引数はプロセス、プロセスの名前、バッファー、バッファーの名前かもしれない(バッファーやバッファー名ならget-buffer-process
がリターンするプロセスを、processが省略またはnil
ならカレントバッファーのプロセスをkillする必要があることを意味する)。実行中のプロセスに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>)
この関数はプロセッサー数を正の整数としてリターンする。使用可能なスレッドの各実行ユニットはプロセッサーとしてカウントされる。このカウントにはデフォルトでは利用できるプロセッサー数が含まれる。これはOpenMPの環境変数OMP_NUM_THREADS
ををセットすることによってオーバーライドできる。オプション引数queryがcurrent
なら、この関数はOMP_NUM_THREADS
を無視する。queryがall
ならシステム上にあるがカレントプロセスで利用できないプロセッサーもカウントする。
この関数は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がまだ完全にセットアップされていない非ブロッキングネットワークストリームなら、この関数はセットアップされるまでブロックする。オプションのno-blockパラメーターが与えられると、この関数はブロックせずにnil
をリターンする。
この関数は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の標準ストリームのいずれかが端末を使用していれば、デフォルトではその端末の名前をリターンする。streamがstdin
、stdout
、stderr
のいずれかであれば、この関数は特にそのストリームにたいしてprocessが使用している端末の名前(または上述したようにnil
)をリターンする。これを用いれば、特定のストリームがpipeとptyのどちらを使用しているかを判断できる。
この関数はprocessがリモートホストで実行中のプログラムを表す場合には、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の子プロセス以外のプロセスにシグナルを送信できる。別のプロセスへのアクセスを参照のこと。
processがプロパティremote-pid
をもつプロセスオブジェクト、あるいはprocessが数値でremoteがリモートファイル名の場合には、processはプロセスにシグナルを送信するリモートホスト上のプロセスとして解釈される。
非ローカルな非同期プロセスへのシグナル送信が必要になることがあります。これはinterrupt-process
およびsignal-process
にたいして実装を独自に記述することにより可能です。それからそれらの関数をそれぞれinterrupt-process-functions
およびsignal-process-functions
に追加する必要があります。
この変数はinterrupt-process
用に呼び出される関数のリスト。関数の引数はinterrupt-process
にたいする引数と同じ。これらの関数はいずれかが非nil
をリターンするまでリスト順に呼び出される。このリスト上で常に最後になるデフォルトの関数はinternal-default-interrupt-process
。
これはTrampがinterrupt-process
を実装するメカニズムである。
この変数はsignal-process
用に呼び出される関数のリスト。関数の引数はsignal-process
にたいする引数と同じ。これらの関数はいずれかが非nil
をリターンするまでリスト順に呼び出される。このリスト上で常に最後になるデフォルトの関数はinternal-default-signal-process
。
これはTrampがsignal-process
を実装するメカニズムである。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
非同期サブプロセスが自身の標準出力に書き込んだ出力はフィルター関数(filter function)と呼ばれる関数に渡されます。デフォルトのフィルター関数は単に出力をバッファーに挿入します。このバッファーをプロセスに関連付けられたバッファーと呼びます(プロセスのバッファーを参照)。プロセスがバッファーをもたなければデフォルトフィルターは出力を破棄します。
サブプロセスが自身の標準エラーストリームに書き込む場合には、デフォルトではそのエラー出力もプロセスフィルター関数に渡されます。かわりに非nil
の:stderr
パラメーターでmake-process
(make-processを参照)を呼び出して、エラーの出力先を標準出力から分けることができます。
サブプロセス終了時にEmacsは保留中の出力を読み取って、その後そのサブプロセスからの出力の読み取りを停止します。したがってそのサブプロセスに生きた子プロセスがあり、まだ出力を生成するような場合には、Emacsはその出力を受け取らないでしょう。
サブプロセスからの出力はEmacsが待機している間、端末入力読み取り時(関数waiting-for-user-input-p
、時間の経過や入力の待機のsit-for
とsleep-for
、プロセスの出力を受け取るのaccept-process-output
、およびプロセスへのデータ送信関数(プロセスへの入力の送信を参照)のみ到着可能です。これは並列プログラミングで普遍的に悩みの種であるタイミングエラーの問題を最小化します。たとえば安全にプロセスを作成して、その後でのみプロセスのバッファーやフィルター関数を指定できます。その間にあるコードが待機するプリミティブを何も呼び出さなければ、完了するまで到着可能な出力はありません。
いくつかのシステムではEmacsがサブプロセスの出力を読み取る際に出力データを非常に小さいブロックで読み取るために、結果として潜在的に非常に貧弱なパフォーマンスとなることがる。この挙動は変数process-adaptive-read-buffering
を非nil
値(デフォルト)にセットして拡張することにより改善し得る。これにより、そのようなプロセスからの読み取りを自動的に遅延して、Emacsが読み取りを試みる前に出力がより多く生成されるようになる。
40.9.1 プロセスのバッファー | デフォルトでは出力はバッファーに送信される。 | |
40.9.2 プロセスのフィルター関数 | フィルター関数はプロセスからの出力を受け取る。 | |
40.9.3 プロセス出力のデコード | フィルターはユニバイトやマルチバイトの文字列を取得できる。 | |
40.9.4 プロセスの出力を受け取る | プロセスの出力到着まで待機する方法。 | |
40.9.5 プロセスとスレッド | プロセスとスレッドが相互作用する方法。 |
[ << ] | [ < ] | [ 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
ならプロセスはバッファーに関連付けられない。非nil
なら、bufferの終端ポイントにプロセスマークがセットされる。
この関数は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は特定の関数の呼び出し中のみフィルター関数を呼び出します。プロセスからの出力の受信を参照してください。フィルターによりこれらの関数のいずれかが呼び出されると、フィルターが再帰的に呼び出されるかもしれないことに注意してください。
フィルター関数は関連付けられたプロセス、およびそのプロセスから正に受信した出力である文字列という2つの引数を受け取らなければなりません。関数はその後に出力にたいして何であれ自由に行うことができます。
quitは通常はフィルター関数内では抑制されます。さもないとコマンドレベルでのC-gのタイプ、またはユーザーコマンドのquitは予測できません。フィルター関数内部でのquitを許可したければinhibit-quit
をnil
にバインドしてください。ほとんどの場合において、これを行う正しい方法はマクロwith-local-quit
です。quitを参照してください。
フィルター関数の実行中にエラーが発生すると、フィルター開始時に実行中だったプログラムが何であれ実行を停止しないように自動的にcatchされます。しかしdebug-on-error
が非nil
ならエラーはcatchされません。これによりLispデバッガーを使用したフィルター関数のデバッグが可能になります。Lispデバッガを参照してください。エラーがcatchされると、ユーザーがそのエラーを確認できるようにEmacsは一時停止します(process-error-pause-time
秒間)。非同期プロセスの作成を参照してください。
多くのフィルター関数は時折(または常に)、デフォルトフィルターの動作を真似てプロセスのバッファーにその出力を挿入します。そのようなフィルター関数は確実にカレントバッファーの保存と、(もし異なるなら)出力を挿入する前に正しいバッファーを選択して、その後に元のバッファーをリストアする必要があります。またそのバッファーがまだ生きているか、プロセスマーカーを更新しているか、そしていくつかのケースにおいてはポイントの値を更新しているかもチェックするべきです。以下はこれらを行う方法です:
(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
を呼び出してください。これはウィンドウポイントの移動では必要ないことに注意してください。デフォルトのフィルターは実際にはウィンドウポイントを含むすべてのマーカーを移動するinsert-before-markers
を使用します。これは無関係のマーカーを移動するかもしれないので、一般的にはウィンドウポイントを明示的に移動するか、挿入タイプをt
(ウィンドウとポイントを参照)にセットしたほうがよいでしょう。
フィルター関数の実行中には、Emacsが自動的にマッチデータの保存とリストアを行うことに注意してください。マッチデータを参照してください。
フィルターへの出力は任意のサイズのchunkで到着する可能性があります。同じ出力を連続して2回生成するプログラムは一度に200文字を1回のバッチで送信して、次に40文字を5回のバッチで送信するかもしれません。フィルターが特定のテキスト文字列をサブプロセスの出力から探す場合には、それらの文字列が2回以上のバッチ出力を横断するケースに留意して処理してください。これを行うには受信したテキストを一時的なバッファーに挿入してから検索するのが1つの方法です。
この関数はprocessにフィルター関数filterを与える。filterがnil
なら、そのプロセスにたいしてプロセスバッファーにプロセス出力を挿入するデフォルトフィルターを与える。filterがt
の場合には、Emacsは接続待機でlisten中のネットワークサーバー以外のプロセスからの出力の受け入れを停止する。
この関数は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から何らかの出力を受け取るかprocessが接続をcloseするまでリターンしない。
引数secondsとmillisecによりタイムアウトの長さを指定できる。前者は秒単位、後者はミリ秒単位でタイムアウトを指定する。この2つの秒数は、互いに足し合わせることによりタイムアウトを指定して、その秒数経過後はサブプロセスの出力が存在しなくてもリターンする。
secondsに浮動小数点数を指定することにより秒を小数点で指定できるので引数millisecは時代遅れ(であり使用するべきではない)。secondsが0ならこの関数は保留中の出力が何であれ受け取り待機しない。
processがプロセスで引数just-this-oneが非nil
ならプロセスからの出力だけが処理され、そのプロセスからの出力を受信するかタイムアウトとなるまで他のプロセスの出力は停止される。just-this-oneが整数ならタイマーの実行も抑制される。この機能は一般的には推奨されないが、音声合成のような特定のアプリケーションにとっては必要かもしれない。
関数accept-process-output
はprocess、processがnil
なら何らかのプロセスからから出力を取得したら非nil
をリターンする。これは対応する接続にバッファーされたデータが含まれていれば、たとえプロセスのexit後にも発生し得る。この関数はタイムアウトが発生したり出力の到着前に接続がcloseされるとnil
をリターンする。
プロセスからの接続にバッファーデータが含まれる場合には、プロセスのexit後でもaccept-process-output
が非nil
をリターンするかもしれません。したがって、たとえ以下のようなループでも:
;; このループにはバグがある (while (process-live-p process) (accept-process-output process))
これはprocessからすべての出力を読み取ることが頻繁にあり、接続にまだデータが含まれている間にprocess-live-p
がnil
をリターンすると競合条件をもつとともに何らかのデータが失われるかもしれません。以下のようなループを記述するほうがよいでしょう:
(while (accept-process-output process))
make-process
に非nil
のstderrを渡すと、標準エラープロセスをもつことになる。非同期プロセスの作成を参照のこと。この場合にはメインプロセスからのプロセス出力の待機は、標準エラープロセスからの出力を待機しない。プロセスからすべての標準出力と標準エラーを確実に受け取るためには、以下のコードを使用する:
(while (accept-process-output process)) (while (accept-process-output stderr-process))
make-process
のstderr引数にバッファーを渡した場合でも、以下のように標準エラープロセスを待機する必要があります:
(let* ((stdout (generate-new-buffer "stdout")) (stderr (generate-new-buffer "stderr")) (process (make-process :name "test" :command '("my-program") :buffer stdout :stderr stderr)) (stderr-process (get-buffer-process stderr))) (unless (and process stderr-process) (error "Process unexpectedly nil")) (while (accept-process-output process)) (while (accept-process-output stderr-process)))
両方のaccept-process-output
フォームがnil
をリターンしたときのみ、プロセスがexitしてEmacsがすべての出力を読み取ったと確信することができます。
この方法でリモートホスト上で実行中のプロセスからの保留中の標準エラーを読み取ることはできません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
スレッドは比較的に新しくEmacs
Lispに追加されたものであり、ダイナミックバインドがaccept-process-output
と組み合わせて使用される方法のために、デフォルトではプロセスはそれを作成したスレッドにロックされます。プロセスがスレッドにロックされた場合には、プロセスの出力はそのスレッドだけが受け取ることができます。
Lispプログラムはプロセスがロックされたスレッドがどれかを指定したり、あるいはEmacsにプロセスのアンロックを指示することができ、この場合にはプロセスの出力を任意のスレッドが受け取ることができます。与えられたプロセスから出力を待機できるのは一度に1つのスレッドだけです。1つのスレッドが一度出力を待機すると、プロセスはaccept-process-output
かsit-for
がリターンするまで一時的にロックされます。
スレッドがexitすると、それにロックされたすべてのプロセスがアンロックされます。
processがロックされているスレッドをリターンする。processがロックされていなければnil
をリターンする。
processをロックするスレッドをthreadにセットする。threadは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"
.
"run\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デバッガを参照してください。エラーがcatchされると、ユーザーがそのエラーを確認できるようにEmacsは一時停止します(process-error-pause-time
秒間)。非同期プロセスの作成を参照してください。
センチネルの実行中にはセンチネルが再帰的に実行されないように、プロセスセンチネルは一時的に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
このユーザーオプションがt
(デフォルト)にセットされていると、Emacsはexitに際してプロセスをkillする前に確認を求める。nil
ならEmacsは確認なしでプロセスをkillする(すべてのプロセスの問い合わせフラグを無視する)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
カレントEmacsセッションのサブプロセスにたいするアクセスと操作に加えて、他のプロセスにたいしてEmacs Lispプログラムがアクセスすることもできます。Emacsのサブプロセスと区別するために、わたしたちはこれらをシステムプロセス(system processes)と呼んでいます。
Emacsはシステムプロセスへのアクセス用のプリミティブをいくつか提供します。これらのプリミティブはすべてのプラットフォームではサポートされません。これらのプリミティブはサポートされないシステムではnil
をリターンします。
この関数はそのシステム上で実行中のすべてのプロセスのリストをリターンする。各プロセスはPIDというOSから割り当てられた数値によるプロセスIDにより識別され、同一時に同一マシン上で実行中の他のプロセスと区別される。
default-directory
がリモートホスト上を示す場合には、そのホスト上のプロセスがリターンされる。
この関数はプロセスID
pidで指定されるプロセスにたいする属性のalistをリターンする。このalist内の各属性は(key
.
value)
という形式でありkeyは属性、valueはその属性の値である。この関数がリターン可能なさまざまな属性にたいするkeyを以下にリストした。これらすべての属性をすべてのプラットフォームがサポートする訳ではない。ある属性がサポートされていなければ、その連想値はリターンされるalist内に出現しない。
default-directory
がリモートホスト上を示す場合には、そのホスト上のpidとみなされる。
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はLispのタイムスタンプ(時刻を参照)。
stime
システムコールの処理にたいしてシステム(kernel)コンテキスト内でプロセスに消費された時間。対応するvalueはLispのタイムスタンプ。
time
utime
とstime
の和。対応するvalueはLispのタイムスタンプ。
cutime
cstime
ctime
utime
やstime
と同様だが与えられたプロセスのすべての子プロセスの時間が含まれる点が異なる。
pri
そのプロセスの数値的な優先度。
nice
そのプロセスのnice値(nice value)であるような数値(小さいnice値のプロセスがより優先的にスケジュールされる)。
thcount
そのプロセス内のスレッド数。
start
プロセスの開始時刻(Lispのタイムスタンプ)。
etime
プロセスの開始からの経過時間(Lispのタイムスタンプ)。
vsize
そのプロセスの仮想メモリーのKB単位でのサイズ。
rss
そのプロセスがマシンの物理メモリー内で占める常駐セット(resident set)のKB単位でのサイズ。
pcpu
そのプロセス開始以降に使用されたCPU時間のパーセンテージ。valueは負ではない浮動小数点数。この数値はマルチコアプラットフォームでは理論上100を超過し得るものの、Emacsは通常はシングルスレッドなので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
なら停止しています。
ビルトインのGnuTLSトランスポート層セキュリティーライブラリーを使用することにより、Emacsは暗号化されたネットワーク接続を作成できます。the GnuTLS project
pageを参照してください。これにはシステムにインストール済みの、gnutls-cli
のようなヘルパーユーティリティーが必要です。GnuTLSサポートつきでEmacsをコンパイルした場合には関数gnutls-available-p
が定義されて非nil
をリターンします。詳細はOverview in The Emacs-GnuTLS
manualを参照してください。open-network-stream
関数は何であれ利用可能なサポートを使用して、暗号化接続作成の詳細を透過的に処理できます。
この関数はオプションで暗号つきでTCP接続をオープンして、その接続を表すプロセスオブジェクトをリターンする。
name引数はプロセスオブジェクトの名前を指定する。これは必要に応じて一意になるよう変更される。
buffer引数はその接続に関連付けるバッファー。その接続からの出力は出力を処理する独自のフィルター関数を指定していない場合には、bufferがnil
ならその接続はバッファーに関連付けられない。
引数hostとserviceは接続先を指定する。hostはホスト名(文字列)、serviceは定義済みのネットワークサービス名(文字列)、またはポート番号(80
のような整数か"80"
のような整数文字列)。
残りの引数parametersは主に暗号化された接続に関連するキーワード/引数のペアー:
:nowait boolean
非nil
なら非同期接続を試みる。
:noquery query-flag
プロセスqueryフラグをquery-flagに初期化する。exit前の問い合わせを参照のこと。
:coding coding
これはcoding-system-for-read
やcoding-system-for-write
のバインディングより優先してネットワークプロセスが使用するコーディングシステムをセットするために使用する。詳細はmake-network-process
を参照のこと。
: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
ホストの能力を問い合わせるためのコマンド。文字列(そのままサーバーに送信される)、または関数(接続時のサーバーからの"greeting"を単一のパラメーターでとして呼び出されて文字列をリターンすること)のいずれか。
: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
のいずれか(auth-source in Emacs auth-source
Libraryを参照)。TLSやSTARTTLSにたいしてのみ使用される。:client-certificate
を未指定時に、自動的なauth-source
の問い合わせを有効にするには、network-stream-use-client-certificates
をt
にカスタマイズすればよい。
: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’のいずれか。
:shell-command string-or-nil
接続type
がshell
なら、このパラメーターは接続の作成のために実行されるフォーマット仕様文字列として解釈される。利用可能な仕様はホスト名の‘%s’とポート番号の‘%p’。たとえばプレーン接続を作成する前にまず‘gateway’にsshで接続したければ、このパラメーターは‘ssh
gateway nc %s %p’のようになるかもしれない。
[ << ] | [ < ] | [ 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
より低レベルでの処理からネットワーク接続を作成することもできます。
40.17.1 make-network-process | make-network-process の使用。
| |
40.17.2 ネットワークのオプション | 更なるネットワーク接続の制御。 | |
40.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に指定する場合にはローカルホストにとって有効なアドレスを指定しなければならず、そのアドレスへはクライアント接続だけが許可されるようになる。local
を使用する際にはデフォルトではIPv4を使用するが、ipv6
のfamilyを指定してこれをオーバーライドできる。すべてのインターフェースをlistenするにはIPv4では‘"0.0.0.0"’、IPv6では‘"::"’を指定する。いくつかのオペレーティングシステムでは‘"::"’をlistenするとIPv4もlistenするので、その後で別個にIPv4のlistenを試みると結果はエラーEADDRINUSE
(‘"Address already in use"’)となるだろう。
serviceは接続先のポート番号、またはサーバーにたいしてはlistenするポート番号である。これは‘"https"’のようにポート番号に変換されるようなサービス名、または直接ポート番号を指定する‘443’のような整数か‘"443"’のような整数文字列であること。サーバーにたいしてはt
も指定でき、これは未使用のポート番号をシステムに選択させることを意味する。
familyは接続のアドレス(またはプロトコル)のファミリーを指定する。nil
は与えられたhostとserviceにたいして自動的に適切なアドレスファミリーを決定する。local
はUnixのsocketを指定して、この場合にはhostは無視される。ipv4
とipv6
はそれぞれIPv4とIPv6の使用を指定する。
use-external-socketが非nil
なら割り当てられたsocketのかわりに呼び出し時にEmacsに渡されたsocketを使用する。これはEmacsサーバーのコードにおいてオンデマンドのsocketアクティベージョンを可能にするために使用される。Emacsがsocketを渡されていなければ、このオプションは暗黙に無視される。
サーバープロセスでは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
はその接続が成功または失敗するまでリターンしない。
非同期TLS接続をセットアップする場合には:tls-parameters
パラメーター(下記参照)も提供する必要があるだろう。
Emacsの機能に応じて:nowait
が非同期になる方法は異なる。非同期で実行可能(または不可能)な3つの要素はドメイン名解決、socketのセットアップ、および(TLS接続にいする)TLSネゴシエーション。
プロセスオブジェクトと相互作用する多くの関数(たとえばprocess-datagram-address
)は有用な値をリターンする以前に、少なくともsocketを所有することに依存する。これらの関数はsocketが望ましい状態に達するまでブロックされる。非同期socketと相互作用するための推奨方法はプロセスにセンチネルを配置して、その状態が‘"run"’になるまで相互作用を試みないことである。この方法ではこれらの関数はブロックされない。
TLS接続をオープンする際には最初の要素はTLSタイプ(gnutls-x509pki
かgnutls-anon
のいずれか)であり、残りの要素はgnutls-boot
が受容するキーワードリスト形式であること(このキーワードリストはgnutls-boot-parameters
関数で取得できる)。それからホストへの接続が完了後にTLS接続は確立される。
stoppedが非nil
ならstopped(停止)の状態でネットワーク接続、またはサーバーを開始する。
プロセスバッファーとしてbufferを使用する。
このプロセスにたいするコーディングシステムとしてcodingを使用する。接続からのデータのデコードおよび接続への送信データのエンコードに異なるコーディングシステムを指定するには、codingにたいして(decoding
. encoding)
と指定する。
このキーワードをまったく指定しないかった場合のデフォルトは、そのデータからコーディングシステムを判断する。
プロセスqueryフラグをquery-flagに初期化する。exit前の問い合わせを参照のこと。
プロセスフィルターをfilterに初期化する。
multibyteが非nil
ならマルチバイト文字列、それ以外ならユニバイト文字列がプロセスフィルターに与えられるデフォルトはt
。
プロセスセンチネルを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] | [ ? ] |
以下の追加の関数はネットワーク接続の作成や操作に有用です。これらはいくつかのシステムでのみサポートされることに注意してください。
この関数は使用しているマシン上のネットワークインターフェースを記述するリストをリターンする。値は要素が(ifname
.
address)
という形式をもつようなalist。ifnameはそのインターフェースを命名する文字列、addressはmake-network-process
の引数local-addressおよびremote-addressの形式と同じ。デフォルトでは可能ならIPv4とIPv6の両方のアドレスをリターンする。
オプション引数fullが非nil
なら、かわりに(ifname addr bcast netmask)
という形式の要素を1つ以上もつリストをリターンする。ifnameはそのインターフェースを命名する一意ではない文字列。addr、bcast、netmaskはそれぞれIPアドレス、ブロードキャストアドレス、ネットワークマスクを詳述する整数のベクター。
シンボルipv4
またはipv6
としてオプション引数familyを指定すると、fullの値とは独立してリターンする情報をそれぞれIPv4またはIPv6に制限する。IPv6サポートが利用不可な際にipv6
を指定するとエラーがシグナルされるだろう。
いくつか例を示す:
(network-interface-list) ⇒ (("vmnet8" . [172 16 76 1 0]) ("vmnet1" . [172 16 206 1 0]) ("lo0" . [65152 0 0 0 0 0 0 1 0]) ("lo0" . [0 0 0 0 0 0 0 1 0]) ("lo0" . [127 0 0 1 0]))
(network-interface-list t) ⇒ (("vmnet8" [172 16 76 1 0] [172 16 76 255 0] [255 255 255 0 0]) ("vmnet1" [172 16 206 1 0] [172 16 206 255 0] [255 255 255 0 0]) ("lo0" [65152 0 0 0 0 0 0 1 0] [65152 0 0 0 65535 65535 65535 65535 0] [65535 65535 65535 65535 0 0 0 0 0]) ("lo0" [0 0 0 0 0 0 0 1 0] [0 0 0 0 0 0 0 1 0] [65535 65535 65535 65535 65535 65535 65535 65535 0]) ("lo0" [127 0 0 1 0] [127 255 255 255 0] [255 0 0 0 0]))
この関数はifnameという名前のネットワークインターフェースに関する情報をリターンする。値は(addr
bcast netmask hwaddr flags)
という形式をもつリスト。
インターネットプロトコルアドレス。
ブロードキャストアドレス。
ネットワークマスク。
レイヤー2アドレス(たとえばイーサネットMACアドレス)。
そのインターフェースのカレントのフラグ。
この関数はIPv4の情報だけをリターンすることに注意。
この関数はネットワークアドレスの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
は含まれない。
この関数はnameでホスト名の照合を行う。この名前にはASCII文字列のみを期待しており、さもなくばエラーをシグナルする。国際化されたホスト名を照合したければ、最初にnameにたいしてpuny-encode-domain
を呼び出すこと。
この関数は成功時にはネットワークアドレスを表すLispのリスト(フォーマットについてはmake-network-process
を参照)、それ以外はnil
をリターンする。後者の場合には、(運がよければ)何が悪かったのかを説明するエラーメッセージもロギングされるだろう。
デフォルトではIPv4とIPv6の両方の照合を試みる。オプション引数familyがこの挙動を制御する。これにシンボルipv4
またはipv6
を指定すると、それぞれIPv4またはIPv6に照合を制限する。
オプション引数のhintsがnumeric
なら、この関数はnameを数値によるIPアドレスとして扱う(更にDNSの照合も行わない)。これは文字列がIPアドレスを表す有効な数値かどうかをチェックしたり、数値であるような文字列を正規の表現に変換する場合に役に立つかもしれない。たとえば
(network-lookup-address-info "127.1" 'ipv4 'numeric) ⇒ ([127 0 0 1 0]) (network-lookup-address-info "::1" nil 'numeric) ⇒ ([0 0 0 0 0 0 0 1 0])
特にIPv4ではたとえば‘0’や‘1’が有効であるのと同様に、‘0xe3010203’や‘0343.1.2.3’のように驚くような形式も有効であることに注意(ただしIPv6では無効)。
[ << ] | [ < ] | [ 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を参照のこと。モードラインメニューからスピードと設定を変更できる。line-modeが非nil
ならterm-line-mode
、それ以外はterm-raw-mode
を使用する。
この関数はプロセスとバッファーを作成する。引数はキーワード/引数ペアーで指定する。以下は意味のあるキーワードのリストで、最初の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)として知られています。
40.20.1 データレイアウトの記述 | ||
40.20.2 バイトのunpackとpackを行う関数 | unpack化とpack化を行う。 | |
40.20.3 高度なデータレイアウト仕様 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
unpackとpackを制御するためには、データレイアウト仕様(data layout
specification)を記述します(Bindatタイプ式(Bindat type
expression)とも呼ばれる)。これにはベースタイプ(base
type)と複数フィールドからなるコンポジットタイプ(composite
type)があり、処理するフィールドそれぞれの長さ、packやunpackを行う方法をこの仕様が制御します。わたしたちはbindatタイプの値を、通常は-bindat-spec
で終わる名前の変数に保持しています。このような種類の名前は、自動的に危険(risky)だと認識されます(ファイルローカル変数を参照)。
Bindatタイプの式であるtypeに応じて、Bindatタイプの値オブジェクトを作成する。
フィールドのタイプ(type)はフィールドが表すオブジェクトのサイズ(バイト単位)、およびそれがマルチバイトフィールドならフィールがバイトオーダーされる方法を記述します。可能なオーダーはビッグエンディアン(big
endian。ネットワークバイトオーダーとも呼ばれる)、およびリトルエンディアン(little
endian)の2つです。たとえば数字#x23cd
(10進の9165)のビッグエンディアンは#x23
#xcd
の2バイト、リトルエンディアンは#xcd
#x23
になるでしょう。以下は可能なタイプの値です:
u8
byte
長さ1の符号なしタイプ。
uint bitlen &optional le
長さbitlenビットのネットワークバイトオーダー(ビッグエンディアン)による符号なし整数。bitlenは8の倍数であること。leが非nil
なら、リトルエンディアンによるバイトオーダーを使用する。
sint bitlen le
長さbitlenビットのネットワークバイトオーダー(ビッグエンディアン)による符号付き整数。bitlenは8の倍数であること。leが非nil
なら、リトルエンディアンによるバイトオーダーを使用する。
str len
長さがlenバイトであるようなユニバイト文字列(テキストの表現方法を参照)。packを行う際には入力文字列の最初のlenバイトがpack済み出力にコピーされる。入力文字列がlenより短い場合には、残りのバイトはnull(0)になる。ただし事前に割り当てた文字列がbindat-pack
に与えられた場合には、残りのバイトは未変更のまま残される。入力文字列がASCII文字とeight-bit
文字だけから構成されたマルチバイト文字列の場合には、packを行う前にユニバイトに変換される。それ以外のマルチバイト文字列の場合にはエラーをシグナルする。unpackを行う際には、pack済み入力文字列中のすべてのnullバイトはunpack済み出力にも出現することになるだろう。
strz &optional len
lenが与えられない場合にはnull終端された可変長ユニバイト文字列である(テキストの表現方法を参照)。strz
へpackする際には、入力文字列全体にnull(0)バイトを付加してpack出力にコピーする(strz
へのpackに事前割り当て済みの文字列が与えられた場合には、その事前割り当て済み文字列は出力文字列の終端にnullバイトを付加するための十分なスペースをもっている必要がある;
バイトのunpackとpackを行う関数を参照)。pack済み出力の長さは、入力文字列の長さに(null終端用の)1を加えた値になる。入力文字列にnullバイトが含まれていてはならない。入力文字列がASCII文字とeight-bit
文字だけから構成されたマルチバイト文字列の場合には、packを行う前にユニバイトに変換される。それ以外のマルチバイト文字列の場合にはエラーをシグナルする。strz
のunpack時には、入力文字列を終端するnullバイトまで(ただしnullバイト自体は除外)のすべてのバイトが出力文字列に含まれることになる。
lenが与えられた場合にはstr
と同じように振る舞うが2つ異なる点がある:
警告: 入力文字列がlenより短かったり、最初のlenバイトにnullバイトが含まれている場合のみ、pack済出力がnull終端される。
vec len [type]
len要素のベクター。要素のタイプはtypeにより与えられる(デフォルトはバイト)。typeは任意のBindatタイプ式を指定できる。
repeat len [type]
vec
と同様だがリストから双方向にunpack/packする(vec
はunpackするベクター)。
bits len
lenバイト内で1にセットされたビットのリスト。バイトはビッグエンディアンオーダーで、ビットは8 * len
- 1
で始まり0で終わるよう番号が付けされる。たとえばbits 2
では、#x28
#x1c
は(2 3 4 11 13)
、#x1c
#x28
は(3 5 10 11
12)
にunpackされる。
fill len
lenバイトは単なるフィラーとして使用される。これらのバイトはpack時には未変更のままとなり通常は0のままであることを、unpack時には単にnil
をリターンすることを意味する。
align len
fill
と同様だが、次のlenの倍数バイトまでスキップを要するバイト数である点が異なる。
type exp
これによりタイプを間接的に参照できる。expはBindatタイプvalueをリターンするLisp式であること。
unit exp
これは0ビットのスペースを使用する簡易タイプ。expはそのようなフィールドの“unpack”を試みた際にリターンされる値を記述する。
struct fields...
複数フィールドから構成されるコンポジットタイプ(composite typex: 複合型)。フィールドはそれぞれ(name
type)
という形式をもち、typeには任意のBindatタイプ式を指定できる。align
やfill
のフィールドのように、そのフィールド値が命名に値しない場合には、nameは_
でもよい。コンテキストによりBindatタイプ式であることが明確なら、シンボルstruct
は省略可。
上述のタイプの中で、lenとbitlenはフィールド内のバイト数(またはビット数)を指定する整数として与えられます。そのフィールドが固定長でなければ、通常は値は先行するフィールドの値に依存します。この理由により、lenの長さは定数である必要がないので任意のLisp式を指定することができ、フィールド名から先行するフィールドの値を通じて参照することができるのです。
たとえば先頭のバイトが16ビット整数の後続ベクターにサイズを与えるデータレイアウトの仕様は、以下のようになります:
(bindat-type (len u8) (payload vec (1+ len) uint 16))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以降のドキュメントではtypeはbindat-type
がリターンするようなBindatデータ値、raw
はバイト配列、structはunpackされたフィールドデータを表すalistを参照します。
この関数はユニバイト文字列、またはバイト配列raw
のデータをtypeに応じてunpackする。これは通常はバイト配列の先頭からunpack化を開始するが、idxが非nil
ならかわりに使用する0基準の開始位置を指定する。
値はそれぞれの要素がunpackされたフィールドを記述するalistかネストされたalist。
この関数はネストされたalistであるstructからフィールドのデータを選択する。structは通常はbindat-unpack
がリターンしたもの。nameが単一の引数に対応する場合にはトップレベルのフィールド値を抽出することを意味する。複数のname引数は副構造体を繰り返して照合することを指定する。nameが整数なら配列のインデックスとして動作する。
たとえば(bindat-get-field struct a b 2 c)
なら、フィールドa
の副フィールドb
の3つ目の要素からフィールドc
を探すことを意味する(Cプログラミング言語の構文struct.a.b[2].c
に該当)。
packやunpackの処理をすることによりメモリー内でデータ構造が変化しても、そのデータの全フィールド長の合計バイト数であるトータル長(total length)は保たれます。この値は一般的に仕様またはalist単独では固有ではありません。そのかわりこれら両方の情報がこの計算に役立ちます。同様にunpackされる文字列や配列の長さは仕様の記述にしたがってデータのトータル長より長くなるかもしれません。
この関数はstruct内のデータのtypeに応じたトータル長をリターンする。
この関数はalist
struct内のデータからtypeに応じてpackされたバイト配列をリターンする。これは通常は先頭から充填された新たなバイト配列を作成する。しかしrawが非nil
なら、それはpack先として事前に割り当てられたユニバイト文字列かベクターを指定する。idxが非nil
ならrawへpackする開始オフセットを指定する。
事前に割り当てる際にはout-of-rangeエラーを避けるために、(length
raw)
がトータル長またはそれ以上であることを確認すること。
インターネットアドレスのベクターipを通常のドット表記による文字列に変換する。
(bindat-ip-to-string [127 0 0 1]) ⇒ "127.0.0.1"
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Bindatタイプ式は、これまでに説明したタイプに限定されません。Bindatタイプ式をリターンする、任意のLispフォームも可能です。たとえば以下のタイプは24ビットカラー、またはバイトのベクターのいずれかを含むことが可能なデータを記述します:
(bindat-type (len u8) (payload . (if (zerop len) (uint 24) (vec (1- len)))))
さらに複合タイプは通常は連想リストにunpack(または逆にpack)されませんが、以下のスペシャルキーワード引数を使用してこれを変更することができます:
:unpack-val exp
フィールドのリストがこのキーワードで終わる場合には、unpack時リターンされる値は標準のalistではなくexpの値となる。expは名前によって前のフィールドすべてを参照できる。
:pack-val exp
このキーワード引数がフィールドのタイプの後に続く場合には、このフィールドにはalistから抽出するかわりにexpがリターンした値がpackされる。
:pack-var name
このキーワード引数がフィールドのリストの前に前置されている場合には、後続するすべての:pack-val
引数がnameという名前の引数を介して、この複合タイプにpackされた全体値を参照できる。
たとえば以下のように16ビット符号付き整数を記述できます:
(defconst sint16-bindat-spec (let* ((max (ash 1 15)) (wrap (+ max max))) (bindat-type :pack-var v (n uint 16 :pack-val (if (< v 0) (+ v wrap) v)) :unpack-val (if (>= n max) (- n wrap) n))))
これは以下のようになります:
(bindat-pack sint16-bindat-spec -8) ⇒ "\377\370" (bindat-unpack sint16-bindat-spec "\300\100") ⇒ -16320
最後にbindat-defmacro
でBindatタイプ式を使用することによって、Bindatタイプフォームを新たに定義できます:
argsを受け取るnameという名前のBindatタイプ式を新たに定義する。これの挙動はdefmacro
に準ずるが、重要な違いは新たなフォームがBindatタイプ式でのみ使用できることである。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このチャプターではEmacsによるユーザーへのプレゼンテーションとなる、表示に関連するいくつかの機能を説明します。
41.1 スクリーンのリフレッシュ | スクリーン上にあるすべてのもののクリアーと再描画。 | |
41.2 強制的な再表示 | 再描画の強制。 | |
41.3 切り詰め | 長いテキストの折り畳みと折り返し。 | |
41.4 エコーエリア | スクリーン最下部へのメッセージ表示。 | |
41.5 警告のレポート | ユーザーへの警告メッセージの表示。 | |
41.6 不可視のテキスト | バッファーのテキストの一部を隠す。 | |
41.7 選択的な表示 | バッファーのテキストの一部を隠す(旧来の方式)。 | |
41.8 一時的な表示 | 自動的に消える表示。 | |
41.9 オーバーレイ | オーバーレイを使用したバッファーの一部のハイライト。 | |
41.10 表示されるテキストのサイズ | 表示されたテキストの大きさ。 | |
41.11 行の高さ | 行の高さの制御。 | |
41.12 フェイス | テキスト文字のグラフィカルスタイル(フォント、カラー等)を定義するフェイス。 | |
41.13 フリンジ | ウィンドウフリンジの制御。 | |
41.14 スクロールバー | スクロールバーの制御。 | |
41.15 ウィンドウディバイダー | ウィンドウを視覚的に区別する。 | |
41.16 display プロパティ | イメージ、マージン、テキストサイズ、etc. | |
41.17 イメージ | Emacsバッファー内でのイメージ表示。 | |
41.18 アイコン | Emacsバッファー内でのアイコン表示。 | |
41.19 埋め込みネイティブウィジェット | Emacsバッファー内でのネイティブウィジェットの表示。 | |
41.20 ボタン | Emacsバッファー内へのイメージ表示クリック可能ボタン追加。 | |
41.21 抽象的なディスプレイ | オブジェクトコレクション用のEmacsウィジェット。 | |
41.22 カッコの点滅 | Emacsがマッチする開カッコを表示する方法。 | |
41.23 文字の表示 | Emacsがマッチする個々の文字を表示する方法。 | |
41.24 ビープ | ユーザーへの可聴シグナル。 | |
41.25 ウィンドウシステム | どのウィンドウシステムが使用されているか。 | |
41.26 ツールチップ | Emacsでのツールチップの表示。 | |
41.27 双方向テキストの表示 | アラビア語やペルシア語のような双方向スクリプトの表示。 |
[ << ] | [ < ] | [ 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を参照してください。
グラフィカルなディスプレイでは切り詰めと継続はウィンドウフリンジ内の小さな矢印イメージで示されます(フリンジを参照)。テキスト端末では切り詰めはそのウィンドウの最右列の‘$’、折り返しは最右列の‘\’で示されます(ディスプレイテーブルでこれを行うための代替え文字を指定できる。ディスプレイテーブルを参照)。
テキストの折り返しと切り詰めは互いに反する操作なので、Emacsは折り返しを要求されたら行の切り詰めをオフに、あるいはその逆も行います。
このバッファーローカル変数が非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オブジェクトをプリントできます。出力ストリームを参照してください。
41.4.1 エコーエリアへのメッセージの表示 | エコーエリア内に明示的にテキストを表示する。 | |
41.4.2 処理の進捗レポート | 長時間の処理の進行状況をユーザーに知らせる。 | |
41.4.3 *Messages*へのメッセージのロギング | ユーザー用にログされるエコーエリアメッセージ。 | |
41.4.4 エコーエリアのカスタマイズ | エコーエリアの制御。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではエコーエリア内にメッセージを表示する標準的な関数を説明します。
この関数はエコーエリア内にメッセージを表示する。format-message
関数(文字列のフォーマットを参照)の場合と同じようにformat-stringはフォーマット文字列、argumentsはそのフォーマット仕様にたいするオブジェクトである。フォーマットされた結果文字列はエコーエリア内に表示される。それにface
テキストプロパティが含まれる場合には指定されたフェイスにより表示される(フェイスを参照)。この文字列は*Messages*バッファーにも追加されるがテキストプロパティは含まれない(*Messages*へのメッセージのロギングを参照)。
フォーマット内のグレイヴアクセントとアポストロフィーは"Missing `%s'"から"Missing ‘foo’"のように、通常は対応するcurved quoteとして結果内に変換される。この変換に影響を与えたり抑制する方法についてはテキストのクォートスタイルを参照のこと。
バッチモードでは後に改行が付加されたメッセージが標準エラーストリームにプリントされる。
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)
を使用すること。
以下の機能により、ユーザーおよびLispプログラムはエコーエリアメッセージの表示方法を制御できます。
この変数が非nil
なら、エコーエリア内に表示するためのメッセージテキストを単一の引数とする関数であること。その関数はmessage
および関連する関数から呼び出されることになる。その関数がnil
をリターンすると、通常どおりメッセージはエコーエリアに表示される。関数が文字列をリターンすると、その文字列が元メッセージのかわりにエコーエリアに表示される。その関数が他の非nil
値をリターンした場合にはメッセージが処理済みであることを意味するので、message
はエコーエリアに何も表示しない。その関数で表示されたメッセージのクリアーに使用可能なclear-message-function
も参照のこと。
デフォルト値では以下で説明するset-minibuffer-message
を呼び出す。
この変数が非nil
の場合には引数のない関数であること。message
および関連する関数は引数となるメッセージがnil
か空文字列なら、エコーエリアをクリアーするために引数なしでその関数を呼び出す。
この関数は通常はエコーエリアメッセージの表示後、次の入力イベントの到着時に呼び出される。これはset-message-function
により指定されたカウンターパートとなる関数が表示したメッセージのクリアーを期待される関数だが、必ずしもクリアーを行う必要はない。関数がクリアーしない状態でエコーエリアを残したければ、シンボルdont-clear-message
をリターンすること。それ以外の値であればエコーエリアがクリアーされたことを意味する。
デフォルト値はアクティブなミニバッファーに表示されたメッセージをクリアーする関数。
このユーザーオプションの値は、エコーエリアへのメッセージ表示を処理する関数のリストである。関数はそれぞれ表示するメッセージテキストを唯一の引数として呼び出される。その関数が文字列をリターンしたら元の文字列はその文字列で置換されて、リストの次の関数はその新たなメッセージテキストを引数として呼び出される関数がnil
をリターンした場合には同じテキストでリストの次の関数が呼び出される。リストで最後の関数がnil
をリターンすると、エコーエリにメッセージテキストを表示、文字列以外の非nil
値をリターンした場合にはメッセージを処理済みとみなしてそれ以上リストの関数は呼び出さない。
このリストに配置する値として役に立つ3つの関数を以下に挙げる。
この関数はミニバッファーが非アクティブならエコーエリア、アクティブならミニバッファー終端にメッセージを表示する。しかしアクティブなミニバッファーに表示されるテキストの何らかの文字がminibuffer-message
テキストプロパティ(特殊な意味をもつプロパティを参照)をもつ場合には、メッセージはそのプロパティをもつ最初の文字の前に表示される。
デフォルトではこの関数がset-message-functions
のリストの唯一のメンバーである。
この関数はエコーエリアのmessageがユーザーオプションinhibit-message-regexps
の値となっているリストのregexpのいずれかにマッチしたらそのメッセージの表示を抑制して文字列以外の非nil
値をリターンする。したがってこの関数がリストset-message-functions
にあると、messageがinhibit-message-regexps
のregexpにマッチする場合にはリストの残りの関数は呼び出されない。マッチするmessageの表示を確実に抑制するには、この関数をset-message-functions
のリストの最初の要素にすればよい。
この関数は発行されていく複数のエコーエリアメッセージを逐一溜め込み、改行を区切られた個々のメッセージを単一の文字列としてリターンする。直近でmulti-message-max
回までのメッセージを蓄積できる。蓄積されたメッセージは最初のメッセージの発行からmulti-message-timeout
秒経過後に破棄される。
この変数が非nil
なら、message
および関連する関数はエコーエリアに何もメッセージは表示しない。ただしエコーエリアのメッセージは依然として*Messages*バッファーにはロギングされる。
この構文は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
び呼び出し結果であるべきだろう。
オプション引数suffixは、reporterのメインメッセージと進行状況テキストの後に表示する文字列。reporterが非数値のレポーターならvalueはnil
、またはsuffixのかわりに使用する文字列であること。
この関数はmake-progress-reporter
に渡されたmin-changeとmin-timeにしたがい、毎回の呼び出しで新たなメッセージを出力しない。したがってこれは非常に高速であり、通常はこれを呼び出す回数を減らすことを試みるべきではない。結果として生じるオーバーヘッドは、あなたの努力をほぼ否定するだろう。
この関数はprogress-reporter-update
と同様だが、これは無条件にメッセージをエコーエリアにプリントする点が異なる。
reporter、value、suffixはprogress-reporter-update
の場合と同じ意味をもつ。オプションのnew-messageでreporterのメッセージを変更できる。この関数は常にエコーエリアを更新するので、そのような変更は即座にユーザーに示されるだろう。
この関数は処理の完了時に呼び出されること。これはエコーエリア内に単語‘done’を付加したreporterのメッセージを表示する。
progress-reporter-update
に‘100%’とプリントさせようとせずに、常にこの関数を呼び出すこと。まずこの関数は決してそれをプリントしないだろうし、これが発生しないために多くの正当な理由がある。次に‘done’はより自明である。
これはdotimes
と同じ方法で機能するが、上述の関数を使用してループ進行状況(loop
progress)の報告も行う便利なマクロである。これによりタイプ量を幾分節約できる。引数reporter-or-messageは文字列、またはプログレスレポーターオブジェクト。
以下の方法でこのマクロを使用することにより、このサブセクションの例を書き換えることができる:
(dotimes-with-progress-reporter (k 500) "Collecting some mana for Emacs..." (sit-for 0.01))
make-progress-reporterのオプション引数を指定したい場合には、reporter-or-message引数としてレポーターオブジェクトを使用するのが便利。たとえば前出の例は以下のように書き換えられる:
(dotimes-with-progress-reporter (k 500) (make-progress-reporter "Collecting some mana for Emacs..." 0 500 0 1 1.5) (sit-for 0.01))
これはdolist
と同じ方法で機能するが、上述の関数を使用してループ進行状況(loop
progress)の報告も行う便利なマクロである。これによりタイプ量を幾分節約できる。dotimes-with-progress-reporter
の場合のように、reporter-or-message
はプログレスレポーターか文字列。このマクロにより、前出の例を以下のように書き換えられる:
(dolist-with-progress-reporter (k (number-sequence 0 500)) "Collecting some mana for Emacs..." (sit-for 0.01))
ある処理にたいして、実行に長時間を要するか否かが不明瞭だったり、処理がプログレスレポーターの実装に向いていない場合があるかもしれない。このマクロはそのような状況下で使用できるだろう。
(with-delayed-message (2 (format "Gathering data for %s" entry)) (setq data (gather-data entry)))
この例では、処理の実行が2秒を超える場合にはメッセージが表示される。2秒以下の場合にはメッセージは表示されない。いずれの場合でもbodyは通常どおり評価される。このマクロのリターン値は、bodyの最後の要素のリターン値。
メッセージわwo表示するか否かに関わらず、要素messageはbodyより前に、常に評価される。
[ << ] | [ < ] | [ 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*。(恐らくは後でバッファーをログファイルに書き込む等の理由で)一時的に出力を別バッファーにリダイレクトできると都合がよいパッケージがあれば、この変数に別のバッファー名をバインドすればよい(そのバッファーがまだ存在しなければ、そのバッファーが新たにmessages-buffer-mode
で作成されることに注意)。
*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)とはプログラムがユーザーにたいして問題の可能性を知らせるが、実行は継続するための機能です(エラーのシグナルとは逆; エラーを参照)。
41.5.1 警告の基礎 | 警告の概念と報告するための関数。 | |
41.5.2 警告のための変数 | プログラムが警告をカスタマイズするためにバインドする変数。 | |
41.5.3 警告のためのオプション | ユーザーが警告の表示を制御するためにセットする変数。 | |
41.5.4 遅延された警告 | コマンド終了まで警告を延期する。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
すべての警告はユーザーに問題を説明するためのテキストのメッセージと、それに関連付けられた重大度レベル(severity level)をもっています。重大度レベルはシンボルです。以下に想定される重大度レベルと意味を重大度の降順で示します:
:emergency
ユーザーが直ちに対処しなければEmacs処理が間もなく深刻に害される問題。
:error
本質的に悪いデータや状況に関するレポート。
:warning
本質的に悪くはないが、可能性のある問題を励起する恐れのあるデータや状況に関するレポート。
:debug
ユーザーが警告を発するLispプログラムをデバッグ中に役に立つかもしれない情報のレポート。
あなたのプログラムが無効な入力データに遭遇した際には、error
やsignal
(エラーをシグナルする方法を参照)の呼び出しによってLispエラーのシグナルするか、あるいは重大度:error
の警告をレポートすることができます。もっとも簡単なのはLispエラーのシグナルですが、それはプログラムが処理を継続できないようシグナルすることを意味します。間違ったデータでも処理を継続するための方法を実装するためにトラブルを受け取めたい場合には、その問題をユーザーに知らせるために重大度:error
の警告をレポートするのが正しい方法です。たとえばEmacs
Lispバイトコンパイラーはこの方法によりエラーを報告して、他の関数のコンパイルを継続できます(プログラムがLispエラーをシグナルしてcondition-case
でhandleしたならユーザーがそのエラーを確認することはないだろう;
これは警告としてレポートすることにより、問題を避けるのではなくユーザーに問題を報告するのだ)。
重大度レベルの他にも、クラス分けのために警告にはそれぞれ警告タイプ(warning
type)があります。このタイプはシンボル、またはシンボルのリストです。シンボルならそのプログラムのユーザーオプションとして使用するカスタムグループ、リストならリストの1つ目の要素がそのカスタムグループであることが必要です。たとえばバイトコンパイラーの警告は警告タイプ(bytecomp)
を使用しています。警告タイプがリストの場合には、後続する2つ目以降の要素はそれぞれが警告のサブカテゴリーを表す任意のシンボルであることが必要です。これらの要素は、その警告の特性についてよりよい説明を表示するために使用されることでしょう。
この関数は警告テキストとして文字列message、警告タイプとしてtypeを使用して警告をレポートする。levelは重大度レベルであること。省略またはnil
の場合のデフォルトは: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
なら、これはユーザーの注目を得るために引数なしで呼び出される関数であること。ding
の例は注目に値する(ビープを参照)。
通常はこの変数の値を変更しないこと。
値が非nil
なら、それは警告用にプレフィックスを生成する関数であること。プログラムはこの変数を適切な関数にバインドできる。display-warning
はwarningsバッファーがカレントの状態でこの関数を呼び出して、関数はそのバッファーにテキストを挿入できる。そのテキストが警告メッセージの先頭になる。
この関数は重大度レベル、およびwarning-levels
内でのその重大度レベルのエントリーという2つの引数で呼び出される。これはエントリーのかわりに使用するためのリストをリターンすること(この値はwarning-levels
の実際のメンバーである必要はないが同じ後続でなければならない)。この値を構築することにより関数はその警告の重大度レベルを変更したり、与えられた重大度レベルにたいして異なる処理を指定することができる。
変数の値がnil
なら警告が表示される前のプレフィックステキストは存在せず、その警告のレベルに応じたwarning-levels
内のエントリーのstring部分から始まる。
プログラムは次の警告がシリーズの開始であることを告げるために、この変数をt
にバインドできる。複数の警告がシリーズを形成するということは、それぞれの警告にたいしてポイントが維持されるように移動して、最後の警告にポイントが表示されるのではなくシリーズの最初の警告にポイントを残すことを意味する。このシリーズはこの変数のローカルバインドが解消されてwarning-series
が再びnil
になったときに終了する。
この値は関数定義をもつシンボルでもよい。これは次の警告によりwarningsバッファーがカレントの状態で、引数なしでその関数が呼び出されることを除きt
と等価。この関数はたとえば警告シリーズのヘッダーの役目をもつであろうテキストを挿入できる。
あるシリーズが開始されると、この変数の値はwarningsバッファー内でシリーズ開始となるバッファー位置を指すマーカーとなる。
この変数の通常の値はnil
で、これはそれぞれの警告を個別に処理することを意味する。
この変数が非nil
なら、警告それぞれのテキストのフィルに使用するフィルプレフィックスを指定する。
警告をフィルする列。
この変数は警告テキスト内の警告タイプを表示するためのフォーマットを指定する。この方法でフォーマットされたタイプは、warning-levels
内のエントリー内の文字列制御下にあるメッセージに含まれることになる。デフォルト値は"
(%s)"
。これを空文字列""
にバインドすると警告タイプはまったく表示されなくなる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の変数は何が発生したときにLispプログラムが警告をレポートするかをユーザーが制御するために使用されます。
このユーザーオプションはどこかのウィンドウに警告バッファーをポップアップすることによってユーザーに即座に表示すべき最小の重大度レベルを指定する。デフォルトの:warning
は:debug
以外のすべての警告重大度にたいして警告バッファーを表示することを意味する。この変数の与えられたより低い重大度レベルは依然として警告バッファーに書き込まれるが、そのバッファーが強制的に表示されることはない。
このユーザーオプションはwarningsバッファー内にログされるべき最小の重大度レベルを指定する。これより低い重大度レベルは完全に無視される。すなわち警告バッファーに書き込まれず表示もされない。デフォルトは:warning
であり、これは:debug
を除くすべての警告がログされることを意味する。
このリストは発生時即座に表示するべきではない警告タイプを指定する。このリストの要素はそれぞれシンボルのリストであること。警告タイプの最初の要素がこのリストのいずれかの要素と同一であれば、そのタイプの警告がどこかのウィンドウに警告バッファーをポップアップして表示されることはなくなる(警告バッファーへの警告の書き込みは依然として行われる)。
たとえばこの変数の値が以下のようなリストであれば:
((foo) (bar subtype))
foo
、(foo)
、(foo something)
、(bar subtype other)
といったタイプの警告はユーザーに表示されなくなる。
このリストは無視、すなわち警告バッファーにロギングされずユーザーにも表示しない警告タイプを指定する。リストの構造と警告タイプにたいするマッチングは、上述のwarning-suppress-types
の場合と同様。
スタートアップの間にEmacsはサイト単位のinitファイルとユーザーのinitファイル(要約: スタートアップ時のアクション順序を参照)のロードと処理が終わるまで、すべての警告の表示を遅延します。initファイルで警告を発するかもしれないコードの前後で以下のオプションの値をletバインディング(ローカル変数を参照)しても、実際に警告が処理される時点では効果がなくなっており機能しません。したがってスタートアップの間に警告を抑制したければ、initファイルの十分早い段階で上述のオプションの値を変更するか、あるいはafter-init-hook
やemacs-startup-hook
の関数内にletバインディングを行うフォームを配置してください。initファイルを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コマンド実行中には警告の表示を避けてコマンドの終わりでのみ警告を表示したいことがあるかもしれません。これは関数delay-warning
を使用して行うことができます。Emacsはスタートアップの初期ステージの間は自動的にすべての警告メッセージ発行を遅延して、initファイルを処理した後でのみそれらを表示します。
この関数はdisplay-warning
(警告の基礎を参照)の遅延対応版であり、同じ引数で呼び出される。警告メッセージはdelayed-warnings-list
にキューイングされる。
この変数の値はカレントのコマンド完了後に表示される警告のリスト。各要素は以下のようなリストでなければならない:
(type message [level [buffer-name]])
これらはdisplay-warning
の引数リストと同じ形式、同じ意味である。post-command-hook
(コマンドループの概要を参照)の実行直後に、Emacsのコマンドループはこの変数で指定されたすべての警告を表示してから変数をnil
にリセットする。
遅延警告メカニズムをよりカスタマイズする必要があるプログラムは変数delayed-warnings-hook
を変更することができます:
これは遅延警告を処理して表示するために、post-command-hook
の後にEmacsコマンドループが実行するノーマルフック。Emacsはスタートアップ中、およびsite-startファイルとinitファイルをロードした後(要約: スタートアップ時のアクション順序を参照)にもこのフックを実行する。これはそれ以前に発せられた警告は自動的に遅延されるためである。
デフォルト値は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
をリターンする。
この関数のリターン値はテキストがディスプレイ上で完全に非表示ならt
、省略記号(ellipsis)で置き換えられていればnil
でもt
でもない値となる。
テキストを操作したりポイントを移動する関数は、通常はそのテキストが不可視かどうかに注意を払わずに、可視と不可視のテキストを同様に処理します。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で指定したバッファーをカレントにする点が異なる。
一時バッファーを表示しているウィンドウは以下のモードを使用してそのバッファーにサイズを適合できます:
このマイナーモードが有効なときは、一時的バッファーを表示しているウィンドウはバッファーのコンテンツにフィットするように自動的にリサイズされる。
そのバッファーにたいして特別に作成されたウィンドウの場合のみウィンドウはリサイズされる。特に前に別のバッファーを表示していたウィンドウはリサイズされない。デフォルトではこのモードはリサイズにfit-window-to-buffer
を使用する(ウィンドウのリサイズを参照)。以下のオプションtemp-buffer-max-height
とtemp-buffer-max-width
をカスタマイズして他の関数を指定できる。
display-buffer
にたいしてアクションalistのエントリーとして適切なwindow-height
、window-width
、window-size
を供給することによって、このオプションの効果をオーバーライドできる(バッファー表示用のアクションalistを参照)。
このオプションは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)を使用できます。オーバーレイとは個々のバッファーに属するオブジェクトであり、指定された開始と終了をもっています。確認したりセットすることができるプロパティももっています。それらはオーバーレイされたバッファー部分のテキスト表示に影響を与えます。
バッファーのテキスト編集では、すべてのオーバーレイがそのテキストに留まるように開始と終了が調整されます。オーバーレイ作成時にはオーバーレイの先頭、または同様に終端にテキストが挿入された場合に、それがオーバーレイの内側(または外側)になるべきなのかを指定できます。
41.9.1 オーバーレイの管理 | オーバーレイの作成と変更。 | |
41.9.2 オーバーレイのプロパティ | プロパティ読み取りとセットの方法。どのプロパティがスクリーン表示に何を行うか。 | |
41.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はそれぞれ、先頭(startの前)あるいは終端にテキストが挿入された際に何が起こるかを指定する。どちらも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と同じ両端位置とプロパティをもつ。しかしオーバーレイの開始と終了にたいするテキスト挿入タイプはデフォルト値にセットされる。
以下にいくつか例を示します:
;; オーバーレイを作成
(setq foo (make-overlay 1 10))
⇒ #<overlay from 1 to 10 in display-ja.texi>
(setq selective-display 2) ⇒ 2
(overlay-end foo) ⇒ 10 (overlay-buffer foo) ⇒ #<buffer display-ja.texi> ;; 後でチェック可能なプロパティを付与 (overlay-put foo 'happy t) ⇒ t ;; 付与されたか検証 (overlay-get foo 'happy) ⇒ t
;; オーバーレイを移動
(move-overlay foo 5 20)
⇒ #<overlay from 5 to 20 in display-ja.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-ja.texi> ;; 結果の検証 (overlay-start foo) ⇒ 1 (overlay-end foo) ⇒ 20 (overlay-buffer foo) ⇒ #<buffer display-ja.texi>
;; 移動や削除によってオーバーレイのプロパティは変更されない
(overlay-get foo 'happy)
⇒ t
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
オーバーレイプロパティは文字が表示される方法をどちらのソースからも取得できるという点においてテキストプロパティと似ています。しかしほとんどの観点において両者は異なります。これらの比較はテキストのプロパティを参照してください。
テキストプロパティはそのテキストの一部として考えることができます。オーバーレイとそのプロパティは特にテキストの一部とはみなされません。したがってさまざまなバッファーや文字列の間でテキストをコピーすると、テキストプロパティは保持されますがオーバーレイを保持しようとは試みません。バッファーのテキストプロパティの変更はバッファーを変更済みとマークしますが、オーバーレイの移動やプロパティの変更は違います。テキストプロパティの変更とは異なり、オーバーレイプロパティの変更はバッファーのundoリストに記録されません。
複数のオーバーレイが同じ文字にたいしてプロパティ値を指定できるので、Emacsは各オーバーレイにたいして優先度の指定を促します。優先度の値はオーバーラップするオーバーレイのどちらが“勝つ”かを判断するために使用されます。
以下の関数はオーバーレイのプロパティの読み取りとセットを行います:
この関数はoverlay内に記録されたプロパティpropの値をリターンする。そのプロパティにたいしてoverlayが何も値を記録していないが、シンボルであるようなcategory
プロパティをもつ場合には、そのシンボルのpropプロパティが使用される。それ以外なら値はnil
。
この関数はoverlay内に記録されたプロパティpropの値にvalueをセットする。リターン値はvalue。
これはoverlayのプロパティリストのコピーをリターンする。
与えられた文字にたいしてテキストプロパティとオーバーレイプロパティの両方をチェックする関数get-char-property
も参照してください。テキストプロパティを調べるを参照してください。
多くのオーバーレイプロパティには特別な意味があります。以下はそれらのテーブルです:
priority
¶このプロパティの値はオーバーレイの優先度を決定する。優先度にたいして値を指定したければnil
(か0)、正の整数、あるいは2つの値のコンスセルを使用すること。それ以外のすべての値にたいしては未定義の動作が起こる。
2つ以上のオーバーレイが同じ文字をカバーし、それぞれが同じプロパティに違う値を指定する場合には優先度が重要になる。そのような場合には他よりpriority
の値が大きいほうが他をオーバーライドする(face
プロパティにたいしては、より高い優先度のオーバーレイの値は他の値を完全にはオーバーライドしない;
それぞれのface属性にたいしてより高い優先度のface属性が低い優先度のface
プロパティのface属性をオーバーライドする)。2つのオーバーレイが同じ優先値をもち、一方がもう一方に“ネスト”されている(カバーしているバッファーや文字列位置が小さい)場合には、内側のオーバーレイが外側のオーバーレイより優先される。いずれのオーバーレイも他方にネストされていなければ、どちらのオーバーレイが優先するかを仮定しないこと。
優先度のないオーバーレイをもつかもしれないテキストにLispプログラムが優先度を定義する際には、望ましくない結果が生じるかもしれない。なぜなら優先度のないオーバーレイは、正の優先度をもつすべてのオーバーレイにオーバーライドされてしまうからである。Emacsのほとんどの機能は優先度を指定せずにオーバーレイを使っているため、整数の優先度の使用には注意を要する。整数の優先度を使用することによって他のオーバーレイをオーバーライドしてしまう危険を冒すかわりに、(primary . secondary)
という形式の値を優先度にすることができる。ここでprimaryは上述のように使用されるが、primaryにたいするネスト状況の検討においてそれぞれのオーバーレイの間の優先度の解決に失敗した際に用いられるフォールバック値がsecondaryである。特に優先度の値として(nil . n)
のnに正の整数を指定すると、他のオーバーレイを完全にオーバーライドせずに、必要に応じてオーバーレイを優先度順に並べることができる。
現在のところ、すべてのオーバーレイはテキストプロパティより優先される。
優先度順にオーバーレイを配置する必要がある場合には、overlays-at
のsorted引数を用いることができる。See オーバーレイにたいする検索を参照のこと。
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
が、非nil
にバインドされる。関数がバッファーを変更した場合には変更にたいして変更フックが実行されるように、inhibit-modification-hooks
をnil
にバインドしたいと思うかもしれない。しかしこれを行うことにより、あなた自身の変更フックが再帰的に呼び出されるかもしれないので、それに確実に備える必要がある。フックの変更を参照のこと。
テキストプロパティもmodification-hooks
プロパティをサポートするが詳細は幾分異なる(特殊な意味をもつプロパティを参照)。
insert-in-front-hooks
¶このプロパティの値はオーバーレイ先頭へのテキスト挿入前後に呼び出される関数のリスト。呼び出し方はmodification-hooks
の関数と同様。
insert-behind-hooks
¶このプロパティの値はオーバーレイ終端へのテキスト挿入前後に呼び出される関数のリスト。呼び出し方はmodification-hooks
の関数と同様。
invisible
¶invisible
プロパティによりオーバーレイ内のテキストを不可視にできる。これはそのテキストがスクリーン上に表示されないことを意味する。詳細は不可視のテキストを下さいのこと。
intangible
¶オーバーレイのintangible
プロパティは正にintangible
テキストプロパティと同様に機能する。これは時代遅れである。詳細はSee 特殊な意味をもつプロパティを参照のこと。
isearch-open-invisible
このプロパティはインクリメンタル検索(Incremental Search in The GNU Emacs Manualを参照)にたいして最後のマッチがそのオーバーレイに重なる場合に、不可視なオーバーレイを永続的に可視にする方法を告げる。不可視のテキストを参照のこと。
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
なら、そのテキスト範囲にたいしてキーマップを指定する。このキーマップはポイントがオーバーレイ内部(境界だ内部か否かの定義にはfront-advanceおよびrear-advanceのプロパティを考慮する)にあるとき使用されて、他のほとんどのキーマップ(アクティブなキーマップを参照)より優先される。
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
(通常の表示の慣習を参照)。
charがUnicodeに照らして大文字であれば非nil
をリターンする。
この関数は文字列stringがカレントバッファーおよび選択されたウィンドウに表示された場合の幅を列数でリターンする。オプション引数fromとtoはstring内で考慮すべき部分文字列を指定するもので、substring
の場合のように解釈される(文字列の作成を参照)。
リターン値は近似値。ディスプレイプロパティやフォント等は無視して構成文字(constituent
characters)にたいしてはchar-width
のリターン値、タブ文字は常にtab-width
列を占めるものとみなす。これらの理由により、以下で説明するwindow-text-pixel-size
やstring-pixel-width
の使用を推奨する。
この関数はディスプレイ上でwidth列を満たすようにstringを切り詰めて、新たな文字列としてリターンする。
stringがwidthに満たなければ、結果はstringと等しい。それ以外の場合には超過した文の文字列は結果から省かれる。string内の複数列文字が列widthを超過する場合には、その文字は結果に含まれない。つまり結果がwidthより短くなりことはあり得るが、超過することはない。
オプション引数start-columnは開始列を指定する(デフォルトは0)。これが非nil
なら、その文字列の最初のstart-column列は値から省かれる。string内の1つの複数列文字が列start-columnを超えて跨がるようなら、その文字は結果に含まれない。
オプション引数paddingが非nil
なら、結果となる文字列の幅を正確にwidth列に拡張するためにパディング文字が追加される。結果がwidthより短ければ、widthに達するまで必要な個数分のパディング文字が終端に追加される。string内の複数列文字が列start-columnを超える場合には、結果の先頭にもパディング文字が追加される。
ellipsisが非nil
の場合には、stringを切り詰める際にstring終端を置き換える文字列であること。この場合にはwidth列に収まるよう、ellipsis用に必要なスペースを開放するために、より多くの文字がstringから削除される。しかしstringの表示幅がellipsisの表示幅より小さければ、ellipsisを結果に追加しない。ellipsisが非nil
かつ文字列以外なら、それは変数truncate-string-ellipsis
の値を意味する。
オプション引数ellipsis-text-propertyが非nil
なら、実際に文字列を切り詰めずに省略記号(ellipsis)を表示するdisplay
テキストプロパティ(display
プロパティを参照)でstringの超過部分を隠すことを意味する。
(truncate-string-to-width "\tab\t" 12 4) ⇒ "ab" (truncate-string-to-width "\tab\t" 12 4 ?\s) ⇒ " ab "
この関数はstringが広すぎる際に適切な切り詰め位置を見つけるためにstring-width
とchar-width
が使用するのでstring-width
と同じ問題を抱えている。とりわけstring内で文字合成(character
composition)が発生した際には、文字列の表示幅が構成文字の合計幅より短くなるかもしれず、この関数が不正確な結果をリターンするかもしれない。
この関数はtruncate-string-to-width
および同様のコンテキストにおいて省略記号(ellipses)として使用する文字列をリターンする。値は変数truncate-string-ellipsis
がnil
でなければその値、すなわち選択されたフレームで表示可能なら単一文字U+2026
HORIZONTAL ELLIPSIS、それ以外なら文字列‘...’。
以下の関数は与えられたウィンドウにあるテキストを表示したときのサイズをピクセル単位でリターンします。この関数はテキストを含むためにウィンドウを十分大きくするためにfit-window-to-buffer
とfit-frame-to-buffer
(ウィンドウのリサイズを参照)により使用されます。
この関数はwindowのバッファーのテキストサイズをピクセル単位でリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。リターン値は任意のテキスト行の最大ピクセル幅と、すべてのテキスト行の最大ピクセル高さのコンス。この関数はバッファーがテキストの表示を要したり、その他似たような状況において必要となるwindowサイズをLispプログラムが調整できるようにするために存在する。
リターン値にはオプションでサイズが計測された最初の行のバッファー位置を含めることができる(以下参照)。
オプション引数fromが非nil
なら、それは考慮すべき最初のテキスト位置を指定する。デフォルトはそのバッファーのアクセス可能な最小の位置。fromがt
なら、改行文字ではないアクセス可能な最小位置を意味する。fromがコンスセルの場合にはcar
がバッファー位置、cdr
にはその位置から、サイズを測定するテキストが属する最初のスクリーン行までの垂直オフセットをピクセル単位で指定する(計測はそのスクリーン行の視覚的な先頭から開始されることになる)。この場合にはピクセルの幅と高さ、それにバッファー位置からなるリストが値としてリターンされる。オプション引数toが非nil
なら、それは考慮すべき最後のテキスト位置を指定する。デフォルトはそのバッファーのアクセス可能な最大の位置。toがt
なら、改行文字ではないアクセス可能な最大位置を意味する。
オプション引数x-limitが非nil
なら、その位置を超えるテキストを指定するような最大X座標を指定する。したがってこれはこの関数がリターンし得る最大のピクセル幅でもある。x-limitがnil
または省略なら、windowのbody(ウィンドウのサイズを参照)のピクセル幅を使用することを意味する。このデフォルト値はウィンドウより長い切り詰められた行のテキストは無視されることを意味する。このデフォルト値はは呼び出し側がwindowの幅の変更を意図しない場合に有用。それ以外なら呼び出し側はここで想定されるwindowのbodyの最大幅を指定すること。特に行の切り詰めが予想される場合に、それらの行のテキストを勘定に入れる必要があるなら、x-limitを大きな値にセットする必要がある。長い行の幅の計算にはいくらかの時間を要するかもしれないので、必要に応じてこの変数を小さくするのはよいアイデアである。これはいずれにせよ切り詰められるような長い行をバッファーが含む場合が特に該当する。
オプション引数y-limitが非nil
なら、その値を超えるテキストは無視されるような最大Y座標を指定する。したがってこれは関数がリターンし得る最大のピクセル高さでもある。y-limitがnil
か省略なら、toで指定したバッファー位置までのすべてのテキスト行を考慮することを意味する。大きなバッファーのピクセル高さの計算には多くの時間を要する可能性があるので、特に呼び出し側がバッファーのサイズを知らない場合におけるこの変数の指定は合理的である。
オプション引数mode-linesがnil
または省略された場合には、リターン値にwindowのモードライ、タブライン、ヘッダーラインの高さを含めないことを意味する。これがシンボルmode-line
、tab-line
、header-line
のいずれかなら、それらが存在する場合にはリターン値にそのラインの高さだけを含める。これがt
の場合には、もし存在すればすべてのラインの高さをリターン値に含める。
オプション引数ignore-line-at-endはリターンするpixel-heightにtoのスクリーン行のテキスト高さを含めるかどうかを制御します。これはあなたのLispプログラムにとって関心があるのは、toのスクリーン行の視覚的な先頭を除外したテキストのサイズだけという場合に役に立つでしょう。
window-text-pixel-size
はウィンドウ内に表示されているテキスト全体を扱い、個々の行サイズには留意しません。それは以下の関数が行います。
この関数は指定したwindowに表示された各行のピクセルサイズを計算する。これはwindowのカレントグリフマトリクス( windowにカレントで表示されている各バッファー文字のグリフを格納するマトリクス。グリフを参照)を調べることにより機能する。成功したら各行末文字の右下隅のX座標とY座標を表すコンスペアのリストをリターンする。これらの座標はwindowの左上隅にある原点(0, 0)からピクセル単位で計測される。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。
オプション引数firstが整数なら、リターンするwindowのグリフマトリクスの最初の行のインデックス(0から開始)を示す。windowにヘッダーラインがあればインデックス0の行はヘッダーラインになることに注意。firstがnil
なら考慮する最初の行はオプション引数bodyの値で判断される。bodyが非nil
なら、(もしあれば)ヘッダーラインをすべてスキップしてwindowのbodyの最初の行から開始することを意味する。それ以外ならwindowのグリフマトリクスの最初の行(ヘッダーラインかもしれない)から開始することを意味する。
オプション引数lastが整数なら、リターンするwindowのグリフマトリクスの最後の行のインデックスを示す。lastがnil
なら考慮する最初の行はオプション引数bodyの値で判断される。bodyが非nil
なら、windowのモードラインを省略してwindowのbodyの最後の行を使用することを意味する。それ以外ならwindowのグリフマトリクスの最後の行(モードラインかもしれない)を使用することを意味する。
オプション引数inverseがnil
なら、リターンされる任意の行にたいするYピクセル値がwindowの左エッジ(bodyが非nil
なら左bodyエッジ)から、その行の最後のグリフの右エッジまでのピクセル単位の距離を指定することを意味する。非nil
のinverseは、リターンされる任意の行にたいするYピクセル値がその行の最後のグリフの右エッジから右エッジ(bodyが非nil
なら右bodyエッジ)までのピクセル単位の距離を指定することを意味する。これは各行末の未使用スペースの量を判断するために有用。
オプション引数leftが非nil
なら各行左端文字の左下隅のX座標とY座標をリターンすることを意味する。これは主に右から左にテキストを表示にたいして使用されるべき値である。
leftが非nil
でinverseがnil
なら、リターンされる任意の行にたいするYピクセル値がその行の最後(左端)のグリフの左エッジから、windowの右エッジ(
bodyが非nil
なら右bodyエッジ)までのピクセル単位の距離を指定することを意味する。leftとinverseがいずれも非nil
なら、リターンされる任意の行にたいするYピクセル値がwindowの左エッジ(
bodyが非nil
なら左bodyエッジ)から、その行の最後(左端)のグリフの左エッジまでのピクセル単位の距離を指定することを意味する。
この関数はwindowのカレントグリフマトリクスが最新でなければnil
をリターンする。これはたとえばコマンドの処理中のようにEmacsがbusyな際に通常は発生する。これは遅延が0秒であるようなアイドルタイマーからこの関数が実行された際に取得され得る値である。
これはwindow-text-pixel-size
に酷似しているが、そのバッファーがウィンドウに表示されていない際に使用できる(ウィンドウに表示されていればwindow-text-pixel-size
のほうが高速なのでこの関数を使用するべきではない)。
buffer-or-nameには生きたバッファーか生きたバッファーの名前を指定しなければならず、デフォルトはカレントバッファー。windowは生きたウィンドウでなければならず、デフォルトは選択されたウィンドウ。この関数はあたかもbufferがwindowで表示されているかのようにテキストのサイズを算出する。リターン値は全テキスト行の最大pixel-width、およびbuffer-or-nameで指定されたバッファーの全テキスト行のpixel-heightからなるコンス。
オプション引数x-limitとy-limitは、window-text-pixel-size
の場合と同じ意味をもつ。
これはwindow-text-pixel-size
を用いてstringの幅(ピクセル単位)を計算する利便関数である。
この関数は選択されたウィンドウのポイント位置にある行の高さをピクセル単位でリターンする。値にはその行の行スペーシングが含まれる(行の高さを参照)。
文字合成(character composition)が効力をもっていれば、たとえばアクセント付き文字、合字、あるいは複雑なテキストシェイプが一部スクリプト用に必要な際に書記素クラスター(grapheme cluster)を形成するよう文字シーケンスを合成できる。これが発生すると単純な方法によって文字が表示列にマップされなくなり、そのような文字列にたいする表示レイアウト、そしてワイド文字列の切り詰めも複雑な処理となり得る。これはそのような処理において一助となる関数である。この関数は引数stringを部分文字列のリストに分割する。この部分文字列はそれぞれ1つの単位として表示されるべき単一の書記素クラスターを生成する。このリストを使用すればLispプログラムは表示において正しい見た目になるよう視覚的に有効にstringの部分文字列を構成したり、リターンされたリストの構成要素の幅を追加してstringの任意の部分文字列の幅を計算する等を行うことができるだろう。
たとえば1つ目のグリフ以外を表示したければ以下のようにすればよい:
(apply #'insert (cdr (string-glyph-split string))))
行番号(Display Custom in The GNU Emacs Manualを参照)とともにバッファーを表示している際には、行番号の表示に必要な幅が解ると便利なときがあります。以下はレイアウト計算用にこの情報を必要とするLispプログラムのための関数です。
この関数は選択されたウィンドウで行番号の表示に使用される幅をリターンする。オプション引数pixelwiseがシンボルcolumns
なら、リターン値はフレームの正準列(正準文字幅)にたいする浮動小数点数となる。pixelwiseがt
やそれ以外の非nil
値なら、値はピクセルで計測した整数となる。pixelwiseが省略かnil
なら、値はline-number
フェイスにたいして定義されたフォントによる列数を表す整数となる。この場合には値には番号の表示の間隙を埋めるために使用する2列分は含まれない。選択されたウィンドウに行番号が表示されていなければ、pixelwiseの値にかかわらず値は0になる。別のウィンドウにたいしてこの情報が必要ならwith-selected-window
を使用すること(ウィンドウの選択を参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
各ディスプレイ行のトータル高さは、その行のコンテンツ高さにディスプレイ上部や下部にオプションで追加される垂直行スペーシングを加えて構成されます。
行のコンテンツ高さは、もしあれば最後の改行を含む、そのディスプレイ行の文字またはイメージの最大高さです(継続されるディスプレイ行には最後の改行が含まれない)。特にこれより大きい高さを指定しなければ、これがデフォルトの行高さになります(これは一般的には対応するフレームのデフォルトのフォント高さに等しい。フレームのフォントを参照)。
より大きい行高さを明示的に指定するためにはディスプレイ行の絶対高さ、または垂直スペースを指定する複数の方法が存在します。しかし何を指定したかに関わらず、実際の行高さがデフォルトの高さより小さくなることはありません。
改行はその改行で終わるディスプレイ行のトータル高さを制御するテキストプロパティとオーバーレイプロパティline-height
をもつことができます。プロパティ値はいずれかの形式をもつことができます:
t
プロパティの値が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
をもつことができます。その値がバッファーやフレームのデフォルトより大きければ、その改行で終端されるディスプレイ行にはかわりにその値が使用されます(改行にline-height
もあり、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シンボル29です。名前つきフェイスはdefface
マクロを使用して定義できます(フェイスの定義を参照)。Emacsにはいくつかの標準名前つきフェイスが同梱されています(基本的なフェイスを参照)。
Emacsのある部分では名前つきフェイスが要求されます(たとえばフェイス属性のための関数に記す関数)。特に明記しないかぎり、名前つきフェイスの参照だけに用語フェイスを使用することにします。
この関数はobjectが名前つきフェイス(フェイス名の役目をもつLispシンボルか文字列)なら非nil
、それ以外ならnil
をリターンする。
41.12.1 フェイスの属性 | フェイスとは? | |
41.12.2 フェイスの定義 | フェイスを定義する方法。 | |
41.12.3 フェイス属性のための関数 | フェイス属性の確認やセットを行う関数。 | |
41.12.4 フェイスの表示 | ある文字にたいして指定されたフェイスをEmacsが組み合わせる方法。 | |
41.12.5 フェイスのリマップ | フェイスを別の定義にリマップする。 | |
41.12.6 フェイスを処理するための関数 | フェイスの定義と確認を行う方法。 | |
41.12.7 フェイスの自動割り当て | 自動的にフェイスを割り当てるフック。 | |
41.12.8 基本的なフェイス | デフォルトで定義されるフェイス。 | |
41.12.9 フォントの選択 | あるフェイスに最適なフォントを見つける。 | |
41.12.10 フォントの照会 | 利用可能なフォント名とそれらの情報の照会。 | |
41.12.11 フォントセット | フォントセットは文字セットの範囲を処理するフォントコレクション。 | |
41.12.12 低レベルのフォント表現 | 文字表示フォントのLisp表現。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フェイス属性(Face attributes)は、フェイスの視覚的外観を決定します。以下はすべてのフェイス属性と、それらの可能な値と効果に関するテーブルです。
以下の値とは別に各フェイス属性は値unspecified
をもつことができます。この特殊な値はフェイスがその属性を直接指定しないことを意味します。unspecified
属性はEmacsにかわりに親フェイス(以下の:inherit
属性の記述を参照)を参照して、それに失敗したら基礎フェイス(フェイスの表示を参照)を参照することを指示します(ただしdefface
においてunspecified
は有効な値ではない)。
フェイスの属性としてreset
という値をもつこともできます。これはdefault
フェイスの相当する属性を意味する特別な値です。
default
フェイスではすべての属性を明示的に指定しなければならずスペシャル値reset
は使用できません。
これらの属性のいくつかは特定の種類のディスプレイにおいてのみ意味があります。ディスプレイが特定の属性を処理できなければ、その属性は無視されます。
:family
フォントファミリー名(文字列)。フォントファミリーに関する詳細は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
、regular
、medium
、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 :position position)
colorは文字列、またはそのフェイスのフォアグラウンドカラーを意味するシンボルforeground-color
。属性:color
の省略はフェイスのフォアグラウンドカラーの使用を意味する。styleは直線を意味するline
、または波線を意味するwave
いずれかのシンボルであること。属性:style
の省略は直線を意味する。positionが非nil
の場合には、アンダーラインをベースラインではなく、そのテキストのディセントに表示することを意味する。数値の場合には、ディセントの上方何ピクセルにアンダーラインを表示するかを指定する。
:overline
文字にオーバーラインを引くべきか否か、およびそのカラー。値がt
ならフェイスのフォアグラウンドカラーを使用してオーバーラインを引く。値が文字列ならそのカラーを使用してオーバーラインを引く。値nil
はオーバーラインを引かないことを意味する。
:strike-through
文字に取り消し線を引くべきか否か、およびそのカラー。値は:overline
で使用される値と同じ。
:box
文字周囲に枠(box)を描画するか否か、そのカラー、枠線の幅、および3D外観。以下は:box
の可能な値と意味:
nil
枠を描画しない。
t
幅1のフォアグラウンドカラーで枠線を描画する。
幅1のカラーcolorで枠線を描画する。
(:line-width (vwidth . hwidth) :color color :style style)
このフォームのようなplistによって、枠(box)に関するすべての側面を明示的に指定できる。このplistの任意の要素は省略できる。
値vwidthとhwidthはそれぞれ、垂直および水平方向に描画する線幅を指定する。デフォルトは(1
.
1)。負の水平または垂直幅-nは、背後にあるテキスト文字の高さや幅の増加を避けるために、テキストスペースを占める幅nの線の描画を意味する。リストのかわりに簡素化のために単一の数値nを指定でき、この場合には((abs
n) . n)
を指定したのと等しい。
値styleは3D枠線を描画するか否かを指定する。released-button
なら押下された3Dボタンのような外観、pressed-button
なら押下されていない3Dボタンのような外観、nil
、flat-button
、または省略なら2D枠線が使用される。
値colorは描画するカラーを指定する。デフォルトは3D枠線とflat-button
ではフェイスのバックグラウンドカラー、それ以外の枠線ではフェイスのフォアグラウンドカラー。
:inverse-video
文字が反転表示されて表示されるべきか否か。値はt
(反転表示する)かnil
(反転表示しない)のいずれか。
:stipple
バックグラウンドの点描(ビットマップ)。
値には文字列を指定できる。外部形式Xビットマップデータを含むファイルの名前であること。ファイルは変数x-bitmap-file-path
にリストされるディレクトリー内で検索される。
かわりに(width height
data)
という形式のリストによりビットマップで直接値を指定できる。ここでwidthとheightはピクセル単位によるサイズ、dataは行単位でビットマップのrawビットを含む文字列。各行は文字列内で連続する(width
+ 7) / 8バイトを占める(最善の結果を得るためにはユニバイト文字列であること)。これは各行が常に少なくとも1バイト全体を占めることを意味する。
値がnil
なら点描パターンを使用しないことを意味する。
これは特定のグレー色調を処理するために自動的に使用されるので、通常はstipple属性のセットは必要ない。
:font
そのフェイスの表示に使用されるフォント。値はフォントオブジェクトかフォントセットであること。フォントオブジェクトならASCII文字の表示用フェイスに使用されるフォントを指定する。フォントオブジェクト、フォントスペース、フォントエンティティーに関する情報は低レベルのフォント表現、フォントセットに関する情報はフォントセットを参照のこと。
set-face-attribute
やset-face-font
(フェイス属性のための関数を参照)を使用してこの属性を指定する際にはフォントspec、フォントエンティティー、または文字列を与えることもできる。Emacsはそのような値を適切なフォントオブジェクトに変換して、実際の属性値としてそのフォントオブジェクトを格納する。文字列を指定する場合には、その文字列のコンテンツはフォント名であること(Fonts in The GNU Emacs
Manualを参照)。フォント名がワイルドカードを含むXLFDなら、Emacsはそれらのワイルドカードに最初にマッチするフォントを選択する。この属性の指定により:family
、:foundry
、:width
、:height
、:weight
、:slant
の属性値も変更される。
:inherit
属性を継承するフェイス名、またはフェイス名のリスト。継承フェイス由来の属性は基礎フェイスより高い優先度で、基礎フェイスの場合と同じような方法でマージされる(フェイスの表示を参照)。継承元のフェイスがunspecified
ならEmacsは:inherit
属性を決してマージしないのでnil
と同様に扱われる。フェイスのリストが使用された場合には、リスト内先頭側フェイスの属性が末尾側フェイスの属性をオーバーライドする。
:extend
そのフェイスが行末を超えて拡張されるか、および行末とウィンドウのエッジの間の空スペースの表示に影響を与えるかどうか。値は行末とウィンドウのエッジの間の空スペースの表示にそのフェイスを使用するならt
、使用しなければnil
。Emacsが行末を超える空スペースの表示でいくつかのフォントをマージする際に、:extend
が非nil
のフェイスだけがマージされる。デフォルトではこの属性がセットされているのは少数のフェイス、特にregion
だけである。この属性はテーマがフェイスに明示的な値を指定しない際に、値がdefface
によるフェイスの元定義から継承される点において他の属性とは異なる(フェイスの定義を参照)。
hl-line-mode
のようないくつかのモードは、カレント行全体をマークするために:extend
プロパティをもつフェイスを使用する。ただしEmacsはバッファー内の最後の文字の後へのポイントの移動を常に許容するので、バッファーが改行文字で終わる場合にはバッファーの最後にある行のような場所にポイントが配置されるかもしれないことに注意。この“行”は実際は存在しない行なのでEmacsがハイライトすることはできない。
この関数は利用可能なフォントファミリー名のリストをリターンする。オプション引数frameはそのテキストが表示されるフレームを指定する。これがnil
なら選択されたフレームが使用される。
この変数はアンダーラインが引かれたテキスト表示時に、ベースラインとアンダーライン間の最小距離をピクセル単位で指定する。
この変数は:stipple
属性のビットマップファイルを検索するディレクトリーのリストを指定する。
これはobject、:stipple
(上記参照)での使用に適した有効なビットマップ仕様ならt
、それ以外ならnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フェイスを定義する通常の方法はdefface
マクロを通じて定義する方法です。このマクロはフェイス名(シンボル)をデフォルトのフェイスspec(face
spec)と関連付けます。フェイスspecとは任意の与えられた端末上でフェイスがどの属性をもつべきかを指定する構文です。たとえばあるフェイスspecは高カラー端末ではあるフォアグラウンドカラーし、低カラー端末では異なるフォアグラウンドカラーを指定するかもしれません。
値がフェイス名であるような変数を作りたがる人がいます。ほとんどの場合には、これは必要ありません。通常の手順はdefface
でフェイスを定義して、その名前を直接使用することです。
(通常はdefface
により)一度フェイスを定義したら、Emacsを再起動する以外にそのフェイスを安全に未定義にすることはできません。
このマクロはspecによりデフォルトフェイスspecが与えられるような名前つきフェイスとしてfaceを宣言する。シンボルfaceはクォートせずに‘-face’で終わらないこと(冗長かもしれない)。引数docはフェイスにたいするドキュメント文字列。追加のkeyword引数はdefgroup
やdefcustom
の場合と同じ意味をもつ(一般的なキーワードアイテムを参照)。
faceがすでにデフォルトフェイスspecをもつ場合には、このマクロは何も行わない。
デフォルトフェイスspecは何もカスタマイゼーション(カスタマイゼーション設定を参照)の効果がないときのfaceの外観を決定する。faceが(Customテーマやinitファイルから読み込んだカスタマイズにより)すでにカスタマイズ済みなら、その外観はデフォルトフェイスspecのspecをオーバーライドするカスタムフェイスspecにより決定される。しかしその後カスタマイゼーションが削除されたら、faceの外観は再びそのデフォルトフェイスspecにより決定されるだろう。
例外としてC-M-x (eval-defun
)、あるいはEmacs LispモードでC-x C-e
(eval-last-sexp
)によりdefface
を評価した場合には、これらコマンドの特別な機能により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)、haiku
(Haiku)、pgtk
(pure GTK)、または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をオーバーライドする。これはCustomのコード外部からこの関数を呼び出す際に有用。spec-typeがcustomized-face
かsaved-face
なら、この関数はカスタマイズされたspec、または保存されたカスタムspecをセットする。face-defface-spec
なら、この関数はデフォルトフェイスspec(defface
によりセットされるものと同一)をセットする。reset
なら、この関数はfaceからすべてのカスタマイゼーションspecとオーバーライドspecをクリアーする(この場合にはspecの値は無視される)。spec-typeの他の任意の値がフェイスspecに及ぼす効果は内部的な使用のために予約済みだが、それでも後述するようにこの関数はface自体の定義を行い属性を再計算する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでは名前つきフェイスの属性に直接アクセスしたり変更する関数を説明します。
この関数はframe上のfaceにたいする属性attributeの値をリターンする。サポートされている属性についてはフェイスの属性See フェイスの属性を参照のこと。
frameが省略かnil
なら選択されたフレームを意味する(入力のフォーカスを参照)。frameがt
なら、この関数は新たに作成されるフレームにたいして指定された属性の値、すなわちフェイスのdefface
定義(フェイスの定義を参照)の中のフェイスspecを適用する前、またはface-spec-set
でセットしたspecの属性の値。。このattributeのデフォルト値は下記の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のデフォルト属性、すなわちフェイスのdefface
定義の中のフェイスspecを適用する前、またはface-spec-set
でセットしたspecの属性の値が記述される。。このattributeのデフォルト値は下記のset-face-attribute
を使用して何らかの値を指定していなければ通常はunspecified
。
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
なら、この関数は新たに作成するフレームにデフォルトの属性をセットする。これらはdefface
によって指定された属性値を効果的にオーバーライドする。frameがnil
の場合には、この関数は既存のフレームすべてにたいして、新たに作成するフレームと同じように属性をセットする。
属性の値をリセットする、つまりそのフェイスが属性の値を独自に指定しないことを示すにはframeにnil
をセットしてこの関数を呼び出すことに加えて、更に属性にたいして特別な値であるunspecified
(nil
ではない!)、frame引数にt
をセットしてこの関数を呼び出す必要がある。これは新たにフレームが作成される際のデフォルト属性はdefface
内のフェイスspecとマージされるためであり、新たに作成されたフレームのデフォルト属性にunspecified
をもつことによってdefface
をオーバーライドできなくなる。この関数にたいして上述した特別な呼び出しを行うことによって、defface
がオーバーライドされるように調整を行う。
属性と値のペアーは最初に評価される:family
および:foundry
の属性以外は指定された順に評価されることに注意。これはもし特定の属性を2回以上指定すると、最後に指定した値が使用されること、更にある場合においては異なる属性順によって異なる結果が生成されるかもしれないことをも意味している。たとえば:weight
の前に:font
があると指定したフォントにウェイトの値が適用されるが、:font
の前に:weight
がある場合にはそのフェイスのカレントフォントにウェイトの値が適用されて、もしかしたらそのフォントで利用できるもっとも近いウェイトに丸められるかもしれない。
以下のコマンドと関数は主として古いバージョンのEmacsにたいする互換性のために提供されます。これらはset-face-attribute
を呼び出すことにより機能します。これらのframe引数にたいする値t
とnil
(や省略)はset-face-attribute
やface-attribute
の場合と同様に処理されます。コマンドがインタラクティブに呼び出されるとミニバッファーを使用して引数を読み取ります。
これらはそれぞれfaceの:foreground
属性、または:background
属性にcolorをセットする。
これはfaceの:stipple
属性にpatternをセットする。
faceのフォント関連の属性をfont
(文字列かフォントオブジェクト)の属性に変更する。font引数でアポートされるフォーマットについてはface-font-attributeを参照のこと。この関数はフェイスの:font
属性、および間接的に:family
、:foundry
、:width
、:height
、:weight
、:slant
の属性もそのフォントで定義された値にセットする。frameが非nil
なら、指定したフレームの属性だけを変更する。
これはfaceの:weight
属性にたいしてbold-pがnil
ならnormal、それ以外ならboldをセットする。
これはfaceの:slant
属性にたいしてitalic-pがnil
ならnormal、それ以外ならitalicをセットする。
これはfaceの:underline
属性にunderlineをセットする。
これはfaceの:inverse-video
属性にinverse-video-pをセットする。
これはフェイスfaceのフォアグラウンドカラーとバックグラウンドカラーを交換する。
これはfaceの:extend
属性にextendをセットする。
以下はフェイスの属性を調べる関数です。これらは主として古いバージョンのEmacsとの互換性のために提供されます。これらにたいしてframeを指定しなければ選択されたフレーム、t
なら新たなフレームにたいするデフォルトデータを参照します。フェイスがその属性にたいして何の値も定義していなければunspecified
がリターンされます。inheritがnil
ならそのフェイスにより直接定義された属性だけがリターンされます。inheritが非nil
ならそのフェイスの:inherit
属性により指定される任意のフェイス、inheritがフェイスまたはフェイスのリストなら指定された属性が見つかるまでそれらも考慮します。リターンされる値が常に指定された値であることを保証するためにはinheritに値default
を使用してください。
この関数は指定されたfaceが使用するフォント名をリターンする。
オプション引数frameが指定されたら、そのフレームのfaceのフォント名をリターンする。frameが省略かnil
ならデフォルトは選択されたフレーム。frameがt
なら、この関数は新たに作成されたフレームがfaceにたいして使用するデフォルトフォントについて報告する。
デフォルトではASCII文字表示用のフォントをリターンするが、frameがt
以外で3つ目のオプション引数characterが与えられた場合には、その文字にたいしてfaceが使用するフォント名をリターンする。
これらの関数はそれぞれフェイス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
をリターンする。
この関数はフェイスfaceが非nil
の:extend
属性を指定すれば非nil
をリターンする。inherit引数はface-attribute
に渡される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsが与えられたテキスト断片を表示する際には、そのテキストの視覚的外観は異なるソースから描画されるフェイスにより決定されるかもしれません。これら種々のソースが特定の文字にいたいして複数のフェイスを指定する場合には、Emacsはそれらのさまざまなフェイスの属性をマージします。以下にEmacsがフェイスをマージする順序を優先度順に記します:
region
フェイスを使用してそれをハイライトする。Standard
Faces in The GNU Emacs Manualを参照のこと。
nil
のface
属性をもつオーバーレイにテキストがある場合には、Emacsはそのプロパティにより指定されるフェイス(1つ以上)を適用する。そのオーバーレイがmouse-face
プロパティをもち、マウスがそのオーバーレイに十分に近ければEmacsはかわりにmouse-face
で指定されるフェイスかフェイス属性を適用する。オーバーレイのプロパティを参照のこと。
同一の文字を複数のオーバーレイがカバーする場合には、高優先度のオーバーレイが低優先度のオーバーレイをオーバーライドする。オーバーレイを参照のこと。
face
やmouse-face
プロパティを含む場合には、Emacsは指定されたフェイスやフェイス属性を適用する。特殊な意味をもつプロパティを参照のこと(これはFont Lockモードのフェイス適用方法。Font Lockモードを参照)。
mode-line
フェイスを適用する。選択されていないウィンドウのモードラインではEmacsはmode-line-inactive
フェイスを使用する。ヘッダーラインにたいしてはEmacsはheader-line
フェイスを適用する。タブラインにたいしては、Emacsはtab-line
フェイスを適用する。
before-string
やafter-string
プロパティを介したオーバーレイ文字列(オーバーレイのプロパティを参照)、あるいはディスプレイ文字列(その他のディスプレイ仕様を参照)に由来するテキストであり、かつ文字列にface
やmouse-face
のプロパティが含まれない、またはそれらのプロパィが何らかのフェイス属性を未定義のままにしているが、バッファーのテキストがフェイスを定義するディスプレイプロパティやオーバーレイプロパティの影響を受ける場合には、Emacsは“基礎”にあるバッファーテキストのフェイスやフェイス属性を適用する。これはたとえオーバーレイ文字列やディスプレイ文字列がマージン内に表示されている場合も同様であることに注意(マージン内への表示を参照)。
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
がバッファーローカルなら、そのローカル値はそのバッファーだけに効果をもつ。(:filtered (:window param val) spec)
を使用することにより特定のウィンドウだけに適用されるフェイスを含んだface-remapping-alist
では、そのフェイスはそのフィルター条件にマッチするだけに効果を及ぼす(特殊な意味をもつプロパティを参照)。フェイスのフィルタリングを一時的にオフにするには、face-filters-always-match
を非nil
値にバインドすれば、すべてのフェイスフィルターは任意のウィンドウにマッチする。
注意:
フェイスのリマッピングは再帰的ではない。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を追加する。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)
バッファーローカルなフェイスのリマップは、基本フェイス(基本的なフェイスを参照)の親フェイスでは動作が不確実であることに注意(これらはモードライン、ヘッダーライン、およびウィンドウやフレームのその他基本的な装飾に用いられるフェイスである)。たとえばmode-line-inactive
はmode-line
から派生したフェイスだが、mode-line
をリマップしても通常ならmode-line-inactive
には期待した効果は得られないだろう(特にリマップが一部バッファーにたいしてローカルに行われた場合)。かわりにmode-line-inactive
を直接リマップする必要がある。
この関数は以前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内部の低レベルでフィエスを一意に識別する番号。フェイス番号によるフェイスの参照を要するのは稀である。しかしmake-glyph-code
やglyph-face
(グリフを参照)のようなグリフを操作する関数は内部的にフェイス番号にアクセスする。フェイス番号はフェイスシンボルのface
プロパティの値として格納されることに注意。このフェイスプロパティにあなた自身が値をセットしないことを推奨する。
この関数はフェイス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前後の文字にフェイスを割り当てるように、これらの関数を記述することを推奨する。
非常に長い行がバッファーに含まれていると、これらの関数はあたかもposの周辺部分にナローイングされてlong-line-optimizations-in-fontification-functions
のラベルが付されたバッファーにおいて(ナローイングを参照)、with-restriction
フォームの内部であるかのように呼び出されることに注意。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
テキストにたいしてEmacs Lispプログラムが何らかのフェイス割り当てを要する場合には、完全に新たなフェイスを定義するより特定の既存フェイス、またはそれらを継承したフェイスを使用するほうがよいアイデアである場合がしばしばあります。Emacsに特定の外観を与えるために別のユーザーが既存フェイスをカスタマイズしていても、この方法なら追加のカスタマイズなしでプログラムは適合することでしょう。
以下にEmacsが定義する基本フェイス(basic face)のいくつかをリストしました。これらに加えて、ハイライトがFont Lockモードによりまだ処理されていなかったり、いくつかのFont Lockフェイスが使用されていなければ、構文的ハイライトのためにFont Lockフェイスを使うようにしたいと思うかもしれません。Font Lockのためのフェイスを参照してください。
default
属性がすべて指定されたデフォルトフェイス。他のすべてのフェイスは暗にこのフェイスを継承する。未指定(unspecified)な任意の属性は、このフェイスの属性をデフォルトとする(フェイスの属性を参照)。
mode-line-active
mode-line-inactive
header-line
tab-line
モードライン、ヘッダーライン、タブラインに使用される基本フェイス。
tool-bar
tab-bar
fringe
scroll-bar
window-divider
border
child-frame-border
GUIフレームのそれぞれ対応する装飾に使用される基本フェイス。
cursor
テキストカーソルに使用される基本フェイス。
mouse
テキスト上にマウスポインターがある際にマウスセンシティブなテキストの表示に使用される基本フェイス。
bold
italic
bold-italic
underline
fixed-pitch
fixed-pitch-serif
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)を選択しなければなりません30。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フィールドにワイルドカード‘*’をもちます。
この関数は指定されたcharactersにたいして、font-specのフォントマッチングを使用するように既存のフォントセットfontsetを変更する。
fontsetがnil
ならこの関数はframeのフォントセット、frameがnil
なら選択されたフレームのフォントセットを変更する。
fontsetがt
ならこの関数はshort名が‘fontset-default’であるようなデフォルトフォントセットを変更する。
characters引数はfont-specを使って表示すべき単一の文字を指定する。fromとtoが文字であるようなコンスセル(from . to)
でもよい。この場合には範囲fromからto
(両端を含む)までのすべての文字にたいしてfont-specを使用する。
charactersには文字セット(文字セットを参照)も指定できる。この場合には、その文字セット内のすべての文字にたいしてfont-specを使用する。
charactersにはスクリプト名(char-script-tableを参照)も指定できる。この場合にはスクリプトに属するすべての文字にたいしてfont-specを使用する。
charactersにはnil
も指定できる。この場合にはフォント仕様が指定されていないすべての文字にfont-specを使用する。
font-specは関数font-spec
が作成したfont-specオブジェクトかもしれない(低レベルのフォント表現を参照)。
font-specにはコンスセル(family
.
registry)
を指定できる。ここでfamilyはフォントのファミリー名(先頭にfoundry名が含まれるかもしれない)、registryはフォントのレジストリー名(末尾にエンコーディング名が含まれるかもしれない)。
font-specにはフォント名(文字列)も指定できる。
font-specには、指定されたcharactersにたいするフォントが存在しないことを明示的に指定するnil
を指定できる。これはたとえばUnicodeのPUA(Private
Use Area)由来のようなグリフをもたない文字のフォントにたいするシステムワイドの高価な検索を避けるために有用。
オプション引数addが非nil
なら、以前charactersにセットされたフォントspecにfont-specを追加する方法を指定する。prepend
ならfont-specは既存specの先頭、append
ならfont-specは末尾に追加される。デフォルトではfont-specは以前のセットされたfontspecをオーバーライドする。
たとえば以下は文字セットjapanese-jisx0208
に属するすえての文字にたいして、ファミリー名が‘Kochi
Gothic’であるようなフォントを使用するようにデフォルトフォントセットを変更する。
(set-fontset-font t 'japanese-jisx0208 (font-spec :family "Kochi Gothic"))
この関数はEmacsがcharを表示できるようなら非nil
をリターンする。またはより正確には選択されたフレームのフォントセットが、charが属する文字セットを表示するためのフォントをもてばt
をリターンする。
フォントセットは文字単位でフォントを指定できる。フォントセットがこれを行う場合には、この関数の値は正確ではないかもしれない。
この関数はテキスト端末用のコーディングシステムがその文字をエンコード可能かどうかもチェックするので、利用可能なフォントがなくても非nil
をリターンするかもしれない(端末I/Oのエンコーディングを参照)。
[ << ] | [ < ] | [ 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
これらは同じ名前のフェイス属性と同じ意味をもつ。フェイスの属性を参照のこと。:family
と:foundry
は文字列で、それ以外はシンボル。例の値のように:slant
はitalic
、:weight
はbold
、:width
はnormal
かもしれない。
:size
フォントサイズ。非負の整数はピクセル単位、浮動小数点数ならポイントサイズを指定する。
:adstyle
‘sans’のような、そのフォントにたいするタイポグラフィックスタイル(typographic style)の追加情報。値は文字列かシンボルであること。
:registry
‘iso8859-1’のようなフォントの文字セットレジストリーとエンコーディング。値は文字列かシンボルであること。
:dpi
フォントがデザインされたインチあたりのドット数による解像度。値は非負の数値でなければならない。
:spacing
フォントのスペーシング(proportional, dual, mono, or
charcell)。値は整数(proportionalは0、dualは90、monoは100、charcellは110)、あるいは1文字のシンボル(P
、D
、M
、C
)であること。
:avgwidth
1/10ピクセル単位でのフォントの平均幅。値は非負の数値であること。
: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
は省略可。OpenTypeのスクリプト、言語、機能タグのリストについてはthe list of registered OTF tagsを参照のこと。
:type
¶文字の描画に使用されるフォントバックエンド(font
backend)を指定するシンボル。指定できる値はプラットフォームとビルド時にEmacsがどのようにconfigureされたかに依存する。典型的な値としてはXではftcrhb
とxfthb
、MS-Windowsではharfbuzz
、GNUstepではns
などが含まれる。font-specのように未指定のままだとnil
もあり得る。
フォントspec font-spec内のプロパティpropertyにvalueをセットする。propertyには上述のいずれかを指定できる。
フォントエンティティーはオープンする必要がないフォントへの参照です。フォントオブジェクトとフォント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の値をリターンする。propertyにはfont-spec
がサポートするもののいずれかを指定できる。
fontがフォントspecであり、そのフォントspecがpropertyを指定しなければリターン値はnil
。fontがフォントオブジェクトかフォントエンティティーなら、:scriptプロパティにたいする値はそのフォントがサポートするスクリプトのリスト、:otf
プロパティにたいする値は(gsub . gpos)
のような形式のコンス。ここでgsubとgposはそのフォントがサポートするOpenType機能を表す以下のような形式のリスト
((script-tag (langsys-tag feature…) …) …)
where script-tag, langsys-tag, and feature ここでscript-tag、langsys-tag、featureはOpenTypeのレイアウトtagを表すシンボル。
fontがフォントオブジェクトの場合には、fontのフォントバックエンドが非OpenTypeフォントにたいする結合文字(combining
characters)をサポートしていればスペシャルプロパティ:combining-capability
は非nil
。
この関数は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)、水平スクロールを示すビットマップを表示できる側面の細い垂直ストリップです。
41.13.1 フリンジのサイズと位置 | ウィンドウフリンジの配置場所を指定する。 | |
41.13.2 フリンジのインジケーター | ウィンドウフリンジ内にインジケーターアイコンを表示する。 | |
41.13.3 フリンジのカーソルFrin | 右フリンジ内にカーソルを表示する。 | |
41.13.4 フリンジのビットマップ | フリンジインジケーターにたいしてビットマップを指定する。 | |
41.13.5 フリンジビットマップのカスタマイズ | フリンジ内で使用する独自ビットマップの指定。 | |
41.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のフリンジは未変更のままになる。
ここで指定した値は、windowにたいしてkeep-marginsをnil
か省略したset-window-buffer
(バッファーとウィンドウを参照)の呼び出しによって後刻オーバーライドされるかもしれない。しかしオプションの5つ目の引数persistentが非nil
、かつ他の引数が成功裏に処理されたら、ここで指定した値は後続のset-window-buffer
呼び出しに引き継がれる。これはミニバッファーウィンドウでフリンジを永続的にオフにするために使用できる。例はset-window-scroll-bars
(スクロールバーを参照)の説明を参照のこと。
この関数はウィンドウwindowのフリンジに関する情報をリターンする。windowが省略かnil
なら選択されたウィンドウが使用される。値は(left-width
right-width outside-margins persistent)
という形式。
[ << ] | [ < ] | [ 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
(フリンジのカーソルFrinを参照)から参照されます。
Lispプログラムも行内に出現する文字の1つにdisplay
プロパティを使用することにより、左フリンジまたは右フリンジ内にビットマップを直接表示することができます。そのような表示指定は以下の形式をもちます
(fringe bitmap [face])
fringeはleft-fringe
かright-fringe
いずれかのシンボル、bitmapは表示するビットマップを識別するシンボルです。オプションのfaceはビットマップの表示でフォアグラウンカラーおよびバックグラウンドカラーを使用するフェイスを命名します(
faceが指定しないカラーにたいしてはfringe
フェイスの属性を使用する)。faceを省略すると、fringe
が指定しないカラーにdefault
フェイスの属性を使用することを意味します。default
フェイスやfringe
フェイスの属性に依存しない予測可能な結果を得るために、faceは省略せず常に特定のフェイスを与えることを推奨します。特にビットマップをfringe
フェイスで表示したければ、faceとしてfringe
を使用してください。
たとえば左フリンジに矢印を表示するためには、warning
フェイスを使用して以下のようにできます:
(overlay-put (make-overlay (point) (point)) 'before-string (propertize "x" 'display `(left-fringe right-arrow warning)))
以下は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
bottom-left-angle
、bottom-right-angle
top-left-angle
、top-right-angle
left-bracket
、right-bracket
empty-line
バッファー境界を示すために使用される。
filled-rectangle
、hollow-rectangle
filled-square
、hollow-square
vertical-bar
、horizontal-bar
フリンジカーソルの異なるタイプにたいして使用される。
exclamation-mark
、question-mark
large-circle
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ピクセル、低位ビットはそのビットマップの最右ピクセルに対応する(このビットオーダーはXBMイメージと逆順であることに注意。XBMイメージを参照)。
高さは通常は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のスクロールバーの幅および/または高さ、およびタイプをセットする。windowがnil
なら選択されたウィンドウが使用される。
widthはピクセル単位で垂直スクロールバーの幅を指定する(nil
はそのフレームにたいして指定された幅の使用を意味する)。vertical-typeは垂直スクロールバーをもつかどうか、もつ場合にはその位置を指定する。可能な値はleft
、right
、t
(フレームのデフォルトの使用を意味する)、垂直スクロールバーなしならnil
のいずれか。
heightはピクセル単位で水平スクロールバーの高さを指定する(nil
はそのフレームにたいして指定された高さの使用を意味する)。horizontal-typeは水平スクロールバーをもつかどうかを指定する。可能な値はbottom
、t
(フレームのデフォルトの使用を意味する)、水平スクロールバーなしならnil
のいずれか。ミニウィンドウにたいして値t
はnil
、すなわち水平スクロールバーを表示しないことを意味することに注意。ミニウィンドウで水平スクロールバーを表示するためには、明示的にbottom
を指定する必要がある。
期待するサイズのスクロールバーを収容するのにwindowが十分大きくなければ、windowのスクロールバーは未変更のままになる。
ここで指定した値はwindowにたいする引数keep-marginsがnil
か省略したset-window-buffer
(バッファーとウィンドウを参照)の呼び出しにより後からオーバーライドされるかもしれない。しかしオプションの1つ目の引数persistentが非nil
、かつ他の引数が成功裏に処理されたなら、ここで指定された値は後続のset-window-buffer
呼び出しに引き継がれる。
set-window-scroll-bars
およびset-window-fringes
(フリンジのサイズと位置を参照)のpersistent引数を使用すれば、以下のスニペットを早期initファイル(early init
file)に追加することにより、すべてのミニバッファーウィンドウでスクロールバーおよび/またはフリンジを信頼性をもって永続的にオフにすることができます(initファイルを参照)。
(add-hook 'after-make-frame-functions (lambda (frame) (set-window-scroll-bars (minibuffer-window frame) 0 nil 0 nil t) (set-window-fringes (minibuffer-window frame) 0 0 nil t)))
以下の4つの関数は引数として生きたウィンドウを受け取り、デフォルトは選択されたウィンドウです。
この関数は(width columns vertical-type height
lines horizontal-type persistent)
という形式のリストをリターンする。
値widthは垂直スクロールバーの幅に指定された値(nil
もあり得る)。columnsは垂直スクロールバーが実際に占有する列数(丸められているかもしれない)。
値heightは水平スクロールバーの高さに指定された値(nil
もあり得る)。linesは水平スクロールバーが実際に占有する行数(丸められているかもしれない)。
persistentの値は最後に成功裏にset-window-scroll-bars
を呼び出した際にwindowに指定した値、そのような呼び出しがなければnil
。
この関数はウィンドウ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
プロパティにたいして値を指定しますが1つの値だけが効果をもち、それはget-char-property
のルールにしたがいます。テキストプロパティを調べるを参照してください。
display
プロパティの値はディスプレイ仕様、または複数のディスプレイ仕様を含むリストかベクターであるべきです。
これはベクター、リスト、あるいは単純なプロパティであるかどうかに関係なく、特定のdisplay
を取得するために使用できる利便用関数である。これはget-text-property
(テキストプロパティを調べるを参照)と似ているが、display
プロパティにたいしてのみ動作する点が異なる。
positionは調べるバッファーまたは文字列内の位置、propはリターンされるdisplay
プロパティ。オプション引数objectは文字列かバッファーのいずれかで、デフォルトはカレントバッファー。オプション引数propertiesが非nil
ならそれはdisplay
プロパティでなければならず、その場合にはpositionとobjectは無視される(これはたとえばget-char-property
(テキストプロパティを調べるを参照)ですでにdisplay
プロパティを取得済みな場合に役に立つかもしれない)。
startからendのテキストのdisplay
プロパティpropnvalueを追加する。
リージョン内にdisplay
プロパティが非nil
のテキストがあれば、それらのプロパティは保たれる。たとえば:
(add-display-text-property 4 8 'height 2.0) (add-display-text-property 2 12 'raise 0.5)
これを行うと2から4のリージョンのdisplay
プロパティはraise
、4から8のリージョンのdisplay
プロパティにはraise
とheight
の両方、そして最後の8から12のdisplay
プロパティはraise
だけになる。
objectが非nil
なら、それは文字列かバッファーであること。nil
の場合のデフォルトはカレントバッファー。
いくつかのディスプレイ仕様には、表示時に評価されるLispフォームを含めることができます。これは特定の状況では安全ではないかもしれません(ディスプレイ仕様が何らかの外部のプログラムやエージェントにより生成されたとき等)。(disable-eval spec)
のように特別なシンボルdisable-eval
で始まるリスト内にディスプレイ仕様をラップすることにより、他のすべてのディスプレイプロパティ機能をサポートしつつ、spec内の任意のLisp評価が無効になります。
このセクションの残りの部分では、複数の種類のディスプレイ仕様とそれらの意味を説明します。
41.16.1 テキストを置換するディスプレイ仕様 | テキストを置換するディスプレイspec。 | |
41.16.2 スペースの指定 | 指定された幅に1つのスペースを表示する。 | |
41.16.3 スペースにたいするピクセル指定 | ピクセル単位でスペースの幅や高さを指定する。 | |
41.16.4 その他のディスプレイ仕様 | イメージの表示。高さ、スペーシング、その他のテキストプロパティの調整。 | |
41.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 | xwidget | 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なら、それのバッファーローカルな変数バインディングが使用されます。このバインディングには数字か上述の形式のコンスセル(他にもバッファーローカルなバインディングをもつシンボルがcar
であるような他のコンスセルも含む)が可能です。
単位in
、mm
、cm
はそれぞれインチ、ミリメートル、センチメートルごとのピクセル数を指定します。単位width
とheight
はそれぞれカレントフェイスのデフォルトの幅と高さに対応します。(image . props)
という形式のイメージ仕様は、指定されたイメージの幅や高さに対応します(イメージのディスクリプタを参照)。同様に(xwidget . props)
という形式のxwidget仕様は指定されたxwidgetび幅や高さを意味します。埋め込みネイティブウィジェットを参照してください。
要素left-fringe
、right-fringe
、left-margin
、right-margin
、scroll-bar
、text
はそのウィンドウの対応する領域の幅を指定します。そのウィンドウで行番号(表示されるテキストのサイズを参照)を表示している際にはテキストエリアの幅は行番号の表示に要するスクリーンスペースで減じられます。
位置left
、center
、right
はテキストエリアの左端、中央、右端から相対的に位置を指定するために:align-to
とともに使用できます。ウィンドウで行番号を表示していて、バッファーのテキスト(ヘッダーラインではない;
以下参照)のディスプレイプロパティに:align-to
が使用されている場合のleft
とcenter
の位置は、行番号の表示に要するスクリーンスペースを考慮したオフセットになります。
(text
を除いた)上記ウィンドウ要素は与えられたエリアの左端から相対的に位置を指定するために:align-to
とともに使用することもできます。(最初に出現するこれらシンボルのいずれかにより)相対的位置にたいするベースオフセットが一度セットがされると、残りのシンボルは指定されたエリアの幅として解釈されます。たとえば左マージンの中央に位置揃えするには以下のようにします
:align-to (+ left-margin (0.5 . left-margin))
位置揃えにたいしてベースオフセットが何も指定されなければ、テキストエリア左端にたいして常に相対的になります。たとえば‘:align-to 0’はテキストエリアの最初のテキスト行に位置揃えします。ウィンドウで行番号を表示している際には、テキストは行番号表示の終了に使用されるスペースから開始するとみなされます。
(num
. expr)
という形式の値は、numとexprにより生成される値を意味します。たとえば(2
. in)
は2インチの幅、(0.5 . image)
は指定されたimage
(それのイメージspecにより与えられる必要がある)の幅(または高さ)の半分を指定します。
フォーム(+ expr ...)
は式の値を合計します。フォーム(- expr
...)
は式の値を符号反転または減算します。
ディスプレイ仕様:align-to
を使用しているヘッダーラインに表示されているテキストは、display-line-numbers-mode
のオンオフや行番号の表示幅の変更時に自動的に再度位置揃えされることはありません。ヘッダーラインのテキストの位置揃え(alignment)を更新してヘッダーラインのテキストとバッファーテキストの位置揃えを保つには、そのバッファーでheader-line-indent-mode
をオンにして、ディスプレイ仕様の中でこのモードのheader-line-indent
およびheader-line-indent-width
という2つの変数を使用します。ウィンドウのヘッダーラインを参照してください。以下に単純な例を示します:
(setq header-line-format (concat (propertize " " 'display '(space :align-to (+ header-line-indent-width 10))) "Column"))
この例ではdisplay-line-numbers-mode
のオンオフや行番号の表示幅の変更とは関係なく、ヘッダーラインのテキスト‘Column’をバッファーのテキストの10列目に位置揃えしています。
[ << ] | [ < ] | [ 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は整数か浮動小数点数であること。スペース以外の文字は影響を受けない。特にこれはタブ文字に影響を与えない。
(min-width (width))
このディスプレイ仕様はテキストがwidthより短ければ、終端に空白を追加することで少なくともwidthのスペースを占めるよう保証する。このテキストはパラメーターの識別子を用いて分割される。パラメーターが1要素のリストであるのはこれが理由。たとえば:
(insert (propertize "foo" 'display '(min-width (6.0))))
これにより‘foo’の後にパディングが追加されて、合計幅が通常の文字6つ分の幅になる。影響を受ける文字はdisplayプロパティのリスト(6.0)
をeq
で比較することで識別されることに注意。要素widthはテキストに要求される最小幅を指定する整数または浮動小数点数(スペースにたいするピクセル指定を参照)。
(height height)
このディスプレイ仕様はテキストを高く(taller)、または低く(shorter)する。heightには以下を指定できる:
(+ n)
これはnステップ大きいフォントの使用を意味する。ステップは利用可能なフォントのセットから定義される。利用可能なフォントとは、具体的には、このような場合でなければ、heightを除いてそのテキストに指定されたすべての属性にマッチするフォント。適切なフォントの各サイズは別のステップとして利用可能とみなされる。nは整数であること。
(- n)
これはnステップ小さいフォントの使用を意味する。
数値factorはデフォルトフォントのfactor倍高いフォントの使用を意味する。
高さを計算する関数。この関数はカレントの高さを引数として呼び出されて、使用する新たな高さをリターンすること。
heightの値が上記のいずれにもマッチしなければ、それはフォームである。Emacsはheight
をカレントで指定されたフォントの高さにバインドして新たな高さを取得するためにフォームを評価する。
(raise factor)
この種のディスプレイ仕様は、その行のベースラインに相対的にテキストを上(raise)、または下(lower)に指定する。これは主に上付き文字と下付き文字を意図している。
factorは影響を受けるテキストの高さにたいする乗数として解釈される数値でなければならない。これが正なら上、負なら下に文字を表示することを意味する。
テキストがraise
より前(左)に指定されたheight
ディスプレイ仕様をもつ場合には、テキストが上下される量はテキストの高さにもとづくので、上下されるピクセル数にはraise
が効果をもつ。したがって通常のテキスト高さより小さい上付きや下付きで表示したければ、height
の前にraise
を指定することを考慮するべきである。
任意のディスプレイ仕様にたいして条件を作成できます。これを行うには、(when condition
.
spec)
という形式の別リスト内にパッケージします。この場合には、仕様specはconditionが非nil
値に評価されたときだけ適用されます。この評価の間にobject
は条件つきdisplay
プロパティをもつ文字列、またはバッファーにバインドされます。position
とbuffer-position
はそれぞれobject
内の位置、およびdisplay
プロパティが見つかったバッファー位置にバインドされます。object
が文字列の際には両者の位置は異なるかもしれません。
conditionはこのディスプレイ仕様が配置された箇所のテキストを再表示が調べる際だけ評価されるので、この機能は比較的安定した条件にもっとも適していることに注意してください(特定のバッファー位置それぞれにたいして評価ごとに同じ結果を取得する)。同じのテキスト位置にたいする結果が異なる、つまり結果がポイント位置に依存するようなら、この条件仕様はあなたの望むものではないかもしれません。なぜなら再表示は最後の表示サイクル以降に何かが変更されたといなす理由があるバッファーテキストの部分だけを調べるからです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バッファーはその左側と右側にディスプレイマージン(display
margins)と呼ばれるブランクエリアをもつことができます。それらのエリア内には通常はテキストが出現することはありませんが、display
プロパティを使用してディスプレイマージン内に何かを配置することができます。現在のところマージン内のテキストやイメージをマウスセンシティブにする方法はありません。
マージン内に何かを表示するにはテキストのdisplay
プロパティのマージンディスプレイ仕様(margin display
specification)で指定します。これは配置したテキストが表示されないことを意味する置換ディスプレイ仕様です。マージン表示は表示されますがそのテキストは表示されません。
マージンディスプレイ仕様とは((margin right-margin) spec)
や((margin
left-margin)
spec)
のようなものです。ここでspecはマージン内に何を表示するかを告げる別のディスプレイ仕様です。典型的にはこれは表示するテキスト文字列やイメージディスクリプタです。
特定のバッファーテキストに割り当てられたマージンに何かを表示するためには、そのテキストにbefore-string
プロパティをもつオーバーレイをput、before-stringのコンテンツとしてマージンディスプレイ仕様をputします。
マージン内に表示する文字列がフェイスを指定しなければ、テキストエリア内に表示される文字列に準じたいくつかの規則と優先度によりフェイスが決定されることに注意してください(フェイスの表示を参照)。これが望ましくないマージンへのフェイスの“漏洩”をもたらすようなら、文字列が文字列用に明示的なフェイスを確実にもつようにしてください。
ディスプレイマージンが何かを表示可能になる前に、それらに非0の幅を与えなければなりません。これを行う通常の方法は以下の変数をセットする方法です:
この変数は左マージンの幅を文字セル(別名は“列”)単位で指定する。これ、すべてのバッファーでバッファーローカルである。値nil
は左マージンエリアなしを意味する。
この変数は右マージンの幅を文字セル単位で指定する。これはすべてのバッファーでバッファーローカルである。値nil
は右マージンエリアなしを意味する。
これらの変数をセットしてもウィンドウには即座には反映されません。これらの変数はウィンドウ内に新たなバッファーを表示する際にチェックされます。したがってset-window-buffer
を呼び出すことにより変更を反映することができます。これらの変数を左右のマージンのカレント幅の判定を試みるために使用してはいけません。かわりに関数window-margins
を使用してください。
マージン幅を即座にセットすることもできます。
この関数はウィンドウwindowのマージン幅、文字セル単位で指定する。引数leftは左マージン、rightは右マージン(デフォルトは0
)を制御する。
期待する幅のマージンを収容するのにwindowが十分大きくなければ、windowのマージンは未変更のままになる。
ここで指定した値はwindowにたいする引数keep-marginsがnil
か省略したset-window-buffer
(バッファーとウィンドウを参照)の呼び出しにより後からオーバーライドされるかもしれない。
この関数はwindowの左マージンと右マージンの幅を(left . right)
という形式のコンスセルでリターンする。2つのマージンエリアのいずれか一方が存在しなければ幅はnil
でリターンされる。2つのマージンがどちらも存在しなければ、この関数は(nil)
をリターンする。windowがnil
なら選択されたウィンドウが使用される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsバッファー内にイメージを表示するためには最初にイメージディスクリプタを作成して、それを表示されるテキストのdisplay
プロパティ(display
プロパティを参照)内のディスプレイ指定子として使用しなければなりません。
Emacsはグラフィカルな端末で実行時には、通常はイメージの表示が可能です。テキスト端末、イメージサポートを欠く特定のグラフィカル端末、またはイメージサポートなしでコンパイルされたEmacsではイメージを表示できません。原則的にイメージが表示可能か判断するためには関数display-images-p
を使用できます(ディスプレイ機能のテストを参照)。
41.17.1 イメージのフォーマット | サポートされるイメージフォーマット。 | |
41.17.2 イメージのディスクリプタ | :display 内で使用されるイメージの指定方法。
| |
41.17.3 XBMイメージ | XBMフォーマット用の特別な機能。 | |
41.17.4 XPMイメージ | XPMフォーマット用の特別な機能。 | |
41.17.5 ImageMagickイメージ | ImageMagickを通じて利用できる特別な機能。 | |
41.17.6 SVGイメージ | SVGイメージの作成と操作。 | |
41.17.7 その他のイメージタイプ | サポートされる他のさまざまなフォーマット。 | |
41.17.8 イメージの定義 | 後で使用するためにイメージを定義する便利な方法。 | |
41.17.9 イメージの表示 | 一度定義されたイメージを表示するための便利な方法。 | |
41.17.10 マルチフレームのイメージ | 1つ以上のフレームを含むイメージ。 | |
41.17.11 イメージキャッシュ | イメージ表示の内部的メカニズム。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsはいくつかの異なるフォーマットのイメージを表示できます。これらのイメージフォーマットのいくつかは、特定のサポートライブラリーがインストールされている場合のみサポートされます。いくつかのプラットフォームではEmacsはオンデマンドでサポートライブラリーをロードできます。そのような場合には、それらの動的ライブラリーにたいする既知の名前セットを変更するために変数dynamic-library-alist
を使用できます。動的にロードされるライブラリーを参照してください。
サポートされるイメージフォーマット(と要求されるサポートライブラリー)にはPBMとXBM(サポートライブラリーに依存せず常に利用可能)、XPM
(libXpm
)、GIF (libgif
かlibungif
)、JPEG
(libjpeg
)、TIFF (libtiff
)、PNG (libpng
)、SVG
(librsvg
)、WebP (libwebp
)が含まれます。
これらのイメージフォーマットはそれぞれイメージタイプシンボル(image type
symbol)に関連付けられます。上記のフォーマットにたいするシンボルは順にpbm
、xbm
、xpm
、gif
、jpeg
、tiff
、png
、svg
、webp
です。
一部のプラットフォームではオプションのライブラリーを何も要求しないイメージサポートが組み込まれており、それにはBMPイメージも含まれています31。
さらに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
を含みます。
イメージのサイズを定義するイメージディスクリプタ:width
、:height
、:max-width
、:max-height
は整数(サイズをピクセルで表現)、あるいは
(value
.
em)
という形式をとります。ここでvalueはems32によるサイズの長さ。1emはフォント高さと等しく、valueは整数または浮動小数。
以下はすべてのイメージタイプにたいして意味のあるプロパティのリストです(以降のサブセクションで説明するように特定のイメージタイプにたいしてのみ意味があるプロパティも存在する):
:type type
イメージタイプ。 イメージのフォーマットを参照のこと。 すべてのイメージディスクリプタは。このプロパティを含まなければならない。
:file file
これはファイルfileからイメージをロードすることを意味する。fileが絶対ファイル名でなければ、それはimage-load-path
のディレクトリーそれぞれから相対的に展開される(イメージの定義を参照)。
: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が負ならボタンを押下した状態、それ以外はボタンを押下していない状態のイメージでシャドーを描画する。
: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
と:height
が指定されていて:width
が未指定なら、アスペクト比を維持することにより:max-width
を超える幅が要求されるかもしれない。これが発生した場合には、スケーリングは:max-width
を超過しないアスペクト比を維持できるように、小さい値を使用する。:max-height
と:width
が指定されていて:height
が未指定のときも同様。たとえば200x100のイメージがあり:width
を400、:max-height
を150に指定すると、アスペクト比を保持しつつ“max”のセッティングを超過しないようにイメージは最終的には300x150になる。このパラメーターの組み合わせは、“可能なかぎり大きく、ただし利用可能なディスプレイエリア以下でこのイメージを表示せよ”のように指示する簡便な手段である。
:scale scale
これは数字であること。1より大きい値は幅および高さを乗じたサイズの増加、小さい値はサイズの減少を意味する。たとえば値0.25はイメージをオリジナルの1/4のサイズにするだろう。このスケーリングにより:max-width
や:max-height
で指定されたイメージの元のサイズより大きくなる場合でも、結果サイズがこれら2つの値を超過することはない。:scale
および:height
/:width
の両方が指定されたら、高さ/幅は指定されたスケーリング倍率に調整される。
:rotation angle
ローテーション角度を度数(degree)で指定する。イメージタイプがimagemagick
でなければ、90°の倍数のみをサポート。値が正なら時計回り、負なら反時計回り。ローテーションはスケーリングとクロッピング(cropping:
切り取り、抜き出し)の後に行われる。
:flip flip
t
ならイメージを水平方向に反転(flip)する。現在のところイメージタイプがimagemagick
なら効果はない。垂直方向の反転はイメージの180度回転とこの値を切り替えることによって行われている。
:transform-smoothing smooth
これがt
ならイメージ変換にスムージングを適用、nil
ならスムージングを適用しない。使用する正確なアルゴリズムはプラットフォームに依存するが、バイリニアフィルタリング(bilinear
filtering)と等価であること。スムージングを無効にすると、もっとも近い類似アルゴリズムを使用する。
このプロパティが未指定なら、create-image
はスケーリングするかしないかを指示するために、ユーザーオプションimage-transform-smoothing
を使用する。このオプションはnil
(スムージングなし)、t
(スムージングを使用)、またはイメージオブジェクトを唯一のパラメーターとして呼び出されてnil
かt
をリターンする述語関数であること。デフォルトではダウンスケーリングにはスムージングを適用、巨大なアップスケーリングにはスムージングを適用しない。
:index frame
マルチフレームのイメージを参照のこと。
: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]
。
このマップの座標はすべての変換(ローテーション、スケーリング等)の後に表示されたイメージを反映する必要があり、更に(デフォルトでは)Emacsの行う自動スケーリングの効果もあるので、イメージ作成時には:scale
1.0
を指定するか、マップ要素の計算にimage-compute-scaling-factor
の結果を用いる必要があることにも注意。
この関数はイメージspecがマスクビットマップをもつならt
をリターンする。frameはそのイメージが表示されるフレーム。frameがnil
か省略された場合には選択されたフレームが使用される(入力のフォーカスを参照)。
この関数はframeがイメージのスケーリングとローテーションをサポートすれば非nil
をリターンする。frameがnil
か省略なら選択されたフレームの使用を意味する(入力のフォーカスを参照)。リターンされるリストには何のイメージ変換操作がサポートされるかを示すシンボルが含まれる:
scale
frameは:scale
、:width
、:height
、:max-width
、:max-height
のプロパティを通じたイメージスケーリングをサポートする。
rotate90
frameはローテーション角度が90°の整数倍ならイメージローテーションをサポートする。
イメージ変換がサポートされていなければ:rotation
、:crop
、:width
、:height
、:scale
、:max-width
、:max-height
は(利用可能なら)ImageMagickを通じた場合のみ使用可能(ImageMagickイメージを参照)。
[ << ] | [ < ] | [ 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つのフォーマットが存在する:
:data-height
と:data-width
を指定する。
stride * height
ビットを含むこと(strideはイメージ幅以上の8の最小倍数)。この場合にはその文字列がXBMファイル全体ではなく、単にビットだけを含むことを示すとともに、そのイメージのサイズを指定するために:data-height
、:data-width
、:stride
を指定する必要がある。
:stride stride
各行に格納さたブールベクターのエントリー数(width以上の8の最小倍数)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
XPMフォーマットを使用するにはイメージタイプにxpm
を指定します。xpm
イメージタイプでは追加のプロパティ:color-symbols
にも意味があります。
:color-symbols symbols
値symbolsは要素が(name
.
color)
という形式をもつようなalistであること。各要素においてnameはイメージファイル内に出現するカラー名、colorはそのカラー名の実際の表示に使用するカラーを指定する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ImageMagickのサポートつきのEmacsビルドでは、多くくのイメージフォーマットをロードするためにImageMagickライブラリーを使用できます(File
Conveniences in The GNU Emacs
Manualを参照)。ImageMagickを通じてロードしたイメージのイメージタイプシンボルは、基礎となる実際のイメージフォーマットとは無関係にimagemagick
になります。
ImageMagickサポートをチェックするには以下を使用してください:
(image-type-available-p '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
の場合のデフォルトはフレームのバックグラウンドカラー。
:format type
値typeはimage-format-suffixes
で見られるような、イメージのタイプを指定するシンボルであること。これはイメージが関連付けられたファイル名をもたない際に、イメージタイプを検出する助けとなるヒントをImageMagickに提供する。
:crop geometry
geometryの値は(width height x
y)
という形式のリストであること。widthとheightはクロップするイメージの幅と高さを指定する。xが正の数値なら元イメージの左エッジ、負の数値なら右エッジからクロップのオフセットを指定する。yが正の数値なら元イメージの上エッジ、負の数値なら下エッジからクロップのオフセットを指定する。xかyがnil
か未指定ならクロップ領域は元イメージの中央になる。
クロップ領域がイメージ外部、またはエッジとオーバーラップする場合には、イメージ外部の全領域を除外するように縮小される。これはwidthやheightに大きな値を与えてイメージサイズを増加するために:crop
を使用できないことを意味する。
クロッピングはスケーリング後、ローテーション前に行われる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SVG (Scalable Vector Graphics: 変倍ベクタ図形)はイメージを指定するためのXMLフォーマットです。SVGイメージは、追加で以下のイメージディスクリプタプロパティをサポートします:
:foreground foreground
foregroundが非nil
なら、カラーを指定する文字列であること。これはイメージのフォアグラウンドカラーとして使用される。値がnil
の場合のデフォルトはカレントフェイスのフォアグラウンドカラー。
:background background
backgroundが非nil
なら、カラーを指定する文字列であること。これはイメージが透明度をサポートする場合に、イメージのバックグラウンドカラーとして使用される。値がnil
の場合のデフォルトはカレントフェイスのバックグラウンドカラー。
:css css
cssが非nil
なら、イメージ生成時に使用されるデフォルトCSSをオーバーライドするCSSを指定する文字列であること。
SVGサポートつきでEmacsがビルドされていれば、以下のsvg.elライブラリー由来の関数でこれらのイメージの作成や操作ができます。
指定したサイズで新たにSVGイメージを作成する。argsはplist引数であり、以下を指定できる:
:stroke-width
作成するすべてのラインのデフォルト幅(ピクセル単位)。
:stroke
作成するすべてのラインのデフォルトのストロークカラー。
この関数はSVGオブジェクト (SVGイメージを指定するLispデータ構造)をリターンする。以下の関数はすべてこのブジェクトにたいして機能する。以下の関数の引数svgはこのようなSVGオブジェクトを指定する。
svgに識別子idでグラデーションを作成する。typeはグラデーションタイプでlinear
かradial
のいずれかを指定する。stopsはパーセント割合/カラーのペアからなるリスト。
以下は最初の赤から25%の緑、最後は青に至る線形グラデーションを作成する:
(svg-gradient svg "gradient1" 'linear '((0 . "red") (25 . "green") (100 . "blue")))
作成(およびSVGオブジェクトに挿入)されたグラデーションは、後でシェイプを作成するすべての関数で使用できる。
以下の関数はすべてさまざまな属性のデフォルト値を変更するオプションのキーワードパラメーターを受け取ります。有効な属性には以下が含まれます:
:stroke-width
ラインとソリッドシェイプ枠線の描画幅(ピクセル単位)。
:stroke-color
ラインとソリッドシェイプ枠線の描画カラー。
:fill-color
ラインとソリッドシェイプに使用するカラー。
:id
シェイプの識別子。
:gradient
与えられた場合には以前に定義されたグラデーションオブジェクトの識別子であること。
:clip-path
クリックパスの識別子。
左上隅が位置x/y、サイズがwidth/heightの矩形をsvgに追加する。
(svg-rectangle svg 100 100 500 500 :gradient "gradient1")
中央が位置x/y、半径がradiusの円をsvgに追加する。
中央が位置x/y、水平半径がx-radius、垂直半径がy-radiusの楕円をsvgに追加する。
始点がx1/y1、終点がx2/y2の線をsvgに追加する。
points (XとYの位置ペアのリスト)を通過する複数セグメントラライン、いわゆる“ポリゴン(polyline)”をsvgに追加する。
(svg-polyline svg '((200 . 100) (500 . 450) (80 . 100)) :stroke-color "green")
ポリゴン外周の位置XとYのペアからなるリストであるようなpointsにより記述されるポリゴンをsvgに追加する。
(svg-polygon svg '((100 . 100) (200 . 150) (150 . 90)) :stroke-color "blue" :fill-color "red")
commandsに応じてsvgにシェイプのアウトラインを追加する。SVG Path Commandsを参照のこと。
デフォルトでは絶対座標。最後(または最初)の位置を基準に相対座標を指定するには、属性:relativeにt
をセットする。この属性は関数や個々のcommandsにたいして指定できる。関数に指定された場合には、すべてのcommandsはデフォルトで相対座標を使用する。個々のcommandsに絶対座標を使用させるなら、:relativeにnil
をセットする。
(svg-path svg '((moveto ((100 . 100))) (lineto ((200 . 0) (0 . 200) (-200 . 0))) (lineto ((100 . 100)) :relative nil)) :stroke-color "blue" :fill-color "lightblue" :relative t)
指定したtextをsvgに追加する。
(svg-text svg "This is a text" :font-size "40" :font-weight "bold" :stroke "black" :fill "white" :font-family "impact" :letter-spacing "4pt" :x 300 :y 400 :stroke-width 1)
埋め込みの(ラスター)イメージをsvgに追加する。datapがnil
ならimageはファイル名、それ以外ならimageはイメージデータをrawバイトとして含む文字列であること。image-typeは"image/jpeg"
のようなMIMEイメージタイプであること。
(svg-embed svg "~/rms.jpg" "image/jpeg" nil :width "100px" :height "100px" :x "50px" :y "75px")
svgにrelative-filenameにある埋め込み(ラスター)イメージを追加する。relative-filenameはsvgのイメージプロパティ:base-uri
のfile-name-directory
内部で検索される。:base-uri
は作成する(存在しないかもしれない)svgイメージのファイル名を指定するので、すべての埋め込みファイルは:base-uri
ファイル名の電子に相対的に検索される。:base-uri
が省略された場合には、svgイメージをロードするファイル名を使用する。svg-embed
と比較してlibrsvgが処理を直接行うので、:base-uri
の使用は巨大なイメージの埋め込みの効率を改善する。
;; Embedding /tmp/subdir/rms.jpg and /tmp/another/rms.jpg (svg-embed-base-uri-image svg "subdir/rms.jpg" :width "100px" :height "100px" :x "50px" :y "75px") (svg-embed-base-uri-image svg "another/rms.jpg" :width "100px" :height "100px" :x "75px" :y "50px") (svg-image svg :scale 1.0 :base-uri "/tmp/dummy" :width 175 :height 175)
svgにクリッピングパスを追加する。:clip-pathプロパティを通じてシェイプに適用された場合には、クリッピング外部のシェイプ部分は描画されない。
(let ((clip-path (svg-clip-path svg :id "foo"))) (svg-circle clip-path 200 200 175)) (svg-rectangle svg 50 50 300 300 :fill-color "red" :clip-path "url(#foo)")
カスタムノードtagをsvgに追加する。
(svg-node svg 'rect :width 300 :height 200 :x 50 :y 100 :fill-color "green")
svg
から識別子id
の要素を取り除く。
最後にsvg-image
は引数としてSVGを受け取り、insert-image
のような関数での使用に適したイメージオブジェクトをリターンする。
以下は円のイメージを作成して挿入する完全な例です:
(let ((svg (svg-create 400 400 :stroke-width 10))) (svg-gradient svg "gradient1" 'linear '((0 . "red") (100 . "blue"))) (svg-circle svg 200 200 100 :gradient "gradient1" :stroke-color "green") (insert-image (svg-image svg)))
SVGパス(SVG paths)によりライン(lines: 線)、カーブ(curves: 曲線)、アーク(arcs: 円弧)、またはその他の基本的なシェイプを組み合わせて複雑なイメージを作成できます。以下に説明する関数でLispプログラムからSVGパスコマンドを呼び出すことができます。
pointsの最初のポイントにペンを移動する。それ以降のポイントはラインで接続される。pointsはXY座標ペアのリスト。後続のmoveto
コマンドは新たなサブパス(subpath)の開始を表す。
(svg-path svg '((moveto ((200 . 100) (100 . 200) (0 . 100)))) :fill "white" :stroke "black")
サブパスの初期ポイントに接続することによりカレントのサブパスを終了する。ラインは接続に沿って描画される。
(svg-path svg '((moveto ((200 . 100) (100 . 200) (0 . 100))) (closepath) (moveto ((75 . 125) (100 . 150) (125 . 125))) (closepath)) :fill "red" :stroke "black")
カレントのポイントからpoints (XY位置ペアのリスト)の最初の要素にラインを描画する。複数ポイントを指定するとポリライン(polyline: 折れ線)を描画する。
(svg-path svg '((moveto ((200 . 100))) (lineto ((100 . 200) (0 . 100)))) :fill "yellow" :stroke "red")
カレントポイントからx-coordinatesの最初の要素へ水平ラインを描画する。通常は無意味だが複数座標の指定は可能。
(svg-path svg '((moveto ((100 . 200))) (horizontal-lineto (300))) :stroke "green")
垂直ラインを描画する。
(svg-path svg '((moveto ((200 . 100))) (vertical-lineto (300))) :stroke "green")
coordinate-setsの最初の要素を使用して、カレントポイントからベジェ曲線(cubic Bézier
curve)を描画する。複数の座標セットがあればポリベジェ(polybezier:
複数のベジェ曲線)を描画する。座標セットはそれぞれ(x1 y1 x2 y2 x
y)
という形式のリストであり、(x, y)はカーブの終点。(x1, y1)と(x2, y2)はそれぞれ先頭ポイントと終点ポイントを制御する。
(svg-path svg '((moveto ((100 . 100))) (curveto ((200 100 100 200 200 200) (300 200 0 100 100 100)))) :fill "transparent" :stroke "red")
coordinate-setsの最初の要素を使用して、カレントポイントから三次ベジェ曲線(cubic Bézier
curve)を描画する。複数の座標セットがあればポリベジェ(polybezier:
複数のベジェ曲線)を描画する。座標セットはそれぞれ(x2 y2 x
y)
という形式のリストであり、(x, y)はカーブの終点、(x2, y2)は対応するコントロールポイント。前のコマンドがcurveto
かsmooth-curveto
なら、そのコマンドの2つ目のコントロールポイントのカレントポイントから相対的なリフレクション(reflection)。それ以外なら最初のコントロールポイントはカレントポイントと一致する。
(svg-path svg '((moveto ((100 . 100))) (curveto ((200 100 100 200 200 200))) (smooth-curveto ((0 100 100 100)))) :fill "transparent" :stroke "blue")
coordinate-setsの最初の要素を使用して、カレントポイントから二次ベジェ曲線(quadratic Bézier
curve)を描画する。複数の座標セットがあればポリベジェ(polybezier:
複数のベジェ曲線)を描画する。座標セットはそれぞれ(x1 y1 x
y)
という形式のリストであり、(x, y)はカーブの終点、(x1, y1)はコントロールポイント。
(svg-path svg '((moveto ((200 . 100))) (quadratic-bezier-curveto ((300 100 300 200))) (quadratic-bezier-curveto ((300 300 200 300))) (quadratic-bezier-curveto ((100 300 100 200))) (quadratic-bezier-curveto ((100 100 200 100)))) :fill "transparent" :stroke "pink")
coordinate-setsの最初の要素を使用して、カレントポイントから二次ベジェ曲線(quadratic Bézier
curve)を描画する。複数の座標セットがあればポリベジェ(polybezier:
複数のベジェ曲線)を描画する。座標セットはそれぞれ(x y)
という形式のリストであり、(x, y)はカーブの終点。前のコマンドがquadratic-bezier-curveto
かsmooth-quadratic-bezier-curveto
なら、そのコマンドのコントロールポイントのカレントポイントから相対的なリフレクション(reflection)。それ以外なら最初のコントロールポイントはカレントポイントと一致する。
(svg-path svg '((moveto ((200 . 100))) (quadratic-bezier-curveto ((300 100 300 200))) (smooth-quadratic-bezier-curveto ((200 300))) (smooth-quadratic-bezier-curveto ((100 200))) (smooth-quadratic-bezier-curveto ((200 100)))) :fill "transparent" :stroke "lightblue")
coordinate-setsの最初の要素を使用して、カレントポイントから楕円弧(elliptical
arc)を描画する。複数の座標セットがあれば一連の楕円弧を描画する。座標セットはそれぞれ(rx ry x
y)
という形式のリストであり、(x, y)は楕円の終点、(rx, ry)は楕円の半径。リストに属性を追加できる:
:x-axis-rotation
カレントの座標システムのX軸から相対的にローテートされた楕円X軸の度数角度。
:large-arc
t
にセットすると、180°以上のアークスイープ(arc sweep)を描画する。それ以外なら180°以下のアークスイープを描画する。
:sweep
t
にセットすると正の角度方向(positive angle
direction)、それ以外なら負の角度方向(negative angle direction)にアークを描画する。
(svg-path svg '((moveto ((200 . 250))) (elliptical-arc ((75 75 200 350)))) :fill "transparent" :stroke "red") (svg-path svg '((moveto ((200 . 250))) (elliptical-arc ((75 75 200 350 :large-arc t)))) :fill "transparent" :stroke "green") (svg-path svg '((moveto ((200 . 250))) (elliptical-arc ((75 75 200 350 :sweep t)))) :fill "transparent" :stroke "blue") (svg-path svg '((moveto ((200 . 250))) (elliptical-arc ((75 75 200 350 :large-arc t :sweep t)))) :fill "transparent" :stroke "gray") (svg-path svg '((moveto ((160 . 100))) (elliptical-arc ((40 100 80 0))) (elliptical-arc ((40 100 -40 -70 :x-axis-rotation -120))) (elliptical-arc ((40 100 -40 70 :x-axis-rotation -240)))) :stroke "pink" :fill "lightblue" :relative t)
[ << ] | [ < ] | [ 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
。
イメージタイプtiff
。:index
プロパティをサポートする。マルチフレームのイメージを参照のこと。
イメージタイプwebp
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
関数create-image
、defimage
、find-image
はイメージディスクリプタを作成するための便利な手段を提供します。
この関数はfile-or-data内のデータを使用するイメージディスクリプタを作成してリターンする。file-or-dataはファイル名、またはイメージデータを含む文字列を指定できる。前者ならdata-pはnil
、後者なら非nil
であること。file-or-dataが相対ファイル名なら、この関数はimage-load-path
にセットされているディレクトリーにたいして検索を行う。
オプション引数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
として定義される。
imageのpropertyの値をリターンする。プロパティはsetf
を使用してセットできる。プロパティに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))
イメージはimage-scaling-factor
変数にもとづいて作成時に自動的にスケーリングされます。この値は浮動小数点数(1より大きい値はサイズの拡大、小さい値はサイズの縮小を意味する)、またはフォントのピクセルサイズにもとづいたスケーリング倍率で計算を行うシンボルauto
のいずれかです。
[ << ] | [ < ] | [ 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
プロパティを参照のこと。デフォルトではそのバッファーでのインタラクティブな検索ではstringを考慮して検索が行われる。この挙動はinhibit-isearchg非nil
なら抑制される。
この関数はinsert-image
と同様にカレントバッファー内にimageを挿入するが、イメージをrows✕colsの同一サイズのスライスに分割する点が異なる。
Emacsは各スライスを個別のイメージとして表示して、(巨大な)イメージを表示するバッファーのページングの際にイメージ全体を上下にジャンプするのではなく、より直感的な上下スクロールが可能になる。
この関数はカレントバッファー内のposの前にイメージimageを配置する。引数posは整数かマーカーであること。これはイメージが表示されるべきバッファー位置を指定する。引数string (デフォルトは‘x’)は、代替となるイメージを保持するテキストであること。
引数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はイメージspec。pixelsが非nil
ならピクセル単位、それ以外ならframeのデフォルトの文字サイズ単位で量ったサイズをリターンする(フレームのフォントを参照)。frameはイメージが表示されるフレーム。frameがnil
または省略された場合には選択されたフレームを使用する(入力のフォーカスを参照)。
この変数はEmacsがロードするイメージの最大サイズを定義するために使用される。Emacsはこの制限より大きいイメージのロード(と表示)を拒絶するだろう。
値が整数ならピクセル単位で量ったイメージの最大の高さと幅を直接指定する。浮動小数点数ならフレームの高さと幅にたいする比率として、イメージの最大の高さと幅を指定する。値が数値でなければイメージサイズにたいする明示的な制限は存在しない。
この変数の目的は意図せずEmacsに不当に大きなイメージがロードされるとを防ぐことである。これはイメージの初回ロード時だけ効果がある。イメージが一度イメージキャッシュに置かれると、その後にmax-image-size
の値が変更されても、そのイメージは常に表示可能である(イメージキャッシュを参照)。
この関数はポイントがイメージ上にあればt
、それ以外はnil
をリターンする。
上記の挿入関数で挿入されたイメージは、表示されたイメージを横断するテキスト(またはオーバーレイ)のプロパティ内にインストールされたローカルキーマップも取得します。このキーマップは以下のコマンドを定義します。
イメージのサイズを拡大する(image-increase-size
)。
イメージのサイズを縮小する(image-decrease-size
)。
イメージを回転させる(image-rotate
)。
水平方向にイメージを反転させる(image-flip-horizontally
)。
垂直方向にイメージを反転させる(image-flip-vertically
)。
イメージをファイルに保存する(image-save
)。
インタラクティブにイメージをクロップする(image-crop
)。
インタラクティブにイメージから矩形を切り取る(image-cut
)。
これらのイメージ固有なキーバインディングについての詳細は、Image Mode in The GNU Emacs Manualを参照してください。
[ << ] | [ < ] | [ 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
なら永久にループ表示する。数値ならその秒数後にアニメーションは停止する。
Animation operates by means of a timer. Note that Emacs imposes a
アニメーションはタイマーにより処理されます。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はキャッシュからイメージを削除しない。このモードはデバッグ時に有用かもしれない。
この関数はカレントイメージキャッシュの総バイト数をリターンする。たとえば24ビットカラーでサイズ200x100のイメージのキャッシュサイズは60000バイト。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsでは(クリックできる)ボタンや小さい(何かを説明するための)グラフィックスが使える場合があります。Emacsは異なる機能をもつ多種多様なシステムで利用できる、更に好みはユーザーごとにそれぞれ異なることから、Emacsはこれを処理するための機能として、テーマと同じようにカスタマイズでき、優美な装飾とアクセシビリティをもつアイコン(Icon)を提供します。
ここで中心となるのはdefine-icon
というマクロです。以下に単純な例を示します:
(define-icon outline-open button '((image "right.svg" "open.xpm" "open.pbm" :height line) (emoji "▶️") (symbol "▶" "➤") (text "open" :face icon-button)) "Icon used for buttons for opening a section in outline buffers." :version "29.1" :help-echo "Open this section")
実際にどの選択肢が表示されるかはユーザーオプションicon-preference
(Icons in The
GNU Emacs Manualを参照)の値と、カレントフレームの端末が実際に表示できるかどうかの実行時チェックの結果に依存します。
上記の例はoutline-open
をアイコンとして定義するマクロです。これはbutton
と呼ばれるアイコンからプロパティを継承します(バッファーにはクリック可能なボタンとして挿入されることを意図している)。その後にはアイコンタイプ(icon
type)のリストと実際のアイコンのシェイプ(形状)が続きます。更にドキュメント文字列や追加の情報とプロパティを含むさまざまキーワードも存在します。
アイコンをインスタンス化するためにはicon-string
を使用します。これはカレントのCustomizeテーマ、ユーザーオプションicon-preference
、そして最後にEmacsが実際に何を表示できるかを調べます。icon-preference
が(image
emoji symbol text)
(これらすべての形式を許容するアイコン)の場合には、icon-string
はまずEmacsがイメージを表示できるのか、そして異なるイメージフォーマットそれぞれについてサポートしているかどうかをチェックします。これが失敗したら、Emacsは(カレントフレームにおいて)emojiを表示できるかどうかをチェックします。これが失敗すると、対象となるシンボルを表示できるかどうかをチェックして、それが失敗したら平文テキストのバージョンが使用されることになります。
たとえばもしもicon-preference
にimage
やemoji
が含まれていなければ、それらのエントリーはスキップされます。
コードはどんな状況下においても安心してicon-string
を呼び出すことができ、ユーザーが使っているのがグラフィカルな端末とテキスト端末のどちらなのか、あるいはEmacsが何の機能とともにビルドされているかに関わらず、読み取り可能な何かがスクリーン上に表示されることが保証されているのです。
アイコンname
(シンボル)を代替表示specとともに定義する。後でicon-string
を使ってインスタンス化できる。nameは結果となるキーワード名。
結果として得られるアイコンはそのspecをparent、その親、...から継承する。もっとも下位の子孫のspecが優先される。
specsはアイコン仕様のリスト。各仕様の1つ目の要素はタイプ、残りはそのタイプのアイコンに使用される何かしら、その後はキーワードリスト。以下は利用可能なアイコンタイプ:
image
この場合には候補として多くのイメージがリストされているかもしれない。EmacsはカレントのEmacsインスタンスが表示できる最初の候補を選択する。リストされているイメージが絶対ファイル名ならそれを使い、そうでなければimage-load-path
(イメージの定義を参照)にリストされたディレクトリーを検索する。
emoji
(恐らくはカラフルな)emoji。
symbol
(モノクロの)シンボル文字。
text
アイコンにはテキスト的なフォールバックも必要である。これは視覚障害者に用いられることもあり得る。icon-preference
が(text)
だけの場合には、すべてのアイコンはテキストに置き換えられる。
アイコン仕様のリストの後にはさまざまなキーワードを続けることができる。たとえば:
(symbol "▶" "➤" :face icon-button)
不明なキーワードは無視される。以下のキーワードが使用できる:
:face
アイコンに使用するフェイス。
:height
image
アイコンにたいしてのみ有効。数値(ピクセル単位で高さを指定)、あるいはシンボルline
カレントで選択されているウィンドウのデフォルトの行高さを使用のいずれかを指定できる。
:width
image
アイコンにたいしてのみ有効。数値(ピクセル単位で幅を指定)、あるいはシンボルline
(カレントバッファーのデフォルトフェイスのフォントのピクセル幅を使用)のいずれかを指定できる。
docはドキュメント文字列であること。
keywordsはキーワード/値のペアーのリスト。以下のキーワードを指定できる:
:version
このボタンが最初に現れたEmacsの(おおよその)バージョン(このキーワードは必須)。
:group
このアイコンが所属するCustomizationグループ。未指定なら推測。
:help-echo
アイコン上にマウスポインターを置いた際に表示されるヘルプ文字列。
この関数はカレントバッファーでiconを表示する際に適切な文字列をリターンする。
あるいはこの関数によってiconの“分解された”バージョンを取得できる。この関数はキーがstring
、face
、imageであるようなplist(プロパティリストを参照)をリターンする(imageはアイコンがイメージとして表現される場合のみ与えられる)。これはアイコンをバッファーに直接挿入せずに、まず何らかの事前処理を行う必要があるとき有用かもしれない。
アイコンはM-x customize-iconでカスタマイズできます。たとえばテーマは以下のようにアイコンの変更を指定できます:
(custom-theme-set-icons 'my-theme '(outline-open ((image :height 100) (text " OPEN "))) '(outline-close ((image :height 100) (text " CLOSE " :face warning))))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
必要なサポートライブラリーつきでEmacsがビルドされていて、かつグラフィカル端末上で実行されていれば、Emacsバッファー内にGTK+
WebKitウィジェットのようなネイティブウィジェットを表示することができます。Emacsが埋め込みウィジェットを表示可能かテストするには、xwidget-internal
機能が利用可能かどうかをチェックします(名前つき機能を参照)。
Emacsバッファー内に埋め込みウィジェットを表示するためには、最初にxwidgetオブジェクトを作成して、テキストプロパティまたはオーバーレイプロパティdisplay
内のディスプレイ仕様としてそのオブジェクトを使用します(display
プロパティを参照)。
埋め込みウィジェットは自身に生じた変更をLispコードに通知するイベントを送信できます(Xwidgetイベントを参照)。
これはxwidgetオブジェクトを作成してリターンする。bufferが省略かnil
の場合のデフォルトはカレントバッファー。bufferが存在しないバッファーの名前を指定する場合には作成する。typeはxwidgetコンポーネントを識別するもので以下のいずれかが可能:
webkit
WebKitコンポーネント。
引数widthとheightはウィジェットのサイズをピクセル単位で指定、titleはウィジェットのタイトルを指定する文字列。relatedはWebKitウィジェットが内部で使用するもので、新たに作成されるウィジェットが設定とサブプロセスを共有する必要がある別のWebKitウィジェットを指定する。
リターンされたxwidgetはそのバッファーとともにkillされる(バッファーのkillを参照)。kill-xwidget
を使ってkillすることもできる。xwidgetが一旦killされてもすべての参照が解放されるまではLispオブジェクトとして存在し続けてdisplay
プロパティとして動作するが、生きたxwidgetで実行できるほとんどのアクションは利用できなくなる。
この関数はobjectがxwidgetならt
、それ以外はnil
をリターンする。
この関数はobjectがkillされていないxwidgetならt
、それ以外はnil
をリターンする。
この関数はxwidgetをバッファーから削除して、それが保有していたウィンドウシステムのリソースを解放することによってkillする。
この関数はxwidgetのプロパティリストをリターンする。
この関数はplistで与えられた新たなプロパティリストでxwidgetのプロパティリストを置き換える。
この関数はxwidgetのバッファーをリターンする。xwidgetがkillされていたらnil
をリターンする。
この関数はxwidgetのバッファーをbufferにセットする。
この関数は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
のいずれかでリターンする。
入力イベントeventをxwidgetに送信する。実行される正確なアクションはプラットフォームに依存する。入力イベントを参照のこと。
オプションとしてframeを介してこのイベントが生成されたフレームを渡すことができる。X11の場合にはframeがnil
かつ選択されたフレームがX-Windowsフレーム以外なら、キーイベント中の修飾キーは考慮しない。
GTKでサポートされているのはキーボードとファンクションキーのイベントのみ。マウス、移動キー、クリックにたいするイベントはLispコードを介さずxwidgetにディスパッチされるため、この関数は呼び出されない。
WebKitウィジェットxwidgetにたいして、文字列queryを問い合わせるインクリメンタル検索を開始する。case-insensitiveは検索でcase(大文字小文字)を区別するかどうか、backwardsはドキュメント先頭から後方に検索を行うかどうか、そしてwrap-aroundは検索をドキュメント終端で終了するかどうかを指定する。
検索クエリーがすでに与えられた状態でこの関数を呼び出すと、既存のクエリーはここで指定したクエリーに置き換えられる。
検索クエリーを停止するにはxwidget-webkit-finish-search
を使用すること。
xwidgetの次の検索結果を表示する。xwidget-webkit-search
による検索クエリーがxwidget内でまだ開始されていなければ、この関数はエラーをシグナルする。
xwidget-webkit-search
の呼び出し時にwrap-around
が非nil
だった場合には、検索がドキュメント終端に達すると先頭から検索を再開する。
xwidgetの前の検索結果を表示する。xwidget-webkit-search
による検索クエリーがxwidget内でまだ開始されていなければ、この関数はエラーをシグナルする。
xwidget-webkit-search
の呼び出し時にwrap-around
が非nil
だった場合には、検索がドキュメント先頭に達すると終端から検索を再開する。
xwidgetで開始されたxwidget-webkit-search
による検索操作を終了する。現在進行中のクエリーがなければ、この関数はエラーをシグナルする。
xwidget (WebKitウィジェット)にtext (文字列)をロードする。text内にあるHTMLマークアップはテキスト描画の際にすべてxwidgetによって処理される。
オプション引数base-uri (文字列)はtextによって参照されるwebリソースの絶対位置を指定する。これはtext内の相対リンクの解決に使用される。
WebKitウィジェットxwidgetにナビゲーション履歴でrel-pos番目の要素をロードさせる。
rel-posが0ならカレントページをリロードさせる。
xwidgetのナビゲーション履歴を両方向にlimit番目のアイテムまでリターンする。limitを指定しない場合のデフォルトは50。
リターン値は(back here forward)
という形式のリスト。ここでhereはカレントナビゲーションアイテム、backはカレントナビゲーションアイテムの前にWebKitが記録されたアイテムを含むアイテムリスト、forwardはカレントナビゲーションアイテムの後に記録されたアイテムリスト。back、here、forwardはnil
の場合もあり得る。
hereがnil
なら、記録済みアイテムが存在しないことを意味する。backやforwardがnil
なら、カレントアイテムにたいして前または後に記録された履歴が存在しないことを意味する。
ナビゲーションアイテム自体は(idx title uri)
という形式のリスト。ここでidxはxwidget-webkit-goto-history
に渡すことができるインデックス、titleは人間が読めるアイテムのタイトル、uriはそのアイテムのURL。ユーザーは特定の履歴アイテムに到達するために手作業によるuriのロードを必要とする理由は通常はない。かわりにインデックスとしてxwidget-webkit-goto-history
にidxを渡せばよいからだ。
WebKitウィジェットxwidgetによってページが完全にロードされて表示されるまでに転送を要する残りのデータ量の推測値をリターンする。
リターン値は0.0から1.0までの浮動小数点数。
WebKitウィジェットxwidgetにたいしてfileにcookieを格納させる。
fileは絶対ファイル名でなければならない。新しいセッティングはmake-xwidget
の引数related
として作成されたxwidget、およびそれらに関連するウィジェットにも影響を及ぼす。
xwidgetや関連するウィジェットにたいして最低でも1回はこの関数を呼び出さなければ、xwidgetはディスクに何のcookieも格納しない。
ページロード操作の一環となるWebKitウィジェット進行中のデータ転送はすべて終了される。ページがロードされない場合には、この関数は何も行わない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Buttonパッケージはマウスやキーボードコマンドでアクティブ化することができる、ボタン(buttons)の挿入と操作に関する関数を定義します。これらのボタンは典型的には種々のハイパーリンクに使用されます。
本質的にボタンとはバッファー内のテキスト範囲にアタッチされたテキストプロパティやオーバーレイのプロパティのセットです。これらのプロパティはボタンプロパティ(button properties)と呼ばれます。これらのプロパティのうちの1つはアクションプロパティ(action property)であり、これはユーザーがキーボードかマウスを使用してボタンを呼び出した際に呼び出される関数を指定します。アクション関数はボタンを調べ、必要に応じて他のプロパティを使用できます。
いくつかの機能面でButtonパッケージとWidgetパッケージは重複しています。Introduction in The Emacs Widget Libraryを参照してください。Buttonパッケージの利点は、より高速で小さくプログラムにたいしてよりシンプルであることです。ユーザーの観点からは、2つのパッケージが提供するインターフェイスは非常に類似しています。
41.20.1 ボタンのプロパティ | 特別な意味をもつボタンプロパティ。 | |
41.20.2 ボタンのタイプ | ボタンのクラスにたいして一般的なプロパティを定義する。 | |
41.20.3 ボタンの作成 | Emacsバッファーへのボタンの追加。 | |
41.20.4 ボタンの操作 | ボタンプロパティの取得とセット。 | |
41.20.5 ボタンのためのバッファーコマンド | ボタンにたいするバッファー規模のコマンドとバインディング。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ボタンはその外観と振る舞いを定義するプロパティの連想リスト(associated list)をもち、アプリケーションの特別な目的のために他の任意のプロパティを使用できます。以下のプロパティはButtonパッケージにたいして特別な意味をもちます:
ユーザーがボタンを呼び出した際に呼び出す関数であり、単一の引数buttonを渡して呼び出される。デフォルトではこれは何も行わないignore
。
これはaction
と似ているが与えられた際には、(RET押下のかわりに)マウスクリックによりボタンが呼び出された場合naction
のかわりに使用される。与えられなければマウスクリックはかわりにaction
を使用する。
このタイプのボタンが表示される方法を制御するEmacsフェイス。デフォルトはbutton
フェイス。
ボタン上にマウスがある際の外観を制御する追加のフェイス(通常のbuttonフェイスとマージされる)。デフォルトはEmacsの通常のhighlight
フェイス。
そのボタンリージョン(button
region)でアクティブなバインディングを定義するボタンのキーマップ。デフォルトは変数button-map
に格納された通常のボタンリージョンキーマップであり、これはボタン呼び出しにたいしてRETとmouse-2を定義している。
ボタンのタイプ。ボタンのタイプを参照のこと。
Emacsのツールチップヘルプシステムが表示する文字列であり、デフォルトは"mouse-2, RET: Push this
button"
。かわりに表示される文字列をリターンする関数や文字列に評価されるフォーム、あるいはnil
。詳細はText help-echoを参照のこと。
関数ならwindow、object、posという3つの引数で呼び出される。2つ目の引数objectはプロパティをもつオーバーレイ(オーバーレイボタンにたいして)、あるいはボタンを含むバッファー(テキストプロパティボタンにたいして)のいずれか。その他の引数はスペシャルテキストプロパティhelp-echo
の場合と同じ意味をもつ。
このボタンにたいしてmouse-1クリックが振る舞う方法を定義するfollow-link
プロパティ。クリック可能なテキストの定義を参照のこと。
すべてのボタンは非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のボタンを挿入する。
たとえば後でバッファーに挿入されるかもしれないデータ構造の作成時など、即座にバッファーに挿入せずに文字列をボタンにできれば便利なことがある。この関数はstringをそのような文字列にして、ユーザーがそのボタンをクリックした際にはcallbackが呼び出されるようにする。オプションのdataパラメーターはcallbackの呼び出し時にパラメーターとして使用される。nil
ならかわりにボタンがパラメーターとして使用される。
[ << ] | [ < ] | [ 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-data
プロパティが与えられた場合には、action
関数の引数としてbuttonのかわりに使用される。
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
の使用を望むかもしれません。かわりにbutton-mode
をオンに切り替えれば、ほぼ同様の効果を得ることができます。これはマイナーモードキーマップとして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
プロパティをもつボタンはすべてスキップされる。見つかったボタンをリターンするか、ボタンが見つからなければエラーをシグナルする。no-errorが非nil
なら、エラーをシグナルするかわりにnil
をリターンする。
前のn番目、nが負なら次のn番目のボタンに移動する。nが0ならポイント位置にある任意のボタンの開始に移動する。wrapが非nil
ならバッファーの先頭または終端を超えて、もう一方の端へ移動を継続する。display-messageが非nil
ならボタンのhelp-echo文字列が表示される。非nil
のskip
プロパティをもつボタンはすべてスキップされる。見つかったボタンをリターンするか、ボタンが見つからなければエラーをシグナルする。no-errorが非nil
なら、エラーをシグナルするかわりにnil
をリターンする。
カレントバッファー内の位置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からのノード削除はバッファーからそれに関連付けられたテキスト記述も同様に削除します。
41.21.1 抽象ディスプレイの関数 | Ewocパッケージ内の関数。 | |
41.21.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 (define-keymap :suppress t "i" 'colorcomp-R-less "o" 'colorcomp-R-more "k" 'colorcomp-G-less "l" 'colorcomp-G-more "," 'colorcomp-B-less "." 'colorcomp-B-more "SPC" 'colorcomp-copy-as-kill-and-exit))
わたしたちが決して各ノード内のデータを変更していないことに注意してください。それらのデータは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)を定義することにより、各文字が表示される方法を変更できます。これはそれぞれの文字をグリフのシーケンスにマップするテーブルです。ディスプレイテーブルを参照してください。
41.23.1 通常の表示の慣習 | 文字の表示にたいする通常の慣習。 | |
41.23.2 ディスプレイテーブル | ディスプレイテーブルの構成要素。 | |
41.23.3 アクティブなディスプレイテーブル | 使用するディスプレイテーブルをEmacsが選択する方法。 | |
41.23.4 グリフ | グリフの定義方法とグリフの意味。 | |
41.23.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
で使用されるユーザー設定可能なタブストップとは完全に無関係であることに注意。調整可能なタブストップを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ディスプレイテーブルとはサブタイプとしてdisplay-table
をもつ特殊用途の文字テーブル(文字テーブルを参照)であり、文字の通常の表示慣習をオーバーライドするために使用されます。このセクションではディスプレイテーブルオブジェクトの作成と調査、および要素を割り当てる方法について説明します。次のセクション(アクティブなディスプレイテーブルを参照)では標準的なディスプレイテーブルと優先順位について説明します。
これはディスプレイテーブルを作成してリターンする。テーブルは初期状態ではすべての要素にnil
をもつ。
ディスプレイテーブルの通常の要素は文字コードによりインデックス付けされます。インデックスcの要素はコードcの表示方法を示します。値はnil
(これは通常の表示慣習に応じて文字cを表示することを意味する。通常の表示の慣習を参照)、またはグリフコードのベクター(これらのグリフとして文字cを表示することを意味する。グリフを参照)のいずれかです。
警告: 改行文字の表示を変更するためにディスプレイテーブルを使用すると、バッファー全体が1つの長い行として表示されるでしょう。
ディスプレイテーブルは特殊用途向け6つのエクストラスロット(extra
slots)をもつこともできます。以下はそれらの意味についてのテーブルです。nil
のスロットは以下で示すそのスロットにたいするデフォルトの使用を意味します。
切り詰められたスクリーン行終端のグリフ(デフォルトでは‘$’)。グリフを参照のこと。グラフィカルな端末ではフリンジを無効にしていなれば(Window Fringes in the GNU Emacs Manualを参照)、Emacsはデフォルトでは切り詰められたことをフリンジ内の矢印で示し、ディスプレイテーブルは使用しない。
継続行終端のグリフ(デフォルトは‘\’)。グラフィカルな端末ではフリンジを無効にしていなれば、デフォルトではEmacsは継続ををフリンジ内の曲矢印で示し、ディスプレイテーブルは使用しない。
8進文字コードとして表示される文字を示すグリフ(デフォルトは‘\’)。
コントロール文字を示す(デフォルトは‘^’)。
不可視行があることを示すグリフのベクター(デフォルトは‘...’)。選択的な表示を参照のこと。
横並びのウィンドウ間のボーダー描画に使用されるグリフ(デフォルトは‘|’)。ウィンドウの分割を参照のこと。これは現在のところテキスト端末でのみ効果がある。グラフィカル端末では垂直スクロールバーがサポートされていて使用中ならスクロールバーが2つのウィンドウを分割する。垂直スクロールバーとディバイダー(ウィンドウディバイダーを参照)がなければ、Emacsは境界を示すために細いラインを使用する。
たとえば以下は関数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は通常の文字表示慣習(通常の表示の慣習を参照)を使用します(Emacsはディスプレイテーブルの“merge”は行わない;
ウィンドウにディスプレイテーブルがあれば、バッファーのディスプレイテーブルと標準ディスプレイテーブルは完全に無視される)。
ディスプレイテーブルはモードラインが表示される方法に影響を与えるので、新たなディスプレイテーブルを使用してモードラインを強制的に再表示するには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進コードを中に含むボックスとして表示される文字です。これらの文字にはグリフが無いと明示的に定義された文字や、利用可能なフォントがない文字(グラフィカルなディスプレイ)、その端末のコーディングシステムではエンコードできない文字(テキスト端末)が同様に含まれます。
glyphless-display-mode
はカレントバッファーにとって便利な方法でグリフ無し文字の表示を切り替えるマイナーモードです。このモードが有効だと、グリフ無し文字はそのの頭文字を表示するボックスとして表示されます。
この変数を使用すれば、よりきめ細かく(かつグローバルな)制御ができる。この変数の値はグリフ無し文字と表示方法を定義する文字テーブル。エントリーはそれぞれ以下の表示メソッドのいずれかでなければならない:
nil
通常の方法でその文字を表示する。
zero-width
その文字を表示しない。
thin-space
グラフィカルな端末では幅が1ピクセル、テキスト端末では幅が1文字の狭いスペース。
empty-box
空のボックスを表示する。
hex-code
その文字のUnicodeコードポイントの16進表記を含むボックスを表示する。
その文字列を含むボックスを表示する。文字列には少なくとも6個のASCII文字が含まれていること。例外として文字列に含まれるのが1文字だけの場合には、テキストモード端末ではボックスなしでその文字が表示される。これによって端末が表示できない文字にたいする置換文字として“頭文字”を処理することができる。
(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 LEFT-TO-RIGHT MARKのようなUnicode General Category [Cf]の文字だが、U+00AD SOFT HYPHENのようにグラフィックイメージをもつ文字を除く。
bidi-control
これはformat-control
のサブセットだがU+2069 POP DIRECTIONAL ISOLATEやU+202A
LEFT-TO-RIGHT
EMBEDDINGのような双方向テキストのフォーマットに関連する文字だけを含む。双方向テキストの表示を参照のこと。
U+200E LEFT-TO-RIGHT MARKのようなUnicode General Category [Cf]の文字だが、U+00AD SOFT HYPHENのようにグラフィックイメージをもつ文字を除く。
variation-selectors
UnicodeのVS-1からVS-256 (U+FE00からU+FE0FとU+E0100からU+E01EF)は同一コードポイントにたいして異なるグリフを選択するために使用される(一般的には絵文字)。
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とmacOSで使用されている)。
pc
EmacsはMS-DOSのスクリーン直接書き込みを使用してフレームを表示している。
haiku
EmacsはHaikuのをApplication Kit使用してフレームを表示している。
pgtk
Emacsはpure GTKの機能を使用してフレームを表示している。
nil
Emacsは文字ベース端末を使用してフレームを表示している。
この変数はスタートアップの間にEmacsが作成する最初のフレームにたいして使用されるwindow-system
の値を保持する(デーモンとしてEmacsを呼び出し時には初期フレームを作成しないので、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+ツールキットかHaikuのウィンドウシステムのサポート付きでEmacsがビルドされた際にはデフォルトではツールキット機能を使用してツールチップを表示して、ツールチップの外観はツールキットのセッティングにより制御されます。ツールキットが提供するツールチップは変数use-system-tooltips
の値をnil
に変更して無効にできます。このセクションの残りではEmacs自身が提供する非ツールキットのツールチップを制御する方法を説明します。
ツールチップは独自のパラメーターをもつツールチップフレームと呼ばれる特別なフレームに表示されます(フレームのパラメーターを参照)。他のフレームとは異なり、ツールチップフレームのデフォルトパラメターは特別な変数に格納されています。
このカスタマイズ可能なオプションはツールチップ表示に使用するデフォルトのフレームパラメーターを保持する。フォントとカラーに関するパラメーターは無視して、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)にしたがいます(https://www.unicode.org/reports/tr9/)。EmacsはUnicode Standard v9.0の要件に合致するUBAの“Full Bidirectionality(完全な双方向性)”を提供します。とはいえテキストがパラグラフの基本方向と逆方向なときにEmacsが継続行を表示する方法は、表示するテキストの再並び換えの前に行の折り返しを要求するUBAからは逸脱していることに注意してください。
このバッファーローカル変数の値が非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実装の目的におけるパラグラフの開始および終了の正確な位置は、以下の2つのローカル変数により決定されます(paragraph-start
とparagraph-separate
に効果はないことに注意)。デフォルトではこれらの変数はnil
であり、パラグラフは空行(改行を後に併なう0個以上の空白文字)で囲まれます。
この変数の値が非nil
ならパラグラフの開始か2つのパラグラフを分割する行にマッチする正規表現であること。この正規表現は常に改行の後にマッチするので、それをアンカーにする("^"
で開始する)のが最善である。
この変数の値が非nil
なら2つのパラグラフを分割する行にマッチする正規表現であること。この正規表現は常に改行の後にマッチするので、それをアンカーにする("^"
で開始する)のが最善である。
これら2つの変数
のいずれかを変更する場合には、整合性のあるパラグラフの記述を保証するために、通常は両方を変更するべきです。たとえば双方向の並べ替え目的のために各改行を新たなパラグラフの開始とするには両方の変数に"^"
をセットしてください。
デフォルトでは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モードのようにバッファーがスペースや区切り文字分割されたテキストのフィールドのシーケンスで構成されているときです。それはセパレーターとして使用されている区切り文字が弱い方向性をもち、周囲のテキストの方向を採用するためです。結果として双方向の内容のフィールドが後続する数値フィールドは、先行するフィールドヘ左方向に表示され、期待したレイアウトを破壊してしまいます。この問題を回避するための方法がいくつかあります:
bidi-string-mark-left-to-right
は、この目的に手頃(R2LパラグラフではかわりにRIGHT-TO-LEFT
MARK、略してRLMのU+200F RIGHT-TO-LEFT
MARKを使用する)。これは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のディスプレイ表示を参照してください。
42.1 Emacsのスタートアップ | Emacsのスタートアッププロセスのカスタマイズ。 | |
42.2 Emacsからの脱出 | (永久または一時的に)exitが機能する方法。 | |
42.3 オペレーティングシステムの環境 | システム名と種類の区別。 | |
42.4 ユーザーの識別 | ユーザーの名前とユーザーIDを調べる。 | |
42.5 時刻 | カレント時刻の取得。 | |
42.6 タイムゾーンのルール | タイムゾーンと夏時間のルール。 | |
42.7 時刻の変換 | タイムスタンプ形式間の変換。 | |
42.8 時刻のパースとフォーマット | タイムスタンプとテキストの双方向変換。 | |
42.9 プロセッサーの実行時間 | Emacsによる実行時間の取得。 | |
42.10 時間の計算 | 時間の加減算、その他。 | |
42.11 遅延実行のためのタイマー | 特定時刻に関数を呼び出すためにターマーをセットする。 | |
42.12 アイドルタイマー | Emacsが特定の時間の間アイドル時に関数を呼び出すためにタイマーをセットする。 | |
42.13 端末の入力 | 端末入力へのアクセスと記録。 | |
42.14 端末の出力 | 端末出力の制御と記録。 | |
42.15 サウンドの出力 | コンピューターのスピーカーでのサウンド再生。 | |
42.16 X11キーシンボルの処理 | Xウィンドウにたいするキーシンボルの操作。 | |
42.17 batchモード | 端末との対話なしでEmacsを実行する。 | |
42.18 セッションマネージャー | Xセッション管理の保存とリストア。 | |
42.19 デスクトップ通知 | ||
42.20 ファイル変更による通知 | ファイル通知。 | |
42.21 動的にロードされるライブラリー | サポートライブラリーのオンデマンドロード。 | |
42.22 セキュリティへの配慮 | 非有効的な環境でのEmacsの実行。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではEmacsが開始時に何を行うか、およびそれらのアクションのカスタマイズ方法を説明します。
42.1.1 要約: スタートアップ時のアクション順序 | スタートアップ時にEmacsが行うアクションの順序。 | |
42.1.2 initファイル | initファイル読み込みの詳細。 | |
42.1.3 端末固有の初期化 | 端末固有のLispファイルの読み込み方法。 | |
42.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
のような環境変数がそれを要するなら言語環境と端末のコーディングシステムをセットする。
package-activate-all
を呼び出す。パッケージ化の基礎を参照のこと。しかしpackage-enable-at-startup
がnil
、または‘-q’、‘-Q’、‘--batch’のいずれかのオプションで開始時には、Emacsはパッケージのアクティブ化をしない。後者のケースでパッケージをアクティブ化するには、(たとえば‘--funcall’オプションを通じて)明示的にpackage-activate-all
を呼び出すこと。
initial-window-system
が指定するウィンドウシステムを初期化する(initial-window-systemを参照)。初期化関数window-system-initialization
はジェネリック関数generic
functionであり、本当の実装はサポートされる各ウィンドウシステムごとに異なる(ジェネリック関数を参照)。initial-window-system
の値がwindowsystemなら、ファイルterm/windowsystem-win.el内で適切な初期化関数の実装が定義されている。このファイルはビルド時にEmacs実行可能形式にコンパイルされているはずである。
before-init-hook
を実行する。
initial-frame-alist
とdefault-frame-alist
(フレームの初期パラメーターを参照)により指定されたウィンドウシステム用のwindow-system-initialization
関数を呼び出すことにより、そのウィンドウシステムのグラフィカルなフレームを初期化する。これは(非インタラクティブな)batchモードやデーモンモードでは行われない。
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’が指定されていたら行われない。
after-init-time
にcurrent-time
の値をセットする。この変数は事前にnil
にセットされている。これをカレント時刻にセットすることが初期化フェーズが終わったことの合図となり、かつbefore-init-time
と共に用いることにより初期化に要した時間の計測手段を提供する。
after-init-hook
とdelayed-warnings-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’が指定されていたら行われない。
server-start
を呼び出す(POSIXシステムではバックグラウンドのデーモンが要求された場合には制御端末からデタッチされる)。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
--bg-daemon
--fg-daemon
表示の初期化を何も行わず単にサーバーを開始する(“バックグラウンド”のデーモンは自動的にバックグラウンドで実行される)。
--no-init-file
-q
initファイルとdefaultライブラリーをいずれもロードしない。
--no-site-file
site-startライブラリーをロードしない。
--quick
-Q
‘-q --no-site-file --no-splash’と等価。
--init-directory
Emacsのinitファイルを探す際に使用するディレクトリーを指定する。
[ << ] | [ < ] | [ 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は早期initファイル(early init file)と呼ばれる2つ目のinitファイルが存在すれば、それのロードも試みます。これは~/.emacs.dにあるearly-init.elという名前のファイルです。早期initファイルはスタートアッププロセスのより速いタイミングでロードされるために、通常のinitファイルのロード前に初期化される何かをカスタマイズするために使用できるのが早期initファイルと通常のinitファイルの違いです。たとえばpackage-load-listやpackage-enable-at-startupのような変数をセットしてパッケージシステムの初期化プロセスをカスタマイズできます。Package Installation in The GNU Emacs Manualを参照してください。
インストールした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のデフォルトディレクトリーの名前を保持する。~/.emacs.d/および~/.emacsが存在せず${XDG_CONFIG_HOME-'~/.config'}/emacs/が存在すればそのディレクトリーがデフォルト、それ以外ならMS-DOS以外のすべてのプラットフォームでは~/.emacs.d/がデフォルト。ここで${XDG_CONFIG_HOME-'~/.config'}は環境変数XDG_CONFIG_HOME
がセットされていればその値、それ以外なら~/.configを意味する。How Emacs Finds Your Init File in The GNU Emacs Manualを参照のこと。
[ << ] | [ < ] | [ 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")
という形式の要素は‘vt102’というタイプの端末を‘vt100’タイプの端末として扱うことを意味する。
この変数は新たなテキスト端末の初期化後に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
)。
command-switch-alist
の処理はoption内の等号を特別扱いしないことに注意。つまりコマンドラインに--name=value
のようなオプションがなければ、car
が文字通り--name=value
のcommand-switch-alist
のメンバーでなければこのオプションにマッチしない。そのようなオプションをパースしたければ、かわりにcommand-line-functions
(以下参照)を使う必要がある。
コマンドライン引数は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に戻れる)。
42.2.1 Emacsのkill | Emacsからの不可逆的なexit。 | |
42.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(や何であれ次の入力を読み込むプログラム)が読み込むことができる。
exit-dataが整数や文字列以外、または省略なら成功裏にプログラムが終了したことを示すexitステータス(システム固有)の使用を意味する。
restartが非nil
なら最後にexitするだけではなく、カレントで実行中のEmacsプロセスと同じコマンドライン引数で新たなEmacsプロセスを開始する。
関数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
を呼び出すとフックは実行されない。
このコマンドはsave-buffers-kill-emacs
と同じことを行うが、最後にカレントEmacsプロセスをkillするだけではなく、カレントで実行中のEmacsプロセスと同じコマンドライン引数を用いて新たな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 (macOS).
gnu
(HURDとMachから構成される)GNUシステム。
gnu/linux
GNU/Linuxシステム — すなわちLinuxカーネルを使用するGNUシステムの変種(これらのシステムは人がしばしば“Linux”と呼ぶシステムだが実際にはLinuxは単なるカーネルであってシステム全体ではない)。
gnu/kfreebsd
FreeBSDカーネルによる(glibcベースの)GNUシステム。
haiku
Beオペレーティングシステムから派生したHaikuオペレーティングシステム。
hpux
ヒューレット・パッカードのHPUXオペレーティングシステム。
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
のデフォルト値の構築時に使用される。ユーザーの識別を参照のこと。
この関数は環境変数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
をリターンする。
このマクロはbodyを実行する際に、variablesに応じて環境変数を一時的にセットする。終了時には以前の値がリストアされる。引数variablesは(var value)
という形式の文字列ペアーのリストであること。ここでvarは環境変数の名前、valueはその変数の値。
(with-environment-variables (("LANG" "C") ("LANGUAGE" "en_US:en")) (call-process "ls" nil t))
この変数はそれぞれが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-separator
の接続ローカル値をリターンする。これはMSシステムかつローカルのdefault-directory
なら";"
、UnixおよびGNUのシステムまたはリモートのdefault-directory
なら":"
。
この関数は環境変数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文字を保持する。
この変数はシステムのnullデバイスを保持する。値はUnixおよびGNUシステムでは"/dev/null"
、MSシステムでは"NUL"
。
この関数は変数null-device
の接続ローカル値をリターンする。これはMSシステムかつローカルのdefault-directory
なら"NUL"
、UnixおよびGNUシステムまたはリモートのdefault-directory
なら"/dev/null"
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この変数はEmacsによりどのユーザーのinitが使用されるべきか —
なければnil
をリターンする。""
はログイン時のオリジナルのユーザーをリターンする。この値は‘-q’や‘-u
user’のようなコマンドラインオプションを反映する。
カスタマイズ関連のファイルや、他の類の短いユーザープロファイルをロードするLispパッケージは、それをどこで探すか判断するためにこの変数にしたがうこと。これらのLispパッケージはこの変数内で見つかったユーザー名のプロファイルをロードすること。init-file-user
がnil
なら‘-q’、‘-Q’、または‘-batch’オプションが使用されたことを意味しており、その場合にはLispパッケージはカスタマイズファイルやユーザープロファイルを何もロードするべきではない。
これはEmacsを使用中のユーザーの電子メールアドレスを保持する。
この関数はユーザーのログイン名をリターンする。これはいずれかがセットされていれば環境変数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をリターンする。 This function returns the real of the user.
この関数はユーザーの実効UIDをリターンする。
この関数はEmacsプロセスの実効GIDをリターンする。
この関数はEmacsプロセスの実GIDをリターンする。
この関数はシステム上のユーザー名をリストする文字列リストをリターンする。この情報をEmacsが取得できなければuser-real-login-name
の値だけを含んだリストをリターンする。
この関数はシステム上のグループ名をリストする文字列リストをリターンする。この情報をEmacsが取得できなければリターン値はnil
。
この関数は数値のグループID gidに対応するグループ名、そのようなグループがなければnil
をリターンする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションではカレント時刻とタイムゾーンを決定する方法を説明します。
current-time
やfile-attributes
のような多くの関数は秒をカウントするLispタイムスタンプ(Lisp
timestamp)値をリターンします。この値は1970-01-01 00:00:00 UTC(Coordinated Universal Time:
協定世界時)というエポック(epoch)からの経過秒数をカウントすることにより絶対時刻を表すことができます。通常これらのカウントは閏秒(leap
seconds)を無視します。ただしGNUや一部のオペレーティングシステムでは閏秒をカウントするように構成できます。
伝統的なLispタイムスタンプが整数のペアであったとしても、それらの形式は進化しており、プログラムは通常はカレントのデフォルト形式に依存するべきではありません。プログラムに特定のタイムスタンプ形式が必要なら、time-convert
関数を使用して必要とする形式に変換できます。時刻の変換を参照してください。
現在のところ3つのLispタイムスタンプ形式があり、それぞれが秒数を表します:
(ticks . hz)
(
hzは正)。これはticks/hz秒を表し、hzが1なら単なるticksと同時刻。hzにたいして一般的な値はナノ秒解像度クロック用の1000000000。
(high low micro pico)
(0≤low<65536、0≤micro<1000000、0≤pico<1000000)。これは次式を使用して秒数を表す:
high * 2**16 + low + micro * 10**-6 + pico *
10**-12。
current-time-list
がt
の場合には、一部の関数がデフォルトでmicroおよびpicoを0に省略した2つ、または3つの要素のリストをリターンする場合があるかもしれない。現在のすべてのマシンではpicoは1000の倍数だが、より高精度のクロックが利用可能になったらこれは変更されるかもしれない。
関数の引数(format-time-string
のtime引数)には、より一般的なtime値(time
value)のフォーマット(Lispタイムスタンプ、カレント時刻にたいするnil
、秒にたいする有限浮動小数点数、欠落要素を0に切り詰めたタイムスタンプリスト(high
low micro)
)が許されています。
time値は暦形式や他形式に相互に変換できます。これらの変換のいくつかは利用可能なtime値範囲を制限するオペレーティングシステム関数に依存しており、その制限を超えると‘"Specified
time is not
representable"’のようなエラーをシグナルします。たとえばあるシステムではエポック以前のタイムスタンプ、あるいは遠い将来の年をサポートしないかもしれません。format-time-string
を使用して可読性のある文字列、time-convert
を使用してLispタイムスタンプ、decode-time
やfloat-time
を使用して別の形式にtime値を変換できます。これらの関数については以降のセクションで説明します。
この関数はカレントの時刻と日付を可読形式の文字列でリターンする。この文字列の先頭部分には曜日、月、日付、時刻がこの順に含まれて、それらが可変長となることはない。これらのフィールドにたいして使用される文字数は常に同じとはいえ、年は正確に4桁とはかぎらず、いつかの将来に終端に追加情報が追加されるかもしれないので、current-time-string
の出力からフィールドを抽出するよりformat-time-string
を使うほうが通常は便利です。
引数timeが与えられたら、それはカレント時刻のかわりにフォーマットする時刻を指定する。オプション引数zoneのデフォルトはカレントのタイムゾーンルール。タイムゾーンのルールを参照のこと。timeの範囲およびzoneの値はオペレーティングシステムが制限する。
(current-time-string) ⇒ "Fri Nov 1 15:59:49 2019"
これは移行支援用のブーリーン変数である。t
ならcurrent-time
や関連する関数は(high
low micro pico)
)、それ以外なら(ticks
.
hz)
という形式を用いてタイムスタンプをリターンする。現在のところ以前のバージョンのEmacsの挙動と互換性をとるために、この変数のデフォルトはt
になっている。この変数のデフォルトはEmacsの将来のバージョンではnil
となり、その後いくつかのバージョンを経た後に削除されるので、開発者はこの変数をnil
にセットしてタイムスタンプ関連のコードをテストするようお勧めする。
この関数はカレント時刻をLispタイムスタンプとしてリターンする。current-time-list
がnil
ならタイムスタンプの形式は(ticks
. hz)
(ticksはクロックチックカウント、hzは1秒当たりのクロックチック)、それ以外の場合にはタイムスタンプは(high
low usec
psec)
という形式のリスト。current-time-list
の値に関わらず特定の形式を得るには(time-convert
nil t)
や(time-convert nil 'list)
を使うことができる。時刻の変換を参照のこと。
この関数はエポックからの経過秒数を浮動小数点数としてリターンする。オプション引数time-valueが与えられた場合には、カレント時刻ではなく変換する時刻を指定する。
警告:
結果は浮動小数点数なので正確ではないかもしれない。正確なタイムスタンプが必要なら使用しないこと。たとえば典型的なシステムにおいては(float-time
'(1 . 10))
を‘0.1’と表示するが、これは1/10より若干大きい。
time-to-seconds
はこの関数のエイリアス。
カレントCPU時間を解像度とともにリターンする。値は(CPU-TICKS
. TICKS-PER-SEC)
のようなペアーとしてリターンされる。CPU-TICKSカウンターはラップアラウンド(wrap
around: 最後に達したら最初に戻る)するかもしれないので、時間が経過し過ぎると値の比較は無意味になるだろう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
デフォルトのタイムゾーンは環境変数TZ
により判断されます。オペレーティングシステムの環境を参照してください。たとえば(setenv "TZ"
"UTC0")
とすれば万国標準時の使用をEmacsに指示できます。その環境にTZ
がなければ、Emacsはプラットフォーム依存のデフォルト時刻であるシステムの実時間(system
wall clock time)を使用します。
サポートされるTZ
のセットはシステム依存です。GNUと他の多くのシステムはTZDBタイムゾーンをサポートします。これはたとえば‘"America/New_York"’はニューヨーク市周辺のタイムゾーンを夏時間ヒストリーを指定します。GNUと他の多くのシステムはPOSIXスタイルのTZ
セッティングをサポートします。これはたとえば‘\"EST+5EDT,M4.1.0/2,M10.5.0/2\"’は1987から2006にニューヨークで使用されたルールを指定します。すべてのシステムは万国標準時(Universal
Time)を意味する‘"UTC0"’文字列をサポートします。
ローカル時刻にたいする変換関数は、変換のタイムゾーンと夏時間の履歴を指定するタイムゾーンルール)time zone
ruleをオプションとして受け取ります。タイムゾーンルールが省略かnil
なら、変換にはデフォルトのタイムゾーン、t
なら万国標準時、wall
ならシステムの実時間(system
wall clock
time)が使用されます。これが文字列なら変換にはTZ
にその文字列をセットしたのと等価なタイムゾーンルールが使用されます。(offset
abbr) (
offsetは万国標準時刻より進んでいる秒数を与える整数でabbrは文字列)のようなリストなら、変換には与えられたオフセットと省略名の固定タイムゾーンが使用されます。整数offsetの場合には、POSIX互換プラットフォームでは数値省略形のabbr、MS-Windowsでは未指定のabbrのとなるような(offset
abbr)であるかのように扱われます。
この関数はユーザーが居るタイムゾーンを記すリストをリターンする。
値は(offset
abbr)
という形式をもつ。ここでoffsetは万国標準時刻より進んでいる秒数(グリニッジより東)を与える整数。負の値はグリニッジより西を意味する。2つ目の要素abbrはそのタイムゾーンのを与える省略名の文字列。たとえば‘"CST"’は中国標準時か米国中部標準時のタイムゾーン。夏時間の開始と終了時に、いずれの要素も変化し得る。ユーザーが季節時間調整を用いていないタイムゾーンを指定した場合には、値は時期を通して定数となる。
この値を計算するのに必要なすべての情報をオペレーティングシステムが提供しなければ、このリストの未知の要素はnil
になる。
引数timeが与えられたら、それはカレント時刻のかわりに分析するべきtime値を指定する。オプション引数zoneのデフォルトはカレントのタイムゾーンルール。timeの範囲およびzoneの値はオペレーティングシステムが制限する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はtime値(時刻を参照)をLispタイムスタンプや暦情報(calendrical information)に変換したり逆の変換を行います。
秒を数えるために多くのオペレーティングシステムは64ビット符号付き整数を使用しており、過去や未来の時刻を表すことができます。しかしより制限されているオペレーティングシステムもいくつか存在します。たとえば32ビット符号付き整数を使用する旧式のオペレーティングシステムでは、通常は協定世界時で1901-12-13 20:45:52から2038-01-19 03:14:07までの時刻しか扱うことができません。
暦変換関数はたとえグレゴリオ暦導入前の日付や、グレゴリオ暦では誤差が非常大きくなるために天文学や古生物学のような科学分野の一般的慣習としてユリウス暦の年数が使用されるような遠い過去や未来の日付であってもグレゴリオ暦を使用します。伝統的なグレゴリオ年が行うように0年をスキップせずにBCE 1年から年数を数えます。たとえば年数-37はグレゴリオ年のBCE 38年を表します。
この関数はtime値をLispタイムスタンプに変換する。
form引数はリターンするタイムスタンプ形式を指定する。この関数はformがシンボルinteger
なら整数でカウントした秒数をリターンする。正の整数のformはクロック周波数を指定する。その場合にはこの関数は(ticks
.
form)
という整数ペアのタイムスタンプをリターンする。formがt
なら、この関数はタイムスタンプを適切に表現するような正の整数としてそれを扱う。たとえばtimeがnil
でプラットフォームのタイムスタンプがナノ秒の解像度をもつ場合には1000000000としてそれを扱う。formがlist
なら、この関数は整数のリスト(high
low micro
pico)
をリターンする。現在のところformがnil
の場合にはlist
のように動作するとしても、Emacsの将来バージョンで変更が予定されているので、呼び出し側がリスト形式のタイムスタンプを必要とする場合には明示的にlist
を渡すこと。
timeがtime値でなければ、この関数はエラーをシグナルする。それ以外の場合には、timeを正確に表せなければ負の無限大方向に切り詰めて変換する。formがt
なら変換は常に正確なので切り詰めは発生せず、リターン値のクロック解像度がtimeの解像度より小さくなることはない。それとは対照的にfloat-time
はエラーをシグナルせずに任意のtime値を変換できるものの、結果は不正確かもしれない。時刻を参照のこと。
この関数は効率化のためにtimeとeq
な値、あるいはtimeと構造を共有する値をリターンするかもしれない。
(time-convert nil nil)
は(current-time)
と等価だが後者は幾分速い。
(setq a (time-convert nil t)) ⇒ (1564826753904873156 . 1000000000)
(time-convert a 100000) ⇒ (156482675390487 . 100000)
(time-convert a 'integer) ⇒ 1564826753
(time-convert a 'list) ⇒ (23877 23681 904873 156000)
この関数はtime値を暦情報に変換する。timeを指定しなければカレント時刻をデコードする。同様にzoneのデフォルトはカレントのタイムゾーンルール。タイムゾーンのルールを参照のこと。timeの範囲およびzoneの値はオペレーティングシステムが制限する。
form引数はリターンされるseconds要素の形式を制御する(以下参照)。リターン値は以下のような9要素のリスト:
(seconds minutes hour day month year dow dst utcoff)
以下は各要素の意味:
以下で説明する形式による、分秒の秒。
0から59までの整数で表した時を過ぎた時分秒の分。
0から23までの整数で表した時分秒の時。
1から31までの整数で表した年月日の日。
1から12までの整数で表した年月日の月。
通常は1900より大きい整数で表した年月日の年。
0から6までの整数で表した曜日であり0は日曜日を意味する。
夏時間が有効ならt
、無効ならnil
、その情報が利用できなければ-1。
万国標準時からの秒数、すなわち東グリニッジの秒数を示す整数。
Lispタイムスタンプのseconds要素は非負かつ61より小さいこと。これはは正の閏秒の間以外は60より小さくなる(オペレーティングシステムが閏秒をサポートする場合)。オプションのform引数がt
なら、secondsはtimeと同じ精度を使用する。formがinteger
ならsecondsを整数に切り捨てる。たとえばtimeがタイムスタンプ(1566009571321
. 1000)
(閏秒がない通常のシステムでは2019-08-17 02:39:31.321 UTCを表す)なら、(decode-time
time t t)
は((31321 . 1000) 39 2 17 8 2019 6 nil
0)
だが(decode-time time t 'integer)
は(31 39 2 17 8 2019 6
nil
0)
をリターンする。formが省略かnil
の場合のデフォルトは現在のところinteger
だが、このデフォルトはEmacsの将来バージョンで変更されるかもしれないので、呼び出し側は特定の形式が必要ならformを指定すること。
Common Lispに関する注意: Common
Lispではdow、dst
、utcoffの意味が異なり、secondは0から59(両端を含む)の整数である。
暦情報の要素にアクセス(や変更)するためのアクセッサとしてdecoded-time-second
、decoded-time-minute
、decoded-time-hour
、decoded-time-day
、decoded-time-month
、decoded-time-year
、decoded-time-weekday
、decoded-time-dst
、decoded-time-zone
を使用できる。
これはtimeをLispタイムスタンプに変換する。これはdecode-time
の逆の関数として機能する。
通常だとdecode-time
形式でデコードされた時刻を指定する(second minute
hour day month year ignored dst
zone)
がリストの1つ目の引数となる。これらのリスト要素の意味については、decode-time
のテーブルを参照のこと。特にdstはタイムスタンプが繰り返される夏時間(DST:
daylight saving
time)の期間中のフォールバックにおけるタイムスタンプの解釈法を指定する。dstが-1ならDSTを推測、t
かnil
の場合にはそのDST値をもつタイムスタンプをリターン、そのようなタイムスタンプが存在しなければエラーをシグナルする。残念なことにt
やnil
のdst値は、たとえばzoneが‘"Europe/Volgograd"’において、その日の02:00にグリニッジ東の標準時を+04:00から+03:00に変更した際の2020-12-27
01:30にたいする2つの標準時タイムスタンプの不明確さといったような、TZDBタイムゾーンがグリニッジを更に超えて西に移動した際における重複したタイムスタンプの不明確さを解消するものではない。このような状況を処理するためには、不明確さを解消するために数値のzoneを使用することができる。
1つ目の引数は(second minute hour day month
year)
のようなリストでもよい。これは(second minute hour
day month year nil -1 nil)
のようなリストとして扱われる。
廃れた呼び出し規約として、この関数は6つ以上の引数を受け取ることができる。最初の6つの引数second、minute、hour、day、month、yearはデコード済みtimeのほとんどの要素を指定する。7つ目以降の引数があれば、最後の引数はzoneとして使用されれるので、(apply
#'encode-time (decode-time
...))
は機能する。この廃れた規約においてはdstは-1、zoneのデフォルトはカレントタイムゾーンルール(タイムゾーンのルールを参照)となる。時代遅れな呼び出し側を現代化する際には、9つの要素を含んだより最新の同等リストのdst
要素に、nil
ではなく-1がセットされていることを確認すること。
100未満の年が特別に扱われることはない。これに1900や2000を超える年を意味させたい場合には、encode-time
を呼び出す前に自身でこれらを修正しなければならない。timeの範囲およびzoneの値はオペレーティングシステムが制限する。とはいえエポックから近い将来に渡るタイムスタンプ範囲は常にサポートされる。
encode-time
関数はdecode-time
のラフな逆関数として動作する。たとえば以下のように後者の出力を前者に渡すことができる:
(encode-time (decode-time …))
seconds、minutes、hour、day、monthに範囲外の値を使用することにより単純な日付計算ができる。たとえばdayが0なら与えられたmonthの前月末日になる。失敗する場合もよくあるので、これを行う際には注意すること。たとえば:
;; 現在から1ヶ月後を算出。 ;; 期待どおりに動かないかもしれないので注意 (let ((time (decode-time))) (setf (decoded-time-month time) (+ (decoded-time-month time) 1)) time)
残念ながらこのコードは月の長さの違いによって結果時刻が不正になったり、夏時間への移行、タイムゾーン変更、閏日や閏秒を考慮しない等で期待どおり動作しないかもしれない。たとえばこのコードを1月30日に実行すれば、encode-time
であれば3月初頭に調整するであろう2月30日という存在しない日付を得ることになる。同様に2096年2月29日に4年を加えた2100年2月29日は存在せず、ニューヨークで3月13日の01:30に1時間を加えるとタイムスタンプとして02:30を得るだろうが、ニューヨークではその日の02:00に03:00へ時刻が飛ぶのでこれも存在しないタイムスタンプを得ることになる。問題のいくつか(すべてではない)を回避するために影響を受ける単位の半ば、たとえば月の加算を行う際にはその月の15日で開始するといったような計算を基にすることができる。別の策としてはcalendarやtime-dateといったライブラリーを使うことができる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はtime値とテキスト文字列の間で変換と逆変換を行います。time値はLispタイムスタンプ(時刻を参照)、またはデコード済みtime構造(時刻の変換を参照)のいずれかで表現されます。
この関数はtime文字列stringをパースして対応するLispタイムスタンプをリターンする。引数stringは日時を表現するparse-time-string
(以下参照)が認識する形式のいずれかであること。この関数はstringに明示的なタイムゾーン情報が欠落していれば万国標準時(Universal
Time)を仮定する。またstringに月、日、時刻がなければ、もっとも過去の値とみなす。timeの範囲およびzoneの値はオペレーティングシステムが制限する。
この関数はtime文字列stringをデコード済みtime構造(時刻の変換を参照)にパースする。引数stringはRFC 822(またはそれ以降)やISO 8601に類似した“Fri, 25 Mar 2016 16:24:56 +0100”や“1998-09-12T12:21:54-0200”のような文字列であることが必要だが、この関数は形式が若干不正なtime文字列のパースも同様に試みる。
より厳格な(無効な入力にはエラーを出力する)関数のかわりに、この関数を使用できる。これはISO
8601標準の変種をパースできるので、上述のフォーマットに加えて“1998W45-3” (週番号)や“1998-245”
(序数日)のような日付をパースできる。期間(duration)のパースはiso8601-parse-duration
、間隔(interval)のパースにはiso8601-parse-interval
がある。これらの関数は最後の関数(それらのうち開始、終了、期間の3つをリターンする)を除いて、すべてデコード済みtime構造をリターンする。
この関数はLispタイムスタンプtime
(省略かnil
の場合のデフォルトはカレント時刻)をformat-stringに応じて文字列に変換する。この変換にはタイムゾーンルールzone
(デフォルトはカレントのタイムゾーンルール)を使用する。タイムゾーンのルールを参照のこと。引数format-stringには、時刻を置換する‘%’シーケンスを含めることができる。以下は‘%’シーケンスは何を意味するかのテーブルである:
曜日の短縮名を意味する。
曜日の完全名を意味する。
月の短縮名を意味する。
月の完全名を意味する。
‘%x %X’のシノニム。
これは世紀、つまり年を100で除して小数点以下を切り捨てる。デフォルトのフィールド幅は2。
0パディングされた年月日の日。
‘%m/%d/%y’のシノニム。
ブランクでパディングされた年月日の日。
これは‘%+4Y-%m-%d’のようなISO 8601日付フォーマットと似ているが、‘+’と‘4’を任意のフラグとフィールド幅(6を減じた後)をオーバーライドする点が異なる。
これはカレントのISO週(ISO week)の番号に対応する、世紀部分(00–99)を除いた年を意味する。ISO週は月曜が開始で終了は日曜。ISO週の開始と終了の年が異なる場合に‘%g’が生成する年にたいする規則は複雑であり、ここでは説明しない。しかし一般的には、もし週のうちのほとんどが終了年にあれば‘%g’はその年を生成するだろう。
これはカレントのISO週番号に対応する、世紀を含めた年を意味する。
‘%b’のシノニム。
時分秒の時(00から23)を意味する。
時分秒の時(01から12)を意味する。
年内の経過日(001から366)を意味する。
ブランクでパディングされた時分秒の時(0から23)を意味する。
ブランクでパディングされた時分秒の時(1から12)を意味する。
年月日の月(01から12)を意味する。
時分秒の分(00から59)を意味する。
改行を意味する。
ナノ秒(000000000–999999999)を意味する。より少ない桁数を求める場合にはミリ秒は‘%3N’、マイクロ秒は‘%6N’を使用する。余分な桁は丸めずに切り捨てられる。
必要に応じて‘AM’か‘PM’を意味する。
これはカレンダーの四半期(1–4)を意味する(訳注: 会計年度で使用される4月1日を年度開始日とする四半期ではなく元旦を年度開始日とする四半期)。
‘%I:%M:%S %p’のシノニム。
‘%H:%M’のシノニム。
これはエポック以降の経過秒数を表す整数。
これは秒を意味する(00–59、閏年をサポートするプラットフォームでは00–60)。
タブ文字を意味する。
‘%H:%M:%S’のシノニム。
これは数字で表した曜日(1から7)で、月曜日が1。
週の開始を日曜日とみなした年内の週(01から52)。
これはISO 8601にたいする年内の週を意味する。
数字で表した曜日(0から6)で日曜日が0。
これは週の開始を月曜日とみなした年内の週(01から52)。
これはlocale固有の意味をもつ。デフォルトlocale(Cという名前のlocale)では‘%D’と等価。
これはlocale固有の意味をもつ。デフォルトlocale(Cという名前のlocale)では‘%T’と等価。
世紀を含まない年(00から99)を意味する。
世紀を併なう年を意味する。
タイムゾーンの短縮形(たとえば‘EST’)を意味する。
これはタイムゾーンの数値オフセットを意味する。‘z’の前に1つ、2つ、または3つのコロンを前置できる。単なる‘%z’が‘-0500’を意味する場合には‘%:z’は‘-05:00’、‘%::z’は‘-05:00:00’を意味する。‘%:::z’は‘%::z’と同様だが末尾の‘:00’を無するので、この例では‘-05’を意味する。
これは単独の‘%’を意味する。
‘%’の直後には1つ以上のフラグ文字を記述してもよい。‘0’は0、‘+’は0をパディングして5桁以上の非負の年の前に‘+’を配置、‘_’は空白によるパディング、‘-’はパディングの抑制、‘^’は英大文字、‘#’は文字のcase(大文字小文字)を反転させる。
これらの‘%’シーケンスすべてにたいしてフィールド幅とパディングのタイプの指定でのきる。これはprintf
と同じように機能する。フィールド幅は‘%’シーケンス内の任意のフラグの後に数字として記述するたとえば‘%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の数字の代替表現を使用する。これは数字を出力する、ほとんどすべてのアルファベットで使用が許されている。
デバッグプログラム支援のために、認識されない‘%’シーケンスはそれ自体を意味しており、そのまま出力される。将来のEmacsバージョンでは拡張として新たな‘%’シーケンスが認識されるかもしれないので、プログラムはこの挙動に頼るべきではない。
この関数は処理のほとんどを行うためにCライブラリー関数strftime
を使用している(Formatting Calendar
Time in The GNU C Library Reference
Manualを参照)。その関数とやり取りするために最初にtimeとzoneを内部形式に変換する。timeの範囲およびzoneの値はオペレーティングシステムが制限する。この関数はformat-stringもエンコードする。strftime
が結果文字列をリターンした後に同じコーディングシステムを使用してformat-time-string
はデコードを行う。
この関数は引数secondsをformat-stringに応じた年、日、時、...の文字列に変換する。引数format-stringには変換を制御する‘%’シーケンスを指定することができる。以下のテーブルは‘%’の意味:
年間365日での年の整数。
年月日の日。
時分秒の時の整数。
時分秒の分の整数。
秒数。オプションの‘,’パラメーターが使用されていたらそれは浮動小数点数であり、‘,’の後の数は使用する小数点以下の桁数を指定する。‘%,2s’は“小数点以下2桁の使用”を意味する。
非プリント制御フラグ。これを使用する際には他の指定はサイズ減少順、すなわち年、日、時刻、分、...のように与えなければならない。最初の非0変換に遭遇するまで‘%z’の左側の結果文字列は生成されない。たとえばemacs-uptime
(emacs-uptimeを参照)で使用されるデフォルトフォーマットでは、秒数は常に生成されるが年、日、時、分はそれらが非0の場合のみ生成されるだろう。
‘%z’と同じ行に作用する非プリント制御フラグだが、末尾にある0値のtime要素のプリントを抑制する。
リテラルの‘%’を生成する。
大文字のフォーマットシーケンスは数字に加えて単位を生成するが、小文字フォーマットは数字だけを生成する。
‘%’に続けてフィールド幅を指定できる。指定したフ幅より短ければブランクでパディングされる。この幅の前にオプションでピリオドを指定すれば、かわりに0パディングを要求する。たとえば"%.3Y"
は"004
years"
を生成するだろう。
[ << ] | [ < ] | [ 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が使用したプロセッサー実行時間をLispタイムスタンプとしてリターンする(時刻を参照)。
この関数がリターンする値にはEmacsがプロセッサーを使用していない時間は含まれないこと、そしてEmacsプロセスが複数のスレッドをもつ場合には、すべてのEmacsスレッドにより使用されたプロセッサー時間の合計値がリターンされることに注意。
システムがプロセッサー実行時間を判断する方法を提供しなければget-internal-run-time
はcurrent-time
と同じ値をリターンする。
この関数はEmacsの初期化(要約: スタートアップ時のアクション順序を参照)にかかった秒数を文字列としてリターンする。インタラクティブに呼び出された場合にはエコーエリアにプリントする。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の関数はtime値を使用して暦計算を行います(時刻を参照)。これらの関数でtime値を受け取るすべての引数では、他のtime値と同じようにnil
値はカレントシステム時刻、有限の数値はエポックからの経過秒数を意味します。
これはtime値t1がtime値t2より小ならt
をリターンする。
この関数は2つのtime値t1とt2等しければt
をリターンする。引数のいずれかがNaNの場合は結果はnil
となる。比較という目的のために、nil
の引数は無限大の解像度によるカレント時刻を表すので、呼び出し側は任意のタイムスタンプと等しくならない未知のtime値としてnil
を使うことができる。したがって一方の引数がnil
でもう一方がnil
でなければこの関数はnil
をリターンする。
これは2つのtime値の差t1 -
t2をLispタイムスタンプとしてリターンする。結果は正確であり、そのクロック解像度が2つの引数の解像度より劣ることはない。経過秒の単位の差が必要なら、time-convert
やfloat-time
で変換できる。時刻の変換を参照のこと。
これはtime-subtract
のようないくつかの変換ルールを使用して、2つのtime値の和をtime値としてリターンする。ここで引数のうち1つはある時点での時刻ではなく時間差を表すこと(time値は経過秒数という単一の数値であることがよくある)。以下はあるtime値に秒数を加算する方法:
(time-add time seconds)
この関数はAC. 1年元日からtime-valueまでの間の日数をデフォルトタイムゾーンとみなしてリターンする。timeの範囲およびzoneの値はオペレーティングシステムが制限する。
これはtime-valueに対応する年内の日数をデフォルトタイムゾーンとみなしてリターンする。timeの範囲およびzoneの値はオペレーティングシステムが制限する。
この関数はyearが閏年ならt
をリターンする。
yearのmonthの日数をリターンする。たとえば2020年2月は29日。
yearの序数日ordinalをデコード済みtime構造体としてリターンする。たとえば2004年の120日目は2004年4月29日。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
将来の特定時刻や特定の長さのアイドル時間経過後に関数を呼び出すためにタイマー(timer)をセットアップできます。タイマーは次回の呼び出し時刻と呼び出す関数についての情報を格納したスペシャルオブジェクトです。
この述語関数はobject
がタイマーなら非nil
をリターンする。
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に待機を発生させるような関数(時間の経過や入力の待機を参照)の呼び出しも避けるべきです。その待機中に別のタイマー(同じタイマーとう可能性さえある)が実行され得るので、これは予測不可能な効果を導く恐れがあります。特定時間の経過後に処理される必要があるタイマー関数は、新たなタイマーをスケジュールしてこれを行うことができます。
タイマー関数がリモートファイルを処理する場合には、同一接続ですでに実行中のリモートファイル処理と競合する可能性があります。そのような競合が検出されると、結果はremote-file-error
エラーに格納されます(標準的なエラーを参照)。このようなエラーはタイマー関数のbodyでラップすることで保護する必要があります。
(ignore-error 'remote-file-error …)
マッチデータを変更するかもしれない関数を呼び出すタイマー関数はマッチデータの保存とリストアをするべきです。マッチデータの保存とリストアを参照してください。
これは時刻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
のような関数にとって有用。たとえば以下はfunctionを“毎分丁度”(‘11:03:00’、‘11:04:00’、...)に実行する:
(run-at-time t 60 function)
タイマーが実行されるべきタイミングでEmacsがCPUタイムを取得できなかった場合(たとえば別プロセス実行中のためシステムがビジーだったり、コンピューターがスリープ中やサスペンド中の場合)には、Emacsが再開されてアイドルになり次第タイマーが実行される。
関数run-at-time
はスケジュール済みの将来の特定アクションを識別するtime値をリターンする。cancel-timer
(以下参照)の呼び出しにこの値を使用できる。
これは正にrun-at-time
と同じだが、これは遅延を秒で指定する際の使用を意図している(パラメーターはrun-at-time
の説明を参照。ただしこの関数はtimeをsecsとして渡している)。
タイマーのリピートは名目上は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つの呼び出しの効果をキャンセルする。指定した時刻が到来しても特に何も起きないだろう。
list-timers
コマンドはカレントでアクティブなすべてのタイマーをリストします。コマンドc
(timer-list-cancel
)はポイントのある行のタイマーをキャンセルします。コマンドS
(tabulated-list-sort
)を使用すれば、列でリストをソートできます。
[ << ] | [ < ] | [ 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
で使用するのと同じフォーマットでリターンする(時刻を参照)。
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のディスプレイ表示を参照してください。
42.13.1 入力のモード | 入力の処理方法にたいするオプション。 | |
42.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番目のビットがセットされた文字を、必要に応じてデコードする前(端末I/Oのエンコーディングを参照)にメタ文字に変換する。metaがシンボルencoded
の場合には、Emacsはまず各バイトの8ビットすべてを使って文字をデコードしてから、デコードされたシングルバイトの8ビット目がセットされていればそれをMeta文字に変換する。最後にmetaがt
、nil
、あるいはencoded
のいずれでもなければ、デコードの前後においてEmacsは入力の8ビットすべてを変更せずに使用する。これはMeta修飾を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番目のビットをMetaビットとして扱う場合にはt
、デコードされたシングルバイト文字の8番目のビットをMetaビットとして扱う場合にはencoded
、すべての入力文字の8ビット目をクリアーする場合にはnil
。その他の値はEmacsが8ビットすべてを基本的な文字コードとして使用することを意味する。
カレントでEmacsがquitに使用する文字であり通常はC-g。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この関数はキーボードかマウスからの最後の入力イベント300個を含んだベクターをリターンする。その入力イベントがキーシーケンスに含まれるか否かに関わらずすべての入力イベントが含まれる。つまりキーボードマクロにより生成されたイベントを含まない、最後の入力イベント300個を常に入手することになる(キーボードマクロは、デバッグにとってより興味深いとはいえないので除外されている。そのマクロを呼び出したイベントを確認するだけで充分であるはず)、
include-cmdsが非nil
なら、結果ベクター内の完全なキーシーケンスが(nil
.
COMMAND)
という形式の疑似イベントが差し込まれる。ここでCOMMANDはそのキーシーケンスの開始(コマンドループの概要を参照)。
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が修飾キーControl、Meta、Alt、Hyper、Superにたいして何のkeysymを使用するべきかを指定できます。
keysymの名前はそれぞれ修飾子Control、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モードではgc-cons-percentage
変数の値をデフォルトの‘0.1’から‘1.0’まで増加します。これはガーベージコレクションの実行がデフォルトより少なくなる(そしてメモリー消費は多くなる)ことを意味するので、長時間の実行が予想されるbatchジョブではこの制限を元に戻すように調整する必要があります。
Emacsがbatchモードで実行中ならこの変数は非nil
。
batchモードでEmacsがエラーのシグナルによりexitすると、Emacsのexitステータスは非0です:
$ emacs -Q --batch --eval '(error "foo")'; echo $? foo 255
[ << ] | [ < ] | [ 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 (format "%S" '(with-current-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
を提供しています。ファイル通知を受け取りたいLispプログラムは、ネイティブのライブラリーよりこのライブラリーを優先する必要があります:このセクションではfilenotify
ライブラリーの関数と変数について説明します。
fileに関するファイルシステムイベントの監視を追加する。これはfileに関するファイルシステムイベントがEmacsに報告されるように取り計らう。
リターン値は追加された監視ディスクリプター(descriptor)。タイプは背景にあるライブラリーに依存しており、以下の例に示すとおり一般的には整数とみなすことはできない。比較にはequal
を使用すること。
何らかの理由によりfileが監視不可能なら、この関数はエラーfile-notify-error
をシグナルする。
マウントされたファイルシステムでファイル変更を監視できないことがある。これはこの関数により検出されないので、非nil
のリターン値が実際にfileが変更された通知であることを保証するものではない。
fileがシンボリックリンクの場合には、そのリンクのフォローは行わずfileそのものだけを監視する。
flagsは何を監視するかセットするためのコンディションのリスト。以下のシンボルを含めることができる:
change
ファイル内容の変更を監視。
attribute-change
パーミッションや変更時刻のようなファイル属性の変更を監視。
fileがディレクトリーなら、change
はそのディレクトリーでのファイルの作成と削除を監視する。このような場合にファイルの変更もレポートするファイル通知バックエンドもいくつかある。これは再帰的に機能しない。
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) 'nofollow) ⇒ 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
がリターンしたオブジェクトであること。
Removes all existing file notification watches from Emacs.
ファイル監視にもとづくパッケージでは予期せぬ副作用が起こり得るので、このコマンドの使用には注意を要する。これは主にデバッグ目的やEmacsがフリーズした際の使用を意図した関数である。
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
はシェルのメタ文字はクォートするが先頭の‘-’のクォートはしない。MS-Windowsでの‘%’にたいするクォートでは名前に‘^’がある環境変数を想定していない。shell引数を参照のこと。通常はサブシェルよりcall-process
を使用するほうが安全である。同期プロセスの作成を参照のこと。そしてEmacsのビルトイン関数を使用するほうが安全である。たとえばmv
を呼び出すかわりに(rename-file
"a" "b" t)
を使用する。ファイルの名前と属性の変更を参照のこと。
Emacsはアクセスするファイルとネットワークのコーディングシステムを推察する。コーディングシステムを参照のこと。Emacsの推察が誤っていたりネットワークの相手先がEmacsの推察に不同意なら、結果となるコーディングシステムは信頼できないかもしれない。更にその推察が正しいときでさえ、他のプログラムが使用できないバイトをEmacsが使用できる場合がよくある。たとえばEmacsEmacsにとってはnullバイトは他と同じ単なる文字だとしても、他の多くのアプリケーションはnull文字を文字列終端として扱うので、nullバイトを含む文字列やファイルを誤って処理する。
POSIXはEmacsの挙動に影響し得る環境変数をいくつか指定する。ASCII英大文字、数字、アンダースコアだけから構成される名前をもつ任意の環境変数がEmacsの内部の動作に影響を及ぼし得る。Emacsはその種のEMACSLOADPATH
のような変数をいくつか使用する。See ライブラリー検索を参照のこと。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を参照してください。
これらのセクションは主にパッケージアーカイブのメンテナー向けであり、情報の多くはパッケージ作成者(これらのアーカイブを介して配布されるコードを記述した人)には関係ありません。
43.1 パッケージ化の基礎 | Emacs Lispパッケージの基本的概念。 | |
43.2 単純なパッケージ | 単一.elファイルをパッケージする方法。 | |
43.3 複数ファイルのパッケージ | 複数ファイルをパッケージする方法。 | |
43.4 パッケージアーカイブの作成と保守 | パッケージアーカイブの保守。 | |
43.5 アーカイブウェブサーバーとのインターフェイス | アーカイブウェブサーバーへのインターフェース。 |
[ << ] | [ < ] | [ 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-activate-all
を呼び出します。これは早期initファイルロード後、かつ通常initファイルロード後に行われます(要約: スタートアップ時のアクション順序を参照)。早期initファイルでユーザーオプションpackage-enable-at-startup
がnil
にセットされている場合には、パッケージは自動的に利用可能にはなりません。
この関数はカレントセッションでパッケージを利用可能にする。ユーザーオプションpackage-load-list
は利用可能にするパッケージを指定する。デフォルトではインストール済みのパッージすべてが利用可能になる。Package
Installation in The GNU Emacs Manualを参照のこと。
ほとんどの場合には、スタートアップの間に自動的に行われるのでpackage-activate-all
を呼び出す必要はないはずである。単に早期initファイル内にpackage-activate-all
の前に実行される必要のあるコードを配置するとともに、package-activate-all
の後に実行される必要のあるコードを主linitファイルに配置することを確実に行なえばよい(Init
File in The GNU Emacs Manualを参照)。
この関数は何のパッケージがインストール済みかに関するEmacsの内部レコードを初期化してからpackage-activate-all
を呼び出す。
オプション引数no-activateが非nil
なら、インストール済みパッケージを実際に利用可能にせずにこのレコードを更新する。これは内部でのみ使用される。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
シンプルパッケージは単一のEmacs Lispソースファイルで構成されます。このファイルはEmacs Lispライブラリーのヘッダー規約に準拠していなればなりません(Emacsライブラリーのヘッダーの慣習を参照)。以下の例に示すようにパッケージの属性は種々のヘッダーから取得されます:
;;; superfrobnicator.el --- Frobnicate and bifurcate flanges -*- lexical-binding:t -*- ;; Copyright (C) 2022 Free Software Foundation, Inc.
;; Author: J. R. Hacker <jrh@example.com> ;; Version: 1.3 ;; Package-Requires: ((flange "1.0")) ;; Keywords: multimedia, hypermedia ;; URL: https://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という名前のファイルがあれば、(すべての‘;;; Commentary:’セクションをオーバーライドして)長い説明(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
で指定されます。この変数のデフォルト値はGNU ELPAとnon-GNU
ELPAでホストされるアーカイブのリストです。このセクションではパッケージアーカイブのセットアップと保守の方法について説明します。
この変数の値はEmacsパッケージマネージャーが認識するパッケージアーカイブのリスト。
このalistの要素はそれぞれが1つのアーカイブに対応する(id
.
location)
という形式であること。ここでidはパッケージ名(文字列)、locationは文字列であるようなベースロケーション(base
location)。
ベースロケーションが‘http:’か‘https:’で始まる場合にはHTTP(S)のURLとして扱われて、(デフォルトのGNUアーカイブのように)HTTP(S)を介してこのアーカイブからパッケージがダウンロードされる。
それ以外ならベースロケーションはディレクトリー名であること。この場合には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-archives
内になければPackage
Menuインターフェースからアクセスできないことを忘れないでください。
公的なパッケージアーカイブの保守には責任が併ないます。アーカイブからEmacsユーザーがパッケージをインストールする際には、それらのパッケージはそのユーザーの権限において任意のコードを実行できるようになります(これはパッケージにたいしてだけでなく一般的なEmacsコードにたいしても真といえる)。そのためアーカイブの保守を保つとともにホスティングシステムが安全であるよう維持するべきです。
暗号化されたキーを使用してパッケージにサイン(sign)するのがパッケージのセキュリティーを向上する1つの方法です。gpgのprivateキーとpublicキーを生成してあれば以下のようにそのパッケージにサインするためにgpgを使用できます:
gpg -ba -o file.sig file
単一ファイルパッケージにたいしては、fileはそのパッケージのLispファイルです。複数ファイルパッケージではそのパッケージのtarファイルです。同じ方法によりアーカイブのコンテンツファイルにもサインできます。これを行うにはパッケージと同じディレクトリーで.sigファイルを利用可能できるようにしてください。ダウンロードする人にたいしても、https://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] | [ ? ] |
パッケージアーカイブへのアクセスを提供するウェブサーバーは、以下のクエリーをサポートしなければなりません:
アーカイブ内容を記述するlispフォーム。このフォームはリストの最初の要素がアーカイブバージョンであることを除けば’package-desc’構造(package.elを参照)のリストである。
パッケージの長い説明(long description)をリターンする。
そのファイルの署名をリターンする。
そのファイルをリターンする。これは複数ファイルパッケージではtarball、シンプルパッケージでは単一ファイルかもしれない。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
時代に逆らって生きるユーザーのために、以下はEmacsバージョン28.2へのダウングレードに関する情報です。Emacs 29.1機能の不在による結果としての偉大なる単純さをぜひ堪能してください。
substitute-command-keys
を呼び出さないことによって、いくつかの関数がクォート文字やキーシーケンスの煩わしい変換を行わなくなりました。目を引く例としてformat-prompt
、およびそれを呼び出す多くの関数すべてが挙げられます。これによってこれらの関数が生成する文字列の予測がより容易になり、Lispプログラマーであるあなたにとってはユーザーに表示するテキスト内にどの句読点文字を表示させるかが制御しやすくなりました。同様の理由によってsubstitute-quotes
関数が削除されました。
buffer-modified-p
関数は紛らわしい値ではなく、以前のように確実にnil
かt
だけをリターンするようになりました。
compiled-function-p
を削除しました。Lispプログラムには関数オブジェクトに関するbuilt-in、byte-compiled、natively-compiledといったタイプを明示的にテストすることが期待されています。同様の理由によりpos-bol
、pos-eol
、file-attribute-file-identifier
といった多くの関数が削除されました。このような派手な関数が失われたことを悲しむ人がいるなど、わたしたちは期待していません。
x-show-tip
によって用いられるタイムアウトは、Lispプログラムから指定するのではなく関数内にハードコードされます(訳注:
x-show-tipは内部的な使用を意図した関数でありユーザー用の関数はtooltip-show; Emacs
29.1からツールチップ表示タイムアウトがハードコードされた値ではなくx-show-tooltip-timeoutでカスタマイズ可能になった)。これによってコードがシンプルかつ保守しやすくなりますし、ツールチップのポップアップが非表示になるまでのタイムアウトを制御したい人など存在しない筈です。
setopt
が削除されました。かわりにcustomize-variable
を使うか、Lispから:set
関数を呼び出してください。
lisp-directory
変数の値は、似たようなinstallation-directory
やsource-directory
の等の他の変数から(それらの変数が関係する場合には)容易に推測できるので削除しました。
get-display-property
とadd-display-text-property
を削除しました。かわりに汎用性のあるget-text-property
とput-text-property
を使ってください。
keymap-set
、keymap-global-set
、keymap-local-set
、keymap-substitute
、keymap-lookup
、その他の関数が削除されました。伝統的なdefine-key
、global-set-key
、local-set-key
、substitute-key-definition
、key-binding
で十分すぎます。これらの関数が受け付けるキー構文の些細な一貫性の欠如こそ、Emacs
Lispプログラミングにおける終わりなき愉悦の源だからです。何故にEmacsプログラミングをつまらない場にするのでしょうか?
kbd
の寛大な性質をよりEmacs
Lisp精神に則って考慮した結果、同様の理由によってkey-valid-p
を削除しました。
string-pixel-width
とstring-glyph-split
は削除しました。表示はCで記述されたディスプレイエンジンのためのものであり、そこに留まるべきなのです!
xwidget-perform-lispy-event
、xwidget-webkit-load-html
、xwidget-webkit-back-forward-list
といった新しいさまざまなXwidget関数が削除されました。
make-process
呼び出しにおいて:stderr
プロパティをセットすることによって、そのプロセス接続にはすべての標準ストリームにptyではなく、以前のようにpipeの使用が強制されるようになりました。この複雑なインターフェイスが大幅に単純化がされたのです。
string-equal-ignore-case
を削除しました。かわりにcompare-strings
を使ってください。
バイトコンパイラーを複雑にするいくつかの機能を削除しました。
choice
リストにおけるダブルクォートされたシンボルのような、不正な形式のdefcustom
について警告。
with-buffer-unmodified-if-unchanged
を削除しました。そのような場合においてバッファーを未変更のままにする必要があるLispプログラムは、変更の前後でテキストを比較することは常に可能なのですから。
string-edit
とread-string-from-buffer
を削除しました。
readablep
、およびそれに関連する変数print-unreadable-function
は削除しました。
multisession-value
、define-multisession-variable
、list-multisession-values
はなくなりました。
cursor-face
にたいするサポートを削除しました。この機能のサポートは残されたフェイスだけで十分だと考えます。
tooltip-show
から、ツールチップのフェイスおよびトップフレームのカラーに奇抜な制御を許すためのオプション変数text-face
とtext-face
のサポートを削除しました。わたしたちはユーザーの混乱を避けるために、ツールチップはすべて同じ外観であるべきだと判断しました。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. https://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 https://www.gnu.org/licenses/.
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. https://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 https://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 https://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 https://www.gnu.org/licenses/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コードを記述する際にしたがうべき慣習です:
この慣習はカスタム定義を含むすべてのファイルに必須である。そのようなファイルを慣習にしたがうために修正するのが非互換の変更を要するなら、構うことはないから非互換の修正を行うこと。先送りにしてはならない。
ユーザーの使用を意図したコマンド名では、何らかの単語がそのパッケージ名のプレフィクスの前にあると便利なことがある。たとえばわたしちの慣習ではオブジェクトをリストするコマンドの名前なら‘list-something’、すなわち‘frob’と呼ばれるパッケージのグローバルシンボルが‘frob-’で始まれば‘list-frobs’というコマンドをもつかもしれない。さらに関数や変数等を定義する構文が‘define-’で始まればより良く機能するので、名前内でそれらの後に名前プレフィクスを置くこと。
この勧告は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つの一般的なプレフィクス候補を使用できる。
lexical-binding
を有効にすること、まだ有効にされていない既存のEmacs
Lispコードではlexical-binding
を有効にするよう変換することを推奨する。レキシカルバインディングの使用を参照のこと。
provide
呼出を配置すること。名前つき機能を参照のこと。
require
を使用すること。名前つき機能を参照のこと。
(eval-when-compile (require 'bar))
これはfooのバイトコンパイル直前にbarをロードするようEmacsに告げるので、そのマクロはコンパイル中は利用可能になる。eval-when-compile
の使用によりコンパイル済みバージョンのfooが中古ならbarのロードを避けられる。これはファイル内の最初のマクロ呼び出しの前に呼び出すこと。マクロとバイトコンパイルを参照のこと。
require
してこれを行うこと。しかしあなたのファイルがいくつかの独立した機能を含み、それらの1つか2つだけが余分なライブラリーを要するなら、トップレベルではなく関連する関数内部へのrequire
の配置を考慮すること。または必要時に余分のライブラリーをロードするためにautoload
ステートメントを使用すること。この方法ではあなたのファイルの該当部分を使用しない人は、余分なライブラリーをロードする必要がなくなる。
cl
ライブラリーではなく、cl-lib
ライブラリーを使うこと。cl
ライブラリーは非推奨でありEmacsの将来バージョンでは削除されるだろう。
framep
やframe-live-p
。変数が述語関数でないなら、この-p
サフィックスの使用を避けるよう推奨する。かわりに-flag
サフィックスやis-foo
のような名前を使用すること。
unload-feature
を使用することで、通常は機能のロードにより行われる(フックへの関数追加のような)変更がアンドゥされる。しかしfeatureのロードが何か特殊で複雑なことを行う場合には、feature-unload-function
という名前の関数を定義して、そのような特別な変更をアンドゥさせることができる。この関数が存在する場合には、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と同様にデバッグの障害になる。
path
を使うことを避けて、かわりにfile
、file-name
、directory
を優先して使用すること。なぜならGNUコーディング規約では検索パス(ディレクトリー名のリスト)だけにpathという用語を用いることになっており、Emacsはそれを遵守するからである。
[ << ] | [ < ] | [ 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
を使用しないこと。
たとえdebug-on-error
がnil
であっても、ユーザーにエラーの発生元を伝えることが有用な場合もある。そのような場合には、エラーメッセージに小文字のLispシンボルを前置できる。たとえばエラーメッセージ“Invalid
input”を“some-function: Invalid input”となるように拡張できる。
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
を追加できる(requireを参照):
(require 'foo)
何らかののファイルのマクロだけが必要ならコンパイル時だけ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.
これらのドキュメント文字列をEmacsが表示する際には、文字の表示がサポートされていれば通常は‘`’ (グレイブアクセント)に‘‘’ (左シングルクォーテーションマーク)、‘'’ (アポストロフィー)に‘’’ (右シングルクォーテーションマーク)を表示することに注意。ドキュメント内でのキーバインディングの置き換えを参照のこと。 (このセクションの以前のバージョンでは、doc文字列で非ASCIIのシングルクォーテーションマークを推奨するバージョンがありましたが、このような文字をサポートしない端末におけるヘルプ文字列の表示が破壊されるので現在は推奨されていません。)
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'.
manページにハイパーリンクを作成するには‘Man page’,‘man page’、‘man page for’のいずれかの後にシングルクォートされた名前記述する。たとえば、
See the man page `chmod(1)' for details.
manページInfoドキュメントのほうが常に好ましいので、リンク可能なInfoマニュアルがあるならリンクすること。たとえばchmod
はGNU
Coreutilsマニュアルにドキュメントされているので、manページよりそれにリンクするほうがよい。
カスタマイゼーショングループをリンクするには、‘customization group’を前置してシングルクォートしたグループ名を記述する(各単語の先頭文字のcaseは区別しない)。たとえば、
See the customization group `whitespace' for details.
最後にURLのハイパーリンクを作成するには‘URL’の後にURLをシングルクォートして記述する。たとえば、
The GNU project website has more information (see URL `https://www.gnu.org/').
forward-char
にバインドされたキーに置き換える(これは通常は‘C-f’だがユーザーがキーバインディングを変更していれば何か他の文字かもしれない)。ドキュメント内でのキーバインディングの置き換えを参照のこと。
‘\\[…]’を使用するたびに、僅かだがドキュメント文字列の表示が低速になる。これらを大量に使用すると僅かな低速化が積み重なり、特に低速なシステムでは有意なものとなるかもしれない。したがってこれらの過度な使用は推奨しない(同一ドキュメント内で同じコマンドへの複数参照の使用を避けるよう試みる等)。
dired-find-file
のドキュメントは:
In Dired, visit the file or directory named on this line.
defcustom
を使用すること。グローバル変数の定義を参照のこと。
nil
値が等価であることを明確にして、nil
と非nil
が何を意味するかを明示的に示すために“Non-nil
means”のような単語で始めること。
The argument FOO can be either a number \(a buffer position) or a string (a file name).
これは‘(’をdefunの開始として扱う27.1より古いバージョンのEmacsでのバグを回避する(Defuns in The GNU Emacs Manualを参照)。コードを古いバージョンのEmacsで編集する誰かをあなたが予期せぬのなら、この回避策は必要ない。
[ << ] | [ < ] | [ 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つのセミコロンはsectionのヘッダーとみなして、2つ以下のセミコロンで始まるものはみなさない。
(歴史的に3連セミコロンのコメントは関数内の行のコメントアウトに使用されたきたが、この用途では2つだけのセミコロン使用を推奨し、3連セミコロンの使用は推奨しない。これは2連セミコロンを使用して関数全体をコメントアウトする際にも適用される。)
セミコロン3つはトップレベルのセクション、4つはサブセクション、5つはサブサブセクション、のように使用される。
ライブラリーは通常はトップレベルのセクションを少なくとも4つもつ。たとえばこれらのセクションすべてが隠されているときは:
;;; backquote.el --- implement the ` Lisp construct... ;;; Commentary:... ;;; Code:... ;;; backquote.el ends here
(テキストが後続することがあってはならない最後の行は、ある意味セクションヘッダーではない。これは最終的にはファイル終端をマークする。)
長いライブラリーではコードを複数セクションに分割するのが賢明である。これは‘Code:’セクションを複数のサブセクションに分割することで行うことができる。長い間、これが推奨される唯一のアプローチであったとはいえ、多くの人が複数のトップレベルセクションの使用を選択してきた。あなたはいずれかのスタイルを選択できる。
トップレベルのコードセクションの複数使用には、ネスティングレベルの追加導入を避けるという利点があるが、それはすべてのコードが‘Code’という名前のセクションに含まれていないという不体裁な結果をも意味する。これを避けるためには、そのセクション内部にコードを何も配置しないこと。この方法により、それをセクションヘッダーではなくセパレーターとみなすことができる。
この問題に対象するためにヘッダーをコロンや他の句読点で終了させないことを最後に推奨しておく。歴史的な理由により‘Code:’と‘Commentary:’のヘッダーはコロンで終わるが、何にせよ他のヘッダーに同じことを行わないことをお勧めする。
一般的に言うとコマンドM-;
(comment-dwim
)は適切なタイプのコメントを自動的に開始するか、セミコロンの数に応じて既存のコメントを正しい位置にインデントします。Manipulating Comments in The GNU Emacs Manualを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsにはセクションに分割してそれの記述者のような情報を与えるために、Lispライブラリー内で特別なコメントを使用する慣習があります。それらのアイテムにたいして標準的なフォーマットを使用すれば、ツール(や人)が関連する情報を抽出するのが簡単になります。このセクションでは以下の例を出発点にこれらの慣習を説明します。
;;; foo.el --- Support for the Foo programming language -*- lexical-binding: t; -*- ;; Copyright (C) 2010-2021 Your Name
;; Author: Your Name <yourname@example.com> ;; Maintainer: Someone Else <someone@example.com> ;; Created: 14 Jul 2010
;; Keywords: languages ;; URL: https://example.com/foo ;; This file is not part of GNU Emacs. ;; This file is free software… … ;; along with this file. If not, see <https://www.gnu.org/licenses/>.
一番最初の行は以下のフォーマットをもつべきです:
;;; filename --- description -*- lexical-binding: t; -*-
この説明は1行に収まる必要があります。そのファイルで更に変数をセットするために‘-*-’指定が必要なら、lexical-binding
の後に配置してください。これにより最初の行が長くなりすぎるようなら、そのファイル終端で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内のいくつかのファイルは、そのファイルのオリジナル作者がもはや責任をもっておらずEmacsの一部として保守されていることを意味するために、Maintainerに‘emacs-devel@gnu.org’を使用している。
このオプションの行はファイルのオリジナルの作成日付を与えるもので歴史的な興味のためだけに存在する。
個々の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
はversion-to-list
でパース可能な許容し得る最小のバージョン番号(文字列)。バージョンが欠落したエントリー(単なるシンボルやある要素のサブリストであるようなエントリー)はバージョンが"0"のエントリーと等価。たとえば:
;; Package-Requires: ((gnus "1.0") (bubbles "2.7.2") cl-lib (seq))
パッケージのコードは自動的に、実行中の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 スタックに割り当てられたオブジェクト | Cスタック上の一時的なコンスと文字列。 | |
E.5 メモリー使用量 | これまでに作成されたLispオブジェクトの総サイズの情報。 | |
E.6 C方言 | Emacsを記述するC系言語は何か。 | |
E.7 Emacsプリミティブの記述 | Emacs用にCコードを記述する。 | |
E.8 動的にロードされるモジュールの記述 | Emacsにロード可能なモジュールの記述。 | |
E.9 オブジェクトの内部 | バッファー、ウィンドウ、プロセスのデータフォーマット。 | |
E.10 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ビルドの最終ステップの1つとしてコマンド‘temacs -batch -l loadup --temacs=dump-method’が実行されます。特別なオプション--temacsはtemacs
にたいして、この後に続けてEmacsを実行した際に開始がより高速になるように、標準のすべての事前ロードされるLispの関数と変数の記録方法を指示します。オプション--temacsには引数dump-methodが必要であり、以下のいずれかを指定できます:
ダンプファイル(dump
file)に事前ロードLispデータを記録する。このメソッドはEmacsの開始時にロードされることになる追加データファイルを生成する。生成されたダンプファイルは通常はemacs.pdmpと呼ばれて、Emacsのexec-directory
にインストールされる(ヘルプ関数を参照)。これはモダンなシステムにおいてセキュリティとプライバシーを強化するために使用されるさまざまなメモリーレイアウト技術を妨害する可能性のある、メモリー割り当ての特別なテクニックの使用をEmacsに要求しないので、もっとも好ましいメソッドの1つ。
‘pdump’と同様だが、以前のEmacsバイナリおよびバイトコンパイル済みLispファイル*.elcが存在しないときに、Emacsのブートストラップ(bootstrapping)の間に使用される。この場合には、生成されるダンプファイルは通常はbootstrap-emacs.pdmp。
このメソッドはすべての標準Lispファイルがすでに事前ロード済みのemacsという実行可能プログラムをtemacs
にダンプさせる(‘-batch’引数はtemacs
にその端末上のすべてのデータ初期化の試みを抑制するので、ダンプされたEmacsの端末情報テーブルは空になる)。このメソッドは実行中プロセスからプログラムファイルを生成するため、プログラムを実行(exec)してプロセスを開始することとある意味で反対なことからunexecとして知られている。このメソッドは伝統的にEmacsの状態を保存する手段だったが、今や非推奨となった。
‘dump’と同様だが、unexec
メソッドでEmacsをブートストラップする際に使用する。
インストールされるEmacsは、ダンプされたemacs実行可能形式です(pureなEmacsとも呼ばれる)。Emacsのビルドにポータブルダンパーを使用した場合には、emacs実行可能形式は実際にはtemacsの正確なコピーであり、対応機種emacs.pdmpファイルも同様にインストールされます。変数preloaded-file-list
にはダンプファイルやダンプされたEmacs実行可能形式に記録された事前ロード済みLispファイルのリストが格納されます。新たなオペレーティングシステムにEmacsをポートする際に、そのOSが何の種類のダンプも実装していなければEmacsは起動時に毎回loadup.elをロードしなければなりません。
ダンプされたemacsにはデフォルトではビルド時刻やホスト名のような詳細が記録されます。これらの詳細を抑制するためにconfigure
のオプションに--disable-build-detailsを使用すれば、同一のソースからEmacsを2回ビルドしてインストールする際に同一のEmacsのコピーが生成される可能性が高くなります。
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
を使用できます(要約: スタートアップ時のアクション順序を参照)。
この関数はpdump
メソッドを使用して、Emacsのカレント状態をダンプファイルto-fileにダンプする。ダンプファイルは通常はemacs-name.dmpと呼ばれる。ここでemacs-nameはEmacsの実行可能形式ファイル名。オプション引数track-referrersが非nil
なら、ポータブルダンパーはpdump
メソッドでは未サポートのオブジェクトタイプの出所追跡の助けとなる追加情報を維持する。
多くのプラットフォームでポータブルダンパーのコードが実行可能だとしても、それが生成するダンプファイルに可搬性はない(ダンプしたEmacs実行可能形式だけがロードできる)。
すでにダンプ済みのEmacs内でこの関数を使用する場合には‘-batch’オプションでEmacsを実行しなければならない。
ダンプ済みのEmacsに‘.el’ファイルが含まれていて、かつその‘.el’ファイルには通常はロード時に実行されるコードがある場合には、ダンプ後にEmacsを起動する際にそのコードは実行されないだろう。この問題を回避するために、after-pdump-load-hook
フックに関数を配置することができる。このフックはEmacs起動時に実行される。
この関数はunexec
メソッドを使用して、Emacsのカレント状態を実行可能ファイルto-fileにダンプする。これはfrom-file
(通常はファイルtemacs)からシンボルを取得する。
この関数をすでにダンプ済みのEmacsで使用することはできない。この関数は非推奨であり、Emacsはデフォルトではunexec
サポートなしでビルドされているので利用できない。
カレントのEmacsセッションの状態がダンプファイルからリストアされると、この関数はダンプファイルに関する情報とEmacs状態のリストアに要した時間をリターンする。値は((dumped-with-pdumper . t) (load-time . time) (dump-file-name . file))
のようなalist。ここでfileはダンプファイル名、timeはダンプファイルから状態をリストアするのに要した秒数。カレントセッションがダンプファイルからリストアされたものでなければ値はnil
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispはユーザー作成Lispオブジェクトにたいして、通常ストレージ(normal storage)と純粋ストレージ(pure storage)という2種のストレージをもちます。通常ストレージはEmacsセッションが維持される間に新たにデータが作成される場所です。純粋ストレージは事前ロードされた標準Lispファイル内の特定のデータのために使用されます。このデータは実際のEmacs使用中に決して変更されるべきではないデータです。
純粋ストレージはtemacs
が標準的な事前ローLispライブラリーのロード中にのみ割り当てられます。ファイルemacsではこのメモリースペースは読み取り専用とマークされるのでマシン上で実行中のすべてのEmacsジョブで共有できます。純粋ストレージは拡張できません。Emacsのコンパイル時に固定された量が割り当てられて、それが事前ロードされるライブラリーにたいして不足ならtemacsはそれに収まらない部分を動的メモリーに割り当てます。Emacsをpdump
メソッド(Emacsのビルドを参照)を使用してダンプする場合には純粋ストレージのオーバーフローは特に重要ではありません(単に事前ロード済みのライブラリーのいくつかが別のEmacsジョブで共有できないことを意味する)。しかしEmacsを時代遅れとなったunexec
メソッドでダンプする場合には結果イメージは動作するでしょうが、この状況ではメモリーリークとなるのでガーベージコレクション(ガーベージコレクションを参照)は無効です。そのような通常なら発生しないオーバーフローは、あなたが事前ロードライブラリの追加や標準的な事前ロードライブラリに追加を試みないかぎり発生しません。Emacsがunexec
を使用してダンプされていたら、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データ構造体にはunion
vectorlike_header
フィールドが含まれ、そのメンバーsize
にはenum
pvec_type
で列挙されたサブタイプ、その構造体が含むLisp_Object
フィールドの数に関する情報、および残りのデータのサイズが含まれます。この情報は、オブジェクトのメモリーフットプリントの計算に必要であり、ベクターブロックの繰り返し処理の際のベクター割り当てコードにより使用されます。
しばらくの間いくつかのストレージを使用して、(たとえば)バッファーのkillやあるオブジェクトを指す最後のポインターの削除によりそれを解放するのは非常に一般的です。この放棄されたストレージを再利用するためにEmacsはガーベージコレクター(garbage collector)を提供します。ガーベージコレクターは本質的には、いまだにLispプログラムからアクセス可能なすべてのLispオブジェクトを検索、マークすることにより動作します。これを開始するにはすべてのシンボル、それらの値と関連付けられている関数定義、現在スタック上にあるすべてのデータをアクセス可能であると仮定します。別のアクセス可能オブジェクトを介して間接的に到達できるすべてのオブジェクトもアクセス可能とみなされますが計算は“保守的”に行われるので、アクセス可能なオブジェクトの個数はいくらか過大に評価されるかもしれません。 accessible, but this calculation is done , so it may slightly overestimate how many objects that are accessible.
マーキングが終了してもマークされないオブジェクトはすべてガーベージ(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) (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) (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 (struct Lisp_String)
)。
使用中の文字列ヘッダーの数。
オペレーティングシステムから取得したスペースにあるがカレントで未使用の文字列ヘッダーの数。
これは利便性のために使用されるものでsizeof (char)
と同じ。
すべての文字列データの総バイト数。
長さ1のベクターのヘッダーを含めたバイトサイズ。
ベクターブロックから割り当てられたベクターブロック数。
ベクタースロットの内部的なサイズで常に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単位でのカレントで未使用のヒープスペース。
純粋スペース(純粋ストレージを参照)内にオーバーフローがあり、かつEmacsが(時代遅れとなった)unexec
メソッド(Emacsのビルドを参照)を使用してダンプされていたら、この場合は実際にガーベージコレクションを行うことは不可能なのでgarbage-collect
はnil
をリターンする。
この変数が非nil
ならEmacsはガーベージコレクションの最初と最後にメッセージを表示する。デフォルト値はnil
。
これはガーベージコレクションの終わりに実行されるノーマルフック。ガーベージコレクションはこのフックの関数の実行中は抑制されるので慎重に記述すること。
この変数の値は別のガーベージコレクションをトリガーするために、ガーベージコレクション後にLispオブジェクト用に割り当てなければならないストレージのバイト数。特定のオブジェクトタイプに関する情報を取得するために、garbage-collect
がリターンした結果を使用できる。バッファーのコンテンツに割り当てられたスペースは勘定に入らない。
threshold(しきい値)の初期値はGC_DEFAULT_THRESHOLD
であり、これはalloc.c内で定義されている。これはword_size
単位で定義されているので、デフォルトの32ビット設定では400,000、64ビット設定では800,000になる。大きい値を指定するとガーベージコレクションの頻度が下る。これはガーベージコレクションにより費やされる時間を減少させる(のでガーベージコレクションが滅多に発生しないサイクル間ではLispプログラムは高速に実行されるだろう)が、メモリーの総使用量は増大する。大量のLispデータを作成するプログラムにおいて、特に高速な実行を要する場合にはこれを行いたいと思うかもしれない。ただしわたしたちは長期間に渡るthresholdの増加は推奨しないし、満足できる速さでプログラムが実行できる以上にの値には決してセットしないことをお勧める。必要以上に大きいthresholdを用いることによってシステムレベルでメモリーが逼迫する可能性があること、更にガーベージコレクションの各サイクルにより時間を要することにもなるので避けるべきである。
GC_DEFAULT_THRESHOLD
の1/10まで下げた小さな値を指定することにより、より頻繁にガーベージコレクションを発生させることができる。この最小値より小さい値は後続のガーベージコレクションで、garbage-collect
がthresholdを最小値に戻すときまでしか効果をもたないだろう。
この変数の値はガーベージコレクション発生するまでのコンス(訳注:
これはgc-cons-threshold
やgc-cons-percentage
の‘-cons-’のことで、これらの変数が定義されているalloc.c内ではLisp方言での‘cons’をより一般化したメモリー割り当てプロセスのことを指す模様)の量をカレントヒープサイズにたいする割り合いで指定する。この条件とgc-cons-threshold
を並行して適用して、条件が両方満足されたときだけガーベージコレクションが発生する。
ヒープサイズ増加にともないガーベージコレクションの処理時間は増大する。したがってガーベージコレクションの頻度割合を減らすのが望ましいことがある。
gc-cons-threshold
と同じように必要以上に増加させず、長期間増加したままにしないこと。
gc-cons-threshold
およびgc-cons-percentage
を介した制御は単なる近似です。たとえEmacsが定期的にしきい値(threshold)の枯渇をチェックしていても、効率上の理由によりヒープ、またはgc-cons-threshold
やgc-cons-percentage
の変更のそれぞれにたいして、その後即座にガーベージコレクターをトリガーする訳ではありません。更にしきい値計算の効率化のために、Emacsはヒープ内のカレントでアクセス可能なオブジェクトを計数してヒープサイズを近似します。
garbage-collect
がリターンする値はデータ型に分類されたLispデータのメモリー使用量を記述します。それとは対照的に関数memory-limit
はEmacsがカレントで使用中の総メモリー量の情報を提供します。
この関数はEmacsがカレントで使用中の仮想メモリーの総バイト数を1024で除してリターンする。あるアクションがメモリー使用にどのよな効果を及ぼすかについて概観を得るためにこの関数を使用できる。
この変数はLispオブジェクト用のメモリーが不足に近い状態ならt
、それ以外ならnil
。
これはそのEmacsセッションで作成されたオブジェクト数をカウントしたリスト。これらのカウンターはそれぞれ特定の種類のオブジェクトを数える。詳細はドキュメント文字列を参照のこと。
この関数はシステムメモリーのトータル量とフリーな量をリターンする。サポートされないシステムでは値はnil
かもしれない。
default-directory
がリモートホスト上を指している場合には、そのホストのメモリー情報がリターンされる。
この変数はそのEmacsセッションでそれまでに行われたガーベージコレクションの合計回数。
この変数はそのEmacsセッションでガーベージコレクションの間に費やされた経過時間を浮動小数点数で表した総秒数。
Emacsがどこでメモリーを使用(種々の変数、バッファー、キャッシュ)しているかが確認できれば便利なときがあるかもしれない。このコマンドはその概要を提供する(‘"*Memory Report*"’という)バッファーを新たにオープンすることに加えて、“最大”のバッファーおよび変数をリストする。
ここでのデータは変数サイズを計算する同質的な方法が究極的に存在しないために近似値である。たとえば2つの変数がデータ構造を共有するかもしれず、その場合には2回カウントされるだろうが、このコマンドは依然として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セッションでそれまでに割り当てられた文字列の総数。
[ << ] | [ < ] | [ 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); maybe_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
の引数として使用されるようなインタラクティブ仕様(文字列)である(interactive
の使用を参照)。or
の場合は0
(nullポインター)でありor
がインタラクティブに呼び出せないことを示す。値""
はインタラクティブに呼び出し時に、関数が引数を受け取るべきではないことを示す。値が‘"(’で始まる場合には、その文字列はLispフォームとして評価される。たとえば:
DEFUN ("foo", Ffoo, Sfoo, 0, 3, "(list (read-char-by-name \"Insert character: \")\ (prefix-numeric-value current-prefix-arg)\ t)", doc: /* … */)
これはドキュメント文字列。複数行を含むために特別なことを要しないので、これにはCの文字列構文ではなくCコメント構文を使用する。‘doc:’の後のコメントはドキュメント文字列として認識される。コメントの開始と終了の区切り文字‘/*’と‘*/’はドキュメント文字列の一部にはならない。
ドキュメント文字列の最後の行がキーワード‘usage:’で始まる場合には、その行の残りの部分は引数リストをドキュメント化するためのものとして扱われる。この方法によりCコード内で使用される引数名とは異なる引数名をドキュメント文字列内で使用することができる。その関数の引数の個数に制限がなければ‘usage:’は必須。
プロットフォームにたいして1つといったように、複数の定義をもつプリミティブがいくつかある(たとえばx-create-frame
)。このような場合には各定義に同じドキュメント文字列を記述するよりも、ただ1つの定義が実際のドキュメントをもつようにしたほうがよい。他の定義はDOCファイルをパースする関数から無視される、‘SKIP’で始まるプレースホルダーをもつ。
Lispコードでのドキュメント文字列にたいするすべての通常ルール(ドキュメント文字列のヒントを参照)はCコードのドキュメント文字列にも適用される。
以下のようにドキュメント文字列の後に、そのプリミティブを実装するC関数にたいするC関数属性のリストがあるかもしれない:
DEFUN ("bar", Fbar, Sbar, 0, UNEVALLED, 0 doc: /* … */ attributes: attr1 attr2 …)
後に続けることにより複数の属性を指定できる。現在のところ以下の属性が認識される:
noreturn
決してリターンしないC関数を宣言する。これはC11のキーワード_Noreturn
、GCCの属性__attribute__ ((__noreturn__))
に対応している(Function Attributes in Using the GNU
Compiler Collectionを参照)。
const
引数以外の値を検査せず、リターン値以外に影響しない関数を宣言する。これはGCCの属性__attribute__ ((__const__))
に対応している。
noinline
これは関数がインラインとみなされることを抑止するGCCの属性__attribute__ ((__noinline__))
に対応している。これはたとえばスタックベースの変数にたいするリンク時の最適化の効果を取り消すために必要になるかもしれない。
DEFUN
マクロ呼び出しの後には、そのC関数にたいする引数リストを引数のタイプを含めて記述しなければなりません。そのプリミティブがLispで固定された最大個数をもつ引数を受け入れるなら、Lisp引数それぞれにたいして1つのC引数をもち、各引数のタイプはLisp_Object
でなければなりません(ファイルlisp.hではタイプLisp_Object
の値を作成する種々のマクロと関数が宣言されている)。プリミティブがスペシャルフォームなら、評価されないタイプLisp_Object
の単一のLisp引数を含むLispリストを受け取らなければなりません。プリミティブのLispの最大引数個数に上限がない場合には正確に2つのC引数をもたなければなりません。1つ目はLisp引数の個数、2つ目はそれらの値を含むブロックのアドレスです。これらはそれぞれptrdiff_t
、Lisp_Object *
のタイプをもちます。Lisp_Object
は任意のデータ型と任意のLispオブジェクトを保持できるので、実行時のみ実際のデータ型を判断できます。特定のタイプの引数だけを受け入れるプリミティブを記述したい場合は、適切な述語を使用してタイプを明確にチェックしなければなりません(型のための述語を参照)。
関数For
自体ではローカル変数args
はEmacsのスタックマーキングによるガーベージコレクターが制御するオブジェクトを参照します。ガーベージコレクターはたとえCのLisp_Object
スタック変数から到達可能なオブジェクトを回収しなくても、文字列コンテンツやバッファーのテキストのようなオブジェクトの何らかのコンポーネントを移動するかもしれません。したがってこれらのコンポーネントにアクセスする関数はLispの評価を行なった後に、それらのアドレスの再取得に留意しなければなりません。これはコードが文字列コンテンツやバッファーテキストにたいするCポインターを維持するかわりに、バッファーや文字列の位置を維持して、Lispの評価を行なった後にその位置からCポインターを再計算する必要があることを意味しています。Lisp評価は直接と間接を問わず、eval_sub
やFeval
の呼び出しを通じて発生する可能性があります。
ループ内部のmaybe_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
に自動的に追加されることに注意してください。
これらのマクロはすべて3つの引数を期待します:
lname
Lispプログラムが使用する変数名。
vname
Cソース内の変数名。
doc
Cコメントとしての変数用のドキュメント。詳細はドキュメントの基礎を参照のこと。
慣例として“ネイティブ”なタイプ(int
とbool
)の変数の定義時には、Cの変数名はLisp変数の-
が_
で置換されます。変数がタイプLisp_Object
をもつ際には、Cの変数名にV
も前置します。たとえば
DEFVAR_INT ("my-int-variable", my_int_variable, doc: /* An integer variable. */); DEFVAR_LISP ("my-lisp-variable", Vmy_lisp_variable, doc: /* A Lisp variable. */);
Lispではシンボルの値ではなくシンボル自身の参照を要する状況が存在します。1つは変数の値の一時的なオーバーライドであり、これはLispではlet
で行われます。これはCソースでは、specbind
を使用して対応する定数シンボルを定義することにより行われます。慣例によりQmy_lisp_variable
はVmy_lisp_variable
に対応します。これを定義するにはDEFSYM
マクロを使用します。たとえば
DEFSYM (Qmy_lisp_variable, "my-lisp-variable");
実際にバインディングを行うには:
specbind (Qmy_lisp_variable, Qt);
Lispシンボルではクォートの使用が必要な場合がありますが、Cで同様の効果を達成するためには対応する定数シンボルQmy_lisp_variable
を使用します。たとえばLispでバッファーローカル変数(バッファーローカル変数を参照)を作成する際には以下のように記述します:
(make-variable-buffer-local 'my-lisp-variable)
C側の対応するコードは、以下のようにDEFSYM
と組み合わせてFmake_variable_buffer_local
を使用します。
DEFSYM (Qmy_lisp_variable, "my-lisp-variable"); Fmake_variable_buffer_local (Qmy_lisp_variable);
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;
w = decode_live_window (window); f = XFRAME (w->frame); CHECK_CONS (coordinates); lx = Fcar (coordinates); ly = Fcdr (coordinates); CHECK_NUMBER (lx); CHECK_NUMBER (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: emacs_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
やpure
のプロパティに非nil
を与えてください(シンボルの標準的なプロパティを参照)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このセクションでがEmacsのモジュールAPI、およびEmacs用の拡張モジュール記述の一部としてそれらを使用する方法について説明します。モジュールAPIはCプログラム言語で定義されているので、このセクション内の記述と例はモジュールがCで記述されていると仮定します。別のプログラム言語ではCコード呼び出しのための適切なバインディングやインターフェースと機能の使用が必要になるでしょう。EmacsのCコードにはC99以降のコンパイラー(C方言を参照)が必要であり、このセクションもこの標準にしたがいます。
モジュールの記述とEmacsへの統合には以下のタスクが含まれます:
以下のサクセクションこれらのタスクとAPI自体の詳細を説明します。
モジュールを一度記述したら共有ライブラリーを生成するために、背景のプラットドームの慣習に応じてモジュールをコンパイルします。その後でload-path
(ライブラリー検索を参照)に言及されたディレクトリー内(Emacsが共有ライブラリーを探す場所)にそれを配置します。
EmacsダイナミックモジュールAPIにたいしてモジュールの適合性を検証したければ--module-assertionsオプションでEmacsを呼び出します。Initial Options in The GNU Emacs Manualを参照してください。
E.8.1 モジュールの初期化コード | ||
E.8.2 モジュール関数の記述 | ||
E.8.3 Lisp・モジュール間の値変換 | ||
E.8.4 その他の便利なモジュール用関数 | ||
E.8.5 モジュールでの非ローカル脱出 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ヘッダーファイルemacs-module.hのインクルードとGPL互換性シンボル(GPL compatibility symbol)によりモジュールの記述を始めましょう:
#include <emacs-module.h> int plugin_is_GPL_compatible;
Emacsインストールの一部としてシステムのインクルードツリーにemacs-module.hファイルがインストールされます。かわりにEmacsのソースツリー内で見つけることもできます。
次にモジュール用の初期化関数を記述します。
Emacsはモジュールをロードする際にこの関数を呼び出す。モジュールがemacs_module_init
という名前の関数をエクスポートしていなければモジュールはエラーをシグナルする。この初期化関数は初期化成功時には0、それ以外は非0をリターンすること。後者の場合にはEmacsはエラーをシグナルして、モジュールのロードは失敗する。初期化中にユーザーがC-gを押下すると、Emacsは初期化関数のリターン値を無視してquitする(quitを参照)(必要なら初期化関数内でユーザーのquitをcatchできる。should_quitを参照)。
引数runtimeは2つのパブリックなフィールドを含むCのstruct
へのポインター、size
はその構造体のバイトサイズ、get_environment
はEmacsの環境オブジェクトとそのインターフェースにモジュール初期化関数をアクセス可能にする関数へのポインターを提供する。
初期化関数はモジュールに必要な初期化は何であれすべて行うこと。さらに以下のタスクを行うことができる:
モジュールにコンパイルされたruntime構造体のsize
メンバーの値を比較することにより、モジュールをロードするEmacs実行可能形式がモジュールと互換性があるか検証できる。
int emacs_module_init (struct emacs_runtime *runtime) { if (runtime->size < sizeof (*runtime)) return 1; }
モジュールに渡されたruntimeオブジェクトのsizeが期待する値より小さければ、ロードしようとしているモジュールがEmacsの新しい(最近の)バージョン向けにコンパイルされていることを意味する(そのモジュールはEmacsのバイナリーとは非互換かもしれない)。
さらにモジュールは期待しているモジュールAPIの互換性も検証できる。以下の例では上述のemacs_module_init
関数の一部であることを仮定している:
emacs_env *env = runtime->get_environment (runtime); if (env->size < sizeof (*env)) return 2;
これはAPIの環境(environment)へのポインターの取得用に構造体runtime
(size
フィールドに構造体のバイトサイズも保有するCstruct
)で提供されるポインターを使用してget_environment
関数を呼び出す。
最後にEmacsから渡された環境のサイズと既知のサイズを比較することによって、以下のように古いバージョンのEmacsで動作するモジュールを記述できる:
emacs_env *env = runtime->get_environment (runtime); if (env->size >= sizeof (struct emacs_env_26)) emacs_version = 26; /* Emacs 26 or later. */ else if (env->size >= sizeof (struct emacs_env_25)) emacs_version = 25; else return 2; /* Unknown or unsupported version. */
新しいバージョンのEmacsではメンバーを環境に常に追加して削除は決して行わないので、新たなEmacsのリリースではサイズは増加するだけであることにより機能する。与えられたバージョンのEmacsにたいして、そのバージョンに存在するモジュールAPIは新しいバージョンのものと等しいので、その部分だけを使用できる。
emacs-module.hはプリプロセッサマクロEMACS_MAJOR_VERSION
を定義する。これはヘッダーがサポートするEmacsの最新バージョンとなる整数リテラルに展開される。バージョンの情報を参照のこと。EMACS_MAJOR_VERSION
はコンパイル時の定数であり、モジュールをロードしたカレントで実行中のEmacsのバージョンを表さないことに注意。emacs-module.hやEmacsの種々なバージョンにたいして互換性をもたせたければ、EMACS_MAJOR_VERSION
にもとづいた条件コンパイルを使用できる。
モジュールが処理全体を初期化関数内で行い、Lispオブジェクトにアクセスしたり環境構造体を通じてアクセス可能なEmacs関数を使用することがない場合を除いて、モジュールの互換性検証を常に行うことを推奨する。
これはLispコードが名前で呼び出せるようにモジュール関数に名前を与える。これを行う方法については以下のモジュール関数の記述で説明する。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacsモジュールを記述する主な理由は、そのモジュールをロードしたLispプログラムが追加の関数を利用できるようにするためです。このサブセクションでは、そのようなモジュール関数(module functions)の記述方法を説明します。
モジュール関数は以下のような一般的なフォームとシグネチャをもっています:
The env argument provides a pointer to the API environment,
needed to access Emacs objects and functions. The nargs argument is
the required number of arguments, which can be zero (see
make_function
below for more flexible specification of the argument
number), and args is a pointer to the array of the function
arguments. The argument data points to additional data required by
the function, which was arranged when make_function
(see below) was
called to create an Emacs function from emacs_function
.
モジュール関数はEmacsとモジュール間でLispオブジェクトをやり取りするためにタイプemacs_value
を使用する(Lisp・モジュール間の値変換を参照)。以下で説明するAPIと以降のサブセクションではCの基本データ型と、それらに対応するemacs_value
オブジェクトの慣習にたいする機能を提供する。
モジュール関数は常に値をリターンする。関数が正常にリターンすると、それに呼び出されたLispコードは関数がリターンしたemacs_value
値に対応するLispオブジェクトを目にすることになる。しかしユーザーがC-gをタイプしたり、モジュール関数やその呼び出し先がエラーをシグナルしたり非ローカルなexit
(モジュールでの非ローカル脱出を参照)を行なった場合には、Emacsはリターン値を無視してLispコードが同じ状況に遭遇した際のようにquitやthrrowを行う。
ヘッダーemacs-module.hは関数ポインターからモジュール関数へのエイリアス型としてemacs_function
型をを提供する。
モジュール関数用のCコード記述後には、そこからmake_function
を使用してLisp関数オブジェクトを作成する必要があります。make_function
関数へのポインターは環境内で提供されます(環境へのポインターはget_environment
がリターンすることを思い出してほしい)。これは通常はAPIのモジュール初期化関数(module initialization functionを参照)の内部で互換性検証後に行われます。
これはC関数funcが作成した上記emacs_function
で説明したシグネチャをもつEmacs関数をリターンする。引数min_arityとmax_arityは、funcが受け付ける引数の最大個数と最小個数を指定する。引数max_arityは特別な値emacs_variadic_function
をもつことができる。これはLispの&rest
キーワードのように、関数の受け付ける引数の個数を無制限にする(引数リストの機能を参照)。
引数dataはfuncの呼び出し時に任意の追加データを渡すための手段である。make_function
に渡されたポインターが何であれ、それは変更されずにfuncに渡される。
引数docstringはその関数用のドキュメント文字列を指定する。これはASCII文字列かUTF-8にエンコードされた非ASCII文字列、またはNULL
ポインターのいずれかであること。後者の場合には関数がドキュメントをもたないことを意味する。ドキュメント文字列はadvertised-calling-conventionを指定する行で終端できる。関数のドキュメント文字列を参照のこと。
すべてのモジュール関数は1つ目の引数として環境へのポインターを受け取らなければならないので、make_function
は任意のモジュール関数から呼び出され得るが、モジュールが一度ロードされればすべてのモジュール関数がEmacsに既知となるように、通常はこれをモジュール初期化関数で行うことを望むだろう。
最後にLispコードが関数を名前で呼び出せるようにLisp関数をシンボルにバインドする必要があります。これを行うにはモジュールAPI関数intern
(internを参照)を使用します。この関数のポインターもモジュール関数がアクセス可能な環境内で提供されています。
上述のステップを組み合わせて、モジュール初期化関数の中で以下のようにC用にアレンジしたコードmodule_func
が、Lispからmodule-func
として呼び出し可能になります:
emacs_env *env = runtime->get_environment (runtime); emacs_value func = env->make_function (env, min_arity, max_arity, module_func, docstring, data); emacs_value symbol = env->intern (env, "module-func"); emacs_value args[] = {symbol, func}; env->funcall (env, env->intern (env, "defalias"), 2, args);
env->intern
の呼び出しによりシンボルmodule-func
はEmacsが知ることとなり、それから関数をこのシンボルにバインドするためにEmacsからdefalias
を呼び出します。defalias
のかわりにfset
の使用も可能なことに注意してください。両者の違いはdefaliasに説明があります。
emacs_module_init
関数(module initialization functionを参照)を含むモジュール関数は、直接間接を問わずEmacsから呼び出されていれば、何らかの生きたemacs_env
ポインターによる環境関数呼び出しにより、Emacsだけと対話する可能性があります。言い換えると、モジュール関数によるLisp関数やEmacsプリミティブを呼び出し、emacs_value
とCデータタイプ(Lisp・モジュール間の値変換を参照)の間の変換、あるいは別の方法によるEmacsとの対話を行いたい場合には、Emacsからのemacs_module_init
やモジュール関数への呼び出しのいくつかがコールスタック上になければなりません。モジュール関数はガーベージコレクションの間はEmacsと対話しないかもしれません。ガーベージコレクションを参照してください。モジュール関数はEmacsが作成したLispインタープリタースレッド(メインスレッドを含む)とだけ対話するかもしれません。スレッドを参照してください。コマンドラインオプション--module-assertionsは、上記の要件にたいする違反のいくつかを検知できます。Initial
Options in The GNU Emacs Manualを参照してください。
モジュールAPIの使用により、より複雑な関数やデータ型(インライン関数、マクロ等)の定義が可能になります。ただしCの結果コードは扱いにくく、可読性も低下します。したがって関数やデータ構造を作成するモジュールコードを可能なかぎり最小限に留めるとともに、残りの部分をモジュールに付属するLispパッケージに付託することを推奨します。なぜならこれらの追加タスクをLispで行うのはより用意であり、より可読性の高いコードが生成されるでしょう。たとえば上記のようにモジュール関数module-func
が定義されていれば、以下のようなシンプルなLispラッパーによってマクロmodule-macro
を作成するのも1つの方法です:
(defmacro module-macro (&rest args) "Documentation string for the macro." (module-func args))
モジュールに同梱されるLispパッケージは、Emacsにパッケージがロードされる際にload
プリミティブ(Emacsのダイナミックモジュールを参照)を使用してモジュールをロードできます。
デフォルトではmake_function
により作成したモジュール関数は非インタラクティブです。これらをインタラクティブにするために、以下の関数を使用できます。
このEmacs
28以降で利用可能になった関数はインタラクティブ仕様specを使用して、関数functionをインタラクティブにする。Emacsはspecをinteractive
フォームの引数のように解釈する。interactive
の使用とinteractive
にたいするコード文字を参照のこと。functionはmake_function
がリターンするEmacsモジュール関数であること。
モジュール関数のインタラクティブ仕様を取得するためのネイティブなモジュールサポートは存在しないことに注意。これを行うためにはinteractive-form
を使用する。interactive
の使用を参照のこと。一度make_interactive
を使用してモジュール関数をインタラクティブにした後に、非インタラクティブにすることはできない。
モジュール関数オブジェクト(例:
make_function
がリターンしたオブジェクト)がガーベージコレクトされた際に何らかのコードを実行したい場合には、関数ファイナライザー(function
finalizer)をインストールできます。関数ファイナライザーはEmacs
28以降で利用できます。たとえばmake_function
のdata引数にヒープ割り当てした構造体を渡した場合には、構造体の割り当て解放にファイナライザーを使用できます。(libc)Basic
Allocationと(libc)Freeing after
Mallocを参照してください。ファイナライザー関数は以下のsignatureをもちます:
void finalizer (void *data)
ここでdataはmake_function
呼び出し時にdataに渡された値です。ファイナライザーがEmacsと相互作用する手段は何もないことに注意してください。
make_function
呼びの直後には、新たに作成された関数はファイナライザーをもちません。ファイナライザーを望む場合には、ファイナライザーを追加するためにset_function_finalizer
を使用します。
ヘッダーemacs-module.hはEmacsファイナライザー関数にたいするエイリアスタイプとしてタイプemacs_finalizer
を提供する。
このEmacs
28以降で利用可能になった関数は、argにより示されるモジュール関数に関連付けられた関数ファイナライザーをリターンする。argはモジュール関数、すなわちmake_function
がリターンするオブジェクトを参照しなければならない。その関数に関連付けられたファイナライザーがなければ、NULL
をリターンする。
このEmacs
28以降で利用可能になった関数は、argで示されるモジュール関数に関連付けられる関数ファイナライザーにfinをセットする。argはモジュール関数、すなわちmake_function
がリターンするオブジェクトを参照しなければならない。finにはargの関数ファイナライザーをクリアーするNULL
、あるいはargにより示されるオブジェクトのガーベージコレクト時に呼び出される関数へのポインターを指定できる。関数ごとに最大で1つの関数ファイナライザーをセットできる。argがすでにファイナライザーを所有する場合にはfinで置き換えられる。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
非常に少数の例外を除くほとんどのモジュールでは、モジュールを呼び出すLispプログラムとの間でモジュール関数への引数やリターン値の受け渡しでデータのやり取りが必要になります。この目的にたいしてモジュールAPIはemacs_value
タイプを提供しています。これはAPIを通じたやり取りにおいてEmacsのLispオブジェクトを表現するタイプであり、EmacsのCプリミティブ(Emacsプリミティブの記述を参照)で使用されるLisp_Object
タイプと機能的には等価です。このセクションではLispの基本データ型に対応するemacs_value
オブジェクトの作成を可能とするモジュールAPIの部分と、Lispオブジェクトに対応するemacs_value
オブジェクト内のCデータへのアクセス方法について説明します。
以下で説明するすべての関数は、実際にはすべてのモジュール関数が受け取る環境へのポインターを介して提供される関数ポインター(function pointers)です。したがってモジュールのコードでは以下のように環境ポインターを通じてこれらの関数を呼び出す必要があります:
emacs_env *env; /* the environment pointer */ env->some_function (arguments…);
emacs_env
ポインターは通常はモジュール関数の1つ目の引数、モジュール初期化関数内で環境が必要な場合にはget_environment
の呼び出しから取得できます。
以下で説明するもののほとんどはEmacs 25で利用可能になった関数であり、Emacs 25はダイナミックモジュールを最初にサポートした最初のEmacsリリースです。それ以降のリリースで利用可能になったいくつかの関数につていは、それらをサポートする最初のEmacsバージョンを付記します。
以下のAPI関数はemacs_value
オブジェクトから種々のCデータ型を抽出します。これらすべては引数のemacs_value
オブジェクトがその関数の期待するタイプでなければ、エラーコンディションwrong-type-argument
をraiseします(型のための述語を参照)。Emacsモジュール内でエラーをシグナルする方法、およびEmacsにエラーが報告される前にモジュール内部でエラーコンディションをcatchする方法の詳細はモジュールでの非ローカル脱出を参照してください。emacs_value
のタイプ取得にはAPI関数type_of
を使用できます(type_ofを参照)。
この関数はargで指定されたLisp整数の値をリターンする。リターン値のCデータ型intmax_t
はCコンパイラーがサポートする最大の整数型であり、一般的にはlong long
。argの値がintmax_t
に収まらなければ、関数はエラーシンボルoverflow-error
を使用してエラーをシグナルする。
このEmacs
27から利用可能になった関数は、argの整数値を抽出する。argの値は整数(fixnumかbignum)でなければならない。signがNULL
以外なら、argの符号(-1、0、+1)を*sign
に格納する。マグニチュード(magnitude:
大きさ)は次のようにmagnitudeに格納される。countとmagnitudeがいずれも非NULL
なら、magnitudeは少なくとも*count
unsigned
long
要素の配列を指さなければならない。magnitudeがargのマグニチュードを保持するのに十分大きければ、この関数はmagnitude配列にリトルエンディアン形式でマグニチュードを書き込み、配列の要素数を*count
に格納してtrue
をリターンする。magnitudeの大きさが十分でなければ、必要な配列サイズを*count
に格納,エラーをシグナルしてfalse
をリターンする。countが非NULL
かつmagnitudeがNULL
なら、必要となる配列サイズを*count
に格納してtrue
をリターンする。
Emacsは*count
に要求される最大値がmin (PTRDIFF_MAX, SIZE_MAX) / sizeof
(emacs_limb_t)
を超えないことを保証するので、magnitude
配列の割り当てではサイズ計算で整数のオーバーフローを心配せずにmalloc
(*count * sizeof *magnitude)
を使用できる。
これは大きい整数向け変換関数のマグニチュード配列の要素タイプとして使用される符号なし整数タイプ。このタイプは一意なオブジェクト表現をもつ(パディングビットがない)ことが保証されている。
これはemacs_limb_t
にたいして可能な最大値を指定する定数式に展開されるマクロ。この式は#if
内での利用に適する。
この関数はargで指定されたLisp浮動小数の値をCのdouble
値としてリターンする。
このEmacs 27から利用可能になった関数はargをEmacs Lispのtime値として解釈して、それに対応するstruct
timespec
をリターンする。時刻を参照のこと。struct
timespec
はナノ秒の精度のタイムスタンプを表す。以下のメンバーをもつ:
time_t tv_sec
整数秒。
long tv_nsec
ナノ秒としての小数秒数。extract_time
がリターンするタイムスタンプでは常に非負かつ十億未満(tv_nsec
のタイプがlong
であることをPOSIXがが要求しているとしても、非標準的なプラットフォームではlong
long
である)。
(libc)Elapsed Timeを参照のこと。
timeがナノ秒より高い精度をもつ場合には、この関数はナノ秒の精度へ負の無限大方向に切り詰める。struct
timespec
が(ナノ秒に切り詰めた)timeを表現できなければ、この関数はエラーをシグナルする。たとえばtime_t
が32ビット整数タイプなら100億秒というtime値はエラーをシグナルするが、600ピコ秒のtime値は0に切り詰められるだろう。
struct
timespec
で表現できないtime値を処理する必要があったり、より高い精度が必要ならLisp関数encode-time
を呼び出してリターン値を処理すればよい。時刻の変換を参照のこと。
これはargで指定されたLisp文字列をUTF-8にエンコードしたテキストをbufが指すchar
配列に格納する。bufは少なくとも終端のnullバイトを含む*len
バイトを保持するために十分なスペースをもつこと。引数lenはNULL
ポインターであってはならない。この関数の呼び出し時にはbufのバイトサイズを指定する値を指していること。
*len
で指定されたバッファーサイズが文字列のテキストを保持するために十分大きければ、関数は終端のnullバイト含む実際にコピーされる*len
バイトをbufにコピーしてtrue
をリターンする。バッファーが小さすぎる場合には、関数はエラーコンディションargs-out-of-range
をraiseするとともに、必要なバイト数を*len
に格納してfalse
をリターンする。保留中のエラーコンディションのハンドル方法はモジュールでの非ローカル脱出を参照のこと。
引数bufはNULL
ポインターでもよく、この場合には関数はargのコンテンツの格納に必要なバイト数を*len
に格納してtrue
をリターンする。これは特定の文字列を格納するために必要なbufサイズを決定する手段となり得る。1回目はbufをNULL
でcopy_string_contents
を呼び出して、関数により*len
に格納されたバイト数の保持に十分なメモリーを割り当ててから、実際にテキストのコピーを行うために非NULL
のbufで関数を再び呼び出す。
この関数はvectorのindexの要素をリターンする。ベクターの最初の要素のindexは0。indexの値が無効ならこの関数はエラーコンディションargs-out-of-range
をraiseする。関数のリターン値からCデータを抽出するためには、ベクターの当該要素に格納されたLispデータタイプに応じて、ここで説明している他の抽出関数を使用すればよい。
この関数はvector内の要素数をリターンする。
この関数はvectorのインデックスindexの要素にvalueを格納する。indexの値が無効ならこの関数はエラーコンディションargs-out-of-range
をraiseする。
以下はCの基本データ型からemacs_value
オブジェクトを作成するAPI関数です。これらはすべて作成したemacs_value
オブジェクトをリターンします。
この関数は引数n
(整数)を受け取り対応するemacs_value
オブジェクトをリターンする。nの値がmost-negative-fixnum
とmost-positive-fixnum
の内外いずれであるかに応じてfixnumかbignumのいずれかをリターンする(整数の基礎を参照)。nの値をEmacs整数で表現できない、すなわちmost-negative-fixnum
とmost-positive-fixnum
の範囲外(整数の基礎を参照)ならエラーコンディションoverflow-error
をraiseする。
このEmacs
27から利用可能になった関数は任意のサイズの整数の引数を受け取り、それに対応するemacs_value
オブジェクトをリターンする。sign引数はリターン値の符号を与える。signが0以外なら、magnitudeはリターン値のマグニチュードをリトルエンディアンで指定する、少なくともcount個の要素数の配列を指さなければならない。
以下は与えられた整数の次の確率的素数を計算するためにGNU Multiprecision Library
(GMP)を使用する例です。GMPの概要は(gmp)Top、magnitude
とGMPのmpz_t
値との間の変換方法については(gmp)Integer
Import and Exportを参照してください。
#include <emacs-module.h> int plugin_is_GPL_compatible; #include <assert.h> #include <limits.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <gmp.h> static void memory_full (emacs_env *env) { static const char message[] = "Memory exhausted"; emacs_value data = env->make_string (env, message, strlen (message)); env->non_local_exit_signal (env, env->intern (env, "error"), env->funcall (env, env->intern (env, "list"), 1, &data)); } enum { order = -1, endian = 0, nails = 0, limb_size = sizeof (emacs_limb_t), max_nlimbs = ((SIZE_MAX < PTRDIFF_MAX ? SIZE_MAX : PTRDIFF_MAX) / limb_size) }; static bool extract_big_integer (emacs_env *env, emacs_value arg, mpz_t result) { ptrdiff_t nlimbs; bool ok = env->extract_big_integer (env, arg, NULL, &nlimbs, NULL); if (!ok) return false; assert (0 < nlimbs && nlimbs <= max_nlimbs); emacs_limb_t *magnitude = malloc (nlimbs * limb_size); if (magnitude == NULL) { memory_full (env); return false; } int sign; ok = env->extract_big_integer (env, arg, &sign, &nlimbs, magnitude); assert (ok); mpz_import (result, nlimbs, order, limb_size, endian, nails, magnitude); free (magnitude); if (sign < 0) mpz_neg (result, result); return true; } static emacs_value make_big_integer (emacs_env *env, const mpz_t value) { size_t nbits = mpz_sizeinbase (value, 2); int bitsperlimb = CHAR_BIT * limb_size - nails; size_t nlimbs = nbits / bitsperlimb + (nbits % bitsperlimb != 0); emacs_limb_t *magnitude = nlimbs <= max_nlimbs ? malloc (nlimbs * limb_size) : NULL; if (magnitude == NULL) { memory_full (env); return NULL; } size_t written; mpz_export (magnitude, &written, order, limb_size, endian, nails, value); assert (written == nlimbs); assert (nlimbs <= PTRDIFF_MAX); emacs_value result = env->make_big_integer (env, mpz_sgn (value), nlimbs, magnitude); free (magnitude); return result; } static emacs_value next_prime (emacs_env *env, ptrdiff_t nargs, emacs_value *args, void *data) { assert (nargs == 1); mpz_t p; mpz_init (p); extract_big_integer (env, args[0], p); mpz_nextprime (p, p); emacs_value result = make_big_integer (env, p); mpz_clear (p); return result; } int emacs_module_init (struct emacs_runtime *runtime) { emacs_env *env = runtime->get_environment (runtime); emacs_value symbol = env->intern (env, "next-prime"); emacs_value func = env->make_function (env, 1, 1, next_prime, NULL, NULL); emacs_value args[] = {symbol, func}; env->funcall (env, env->intern (env, "defalias"), 2, args); return 0; }
この関数はdouble
の引数dを受け取り対応するEmacs浮動小数点値をリターンする。
このEmacs 27から利用可能になった関数はstruct
timespec
の引数timeを受け取り、(ticks
.
hz)
というペアーとしてそれに対応するEmacsタイムスタンプをリターンする。リターン値は正確にtimeと同一のタイムスタンプを表す。つまりすべての入力値は表現可能であり、精度を失うことは決してない。time.tv_sec
およびtime.tv_nsec
は任意の値をとり得る。特にtimeが正規化されている必要はない。これはtime.tv_nsec
が負、あるいは999,999,999より大きくなり得ることを意味する。
この関数はstrが指す、終端のnullバイトを含まないバイト長がlenであるようなCテキスト文字列からEmacs文字列を作成する。strの元文字列はASCII文字列かUTF-8にエンコードされた非ASCII文字列が可能であり、文字列には埋め込みのnullバイトを含むことができ、str[len]
にあるnullバイトで終端される必要はない。lenが負、またはEmacs文字列の最大長を超過する場合には、この関数はエラーコンディションoverflow-error
をraiseする。lenが0ならstrはNULL
でもよいが、そうでなければ有効なメモリーを指していなければならない。非0のlenでは、make_string
は一意でmutableな文字列オブジェクトをリターンする。
この関数はmake_string
と似ているがC文字列のバイト値にたいする制限がなく、Emacsにユニバイト形式でバイナリーデータを渡すために使用できる。
このAPIはたとえばcons
とlist
によるリスト作成(コンスセルおよびリストの構築を参照)、car
とcdr
によるリストメンバーの抽出(リスト要素へのアクセスを参照)、vector
によるベクター作成(ベクターのための関数を参照)等のようなLispデータ構造を操作する関数は提供しません。これらにたいしてはたいおう
するLisp関数を呼び出すために、次のサブセクションで説明するintern
とfuncall
を使用します。
emacs_value
オブジェクトのライフタイムはかなり短いのが普通です。このライフタイムはオブジェクトの作成に使用されたemacs_env
ポインターがスコープ外になると終了します。emacs_value
が望む間は行き続けるようなグローバル参照(global
references)を作成を要する場合もあるかもしれません。そのようなオブジェクトの管理には以下の2つの関数を使用します。
この関数はvalueのグローバル参照をリターンする。
この関数は以前にmake_global_ref
で作成したglobal_valueを解放する。global_valueはこの呼び出し後は無効になる。モジュールのコードではmake_global_ref
と対応するfree_global_ref
の呼び出しそれぞれをペアーとすること。
後でモジュール関数に渡す必要があるCデータ構造体を追跡するための代替え手段はユーザーポインター(user
pointer)オブジェクトの作成です。ユーザーポインター(またはuser-ptr
)はCポインターをカプセル化したLispオブジェクトであり、関連付けられたファイナライザー(オブジェクトがガーベージコレクトされる際に呼び出される。ガーベージコレクションを参照)をもつことができます。モジュールAPIはuser-ptr
オブジェクトの作成やアクセスを行う関数を提供します。これらの関数はuser-ptr
オブジェクトを表現しないemacs_value
で呼び出されるとエラーコンディションwrong-type-argument
をraiseします。
この関数はCポインターptrをラップしたuser-ptr
オブジェクトを作成してリターンする。ファイナライザー関数finはNULL
(ファイナライザーなし)、または以下のシグネチャをもつ関数のいずれか:
typedef void (*emacs_finalizer) (void *ptr);
finがNULL
ポインターでなければ、user-ptr
オブジェクトがガーベージコレクトされる際にptrを引数として呼び出される。Emacsの応答性を維持するためにGCは短時間で終了しなければならないので、ファイナライザーでは高価なコードの実行は行ってはならない。
この関数はargで表されるLispオブジェクトからCポインターを抽出する。
この関数はargで表されるuser-ptr
オブジェクトに埋め込まれたCポインターにptrをセットする。
この関数はargで表されるuser-ptr
オブジェクトのファイナライザー、ファイナライザーがなければNULL
をリターンする。
この関数はargで表されるuser-ptr
オブジェクトのファイナライザーをfinに変更する。finがNULL
ならuser-ptr
オブジェクトのファイナライザーはなくなる。
emacs_finalizer
タイプはユーザーポインターと関数ファイナライザーの両方にたいして機能することに注意してください。Module Function Finalizersを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このサブセクションではモジュールAPIが提供する便利な関数をいくつか説明します。前のサブセクションで説明した関数と同じようにこれらの関数は実際には関数ポインターであり、emacs_env
ポインターを介して呼び出す必要があります。Emacs
25以降に導入された関数の説明はそれらが利用可能になった最初のバージョンを付記します。
この関数はaとbが表すLispオブジェクトが等しければtrue
、それ以外ならfalse
をリターンする。これはLisp関数eq
(同等性のための述語を参照)と同じだが、引数が表すオブジェクトのinternの要否を無視する。
等価性に関する他の述語はAPI関数には存在しないので、より複雑な等価性のテストを行うためには、以下で説明するintern
とfuncall
を使う必要がある。
このえ関数はargで表されるLispオブジェクトをテストして非nil
ならtrue
、それ以外はfalse
をリターンする。
等価性をテストするたにintern
を使ってnil
を表すemacs_value
を取得して、上述のeq
を使用すれば自身で等価性テストを実装できることに注意。しかしこの関数を使用するほうが簡便だろう。
arg
) ¶この関数はシンボルを表す値(文字列はstring
、整数はinteger
、プロセスならprocess
等)としてargのタイプをリターンする。型のための述語を参照のこと。オブジェクトのタイプにコードが依存する必要があれば、既知のタイプシンボルと比較するためにintern
とeq
を使用できる。
この関数は名前がname (null終端されたASCII文字列であること)であるような、internされたEmacsシンボルをリターンする。すでに存在していなれば新たにシンボルを作成する。
この関数は以下で説明するfuncall
と共に用いることにより、Lispで呼び出し可能なEmcas関数(名前が純粋なASCII文字列である場合にかぎる)純粋なASCII文字列であるようなを呼び出す手段を提供する。たとえば以下はより協力なEmacsのintern
関数(シンボルの作成とinternを参照)を呼び出すことにより、名前name_str
が非ASCIIであるようなシンボルをinternする方法:
emacs_value fintern = env->intern (env, "intern"); emacs_value sym_name = env->make_string (env, name_str, strlen (name_str)); emacs_value symbol = env->funcall (env, fintern, 1, &sym_name);
この関数はargsが指す配列のnargs個の引数を渡してfuncの指定先を呼び出す。引数funcは(上述のintern
がリターンした)関数シンボル、make_function
がリターンしたモジュール関数(モジュール関数の記述を参照)、Cで記述されたサブルーチン等。nargsが0ならargsはNULL
ポインターでもよい。
この関数はfuncがリターンした値をリターンする。
モジュールに長時間実行される可能性のあるコードが含まれる場合には、たとえばC-gをタイプする(quitを参照)等によりユーザーがquitを望むかどうかをコード内でときどきチェックするのはよいアイデアです。Emacs 26.1から利用可能になった以下の関数は、この目的のために提供されました。
この関数はユーザーがquitを望むようならtrue
をリターンする。この場合にはモジュール関数は実行中の処理をabortして可能なかぎり速やかにリターンすることを推奨する。ほとんどの場合はprocess_input
を使用すること。
ユーザーがquitを望むかどうかをチェックすることに加えて入力イベントを処理するには、Emacs 27.1以降で利用可能になった以下の関数を使用してください。
この関数は保留中の入力イベントを処理する。ユーザーがquitを望んでいたり、シグナル処理中にエラーが発生したらemacs_process_input_quit
をリターンする。この場合にはモジュール関数は行っているすべての処理をabortして可能なかぎり即座にリターンすることを推奨する。モジュールコードが実行を継続できるなら、process_input
はemacs_process_input_continue
をリターンする。env
内に保留中の非ローカルexitが存在しない場合のみ、リターン値はemacs_process_input_continue
。process_input
呼び出し後にモジュールが継続する場合には、変数値やバッファーコンテンツのとうなグローバル状態は任意の手段で変更され得る。
このEmacs
28以降で利用可能になった関数は、既存のpipeプロセスへのチャンネルをオープンする。pipe_processはmake-pipe-process
が作成した既存のpipeプロセスを参照しなければならない。Pipe Processesを参照のこと。成功すると、そのpipeへの書き込みに使用できる新たなファイルデスクリプターを値としてリターンする。他のすべてのモジュール関数と異なり、アクティブなモジュール環境がなくても、任意のスレッドがリターンしたファイルデスクリプターを使用できる。このファイルデスクリプターへの書き込みにはwrite
関数を使用できる。使用後にはclose
を使用してファイルデスクリプターをクローズする。(libc)Low-Level
I/Oを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispは非ローカル脱出(nonlocal
exits)をサポートしており、これによりプログラムの制御はプログラムのあるポイントから別の離れたポイントに転送されます。非ローカル脱出を参照してください。したがってモジュールから呼び出されたLisp関数はsignal
やthrow
を呼び出して非ローカルにexitするかもしれず、そのような非ローカル脱出をモジュール関数は正しくハンドルしなければなりません。このようなハンドリングはCプログラムがリソースを自動的に解放せず、このような場合には別のクリーンアップを行うために必要になります。モジュールコードは自身でこれを行わなければなりません。そのための機能をモジュールAPIは提供しており、このサブセクションではそれを説明します。これらは一般的にはEmacs
25以降で利用可能です。これ以降のリリースで利用可能になったものについては、APIに含まれるようになった最初のEmacsのバージョンを付記します。
モジュール関数から呼び出されたLispコードがエラーをシグナルしたりthrowを行う際には、非ローカル脱出はtrapされて保留中のexitと関連するデータは環境内に格納されます。環境内で非ローカル脱出が保留中の際には、環境へのポインターで呼び出されたすべてのモジュールAPI関数は何も処理を行わずに即座にリターンします(関数non_local_exit_check
、non_local_exit_get
、non_local_exit_clear
はこのルールの例外)。モジュール関数が何も行わずにEmacsにリターンすれば、保留中の非ローカル脱出にたいしてEmacsがエラーをシグナルしたり、対応するcatch
へのthrowという対処を行うでしょう。
したがって特別なことな何も行わずに、何事もなかったかのようにコードの残りを実行するのが、モジュール関数での非ローカル脱出にけるもっともシンプルな“ハンドリング”です。しかしこれは2つのクラスの問題を引き起こすかもしれません:
したがってモジュール関数は以下に説明する関数を使用して、非ローカル脱出のコンディションのチェックとリカバリングを行うことを推奨します。
この関数はenvに格納された非ローカル脱出のコンディションをリターンする。可能な値は:
この関数はnon_local_exit_check
が行うようにenvに格納された非ローカル脱出の種別をリターンするが、もしあれば非ローカル脱出に関する完全な情報もリターンする。リターン値がemacs_funcall_exit_signal
なら関数は*symbol
にエラーシンボル、*data
にエラーデータを格納する(エラーをシグナルする方法を参照)。リターン値がemacs_funcall_exit_throw
なら関数は*symbol
にcatch
されたたタグシンボル、*data
にthrow
された値を格納する。リターン値がemacs_funcall_exit_return
なら関数はこれらの引数が指すメンモリー内に何も格納しない。
何らかのリソースの割り当て前や解放を要するリソースの割り当て後、あるいは失敗がそれ以上の処理が不可能もしくは実行不能を意味するような場合のように、非ローカル脱出が問題になるようならチェックするべきです。
モジュール関数が保留中の非ローカル脱出を一度検知すれば、(必要なローカルクリーンアップの実施後に)Emacsにリターンしたり、非ローカル脱出からのリカバリーを試みることができます。以下のAPI関数はこれらのタスクの助けとなるでしょう。
この関数は保留中の非ローカル脱出のコンディションとenv由来のデータをクリアーする。これの呼び出し後にはモジュールAPI関数は通常どおり機能するだろう。モジュール関数が呼び出したLisp関数の非ローカル脱出からリカバーして継続可能な場合、あるいは以下の2つの関数のいずれか(非ローカル脱出が保留中の際に他のAPI関数に意図した動作を行わせたい場合にはそれらのAPI関数も)を呼び出す前にもこの関数を使用すること
この関数はtagで表されるLispのcatch
シンボルにリターン値としてvalueを渡してthrowを行う。モジュール関数は一般的にはこの関数の呼び出し後は即座にリターンすること。この関数は呼び出されたAPI関数やLisp関数のいずれかから非ローカル脱出を再throwしたい際の1つの手段である。
この関数はエラーシンボルsymbolで表されるエラーを、指定したエラーデータdataとともにシグナルする。モジュール関数はこの関数の呼び出し後は即座にリターンすること。この関数はたとえばモジュール関数からEmacsにエラーをシグナルする際に有用かもしれない。
[ << ] | [ < ] | [ 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.
これらのタイプは内部的タイプシステムのファーストクラスの市民です。タグスペースは限られているので他のすべてのタイプはLisp_Vectorlike
のサブクラスです。サブタイプのベクターはenum
pvec_type
により列挙されておりウィンドウ、バッファー、フレーム、プロセスのようなほとんどすべての複雑なオブジェクトはこのカテゴリーに分類されます。
Lisp_Vectorlike
のいくつかのサブタイプを説明します。バッファーオブジェクトは表示や編集を行うテキストを表します。ウィンドウはバッファーを表示したり、同一フレーム上で再帰的に他のウィンドウを配置するためのコンテナーとして使用される表示構造の一部です(Emacs
Lispのウィンドウオブジェクトと、のようなユーザーインターフェースシステムに管理されるエンティティとしてのウィンドウを混同しないこと。Emacsの用語では後者はフレームと呼ばれる)。最後にプロセスオブジェクトはサブプロセスの管理に使用されます。
E.9.1 バッファーの内部 | バッファー構造体の構成子。 | |
E.9.2 ウィンドウの内部 | ウィンドウ構造体の構成子。 | |
E.9.3 プロセスの内部 | プロセス構造体の構成子。 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Cでバッファーを表すために2つの構造体(buffer.hを参照)が使用されます。buffer_text
構造体にはバッファーのテキストを記述するフィールドが含まれます。buffer
構造体は他のフィールドを保持します。インダイレクトバッファーの場合には、2つ以上のbuffer
構造体が同じbuffer_text
構造体を参照します。
以下にstruct buffer_text
内のフィールドをいくつか示します:
beg
バッファーコンテンツのアドレス。バッファーコンテンツは途中にギャップをもつchar
の線形C配列。
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
タイプunion 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
このフラグはバッファーの表示において再表示最適化が使用されるべきではないことを示す。
inhibit_buffer_hooks
このフラグはそのバッファーではフックkill-buffer-hook
、kill-buffer-query-functions
(バッファーのkillを参照)、buffer-list-update-hook
(バッファーリストを参照)が実行されないことを示す。このフラグはバッファー作成時にセットされて(バッファーの作成を参照)、内部バッファーやwith-temp-buffer
(Current Buffer)が作成するバッファーの速度低下を防ぐ。
name
バッファーを命名するLisp文字列。一意であることが保証されている。バッファーの名前を参照のこと。このフィールドと以降のフィールドは以下のようにBVAR
を介するアクセス以外の方法で直接アクセスするべきではないことを示すためにC構造体定義内の名前の最後に_
をもつ:
Lisp_Object buf_name = BVAR (buffer, name);
save_length
そのバッファーがvisitしているファイルを最後に読み込み、または保存したときの長さ。2つの特別な値をもつことができる。-1はそのバッファーで自動保存がオフであること、-2はバッファーのテキストが大量に減少するようなら自動保存をオフに切り替えないことを意味する。インダイレクトバッファーは決して保存されることはないので、保存に関して、このフィールドとその他のフィールドは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
の値を格納する。
overlays
そのバッファーのオーバーレイを含んだインターバルツリー(interval tree: 区間木)。
last_selected_window
これは最後に選択されていたときにそのバッファーを表示していたウィンドウ、またはそのウィンドウがすでにそのバッファーを表示していなければnil
。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウのフィールドには以下が含まれます(完全なリストはwindow.hのstruct window
を参照):
frame
そのウィンドウがあるフレーム(Lispオブジェクト)。
mini
そのウィンドウがミニバッファーウィンドウ、ミニバッファーかエコーエリアを表示しているウィンドウなら非0。
pseudo_window_p
¶そのウィンドウが疑似ウィンドウ(pseudo window)なら非0。疑似ウィンドウとはメニューバーかツールバーの表示に使用されているウィンドウ(自身のメニューバーやツールバーを表示しないツールキットをEmacsが使用している場合)、タブバー、またはツールチップフレーム上でツールチップを表示しているウィンドウのいずれか。一般的には疑似ウィンドウはLispコードからアクセスできない。
parent
Emacsは内部的にウィンドウをツリーにアレンジする。ウィンドウの兄弟グループは、そのエリアがすべての兄弟を含むような親ウィンドウをもつ。このフィールドはツリー内でのウィンドウの親をLispオブジェクトとして指す。これはツリーのルートウィンドウとミニバッファーウィンドウでは常にnil
。
親ウィンドウはバッファーを表示せず、子ウィンドウ形成を除いて表示では少ししか役割を果たさない。Emacs Lispプログラムは親ウィンドウを直接操作できない。Emacs Lispプログラムでは実際にバッファーを表示するツリーの子ノードのウィンドウにたいして操作を行う。
contents
リーフウィンドウ(leaf
window)およびツールチップを表示中のウィンドウでは、そのウィンドウが表示しているLispオブジェクトとしてのバッファー、内部ウィンドウ(“親”ウィンドウ)では最初の子ウィンドウ、メニューバーやツールバーを表示している疑似ウィンドウではnil
、削除されたウィンドウでもnil
。
next
prev
そのウィンドウの次の兄弟と前の兄弟(Lispオブジェクト)。自身のグループ内でそのウィンドウが右端か下端ならnext
はnil
。自身のグループ内でそのウィンドウが左端か上端ならprev
はnil
。兄弟が左右あるいは上下であるかは兄弟の親のhorizontal
フィールドで判断される。これが非0なら兄弟は水平に配置されている。
特別なケースとしてミニバッファーのみのフレームやミニバッファーなしのフレームでなければ、フレームのルートウィンドウのnext
は、そのフレームのミニバッファーウィンドウを指す。そのようなフレームのミニバッファーウィンドウのprev
は、そのフレームのルートウィンドウを指す。それ以外の場合にはルートウィンドウのnext
フィールド、および(もしあれば)ミニバッファーのprev
フィールドはnil
。
left_col
そのウィンドウの左端をウィンドウのネイティブフレームの最左列(列0)から相対的に数えた列数。
top_line
そのウィンドウの上端をウィンドウのネイティブフレームの最上行(行0)から相対的に数えた行数。
pixel_left
pixel_top
そのウィンドウの左側上端をウィンドウのネイティブフレームの左上隅(0, 0)から相対的に計測したピクセル数。
total_cols
total_lines
列数または行数で数えた、そのウィンドウの幅または高さの合計。値にはスクロールバーとフリンジ、ディバイダー、および/または(もしあれば)ウィンドウ右側のセパレーターラインが含まれる。
pixel_width;
pixel_height;
ピクセルで計測したウィンドウの幅または高さの合計。
start
そのウィンドウ内に表示されるバッファーで、ウィンドウに最初(ロジカル順。双方向テキストの表示を参照)に表示される文字の位置を指すマーカー。
pointm
¶これはウィンドウが選択されているときのカレントバッファーのポイント値。選択されていなければ前の値が保たれる。
old_pointm
最後の再表示時のpointm
の値。
force_start
このフラグが非nil
ならLispプログラムによりそのウィンドウが明示的にスクロールされたことを示し、再表示のためにウィンドウのstart
の値がセットされる。これはポイントがスクリーン外の場合の次回再表示に影響を与える。影響とはポイント周辺のテキストを表示するためにウィンドウをスクロールするかわりに、スクリーン上にある位置にポイントを移動するというものである。
optional_new_start
これはforce_start
と同様だが、次回表示ではポイントが可視の場合のみしたがう。
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
非0値はウィンドウが最後に更新されたとき、そのウィンドウのバッファーが変更されたことを意味する。
vertical_scroll_bar_type
horizontal_scroll_bar_type
そのウィンドウの垂直スクロールバーおよび水平スクロールバーのタイプ。
scroll_bar_width
scroll_bar_height
そのウィンドウの垂直スクロールバーの幅および水平スクロールバーの高さ(ピクセル単位)。
left_margin_cols
right_margin_cols
そのウィンドウの左マージンと右マージンの幅。値0はマージンがないことを意味する。
left_fringe_width
right_fringe_width
そのウィンドウの左フリンジと右フリンジのピクセル幅。値-1はフレームの値の使用を意味する。
fringes_outside_margins
非0値はディスプレイマージン外側のフリンジ、それ以外ならフリンジはマージンとテキストの間にあることを意味する。
window_end_pos
これはz
から、そのウィンドウのカレントマトリクス内の最後のグリフのバッファー位置を減じて算出される。この値はwindow_end_valid
が非0のときだけ有効である。
window_end_bytepos
window_end_pos
に対応するバイト位置。
window_end_vpos
window_end_pos
を含む行のウィンドウに相対的な垂直位置。
window_end_valid
このフィールドはwindow_end_pos
およびwindow_end_vpos
が真に有効なら非0値にセットされる。これは重要な再表示が先に割り込んだ場合には、window_end_pos
を算出した表示がスクリーン上に出現しなくなるので0になる。
cursor
そのウィンドウ内でカーソルがどこにあるかを記述する構造体。
last_cursor_vpos
最後の再表示完了時にカーソルを表示していた行の、ウィンドウに相対的な垂直位置。
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。カレント行だけが水平スクロールされている際には、カレント行がどれだけ左へ水平スクロールされているかを示す。
min_hscroll
set-window-hscroll
を通じてユーザーがセットするhscroll
の最小値(水平スクロールを参照)。カレント行だけが水平スクロールされている際には、カレント行以外の行がどれだけ左へ水平スクロールされているかを示す。
vscroll
ピクセル単位での垂直スクロール量。これは通常は0。
dedicated
そのウィンドウがそれのバッファー専用(dedicated)なら非nil
。
combination_limit
このウィンドウの組み合わせ限界は親ウィンドウにとってのみ意味がある。これがt
ならそのウィンドウの削除は許されず、そのウィンドウの他の兄弟と子ウィンドウを再組み合わせする。
window_parameters
そのウィンドウのパラメーターのalist。
display_table
そのウィンドウのディスプレイテーブル、何も指定されていなければnil
。
update_mode_line
非0はウィンドウのモードラインの更新が必要なことを意味する。
mode_line_height
header_line_height
モードラインおよびヘッダーラインのピクセル高さ、不明なら-1。
base_line_number
そのバッファーの特定の位置の行番号か0。これはモードラインでポイントの行番号を表示するために使用される。
base_line_pos
行番号が既知であるバッファー位置、不明なら0。これが-1なら、そのウィンドウがバッファーを表示するかぎり行番号は表示されない。
column_number_displayed
そのウィンドウのモードラインに表示されているカレント列番号、列番号が表示されていなければ-1。
current_matrix
desired_matrix
そのウィンドウのカレント、および望まれる表示を記述するグリフ。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プロセスのフィールドには以下が含まれます(完全なリストはprocess.hのstruct
Lisp_Process
の定義を参照):
name
プロセス名(Lisp文字列)。
command
そのプロセスの開始に使用されたコマンド引数を含むリスト。ネットワークプロセスとシリアルプロセスではプロセスが実行中ならnil
、停止していたらt
。
filter
そのプロセスから出力を受け取るために使用されるLisp関数。
sentinel
そのプロセスの状態が変化したら常に呼び出されるLisp関数。
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
がリターンするようなプロセス状態。Lispシンボル、コンスセル、またはリストのいずれか。
tick
update_tick
これら2つのフィールドが等しくないなら、センチネル実行かプロセスバッファーへのメッセージ挿入によりプロセスの状態変更が報告される必要がある。
pty_flag
そのサブプロセスがptyを使用して対話する場合は非0。パイプを使用する場合には0。
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
を優先すること。しかしページ境界を横切る可能性のあるポインター演算を表す場合にはuintptr_t
を優先すること。たとえば32ビットのアドレス空間をもつマシンでの配列は0x7fffffff/0x80000000境界を横断する可能性があり、(intptr_t)
0x7fffffff
に1を加算することによって整数のオーバーフローが発生し得る。
EMACS_INT
にもとづくのでEmacsで定義されたタイプEMACS_INT
を優先すること。
off_t
やtime_t
等の)システムタイプを優先すること。安全だと解っていなければシステムタイプが符号付きだと仮定してはならない。たとえばoff_t
は常に符号付きだがtime_t
は符号付きである必要はない。
intmax_t
を優先すること。printf
族の関数は"%"PRIdMAX
のようなフォーマットを使用してこのような値をプリントできる。
bool
、false
、true
を使用すること。bool
の使用によりプログラムの可読性が増して、int
を使用するより若干高速になる。int
、0
、1
を使用しても大丈夫だが旧スタイルは段階的に廃止される。bool
を使用する際には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
とminibuffer-quit
は、quitはエラーはみなさないという理由から、コンディションerror
をもっていません。
これらのエラーシンボルのほとんどはC(主にdata.c)で定義されていますが、いくつかはLispで定義されています。たとえばファイルuserlock.elではfile-locked
とfile-supersession
のエラーが定義されています。Emacsとともに配布される専門的なLispライブラリーのいくつかは、それら自身のエラーシンボルを定義しています。それらのすべてをここではリストしません。
エラーの発生とそれを処理する方法についてはエラーを参照してください。
error
メッセージは‘error’。エラーを参照のこと。
quit
メッセージは‘Quit’。quitを参照のこと。
minibuffer-quit
メッセージは‘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 シンボル関数インダイレクションを参照のこと。
cyclic-variable-indirection
メッセージは‘Symbol's chain of variable indirections contains a loop’。See 変数のエイリアスを参照のこと。
dbus-error
メッセージは‘D-Bus error’。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
のサブカテゴリー。ファイルへの書き込みを参照のこと。
permission-denied
これはこれは何らかの理由により、EmacsによるファイルやディレクトリーへのアクセスをOSが拒否する際に発生するfile-error
のサブカテゴリー。
file-date-error
これはfile-error
のサブカテゴリー。これはcopy-file
を試行して出力ファイルの最終変更時刻のセットに失敗したときに発生する。ファイルの名前と属性の変更を参照のこと。
file-error
このエラーメッセージは、通常はエラーコンディションfile-error
が与えられたときはデータアイテムだけから構築されるので、エラー文字列とサブカテゴリーはここにリストしない。つまりエラー文字列は特に関連しない。しかしこれらのエラーシンボルはerror-message
プロパティをもち、何もデータが与えられなければerror-message
が使用される。ファイルを参照のこと。
file-missing
これはfile-error
のサブカテゴリー。これは存在しないファイルの処理を試みた際に発生する。ファイルの名前と属性の変更を参照のこと。
compression-error
これは圧縮ファイルの処理の問題を起因とするfile-error
のサブカテゴリー。プログラムがロードを行う方法を参照のこと。
file-locked
これはfile-error
のサブカテゴリー。ファイルのロックを参照のこと。
file-supersession
これはfile-error
のサブカテゴリー。バッファーの変更時刻を参照のこと。
file-notify-error
これはfile-error
のサブカテゴリー。ファイル変更による通知を参照のこと。
remote-file-error
これはリモートファイルへのアクセスにおける問題の結果であり、file-error
のサブカテゴリー。Remote Files in The GNU Emacs
Manualを参照のこと。このエラーは一般的にリモートファイルへのアクセス試行と別のリモートファイル操作の衝突によりタイマー、プロセスフィルター、プロセスセンチネル、スペシャルイベントにおいて頻出する。一般的にはバグレポートの記述するのが良いアイデアである。Bugs in The GNU Emacs Manualを参照のこと。
ftp-error
これはftpを使用したリモートファイルへのアクセスの問題を起因とするremote-file-error
のサブカテゴリー。Remote
Files in The GNU Emacs Manualを参照のこと。
invalid-function
メッセージは‘Invalid function’。シンボル関数インダイレクションを参照のこと。
invalid-read-syntax
メッセージは通常は‘Invalid read syntax’。プリント表現と読み取り構文を参照のこと。このエラーは後の式が続くようなテキストがある際の、eval-expression
のようなコマンドでもraiseされ得る。この場合にはメッセージは‘Trailing
garbage following expression’。
invalid-regexp
メッセージは‘Invalid regexp’。正規表現を参照のこと。
mark-inactive
メッセージは‘The mark is not active now’。マークを参照のこと。
no-catch
メッセージは‘No catch for tag’。明示的な非ローカル脱出: catch
とthrow
を参照のこと。
range-error
メッセージはArithmetic range error
。
overflow-error
メッセージは‘Arithmetic overflow
error’。これはrange-error
のサブカテゴリー。これはリミットinteger-width
を超過する整数で発生し得る。整数の基礎を参照のこと。
scan-error
メッセージは‘Scan error’。これは特定の構文解析関数が無効な構文やマッチしないカッコを見つけたときに発生する。慣習的に人間が可読なエラーメッセージ、移動を妨害する開始位置、妨害の終了位置という3つの引数でraiseされる。釣り合いのとれたカッコを越えた移動と式のパースを参照のこと。
search-failed
メッセージは‘Search failed’。検索とマッチングを参照のこと。
setting-constant
メッセージは‘Attempt to set a constant
symbol’。これはnil
、t
、most-positive-fixnum
、most-negative-fixnum
およびキーワードシンボルへの値の割り当て時に発生する。これはenable-multibyte-characters
や何らかの理由により値の直接割り当てが許されていないインボルへの値の割り当て時にも発生する。変更不可な変数を参照のこと。
text-read-only
メッセージは‘Text is
read-only’。これはbuffer-read-only
のサブカテゴリー。特殊な意味をもつプロパティを参照のこと。
undefined-color
メッセージは‘Undefined color’。カラー名を参照のこと。
user-error
メッセージは空文字列。エラーをシグナルする方法を参照のこと。
user-search-failed
これは‘search-failed’と似ているが、‘user-error’のようにデバッガーをトリガーしない。エラーをシグナルする方法と検索とマッチングを参照のこと。これはInfoファイル内での検索に使用される。Search Text in Infoを参照のこと。
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’。型のための述語を参照のこと。
unknown-image-type
メッセージは‘Cannot determine image type’. See イメージ。
inhibited-interaction
メッセージは‘User interaction while
inhibited’。このエラーはinhibit-interaction
が非nil
の場合に(
read-from-minibuffer
のような)ユーザー対話関数が呼び出されるとシグナルされる。
[ << ] | [ < ] | [ 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)コマンドにたいする完全なキーマップ。
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-edit-menu
menu-bar-options-menu
global-buffers-menu-map
menu-bar-tools-menu
menu-bar-help-menu
これらのキーマップはメニューバー内のメインとなるトップレベルメニューを表示する。
これらのいくつかはサブメニューを含む。たとえばEditメニューはmenu-bar-search-menu
を含む等。メニューバーを参照のこと。
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
)内で有益なのでこの名前が選ばれた。
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モードにより使用されるキーマップ。
基本的なメジャーモードを参照のこと。
tab-prefix-map
タブバー関連コマンド用のプレフィックスキーC-x tにたいして使用されるグローバルキーマップ。
Tab Bars in The GNU Emacs Manualを参照のこと。
tab-bar-map
タブバーのコンテンツを定義するキーマップ。
Tab Bars in The GNU Emacs Manualを参照のこと。
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
server-after-make-frame-hook
フレームの作成を参照のこと。
after-save-hook
before-save-hook
write-contents-functions
write-file-functions
バッファーの保存を参照のこと。
after-setting-font-hook
¶フレームのフォント変更後に実行されるフック。
auto-save-hook
See 自動保存を参照のこと。
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
バッファーローカルなバインディングの作成と削除を参照のこと。
comint-password-function
これは派生モードにたいして、ユーザーにプロンプト表示せずに、背後にあるコマンドインタープリター用にパスワードを供給することを許可するアブノーマルフック。
command-line-functions
コマンドライン引数を参照のこと。
delayed-warnings-hook
¶コマンドループはpost-command-hook
(以下参照)の直後にこれを実行する。
focus-in-hook
¶focus-out-hook
入力のフォーカスを参照のこと。
delete-frame-functions
after-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を参照のこと。
quit-window-hook
ウィンドウのquitを参照のこと。
kill-buffer-hook
kill-buffer-query-functions
バッファーのkillを参照のこと。
kill-emacs-hook
kill-emacs-query-functions
Emacsのkillを参照のこと。
menu-bar-update-hook
メニューバーを参照のこと。
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
ウィンドウのスクロールと変更のためのフックを参照のこと。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Jump to: | "
#
$
%
&
'
(
)
*
+
,
-
.
/
0
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: | "
#
$
%
&
'
(
)
*
+
,
-
.
/
0
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)に使用される‘#^^’を目にすることがあるかもしれません。
これはCommon LispやCのような言語が定数にたいして指定する挙動であり、プログラムによるimmutableオブジェクト変更の試みにエラーのシグナルを要求するJavaScriptやPythonのようなインタープリターとは異なる。理想的にはEmacs Lispインタープリターは後者を目指して進化するであろう。
照合ルールとlocaleにたいする依存関係についての詳細はThe Unicode Collation Algorithmを参照のこと。GNU Cライブラリー(glibcとも呼ばれる)のような一部の標準CライブラリーはUCA(Unicode Collation Algorithm: Unicode照合アルゴリズム)の大部分を実装しており、関連のあるlocaleデータやCLDR(Common Locale Data Repository: 共通ロケールデータレポジトリ)を使用する。
これは真リスト(true list)と呼ばれることもありますが、このマニュアルでは一般的にこの用語を使用しません。
リストの最後に要素を追加するための、これと完全に同等な方法はありません。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という名前を使用します。
lexical-binding
を用いたコードでのみ機能します。
これはカリー化(currying)と関連しますが異なる機能です。カーリングは複数の引数を受け取る関数を、関数チェーンとして呼び出せるような1つの引数を取る個々の関数に変換するような方法です。
funcが受け取ることができる引数の個数に制限がない場合には、新たな関数が受け取ることができる引数の個数も無制限になるので、このようなケースではapply-partially
は新たな関数が受け取ることができる引数の個数を減らしません。
ビルトイン関数とは異なり、このバージョンでは任意個数の引数を許容することに注意してください。
いくつかの要素は実際に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
を使用できます。
EmacsはGNUの慣習に則りパス名(pathname)ではなくファイル名(file name)という用語を使用する。わたしたちがパス(path)という用語を用いるのは検索パス(ディレクトリーのリスト)にたいしてだけである。
PGTKのフレームではfullheight
やfullwidth
の値をセットしても効果はない。
Haikuで子フレームが可視なのは親フレームがアクティブなときだけであり、これはHaikuウィンドウシステムの制限によるものです。同じ制限により子フレームはトップレベルの親、すなわち階層上一番上位にある親をもたないフレームの上でのみ表示が保証されています。
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モードを参照)にたいして何も行いません。
MS-Windowsではw32-use-native-image-API
が非nil
にセットされている必要があります。
タイポグラフィではemはタイプの高さに相当する距離のこと。たとえば12ポイントタイプの1emは12ポイントと同じ。これの使用により距離とタイプの比率が保たれる。
Common Lispスタイルのパッケージシステムの恩恵はコストを上回るとは考えられない。
わたしたちは時折これを使用しますが、やりすぎないでください。
[Top] | [Contents] | [Index] | [ ? ] |
display
プロパティ
[Top] | [Contents] | [Index] | [ ? ] |
[Top] | [Contents] | [Index] | [ ? ] |
This document was generated on October 20, 2023 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 October 20, 2023 using texi2any.