Emacs Lisp 1 イントロダクション 2 Lispのデータ型 3 数値 4 文字列と文字 5 リスト 6 シーケンス、配列、ベクター 7 ハッシュテーブル 8 シンボル 9 評価 10 制御構造 11 変数 12 関数 13 マクロ 14 カスタマイゼーション設定 15 ロード 16 バイトコンパイル 17 Lispプログラムのデバッグ 18 Lispオブジェクトの読み取りとプリント 19 ミニバッファー 20 コマンドループ 21 キーマップ 22 メジャーモードとマイナーモード 23 ドキュメント 24 ファイル 25 バックアップと自動保存 26 バッファー 27 ウィンドウ 28 フレーム 29 ポジション 30 マーカー 31 テキスト 32 非ASCII文字 33 検索とマッチング 34 構文テーブル 35 abbrevとabbrev展開 36 プロセス 37 Emacsのディスプレー表示 38 オペレーティングシステムのインターフェース 39 配布用 Lispコードの準備 Appendix A Emacs 24 Antinews Appendix B GNU Free Documentation License Appendix C GNU General Public License Appendix D ヒントと規約 Appendix E GNU Emacsの内部 Appendix F 標準的なエラー Appendix G 標準的なキーマップ Appendix H 標準的なフック Index Emacs Lisp 1 イントロダクション 1.1 注意事項 1.2 Lispの歴史 1.3 表記について 1.3.1 用語について 1.3.2 ‘nil’と‘t’ 1.3.3 評価の表記 1.3.4 プリントの表記 1.3.5 エラーメッセージ 1.3.6 バッファーテキストの表記 1.3.7 説明のフォーマット 1.3.7.1 関数の説明例 1.3.7.2 変数の説明例 1.4 バージョンの情報 1.5 謝辞 2 Lispのデータ型 2.1 プリント表現と読み取り構文 2.2 コメント 2.3 プログラミングの型 2.3.1 整数型 2.3.2 浮動小数点数型 2.3.3 文字型 2.3.3.1 基本的な文字構文 2.3.3.2 一般的なエスケープ構文 2.3.3.3 コントロール文字構文 2.3.3.4 メタ文字構文 2.3.3.5 その他の文字修飾ビット 2.3.4 シンボル型 2.3.5 シーケンス型 2.3.6 コンスセルとリスト型 2.3.6.1 ボックスダイアグラムとしてのリストの描写 2.3.6.2 ドットペア表記 2.3.6.3 連想リスト型 2.3.7 配列型 2.3.8 文字列型 2.3.8.1 文字列の構文 2.3.8.2 文字列内の非ASCII文字 2.3.8.3 文字列内の非プリント文字 2.3.8.4 文字列内のテキストプロパティ 2.3.9 ベクター型 2.3.10 文字テーブル型 2.3.11 ブールベクター型 2.3.12 ハッシュテーブル型 2.3.13 関数型 2.3.14 マクロ型 2.3.15 プリミティブ関数型 2.3.16 バイトコード関数型 2.3.17 autoload型 2.3.18 Finalizer Type 2.4 編集用の型 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 ストリーム型 2.4.10 キーマップ型 2.4.11 オーバーレイ型 2.4.12 フォント型 2.5 循環オブジェクトの読み取り構文 2.6 型のための述語 2.7 同等性のための述語 3 数値 3.1 整数の基礎 3.2 浮動小数点数の基礎 3.3 数値のための述語 3.4 数値の比較 3.5 数値の変換 3.6 算術演算 3.7 丸め処理 3.8 ビット演算 on Integers 3.9 標準的な数学関数 3.10 乱数 4 文字列と文字 4.1 文字列と文字の基礎 4.2 文字列のための述語 4.3 文字列の作成 4.4 文字列の変更 4.5 文字および文字列の比較 4.6 文字および文字列の変換 4.7 文字列のフォーマット 4.8 Lispでの大文字小文字変換 4.9 caseテーブル 5 リスト 5.1 リストとコンスセル 5.2 リストのための述語 5.3 リスト要素へのアクセス 5.4 コンスセルおよびリストの構築 5.5 リスト変数の変更 5.6 既存のリスト構造の変更 5.6.1 ‘setcar’によるリスト要素の変更 5.6.2 リストのCDRの変更 5.6.3 リストを再配置する関数 5.7 集合としてのリストの使用 5.8 連想リスト 5.9 プロパティリスト 5.9.1 プロパティリストと連想リスト 5.9.2 プロパティリストと外部シンボル 6 シーケンス、配列、ベクター 6.1 シーケンス 6.2 配列 6.3 配列を操作する関数 6.4 ベクター 6.5 ベクターのための関数 6.6 文字テーブル 6.7 ブールベクター 6.8 オブジェクト用固定長リングの管理 7 ハッシュテーブル 7.1 ハッシュテーブルの作成 7.2 ハッシュテーブルへのアクセス 7.3 ハッシュの比較の定義 7.4 ハッシュテーブルのためのその他関数 8 シンボル 8.1 シンボルの構成要素 8.2 シンボルの定義 8.3 シンボルの作成とintern 8.4 シンボルのプロパティ 8.4.1 シンボルのプロパティへのアクセス 8.4.2 シンボルの標準的なプロパティ 9 評価 9.1 評価の概要 9.2 フォームの種類 9.2.1 自己評価を行うフォーム 9.2.2 シンボルのフォーム 9.2.3 リストフォームの分類 9.2.4 シンボル関数インダイレクション 9.2.5 関数フォームの評価 9.2.6 Lispマクロの評価 9.2.7 スペシャルフォーム 9.2.8 自動ロード 9.3 クォート 9.4 バッククォート 9.5 eval 10 制御構造 10.1 順序 10.2 条件 10.2.1 パターンマッチングによるcase文 10.3 条件の組み合わせ 10.4 繰り返し 10.5 Generators 10.6 非ローカル脱出 10.6.1 明示的な非ローカル脱出: ‘catch’と‘throw’ 10.6.2 ‘catch’と‘thrown’の例 10.6.3 エラー 10.6.3.1 エラーをシグナルする方法 10.6.3.2 Emacsがエラーを処理する方法 10.6.3.3 エラーを処理するコードの記述 10.6.3.4 エラーシンボルとエラー条件 10.6.4 非ローカル脱出のクリーンアップ 11 変数 11.1 グローバル変数 11.2 Variables that Never Change 11.3 ローカル変数 11.4 変数がvoidのとき 11.5 グローバル変数の定義 11.6 堅牢な変数定義のためのヒント 11.7 変数の値へのアクセス 11.8 変数の値のセット 11.9 変数のバインディングのスコーピングルール 11.9.1 ダイナミックバインディング 11.9.2 ダイナミックバインディングの正しい使用 11.9.3 レキシカルバインディング 11.9.4 レキシカルバインディングの使用 11.10 バッファーローカル変数 11.10.1 バッファーローカル変数の概要 11.10.2 バッファーローカルなバインディングの作成と削除 11.10.3 バッファーローカル変数のデフォルト値 11.11 ファイルローカル変数 11.12 ディレクトリーローカル変数 11.13 変数のエイリアス 11.14 値を制限された変数 11.15 ジェネリック変数 11.15.1 ‘setf’マクロ 11.15.2 新たな‘setf’フォーム 12 関数 12.1 関数とは? 12.2 ラムダ式 12.2.1 ラムダ式の構成要素 12.2.2 単純なラムダ式の例 12.2.3 引数リストのその他機能 12.2.4 関数のドキュメント文字列 12.3 関数の命名 12.4 関数の定義 12.5 関数の呼び出し 12.6 関数のマッピング 12.7 無名関数 12.8 Generic Functions 12.9 関数セルの内容へのアクセス 12.10 クロージャー 12.11 Emacs Lisp関数にたいするアドバイス 12.11.1 アドバイスを操作するためのプリミティブ 12.11.2 名前つき関数にたいするアドバイス 12.11.3 アドバイスの構築方法 12.11.4 古いdefadviceを使用するコードの改良 12.12 関数を陳腐と宣言する 12.13 インライン関数Inline Functions 12.14 ‘declare’フォーム 12.15 コンパイラーへの定義済み関数の指示 12.16 安全に関数を呼び出せるかどうかの判断 12.17 関数に関するその他トピック 13 マクロ 13.1 単純なマクロの例 13.2 マクロ呼び出しの展開 13.3 マクロとバイトコンパイル 13.4 マクロの定義 13.5 マクロ使用に関する一般的な問題 13.5.1 タイミング間違い 13.5.2 マクロ引数の多重評価 13.5.3 マクロ展開でのローカル変数 13.5.4 展開におけるマクロ引数の評価 13.5.5 マクロが展開される回数は? 13.6 マクロのインデント 14 カスタマイゼーション設定 14.1 一般的なキーワードアイテム 14.2 カスタマイゼーショングループの定義 14.3 カスタマイゼーション変数の定義 14.4 カスタマイゼーション型 14.4.1 単純型 14.4.2 複合型 14.4.3 リストへのスプライス 14.4.4 型キーワード 14.4.5 新たな型の定義 14.5 カスタマイゼーションの適用 14.6 Customテーマ 15 ロード 15.1 プログラムがロードを行う方法 15.2 ロードでの拡張子 15.3 ライブラリー検索 15.4 非ASCII文字のロード 15.5 autoload 15.6 多重ロード 15.7 名前つき機能 15.8 どのファイルで特定のシンボルが定義されているか 15.9 アンロード 15.10 ロードのためのフック 15.11 Emacs Dynamic Modules 16 バイトコンパイル 16.1 バイトコンパイル済みコードのパフォーマンス 16.2 バイトコンパイル関数 16.3 ドキュメント文字列とコンパイル 16.4 個別関数のダイナミックロード 16.5 コンパイル中の評価 16.6 コンパイラーのエラー 16.7 バイトコード関数オブジェクト 16.8 逆アセンブルされたバイトコード 17 Lispプログラムのデバッグ 17.1 Lispデバッガ 17.1.1 エラーによるデバッガへのエンター 17.1.2 無限ループのデバッグ 17.1.3 関数呼び出しによるデバッガへのエンター 17.1.4 明示的なデバッガへのエントリー 17.1.5 デバッガの使用 17.1.6 デバッガのコマンド 17.1.7 デバッガの呼び出し 17.1.8 デバッガの内部 17.2 Edebug 17.2.1 Edebugの使用 17.2.2 Edebugのためのインストルメント 17.2.3 Edebugの実行モード 17.2.4 ジャンプ 17.2.5 その他のEdebugコマンド 17.2.6 ブレーク 17.2.6.1 Edebugのブレークポイント 17.2.6.2 グローバルなブレーク条件 17.2.6.3 ソースブレークポイント 17.2.7 エラーのトラップ 17.2.8 Edebugのビュー 17.2.9 評価 17.2.10 評価 List Buffer 17.2.11 Edebugでのプリント 17.2.12 トレースバッファー 17.2.13 カバレッジテスト 17.2.14 コンテキスト外部 17.2.14.1 停止するかどうかのチェック 17.2.14.2 Edebugの表示の更新 17.2.14.3 Edebugの再帰編集 17.2.15 Edebugとマクロ 17.2.15.1 マクロ呼び出しのインストルメント 17.2.15.2 仕様リスト 17.2.15.3 仕様でのバックトレース 17.2.15.4 仕様の例 17.2.16 Edebugのオプション 17.3 無効なLisp構文のデバッグ 17.3.1 過剰な開カッコ 17.3.2 過剰な閉カッコ 17.4 カバレッジテスト 17.5 プロファイリング 18 Lispオブジェクトの読み取りとプリント 18.1 読み取りとプリントの概念 18.2 入力ストリーム 18.3 入力関数 18.4 出力ストリーム 18.5 出力関数 18.6 出力に影響する変数 19 ミニバッファー 19.1 ミニバッファーの概念 19.2 ミニバッファーでのテキスト文字列の読み取り 19.3 ミニバッファーでのLispオブジェクトの読み取り 19.4 ミニバッファーのヒストリー 19.5 入力の初期値 19.6 補完 19.6.1 基本的な補完関数 19.6.2 補完とミニバッファー 19.6.3 補完を行うミニバッファーコマンド 19.6.4 高レベルの補完関数 19.6.5 ファイル名の読み取り 19.6.6 補完変数 19.6.7 プログラムされた補完 19.6.8 通常バッファーでの補完 19.7 Yes-or-Noによる問い合わせ 19.8 複数のY-or-Nの問い合わせ 19.9 パスワードの読み取り 19.10 ミニバッファーのコマンド 19.11 ミニバッファーのウィンドウ 19.12 ミニバッファーのコンテンツ 19.13 再帰的なミニバッファー 19.14 ミニバッファー、その他の事項 20 コマンドループ 20.1 コマンドループの概要 20.2 コマンドの定義 20.2.1 ‘interactive’の使用 20.2.2 ‘interactive’にたいするコード文字 20.2.3 ‘interactive’の使用例 20.2.4 コマンド候補からの選択 20.3 interactiveな呼び出し 20.4 interactiveな呼び出しの区別 20.5 コマンドループからの情報 20.6 コマンド後のポイントの調整 20.7 入力イベント 20.7.1 キーボードイベント 20.7.2 ファンクションキー 20.7.3 マウスイベント 20.7.4 クリックイベント 20.7.5 ドラッグイベント 20.7.6 ボタンダウンイベント 20.7.7 リピートイベント 20.7.8 モーションイベント 20.7.9 フォーカスイベント 20.7.10 その他のシステムイベント 20.7.11 イベントの例 20.7.12 イベントの分類 20.7.13 マウスイベントへのアクセス 20.7.14 スクロールバーイベントへのアクセス 20.7.15 文字列内へのキーボードイベントの配置 20.8 入力の読み取り 20.8.1 キーシーケンス入力 20.8.2 単一イベントの読み取り 20.8.3 入力イベントの変更と変換 20.8.4 入力メソッドの呼び出し 20.8.5 クォートされた文字の入力 20.8.6 その他のイベント入力の機能 20.9 スペシャルイベント 20.10 時間の経過や入力の待機 20.11 quit 20.12 プレフィクスコマンド引数 20.13 再帰編集 20.14 コマンドの無効化 20.15 コマンドのヒストリー 20.16 キーボードマクロ 21 キーマップ 21.1 キーシーケンス 21.2 キーマップの基礎 21.3 キーマップのフォーマット 21.4 キーマップの作成 21.5 継承とキーマップ 21.6 プレフィクスキー 21.7 アクティブなキーマップ 21.8 アクティブなキーマップの検索 21.9 アクティブなキーマップの制御 21.10 キーの照合 21.11 キー照合のための関数 21.12 キーバインディングの変更 21.13 コマンドのリマップ 21.14 イベントシーケンス変換のためのキーマップ 21.14.1 通常のキーマップとの対話 21.15 キーのバインドのためのコマンド 21.16 キーマップのスキャン 21.17 メニューキーアップ 21.17.1 メニューの定義 21.17.1.1 単純なメニューアイテム 21.17.1.2 拡張メニューアイテム 21.17.1.3 メニューセパレーター 21.17.1.4 メニューアイテムのエイリアス 21.17.2 メニューとマウス 21.17.3 メニューとキーボード 21.17.4 メニューの例 21.17.5 メニューバー Bar 21.17.6 ツールバー 21.17.7 メニューの変更 21.17.8 easy-menu 22 メジャーモードとマイナーモード 22.1 フック 22.1.1 フックの実行 22.1.2 フックのセットSetting Hooks 22.2 メジャーモード 22.2.1 メジャーモードの慣習 22.2.2 Emacsがメジャーモードを選択する方法 22.2.3 メジャーモードでのヘルプ入手 22.2.4 派生モードの定義 22.2.5 基本的なメジャーモード 22.2.6 モードフック 22.2.7 Tabulated Listモード 22.2.8 ジェネリックモード 22.2.9 メジャーモードの例 22.3 マイナーモード 22.3.1 マイナーモード記述の規約 22.3.2 キーマップとマイナーモード 22.3.3 マイナーモードの定義 22.4 モードラインのフォーマット 22.4.1 モードラインの基礎 22.4.2 モードラインのデータ構造 22.4.3 モードライン制御のトップレベル 22.4.4 モードラインで使用される変数 22.4.5 モードラインでの‘%’構造 22.4.6 モードラインでのプロパティ 22.4.7 ウィンドウのヘッダーライン 22.4.8 モードラインのフォーマットのエミュレート 22.5 Imenu 22.6 Font Lockモード 22.6.1 Font Lockの基礎 22.6.2 検索ベースのフォント化 22.6.3 検索ベースのフォント化のカスタマイズ 22.6.4 Font Lockのその他の変数 22.6.5 Font Lockのレベル 22.6.6 事前計算されたフォント化 22.6.7 Font Lockのためのフェイス 22.6.8 構文的なFont Lock 22.6.9 複数行のFont Lock構造 22.6.9.1 複数行のFont Lock 22.6.9.2 バッファー変更後のリージョンのフォント化 22.7 コードの自動インデント 22.7.1 SMIE: 無邪気なインデントエンジン 22.7.1.1 SMIEのセットアップと機能 22.7.1.2 演算子順位文法 22.7.1.3 言語の文法の定義 22.7.1.4 トークンの定義 22.7.1.5 非力なパーサーの使用 22.7.1.6 インデントルールの指定 22.7.1.7 インデントルールにたいするヘルパー関数 22.7.1.8 インデントルールの例 22.7.1.9 インデントのカスタマイズ 22.8 Desktop Saveモード 23 ドキュメント 23.1 ドキュメントの基礎 23.2 ドキュメント文字列へのアクセス 23.3 ドキュメント内でのキーバインディングの置き換え 23.4 ヘルプメッセージの文字記述 23.5 ヘルプ関数 24 ファイル 24.1 ファイルのvisit 24.1.1 ファイルをvisitする関数 24.1.2 visitのためのサブルーチン 24.2 バッファーの保存 24.3 ファイルの読み込み 24.4 ファイルの書き込み 24.5 ファイルのロック 24.6 ファイルの情報 24.6.1 アクセシビリティのテスト 24.6.2 ファイル種別の区別 24.6.3 本当の名前 24.6.4 ファイルの属性 24.6.5 拡張されたファイル属性 24.6.6 標準的な場所へのファイルの配置 24.7 ファイルの名前と属性の変更 24.8 ファイルの名前 24.8.1 ファイル名の構成要素 24.8.2 絶対ファイル名と相対ファイル名 24.8.3 ディレクトリーの名前 24.8.4 ファイル名を展開する関数 24.8.5 一意なファイル名の生成 24.8.6 ファイル名の補完 24.8.7 標準的なファイル名 24.9 ディレクトリーのコンテンツ 24.10 ディレクトリーの作成・コピー・削除 24.11 特定のファイル名の“Magic”の作成 24.12 ファイルのフォーマット変換 24.12.1 概要 24.12.2 ラウンドトリップ仕様 24.12.3 漸次仕様 25 バックアップと自動保存 25.1 ファイルのバックアップ 25.1.1 バックアップファイルの作成 25.1.2 リネームかコピーのどちらでバックアップするか? 25.1.3 番号つきバックアップファイルの作成と削除 25.1.4 バックアップファイルの命名 25.2 自動保存 25.3 リバート 26 バッファー 26.1 バッファーの基礎 26.2 カレントバッファー 26.3 バッファーの名前 26.4 バッファーのファイル名 26.5 バッファーの変更 26.6 バッファーの変更 Time 26.7 読み取り専用のバッファー 26.8 バッファーリスト 26.9 バッファーの作成 26.10 バッファーのkill 26.11 インダイレクトバッファー 26.12 2つのバッファー間でのテキストの交換 26.13 バッファーのギャップ 27 ウィンドウ 27.1 Emacsウィンドウの基本概念 27.2 ウィンドウとフレーム 27.3 ウィンドウのサイズ 27.4 ウィンドウのリサイズ 27.5 Preserving Window Sizes 27.6 ウィンドウの分割 27.7 ウィンドウの削除 27.8 ウィンドウの再結合 27.9 ウィンドウの選択 27.10 ウィンドウのサイクル順 27.11 バッファーとウィンドウ 27.12 ウィンドウ内のバッファーへの切り替え 27.13 表示するウィンドウの選択 27.14 ‘display-buffer’にたいするアクション関数 27.15 バッファー表示の追加オプション 27.16 ウィンドウのヒストリー 27.17 専用のウィンドウ 27.18 ウィンドウのquit 27.19 ウィンドウとポイント 27.20 ウィンドウの開始位置と終了位置 27.21 テキスト的なスクロール 27.22 割り合いによる垂直スクロール 27.23 水平スクロール 27.24 座標とウィンドウ 27.25 ウィンドウの構成 27.26 ウィンドウのパラメーター 27.27 ウィンドウのスクロールと変更のためのフック 28 フレーム 28.1 フレームの作成 28.2 複数の端末 28.3 Frame Geometry 28.3.1 Frame Layout 28.3.2 Frame Font 28.3.3 Size and Position 28.3.4 Implied Frame Resizing 28.4 フレームのパラメーター 28.4.1 フレームパラメーターへのアクセス 28.4.2 フレームの初期パラメーター 28.4.3 ウィンドウフレームパラメーター 28.4.3.1 基本パラメーター 28.4.3.2 位置のパラメーター 28.4.3.3 サイズのパラメーター 28.4.3.4 レイアウトのパラメーター 28.4.3.5 バッファーのパラメーター 28.4.3.6 ウィンドウ管理のパラメーター 28.4.3.7 カーソルのパラメーター 28.4.3.8 フォントとカラーのパラメーター 28.4.4 ジオメトリー 28.5 端末のパラメーター 28.6 フレームのタイトル 28.7 フレームの削除 28.8 すべてのフレームを探す 28.9 ミニバッファーとフレーム 28.10 入力のフォーカス 28.11 フレームの可視性 28.12 フレームを前面や背面に移動する 28.13 フレーム構成 28.14 マウスの追跡 28.15 マウスの位置 28.16 ポップアップメニュー 28.17 ダイアログボックス 28.18 ポインターの形状 28.19 ウィンドウシステムによる選択 28.20 ドラッグアンドドロップ 28.21 カラー名 28.22 テキスト端末のカラー 28.23 Xリソース 28.24 ディスプレー機能のテスト 29 ポジション 29.1 ポイント 29.2 モーション 29.2.1 文字単位の移動 29.2.2 単語単位の移動 29.2.3 バッファー終端への移動 29.2.4 テキスト行単位の移動 29.2.5 スクリーン行単位の移動 29.2.6 バランスのとれたカッコを越えた移動 29.2.7 文字のスキップ 29.3 エクスカーション 29.4 ナローイング 30 マーカー 30.1 マーカーの概要 30.2 マーカーのための述語 30.3 マーカーを作成する関数 30.4 マーカーからの情報 30.5 Marker 挿入タイプ 30.6 マーカー位置の移動 30.7 マーク 30.8 リージョン 31 テキスト 31.1 ポイント周辺のテキストを調べる 31.2 バッファーのコンテンツを調べる 31.3 テキストの比較 31.4 テキストの挿入 31.5 ユーザーレベルの挿入コマンド 31.6 テキストの削除 31.7 ユーザーレベルの削除コマンド 31.8 killリング 31.8.1 killリングの概念 31.8.2 killリングのための関数 31.8.3 yank 31.8.4 yankのための関数 31.8.5 低レベルのkillリング 31.8.6 killリングの内部 31.9 アンドゥ 31.10 アンドゥリストの保守 31.11 fill 31.12 fillのマージン 31.13 Adaptive Fillモード 31.14 オートfill 31.15 テキストのソート 31.16 列を数える 31.17 インデント 31.17.1 インデント用のプリミティブ 31.17.2 メジャーモードが制御するインデント 31.17.3 リージョン全体のインデント 31.17.4 前行に相対的なインデント 31.17.5 Adjustable Tab Stops 31.17.6 インデントにもとづくモーションコマンド 31.18 大文字小文字の変更 31.19 テキストのプロパティ 31.19.1 テキストプロパティを調べる 31.19.2 テキストプロパティの変更 31.19.3 テキストプロパティの検索関数 31.19.4 特殊な意味をもつプロパティ 31.19.5 Formatted Text Properties 31.19.6 テキストプロパティの粘着性 31.19.7 テキストプロパティのlazyな計算 31.19.8 クリック可能なテキストの定義 31.19.9 フィールドの定義と使用 31.19.10 なぜテキストプロパティはインターバルではないのか 31.20 文字コードの置き換え 31.21 レジスター 31.22 テキストの交換 31.23 圧縮されたデータの処理 31.24 Base 64エンコーディング 31.25 チェックサムとハッシュ 31.26 HTMLとXMLの解析 31.26.1 Document Object Model 31.27 グループのアトミックな変更 31.28 フックの変更 32 非ASCII文字 32.1 テキストの表現方法 32.2 マルチバイト文字の無効化 32.3 テキスト表現の変換 32.4 表現の選択 32.5 文字コード 32.6 文字のプロパティ 32.7 文字セット 32.8 文字セットのスキャン 32.9 文字の変換 32.10 コーディングシステム 32.10.1 コーディングシステムの基本概念 32.10.2 エンコーディングとI/O 32.10.3 Lispでのコーディングシステム 32.10.4 ユーザー選択のコーディングシステム 32.10.5 デフォルトのコーディングシステム 32.10.6 単一の操作にたいするコーディングシステムの指定 32.10.7 明示的なエンコードとデコード 32.10.8 端末I/Oのエンコーディング 32.11 入力メソッド 32.12 locale 33 検索とマッチング 33.1 文字列の検索 33.2 検索と大文字小文字 33.3 正規表現 33.3.1 正規表現の構文 33.3.1.1 正規表現内の特殊文字 33.3.1.2 文字クラス 33.3.1.3 正規表現内のバッククラッシュ構造 33.3.2 正規表現の複雑な例 33.3.3 正規表現の関数 33.4 正規表現の検索 33.5 POSIX正規表現の検索 33.6 マッチデータ 33.6.1 マッチしたテキストの置換 33.6.2 単純なマッチデータへのアクセス 33.6.3 マッチデータ全体へのアクセス 33.6.4 マッチデータの保存とリストア 33.7 検索と置換 33.8 編集で使用される標準的な正規表現 34 構文テーブル 34.1 構文テーブルの概念 34.2 構文記述子 34.2.1 構文クラスのテーブル 34.2.2 構文フラグ 34.3 構文テーブルの関数 34.4 構文プロパティ 34.5 モーションと構文 34.6 式のパース 34.6.1 パースにもとづくモーションコマンド 34.6.2 ある位置のパース状態を調べる 34.6.3 パーサー状態 34.6.4 低レベルのパース 34.6.5 パースを制御するためのパラメーター 34.7 構文テーブルの内部 34.8 カテゴリー 35 abbrevとabbrev展開 35.1 abbrevテーブル 35.2 abbrevの定義 35.3 ファイルへのabbrevの保存 35.4 略語の照会と展開 35.5 標準的なabbrevテーブル 35.6 abbrevプロパティー 35.7 abbrevテーブルのプロパティー 36 プロセス 36.1 サブプロセスを作成する関数 36.2 shell引数 36.3 同期プロセスの作成 36.4 非同期プロセスの作成 36.5 プロセスの削除 36.6 プロセスの情報 36.7 プロセスへの入力の送信 36.8 プロセスへのシグナルの送信 36.9 プロセスからの出力の受信 36.9.1 プロセスのバッファー 36.9.2 プロセスのフィルター関数 36.9.3 プロセス出力のデコード 36.9.4 プロセスからの出力を受け入れる 36.10 センチネル: プロセス状態の変更の検知 36.11 exit前の問い合わせ 36.12 別のプセスへのアクセス 36.13 トランザクションキュー 36.14 ネットワーク接続 36.15 ネットワークサーバー 36.16 データグラム 36.17 低レベルのネットワークアクセス 36.17.1 ‘make-network-process’ 36.17.2 ネットワークのオプション 36.17.3 ネットワーク機能の可用性のテスト 36.18 その他のネットワーク機能 36.19 シリアルポートとの対話 36.20 バイト配列のpackとunpack 36.20.1 データレイアウトの記述 36.20.2 バイトのunpackとpackのための関数 36.20.3 バイトのunpackとpackの例 37 Emacsのディスプレー表示 37.1 スクリーンのリフレッシュ 37.2 強制的な再表示 37.3 切り詰め 37.4 エコーエリア 37.4.1 エコーエリアへのメッセージの表示 37.4.2 処理の進捗レポート 37.4.3 ‘*Messages*’へのメッセージのロギング 37.4.4 エコーエリアのカスタマイズ 37.5 警告のレポート 37.5.1 警告の基礎 37.5.2 警告のための変数 37.5.3 警告のためのオプション 37.5.4 遅延された警告 37.6 不可視のテキスト 37.7 選択的な表示 37.8 一時的な表示 37.9 オーバーレイ 37.9.1 オーバーレイの管理 37.9.2 オーバーレイのプロパティ 37.9.3 オーバーレイにたいする検索 37.10 表示されるテキストのサイズ 37.11 行の高さ 37.12 フェイス 37.12.1 フェイスの属性 37.12.2 フェイスの定義 37.12.3 フェイス属性のための関数 37.12.4 フェイスの表示 37.12.5 フェイスのリマップ 37.12.6 フェイスを処理するための関数 37.12.7 フェイスの自動割り当て 37.12.8 基本的なフェイス 37.12.9 フォントの選択 37.12.10 フォントの照会 37.12.11 フォントセット 37.12.12 低レベルのフォント表現 37.13 フリンジ 37.13.1 フリンジのサイズと位置 37.13.2 フリンジのインジケーター 37.13.3 フリンジのカーソルFringe Cursors 37.13.4 フリンジのビットマップ 37.13.5 フリンジビットマップのカスタマイズ 37.13.6 オーバーレイ矢印 37.14 スクロールバー 37.15 ウィンドウディバイダー 37.16 ‘display’プロパティ 37.16.1 テキストを置換するディスプレー仕様 37.16.2 スペースの指定 37.16.3 スペースにたいするピクセル指定 37.16.4 その他のディスプレー仕様 37.16.5 マージン内への表示 37.17 イメージ 37.17.1 イメージのフォーマット 37.17.2 イメージのディスクリプタ 37.17.3 XBMイメージ 37.17.4 XPMイメージ 37.17.5 PostScriptイメージ 37.17.6 ImageMagickイメージ 37.17.7 その他のイメージタイプ 37.17.8 イメージの定義 37.17.9 イメージの表示 37.17.10 マルチフレームのイメージ 37.17.11 イメージキャッシュ 37.18 Embedded Native Widgets 37.19 ボタン 37.19.1 ボタンのプロパティ 37.19.2 ボタンのタイプ 37.19.3 ボタンの作成 37.19.4 ボタンの操作 37.19.5 ボタンのためのバッファーコマンド 37.20 抽象的なディスプレー 37.20.1 抽象ディスプレーの関数 37.20.2 抽象ディスプレーの例 37.21 カッコの点滅 37.22 文字の表示 37.22.1 通常の表示の慣習 37.22.2 ディスプレーテーブル 37.22.3 アクティブなディスプレーテーブル 37.22.4 グリフ 37.22.5 グリフ文字の表示 37.23 ビープ 37.24 ウィンドウシステム 37.25 Tooltips 37.26 双方向テキストの表示 38 オペレーティングシステムのインターフェース 38.1 Emacsのスタートアップ 38.1.1 要約: スタートアップ時のアクション順序 38.1.2 initファイル 38.1.3 端末固有の初期化 38.1.4 コマンドライン引数 38.2 Emacsからの脱出 38.2.1 Emacsのkill 38.2.2 Emacsのサスペンド 38.3 オペレーティングシステムの環境 38.4 ユーザーの識別 38.5 時刻 38.6 Time Zone Rules 38.7 時刻の変換 38.8 時刻のパースとフォーマット 38.9 プロセッサーの実行時間 38.10 時間の計算 38.11 遅延実行のためのタイマー 38.12 アイドルタイマー 38.13 端末の入力 38.13.1 入力のモード 38.13.2 入力の記録 38.14 端末の出力 38.15 サウンドの出力 38.16 X11キーシンボルの処理 38.17 batchモード 38.18 セッションマネージャー 38.19 デスクトップ通知 38.20 ファイル変更による通知 38.21 動的にロードされるライブラリー 38.22 Security Considerations 39 配布用 Lispコードの準備 39.1 パッケージ化の基礎 39.2 単純なパッケージ 39.3 複数ファイルのパッケージ 39.4 パッケージアーカイブの作成と保守 Appendix A Emacs 24 Antinews A.1 Old Lisp Features in Emacs 24 Appendix B GNU Free Documentation License Appendix C GNU General Public License Appendix D ヒントと規約 D.1 Emacs Lispコーディングの慣習 D.2 キーバインディングの慣習 D.3 Emacsプログラミングのヒント D.4 コンパイル済みコードを高速化ためのヒント D.5 コンパイラー警告を回避するためのヒント D.6 ドキュメント文字列のヒント D.7 コメント記述のヒント D.8 Emacsライブラリーのヘッダーの慣習 Appendix E GNU Emacsの内部 E.1 Emacsのビルド E.2 純粋ストレージ E.3 ガーベージコレクション E.4 Stack-allocated Objects E.5 メモリー使用量 E.6 C方言 E.7 Emacsプリミティブの記述 E.8 オブジェクトの内部 E.8.1 バッファーの内部 E.8.2 ウィンドウの内部 E.8.3 プロセスの内部 E.9 Cの整数型 Appendix F 標準的なエラー Appendix G 標準的なキーマップ Appendix H 標準的なフック Index Emacs Lisp ********** This is the ‘GNU Emacs Lisp Reference Manual’ corresponding to Emacs version 25.1. Copyright © 1990–1996, 1998–2016 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with the Invariant Sections being “GNU General Public License,” with the Front-Cover Texts being “A GNU Manual,” and with the Back-Cover Texts as in (a) below. A copy of the license is included in the section entitled “GNU Free Documentation License.” (a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify this GNU manual. Buying copies from the FSF supports it in developing GNU and promoting software freedom.” 1 イントロダクション ******************** GNU Emacsテキストエディターのほとんどの部分は、Emacs Lispと呼ばれるプロ グラミング言語で記述されています。新しいコードをEmacs Lispで記述して、こ のエディターの拡張としてインストールできます。しかしEmacs Lispは、単なる 拡張言語を越える言語であり、それ自体で完全なコンピュータープログラミング 言語です。他のプログラミング言語で行なうすべてのことに、この言語を使用で きます。 Emacs Lispはエディターの中で使用するようにデザインされているので、テ キストのスキャンやパースのための特別な機能をもち、同様にファイル、バッフ ァー、ディスプレー、サブプロセスを処理する機能をもちます。Emacs Lispは編 集機能と密に統合されています。つまり編集コマンドはLispプログラムから簡単 に呼び出せる関数で、カスタマイズのためのパラメーターは普通のLisp変数です 。 このマニュアルはEmacs Lispの完全な記述を試みます。初心者のためのEmacs Lispのイントロダクションは、Free Software Foundationからも出版されている 、Bob Chassellの‘An Introduction to Emacs Lisp Programming’を参照してく ださい。このマニュアルは、Emacsを使用した編集に熟知していることを前提と しています。これの基本的な情報については、‘The GNU Emacs Manual’を参照し てください。 おおまかに言うと、前の方のチャプターでは多くのプログラミング言語の機 能にたいして、Emacs Lispでの対応する機能を説明し、後の方のチャプターでは Emacs Lispに特異な機能や、編集に特化した関連する機能を説明します。 これは Emacs 25.1に対応した‘GNU Emacs Lisp Reference Manual’です。 1.1 注意事項 ============ このマニュアルは幾多のドラフトを経てきました。ほとんど完璧ではありますが 、不備がないとも言えません。(ほとんどの特定のモードのように)それらが副次 的であるとか、まだ記述されていないという理由により、カバーされていないト ピックもあります。わたしたちがそれらを完璧に扱うことはできないので、いく つかの部分は意図的に省略しました。 このマニュアルは、それがカバーしている事柄については完全に正しくある べきあり、故に特定の説明テキスト、チャプターやセクションの順番にたいして の批判にオープンであるべきです。判りにくかったり、このマニュアルでカバー されていない何かを学ぶためにソースを見たり実地から学ぶ必要があるなら、こ のマニュアルはおそらく訂正されるべきなのかもしれません。どうかわたしたち にそれを教えてください。 このマニュアルを使用するときは、間違いを見つけたらすぐに訂正を送って ください。関数または関数グループの単純な現実例を考えたときは、ぜひそれを 記述して送ってください。それが妥当ならコメントでノード名と関数名や変数名 を参照してください。あなたが訂正を求めるエディションのバージョンも示して ください。 ‘M-x report-emacs-bug’を使用して、コメントや訂正を送ってください。 1.2 Lispの歴史 ============== 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をかなりエミュレートできます 。*note Overview: (cl)Top.を参照してください。 Emacs LispはSchemeの影響は受けていません。しかしGNUプロジェクトには Guileと呼ばれるScheme実装があります。拡張が必要な新しいGNUソフトウェアー では、Guileを使用します。 1.3 表記について ================ このセクションでは、このマニュアルで使用する表記規約を説明します。あなた はこのセクションをスキップして、後から参照したいと思うかもしれません。 1.3.1 用語について ------------------ このマニュアルでは、“Lispリーダー”および“Lispプリンター”という用語で、 Lispのテキスト表現を実際のLispオブジェクトに変換したり、その逆を行なう Lispルーチンを参照します。詳細については、*note Printed Representation::を参照してください。あなた、つまりこのマニュアルを読んで いる人のことはプログラマーと考えて“あなた”と呼びます。“ユーザー”とは、あ なたの記述したものも含めて、Lispプログラムを使用する人を指します。 Lispコードの例は、‘(list 1 2 3)’のようなフォーマットです。メタ構文変 数(metasyntactic variables)を表す名前や、説明されている関数の引数名前は 、FIRST-NUMBERのようにフォーマットされています。 1.3.2 ‘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’エラーと なります。*note Constant Variables::を参照してください。 -- Function: booleanp object OBJECTが2つの正規のブーリーン値(‘t’か‘nil’)のいずれかなら、非 ‘nil’をリターンする。 1.3.3 評価の表記 ---------------- 評価できる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) 1.3.4 プリントの表記 -------------------- このマニュアルの例の多くは、それらが評価されるときにテキストをプリントし ます。(‘*scratch*’バッファーのような)Lisp Interactionバッファーでコード 例を実行する場合、プリントされるテキストはそのバッファーに挿入されます。 (関数‘eval-region’での評価のように)他の方法でコード例を実行する場合、プ リントされるテキストはエコーエリアに表示されます。 このマニュアルの例はプリントされるテキストがどこに出力されるかに関わ らず、それを‘⊣’で表します。フォームを評価することにより戻される値は、 ‘⇒’とともに後続の行で示します。 (progn (prin1 'foo) (princ "\n") (prin1 'bar)) ⊣ foo ⊣ bar ⇒ bar 1.3.5 エラーメッセージ ---------------------- エラーをシグナルする例もあります。これは通常、エコーエリアにエラーメッセ ージを表示します。エラーメッセージの行は‘error→’で始まります。‘error→’自 体は、エコーエリアに表示されないことに注意してください。 (+ 23 'x) error→ Wrong type argument: number-or-marker-p, x 1.3.6 バッファーテキストの表記 ------------------------------ バッファー内容の変更を説明する例もあます。それらの例では、そのテキストの 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 ---------- 1.3.7 説明のフォーマット ------------------------ このマニュアルでは関数(function)、変数(variable)、コマンド(command)、ユ ーザーオプション(user option)、スペシャルフォーム(special form)を、統一 されたフォーマットで記述します。記述の最初の行には、そのアイテムの名前と 、もしあれば引数(argument)が続きます。 そのアイテムの属するカテゴリー (function、variableなど)は、行の先頭に表示します。 それ以降の行は説明行 で、例を含む場合もあります。 1.3.7.1 関数の説明例 .................... 関数の記述では、関数の名前が最初に記述されます。同じ行に引数の名前のリス トが続きます。引数の値を参照するために、引数の名前は記述の本文にも使用さ れます。 引数リストの中にキーワード‘&optional’がある場合、その後の引数が省略可 能であることを示します(省略された引数のデフォルトは‘nil’)。その関数を呼 び出すときは、‘&optional’を記述しないでください。 キーワード‘&rest’(これの後には1つの引数名を続けなければならない)は、 その後に任意の引数を続けることができることを表します。‘&rest’の後に記述 された引数名の値には、その関数に渡された残りのすべての引数がリストとして セットされます。この関数を呼び出すときは、‘&rest’を記述しないでください 。 以下は‘foo’という架空の関数(function)の説明です: -- Function: foo integer1 &optional integer2 &rest integers 関数‘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オブジェクトタイプのリストは *note Lisp Data Types::を参照)。他の名前をもつ引数(たとえばNEW-FILE)はそ の関数に固有の引数で、関数がドキュメント文字列をもつ場合、引数のタイプは その中で説明されるべきです(*note Documentation::を参照)。 ‘&optional’や‘&rest’により修飾される引数のより完全な説明は、*note Lambda Expressions::を参照してください。 コマンド(command)、マクロ(macro)、スペシャルフォーム(special form)の 説明も同じフォーマットですが、‘Function’が‘Command’、‘Macro’、‘Special Form’に置き換えられます。コマンドはとは単に、インタラクティブ (interactive: 対話的)に呼び出すことができる関数です。マクロは関数とは違 う方法(引数は評価されない)で引数を処理しますが、同じ方法で記述します。 マクロとスペシャルフォームにたいする説明には、特定のオプション引数や 繰り替えされる引数のために、より複雑な表記が使用されます。なぜなら引数リ ストが、より複雑な方法で別の引数に分離されるからです。‘[OPTIONAL-ARG]’は OPTIONAL-ARGがオプションであることを意味し、‘REPEATED-ARGS...’は0個以上 の引数を表します。カッコ(parentheses)は、複数の引数をリスト構造の追加レ ベルにグループ化するのに使用されます。以下は例です: -- Special Form: count-loop (var [from to [inc]]) body... この架空のスペシャルフォームは、 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とともにリストにグループ化されます。 1.3.7.2 変数の説明例 .................... “変数(variable)”とは、オブジェクトに“バインド(bind)”される名前です(“セッ ト(set)”とも言う)。変数がバインドされたオブジェクトのことを“値(value)”と 呼びます。このような場合には、その変数が値をもつという言い方もします。ほ とんどすべての変数はユーザーがセットすることができますが、特にユーザーが 変更できる特定の変数も存在し、これらは“ユーザーオプション(user options)”と呼ばれます。通常の変数およびユーザーオプションは、関数と同様 のフォーマットを使用して説明されますが、それらには引数がありません。 以下は架空の変数‘electric-future-map’の説明です。 -- Variable: electric-future-map この変数の値はElectric Command Futureモードで使用される完全なキーマ ップである。このマップ内の関数により、まだ実行を考えていないコマン ドの編集が可能になる。 ユーザーオプションも同じフォーマットをもちますが、‘Variable’が‘User Option’に置き換えられます。 1.4 バージョンの情報 ==================== 以下の機能は、使用しているEmacsに関する情報を提供します。 -- Command: emacs-version &optional here この関数は実行しているEmacsのバージョンを説明する文字列をreturnすす 。これはバグレポートにこの文字列を含めるときに有用である。 (emacs-version) ⇒ "GNU Emacs 24.5.1 (x86_64-unknown-linux-gnu, GTK+ Version 3.16) of 2015-06-01" HEREが非‘nil’ならテキストをバッファーのポイントの前に挿入して、 ‘nil’をリターンする。この関数がインタラクティブに呼び出すと、同じ情 報をエコーエリアに出力する。プレフィクス引数を与えると、HEREが非 ‘nil’になる。 -- Variable: emacs-build-time この変数の値はEmacsがビルドされた日時を示す。値は‘current-time’と同 様の、4つの整数からなるリストである(*note Time of Day::を参照)。 emacs-build-time ⇒ (20614 63694 515336 438000) -- Variable: emacs-version この変数の値は実行中のEmacsのバージョンであり、‘"23.1.1"’のような文 字列。この文字列の最後の数字は、実際にはEmacsリリースのバージョン番 号の一部ではなく、任意のディレクトリーにおいてEmacsがビルドされる度 に増分される。‘"22.0.91.1"’のように4つの数字から構成される値は、そ れがリリースではないテストバージョンであることを示す。 -- Variable: emacs-major-version Emacsのメジャーバージョン番号を示す整数。Emacs 23.1では値は23。 -- Variable: emacs-minor-version Emacsのマイナーバージョン番号を示す整数。Emacs 23.1では値は1。 1.5 謝辞 ======== このマニュアルは当初、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ソースリポジトリーの関連する変更ログ エントリーを参照してください。 2 Lispのデータ型 **************** Lispの“オブジェクト(object)”とは、Lispプログラムから操作されるデータです 。“型(type)”や“データ型(data type)”とは、可能なオブジェクトの集合を意味 します。 すべてのオブジェクトは少なくとも1つの型に属します。同じ型のオブジェク トは同様な構造をもち、通常は同じコンテキストで使用されます。型を重複して もつことができ、オブジェクトは複数の型に属することができます。その結果と して、あるオブジェクトが特定の型に属するかどうかを尋ねることはできますが 、オブジェクトが_その_型だけに属するかどうかは決定できません。 Emacsにはいくつかの基本オブジェクト型が組み込まれています。これらの型 は他のすべての型を構成するもとであり、“プリミティブ型(primitive types: 基 本型)”と呼ばれます。すべてのオブジェクトはただ1つのプリミティブ型に属し ます。これらの型には“整数(integer)”、“浮動小数点数(float)”、“コンス (cons)”、“シンボル(symbol)”、“文字列(string)”、“ベクター(vector)”、“ハッ シュテーブル(hash-table)”、“サブルーチン(subr)”、“バイトコード関数 (byte-code function)”、および“buffer”のような編集に関連した特別な型が含 まれます(*note Editing Types::を参照)。 プリミティブ型にはそれぞれ、オブジェクトがその型のメンバーかどうかの チェックを行なうために、それぞれ対応するLisp関数があります。 他の多くの言語とは異なり、Lispのオブジェクトは“自己記述 (self-typing)”的です。オブジェクトのプリミティブ型は、オブジェクト自体に 暗に含まれます。たとえばオブジェクトがベクターなら、それを数字として扱う ことはできません。Lispはベクターが数字でないことを知っているのです。 多くの言語では、プログラマーは各変数にたいしてデータ型を宣言しなけれ ばならず、コンパイラーは型を知っていますが、データの中に型はありません。 Emacs Lispには、このような型宣言はありません。Lisp変数は任意の型の値をも つことができ、変数に保存した値と型を記憶します(実際には特定の型の値だけ をもつことができる少数のEmacs Lisp変数がある。*note Variables with Restricted Values::を参照されたい)。 このチャプターでは、GNU Emacs Lispの各標準型の意味、プリント表現 (printed representation)、入力構文(read syntax)を説明します。これらのデ ータ型を使用する方法についての詳細は、以降のチャプターを参照してください 。 2.1 プリント表現と読み取り構文 ============================== オブジェクトのプリント表現(printed representation)とは、オブジェクトにた いしてLispプリンター(関数‘prin1’)が生成する出力のフォーマットです。すべ てのデータ型は一意なプリント表現をもちます。オブジェクトの“入力構文(read syntax)”とは、オブジェクトにたいしてLispリーダー(関数‘read’)が受け取る入 力のフォーマットです。これは一意である必要はありません。多くの種類のオブ ジェクトが複数の構文をもちます。*note Read and Print::を参照してください 。 ほとんどの場合、オブジェクトのプリント表現が、入力構文としても使用さ れます。しかしLispプログラム内の定数とすることに意味が無いいくつかの型に は、入力構文がありません。これらのオブジェクトは“ハッシュ表記(hash notation)”でプリントされ、‘#<’、説明的な文字列(典型的には型名にオブジェ クトの名前を続けたもの)、‘>’で構成される文字列です。たとえば: (current-buffer) ⇒ # ハッシュ表記は読み取ることができないので、Lispリーダーは‘#<’に遭遇すると 常にエラー‘invalid-read-syntax’をシグナルします。 他の言語では式はテキストであり、これ以外の形式はありません。Lispでは 式は第一にまずLispオブジェクトであって、オブジェクトの入力構文であるテキ ストは副次的なものに過ぎません。たいていこの違いを強調する必要はありませ んが、このことを心に留めておかないとたまに混乱することがあるでしょう。 インタラクティブに式を評価するとき、Lispインタープリターは最初にそれ のテキスト表現を読み取り、Lispオブジェクトを生成してからそのオブジェクト を評価します(*note Evaluation::を参照)。しかし評価と読み取りは別の処理で す。読み取りによりテキストにより表現されたLispオブジェクトを読み取り、 Lispオブジェクトがリターンされます。後でオブジェクトは評価されるかもしれ ないし、評価されないかもしれません。オブジェクトを読み取るための基本的な 関数‘read’の説明は、*note Input Functions::を参照してください。 2.2 コメント ============ “コメント(comment)”はプログラム中に記述されたテキストであり、そのプログ ラムを読む人間ためだけに存在するもので、プログラムの意味には何の影響もも ちません。Lispではそれが文字列や文字定数にある場合をのぞき、セミコロン (‘;’)でコメントが開始されます。行の終端までがコメントになります。Lispリ ーダーはコメントを破棄します。コメントはLispシステム内でプログラムを表す Lispオブジェクトの一部にはなりません。 ‘#@COUNT’構成は、次のCOUNT個の文字をスキップします。これはプログラム により生成されたバイナリーデータを含むコメントにたいして有用です。Emacs Lispバイトコンパイラーは出力ファイルにこれを使用します(*note Byte Compilation::を参照)。しかしソースファイル用ではありません。 コメントのフォーマットにたいする慣例は、*note Comment Tips::を参照し てください。 2.3 プログラミングの型 ====================== Emacs Lispには2種類の一般的な型があります。1つはLispプログラミングに関わ るもので、もう1つは編集に関わるものです。前者はさまざまな形で多くの Lisp実装に存在します。後者はEmacs Lispに固有です。 2.3.1 整数型 ------------ 整数の値の範囲はマシンに依存します、最小のレンジは−536,870,912から 536,870,911(30ビットでは −2**29 から 2**29 − 1) ですが、多くのマシンはこ れより広い範囲を提供します。Emacs Lispの数学関数は整数のオーバーフローを チェックしません。したがってEmacsのh整数が30ビットの場合、‘(1+ 536870911)’は−536,870,912になります。 整数にたいする入力構文は、(10を基数とする)数字のシーケンスで、オプシ ョンで先頭に符号、最後にピリオドがつきます。Lispインタープリターにより生 成されるプリント表現には、先頭の ‘+’や最後の‘.’はありません。 -1 ; 整数の−1 1 ; 整数の1 1. ; これも整数の1 +1 ; これも整数の1 特別な例外として、数字シーケンスが有効なオブジェクトとしては大きすたり小 さすぎる整数を指定する場合、Lispリーダーはそれを浮動小数点数(*note Floating-Point Type::を参照)として読み取ります。たとえば、Emacsの整数が 30ビットの場合、‘536870912’は浮動小数点数の‘536870912.0’として読み取られ ます。 詳細は*note Numbers::を参照してください。 2.3.2 浮動小数点数型 -------------------- 浮動小数点数は、コンピューターにおける科学表記に相当するものです。浮動小 数点数を10の指数をともなう有理数として考えることができます。正確な有効桁 数と可能な指数はマシン固有です。Emacsは値の保存にCデータ型の‘double’を使 用し、内部的には10の指数ではなく、2の指数として記録します。 浮動小数点数のプリント表現には、(後に最低1つの数字をともなう)小数点と 、指数のどちらか一方、または両方が必要です。たとえば‘1500.0’、‘+15e2’、 ‘15.0e+2’、‘+1500000e-3’、‘.15e4’は、いずれも浮動小数点数の1500を記述し 、これらはすべて等価です。 詳細は*note Numbers::を参照してください。 2.3.3 文字型 ------------ Emacs Lispでの“文字(character)”は、整数以外の何者でもありません。言い換 えると、文字は文字コードで表現されます。たとえば文字‘A’は、整数の65とし て表現されます。 プログラムで文字を個別に使用するのは稀であり、文字のシーケンスとして 構成される_文字列(strings)_として扱われるのがより一般的です。*note String Type::を参照してください。 文字列やバッファーの中の文字は、現在のところ0から4194303の範囲 — つま り22ビットに制限されています(*note Character Codes::を参照)。0から127の コードはASCIIコードで、残りは非ASCIIです(*note Non-ASCII Characters::を 参照)。キーボード入力を表す文字はコントロール(Control)、メタ(Meta)、シフ ト(Shift)などの修飾キーをエンコードするために、より広い範囲をもちます。 文字から可読なテキスト記述を生成する、メッセージ用の特別な関数が存在 します。*note Describing Characters::を参照してください。 2.3.3.1 基本的な文字構文 ........................ 文字は実際には整数なので、文字のプリント表現は10進数です。文字にたいする 入力構文も利用可能ですが、Lispプログラムでこの方法により文字を記述するの は、明解なプログラミングではありません。文字にたいしては、Emacs Lispが提 供する、特別な入力構文を_常に_使用するべきです。これらの構文フォーマット はクエスチョンマークで開始されます。 英数字にたいする通常の入力構文は、クエスチョンマークと、その後にその 文字を記述します。したがって文字‘A’は‘?A’、文字‘B’は‘?B’、文字‘a’は ‘?a’となります。 たとえば: ?Q ⇒ 81 ?q ⇒ 113 区切り文字(punctuation characters)にも同じ構文を使用できますが、 Lispコードを編集するためのEmacsコマンドが混乱しないように、‘\’を追加する のがよい場合がしばしばあります。たとえば開カッコを記述するために‘?\(’と 記述します。その文字が‘\’の場合、それをクォートするために、‘?\\’のように 2つ目の‘\’を_使用しなければなりません_。 Ctrl+g(control-g)、バックスペース(backspace)、タブ(tab)、改行 (newline)、垂直タブ(vertical tab)、フォームフィード(formfeed)、スペース (space)、キャリッジリターン(return)、デリート(del)、エスケープ(escape)は それぞれ‘?\a’、‘?\b’、‘?\t’、‘?\n’、‘?\v’、‘?\f’、‘?\s’、‘?\r’、‘?\d’、 ‘?\e’と表すことができます(後にダッシュのついた‘?\s’は違う意味をもつ — こ れは後続の文字にたいしてスーパーによる修飾を適用する)。したがって、 ?\a ⇒ 7 ; control-g、‘C-g’ ?\b ⇒ 8 ; バックスペース、、‘C-h’ ?\t ⇒ 9 ; タブ、、‘C-i’ ?\n ⇒ 10 ; 改行、‘C-j’ ?\v ⇒ 11 ; 垂直タブ、‘C-k’ ?\f ⇒ 12 ; フォームフィード文字、‘C-l’ ?\r ⇒ 13 ; キャリッジリターン、、‘C-m’ ?\e ⇒ 27 ; エスケープ文字、、‘C-[’ ?\s ⇒ 32 ; スペース文字、 ?\\ ⇒ 92 ; バックスラッシュ文字、‘\’ ?\d ⇒ 127 ; デリート文字、 バックスラッシュがエスケープ文字の役割を果たすので、これらのバックス ラッシュで始まるシーケンスは“エスケープシーケンス(escape sequences)”とも 呼ばれます。この用語法は文字とは関係ありません。‘\s’は文字定数とし ての使用を意図しており、文字定数の内部では単にスペースを記述します。 エスケープという特別な意味を与えずに、任意の文字の前にバックスラッシ ュの使用することは許されており、害もありません。したがって‘?\+’は‘?+’と 等価です。ほとんどの文字の前にバックスラッシュを追加することに理由はあり ません。しかしLispコードを編集するEmacsコマンドが混乱するのを避けるため に、文字‘()\|;'`"#.,’の前にはバックスラッシュを追加するべきです。スペー ス、タブ、改行、フォームフィードのような空白文字の前にもバックスラッシュ を追加できます。しかしタブやスペースspaceのような実際の空白文字のかわり に、‘\t’や‘\s’のような可読性のあるエスケープシーケンスを使用するほうが明 解です(スペースを後にともなうバックスラッシュを記述する場合、後続のテキ ストと区別するために、文字定数の後に余分なスペースを記述すること)。 2.3.3.2 一般的なエスケープ構文 .............................. 特に重要なコントロール文字にたいする特別なエスケープシーケンスに加えて、 Emacsは非ASCIIテキスト文字の指定に使用できる、何種類かのエスケープ構文を 提供します。 最初に、文字をUnicodeの値で指定することができます。‘?\uNNNN’は Unicodeのコードポイント‘U+NNNN’の文字を表します。ここでNNNNは、(慣例によ り)正確に4桁の16進数です。バックスラッシュは、後続の文字がエスケープシー ケンスを形成することを示し、‘u’はUnicodeエスケープシーケンスを指定します 。 ‘U+FFFF’より大きなコードポイントをもつUnicode文字を指定するために、若 干異なる構文が存在します。‘?\U00NNNNNN’はコードポイント‘U+NNNNNN’の文字 を表します。ここでNNNNNNは6桁の16進数です。Unicode標準は‘U+10FFFF’までの コードポイントだけを定義するので、これより大きいコードポイントを指定する とEmacsはエラーをシグナルします。 次に文字を16進の文字コードで指定できます。16進エスケープシーケンスは バックスラッシュ、‘x’、および16進の文字コードにより構成されます。したが って‘?\x41’は文字‘A’、‘?\x1’は文字‘C-a’、‘?\xe0’は文字‘à’(グレイブアクセ ントつきの‘a’)になります。任意の16進数を使用できるので、この方法で任意の 文字を表すことができます。 最後に、8進の文字コードにより文字を指定できます。8進エスケープシーケ ンスは、3桁までの8進数字をともなうバックスラッシュにより形成されます。し たがって‘?\101’は文字‘A’、‘?\001’は文字‘C-a’、‘?\002’は文字‘C-b’を表しま す。この方法で指定できるのは、8進コード777までの文字だけです。 これらのエスケープシーケンスは文字列内でも使用されます。*note Non-ASCII in Strings::を参照してください。 2.3.3.3 コントロール文字構文 ............................ 他の入力構文を使用してコントロール文字を表すことができます。これは後にバ ックスラッシュ、カレット、対応する非コントロール文字(大文字か小文字)をと もなうクエスチョンマークから構成されます。たとえば‘?\^I’と‘?\^i’はどちら も、値が9である文字‘C-i’の有効な入力構文です。 ‘^’のかわりに‘C-’を使用することもできます。したがって‘?\C-i’は ‘?\^I’や‘?\^i’と等価です。 ?\^I ⇒ 9 ?\C-I ⇒ 9 文字列やバッファーの中ではASCIIのコントロール文字だけが許されますが、 キーボード入力にたいしては‘C-’により任意の文字をコントロール文字にするこ とができます。これらの非ASCIIのコントロール文字にたいするコントロール文 字には 非コントロール文字にたいするコードと同様に、2**26 ビットが含まれ ます。通常のテキスト端末には非ASCIIコントロール文字を生成する方法があり ませんが、Xやその他のウィンドウシステムを使用すれば簡単に生成することが できます。 歴史的な理由により、Emacsは文字を‘?’のコントロール文字として扱い ます: ?\^? ⇒ 127 ?\C-? ⇒ 127 結果として、Xでは有意な入力文字である‘Control-?’文字を、‘\C-’を使用して 表現することは今のところできません。さまざまなLispファイルがこの方法で を参照するので、これを変更するのは簡単ではないのです。 コントロール文字の表現はファイルや文字列内で見ることができますが、わ たしたちは‘^’構文を推奨します。キーボード入力にたいするコントロール文字 に好ましいのは、‘C-’構文です。どちらを使用するかはプログラムの意味に影響 しませんが、プログラムを読む人の理解を助けるでしょう。 2.3.3.4 メタ文字構文 .................... “メタ文字(meta character)”とは、修飾キーとともにタイプされた文字で す。そのような文字を表す整数には 2**27 のビットがセットされています。基 本的な文字コードの広い範囲を利用可能にするために、メタやその他の修飾にた いしては上位ビットを使用します。 文字列では、メタ文字を示すASCII文字に、 2**7 ビットが付加されます。し たがって文字列に含めることができるメタ文字のコードは1から255の範囲となり 、メタ文字は通常のASCII文字のメタ修飾されたバージョンとなります。文字列 内での処理の詳細については、*note Strings of Events::を参照してく ださい。 メタ文字の入力構文には‘\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’と記述する ことができます。 2.3.3.5 その他の文字修飾ビット .............................. グラフィック文字(graphic character)のcaseは文字コードで示されます。たと えばASCIIでは、文字‘a’と文字‘A’は区別されます。しかしASCIIにはコントロー ル文字が大文字なのか小文字なのかを表現する方法がありません。コントロール 文字がタイプされたときシフトキーが使用されたかを示すために、Emacsは 2**25 のビットを使用します。この区別はX端末や、その他の特別な端末を使用 しているときだけ可能です。通常のテキスト端末は、これらの違いを報告しませ ん。シフトをあらわすビットのためのLisp構文は‘\S-’です。したがって ‘?\C-\S-o’や‘?\C-\S-O’は、Shift+Ctrl+o文字を表します。 Xウィンドウシステムは文字にセットするために、他にも3つ修飾ビット — “ハ イパー(hyper)”、“スーパー(super)”、“アルト(alt)”を定義します。これらのビ ットにたいする構文は、‘\H-’、‘\s-’、‘\A-’です(これらのプレフィクスでは、 caseは意味がある)。したがって‘?\H-\M-\A-x’は‘Alt-Hyper-Meta-x’を表します (‘-’が後にない‘\s’はスペース文字を表すことに注意)。 数値としてはビット値 2**22はアルト、2**23はスーパー、2**24はハイパーです。 2.3.4 シンボル型 ---------------- GNU Emacs Lispでの“シンボル(symbol)”とは、名前をもつオブジェクトです。シ ンボル名は、そのシンボルのプリント表現としての役割があります。Lispの通常 の使用では、1つのobarray(*note Creating Symbols::を参照)により、シンボル 名は一意です — 2つのシンボルが同じ名前をもつことはありません。 シンボルは変数や関数名としての役割、プロパティーリストを保持する役割 をもつことができます。データ構造内にそのようなシンボルが存在することが確 実に認識できるように、他のすべてのLispオブジェクトから区別するためだけの 役割をもつ場合もあります。与えられたコンテキストにおいて、通常はこれらの うちの1つの使用だけが意図されます。しかし3つすべての方法で、1つのシンボ ルを独立して使用することもできます。 名前がコロン(‘:’)で始まるシンボルは“キーワードシンボル(keyword symbol)”と呼ばれます。これらのシンボルは自動的に定数として振る舞い、通常 は未知のシンボルといくつかの特定の候補を比較することだけに使用されます。 *note Constant Variables::を参照してください。 シンボル名にはどんな文字でも含めることができます。ほとんどのシンボル 名は英字、数字、‘-+=*/’などの区切り文字で記述されます。このような名前に は特別な区切り文字は必要ありません。名前が数字のように見えない限り、名前 にはどのような文字も使用できます(名前が数字のように見える場合は、名前の 先頭に‘\’を記述して強制的にシンボルとして解釈させる)。文字 ‘_~!@$%^&:<>{}?’はあまり使用されませんが、これらも特別な句読点文字を必要 としません。他の文字も、バックスラッシュでエスケープすることにより、シン ボル名に含めることができます。しかし文字列内でのバックスラッシュの使用と は対照的に、シンボル名でのバックスラッシュは、バックスラッシュの後の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する。 *note Creating Symbols::を参照されたい)。 2.3.5 シーケンス型 ------------------ “シーケンス(sequence)”とは、要素の順序セットを表現するLispオブジェクトで す。Emacs Lispには2種類のシーケンス — “リスト(lists)”と“配列(arrays)”が あります。 リストはもっとも一般的に使用されるシーケンスです。リストは任意の型の 要素を保持でき、要素の追加と削除により簡単に長さを変更できます。リストに ついては、次のサブセクションを参照してください。 配列は固定長のシーケンスです。配列はさらに文字列(strings)、ベクター (vectors)、文字テーブル(char-tables)、ブールベクター(bool-vectors)に細分 されます。ベクターは任意の型の要素を保持できますが、文字列の要素は文字で なければならず、ブールベクターの要素は‘t’か‘nil’でなければなりません。文 字テーブルはベクターと似ていますが、有効な文字によりインデックスづけされ る点が異なります。文字列内の文字は、バッファー内の文字のようにテキストプ ロパティーをもつことができます(*note Text Properties::を参照)。しかしベ クターはその要素が文字のときでも、テキストプロパティーをサポートしません 。 リスト、文字列、およびその他の配列型も、重要な類似点を共有します。た とえば、それらはすべて長さLをもち、要素は0からL−1でインデックスづけされ ます。いくつかの関数はシーケンス関数と呼ばれ、これらは任意の種類のシーケ ンスを許容します。たとえば、関数‘length’は、任意の種類のシーケンスの長さ を報告します。*note Sequences Arrays Vectors::を参照してください。 シーケンスは読み取りにより常に新たに作成されるやめ、同じシーケンスを 2回読み取るのは一般的に不可能です。シーケンスにたいする入力構文を2回読み 取った場合には、内容が等しい2つのシーケンスを得ます。これには1つ例外があ ります。空リスト‘()’は、常に同じオブジェクト‘nil’を表します。 2.3.6 コンスセルとリスト型 -------------------------- “コンスセル(cons cell)”はCARスロット、CDRスロットと呼ばれる2つのスロット から構成されるオブジェクトです。それぞれのスロットはには、任意のLispオブ ジェクトを“保持”できます。そのときCARスロットに保持されるオブジェクトが 何であれ、わたしたちは“このコンスセルのCAR”のような言い方をします。これ はCDRの場合も同様です。 “リスト(list)”はコンスセルの連続するシリーズで、各コンスセルのCDRスロ ットは次のコンスセル、または空リストを保持します。空リストは実際にはシン ボル‘nil’です。詳細については、*note Lists::を参照してください。ほとんど のコンスセルはリストの一部として使用されるので、わたしたちはコンスセルに より構成される任意の構造を、“リスト構造(list structure)”という用語で参照 します。 Cプログラマーにたいする注意: Lispのリストはコンスセルにより構築され る“リンクリスト(linked list)”として機能する。Lispではポインターは暗 黙的なので、コンスセルのスロットが値を“保持(hold)”するのか、それと も値を“指す(point)”のかは区別しない。 コンスセルはLispの中核なので、コンスセルではないオブジェクトにたいす る用語もあります。これらのオブジェクトは“アトム(atoms)”と呼ばれます。 リストにたいする入力構文とプリント表現は同じで左カッコ、任意の数の要 素、右カコから構成されます。以下はリストの例です: (A 2 "A") ; 3要素のリスト () ; 要素がないリスト(空リスト) nil ; 要素がないリスト(空リスト) ("A ()") ; 1要素のリスト: 文字列‘"A ()"’ (A ()) ; 2要素のリスト: ‘A’と空リスト (A nil) ; 同上 ((A B C)) ; 1要素のリスト ; (この要素は、3要素のリスト) 読み取りではカッコの内側はリストの要素になります。つまりコンスセルは 各要素から作成されます。コンスセルのCARスロットは要素を保持し、CDRスロッ トはリスト内の次のコンスセル(このコンスセルはリスト内の次の要素をする)を 参照します。最後のコンスセルのCDRスロットは‘nil’を保持するようにセットさ れます。 CARやCDRという名称はLispの歴史に由来します。オリジナルのLisp実装は IBM 704コンピューターで実行されていました。ワードを2つの部分、つまり “address”と呼ばれる部分と、“decrement”と呼ばれる部分に分割していて、その 際CARはaddress部から内容を取り出す命令で、CDRはdecrement部から内容を取り 出す命令でした。これとは対照的に“cons cells”は、これらを作成する関数 ‘cons’から命名されました。この関数は関数の目的、すなわちセルを作る (construction of cells)という目的から命名されました。 2.3.6.1 ボックスダイアグラムとしてのリストの描写 ................................................ コンスセルを表現するドミノのような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 | | | | | | | -------------- ---------------- 2.3.6.2 ドットペア表記 ...................... “ドットペア表記(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 2.3.6.3 連想リスト型 .................... “連想リスト(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関数についての詳細な説明は*note Association Lists::を参照 してください。(多くのキーの操作をより高速に行なう)テーブルを照合する他の 手段については*note Hash Tables::を参照してください。 2.3.7 配列型 ------------ “配列(array)”は、他のLispオブジェクトを保持または参照する任意の数のスロ ットから構成され、メモリーの連続ブロックに配列されます。配列の任意の要素 へのアクセス時間は大体同じです。対照的にリストの要素にたいするアクセスは 、リスト内でのその要素の位置に比例した時間を要します(リストの最後の要素 にアクセスするにはリストの最初の要素にアクセスするより長い時間が必要)。 Emacsは文字列(strings)、ベクター(vectors)、ブールベクター (bool-vectors)、文字テーブル(char-tables)という4種の配列を定義します。 文字列は文字の配列であり、ベクターは任意のオブジェクトの配列です。ブ ールベクターは‘t’か‘nil’だけを保持できます。この種の配列は、もっとも大き い整数までの任意の長さをもつことができます。文字テーブルは、任意の有効な 文字コードによりインデックスづけされる疎な配列であり、任意のオブジェクト を保持することができます。 配列の最初の要素はインデックス0、2番目の要素はインデックス1、...とな ります。これは“0基準(zero-origin)”のインデックスづけと呼ばれます。たとえ ば、4要素の配列はインデックス0、1、2、3をもちます。利用できる最大のイン デックス値は、配列の長さより1つ小さくなります。▼一度配列が作成されると、 長さは固定されます。 Emacs Lispのすべての配列は、1次元です(他のほとんどのプログラミング言 語は多次元配列をサポートするが、これらは必須ではない。ネストされた1次元 配列により同じ効果を得ることが可能)。各種の配列は独自の入力構文をもちま す。詳細は以降のセクションを参照してください。 配列型はシーケンス型のサブセットであり文字列型、ベクター型、ブールベ クター型、文字テーブル型が含まれます。 2.3.8 文字列型 -------------- “文字列(string)”とは文字の配列です。Emacsがテキストエディターであること から予想できるように、文字列はたとえばLispシンボルの名前、ユーザーへのメ ッセージ、バッファーから抽出されたテキストの表現など多くの目的のために使 用されます。Lispの文字列は定数です。文字列を評価すると、それと同じ文字列 がリターンされます。 文字列を操作する関数については*note Strings and Characters::を参照し てください。 2.3.8.1 文字列の構文 .................... 文字列にたいする入力構文は‘"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." 2.3.8.2 文字列内の非ASCII文字 ............................. Emacdの文字列内の非ASCII文字にたいしては2つのテキスト表現 — マルチバイト (multibyte)とユニバイト(unibyte)があります(*note Text Representations::を 参照)。大まかに言うとユニバイト文字列にはraw(生)バイトが保存され、マルチ バイト文字列には人間が読めるテキストが保存されます。ユニバイト文字列内の 各文字はバイトであり、値は0から255となります。対照的にマルチバイト文字列 内の各文字は、0から4194303の値をもつかもしれません(*note Character Type::を参照)。いずれも127より上の文字は非ASCIIです。 文字をリテラルとして記述することにより、文字列に非ASCII文字を含めるこ とができます。マルチバイトのバッファーや文字列、あるいはマルチバイトとし てvisitされたファイル等、マルチバイトのソースから文字列定数を読み込む場 合、Emacsは非ASCII文字をマルチバイト文字として読み取り、その文字列を自動 的にマルチバイト文字列にします。ユニバイトのソースから文字列定数を読み込 む場合、Emacsは非ASCII文字をユニバイト文字として読み取り、その文字列をユ ニバイト文字列にします。 マルチバイト文字列内にリテラルとして文字を記述するかわりに、エスケー プシーケンスを使用して文字コードとして記述できます。エスケープシーケンス についての詳細は、*note General Escape Syntax::を参照してください。 文字列定数内で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進エスケープを終了します。 2.3.8.3 文字列内の非プリント文字 ................................ リテラル文字と同様に、文字列定数内でバックスラッシュによるエスケープシー ケンスを使用できます(ただし文字定数を開始するクエスチョンマークは使用し ない)。たとえば非プリント文字のタブと‘C-a’を含む文字列は、‘"\t, \C-a"’の ように、それらの間にカンマとスペースを記述します。文字にたいする入力構文 については*note Character Type::を参照してください。 しかしバックスラッシュによるエスケープシーケンスとともに記述できるす べての文字が、文字列内で有効というわけではありません。文字列が保持できる コントロール文字はASCIIコントロール文字だけです。ASCIIコントロール文字で は、文字列のcaseは区別されません。 正確に言うと、文字列はメタ文字を保持できません。しかし文字列がキーシ ーケンスとして使用される場合には、文字列内でメタ修飾されたASCII文字を表 現するための方法を提供する特別な慣習があります。文字列定数内でメタ文字を 示すために‘\M-’構文を使用した場合、これは文字列内の文字の 2**7 のビット をセットします。その文字列が‘define-key’または‘lookup-key’で使用される場 合、この数字コードは等価なメタ文字に変換されます。*note Character Type::を参照してください。 文字列はハイパー(hyper)、スーパー(super)、アルト(alt)で修飾された文字 を保持できません。 2.3.8.4 文字列内のテキストプロパティ .................................... 文字列にはその文字自身に加えて、文字のプロパティーも保持することができま す。これにより特別なことをしなくても、文字列とバッファーとの間でテキスト をコピーするプログラムが、テキストプロパティーをコピーすることが可能にな ります。テキストプロパティーが何を意味するかについては*note Text Properties::を参照してください。テキストプロパティーをもつ文字列は、特別 な入力構文とプリント構文を使用します。 #("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’と指定する必要ない)。 2.3.9 ベクター型 ---------------- “ベクター(vector)”は任意の型の要素からなる1次元の配列です。ベクター内の 任意の要素へのアクセスに要す時間は一定です(リストの場合では要素へのアク セスに要す時間は、リストの先頭からその要素までの距離に比例する)。 ベクターのプリント表現は左角カッコ(left square bracket)、要素、右角カ ッコ(right square bracket)から構成されます。これは入力構文でもあります。 数字や文字列と同様にベクターは評価において定数と判断されます。 [1 "two" (three)] ; 3要素のベクター ⇒ [1 "two" (three)] ベクターに作用する関数については*note Vectors::を参照してください。 2.3.10 文字テーブル型 --------------------- “文字テーブル(char-table)”は任意の型の要素をもつ1次元の配列であり、文字 コードによりインデックスづけされます。文字テーブルは、文字コードに情報を 割り当てることを必要とする多くの処理を簡単にするための、特別な追加の機能 をもちます — たとえば文字テーブルは継承する親、デフォルト値、特別な目的 のために使用する余分なスロットをいくつかもつことができます。文字テーブル は文字セット全体にたいして1つの値を指定することもできます。 文字テーブルのプリント表現はベクターと似ていますが、最初に余分な ‘#^’があります(1)。 文字テーブルを操作する特別な関数については*note Char-Tables::を参照し てください。文字テーブルの使用には以下が含まれます: • caseテーブル(*note Case Tables::を参照)。 • 文字カテゴリーテーブル(*note Categories::を参照)。 • ディスプレーテーブル(*note Display Tables::を参照)。 • 構文テーブル(*note Syntax Tables::を参照)。 ---------- Footnotes ---------- (1) 副文字テーブル(sub-char-tables)に使用される‘#^^’を目にすることが あるかもしれません。 2.3.11 ブールベクター型 ----------------------- “ブールベクター(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 2.3.12 ハッシュテーブル型 ------------------------- ハッシュテーブルは非常に高速な照合テーブルの一種で、キーを対応する値にマ ップするalistと似ていますがより高速です。ハッシュテーブルのプリント表現 では、以下のようにハッシュテーブルのプロパティーと内容を指定します: (make-hash-table) ⇒ #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8 data ()) ハッシュテーブルについての詳細は*note Hash Tables::を参照してください。 2.3.13 関数型 ------------- 他のプログラミング言語の関数と同様、Lisp関数は実行可能なコードです。他の 言語と異なり、Lispの関数はLispオブジェクトでもあります。Lispのコンパイル されていない関数はラムダ式 — つまり1番目の要素がシンボル‘lambda’であるリ ストです(*note Lambda Expressions::を参照)。 ほとんどのプログラミング言語では名前のない関数はありません。Lispでは 関数に本質的な名前はありません。名前がなくてもラムダ式を関数として呼び出 すことができます。これを強調するために、わたしたちはこれを“無名関数 (anonymous function)”とも呼びます(*note Anonymous Functions::を参照)。 Lispの名前つき関数は関数セルに有効な関数がセットされた単なるシンボルです (*note Defining Functions::を参照)。 ほとんどの場合、関数はLispプログラム内のLisp式の名前が記述されたとこ ろで呼び出されます。しかし実行時に関数オブジェクトを構築または取得してか ら、プリミティブ関数‘funcall’および‘apply’により呼び出すことができます。 *note Calling Functions::を参照してください。 2.3.14 マクロ型 --------------- “Lispマクロ(Lisp macro)”はLisp言語を拡張するユーザー定義の構成です。これ はオブジェクトとしてではなく関数のように表現されますが、引数の渡し方の意 味が異なります。Lispマクロの形式はリストです。これは最初の要素が ‘macro’で、CDRがLisp関数オブジェクト(‘lambda’シンボルを含む)であるような リストです。 Lispマクロオブジェクトは通常、ビルトインの‘defmacro’関数で定義されま すが、‘macro’で始まる任意のリストもEmacsにとってはマクロです。マクロを記 述する方法の説明は*note Macros::を参照してください。 *警告*: Lispマクロとキーボードマクロ(*note Keyboard Macros::を参照)は 完全に別の物である。修飾なしで“マクロ”という単語を使用したときは、キーボ ードマクロではなくLispマクロのことを指す。 2.3.15 プリミティブ関数型 ------------------------- “プリミティブ関数(primitive function)”とは、Cプログラミング言語で記述さ れたLispから呼び出せる関数です。プリミティブ関数は“subrs”や“ビルトイン関 数(built-in functions)”とも呼ばれます(単語“subr”は“サブルーチン (subroutine)”が由来)。ほとんどのプリミティブ関数ハ、呼び出されたときニす べての引数を評価します。すべての引数を評価しないプリミティブ関数は“スペ シャルフォーム(special form)”と呼ばれます(*note Special Forms::を参照)。 呼び出す側からすれば、その関数がプリミティブ関数かどうかは問題になり ません。しかしプリミティブ関数をLispで記述された関数で再定義した場合に問 題になります。理由はそのプリミティブ関数がCコードから直接呼び出されてい るかもしれないからです。Lispから再定義した関数を呼び出すと新しい定義を使 用するでしょうが、Cコードから呼び出すとビルトインの定義が使用されるでし ょう。したがって、*プリミティブ関数の再定義はしないでください*。 “関数(function)”という用語で、LispやCで記述されたすべてのEmacs関数を 参照します。Lispで記述された関数についての情報は*note Function Type::を 参照してください。 プリミティブ関数に入力構文はなく、サブルーチン名とともにハッシュ表記 でプリントします。 (symbol-function 'car) ; そのシンボルの関数セルに ; アクセスする ⇒ # (subrp (symbol-function 'car)) ; これはプリミティブ関数? ⇒ t ; そのとおり 2.3.16 バイトコード関数型 ------------------------- “バイトコード関数オブジェクト(byte-code function objects)”は、Lispコード をバイトコンパイルすることにより生成されます(*note Byte Compilation::を 参照)。バイトコード関数オブジェクトは、内部的にはベクターによく似ていま す。しかしバイトコード関数オブジェクトが関数呼び出しのように見える場合、 評価プロセスによりこのデータ型は特別に処理されます。*note Byte-Code Objects::を参照してください。 バイトコード関数オブジェクトのプリント表現と入力構文はベクターのもの と似ていますが、開き角カッコ‘[’の前に‘#’があります。 2.3.17 autoload型 ----------------- “autoloadオブジェクト(autoload object)”は、最初の要素がシンボル ‘autoload’のリストです。これはシンボルの関数定義として保存され、実際の定 義にたいする代替としての役割をもちます。autoloadオブジェクトは、必要な時 にロードされるLispコードファイルの中で実際の定義を見つけることができるこ とを宣言します。これにはファイル名と、それに加えて実際の定義についての他 のいくつかの情報が含まれます。 ファイルのロード後、そのシンボルはautoloadオブジェクトではない新しい 関数定義をもつはずです。新しい定義は、最初からそこにあったかのように呼び 出されます。ユーザーの観点からは関数呼び出しは期待された動作、つまりロー ドされたファイル内の関数定義を使用します。 autoloadオブジェクトは通常、シンボルの関数セルにオブジェクトを保存す る関数‘autoload’により作成されます。詳細は*note Autoload::を参照してくだ さい。 2.3.18 Finalizer Type --------------------- “ファイナライザーオブジェクト(finalizer object)”は、オブジェクトがもはや 必要なくなった後のLispコードのクリーンアップを助けます。ファイナライザー は、Lisp関数オブジェクトを保持します。ガーベージコレクションのオアス後に ファイナライザーオブジェクトが到達不能になったとき、Emacsはそのファイナ ライザーに関連付けられた関数オブジェクトを呼び出します。ファイナライザー の到達可否の判定時、もしかしてファイナライザーオブジェクト自身が参照を離 さないのではないかと心配することなくファイナライザーを使用できるように、 Emacsはファイナラーオブジェト自身からの参照は勘定しません。 ファイナラーザー内でのエラーは‘*Messages*’にプリントされます。その関 数が失敗しても、Emacsは与えられたファイナライザーオブジェクトに関連付け られた関数を正確に1回実行します。 -- Function: make-finalizer function FUNCTIONを実行するファイナライザーを作成する。FUNCTIONはガーベージ コレクション後、リターンされたファイナライザーオブジェクトが到達不 能になったときに実行される。そのファイナライザーオブジェクトがファ イナライザーオブジェクトからの参照を通じてのみ到達可能なら、 FUNCTIONの実行是非の判断時の目的にたいして、それは到達可能とみなさ れない。FUNCTIONはファイナライザーオブジェクトごとに1回実行される。 2.4 編集用の型 ============== 前セクションの型は一般的なプログラミング目的のために使用され、これらの型 のほとんどはLisp方言のほとんどで一般的です。Emacs Lispは編集に関する目的 のために、いくつかの追加のデータ型を提供します。 2.4.1 バッファー型 ------------------ “バッファー(buffer)”とは、編集されるテキストを保持するオブジェクトです (*note Buffers::を参照)。ほとんどのバッファーはディスクファイル(*note Files::を参照)の内容を保持するので編集できますが、他の目的のために使用さ れるものもいくつかあります。ほとんどのバッファーはユーザーにより閲覧され ることも意図しているので、いつかはウィンドウ内(*note Windows::を参照)に 表示されます。しかしバッファーはウィンドウに表示される必要はありません。 バッファーはそれぞれ、“ポイント(point)”と呼ばれる位置指定をもちます (*note Positions::を参照)。ほとんどの編集コマンドは、カレントバッファー 内のポイントに隣接する内容を処理します。常に1つのバッファーが“カレントバ ッファー(current buffer)”です。 バッファーの内容は文字列によく似ていますが、バッファーはEmacs Lispの 文字列と同じようには使用されず、利用可能な操作は異なります。文字列にテキ ストを挿入するためには部分文字列の結合が必要で、結果は完全に新しい文字列 オブジェクトなのるのにたいして、バッファーでは既存のバッファーに効率的に テキストを挿入してバッファーの内容を変更できます。 標準的なEmacs関数の多くは、カレントバッファー内の文字を操作したりテス トするためのものです。このマニュアルはこれらの関数の説明のために、1つの チャプターを設けています(*note Text::を参照)。 他のデータ構造のいくつかは、各バッファーに関連付けられています: • ローカル構文テーブル(*note Syntax Tables::を参照)。 • ローカルキーマップ(*note Keymaps::を参照)。 • バッファーローカルな変数バインディングのリスト(*note Buffer-Local Variables::を参照)。 • オーバーレイ(*note Overlays::を参照)。 • バッファー内のテキストにたいするテキストプロパティー(*note Text Properties::を参照)。 ローカルキーマップと変数リストは、グローバルなバインディングや値を個別に オーバーライドするためのエントリーを含みます。これらは実際にプログラムを 変更することなく、異なるバッファーでプログラムの振る舞いをカスタマイズす るために使用されます。 バッファーは“インダイレクト(indirect: 間接)” — つまり他のバッファーと テキストを共有するがそれぞれ別に表示する — かもしれません。*note Indirect Buffers::を参照してください。 バッファーに入力構文はありません。バッファーはバッファー名を含むハッ シュ表記でプリントされます。 (current-buffer) ⇒ # 2.4.2 マーカー型 ---------------- “マーカー(marker)”は特定のバッファー内の位置を表します。したがってマーカ ーには2つの内容 — 1つはバッファー、もう1つは位置 — をもちます。バッファ ーのテキストの変更では、マーカーが常にバッファー内の同じ2つの文字の間に 位置することを確実にするために、必要に応じて自動的に位置の値が再配置され ます。 マーカーは入力構文をもちません。マーカーはカレントの文字位置とそのバ ッファー名を与える、ハッシュ表記でプリントされます。 (point-marker) ⇒ # マーカーのテスト、作成、コピー、移動の方法についての情報は*note Markers::を参照してください。 2.4.3 ウィンドウ型 ------------------ “ウィンドウ(window)”はEmacsがバッファーを表示するために使用する端末スク リーンの部分を記述します。すべてのウィンドウは関連付けられた1つのバッフ ァーをもち、バッファーの内容はそのウィンドウに表示されます。それとは対照 的に、あるバッファーは1つのウィンドウに表示されるか表示されないか、それ とも複数のウィンドウに表示されるかもしれません。 同時に複数のウィンドウが存在するかもしれませんが、常に1つのウィンドウ が“選択されたウィンドウ(selected window)”になります。Emacsがコマンドにた いして準備できているときは、(通常は)カーソルが表示されるウィンドウが選択 されたウィンドウです。選択されたウィンドウは、通常はカレントバッファー (*note Current Buffer::を参照)を表示しますがこれは必須ではありません。 スクリーン上でウィンドウはフレームにグループ化されます。ウィンドウは それぞれ、ただ1つのフレームだけに属します。*note Frame Type::を参照して ください。 ウィンドウは入力構文をもちません。ウィンドウはウィンドウ番号と表示さ れているバッファー名を与える、ハッシュ表記でプリントされます。与えられた ウィンドウに表示されるバッファーは頻繁に変更されるかもしれないので、一意 にウィンドウを識別するためにウィンドウ番号が存在します。 (selected-window) ⇒ # ウィンドウに作用する関数の説明は*note Windows::を参照してください。 2.4.4 フレーム型 ---------------- “フレーム(frame)”とは1つ以上のEmacsウィンドウを含むスクリーン領域です。 スクリーン領域を参照するためにEmacsが使用するLispオブジェクトを指す場合 にも“フレーム”という用語を使用します。 フレームは入力構文をもちません。フレームはフレームのタイトルとメモリ ー内のアドレス(フレームを一意に識別するのに有用)を与えるハッシュ表記でプ リントされます。 (selected-frame) ⇒ # フレームに作用する関数の説明は*note Frames::を参照してください。 2.4.5 端末型 ------------ “端末(terminal)”は1つ以上のEmacsフレーム(*note Frame Type::を参照)を表示 する能力があるデバイスです。 端末は入力構文をもちません。端末はその端末の順序番号とTTYデバイスファ イル名を与える、ハッシュ表記でプリントされます。 (get-device-terminal nil) ⇒ # 2.4.6 ウィンドウ構成型 ---------------------- “ウィンドウ構成(window configuration)”はフレーム内のウィンドウの位置とサ イズ、内容についての情報を保持します。これにより後で同じウィンドウ配置を 再作成できます。 ウィンドウ構成は入力構文をもちません。ウィンドウ構成のプリント表現は ‘#’のようになります。ウィンドウ構成に関連するいく つかの関数の説明は*note Window Configurations::を参照してください。 2.4.7 フレーム構成型 -------------------- “フレーム構成(frame configuration)”はすべてのフレーム内のウィンドウの位 置とサイズ、内容についての情報を保持します。これは基本型ではありません — 実際のところ、これはCARが‘frame-configuration’でCDRがalistであるようなリ ストです。それぞれのalist要素は、その要素のCARに示される1つのフレームを 記述します。 フレーム構成に関連するいくつかの関数の説明は*note Frame Configurations::を参照してください。 2.4.8 プロセス型 ---------------- “プロセス(process)”という単語は、通常は実行中のプログラムを意味します。 Emacs自身はこの種のプロセス内で実行されます。しかしEmacs Lispでは、プロ セスとはEmacsプロセスにより作成されたサブプロセスを表すLispオブジェクト です。シェル、GDB、ftp、コンパイラーなどのプログラムは、Emacsのサブプロ セスとして実行されEmacsの能力を拡張します。さらに操作を行なうために、 EmacsサブプロセスはEmacsからテキスト入力を受け取り、テキスト出力を Emacsにリターンします。Emacsがサブプロセスにシグナルを送ることもできます 。 プロセスオブジェクトは入力構文をもちません。プロセスオブジェクトはプ ロセス名を与えるハッシュ表記でプリントされます。 (process-list) ⇒ (#) プロセスの作成、削除、プロセスに関する情報のリターン、入力やシグナル の送信、出力の受信を行なう関数についての情報は*note Processes::を参照し てください。 2.4.9 ストリーム型 ------------------ “ストリーム(stream)”とは、文字のソースまたはシンクとして — つまり入力と して文字を供給したり、出力として文字を受け入れるために使用できるオブジェ クトです。多くの異なるタイプ — マーカー、バッファー、文字列、関数をこの 方法で使用できます。ほとんどの場合、入力ストリーム(文字列ソース)はキーボ ード、バッファー、ファイルから文字を受け取り、出力ストリーム(文字シンク )は文字を‘*Help*’バッファーのようなバッファーやエコーエリアに文字を送り ます。 オブジェクト‘nil’は、他の意味に加えてストリームとして使用されることが あります。‘nil’は変数‘standard-input’や‘standard-output’の値を表します。 オブジェクト‘t’も入力としてミニバッファー(*note Minibuffers::を参照)、出 力としてエコーエリア(*note The Echo Area::を参照)の使用を指定するストリ ームになります。 ストリームは特別なプリント表現や入力構文をもたず、それが何であれそれ らの基本型としてプリントされます。 パース関数およびプリント関数を含む、ストリームに関連した関数の説明は *note Read and Print::を参照してください。 2.4.10 キーマップ型 ------------------- “キーマップ(keymap)”はユーザーがタイプした文字をコマンドにマップします。 このマップはユーザーのコマンド入力が実行される方法を制御します。キーマッ プは、実際にはCARがシンボル‘keymap’であるようなリストです。 キーマップの作成、プレフィクスキーの処理、ローカルキーマップやグロー バルキーマップ、キーバインドの変更についての情報は*note Keymaps::を参照 してください。 2.4.11 オーバーレイ型 --------------------- “オーバーレイ(overlay)”はバッファーの一部に適用するプロパティーを指定し ます。それぞれのオーバーレイはバッファーの指定された範囲に適用され、プロ パティーリスト(プロパティー名と値が交互に記述された要素のリスト)を含みま す。オーバーレイプロパティーは、バッファーの指定された一部を、一時的に異 なるスタイルで表示するために使用されます。オーバーレイは入力構文をもたず 、バッファー名と範囲の位置を与えるハッシュ表記でプリントされます。 オーバーレイを作成したり使用する方法についての情報は*note Overlays::を 参照してください。 2.4.12 フォント型 ----------------- “font”はグラフィカルな端末上のテキストを表示する方法を指定します。実際に は異なる3つのフォント型 — “フォントオブジェクト(font objects)”、“フォン トスペック(font specs)”、“フォントエンティティー(font entities)” — が存 在します。これらは入力構文をもちません。これらのプリント構文は ‘#’、‘#’、‘#’のようになります。これ らのLispオブジェクトの説明は*note Low-Level Font::を参照してください。 2.5 循環オブジェクトの読み取り構文 ================================== 複雑な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オブジェクトを記録するこの構文を生成することができ ます。*note Output Variables::を参照してください。 2.6 型のための述語 ================== 関数が呼び出されたとき、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’ *note atom: List-related Predicates.を参照のこと。 ‘arrayp’ *note arrayp: Array Functions.を参照のこと。 ‘bool-vector-p’ *note bool-vector-p: Bool-Vectors.を参照のこと。 ‘bufferp’ *note bufferp: Buffer Basics.を参照のこと。 ‘byte-code-function-p’ *note byte-code-function-p: Byte-Code Type.を参照のこと。 ‘case-table-p’ *note case-table-p: Case Tables.を参照のこと。 ‘char-or-string-p’ *note char-or-string-p: Predicates for Strings.を参照のこと。 ‘char-table-p’ *note char-table-p: Char-Tables.を参照のこと。 ‘commandp’ *note commandp: Interactive Call.を参照のこと。 ‘consp’ *note consp: List-related Predicates.を参照のこと。 ‘custom-variable-p’ *note custom-variable-p: Variable Definitions.を参照のこと。 ‘floatp’ *note floatp: Predicates on Numbers.を参照のこと。 ‘fontp’ *note Low-Level Font::を参照のこと。 ‘frame-configuration-p’ *note frame-configuration-p: Frame Configurations.を参照のこと。 ‘frame-live-p’ *note frame-live-p: Deleting Frames.を参照のこと。 ‘framep’ *note framep: Frames.を参照のこと。 ‘functionp’ *note functionp: Functions.を参照のこと。 ‘hash-table-p’ *note hash-table-p: Other Hash.を参照のこと。 ‘integer-or-marker-p’ *note integer-or-marker-p: Predicates on Markers.を参照のこと。 ‘integerp’ *note integerp: Predicates on Numbers.を参照のこと。 ‘keymapp’ *note keymapp: Creating Keymaps.を参照のこと。 ‘keywordp’ *note Constant Variables::を参照のこと。 ‘listp’ *note listp: List-related Predicates.を参照のこと。 ‘markerp’ *note markerp: Predicates on Markers.を参照のこと。 ‘wholenump’ *note wholenump: Predicates on Numbers.を参照のこと。 ‘nlistp’ *note nlistp: List-related Predicates.を参照のこと。 ‘numberp’ *note numberp: Predicates on Numbers.を参照のこと。 ‘number-or-marker-p’ *note number-or-marker-p: Predicates on Markers.を参照のこと。 ‘overlayp’ *note overlayp: Overlays.を参照のこと。 ‘processp’ *note processp: Processes.を参照のこと。 ‘sequencep’ *note sequencep: Sequence Functions.を参照のこと。 ‘stringp’ *note stringp: Predicates for Strings.を参照のこと。 ‘subrp’ *note subrp: Function Cells.を参照のこと。 ‘symbolp’ *note symbolp: Symbols.を参照のこと。 ‘syntax-table-p’ *note syntax-table-p: Syntax Tables.を参照のこと。 ‘vectorp’ *note vectorp: Vectors.を参照のこと。 ‘window-configuration-p’ *note window-configuration-p: Window Configurations.を参照のこと。 ‘window-live-p’ *note window-live-p: Deleting Windows.を参照のこと。 ‘windowp’ *note windowp: Basic Windows.を参照のこと。 ‘booleanp’ *note booleanp: nil and t.を参照のこと。 ‘string-or-null-p’ *note string-or-null-p: Predicates for Strings.を参照のこと。 あるオブジェクトがどの型かチェックするもっとも一般的な方法は、関数 ‘type-of’の呼び出しです。オブジェクトは、ただ1つだけの基本型に属すること を思い出してください。‘type-of’は、それがどの型かを告げます(*note Lisp Data Types::を参照)。しかし‘type-of’は基本型以外の型については何も知りま せん。ほとんどの場合では、‘type-of’より型述語を使用するほうが便利でしょ う。 -- Function: type-of object この関数はOBJECTの基本型を名前とするシンボルをリターンする。リター ン値はシンボル‘bool-vector’、‘buffer’、‘char-table’、 ‘compiled-function’、‘cons’、‘finalizer’、‘float’、‘font-entity’、 ‘font-object’、‘font-spec’、‘frame’、‘hash-table’、‘integer’、 ‘marker’、‘overlay’、‘process’、‘string’、‘subr’、‘symbol’、 ‘vector’、‘window’、‘window-configuration’のいずれか。 (type-of 1) ⇒ integer (type-of 'nil) ⇒ symbol (type-of '()) ; ‘()’は‘nil’です。 ⇒ symbol (type-of '(x)) ⇒ cons 2.7 同等性のための述語 ====================== ここでは2つのオブジェクトの同一性をテストする関数を説明します。(たとえば 文字列などの)特定の型のオブジェクト同士で内容の同一性をテストするのは、 別の関数を使用します。これらの述語にたいしては、そのデータ型を説明する適 切なチャプターを参照してください。 -- Function: eq object1 object2 この関数はOBJECT1とOBJECT2が同じオブジェクトなら‘t’、それ以外は ‘nil’をリターンする。 OBJECT1とOBJECT2が同じ値をもつ整数なら、これらは同じオブジェクトと 判断される(‘eq’は‘t’をリターンする)。OBJECT1とOBJECT2が同じ名前のシ ンボルなら、通常は同じオブジェクトであるが例外もある。*note Creating Symbols::を参照のこと。(リストやベクター、文字列などの)他 の型にたいしては、同じ内容(または要素)の2つの引数が両者‘eq’である必 要はない。これらが同じオブジェクトの場合だけ‘eq’であり、その場合は 一方の内容を変更するともう一方の内容にも同じ変更が反映される。 (eq 'foo 'foo) ⇒ t (eq 456 456) ⇒ t (eq "asdf" "asdf") ⇒ nil (eq "" "") ⇒ t ;; この例外は省スペースのためにEmacs Lispが ;; マルチバイトの空文字列を1つだけ作成するため (eq '(1 (2 (3))) '(1 (2 (3)))) ⇒ nil (setq foo '(1 (2 (3)))) ⇒ (1 (2 (3))) (eq foo foo) ⇒ t (eq foo '(1 (2 (3)))) ⇒ nil (eq [(1 2) 3] [(1 2) 3]) ⇒ nil (eq (point-marker) (point-marker)) ⇒ nil ‘make-symbol’関数はinternされていないシンボルをリターンする。これは Lisp式内でその名前を記述したシンボルとは区別される。同じ名前の異な るシンボルは‘eq’ではない。*note Creating Symbols::を参照のこと。 (eq (make-symbol "foo") 'foo) ⇒ nil -- Function: equal object1 object2 この関数は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を区別するがテキストプロパティーは考慮しない — こ れは文字列内の文字だけを比較する。*note Text Properties::を参照のこ と。テキストプロパティーも比較する場合には、 ‘equal-including-properties’を使用すること。技術的な理由によりユニ バイト文字列とマルチバイト文字列は、それらが同じ文字シーケンスを含 みすべてのコードが0から127(ASCII)、または160から255(‘8ビットグラフ ィック’)の場合に限り‘equal’となる(*note Text Representations::を参 照)。 (equal "asdf" "ASDF") ⇒ nil しかし2つの別のバッファーは、それらのテキスト内容が同じでも ‘equal’と判断されることはない。 ‘equal’のテストは再帰的に実装されています。たとえば2つのコンスセルXと Yを与えると、‘(equal X Y)’は、以下の式の両方が‘t’をリターンする場合だけ ‘t’をリターンします: (equal (car X) (car Y)) (equal (cdr X) (cdr Y)) これは再帰処理なので循環するリストがあると無限再帰となる(エラーとなる )。 -- Function: equal-including-properties object1 object2 この関数はすべてのケースにおいて‘equal’と同様に振る舞うが、2つの文 字列が‘equal’になるためには、それらが同じテキストプロパティーをもつ 必要がある。 (equal "asdf" (propertize "asdf" 'asdf t)) ⇒ t (equal-including-properties "asdf" (propertize "asdf" 'asdf t)) ⇒ nil 3 数値 ****** 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 整数の基礎 ============== 整数の値の範囲はマシンに依存します。最小の範囲は−536,870,912から 536,870,911(30ビット長の −2**29 から 2**29 − 1) ですが、多くのマシンはこ れより広い範囲を提供します。このチャプターの例の多くは、最小の整数が30ビ ット長であると仮定します。 Lispリーダーは、数字のシーケンス(オプションで最初の符号記号と最後のピ リオドをともなう)として整数を読み取ります。Emacsの範囲を超える整数は浮動 小数点数として扱われます。 1 ; 整数1 1. ; 整数1 +1 ; これも整数1 -1 ; 整数−1 9000000000000000000 ; 浮動小数点数9e18 0 ; 整数0 -0 ; 整数0 基数が10以外の整数の構文では‘#’の後に基数を指定する文字 — 2進は‘b’、 8進は‘o’、16進は‘x’、‘RADIXr’は基数RADIX — を記述します。基数を指定する 文字のcaseは区別されません。したがって‘#bINTEGER’はINTEGERを2進として読 み取り、‘#RADIXrINTEGER’はINTEGERを基数RADIXとして読み取ります。RADIXに 指定できる値は2から36です。たとえば: #b101100 ⇒ 44 #o54 ⇒ 44 #x2c ⇒ 44 #24r1k ⇒ 44 整数にたいして処理を行なうさまざまな関数、特にビット演算(*note Bitwise Operations::を参照)を理解するためには、数を2進形式で見ることが助 けになることがよくあります。 30ビットの2進では10進数の整数5は以下のようになります: 0000...000101 (全部で30ビット) (‘...’は30ビットのワードを満たすのに充分なビットを意味しており、この場合 の‘...’は12個の0ビットを意味する。以下の例でも2進の整数を読みやすくする ために、‘...’の表記を使用している。) 整数の−1は以下のようになります: 1111...111111 (全部で30ビット) −1は30個の1で表現されます(“2の補数”表記と呼ばれる)。 −1から4を減じることで負の整数−5が得られます。10進の整数4は2進では 100です。したがって−5は以下のようになります: 1111...111011 (全部で30ビット) この実装では、0ビットの2進の最大は10進の536,870,911です。これは2進で は以下のようになります: 0111...111111 (全部で30ビット) 算術関数は整数が範囲外かどうかをチェックしないので、536,870,911に1を 加えるとその値は負の整数−536,870,912になります: (+ 1 536870911) ⇒ -536870912 ⇒ 1000...000000 (全部で30ビット) このチャプターで説明する多くの関数は、数字の位置として引数にマーカー (*note Markers::を参照)を受け取ります。そのような関数にたいする実際の引 数は数字かマーカーなので、わたしたちはこれらの引数にNUMBER-OR-MARKERとい う名前を与えることがあります。引数の値がマーカーならマーカーの位置が使用 され、マーカーのバッファーは無視されます。 -- Variable: most-positive-fixnum この変数の値はEmacs Lispが扱える整数の最大値。典型的な値は32ビット では 2**29 − 1 、64ビットでは 2**61 − 1 。 -- Variable: most-negative-fixnum この変数の値はEmacs Lispが扱える最小の整数。これは負の整数になる。 典型的な値は32ビットでは −2**29 、64ビットでは −2**61、 。 Emacs Lispでは、テキスト文字は整数により表現されます。0から ‘(max-char)’までの整数は、有効な文字として判断されます。*note Character Codes::を参照してください。 3.2 浮動小数点数の基礎 ====================== 浮動小数点数は整数ではない数を表現するのに有用です。浮動小数点数の範囲は 、使用しているマシンでのCデータ型の‘double’と同じ範囲です。Emacsで現在サ ポートされているすべてのコンピューターでは、これは倍精度のIEEE浮動小数点 数です。 浮動小数点数にたいする入力構文は、小数点と指数のどちらか1つ、または両 方が必要とします。オプションの符号(‘+’か‘-’)は、その数字と指数の前に記述 します。たとえば‘1500.0’、‘+15e2’、‘15.0e+2’、‘+1500000e-3’、‘.15e4’は値 が1500の浮動小数点数を記述する5つの方法です。これらはすべて等価です。 Common Lispと同様、Emacs Lispは浮動小数点数の小数点の後に少なくとも1つの 数字を必要とします。‘1500.’は整数であって浮動小数点数ではありません。 Emacs Lispは‘equal’と‘=’に関して、‘-0.0’を通常の0と数学的に同じものと して扱います。これは、(他の処理がこれらを区別にしても‘-0.0’と‘0.0’は数学 的に等しいとする)IEEE浮動小数点数規格にしたがっています。 IEEE浮動小数点数規格は浮動小数点数として、正の無限大と負の無限大をサ ポートします。この規格はNaNまたは“not a number(数字ではない)”と呼ばれる 値クラスも提供します。正しい答えが存在しないような場合に、数学関数はこの ような値をリターンします。たとえば‘(/ 0.0 0.0)’はNaNをリターンします。実 用に際し、たとえNaN値に符号がついていたとしても、Emacs Lispでは異なる NaN値に有意な差はありません。 以下は、これらの特別な浮動小数点数にたいする入力構文です: infinity ‘1.0e+INF’と‘-1.0e+INF’ not-a-number ‘0.0e+NaN’と‘-0.0e+NaN’ 以下の関数は浮動小数点数を扱うために特化したものです: -- Function: isnan x この述語は浮動小数引数がNaNなら‘t’、それ以外は‘nil’をリターンする。 -- Function: frexp x この関数はコンスセル‘(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。 -- Function: ldexp s e 数値の仮数Sと整数の指数Eを与えられると、この関数は浮動小数点数 S * 2**Eをリターンする。 -- Function: copysign x1 x2 この関数はX2の符号をX1の値にコピーして結果をリターンする。X1とX2は 浮動小数でなければならない。 -- Function: logb x この関数はXの2進指数をリターンする。より正確には、これは|x|の2を底 とする対数を整数に切り下げた値。 (logb 10) ⇒ 3 (logb 10.0e20) ⇒ 69 3.3 数値のための述語 ==================== このセクションの関数は数値や、特定の数値型にたいしてテストを行ないます。 関数‘integerp’と‘floatp’は、引数として任意のLispオブジェクト型をとること ができます(でなければ、あまり使用する機会ない)。しかし述語‘zerop’は引数 として数値を要求します。*note Predicates on Markers::の ‘integer-or-marker-p’、‘number-or-marker-p’も参照してください。 -- Function: floatp object この述語は引数が浮動小数かどうかをテストしてもしそうなら‘t’、それ以 外は‘nil’をリターンする。 -- Function: integerp object この述語は引数が整数かどうかをテストしてもしそうなら‘t’、それ以外は ‘nil’をリターンする。 -- Function: numberp object この述語は引数が数(整数か浮動小数)かどうかをテストしてもしそうなら ‘t’、それ以外は‘nil’をリターンする。 -- Function: natnump object この述語は引数が正の整数かどうかをテストしてもしそうなら‘t’、それ以 外は‘nil’をリターンする(名前は“natural numberl: 自然数”が由来)。0は 整数と判断される。 ‘wholenump’は‘natnump’のシノニム。 -- Function: zerop number この述語は引数が0かどうかをテストしてもしそうなら‘t’、それ以外は ‘nil’をリターンする。引数は数でなければならない。 ‘(zerop x)’は‘(= x 0)’と等価。 3.4 数値の比較 ============== 数が数値的に等しいかのテストには、‘eq’ではなく通常は‘=’を使用するべきで す。同じ数値をもつ多くの浮動小数オブジェクトが存在するかもしれません。こ れらを比較するのに‘eq’を使用する場合、これは2つの値が同じオブジェクトか どうかをテストすることになります。対照的に‘=’はオブジェクトの数値的な値 だけを比較します。 Emacs Lispでは、それぞれの整数は一意なLispオブジェクトです。したがっ て整数に関しては‘eq’は‘=’と同じです。未知の整数の値の比較に、‘eq’を使用 する方が便利な場合があります。なぜなら未知の値が数でない場合でも‘eq’はエ ラーを報告しないからです。対照的に引数が数でもマーカーでもない場合、 ‘=’はエラーをシグナルします。しかし整数の比較においてさえ、使用できる場 合は‘=’を使用するのがよいプログラミング習慣です。 数の比較において、2つの数が同じデータ型(どちらも整数か浮動小数)では、 同じ値の場合は等しい数として扱う‘equal’のほうが便利なときもあります。対 照的に‘=’は整数と浮動小数点数を等しい数と扱うことができます。*note Equality Predicates::を参照してください。 他の欠点もあります。浮動小数演算は正確ではないので、浮動小数値を比較 するのが悪いアイデアとなるときがよくあります。通常は近似的に等しいことを テストするほうがよいでしょう。以下はこれを行なう関数です: (defvar fuzz-factor 1.0e-6) (defun approx-equal (x y) (or (= x y) (< (/ (abs (- x y)) (max (abs x) (abs y))) fuzz-factor))) Common Lispに関する注意: Common Lispは複数ワード整数を実装していて 、2つの別の整数オブジェクトが同じ数値的な値をもつことができるので、 Common Lispでの数の比較はには常に‘=’が要求されます。Emacs Lispの整 数は範囲が制限されているため、与えられた値に対応する整数オブジェク トは1つだけです。 -- Function: = number-or-marker &rest number-or-markers この関数はすべての引数が数値的に等しいかどうかをテストしてもしそう なら‘t’、それ以外は‘nil’をリターンする。 -- Function: eql value1 value2 この関数は‘eq’と同様に振る舞うが引数が両方とも数のときを除く。これ は数を型と数値的な値により比較するので、‘(eql 1.0 1)’は‘nil’をリタ ーンするが、‘(eql 1.0 1.0)’と‘(eql 1 1)’は‘t’をリターンする。 -- Function: /= number-or-marker1 number-or-marker2 この関数は引数が数値的に等しいかどうかをテストして、もし異なる場合 は‘t’、等しい場合は‘nil’をリターンする。 -- Function: < number-or-marker &rest number-or-markers この関数は、各引数それぞれを後の引数より小さいかどうかをテストして もしそうなら‘t’、それ以外は‘nil’をリターンする。 -- Function: <= number-or-marker &rest number-or-markers この関数は、各引数それぞれが後の引数以下かどうかをテストしてもしそ うなら‘t’、それ以外は‘nil’をリターンする。 -- Function: > number-or-marker &rest number-or-markers この関数は、各引数それぞれが後の引数より大きいかどうかをテストして もしそうなら‘t’、それ以外は‘nil’をリターンする。 -- Function: >= number-or-marker &rest number-or-markers この関数は、各引数それぞれが後の引数以上かどうかをテストしてもしそ うなら‘t’、それ以外は‘nil’をリターンする。 -- Function: max number-or-marker &rest numbers-or-markers この関数は引数の最大をリターンする。引数のどれかが浮動小数なら、た とえ最大が整数であっても浮動小数として値がリターンする。 (max 20) ⇒ 20 (max 1 2.5) ⇒ 2.5 (max 1 3 2.5) ⇒ 3.0 -- Function: min number-or-marker &rest numbers-or-markers この関数は引数の最小をリターンする。引数のどれかが浮動小数なら、た とえ最小が整数であっても浮動小数として値がリターンする。 (min -4 1) ⇒ -4 -- Function: abs number この関数はNUMBERの絶対値をリターンする。 3.5 数値の変換 ============== 整数を浮動少数の変換には関数‘float’を使用します。 -- Function: float number これは浮動小数点数に変換されたNUMBERをリターンする。すでにNUMBERが 浮動小数点数なら‘float’はそれを変更せずにリターンする。 浮動小数点数を整数に変換する関数が4つあります。これらは浮動小数点数を 丸める方法が異なります。これらはすべて引数NUMBER、およびオプション引数と してDIVISORを受け取ります。引数は両方とも整数か浮動小数点数です。 DIVISORが‘nil’のこともあります。DIVISORが‘nil’または省略された場合、これ らの関数はNUMBERを整数に変換するか、それが既に整数の場合は変更せずにリタ ーンします。DIVISORが非‘nil’なら、これらの関数はNUMBERをDIVISORで除して 結果を整数に変換します。DIVISORが(整数か浮動小数かに関わらず)0の場合、 Emacsは‘arith-error’エラーをシグナルします。 -- Function: truncate number &optional divisor これは0に向かって丸めることにより整数に変換したNUMBERをリターンする 。 (truncate 1.2) ⇒ 1 (truncate 1.7) ⇒ 1 (truncate -1.2) ⇒ -1 (truncate -1.7) ⇒ -1 -- Function: floor number &optional divisor これは下方(負の無限大に向かって)に丸めることにより整数に変換した NUMBERをリターンする。 DIVISORが指定された場合には、‘mod’に相当する種類の除算演算を使用し て下方に丸めを行う。 (floor 1.2) ⇒ 1 (floor 1.7) ⇒ 1 (floor -1.2) ⇒ -2 (floor -1.7) ⇒ -2 (floor 5.99 3) ⇒ 1 -- Function: ceiling number &optional divisor これは上方(正の無限大に向かって)に丸めることにより整数に変換した NUMBERをリターンする。 (ceiling 1.2) ⇒ 2 (ceiling 1.7) ⇒ 2 (ceiling -1.2) ⇒ -1 (ceiling -1.7) ⇒ -1 -- Function: round number &optional divisor これはもっとも近い整数に向かって丸めることにより、整数に変換した NUMBERをリターンする。2つの整数から等距離にある値の丸めでは、偶数の 整数をリターンする。 (round 1.2) ⇒ 1 (round 1.7) ⇒ 2 (round -1.2) ⇒ -1 (round -1.7) ⇒ -2 3.6 算術演算 ============ Emacs Lispは伝統的な4つの算術演算(加減乗除)、同様に剰余とmodulusの関数、 および1の加算と減算を行う関数を提供します。‘%’を除き、これらの各関数は引 き数として整数か浮動小数を受け取り、浮動小数の引数がある場合は浮動小数点 数をリターンします。 Emacs Lispの算術関数は整数のオーバーフローをチェックしません。したが って‘(1+ 536870911)’は−536870912に評価されるかもしれず、それはハードウェ アーに依存します。 -- Function: 1+ number-or-marker この関数はNUMBER-OR-MARKER + 1をリターンする。例えば、 (setq foo 4) ⇒ 4 (1+ foo) ⇒ 5 この関数はCの演算子‘++’とは異なり、変数をインクリメントしない。この 関数は和を計算するだけである。したがって以下を続けて評価すると、 foo ⇒ 4 変数をインクリメントしたい場合は、以下のように‘setq’を使用しなけれ ばならない: (setq foo (1+ foo)) ⇒ 5 -- Function: 1- number-or-marker この関数はNUMBER-OR-MARKER − 1をリターンする。 -- Function: + &rest numbers-or-markers この関数は引数すべてを加算する。引数を与えないと‘+’は0をリターンす る。 (+) ⇒ 0 (+ 1) ⇒ 1 (+ 1 2 3 4) ⇒ 10 -- Function: - &optional number-or-marker &rest more-numbers-or-markers ‘-’関数は2つの目的 — 符号反転と減算 — をもつ。‘-’に1つの引数を与え ると、値は引数の符号を反転したものになる。複数の引数の場合は、 NUMBER-OR-MARKERからMORE-NUMBERS-OR-MARKERSまでの各値を蓄積的に減算 する。引数がなければ結果は0。 (- 10 1 2 3 4) ⇒ 0 (- 10) ⇒ -10 (-) ⇒ 0 -- Function: * &rest numbers-or-markers この関数はすべての引数を乗じて積をリターンする。引数がなかれば‘*’は 1をリターンする。 (*) ⇒ 1 (* 1) ⇒ 1 (* 1 2 3 4) ⇒ 24 -- Function: / number &rest divisors 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’エラー(*note Errors::を参 照)をシグナルする。浮動小数点数の除算では、非0の数を0で除することで 正の無限大または負の無限大を得る(*note Float Basics::を参照)。 -- Function: % dividend divisor この関数は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 -- Function: mod dividend divisor この関数は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’については、*note Numeric Conversions::を参照のこと。 3.7 丸め処理 ============ 関数‘ffloor’、‘fceiling’、‘fround’、‘ftruncate’は浮動小数の引数をとり、 値が近くの整数であるような浮動少数をリターンします。‘ffloor’は一番近い下 方の整数、‘fceiling’は一番近い上方の整数、‘ftruncate’は0に向かう方向で一 番近い整数、‘fround’は一番近い整数をリターンします。 -- Function: ffloor float この関数はFLOATを次に小さい整数値に丸めて、その値を浮動小数点数とし てリターンする。 -- Function: fceiling float この関数はFLOATを次に大きい整数値に丸めて、その値を浮動小数点数とし てリターンする。 -- Function: ftruncate float この関数はFLOATを0方向の整数値に丸めて、その値を浮動小数点数として リターンする。 -- Function: fround float この関数はFLOATを一番近い整数値に丸めて、その値を浮動小数点数として リターンする。2つの整数値との距離が等しい値にたいする丸めでは、偶数 の整数をリターンする。 3.8 ビット演算 on Integers ========================== コンピューターの中では、整数は“ビット(bit: 0か1の数字)”のシーケンスであ る2進数で表されます。ビット演算は、そのようなシーケンスの中の個々のビッ トに作用します。たとえば“シフト(shifting)”はシーケンス全体を1つ以上左ま たは右に移動して、移動されたのと同じパターンを再現します。 Emacs Lispのビット演算は整数だけに適用されます。 -- Function: lsh integer1 count ‘lsh’は“logical shift”の略で、INTEGER1のビットを左にCOUNT個シフトす る。COUNTが負なら右にシフトし、シフトにより空きになったビットには 0がセットされる。COUNTが負なら‘lsh’は左端(最上位)に0をシフトするの で、INTEGER1が負の場合でも正の結果が生成される。これと対照的なのが 以下で説明する‘ash’である。 以下は‘lsh’でビットパターンの位置を1つ左にシフトする例である。ここ では下位8ビットの2進パターンだけを表示しており、残りのビットはすべ て0である。 (lsh 5 1) ⇒ 10 ;; 10進の5が10進の10になる 00000101 ⇒ 00001010 (lsh 7 1) ⇒ 14 ;; 10進の7は10進の14になる 00000111 ⇒ 00001110 この例が示すように、ビットパターンを左に1シフトすると、生成される数 は元の数の2倍になる。 ビットパターンを左に2シフトすると、以下の結果が生成される(8ビット 2進数): (lsh 3 2) ⇒ 12 ;; 10進の3が10進の12になる 00000011 ⇒ 00001100 一方、右に1シフトすると以下のようになる: (lsh 6 -1) ⇒ 3 ;; 10進の6は10進の3になる 00000110 ⇒ 00000011 (lsh 5 -1) ⇒ 2 ;; 10進の5は10進の2になる 00000101 ⇒ 00000010 例で明らかなように右に1シフトすることにより、正の整数の値が2で除さ れ下方に丸められる。 関数‘lsh’は他のEmacs Lisp算術関数と同様、オーバーフローをチェックし ないので、左にシフトすることにより上位ビットが捨てられ、その数の符 号が変化するかもしれない。たとえば30ビットの実装では、536,870,911を 左にシフトすると−2が生成されます。 (lsh 536870911 1) ; 左シフト ⇒ -2 2進ではこの引数は以下のようになる: ;; 10進の536,870,911 0111...111111 (全部で30ビット) これを左にシフトすると以下のようになる: ;; 10進の−2 1111...111110 (全部で30ビット) -- Function: ash integer1 count ‘ash’ (“算術シフト(arithmetic shift)”)は、INTEGER1の中のビット位置 を左にCOUNTシフトする。COUNTが負なら右にシフトする。 ‘ash’は‘lsh’と同じ結果を与えるが、例外はINTEGER1とCOUNTがいずれも負 の場合である。この場合、‘lsh’は左にできる空きビットに0、‘ash’は1を 置く。 したがって‘ash’でビットパターンの位置を右に1シフトすると以下のよう になる: (ash -6 -1) ⇒ -3 ;; 10進の−6は10進の−3になる 1111...111010 (30 bits total) ⇒ 1111...111101 (30 bits total) 対照的に、‘lsh’でビットパターンの位置を1右にシフトすると以下のよう になる: (lsh -6 -1) ⇒ 536870909 ;; 10進の−6は10進の536,870,909になる 1111...111010 (30 bits total) ⇒ 0111...111101 (30 bits total) 他にも例を示す: ; 30ビットの2進数 (lsh 5 2) ; 5 = 0000...000101 ⇒ 20 ; = 0000...010100 (ash 5 2) ⇒ 20 (lsh -5 2) ; -5 = 1111...111011 ⇒ -20 ; = 1111...101100 (ash -5 2) ⇒ -20 (lsh 5 -2) ; 5 = 0000...000101 ⇒ 1 ; = 0000...000001 (ash 5 -2) ⇒ 1 (lsh -5 -2) ; -5 = 1111...111011 ⇒ 268435454 ; = 0011...111110 (ash -5 -2) ; -5 = 1111...111011 ⇒ -2 ; = 1111...111110 -- Function: logand &rest ints-or-markers この関数は引数のビットのANDをリターンする。すべての引数のN番目のビ ットが1の場合に限り、結果のN番目のビットが1となる。 たとえば13と12では、4ビット2進数を使用すると1101と1100のビットANDは 1100を生成する。この2進数ではいずれも左の2ビットがセット(つまり1)さ れているので、リターンされる値の左2ビットがセットされる。しかし右の 2ビットにたいしては少なくとも1つの引数でそのビットが0なので、リター ンされる値の右2ビットは0になる。 したがって、 (logand 13 12) ⇒ 12 ‘logand’に何も引数も渡さなければ、値−1がリターンされる。−1を2進数で 表すとすべてのビットが1なので、−1は‘logand’にたいする単位元 (identity element)である。 ; 30ビット2進数 (logand 14 13) ; 14 = 0000...001110 ; 13 = 0000...001101 ⇒ 12 ; 12 = 0000...001100 (logand 14 13 4) ; 14 = 0000...001110 ; 13 = 0000...001101 ; 4 = 0000...000100 ⇒ 4 ; 4 = 0000...000100 (logand) ⇒ -1 ; -1 = 1111...111111 -- Function: logior &rest ints-or-markers この関数は、引数のビット単位の包含的ORをリターンする。少なくとも1つ の引数でN番目のビットが1なら、結果のN番目のビットが1になる。引数を 与えなければ、結果はこの処理にたいする単位元である0となる。 ‘logior’に渡す引数が1つだけならその引数がリターンされる。 ; 30ビット2進数 (logior 12 5) ; 12 = 0000...001100 ; 5 = 0000...000101 ⇒ 13 ; 13 = 0000...001101 (logior 12 5 7) ; 12 = 0000...001100 ; 5 = 0000...000101 ; 7 = 0000...000111 ⇒ 15 ; 15 = 0000...001111 -- Function: logxor &rest ints-or-markers この関数は、引数のビット単位の排他的ORをリターンする。N番目のビット が1であるような引数の数が奇数個の場合のみ、結果のN番目のビットが1と なる。引数を与えなければ、結果はこの処理の単位元である0となる。 ‘logxor’に渡す引数が1つだけならその引数がリターンされる。 ; 30ビット2進数 (logxor 12 5) ; 12 = 0000...001100 ; 5 = 0000...000101 ⇒ 9 ; 9 = 0000...001001 (logxor 12 5 7) ; 12 = 0000...001100 ; 5 = 0000...000101 ; 7 = 0000...000111 ⇒ 14 ; 14 = 0000...001110 -- Function: lognot integer この関数は引数のビット単位の補数(bitwise complement)をリターンする 。INTEGERのN番目のビットが0の場合に限り、結果のN番目のビットが1にな り、その逆も成り立つ。 (lognot 5) ⇒ -6 ;; 5 = 0000...000101 (全部で30ビット) ;; becomes ;; -6 = 1111...111010 (全部で30ビット) 3.9 標準的な数学関数 ==================== 以下の数学的関数は、引数として整数と同様に浮動小数点数も受け入れます。 -- Function: sin arg -- Function: cos arg -- Function: tan arg これらは三角関数であり、引数ARGはラジアン単位。 -- Function: asin arg ‘(asin ARG)’の値は、sinの値がARGとなるような −pi/2 から pi/2 (両端 を含む)の数である。ARGが範囲外([−1, 1]の外)なら、‘asin’はNaNをリタ ーンする。 -- Function: acos arg ‘(acos ARG)’の値は、cosの値がARGとなるような、0から pi (両端を含む )の数である。argが範囲外([-1, 1]の外)なら‘acos’はNaNをリターンする 。 -- Function: atan y &optional x ‘(atan Y)’の値は、tanの値がYとなるような、 −pi/2 から pi/2 (両端を 含まず)の数である。オプションの第2引数Xが与えられると、‘(atan y x)’の値はベクトル‘[X, Y]’と‘X’軸が成す角度のラジアン値となる。 -- Function: exp arg これは指数関数である。この関数はeの指数ARGをリターンする。 -- Function: log arg &optional base この関数は底をBASEとするARGの対数をリターンする。BASEを指定しなけれ ば、自然底(natural base)eが使用される。ARGかBASEが負なら、‘log’は NaNをリターンする。 -- Function: expt x y この関数はXにYを乗じてリターンする。引数が両方とも整数でYが正なら結 果は整数になる。この場合オーバーフローによる切り捨てが発生するので 注意しされたい。Xが有限の負数でYが有限の非整数なら、‘expt’はNaNをリ ターンする。 -- Function: sqrt arg これはARGの平方根をリターンする。ARGが有限で0より小さければ、 ‘sqrt’はNaNをリターンする。 加えて、Emacsは以下の数学的な定数を定義します: -- Variable: float-e 自然対数e(2.71828...) -- Variable: float-pi 円周率pi(3.14159...) 3.10 乱数 ========= 決定論的なコンピュータープログラムでは真の乱数を生成することはできません 。しかしほとんどの目的には、“疑似乱数(pseudo-random numbers)”で充分です 。一連の疑似乱数は決定論的な手法により生成されます。真の乱数ではありませ んが、それらにはランダム列を模する特別な性質があります。たとえば疑似ラン ダム系では、すべての可能な値は均等に発生します。 疑似乱数は“シード値(seed value)”から生成されます。与えられた任意のシ ードから開始することにより、‘random’関数は常に同じ数列を生成します。デフ ォルトでは、Emacsは開始時に乱数シードを初期化することにより、それぞれの Emacsの実行において、‘random’の値シーケンスは(ほとんど確実に)異なります 。 再現可能な乱数シーケンスが欲しい場合もあります。たとえば乱数シーケン スに依存するプログラムをデバッグする場合、プログラムの各実行において同じ 挙動を得ることが助けになります。再現可能なシーケンスを作成するには、 ‘(random "")’を実行します。これは特定のEmacsの実行可能ファイルにたいして 、シードに定数値をセットします(しかしこの実行可能ファイルは、その他の Emacsビルドと異なるものになるであろう)。シード値として、他のさまざまな文 字列を使用することができます。 -- Function: random &optional limit この関数は疑似乱数の整数をリターンする。繰り返し呼び出すと一連の疑 似乱数の整数をリターンする。 LIMITが正なら、値は負ではないLIMIT未満の値から選択される。それ以外 なら値は‘most-negative-fixnum’から‘most-positive-fixnum’の間の、 Lispで表現可能な任意の整数(*note Integer Basics::を参照)となるだろ う。 LIMITが‘t’なら、あたかもEmacsが再起動されたかのように、通常はシステ ムのエントロピーから新たなシードが選択されることを意味する。エント ロピープールを欠くシステムでは、カレント時刻のような若干揮発性が低 い乱数からシードが選択される。 LIMITが文字列なら、その文字列定数にもとづいた新しいシードを選択する ことを意味する。 4 文字列と文字 ************** Emacs Lispの文字列は、文字列の順序列(ordered sequence)を含む配列です。文 字列はシンボル、バッファー、ファイルの名前に使用されます。その他にもユー ザーにたいしてメッセージを送ったりバッファー間でコピーする文字列を保持し たり等、多くの目的に使用されます。文字列は特に重要なので、Emacs Lispは特 別には文字列を操作するために多くの関数があります。Emacs Lispプログラムで は個々の文字より文字列を多用します。 キーボードの文字イベントの文字列にたいする特別な考慮は、*note Strings of Events::を参照してください。 4.1 文字列と文字の基礎 ====================== 文字(character)とは、テキスト内の1つの文字を表すLispオブジェクトです。 Emacs Lispでは文字は単なる整数です。ある整数が文字か文字でないかを区別す るのは、それが使用される方法だけです。Emacsでの文字表現についての詳細は *note Character Codes::を参照してください。 文字列(string)とは固定された文字シーケンスです。これは“配列(array)”と 呼ばれるシーケンス型であり、配列長が固定で一度作成したら変更できないこと を意味します(*note Sequences Arrays Vectors::を参照)。Cとは異なり、Emacs Lispの文字列は文字コードを判断することにより_終端されません_。 文字列は配列であるということは同様にシーケンスでもあるので、*note Sequences Arrays Vectors::にドキュメントされている一般的な配列関数やシー ケンス関数で文字列を処理できます。たとえば文字列内の特定の文字にアクセス したり変更することができます。しかし表示された文字列の幅を計算するために 、‘length’を_使用するべきではない_ことに注意してください。かわりに ‘string-width’を使用してください(*note Size of Displayed Text::を参照)。 Emacs文字列での非ASCIIにたいすテキスト表現は2つ — ユニバイト (unibyte)とマルチバイト(multibyte)があります。ほとんどのLispプログラミン グでは、これら2つの表現を気にする必要はありません。詳細は*note Text Representations::を参照してください。 キーシーケンスがユニバイト文字列で表されることがあります。ユニバイト 文字列がキーシーケンスの場合、範囲128から255までの文字列要素は範囲128か ら255の文字コードではなく、メタ文字(これは非常に大きな整数である)を表し ます。文字列はハイパー(hyper)、スーパー(super)、アルト(alt)で修飾された 文字を保持できません。文字列はASCIIコントロール文字を保持できますが、そ れは他のコントロール文字です。文字列はASCIIコントロール文字のcaseを区別 できません。そのような文字をシーケンスに保存したい場合は、文字列ではなく ベクターを使用しなければなりません。キーボード入力文字についての情報は *note Character Type::を参照してください。 文字列は正規表現を保持するために便利です。‘string-match’ (*note Regexp Search::を参照)を使用して、文字列にたいして正規表現をマッチするこ ともできます。関数‘match-string’ (*note Simple Match Data::を参照)と ‘replace-match’ (*note Replacing Match::を参照)は、文字列にたいして正規 表現をマッチした後に、文字列を分解・変更するのに便利です。 バッファーのように、文字列は文字列内の文字自身とその文字にたいするテ キストプロパティーを含みます。*note Text Properties::を参照してください 。文字列からバッファーや他の文字列にテキストをコピーする、すべてのLispプ リミティブ(Lisp primitives)はコピーされる文字のプロパティーもコピーしま す。 文字列の表示やバッファーにコピーする関数についての情報は*note Text::を 参照してください。文字または文字列の構文についての情報は、*note Character Type::と*note String Type::を参照してください。異なるテキスト 表現間で変換したり、文字コードをエンコード、デコードする関数については *note Non-ASCII Characters::を参照してください。 4.2 文字列のための述語 ====================== 一般的なシーケンスや配列にたいする述語についての情報は、*note Sequences Arrays Vectors::と*note Arrays::を参照してください。 -- Function: stringp object この関数はOBJECTが文字列なら‘t’、それ以外は‘nil’をリターンする。 -- Function: string-or-null-p object この関数はOBJECTが文字列か‘nil’なら‘t’、それ以外は‘nil’をリターンす る。 -- Function: char-or-string-p object この関数はOBJECTが文字列か文字(たとえば整数)なら‘t’、それ以外は ‘nil’をリターンする。 4.3 文字列の作成 ================ 以下の関数は新たに文字列を作成したり、文字列同士の結合による文字列の作成 や、文字列の一部から文字列を作成する関数です。 -- Function: make-string count character この関数はCHARACTERをCOUNT回繰り返すことにより作成された文字列をリ ターンする。COUNTが負ならエラーをシグナルする。 (make-string 5 ?x) ⇒ "xxxxx" (make-string 0 ?x) ⇒ "" この関数に対応する他の関数には‘make-vector’ (*note Vectors::を参照 )や‘make-list’ (*note Building Lists::を参照)が含まれる。 -- Function: string &rest characters この関数は文字CHARACTERSを含む文字列をリターンする。 (string ?a ?b ?c) ⇒ "abc" -- Function: substring string &optional start end この関数は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’を推奨する(*note Sequence Functions::を参照)。 STRINGからコピーされた文字がテキストプロパティーをもつなら、そのプ ロパティーは新しい文字列へもコピーされる。*note Text Properties::を 参照のこと。 ‘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’ (*note Buffer Contents::を 参照)で、これはカレントバッファー内のテキストの一部を含む文字列をリ ターンする。文字列の先頭はインデックス0だが、バッファーの先頭はイン デックス1である。 -- Function: substring-no-properties string &optional start end これは‘substring’と同じように機能するが、値のすべてのテキストプロパ ティーを破棄する。STARTを省略したり‘nil’を指定することができ、その 場合は0と等価だる。したがって‘(substring-no-properties STRING)’は、 すべてのテキストプロパティーが削除されたSTRINGのコピーをリターンす る。 -- Function: concat &rest sequences この関数は渡された引数内の文字からなる、新しい文字列をリターンする (もしあればテキストプロパティーも)。引数には文字列、数のリスト、数 のベクターを指定できる。引数は変更されない。‘concat’に引数を指定し なければ空文字列をリターンする。 (concat "abc" "-def") ⇒ "abc-def" (concat "abc" (list 120 121) [122]) ⇒ "abcxyz" ;; ‘nil’hあ空のシーケンス。 (concat "abc" nil "-def") ⇒ "abc-def" (concat "The " "quick brown " "fox.") ⇒ "The quick brown fox." (concat) ⇒ "" この関数は常に、任意の既存文字列にたいして‘eq’ではない、新しい文字 列を構築するが、結果が空文字列の時を除く(スペース省略のために Emacsは空のマルチバイト文字列を1つだけ作成する)。 他の結合関数(concatenation functions)についての情報は*note Mapping Functions::の‘mapconcat’、*note Vector Functions::の‘vconcat’、 *note Building Lists::の‘append’を参照のこと。シェルコマンドで使用 される文字列の中に、個々のコマンドライン引数を結合するには、*note combine-and-quote-strings: Shell Arguments.を参照されたい。 -- Function: split-string string &optional separators omit-nulls trim この関数は正規表現SEPARATORS(*note Regular Expressions::を参照)にも とづいて、STRINGを部分文字列に分解する。SEPARATORSにたいする各マッ チは分割位置を定義する。分割位置の間にある部分文字列をリストにまと めてリターンする。 OMIT-NULLSが‘nil’(または省略)なら、連続する2つのSEPARATORSへのマッ チか、STRINGの最初か最後にマッチしたときの空文字列が結果に含まれる 。OMIT-NULLSが‘t’なら、これらの空文字列は結果から除外される。 SEPARATORSが‘nil’(または省略)なら、デフォルトは ‘split-string-default-separators’の値となる。 特別なケースとしてSEPARATORSが‘nil’(または省略)なら、常に結果から空 文字列が除外される。したがって: (split-string " two words ") ⇒ ("two" "words") 有用性はほとんどないであろう‘("" "two" "words" "")’という結果とはな らない。このような結果が必要ならSEPARATORSに明示的な値を使用するこ と (split-string " two words " split-string-default-separators) ⇒ ("" "two" "words" "") 他にも例を示す: (split-string "Soup is good food" "o") ⇒ ("S" "up is g" "" "d f" "" "d") (split-string "Soup is good food" "o" t) ⇒ ("S" "up is g" "d f" "d") (split-string "Soup is good food" "o+") ⇒ ("S" "up is g" "d f" "d") 空のマッチはカウントされます。例外は、空でないマッチを使用すること により、すでに文字列の最後に到達しているとき、またはSTRINGが空の時 で、この場合‘split-string’は最後の空マッチを探しません。 (split-string "aooob" "o*") ⇒ ("" "a" "" "b" "") (split-string "ooaboo" "o*") ⇒ ("" "" "a" "b" "") (split-string "" "") ⇒ ("") しかしSEPARATORSが空文字列にマッチできるとき、通常はOMIT-NULLSを ‘t’にすれば、前の3つの例の不明瞭さはほとんど発生しない: (split-string "Soup is good food" "o*" t) ⇒ ("S" "u" "p" " " "i" "s" " " "g" "d" " " "f" "d") (split-string "Nice doggy!" "" t) ⇒ ("N" "i" "c" "e" " " "d" "o" "g" "g" "y" "!") (split-string "" "" t) ⇒ nil 空でないマッチより空のマッチを優先するような、一部の“非貪欲 (non-greedy)”な値をSEPARATORSに指定することにより、幾分奇妙(ではあ るが予見可能)な振る舞いが発生することがある。繰り返しになるが、その ような値は実際には稀である: (split-string "ooo" "o*" t) ⇒ nil (split-string "ooo" "\\|o+" t) ⇒ ("o" "o" "o") オプションの引数TRIMが非‘nil’なら、その値は各部分文字列の最初と最後 からトリム(trim: 除去)するテキストにマッチする正規表現を指定する。 トリムによりその部分文字列が空になるようなら、それは空文字列として 扱われる。 文字列を分割して‘call-process’や‘start-process’に適するような、個々 のコマンドライン引数のリストにする必要がある場合は、*note split-string-and-unquote: Shell Arguments.を参照されたい。 -- Variable: split-string-default-separators ‘split-string’のSEPARATORSにたいするデフォルト値。通常の値は ‘"[ \f\t\n\r\v]+"’。 4.4 文字列の変更 ================ 既存の文字列の内容を変更するもっとも基本的な方法は、‘aset’ (*note Array Functions::を参照)を使用する方法です。‘(aset STRING IDX CHAR)’は、 STRINGのインデックスIDXに、CHARを格納します。それぞれの文字は1文字以上を 占有しますが、すでにインデックスの場所にある文字のバイト数がCHARが要する バイト数と異なる場合、‘aset’はエラーをシグナルします。 より強力な関数は‘store-substring’です: -- Function: store-substring string idx obj この関数はインデックスIDXで開始される位置にOBJを格納することにより 、文字列STRINGの内容の一部を変更する。OBJは文字、または(STRINGより 小さい)文字列です。 既存の文字列の長さを変更するのは不可能なので、STRINGの実際の長さに OBJが収まらない、またはSTRINGのその位置に現在ある文字のバイト数が新 しい文字に必要なバイト数と異なる場合はエラーになる。 パスワードを含む文字列をクリアーするときには‘clear-string’を使用しま す: -- Function: clear-string string これはSTRINGをユニバイト文字列にして、内容を0にクリアーする。これに よりSTRINGの長さも変更されるだろう。 4.5 文字および文字列の比較 ========================== -- Function: char-equal character1 character2 この関数は引数が同じ文字を表すなら‘t’、それ以外は‘nil’をリターンす る。‘case-fold-search’が非‘nil’なら、この関数はcaseの違いを無視する 。 (char-equal ?x ?x) ⇒ t (let ((case-fold-search nil)) (char-equal ?x ?X)) ⇒ nil -- Function: string= string1 string2 この関数は、2つの文字列の文字が正確にマッチすれば‘t’をリターンする 。引数にはシンボルも指定でき、この場合はそのシンボル名が使用される 。‘case-fold-search’とは無関係にcaseは常に意味をもつ。 この関数は、‘equal’で2つの文字列を比較するのと等価である(*note Equality Predicates::を参照)。特に、2つの文字列のテキストプロパティ ーは無視されます。テキストプロパティーだけが異なる文字列を区別する 必要があるなら‘equal-including-properties’を使用すること。しかし ‘equal’とは異なり、いずれかの引数が文字列でもシンボルでもなければ、 ‘string=’はエラーをシグナルする。 (string= "abc" "abc") ⇒ t (string= "abc" "ABC") ⇒ nil (string= "ab" "ABC") ⇒ nil 技術的な理由によりユニバイト文字列とマルチバイト文字列が‘equal’にな るのは、それらが同じ文字コードのシーケンスを含み、それらすべてのコ ードが0から127(ASCII)、または160から255(‘eight-bit-graphic’)のとき だけである。しかしユニバイト文字列をマルチバイト文字列に変更する際 、コードが160から255の範囲にあるすべての文字はより高いコードに変換 され、ASCII文字は変換されないまま残る。したがってユニバイト文字列と それを変換したマルチバイト文字列は、その文字列のすべてがASCIIのとき だけ‘equal’となる。もしマルチバイト文字列中で文字コード160から255の 文字があったとしても、それは完全に正しいとは言えない。結果として、 すべてがASCIIではないユニバイト文字列とマルチバイト文字列が ‘equal’という状況は、もしかしたらEmacs Lispプロプラマーが直面するか もしれない、とても稀で記述的に不可解な状況だといえよう。*note Text Representations::を参照されたい。 -- Function: string-equal string1 string2 ‘string-equal’は‘string=’の別名である。 -- Function: string-collate-equalp string1 string2 &optional locale ignore-case この関数は照合ルール(collation rules)にもとづいてSTRING1とSTRING2が 等しければ‘t’をリターンする。照合ルールはSTRING1とSTRING2に含まれる 文字の辞書順だけではなく、それらの文字間の関係に関する他のルールに より判断される。これは通常は、Emacs実行中のLOCALE環境により決定され る。 たとえば異なるコーディングポイントでも、Unicodeのグレイブアクセント 文字のように同じ意味なら等しいとみなされる。 (string-collate-equalp (string ?\uFF40) (string ?\u1FEF)) ⇒ t オプション引数LOCALE(文字列)は、照合用のカレントlocale識別子 (current locale identifier)をオーバーライドする。値はシステムに依存 する。たとえばPOSIXシステムでは‘"en_US.UTF-8"’、MS-Windowsシステム では‘"enu_USA.1252"’のLOCALEが適用できるだろう。 IGNORE-CASEが非‘nil’なら、それらは比較前に小文字に変換される。 MS-WindowsシステムでUnicode互換の照合をエミュレートする場合、 MS-Windowsではlocaleのコードセット部分を‘"UTF-8"’にできないので、 ‘w32-collate-ignore-punctuation’に非‘nil’値をバインドすること。 あるlocale環境をシステムがサポートしなれければ、この関数は ‘string-equal’と同様に振る舞う。 一般的にファイルシステムは照合ルールが実装するような文字列の言語学 的な等価性を尊重しないので、この関数をファイル名の等価性の比較に_使 用しないこと_。 -- Function: string-prefix-p string1 string2 &optional ignore-case この関数はSTRING1がSTRING2のプレフィクス(たとえばSTRING2がSTRING1で 始まる)なら、非‘nil’をリターンする。オプションの引数IGNORE-CASEが非 ‘nil’ばら、比較においてcaseの違いは無視される。 -- Function: string-suffix-p suffix string &optional ignore-case この関数はSUFFIXがSTRINGのサフィックス(たとえばSTRINGがSUFFIXで終わ る)なら、非‘nil’をリターンする。オプションの引数IGNORE-CASEが非 ‘nil’なら、比較においてcaseの違いは無視される。 -- Function: string< string1 string2 この関数は2つの文字列を1文字ずつ比較する。この関数は同時に2つの文字 列をスキャンして、対応する文字同士がマッチしない最初のペアを探す。 2つの文字列内で小さいほうの文字がSTRING1の文字ならSTRING1が小さいこ とになり、この関数は‘t’をリターンする。小さいほうの文字がSTRING2の 文字ならSTRING1が大きいことになり、この関数は‘nil’をリターンする。 2つの文字列が完全にマッチしたら値は‘nil’になる。 文字のペアーは文字コードで比較されル。ASCII文字セットでは英小文字は 英大文字より高い数値をもつことに留意されたい。数字と区切り文字の多 くは英大文字より低い数値をもつ。ASCII文字は任意の非ASCII文字より小 さくなる。ユニバイトの非ASCII文字は、任意のマルチバイト非ASCII文字 より常に小さくなります(*note Text Representations::を参照)。 (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 引数としてシンボルを指定することもでき、この場合はシンボルのプリン ト名が比較される。 -- Function: string-lessp string1 string2 ‘string-lessp’は‘string<’の別名である。 -- Function: string-greaterp string1 string2 この関数は逆順でSTRING1とSTRING2を比較した結果をリタンーする。つま りこれは‘(string-lessp STRING2 STRING1)’を呼び出すのと等価である。 -- Function: string-collate-lessp string1 string2 &optional locale ignore-case この関数は照合順でSTRING1がSTRING2より小さければ‘t’をリターンする。 照合順はSTRING1とSTRING2に含まれる文字の辞書順だけではなく、それら の文字間の関係に関するルールによっても判断される。これは通常は Emacs実行中のLOCALE環境により決定される。 たとえばソートでは区切り文字と空白文字は無視されるだろう(*note Sequence Functions::を参照)。 (sort '("11" "12" "1 1" "1 2" "1.1" "1.2") 'string-collate-lessp) ⇒ ("11" "1 1" "1.1" "12" "1 2" "1.2") Cygwinではlocaleと無関係に区切り文字と空白文字が無視されることが決 してないように、この振る舞いはシステム依存である。 オプション引数LOCALE(文字列)は、照合用のカレントlocale識別子 (current locale identifier)をオーバーライドする。値はシステムに依存 する。たとえばPOSIXシステムでは‘"en_US.UTF-8"’、MS-Windowsシステム では‘"enu_USA.1252"’のLOCALEが適用できるだろう。LOCALEの値を ‘"POSIX"’か‘"C"’にすると、‘string-collate-lessp’は‘string-lessp’と 同様に振る舞う。 (sort '("11" "12" "1 1" "1 2" "1.1" "1.2") (lambda (s1 s2) (string-collate-lessp s1 s2 "POSIX"))) ⇒ ("1 1" "1 2" "1.1" "1.2" "11" "12") IGNORE-CASEが非‘nil’なら、それらは比較前に小文字に変換される。 MS-WindowsシステムでUnicode互換の照合をエミュレートする場合、 MS-Windowsではlocaleのコードセット部分を‘"UTF-8"’にできないので、 ‘w32-collate-ignore-punctuation’に非‘nil’値をバインドすること。 locale環境をサポートしないシステムでは、この関数は‘string-lessp’と 同様に振る舞う。 -- Function: string-prefix-p string1 string2 &optional ignore-case この関数はSTRING1がSTRING2のプレフィクス(たとえばSTRING2がSTRING1で 始まる)なら、非‘nil’をリターンする。オプションの引数IGNORE-CASEが非 ‘nil’ばら、比較においてcaseの違いは無視される。 -- Function: string-suffix-p suffix string &optional ignore-case この関数はSUFFIXがSTRINGのサフィックス(たとえばSTRINGがSUFFIXで終わ る)なら、非‘nil’をリターンする。オプションの引数IGNORE-CASEが非 ‘nil’なら、比較においてcaseの違いは無視される。 -- Function: compare-strings string1 start1 end1 string2 start2 end2 &optional ignore-case この関数はSTRING1の指定部分をとSTRING2指定部分を比較する。STRING1の 指定部分とは、インデックスSTART1(その文字を含む)から、インデックス END1(その文字を含まない)まで。START1に‘nil’を指定すると文字列の最初 という意味になり、END1に‘nil’を指定すると文字列の長さを意味する。同 様にSTRING2の指定部分とはインデックスSTART2からインデックスEND2まで 。 文字列は文字列内の文字の数値により比較される。たとえばSTR1とSTR2は 、最初に異なる文字でSTR1の文字の数値が小さければ小さいと判断される 。IGNORE-CASEが非‘nil’なら比較を行なう前に大文字に変換される。比較 用にユニバイト文字列はマルチバイト文字列に変換されるので(*note Text Representations::を参照)、ユニバイト文字列とそれを変換したマルチバ イト文字列は常に等しくなる。 2つの文字列の指定部分がマッチした場合、値は‘t’になる。それ以外なら 値は整数で、何文字が一致してどちらの文字が小さいかを示す。この値の 絶対値は、2つの文字列の先頭から一致した文字数に1加えた値になる。 STRING1(または指定部分)のほうが小さければ符号は負になる。 -- Function: assoc-string key alist &optional case-fold この関数は‘assoc’と同様に機能するが、KEYは文字列かシンボルでなけれ ばならず、比較は‘compare-strings’を使用して行なわれる。テストする前 にシンボルは文字列に変換される。CASE-FOLDが非‘nil’なら、KEYと ALISTの要素は比較前に大文字に変換される。‘assoc’とは異なり、この関 数はコンスではない文字列またはシンボルのalist要素もマッチできる。特 にALISTは実際のalistではなく、文字列またはリストでも可。*note Association Lists::を参照のこと。 バッファー内のテキストを比較する方法として、*note Comparing Text::の 関数‘compare-buffer-substrings’も参照してください。文字列にたいして正規 表現のマッチを行なう関数‘string-match’も、ある種の文字列比較に使用するこ とができます。*note Regexp Search::を参照してください。 4.6 文字および文字列の変換 ========================== このセクションでは文字、文字列、整数の間で変換を行なう関数を説明します。 ‘format’ (*note Formatting Strings::を参照)と‘prin1-to-string’ (*note Output Functions::を参照)もLispオブジェクトを文字列に変換できます。 ‘read-from-string’ (*note Input Functions::を参照)は、Lispオブジェクトの 文字列表現をオブジェクトに“変換”できます。関数‘string-to-multibyte’と ‘string-to-unibyte’は、テキスト表現を文字列に変換します(*note Converting Representations::を参照)。 テキスト文字と一般的なインプットイベントにたいするテキスト記述を生成 する関数(‘single-key-description’と‘text-char-description’)については、 *note Documentation::を参照してください。これらの関数は主にヘルプメッセ ージを作成するために使用されます。 -- Function: number-to-string number この関数はNUMBERの10進プリント表現からなる文字列をリターンする。引 数が負ならリターン値はマイナス記号から開始される。 (number-to-string 256) ⇒ "256" (number-to-string -23) ⇒ "-23" (number-to-string -23.5) ⇒ "-23.5" ‘int-to-string’はこの関数にたいする半ば廃れたエイリアスである。 *note Formatting Strings::の関数‘format’も参照されたい。 -- Function: string-to-number string &optional base この関数はSTRING内の文字の数値的な値をリターンする。BASEが非‘nil’な ら値は2以上16以下でなければならず、整数はその基数に変換される。 BASEが‘nil’なら基数に10が使用される。浮動少数点数の変換は基数が10の ときだけ機能する。わたしたちは浮動小数点数にたいして他の基数を実装 しない。なぜならこれには多くの作業を要し、その割にその機能が有用に は思えないからだ。STRINGが整数のように見えるが、その値がLispの整数 に収まらないほど大きな値なら、‘string-to-number’は浮動小数点数の結 果をリターンする。 パースではSTRINGの先頭にあるスペースとタブはスキップして、与えられ た基数で数字として解釈できるところまでSTRINGを読み取る(スペースとタ ブだけではなく先頭にある他の空白文字を無視するシステムもある)。 STRINGを数字として解釈できなければこの関数は0をリターンする。 (string-to-number "256") ⇒ 256 (string-to-number "25 is a perfect square.") ⇒ 25 (string-to-number "X256") ⇒ 0 (string-to-number "-4.5") ⇒ -4.5 (string-to-number "1e5") ⇒ 100000.0 ‘string-to-int’はこの関数にたいする半ば廃れたエイリアスである。 -- Function: char-to-string character この関数は1つの文字CHARACTERを含む新しい文字列をリターンする。関数 ‘string’のほうがより一般的であり、この関数は半ば廃れている。*note Creating Strings::を参照のこと。 -- Function: string-to-char string この関数はSTRINGの最初の文字をリターンする。これはほとんど‘(aref string 0)’と同じで、例外は文字列が空のときに0をリターンすること(文 字列の最初の文字がASCIIコード0のヌル文字のときも0をリターンする)。 この関数は残すのに充分なほど有用と思えないければ、将来削除されるか もしれない。 以下は文字列へ/からの変換に使用できるその他の関数です: ‘concat’ この関数はベクターまたはリストから文字列に変換する。*note Creating Strings::を参照のこと。 ‘vconcat’ この関数は文字列をベクターに変換する。*note Vector Functions::を参 照のこと。 ‘append’ この関数は文字列をリストに変換する。*note Building Lists::を参照の こと。 ‘byte-to-string’ この関数は文字データのバイトをユニバイト文字列に変換する。*note Converting Representations::を参照のこと。 4.7 文字列のフォーマット ======================== “フォーマット(formatting)”とは、定数文字列内のなまざまな場所を計算された 値で置き換えることにより、文字列を構築することを意味します。この定数文字 列は他の値がプリントされる方法、同様にどこに表示するかを制御します。これ は“フォーマット文字列(format string)”と呼ばれます。 表示されるメッセージを計算するためにフォーマットが便利なことがしばし ばあります。実際に関数‘message’と‘error’は、ここで説明する機能と同じフォ ーマットを提供します。これらの関数と‘format-message’の違いはフォーマット された結果を使用する方法だけです。 -- Function: format string &rest objects この関数はSTRINGをコピーしてから、対応するOBJECTSをエンコードする、 そのコピー内の任意のフォーマット仕様(format specification)を置換し て作成される、新しい文字列をリターンする。引数OBJECTSはフォーマット される計算された値。 (もしあれば)STRING内のフォーマット仕様以外の文字は、テキストプロパ ティーを含めて出力に直接コピーされる。 -- Function: format-message string &rest objects この関数は‘format’と同様に機能するが、‘text-quoting-style’の各値に 応じてSTRING内のすべてのcurved single quotes文字も変換して、グレイ ブアクセント(`)とアポストロフィー(')があたかもcurved single quotes文 字であるかのように扱う点が異なる。 グレイブアクセントとアポストロフィーでクォートされたフォーマット `like this'は、通常はcurved quotesされた‘like this’を生成する。対照 的にアポストロフィーだけでクォートされた'like this'は、通常の英文ス タイルであるは2つのclosing curved quotesでクォートされた’like this’を生成する。変数‘text-quoting-style’が生成されるクォートに影響 を与える方法については、*note Keys in Documentation::を参照のこと。 フォーマット仕様(format specification)は‘%’で始まる文字シーケンスです 。したがってSTRING内に‘%d’がると‘format’はそれを、フォーマットされる値の 1つ(引数OBJECTSのうちの1つ)にたいするプリント表現で置き換えます。たとえ ば: (format "The value of fill-column is %d." fill-column) ⇒ "The value of fill-column is 72." ‘format’は文字‘%’をフォーマット仕様と解釈するので、_決して_最初の引数 に不定な文字列(arbitrary string)を渡すべきではありません。これは特に何ら かのLispコードga生成siた文字列の場合に当てはまります。その文字列が決して 文字‘%’を含まないと_確信_できないならば、以下で説明するように最初の引数 に‘"%s"’を渡して、不定な文字列を2番目の引数として渡します: (format "%s" ARBITRARY-STRING) STRINGに複数のフォーマット仕様が含まれる場合、フォーマット仕様は OBJECTSから連続して値を引き当てます。つまり、STRING内の1番目のフォーマッ ト仕様は1番目の値、2番目のフォーマット仕様は2番目の値、...を使用します。 余分なフォーマット仕様(対応する値がない場合)にはエラーとなります。フォー マットされる値が余分にある場合は無視されます。 ある種のフォーマット仕様は特定の型の値を要求します。その要求に適合し ない値を与えた場合にはエラーがシグナルされます。 以下は有効なフォーマット仕様のテーブルです: ‘%s’ フォーマット仕様を、クォートなしのオブジェクトのプリント表現で置き 換える(つまり‘prin1’ではなく‘princ’を使用して置き換える。*note Output Functions::を参照されたい)。したがって文字列は‘"’文字なしの 文字列内容だけが表示され、シンボルは‘\’文字なしで表される。 オブジェクトが文字列なら文字列のプロパティーは出力にコピーされる。 ‘%s’のテキストプロパティー自身もコピーされるが、オブジェクトのテキ ストプロパティーが優先される。 ‘%S’ フォーマット仕様を、クォートありのオブジェクトのプリント表現で置き 換える(つまり‘prin1’を使用して変換する。*note Output Functions::を 参照されたい)。したがって文字列は‘"’文字で囲まれ、必要となる特別文 字の前に‘\’文字が表示される。 ‘%o’ フォーマット仕様を8進表現の整数で置き換える。 ‘%d’ フォーマット仕様を10進表現の整数で置き換える。 ‘%x’ ‘%X’ フォーマット仕様を16進表現の整数で置き換える。‘%x’なら小文字、 ‘%X’なら大文字が使用される。 ‘%c’ フォーマット仕様を与えられた値の文字で置き換える。 ‘%e’ フォーマット仕様を浮動小数点数の指数表現で置き換える。 ‘%f’ フォーマット仕様を浮動小数点数にたいする10進少数表記で置き換える。 ‘%g’ フォーマット仕様を指数か10進少数のいずれか短いほうの表記を使用した 浮動小数点数で置き換える。 ‘%%’ フォーマット仕様を1つの‘%’で置き換える。このフォーマット仕様は値を 使用しない。たとえば‘(format "%% %d" 30)’は‘"% 30"’をリターンする。 他のフォーマット文字は‘Invalid format operation’エラーとなります。 以下は典型的な‘text-quoting-style’のセッティングを想定した場合の例で す: (format "The octal value of %d is %o, and the hex value is %x." 18 18 18) ⇒ "The octal value of 18 is 22, and the hex value is 12." (format-message "The name of this buffer is ‘%s’." (buffer-name)) ⇒ "The name of this buffer is ‘strings.texi’." (format-message "The buffer object prints as `%s'." (current-buffer)) ⇒ "The buffer object prints as ‘strings.texi’." フォーマット仕様は“フィールド幅(width)”をもつことができます。これは ‘%’とフォーマット仕様文字(specification character)の間の10進の数字です。 そのオブジェクトのプリント表現がこのフィールド幅より少ない文字で構成され る場合、‘format’はパディングによりフィールド幅に拡張します。フォーマット 仕様‘%%’ではフィールド幅の指定は無視されます。フィールド幅指定子により行 なわれるパディングは、通常は左側にスペースを挿入します。 (format "%5d is padded on the left with spaces" 123) ⇒ " 123 is padded on the left with spaces" フィールド幅が小さすぎる場合でも‘format’はオブジェクトのプリント表現を切 り詰めません。したがって情報を失う危険を犯すことなく、フィールドの最小幅 を指定することができます。以下の2つの例では‘%7s’は最小幅に7を指定します 。1番目の例では‘%7s’に挿入される文字列は3文字だけなので、4つのブランクス ペースによりパディングされます。2番目の例では文字列‘"specification"’は 13文字ですが切り詰めはされません。 (format "The word '%7s' has %d letters in it." "foo" (length "foo")) ⇒ "The word ' foo' has 3 letters in it." (format "The word '%7s' has %d letters in it." "specification" (length "specification")) ⇒ "The word 'specification' has 13 letters in it." ‘%’の直後、オプションのフィールド幅指定子の前に“フラグ文字(flag characters)”を置くこともできます。 フラグ‘+’は正の数の前にプラス符号を挿入するので、数には常に符号がつき ます。フラグとしてスペースを指定すると、正数の前に1つのスペースが挿入さ れます(それ以外は、正数は最初の数字から開始される)。これらのフラグは、確 実に正数と負数が同じ列数を使用させるために有用です。これらは‘%d’、‘%e’、 ‘%f’、‘%g’以外では無視され、両方が指定された場合は‘+’が優先されます。 フラグ‘#’は代替形式(alternate form)を指定します。これは使用するフォー マットに依存します。‘%o’にたいしては結果を‘0’で開始させます。‘%x’と ‘%X’にたいしては結果のプレフィクスは‘0x’または‘0X’になります。‘%e’、 ‘%f’、‘%g’にたいしての‘#’フラグは、少数部が0のときにも小数点が含まれるこ とを意味します。 フラグ‘0’はスペースの代わりに文字‘0’でパディングします。このフラグは ‘%s’、‘%S’、‘%c’のような非数値のフォーマット仕様文字では無視されます。こ れらのフォーマット仕様文字で‘0’フラグを指定できますが、それでも_スペース _でパディングされます。 フラグ‘-’はフィールド幅指定子により挿入されるパディングに作用し、もし パディングがあるなら左側ではなく右側にパディングされます。‘-’と‘0’の両方 が指定されると‘0’フラグは無視されます。 (format "%06d is padded on the left with zeros" 123) ⇒ "000123 is padded on the left with zeros" (format "'%-6d' is padded on the right" 123) ⇒ "'123 ' is padded on the right" (format "The word '%-7s' actually has %d letters in it." "foo" (length "foo")) ⇒ "The word 'foo ' actually has 3 letters in it." すべてのフォーマット仕様文字には、その文字の前(フィールド幅がある場合 はその後)に、オプションで“精度(precision)”を指定できます。精度は小数点 ‘.’と、その後に桁文字列(digit-string)を指定します。浮動少数点数のフォー マット仕様(‘%e’、‘%f’、‘%g’)では、精度は表示する小数点以下の桁数を指定し ます。0の場合は小数点も省略されます。‘%s’と‘%S’にたいしては、文字列を精 度で指定された幅に切り詰めます。したがって‘%.3s’では、OBJECTにたいするプ リント表現の最初の3文字だけが表示されます。他のフォーマット仕様文字にた いしては、精度の効果はローカルライブラリーの‘printf’関数ファミリーが生成 する効果となります。 4.8 Lispでの大文字小文字変換 ============================ case変換関数(character case functions)は、1つの文字または文字列中の大文 字小文字を変換します。関数は通常、アルファベット文字(英字‘A’から‘Z’と ‘a’から‘z’、同様に非ASCIIの英字)だけを変換し、それ以外の文字は変換しませ ん。caseテーブル(case table。*note Case Tables::を参照されたい)で指定す ることにより、caseの変換に異なるマッピングを指定できます。 これらの関数は引数として渡された文字列は変更しません。 以下の例では文字‘X’と‘x’を使用します。これらのASCIIコードは88と120で す。 -- Function: downcase string-or-char この関数はSTRING-OR-CHAR(文字か文字列)を小文字に変換する。 STRING-OR-CHARが文字列なら、この関数は引数の大文字を小文字に変換し た新しい文字列をリターンする。STRING-OR-CHARが文字なら、この関数は 対応する小文字(整数)をリターンする。元の文字が小文字か非英字ならリ ターン値は元の文字と同じ。 (downcase "The cat in the hat") ⇒ "the cat in the hat" (downcase ?X) ⇒ 120 -- Function: upcase string-or-char この関数はSTRING-OR-CHAR(文字か文字列)を大文字に変換する。 STRING-OR-CHARが文字列なら、この関数は引数の小文字を大文字に変換し た新しい文字列をリターンする。STRING-OR-CHARが文字なら、この関数は 対応する大文字(整数)をリターンする。元の文字が大文字か非英字ならリ ターン値は元の文字と同じ。 (upcase "The cat in the hat") ⇒ "THE CAT IN THE HAT" (upcase ?x) ⇒ 88 -- Function: capitalize string-or-char この関数は文字列や文字をキャピタライズ(capitalize: 先頭が大文字で残 りは小文字)する。この関数はSTRING-OR-CHARが文字列なら STRING-OR-CHARの各単語をキャピタライズした新たなコピーをリターンす る。これは各単語の最初の文字が大文字に変換され、残りは小文字に変換 されることを意味する。 単語の定義はカレント構文テーブル(current syntax table)の単語構成構 文クラス(word constituent syntax class)に割り当てられた、連続する文 字の任意シーケンスである(*note Syntax Class Table::を参照)。 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 -- Function: upcase-initials string-or-char この関数はSTRING-OR-CHARが文字列なら、STRING-OR-CHARの中の単語の頭 文字をキャピタライズして、頭文字以外の文字は変更しない。この関数は STRING-OR-CHARの各単語の頭文字が大文字に変換された新しいコピーをリ ターンする。 単語の定義はカレント構文テーブル(current syntax table)の単語構成構 文クラス(word constituent syntax class)に割り当てられた、連続する文 字の任意シーケンスである(*note Syntax Class Table::を参照)。 ‘upcase-initials’の引数が文字なら、‘upcase-initials’の結果は ‘upcase’と同じ。 (upcase-initials "The CAT in the hAt") ⇒ "The CAT In The HAt" 文字列を比較する関数(caseの違いを無視するものや、オプションでcaseの違 いを無視できるもの)については、*note Text Comparison::を参照されたい。 4.9 caseテーブル ================ 特別な“caseテーブル(case table)”をインストールすることにより、caseの変換 をカスタマイズできます。caseテーブルは大文字と小文字の間のマッピングを指 定します。caseテーブルはLispオブジェクトにたいするcase変換関数(前のセク ションを参照)と、バッファー内のテキストに適用される関数の両方に影響しま す。それぞれのバッファーにはcaseテーブルがあります。新しいバッファーの caseテーブルを初期化するために使用される、標準のcaseテーブル(standard case table)もあります。 caseテーブルは、サブタイプが‘case-table’の文字テーブル(char-table。 *note Char-Tables::を参照)です。この文字テーブルはそれぞれの文字を対応す る小文字にマップします。caseテーブルは、関連するテーブルを保持する3つの 余分なスロットをもちます: UPCASE upcase(大文字)テーブルはそれぞれの文字を対応する大文字にマップする 。 CANONICALIZE canonicalize(正準化)テーブルは、caseに関連する文字セットのすべてを 、その文字セットの特別なメンバーにマップする。 EQUIVALENCES 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テーブルに作用する関数です: -- Function: case-table-p object この述語は、OBJECTが有効なcaseテーブルなら非‘nil’をリターンする。 -- Function: set-standard-case-table table この関数はTABLEを標準caseテーブルにして、これ以降に作成される任意の バッファーにたいしてこのテーブルが使用されるようにする。 -- Function: standard-case-table これは標準caseテーブル(standard case table)をリターンする。 -- Function: current-case-table この関数はカレントバッファーのcaseテーブルをリターンする。 -- Function: set-case-table table これはカレントバッファーのcaseテーブルをTABLEにセットする。 -- Macro: with-case-table table body... ‘with-case-table’マクロはカレントcaseテーブルを保存してから、 TABLEをカレントcaseテーブルにセットし、その後にBODYフォームを評価し てから、最後にcaseテーブルをリストアします。リターン値は、BODYの最 後のフォームの値です。‘throw’かエラー(*note Nonlocal Exits::を参照 )により異常終了した場合でも、caseテーブルはリストアされます。 ASCII文字のcase変換を変更する言語環境(language environment)がいくつか あります。たとえばトルコ語の言語環境では、ASCIIの大文字‘I’にたいする小文 字は、トルコ語のドットがないi(‘ı’)です。これは(ASCIIベースのネットワーク プロトコル実装のような)ASCIIの通常のcase変換を要求するコードに干渉する可 能性があります。このような場合には、変数ASCII-CASE-TABLEにたいして ‘with-case-table’マクロを使用してください。これにより変更されていない ASCII文字セットのcaseテーブルが保存されます。 -- Variable: ascii-case-table ASCII文字セットにたいするcaseテーブル。すべての言語環境セッティング において、これを変更するべきではない。 以下の3つの関数は、非ASCII文字セットを定義するパッケージにたいして便 利なサブルーチンです。これらはCASE-TABLEに指定されたcaseテーブルを変更し ます。これは標準構文テーブルも変更します。*note Syntax Tables::を参照し てください。通常これらの関数は、標準caseテーブルを変更するために使用され ます。 -- Function: set-case-syntax-pair uc lc case-table この関数は対応する文字のペアー(一方は大文字でもう一方は小文字)を指 定する。 -- Function: set-case-syntax-delims l r case-table この関数は文字LとRを、case不変区切り(case-invariant delimiter)のマ ッチングペアーとする。 -- Function: set-case-syntax char syntax case-table この関数はCHARを構文SYNTAXのcase不変(case-invariant)とする。 -- Command: describe-buffer-case-table このコマンドはカレントバッファーのcaseテーブルの内容にたいする説明 を表示する。 5 リスト ******** “リスト(list)”は0個以上の要素(任意のLispオブジェクト)のシーケンスを表し ます。リストとベクターの重要な違いは、2つ以上のリストが構造の一部を共有 できることです。加えて、リスト全体をコピーすることなく要素の挿入と削除が できます。 5.1 リストとコンスセル ====================== Lispでのリストは基本データ型ではありません。リストは“コンスセル(cons cells)”から構築されます(*note Cons Cell Type::を参照)。コンスセルは順序 つきペアを表現するデータオブジェクトです。つまりコンスセルは2つのスロッ トをもち、それぞれのスロットはLispオブジェクトを“保持(holds)”または“参照 (refers to)”します。1つのスロットはCAR、もう1つはCDRです(これらの名前は 歴史的なものである。*note Cons Cell Type::を参照されたい)。CDRは “could-er(クダー)”と発音します。 わたしたちは、コンスセルのCARスロットに現在保持されているオブジェクト が何であれ、“このコンスセルのCARは、...”のような言い方をします。これは CDRの場合でも同様です。 リストとは互いに連なる(chained together)一連のコンスセルであり、各セ ルは次のセルを参照します。リストの各要素にたいして1つのコンスセルがあり ます。慣例によりコンスセルのCARはリストの要素を保持し、CDRはリストをチェ ーンするのに使用されます(CARとCDRの間の非対称性は完全に慣例的なものであ る。コンスセルのレベルではCARスロットとCDRスロットは同じようなプロパティ ーをもつ)。したがって、リスト内の各コンスセルのCDRスロットは次のコンスセ ルを参照します。 これも慣例的なものですが、リスト内の最後のコンスセルのCDRは‘nil’です 。わたしたちはこのような‘nil’で終端された構造を、“真リスト(true list)”と 呼びます。Emacs Lispではシンボル‘nil’はシンボルであり、かつ要素なしのリ ストでもあります。便宜上、シンボル‘nil’はそのCDR(とCAR)に‘nil’をもつと考 えます。 したがって真リストのCDRは、常に真リストです。空でない真リストのCDRは 、1番目の要素以外を含む真リストです。 リストの最後のコンスセルのCDRが‘nil’以外の何らかの値の場合、このリス トのプリント表現はドットペア表記(dotted pair notation。*note Dotted Pair Notation::を参照のこと)を使用するので、わたしたちはこの構造を“ドットリス ト(dotted list)”と呼びます。他の可能性もあります。あるコンスセルのCDRが 、そのリストのそれより前にある要素を指すかもしれません。わたしたちは、こ の構造を“循環リスト(circular list)”と呼びます。 ある目的においてはそのリストが真リストか、循環リストなのか、ドットリ ストなのかが問題にならない場合もあります。そのプログラムがリストを充分に 辿って最後のコンスセルのCDRを確認しようとしないなら、これは問題になりま せん。しかしリストを処理する関数のいくつかは真リストを要求し、ドットリス トの場合はエラーをシグナルします。リストの最後を探そうと試みる関数のほと んどは、循環リストを与えると無限ループに突入します。 ほとんどのコンスセルはリストの一部として使用されるので、わたしたちは コンスセルで構成される任意の構造を“リスト構造(list structure)”と呼びます 。 5.2 リストのための述語 ====================== 以下の述語はあるLispオブジェクトがアトムか、コンスセルか、リストなのか、 またはオブジェクトが‘nil’かどうかテストします(これらの述語の多くは他の述 語で定義することもできるが、多用されるので個別に定義する価値がある)。 -- Function: consp object この関数はOBJECTがコンスセルなら‘t’、それ以外は‘nil’をリターンする 。たとえ‘nil’が_リスト_であっても、コンスセルではない。 -- Function: atom object この関数はOBJECTがアトムなら‘t’、それ以外は‘nil’をリターンする。シ ンボル‘nil’はアトムであり、かつリストでもある。そのようなLispオブジ ェクトは‘nil’だけである。 (atom OBJECT) ≡ (not (consp OBJECT)) -- Function: listp object この関数はOBJECTがコンスセルか‘nil’なら‘t’、それ以外は‘nil’をリター ンする。 (listp '(1)) ⇒ t (listp '()) ⇒ t -- Function: nlistp object この関数は‘listp’の反対である。OBJECTがリストでなければ‘t’、それ以 外は‘nil’をリターンする。 (listp OBJECT) ≡ (not (nlistp OBJECT)) -- Function: null object この関数はOBJECTが‘nil’なら‘t’、それ以外は‘nil’をリターンする。この 関数は‘not’と等価だが、明解にするためにOBJECTをリストだと考えるとき は‘null’、真偽値だと考えるときは‘not’を使用すること(*note Combining Conditions::の‘not’を参照)。 (null '(1)) ⇒ nil (null '()) ⇒ t 5.3 リスト要素へのアクセス ========================== -- Function: car cons-cell この関数はコンスセルCONS-CELLの1番目のスロットが参照する値をリター ンする。言い換えるとこの関数はCONS-CELLのCARをリターンする。 特別なケースとしてCONS-CELLが‘nil’の場合、この関数は‘nil’をリターン する。したがってリストはすべて引数として有効である。引数がコンスセ ルでも‘nil’でもなければエラーがシグナルされる。 (car '(a b c)) ⇒ a (car '()) ⇒ nil -- Function: cdr cons-cell この関数はコンスセルCONS-CELLの2番目のスロットにより参照される値を リターンする。言い換えるとこの関数はCONS-CELLのCDRをリターンする。 特別なケースとしてCONS-CELLが‘nil’の場合、この関数は‘nil’をリターン する。したがってリストはすべて引数として有効である。引数がコンスセ ルでも‘nil’でもければエラーがシグナルされる。 (cdr '(a b c)) ⇒ (b c) (cdr '()) ⇒ nil -- Function: car-safe object この関数により他のデータ型によるエラーを起こさずに、コンスセルの CARを取得できり。この関数はOBJECTがコンスセルならOBJECTのCAR、それ 以外は‘nil’をリターンする。この関数は、OBJECTがリストでなければエラ ーをシグナルする‘car’とは対象的である。 (car-safe OBJECT) ≡ (let ((x OBJECT)) (if (consp x) (car x) nil)) -- Function: cdr-safe object この関数により他のデータ型によるエラーを起こさずに、コンスセルの CDRを取得できる。この関数はOBJECTがコンスセルならOBJECTのCDR、それ 以外は‘nil’をリターンする。この関数は、OBJECTがリストでないときはエ ラーをシグナルする‘cdr’とは対象的である。 (cdr-safe OBJECT) ≡ (let ((x OBJECT)) (if (consp x) (cdr x) nil)) -- Macro: pop listname このマクロはリストの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に保存する。*note Generalized Variables::を参照のこと。 リストに要素を追加する‘push’マクロについては*note List Variables::を 参照のこと。 -- Function: nth n list この関数は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’も類似しているが、任意の種類のシーケンスに適用される 。歴史的な理由によりこの関数は逆の順序で引数を受け取る。*note Sequence Functions::を参照のこと。 -- Function: nthcdr n list この関数は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) -- Function: last list &optional n この関数はLISTの最後のリンクをリターンする。このリンクの‘car’はこの リストの最後の要素。LISTがnullなら‘nil’がリターンされる。Nが非 ‘nil’ならN番目から最後までのリンクがリターンされる。NがLISTの長さよ り大きければLIST全体がリターンされる。 -- Function: safe-length list この関数はエラーや無限ループの危険なしで、LISTの長さをリターンする 。この関数は一般的に、リスト内のコンスセルの個数をリターンする。し かし循環リストでは単に上限値が値となるため、非常に大きくなる場合が あります。 LISTが‘nil’]とコンスセルのいずれでもなければ‘safe-length’は0をリタ ーンする。 循環リストを考慮しなくてもよい場合にリストの長さを計算するもっとも一 般的な方法は、‘length’を使う方法です。*note Sequence Functions::を参照し てください。 -- Function: caar cons-cell これは‘(car (car CONS-CELL))’と同じ。 -- Function: cadr cons-cell これは‘(car (cdr CONS-CELL))’か‘(nth 1 CONS-CELL)’と同じ。 -- Function: cdar cons-cell これは‘(cdr (car CONS-CELL))’と同じ。 -- Function: cddr cons-cell これは‘(cdr (cdr CONS-CELL))’か‘(nthcdr 2 CONS-CELL)’と同じ。 -- Function: butlast x &optional n この関数はリストXから、最後の要素か最後のN個の要素を削除してリター ンする。Nが0より大きければこの関数はリストのコピーを作成するので、 元のリストに影響はない。一般的に‘(append (butlast X N) (last X N))’は、Xと等しいリストをリターンする。 -- Function: nbutlast x &optional n この関数はリストのコピーを作成するのではなく、‘cdr’を適切な要素に変 更することにより破壊的に機能するバージョンの‘butlast’である。 5.4 コンスセルおよびリストの構築 ================================ リストはLispの中核にあたる機能なので、リストを構築するために多くの関数が あります。‘cons’はリストを構築する基本的な関数です。しかしEmacsのソース コードでは、‘cons’より‘list’のほうが多く使用されているのは興味深いことで す。 -- Function: cons object1 object2 この関数は新しいリスト構造を構築するための、もっとも基本的な関数で ある。この関数はOBJECT1をCAR、OBJECT2をCDRとする新しいコンスセルを 作成して、それから新しいコンスセルをリターンする。引数OBJECT1と OBJECT2には任意のLispオブジェクトを指定できるが、ほとんどの場合 OBJECT2はリストである。 (cons 1 '(2)) ⇒ (1 2) (cons 1 '()) ⇒ (1) (cons 1 2) ⇒ (1 . 2) リストの先頭に1つの要素を追加するために、‘cons’がよく使用される。こ れを“リストに要素をコンスする”と言います。(1)たとえば: (setq list (cons newelt list)) この例で使用されている‘list’という名前の変数と、以下で説明する ‘list’という名前の関数は競合しないことに注意されたい。すべてのシン ボルが、変数ト関数の両方の役割を果たすことができる。 -- Function: list &rest objects この関数は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 -- Function: make-list length object この関数は各要素がOBJECTであるような、LENGTH個の要素からなるリスト を作成する。‘make-list’と‘make-string’(*note Creating Strings::を参 照)を比較してみよ。 (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 -- Function: append &rest sequences この関数はSEQUENCESのすべての要素を含むリストをreturnします。 SEQUENCESにはリスト、ベクター、ブールベクター、文字列も指定できるが 、通常は最後にリストを指定すること。最後の引数を除くすべての引数は コピーされるので、変更される引数はない(コピーを行なわずにリストを結 合する方法については*note Rearrangement::の‘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’が導入される以前は,これがリストをコピーする通常の方法 でした。*note Sequences Arrays Vectors::を参照してください。 以下は‘append’の引数としてベクターと文字列を使用する例です: (append [a b] "cd" nil) ⇒ (a b 99 100) ‘apply’ (*note Calling Functions::を参照)の助けを借りることにより、リ ストのリストの中のすべてのリストを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になります。 -- Function: copy-tree tree &optional vecp この関数はツリー‘tree’のコピーをリターンする。TREEがコンスセルなら 、同じCARとCDRをもつ新しいコンスセルを作成してから、同じ方法により CARとCDRを再帰的にコピーする。 TREEがコンスセル以外の場合、通常は‘copy-tree’は単にTREEをリターンす る。しかしVECPが非‘nil’なら、この関数はベクターでもコピーします(そ してベクターの要素を再帰的に処理する)。 -- Function: number-sequence from &optional to separation これはFROMからSEPARATIONづつインクリメントして、TOの直前で終わる、 数字のリストをリターンする。SEPARATIONには正か負の数を指定でき、デ フォルトは1。TOが‘nil’、または数値的にFROMと等しければ、値は1要素の リスト‘(FROM)’になる。SEPARATIONが正でTOがFROMより小さい、または SEPARATIONが負でTOがFROMより大きければ、これらの引数は空のシーケン スを指示することになるので、値は‘nil’になります。 SEPARATIONが0で、TOが‘nil’でもなく、数値的にFROMとも等しくまければ 、これらの引数は無限シーケンスを指示することになるので、エラーがシ グナルされる。 引数はすべて数字である。浮動少数点数の計算は正確ではないので、浮動 少数点数の引数には注意する必要がある。たとえばマシンへの依存により 、‘(number-sequence 0.4 0.8 0.2)’が3要素のリストをリターンして、 ‘(number-sequence 0.4 0.6 0.2)’が1要素のリスト‘(0.4)’をリターンnす ることがよく起こる。リストのN番目の要素は、厳密に‘(+ FROM (* N SEPARATION))’という式により計算される。リストに確実にTOが含まれるよ うにするために、この式に適切な型のTOを渡すことができる。別の方法と してTOを少しだけ大きな値(SEPARATIONが負なら少しだけ小さな値)に置き 換えることもできる。 例をいくつか示す: (number-sequence 4 9) ⇒ (4 5 6 7 8 9) (number-sequence 9 4 -1) ⇒ (9 8 7 6 5 4) (number-sequence 9 4 -2) ⇒ (9 7 5) (number-sequence 8) ⇒ (8) (number-sequence 8 5) ⇒ nil (number-sequence 5 8 -1) ⇒ nil (number-sequence 1.5 6 2) ⇒ (1.5 3.5 5.5) ---------- Footnotes ---------- (1) リストの最後に要素を追加するための、これと完全に同等な方法はあり ません。LISTNAMEをコピーすることにより新しいリストを作成してから、 NEWELTをそのリストの最後に追加する‘(append LISTNAME (list NEWELT))’を使 用することができます。すべてのCDRを辿って終端の‘nil’を置き換える、 ‘(nconc LISTNAME (list NEWELT))’を使用することもできます。コピーも変更も 行なわずにリストの先頭に要素を追加する‘cons’と比較してみてください。 5.5 リスト変数の変更 ==================== 以下の関数と1つのマクロは、変数に格納されたリストを変更する便利な方法を 提供します。 -- Macro: push element listname このマクロは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))’と等価になる。*note Generalized Variables::を参照のこと。 リストから1番目の要素を取り出す‘pop’マクロについては、*note List Elements::を参照されたい。 以下の2つの関数は、変数の値であるリストを変更します。 -- Function: add-to-list symbol element &optional append compare-fn この関数はELEMENTがSYMBOLの値のメンバーでなければ、SYMBOLに ELEMENTをコンスすることにより、変数SYMBOLをセットする。この関数はリ ストが更新されているか否かに関わらず、結果のリストをリターンする。 SYMBOLの値は呼び出し前にすでにリストであることが望ましい。ELEMENTが リストの既存メンバーか比較するために、‘add-to-list’はCOMPARE-FNを使 用する。COMPARE-FNが‘nil’なら‘equal’を使用する。 ELEMENTが追加される場合は、通常はSYMBOLの前に追加されるが、オプショ ンの引数APPENDが非‘nil’なら最後に追加される。 引数SYMBOLは暗黙にクォートされない。‘setq’とは異なり‘add-to-list’は ‘set’のような通常の関数である。クォートしたい場合には自分で引数をク ォートすること。 以下に‘add-to-list’を使用する方法をシナリオで示します: (setq foo '(a b)) ⇒ (a b) (add-to-list 'foo 'c) ;; ‘c’を追加 ⇒ (c a b) (add-to-list 'foo 'b) ;; 効果なし ⇒ (c a b) foo ;; ‘foo’が変更された ⇒ (c a b) 以下は‘(add-to-list 'VAR VALUE)’と等価な式です: (or (member VALUE VAR) (setq VAR (cons VALUE VAR))) -- Function: add-to-ordered-list symbol element &optional order この関数は古い値のORDER (リストであること)で指定された位置に、 ELEMENTを挿入して変数SYMBOLをセットする。ELEMENTがすでにこのリスト のメンバなら、リスト内の要素の位置はORDERにしたがって調整される。メ ンバーか否かは‘eq’を使用してテストされる。この関数は更新されている かどうかに関わらず、結果のリストをリターンする。 ORDERは通常は数字(整数か浮動小数点数)で、リストの要素はその数字の昇 順で並べられる。 ORDERは省略または‘nil’を指定できる。これによりリストにELEMENTがすで に存在するなら、ELEMENTの数字順序は変更されない。それ以外なら ELEMENTは数字順序をもたない。リストの数字順序をもたない要素はリスト の最後に配置され、特別な順序はつかない。 ORDERに他の値を指定すると、ELEMENTがすでに数字順序をもつときは数字 順序が削除される。それ以外はなら‘nil’と同じ。 引数SYMBOLは暗黙にクォートされない。‘add-to-ordered-list’は‘setq’な どとは異なり、‘set’のような通常の関数である。必要なら引数を自分でク ォートすること。 順序の情報はSYMBOLの‘list-order’プロパティーにハッシュテーブルで保 存される。 以下に‘add-to-ordered-list’を使用する方法をシナリオで示します: (setq foo '()) ⇒ nil (add-to-ordered-list 'foo 'a 1) ;; ‘a’を追加 ⇒ (a) (add-to-ordered-list 'foo 'c 3) ;; ‘c’を追加 ⇒ (a c) (add-to-ordered-list 'foo 'b 2) ;; ‘b’を追加 ⇒ (a b c) (add-to-ordered-list 'foo 'b 4) ;; ‘b’を移動 ⇒ (a c b) (add-to-ordered-list 'foo 'd) ;; ‘d’を後に追加 ⇒ (a c b d) (add-to-ordered-list 'foo 'e) ;; ‘e’を追加 ⇒ (a c b e d) foo ;; ‘foo’が変更された ⇒ (a c b e d) 5.6 既存のリスト構造の変更 ========================== プリミティブ関数‘setcar’と‘setcdr’により、コンスセルのCARおよびCDRの内容 を変更できます。わたしたちは、これらは既存のリスト構造を変更するので、こ れらを破壊的処理です。 Common Lispに関する注意: Common Lispはリスト構造の変更に‘rplaca’と ‘rplacd’を使用する。これらは‘setcar’や‘setcdr’と同じ方法でリスト構 造を変更するが、‘setcar’と‘setcdr’は新しいCARやCDRをリターンするの にたいして、Common Lispの関数はコンスセルをリターンする。 5.6.1 ‘setcar’によるリスト要素の変更 ------------------------------------ コンスセルのCARの変更は‘setcar’で行ないます。リストにたいして使用すると ‘setcar’はリストの1つの要素を別の要素に置き換えます。 -- Function: setcar cons object この関数は以前のCARを置き換えて、CONSの新しいCARにOBJECTを格納する 。言い換えると、この関数はCONSのCARスロットをOBJECTを参照するように 変更する。この関数は値OBJECTをリターンする。たとえば: (setq x '(1 2)) ⇒ (1 2) (setcar x 4) ⇒ 4 x ⇒ (4 2) コンスセルが複数のリストを共有する構造の一部なら、コンスに新しいCARを 格納することにより、これら共有されたリストの各1つの要素を変更します。以 下は例です: ;; 部分的に共有された2つのリストを作成 (setq x1 '(a b c)) ⇒ (a b c) (setq x2 (cons 'z (cdr x1))) ⇒ (z b c) ;; 共有されたリンクのCARを置き換え (setcar (cdr x1) 'foo) ⇒ foo x1 ; 両方のリストが変更された ⇒ (a foo c) x2 ⇒ (z foo c) ;; 共有されていないリンクのCARを置き換え (setcar x1 'baz) ⇒ baz x1 ; 1つのリストだけが変更された ⇒ (baz foo c) x2 ⇒ (z foo c) なぜ‘b’を置き換えると両方が変更されるのかを説明するために、変数‘x1’と ‘x2’の2つのリストによる共有構造を視覚化してみましょう: --- --- --- --- --- --- x1---> | | |----> | | |--> | | |--> nil --- --- --- --- --- --- | --> | | | | | | --> a | --> b --> c | --- --- | x2--> | | |-- --- --- | | --> z 同じ関係を別のボックス図で示すと、以下のようになります: x1: -------------- -------------- -------------- | car | cdr | | car | cdr | | car | cdr | | a | o------->| b | o------->| c | nil | | | | -->| | | | | | -------------- | -------------- -------------- | x2: | -------------- | | car | cdr | | | z | o---- | | | -------------- 5.6.2 リストのCDRの変更 ----------------------- CDRを変更するもっとも低レベルのプリミティブ関数は‘setcdr’です: -- Function: setcdr cons object この関数は前のCDRを置き換えて、CONSの新しいCDRにOBJECTを格納する。 言い換えると、この関数はCONSのCDRがOBJECTを参照するように変更する。 この関数は値OBJECTをリターンする。 以下はリストのCDRを、他のリストに置き換える例です。1番目の要素以外の すべての要素は、別のシーケンスまたは要素のために取り除かれます。1番目の 要素はリストのCARなので変更されず、CDRを通じて到達することもできないから です。 (setq x '(1 2 3)) ⇒ (1 2 3) (setcdr x '(4)) ⇒ (4) x ⇒ (1 4) リスト内のコンスセルのCDRを変更することにより、リストの途中から要素を 削除できます。たとえば以下では、1番目のコンスセルのCDRを変更することによ り、2番目の要素‘b’をリスト‘(a b c)’から削除します。 (setq x1 '(a b c)) ⇒ (a b c) (setcdr x1 (cdr (cdr x1))) ⇒ (c) x1 ⇒ (a c) 以下に結果をボックス表記で示します: -------------------- | | -------------- | -------------- | -------------- | car | cdr | | | car | cdr | -->| car | cdr | | a | o----- | b | o-------->| c | nil | | | | | | | | | | -------------- -------------- -------------- 以前は要素‘b’を保持していた2番目のコンスセルは依然として存在し、その CARも‘b’のままですが、すでにこのリストの一部を形成していません。 CDRを変更して新しい要素を挿入するのも同じくらい簡単です: (setq x1 '(a b c)) ⇒ (a b c) (setcdr x1 (cons 'd (cdr x1))) ⇒ (d b c) x1 ⇒ (a d b c) 以下に結果をボックス表記で示します: -------------- ------------- ------------- | car | cdr | | car | cdr | | car | cdr | | a | o | -->| b | o------->| c | nil | | | | | | | | | | | | --------- | -- | ------------- ------------- | | ----- -------- | | | --------------- | | | car | cdr | | -->| d | o------ | | | --------------- 5.6.3 リストを再配置する関数 ---------------------------- 以下ではリストの構成要素であるコンスセルのCDRを変更することにより、リス トを破壊的に再配置する関数をいくつか示します。これらの関数が破壊的だとい う理由は、これらの関数が引数として渡された元のリストを処理してリターン値 となる新しいリストを形成するために、リストのコンスセルを再リンクするから です。 コンスセルを変更する他の関数については、*note Sets And Lists::の ‘delq’を参照してください。 -- Function: nconc &rest lists この関数はLISTSの要素すべてを含むリストをリターンする。‘append’ (*note Building Lists::を参照)とは異なり、LISTSは_コピーされない_。 かわりにLISTSの各リストの最後のCDRが次のリストを参照するように変更 される。LISTSの最後のリストは変更されない。たとえば: (setq x '(1 2 3)) ⇒ (1 2 3) (nconc x '(4 5)) ⇒ (1 2 3 4 5) x ⇒ (1 2 3 4 5) ‘nconc’の最後の引数は変更されないので、上記の例のように‘'(4 5)’のよ うな定数リストを使用するのが合理的である。また同じ理由により最後の 引数がリストである必要はない。 (setq x '(1 2 3)) ⇒ (1 2 3) (nconc x 'z) ⇒ (1 2 3 . z) x ⇒ (1 2 3 . z) しかし他の(最後を除くすべての)引数はリストでなければなければならな い。 一般的な落とし穴としては、‘nconc’にたいしてクォートされたリスト定数 を最後以外の引数として使用した場合である。これを行なうと、実行する ごとにプログラムはリスト定数を変更するだろう! 何が起こるのかを以下 に示す: (defun add-foo (x) ; この関数では‘foo’ (nconc '(foo) x)) ; を引数の前に追加したい (symbol-function 'add-foo) ⇒ (lambda (x) (nconc (quote (foo)) x)) (setq xx (add-foo '(1 2))) ; 動いているように見える ⇒ (foo 1 2) (setq xy (add-foo '(3 4))) ; 何が起きているのか? ⇒ (foo 1 2 3 4) (eq xx xy) ⇒ t (symbol-function 'add-foo) ⇒ (lambda (x) (nconc (quote (foo 1 2 3 4) x))) 5.7 集合としてのリストの使用 ============================ リストは順序なしの数学的集合 — リスト内に要素があれば集合の要素の値とし てリスト内の順序は無視される — を表すことができます。2つの集合を結合 (union)するには、(重複する要素を気にしなければ)‘append’を使用します。 ‘equal’である重複を取り除くには‘delete-dups’を使用します。集合にたいする 他の有用な関数には‘memq’や‘delq’や、それらの‘equal’バージョンである ‘member’と‘delete’が含まれます。 Common Lispに関する注意: 集合を処理するためにCommon Lispには(要素の 重複がない)関数‘union’がある。これらの関数は標準のGNU Emacs Lispに は存在しないが、‘cl-lib’がこれらを提供する。*note (cl)Lists as Sets::を参照されたい。 -- Function: memq object list この関数は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 -- Function: delq object list この関数はLISTからOBJECTと‘eq’であるような、すべての要素を破壊的に 取り除いて結果のリストをリターンする。‘delq’の文字‘q’は、この関数が OBJECTとリスト内の要素の比較に‘eq’を使用することを示す(‘memq’や ‘remq’と同様)。 ‘delq’を呼び出すときは、通常は元のリストを保持していた変数にリター ン値を割り当てて使用する必要がある(理由は以下参照)。 ‘delq’関数がリストの先頭にある要素を削除する場合は、単にリストを読み 進めてこの要素の後から開始される部分リストをリターンします。つまり: (delq 'a '(a b c)) ≡ (cdr '(a b c)) リストの途中にある要素を削除するときは、必要なCDR (*note Setcdr::を参照 )を変更することで削除を行います。 (setq sample-list '(a b c (4))) ⇒ (a b c (4)) (delq 'a sample-list) ⇒ (b c (4)) sample-list ⇒ (a b c (4)) (delq 'c sample-list) ⇒ (a b (4)) sample-list ⇒ (a b (4)) ‘(delq 'a sample-list)’は何も取り除きませんが(単に短いリストをリター ンする)、‘(delq 'c sample-list)’は3番目の要素を取り除いて‘sample-list’を 変更することに注意してください。引数LISTを保持するように形成された変数が 、実行後にもっと少ない要素になるとか、元のリストを保持すると仮定しないで ください! かわりに‘delq’の結果を保存して、それを使用してください。元のリ ストを保持していた変数に結果を書き戻すことはよく行なわれます。 (setq flowers (delq 'rose flowers)) 以下の例では、‘delq’が比較しようとしている‘(4)’と、‘sample-list’内の ‘(4)’は‘eq’ではありません: (delq '(4) sample-list) ⇒ (a c (4)) 与えられた値と‘equal’な要素を削除したい場合には、‘delete’ (以下参照 )を使用してください。 -- Function: remq object list この関数はOBJECTと‘eq’なすべての要素が除かれた、LISTのコピーをリタ ーンする。‘remq’の文字‘q’は、この関数がOBJECTとリスト内の要素の比較 に‘eq’を使用することを示す。 (setq sample-list '(a b c a b c)) ⇒ (a b c a b c) (remq 'a sample-list) ⇒ (b c b c) sample-list ⇒ (a b c a b c) -- Function: memql object list 関数‘memql’は‘eql’(浮動少数点数の要素は値で比較される)を使用してメ ンバーと‘eql’を比較することにより、OBJECTがLISTのメンバーかどうかを テストする。OBJECTがメンバーなら、‘memql’はLIST内で最初に見つかった 要素から始まるリスト、それ以外なら‘nil’をリターンする。 ‘memq’と比較してみよう: (memql 1.2 '(1.1 1.2 1.3)) ; ‘1.2’と‘1.2’は‘eql’。 ⇒ (1.2 1.3) (memq 1.2 '(1.1 1.2 1.3)) ; ‘1.2’と‘1.2’は‘eq’ではない。 ⇒ nil 以下の3つの関数は‘memq’、‘delq’、‘remq’と似ていますが、要素の比較に ‘eq’ではなく‘equal’を使用します。*note Equality Predicates::を参照してく ださい。 -- Function: member object list 関数‘member’は、メンバーとOBJECTを‘equal’を使用して比較して、 OBJECTがLISTのメンバーかどうかをテストする。OBJECTがメンバーなら、 ‘member’はLISTで最初に見つかったところから開始されるリスト、それ以 外なら‘nil’をリターンする。 ‘memq’と比較してみよう: (member '(2) '((1) (2))) ; ‘(2)’ and ‘(2)’ are ‘equal’. ⇒ ((2)) (memq '(2) '((1) (2))) ; ‘(2)’と‘(2)’は‘eq’ではない。 ⇒ nil ;; 同じ内容の2つの文字列は‘equal’ (member "foo" '("foo" "bar")) ⇒ ("foo" "bar") -- Function: delete object sequence この関数はSEQUENCEからOBJECTと‘equal’な要素を取り除いて、結果のシー ケンスをリターンする。 SEQUENCEがリストなら、‘delete’が‘delq’に対応するように、‘member’は ‘memq’に対応する。つまりこの関数は‘member’と同様、要素とOBJECTの比 較に‘equal’を使用する。マッチする要素が見つかったら、‘delq’が行なう ようにその要素を取り除く。‘delq’と同様、通常は元のリストを保持して いた変数にリターン値を割り当てて使用する。 ‘sequence’がベクターか文字列なら、‘delete’は‘object’と‘equal’なすべ ての要素を取り除いた‘sequence’のコピーをリターンする。 たとえば: (setq l '((2) (1) (2))) (delete '(2) l) ⇒ ((1)) l ⇒ ((2) (1)) ;; ‘l’の変更に信頼性を要するときは ;; ‘(setq l (delete '(2) l))’と記述する。 (setq l '((2) (1) (2))) (delete '(1) l) ⇒ ((2) (2)) l ⇒ ((2) (2)) ;; このケースでは‘l’のセットの有無に違い ;; はないが他のケースに倣ってセットするべき (delete '(2) [(2) (1) (2)]) ⇒ [(1)] -- Function: remove object sequence この関数は‘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’を使用しない。 -- Function: member-ignore-case object list この関数は‘member’と同様だが、OBJECTが文字列でcaseとテキスト表現の 違いを無視する。文字の大文字と小文字は等しいものとして扱われ、比較 に先立ちユニバイト文字列はマルチバイト文字列に変換される。 -- Function: delete-dups list この関数はLISTからすべての‘equal’な重複を破壊的に取り除いて、結果を LISTに保管してそれをリターンする。LIST内の要素に‘equal’な要素がいく つかあるなら、‘delete-dups’は最初の要素を残す。 変数に格納されたリストへの要素の追加や、それを集合として使用する方法 については、*note List Variables::の関数‘add-to-list’も参照してください 。 5.8 連想リスト ============== “連想配列(association list、短くはalist)”は、キーと値のマッピングを記録 します。これは“連想(associations)”と呼ばれるコンスセルのリストです。各コ ンスセルにおいてCARは“キー(key)”で、CDRは“連想値(associated value)”とな ります。(1) 以下はalistの例です。キー‘pine’は値‘cones’、キー‘oak’は‘acorns’、キー ‘maple’は‘seeds’に関連付けられます。 ((pine . cones) (oak . acorns) (maple . seeds)) alist内の値とキーには、任意のLispオブジェクトを指定できます。たとえば 以下のalist0では、シンボル‘a’は数字‘1’、文字列‘"b"’は_リスト_‘(2 3)’(alist要素のCDR)に関連付けられます。 ((a . 1) ("b" 2 3)) 要素のCDRのCARに連想値を格納するようにalistデザインするほうがよい場合 があります。以下はそのようなalistです。 ((rose red) (lily white) (buttercup yellow)) この例では、‘red’が‘rose’に関連付けられる値だと考えます。この種のalistの 利点は、CDRのCDRの中に他の関連する情報 — 他のアイテムのリストでさえも — を格納することができることです。不利な点は、与えられた値を含む要素を見つ けるために‘rassq’(以下参照)を使用できないことです。これらを検討すること が重要でない場合には、すべての与えられたalistにたいして一貫している限り 、選択は好みの問題といえます。 上記で示したのと同じalistは、要素のCDRに連想値をもつと考えることがで きます。この場合、‘rose’に関連付けられる値はリスト‘(red)’になるでしょう 。 連想リストは新しい連想値を簡単にリストの先頭に追加できるので、スタッ クに保持したいような情報を記録するのによく使用されます。連想リストから与 えられたキーにたいして連想値を検索する場合、それが複数ある場合は、最初に 見つかったものがreturnされます。 Emacs Lispでは、連想リストがコンスセルでなくても、それは_エラーではあ りません_。alist検索関数は、単にそのような要素を無視します。多くの他のバ ージョンのLispでは、このような場合はエラーをシグナルします。 いくつかの観点において、プロパティーリストは連想リストと似ていること に注意してください。それぞれのキーが一度だけ出現するような場合、プロパテ ィーリストは連想リストと同様に振る舞います。プロパティーリストと連想リス トの比較については、*note Property Lists::を参照してください。 -- Function: assoc key alist この関数は、alist要素にたいしてKEYを比較するのに‘equal’を使用して、 ALIST内からKEYをもつ最初の連想をリターンする。CARがKEYと‘equal’であ るような連想値がALISTになければ、この関数は‘nil’をリターンする。た とえば: (setq trees '((pine . cones) (oak . acorns) (maple . seeds))) ⇒ ((pine . cones) (oak . acorns) (maple . seeds)) (assoc 'oak trees) ⇒ (oak . acorns) (cdr (assoc 'oak trees)) ⇒ acorns (assoc 'birch trees) ⇒ nil 以下はキーと値がシンボルでない場合の例である: (setq needles-per-cluster '((2 "Austrian Pine" "Red Pine") (3 "Pitch Pine") (5 "White Pine"))) (cdr (assoc 3 needles-per-cluster)) ⇒ ("Pitch Pine") (cdr (assoc 2 needles-per-cluster)) ⇒ ("Austrian Pine" "Red Pine") 関数‘assoc-string’は‘assoc’と似ていますが、文字列間の特定の違いを無視 する点が異なります。*note Text Comparison::を参照してください。 -- Function: rassoc value alist この関数はALISTの中から値VALUEをもつ最初の連想をリターンする。CDRが VALUEと‘equal’であるような連想値がALISTになければ、この関数は ‘nil’をリターンする。 ‘rassoc’は‘assoc’と似てイルが、CARではなくALISTの連想値のCDRを比較 する。この関数は与えられた値に対応するキーを探す、‘assoc’の逆バージ ョンと考えることができよう。 -- Function: assq key alist この関数は、ALISTからKEYをもつ最初の連想値をリターンする点は ‘assoc’と同様だが、比較に‘equal’ではなく‘eq’を使用する点が異なる。 CARがKEYと‘eq’であるような連想値がALIST内に存在しなければ、‘assq’は ‘nil’をリターンする。‘eq’は‘equal’より早く、ほとんどのalistはキーに シンボルを使用するので、この関数は‘assoc’より多用される。*note Equality Predicates::を参照のこと。 (setq trees '((pine . cones) (oak . acorns) (maple . seeds))) ⇒ ((pine . cones) (oak . acorns) (maple . seeds)) (assq 'pine trees) ⇒ (pine . cones) 逆にキーがシンボルではないalistでは、通常は‘assq’は有用ではない: (setq leaves '(("simple leaves" . oak) ("compound leaves" . horsechestnut))) (assq "simple leaves" leaves) ⇒ nil (assoc "simple leaves" leaves) ⇒ ("simple leaves" . oak) -- Function: alist-get key value &optional default remove この関数は‘assq’と似ているが、KEYにたいする連想値全体‘(KEY . VALUE)’ではなく、VALUEだけをリターンする点が異なる。KEYがALIST内で 見つからなければDEFAULTをリターンする。 これは‘setf’での値の変更に使用できる汎変数である(*note Generalized Variables::を参照)。値の値へのセットにこれを使用する際、オプション 引数REMOVEが非nilの場合は、新たな値がDEFAULTと‘eql’なら、ALISTから KEYを削除することを意味する。 -- Function: rassq value alist この関数は、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)) -- Function: assoc-default key alist &optional test default この関数は、KEYにたいするマッチをALISTから検索する。ALISTの各要素に たいして、この関数はKEYと要素(アトムの場合)、または要素のCAR(コンス の場合)を比較する。比較はTESTに2つの引数 — 要素(か要素のCAR)とKEY — を与えて呼び出すことにより行なわれる。引数はこの順番で渡されるので 、正規表現(*note Regexp Search::を参照)を含むalistでは、 ‘string-match’を使用することにより有益な結果を得ることができる。 TESTが省略または‘nil’なら比較に‘equal’が使用される。 alistの要素がこの条件によりKEYとマッチすると、‘assoc-default’はその 要素の値をリターンする。要素がコンスなら値は要素のCDR、それ以外なら リターン値はDEFAULTとなる。 KEYにマッチする要素がalistに存在しないければ、‘assoc-default’は ‘nil’をリターンする。 -- Function: copy-alist alist この関数は深さのレベルが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") -- Function: assq-delete-all key alist この関数は、‘delq’を使用してマッチする要素を1つずつ削除するときのよ うに、CARがKEYと‘eq’であるようなすべての要素をALISTから削除する。こ の関数は短くなったalistをリターンし、ALISTの元のリスト構造を変更す ることもよくある。正しい結果を得るために、ALISTに保存された値ではな く‘assq-delete-all’のリターン値を使用すること。 (setq alist '((foo 1) (bar 2) (foo 3) (lose 4))) ⇒ ((foo 1) (bar 2) (foo 3) (lose 4)) (assq-delete-all 'foo alist) ⇒ ((bar 2) (lose 4)) alist ⇒ ((foo 1) (bar 2) (lose 4)) -- Function: rassq-delete-all value alist この関数は、ALISTからCDRがVALUEと‘eq’であるようなすべての要素を削除 する。この関数は短くなったリストをリターンし、ALISTの元のリスト構造 を変更することもよくある。‘rassq-delete-all’は‘assq-delete-all’と似 ているが、CARではなくALISTの各連想のCDRを比較する。 ---------- Footnotes ---------- (1) ここでの“キー(key)”の使い方は、用語“キーシーケンス(key sequence)”とは関係ありません。キーはテーブルにあるアイテムを探すために使 用される値という意味です。この場合、テーブルはalistでありalistはアイテム に関連付けられます。 5.9 プロパティリスト ==================== “プロパティーリスト(property list、短くはplist)”は、ペアになった要素のリ ストです。各ペアはプロパティー名(通常はシンボル)とプロパティー値を対応づ けます。以下はプロパティーリストの例です: (pine cones numbers (1 2 3) color "blue") このプロパティーリストは‘pine’を‘cones’、‘numbers’を‘(1 2 3)’、‘color’を ‘"blue"’に関連づけます。プロパティー名とプロパティー値には任意のLispオブ ジェクトを指定できますが、通常プロパティー名は(この例のように)シンボルで す。 いくつかのコンテキストでプロパティーリストが使用されます。たとえば関 数‘put-text-property’はプロパティーリストを引数にとり、文字列やバッファ ー内のテキストにたいして、テキストプロパティーとテキストに適用するプロパ ティー値を指定します。*note Text Properties::を参照してください。 プロパティーリストが頻繁に使用される他の例は、シンボルプロパティーの 保管です。すべてのシンボルはシンボルに関する様々な情報を記録するために、 プロパティーのリストを処理します。これらのプロパティーはプロパティーリス トの形式で保管されます。*note Symbol Properties::を参照してください。 5.9.1 プロパティリストと連想リスト ---------------------------------- 連想リスト(*note Association Lists::を参照)は、プロパティーリストとよく 似ています。連想リストとは対照的にプロパティー名は一意でなければならない ので、プロパティーリスト内でペアの順序に意味はありません。 様々なLisp関数や変数に情報を付加するためには、連想リストよりプロパテ ィーリストの方が適しています。プログラムでこのような情報すべてを1つの連 想リストに保持する場合は、特定のLisp関数や変数にたいする連想をチェックす る度にリスト全体を検索する必要が生じ、それにより遅くなる可能性があります 。対照的に関数名や変数自体のプロパティーリストに同じ情報を保持すれば、検 索ごとにそのプロパティーリストの長さだけを検索するようになり、通常はこち らの方が短時間で済みます。変数のドキュメントが‘variable-documentation’と いう名前のプロパティーに記録されているのはこれが理由です。同様にバイトコ ンパイラーも、特別に扱う必要がある関数を記録するためにプロパティーを使用 します。 とはいえ連想リストにも独自の利点があります。アプリケーションに依存し ますが、プロパティーを更新するより連想リストの先頭に連想を追加する方が高 速でしょう。シンボルにたいするすべてのプロパティーは同じプロパティーリス トに保管されるので、プロパティー名を異なる用途のために使用すると衝突の可 能性があります(この理由により、そのプログラムで通常の変数や関数の名前に つけるプレフィクスをプロパティー名の先頭につけて、一意と思われるプロパテ ィー名を選ぶのはよいアイデアだと言える)。連想リストは、連想をリストの先 頭にpushして、その後にある連想は無視されるので、スタックと同様に使用でき ます。これはプロパティーリストでは不可能です。 5.9.2 プロパティリストと外部シンボル ------------------------------------ 以下の関数はプロパティーリストを操作するために使用されます。これらの関数 はすべて、プロパティー名の比較に‘eq’を使用します。 -- Function: plist-get plist property この関数はプロパティーリストPLISTに保管された、プロパティー PROPERTYの値をリターンする。この関数には不正な形式(malformed)の PLIST引数を指定できる。PLISTでPROPERTYが見つからないと、この関数は ‘nil’をリターンする。たとえば、 (plist-get '(foo 4) 'foo) ⇒ 4 (plist-get '(foo 4 bad) 'foo) ⇒ 4 (plist-get '(foo 4 bad) 'bad) ⇒ nil (plist-get '(foo 4 bad) 'bar) ⇒ nil -- Function: plist-put plist property value この関数はプロパティーリストPLISTに、プロパティーPROPERTYの値として VALUEを保管する。この関数はPLISTを破壊的に変更するかもしれず、元の リスト構造を変更せずに新しいリストを構築することもある。この関数は 変更されたプロパティーリストをリターンするので、PLISTを取得した場所 に書き戻すことができる。たとえば、 (setq my-plist '(bar t foo 4)) ⇒ (bar t foo 4) (setq my-plist (plist-put my-plist 'foo 69)) ⇒ (bar t foo 69) (setq my-plist (plist-put my-plist 'quux '(a))) ⇒ (bar t foo 69 quux (a)) -- Function: lax-plist-get plist property ‘plist-get’と同様だがプロパティーの比較に‘eq’ではなく‘equal’を使用 する。 -- Function: lax-plist-put plist property value ‘plist-put’と同様だがプロパティーの比較に‘eq’ではなく‘equal’を使用 する。 -- Function: plist-member plist property この関数は与えられたPROPERTYがPLISTに含まれるなら非‘nil’をリターン する。‘plist-get’とは異なりこの関数は存在しないプロパティーと、値が ‘nil’のプロパティーを区別できる。実際にリターンされる値は、‘car’が PROPERTYで始まるPLISTの末尾部分である。 6 シーケンス、配列、ベクター **************************** “シーケンス(sequence)”型は2つの異なるLisp型 — リストと配列 — を結合した 型です。言い換えると任意のリストはシーケンスであり任意の配列はシーケンス です。すべてのシーケンスがもつ共通な属性は、それぞれが順序づけされた要素 のコレクションであることです。 “配列(array)”はスロットがその要素であるような、固定長のオブジェクトで す。すべての要素に一定時間でアクセスできます。配列の4つの型として文字列 、ベクター、文字テーブル、ブールベクターがあります。 リストは要素のシーケンスですが、要素は単一の基本オブジェクトではあり ません。リストはコンスセルにより作られ、要素ごとに1つのセルをもちます。 N番目の要素を探すにはN個のコンスセルを走査する必要があるので、先頭から離 れた要素ほどアクセスに時間を要します。しかしリストは要素の追加や削除が可 能です。 以下の図はこれらの型の関連を表しています: _____________________________________________ | | | Sequence | | ______ ________________________________ | | | | | | | | | List | | Array | | | | | | ________ ________ | | | |______| | | | | | | | | | | Vector | | String | | | | | |________| |________| | | | | ____________ _____________ | | | | | | | | | | | | | Char-table | | Bool-vector | | | | | |____________| |_____________| | | | |________________________________| | |_____________________________________________| 6.1 シーケンス ============== このセクションでは任意の種類のシーケンスを許す関数を説明します。 -- Function: sequencep object この関数はOBJECTがリスト、ベクター、文字列、ブールベクター、文字テ ーブルなら‘t’、それ以外は‘nil’をリターンする。 -- Function: length sequence この関数はSEQUENCE内の要素の数をリターンする。SEQUENCEがドットリス トなら‘wrong-type-argument’エラーがシグナルされる。循環リストは無限 ループを引き起こす。文字テーブルではEmacsの最大文字コードより1大き い値が常にリターンされる。 関連する関数‘safe-length’については*note 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 *note Text Representations::の‘string-bytes’も参照されたい。 ディスプレー上での文字列の幅を計算する必要があるなら、文字数だけを数 えて各文字のディスプレー幅を計算しない‘length’ではなく、‘string-width’ (*note Size of Displayed Text::を参照)を使用すること。 -- Function: elt sequence index この関数はINDEXによりインデックスづけされた、SEQUENCEの要素をリター ンする。INDEXの値として妥当なのは、0からSEQUENCEの長さより1小さい数 までの範囲の整数。SEQUENCEがリストなら範囲外の値は‘nth’と同じように 振る舞う。*note 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’ (*note Array Functions::を参照)と‘nth’ (*note Definition of nth::を参照)を一般化したものである。 -- Function: copy-sequence sequence この関数はSEQUENCEのコピーをリターンする。コピーは元のシーケンスと 同じ型、同じ要素、同じ順番となる。 コピーに新しい要素を格納するのは、元のSEQUENCEに影響を与えずその逆 も真である。しかし新しいシーケンス内の要素がコピーされたものでなけ れば、元のシーケンスの要素と同一(‘eq’)になる。したがって、コピーさ れたシーケンスを介して見つかった要素を変更すると、この変更は元のシ ーケンスでも見ることができる。 シーケンスがテキストプロパティーをもつ文字列なら、コピー内のプロパ ティーリスト自身もコピーとなり、元のシーケンスのプロパティーリスト と共有はされない。しかしプロパティーリストの実際の値は共有される。 *note Text Properties::を参照のこと。 この関数はドットリストでは機能しない。循環リストのコピーは無限ルー プを起こすだろう。 シーケンスをコピーする別の方法については*note Building Lists::の ‘append’、*note Creating Strings::の‘concat’、*note Vector Functions::の‘vconcat’も参照されたい。 (setq bar '(1 2)) ⇒ (1 2) (setq x (vector 'foo bar)) ⇒ [foo (1 2)] (setq y (copy-sequence x)) ⇒ [foo (1 2)] (eq x y) ⇒ nil (equal x y) ⇒ t (eq (elt x 1) (elt y 1)) ⇒ t ;; 一方のシーケンスの要素を置き換え (aset x 0 'quux) x ⇒ [quux (1 2)] y ⇒ [foo (1 2)] ;; 共有された要素の内部を変更 (setcar (aref x 1) 69) x ⇒ [quux (69 2)] y ⇒ [foo (69 2)] -- Function: reverse sequence この関数は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" -- Function: nreverse sequence この関数はSEQUENCEの要素を反転する。‘reverse’とは異なり、元となる SEQUENCEは変更されるかもしれない。 たとえば: (setq x '(a b c)) ⇒ (a b c) x ⇒ (a b c) (nreverse x) ⇒ (c b a) ;; 先頭にあったコンスセルが末尾となった x ⇒ (a) 混乱しないように、通常は元となるリストを保持する同じ変数に、 ‘nreverse’の結果を書き戻す: (setq x (nreverse x)) お馴染の例‘(a b c)’の‘nreverse’を以下に図示する: Original list head: Reversed list: ------------- ------------- ------------ | car | cdr | | car | cdr | | car | cdr | | a | nil |<-- | b | o |<-- | c | o | | | | | | | | | | | | | | ------------- | --------- | - | -------- | - | | | | ------------- ------------ setqが不要なのでベクターはより単純になる: (setq x [1 2 3 4]) ⇒ [1 2 3 4] (nreverse x) ⇒ [4 3 2 1] x ⇒ [4 3 2 1] ‘reverse’とは異なり、この関数は文字列では機能しない。‘aset’を使用し て文字列データを変更できても、文字列は不変として扱うことを強く推奨 する。 -- Function: sort sequence predicate この関数はSEQUENCEを安定ソートする。この関数はすべてのシーケンスに たいしては機能せず、リストとベクターにたいしてのみ使用できることに 注意されたい。SEQUENCEがリストなら破壊的に変更される。この関数はソ ートされたSEQUENCEをリターンして、要素の比較にはPREDICATEを使用する 。安定ソートでは、ソートキーが等しい要素の相対順序がソートの前後で 保たれる。この安定性は異なる条件により要素を並べ替えるために、連続 してソートを行う場合に重要となる。 引数PREDICATEは2つの引数を受け取る関数でなければならない。これは SEQUENCEの2つの要素で呼び出される。昇順でソートするなら、1つ目の要 素が2つ目の要素より“小”なら非‘nil’、それ以外なら‘nil’をリターンする こと。 比較関数PREDICATEは、少なくとも‘sort’の単一の呼び出しにおいて、与え られた任意の引数ペアにたいして信頼できる結果をリターンしなければな らない。これは“非対照的(antisymmetric)”、すなわちAがBより小なら、 BがAより小であってはならず、“推移律(transitive)”、すなわちAがBより 小、かつBがCより小なら、AはCより小でなければならない。これらの要件 に合致しない比較関数を使用すると、‘sort’の結果は予想できない。 ‘sort’のリストにたいする破壊的側面は、CDRを変更することにより SEQUENCEを形成するコンスセルを再配置することにある。非破壊ソート関 数は、それらのソート順に要素を格納するために、新たなコンスセルを作 成するだろう。オリジナルを破壊せずにソートしたコピーを望むなら、ま ず‘copy-sequence’でコピーしてからソートすること。 ソートによりSEQUENCEのコンスセルのCARは変化しない。元々SEQUENCE内で 要素‘a’を含むコンスセルは、ソート後もそのCARに‘a’を保持する。しかし CDRの変更により、ソート後には異なる位置に出現する。たとえば: (setq nums '(1 3 2 6 5 4 0)) ⇒ (1 3 2 6 5 4 0) (sort nums '<) ⇒ (0 1 2 3 4 5 6) nums ⇒ (1 2 3 4 5 6) *警告* ‘nums’内のリストが0を含まないことに注意。これはソート前と同 じコンスセルだがもはやリストの先頭ではない。ソート前に引数を保持し ていた変数がソート済みリスト全体を保持すると仮定してはならない! か わりに‘sort’の結果を保存して、それを使うこと。ほとんどの場合、わた したちは元のリストを保持していた変数に結果を書き戻すようにしている 。 (setq nums (sort nums '<)) 安定ソートの何たるかをより理解するには、以下のベクターのサンプルを 考えてみよ。ソート後、‘car’が8であるようなすべてのアイテムは ‘vector’の先頭にグループ化されるが、それらの相対的な順序は保たれる 。‘car’が9であるようなすべてのアイテムは‘vector’の末尾にグループ化 されるが、それらの相対的な順序も保たれる。 (setq vector (vector '(8 . "xxx") '(9 . "aaa") '(8 . "bbb") '(9 . "zzz") '(9 . "ppp") '(8 . "ttt") '(8 . "eee") '(9 . "fff"))) ⇒ [(8 . "xxx") (9 . "aaa") (8 . "bbb") (9 . "zzz") (9 . "ppp") (8 . "ttt") (8 . "eee") (9 . "fff")] (sort vector (lambda (x y) (< (car x) (car y)))) ⇒ [(8 . "xxx") (8 . "bbb") (8 . "ttt") (8 . "eee") (9 . "aaa") (9 . "zzz") (9 . "ppp") (9 . "fff")] ソートを行う他の関数については*note Sorting::を参照のこと。‘sort’の 有用な例は、*note Accessing Documentation::の‘documentation’を参照 されたい。 ‘seq.el’ライブラリーは、以下のようなプレフィクス‘seq-’がついたシーケ ンス操作用の追加のマクロと関数を提供します。それらを使用するには、最初に ‘seq’ライブラリーをロードしなければなりません。 このライブラリー内で定義されたすべての関数は、副作用をもちません。こ れらは引数として渡されたすべてのシーケンス(リスト、ベクター、文字列)を変 更しません。特に明記しなければ、結果は入力と同じ型のシーケンスです。述語 を受け取る関数では、それらは単一の関数である必要があります。 ‘seq.el’ライブラリーは、シーケンシャルなデータ構造の追加型で機能する ように拡張可能です。そのためにすべての関数は‘cl-defgeneric’を使用して定 義されています。‘cl-defgeneric’を使用した拡張の追加に関する詳細は、*note Generic Functions::を参照してください。 -- Function: seq-elt sequence index この関数はINDEX(有効な範囲は0からSEQUENCEの長さより1少ない整数)で指 定されたSEQUENCEの要素をリターンする。ビルトインのシーケンス型にた いする範囲外(out-of-range)の値にたいして、‘seq-elt’は‘elt’と同様に 振る舞う。詳細は*note Definition of elt::を参照のこと。 (seq-elt [1 2 3 4] 2) ⇒ 3 ‘seq-elt’は‘setf’を使用してセット可能なplaceをリターンする(*note Setting Generalized Variables::を参照)。 (setq vec [1 2 3 4]) (setf (seq-elt vec 2) 5) vec ⇒ [1 2 5 4] -- Function: seq-length sequence この関数はSEQUENCE内の要素の個数をリターンする。ビルトインのシーケ ンス型にたいして‘seq-length’は‘length’と同様に振る舞う。*note Definition of length::を参照のこと。 -- Function: seqp sequence この関数はSEQUENCEがシーケンス(リストか配列)、または‘seq.el’のジェ ネリック関数を通じて定義されたすべての追加シーケンス型なら非‘nil’を リターンする。 (seqp [1 2]) ⇒ t (seqp 2) ⇒ nil -- Function: seq-drop sequence n この関数はSEQUENCEの最初のN個(整数)を除く、すべての要素をリターンす る.Nが0以下なら結果はSEQUENCE。 (seq-drop [1 2 3 4 5 6] 3) ⇒ [4 5 6] (seq-drop "hello world" -4) ⇒ "hello world" -- Function: seq-take sequence n この関数はSEQUENCEの最初のN個(整数)の要素をリターンする。Nが0以下な ら結果は‘nil’。 (seq-take '(1 2 3 4) 3) ⇒ (1 2 3) (seq-take [1 2 3 4] 0) ⇒ [] -- Function: seq-take-while predicate sequence この関数は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]) ⇒ [] -- Function: seq-drop-while predicate sequence この関数は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] -- Function: seq-do function sequence この関数はSEQUENCEの各要素にたいして、(恐らくは副作用を得るために )順番にFUNCTIONを適用して、SEQUENCEをリターンする。 -- Function: seq-map function sequence この関数はSEQUENCEの各要素にFUNCTIONを適用した結果をリターンする。 リターン値はリスト。 (seq-map #'1+ '(2 4 6)) ⇒ (3 5 7) (seq-map #'symbol-name [foo bar]) ⇒ ("foo" "bar") -- Function: seq-mapn function &rest sequences この関数はSEQUENCESの各要素にFUNCTIONを適用した結果をリターンする。 FUNCTIONのarity (関数が受け取れる引数の個数。*note sub-arity: What Is a Function.を参照)はシーケンスの個数にマッチしなければならない。 マッピングは最短のシーケンス終端で停止する。リターン値はリスト。 (seq-mapn #'+ '(2 4 6) '(20 40 60)) ⇒ (22 44 66) (seq-mapn #'concat '("moskito" "bite") ["bee" "sting"]) ⇒ ("moskitobee" "bitesting") -- Function: seq-filter predicate sequence この関数は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 -- Function: seq-remove predicate sequence この関数は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 -- Function: seq-reduce function sequence initial-value この関数はINITIAL-VALUEとSEQUENCEの1つ目の要素でFUNCTIONを呼び出し 、次にその結果とSEQUENCEの2つ目の要素でFUNCTIONを呼び出し、その次に その結果とSEQUENCEの3つ目の要素で、...と呼び出した結果をリターンす る。FUNCTIONは引数が2つの関数であること。SEQUENCEが空なら、これは FUNCTIONを呼び出さずにINITIAL-VALUEをリターンする。 (seq-reduce #'+ [1 2 3 4] 0) ⇒ 10 (seq-reduce #'+ '(1 2 3 4) 5) ⇒ 15 (seq-reduce #'+ '() 3) ⇒ 3 -- Function: seq-some predicate sequence この関数は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 -- Function: seq-find predicate sequence &optional default この関数はPREDICATEが非‘nil’をリターンした、SEQUENCE内の最初の要素 をリターンする。PREDICATEにマッチする要素がなければ、この関数は DEFAULTをリターンする。 この関数は見つかった要素がDEFAULTと等しい場合、要素が見つかったかど うかを知る術がないので曖昧さをもつことに注意。 (seq-find #'numberp ["abc" 1 nil]) ⇒ 1 (seq-find #'numberp ["abc" "def"]) ⇒ nil -- Function: seq-every-p predicate sequence この関数はSEQUENCEの各要素にPREDICATEを適用して、すべてが非‘nil’を リターンしたら非‘nil’をリターンする。 (seq-every-p #'numberp [2 4 6]) ⇒ t (seq-some #'numberp [2 4 "6"]) ⇒ nil -- Function: seq-empty-p sequence この関数はSEQUENCEが空なら‘nil’をリターンする。 (seq-empty-p "not empty") ⇒ nil (seq-empty-p "") ⇒ t -- Function: seq-count predicate sequence この関数はSEQUENCE内でPREDICATEが非‘nil’をリターンした要素の個数を リターンする。 (seq-count (lambda (elt) (> elt 0)) [-1 2 0 3 -2]) ⇒ 2 -- Function: seq-sort function sequence この関数はFUNCTIONに応じてソートされたSEQUENCEのコピーをリターンす る。FUNCTIONは2つの引数を受け取り、1つ目の引数が2つ目より前にソート されるべきなら非‘nil’をリターンする。 -- Function: seq-contains sequence elt &optional function この関数はSEQUENCE内のELTと‘equal’であるような最初の要素をリターン する。オプション引数FUNCTIONが非‘nil’なら、それはデフォルトの ‘equal’のかわりに使用する2つの引数を受け取る関数であること。 (seq-contains '(symbol1 symbol2) 'symbol1) ⇒ symbol1 (seq-contains '(symbol1 symbol2) 'symbol3) ⇒ nil -- Function: seq-position sequence elt &optional function この関数はELTと‘equal’であるようなSEQUENCE内の最初の要素のインデッ クスをリターンする。オプション引数FUNCTIONが非‘nil’なら、それはデフ ォルトの‘equal’のかわりに使用する2つの引数を受け取る関数であること 。 (seq-position '(a b c) 'b) ⇒ 1 (seq-position '(a b c) 'd) ⇒ nil -- Function: seq-uniq sequence &optional function この関数は重複を削除したSEQUENCEの要素のリストをリターンする。オプ ション引数FUNCTIONが非‘nil’なら、それはデフォルトの‘equal’のかわり に使用する2つの引数を受け取る関数であること。 (seq-uniq '(1 2 2 1 3)) ⇒ (1 2 3) (seq-uniq '(1 2 2.0 1.0) #'=) ⇒ [3 4] -- Function: seq-subseq sequence start &optional end この関数は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] -- Function: seq-concatenate type &rest sequences この関数はSEQUENCESを結合して作成されたTYPE型のシーケンスをリターン する。TYPEは‘vector’、‘list’、‘string’のいずれか。 (seq-concatenate 'list '(1 2) '(3 4) [5 6]) ⇒ (1 2 3 5 6) (seq-concatenate 'string "Hello " "world") ⇒ "Hello world" -- Function: seq-mapcat function sequence &optional type この関数はSEQUENCEの各要素にFUNCTIONを適用した結果に、 ‘seq-concatenate’を適用した結果をリターンする。結果はTYPE型のシーケ ンス、またはTYPEが‘nil’ならリストである。 (seq-mapcat #'seq-reverse '((3 2 1) (6 5 4))) ⇒ (1 2 3 4 5 6) -- Function: seq-partition sequence n この関数は長さ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)) -- Function: seq-intersection sequence1 sequence2 &optional function この関数はSEQUENCE1とSEQUENCE2の両方に出現する要素のリストをリター ンする。オプション引数FUNCTIONが非‘nil’なら、それはデフォルトの ‘equal’のかわりに比較に使用する2つの引数を受け取る関数であること。 (seq-intersection [2 3 4 5] [1 3 5 6 7]) ⇒ (3 5) -- Function: seq-difference sequence1 sequence2 &optional function この関数はSEQUENCE1に出現するがSEQUENCE2に出現しない要素のリストを リターンする。オプション引数FUNCTIONが非‘nil’なら、それはデフォルト の‘equal’のかわりに比較に使用する2つの引数を受け取る関数であること 。 (seq-difference '(2 3 4 5) [1 3 5 6 7]) ⇒ (2 4) -- Function: seq-group-by function sequence この関数は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))) -- Function: seq-into sequence type この関数はシーケンス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] -- Function: seq-min sequence この関数はSEQUENCEの最小の要素をリターンする。SEQUENCEの要素は数字 かマーカー(*note Markers::を参照)でなければならない。 (seq-min [3 1 2]) ⇒ 1 (seq-min "Hello") ⇒ 72 -- Function: seq-max sequence この関数はSEQUENCEの最大の要素をリターンする。SEQUENCEの要素は数字 かマーカーでなければならない。 (seq-max [1 3 2]) ⇒ 3 (seq-max "Hello") ⇒ 111 -- Macro: seq-doseq (var sequence) body... このマクロは‘dolist’ (*note dolist: Iteration.を参照)と同様だが、 SEQUENCEにリスト、ベクター、文字列のいずれかを指定できる点が異なる 。これ主な利点は副作用である。 -- Macro: seq-let arguments sequence body... このマクロはARGUMENTS内で定義される変数にSEQUENCEの要素をバインドす る。ARGUMENTSはネストされた非構造化を許容することにより、自身にシー ケンスを含むことができる。 ARGUMENTSシーケンスには、‘sequence’の残りにバインドされる変数名が後 続するような、‘&rest’マーカーを含めることもできる。 (seq-let [first second] [1 2 3 4] (list first second)) ⇒ (1 2) (seq-let (_ a _ b) '(1 2 3 4) (list a b)) ⇒ (2 4) (seq-let [a [b [c]]] [1 [2 [3]]] (list a b c)) ⇒ (1 2 3) (seq-let [a b &rest others] [1 2 3 4] others) ⇒ [3 4] 6.2 配列 ======== “配列(array)”オブジェクトは、いくつかのLispオブジェクトを保持するスロッ トをもち、これらのオブジェクトは配列の要素と呼ばれます。配列内の任意の要 素は一定時間でアクセスされます。対照的にリスト内の要素のアクセスに要する 時間は、その要素がリスト内のどの位置にあるかに比例します。 Emacsは4つの配列型 —“文字列(strings、*note String Type::を参照)”、“ベ クター(vectors、*note Vector Type::を参照)”、“ブールベクター (bool-vectors、*note Bool-Vector Type::を参照)”、“文字テーブル (char-tables、*note Char-Table Type::を参照)” — を定義しており、これらは すべて1次元です。ベクターと文字テーブルは任意の型の要素を保持できますが 、文字列は文字だけ、ブールベクターは‘t’か‘nil’しか保持できません。 4種のすべての配列はこれらの特性を共有します: • 配列の1番目の要素はインデックス0、2番目はインデックス1、...となる。 これは“0基準(zero-origin)”のインデックスづけと呼ばれる。たとえば4要 素の配列のインデックスは0、1、2、3。 • 配列の長さは一度配列が作成されたら固定されるので、既存の配列の長さ は変更できない。 • 評価において配列は定数 — つまりそれ自身へと評価される。 • 配列の要素は関数‘aref’で参照したり、関数‘aset’で変更できる(*note Array Functions::を参照)。 配列を作成したとき、文字テーブル以外では長さを指定しなければなりませ ん。文字テーブルの長さは文字コードの範囲により決定されるので長さを指定で きません。 原則として、テキスト文字の配列が欲しい場合は、文字列とベクターのどち らかを使用できます。実際のところ4つの理由により,そのような用途にたいして は、わたしたちは常に文字列を選択します: • 文字列は同じ要素をもつベクターと比較して占めるスペースが1/4である。 • 文字列の内容はテキストとして、より明解な方法によりプリントされる。 • 文字列はテキストプロパティーを保持できる。*note Text Properties::を 参照のこと。 • Emacsの特化した編集機能とI/O機能の多くが文字列だけに適用される。た とえば文字列をバッファーに挿入する方法では、文字のベクターをバッフ ァーに挿入できない。*note Strings and Characters::を参照のこと 対照的に、(キーシーケンスのような)キーボード入力文字の配列では、多く のキーボード入力文字は文字列に収まる範囲の外にあるので、ベクターが必要に なるでしょう。*note Key Sequence Input::を参照してください。 6.3 配列を操作する関数 ====================== このセクションではすべての型の配列に適用される関数を説明します。 -- Function: arrayp object この関数はOBJECTが配列(ベクター、文字列、ブールベクター、文字テーブ ル)なら‘t’をリターンする。 (arrayp [a]) ⇒ t (arrayp "asdf") ⇒ t (arrayp (syntax-table)) ;; 文字テーブル ⇒ t -- Function: aref array index この関数は ARRAYのINDEX番目の要素をリターンする。1番目の要素のイン デクスは0。 (setq primes [2 3 5 7 11 13]) ⇒ [2 3 5 7 11 13] (aref primes 4) ⇒ 11 (aref "abcdefg" 1) ⇒ 98 ; ‘b’のASCIIコードは98 *note Sequence Functions::の関数‘elt’も参照されたい。 -- Function: aset array index object この関数はARRAYのINDEX番目の要素をOBJECTにセットする。この関数は OBJECTをリターンする。 (setq w [foo bar baz]) ⇒ [foo bar baz] (aset w 0 'fu) ⇒ fu w ⇒ [fu bar baz] (setq x "asdfasfd") ⇒ "asdfasfd" (aset x 3 ?Z) ⇒ 90 x ⇒ "asdZasfd" ARRAYが文字列でOBJECTが文字でなければ、結果は ‘wrong-type-argument’エラーとなる。この関数は文字列の挿入で必要なら 、ユニバイト文字列をマルチバイト文字列に変換する。 -- Function: fillarray array object この関数は配列ARRAYをOBJECTで充填するので、ARRAYのすべての要素は OBJECTになる。この関数はARRAYをリターンする。 (setq a [a b c d e f g]) ⇒ [a b c d e f g] (fillarray a 0) ⇒ [0 0 0 0 0 0 0] a ⇒ [0 0 0 0 0 0 0] (setq s "When in the course") ⇒ "When in the course" (fillarray s ?-) ⇒ "------------------" ARRAYが文字列でOBJECTが文字でなければ、結果は ‘wrong-type-argument’エラーとなる。 配列と判っているオブジェクトにたいしては、一般的なシーケンス関数 ‘copy-sequence’と‘length’が有用なときがよくあります。*note Sequence Functions::を参照してください。 6.4 ベクター ============ “ベクター(vector)”とは任意のLispオブジェクトを要素にもつことができる、一 般用途のための配列です(対照的に文字列の要素は文字のみ。*note Strings and Characters::を参照)。Emacsではベクターはキーシーケンス(*note Key Sequences::を参照)、シンボル検索用のテーブル(*note Creating Symbols::を 参照)、バイトコンパイルされた関数表現の一部(*note Byte Compilation::を参 照)などの多くの目的で使用されます。 他の配列と同様、ベクターは0基準のインデックスづけを使用し、1番目の要 素はインデックス0になります。 ベクターは角カッコ(square brackets)で囲まれた要素としてプリントされま す。したがってシンボル‘a’、‘b’、‘a’を要素にもつベクターは、‘[a b a]’とプ リントされます。Lisp入力として同じ方法でベクターを記述できます。 文字列や数値と同様にベクターは定数として評価され、評価された結果は同 じベクターになります。ベクターの要素は評価も確認もされません。*note Self-Evaluating Forms::を参照してください。 以下はこれらの原理を表す例です: (setq avector [1 two '(three) "four" [five]]) ⇒ [1 two (quote (three)) "four" [five]] (eval avector) ⇒ [1 two (quote (three)) "four" [five]] (eq avector (eval avector)) ⇒ t 6.5 ベクターのための関数 ======================== ベクターに関連した関数をいくつか示します: -- Function: vectorp object この関数はOBJECTがベクターなら‘t’をリターンする。 (vectorp [a]) ⇒ t (vectorp "asdf") ⇒ nil -- Function: vector &rest objects この関数は引数OBJECTSを要素にもつベクターを作成してリターンする。 (vector 'foo 23 [bar baz] "rats") ⇒ [foo 23 [bar baz] "rats"] (vector) ⇒ [] -- Function: make-vector length object この関数は各要素がOBJECTに初期化された、LENGTH個の要素からなる新し いベクターをリターンする。 (setq sleepy (make-vector 9 'Z)) ⇒ [Z Z Z Z Z Z Z Z Z] -- Function: vconcat &rest sequences この関数は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’関数は、引数としてバイトコード関数オブジェクトも受け取るこ とができる。これはバイトコード関数オブジェクトの内容全体にアクセス するのを容易にするための特別な機能である。*note Byte-Code Objects::を参照のこと。 結合を行なう他の関数については*note Mapping Functions::の ‘mapconcat’、*note Creating Strings::の‘concat’、*note Building Lists::の‘append’を参照されたい。 ‘append’関数はベクターを同じ要素をもつリストに変換する方法も提供しま す: (setq avector [1 two (quote (three)) "four" [five]]) ⇒ [1 two (quote (three)) "four" [five]] (append avector nil) ⇒ (1 two (quote (three)) "four" [five]) 6.6 文字テーブル ================ 文字テーブル(char-table)はベクターとよく似ていますが、文字テーブルは文字 コードによりインデックスづけされます。文字テーブルのインデックスには、修 飾キーをともなわない任意の有効な文字コードを使用できます。他の配列と同様 に、‘aref’と‘aset’で文字テーブルの要素にアクセスできます。加えて、文字テ ーブルは追加のデータを保持するために、特定の文字コードに関連づけられてい ない“エキストラスロット(extra slots)”をもつことができます。ベクターと同 様、文字テーブルは定数として評価され、任意の型の要素を保持できます。 文字テーブルはそれぞれ“サブタイプ(subtype)”をもち、これは2つの目的を もつシンボルです: • サブタイプはそれがなんのための文字テーブルなのかを簡単に表す方法を 提供する。たとえばディスプレーテーブル(display tables)はサブタイプ が‘display-table’の文字テーブルであり、構文テーブル(syntax tables)は サブタイプが‘syntax-table’の文字テーブル。以下で説明するように関数 ‘char-table-subtype’を使用してサブタイプの問い合わせが可能。 • サブタイプは文字テーブル内のいくつかの“エキストラスロット(extra slots)”を制御する。エキストラスロットの数は、そのサブタイプの ‘char-table-extra-slots’シンボルプロパティー(*note Symbol Properties::を参照)により指定され、値は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)’はデフォルト値をリターンします。 -- Function: make-char-table subtype &optional init サブタイプSUBTYPE(シンボル)をもつ、新たに作成された文字テーブルをリ ターンする。各要素はINITに初期化され、デフォルトは‘nil’。文字テーブ ルが作成された後で、文字テーブルのサブタイプを変更することはできな い。 すべての文字テーブルは、インデックスとなる任意の有効な文字テーブル のための空間をもつので、文字テーブルの長さを指定する引数はない。 SUBTYPEがシンボルプロパティー‘char-table-extra-slots’をもつなら、そ れはその文字列テーブル内のエキストラスロットの数を指定する。値には 0から10の整数を指定し、これ以外なら‘make-char-table’はエラーとなる 。SUBTYPEがシンボルプロパティー‘char-table-extra-slots’(*note Property Lists::を参照)をもたなければ、その文字テーブルはエキストラ スロットをもたない。 -- Function: char-table-p object この関数はOBJECTが文字テーブルなら‘t’、それ以外は‘nil’をリターンす る。 -- Function: char-table-subtype char-table この関数はCHAR-TABLEのサブタイプのシンボルをリターンする。 文字テーブルのデフォルト値にアクセスするための特別な関数は存在しませ ん。これを行なうには‘char-table-range’を使用します(以下参照)。 -- Function: char-table-parent char-table この関数はCHAR-TABLEの親をリターンする。親は常に‘nil’か他の文字テー ブルである。 -- Function: set-char-table-parent char-table new-parent この関数はCHAR-TABLEの親をNEW-PARENTにセットする。 -- Function: char-table-extra-slot char-table n この関数はCHAR-TABLEのエキストラスロットN (0基準)の内容をリターンす る。文字テーブルのエキストラスロットの数は文字テーブルのサブタイプ により決定される。 -- Function: set-char-table-extra-slot char-table n value この関数はCHAR-TABLEのエキストラスロットN (0基準)にVALUEを格納する 。 文字テーブルは1つの文字コードにたいして1つの要素値(element value)を指 定できます。文字テーブルは文字セット全体にたいして値を指定することもでき ます。 -- Function: char-table-range char-table range この関数は文字範囲RANGEにたいしてCHAR-TABLEで指定された値をリターン する。可能なRANGEは以下のとおり: ‘nil’ デフォルト値への参照。 CHAR 文字CHARにたいする要素への参照(CHARは有効な文字コードであると 仮定)。 ‘(FROM . TO)’ 包括的な範囲‘[FROM..TO]’内のすべての文字を参照するコンスセル。 -- Function: set-char-table-range char-table range value この関数はCHAR-TABLE内の文字範囲RANGEにたいして値をセットする。可能 なRANGEは以下のとおり: ‘nil’ デフォルト値への参照。 ‘t’ 文字コード範囲の全体を参照。 CHAR 文字CHARにたいする要素への参照(CHARは有効な文字コードであると 仮定)。 ‘(FROM . TO)’ 包括的な範囲‘[FROM..TO]’内のすべての文字を参照するコンスセル。 -- Function: map-char-table function char-table この関数は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))) 6.7 ブールベクター ================== ブールベクター(bool-vector)はベクターとよく似ていますが、値に‘t’と ‘nil’しか格納できません。ブールベクターの要素に非‘nil’値の格納を試みたる と、そこには‘t’が格納されます。すべての配列と同様、ブールベクターのイン デックスは0から開始され、一度ブールベクターが作成されたら長さを変更する ことはできません。ブールベクターは定数として評価されます。 ブールベクターを処理する特別な関数がいくつかあります。その関数以外に も、他の種類の配列に使用されるのと同じ関数でブールベクターを操作できます 。 -- Function: make-bool-vector length initial INITIALに初期化されたLENGTH要素の新しいブールベクターをリターンする 。 -- Function: bool-vector &rest objects この関数は引数OBJECTSを要素にもつブールベクターを作成してリターンす る。 -- Function: bool-vector-p object この関数はOBJECTがブールベクターであれば‘t’、それ以外は‘nil’をリタ ーンする。 以下で説明するように、ブールベクターのセット処理を行なう関数がいくつ かあります: -- Function: bool-vector-exclusive-or a b &optional c ブールベクターAとBの“ビットごとの排他的論理和(bitwise exclusive or)”をリターンする。オプション引数Cが与えられたら、この処理の結果は Cに格納される。引数にはすべて同じ長さのブールベクターを指定すること 。 -- Function: bool-vector-union a b &optional c ブールベクターAとBの“ビットごとの論理和(bitwise or)”をリターンする 。オプション引数Cが与えられたら、この処理の結果はCに格納される。引 数にはすべて同じ長さのブールベクターを指定すること。 -- Function: bool-vector-intersection a b &optional c ブールベクターAとBの“ビットごとの論理積(bitwise and)”をリターンする 。オプション引数Cが与えられたら、この処理の結果はCに格納される。引 数にはすべて同じ長さのブールベクターを指定すること。 -- Function: bool-vector-set-difference a b &optional c ブールベクターAとBの“差集合(set difference)”をリターンする。オプシ ョン引数Cが与えられたら、この処理の結果はCに格納される。引数にはす べて同じ長さのブールベクターを指定すること。 -- Function: bool-vector-not a &optional b ブールベクターAの“補集合(set complement)”をリターンする。オプション 引数Bが与えられたら、この処理の結果はBに格納される。引数にはすべて 同じ長さのブールベクターを指定すること。 -- Function: bool-vector-subsetp a b A内のすべての‘t’値が、Bでも‘t’値なら‘t’、それ以外は‘nil’をリターン する。引数にはすべて同じ長さのブールベクターを指定すること。 -- Function: bool-vector-count-consecutive a b i Iから始まるAの、Bと等しい連続する要素の数をリターンする。‘a’はブー ルベクターで、Bは‘t’か‘nil’、Iは‘a’のインデックス。 -- Function: bool-vector-count-population 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なので、この結果は理にかな っています。 6.8 オブジェクト用固定長リングの管理 ==================================== “リング(ring)”は挿入、削除、ローテーション、剰余(modulo)でインデックスづ けされた、参照と走査(traversal)をサポートする固定長のデータ構造です。 ‘ring’パッケージにより効率的なリングデータ構造が実装されています。このパ ッケージは、このセクションにリストした関数を提供します。 Emacsにあるkillリングやマークリングのようないくつかのリングは、実際に は単なるリストとして実装されていることに注意してください。したがってこれ らのリングにたいしては、以下の関数は機能しないでしょう。 -- Function: make-ring size この関数はSIZEオブジェクトを保持できる、新しいリングをリターンする 。SIZEは整数。 -- Function: ring-p object この関数はOBJECTがリングなら‘t’、それ以外は‘nil’をリターンする。 -- Function: ring-size ring この関数はRINGの最大の要素数をリターンする。 -- Function: ring-length ring この関数はRINGに現在含まれるオブジェクトの数をリターンする。値が ‘ring-size’のリターンする値を超えることはない。 -- Function: ring-elements ring この関数はRING内のオブジェクトのリストをリターンする。リストの順序 は新しいオブジェクトが先頭になる。 -- Function: ring-copy ring この関数は新しいリングとしてRINGのコピーをリターンする。新しいリン グはRINGと同じ(‘eq’な)オブジェクトを含む。 -- Function: ring-empty-p ring この関数はRINGが空なら‘t’、それ以外は‘nil’をリターンする。 リング内の1番新しい要素は常にインデックス0をもちます。より大きいイン デックスは、より古い要素に対応します。インデックスはリング長のmoduloによ り計算されます。インデックス−1は1番古い要素、−2は次に古い要素、...となり ます。 -- Function: ring-ref ring index この関数はインデックスINDEXにあるRING内のオブジェクトをリターンする 。INDEXには負やリング長より大きい数を指定できる。RINGが空なら ‘ring-ref’はエラーをシグナルする。 -- Function: ring-insert ring object この関数は1番新しい要素としてOBJECTをRINGに挿入してOBJECTをリターン する。 リングが満杯なら新しい要素用の空きを作るために、挿入により1番古い要 素が削除される。 -- Function: ring-remove ring &optional index RINGからオブジェクトを削除してそのオブジェクトをリターンする。引数 INDEXはどのアイテムを削除するかを指定する。これが‘nil’なら、それは 1番古いアイテムを削除することを意味する。RINGが空なら ‘ring-remove’はエラーをシグナルする。 -- Function: ring-insert-at-beginning ring object この関数は1番古い要素としてOBJECTをRINGに挿入する。リターン値に意味 はない。 リングが満杯なら、この関数は挿入される要素のための空きを作るために 1番新しい要素を削除する。 リングサイズを超過しないよう注意すれば、そのリングを FIFO(first-in-first-out: 先入れ先出し)のキューとして使用することができま す。たとえば: (let ((fifo (make-ring 5))) (mapc (lambda (obj) (ring-insert fifo obj)) '(0 one "two")) (list (ring-remove fifo) t (ring-remove fifo) t (ring-remove fifo))) ⇒ (0 t one t "two") 7 ハッシュテーブル ****************** ハッシュテーブル(hash table)は非常に高速なルックアップテーブルの一種で、 キーに対応する値をマップするという点ではalist(*note Association Lists::を 参照)に似ています。ハッシュテーブルは以下の点でalistと異なります: • ハッシュテーブルでのルックアップ(lookup: 照合)は、巨大なテーブルに たいして非常に高速である — 実際のところルックアップに必要な時間は、 そのテーブルに格納されている要素数とは基本的に_無関係_である。ハッ シュテーブルには一定のオーバーヘッドが多少あるので、小さいテーブル (数十の要素)ではalistのほうが高速だろう。 • ハッシュテーブル内の対応関係に特定の順序はない。 • 2つのalistで共通の末尾(tail)を共有させるような、2つのハッシュテーブ ル間で構造を共有する方法はない。 Emacs Lispは一般的な用途のハッシュテーブルデータ型とともに、それらを 処理する一連の関数を提供します。ハッシュテーブルは‘#s’、その後にハッシュ テーブルのプロパティーと内容を指定するリストが続く、特別なプリント表現を もちます。*note Creating Hash::を参照してください(ハッシュ表記の最初に使 用される‘#’文字は、読み取り表現をもたないオブジェクトのプリント表現であ り、これはハッシュテーブルに何も行わない。*note Printed Representation::を参照のこと)。 obarray(オブジェクト配列)もハッシュテーブルの一種ですが、これらは異な る型のオブジェクトであり、intern(インターン)されたシンボルを記録するため だけに使用されます(*note Creating Symbols::を参照)。 7.1 ハッシュテーブルの作成 ========================== ハッシュテーブルを作成する基本的な関数は‘make-hash-table’です。 -- Function: make-hash-table &rest keyword-args この関数は指定された引数に対応する新しいハッシュテーブルを作成する 。引数はキーワード(特別に認識される独自のシンボル)と、それに対応す る値を交互に指定することで構成される。 ‘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’ (*note Defining Hash::を参照)を使用す ることができる。 ‘:weakness WEAK’ ハッシュテーブルのweakness(強度)は、ハッシュテーブル内に存在す るキーと値をガーベージコレクションから保護するかどうかを指定す る。 値WEAKには‘nil’、‘key’、‘value’、‘key-or-value’、 ‘key-and-value’、または‘t’(‘key-and-value’のエイリアス)のいず れかを指定しなければならない。WEAKが‘key’ならそのハッシュテー ブルは、(キーが他の場所で参照されていなければ)ハッシュテーブル のキーがガーベージコレクトされるのを妨げられない。ある特定のキ ーがガーベージコレクトされると、それに対応する連想はハッシュテ ーブルから削除される。 WEAKが‘value’ならそのハッシュテーブルは、(値が他の場所で参照さ れていなければ)ハッシュテーブルの値がガベージコレクトされるの を妨げませんられない。ある特定の値がガーベージコレクトされると 、それに対応する連想はハッシュテーブルから削除される。 WEAKが‘key-and-value’(か‘t’)なら、その連想を保護するためにはキ ーと値の両方が生きていなければならない。したがってそのハッシュ テーブルは、キーと値の一方だけをガーベージコレクトから守ること はしない。キーか値のどちらか一方がガーベージコレクトされたら、 その連想は削除される。 WEAKが‘key-or-value’nara、キーか値のどちらか一方で、その連想を 保護することができる。したがってキーと値の両方がガベージコレク トされたときだけ(それがハッシュテーブル自体にたいする参照でな ければ)、ハッシュテーブルからその連想が削除される。 WEAKのデフォルトは‘nil’なので、ハッシュテーブルから参照されて いるキーと値はすべてガーベージコレクションから保護される。 ‘:size SIZE’ これはそのハッシュテーブルに保管しようとしている、連想の数にた いするヒントを指定する。数が概算で判っていれば、この方法でそれ を指定して処理を若干効率的にすることができる。小さすぎるサイズ を指定すると、そのハッシュテーブルは必要に応じて自動的に拡張さ れるが、これを行なうために時間が余計にかかる。 デフォルトのサイズは65。 ‘:rehash-size REHASH-SIZE’ ハッシュテーブルに連想を追加するとき、そのテーブルが満杯ならテ ーブルを自動的に拡張する。この値はその際にどれだけハッシュテー ブルを拡張するかを指定する。 REHASH-SIZEが整数(正であること)なら、通常のサイズに REHASH-SIZEを加えてハッシュテーブルを拡張する。REHASH-SIZEが浮 動小数点数(1より大きい方がよい)なら、古いサイズにその数を乗じ てハッシュテーブルを拡張する。 デフォルト値は1.5。 ‘:rehash-threshold THRESHOLD’ これはハッシュテーブルが満杯(なのでもっと大きく拡張する必要が ある)と判断される基準を指定する。THRESHOLDの値は、1以下の正の 浮動小数点数であること。実際のエントリー数が、通常のサイズにた いする指定割合を超えると、そのハッシュテーブルは満杯となる。 THRESHOLDのデフォルトは0.8。 ハッシュテーブルのプリント表現を使用して、新しいハッシュテーブルを作 成することもできます。指定されたハッシュテーブル内の各要素が、有効な入力 構文(*note Printed Representation::を参照)をもっていれば、Lispリーダーは このプリント表現を読み取ることができます。たとえば以下は値‘val1’(シンボ ル)と‘300’(数字)に関連づけられた、キー‘key1’と‘key2’(両方ともシンボル)を 、新しいハッシュテーブルに指定します。 #s(hash-table size 30 data (key1 val1 key2 300)) ハッシュテーブルのプリント表現は‘#s’と、その後の‘hash-table’で始まるリス トにより構成されます。このリストの残りの部分はそのハッシュテーブルのプロ パティーと初期内容を指定する、0個以上のプロパティーと値からなるペアで構 成されるべきです。プロパティーと値はそのまま読み取られます。有効なプロパ ティー名は‘size’、‘test’、‘weakness’、‘rehash-size’、 ‘rehash-threshold’、‘data’です。‘data’プロパティーは、初期内容にたいする キーと値のペアのリストであるべきです。他のプロパティーは、上記で説明した ‘make-hash-table’のキーワード(‘:size’、‘:test’など)と同じ意味をもちます 。 バッファーやフレームのような、入力構文をもたないオブジェクトを含んだ 初期内容をもつハッシュテーブルを指定できないことに注意してください。その ようなオブジェクトは、ハッシュテーブルを作成した後に追加します。 7.2 ハッシュテーブルへのアクセス ================================ このセクションではハッシュテーブルにアクセスしたり、連想を保管する関数を 説明します。比較方法による制限がない限り、一般的には任意のLispオブジェク トをハッシュキーとして使用できます。 -- Function: gethash key table &optional default この関数はTABLEのKEYを照合してそれに関連づけられたVALUE、TABLE内に KEYをもつ連想が存在しなければDEFAULTをリターンする。 -- Function: puthash key value table この関数はTABLE内に値VALUEをもつKEYの連想を挿入します。TABLEがすで にKEYの連想をもつなら、VALUEで古い連想値を置き換える。 -- Function: remhash key table この関数はTABLEにKEYの連想があればそれを削除する。KEYが連想をもたな ければ‘remhash’は何も行なわない。 Common Lispに関する注意: Common Lispでは‘remhash’が実際に連想を削除 したときは非‘nil’、それ以外は‘nil’をリターンする。Emacs Lispでは ‘remhash’は常に‘nil’をリターンする。 -- Function: clrhash table この関数はハッシュテーブルTABLEからすべての連想を削除するので、その ハッシュテーブルは空になる。これはハッシュテーブルの“クリーニング (clearing)”とも呼ばれる。 Common Lispに関する注意: Common Lispでは‘clrhash’は空のTABLEをリタ ーンする。Emacs Lispでは‘nil’をリターンする。 -- Function: maphash function table この関数はTABLE内の各連想にたいして一度ずつFUNCTIONを呼び出す。関数 FUNCTIONは2つの引数 — TABLEにリストされたKEYと、それに関連づけられ たVALUE — を受け取ること。‘maphash’は‘nil’をリターンする。 7.3 ハッシュの比較の定義 ======================== ‘define-hash-table-test’でキーを照合する新しい方法を定義できます。この機 能を使用するにはハッシュテーブルの動作方法と、“ハッシュコード(hash code)”の意味を理解する必要があります。 概念的にはハッシュテーブルを1つの連想を保持できるスロットがたくさんあ る巨大な配列として考えることができます。キーを照合するにはまず、 ‘gethash’がキーから整数のハッシュコードを計算します。配列内のインデック スを生成するために、‘gethash’は配列の長さからこの整数のmoduloを得ます。 それからキーが見つかったかどうか確認するためにそのスロット、もし必要なら 近くのスロットを探します。 したがってキー照合の新しい方法を定義するためには、キーからハッシュコ ードを計算する関数と、2つのキーを直接比較する関数の両方が必要です。 -- Function: define-hash-table-test name test-fn hash-fn この関数はNAMEという名前の新たなハッシュテーブルテストを定義します 。 この方法でNAMEを定義した後は、‘make-hash-table’の引数TESTにこれを使 用することができる。これを行なう際は、そのハッシュテーブルのキー値 の比較にTEST-FN、キー値からハッシュコードを計算するためにHASH-FNを 使用することになる。 関数TEST-FNは2つの引数(2つのキー)をとり、それらが同一と判断されたと きは非‘nil’をリターンする。 関数HASH-FNは1つの引数(キー)を受け取り、そのキーのハッシュコード(整 数)をリターンすること。よい結果を得るために、その関数は負の整数を含 む整数の全範囲をハッシュコードに使用するべきある。 指定された関数は、プロパティー‘hash-table-test’の配下の、NAMEという プロパティーリストに格納される。そのプロパティーの値形式は‘(TEST-FN HASH-FN)’。 -- Function: sxhash obj この関数はLispオブジェクトOBJのハッシュコードをリターンする。リター ン値はOBJと、それが指す別のLispオブジェクトの内容を表す整数。 2つのオブジェクトOBJ1とOBJ2がequalなら、‘(sxhash OBJ1)’と‘(sxhash OBJ2)’は同じ整数になる。 2つのオブジェクトがequalでなければ、通常は‘sxhash’がリターンする値 は異なるが、常に異なるとは限らない。稀(運次第)にだが‘sxhash’が同じ 結果を与えるような、2つの異なった外見のオブジェクトに遭遇するかもし れない。 以下はlcaseを区別しない文字列のキーをもつハッシュテーブルを作成する例 です。 (defun case-fold-string= (a b) (eq t (compare-strings a nil nil b nil nil t))) (defun case-fold-string-hash (a) (sxhash (upcase a))) (define-hash-table-test 'case-fold 'case-fold-string= 'case-fold-string-hash) (make-hash-table :test 'case-fold) 以下は事前に定義されたテスト値‘equal’と等価なテストを行なうハッシュテ ーブルを定義できるという例です。キーは任意のLispオブジェクトで、equalに 見えるオブジェクトは同じキーと判断されます。 (define-hash-table-test 'contents-hash 'equal 'sxhash) (make-hash-table :test 'contents-hash) 7.4 ハッシュテーブルのためのその他関数 ====================================== 以下はハッシュテーブルに作用する他の関数です。 -- Function: hash-table-p table この関数はTABLEがハッシュテーブルオブジェクトなら非‘nil’をリターン する。 -- Function: copy-hash-table table この関数はTABLEのコピーを作成してリターンする。そのテーブル自体がコ ピーされたものである場合のみ、キーと値が共有される。 -- Function: hash-table-count table この関数はTABLE内の実際のエントリー数をリターンする。 -- Function: hash-table-test table この関数はハッシュを行なう方法と、キーを比較する方法を指定するため に、TABLE作成時に与えられたTESTの値をリターンする。*note Creating Hash::の‘make-hash-table’を参照されたい。 -- Function: hash-table-weakness table この関数はハッシュテーブルTABLEに指定されたWEAKの値をリターンする。 -- Function: hash-table-rehash-size table この関数はTABLEのrehash-sizeをリターンする。 -- Function: hash-table-rehash-threshold table この関数はTABLEのrehash-thresholdをリターンする。 -- Function: hash-table-size table この関数はTABLEの現在の定義されたサイズをリターンする。 8 シンボル ********** “シンボル(symbol)”は一意な名前をもつオブジェクトです。このチャプターでは シンボル、シンボルの構成要素とプロパティーリスト、およびシンボルの作成と インターンする方法を説明します。別のチャプターではシンボルを変数として使 用したり、関数名として使用する方法が説明されています。*note Variables::と *note Functions::を参照してください。シンボルの正確な入力構文については 、*note Symbol Type::を参照してください。 ‘symbolp’を使用して、任意のLispオブジェクトがシンボルかどうかをテスト できます: -- Function: symbolp object この関数はOBJECTがシンボルなら‘t’、それ以外は‘nil’をリターンする。 8.1 シンボルの構成要素 ====================== 各シンボルは4つの構成要素(もしくは“セル”)をもち、構成要素はそれぞれ別の オブジェクトを参照します: プリント名(print name) そのシンボルの名前。 値(value) 変数としてのそのシンボルの現在値。 関数(function) そのシンボルの関数定義。シンボル、キーマップ、キーボードマクロも保 持できる。 プロパティーリスト(property list) そのシンボルのプロパティーリスト。 プリント名のセルは常に文字列を保持し、それを変更することはできません。他 の3つのセルには、任意のLispオブジェクトをセットすることができます。 プリント名のセルはシンボルの名前となる文字列を保持します。シンボルは シンボル名によりテキストとして表されるので、2つのシンボルが同じ名前をも たないことが重要です。Lispリーダーはシンボルを読み取るごとに、それを新規 作成する前に、指定されたシンボルがすでに存在するかを調べます。シンボルの 名前を得るには関数‘symbol-name’(*note Creating Symbols::を参照)を使用し ます。 値セルは変数としてのシンボルの値(そのシンボル自身がLisp式として評価さ れたときに得る値)を保持します。“ローカルバインディング(local binding)”や “スコーピングルール(scoping rules)”等のような複雑なものを含めて、変数の セットや取得方法については*note Variables::を参照してください。ほとんど のシンボルは値として任意のLispオブジェクトをもつことができますが、一部の 特別なシンボルは変更できない値をもちます。これらには‘nil’、‘t’、および名 前が‘:’で始まるすべてのシンボル(“キーワード(keyword)”と呼ばれる)が含まれ ます。*note Constant Variables::を参照してください。 関数セルはシンボルの関数定義を保持します。実際はには‘foo’の関数セルの 中に保管されている関数を意味するときに、“関数‘foo’”といってそれを参照す ることがよくあります。わたしたちは必要なときだけ、これを明確に区別するこ とにします。関数セルは通常は関数(*note Functions::を参照)か、マクロ (*note Macros::を参照)を保持するために使用されます。しかし関数セルはシン ボル(*note Function Indirection::を参照)、キーボードマクロ(*note Keyboard Macros::を参照)、キーマップ(*note Keymaps::を参照)、またはオー トロードオブジェクト(*note Autoloading::を参照)を保持するためにも使用で きます。シンボルの関数セルの内容を得るには、関数‘symbol-function’ (*note Function Cells::を参照)を使用します。 プロパティーリストのセルは、通常は正しくフォーマットされたプロパティ ーリストを保持するべきです。シンボルのプロパティーリストを得るには関数 ‘symbol-plist’を使用します。*note Symbol Properties::を参照してください 。 マクロセルと値セルが“void(空)”のときもあります。voidとはそのセルがど のオブジェクトも参照していないことを意味します(これはシンボル‘void’を保 持するのともシンボル‘nil’を保持するのとも異なる)。voidの関数セルまたは値 セルを調べようとすると結果は‘Symbol's value as variable is void’のような エラーとなります。 各シンボルは値セルと関数セルを別個にもつので、変数名と関数名が衝突す ることはありません。たとえばシンボル‘buffer-file-name’が値(カレントバッ ファーでvisitされているファイルの名前)をもつと同様に、関数定義(ファイル の名前をリターンするプリミティブ関数)をもつことができます: buffer-file-name ⇒ "/gnu/elisp/symbols.texi" (symbol-function 'buffer-file-name) ⇒ # 8.2 シンボルの定義 ================== “定義(definition)”とは、特別な方法での使用の意図を宣言する特別な種類の Lisp式です。定義とは通常はシンボルにたいする値を指定するか、シンボルにた いする1つの種類の使用についての意味とその方法で使用する際のシンボルの意 味のドキュメントを指定します。したがってシンボルを変数として定義すると、 その変数の初期値に加えてその変数のドキュメントを提供できます。 ‘defvar’と‘defconst’は“グローバル変数(global variable)” — Lispプログ ラムの任意の箇所からアクセスできる変数 — として定義するためのスペシャル フォームです。変数についての詳細は*note Variables::を参照してください。 カスタマイズ可能な変数を定義するには‘defcustom’ (サブルーチンとして ‘defvar’も呼び出す)を使用します(*note Customization::を参照)。 最初にシンボルが変数として定義されていなくても、原則として‘setq’で任 意のシンボルに値を割り当てることができます。しかし使用したいグローバル変 数それぞれにたいして変数定義を記述するべきです。さもないとレキシカルスコ ープ(*note Variable Scoping::を参照)が有効なときに変数が評価されたると、 あなたのLispプログラムが正しく動作しないかもしれません。 ‘defun’はラムダ式(lambda expression)を生成して、そのシンボルの関数セ ルに格納することにより、そのシンボルを関数として定義します。したがってこ のシンボルの関数定義は、そのラムダ式になります(関数セルの内容を意味する 用語“関数定義(function definition)”は、‘defun’がシンボルに関数としての定 義を与えるというアイデアに由来する)。*note Functions::を参照してください 。 ‘defmacro’はシンボルをマクロとして定義します。これはマクロオブジェク トを作成してシンボルの関数セルにそれを格納します。シンボルにはマクロと関 数を与えることができますが、マクロと関数定義はどちらも関数セルに保持され るのにたいし、関数セルに保持できるのは常にただ1つのLispオブジェクトなの で、一度に両方を行なうことはできないことに注意してください。*note Macros::を参照してください。 前に注記したようにEmacs Lispではシンボルを(たとえば‘defvar’で)変数と して定義して、同じシンボルを(たとえば‘defun’で)関数やマクロとして両方定 義することができます。このような定義は衝突しません。 これらの定義はプログラミングツールのガイドを果たすこともできます。た とえば‘C-h f’と‘C-h v’コマンドは関連する変数、関数、マクロ定義へのリンク を含むヘルプバッファーを作成します。*note (emacs)Name Help::を参照してく ださい。 8.3 シンボルの作成とintern ========================== GNU Emacs Lispでシンボルが作成される方法を理解するには、Lispがシンボルを 読み取る方法を理解しなければなりません。Lispは、同じ文字綴りを読み取った ら、毎回同じシンボルを見つけることを保証しなければなりません。これに失敗 すると、完全な混乱を招くでしょう。 Lispリーダーがシンボルに出会うと、Lispリーダーは名前のすべての文字を 読み取ります。その後Lispリーダーは“obarray(オブジェクト配列)”と呼ばれる テーブル内のインデックスを決めるために、これらの文字をハッシュ(hash)しま す。ハッシュ化(hashing)は何かを照合するのに効果的な方法です。たとえばJan Jonesを見つけるときは、電話帳を表紙から1頁ずつ探すのではなくJの頁から探 し始めます。これはハッシュ化の簡単なバージョンです。obarrayの各要素は与 えられたハッシュコードとともに、すべてのシンボルを保持する“バケット (bucket)”です。与えられた名前を探すためには、バケットの中からハッシュコ ードがその名前であるような、すべてのシンボルを探すのが効果的です(同じア イデアは一般的なEmacsのハッシュテーブルでも使用されていがこれらはデータ 型が異なる。*note Hash Tables::を参照されたい)。 探している名前のシンボルが見つかったら、リーダーはそのシンボルを使用 します。obarrayにその名前のシンボルが含まれなければ、リーダーは新しいシ ンボルを作成してそれをobarrayに追加します。特定の名前のシンボルを探して 追加することを“インターン(intern)”と言い、これが行なわれた後はそのシンボ ルは“インターンされたシンボル(interned symbol)”と呼ばれます。 インターンすることによりある特定の名前のシンボルは、各obarrayに1つだ けであることが保証されます。同じ名前のシンボルが他に存在するかもしれませ んが、同じobarrayには存在しません。したがってリーダーは、(同じobarrayを 読みつづける限り)同じ名前にたいして同じシンボルを取得します。 インターンは通常はリーダー内で自動的に発生しますが、他のプログラムが これを行なう必要がある場合もあります。たとえば‘M-x’コマンドはその後にミ ニバッファーを使用してコマンド名を文字列として取得して、その文字列をイン ターンしてからインターンされたその名前のシンボルを得ます。 すべてのシンボルを含むobarrayはありません。実際にどのobarrayにも含ま れないシンボルがいくつかあります。これらは“インターンされていないシンボ ル(uninterned symbols)”と呼ばれます。インターンされていないシンボルも、 他のシンボルと同じく4つのセルをもちます。しかしインターンされていないシ ンボルへのアクセスを得る唯一の方法は、他の何らかのオブジェクトとして探す か、変数の値として探す方法だけです。 インターンされていないシンボルの作成は、Lispコードを生成するとき有用 です。なぜなら作成されたコード内で変数として使用されているインターンされ ていないシンボルは、他のLispプログラムで使用されている任意の変数と競合す ることはありえないからです。 Emacs Lispではobarrayはベクターです。ベクター内の各要素がバケットにな ります。要素の値は、名前がそのバケットにハッシュされるようなインターンさ れたシンボル、またはバケットが空のときは0です。インターンされたシンボル は、そのバケット内の次のシンボルへの内部リンク(ユーザーからは見えない)を もちます。これらのリンクは不可視なので、‘mapatoms’ (以下参照)を使用する 方法をのぞき、obarray内のすべてのシンボルを探す方法はありません。バケッ ト内のシンボルの順番に意味はありません。 空のobarrayではすべての要素が0なので、‘(make-vector LENGTH 0)’で obarrayを作成することができます。*obarrayを作成する有効な方法はこれだけ です。*長さに素数を指定するとよいハッシュ化がされる傾向があります。2の累 乗から1減じた長さもよい結果を生む傾向があります。 *自分でobarrayにシンボルを置かないでください。*これはうまくいきません — obarrayに正しくシンボルを入力できるのは‘intern’だけです。 Common Lispに関する注意: Common Lispとは異なりEmacs Lispは1つのシン ボルを複数のobarrayにインターンする方法を提供しない。 以下の関数のほとんどは、引数に名前とobarrayをとります。名前が文字列以 外、またはobarrayがベクター以外なら‘wrong-type-argument’エラーがシグナル されます。 -- Function: symbol-name symbol この関数はSYMBOLの名前を文字列としてリターンする。たとえば: (symbol-name 'foo) ⇒ "foo" *警告: *文字の置き換えにより文字列を変更すると、それはシンボルの名 前を変更しますが、obarrayの更新には失敗するので行なわないこと! -- Function: make-symbol name この関数は新たに割り当てられた、名前がNAME(文字列でなかればならない )であるような、インターンされていないシンボルをリターンする。このシ ンボルの値と関数はvoidで、プロパティーリストは‘nil’。以下の例では ‘sym’の値は‘foo’と‘eq’ではない。なぜならこれは名前が‘foo’という、イ ンターンされていないシンボルだからである。 (setq sym (make-symbol "foo")) ⇒ foo (eq sym 'foo) ⇒ nil -- Function: intern name &optional obarray この関数は名前が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’の引数はシンボルではなく文字 列なのでこれを行なうことはできない。 -- Function: intern-soft name &optional obarray この関数は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 -- Variable: obarray この変数は‘intern’と‘read’が使用する標準のobarrayである。 -- Function: mapatoms function &optional 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’を使用する他の例については、*note Accessing Documentation::の‘documentation’を参照のこと。 -- Function: unintern symbol obarray この関数はオブジェクト配列OBARRAYからSYMBOLを削除する。obarrayの中 に‘symbol’が存在ければ、‘unintern’は何も行なわない。OBARRAYが ‘nil’なら現在のobarrayが使用される。 SYMBOLにシンボルではなく文字列を与えると、それはシンボルの名前を意 味する。この場合、‘unintern’は(もしあれば)obarrayからその名前のシン ボルを削除する。そのようなシンボルが存在するなら‘unintern’は何も行 なわない。 ‘unintern’がシンボルを削除したら‘t’、それ以外は‘nil’をリターンする 。 8.4 シンボルのプロパティ ======================== シンボルはそのシンボルについての様々な情報を記録するために使用される、任 意の数の“シンボルプロパティー(symbol properties)”をもつことができます。 たとえばシンボルの‘risky-local-variable’プロパティーが‘nil’なら、その変 数の名前が危険なファイルローカル変数(*note File Local Variables::を参照 )であることを意味します。 シンボルのプロパティーとプロパティー値はそれぞれ、シンボルのプロパテ ィーリストセル(*note Symbol Components::を参照)に、プロパティーリスト形 式(*note Property Lists::を参照)で格納されます。 8.4.1 シンボルのプロパティへのアクセス -------------------------------------- 以下の関数を使用してシンボルプロパティーにアクセスできます。 -- Function: get symbol property この関数はSYMBOLのプロパティーリスト内の、名前がPROPERTYというプロ パティーの値をリターンする。そのようなプロパティーが存在しなければ ‘nil’をリターンする。したがって値が‘nil’のときとプロパティーが存在 しないときの違いはない。 名前PROPERTYは‘eq’を使用して既存のプロパティーと比較されるので、す べてのオブジェクトがプロパティーとして適正である。 ‘put’の例を参照のこと。 -- Function: put symbol property value この関数は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)) -- Function: symbol-plist symbol この関数はSYMBOLのプロパティーリストをリターンする。 -- Function: setplist symbol plist この関数は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(*note Abbrevs::を参照)のメカニズムでこれを行なってい る。 以下のように‘setplist’と‘plist-put’で‘put’を定義できる: (defun put (symbol prop value) (setplist symbol (plist-put (symbol-plist symbol) prop value))) -- Function: function-get symbol property &optional autoload この関数は‘get’と等価だがSYMBOLが関数のエイリアス名なら。実際の関数 を命名するシンボルのプロパティリストを照合する点が異なる。*note Defining Functions::を参照のこと。オプション引数AUTOLOADが非‘nil’で 、SYMBOLが自動ロードされていれば、その自動ロードによりSYMBOLの PROPERTYがセットされるかもしれないので、この関数はそれの自動ロード を試みるだろう。AUTOLOADがシンボル‘macro’なら、SYMBOLが自動ロードさ れたマクロのときだけ自動ロードを試みる。 -- Function: function-put function property value この関数はFUNCTIONのPROPERTYにVALUEをセットする。FUNCTIONはシンボル であること。関数のプロパティのセットには、‘put’よりこの関数を呼び出 すほうがよい。この関数を使用すれば、いつか古いプロパティから新しい プロパティへのリマップを実装することができるからである。 8.4.2 シンボルの標準的なプロパティ ---------------------------------- Emacsで特別な目的のために使用されるシンボルプロパティーを以下に一覧しま す。以下のテーブルで、“命名される関数(the named function)”と言うときは、 関数名がそのシンボルであるような関数を意味します。“命名される変数(the named variable)”等の場合も同様です。 ‘:advertised-binding’ このプロパティーリストは、命名される関数のドキュメントを表示する際 に優先されるキーバインディングを指定する。*note Keys in Documentation::を参照のこと。 ‘char-table-extra-slots’ 値が非‘nil’なら、それは命名される文字テーブル型の追加スロットの数を 指定する。*note Char-Tables::を参照のこと。 ‘customized-face’ ‘face-defface-spec’ ‘saved-face’ ‘theme-face’ これらのプロパティーはフェイスの標準のフェイス仕様(face specs)と、 フォント仕様のsaved-fase、customized-face、themed-faceを記録するた めに使用される。これらのプロパティーを直接セットしないこと。これら のプロパティーは‘defface’と関連する関数により管理される。*note Defining Faces::を参照のこと。 ‘customized-value’ ‘saved-value’ ‘standard-value’ ‘theme-value’ これらのプロパティーは、カスタマイズ可能な変数のstandard-value、 saved-value、customized-value(しかし保存はされない)、themed-valueを 記録するために使用される。これらのプロパティーを直接セットしないこ と。これらは‘defcustom’と関連する関数により管理される。*note Variable Definitions::を参照のこと。 ‘disabled’ 値が非‘nil’なら命名される関数はコマンドとして無効になる。*note Disabling Commands::を参照のこと。 ‘face-documentation’ 値には命名されるフェイスのドキュメント文字列が格納される。これは ‘defface’により自動的にセットされる。*note Defining Faces::を参照の こと。 ‘history-length’ 値が非‘nil’なら、命名されるヒストリーリスト変数のミニバッファーヒス トリーの最大長を指定する。*note Minibuffer History::を参照のこと。 ‘interactive-form’ この値は命名される関数のインタラクティブ形式である。通常はこれを直 接セットするべきではない。かわりにスペシャルフォーム‘interactive’を 使用すること。*note Interactive Call::を参照されたい。 ‘menu-enable’ この値は命名されるメニューアイテムが、メニュー内で有効であるべきか 否かを決定するための式である。*note Simple Menu Items::を参照のこと 。 ‘mode-class’ 値が‘special’なら命名されるメジャーモードはspecial(特別)である。 *note Major Mode Conventions::を参照のこと。 ‘permanent-local’ 値が非‘nil’なら命名される変数はバッファーローカル変数となり、メジャ ーモードの変更によって変数の値はリセットされない。*note Creating Buffer-Local::を参照のこと。 ‘permanent-local-hook’ 値が非‘nil’なら、命名される関数はメジャーモード変更時にフック変数の ローカル値から削除されない。*note Setting Hooks::を参照のこと。 ‘pure’ 値が非‘nil’なら、命名される関数は副作用の影響を受けないとみなされる 。定数であるような引数で呼び出される場合には、コンパイル時に評価が 可能。これは実行時のエラーをコンパイル時へとシフトする。 ‘risky-local-variable’ 値が非‘nil’なら、命名される変数はファイルローカル変数としては危険だ とみなされる。*note File Local Variables::を参照のこと。 ‘safe-function’ 値が非‘nil’なら、命名される関数は評価において一般的に安全だとみなさ れます。*note Function Safety::を参照のこと。 ‘safe-local-eval-function’ 値が非‘nil’なら、命名される関数はファイルローカルの評価フォーム内で 安全に呼び出すことができる。*note File Local Variables::を参照のこ と。 ‘safe-local-variable’ 値は命名される変数の、安全なファイルローカル値を決定する関数を指定 する。*note File Local Variables::を参照のこと。 ‘side-effect-free’ 非‘nil’値は関数の安全性(*note Function Safety::を参照)、およびバイ トコンパイラーの最適化を決定するために、命名される関数に副作用がな いことを示す。これをセットしないこと。 ‘variable-documentation’ 非‘nil’なら、それは命名される変数のドキュメント文字列を指定する。ド キュメント文字列は‘defvar’と関連する関数により自動的にセットされる 。*note Defining Faces::を参照のこと。 9 評価 ****** Emacs Lispでの式の“評価(evaluation)”は、“Lispインタープリター” — 入力と してLispオブジェクトを受け取り、それの“式としての値(value as an expression)”を計算する — により処理されます。評価を行なう方法はそのオブ ジェクトのデータ型に依存していて、それはこのチャプターで説明するルールに より行なわれます。インタープリターはプログラムの一部を評価するために自動 的に実行されますが、Lispプリミティブ関数の‘eval’を通じて明示的に呼び出す こともできます。 9.1 評価の概要 ============== Lispインタープリター(またはLispエバリュエーター)はEmacsの一部であり、与 えられた式の値を計算します。Lispで記述された関数が呼び出されると、エバリ ュエーターはその関数のbody(本文)の中の式を評価してその関数の値を計算しま す。したがってLispプログラムを実行するとは、実際にはLispインタープリター を実行することを意味します。 評価を意図したLispオブジェクトは“フォーム(form)”、または“式 (expression)”と呼ばれます(1)。フォームはデータオブジェクトであって単なる テキストではないという事実は、Lisp風の言語と通常のプログラミング言語との 間にある基本的な相違点の1つです。任意のオブジェクトを評価できますが、実 際に評価される事が非常に多いのは数字、シンボル、リスト、文字列です。 以降のセクションでは、各種フォームにたいしてそれを評価することが何を 意味するかの詳細を説明します。 Lispフォームを読み取ってそのフォームを評価するのは、非常に一般的なア クティビティーですが、読み取りと評価は別のアクティビティーであって、どち らか一方を単独で処理することができます。読み取っただけでは何も評価されま せん。読み取りはLispオブジェクトのプリント表現をそのオブジェクト自体に変 換します。そのオブジェクトが評価されるべきフォームなのか、そのれともまっ たく違う目的をもつかを指定するのは、‘read’の呼び出し元の役目です。*note Input Functions::を参照してください。 評価とは再帰的な処理であり、あるフォームを評価するとそのフォームの一 部が評価されるといったことがよくあります。たとえば‘(car x)’のような“関数 呼び出し(function call)”のフォームを評価する場合、Emacsは最初にその引数 (サブフォーム‘x’)を評価します。引数を評価した後、Emacsはその関数 (‘car’)を“実行(executes)”します。その関数がLispで記述されていれば、関数 の“body(本文)”を評価することによって実行が行なわれます(しかしこの例で使 用している‘car’はLisp関数ではなくCで実装されたプリミティブ関数である)。 関数と関数呼び出しについての情報は*note Functions::を参照してください。 評価は“環境(environment)”と呼ばれるコンテキストの内部で行なわれます。 環境はすべてのLisp変数(*note Variables::を参照)のカレント値とバインディ ングにより構成されます。(2)フォームが新たなバインディングを作成せずに変 数を参照する際、その変数はカレントの環境から与えられる値へと評価されます 。フォームの評価は、変数のバインディングによって一時的にその環境を変更す ることもあります(*note Local Variables::を参照)。 フォームの評価が永続する変更を行なうこともあります。これらの変更は“副 作用(side effects)”と呼ばれます。副作用を生成するフォームの例は‘(setq foo 1)’です。 コマンドキー解釈での評価と混同しないでください。エディターのコマンド ループはアクティブなキーマップを使用して、キーボード入力をコマンド(イン タラクティブに呼び出すことができる関数)に変換してからそのコマンドを実行 するために、‘call-interactively’を使用します。そのコマンドがLispで記述さ れていれば、そのコマンドの実行には通常は評価を伴います。しかしこのステッ プはコマンドキー解釈の一部とは考えません。*note Command Loop::を参照して ください。 ---------- Footnotes ---------- (1) “S式(S-expression)”、短くは“sexp”という言葉でも呼ばれることがあり ますが、わたしたちはこのマニュアル内では通常はこの用語は使用しません。 (2) “環境”にたいするこの定義は、プログラムの結果に影響し得るすべての データを特に意図したものではありません。 9.2 フォームの種類 ================== 評価される事を意図したLispオブジェクトは“フォーム(form)”、または“式 (expression)”)と呼ばれます。Emacsがフォームを評価する方法はフォームのデ ータ型に依存します。Emacsは3種の異なるフォーム — シンボル、リスト、およ びその他すべての型 — をもち、それらが評価される方法は異なります。このセ クションではまず最初に自己評価フォームのその他の型から開始して、3つの種 類をすべて1つずつ説明します。 9.2.1 自己評価を行うフォーム ---------------------------- “自己評価フォーム(self-evaluating form)”はリストやシンボルではないすべて のフォームです。自己評価フォームはそのフォーム自身を評価します。評価の結 果は評価されたオブジェクトと同じです。したがって数字の25は25、文字列 ‘"foo"’は文字列‘"foo"’に評価されます。同様にベクターの評価では、ベクター の要素の評価は発生しません — 内容が変更されずに同じベクターがリターンさ れます。 '123 ; 評価されずに表示される数字 ⇒ 123 123 ; 通常どおり評価され、同じものがreturnされる ⇒ 123 (eval '123) ; 手動での評価 — 同じものがreturnされる ⇒ 123 (eval (eval '123)) ; 2度評価しても何も変わらない。 ⇒ 123 自己評価されるという事実による利点から数字、文字、文字列、そしてベク ターでさえLispコード内で記述されるのが一般的です。しかし入力構文がない型 にたいしてこれを行なうのは極めて異例です。なぜなら、これらをテキスト的に 記述する方法がないからです。Lispプログラムを使用してこれらの型を含む Lisp式を構築することは可能です。以下は例です: ;; バッファーオブジェクトを含む式を構築する。 (setq print-exp (list 'print (current-buffer))) ⇒ (print #) ;; それを評価する。 (eval print-exp) ⊣ # ⇒ # 9.2.2 シンボルのフォーム ------------------------ シンボルが評価されるときは変数として扱われます。それが値をもつなら結果は その変数の値になります。そのシンボルが変数としての値をもたなければ、 Lispインタープリターはエラーをシグナルします。変数の使用法についての情報 は*note Variables::を参照してください。 以降の例では‘setq’でシンボルに値をセットしています。その後シンボルを 評価してからを‘setq’に戻します。 (setq a 123) ⇒ 123 (eval 'a) ⇒ 123 a ⇒ 123 シンボル‘nil’と‘t’は特別に扱われるので、‘nil’の値は常に‘nil’、‘t’の値 は常に‘t’になります。これらに他の値をセットしたり、他の値にバインドする ことはできません。したがってこの2つのシンボルは、(たとえ‘eval’がそれらを 他の任意のシンボルと同様に扱うとはいえ)自己評価フォームと同じように振る 舞います。名前が‘:’で始まるシンボルも同じ方法で自己評価されます。そして 、(通常は)値を変更できない点も同じです。*note Constant Variables::を参照 してください。 9.2.3 リストフォームの分類 -------------------------- 空ではないリストフォームは関数呼び出し、マクロ呼び出し、スペシャルフォー ムのいずれかで、それは1番目の引数にしたがいます。これら3種のフォームは、 以下で説明するように異なる方法で評価されます。残りの要素は関数、マクロ、 またはスペシャルフォームにたいする“引数(arguments)”を構成します。 空ではないリストを評価する最初のステップは、1番目の要素の確認です。こ の要素は単独でそのリストがどの種類のフォームなのかと、残りの引数をどのよ うに処理するがを決定します。SchemeのようなLisp方言とは異なり、1番目の要 素は評価されません。 9.2.4 シンボル関数インダイレクション ------------------------------------ リストの最初の要素がシンボルなら、評価はそのシンボルの関数セルを調べて、 元のシンボルの代わりに関数セルの内容を使用します。その内容が他のシンボル なら、シンボルではないものが得られるまでこのプロセスが繰り返されます。こ のプロセスのことを“シンボル関数インダイレクション(symbol function indirection: indirectionは間接の意)”と呼びます。シンボル関数インダイレク ションについての情報は*note Function Names::を参照してください。 このプロセスの結果、シンボルの関数セルが同じシンボルを参照する場合に は、無限ループを起こす可能性があります。それ以外なら最終的には非シンボル にたどりつき、それは関数か他の適切なオブジェクトである必要があります。 適切なオブジェクトとは、より正確にはLisp関数(ラムダ式)、バイトコード 関数、プリミティブ関数、Lispマクロ、スペシャルフォーム、またはオートロー ドオブジェクトです。これらそれぞれの型については以降のセクションで説明し ます。これらの型以外のオブジェクトならEmacsは‘invalid-function’エラーを シグナルします。 以下の例はシンボルインダイレクションのプロセスを説明するものです。わ たしたちはシンボルの関数セルへの関数のセットに‘fset’、関数セルの内容 (*note Function Cells::を参照)の取得に‘symbol-function’を使用します。具 体的には‘first’の関数セルにシンボル‘car’を格納して、シンボル‘first’を ‘erste’の関数セルに格納します。 ;; この関数セルのリンクを構築する: ;; ------------- ----- ------- ------- ;; | # | <-- | car | <-- | first | <-- | erste | ;; ------------- ----- ------- ------- (symbol-function '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: indirect-function function &optional noerror この関数はFUNCTIONが意味するものを関数としてリターンする。 FUNCTIONがシンボルならFUNCTIONの関数定義を探して、その値で最初から やり直す。FUNCTIONがシンボルでなければFUNCTION自身をリターンする。 この関数は最終的なシンボルがバインドされていなければ‘nil’をリターン する。特定のシンボル内にループがれば、この関数は ‘cyclic-function-indirection’エラーをシグナルする。 オペション引数NOERRORは廃れており、後方互換のためだけのもので効果は ない。 以下はLispで‘indirect-function’を定義する例である: (defun indirect-function (function) (if (symbolp function) (indirect-function (symbol-function function)) function)) 9.2.5 関数フォームの評価 ------------------------ リストの1番目の要素がLispの関数オブジェクト、バイトコードオブジェクト、 プリミティブ関数オブジェクトのいずれかと評価されると、そのリストは“関数 呼び出し(function call)”になります。たとえば、以下は関数‘+’を呼び出しま す: (+ 1 x) 関数呼び出しを評価する最初のステップでは、そのリストの残りの要素を左 から右に評価します。結果は引数の実際の値で、リストの各要素にたいして1つ の値となります。次のステップでは関数‘apply’(*note Calling Functions::を 参照)を使用して、引数のリストでその関数を呼び出します。関数がLispで記述 されていたら引数はその関数の引数変数にバインドするために使用されます。そ の後に関数body内のフォームが順番に評価されて、リストのbodyフォームの値が 関数呼び出しの値になります。 9.2.6 Lispマクロの評価 ---------------------- リストの最初の要素がマクロオブジェクトと評価されると、そのリストは“マク ロ呼び出し(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マクロの完全な説明は*note Macros::を参照してください。 9.2.7 スペシャルフォーム ------------------------ “スペシャルフォーム(special form)”とは、特別だとマークされたプリミティブ 関数であり、その引数のすべては評価されません。もっとも特別なフォームは制 御構文の定義や変数バインディングの処理等、関数ではできないことを行ないま す。 スペシャルフォームはそれぞれ、どの引数を評価して、どの引数を評価しな いかについて独自のルールをもちます。特定の引数が評価されるかどうかは、他 の引数を評価した結果に依存します。 式の最初のシンボルがスペシャルフォームなら、式はそのスペシャルフォー ムのルールにしたがう必要があります。それ以外ならEmacsの挙動は(たとえクラ ッシュしなくいとしても)未定義です。たとえば‘((lambda (x) x . 3) 4)’は ‘lambda’で始まるサブ式を含みますが、これは適正な‘lambda’式ではないので、 Emacsはエラーをシグナルするかもしれないし、3や4や‘nil’をリターンしたり、 もしかしたら他の挙動を示すかもしれません。 -- Function: special-form-p object この述語は引数がスペシャルフォームかをテストして、スペシャルフォー ムなら‘t’、それ以外なら‘nil’をリターンする。 以下にEmacs Lispのスペシャルフォームすべてと、それらがどこで説明され ているかのリファレンスをアルファベット順でリストします。 ‘and’ *note Combining Conditions::を参照のこと。 ‘catch’ *note Catch and Throw::を参照のこと。 ‘cond’ *note Conditionals::を参照のこと。 ‘condition-case’ *note Handling Errors::を参照のこと。 ‘defconst’ *note Defining Variables::を参照のこと。 ‘defvar’ *note Defining Variables::を参照のこと。 ‘function’ *note Anonymous Functions::を参照のこと。 ‘if’ *note Conditionals::を参照のこと。 ‘interactive’ *note Interactive Call::を参照のこと。 ‘lambda’ *note Lambda Expressions::を参照のこと。 ‘let’ ‘let*’ *note Local Variables::を参照のこと。 ‘or’ *note Combining Conditions::を参照のこと。 ‘prog1’ ‘prog2’ ‘progn’ *note Sequencing::を参照のこと。 ‘quote’ *note Quoting::を参照のこと。 ‘save-current-buffer’ *note Current Buffer::を参照のこと。 ‘save-excursion’ *note Excursions::を参照のこと。 ‘save-restriction’ *note Narrowing::を参照のこと。 ‘setq’ *note Setting Variables::を参照のこと。 ‘setq-default’ *note Creating Buffer-Local::を参照のこと。 ‘track-mouse’ *note Mouse Tracking::を参照のこと。 ‘unwind-protect’ *note Nonlocal Exits::を参照のこと。 ‘while’ *note Iteration::を参照のこと。 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では(複数の値をもたない)関数である。 9.2.8 自動ロード ---------------- “オートロード(autoload)”機能により、まだ関数定義がEmacsにロードされてい ない関数(またはマクロ)を呼び出すことができます。オートロードは定義がどの ファイルに含まれるかを指定します。オートロードオブジェクトがシンボルの関 数定義にある場合は、関数としてそのシンボルを呼び出すことにより、自動的に 指定されたファイルがロードされます。その後にファイルからロードされた実際 の定義を呼び出します。シンボル内の関数定義としてオートロードオブジェクト をアレンジする方法は*note Autoload::で説明します。 9.3 クォート ============ スペシャルフォーム‘quote’は、単一の引数を記述されたままに評価せずにリタ ーンします。これはプログラムに自己評価オブジェクトではない、定数シンボル や定数リストを含める方法を提供します(数字、文字列、ベクターのような自己 評価オブジェクトをクォートする必要はない)。 -- Special Form: quote object このスペシャルフォームは評価せずにOBJECTをリターンする。 ‘quote’はプログラム中で頻繁に使用されるので、Lispはそれにたいする便利 な入力構文を提供します。アポストロフィー文字(‘'’)に続けてLispオブジェク ト(の入力構文)を記述すると、それは1番目の要素が‘quote’、2番目の要素がそ のオブジェクトであるようなリストに展開されます。つまり入力構文‘'x’は ‘(quote x)’の略記になります。 以下に‘quote’を使用した式の例をいくつか示します: (quote (+ 1 2)) ⇒ (+ 1 2) (quote foo) ⇒ foo 'foo ⇒ foo ''foo ⇒ (quote foo) '(quote foo) ⇒ (quote foo) ['foo] ⇒ [(quote foo)] 他のクォート構文としては、コンパイル用にLispで記述された無名のラムダ 式の元となる‘function’ (*note Anonymous Functions::を参照)、リストを計算 して置き換える際にリストの一部だけをクォートするために使用される ‘`’(*note Backquote::を参照)があります。 9.4 バッククォート ================== “バッククォート構文(backquote constructs)”を使用することにより、リストを クォートしてそのリストのある要素を選択的に評価することができます。もっと も簡単な使い方ではスペシャルフォーム‘quote’と同じです (前のセクションで 説明済み。*note Quoting::を参照)。 たとえば以下の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) 9.5 eval ======== フォームはほとんどの場合、実行されるプログラム内に出現することにより自動 的に評価されます。ごく稀に実行時 — たとえば編集されているテキストやプロ パティーリストから取得したフォームを読み取った後 — に計算されるようにフ ォームを評価するコードを記述する必要があるかもしれません。このようなとき は‘eval’関数を使用します。‘eval’が不必要だったり、かわりに他の何かを使用 すべきときがよくあります。たとえば変数から値を取得するには‘eval’も機能し ますが、‘symbol-value’のほうが適しています。‘eval’で評価するためにプロパ ティーリストに式を格納するかわりに、‘funcall’に渡すように関数を格納した 方がよいでしょう。 このセクションで説明する関数と変数はフォームの評価、評価処理の制限の 指定、最後にリターンされた値の記録を行なうものです。ファイルのロードでも 評価が行なわれます(*note Loading::を参照)。 データ構造に式を格納して評価するより、データ構造に関数を格納して ‘funcall’や‘apply’で呼び出すほうが、より明解で柔軟です。関数を使用するこ とにより、引数に情報を渡す能力が提供されます。 -- Function: eval form &optional lexical これは式を評価する基本的な関数である。この関数はカレント環境内で FORMを評価して、その結果をリターンする。FORMオブジェクトの型はそれ が評価される方法を決定します。*note Forms::を参照のこと。 引数LEXICALは、ローカル変数にたいするスコープ規則(*note Variable Scoping::を参照)を指定する。これが省略または‘nil’ならデフォルトのダ イナミックスコープ規則を使用してFORMを評価することを意味する。‘t’な らレキシカルスコープ規則が使用されることを意味する。LEXICALの値には レキシカルバインディングでの特定の“レキシカル環境(lexical environment)”を指定する空ではないalistも指定できる。しかしこの機能 はEmacs Lispデバッガーのような、特別な用途にたいしてのみ有用。*note Lexical Binding::を参照のこと。 ‘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’に制限さ れる(以下参照)。 -- Command: eval-region start end &optional stream read-function この関数はカレントバッファー内の、位置STARTとENDで定義されるリージ ョン内のフォームを評価する。この関数はリージョンからフォームを読み 取って‘eval’を呼び出す。これはリージョンの最後に達するか、処理され ないエラーがシグナルされるまで行なわれる。 デフォルトでは‘eval-region’は出力を何も生成しない。しかしSTREAMが非 ‘nil’なら出力関数(*note Output Functions::を参照)で生成された任意の 出力、同様にリージョン内の式を評価した結果の値が、STREAMを使用して プリントされる。*note Output Streams::を参照のこと。 READ-FUNCTIONが非‘nil’なら、‘read’のかわりに1つずつ式を読み取るため に使用する関数を指定すること。これは入力を読み取るストリームを指定 する、1つの引数で呼び出される関数である。この関数を指定するために変 数‘load-read-function’(*note How Programs Do Loading: Definition of load-read-function.を参照)も使用できるが、引数READ-FUNCTIONを使用す るほうが堅実である。 ‘eval-region’はポイントを移動しない。常に‘nil’をリターンする。 -- Command: eval-buffer &optional buffer-or-name stream filename unibyte print この関数は‘eval-region’と似ているが、引数は異なるオプション機能を提 供する。‘eval-buffer’はバッファーBUFFER-OR-NAMEのアクセス可能な部分 (*note (emacs)Narrowing::を参照)の全体を処理する。BUFFER-OR-NAMEに はバッファー名(文字列)を指定でき、‘nil’(または省略)のときはカレント バッファーを意味する。STREAMが非‘nil’、またはPRINTが‘nil’なら、 ‘eval-region’のようにSTREAMが使用される。この場合には式の評価結果の 値は依然として破棄されるが、出力関数による出力はエコーエリアにプリ ントされる。FILENAMEは‘load-history’ (*note Unloading::を参照)に使 用されるファイル名であり、デフォルトは‘buffer-file-name’ (*note Buffer File Name::を参照)。UNIBYTEが非‘nil’なら‘read’可能な限りは文 字列をユニコードに変換する。 ‘eval-current-buffer’はこのコマンドのエイリアスである。 -- User Option: max-lisp-eval-depth この変数はエラー(エラーメッセージは‘"Lisp nesting exceeds max-lisp-eval-depth"’)がシグナルされる前に‘eval’、‘apply’、 ‘funcall’の呼び出しで許容される最大の深さを定義する。 制限を超過時のエラーを付随するこの制限は、誤って定義された関数によ る無限再帰をEmacs Lispが回避する方法の1つである。 ‘max-lisp-eval-depth’の値を過大に増加させると、そのようなコードはか わりにスタックオーバーフローを起こすだろう。オーバーフローを処理で きるシステムがいくつかある。この場合には通常のLisp評価は割り込まれ て、制御はトップレベルのコマンドループ(‘top-level’)に戻される。この 状況ではEmacs Lispデバッガにエンターする手段は存在しないことに注意 されたい。*note Error Debugging::を参照のこと。 Lisp式に記述された関数の呼び出し、関数呼び出しの引数と関数bodyフォ ームにたいする再帰評価、Lispコード内での明示的な呼び出し等では内部 的に‘eval’、‘apply’、‘funcall’を使用して深さ制限を計数する。 この変数のデフォルト値は400。この値を100未満にセットして値が与えら れた値に達すると、Lispはそれを100にリセットする。デバッガ自身を実行 するために空きが必要になるので、Lispデバッガに入ったとき空きが少な ければこの値が増加されます。 ‘max-specpdl-size’はネストの他の制限を提供する。*note Local Variables: Definition of max-specpdl-size.を参照のこと。 -- Variable: values この変数の値は読み取り、評価、プリントを行なった標準的なEmacsコマン ドにより、バッファー(ミニバッファーを含む)からリターンされる値のリ ストである(これには‘*ielm*’バッファーでの評価や、 ‘lisp-interaction-mode’での‘C-j’や‘C-x C-e’、類似の評価コマンドを使 用した評価は_含まれない_ことに注意)。要素の順番はもっとも最近のもの が最初になる。 (setq x 1) ⇒ 1 (list 'A (1+ 2) auto-save-default) ⇒ (A 3 t) values ⇒ ((A 3 t) 1 ...) この変数は最近評価されたフォームの値を後で参照するのに有用。 ‘values’自体の値のプリントは、値がおそらく非常に長くなるので通常は 悪いアイデアである。かわりに以下のように特定の要素を調べること: ;; もっとも最近評価された結果を参照する (nth 0 values) ⇒ (A 3 t) ;; これは新たな要素をputするので ;; すべての要素が1つ後に移動する (nth 1 values) ⇒ (A 3 t) ;; これは次に新しい、この例の前の次に新しい要素を取得する (nth 3 values) ⇒ 1 10 制御構造 *********** Lispプログラムは一連の“式”、あるいは“フォーム” (*note Forms::を参照)によ り形成されます。これらのフォームの実行順は“制御構造(control structures)”で囲むことによって制御します。制御構造とはその制御構造が含む フォームをいつ、どのような条件で、何回実行するかを制御するスペシャルフォ ームです。 もっとも単純な実行順は1番目はA、2番目はB、...というシーケンシャル実行 (sequential execution: 順番に実行)です。これは関数のbody内の連続する複数 のフォームや、Lispコードのファイル内のトップレベルを記述したときに発生し ます — つまりフォームは記述した順に実行されます。わたしたちはこれを“テキ スト順(textual order)”と呼びます。たとえば関数のbodyが2つのフォームAと Bから構成される場合、関数の評価は最初にA、次にBを評価します。Bを評価した 結果がその関数の値となります。 明示的に制御構造を使用することにより、非シーケンシャルな順番での実行 が可能になります。 Emacs Lispは他の様々な順序づけ、条件、繰り返し、(制御された)ジャンプ を含む複数の種類の制御構造を提供しており、以下ではそれらのすべてを記述し ます。ビルトインの制御構造は制御構造のサブフォームが評価される必要がなか ったり、順番に評価される必要がないのでスペシャルフォームです。独自の制御 構造を構築するためにマクロを使用することができます(*note Macros::を参照 )。 10.1 順序 ========= フォームを出現順に評価するのは、あるフォームから別のフォームに制御を渡す もっとも一般的な制御です。関数の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パートの中であることがほとんどです。 -- Special Form: progn forms... このスペシャルフォームは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つの構文は一連のフォームを同様に評価しますが、異なる値をリターン します: -- Special Form: prog1 form1 forms... このスペシャルフォームは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))) -- Special Form: prog2 form1 form2 forms... このスペシャルフォームは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" 10.2 条件 ========= 条件による制御構造は選択肢の中から選択を行ないます。Emacs Lispには4つの 条件フォームをもちます。‘if’は他の言語のものとほとんど同じです。‘when’と ‘unless’は‘if’の変種です。‘cond’は一般化されたcase命令です。 -- Special Form: if condition then-form else-forms... ‘if’はCONDITIONの値にもとづきTHEN-FORMとELSE-FORMSを選択する。評価 されたCONDITIONが非‘nil’ならTHEN-FORMが評価されて結果がリターンされ る。それ以外ならELSE-FORMSがテキスト順に評価されて最後のフォームの 値がリターンされる(‘if’のELSEパートは暗黙の‘progn’の例である。*note Sequencing::を参照)。 CONDITIONの値が‘nil’でELSE-FORMSが与えられなければ、‘if’は‘nil’をリ ターンする。 選択されなかったブランチは決して評価されない — 無視される — ので、 ‘if’はスペシャルフォームである。したがって以下の例では‘print’が呼び 出されることはないので‘true’はプリントされない。 (if nil (print 'true) 'very-false) ⇒ very-false -- Macro: when condition then-forms... これはELSE-FORMSがなく、複数のTHEN-FORMSが可能な‘if’の変種である。 特に、 (when CONDITION A B C) は以下と完全に等価である (if CONDITION (progn A B C) nil) -- Macro: unless condition forms... これはTHEN-FORMがない‘if’の変種です: (unless CONDITION A B C) は以下と完全に等価である (if CONDITION nil A B C) -- Special Form: cond clause... ‘cond’は任意個数の選択肢から選択を行なう。‘cond’内の各CLAUSEはリス トでなければならない。このリストのCARはCONDITIONで、(もしあれば)残 りの要素はBODY-FORMSとなる。したがってclauseは以下のようになる: (CONDITION BODY-FORMS...) ‘cond’は各clauseのCONDITIONを評価することにより、テキスト順で clauseを試みる。CONDITIONの値が非‘nil’ならそのclauseは成り立つ。そ の後に‘cond’はそのclauseのBODY-FORMSを評価して、BODY-FORMSの最後の 値をリターンする。残りのclauseは無視される。 CONDITIONの値が‘nil’ならそのclauseは失敗して、‘cond’は次のclauseに 移動してそれのCONDITIONを試みる。 clauseは以下のようにも見えるかもしれない: (CONDITION) CONDITIONがテストされたときに非‘nil’なら、‘cond’フォームは CONDITIONの値をリターンする。 すべてのCONDITIONが‘nil’に評価された場合 — つまりすべてのclauseが不 成立なら、‘cond’は‘nil’をリターンする。 以下の例は‘x’の値が数字、文字列、バッファー、シンボルなのかをテスト する4つのclauseをもつ: (cond ((numberp x) x) ((stringp x) x) ((bufferp x) (setq temporary-hack x) ; 1つのclauseに (buffer-name x)) ; 複数bodyフォーム ((symbolp x) (symbol-value x))) 前のclauseが不成立のとき最後の条項を実行したいときがよくある。これ を行なうには‘(t BODY-FORMS)’のように、CONDITIONの最後のclauseに ‘t’を使用する。フォーム‘t’は‘t’に評価され決して‘nil’にならないので 、このclauseが不成立になることはなく最終的に‘cond’はこのclauseに到 達する。たとえば: (setq a 5) (cond ((eq a 'hack) 'foo) (t "default")) ⇒ "default" この‘cond’式は‘a’の値が‘hack’なら‘foo’、それ以外は文字列 ‘"default"’をリターンする。 すべての条件構文は‘cond’か‘if’のいずれかで表すことができます。したが ってどちらを選択するかはスタイルの問題になります。たとえば: (if A B C) ≡ (cond (A B) (t C)) 10.2.1 パターンマッチングによるcase文 ------------------------------------- ‘cond’フォームにより、あらかじめ記述された既知の特定の値と式の値を比較す る述語条件を使用して選択肢を選択できます。しかし広範な値クラス間を区別す る、より一般的な条件にもとづいて選択肢を選択するのが有用なこともあります 。‘pcase’マクロにより、一連のパターンにたいする式の値のマッチングにもと づいて選択肢を選択できます。パターンにはリテラル値(‘cond’で使用した比較 用のリテラル値)や、予想される式の値のより一般的な構造記述を使用できます 。 -- Macro: pcase expression &rest clauses EXPRESSIONを評価して、任意個数の選択肢の中からEXPRESSIONの値にもと づいた選択を行う。可能な選択肢はCLAUSESで指定され、それぞれが ‘(PATTERN BODY-FORMS...)’という形式のリストでなければならない。 ‘pcase’はEXPRESSIONの値と各clauseのPATTERNのマッチを試みる。値がマ ッチしたらそのclauseが成功となり、‘pcase’はそれのBODY-FORMSを評価し て、BODY-FORMSの最後の値をリターンする。残りのCLAUSESはすべて無視さ れる。 PATTERNパートはバッククォートでクォートされた“QPattern”と、クォート されていない“UPattern”のいずれかで指定できる。UPatternsのほうが単純 なのでそれから説明する。 注意: 以下のパターンの記述では‘pcase’の1つ目の引数となる EXPRESSIONの値を参照するために、“マッチされる値”という言葉を使用し ている。 UPatternには以下の形式を指定できる: ‘'VAL’ マッチされる値がVALと‘equal’ならマッチ。 ‘ATOM’ 任意のATOM (キーワード、数字、文字列)にマッチする(これらは自己 クォートされるのでこの種のUPatternは実際には‘'ATOM’の略記であ る)。文字列(浮動小数点数)は同じ内容(値)の任意の文字列(浮動小数 点数)とマッチすることに注意。 ‘_’ 任意の値にマッチする。これは“don’t care”や“wildcard”として知ら れる。 ‘SYMBOL’ 任意の値にマッチする。さらにマッチした値をSYMBOLにletバインド するので、BODY-FORMSや後続のパターンからそれを参照することがで きる。 ‘(pred PREDFUN)’ マッチされる値を引数として述語関数PREDFUNを呼び出して、非 ‘nil’をリターンしたらマッチ。PREDFUNは後述するフォームのいずれ かを指定できる。 ‘(guard BOOLEAN-EXPRESSION)’ BOOLEAN-EXPRESSIONが非‘nil’に評価されたらマッチ。これにより以 前のUPatternで、値(マッチされる値を含む)にバインドされたシンボ ルを参照するブール条件をUPatternに含めることができる。典型的に はUPattern ‘and’内で使用される(以下参照)。たとえば ‘(and x (guard (< x 10)))’は10より小さい任意の数にマッチして、 その数を変数‘x’にletバインドする。 ‘(let UPATTERN EXPRESSION)’ 指定されたEXPRESSIONが指定されたUPATTERNにマッチしたらマッチ。 これにより‘pcase’の1つ目の引数だけでなく、_任意_の式の値にパタ ーンをマッチできる(UPATTERNはUPattern SYMBOLを使用してシンボル を値にバインドできるので‘let’と呼ばれる。たとえば ‘((or `(key . ,val) (let val 5)) val)’)。 ‘(app FUNCTION UPATTERN)’ マッチされる値にFUNCTIONを適用してUPATTERNにマッチする値がリタ ーンされたらマッチ。これはUPattern ‘pred’と似ているが、これは ブールの真値ではなくUPATTERNにたいして結果をテストする点が異な る。FUNCTION呼び出しは後述のフォームのいずれかを使用できる。 ‘(or UPATTERN1 UPATTERN2...)’ 引数のUPatternのいずれかがマッチしたらマッチ。マッチする最初の UPatternが見つかったら残りはテストされない。この理由により、マ ッチされる値にシンボルをletバインドするすべてのUPatternは同じ シンボルをバインドすること。 ‘(and UPATTERN1 UPATTERN2...)’ 引数のUPatternすべてがマッチしたらマッチ。 ‘pred’と‘app’のUPatternで使用される関数呼び出しは、以下のいずれかの フォームをもつことができる: ‘integerp’のような関数シンボル この場合には、その名前つき関数がマッチされる値に適用される。 ラムダ関数 ‘(lambda (ARG) BODY)’ この場合には、そのラムダ関数がマッチされる値を単一の引数として 呼び出される。 ‘(FUNC ARGS...)’ これは指定されたN個の引数で呼び出される関数である。関数はこれ らN個の引数と、マッチされる値であるN+1番目の引数を追加して呼び 出される。 以下はUPatternを使用した説明用の例です: (pcase (get-return-code x) ('success (message "Done!")) ('would-block (message "Sorry, can't do it now")) ('read-only (message "The shmliblick is read-only")) ('access-denied (message "You do not have the needed rights")) (code (message "Unknown return code %S" code))) 加えてより強力なバッククォートされたパターンを使用できます。これら を使用すれば‘pcase’の1つ目の引数の式の値を、その_構造(structure)_の 仕様とマッチさせることができます。たとえば1つ目の要素が特定の文字列 で、2つ目の要素が‘`("first" ,second-elem)’のようなバッククォートさ れた任意の値であるような2要素のリストを、値として強制指定することが できます。 バッククォートされたパターンは‘`QPATTERN’という形式をもち、 QPATTERNは以下の形式をもつことができます: ‘(QPATTERN1 . QPATTERN2)’ マッチされる値が、‘car’がQPATTERN1、‘cdr’がQPATTERN2にマッチす るようなコンスセルならマッチ。これは ‘(QPATTERN1 QPATTERN2 ...)’のように、容易にバッククォートされ たリストに一般化できる。 ‘[QPATTERN1 QPATTERN2 ... QPATTERNM]’ マッチされる値が、長さMで‘0’から‘(M-1)’番目の要素がそれぞれ QPATTERN1、QPATTERN2、...、QPATTERNMにマッチするようなベクター ならマッチ。 ‘ATOM’ マッチされる値の対応する要素が指定されたATOMと‘equal’ならマッ チ。 ‘,UPATTERN’ マッチされる値の対応する要素が指定されたUPATTERNとマッチすれば マッチ。 QPatternは後述の‘pcase-defmacro’を使用してUPatternのトップレベルで 実装されているので、QPatternの使用はUPatternを使用することでのみ表 現可能なことに注意。とはいえQPatternの使用により、多くの場合コード の可読性は向上するだろう。 以下は‘pcase’を使用して、小さな式言語用のシンプルなインタープリターを 実装する例です(この例にはレキシカルバインディングが必要なことに注意。 )*note Lexical Binding::を参照のこと): (defun evaluate (exp env) (pcase exp (`(add ,x ,y) (+ (evaluate x env) (evaluate y env))) (`(call ,fun ,arg) (funcall (evaluate fun env) (evaluate arg env))) (`(fn ,arg ,body) (lambda (val) (evaluate body (cons (cons arg val) env)))) ((pred numberp) exp) ((pred symbolp) (cdr (assq exp env))) (_ (error "Unknown expression %S" exp)))) ここで‘`(add ,x ,y)’は、‘exp’がリテラルシンボル‘add’で始まる3要素のリ ストであることをチェックしてから、2つ目と3つ目の要素を抽出して変数‘x’と ‘y’にバインドするパターンです。それから‘x’と‘y’を評価して結果を加算しま す。同様に‘call’と‘fn’のパターンは、関数呼び出しに相当するものを2つ実装 します。‘(pred numberp)’は‘exp’が数であるかをチェックして、もしそうなら それを評価します。‘(pred symbolp)’はシンボルにマッチして、その連想をリタ ーンします。最後に‘_’はすべてにマッチするcatch-allパターンなので、構文エ ラーの報告に適しています。 以下は評価した結果を含む、この小さな言語のサンプルプログラムの例です: (evaluate '(add 1 2) nil) ;=> 3 (evaluate '(add x y) '((x . 1) (y . 2))) ;=> 3 (evaluate '(call (fn x (add 1 x)) 2) nil) ;=> 3 (evaluate '(sub 1 2) nil) ;=> error ‘pcase-defmacro’を使用することにより追加のUPatternを定義できます。 -- Macro: pcase-defmacro name args &rest body ‘pcase’にたいして新たな種類のUPatternを定義する。新たなUPatternは ‘(NAME ACTUAL-ARGS)’のように呼び出されるだろう。BODYには、UPattern NAMEを他の何らかのUPatternに書き換える方法を記述すること。ARGSが ACTUAL-ARGSにバインドされる環境でBODYを評価した結果がこの書き換えと なる。 10.3 条件の組み合わせ ===================== このセクションでは複雑な条件を表現するために‘if’や‘cond’とともによく使用 される3つの構文を説明します。‘and’と‘or’の構文は、ある種の複数条件の構文 として個別に使用することもできます。 -- Function: not condition この関数はCONDITIONが偽であることをテストする。この関数は CONDITIONが‘nil’なら‘t’、それ以外は‘nil’をリターンする。関数‘not’は ‘null’と等価であり、空のリストをテストする場合は‘null’の使用を推奨 する。 -- Special Form: and conditions... スペシャルフォーム‘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)))) -- Special Form: or conditions... スペシャルフォーム‘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回以上引数を評価する ことは決してない。 10.4 繰り返し ============= 繰り返し(iteration)とは、プログラムの一部を繰り返し実行することを意味し ます。たとえばリストの各要素、または0からNの整数にたいして、繰り返し一度 ずつ何らかの計算を行いたいとしましょう。Emacs Lispではスペシャルフォーム ‘while’でこれを行なうことができます: -- Special Form: while condition forms... ‘while’は最初にCONDITIONを評価する。結果が非‘nil’ならFORMSをテキス ト順に評価する。その後にCONDITIONを再評価して結果が非‘nil’なら、再 度FORMSを評価する。この処理はCONDITIONが‘nil’に評価されるまで繰り返 される。 繰り返し回数に制限はない。このループはCONDITIONが‘nil’に評価される か、エラーになるか、または‘throw’で抜け出す(*note Nonlocal Exits::を 参照)まで継続される。 ‘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つの一般的な種類のループを記述する 、便利な方法を提供します。 -- Macro: dolist (var list [result]) body... この構文はLISTの各要素に一度BODYを実行して、カレント要素をローカル に保持するように、変数VARにバインドする。その後にRESULTを評価した値 、RESULTが省略された場合は‘nil’をリターンする。たとえば以下は ‘reverse’関数を定義するために‘dolist’を使用する方法の例である: (defun reverse (list) (let (value) (dolist (elt list value) (setq value (cons elt value))))) -- Macro: dotimes (var count [result]) body... この構文は0以上COUNT未満の各整数にたいして、一度BODYを実行してから 、繰り返しのカレント回数となる整数を変数VARにバインドする。その後に RESULTの値、RESULTが省略された場合は‘nil’をリターンする。以下は ‘dotimes’を使用して、何らかの処理を100回行なう例である: (dotimes (i 100) (insert "I will not obey absurd orders\n")) 10.5 Generators =============== “ジェネレーター(generator)”とは、潜在的に無限な値ストリームを生成する関 数です。毎回その関数が値を生成するごとに、呼び出し側が次の値を要求するま で、自身をサスペンドします。 -- Macro: iter-defun name args [doc] [declare] [interactive] body... ‘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’フォームの内部にあってはならない 。 -- Macro: iter-lambda args [doc] [interactive] body... ‘iter-lambda’は‘iter-defun’で生成されたジェネレーター関数と同様な、 無名のジェネレーター関数を生成する。 -- Macro: iter-yield value ‘iter-yield’がジェネレーター関数内部で出現した際には、カレント iteratorが一時停止して‘iter-next’からVALUEをリターンすることを示す 。‘iter-yield’は、次回‘iter-next’呼び出しの‘value’パラメーターへと 評価される。 -- Macro: iter-yield-from iterator ‘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を生成します。 -- Function: iter-next iterator value ITERATORから次の値を取得する。(ITERATORのジェネレーター関数がリター ンしていて)生成される値が存在しない場合、‘iter-next’はコンディショ ン‘iter-end-of-sequence’をシグナルする。このコンディションに関連付 けられるデータ値は、ITERATORのジェネレーター関数がリターンした値で ある。 VALUEはiteratorに送信されて、‘iter-yield’を評価した値になる。 ITERATORのジェネレーター関数の開始時には、ジェネレーター関数は ‘iter-yield’フォームを何も評価していないので、与えられたiteratorに たいする最初の‘iter-next’呼び出しではVALUEは無視される。 -- Function: iter-close iterator ITERATORが‘unwind-protect’の‘bodyform’フォーム内でサスペンドされて いたら、ガーベージコレクション処理後にEmacsが最終的にunwindハンドラ ーを実行する(‘unwind-protect’の‘unwindforms’内部では‘iter-yield’は 不当であることに注意)。その前に確実にこれらのハンドラーを実行するに は、‘iter-close’を使用すること。 iteratorを簡単に連携できるように、便利な関数がいくつか提供されていま す: -- Macro: iter-do (var iterator) body ... ITERATORが生成する各値をVARにバインドしつつBODYを実行する。 Common Lispのループ機能にもiteratorと連携する機能が含まれます。*note (cl)Loop Facility::を参照してください。 以下のコード片はiteratorとの連携における重要な原則を示すものです。 (iter-defun my-iter (x) (iter-yield (1+ (iter-yield (1+ x)))) ;; 普通にリターンする -1) (let* ((iter (my-iter 5)) (iter2 (my-iter 0))) ;; 6をプリント (print (iter-next iter)) ;; 9をプリント (print (iter-next iter 8)) ;; 1をプリント ;; iterとiterは異なる状態をもつ (print (iter-next iter2 nil)) ;; ここでiterシーケンスの終了を待機 (condition-case x (iter-next iter) (iter-end-of-sequence ;; my-iterが通常の方法でリターンした-1をプリント (print (cdr x))))) 10.6 非ローカル脱出 =================== “非ローカル脱出(nonlocal exit)”とは、プログラム内のある位置から別の離れ た位置へ制御を移します。Emacs Lispではエラーの結果として非ローカル脱出が 発生することがあります。明示的な制御の下で非ローカル脱出を使用することも できます。非ローカル脱出は脱出しようとしている構文により作成された、すべ ての変数バインディングのバインドを解消します。 10.6.1 明示的な非ローカル脱出: ‘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したときのように 、そのバインディングは解消されます(*note Local Variables::を参照)。同様 に‘throw’は‘save-excursion’(*note Excursions::を参照)によって保存された バッファーと位置を復元します。‘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’ライブラリーはこれらのうちいくつかを提供する。*note (cl)Blocks and Exits::を参照のこと。 -- Special Form: catch tag body... ‘catch’は‘throw’関数にたいするリターン位置を確立する。リターン位置 はTAGにより、この種の他のリターン位置と区別される。TAGは‘nil’以外の 任意のLispオブジェクト。リターン位置が確立される前に、引数TAGは通常 どおり評価される。 リターン位置が効果をもつことにより、‘catch’はBODYのフォームをテキス ト順に評価する。フォームが(エラーや非ローカル脱出なしで)通常に実行 されたなら、bodyの最後のフォームの値が‘catch’からリターンされる。 BODYの実行の間に‘throw’が実行された場合、TAGと同じ値を指定すると ‘catch’フォームは即座にexitする。リターンされる値は、それが何であれ ‘throw’の2番目の引数に指定された値である。 -- Function: throw tag value ‘throw’の目的は、以前に‘catch’により確立されたリターン位置に戻るこ とである。引数TAGは、既存のさまざまなリターン位置からリターン位置を 選択するために使用される。複数のリターン位置がTAGにマッチしたら、最 内のものが使用される。 引数VALUEは‘catch’からリターンされる値として使用される。 タグTAGのリターン位置が存在しなければ、データ‘(TAG VALUE)’とともに ‘no-catch’エラーがシグナルされます。 10.6.2 ‘catch’と‘thrown’の例 ---------------------------- 2重にネストされたループから脱出する1つの方法は、‘catch’と‘throw’を使うこ とです(これはほとんどの言語では‘goto’により行なわれるだろう)。ここでは IとJを0から9に変化させて、‘(foo I J)’を計算します: (defun search-foo () (catch 'loop (let ((i 0)) (while (< i 10) (let ((j 0)) (while (< j 10) (if (foo i j) (throw 'loop (list i j))) (setq j (1+ j)))) (setq i (1+ i)))))) ‘foo’が非‘nil’をリターンしたら即座に処理を中止して、IとJのリストをリター ンしています。‘foo’が常に‘nil’をリターンする場合には、‘catch’は通常どお りリターンして、その値は‘while’の結果である‘nil’となります。 以下では2つのリターン位置を一度に表す、微妙に異なるトリッキーな例を 2つ示します。まず同じタグ‘hack’にたいして2つのリターン位置があります: (defun catch2 (tag) (catch tag (throw 'hack 'yes))) ⇒ catch2 (catch 'hack (print (catch2 'hack)) 'no) ⊣ yes ⇒ no どちらのリターン位置も‘throw’にマッチするタグをもつので内側のもの、つま り‘catch2’で確立されたcatchへgotoします。したがって‘catch2’は通常どおり 値‘yes’をリターンして、その値がプリントされます。最後に外側の‘catch’の 2番目のbody、つまり‘'no’が評価されて外側の‘catch’からそれがリターンされ ます。 ここで‘catch2’に与える引数を変更してみましょう: (catch 'hack (print (catch2 'quux)) 'no) ⇒ yes この場合も2つのリターン位置がありますが、今回は外側だけがタグ‘hack’で、 内側はかわりにタグ‘quux’をもちます。したがって‘throw’により、外側の ‘catch’が値‘yes’をリターンします。関数‘print’が呼び出されることはなく bodyのフォーム‘'no’も決して評価されません。 10.6.3 エラー ------------- Emacs Lispが何らかの理由で評価できないようなフォームの評価を試みると、 “エラー(error)”が“シグナル(signal)”されます。 エラーがシグナルされるとエラーメッセージを表示して、カレントコマンド の実行を終了するのがEmacsデフォルトの反応です。たとえばバッファーの最後 で‘C-f’とタイプしたときのように、ほとんどの場合にはこれは正しい反応にな ります。 複雑なプログラムでは単なる終了が望ましくない場合もあるでしょう。たと えばそのプログラムがータ構造に一時的に変更を行なっていたり、プログラム終 了前に削除する必要がある一時バッファーを作成しているかもしれません。この ような場合には、エラー時に評価される“クリーンアップ式(cleanup expressions)”を設定するために、‘unwind-protect’を使用するでしょう(*note Cleanups::を参照)。サブルーチン内のエラーにもかかわらずに、プログラムの 実行を継続したいときがあるかもしれません。このような場合には、エラー時の リカバリーを制御する“エラーハンドラー(error handlers)”を設定するために ‘condition-case’を使用するでしょう。 エラーハンドラーを使用せずにプログラムの一部から別の部分へ制御を移す ためには、‘catch’と‘throw’を使用します。*note Catch and Throw::を参照し てください。 10.6.3.1 エラーをシグナルする方法 ................................. エラーの“シグナリング(signaling)”とは、エラーの処理を開始することを意味 します。エラー処理は通常は実行中のプログラムのすべて、または一部をアボー ト(abort)してエラーをハンドルするためにセットアップされた位置にリターン します。ここではエラーをシグナルする方法を記述します。 ほとんどのエラーは、たとえば整数にたいしてCARの取得を試みたり、バッフ ァーの最後で1文字前方に移動したときなどのように、他の目的のために呼び出 したLispプリミティブ関数の中で自動的にシグナルされます。関数‘error’と ‘signal’で明示的にエラーをシグナルすることもできます。 ユーザーが‘C-g’をタイプしたときに発生するquitはエラーとは判断されませ んが、ほとんどはエラーと同様に扱われます。*note Quitting::を参照してくだ さい。 すべてのエラーメッセージはそれぞれ、何らかのエラーメッセージを指定し ます。そのメッセージは何が悪いのか(“File does not exist”)、物事がどうし てそうあるべきではない(“File must exist”)かを示すべきです。Emacs Lispの 慣習ではエラーメッセージは大文字で開始され、区切り文字で終わるべきではあ りません。 -- Function: error format-string &rest args この関数はFORMAT-STRINGとARGSにたいして、‘format-message’ (*note Formatting Strings::を参照)を適用して構築されたエラーメッセージとと もに、エラーをシグナルする。 以下は‘error’を使用する典型的な例である: (error "That is an error -- try something else") error→ That is an error -- try something else (error "Invalid name `%s'" "A%%B") error→ Invalid name ‘A%%B’ 2つの引数 — エラーシンボル‘error’と‘format-message’がリターンするる 文字列を含むリスト — で‘signal’を呼び出すことにより‘error’は機能す る。 ‘text-quoting-style’変数は何のクォートを生成するかを制御する。*note Keys in Documentation::を参照のこと。グレイブアクセントやアポストロ フィーを含む"Missing `%s'"のようなフォーマットを使用した呼び出しで は、通常は\"Missing ‘foo’\"のようにマッチするcurved quotesをもつメ ッセージが生成される。対照的に"Missing '%s'"のようにアポストロフィ ーだけのフォーマットを使用した場合には、通常は"Missing ’foo’"のよう に、closing curved quotesだけをもつ英語では普通使用されないスタイル のメッセージが生成される。 *警告: *エラーメッセージとして固定の文字列を使用したい場合、単に ‘(error STRING)’とは記述しないこと。もしSTRINGが‘%’、‘`’、‘'’を含ん でいると、再フォーマットされて望む結果は得られないだろう。かわりに 、‘(error "%s" STRING)’を使用すること。 -- Function: signal error-symbol data この関数はERROR-SYMBOLで命名されるエラーをシグナルする。引数DATAは エラー状況に関連する追加のLispオブジェクトのリスト。 引数ERROR-SYMBOLは“エラーシンボル(error symbol)” — ‘define-error’で 定義されたシンボル — でなければならない。これはEmacs Lispが異なる種 類のエラーをクラス分けする方法である。エラーシンボル(error symbol)、 エラーコンディション(error condition)、コンディション名(condition name)の説明については*note Error Symbols::を参照のこと。 エラーが処理されない場合には、エラーメッセージをプリントするために 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)’というフォームでバインドする(*note Handling Errors::を参照)。 関数‘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" -- Function: user-error format-string &rest args この関数は、‘error’とまったく同じように振る舞うが、‘error’ではなく エラーシンボル‘user-error’を使用する。名前が示唆するように、このエ ラーはコード自身のエラーではなく、ユーザー側のエラーの報告を意図し ている。たとえばInfoの閲覧履歴の開始を超えて履歴を遡るためにコマン ド‘Info-history-back’ (‘l’)を使用した場合、Emacsは‘user-error’をシ グナルする。このようなエラーでは、たとえ‘debug-on-error’が非‘nil’で あっても、デバッガーへのエントリーは発生しない。*note Error Debugging::を参照のこと。 Common Lispに関する注意: Emacs LispにはCommon Lispのような継続可能 なエラーのような概念は存在しない。 10.6.3.2 Emacsがエラーを処理する方法 .................................... エラーがシグナルされたとき、‘signal’はそのエラーにたいするアクティブな “ハンドラー(handler)”を検索します。ハンドラーとは、Lispプログラムの一部 でエラーが発生したときに実行するよう意図されたLisp式のシーケンスです。そ のエラーが適切なハンドラーをもっていればそのハンドラーが実行され、そのハ ンドラーの後から実行が再開されます。ハンドラーはそのハンドラーが設定され た‘condition-case’の環境内で実行されます。‘condition-case’内のすべての関 数呼び出しはすでに終了しているので、ハンドラーがそれらにリターンすること はありません。 そのエラーにたいする適切なハンドラーが存在しなければ、カレントコマン ドを終了してエディターのコマンドループに制御をリターンします(コマンドル ープにはすべての種類のエラーにたいする暗黙のハンドラーがある)。コマンド ループのハンドラーは、エラーメッセージをプリントするためにエラーシンボル と、それに関連付けられたデータを使用します。変数 ‘command-error-function’を使用して、これが行なわれる方法を制御できます: -- Variable: command-error-function この変数が非‘nil’なら、それはEmacsのコマンドループに制御をリターン したエラーの処理に使用する関数を指定する。この関数は3つの引数を受け 取る。1つ目のDATAは、‘condition-case’が自身の変数にバインドするのと 同じフォーム。2つ目のCONTEXTはエラーが発生した状況を記述する文字列 か、(大抵は)‘nil’。3つ目のCALLERはエラーをシグナルしたプリミティブ 関数を呼び出したLisp関数。 明示的なハンドラーがないエラーは、Lispデバッガーを呼び出すかもしれま せん。変数‘debug-on-error’ (*note Error Debugging::を参照)が非‘nil’なら デバッガーが有効です。エラーハンドラーと異なり、デバッガーはそのエラーの 環境内で実行されるので、エラー時の変数の値を正確に調べることができます。 10.6.3.3 エラーを処理するコードの記述 ..................................... エラーをシグナルすることによる通常の効果は、実行されていたコマンドを終了 して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’とその他のフィルタリングメカニズムがデ バッガーを呼び出すように指定されているときだけ、エラーによりデバッガーが 呼び出されます。*note Error Debugging::を参照してください。 -- Macro: condition-case-unless-debug var protected-form handlers... マクロ‘condition-case-unless-debug’は、そのようなフォームのデバッギ ングを処理する、別の方法を提供する。このマクロは変数 ‘debug-on-error’が‘nil’、つまり任意のエラーを処理しないようなケース 以外は、‘condition-case’とまったく同様に振る舞う。 特定のハンドラーがそのエラーを処理するとEmacsが判断すると、Emacsは制 御をそのハンドラーにreturnします。これを行うために、Emacsはそのとき脱出 しつつあるバインディング構成により作成されたすべての変数のバインドを解き 、そのとき脱出しつつあるすべての‘unwind-protect’フォームを実行します。制 御がそのハンドラーに達すると、そのハンドラーのbodyが通常どおり実行されま す。 そのハンドラーのbodyを実行した後、‘condition-case’フォームから実行が returnされます。保護されたフォームは、そのハンドラーの実行の前に完全に exitしているので、そのハンドラーはそのエラーの位置から実行を再開すること はできず、その保護されたフォーム内で作られた変数のバインディングを調べる こともできません。ハンドラーが行なえることは、クリーンアップと、処理を進 行させることだけです。 エラーのシグナルとハンドルには‘throw’と‘catch’ (*note Catch and Throw::を参照)に類似する点がいくつかありますが、これらは完全に別の機能で す。エラーは‘catch’でキャッチできず、‘throw’をエラーハンドラーで処理する ことはできません(しかし対応する‘catch’が存在しないときに‘throw’を使用す ることによりシグナルされるエラーは処理できる)。 -- Special Form: condition-case var protected-form handlers... このスペシャルフォームはPROTECTED-FORMの実行を囲い込むエラーハンド ラーHANDLERSを確立する。エラーなしでPROTECTED-FORMが実行されると、 リターンされる値は‘condition-case’フォームの値になる。この場合、 ‘condition-case’は効果をもたない。PROTECTED-FORMの間にエラーが発生 すると、‘condition-case’フォームは違いを生じる。 HANDLERSはそれぞれ、‘(CONDITIONS BODY...)’というフォームのリストで ある。ここでCONDITIONSはハンドルされるエラーコンディション名、また はそのハンドラーの前にデバッガーを実行するためのコンディション名 (‘debug’を含む)。BODYはこのハンドラーがエラーを処理するときに実行さ れる1つ以上のLisp式。 (error nil) (arith-error (message "Division by zero")) ((arith-error file-error) (message "Either division by zero or failure to open a file")) 発生するエラーはそれぞれ、それが何の種類のエラーかを記述する“エラー シンボル(error symbol)”をもち、これはコンディション名のリストも記述 する(*note Error Symbols::を参照)。Emacsは1つ以上のコンディション名 を指定するハンドラーにたいして、すべてのアクティブな ‘condition-case’フォームを検索する。‘condition-case’の最内のマッチ がそのエラーを処理する。‘condition-case’内では、最初に適合したハン ドラーがそのエラーを処理する。 ハンドラーのbodyを実行した後、‘condition-case’は通常どおりリターン して、ハンドラーのbodyの最後の値をハンドラー全体の値として使用する 。 引数VARは変数である。PROTECTED-FORMを実行するとき、 ‘condition-case’はこの変数をバインドせず、エラーを処理するときだけ バインドする。その場合には、VARを“エラー記述(error description)”に バインドする。これはエラーの詳細を与えるリストである。このエラー記 述は‘(ERROR-SYMBOL . DATA)’というフォームをもつ。ハンドラーは何を行 なうか決定するために、このリストを参照することができる。たとえばフ ァイルオープンの失敗にたいするエラーなら、ファイル名がDATA(エラー記 述の3番目の要素)の2番目の要素になる。 VARが‘nil’なら、それはバインドされた変数がないことを意味する。この 場合、エラーシンボルおよび関連するデータは、そのハンドラーでは利用 できない。 より外側のレベルのハンドラーにcatchさせるために、‘condition-case’に よりcatchされたシグナルを再度throwする必要がある場合もある。以下は これを行なう方法である: (signal (car err) (cdr err)) ここで‘err’はエラー記述変数(error description variable)で、 ‘condition-case’の1番目の引数は、再throwしたいエラーコンディション 。*note Definition of signal::を参照のこと。 -- Function: error-message-string error-descriptor この関数は与えられたエラー記述子(error descriptor)にたいするエラー メッセージ文字列をリターンする。これはそのエラーにたいする通常のエ ラーメッセージをプリントすることにより、エラーを処理したい場合に有 用。*note 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 -- Macro: ignore-errors body... この構文は、それの実行中に発生する任意のエラーを無視してBODYを実行 する。その実行中にエラーがなければ、‘ignore-errors’はBODY内の最後の フォームの値を、それ以外は‘nil’をリターンする。 以下はこのセクションの最初の例を‘ignore-errors’を使用して記述する例 である: (ignore-errors (delete-file filename)) -- Macro: with-demoted-errors format body... このマクロはいわば‘ignore-errors’の穏やかなバージョンである。これは エラーを完全に抑止するのではなく、エラーをメッセージに変換する。こ れはメッセージのフォーマットに、文字列FORMATを使用する。FORMATは ‘"Error: %S"’のように、単一の‘%’シーケンスを含むこと。エラーをシグ ナルするとは予測されないが、もし発生した場合は堅牢であるべきような コードの周囲に‘with-demoted-errors’を使用する。このマクロは ‘condition-case’ではなく、‘condition-case-unless-debug’を使用するこ とに注意。 10.6.3.4 エラーシンボルとエラー条件 ................................... エラーをシグナルするとき、想定するエラーの種類を指定するために“エラーシ ンボル(error symbol)”を指定します。エラーはそれぞれ、それをカテゴリー分 けするために単一のエラーシンボルをもちます。これはEmacs Lisp言語で定義さ れるエラーを分類する、もっともよい方法です。 これらの狭義の分類は“エラー条件(error conditions)”と呼ばれる、より広 義のクラス階層にグループ化され、それらは“コンディション名(condition names)”により識別されます。そのようなもっとも狭義なクラスは、エラーシン ボル自体に属します。つまり各エラーシンボルは、コンディション名でもあるの です。すべての種類のエラー(‘quit’を除く)を引き受けるコンディション名 ‘error’に至る、より広義のクラスにたいするコンディション名も存在します。 したがって各エラーは1つ以上のコンディション名をもちます。つまり‘error’、 ‘error’とは区別されるエラーシンボル、もしかしたらその中間に分類されるも のかもしれません。 -- Function: define-error name message &optional parent シンボルをエラーシンボルとするために、シンボルは親コンディションを 受け取る‘define-error’で定義されなければならない。この親はその種の エラーが属するコンディションを定義する。親の推移的な集合は、常にそ のエラーシンボルとシンボル‘error’を含む。quitはエラーと判断されない ので、‘quit’の親の集合は単なる‘(quit)’である。 親のコンディションに加えてエラーシンボルはメッセージ(MESSAGE)をもち、 これは処理されないエラーがシグナルされたときプリントされる文字列です。そ のメッセージが有効でなければ、エラーメッセージ‘peculiar error’が使用され ます。*note 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’ (*note 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’の効果を著しく減少させるでしょう。コンディション名は エラーハンドラーを記述するとき、一般性のさまざまなレベルにおいて、エラー をカテゴリー分けすることを可能にします。エラーシンボルを単独で使用するこ とは、もっとも狭義なレベルの分類を除くすべてを捨ててしまうことです。 主要なエラーシンボルとそれらのコンディションについては、*note Standard Errors::を参照してください。 10.6.4 非ローカル脱出のクリーンアップ ------------------------------------- ‘unwind-protect’構文は、データ構造を一時的に不整合な状態に置くときに重要 です。これはエラーやthrouのイベントにより、再びデータを整合された状態に することができます(バッファー内容の変更だけに使用される他のクリーンアッ プ構成はアトミックな変更グループである。*note Atomic Changes::を参照)。 -- Special Form: unwind-protect body-form cleanup-forms... ‘unwind-protect’は制御がBODY-FORMを離れる場合に、CLEANUP-FORMSが評 価されるという保証の下において、何が起こったかに関わらずBODY-FORMを 実行する。BODY-FORMは通常どおり完了するかもしれず、 ‘unwind-protect’の外側で‘throw’の実行やエラーが発生するかもしれない が、CLEANUP-FORMSは評価される。 BODY-FORMが正常に終了したら、‘unwind-protect’はCLEANUP-FORMSを評価 した後に、BODY-FORMの値をリターンする。BODY-FORMが終了しなかったら 、‘unwind-protect’は通常の意味におけるような値はリターンしない。 ‘unwind-protect’で保護されるのはBODY-FORMだけである。 CLEANUP-FORMS自体の任意のフォームが、(‘throw’またはエラーにより)非 ローカルにexitすると、‘unwind-protect’は残りのフォームが評価される ことを_保証しない_。CLEANUP-FORMSの中の1つが失敗することが問題とな るようなら、そのフォームの周囲に他の‘unwind-protect’を配置して保護 すること。 現在アクティブな‘unwind-protect’フォーム数とローカルの変数バインデ ィング数の和は、‘max-specpdl-size’ (*note Local Variables: Definition of max-specpdl-size.を参照)により制限される。 たとえば以下は一時的な使用のために不可視のバッファーを作成して、終了 する前に確実にそのバッファーを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’という標準マクロが含まれます(*note Current Buffer: Definition of with-temp-buffer.を参照)。このマニュアル中で定義されるいく つかのマクロは、この方法で‘unwind-protect’を使用します。 以下はFTPパッケージ由来の実例です。これはリモートマシンへの接続の確立 を試みるために、プロセス(*note Processes::を参照)を作成しています。関数 ‘ftp-login’は関数のライター(writer)が予想できないことによる多くの問題か ら非常に影響を受けるので、失敗イベントでプロセスの削除を保証するフォーム で保護されています。そうしないとEmacsは無用なサブプロセスで一杯になって しまうでしょう。 (let ((win nil)) (unwind-protect (progn (setq process (ftp-setup-buffer host file)) (if (setq win (ftp-login process host user password)) (message "Logged in") (error "Ftp login failed"))) (or win (and process (delete-process process))))) この例には小さなバグがあります。ユーザーがquitするために‘C-g’とタイプ すると、関数‘ftp-setup-buffer’のリターン後に即座にquitが発生しますが、そ れは変数‘process’がセットされる前なので、そのプロセスはkillされないでし ょう。このバグを簡単に訂正する方法はありませんが、少なくともこれは非常に 稀なことだと言えます。 11 変数 ******* “変数(variable)”とはプログラム内で値を表すために使用される名前です。 Lispでは変数はそれぞれLispシンボルとして表されます(*note Symbols::を参照 )。変数名は単にそのシンボルの名前であり、変数の値はそのシンボルの値セル (value cell)に格納されます(1)。*note Symbol Components::を参照してくださ い。Emacs Lispではシンボルを変数として使用することは、同じシンボルを関数 名として使用することと関係ありません。 このマニュアルで前述したとおり、Lispプログラムはまず第1にLispオブジェ クトとして表され、副次的にテキストとして表現されます。Lispプログラムのテ キスト的な形式は、そのプログラムを構成するLispオブジェクトの入力構文によ り与えられます。したがってLispプログラム内の変数のテキスト的な形式は、そ の変数を表すシンボルの入力構文を使用して記述されます。 ---------- Footnotes ---------- (1) 正確に言うとデフォルトの“ダイナミックスコープ(dynamic scoping)”の ルールでは、値セルは常にその変数のカレント値を保持しますが、“レキシカル スコープ(lexical scoping)”では異なります。詳細は*note Variable Scoping::を参照してください。 11.1 グローバル変数 =================== 変数を使用するための一番シンプルな方法は、“グローバル(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 11.2 Variables that Never Change ================================ Emacs Lispでは特定のシンボルは、通常は自分自身に評価されます。これらのシ ンボルには‘nil’と‘t’、同様に名前が‘:’で始まる任意のシンボル(これらは“キ ーワード”と呼ばれる)が含まれます。これらのシンボルはリバインドや、値の変 更はできません。‘nil’や‘t’へのセットやリバインドは、‘setting-constant’エ ラーをシグナルします。これはキーワード(名前が‘:’で始まるシンボル)につい ても当てはまります。ただしキーワードが標準のobarrayにinternされていれば 、そのようなシンボルを自分自身にセットしてもエラーになりません。 nil ≡ 'nil ⇒ nil (setq nil 500) error→ Attempt to set constant symbol: nil -- Function: keywordp object この関数はOBJECTが‘:’で始まる名前のシンボルであり、標準のobarrayに internされていれば‘t’、それ以外は‘nil’をリターンする。 これらの定数はスペシャルフォーム‘defconst’(*note Defining Variables::を参照)を使用して定義された定数(constant)とは根本的に異なりま す。‘defconst’フォームは、人間の読み手に値の変更を意図しない変数であるこ とを知らせる役目は果たしますが、実際にそれを変更してもEmacsはエラーを起 こしません。 11.3 ローカル変数 ================= グローバル変数は新しい値で明示的に置き換えるまで値が持続します。変数に “ローカル値(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)”と呼ばれるスコープルールについては、*note Variable Scoping::を参照してください。 スペシャルフォーム‘let’と‘let*’は、ローカルバインディングを作成するた めに存在します: -- Special Form: let (bindings...) forms... このスペシャルフォームは、BINDINGSにより指定される特定の変数セット にたいするローカルバインディングをセットアップしてから、FORMSのすべ てをテキスト順に評価する。これはFORMS内の最後のフォームの値をリター ンする。 BINDINGSの各バインディングは2つの形式のいずれかである。(i) シンボル なら、そのシンボルは‘nil’にローカルにバインドされる。(ii) フォーム ‘(SYMBOL VALUE-FORM)’のリストなら、SYMBOLはVALUE-FORMを評価した結果 へローカルにバインドされる。VALUE-FORMが省略されたら‘nil’が使用され る。 BINDINGS内のすべてのVALUE-FORMは、シンボルがそれらにバインドされる _前_に、記述された順番に評価される。以下の例では‘z’は‘y’の新しい値 (つまり1)にではなく、古い値(つまり2)にバインドされる。 (setq y 2) ⇒ 2 (let ((y 1) (z y)) (list y z)) ⇒ (1 2) -- Special Form: let* (bindings...) forms... このスペシャルフォームは‘let’と似ているが、次の変数値にたいするロー カル値を計算する前に、ローカル値を計算してそれを変数にバインドする 。したがてBINDINGS内の式は、この‘let*’フォーム内の前のシンボルのバ インドを参照できる。以下の例を上記‘let’の例と比較されたい。 (setq y 2) ⇒ 2 (let* ((y 1) (z y)) ; ‘y’の値に今計算されたばかりの値を使用する (list y z)) ⇒ (1 1) 以下はローカルバインディングを作成する他の機能のリストです: • 関数呼び出し(*note Functions::を参照)。 • マクロ呼び出し(*note Macros::を参照)。 • ‘condition-case’ (*note Errors::を参照)。 変数はバッファーローカルなバインディングを持つこともできます(*note Buffer-Local Variables::を参照)。数は多くありませんが、端末ローカル (terminal-local)なバインディングをもつ変数もあります(*note Multiple Terminals::を参照)。この種のバインディングは、通常のローカルバインディン グのように機能することもありますが、これらはEmacs内のどこにいるかに依存 してローカルになります。 -- User Option: max-specpdl-size この変数はローカルな変数バインディングと、‘unwind-protect’にゆるク リーンアップ(*note Cleaning Up from Nonlocal Exits: Cleanups.を参照 )の総数にたいする制限を定義し、この変数を越えるとEmacsは(データ ‘"Variable binding depth exceeds max-specpdl-size"’とともに)エラー をシグナルする。 このリミットは、もし超過したときにエラーが関連付けられていれば、誤 って定義された関数による無限再起を避けるための1つの手段になる。ネス トの深さにたいする他の制限としては、‘max-lisp-eval-depth’がある。 *note Eval: Definition of max-lisp-eval-depth.を参照のこと。 デフォルト値は1300。Lispデバッガーのエントリーしたとき、もし残りが 少なければ、デバッガーを実行するための空きを作るために値が増加され る。 11.4 変数がvoidのとき ===================== シンボルの値セル(*note Symbol Components::を参照)に値が割り当てられてい ない場合、その変数はvoid(空)であると言います。 Emacs Lispのデフォルトであるダイナミックスコープルール(*note Variable Scoping::を参照)の下では、値セルはその変数のカレント値(ローカルまたはグ ローバル)を保持します。値が割り当てられていない値セルは、値セルに‘nil’を もつのとは_異なる_ことに注意してください。シンボル‘nil’はLispオブジェク トであり、他のオブジェクトと同様に変数の値となることができます。‘nil’は 値なのです。変数がvoidの場合にその変数の評価を試みると、値をリターンする かわりに、‘void-variable’エラーがシグナルされます。 オプションであるレキシカルスコープルール(lexical scoping rule)の下で は、値セル保持できるのはその変数のグローバル値 — 任意のレキシカルバイン ディング構造の外側の値だけです。変数がレキシカルにバインドされている場合 、ローカル値はそのレキシカル環境により決定されます。したがってこれらのシ ンボルの値セルに値が割り当てられていなくても、変数はローカル値を持つこと ができます。 -- Function: makunbound symbol この関数は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 -- Function: boundp variable この関数は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 11.5 グローバル変数の定義 ========================= “変数定義(variable definition)”とは、そのシンボルをグローバル変数として 使用する意図を表明する構文です。これには以下で説明するスペシャルフォーム ‘defvar’や‘defconst’が使用されます。 変数宣言は3つの目的をもちます。1番目はコードを読む人にたいして、その シンボルが特定の方法(変数として)使用されることを_意図_したものだと知らせ ることです。2番目はLispシステムにたいしてオプションで初期値とドキュメン ト文字列を与えて、これを知らせることです。3番目は‘etags’のようなプログラ ミングツールにたいして、その変数が定義されている場所を見つけられるように 情報を提供することです。 ‘defconst’と‘defvar’の主な違いは、人間の読み手に値が変更されるかどう かを知らせることにあります。Emacs Lispは実際に、‘defconst’で定義された変 数の値の変更を妨げません。この2つのフォームの特筆すべき違いは、 ‘defconst’は無条件で変数を初期化して、‘defvar’は変数が元々voidのときだけ 初期化することです。 カスタマイズ可能な変数を定義する場合は、‘defcustom’を使用するべきです (これはサブルーチンとして‘defvar’を呼び出す)。*note Variable Definitions::を参照してください。 -- Special Form: defvar symbol [value [doc-string]] このスペシャルフォームは変数としてSYMBOLを定義する。SYMBOLが評価さ れないことに注意。シンボルは‘defvar’フォーム内に明示的に表記して定 義される必要がある。この変数は“特別”だとマークされて、これは常に変 数がダイナミックにバインドされることを意味する(*note Variable Scoping::を参照)。 VALUEが指定されていてSYMBOLがvoid(たとえばこのシンボルがダイナミッ クにバインドされた値を持たないとき。*note Void Variables::を参照)な らVALUEが評価されて、その結果がSYMBOLにセットされる。しかしSYMBOLが voidでなければ、VALUEは評価されずSYMBOLの値は変更されない。VALUEが 省略された場合は、いかなる場合もSYMBOLの値は変更されない。 SYMBOLがカレントバッファー内でバッファーローカルなバインディングを もつ場合、‘defvar’はデフォルト値に作用する。デフォルト値はバッファ ーローカルなバインディングではなく、バッファーにたいして独立である 。デフォルト値がvoidのときはデフォルト値をセットする。*note Buffer-Local Variables::を参照のこと。 すでにSYMBOLがレキシカルにバインドされている場合(たとえばレキシカル バインドが有効な状態で‘let’フォーム内に‘defvar’があるような場合)、 ‘defvar’はダイナミックな値をセットする。バインディング構文を抜ける まで、レキシカルバインディングは効果をもつ。*note Variable Scoping::を参照のこと。 Emacs Lispモードで‘C-M-x’ (‘eval-defun’)でトップレベルの‘defvar’を 評価するとき、‘eval-defun’の特別な機能はその値がvoidであるかテスト することなく、その変数を無条件にセットする。 引数DOC-STRINGが与えられたら、それは変数にたいするドキュメント文字 列を指定する(そのシンボルの‘variable-documentation’プロパティーに格 納される)。*note Documentation::を参照のこと。 以下にいくつか例を示す。これは‘foo’を定義するが初期化は行わない: (defvar foo) ⇒ foo 以下の例は‘bar’の値を‘23’に初期化してドキュメント文字列を与える: (defvar bar 23 "The normal weight of a bar.") ⇒ bar ‘defvar’フォームはSYMBOLをリターンするが、これは通常は値が問題にな らないファイル内のトップレベルで使用される。 -- Special Form: defconst symbol value [doc-string] このスペシャルフォームはある値でSYMBOLを定義して、それを初期化する 。これはコードを読む人に、SYMBOLがここで設定される標準的なグローバ ル値をもち、ユーザーや他のプログラムがそれを変更すべきではないこと を知らせる。SYMBOLが評価されないことに注意。定義されるシンボルは ‘defconst’内に明示的に記されなければならない。 ‘defvar’と同様、‘defconst’は変数を“特別” — この変数が常にダイナミッ クにバインドされているという意味 — であるとマークする(*note Variable Scoping::を参照)。加えてこれはその変数を危険であるとマーク する(*note File Local Variables::を参照)。 ‘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’を使用すると、これらのフォームはグローバルバインディングではなく 、ローカルバインディングをセットします。これは通常は、あなたが望むことで はないはずです。これを防ぐには、これらのスペシャルフォームをファイル内の トップレベルで使用します。この場所は通常、何のローカルバインディングも効 果をもたないので、その変数にたいするローカルバインディングが作成される前 にファイルがロードされることが確実だからです。 11.6 堅牢な変数定義のためのヒント ================================= 値が関数(または関数のリスト)であるような変数を定義するときには、変数の名 前の最後に‘-function’(または‘-functions’)を使用します。 他にも変数名に関する慣習があります。以下はその完全なリストです: ‘...-hook’ 変数はノーマルフック(*note Hooks::を参照)。 ‘...-function’ 値は関数。 ‘...-functions’ 値は関数のリスト。 ‘...-form’ 値はフォーム(式)。 ‘...-forms’ 値はフォーム(式)のリスト。 ‘...-predicate’ 値は述語(predicate) — 1つの引数をとる関数 — であり成功なら非‘nil’、 失敗なら‘nil’をリターンする。 ‘...-flag’ ‘nil’か否かだけが意味をもつような値。結局そのような変数は、やがては 多くの値をもつことが多いので、この慣習を強く推奨はしない。 ‘...-program’ 値はプログラム名。 ‘...-command’ 値は完全なシェルコマンド。 ‘...-switches’ 値はコマンドにたいして指定するオプション。 変数を定義するときは、その変数を安全(safe)とマークすべきか、それとも 危険(risky)とマークすべきかを常に考慮してください。*note File Local Variables::を参照してください。 複雑な値を保持する変数(バインディングをもつkeymapなど)の定義や初期化 を行う場合は、以下のように値の計算をすべて‘defvar’の中に配置するのが最良 です: (defvar my-mode-map (let ((map (make-sparse-keymap))) (define-key map "\C-c\C-a" 'my-command) ... map) DOCSTRING) この方法にはいくつかの利点があります。1つ目はファールをロード中にユーザ ーが中断した場合、変数はまだ初期化されていないか、初期化されているかのど ちらかであり、その中間ということはありません。まだ初期化されていなければ 、ファイルをリロードすれば正しく初期化されます。2つ目は一度初期化された 変数は、ファイルをリロードしても変更されないことです。コンテンツの一部を 変更(たとえばキーのリバインド)するフックをユーザーが実行した場合などに、 これは重要です。3つ目は‘C-M-x’で‘defvar’を評価すると、そのマップは完全に 再初期化されることです。 ‘defvar’フォーム内に多すぎるコードを配置することが不利な点が1つありま す。ドキュメント文字列が変数の名前から離れた場所に配置されることです。こ れを避ける安全な方法は以下の方法です: (defvar my-mode-map nil DOCSTRING) (unless my-mode-map (let ((map (make-sparse-keymap))) (define-key map "\C-c\C-a" 'my-command) ... (setq my-mode-map map))) これは初期化を‘defvar’の内側に配置した場合とまったく同じ利点をもちますが 、変数を再度初期化したい場合は、各フォームにたいして1回ずつ、‘C-M-x’を 2回タイプしなければならない点が異なります。 11.7 変数の値へのアクセス ========================= 変数を参照する通常の方法は、それに名前をつけるシンボルを記述する方法です 。*note Symbol Forms::を参照してください。 実行時にのみ決定される変数を参照したいときがあるかもしれません。その ような場合、プログラム中のテキストで変数名を指定することはできません。そ のような値を抽出するために‘symbol-value’を使うことができます。 -- Function: symbol-value symbol この関数はSYMBOLの値セルに格納された値をリターンする。これはその変 数の(ダイナミックな)カレント値が格納された場所である。その変数がロ ーカルバインディングをもたなければ単にその変数のグローバル値になる 。変数がvoidなら‘void-variable’はエラーをシグナルする。 その変数がレキシカルにバインドされていれば、‘symbol-value’が報告す る値は、その変数のレキシカル値と同じである必要はない。レキシカル値 はそのシンボルの値セルではなく、レキシカル環境により決定される。 *note Variable Scoping::を参照のこと。 (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 11.8 変数の値のセット ===================== ある変数の値を変更する通常の方法は、スペシャルフォーム‘setq’を使用する方 法です。実行時に変数選択を計算する必要がある場合には関数‘set’を使用しま す。 -- Special Form: setq [symbol form]... このスペシャルフォームは、変数の値を変更するためのもっとも一般的な 方法である。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 -- Function: set symbol value この関数はSYMBOLの値セルにVALUEを配置する。これはスペシャルフォーム ではなく関数なので、シンボルにセットするためにSYMBOLに記述された式 は評価される。リターン値はVALUE。 ダイナミックな変数バインドが有効(デフォルト)なら、‘set’は自身の引数 SYMBOLを評価するが、‘setq’は評価しないという点を除き、‘set’は ‘setq’と同じ効果をもつ。しかし変数がレキシカルバインドなら、‘set’は 変数の_ダイナミック_な値に、‘setq’は変数のカレント値(レキシカル値 )に影響する。*note Variable Scoping::を参照のこと。 (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) 11.9 変数のバインディングのスコーピングルール ============================================= ある変数にたいするローカルバインディングを作成するとき、そのバインディン グはプログラムの限られた一部だけに効果をもちます(*note Local Variables::を参照)。このセクションでは、これが正確には何を意味するかにつ いて説明します。 ローカルバインディングはそれぞれ、個別に“スコープ(scope: 範囲という意 味)”と“エクステント(extent: これも範囲を意味する)”をもちます。“スコープ ”はそのバインディングにアクセスできるのが、テキストのソースコードの_どこ (where)_であるかを示します。“エクステント”はプログラムの実行中に、そのバ インディングが存在するのが_いつ(when)_であるかを示します。 デフォルトではEmacsが作成したローカルバインディングは、“ダイナミック バインディング(dynamic binding)”です。このようなバインディングは“ダイナ ミックスコープ(dynamic scope)”をもち、それはプログラムの任意の範囲が、そ の変数バインディングにアクセスするかもしれないことを意味します。これは “ダイナミックエクステント(dynamic extent)”ももっています。これはそのバイ ンディング構造(‘let’フォームのbodyなど)が実行される間だけ、そのバインデ ィングが存続することを意味します。 Emacsはオプションで“レキシカルバインディング(lexical binding)”を作成 することができます。レキシカルバインディングは“レキシカルスコープ (lexical scope)”をもち、これはその変数にたいするすべての参照が、バインデ ィング構文内にテキスト的に配置されなければならないことを意味します(1)。 レキシカルバインディングは“不定エクステント(indefinite extent)”ももって います。これはある状況下において、“クロージャー(closures)”と呼ばれるスペ シャルオブジェクトにより、バインディング構造が実行を終えた後でさえも、存 続し続けることを意味します。 以降のサブセクションでは、ダイナミックバインディングとレキシカルバイ ンディング、およびEmacs Lispプログラムでレキシカルバインディングを有効に する方法についてより詳細に説明します。 ---------- Footnotes ---------- (1) これにはいくつか例外があります。たとえばレキシカルバインディング は、Lispデバッガーからもアクセスできます。 11.9.1 ダイナミックバインディング --------------------------------- デフォルトでは、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でのダイナミックバインディングは、シンプルな方法で実装され ています。シンボルはそれぞれ、シンボルのカレントのダイナミック値(または 値の不在)を指定する値セルをもちます。*note Symbol Components::を参照して ください。あるシンボルがダイナミックなローカル値を与えられたとき、 Emacsは値セルの内容(または値の不在)をスタックに記録して、新しいローカル 値を値セルに格納します。バインディング構文が実行を終えたとき、Emacsはス タックから古い値をpopして値セルにそれを配置します。 11.9.2 ダイナミックバインディングの正しい使用 --------------------------------------------- ダイナミックバインディングは、プログラムにたいしてテキスト的なローカルス コープ内で定義されていない変数を参照することを許容する、強力な機能です。 しかし無制限に使用した場合には、プログラムの理解を困難にしてしまうことも あります。このテクニックを使用するために2つの明解な方法があります: • ある変数がグローバルな定義をもたなければ、ローカル変数としてバイン ディング構文内(その変数がバインドされる‘let’フォームのbodyなどの場 所)だけでそれを使用する。プログラムでこの慣習に一貫してしたがえば、 プログラム内の他の場所で同じ変数シンボルを任意に使用しても、その変 数の値に影響を与えたり、影響を受けることがなくなる。 • それ以外なら‘defvar’、‘defconst’、‘defcustom’で変数を定義する。 *note Defining Variables::を参照のこと。この定義は通常はEmacs Lispフ ァイル内のトップレベルにあること。この定義には変数の意味と目的を説 明するドキュメント文字列を可能な限り含めるべきである。また名前の衝 突を避けるように変数を命名すること(*note Coding Conventions::を参照 )。 そうすればプログラム内のどこか別の場所で、それが何に影響するか確信 をもって変数をバインドすることができます。その変数にどこで出会って も、(たとえば変数の定義がEmacsにロードされていれば‘C-h v’コマンドを 通じて)定義を参照するのが簡単になります。*note (emacs)Name Help::を 参照してください。 たとえば‘case-fold-search’のようなカスタマイズ可能な変数にたいして ローカルバインディングを使用するのは一般的です: (defun search-for-abc () "Search for the string \"abc\", ignoring case differences." (let ((case-fold-search nil)) (re-search-forward "abc"))) 11.9.3 レキシカルバインディング ------------------------------- Emacsのバージョン24.1からオプションの機能としてレキシカルバインディング が導入されました。わたしたちはこの機能の重要性が、将来増加することを期待 しています。レキシカルバインディングは最適化の機会をより広げるので、この 機能を使用するプログラムはおそらくEmacsの将来のバージョンで高速に実行さ れるようになるでしょう。レキシカルバインディングは、わたしたちがEmacsに 将来追加したいと考える並列性(concurrency)とも互換性があります。 レキシカルにバインドされた変数は“レキシカルスコープ(lexical scope)”を もちます。これはその変数にたいする参照が、そのバインディング構文内にテキ スト的に配置されなければならないことを意味しています。以下は例です (実際 にレキシカルバインディングを有功にする方法は、*note Using Lexical Binding::を参照のこと): (let ((x 1)) ; ‘x’はレキシカルにバインドされる (+ x 3)) ⇒ 4 (defun getx () x) ; この関数内では‘x’は自由に使用される (let ((x 1)) ; ‘x’はレキシカルにバインドされる (getx)) error→ Symbol's value as variable is void: x ここでは‘x’はグローバル値をもちません。‘let’フォーム内でレキシカルにバイ ンドされたとき、この変数は‘let’のテキスト境界内で使用できます。しかしこ の‘let’内から呼び出される‘getx’関数からは、‘getx’の関数定義が‘let’フォー ムの外側なので使用することが_できません_。 レキシカルバインディングが機能する方法を説明します。バインディング構 文はぞれぞれ、その構文内でローカル値にバインドする変数を指定する、“レキ シカル環境(lexical environment)”を定義します。Lispの評価機能(Lisp evaluator)が、ある変数のカレント値を得たいときは、最初にレキシカル環境内 を探します。そこで変数が指定されていなければ、ダイナミック値が格納される シンボルの値セルを探します。 (内部的にはレキシカル環境はシンボルと値がペアになったalistでり、 alistの最後の要素はコンスセルではなくシンボル‘t’である。そのような alistはフォームを評価するためのレキシカル環境を指定するために、‘eval’関 数の2番目の引数として渡すことができる。*note Eval::を参照のこと。しかし ほとんどのEmacs Lispプログラムは、この方法で直接レキシカル環境を使用する べきではない。デバッガーのような特化されたプログラムだけが使用すること。 ) レキシカルバインディングは不定エクステント(indefinite extent)をもちま す。バインディング構造が終了した後でも、そのレキシカル環境は“クロージャ ー(closures)”と呼ばれるLispオブジェクト内に“保持”されるかもしれ、あせん 。クロージャーはレキシカルバインディングが有効な、名前つきまたは無名 (anonymous)の関数が作成されたときに作成されます。詳細は*note Closures::を 参照してください。 クロージャーが関数として呼び出されたとき、その関数の定義内のレキシカ ル変数にたいする任意の参照は、維持されたレキシカル環境を使用します。以下 は例です: (defvar my-ticker nil) ; クロージャーを格納するために ; この変数を使用する (let ((x 0)) ; ‘x’はレキシカルにバインドされる (setq my-ticker (lambda () (setq x (1+ x))))) ⇒ (closure ((x . 0) t) () (setq x (1+ x))) (funcall my-ticker) ⇒ 1 (funcall my-ticker) ⇒ 2 (funcall my-ticker) ⇒ 3 x ; ‘x’はグローバル値をもたないことに注意 error→ Symbol's value as variable is void: x ‘let’バインディングは、内部に変数‘x’をもつレキシカル環境を定義して、変数 は0にローカルにバインドされます。このバインディング構文内で‘x’を1増加し て、増加された値をリターンするクロージャーを定義しています。このラムダ式 は自動的にクロージャーとなり、たとえ‘let’構文を抜けた後でも、その内部で はレキシカル環境が存続します。クロージャーを評価するときは、毎回レキシカ ル環境内の‘x’のバインディングが使用されて、‘x’が加算されます。 シンボルオブジェクト自体に束縛されるダイナミック変数と異なり、レキシ カル変数とシンボルの関係はインタープリター(かコンパイラー)内にのみ存在し ます。したがって(‘symbol-value’、‘boundp’、‘set’のような)シンボル引数を 受け取る関数ができるのは、変数のダイナミックなバインディング(そのシンボ ルの値セルの内容)の取得と変更だけです。 11.9.4 レキシカルバインディングの使用 ------------------------------------- Emacs LispファイルのロードやLispバッファーを評価するとき、バッファーロー カルな変数‘lexical-binding’が非‘nil’なら、レキシカルバインディングが有効 になります: -- Variable: lexical-binding このバッファーローカルな変数が非‘nil’なら、Emacs Lispファイルとバッ ファーはダイナミックバインディングではなくレキシカルバインディング を使用して評価される(しかし特別な変数はダイナミックにバインドされた まま。以下を照)。‘nil’ならすべてのローカル変数にたいしてダイナミッ クバインディングが使用される。この変数は、通常はファイルローカル変 数として、Emacs Lispファイル全体にたいしてセットされる(*note File Local Variables::を参照)。他のファイルローカル変数などとは異なり、 ファイルの最初の行でセットされなければならないことに注意。 ‘eval’呼び出しを使用してEmacs Lispコードを直接評価するとき、‘eval’の LEXICAL引数が非‘nil’なら、レキシカルバインディングが有効になります。 *note Eval::を参照してください。 レキシカルバインディングが有効な場合でも、特定の変数はダイナミックに バインドされたままです。これらは“スペシャル変数(special variable)”と呼ば れます。‘defvar’、‘defcustom’、‘defconst’で定義されたすべての変数はスペ シャル変数です(*note Defining Variables::を参照)。その他のすべての変数は レキシカルバインディングの対象になります。 -- Function: special-variable-p symbol この関数はSYMBOLがスペシャル変数(つまり変数が‘defvar’、 ‘defcustom’、‘defconst’による定義をもつ)なら非‘nil’をリターンする。 、それ以外ならリターン値は‘nil’。 関数内での通常の引数としてのスペシャル変数の使用は、推奨されません。 レキシカルバインディングモードが有効なときにこれを行うと、(あるときはレ キシカルバインディング、またあるときはダイナミックバインディングのような )不定な動作が起こります。 Emacs Lispプログラムをレキシカルバインディングに変換するのは簡単です 。最初にEmacs Lispソースファイルのヘッダー行で‘lexical-binding’を‘t’にし て、ファイルローカル変数を追加します(*note File Local Variables::を参照 )。次に意図せずレキシカルにバインドしてしまわないように、ダイナミックな バインドをもつ必要がある変数が変数定義をもつことを各変数ごとにチェックし ます。 どの変数が変数定義をもつ必要があるか見つけるシンプルな方法は、ソース ファイルをバイトコンパイルすることです。*note Byte Compilation::を参照し てください。‘let’フォームの外側で非スペシャル変数が使用されていれば、バ イトコンパイラーはフリーな変数にたいする参照や割り当てについて警告するで しょう。非スペシャル変数がバインドされているが‘let’フォーム内で使用され ていなければ、バイトコンパイラーは使用されないレキシカル変数に関して警告 するでしょう。バイトコンパイラーは、スペシャル変数を関数の引数として使用 している場合も問題を警告します。 (使用されていない変数についての警告を抑制するためには、単に変数名をア ンダースコアーで開始すればよい。そうすればバイトコンパイラーはその変数が 使用されないことを示すと解釈する。) 11.10 バッファーローカル変数 ============================ グローバルおよびローカルな変数バインディングは、いずれかの形式をほとんど のプログラミング言語で見つけることができます。しかしEmacsは1つのバッファ ーだけに適用される“バッファーローカル(buffer-local)”なバインディング用に 、普通には存在しない類の変数バインディングもサポートしています。ある変数 にたいして異なるバッファーごとに別の値をもつのは、カスタマイズでの重要な 手法です(変数は端末ごとにローカルなバインディングをもつこともできる。 *note Multiple Terminals::を参照)。 11.10.1 バッファーローカル変数の概要 ------------------------------------ バッファーローカル変数は特定のバッファーに関連づけられた、バッファーロー カルなバインディングをもちます。このバインディングはそのバッファーがカレ ントのときに効果をもち、カレントでないときには効果がありません。バッファ ーローカルなバインディングが効力をもつときにその変数をセットすると、その バインディングは新しい値をもちますが他のバインディングは変更されません。 これはバッファーローカルなバインディングを作成したバッファーだけで変更が 見えることを意味します。 その変数にたいする特定のバッファーに関連しない通常のバインディングは 、“デフォルトバインディング(default binding)”と呼ばれます。これはほとん どの場合はグローバルバインディングです。 変数はあるバッファーではバッファーローカルなバインディングをもつこと ができ、他のバッファーではもたないことができます。デフォルトバインディン グは、その変数にたいして自身のバインディングをもたないすべてのバッファー で共有されます(これには新たに作成されたバッファーが含まれる)。ある変数に たいして、その変数のバッファーローカルなバインディングをもたないバッファ ーでその変数をセットすると、それによりデフォルトバインディングがセットさ れるので、デフォルトバインディングを参照するすべてのバッファーで新しい値 を見ることになります。 バッファーローカルなバインディングのもっとも一般的な使用は、メジャー モードがコマンドの動作を制御するために変数を変更する場合です。たとえば CモードやLispモードは、空行だけがパラグラフの区切りになるように変数 ‘paragraph-start’をセットします。これらのモードは、CモードやLispモードに なるようなバッファー内でこの変数をバッファーローカルにすることでこれを行 って、その後そのモードにたいする新しい値をセットします。*note Major Modes::を参照してください。 バッファーローカルなバインディングを作成する通常の方法は、 ‘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するときバッファーローカルな値になります。*note (emacs)File Variables::を参照してください。 バッファーローカル変数を端末ローカル(terminal-local)にすることはでき ません(*note Multiple Terminals::を参照)。 11.10.2 バッファーローカルなバインディングの作成と削除 ------------------------------------------------------ -- Command: make-local-variable variable この関数はカレントバッファー内で、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’に 解るのはバインディングが作成される変数だけである。 変数が端末ローカル(*note Multiple Terminals::を参照)なら、この関数 はエラーをシグナルする。そのような変数はバッファーローカルなバイン ディングをもつことができない。 *警告:* フック変数にたいして‘make-local-variable’を使用しないこと。 フック変数は‘add-hook’か‘remove-hook’のLOCAL引数を使用すると、必要 に応じて自動でバッファーローカルになる。 -- Macro: setq-local variable value このマクロはカレントバッファー内でVARIABLEにたいするバッファーロー カルなバインディングを作成して、それにバッファーローカルな値VALUEを 与える。このマクロは‘make-local-variable’に続けて‘setq’を呼び出すの と同じ。VARIABLEはクォートされていないシンボル。 -- Command: make-variable-buffer-local variable このコマンドはVARIABLE(シンボル)が自動的にバッファーローカルになる ようにマークするので、それ以降にその変数へのセットを試みると、その 時点でカレントのバッファーにローカルになる。しばしば混乱を招く ‘make-local-variable’とは異なり、これが取り消されることはなく、すべ てのバッファー内での変数の挙動に影響する。 この機能特有の欠点は、(‘let’やその他のバインディング構文による)変数 のバインディングが、その変数にたいするバッファーローカルなバインデ ィングを作成しないことである。(‘set’や‘setq’による)変数のセットだけ は、その変数がカレントバッファーで作成された‘let’スタイルのバインデ ィングをもたないので、ローカルなバインディングを作成する。 VARIABLEがデフォルト値をもたない場合、このコマンドの呼び出しは ‘nil’のデフォルト値を与える。VARIABLEがすでにデフォルト値をもつなら 、その値は変更されずに残る。それ以降にVARIABLEにたいして ‘makunbound’を呼び出すと、バッファーローカル値をvoidにして、デフォ ルト値は影響を受けずに残る。 ▼リターン値はVARIABLE。 *警告:* ユーザーオプション変数では、ユーザーは異なるバッファーにた いして異なるカスタマイズを望む_かもしれない_ので、 ‘make-variable-buffer-local’を使うべきだと決め込むべきではない。ユ ーザーは望むなら任意の変数をローカルにできる。その選択の余地を残す ほうがよい。 ‘make-variable-buffer-local’を使用すべきなのは、複数のバッファーが 同じバインディングを共有しないことが自明な場合である。たとえばバッ ファーごとに個別な値をもつことに依存するLispプログラム内の内部プロ セスにたいして変数が使用されるときは、 ‘make-variable-buffer-local’の使用が最善の解決策になるかもしれない 。 -- Macro: defvar-local variable value &optional docstring このマクロはVARIABLEを初期値VALUEとDOCSTRINGの変数として定義して、 それを自動的にバッファーローカルとマークする。これは‘defvar’の後に つづけて‘make-variable-buffer-local’を呼び出すのと同じ。VARIABLEは クォートされていないシンボル。 -- Function: local-variable-p variable &optional buffer これはVARIABLEがバッファーBUFFER(デフォルトはカレントバッファー)内 でバッファーローカルなら‘t’、それ以外は‘nil’をリターンする。 -- Function: local-variable-if-set-p variable &optional buffer これはVARIABLEがバッファーBUFFER内でバッファーローカル値をもつ、ま たは自動的にバッファーローカルになるなら‘t’、それ以外は‘nil’をリタ ーンする。BUFFERが省略または‘nil’の場合のデフォルトはカレントバッフ ァー。 -- Function: buffer-local-value variable buffer この関数はバッファーBUFFER内の、VARIABLE(シンボル)のバッファーロー カルなバインディングをリターンする。VARIABLEがバッファーBUFFER内で バッファーローカルなバインディングをもたなければ、かわりに VARIABLEのデフォルト値(*note Default Value::を参照)をリターンする。 -- Function: buffer-local-variables &optional buffer この関数はバッファー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に新たな値を格納しても、その変数のバッ ファーローカル値は_変化しない_ことに注意。 -- Command: kill-local-variable variable この関数はカレントバッファー内のVARIABLE(シンボル)にたいするバッフ ァーローカルなバインディング(もしあれば)を削除する。その結果として 、このバッファー内でVARIABLEのデフォルトバインディングが可視になる 。これは通常はVARIABLEの値を変更する。デフォルト値は削除されたバッ ファーローカル値とは異なるのが普通だからである。 セットしたとき自動的にバッファーローカルになる変数のバッファーロー カルなバインディングをkillすると、これによりカレントバッファー内で デフォルト値が可視になる。しかし変数を再度セットすると、その変数に たいするバッファーローカルなバインディングが再作成される。 ‘kill-local-variable’はVARIABLEをreturnします。 この関数はコマンドである。なぜならバッファーローカル変数のインタラ クティブな作成が有用な場合があるように、あるバッファーローカル変数 のインタラクティブなkillが有用な場合があるからである。 -- Function: kill-all-local-variables この関数はpermanent(永続的)とマークされた変数と ‘permanent-local-hook’プロパティーに非‘nil’をもつローカルフック関数 (*note Setting Hooks::を参照)を除き、カレントバッファーのすべてのバ ッファーローカルなバインディングを解消する。結果として、そのバッフ ァーのほとんどの変数がデフォルト値を参照するようになる。 この関数はそのバッファーに関連する他の特定の情報もリセットする。こ れはローカルキーマップを‘nil’、構文テーブルを ‘(standard-syntax-table)’の値、caseテーブルを ‘(standard-case-table)’、abbrevテーブルを ‘fundamental-mode-abbrev-table’の値にセットする。 この関数が1番最初に行うのはノーマルフック ‘change-major-mode-hook’(以下参照)の実行である。 すべてのメジャーモードコマンドは、Fundamentalモードにスイッチする効 果をもち、以前のメジャーモードのほとんどの効果を消去する、この関数 を呼び出すことによって開始されます。この関数が処理を行うのを確実に するために、メジャーモードがセットする変数はpermanentとマークすべき ではない。 ‘kill-all-local-variables’ returns ‘nil’. -- Variable: change-major-mode-hook 関数‘kill-all-local-variables’は、何か他のことを行う前にまずこのノ ーマルフックを実行する。この関数はメジャーモードにたいして、ユーザ ーが他のメジャーモードにスイッチした場合に行われる何か特別なことを 準備する方法を与える。この関数はユーザーがメジャーモードを変更した 場合に忘れられるべき、バッファー固有のマイナーモードにたいしても有 用。 最善の結果を得るために、この変数をバッファーローカルにすれば、処理 が終了したときに消えるので、以降のメジャーモードに干渉しなくなる。 *note Hooks::を参照のこと。 変数名(シンボル)が非‘nil’の‘permanent-local’プロパティーをもつなら、 そのバッファーローカル変数は“permanent(永続的)”です。そのような変数は ‘kill-all-local-variables’の影響を受けず、したがってメジャーモードの変更 によりそれらのローカルバインディングは作成されません。permanentなローカ ル変数はファイルの内容を編集する方法ではなく、どこから読み込んだファイル か、あるいはどのように保存するかといったことに関連するデータに適していま す。 11.10.3 バッファーローカル変数のデフォルト値 -------------------------------------------- バッファーローカルなバインディングをもつ変数のグローバル値も“デフォルト 値(default)”値と呼ばれます。なぜならその変数にたいしてカレントバッファー や選択されたフレームもバインディングをもたなければ、その値が常に効果をも つからです。 関数‘default-value’と‘setq-default’は、カレントバッファーがバッファー ローカルなバインディングをもつかどうかに関わらず、その変数のデフォルト値 にアクセスまたは変更します。たとえばほとんどのバッファーにたいして、 ‘paragraph-start’のデフォルトのセッティングを変更するために、 ‘setq-default’を使用できます。そしてこの変数にたいするバッファーローカル な値をもつCモードやLispモードにいるときでさえ、これは機能します。 スペシャルフォーム‘defvar’と‘defconst’もバッファーローカルな値ではな く、(もし変数にセットする場合は)デフォルト値をセットします。 -- Function: default-value symbol この関数はSYMBOLのデフォルト値をリターンする。これはこの変数にたい して独自の値をもたないバッファーやフレームから参照される値である。 SYMBOLがバッファーローカルでなければ、これは‘symbol-value’(*note Accessing Variables::を参照)と同じ。 -- Function: default-boundp symbol 関数‘default-boundp’はSYMBOLのデフォルト値がvoidでないか報告する。 ‘(default-boundp 'foo)’が‘nil’をリターンした場合には‘(default-value 'foo)’はエラーになる。 ‘default-boundp’は‘default-value’、‘boundp’は‘symbol-value’にたいす る述語である。 -- Special Form: setq-default [symbol form]... このスペシャルフォームは各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 -- Function: set-default symbol value この関数は‘setq-default’と似ているが、SYMBOLは通常の引数として評価 される。 (set-default (car '(a b c)) 23) ⇒ 23 (default-value 'a) ⇒ 23 11.11 ファイルローカル変数 ========================== ファイルにローカル変数の値を指定できます。そのファイルをvisitしているバ ッファー内で、これらの変数にたいしてバッファーローカルなバインディングを 作成するために、Emacsはこれらを使用します。ファイルローカル変数の基本的 な情報については、*note Local Variables in Files: (emacs)File Variables.を参照してください。このセクションではファイルローカル変数が処 理される方法に影響する関数と変数を説明します。 ファイルローカル変数が勝手に関数や、後で呼び出されるLisp式を指定でき たら、ファイルのvisitによってEmacsが乗っ取られてしまうかもしれません。 Emacsは既知のファイルローカル変数だけにたいして、指定された値が安全だと 自動的にセットすることにより、この危険から保護します。これ以外のファイル ローカル変数は、ユーザーが同意した場合のみセットされます。 追加の安全策としてEmacsがファイルローカル変数を読み込むとき、一時的に ‘read-circle’を‘nil’にバインドします(*note Input Functions::を参照)。こ れは循環認識と共有されたLisp構造からLispリーダーを保護します(*note Circular Objects::を参照)。 -- User Option: enable-local-variables この変数はファイルローカル変数を処理するかどうかを制御する。以下の 値が利用できる: ‘t’(デフォルト) 安全な変数をセット、安全でない変数は問い合わせる(1回)。 ‘:safe’ 安全な変数だけをセット、問い合わせはしない。 ‘:all’ 問い合わせをせずに、すべての変数をセット。 ‘nil’ 変数をセットしない。 その他 すべての変数にたいして問い合わせる(1回)。 -- Variable: inhibit-local-variables-regexps これは正規表現のリストである。ファイルがこのリストの要素にマッチす る名前をもつなら、すべてのファイルローカル変数のフォームはスキャン されない。どんなときにこれを使いたいかの例は、*note Auto Major Mode::を参照のこと。 -- Function: hack-local-variables &optional mode-only この関数はカレントバッファーの内容により指定された任意のローカル変 数にたいしてパースを行い、適切にバインドと評価を行う。変数 ‘enable-local-variables’はここでも効果をもつ。しかしこの関数は ‘-*-’行の、‘mode:’ローカル変数を探さない。‘set-auto-mode’はこれを行 って‘enable-local-variables’も考慮する(*note Auto Major Mode::を参 照)。 この関数は‘file-local-variables-alist’内に格納されたalistを調べて、 各ローカル変数を順に適用することにより機能する。この関数は変数に適 用する前(か後)に、‘before-hack-local-variables-hook’(か ‘hack-local-variables-hook’)を呼び出す。alistが非‘nil’の場合のみ、 事前のフック(before-hook)を呼び出し、その他のフックは常に呼び出す。 この関数はそのバッファーがすでにもつメジャーモードと同じメジャーモ ードが指定された場合は‘mode’要素を無視する。 オプションの引数MODE-ONLYが非‘nil’なら、メジャーモードを指定するシ ンボルをリターンするのがこの関数が行うのすべてであり、‘-*-’行かロー カル変数リストがメジャーモードを指定していればそのモード、それ以外 は‘nil’をリターンする。この関数はモードや他のファイルローカル変数を セットしない。 -- Variable: file-local-variables-alist このバッファーローカルな変数は、ファイルローカル変数のセッティング のalistを保持する。alistの各要素は‘(VAR . VALUE)’という形式で、 VARはローカル変数のシンボル、VALUEはその値である。Emacsがファイルを visitするとき、最初にすべてのファイルローカル変数をこのalistに収集 して、その後で変数に1つずつ関数‘hack-local-variables’を適用する。 -- Variable: before-hack-local-variables-hook Emacsは‘file-local-variables-alist’に格納されたファイルローカル変数 を適用する直前にこのフックを呼び出す。 -- Variable: hack-local-variables-hook Emacsは‘file-local-variables-alist’に格納されたファイルローカル変数 を適用し終えた直後にこのフックを呼び出す。 ある変数にたいして‘safe-local-variable’プロパティーによって安全な値を 指定できます。このプロパティーは引数を1つとる関数です。与えられた値にた いして、その関数が非‘nil’をリターンしたらその値は安全です。一般的に目に するファイル変数の多くは、‘safe-local-variable’プロパティーをもちます。 これらのファイル変数には‘fill-column’、‘fill-prefix’、 ‘indent-tabs-mode’が含まれます。ブーリーン値の変数にたいしては、プロパテ ィーの値に‘booleanp’を使用します。 ‘defcustom’を使用してユーザーオプションを定義する際、‘defcustom’に引 数‘:safe FUNCTION’を追加することにより、‘safe-local-variable’プロパティ ーをセットできます(*note Variable Definitions::を参照)。 -- User Option: safe-local-variable-values この変数はある変数の値が安全であることをマークする、別の方法を提供 する。これはコンスセル‘(VAR . VAL)’のリストでありVARは変数名、VALは その変数にたいして安全な値である。 Emacsが一連のファイルローカル変数にしたがうかどうかユーザーに尋ねる とき、ユーザーはそれらの変数が安全だとマークすることができる。安全 とマークすると‘safe-local-variable-values’にこれらの variable/valueペアーが追加されて、ユーザーのカスタムファイルに保存 する。 -- Function: safe-local-variable-p sym val この関数は上記の条件に基づき、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’も危険だと判断されます。 -- Function: risky-local-variable-p sym この関数はSYMが上記の条件にもとづき危険な変数なら非‘nil’をリターン する。 -- Variable: ignored-local-variables この変数はファイルによりローカル値を与えらるべきではない変数のリス トを保持する。これらの変数に指定された任意の値は、完全に無視される 。 “変数”‘Eval:’も抜け道になる可能性があるので、Emacsは通常はそれを処理 する前に確認を求めます。 -- User Option: enable-local-eval この変数は‘-*-’の行中、またはvisitされるファイル内のローカル変数リ ストにたいする、‘Eval:’の処理を制御する。値‘t’は無条件に実行し、 ‘nil’はそれらを無視することを意味します。それ以外なら各ファイルにた いして何を行うか、ユーザーに確認を求めることを意味する。デフォルト 値は‘maybe’。 -- User Option: safe-local-eval-forms この変数はファイルローカル変数リスト内で‘Eval:’“変数”が見つかった際 に評価しても安全な式のリストを保持する。 式が関数呼び出しであり、その関数が‘safe-local-eval-function’プロパテ ィーをもつなら、その式の評価が安全かどうかはそのプロパティー値が決定しま す。プロパティー値はその式をテストするための述語(predicate)、そのような 述語のリスト(成功した述語があれば安全)、または‘t’(引数が定数である限り常 に安全)を指定できます。 テキストプロパティーには、それらの値に関数呼び出しを含めることができ るので抜け道になる可能性があります。したがってEmacsはファイルローカル変 数にたいして指定された文字列値から、テキストプロパティーを取り除きます。 11.12 ディレクトリーローカル変数 ================================ ディレクトリーは、そのディレクトリー内のすべてのファイルに共通なローカル 変数値を指定することができます。Emacsはそのディレクトリー内の任意のファ イルをvisitしているバッファー内で、それらの変数にたいするバッファーロー カルなバインディングを作成するためにこれを使用します。これはそのディレク トリー内のファイルが何らかの“プロジェクト”に属していて、同じローカル変数 を共有するときなどに有用です。 ディレクトリーローカル変数を指定するために2つの異なる方法があります: 1つは特別なファイルにそれを記述する方法、もう1つはそのディレクトリーに “プロジェクトクラス(project class)”を定義する方法です。 -- Constant: dir-locals-file この定数はEmacsがディレクトリーローカル変数が見つけることができると 期待するファイルの名前である。ファイル名は‘.dir-locals.el’(1)。ディ レクトリー内でその名前をもつファイルにより、Emacsはディレクトリー内 の任意のファイル、または任意のサブディレクトリー(オプションでサブデ ィレクトリーを除外できる。以下参照)にセッティングを適用する。独自に ‘.dir-locals.el’をもつサブディレクトリーがあるなら、Emacsはサブディ レクトリーで見つかった1番深いファイルのディレクトリーからディレクト リーツリーを上方に移動しつつ、1番深いファイルのセッティングを使用す る。このファイルはローカル変数をフォーマットされたリストとして指定 する。詳細は*note Per-directory Local Variables: (emacs)Directory Variables.を参照のこと。 -- Function: hack-dir-local-variables この関数は‘.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’を呼び出すことにより機能する。 -- Function: hack-dir-local-variables-non-file-buffer この関数はディレクトリーローカル変数を探して、即座にそれらをカレン トバッファーに適用する。これはDiredバッファーのような、非ファイルバ ッファーをディレクトリーローカル変数のセッティングにしたがわせるた めに、モードコマンド呼び出しの中から呼び出されることを意図したもの である。非ファイルバッファーにたいしては、Emacsは ‘default-directory’とその親ディレクトリーの中から、ディレクトリーロ ーカル変数を探す。 -- Function: dir-locals-set-class-variables class variables この関数は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つを指定する。 -- Function: dir-locals-set-directory-class directory class &optional mtime この関数は‘directory’とサブディレクトリー内のすべてのファイルに CLASSを割り当てる。その後、CLASSにたいして指定されたすべての変数セ ッティングは、DIRECTORYとその子ディレクトリー内でvisitされたすべて のファイルに適用される。CLASSは事前に ‘dir-locals-set-class-variables’で定義されていなければならない。 Emacsが‘.dir-locals.el’ファイルからディレクトリー変数をロードする際 、内部的にこの関数を使用する。その場合、オプションの引数MTIMEはファ イルの修正日時(modification time。‘file-attributes’によりリターンさ れる)を保持する。Emacsは記憶されたローカル変数がまだ有効化チェック するために、この日時を使用する。ファイルを介さず直接クラスを割り当 てる場合、この引数は‘nil’になる。 -- Variable: dir-locals-class-alist このalistはクラスシンボル(class symbol)とそれに関連づけられる変数の セッティングを保持する。これは‘dir-locals-set-class-variables’によ り更新される。 -- Variable: dir-locals-directory-cache このalistはディレクトリー名、それらに割り当てられたクラス名、および このエントリーに関連するディレクトリーローカル変数ファイルの修正日 時を保持する。関数‘dir-locals-set-directory-class’はこのlistを更新 する。 -- Variable: enable-dir-local-variables ‘nil’ならディレクトリーローカル変数は無視される。この変数はファイル ローカル変数(*note File Local Variables::を参照)にはしたがうが、デ ィレクトリーローカル変数は無視したいモードにたいして有用かもしれな い。 ---------- Footnotes ---------- (1) MS-DOS版のEmacsはDOSファイルシステムの制限により、かわりに ‘_dir-locals.el’という名前を使用します。 11.13 変数のエイリアス ====================== シノニムとして2つの変数を作成できれば便利なときがあります。2つの変数は常 に同じ値をもち、どちらか一方を変更すると、もう一方も変更されます。変数の 名前を変更 — 古い名前はよく考慮して選択されたものではなかったとか、変数 の意味が部分的に変更された等の理由で — するとき、互換性のために新しい名 前の_エイリアス(alias)_として古い名前を維持できれば便利なときがあるかも しれません。‘defvaralias’によってこれを行うことができます。 -- Function: defvaralias new-alias base-variable &optional docstring この関数はシンボル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)してい ると宣言して。それが将来のある時点で削除されるかもしれないことを宣言しま す。 -- Function: make-obsolete-variable obsolete-name current-name when &optional access-type この関数はバイトコンパイラーに変数OBSOLETE-NAMEが陳腐化していると警 告させる。CURRENT-NAMEがシンボルなら、それはこの変数の新たな名前で ある。警告メッセージはその後、OBSOLETE-NAMEのかわりにCURRENT-NAMEを 使用するよう告げるようになる。CURRENT-NAMEが文字列なら、それはメッ セージであり、置き換えられる変数はない。WHENはその変数が最初に陳腐 化するのがいつかを示す文字列(通常はバージョン番号文字列)。 オプションの引数ACCESS-TYPEが非‘nil’なら、それは陳腐化の警告を引き 起こすアクセスの種類を指定すること。‘get’か‘set’を指定できる。 2つの変数シノニムを作成してマクロ‘define-obsolete-variable-alias’を使 用することにより、1つが陳腐化していると同時に宣言できます。 -- Macro: define-obsolete-variable-alias obsolete-name current-name &optional when docstring このマクロは変数OBSOLETE-NAMEが陳腐化しているとマークして、それを変 数CURRENT-NAMEにたいするエイリアスにする。これは以下と等価である: (defvaralias OBSOLETE-NAME CURRENT-NAME DOCSTRING) (make-obsolete-variable OBSOLETE-NAME CURRENT-NAME WHEN) -- Function: indirect-variable variable この関数は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 11.14 値を制限された変数 ======================== 通常のLisp変数には、有効なLispオブジェクトである任意の値を割り当てること ができます。しかしLispではなくCで定義されたLisp変数もあります。これらの 変数のほとんどは、‘DEFVAR_LISP’を使用してCコードで定義されています。 Lispで定義された変数と同様、これらは任意の値をとることができます。しかし いくつかの変数は‘DEFVAR_INT’や‘DEFVAR_BOOL’を使用して定義されています。 C実装の概要的な議論は、*note Writing Emacs Primitives: Defining Lisp variables in C.、特に‘syms_of_FILENAME’型の関数の説明を参照してください 。 ‘DEFVAR_BOOL’型の変数は、値に‘nil’か‘t’しかとることができません。他の 値の割り当てを試みると‘t’がセットされます: (let ((display-hourglass 5)) display-hourglass) ⇒ t -- Variable: byte-boolean-vars この変数は‘DEFVAR_BOOL’型のすべての変数のリストを保持する。 ‘DEFVAR_INT’型の変数は、整数値だけをとることができます。他の値の割り 当てを試みると結果はエラーになります: (setq undo-limit 1000.0) error→ Wrong type argument: integerp, 1000.0 11.15 ジェネリック変数 ====================== “ジェネリック変数(generalized variable: 汎変数)”または“placeフォーム (place form)”は、値が格納されるLispメモリー内の多くの場所のうちの1つです 。1番シンプルなplaceフォームは通常のLisp変数です。しかしリストのCARと CDR、配列の要素、シンボルのプロパティー、その他多くのロケーション (location)もLisp値が格納される場所です。 ジェネリック変数は、C言語のlvalues(左辺値)と類似しています。C言語の lvalueでは‘x = a[i]’で配列から要素を取得し、同じ表記を使用して‘a[i] = x’で要素を格納します。Cでは‘a[i]’のような特定のフォームがlvalueになれる ように、Lispでジェネリック変数になることができる一連のフォームが存在しま す。 11.15.1 ‘setf’マクロ -------------------- ‘setf’マクロはジェネリック変数を操作する、もっとも基本的な方法です。 ‘setf’フォームは‘setq’と似ていますが、シンボルだけでなく左辺の任意の placeフォームを受け入れます。たとえば‘(setf (car a) b)’は‘a’のcarを‘b’に セットして、‘(setcar a b)’と同じ操作を行いますが、すべてのplace型へのセ ットとアクセスを行うために2つの別個の関数を覚える必要はありません。 -- Macro: setf [place form]... このマクロはFORMを評価して、それをPLACEに格納する。PLACEは有効なジ ェネリック変数フォームでなければならない。複数のPLACE/FORMペアーが ある場合、割り当ては‘setq’の場合と同様。‘setf’は最後のFORMの値をリ ターンする。 以下のLispフォームはジェネリック変数として機能するので、‘setf’の PLACE引数にすることができます: • 変数を命名するシンボル。言い換えると‘(setf x y)’は完全に‘(setq x y)’と等しく、厳密に言うと‘setq’自体は‘setf’が存在するので冗長である 。これは純粋にスタイルと歴史的な理由によるが、多くのプログラマーは 依然として単純な変数へのセットに‘setq’を好む。実際にはマクロ‘(setf x y)’は‘(setq x y)’に展開されるので、コンパイルされたコードでこれを 使用することにパフォーマンス的な不利はない。 • 以下の標準的なLisp関数の呼び出し: aref cddr symbol-function car elt symbol-plist caar get symbol-value cadr gethash cdr nth cdar nthcdr • 以下のEmacs特有な関数の呼び出し: alist-get process-get frame-parameter process-sentinel terminal-parameter window-buffer keymap-parent window-display-table match-data window-dedicated-p overlay-get window-hscroll overlay-start window-parameter overlay-end window-point process-buffer window-start process-filter default-value どのように処理すれば良いか未知なPLACEフォームを渡すと、‘setf’はエラーを シグナルします。 ‘nthcdr’の場合、関数のリスト引数はそれ自体が有効なPLACEフォームでなけ ればならないことに注意してください。たとえば‘(setf (nthcdr 0 foo) 7)’は 、‘foo’自体に7をセットするでしょう。 マクロ‘push’(*note List Variables::を参照)と‘pop’(*note List Elements::を参照)は、リストだけでなくジェネリック変数を操作できます。 ‘(pop PLACE)’はPLACE内に格納されたリストの最初の要素を削除してリターンし ます。これは‘(prog1 (car PLACE) (setf PLACE (cdr PLACE)))’と似ていますが 、すべてのサブフォームを一度だけ評価します。‘(push X PLACE)’はPLACE内に 格納されたリストの1番前にXを挿入します。これは‘(setf PLACE (cons X PLACE))’と似ていますが、サブフォームの評価が異なります。‘nthcdr’ placeへ の‘push’と‘pop’は、リスト内の任意の位置での挿入ち削除に使用できることに 注意してください。 ‘cl-lib’ライブラリーでは追加の‘setf’ placeを含む、ジェネリック変数に たいするさまざまな拡張が定義されています。*note (cl)Generalized Variables::を参照してください。 11.15.2 新たな‘setf’フォーム ---------------------------- このセクションでは、‘setf’が操作できる新たなフォームの定義方法を説明しま す。 -- Macro: gv-define-simple-setter name setter &optional fix-return このマクロは単純なケースで‘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) これで正しい結果がリターンされることが保証される。 -- Macro: gv-define-setter name arglist &rest body このマクロは上述のフォームより複雑な‘setf’展開を可能にする。たとえ ば呼び出すべきシンプルなsetter関数が存在しないときや、もしそれが存 在してもplaceフォームとは異なる引数を要求するなら、このフォームを使 う必要があるかもしれない。 このマクロは最初に‘setf’引数フォーム‘(VALUE ARGS...)’をARGLISTにバ インドして、その後BODYを実行することによって、フォーム‘(setf (NAME ARGS...) VALUE)’を展開する。BODYは割り当てを行うLispフォームをリタ ーンして、最終的にはセットされた値をリターンすること。以下はこのマ クロの使用例である: (gv-define-setter caar (val x) `(setcar (car ,x) ,val)) 展開をさらに制御するならマクロ‘gv-define-expander’を参照してください 。マクロ‘gv-letplace’は‘setf’のような処理を行うマクロを定義するのに有用 です。詳細は‘gv.el’のソースファイルを参照してください。 Common Lispに関する注意: Common Lispは関数としての‘setf’、すなわち 関数名がシンボルではなくリスト‘(setf NAME)’であるような‘setf’関数の 挙動を指定するために別の方法を定義する。たとえば‘(defun (setf foo) ...)’は、‘setf’が‘foo’に適用されるときに使用される関数を定義する。 Emacsはこれをサポートしない。適切な展開が定義されていないフォームに ‘setf’を使用するとコンパイル時エラーとなる。Common Lispでは後で関数 ‘(setf FUNC)’が定義されるのでエラーにならない。 12 関数 ******* Lispプログラムは主にLisp関数で構成されます。このチャプターはで関数とは何 か、引数を受け取る方法、そして関数を定義する方法を説明します。 12.1 関数とは? ============== 一般的な意味において関数とは、“引数(arguments)”と呼ばれる与えられた入力 値の計算を担うルールです。計算の結果はその関数の“値(value)”、または“リタ ーン値(return value)”と呼ばれます。計算では変数の値やデータ構造の内容を 変更する等の副作用をもつこともできます。 ほとんどのコンピューター言語では、関数はそれぞれ名前をもちます。しか しLispでは厳密な意味において関数は名前をもちません。関数はオブジェクトで あり、関数の名前の役割を果たすシンボルに関連づけることができますが(たと えば‘car’)、それは_オプション_です。*note Function Names::を参照してくだ さい。関数が名前を与えられたとき、通常はそのシンボルを“関数”として参照し ます(たとえば関数‘car’のように参照する)。このマニュアルでは、関数名と関 数オブジェクト自身との間の区別は通常は重要ではありませんが、それが意味を もつような場合には注記します。 “スペシャルフォーム(special form)”、“マクロ(macro)”と呼ばれる関数 likeなオブジェクトがいくつかあり、それらも引数を受け取って計算を行います 。しかし以下で説明するようにEmacs Lispではこれらは関数とはみなされません 。 以下は関数と関数likeなオブジェクトにたいする重要な条件です: “lambda expression” Lispで記述された関数(厳密には関数オブジェクト)。これらについては以 降のセクションで説明します。 *note Lambda Expressions::を参照のこと 。 “primitive” Lispから呼び出すことができるが実際にはCで記述されている。プリミティ ブは“ビルトイン関数(built-in functions)”とか“サブルーチン(subr)”の ようにも呼ばれる。それらの例には関数likeな‘car’や‘append’が含まれる 。加えてすべてのスペシャルフォーム(以下参照)もプリミティブとみなさ れる。 関数はLispの基礎となる部分(たとえば‘car’)であり、オペレーティングシ ステムのサービスにたいして低レベルのインターフェースを与え、高速に 実行される必要があるために、通常はプリミティブとして実装されている 。Lispで定義された関数と異なり、プリミティブの修正や追加には、Cソー スの変更とEmacsのリコンパイルが必要となる。*note Writing Emacs Primitives::を参照のこと。 “special form” プリミティブは関数と似ているが、すべての引数が通常の方法で評価され ない。いくつかの引数だけが評価されるかもしれず、通常ではない順序で 評価されるか、複数回評価されるかもしれない。プリミティブの例には ‘if’、‘and’、‘while’が含まれる。*note Special Forms::を参照のこと。 “macro” あるLisp式をオリジナルの式のかわりに評価される別の式に変換する、関 数とは別のLispで定義された構文。マクロはスペシャルフォームが行う一 連のことを、Lispプログラマーが行うのを可能にする。*note Macros::を 参照のこと。 “command” プリミティブ‘command-execute’を通じて呼び出すことができるオブジェク トで、通常はそのコマンドに“バインド”されたキーシーケンスをユーザー がタイプすることにより呼び出される。*note Interactive Call::を参照 のこと。コマンドは通常は関数である。その関数がLispで記述されていれ ば、関数の定義内の‘interactive’フォームによってコマンドとなる(*note Defining Commands::を参照)。関数であるコマンドは他の関数と同様、 Lisp式から呼び出すこともできる。 キーボードマクロ(文字列かベクター)は関数ではないが、これらもコマン ドである。*note Keyboard Macros::を参照のこと。シンボルの関数セルに コマンドが含まれてれば、わたしたちはそのシンボルをコマンドと言う (*note Symbol Components::を参照)。そのような“名前つきコマンド (named command)”は‘M-x’で呼び出すことができる。 “closure” ラムダ式とよく似た関数オブジェクトだが、クロージャーはレキシカル変 数バインディングの環境にも囲われている。*note Closures::を参照のこ と。 “byte-code function” バイトコンパイラーによりコンパイル済みの関数。*note Byte-Code Type::を参照のこと。 “autoload object” 実際の関数のプレースホルダー。autoloadオブジェクトが呼び出されると 、Emacsは実際の関数の定義を含むファイルをロードした後に実際の関数を 呼び出す。*note Autoload::を参照のこと。 関数‘functionp’を使用して、あるオブジェクトが関数かどうかテストできま す: -- Function: functionp object この関数はOBJECTが任意の種類の関数(‘funcall’に渡すことができる)なら ‘t’をリターンする。‘functionp’は関数を名づけるシンボルにたいしては ‘t’、スペシャルフォームにたいしては‘nil’をリターンすることに注意。 ‘functionp’と異なり、以下の3つの関数はシンボルをそれの関数定義としては _扱いません_。 -- Function: subrp object この関数はOBJECTがビルトイン関数(たとえばLispプリミティブ)なら‘t’を リターンする。 (subrp 'message) ; ‘message’はシンボルであり、 ⇒ nil ; subrオブジェクトではない (subrp (symbol-function 'message)) ⇒ t -- Function: byte-code-function-p object この関数はOBJECTがバイトコード関数なら‘t’をリターンする。たとえば: (byte-code-function-p (symbol-function 'next-line)) ⇒ t -- Function: subr-arity subr この関数はプリミティブSUBRの引数リストに関する情報を提供する。リタ ーン値は‘(MIN . MAX)’というペアである。MINは引数の最小数、MAXは最大 数、または引数‘&rest’を伴う関数ではシンボル‘many’、SUBRがスペシャル フォームならシンボル‘unevalled’となる。 12.2 ラムダ式 ============= ラムダ式(lambda expression)はLispで記述された関数オブジェクトです。以下 は例です: (lambda (x) "Xの双曲線コサインをreturnする" (* 0.5 (+ (exp x) (exp (- x))))) Emacs Lispではこのようなリストは、関数オブジェクトに評価される有効な式で す。 ラムダ式自身は名前をもたない“無名関数(anonymous function)”です。ラム ダ式をこの方法で使用できますが(*note Anonymous Functions::を参照)、“名前 付き関数(named functions)”を作成するためにシンボルに関連付けられる方が一 般的です(*note Function Names::を参照)。これらの詳細に触れる前に以下のサ ブセクションではラムダ式の構成要素と、それらが行うことについて説明します 。 12.2.1 ラムダ式の構成要素 ------------------------- ラムダ式は以下のようなリストです: (lambda (ARG-VARIABLES...) [DOCUMENTATION-STRING] [INTERACTIVE-DECLARATION] BODY-FORMS...) ラムダ式の1番目の要素は常にシンボル‘lambda’です。これはそのリストが関 数を表すことを示します。‘lambda’で関数定義を開始する理由は、別の目的での 使用が意図された他のリストが、意図せずに関数として評価されないようにする ためです。 2番目の要素はシンボル — 引数変数名のリストです。これは“ラムダリスト (lambda list)”と呼ばれます。Lisp関数が呼び出されたとき、引数値はラムダリ スト内の変数と対応付けされます。ラムダリストには、与えられた値にたいする ローカルバインディングが付与されます。*note Local Variables::を参照して ください。 ドキュメント文字列(documentation string)はEmacs Lispのヘルプ機能にた いして、その関数を説明する関数定義に配されたLispの文字列オブジェクトです 。*note Function Documentation::を参照してください。 インタラクティブ宣言(interactive declaration)は、‘(interactive CODE-STRING)’という形式のリストです。これはこの関数が対話的に使用された 場合に引数を提供する方法を宣言します。この宣言をもつ関数は、“コマンド (command)”と呼ばれます。コマンドは‘M-x’を使用したり、キーにバインドして 呼び出すことができます。この方法で呼び出されることを意図しない関数は、イ ンタラクティブ宣言を持つべきではありません。インタラクティブ定義を記述す る方法は、*note Defining Commands::を参照してください。 残りの要素はその関数の“body(本体)” — その関数が処理を行うためのLispコ ード(Lispプログラマーは“評価されるLispフォームのリスト”と言うだろう)です 。この関数からリターンされる値は、bodyの最後の要素によりリターンされる値 です。 12.2.2 単純なラムダ式の例 ------------------------- 以下の例を考えてみてください: (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’を使用するほうが明解 です(*note Local Variables::を参照)。ラムダ式は主に他の関数の引数として 渡される無名関数(*note Anonymous Functions::を参照)として、あるいは名前 つき関数(*note Function Names::を参照)を生成するためにシンボルの関数定義 に格納するために使用されます。 12.2.3 引数リストのその他機能 ----------------------------- シンプルなサンプル関数‘(lambda (a b c) (+ a b c))’は3つの引数変数を指定 しているので、3つの引数で呼び出されなければなりません。引数を2つしか指定 しなかったり4つ指定した場合は、‘wrong-number-of-arguments’エラーとなりま す。 特定の引数を省略できる関数を記述できると便利なこともあります。たとえ ば関数‘substring’は3つの引数 — 文字列、開始インデックス、終了インデック ス — を受け取りますが、3つ目の引数を省略すると、デフォルトでその文字列の LENGTHとなります。関数‘list’や‘+’が行うように、特定の関数にたいして不定 個の引数を指定できると便利なときもあります。 関数が呼び出されるとき省略されるかもしれないオプションの引数を指定す るには、オプションの引数の前にキーワード‘&optional’を含めるだけです。0個 以上の追加引数のリストを指定するには、最後の引数の前にキーワード ‘&rest’を含めます。 したがって引数リストの完全な構文は以下のようになります: (REQUIRED-VARS... [&optional OPTIONAL-VARS...] [&rest REST-VAR]) 角カッコ(square bracket)は‘&optional’と‘&rest’、およびそれらに続く変数が 省略できることを示します。 この関数の呼び出しではREQUIRED-VARSのそれぞれにたいして、実際の引数が 要求されます。0個以上のOPTIONAL-VARSにたいして実際の引数があるかもしれま せんが、ラムダ式が‘&rest’を使用していなければ、その個数を超えて実際の引 数を記述することはできません。‘&rest’が記述されていれば、追加で任意の個 数の実際の引数があるかもしれません。 optionaやrest変数にたいして実際の引数が省略されると、それらのデフォル トは常に‘nil’になります。関数にたいして引数に明示的に‘nil’が使用されたの か、引数が省略されたのかを区別することはできません。しかし関数のbodyが、 ‘nil’を他の有意な値が省略されたと判断することは自由です。‘substring’はこ れを行います。‘substring’の3つ目の引数が‘nil’なら、それは文字列の長さを 使用することを意味します。 Common Lispに関する注意: Common Lispではオプションの引数が省略され たときに使用するデフォルト値を指定できる。Emacs Lispでは、引数が明 示的に渡されたかを調べる‘supplied-p’変数はサポートされない。 例えば引数リストは以下のようになります: (a b &optional c d &rest e) ‘a’と‘b’は最初の2つの実引数となり、これらは必須です。さらに1つまたは2つ の引数が指定された場合、それらは順番に‘c’と‘d’にバインドされます。1つ目 から4つ目の引数の後の引数は、リストにまとめられて‘e’にそのリストがバイン ドされます。2つしか引数が指定されなかったら、‘c’は‘nil’になります。2つか 3つの引数なら、‘d’は‘nil’です。引数が4つ以下なら、‘e’は‘nil’になります。 オプションの引数の後ろに必須の引数を指定する方法はありません — これは 意味を成さないからです。なぜそうなるかは、この例で‘c’がオプションで‘d’が 必須な場合を考えてみてください。実際に3つの引数が与えられたとします。3番 めの引数は何を指定したのでしょうか? この引数はCなのでしょうか、それとも Dに使用されるのでしょうか? 両方の場合が考えられます。同様に‘&rest’引数の 後に、さらに引数(必須またはオプション)をもつことも意味を成しません。 以下に引数リストと、それを正しく呼び出す例をいくつか示します: (funcall (lambda (n) (1+ n)) ; 1つの必須: 1) ; これは正確に1つの引数を要求する ⇒ 2 (funcall (lambda (n &optional n1) ; 1つは必須で、1つはオプション: (if n1 (+ n n1) (1+ n))) ; 1つまたは2つの引数 1 2) ⇒ 3 (funcall (lambda (n &rest ns) ; 1つは必須で、後は残り: (+ n (apply '+ ns))) ; 1つ以上の引数 1 2 3 4 5) ⇒ 15 12.2.4 関数のドキュメント文字列 ------------------------------- ラムダ式はラムダリストの直後に、オプションで“ドキュメント文字列 (documentation string)”をもつことができます。この文字列は、その関数の実 行に影響を与えません。これはコメントの一種ですがLisp機構に内在するシステ ム化されたコメントであり。Emacsのヘルプ機能で使用できます。ドキュメント 文字列にアクセスする方法は、*note Documentation::を参照してください。 たとえその関数があなたのプログラム内だけで呼び出される関数だとしても 、すべての関数にドキュメント文字列を与えるのはよいアイデアです。ドキュメ ント文字列はコメントと似ていますが、コメントより簡単にアクセスできます。 ドキュメント文字列の1行目は、関数自体にもとづくものであるべきです。な ぜなら‘apropos’は、最初の1行目だけを表示するからです。ドキュメント文字列 の1行目は、その関数の目的を要約する1つか2つの完全なセンテンスで構成され るべきです。 ドキュメント文字列の開始は通常、ソースファイル内ではインデントされて いますが、ドキュメント文字列の開始のダブルクォート文字の前にインデントの スペースがあるので、インデントはドキュメント文字列の一部にはなりません。 ドキュメント文字列の残りの行がプログラムソース内で揃うようにインデントす る人がいます。_これは間違いです_。後続の行のインデントは文字列の内部にあ ります。これはソースコード内での見栄えはよくなりますが、ヘルプコマンドで 表示したとき見栄えが悪くなります。 ドキュメント文字列がなぜオプションになるのか不思議に思うかもしれませ ん。なぜならドキュメント文字列の後には必須となる関数の構成要素である bodyが続くからです。文字列を評価するとその文字列自身がリターンされるので 、それがbody内の最後のフォームでない限りなんの効果もありません。したがっ て実際はbodyの1行目とドキュメント文字列で混乱が生じることはありません。 bodyの唯一のフォームが文字列なら、それはリターン値とドキュメントの両方の 役目を果たします。 ドキュメント文字列の最後の行には、実際の関数引数とは異なる呼び出し規 約を指定できます。これは以下のようなテキストを記述します \(fn ARGLIST) そのテキストの後に空行を配置して、テキスト自身は行頭から記述、ドキュメン ト文字列内でこのテキストの後に改行が続かないように記述します(‘\’は Emacsの移動コマンドが混乱するのを避けるために使用する)。この方法で指定さ れた呼び出し規約は、ヘルプメッセージ内で関数の実引数から生成される呼び出 し例と同じ場所に表示されます。 マクロ定義内に記述された引数は、ユーザーがマクロ呼び出しの一部だと考 える方法とは合致しない場合がしばしばあるので、この機能はマクロ定義で特に 有用です。 12.3 関数の命名 =============== シンボルは関数の名前となることができます。これはそのシンボルの“関数セル (function cell”: *note Symbol Components::を参照)が、関数オブジェクト(た とえばラムダ式)を含むときに起こります。するとそのシンボル自身が呼び出し 可能な有効な関数、つまりそのシンボルの関数セルの関数と等価になります。 関数セルの内容はそのシンボルの“関数定義(function definition)”と呼ぶこ ともできます。そのシンボルのかわりにシンボルの関数定義を使う手続きのこと を“シンボル関数インダイレクション(symbol function indirection)”と呼びま す。*note Function Indirection::を参照。与えられたシンボルに関数定義がな ければシンボルの関数セルは“void”と呼ばれ、それを関数として使用することは できません。 実際のところほとんどすべての関数は名前をもち、その名前により参照され ます。ラムダ式を定義することで名前つきのLisp関数を作成、それを関数セル (*note Function Cells::を参照)に置くことができます。しかしより一般的なの は‘defun’スペシャルフォーム(次のセクションで説明)を使う方法です。 *note Defining Functions::を参照してください。 わたしたちが関数に名前を与えるのは、Lisp式内で関数を名前で参照するの が便利だからです。また名前つきの関数は簡単に自分自身を — 再帰的 (recursive)に参照することができます。さらにプリミティブはテキスト的な名 前だけで参照することができます。なぜならプリミティブ関数は入力構文(read syntax)をもたないオブジェクトだからです(*note Primitive Function Type::を 参照)。 関数が一意な名前をもつ必要はありません。与えられた関数オブジェクトは _通常_は1つのシンボルの関数セルだけに存在しますが、これは単に慣習的なも のです。‘fset’を使用すれば関数を複数のシンボルに格納するのは簡単です。そ れらのシンボルはそれぞれ、同じ関数にたいする有効な名前となります。 関数として使用しているシンボルを、変数としても利用できることに注意し てください。シンボルのこれら2つの利用法は独立しており、競合はしません(こ れはSchemaのような他のいくつかのLisp方言には当てはまらない)。 12.4 関数の定義 =============== わたしたちは通常は関数を最初に作成したときに名前を与えます。これは“関数 の定義(defining a function)”と呼ばれ、‘defun’マクロにより行われます。 -- Macro: defun name args [doc] [declare] [interactive] body... ‘defun’は新たなLisp関数を定義する通常の方法である。これは引数リスト ARGS、およびBODYにより与えられるbodyフォームとともに、シンボル NAMEを関数として定義する。NAMEとARGSをクォートする必要はない。 DOCが与えられたら、それはその関数のドキュメント文字列を指定する文字 列であること(*note Function Documentation::を参照)。DECLAREが与えら れたら、それは関数のメタデータを指定する‘declare’フォームであること (*note Declare Form::を参照)。INTERACTIVEが与えられたら、それは関数 が対話的に呼び出される方法を指定する‘interactive’フォームであるこ (*note Interactive Call::を参照)。 ‘defun’のリターン値は定義されていません。 以下にいくつか例を示す: (defun foo () 5) (foo) ⇒ 5 (defun bar (a &optional b &rest c) (list a b c)) (bar 1 2 3 4 5) ⇒ (1 2 (3 4 5)) (bar 1) ⇒ (1 nil nil) (bar) error→ Wrong number of arguments. (defun capitalize-backwards () "Upcase the last letter of the word at point." (interactive) (backward-word 1) (forward-word 1) (backward-char 1) (capitalize-word 1)) 意図せず既存の関数を再定義しないように注意されたい。‘defun’は ‘car’のようなプリミティブ関数でさえ、問い合わせせずに躊躇なく再定義 する。Emacsがこれを妨げることはない。なぜなら関数の再定義は故意に行 われることがあり、そのような意図した再定義を、意図しない再定義と見 分ける方法はがないからである。 -- Function: defalias name definition &optional doc この関数は定義DEFINITION(任意の有効なLisp関数)とともに、シンボル NAMEを関数として定義する。この関数のリターン値は_未定義_。 DOCが非‘nil’なら、それは関数NAMEのドキュメントとなる。それ以外なら DEFINITIONにより提供されるドキュメントが使用される。 内部的には‘defalias’は、通常は定義のセットに‘fset’を使用する。しか しNAMEが‘defalias-fset-function’プロパティーをもつなら、‘fset’を呼 び出すかわりにそれに割り当てられた値を使用する。 ‘defalias’を使う正しい場所は、特定の関数名が正に定義される場所 — 特 にソースファイルがロードされるとき明示的にその名前が出現する場所で ある。これは‘defalias’が‘defun’と同じように、どれが関数を定義するフ ァイルなのか記録するからである(*note Unloading::を参照)。 それとは対象的に他の目的のために関数を操作するプログラムでは、その ような記録を保持しない‘fset’を使用するほうがよいだろう。*note Function Cells::を参照のこと。 ‘defun’や‘defalias’で新たなプリミティブ関数を作成することはできません が、任意の関数定義を変更するのに使用することができ、通常の定義がプリミテ ィブである‘car’や‘x-popup-menu’のような関数でさえ変更することができます 。しかしこれは危険なことです。たとえばLispの完全性を損なうことなく、 ‘car’を再定義するのはほとんど不可能だからです。それほど有名ではない ‘x-popup-menu’のような関数の再定義では、危険は減少しますが、それでも期待 したとおりに機能しないかもしれません。Cコードにそのプリミティブの呼び出 しがあれば、それは直接そのプリミティブのC定義を呼び出すので、シンボル定 義を変更してもそれらに影響はありません。 ‘defsubst’も参照してください。これは‘defun’のように関数を定義して、そ れのインライン展開を処理するようLispコンパイラーに指示します。*note Inline Functions::を参照してください。 かわりにコンパイラーマクロとしてインライン展開されるコードを記述する ことにより関数を定義できます。以下のマクロがこれを可能にします。 -- Macro: define-inline name args [doc] [declare] body... 自身をインライン化するコードを提供することにより、コンパイラーマク ロとして関数NAMEを定義する。この関数は引数リストARGSを受け取り、指 定されたBODYをもつ。 DOCが与えられたなら、それは関数のドキュメント文字列であること(*note Function Documentation::を参照)。DECLAREが与えられたなら、それは関 数のメタデータを指定する‘declare’フォームであること(*note Declare Form::を参照)。 ‘define-inline’で定義された関数は、‘defsubst’や‘defmacro’で定義された マクロにたいして複数の利点をもちます。 − ‘mapcar’に渡すことができる(*note Mapping Functions::を参照)。 − より効率的である。 − 値を格納するための“placeフォーム(place forms)”として使用できる (*note Generalized Variables::を参照)。 − ‘cl-defsubst’より予測可能な方法で振る舞う(*note (cl)Argument Lists::を参照)。 ‘defmacro’と同様に、‘define-inline’でインライン化された関数は、呼び出 し側からダイナミックかレキシカルいずれかのスコーピングルールを継承します 。*note Variable Scoping::を参照してください。 以下のマクロは‘define-inline’で定義された関数のbody内で使用する必要が あります。 -- Macro: inline-quote expression ‘define-inline’にたいしてEXPRESSIONをクォートする。これはバッククォ ート(*note Backquote::を参照)と似ているが、コードをクォートして ‘,’だけを受け入れ、‘,@’は受け入れない。 -- Macro: inline-letevals (bindings...) body... これは‘let’ (*note Local Variables::を参照)と似ているが、BINDINGSで 指定されたようにローカル変数をセットアップして、そのバインディング の効力の下でBODYを評価する。BINDINGSのそれぞれの要素はシンボルか ‘(VAR EXPR)’という形式のリストのいずれかであること。後者ならEXPRを 評価した結果がVARにバインドされる。BINDINGSの末尾には‘nil’、または 引数のリストを保持するシンボルを指定できる。後者の場合は各引数が評 価されて、そのシンボルに結果リストがバインドされる。 -- Macro: inline-const-p expression EXPRESSIONの値が既知なら非‘nil’をリターンする。 -- Macro: inline-const-val expression EXPRESSIONの値をリターンする。 -- Macro: inline-error format &rest args 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))) 12.5 関数の呼び出し =================== 関数を定義しただけでは半分しか終わっていません。関数はそれを“呼び出す (call)” — たとえば実行(run)するまでは何も行いません。関数のcallは “invocation”としても知られています。 関数を呼び出すもっとも一般的な方法は、リストの評価によるものです。た とえばリスト‘(concat "a" "b")’を評価することにより、関数‘concat’が引数 ‘"a"’と‘"b"’で呼び出されます。評価については*note Evaluation::を参照して ください。 プログラム内で式としてリストを記述するときは、プログラム内にテキスト でどの関数を呼び出すか、いくつの引数を与えるかを指定します。通常はこれが 行いたいことです。どの関数を呼び出すかを実行時に計算する必要がある場合も あります。これを行うには関数‘funcall’を使用します。実行時にいくつの引数 を渡すか決定する必要があるときは‘apply’を使用します。 -- Function: funcall function &rest arguments ‘funcall’は関数FUNCTIONを引数ARGUMENTSで呼び出して、FUNCTIONがリタ ーンした値をリターンする。 ‘funcall’は関数なので、FUNCTIONを含むすべての引数は‘funcall’の呼び 出し前に評価される。これは呼び出される関数を得るために任意の式を使 用できることを意味している。また‘funcall’がARGUMENTSに記述した式で はなく、その値だけを見ることを意味している。これらの値はFUNCTION呼 び出し中では、2回目は_評価されない_。‘funcall’の処理は関数の通常の 呼び出し手続きと似ており、すでに評価された引数は評価されない。 引数FUNCTIONはLisp関数かプリミティブ関数でなければならない。つまり スペシャルフォームやマクロは、未評価の引数式を与えられたときだけ意 味があるので、指定することはできない。上述したように最初の場所で ‘funcall’がそれらを知らないので、‘funcall’がそれらを提供することは できない。 コマンドの呼び出しに‘funcall’を使用して、それがインタラクティブに呼 び出されたように振る舞うようにする必要があるなら、 ‘funcall-interactively’を使用すること(*note Interactive Call::を参 照)。 (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: # これらの例を‘apply’の例と比較されたい。 -- Function: apply function &rest arguments ‘apply’は関数FUNCTIONを引数ARGUMENTSで呼び出す。これは‘funcall’と同 様だが1つ違いがある。ARGUMENTSの最後はオブジェクトのリストである。 これは1つのリストではなく、個別の引数としてFUNCTIONに渡される。わた したちはこれを、‘apply’がこのリストを“展開(spread)”(個々の要素が引 数となるので)すると言う。 ‘apply’はFUNCTIONを呼び出した結果をリターンする。‘funcall’と同様、 FUNCTIONはLisp関数かプリミティブ関数でなければならない。つまりスペ シャルフォームやマクロは‘apply’では意味をもたない。 (setq f 'list) ⇒ list (apply f 'x 'y 'z) error→ Wrong type argument: listp, z (apply '+ 1 2 '(3 4)) ⇒ 10 (apply '+ '(1 2 3 4)) ⇒ 10 (apply 'append '((a b c) nil (x y z) nil)) ⇒ (a b c x y z) ‘apply’を使用した興味深い例は*note Definition of mapcar::を参照のこ と。 ある関数にたいして、その関数のある引数を特定の値に固定して、他の引数 は実際に呼びだされたときの値にできれば便利なことがあります。関数のいくつ かの引数を固定することは、その関数の“部分適用(partial application)”と呼 ばれます(1)。これの結果は残りの引数をとる新たな関数で、すべての引数を合 わせて元の関数を呼び出します。 Emacs Lispで部分適用を行う方法を示します: -- Function: apply-partially func &rest args この関数は新たな関数をリターンする。この新しい関数は呼びだされたと きにARGS、および呼び出し時に指定された追加の引数から成る引数リスト でFUNCを呼び出す関数である。FUNCにN個の引数を指定できる場合、 ‘M < N’個の引数で‘apply-partially’を呼び出すと、‘N - M’個の新たな関 数を生成する。 以下はビルトイン関数‘1+’が存在しないものとして、‘apply-partially’と 他のビルトイン関数‘+’を使用して‘1+’を定義する例である: (defalias '1+ (apply-partially '+ 1) "Increment argument by one.") (1+ 10) ⇒ 11 引数として関数を受け取ったり、データ構造(特にフック変数やプロパティー リスト)から関数を探す関数はLispでは一般的で、それらは‘funcall’や ‘apply’を使用してそれらの関数を呼び出します。引数として関数をとる関数は 、“ファンクショナル(functional)”と呼ばれるときもあります。 ファンクショナルを呼び出すとき、引数としてno-op関数(何も行わない関数 )を指定できると便利なときがあります。以下に2つの異なるno-op関数を示しま す: -- Function: identity arg この関数はARGをリターンする。副作用はない。 -- Function: ignore &rest args この関数はすべての引数を無視して‘nil’をリターンする。 関数のいくつかはユーザーに可視な“コマンド”で、これらは(通常はキーシー ケンスを介して)対話的に呼び出すことができます。そのようなコマンドは、 ‘call-interactively’関数を使用することにより、対話的に呼びだされたときと 同様に呼び出すことができます。*note Interactive Call::を参照してください 。 ---------- Footnotes ---------- (1) これは“カリー化(currying)”と関連しますが異なる機能です。カーリン グは複数の引数を受け取る関数を、関数チェーンとして呼び出せるような1つの 引数を取る個々の関数に変換するような方法です。 12.6 関数のマッピング ===================== “マップ関数(mapping function)”は与えられた関数(スペシャルフォームやマク ロでは_ない_)を、リストや他のコレクションの各要素に適用します。Emacs Lispにはそのような関数がいくつかあります。このセクションではリストにたい してマッピングを行う‘mapcar’、‘mapc’、‘mapconcat’を説明します。obarray内 のシンボルにたいしてマッピングを行う関数‘mapatoms’は、*note Definition of mapatoms::を参照してください。ハッシュテーブル内のkey/value関係にたい してマッピングを行う関数‘maphash’は、*note Definition of maphash::を参照 してください。 これらのマップ関数は文字テーブル(char-table)には適用されません。なぜ なら文字テーブルは非常に広い範囲の疎な配列だからです。疎な配列であるとい う性質に適う方法で文字テーブルにマッピングするには、関数 ‘map-char-table’を使用します(*note Char-Tables::を参照)。 -- Function: mapcar function sequence ‘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)) -- Function: mapc function sequence ‘mapc’は‘mapcar’と似ているが、FUNCTIONは副作用のためだけに使用され る — つまりFUNCTIONがリターンする値は無視されてリストに収集されない 。‘mapc’は常にSEQUENCEをリターンする。 -- Function: mapconcat function sequence separator ‘mapconcat’はSEQUENCEのそれぞれの要素にFUNCTIONを適用する。結果は文 字のシーケンス(文字列、ベクター、リスト)でなければならず、単一の文 字列に結合されてリターン値となる。‘mapconcat’は結果シーケーンスの各 ペアの間にSEPARATORの文字を挿入する。これも文字列、または文字のベク ターかリストでなければならない。*note Sequences Arrays Vectors::を 参照のこと。 引数FUNCTIONは1つの引数を受け取り文字のシーケンス、すなわち文字列、 ベクター、リストのいずれかをリターンする。引数SEQUENCEは文字テーブ ル以外の任意の種類のシーケンス、すなわちリスト、ベクター、ブールベ クター、または文字列を指定できる。 (mapconcat 'symbol-name '(The cat in the hat) " ") ⇒ "The cat in the hat" (mapconcat (function (lambda (x) (format "%c" (1+ x)))) "HAL-8000" "") ⇒ "IBM.9111" 12.7 無名関数 ============= 関数は通常は‘defun’により定義されて、同時に名前が与えられますが、明示的 にラムダ式を使う — “無名関数(anonymous function)”のほうが便利なときもあ ります。無名関数は名前つき関数が有効な場所ならどこでも有効です。無名関数 は変数や関数の引数に割り当てられることがよくあります。たとえばある関数を リストの各要素に適用する‘mapcar’のFUNCTION引数に渡すかもしれません(*note Mapping Functions::を参照)。現実的な例は*note describe-symbols example::を参照してください。 無名関数として使用するためのラムダ式を定義するとき、原則的にはリスト を構築する任意の手法を使用できます。しかし通常はマクロ‘lambda’、スペシャ ルフォーム‘function’、または入力構文‘#'’を使用するべきです。 -- Macro: lambda args [doc] [interactive] body... このマクロは引数リストARGS、(もしあれば)ドキュメント文字列DOC、(も しあれば)インタラクティブ指定INTERACTIVE、およびBODYで与えられる bodyフォームをもつ無名関数をリターンする。 実際にはこのマクロは‘lambda’フォームを自己クォート(self-quoting)す る。つまりCARが‘lambda’であるようなフォームはそのフォーム自身を取得 する。 (lambda (x) (* x x)) ⇒ (lambda (x) (* x x)) ‘lambda’フォームは別の1つの効果をもつ。このマクロは‘function’(以下 参照)をサブルーチンとして使用することにより、Emacs評価機能(Emacs evaluator)とバイトコンパイラーに、その引数が関数であることを告げる 。 -- Special Form: function function-object このスペシャルフォームは評価を行わずにFUNCTION-OBJECTをリターンする 。この点では‘quote’(*note Quoting::を参照)と似ている。しかし ‘quote’とは異なり、Emacs評価機能とバイトコンパイラーに、これを関数 として使用する意図を告げる役割をもつ。FUNCTION-OBJECTが有効なラムダ 式と仮定すると、これは2つの効果をもつ: • そのコードがバイトコンパイルされているとき、FUNCTION-OBJECTは バイトコード関数オブジェクトにコンパイルされる(*note Byte Compilation::を参照)。 • レキシカルバインドが有効ならFUNCTION-OBJECTはクロージャーに変 換される。*note Closures::を参照のこと。 入力構文‘#'’は‘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’が関数としての使用を意図していること を知ることができないので、たとえこの関数が関数のように見えるとしても、こ のリストが関数であると決め込むことができません。 12.8 Generic Functions ====================== ‘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言語と異なり、ジェネリック関数 を実装するメソッドはクラスに属さずに、それらが実装するジェネリック関数に 属することに注意してください。 ジェネリック関数が呼び出されると、呼び出し側に渡された実際の引数と各 メソッドの引数スペシャライザーを比較することにより、適用可能なメソッドを 呼び出します。その呼び出しの実際の引数がメソッドのスペシャライザーと互換 性があれば、そのメソッドが適用可能です。複数のメソッドが適用可能ならば、 それらは以下で説明する特定のルールにより合成されて、その組み合わせが呼び 出しを処理します。 -- Macro: cl-defgeneric name arguments [documentation] [options-and-methods...] &rest body このマクロは指定したNAMEとARGUMENTSでジェネリック関数を定義する。 BODYが与えられたなら、それは実装のデフォルトを与える。(常に与えられ るべきであるが)DOCUMENTATIONが与えられたなら、それは ‘(:documentation DOCSTRING)’の形式でそのジェネリック関数のドキュメ ント文字列を指定する。オプションのOPTIONS-AND-METHODSは以下のフォー ムのいずれかを指定できる: ‘(declare DECLARATIONS)’ *note Declare Form::で説明するようなdeclareフォーム。 ‘(:argument-precedence-order &rest ARGS)’ このフォームは適用可能なメソッド合成にたいするソート順に影響を 与える。合成において2つのメソッドを比較する際、メソッドの引数 は通常は左から右に試験されて、引数スペシャライザーがより特化し た最初のメソッドが他のメソッドより前になる。このフォームで定義 された順序はそれをオーバーライドして、左から右ではなくこのフォ ームの順に応じて試験される。 ‘(:method [QUALIFIERS...] args &rest body)’ このメソッドは‘cl-defmethod’が行うようなメソッドを定義する。 -- Macro: cl-defmethod name [qualifier] arguments &rest [docstring] body このマクロはNAMEと呼ばれるジェネリック関数の、特定の実装を定義する 。実装コードはBODYで与えられる。もし与えられたらDOCSTRINGはそのメソ ッドのドキュメント文字列である。リストARGUMENTSはジェネリック関数を 実装するすべてのメソッドで等しく、その関数の引数リストとマッチしな ければならず、‘(ARG SPEC)’という形式の引数スペシャライザーを提供す る。ここでARGは‘cl-defgeneric’呼び出しで指定された引数名、SPECは以 下のスペシャライザーフォームのいずれかであること: ‘TYPE’ このスペシャライザーは、引数がTYPEのいずれかであることを要求す る。TYPEは以下で説明する型ヒエラルキーのいずれかの型である。 ‘(eql OBJECT)’ このスペシャライザーは、引数がOBJECTと‘eql’であることを要求す る。 ‘(head OBJECT)’ 引数は‘car’がOBJECTと‘eql’であるようなコンスセルでなければなら ない。 ‘STRUCT-TAG’ 引数は‘cl-defstruct’で定義されるSTRUCT-TAGという名前のクラス (*note (cl)Structures::を参照)、またはその親クラスのいずれかの のインスタンスでなければならない。 かわりに引数スペシャライザーは‘&context (EXPR SPEC)’という形式でも よく、この場合はEXPRの値はSPECが提供するスペシャライザーと互換性が なければならない。SPECには以下で説明する任意のフォームを指定できる 。言い換えると、このスペシャライザーのフォームはメソッドが適用可能 かどうかの判定にたいして、引数のかわりにEXPRの値を使用する。たとえ ば‘&context (overwrite-mode (eql t))’は‘overwrite-mode’がオンのとき だけ互換性のあるメソッドを作成する。 型スペシャライザー‘(ARG TYPE)’は以下のリストの“システム型(system types)”のいずれかを指定できる。親の型が指定されたときは、型がより特 化した子型、孫型、曾孫型、...のいずれかであるような任意の引数も互換 となるだろう。 ‘integer’ 親型: ‘number’。 ‘number’ ‘null’ 親型: ‘symbol’。 ‘symbol’ ‘string’ 親型: ‘array’。 ‘array’ 親型: ‘sequence’。 ‘cons’ 親型: ‘list’。 ‘list’ 親型: ‘sequence’。 ‘marker’ ‘overlay’ ‘float’ 親型: ‘number’。 ‘window-configuration’ ‘process’ ‘window’ ‘subr’ ‘compiled-function’ ‘buffer’ ‘char-table’ 親型: ‘array’。 ‘bool-vector’ 親型: ‘array’。 ‘vector’ 親型: ‘array’。 ‘frame’ ‘hash-table’ ‘font-spec’ ‘font-entity’ ‘font-object’ オプションのQUALIFIERは複数の適用可能なメソッドの合成を許容する。与 えられなければ定義されるメソッドは“primary(主)”メソッドとなり、スペ シャライズされた引数にたいする主要な実装の提供に責任を有する。 QUALIFIERとして以下の値のいずれかを使用して“auxiliary(副)”メソッド も定義できる: ‘:before’ このauxiliaryメソッドはprimaryメソッドの前に実行される。より正 確にはすべての‘:before’メソッドは、より特化したメソッドが最初 になる順で、primaryメソッドの前に実行される。 ‘:after’ このauxiliaryメソッドはprimaryメソッドの後に実行される。より正 確にはすべてのこの類のメソッドは、より特化したメソッドが最後に なる順で、primaryメソッドの後に実行される。 ‘:around’ このauxiliaryメソッドはprimaryメソッドの_代替え_として実行され る。この類のメソッドでもっとも特化したものが他のメソッドより前 に実行される。このようなメソッドは他のauxiliaryメソッドや primaryメソッドを呼び出すために、通常は以下で説明する ‘cl-call-next-method’を使用する。 ‘:extra STRING’ これにより同一のspecializerとqualifierにたいして、STRINGで区別 されるメソッドを追加できる。 ジェネリック関数が呼び出されると、毎回その関数にたいして定義された適 用可能なメソッドを合成することによってその呼び出しを処理する“effectiveメ ソッド(effective method)”を構築します。適用可能なメソッドを探して effectiveメソッドを生成するプロセスは“dispatch”と呼ばれます。その呼び出 しの実際の引数と互換性があるスペシャライザーをもつすべてのメソッドが、互 換性のあるメソッドです。すべての引数がスペシャライザーと互換でなければな らないので、それらはすべてメソッドが適用可能かどうか判定します。複数の引 数に明示的に特化したメソッドを“multiple-dispatchメソッド (multiple-dispatch methods)”と呼びます。 適用可能なメソッドはそれらが合成される順にソートされます。最左の引数 スペシャライザーがもっとも特化したものであるようなメソッドが、順序の最初 になります(上述したように‘cl-defmethod’の一部として ‘:argument-precedence-order’を指定することによりこれをオーバーライドでき る)。そのメソッドのbodyが‘cl-call-next-method’を呼び出すと、もっとも特化 した次のメソッドが実行されます。適用可能な‘:around’メソッドがあれば、そ れらのうちもっとも特化したメソッドが実行されます。そのメソッドはより特化 していない任意の‘:around’メソッドを実行するために、 ‘cl-call-next-method’を呼び出すべきです。次に‘:before’メソッドがその特化 した順に、その後にspecificityメソッドが実行されます。そして後に ‘:after’メソッドがその特化した順と逆順で実行されます。 -- Function: cl-call-next-method &rest args primaryメソッドか‘:around’ auxiliaryメソッド内のレキシカルbody内で 呼び出されると、同じジェネリック関数にたいして適用可能な次のメソッ ドを呼び出す。通常これは引数なしで呼び出され、これは次の適用可能な メソッドを呼び出すメソッドが、呼び出されたときと同じ引数で次のメソ ッドを呼び出すことを意味する。それ以外ならかわりに指定された引数が 使用される。 -- Function: cl-next-method-p primaryメソッドか‘:around’ auxiliaryメソッドのレキシカルbody内から この関数を呼び出したときは、呼び出す次のメソッドが存在すれば非 ‘nil’をリターンする。 12.9 関数セルの内容へのアクセス =============================== シンボルの“関数定義(function definition)”とは、そのシンボルの関数セルに 格納されたオブジェクトのことです。ここではシンボルの関数セルへのアクセス やテスト、それをセットする関数を説明します。 *note Definition of indirect-function::の関数‘indirect-function’も参 照してください。 -- Function: symbol-function symbol これはSYMBOLの関数セル内のオブジェクトをリターンする。これはリター ンされたオブジェクトが本物のの関数であるかチェックしない。 関数セルがvoidならリターン値は‘nil’。関数セルがvoidのときと‘nil’が セットされているときを区別するには‘fboundp’(以下参照)を使用する。 (defun bar (n) (+ n 2)) (symbol-function 'bar) ⇒ (lambda (n) (+ n 2)) (fset 'baz 'bar) ⇒ bar (symbol-function 'baz) ⇒ bar シンボルに何の関数定義も与えていなければ、そのシンボルの関数セルは “void”だと言います。言い換えると、その関数セルはどんなLispオブジェクトも 保持しません。そのシンボルを関数として呼びだそうとすると、Emacsは ‘void-function’エラーをシグナルします。 voidは‘nil’やシンボル‘void’とは異なることに注意してください。シンボル ‘nil’と‘void’はLispオブジェクトであり、他のオブジェクトと同じように関数 セルに格納することができます(これらのシンボルは‘defun’を使用して有効な関 数になることができる)。voidであるような関数セルは、どのようなオブジェク トも含んでいません。 ‘fboundp’を使用して任意のシンボルの関数定義がvoidかどうかテストするこ とができます。シンボルに関数定義を与えた後は、‘fmakunbound’を使用して再 びvoidにすることができます。 -- Function: fboundp symbol この関数はそのシンボルが関数セルにオブジェクトをもっていれば‘t’、そ れ以外は‘nil’をリターンする。これはそのオブジェクトが本物の関数であ るかチェックしない。 -- Function: fmakunbound symbol この関数はSYMBOLの関数セルをvoidにする。そのためこれ以降に関数セル へのアクセスを試みると、‘void-function’エラーが発生する。これは SYMBOLをリターンします(*note Void Variables::の‘makunbound’も参照 )。 (defun foo (x) x) (foo 1) ⇒1 (fmakunbound 'foo) ⇒ foo (foo 1) error→ Symbol's function definition is void: foo -- Function: fset symbol definition この関数はSYMBOLの関数セルにDEFINITIONを格納する。結果は DEFINITION。DEFINITIONは通常は関数か関数の名前であるべきだが、これ はチェックされない。引数SYMBOLは通常のどおり評価される引数である。 この関数は主に関数を定義したり変更して構築を行う、‘defun’や ‘advice-add’のようなものからサブルーチンとして使用される。たとえば キーボードマクロ(*note Keyboard Macros::を参照)のような、関数ではな い関数定義をシンボルに与えるためにも使用することができる: ;; 名前つきのキーボードマクロを定義する。 (fset 'kill-two-lines "\^u2\^k") ⇒ "\^u2\^k" 関数にたいして別の名前を作成するために‘fset’を使いたいなら、かわり に‘defalias’の使用を考慮すること。*note Definition of defalias::を 参照。 12.10 クロージャー ================== *note Variable Scoping::で説明したように、Emacsはオプションで変数のレキ シカルバインディングを有効にできます。レキシカルバインディングが有効な場 合は、(たとえば‘defun’などで)作成したすべての名前つき関数、同様に ‘lambda’マクロや‘function’スペシャルフォーム、‘#'’構文を使用して作成した すべての無名関数(*note Anonymous Functions::を参照)が、自動的に“クロージ ャー(closure)”に変換されます。 クロージャーとはその関数が定義されたどときに存在したレキシカル環境の 記録をあわせもつ関数です。クロージャーが呼び出されたとき、定義内のレキシ カル変数の参照には、その保持されたレキシカル環境が使用されます。他のすべ ての点では、クロージャーは通常の関数と同様に振る舞います。特にクロージャ ーは通常の関数と同じ方法で呼び出すことができます。 クロージャー使用する例は*note Lexical Binding::を参照してください。 現在のところEmacs Lispのクロージャーオブジェクトは、1つ目の要素にシン ボル‘closure’をもつリストとして表現されます。そのリストは2つ目の要素とし てレキシカル環境、残りの要素で引数リストとbodyフォームを表します: ;; レキシカルバインディングが有効 (lambda (x) (* x x)) ⇒ (closure (t) (x) (* x x)) しかし実際にはクロージャーの内部構造は、内部的な実装の詳細と判断される残 りのLisp界を晒け出すものだと言えます。この理由により、クロージャーオブジ ェクトの構造を直接調べたり変更することは推奨しません。 12.11 Emacs Lisp関数にたいするアドバイス ======================================== 他のライブラリーの関数定義を変更する必要があるとき、および ‘FOO-function’oのようなフックやプロセスフィルター(process filter)や、関 数を値としてもつ任意の変数やオブジェクトを変更する必要があるときには、名 前つきの関数には‘fset’か‘defun’、フック変数には‘setq’、プロセスフィルタ ーには‘set-process-filter’のように、適切なセッター関数(setter function)を 使用することができます。しかしこれらが以前の値を完全に破棄してしまうのが 好ましくない場合もあります。 “アドバイス(advice)”機能によって“関数にアドバイス”することにより、既 存の関数定義に機能を追加できます。これは関数全体を再定義するより明解な手 法です。 Emacsのアドバイスシステムは2つのプリミティブセットを提供します。コア となるセットは変数やオブジェクトのフィールドに保持された関数値にたいする ものです(対応するプリミティブは‘add-function’と‘remove-function’)。もう 1つのセットは名前つき関数の最上位のレイヤーとなるものです(主要なプリミテ ィブは‘advice-add’と‘advice-remove’)。 たとえばプロセスPROCのプロセスフィルターの呼び出しをトレースするため に以下を使用できます: (defun my-tracing-function (proc string) (message "Proc %S received %S" proc string)) (add-function :before (process-filter PROC) #'my-tracing-function) これによりそのプロセスの出力は元のプロセスフィルターに渡される前に、 ‘my-tracing-function’に渡されるようになります。‘my-tracing-function’は元 の関数と同じ引数を受け取ります。これを行えば以下のようにしてトレースを行 う前の振る舞いにリバートすることができます。 (remove-function (process-filter PROC) #'my-tracing-function) 同様に‘display-buffer’という名前つきの関数の実行をトレースしたいなら 以下を使用できます: (defun his-tracing-function (orig-fun &rest args) (message "display-buffer called with args %S" args) (let ((res (apply orig-fun args))) (message "display-buffer returned %S" res) res)) (advice-add 'display-buffer :around #'his-tracing-function) ここで‘his-tracing-function’は元の関数のかわりに呼び出されて、元の関 数(に加えてその関数の引数)を引数として受け取るので、必要な場合はそれを呼 び出すことができます。出力を確認し終えたら、以下のようにしてトレースを行 う前の振る舞いにリバートできます: (advice-remove 'display-buffer #'his-tracing-function) 上記の例で使用されている引数‘:before’と‘:around’は、2つの関数が構成さ れる方法を指定します(これを行う多くの方法があるから)。追加された関数も _アドバイス(advice)_と呼ばれます。 12.11.1 アドバイスを操作するためのプリミティブ ---------------------------------------------- -- Macro: add-function where place function &optional props このマクロはPLACE(*note Generalized Variables::を参照)に格納された 関数に、アドバイスFUNCTIONを追加する手軽な方法である。 WHEREは既存の関数のどこ — たとえば元の関数の前や後 — にFUNCTIONが構 成されるかを決定する。2つの関数を構成するために利用可能な方法のリス トは、*note Advice combinators::を参照のこと。 (通常は名前が‘-function’で終わる)変数を変更するときには、FUNCTIONが グローバルに使用されるか、あるいはカレントバッファーだけに使用され るか選ぶことができる。PLACEが単にシンボルならFUNCTIONはPLACEのグロ ーバル値に追加される。PLACEが‘(local SYMBOL)’というフォームなら、 SYMBOLはその変数の名前をリターンする式なので、FUNCTIONはカレントバ ッファーだけに追加される。最後にレキシカル変数を変更したければ、 ‘(var VARIABLE)’を使用する必要があるだろう。 ‘add-function’で追加されたすべての関数は、自動的にプロパティー PROPSの連想リストに加えることができる。現在のところ特別な意味をもつ のは以下の2つのプロパティーのみ: ‘name’ これはアドバイスの名前を与える。この名前は‘remove-function’が 取り除く関数を識別するのに使用できます。これは通常はFUNCTIONが 無名関数のときに使用されます。 ‘depth’ これは複数のアドバイスが与えられたときに、どのようにアドバイス を順番づけるべきかを指定する。depthのデフォルト0。depthが100な ら、そのアドバイスは可能な限りの深さを保持すべきことを、-100な ら最外のアドバイスに留めることを意味する。同じdepthで2つのアド バイスが指定されたら、もっとも最近に追加されたアドバイスが最外 となる。 ‘:before’アドバイスにたいしては、最外(outermost)になるというこ とは、このアドバイスが他のすべてのアドバイスの前、つまり1番目 に実行されることを意味し、最内(innermost)とは元の関数が実行さ れる直前、すなわちこのアドバイスと元の関数の間に実行されるアド バイスは存在しないことを意味する。同様に‘:after’アドバイスにた いしては、最内とは元の関数の直後、つまりこの元の関数とアドバイ スの間に実行される他のアドバイスは存在せず、最外とは他のすべて のアドバイスが実行された直後にこのアドバイスが実行されることを 意味する。‘:override’の最内アドバイスは、元の関数だけをオーバ ーライドし、他のアドバイスはそれに適用されるが、‘:override’の 最外アドバイスは元の関数だけではなく、その他すべての適用済みの アドバイスをも同様にオーバーライドする。 FUNCTIONがインタラクティブでなければ合成された関数は、(もしあれば )元の関数のインタラクティブ仕様(interactive spec)を継承します。それ 以外なら合成された関数はインタラクティブとなりFUNCTIONのインタラク ティブ仕様を使用します。1つ例外があります。FUNCTIONのインタラクティ ブ仕様が(式や文字列ではない)関数なら、元の関数のインタラクティブ仕 様を唯一の引数としてその関数を呼び出して、それが合成された関数のイ ンタラクティブ指定になります。引数として受け取ったインタラクティブ 仕様を解釈するためには‘advice-eval-interactive-spec’を使用します。 注意: FUNCTIONのインタラクティブ仕様は合成された関数に適用され、 FUNCTIONではなく結合された関数の呼び出し規約に従うこと。多くの場合 これらは等しいので差異は生じないが、FUNCTIONの‘:around’、 ‘:filter-args’、‘filter-return’では重要になる。 -- Macro: remove-function place function このマクロはPLACEに格納された関数からFUNCTIONを取り除く。これは ‘add-function’を使用してFUNCTIONがPLACEに追加されたときだけ機能する 。 FUNCTIONはPLACEに追加された関数にたいして、ラムダ式にたいしても機能 するように‘equal’を使用して比較を試みる。これは追加でPLACEに追加さ れた関数の‘name’プロパティーも比較する。これは‘equal’を使用してラム ダ式を比較するより信頼性がある。 -- Function: advice-function-member-p advice function-def ADVICEがすでにFUNCTION-DEF内にあれば非‘nil’をリターンする。上記の ‘remove-function’と同様、実際の関数ADVICEのかわりにアドバイスの ‘name’も使用できる。 -- Function: advice-function-mapc f function-def FUNCTION-DEFに追加されたすべてのアドバイスにたいして、関数Fを呼び出 す。Fは2つの引数 — アドバイス関数とそれのプロパティーで呼びだされる 。 -- Function: advice-eval-interactive-spec spec そのようなインタラクティブ仕様で関数がインタラクティブに呼び出され たようにSPECを評価して、構築された引数のリストに対応するリストをリ ターンする。たとえば‘(advice-eval-interactive-spec "r\nP")’はリージ ョンの境界、カレントプレフィクス引数を含む、3つの要素からなるリスト をリターンする。 12.11.2 名前つき関数にたいするアドバイス ---------------------------------------- アドバイスは名前つき関数やマクロにたいして使用するのが一般的な使い方です 。これは単に‘add-function’を使用して以下のように行うことができます: (add-function :around (symbol-function 'FUN) #'his-tracing-function) しかしかわりに‘advice-add’と‘advice-remove’を使うべきです。この異なる 関数セットは名前つき関数に適用されるアドバイスを操作するためのもので、 ‘add-function’と比較して以下の追加機能があります。まずこれらはマクロとオ ートロードされた関数を扱う方法を知っています。次に‘describe-function’に たいして追加されたアドバイスと同様に、元のドキュメント文字列を維持します 。さらに関数が定義される前でも、アドバイスの追加と削除ができます。 既存の関数全体を再定義せずに既存の呼び出しを変更するために、 ‘advice-add’が有用になります。しかしその関数の既存の呼び出し元は古い振る 舞いを前提としているかもしれず、アドバイスによりその振る舞いが変更された ときに正しく機能しないかもしれないので、これはソー内スのバグにもなり得ま す。アドバイスはデバッグを難しくする可能性もあります。デバッグを行う人は その関数がアドバイスにより変更されたことに気づかなかったり、失念している かもしれません。 これらの理由により、他の方法で関数の振る舞いを変更できない場合に備え るために、アドバイスの使用は控えるべきです。フックを通じて同じことが行え るならフック(*note Hooks::を参照)の使用が望ましい方法です。特定のキーが 行う何かを変更したいだけなら、新しいコマンドを記述して、古いコマンドのキ ーバインドを新しいコマンドにリマップ(*note Remapping Commands::を参照)す るのが、おそらくより良い方法です。特にEmacs自身のソースファイルは、 Emacs内の関数をアドバイスするべきではありません(現在のところこの慣習には いくつかの例外があるが、わたしたちはこれを改善しようと思っている)。 スペシャルフォーム(*note Special Forms::を参照)はアドバイスできません が、マクロは関数と同じ方法でアドバイスできます。もちろんこれはすでにマク ロ展開されたコードには影響しないため、マクロ展開前にアドバイスが確実にイ ンストールされる必要があります。 プリミティブ(*note What Is a Function::を参照)にアドバイスするのは可 能ですが、2つの理由により通常は_行うべきではありません_。1つ目の理由はい くつかのプリミティブがアドバイスのメカニズム内で使用されているため、それ らにたいしてアドバイスを行うと無限再帰が発生するからです。2つ目の理由は 多くのプリミティブがCから直接呼び出されていて、そのような呼び出しはアド バイスを無視するからです。したがってプリミティブにたいしてアドバイスの使 用を控えることにより、ある呼び出しはアドバイスにしたがい(Lispコードから 呼びだされたため)、他の呼び出しではアドバイスにしたがわない(Cコードから 呼び出されたため)という混乱した状況を解決できます。 -- Macro: define-advice symbol (where lambda-list &optional name depth) &rest body このマクロはアドバイスを定義して、それをSYMBOLという名前の関数に追 加する。NAMEがnilか‘symbol@name’という名前の関数なら、そのアドバイ スは無名関数である。他の引数の説明は‘advice-add’を参照のこと。 -- Function: advice-add symbol where function &optional props 名前つき関数SYMBOLにアドバイスFUNCTIONを追加する。WHEREとPROPSは ‘add-function’(*note Core Advising Primitives::を参照)のときと同じ 意味をもつ。 -- Function: advice-remove symbol function 名前つき関数SYMBOLからアドバイスFUNCTIONを取り除く。FUNCTIONにアド バイスの‘name’を指定することもできる。 -- Function: advice-member-p function symbol 名前つき関数SYMBOL内にすでにアドバイスFUNCTIONがあれば非‘nil’をリタ ーンする。FUNCTIONにアドバイスの‘name’を指定することもできる。 -- Function: advice-mapc function symbol 名前つき関数SYMBOLにすでに追加されたすべての関数にたいして FUNCTIONを呼び出す。FUNCTIONはアドバイス関数とそのプロパティーとい う2つの引数で呼び出される。 12.11.3 アドバイスの構築方法 ---------------------------- 以下は‘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))) 12.11.4 古いdefadviceを使用するコードの改良 ------------------------------------------- 多くのコードは古い‘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’に変更する必要があるでしょう。 12.12 関数を陳腐と宣言する ========================== 名前つき関数を“陳腐化している(obsolete)”とマークすることができます。これ はその関数が将来のある時点で削除されるかもしれないことを意味します。陳腐 化しているとマークされた関数を含むコードをバイトコンパイルしたとき、 Emacsは警告を発します。またその関数のヘルプドキュメントは表示されなくな ります。他の点では陳腐化した関数は他の任意の関数と同様に振る舞います。 関数を陳腐化しているとマークするもっとも簡単な方法は、その関数の ‘defun’定義に‘(declare (obsolete ...))’を配置することです。*note Declare Form::を参照してください。かわりに以下で説明している‘make-obsolete’関数 を使うこともできます。 ‘make-obsolete’を使用してマクロ(*note Macros::を参照)を陳腐化している とマークすることもできます。これは関数のときと同じ効果をもちます。関数や マクロにたいするエイリアスも、陳腐化しているとマークできます。これはエイ リアス自身をマークするのであって、名前解決される関数やマクロにたいしてで はありません。 -- Function: make-obsolete obsolete-name current-name &optional when この関数はOBSOLETE-NAMEを陳腐化しているとマークする。 OBSOLETE-NAMEには関数かマクロを命名するシンボル、または関数やマクロ にたいするエイリアスを指定する。 CURRENT-NAMEがシンボルならOBSOLETE-NAMEのかわりにCURRENT-NAMEの使用 を促す警告メッセージになる。CURRENT-NAMEがOBSOLETE-NAMEのエイリアス である必要はない。似たような機能をもつ別の関数かもしれない。 CURRENT-NAMEには警告メッセージとなる文字列も指定できる。メッセージ は小文字で始まりピリオドで終わること。‘nil’も指定でき、この場合には 警告メッセージに追加の詳細は提供されない。 WHENが与えられたら、それは最初にその関数が陳腐化する時期を示す文字 列 — たとえば日付やリリース番号を指定する。 -- Macro: define-obsolete-function-alias obsolete-name current-name &optional when doc この便利なマクロは関数OBSOLETE-NAMEを陳腐化しているとマークして、そ れを関数CURRENT-NAMEのエイリアスにする。これは以下と等価: (defalias OBSOLETE-NAME CURRENT-NAME DOC) (make-obsolete OBSOLETE-NAME CURRENT-NAME WHEN) 加えて陳腐化した関数にたいする特定の呼び出し規約をマークできます。 -- Function: set-advertised-calling-convention function signature when この関数はFUNCTIONを呼び出す正しい方法として、引数リストSIGNATUREを 指定する。これによりEmacs Lispプログラムが他の方法でFUNCTIONを呼び 出していたら、Emacsのバイトコンパイラーが警告を発する(それでもコー ドはバイトコンパイルされる)。WHENにはその変数が最初に陳腐化するとき を示す文字列(通常はバージョン番号)を指定する。 たとえば古いバージョンのEmacsでは、‘sit-for’には以下のように3つの引 数を指定していた (sit-for seconds milliseconds nodisp) しかしこの方法による‘sit-for’の呼び出しは陳腐化していると判断される (*note Waiting::を参照)。以下のように古い呼び出し規約は推奨されない : (set-advertised-calling-convention 'sit-for '(seconds &optional nodisp) "22.1") 12.13 インライン関数Inline Functions ==================================== “インライン関数(inline function)”は関数と同様に機能しますが、1つ例外があ ります。その関数の呼び出しがバイトコンパイルされると(*note Byte Compilation::を参照)、その関数の定義が呼び出し側に展開されます。インライ ン関数を定義するには、‘defun’のかわりに‘defsubst’を使用します。 -- Macro: defsubst name args [doc] [declare] [interactive] body... このマクロはインライン関数を定義する。マクロの構文は‘defun’とまった く同じ(*note Defining Functions::を参照)。 関数をインラインにすることにより、その関数の呼び出しが高速になる場合 があります、が欠点もありその1つは柔軟性の減少です。その関数の定義を変更 すると、すでにインライン化された呼び出しは、リコンパイルを行うまで古い定 義を使用することになります。 もう1つの欠点は、大きな関数をインライン化することにより、コンパイルさ れたコードのファイル上およびメモリー上のサイズが増大することです。スピー ド面でのインライン化の有利性は小さい関数で顕著なので、一般的に大きな関数 をインライン化するべきではありません。 インライン関数はデバッグ、トレース、アドバイス(*note Advising Functions::を参照)に際してうまく機能しません。デバッグの容易さと関数の再 定義の柔軟さはEmacsの重要な機能なので、スピードがとても重要であって ‘defun’の使用が実際に性能の面で問題となるのか検証するためにすでにコード をチューニングしたのでなければ、たとえその関数が小さくてもインライン化す るべきではありません。 インライン関数を定義した後そのインライン展開はマクロ同様、同じファイ ル内の後の部分で処理されます。 ‘defsubst’を使用してインライン関数が実行するのと同じコードに展開され るマクロ(*note Macros::を参照)を定義することは可能です。しかし式内でのマ クロの直接の使用には制限があります — ‘apply’、‘mapcar’などでマクロを呼び 出すことはできません。通常の関数からマクロへの変換には、そのための余分な 作業が必要になります。通常の関数をインライン関数に変換するのは簡単です。 ‘defun’を‘defsubst’に置き換えるだけです。インライン関数の引数はそれぞれ 正確に1回評価されるので、マクロのときのようにbodyで引数を何回使用するか 心配する必要はありません。 ‘defsubst’の代替えとして、完全なコンパイラーマクロを通じて関数を定義 する‘define-inline’を使用できます、*note define-inline: Defining Functions.を参照してください。 12.14 ‘declare’フォーム ======================= ‘declare’(宣言)は特別なマクロで、関数やマクロにメタプロパティーを追加す るために使用できます。たとえば陳腐化しているとマークしたり、Emacs Lispモ ード内の特別なインデント規約を与えることができます。 -- Macro: declare specs... このマクロは引数を無視して‘nil’として評価されるので、実行時の効果は ない。しかし‘defun’や‘defsubst’(*note Defining Functions::を参照)、 または‘defmacro’マクロ(*note Defining Macros::を参照)の定義の DECLARE引数に‘declare’フォームがある場合は、SPECSで指定されたプロパ ティーを関数またはマクロに追加します。これは‘defun’、‘defsubst’、 ‘defmacro’により特別に処理される。 SPECS内の各要素は‘(PROPERTY ARGS...)’というフォームをもつこと。また それあをクォートしないこと。これらは以下の効果をもつ: ‘(advertised-calling-convention SIGNATURE WHEN)’ これは‘set-advertised-calling-convention’(*note Obsolete Functions::を参照)の呼び出しと同じように振る舞う。SIGNATUREに はその関数(またはマクロ)にたいする正しい引数リスト、WHENには古 い引数リストが最初に陳腐化する時期を示す文字列を指定する。 ‘(debug EDEBUG-FORM-SPEC)’ これはマクロだけに有効である。Edebugでそのマクロ入ったときに、 EDEBUG-FORM-SPECを使用する。*note Instrumenting Macro Calls::を 参照のこと。 ‘(doc-string N)’ 自身が関数やマクロ、変数のようなエンティティーを定義するために 使用されるような関数やマクロを定義するときにこれが使用される。 これはN番目の引数というこを示し、もしそれがあれば、それはドキ ュメント文字列とみなされる。 ‘(indent INDENT-SPEC)’ この関数(かマクロ)にたいするインデント呼び出しは、 INDENT-SPECにしたがう。これは関数でも機能するが、通常はマクロ で使用される。*note Indenting Macros::を参照のこと。 ‘(interactive-only VALUE)’ その関数の‘interactive-only’プロパティにVALUEをセットする。 *note The interactive-only property::を参照のこと。 ‘(obsolete CURRENT-NAME WHEN)’ ‘make-obsolete’(*note Obsolete Functions::を参照)と同様に、関 数(かマクロ)が陳腐化しているとマークする。CURRENT-NAMEにはシン ボル(かわりにこのシンボルを使うことを促す警告メッセージになる )、文字列(警告メッセージを指定)、または‘nil’(警告メッセージに は追加の詳細が含まれない)を指定すること。WHENにはその関数(かマ クロ)が最初に陳腐化する時期を示す文字列を指定すること。 ‘(compiler-macro EXPANDER)’ これは関数だけに使用でき、最適化関数(optimization function)と してEXPANDERを使用するようコンパイラーに告げる。‘(FUNCTION ARGS...)’のようなその関数への呼び出しフォームに出会うと、マク ロ展開機能(macro expander)はARGS...と同様のフォームで EXPANDERを呼び出す。EXPANDERはその関数呼び出しのかわりに使用す るための新しい式、または変更されていないフォーム(その関数呼び 出しを変更しないことを示す)のどちらかをリターンすることができ る。EXPANDERにはシンボルかフォーム‘(lambda (ARG) BODY)’を指定 できる。フォームならARGは元の関数呼び出し式を保持して、その関 数の形式に適う引数を使用することにより、その関数にたいする(評 価されていない)引数にアクセスができる。 ‘(gv-expander EXPANDER)’ EXPANDERが‘gv-define-expander’と同様、ジェネリック変数としてマ クロ(か関数)にたいする呼び出しを処理する関数であることを宣言す る。EXPANDERはシンボルかフォーム‘(lambda (ARG) BODY)’を指定で きる。フォームなら、その関数は追加でそのマクロ(か関数)の引数に アクセスできる。 ‘(gv-setter SETTER)’ SETTERがジェネリック変数としてマクロ(か関数)にたいする呼び出し を処理する関数であることを宣言する。SETTERはシンボルかフォーム を指定できる。シンボルなら、そのシンボルは ‘gv-define-simple-setter’に渡される。フォームなら‘(lambda (ARG) BODY)’という形式で、その関数は追加でマクロ(か関数)の引数 にアクセスでき、それは‘gv-define-setter’に渡される。 12.15 コンパイラーへの定義済み関数の指示 ======================================== あるファイルをバイトコンパイルするとき、コンパイラーが知らない関数につい て警告が生成されるときがあります(*note Compiler Errors::を参照)。実際に 問題がある場合もありますが、問題となっている関数がそのコードの実行時にロ ードされる他のファイルで定義されている場合が通常です。たとえば以前は ‘fortran.el’をバイトコンパイルすると、以下のような警告が出ていました: In end of data: fortran.el:2152:1:Warning: the function ‘gud-find-c-expr’ is not known to be defined. 実際のところ‘gud-find-c-expr’はFortranモードが使用する ‘gud-find-expr-function’のローカル値(GUDからのコールバック)の中だけで使 用されていて、呼び出されるとGUD関数がロードされます。そのような警告が実 際には問題を示さないことを知っているときには、警告を抑制したほうがよいで しょう。そうすれば実際に問題があることを示す新しい警告の識別性が良くなり ます。‘declare-function’を使用してこれを行うことができます。 必要なのは問題となっている関数を最初に使用する前に ‘declare-function’命令を追加するだけです: (declare-function gud-find-c-expr "gud.el" nil) これは‘gud-find-c-expr’が‘gud.el’(‘.el’は省略可)の中で定義されている ことを告げます。コンパイラーは関数がそのファイルでそれが実際に定義されて いるとみなして、チェックを行いません。 3つ目の引数はオプションで‘gud-find-c-expr’の引数リストを指定します。 この例では引数はありません(‘nil’と値が未指定なのは異なる)。それ以外なら ‘(file &optional overwrite)’のようになります。引数リストを指定する必要は ありませんが、指定すればコンパイラーはその呼び出しが宣言と合致するかチェ ックできます。 -- Macro: declare-function function file &optional arglist fileonly バイトコンパイラーにたいして引数ARGLISTを受け取るFUNCTIONが定義され ていて、その定義はFILEにあるとみなすように告げる。FILEONLYが非 ‘nil’なら、FILEが存在することだけをチェックして実際のFUNCTIONの定義 はチェックしないことを意味する。 これらの関数が‘declare-function’が告げる場所で実際に宣言されているか どうかを検証するには、‘check-declare-file’を使用して1つのソースファイル 中のすべての‘declare-function’呼び出しをチェックするか、 ‘check-declare-directory’を使用して特定のディレクトリー配下のすべてのフ ァイルをチェックする。 これらのコマンドは、‘locate-library’で使用する関数の定義を含むはずの ファイルを探す。ファイルが見つからなければ、これらのコマンドは ‘declare-function’の呼び出しを含むファイルがあるディレクトリーからの相対 ファイル名に、定義ファイル名を展開する。 ‘.c’や‘.m’で終わるファイル名を指定することにより、プリミティブ関数を 指定することもできる。これが有用なのは特定のシステムだけで定義されるプリ ミティブを呼び出す場合だけである。ほとんどのプリミティブは常に定義されて いるので、それらについて警告を受け取ることはありえないはずである。 あるファイルがオプションとして外部のパッケージの関数を使う場合もある 。‘declare-function’命令内のファイル名のプレフィクスを‘ext:’にすると、そ のファイルが見つかった場合はチェックして、見つからない場合はエラーとせず にスキップする。 ‘check-declare’が理解しない関数定義もいくつか存在する(たとえば ‘defstruct’やその他いくつかのマクロ)。そのような場合は ‘declare-function’のFILEONLY引数に非‘nil’を渡すことができる。これはファ イルの存在だけをチェックして、その関数の実際の定義はチェックしないことを 意味する。これを行うなら引数リストを指定する必要はないが、ARGLIST引数に は‘t’をセットする必要があることに注意(なぜなら‘nil’は引数リストが指定さ れなかったという意味ではなく空の引数リストを意味するため)。 12.16 安全に関数を呼び出せるかどうかの判断 ========================================== SESのようないくつかのメジャーモードは、ユーザーファイル内に格納された関 数を呼び出します(SESの詳細は*note (ses)Top::を参照)。 ユーザーファイルは 素性があやふやな場合があります — 初対面の人から受け取ったスプレッドシー トかもしれず、会ったことのない誰かから受け取ったeメールかもしれません。 そのためユーザーファイルに格納されたソースコードの関数を呼び出すのは、そ れが安全だと決定されるすまでは危険です。 -- Function: unsafep form &optional unsafep-vars FORMが“安全(safe)”なLisp式なら‘nil’、危険ならなぜその式が危険かもし れないのか説明するリストをリターンする。引数UNSAFEP-VARSは、この時 点で一時的なバインドだと判っているシンボルのリスト。これは主に内部 的な再帰呼び出しで使用される。カレントバッファーは暗黙の引数になり 、これはバッファーローカルなバインディングのリストを提供する。 高速かつシンプルにするために、‘unsafep’は非常に軽量な分析を行うので、 実際には安全な多くのLisp式を拒絶します。安全ではない式にたいして ‘unsafep’が‘nil’をリターンするケースは確認されていません。しかし安全な Lisp式は‘display’プロパティーと一緒に文字列をリターンでき、これはその文 字列がバッファーに挿入された後に実行される、割り当てられたLisp式を含むこ とができます。割り当てられた式はウィルスかもしれません。安全であるために はバッファーへ挿入する前に、ユーザーコードで計算されたすべての文字列から プロパティーを削除しなければなりません。 12.17 関数に関するその他トピック ================================ 以下のテーブルは関数呼び出しと関数定義に関連したことを行ういくつかの関数 です。これらは別の場所で説明されているので、ここではクロスリファレンスを 提供します。 ‘apply’ *note Calling Functions::を参照のこと。 ‘autoload’ *note Autoload::を参照のこと。 ‘call-interactively’ *note Interactive Call::を参照のこと。 ‘called-interactively-p’ *note Distinguish Interactive::を参照のこと。 ‘commandp’ *note Interactive Call::を参照のこと。 ‘documentation’ *note Accessing Documentation::を参照のこと。 ‘eval’ *note Eval::を参照のこと。 ‘funcall’ *note Calling Functions::を参照のこと。 ‘function’ *note Anonymous Functions::を参照のこと。 ‘ignore’ *note Calling Functions::を参照のこと。 ‘indirect-function’ *note Function Indirection::を参照のこと。 ‘interactive’ *note Using Interactive::を参照のこと。 ‘interactive-p’ *note Distinguish Interactive::を参照のこと。 ‘mapatoms’ *note Creating Symbols::を参照のこと。 ‘mapcar’ *note Mapping Functions::を参照のこと。 ‘map-char-table’ *note Char-Tables::を参照のこと。 ‘mapconcat’ *note Mapping Functions::を参照のこと。 ‘undefined’ *note Functions for Key Lookup::を参照のこと。 13 マクロ ********* “マクロ(macros)”により新たな制御構造や、他の言語機能の定義を可能にします 。マクロは関数のように定義されますが、値の計算方法を指定するかわりに、値 を計算する別のLisp式を計算する方法を指示します。わたしたちはこの式のこと をマクロの“展開(expansion)”と呼んでいます。 マクロは関数が行うように引数の値を処理するのではなく、引数にたいする 未評価の式を処理することによって、これを行うことができます。したがってマ クロは、これらの引数式かその一部を含む式を構築することができます。 て通常の関数が行えることをマクロを使用して行う場合、単にそれが速度面 の理由ならばかわりにインライン関数の使用を考慮してください。*note Inline Functions::を参照してください。 13.1 単純なマクロの例 ===================== 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’がインクリメントされま す。 -- Function: macrop object この述語はその引数がマクロかどうかテストして、もしマクロなら‘t’、そ れ以外は‘nil’をリターンする。 13.2 マクロ呼び出しの展開 ========================= マクロ呼び出しは関数の呼び出しと同じ外観をもち、マクロの名前で始まるリス トで表されます。そのリストの残りの要素はマクロの引数になります。 マクロ呼び出しの評価は1つの重大な違いを除いて、関数の評価と同じように 開始されます。重要な違いとはそのマクロの引数はマクロ呼び出し内で実際の式 として現れます。これらの引数はマクロ定義に与えられる前には評価されません 。対象的に関数の引数はその関数の呼び出しリストの要素を評価した結果です。 こうして得た引数を使用して、Lispは関数呼び出しのようにマクロ定義を呼 び出します。マクロの引数変数はマクロ呼び出しの引数値にバインドされるか、 a ‘&rest’引数の場合は引数地のリストになります。そしてそのマクロのbodyが 実行されて、関数bodyが行うようにマクロbodyの値をリターンします。 マクロと関数の2つ目の重要な違いは、マクロのbodyからリターンされる値が 代替となるLisp式であることで、これはマクロの“展開(expansion)”としても知 られています。Lispインタープリターはマクロから展開形が戻されると、すぐに その展開形の評価を行います。 展開形は通常の方法で評価されるので、もしかしたらその展開形は他のマク ロの呼び出しを含むかもしれません。一般的ではありませんが、もしかすると同 じマクロを呼び出すかもしれません。 EmacsはコンパイルされていないLispファイルをロードするときに、マクロの 展開を試みることに注意してください。これは常に利用可能ではありませんが、 もし可能ならそれ以降の実行の速度を改善します。*note How Programs Do Loading::を参照してください。 ‘macroexpand’を呼び出すことにより、与えられたマクロ呼び出しにたいする 展開形を確認することができます。 -- Function: macroexpand form &optional environment この関数はそれがマクロ呼び出しなら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’は展開されない -- Function: macroexpand-all form &optional environment ‘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))) -- Function: macroexpand-1 form &optional environment この関数は‘macroexpand’のようにマクロを展開するが、展開の1ステップ だけを行う。結果が別のマクロ呼び出しなら‘macroexpand-1’はそれを展開 しない。 13.3 マクロとバイトコンパイル ============================= なぜわざわざマクロにたいする展開形を計算して、その後に展開形を評価する手 間をかけるのか、不思議に思うかもしれません。なぜマクロbodyは直接望ましい 結果を生成しないのでしょうか? それはコンパイルする必要があるからです。 コンパイルされるLispプログラム内にマクロ呼び出しがあるとき、Lispコン パイラーはインタープリターが行うようにマクロ定義を呼び出して展開形を受け 取ります。しかし展開形を評価するかわりに、コンパイラーは展開形が直接プロ グラム内にあるかのようにコンパイルを行います。結果としてコンパイルされた コードはそのマクロにたいする値と副作用を生成しますが、実行速度は完全にコ ンパイルされたときと同じになります。もしマクロbody自身が値と副作用を計算 したら、このようには機能しません — コンパイル時に計算されることになり、 それは有用ではありません。 マクロ呼び出しのコンパイルが機能するためには、マクロを呼び出すコード がコンパイルされるとき、そのマクロがLisp内ですでに定義されていなければな りません。コンパイラーにはこれを行うのを助ける特別な機能があります。コン パイルされるファイルが‘defmacro’フォームを含むなら、そのファイルの残りの 部分をコンパイルするためにそのマクロが一時的に定義されます。 ファイルをバイトコンパイルすると、ファイル内のトップレベルにあるすべ ての‘require’呼び出しも実行されるので、それらを定義しているファイルを requireすることにより、コンパイルの間に必要なマクロ定義が利用できること が確実になります(*note Named Features::を参照)。誰かがコンパイルされたプ ログラムを_実行_するときに、マクロ定義ファイルのロードをしないようにする には、‘require’呼び出しの周囲に‘eval-when-compile’を記述します(*note Eval During Compile::を参照)。 13.4 マクロの定義 ================= Lispのマクロオブジェクトは、CARが‘macro’でCDRが関数であるようなリストで す。マクロの展開形はマクロ呼び出しから、_評価されていない_引数のリストに 、(‘apply’を使って)関数を適用することにより機能します。 無名関数のように無名Lispマクロを使用することも可能ですが、無名マクロ を‘mapcar’のような関数に渡すことに意味がないので、これが行われることはあ りません。実際のところすべてのLispマクロは名前をもち、ほとんど常に ‘defmacro’マクロで定義されます。 -- Macro: defmacro name args [doc] [declare] body... ‘defmacro’はシンボルNAME(クォートはしない)を、以下のようなマクロと して定義する: (macro lambda ARGS . BODY) (このリストのCDRはラムダ式であることに注意。) このマクロオブジェク トはNAMEの関数セルに格納される。ARGSの意味は関数の場合と同じで、キ ーワード‘&rest’や‘&optional’が使用されることもある(*note Argument List::を参照)。NAMEとARGSはどちらもクォートされるべきではない。 ‘defmacro’のリターン値は未定義。 DOCが与えられたら、それはマクロのドキュメント文字列を指定する文字列 であること。DECLAREが与えられたら、それはマクロのメタデータを指定す る‘declare’フォームであること(*note Declare Form::を参照)。マクロを 対話的に呼び出すことはできないので、インタラクティブ宣言をもつこと はできないことに注意。 マクロが定数部と非定数部の混合体から構築される巨大なリスト構造を必要 とする場合があります。これを簡単に行うためには‘`’構文(*note Backquote::を 参照)を使用します。たとえば: (defmacro t-becomes-nil (variable) `(if (eq ,variable t) (setq ,variable nil))) (t-becomes-nil foo) ≡ (if (eq foo t) (setq foo nil)) マクロ定義のbodyには、そのマクロに関する追加のプロパティーを指定する ‘declare’フォームを含めることができます。*note Declare Form::を参照して ください。 13.5 マクロ使用に関する一般的な問題 =================================== マクロ展開が直感に反する結果となることがあり得ます。このセクションでは問 題になりやすい重要な結果と、問題を避けるためにしたがうべきルールをいくつ か説明します。 13.5.1 タイミング間違い ----------------------- マクロを記述する際のもっとも一般的な問題として、展開形の中ではなくマクロ 展開中に早まって実際に何らかの作業を行ってしまうことがあります。たとえば 実際のパッケージが以下のマクロ定義をもつとします: (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’の呼び出しに展開され、そ れはコンパイルされたプログラム実行時に実行されるでしょう。 13.5.2 マクロ引数の多重評価 --------------------------- マクロを定義する場合、展開形が実行されるときに引数が何回評価されるか注意 を払わなければなりません。以下の(繰り返し処理を用意にする)マクロで、この 問題を示してみましょう。このマクロで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)))) 残念なことにこの訂正により以下のセクションで説明する、別の問題が発生 します。 13.5.3 マクロ展開でのローカル変数 --------------------------------- 前のセクションでは‘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)シ ンボルを使用することです(*note Creating Symbols::を参照)。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’のかわりに、式内のその位置に記述します。 13.5.4 展開におけるマクロ引数の評価 ----------------------------------- マクロ定義自体が‘eval’(*note Eval::を参照)の呼び出しなどによりマクロ引数 式を評価した場合には別の問題が発生します。その引数がユーザーの変数を参照 する場合、ユーザーがマクロ引数と同じ名前で変数を使用しようとした場合に問 題となるでしょう。マクロのbody内では、マクロ引数のバインディングはその変 数のもっともローカルなバインディングなので、そのフォーム内部の任意の参照 はそれを参照するように評価されます。以下は例です: (defmacro foo (a) (list 'setq (eval a) t)) (setq x 'b) (foo x) ↦ (setq b t) ⇒ t ; ‘b’がセットされる ;; but (setq a 'c) (foo a) ↦ (setq a t) ⇒ t ; しかし‘c’ではなく‘a’がセットされる ユーザーの変数の名前が‘a’か‘x’かということで違いが生じています。これ は‘a’がマクロの引数変数‘a’と競合しているからです。 マクロ定義内での‘eval’の呼び出しにまつわる別の問題は、それがおそらく コンパイル時にあなたが意図したことを行わないだろうということです。バイト コンパイラーは、そのプログラム自身の(あなたが‘eval’でアクセスしたいと望 む)計算が発生しない、ローカル変数バインディングも存在しないプログラムの コンパイル時にマクロ定義を実行します。 この問題を避けるためには、*マクロ展開形の計算では引数式を評価しないで ください*。かわりにその式をマクロ展開形の中に置き換えれば、その値は展開 形の実行の一部として計算されます。これは、このチャプターの他の例が機能す る方法です。 13.5.5 マクロが展開される回数は? -------------------------------- 逐次解釈される関数で毎回マクロ呼び出しが展開されるが、コンパイルされた関 数では(コンパイル時の)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)’にも使 うことはないでしょう。 13.6 マクロのインデント ======================= マクロ定義ではマクロ呼び出しをがどのようにインデントすべきか指定す るために、‘declare’フォーム(*note Defining Macros::を参照)を使うことがで きます。インデント指定は以下のように記述します: (declare (indent INDENT-SPEC)) この‘lisp-indent-function’プロパティ内の結果はマクロの名前にセットされま す。 以下は利用できるINDENT-SPECです: ‘nil’ これはプロパティーを指定しない場合と同じ — 標準的なインデントパター ンを使用する。 ‘defun’ この関数を‘def’構文 — 2番目の行が“body”の開始 — と同様に扱う。 整数: NUMBER 関数の最初のNUMBER個の引数は“区別”され、残りは式のbodyと判断される 。その式の中の行は、最初の引数が区別されているかどうかにしたがって インデントされる。引数がbodyの一部なら、その行はこの式の先頭の開カ ッコ(open-parenthesis)よりも‘lisp-body-indent’だけ多い列にインデン トされる。引数が区別されていて1つ目か2つ目の引数なら、_2倍_余分にイ ンデントされる。引数が区別されていて1つ目か2つ目以外の引数なら、そ の行は標準パターンによってインデントされる。 シンボル: SYMBOL SYMBOLは関数名。この関数はこの式のインデントを計算するために呼び出 される関数。この関数は2つの引数をとる: POS その行のインデントが開始される位置。 STATE その行の開始まで解析したとき、‘parse-partial-sexp’(インデント とネスト深さの計算のためのLispプリミティブ)によりリターンされ る値。 これは数(その行のインデントの列数)、またはそのような数がcarであるよ うなリストをリターンすること。数とリストの違いは、数の場合は同じネ スト深さの後続のすべての行はこの数と同じインデントとなる。リストな ら、後続の行は異なるインデントを呼び出すかもしれない。これは ‘C-M-q’によりインデントが計算されるときに違いが生じる。値が数なら ‘C-M-q’はリストの終わりまでの後続の行のインデントを再計算する必要は ない。 14 カスタマイゼーション設定 *************************** EmacsのユーザーはCustomizeインターフェースにより、Lispコードを記述するこ となく変数とフェースをカスタマイズできます。*note (emacs)Easy Customization::を参照してください。このチャプターではCustomizeインターフ ェースを通じて、ユーザーとやりとりするための“カスタマイズアイテム( customization items)”を定義する方法を説明します。 カスタマイズアイテムには‘defcustom’マクロ (*note Variable Definitions::を参照)で定義されるカスタマイズ可能変数 ‘defface’(*note Defining Faces::で個別に説明)で定義されるカスタマイズ可能フェイス、およ び‘defgroup’ (*note Group Definitions::を参照)で定義される “カスタマイゼ ーショングループ(customization groups)”が含まれ、これは関連するカスタマ イゼーションアイテムのコンテナとして振る舞います。 14.1 一般的なキーワードアイテム =============================== 以降のセクションで説明するカスタマイゼーション宣言(customization declaration) — ‘defcustom’、‘defgroup’などはすべてさまざまな情報を指定す るためのキーワード引数(*note Constant Variables::を参照)を受け取ります。 このセクションではカスタマイゼーション宣言のすべての種類に適用されるキー ワードを説明します。 ‘: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はライブラリー名を指定する文字列である。*note Library Headers::を参照のこと。 ‘(emacs-library-link LIBRARY)’ Emacs Lispライブラリーファイルへのリンク。LIBRARYはライブラリ ー名を指定する文字列である。 ‘(file-link FILE)’ ファイルへのリンク。FILEはユーザーがこのリンクを呼び出したとき に‘find-file’でvisitするファイルの名前を指定する文字列である。 ‘(function-link FUNCTION)’ 関数のドキュメントへのリンク。FUNCTIONはユーザーがこのリンクを 呼び出したときに‘describe-function’で説明を表示する関数の名前 を指定する文字列である。 ‘(variable-link VARIABLE)’ 変数のドキュメントへのリンク。VARIABLEはユーザーがこのリンクを 呼び出したときに‘describe-variable’で説明を表示する変数の名前 を指定する文字列である。 ‘(custom-group-link GROUP)’ 他のカスタマイゼーショングループへのリンク。このリンクを呼び出 すことによりGROUPにたいする新たなカスタマイゼーションバッファ ーが作成される。 LINK-DATAの1つ目の要素の後に‘:tag NAME’を追加することにより、カスタ マイゼーションバッファーで使用するテキストを指定できます。たとえば ‘(info-link :tag "foo" "(emacs)Top")’は、そのバッファーで‘foo’と表 示されるEmacs manualへのリンクを作成します。 複数のリンクを追加するために、このキーワードを複数回使用することが できます。 ‘:load FILE’ そのカスタマイゼーションアイテムを表示する前にファイルFILEをロード する(*note Loading::を参照)。ロードは‘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’変数も更新しなければな りません。 -- Variable: 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のようなパッケージの公 式名を選択するのがよいだろう。 14.2 カスタマイゼーショングループの定義 ======================================= Emacs Lispパッケージはそれぞれ、1つのメインのカスタマイゼーショングルー プ(main customization group)をもち、それにはすべてのオプションとフェイス 、そのパッケージ内の他のグループが含まれるべきです。そのパッケージに少数 のオプションとフェイスしかなければ、1つのグループだけを使用してその中に すべてを配置します。20以上のオプションやフェイスがあるなら、それらをサブ グループ内に構造化して、そのサブグループをメインのカスタマイゼーショング ループの下に配置します。そのパッケージ内の任意のオプションやフェイスを、 サブグループと並行してメイングループに配置しても問題はありません。 そのパッケージのメイングループ(または唯一のグループ)は、1つ以上の標準 カスタマイゼーショングループ(standard customization group)のメンバーであ るべきです(これらの完全なリストを表示するには‘M-x customize’を使用する )。それらの内から1つ以上(多すぎないこと)を選択して、‘:group’を使用してあ なたのグループをそれらに追加します。 新しいカスタマイゼーショングループは‘defgroup’で宣言します。 -- Macro: defgroup group members doc [keyword value]... MEMBERSを含むカスタマイゼーショングループとしてGROUPを宣言する。シ ンボルGROUPはクォートしない。引数DOCはそのグループにたいするドキュ メント文字列を指定する。 引数MEMBERSはそのグループのメンバーとなるカスタマイゼーションアイテ ムの初期セットを指定するリストである。しかしほとんどの場合は MEMBERSを‘nil’にして、メンバーを定義するときに‘:group’キーワードを 使用することによってそのグループのメンバーを指定する。 MEMBERSを通じてグループのメンバーを指定したければ、要素はそれぞれ ‘(NAME WIDGET)’という形式で指定すること。ここでNAMEはシンボル、 WIDGETはそのシンボルを編集するウィジェット型(widget type)である。変 数には‘custom-variable’、フェイスにはる‘custom-face’、グループには ‘custom-group’が有用なウィジェットである。 Emacsに新しいグループを導入するときは‘defgroup’内で‘:version’キーワ ードを使用する。そうすればグループの個別のメンバーにたいしてそれを 使用する必要がなくなる。 一般的なキーワード(*note Common Keywords::を参照)に加えて、 ‘defgroup’内では以下のキーワードも使用できる: ‘:prefix PREFIX’ グループ内のアイテムの名前がPREFIXで始まり、カスタマイズ変数 ‘custom-unlispify-remove-prefixes’が非‘nil’なら、そのアイテム のタグからPREFIXが省略される。グループは任意の数のプレフィクス をもつことができる。 -- User Option: custom-unlispify-remove-prefixes この変数が非‘nil’ならグループの‘:prefix’キーワードで指定されたプレ フィクスは、ユーザーがグループをカスタマイズするときは常にタグ名か ら省略される。 デフォルト値は‘nil’、つまりプレフィクス省略(prefix-discarding)の機 能は無効となる。これはオプションやフェイスの名前にたいするプレフィ クスの省略が混乱を招くことがあるからである。 14.3 カスタマイゼーション変数の定義 =================================== “カスタマイズ可能変数(customizable variable)”は“ユーザーオプション(user option)”とも呼ばれ、これはCustomizeインターフェースを通じてセットできる グローバルなLisp変数です。‘defvar’(*note Defining Variables::を参照)デ定 義される他のグローバル変数と異なり、カスタマイズ可能変数は‘defcustom’マ クロを使用して定義されます。サブルーチンとして‘defvar’を呼び出すことに加 えテ、‘defcustom’はCustomizeインターフェースでその変数が表示される方法や 、その変数がとることができる値などを明示します。 -- Macro: defcustom option standard doc [keyword value]... このマクロはユーザーオプション(かカスタマイズ可能変数)として OPTIONを宣言する。OPTIONはクォートしないこと。 引数STANDARDはOPTIONの標準値を指定する式である。‘defcustom’フォーム の評価によりSTANDARDが評価されるが、その値にそのオプションをバイン ドする必要はない。OPTIONがすでにデフォルト値をもつなら、それは変更 されずに残る。ユーザーがすでにOPTIONにたいするカスタマイゼーション を保存していれば、ユーザーによりカスタマイズされた値がデフォルト値 としてインストールされる。それ以外ならSTANDARDを評価した結果がデフ ォルト値としてインストールされる。 ‘defvar’と同様、このマクロは‘option’をスペシャル変数 — 常にダイナミ ックにバインドされることを意味する — としてマークする。OPTIONがすで にレキシカルバインドをもつなら、そのレキシカルバインドはバインディ ング構文を抜けるまで効果をもつ。*note Variable Scoping::を参照のこ と。 式STANDARDは別の様々な機会 — カスタマイゼーション機能がOPTIONの標準 値を知る必要があるときは常に — にも評価される可能性がある。そのため 任意回数の評価を行ても安全な式を使用するように留意されたい。 引数DOCはその変数にたいするドキュメント文字列を指定する。 ‘defcustom’が何も‘:group’を指定しなければ、同じファイル内で ‘defgroup’によって最後に定義されたグループが使用される。この方法で はほとんどの‘defcustom’は明示的な‘:group’が不必要になる。 Emacs Lispモードで‘C-M-x’(‘eval-defun’)で‘defcustom’フォームを評価 するとき、‘eval-defun’の特別な機能は変数の値がvoidかどうかテストせ ずに、無条件に変数をセットするよう段取りする(同じ機能は‘defvar’にも 適用される。*note Defining Variables::を参照)。すでに定義された defcustomで‘eval-defun’を使用することにより、(もしあれば)‘:set’関数 (以下参照)が呼び出される。 事前ロード(pre-loaded)されたEmacs Lispファイル(*note Building Emacs::を参照)に‘defcustom’を配置すると、ダンプ時にインストールされ た標準値は正しくない — たとえば依存している他の変数がまだ正しい値を 割り当てられていない — かもしれない。この場合はEmacs起動後に標準値 を再評価するために、以下で説明する‘custom-reevaluate-setting’を使用 する。 *note Common Keywords::にリストされたキーワードに加えて、このマクロに は以下のキーワードを指定できる ‘:type TYPE’ このオプションのデータ型としてTYPEを使用する。これはどんな値が適正 なのか、その値をどのように表示するかを指定する(*note Customization Types::を参照)。‘defcustom’はそれぞれこのキーワードにたいする値を指 定すること。 ‘:options VALUE-LIST’ このオプションに使用する適正な値のリストを指定する。ユーザーが使用 できる値はこれらの値に限定されないが、これらは便利な値の選択肢を提 示する。 これは特定の型にたいしてのみ意味をもち現在のところ‘hook’、‘plist’、 ‘alist’が含まれる。‘:options’を使用する方法は個別の型の定義を参照の こと。 ‘:set SETFUNCTION’ Customizeインターフェースを使用してこのオプションの値を変更する方法 としてSETFUNCTIONを指定する。関数SETFUNCTIONは2つの引数 — シンボル (オプション名)と新しい値 — を受け取り、このオプションにたいして正し く値を更新するために必要なことは何であれ行うこと(これはおそらく Lisp変数として単にオプションをセットすることを意味しない)。この関数 は引数の値を破壊的に変更しないことが望ましい。SETFUNCTIONのデフォル トは‘set-default’。 このキーワードを指定すると、その変数のドキュメント文字列には手入力 のLispコードで同じことを行う方法が記載されること。 ‘:get GETFUNCTION’ このオプションの値を抽出する方法としてGETFUNCTIONを指定する。関数 GETFUNCTIONは1つの引数(シンボル)を受け取り、カスタマイズがそのシン ボル(シンボルのLisp値である必要はない)にたいするカレント値としてそ れを使うべきかどうかをリターンすること。デフォルトは ‘default-value’。 ‘:get’を正しく使用するためには、Customの機能を真に理解する必要があ る。これは変数としてCustom内で扱われる値のためのものだが、実際には Lisp変数には格納されない。実際にLisp変数に格納されている値に GETFUNCTIONを指定するのは、ほとんどの場合は誤りである。 ‘:initialize FUNCTION’ FUNCTIONは‘defcustom’が評価されるときに変数を初期化するために使用さ れる関数であること。これは2つの引数 — オプション名(シンボル)と値を 受け取る。この方法での使用のために事前定義された関数がいくつかある: ‘custom-initialize-set’ 変数の初期化にその変数の‘:set’関数を使用するが、値がすでに非 voidなら再初期化を行わない。 ‘custom-initialize-default’ ‘custom-initialize-set’と同様だが、その変数の‘:set’のかわりに 関数‘set-default’を使用して変数をセットする。これは変数の ‘:set’関数がマイナーモードを有効または無効にする場合の通常の選 択である。この選択により変数の定義ではマイナーモード関数を呼び 出しは行わないが、変数をカスタマイズしたときはマイナーモード関 数を呼び出すだろう。 ‘custom-initialize-reset’ 変数の初期化に常に‘:set’関数を使用する。変数がすでに非voidなら 、(‘:get’メソッドでリターンされる)カレント値を使用して‘:set’関 数を呼び出して変数をリセットする。これはデフォルトの ‘:initialize’関数である。 ‘custom-initialize-changed’ 変数がすでにセットされている、またはカスタマイズされているなら 、変数の初期化のために‘:set’関数を使用して、それ以外なら単に ‘set-default’を使用する。 ‘custom-initialize-safe-set’ ‘custom-initialize-safe-default’ これらのn関数は‘custom-initialize-set’、 ‘custom-initialize-default’と同様に振る舞うがエラーをcatchする 。初期化中にエラーが発生したら、‘set-default’を使用して変数を ‘nil’にセットして、エラーのシグナルはしない。 これらの関数は事前ロードされたファイルで定義されたオプションの ためのものである(requireされた変数や関数がまだ定義されていない ため、STANDARD式はエラーをシグナルするかもしれない)。その値は 通常は‘startup.el’で更新され、‘defcustom’により計算された値は 無視される。startup後にその値をunsetして‘defcustom’を再評価す れば、エラーなしでSTANDARDは評価される。 ‘:risky VALUE’ その変数の‘risky-local-variable’プロパティーをVALUEにセットする (*note File Local Variables::を参照)。 ‘:safe FUNCTION’ その変数の‘safe-local-variable’プロパティーをFUNCTIONにセットします (*note File Local Variables::を参照)。 ‘:set-after VARIABLES’ 保存されたカスタマイゼーションに合わせて変数をセッティングするとき は、その前に変数VARIABLES確実にセット — つまりこれら他のものが処理 される後までセッティングを遅延 — すること。これら他の変数が意図され た値をもっていない場合に、この変数のセッティングが正しく機能しなけ れば‘:set-after’を使用すること。 特定の機能をオンに切り替えるオプションにたいしては、‘:require’キーワ ードを指定すると便利です。これはその機能がまだロードされていないときは、 そのオプションがセットされるとEmacsがその機能をロードするようにします。 *note Common Keywords::を参照してください。以下はライブラリー ‘saveplace.el’の例です: (defcustom save-place nil "Non-nil means automatically save place in each file..." :type 'boolean :require 'saveplace :group 'save-place) あるカスタマイゼーションアイテムが‘:options’がサポートする‘hook’や ‘alist’のような型をもつなら、‘custom-add-frequent-value’を呼び出すことに よって‘defcustom’宣言の外部から別途値を追加できます。たとえば ‘emacs-lisp-mode-hook’から呼び出されることを意図した関数 ‘my-lisp-mode-initialization’を定義する場合は、‘emacs-lisp-mode-hook’に たいする正当な値として、その定義を編集することなくその関数をリストに追加 したいと思うかもしれません。これは以下のようにして行うことができます: (custom-add-frequent-value 'emacs-lisp-mode-hook 'my-lisp-mode-initialization) -- Function: custom-add-frequent-value symbol value カスタマイズオプションSYMBOLにたいして正当な値のリストにVALUEを追加 する。 追加による正確な効果はSYMBOLのカスタマイズ型に依存する。 ‘defcustom’は内部的に、標準値にたいする式の記録にシンボルプロパティ ‘standard-value’、カスタマイゼーションバッファーでユーザーが保存した値の 記録に‘saved-value’、カスタマイゼーションバッファーでユーザーがセットし て未保存の値の記録に‘customized-value’を使用します。*note Symbol Properties::を参照してください。これらのプロパティは、carがその値を評価 する式であるようなリストです。 -- Function: custom-reevaluate-setting symbol この関数は‘defcustom’を通じて宣言されたユーザーオプションSYMBOLの標 準値を再評価する。変数がカスタマイズされたなら、この関数はかわりに 保存された値を再評価する。それからこの関数はその値に、(もし定義され ていればそのオプションの‘:set’プロパティーを使用して)ユーザーオプシ ョンをセットする。 これは値が正しく計算される前に定義されたカスタマイズ可能オプション にたいして有用である。たとえばstartupの間、Emacsは事前ロードされた Emacs Lispファイルで定義されたユーザーオプションにたいしてこの関数 を呼び出すが、これらの初期値は実行時だけ利用可能な情報に依存する。 -- Function: custom-variable-p arg この関数はARGがカスタマイズ可能変数なら非‘nil’をリターンする。カス タマイズ可能変数とは、‘standard-value’か‘custom-autoload’プロパティ ーをもつ(通常は‘defcustom’で宣言されたことを意味する)変数、または別 のカスタマイズ可能変数にたいするエイリアスのことである。 14.4 カスタマイゼーション型 =========================== ‘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ペアー(*note Type Keywords::を参照)を記 述できます。 いくつかの型シンボルは引数を使用しません。これらは“シンプル型(simple types)”と呼ばれます。シンプル型ではkeyword-valueペアーを使用しないなら、 型シンボルの周囲のカッコ(parentheses)を省略できます。たとえばカスタマイ ゼーション型として単に‘string’と記述すると、それは‘(string)’と等価です。 すべてのカスタマイゼーション型はウィジェットとして実装されます。詳細 は、*note Introduction: (widget)Top.を参照してください。 14.4.1 単純型 ------------- このセクションではすべてのシンプルデータ型を説明します。これらのカスタマ イゼーション型のうちのいくつかにたいして、カスタマイゼーションウィジェッ トは‘C-M-i’か‘M-’によるインライン補完を提供します。 ‘sexp’ 値はプリントと読み込みができる任意のLispオブジェクト。より特化した 型を使用するために時間をとりたくなければ、すべてのオプションにたい するフォールバックとして‘sexp’を使用することができる。 ‘integer’ 値は整数でなければならない。 ‘number’ 値は数(浮動小数点数か整数)でなければならない。 ‘float’ 値は浮動小数点数でなければならない。 ‘string’ 値は文字列でなければならない。カスタマイゼーションバッファーはその 文字列を区切り文字‘"’文字と‘\’クォートなしで表示する。 ‘regexp’ ‘string’文字と同様だがその文字列は有効な正規表現でなければならない 。 ‘character’ 値は文字コードでなければならない。文字コードは実際には整数だが、こ の型は数字を表示せずにバッファー内にその文字を挿入することにより値 を表示する。 ‘file’ 値はファイル名でなければならない。ウィジェットは補完を提供する。 ‘(file :must-match t)’ 値は既存のファイル名でなければならない。ウィジェットは補完を提供す る。 ‘directory’ 値はディレクトリー名でなければならない。ウィジェットは補完を提供す る。 ‘hook’ 値は関数のリストでなければならない。このカスタマイゼーション型はフ ック変数にたいして使用される。フック内で使用を推奨される関数のリス トを指定するために、フック変数の‘defcustom’内で‘:options’キーワード を使用できる。*note Variable Definitions::を参照のこと。 ‘symbol’ 値はシンボルでなければならない。これはカスタマイゼーションバッファ ー内でシンボル名として表示される。ウィジェットは補完を提供する。 ‘function’ 値はラムダ式か関数名でなければならない。ウィジェットは関数名にたい する補完を提供する。 ‘variable’ 値は変数名でなければならない。ウィジェットは補完を提供する。 ‘face’ 値はフェイス名のシンボルでなければならない。ウィジェットは補完を提 供する。 ‘boolean’ 値は真偽値 — ‘nil’か‘t’である。‘choice’と‘const’を合わせて使用する ことにより(次のセクションを参照)、値は‘nil’か‘t’でなければならない が、それら選択肢に固有の意味に適合する方法でそれぞれの値を説明する テキストを指定することもできる。 ‘key-sequence’ 値はキーシーケンス。カスタマイゼーションバッファーは‘kbd’関数と同じ 構文を使用してキーシーケンスを表示する。*note Key Sequences::を参照 のこと。 ‘coding-system’ 値はコーディングシステム名でなければならず、‘M-’で補完すること ができる。 ‘color’ 値は有効なカラー名でなければならない。ウィジェットはカラー名にたい する補完と、同様に‘*Colors*’バッファーに表示されるカラーサンプルと カラー名のリストからカラー名を選択するボタンを提供する。 14.4.2 複合型 ------------- 適切なシンプル型がなければ複合型(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’(*note Variable Definitions::を参照)で指定することにより 、あるキーを優先的に扱うことができる。指定されたキーは、(適切な値と ともに)常にカスタマイゼーションバッファーに表示される。また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)情報 がプロパティーリスト(*note Property Lists::を参照)に格納されていて 、(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’キーワード を使用して有効なデフォルト値を指定すること。*note Type Keywords::を 参照のこと。 複数の候補によりいくつかの値が提供されるなら、カスタマイズは適合す る値をもつ最初の候補を選択する。これは常にもっとも特有な型が最初で 、もっとも一般的な型が最後にリストされるべきことを意味する。以下は 適切な使い方の例である (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はリストで、リストの各要素は以下 のうちのいずれかを満たす必要がある: • 述語 — つまり副作用をもたず引数は1つで、その引数に応じて ‘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’と記述する 必要があるのは稀である。なぜなら最後のキーワード/値ペアーの後に続く ものは何であれ、引数として認識されるからである。 14.4.3 リストへのスプライス --------------------------- ‘:inline’機能により可変個の要素を、カスタマイゼーション型の‘list’や ‘vector’の途中にスプライス(splice: 継ぎ足す)することができます。‘list’や ‘vector’記述を含む型にたいして‘:inline t’を追加することによってこれを使 用します。 ‘list’や‘vector’型の仕様は、通常は単一の要素型を表します。しかしエン トリーが‘:inline t’を含むなら、マッチする値は含まれるシーケンスに直接マ ージされます。たとえばエントリーが3要素のリストにマッチするなら、全体が 3要素のシーケンスになります。これはバッククォート構文(*note Backquote::を 参照)の‘,@’に類似しています。 たとえば最初の要素が‘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つ目の要素は文字列でなければなりま せん。 14.4.4 型キーワード ------------------- カスタマイゼーション型内の型名シンボルの後にキーワード/引数ペアーを指定 できます。以下は使用できるキーワードとそれらの意味です: ‘:value DEFAULT’ デフォルト値を提供する。 その候補にたいして‘nil’が有効な値でなければ、‘:value’に有効なデフォ ルトを指定することが必須となる。 ‘choice’の内部の選択肢として出現する型にたいしてこれを使用するなら 、ユーザーがカスタマイゼーションバッファー内のメニューでその選択肢 を選択したときに使用するデフォルト値を最初に指定する。 もちろんオプションの実際の値がこの選択肢に適合するなら、DEFAULTでは なく実際の値が表示される。 ‘:format FORMAT-STRING’ この文字列はその型に対応する値を記述するために、バッファーに挿入さ れる。FORMAT-STRING内では以下の‘%’エスケープが利用できる: ‘%[BUTTON%]’ ボタンとしてマークされたテキストBUTTONを表示する。‘:action’属 性はユーザーがそれを呼び出したときに、そのボタンが何を行うか指 定する。この属性の値は2つの引数 — ボタンが表示されるウィジェッ トとイベント — を受け取る関数である。 異なるアクションを行う2つの異なるボタンを指定する方法はない。 ‘%{SAMPLE%}’ ‘:sample-face’により指定されたスペシャルフェイス内のSAMPLEを表 示する。 ‘%v’ そのアイテムの値を代替えする。その値がどのように表示されるかは アイテムの種類と、(カスタマイゼーション型にたいしては)カスタマ イゼーション型にに依存する。 ‘%d’ そのアイテムのドキュメント文字列を代替えする。 ‘%h’ ‘%d’と同様だが、ドキュメント文字列が複数行なら、ドキュメント文 字列全体か最初の行だけかを制御するボタンを追加する。 ‘%t’ その位置でタグに置き換える。‘:tag’キーワードでタグを指定する。 ‘%%’ リテラル‘%’を表示する。 ‘:action ACTION’ ユーザーがボタンをクリックしたらACTIONを実行する。 ‘:button-face FACE’ ‘%[...%]’で表示されたボタンテキストにたいして、フェイスFACE(フェイ ス名、またはフェイス名のリスト)を使用する。 ‘:button-prefix PREFIX’ ‘:button-suffix SUFFIX’ これらはボタンの前か後に表示されるテキストを指定する。以下が指定で きる: ‘nil’ テキストは挿入されない。 文字列 その文字列がリテラルに挿入される。 シンボル そのシンボルの値が使用される。 ‘:tag TAG’ この型に対応する値(または値の一部)にたいするタグとしてTAG(文字列)を 使用する。 ‘:doc DOC’ この型に対応する値(か値の一部)にたいするドキュメント文字列として DOCを使用する。これが機能するためには‘:format’にたいする値を指定し て、その値にたいして‘%d’か‘%h’を使用しなければならない。 ある型にたいしてドキュメント文字列を指定するのは、‘:choice’内の選択 肢の型や、他の複合型の一部について情報を提供するのが通常の理由であ る。 ‘:help-echo MOTION-DOC’ ‘widget-forward’や‘widget-backward’でこのアイテムに移動したときに、 エコーエリアに文字列MOTION-DOCを表示する。さらにマウスの ‘help-echo’文字列としてMOTION-DOCが使用され、これには実際には」ヘル プ文字列を生成するために評価される関数かフォームを指定できる。もし 関数ならそれは1つの引数(そのウィジェット)で呼び出される。 ‘:match FUNCTION’ 値がその型にマッチするか判断する方法を指定する。対応する値 FUNCTIONは2つの引数(ウィジェットと値)を受け取る関数であり、値が適切 なら非‘nil’をリターンすること。 ‘:validate FUNCTION’ 入力にたいして検証を行う関数を指定する。FUNCTIONは引数としてウィジ ェットを受け取り、そのウィジェットのカレント値がウィジェットにたい して有効なら‘nil’をリターンすること。それ以外なら無効なデータを含む ウィジェットをリターンして、そのウィジェットの‘:error’プロパティに 、そのエラーを記述する文字列をセットすること。 14.4.5 新たな型の定義 --------------------- 前のセクションでは、‘defcustom’にたいして型の詳細な仕様を作成する方法を 説明しました。そのような型仕様に名前を与えたい場合があるかもしれません。 理解しやすいケースとしては、多くのユーザーオプションに同じ型を使用する場 合などです。各オプションにたいして仕様を繰り返すよりその型に名前を与えて 、‘defcustom’それぞれにその名前を使用することができます。他にもユーザー オプションの値が再帰的なデータ構造のケースがあります。あるデータ型がそれ 自身を参照できるようにするためには、それが名前をもつ必要があります。 カスタマイゼーション型はウィジェットとして実装されているめ、新しいカ スタマイゼーション型を定義するには、新たにウィジェット型を定義します。こ こではウィジェットインターフェイスの詳細は説明しません。*note Introduction: (widget)Top.を参照してください。かわりにシンプルな例を用い て、カスタマイゼーション型を新たに定義するために必要な最小限の機能につい て説明します。 (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 binary-tree-of-string ’コマンドで参照することができます。 これらの必須の引数の後にキーワード引数が続きます。もっとも重要なのは ‘:type’で、これはこのウィジェットにマッチさせたいデータ型を表します。上 記の例では‘binary-tree-of-string’は文字列、またはcarとcdrが ‘binary-tree-of-string’であるようなコンスセルです。この定義中でのウィジ ェット型への参照に注意してください。‘:tag’属性はユーザーインターフェイス でウィジェット名となる文字列、‘:offset’引数はカスタマイゼーションバッフ ァーでのツリー構造の外観で,子ノードと関連する親ノードの間に4つのスペー スを確保します。 ‘defcustom’は通常のカスタマイゼーション型に使用される方法で新しいウィ ジェットを表示します。 ‘lazy’という名前の由来は、他のウィジェットではそれらがバッファーでイ ンスタンス化されるとき、他の合成されたウィジェットが下位のウィジェットを 内部形式に変換するからです。この変換は再帰的なので、下位のウィジェットは _それら自身_の下位ウィジェットへと変換されます。データ構造自体が再帰的な ら、その変換は無限再帰(infinite recursion)となります。‘lazy’ウィジェット は、‘:type’引数を必要なときだけ変換することによってこの再帰を防ぎます。 14.5 カスタマイゼーションの適用 =============================== 以下の関数には変数とフェイスにたいして、そのユーザーのカスタマイゼーショ ン設定をインストールする役目をもちます。それらの関数はユーザーが Customizeインターフェイスで‘Save for future sessions’を呼び出したとき、 次回のEmacs起動時に評価されるように‘custom-set-variables’フォーム、およ び/または‘custom-set-faces’フォームがカスタムファイルに書き込まれること によって効果をもちます。 -- Function: custom-set-variables &rest args この関数は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は即座にロードされる機能のリストである(*note Named Features::を参照)。COMMENTはそのカスタマイゼーションを説明す る文字列。 -- Function: custom-set-faces &rest args この関数はARGSにより指定されたフェイスのカスタマイゼーションをイン ストールする。ARGS内の引数はそれぞれ以下のようなフォームであること (FACE SPEC [NOW [COMMENT]]) FACEはフェイス名(シンボル)、SPECはそのフェイスにたいするカスタマイ ズされたフェイス仕様(*note Defining Faces::を参照)。 NOW、REQUEST、COMMENTエントリーは内部的な使用に限られており、省略さ れるかもしれない。NOWがもし非‘nil’なら、たとえ‘defface’フォームが評 価されていなくても、そのフェイス仕様がそのときセットされる。 COMMENTはそのカスタマイズを説明する文字列。 14.6 Customテーマ ================= “Customテーマ(Custom themes)”とはユニットとして有効や無効にできるセッテ ィングのコレクションです。*note (emacs)Custom Themes::を参照してください 。CustomテーマはそれぞれEmacs Lispソースファイルにより定義され、それらは このセクションで説明する慣習にしたがう必要があります(Customテーマを手作 業で記述するかわりに、Customize風のインターフェイスを使用して作成するこ ともできる。*note (emacs)Creating Custom Themes::を参照)。 Customテーマファイルは‘FOO-theme.el’のように命名すること。ここでFOOは テーマの名前。このファイルでの最初のLispフォームは‘deftheme’の呼び出しで 、最後のフォームは‘provide-theme’にすること。 -- Macro: deftheme theme &optional doc このマクロはCustomテーマの名前としてTHEME(シンボル)を宣言する。オプ ション引数DOCは、そのテーマを説明する文字列であること。この文字列は ユーザーが‘describe-theme’コマンドを呼び出したり、‘*Custom Themes*’バッファーで‘?’をタイプしたときに表示される。 2つの特別なテーマ名は禁止されている(使用するとエラーになる)。 ‘user’はそのユーザーの直接的なカスタマイズ設定を格納するためのダミ ーのテーマである。そし‘changed’はCustomizeシステムの外部で行われた 変更を格納するためのダミーのテーマである。 -- Macro: provide-theme theme このマクロは完全に仕様が定められたテーマ名THEMEを宣言する。 ‘deftheme’と‘provide-theme’の違いは、そのテーマセッティングを規定する Lispフォームです(通常は‘custom-theme-set-variables’の呼び出し、および/ま たは‘custom-theme-set-faces’の呼び出し)。 -- Function: custom-theme-set-variables theme &rest args この関数はCustomテーマTHEMEの変数のセッティングを規定する。THEMEは シンボル。ARGS内の各引数はフォームのリスト。 (VAR EXPRESSION [NOW [REQUEST [COMMENT]]]) ここでリストエントリーは‘custom-set-variables’のときと同じ意味をも つ。*note Applying Customizations::を参照のこと。 -- Function: custom-theme-set-faces theme &rest args この関数はCustomテーマTHEMEのフェイスのセッティングを規定する。 THEMEはシンボル。ARGS内の各引数はフォームのリスト。 (FACE SPEC [NOW [COMMENT]]) ここでリストエントリーは‘custom-set-faces’のときと同じ意味をもつ。 *note Applying Customizations::を参照のこと。 原則的にテーマファイルは他のLispフォームを含むこともでき、それらはそ のテーマがロードされるときに評価されるでしょうが、これは悪いフォームです 。悪意のあるコードを含むテーマのロードを防ぐために、最初に非ビルトインテ ーマをロードする前にEmacsはソースファイルを表示して、ユーザーにたいして 確認を求めます。 以下の関数は、テーマをプログラム的に有効または無効にするのに有用です: -- Function: custom-theme-p theme この関数はTHEME(シンボル)がCustomテーマの名前(たとえばそのテーマが 有効かどうかにかかわらず、CustomテーマがEmacsにロードされている)な ら非‘nil’をリターンする。それ以外は‘nil’をリターンする。 -- Variable: custom-known-themes この変数の値はEmacsにロードされたテーマのリストである。テーマはそれ ぞれLispシンボル(テーマ名)により表される。この変数のデフォルト値は 2つのダミーテーマ‘(user changed)’を含む。‘changed’テーマには Customテーマが適用される前に行われたセッティング(たとえばCustomの外 部での変数のセット)が格納されている。‘user’テーマにはそのユーザーが カスタマイズして保存したセッティングが格納されている。‘deftheme’マ クロで宣言されたすべての追加テーマは、このリストの先頭に追加される 。 -- Command: load-theme theme &optional no-confirm no-enable この関数はTHEMEという名前のCustomテーマを、変数 ‘custom-theme-load-path’で指定されたディレクトリーから探して、ソー スファイルからロードする。*note (emacs)Custom Themes::を参照のこと 。またそのテーマの変数とフェイスのセッティングが効果を及ぼすように テーマを“enables”にする(オプション引数NO-ENABLEが‘nil’の場合)。さら にオプション引数NO-CONFIRMが‘nil’なら、そのテーマをロードする前にユ ーザーに確認を求める。 -- Command: enable-theme theme この関数はTHEMEという名前のCustomテーマを有効にする。そのようなテー マがロードされていなければ、エラーをシグナルする。 -- Command: disable-theme theme この関数はTHEMEという名前のCustomテーマを無効にする。テーマはロード されたまま残るので、続けて‘enable-theme’を呼び出せばテーマは再び有 効になる。 15 ロード ********* 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プリミティブで必要となるとあらかじめ判明している外部ライブ ラリーのオンデマンドローディングについては、*note Dynamic Libraries::を 参照してください。 15.1 プログラムがロードを行う方法 ================================= Emacs Lispにはロードのためのインターフェイスがいくつかあります。たとえば ‘autoload’はファイル内で定義された関数にたいしてプレースホルダーとなるオ ブジェクトを作成します。この関数はオートロードされる関数を呼び出すために 、ファイルからその関数の実際の定義の取得を試みます(*note Autoload::を参 照)。‘require’はファイルがまだロードされていない場合にファイルをロードし ます(*note Named Features::を参照)。これらすべての関数は処理を行うために 最終的に‘load’を呼び出します。 -- Function: load filename &optional missing-ok nomessage nosuffix must-suffix この関数はLispコードのファイルを見つけてオープンして、その中のすべ てのフォームを評価してそのファイルをクローズする。 ‘load’はまずファイルを見つけるために、‘FILENAME.elc’という名前、つ まりFILENAMEに拡張子‘.elc’を足した名前のファイルを探す。このような ファイルが存在したらそれをロードする。Emacsがダイナミックモジュール (*note Dynamic Modules::を参照)のサポートつきでコンパイルされていれ ば、、次に‘load’は‘FILENAME.EXT’という名前のファイルを探す。ここで EXTは共有ライブラリーのシステム依存のファイル名拡張子である。その名 前のファイルが存在しなければ、‘load’は‘FILENAME.el’という名前のファ イルを探す。このファイルが存在したらそれをロードする。最後に、もし これらの名前がいずれも見つからなければ、‘load’は何も付け足さない FILENAMEという名前のファイルを探してそれが存在したらロードする (‘load’関数にFILENAMEを認識する賢さはない。‘foo.el.el’のような正し くない名前のファイルでも、‘(load "foo.el")’を評価してそれを見つけて しまうだろう)。 Auto Compressionモードが有効(残念ながらデフォルトでは有効)なら、 ‘load’は他のファイル名を試みる前に圧縮されたバージョンのファイル名 を探すのでファイルを見つけることができない。圧縮されたファイルが存 在したら、それを解凍してロードする。‘load’はファイル名に ‘jka-compr-load-suffixes’内の各サフィックスを足して圧縮されたバージ ョンを探す。この変数の値は文字列のリストでなければならない。標準的 な値は‘(".gz")’。 オプション引数NOSUFFIXが非‘nil’なら、‘load’はサフィックス‘.elc’と ‘.el’のロードを試みない。この場合はロードしたいファイルの正確な名前 を指定しなければならない。ただしAuto Compressionモードが有効なら ‘load’は圧縮されたバージョンを探すために、 ‘jka-compr-load-suffixes’を使用する。正確なファイル名を指定して、 NOSUFFIXに‘t’を使用することにより、‘foo.el.el’のような名前のファイ ルにたいするロードの試みを抑止できる。 オプション引数MUST-SUFFIXが非‘nil’の場合、ロードに使用されるファイ ルの名前に明示的にディレクトリー名が含まれていなければ、‘load’はフ ァイル名が‘.el’か‘.elc’、または共有ライブラリーの拡張子で終わること (もしかしたら圧縮による拡張子が付加されているかもしれない)を要求す る。 オプション‘load-prefer-newer’が非‘nil’なら、‘load’はサフィックスを 検索するとき、どんなファイル(‘.elc’、‘.el’等)であっても、もっとも最 近変更されたファイルのバージョンを選択する。 FILENAMEが‘foo’や‘baz/foo.bar’のような相対ファイル名なら、‘load’は 変数‘load-path’を使用してそのファイルを探す。これは‘load-path’内に リストされた各ディレクトリーにFILENAMEを追加して、最初に見つかった 名前のマッチするファイルをロードする。デフォルトディレクトリーを意 味する‘nil’が‘load-path’で措定されたときだけ、カレントデフォルトデ ィレクトリーを試みる。‘load’は‘load-path’内の最初のディレクトリーで 利用可能な3つのサフィックスすべてを試行してから、2つ目のディレクト リーで3つのサフィックスすべてを試行する、...というようにファイルを 探す。*note Library Search::を参照のこと。 最終的に見つかったファイル、およびEmacsがそのファイルを見つけたディ レクトリーが何であれ、Emacsはそのファイル名を変数‘load-file-name’の 値にセットする。 ‘foo.elc’が‘foo.el’より古いと警告されたら、それは‘foo.el’のリコンパ イルを考慮すべきことを意味する。*note Byte Compilation::を参照のこ と。 (コンパイルされていない)ソースファイルをロードしたとき、Emacsがファ イルをvisitしたときと同じように‘load’は文字セットの変換を行う。 *note Coding Systems::を参照のこと。 コンパイルされていないファイルをロードするとき、Emacsはそのファイル に含まれるすべてのマクロ(*note Macros::を参照)を展開する。わたした ちはこれを“eagerマクロ展開(eager macro expansion)”と呼んでいる。(関 連するコードを実行するまで展開を延期しないで)これを行うことにより、 コンパイルされていないコードの実行スピードが明らかに向上する。循環 参照によりこのマクロ展開を行うことができないときもある。これの一番 簡単な例は、ロードしようとしているファイルが他のファイルで定義され ているマクロを参照しているが、そのファイルはロードしようとしている ファイルを必要としている場合である。これは一般的には無害である。 Emacsは問題の詳細を与えるために警告(‘Eager macro-expansion skipped due to cycle...’)をプリントするが、単にその時点ではマクロを展開せず にそのファイルをロードする。あなたはこの問題が発生しないようにコー ドをリストラクチャーしたいと思うかもしれない。コンパイル済みファイ ルではマクロ展開はコンパイル時に行われるので、ロード時のマクロ展開 は行われない。*note Compiling Macros::を参照のこと。 NOMESSAGEが非‘nil’でなければ、エコーエリアに‘Loading foo...’や ‘Loading foo...done’のようなメッセージがロードの間に表示される。 ファイルをロードする間のハンドルされないエラーはロードを終了させる 。‘autoload’のためのロードの場合、ロードの間に定義された任意の関数 定義は元に戻される。 ‘load’がロードするファイルを見つけられいと、通常は(‘Cannot open load file FILENAME’メッセージとともに)エラー‘file-error’がシグナル される。しかしMISSING-OKが非‘nil’なら、‘load’は単に‘nil’をリターン する。 式の読み取りにたいして‘load’が‘read’のかわりに使用する関数を指定す るために、変数‘load-read-function’を使用できる。以下を参照されたい 。 ファイルが正常にロードされたら、‘load’は‘t’をリターンする。 -- Command: load-file filename このコマンドはファイルFILENAMEをロードする。FILENAMEが相対ファイル 名のなら、それはカレントデフォルトディレクトリーを指定したとみなさ れる。このコマンドは‘load-path’を使用せず、サフィックスの追加もしな い。しかし(Auto Compressionモードが有効なら)圧縮されたバージョンの 検索を行う。ロードするファイル名を正確に指定したければ、このコマン ドを使用すること。 -- Command: load-library library このコマンドはLIBRARYという名前のライブラリーをロードする。このコマ ンドは引数を読み取る方法がインタラクティブであることを除き‘load’と 同じ。*note (emacs)Lisp Libraries::を参照のこと。 -- Variable: load-in-progress この変数はEmacsがファイルをロード中なら非‘nil’、それ以外は‘nil’であ る。 -- Variable: load-file-name このセクションの最初に説明した検索でEmacsがファイルを見つけて、その ファイルをロード中のとき、この変数の値はそのファイルの名前である。 -- Variable: load-read-function この変数は‘load’と‘eval-region’が式を読み取るために、‘read’のかわり に使用する関数を指定する。指定する関数は‘read’と同様、引数が1つの関 数であること。 デフォルトではこの変数の値は‘read’。*note Input Functions::を参照の こと。 この変数を使用するかわりに別の新たな方法を使用するほうが明確である 。それは‘eval-region’のREAD-FUNCTION引数にその関数を渡す方法である 。*note Eval: Definition of eval-region.を参照のこと。 Emacsのビルドで‘load’がどのように使用されているかについての情報は、 *note Building Emacs::を参照のこと。 15.2 ロードでの拡張子 ===================== ここでは‘load’が試行するサフィックスについて、技術的な詳細を説明します。 -- Variable: load-suffixes これは(ソースまたはコンパイル済みの)Emacs Lispファイルを示すサフィ ックスのリストである。空の文字列が含まないこと。‘load’は指定された ファイル名にLispファイルのサフィックスを追加するときに、これらのサ フィックスを使用する。標準的な値は‘(".elc" ".el")’で、これは前のセ クションで説明した振る舞いとなる。 -- Variable: load-file-rep-suffixes これは同じファイルにたいして異なる表現を示すサフィックスのリストで ある。このリストは空の文字列から開始されること。‘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")’である。 -- Function: get-load-suffixes この関数は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’なら後者がスキップされる。 -- User Option: load-prefer-newer このオプションが非‘nil’なら、ファイルが見つかった最初のサフィックス で停止せずに、‘load’はすべてのサフィックスをテストして、一番新しい ファイルを使用する。 15.3 ライブラリー検索 ===================== EmacsがLispライブラリーをロードするときは、変数‘load-path’により指定され るディレクトリー内のライブラリーを検索します。 -- Variable: load-path この変数の値は‘load’でファイルをロードするときに検索するディレクト リーのリストである。リストの各要素は文字列(ディレクトリー名でなけれ ばなりません)、または‘nil’(カレントワーキングディレクトリーを意味す る)である。 Emacsは起動時にいくつかのステップにより‘load-path’の値をセットアップ する。最初にEmacsがコンパイルされたときのデフォルトロケーションセット (default locations set)を使用して、‘load-path’を初期化する。通常これは以 下のようなディレクトリーである "/usr/local/share/emacs/VERSION/lisp" (以降の例ではあなたがインストールしたEmacsのインストールプレフィクス に合うように‘/usr/local’を置き換えること。) これらのディレクトリーには、 Emacsとともにインストールされた標準的なLispファイルが含まれる。Emacsがこ れらを見つけられなければ正常に起動しないだろう。 Emacsをビルドしたディレクトリーから起動した場合 −−− つまり正式にイン ストールされた実行形式ではないEmacsを起動した場合 — 、Emacsはビルドされ たディレクトリーのソースの‘lisp’ディレクトリーを使用して‘load-path’を初 期化する。ソースとは別のディレクトリーでEmacsをビルドした場合は、ビルド したディレクトリーの‘lisp’ディレクトリーも追加する(いずれも要素は絶対フ ァイル名になる)。 ‘--no-site-lisp’オプションでEmacsを起動した場合を除き、‘load-path’の 先頭にさらに2つの‘site-lisp’を追加する。これらはローカルにインストールさ れたLispファイルで、通常は: "/usr/local/share/emacs/VERSION/site-lisp" および "/usr/local/share/emacs/site-lisp" の形式である。1つ目は特定のバージョンのEmacsにたいしてローカルにインスト ールされたものである。2つ目はインストールされたすべてのバージョンの Emacsが使用することを意図してローカルにインストールされたものである(イン ストールされたものでないEmacsが実行されると、もし存在すればソースディレ クトリーとビルドディレクトリーの‘site-lisp’ディレクトリーも追加される。 これらのディレクトリーは通常は‘site-lisp’ディレクトリーを含まない)。 環境変数‘EMACSLOADPATH’がセットされていたら、上述の初期化プロセスが変 更される。Emacsはこの環境変数の値にもとづいて‘load-path’を初期化する。 ‘EMACSLOADPATH’の構文は、‘PATH’で使用される構文と同様である。ディレク トリー名は‘:’(オペレーティングシステムによっては‘;’)で区切られる。 以下 は(‘sh’スタイルのシェルから)‘EMACSLOADPATH’変数をセットする例である: export EMACSLOADPATH=/home/foo/.emacs.d/lisp: 環境変数の値内の空の要素は、(上記例のような)末尾、先頭、中間のいずれ にあるかに関わらず、標準の初期化処理により決定される‘load-path’のデフォ ルト値に置き換えられる。そのような空要素が存在しなければ ‘EMACSLOADPATH’により‘load-path’全体が指定される。空要素、または標準の Lispファイルを含むディレクトリーへの明示的なパスのいずれかを含めなければ ならない。さもないとEmacsが関数を見つけられなくなる(‘load-path’を変更す る他の方法は、Emacs起動時にコマンドラインオプション‘-L’を使用する方法で ある。以下参照)。 ‘load-path’内の各ディレクトリーにたいして、Emacsはそのディレクトリー がファイル‘subdirs.el’を含むか確認して、もしあればそれをロードする。 ‘subdirs.el’ファイルは、‘load-path’のディレクトリーにたいして任意のサブ ディレクトリーを追加するためのコードが含まれており、Emacsがビルド/インス トールされたときに作成される。サブディレクトリーと複数階層下のレベルのサ ブディレクトリーの両方が直接追加される。ただし名前の最初が英数字でないデ ィレクトリー、名前が‘RCS’または‘CVS’のディレクトリー、名前が ‘.nosearch’というファイルを含むディレクトリーは除外される。 次にEmacsはコマンドラインオプション‘-L’(*note (emacs)Action Arguments::を参照)で指定したロードディレクトリーを追加する。もしあればオ プションパッケージ(*note Packaging Basics::を参照)がインストールされた場 所も追加する。 initファイル(*note Init File::を参照)で‘load-path’に1つ以上のディレク トリーを追加するコードを記述するのは一般的に行なわれている。たとえば: (push "~/.emacs.d/lisp" load-path) Emacsのダンプには‘load-path’の特別な値を使用する。ダンプされたEmacsを カスタマイズするために‘site-load.el’か‘site-init.el’を使用する場合、これ らのファイルが行った‘load-path’にたいする変更はすべてダンプ後に失われる 。 -- Command: locate-library library &optional nosuffix path interactive-call このコマンドはライブラリーLIBRARYの正確なファイル名を探す。‘load’と 同じ方法でライブラリーを検索を行い、引数NOSUFFIXも‘load’の場合と同 じ意味をもつ。LIBRARYに指定する名前にはサフィックス‘.elc’または ‘.el’を追加しないこと。 PATHが非‘nil’なら‘load-path’のかわりにそのディレクトリーのリストが 使用される。 ‘locate-library’がプログラムから呼び出されたときはファイル名を文字 列としてリターンする。ユーザーがインタラクティブに ‘locate-library’を実行したときは、引数INTERACTIVE-CALLが‘t’となり、 これは‘locate-library’にたいしてファイル名をエコーエリアに表示する よう指示する。 -- Command: list-load-path-shadows &optional stringp このコマンドは“シャドー(shadowed)”されたEmacs Lispファイルを表示す る。シャドーされたファイルとは、‘load-path’のディレクトリーに存在す るにも関わらず、‘load-path’のディレクトリーリスト内で前の位置にある 他のディレクトリーに同じ名前のファイルが存在するため、通常はロード されないファイルのことである。 たとえば以下のように‘load-path’がセットされていたとする ("/opt/emacs/site-lisp" "/usr/share/emacs/23.3/lisp") そして両方のディレクトリーに‘foo.el’という名前のファイルがあるとす る。この場合、‘(require 'foo)’は決して2つ目のディレクトリーのファイ ルをロードしない。このような状況はEmacsがインストールされた方法に問 題があることを示唆する。 Lispから呼び出されたると、この関数はシャドーされたファイルリストを バッファー内に表示するかわりに、それのメッセージをプリントする。オ プション引数‘stringp’が非‘nil’なら、かわりにシャドーされたファイル を文字列としてリターンする。 15.4 非ASCII文字のロード ======================== Emacs Lispプログラムが非ASCII文字の文字列定数を含むとき、Emacsはそれらを ユニバイト文字列かマルチバイト文字列のいずれかで表現する場合があります。 どちらの表現が使用されるかは、そのファイルがどのようにEmacsに読み込まれ たかに依存します。マルチバイト表現へのデコーディングとともに読み込まれた 場合、Lispプログラム内のテキストはマルチバイトのテキストとなり、ファイル 内の文字列定数はマルチバイト文字列になります。(たとえば)Latin-1文字を含 むファイルをデコーディングなしで読み込むと、そのプログラムのテキストはユ ニバイトのテキストとなり、ファイル内の文字列定数はユニバイト文字列になり ます。*note Coding Systems::を参照してください。 マルチバイト文字列がユニバイトバッファーに挿入されるときは自動的にユ ニバイトに変換されるため、大部分のEmacs Lispプログラムにおいて、マルチバ イト文字列が非ASCII文字列であるという事実を意識させないようにするべきで す。しかしこれが行われことにより違いが生じる場合には、ローカル変数セクシ ョンに‘coding: raw-text’と記述することにより、特定のLispファイルを強制的 にユニバイトとして解釈させることができます。この識別子により、そのファイ ルは無条件でユニバイトとして解釈されます。これは‘?vLITERAL’で記述された 非ASCII文字にキーバインドするとき重要になります。 15.5 autoload ============= “オートロード(autoload: 自動ロード)”の機能により、定義されているファイル をロードすることなく関数やマクロの存在を登録できます。関数の最初の呼び出 しで、実際の定義とその他の関連するコードをインストールするために適切なラ イブラリーを自動的にロードして、すべてがすでにロードされていたかのように 実際の定義を実行します。関数やマクロのドキュメントを参照することによって もオートロードが発生します(*note Documentation Basics::を参照)。 オートロードされた関数をセットアップするには2つの方法があります。それ は‘autoload’を呼び出す方法と、ソースの実際の定義の前に、“マジック”コメン トを記述する方法です。‘autoload’はオートロードのための低レベルのプリミテ ィブです。任意のLispプログラムが、任意のタイミングで‘autoload’を呼び出す ことができます。Emacsとともにインストールされるパッケージにとって、マジ ックコメントは関数をオートロードできるようににするための一番便利な方法で す。そのコメント自身は何も行いませんが、コマンド ‘update-file-autoloads’にたいするガイドの役目を果たします。このコマンド は‘autoload’の呼び出しを構築して、Emacsビルド時に実行されるようにアレン ジします。 -- Function: autoload function filename &optional docstring interactive type この関数はFILENAMEから自動的にロードされるように、FUNCTIONという名 前の関数(かマクロ)を定義する。文字列FILENAMEにはFUNCTIONの実際の定 義を取得するファイルを指定する。 FILENAMEがディレクトリー名、またはサフィックス‘.el’と‘.elc’のいずれ も含まなければ、この関数はこれらのサフィックスのいずれかを強制的に 追加して、サフィックスがないただのFILENAMEという名前のファイルはロ ードしない(変数‘load-suffixes’により要求される正確なサフィックスが 指定される)。 引数DOCSTRINGはその関数のドキュメント文字列である。‘autoload’の呼び 出しでドキュメント文字列を指定することにより、その関数の実際の定義 をロードせずにドキュメントを見ることが可能になる。この引数の値は通 常は関数定義のドキュメント文字列と等しいこと。もし等しくなければ、 その関数定義のドキュメント文字列がロード時に有効になる。 INTERACTIVEが非‘nil’なら、その関数はインタラクティブに呼び出すこと が可能になる。これによりFUNCTIONの実際の定義をロードせずに、‘M-x’に よる補完が機能するようになる。ここでは完全なインタラクティブ仕様は 与えられない。完全な仕様はユーザーが実際にFUNCTIONを呼び出すまで必 要ない。ユーザーが実際に呼び出したときに、実際の定義がロードされる 。 普通の関数と同様、マクロとキーマップをオートロードできる。 FUNCTIONが実際にはマクロならTYPEに‘macro’、キーマップのならTYPEに ‘keymap’を指定する。Emacsのさまざまな部分では、実際の定義をロードせ ずにこれらの情報を知ることが必要とされる。 オートロードされたキーマップは、あるプレフィクスキーがシンボル FUNCTIONにバインドされているとき、キーを探す間に自動的にロードされ る。そのキーマップにたいする他の類のアクセスではオートロードは発生 しない。特にLispプログラムが変数の値からそのキーマップを取得して ‘define-key’を呼び出した場合には、たとえその変数の名前がシンボル FUNCTIONと同じであってもオートロードは発生しない。 FUNCTIONが非voidのオートロードされたオブジェクトではない関数定義を もつなら、その関数は何も行わずに‘nil’をリターンする。それ以外ならオ ートロードされたオブジェクト(*note Autoload Type::を参照)を作成して 、それをFUNCTIONにたいする関数定義として格納する。オートロードされ たオブジェクトは以下の形式をもつ: (autoload FILENAME DOCSTRING INTERACTIVE TYPE) たとえば、 (symbol-function 'run-prolog) ⇒ (autoload "prolog" 169681 t nil) このような場合、‘"prolog"’はロードするファイルの名前、169681は ‘emacs/etc/DOC’ファイル(*note Documentation Basics::を参照)内のドキ ュメント文字列への参照で、‘t’はその関数がインタラクティブであること 、‘nil’はそれがマクロやキーマップでないことを意味する。 -- Function: autoloadp object この関数はOBJECTがオートロードされたオブジェクトなら非‘nil’をリター ンする。たとえば‘run-prolog’がオートロードされたオブジェクトかチェ ックするには以下を評価する (autoloadp (symbol-function 'run-prolog)) オートロードされたファイルは、通常は他の定義を含み1つ以上の機能を必要 としたり、あるいは提供するかもしれません。(内容の評価でのエラーにより)そ のファイルが完全にロードされていなければ、そのロードの間に行われた関数定 義や‘provide’の呼び出しはアンドゥされます。これはそのファイルからオート ロードされる関数にたいして再度呼び出しを試みたときに、そのファイルを確実 に再ロードさせるためです。こうしないと、そのファイル内のいくつかの関数は アボートしたロードにより定義されていて、それらはロードされない修正後のフ ァイルで提供される正しいサブルーチンを欠くため、正しく機能しないからです 。 オートロードされたファイルが意図したLisp関数またはマクロの定義に失敗 すると、データ‘"Autoloading failed to define function FUNCTION-NAME"’と ともにエラーがシグナルされます。 オートロードのマジックコメント(“autoload cookie”とも呼ばれる)は、オー トロード可能なソースファイル内の実際の定義の直前にある、 ‘;;;###autoload’だけの行から構成されます。コマンド‘M-x update-file-autoloads’は、対応する‘autoload’呼び出しを‘loaddefs.el’内に 書き込みます(autoload cookieとなる文字列と‘update-file-autoloads’で生成 されるファイルの名前は上述のデフォルトから変更可能です。以下参照)。 Emacsのビルドでは‘loaddefs.el’をロードするために‘autoload’を呼び出します 。‘M-x update-directory-autoloads’はより強力です。このコマンドはカレント ディレクトリー内のすべてのファイルにたいするオートロードを更新します。 このマジックコメントは任意の種類のフォームを‘loaddefs.el’内にコピーで きます。このマジックコメントに続くフォームはそのままコピーされます。しか しオートロード機能が特別に処理するフォームの場合は_除外_されます(たとえ ば‘autoload’内への変換)。以下はそのままコピーされないフォームです: 関数や関数風オブジェクトの定義: ‘defun’と‘defmacro’。‘cl-defun’と‘cl-defmacro’(*note (cl)Argument Lists::を参照)、および‘define-overloadable-function’ (‘mode-local.el’内のコメントを参照)も該当する。 メジャーモードとマイナーモードの定義: ‘define-minor-mode’、‘define-globalized-minor-mode’、 ‘define-generic-mode’、‘define-derived-mode’、 ‘easy-mmode-define-minor-mode’、‘easy-mmode-define-global-mode’、 ‘define-compilation-mode’、‘define-global-minor-mode’。 その他のタイプの定義: ‘defcustom’、‘defgroup’、‘defclass’ (*note EIEIO: (eieio)Top.を参照 )、および‘define-skeleton’ (‘skeleton.el’内のコメントを参照)。 ビルド時にそのファイル自身をロードするときにフォームを_実行しない_よ うにするためにマジックコメントを使用することもできます。これを行なうには マジックコメントと同じ行にフォームを記述します。これはコメントなのでソー スファイルをロードするときには何も行いません。ただし‘M-x update-file-autoloads’では、Emacsビルド時に実行されたものは‘M-x update-file-autoloads’にコピーします。 以下はマジックコメントによるオートロードのために‘doctor’を準備する例 です: ;;;###autoload (defun doctor () "Switch to *doctor* buffer and start giving psychotherapy." (interactive) (switch-to-buffer "*doctor*") (doctor-mode)) これにより以下が‘loaddefs.el’内に書き込まれます: (autoload (quote doctor) "doctor" "\ Switch to *doctor* buffer and start giving psychotherapy. \(fn)" t nil) ダブルクォートの直後のバックスラッシュと改行は、‘loaddefs.el’のようなプ リロードされた未コンパイルのLispファイルだけに使用される慣習です。これは ‘make-docfile’にたいして、ドキュメント文字列を‘etc/DOC’ファイルに配置す るよう指示します。*note Building Emacs::を参照してください。また ‘lib-src/make-docfile.c’内のコメントも参照してください。ドキュメント文字 列の使い方(usage part)の中の‘(fn)’は、種々のヘルプ関数(*note Help Functions::を参照)が表示するときに、その関数の名前に置き換えられます。 関数定義手法として既知ではなく、認められてもいないような、通常とは異 なるマクロにより関数定義を記述した場合、通常のオートロードのマジックコメ ントの使用によって定義全体が‘loaddefs.el’内にコピーされるでしょう。これ は期待した動作ではありません。かわりに以下を記述することにより、意図した ‘autoload’呼び出しを‘loaddefs.el’内に配置することができます。 ;;;###autoload (autoload 'foo "myfile") (mydefunmacro foo ...) autoload cookieとしてデフォルト以外の文字列を使用して、デフォルトの ‘loaddefs.el’とは異なるファイル内に対応するオートロード呼び出しを記述で きます。これを制御するためにEmacsは2つの変数を提供します: -- Variable: generate-autoload-cookie この変数の値はLispコメントの文法に準じた文字列である。‘M-x update-file-autoloads’はそのcookieの後のLispフォームを、cookieが生 成したオートロードファイル内にコピーします。この変数のデフォルト値 は‘";;;###autoload"’。 -- Variable: generated-autoload-file この変数の値は、オートロード呼び出しが書き込まれるEmacs Lispファイ ルを命名する。デフォルト値は‘loaddefs.el’だが、(たとえば‘.el’ファイ ル内のセクションLocal Variables))をオーバーライドできる。オートロー ドファイルは、フォームフィード文字で開始される終端を含んでいると仮 定される。 以下の関数はオートロードオブジェクトにより指定されたライブラリーを明 示的にロードするために使用されるかもしれません: -- Function: autoload-do-load autoload &optional name macro-only この関数はオートロードオブジェクトAUTOLOADにより指定されたロードを 処理する。オプション引数NAMEに非‘nil’を指定するなら、関数値が AUTOLOADとなるシンボルを指定すること。この場合、この関数のリターン 値がそのシンボルの新しい関数値になる。オプション引数MACRO-ONLYの値 が‘macro’なら、この関数は関数ではなくマクロのロードだけを有効にする 。 15.6 多重ロード =============== 1つのEmacsセッション内でファイルを複数回ロードできます。たとえばバッファ ーで関数定義を編集して再インストールした後に元のバージョンに戻したいとき があるかもしれません。これは元のファイルをリロードすることにより行なうこ とができます。 ファイルのロードやリロードを行う際、‘load’と‘load-library’関数は未コ ンパイルのファイルではなく、バイトコンパイルされた同名のファイルを自動的 にロードすることに留意してください。ファイルを再記述して保存後に再インス トールする場合には、新しいバージョンをバイトコンパイルする必要があります 。さもないとEmacsは新しいソースではなく、古いバイトコンパイルされたファ イルをロードしてしまうでしょう! この場合にはファイルロード時に表示される メッセージに、そのファイルのリコンパイルを促す‘(compiled; note, source is newer)’というメッセージが含まれます。 Lispライブラリーファイル内にフォームを記述するときは、そのファイルが 複数回ロードされるかもしれないことに留意してください。たとえば、そのライ ブラリーをリロードするときには、各変数が再初期化されるべきかどうか考慮し てください。。変数がすでに初期化されていれば、‘defvar’はその変数の値を変 更しません(*note Defining Variables::を参照)。 alistに要素を追加するもっともシンプルな方法は、以下のようなものでしょ う: (push '(leif-mode " Leif") minor-mode-alist) しかしこれはそのライブラリーがリロードされると、複数の要素を追加してしま うでしょう。この問題を避けるには‘add-to-list’(*note List Variables::を参 照)を使用します: (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)) 15.7 名前つき機能 ================= ‘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’が使用されたときは、それをロードした ときと同様、そのファイルをバイトコンパイル(*note Byte Compilation::を参 照)するときにも効果が表れます。これはリクワイアされたパッケージがマクロ を含んでいて、バイトコンパイラーがそれを知らなければならない場合です。こ れは‘require’によりロードされるファイルで定義される関数と変数にへのバイ トコンパイラーの警告も無効にします。 バイトコンパイルの間にトップレベルの‘require’が評価されるとしても、 ‘provide’呼び出しは評価されません。したがって以下の例のように‘provide’の 後に同じ機能にたいする‘require’を含めることにより、バイトコンパイル前に 定義しているファイルを確実にロードできます。 (provide 'my-feature) ; バイトコンパイラーには無視され ; ‘load’には評価される (require 'my-feature) ; バイトコンパイラーにより評価される。 コンパイラーは‘provide’を無視して、その後に対象のファイルをロードするこ とにより‘require’が処理されます。ファイルのロードは‘provide’呼び出しを実 行するので、後続の‘require’はファイルがロードされていれば何も行いません 。 -- Function: provide feature &optional subfeatures この関数はカレントEmacsセッションにFEATUREがロードされたこと、ある いはロードされつつあることをアナウンスする。これはFEATUREに関連する 機能が他のLispプログラムから利用可能できる、あるいは利用可能になる ことを意味する。 ‘provide’呼び出にによる直接的な効果は、リストFEATURE内にまだ追加さ れていなければFEATUREの先頭にそれを追加して、それを必要としている ‘eval-after-load’コードを呼び出すことである(*note Hooks for Loading::を参照)。引数FEATUREはシンボルでなければならない。 ‘provide’はFEATUREをリターンする。 SUBFEATURESが与えられたら、それはFEATUREの当該バージョンによりプロ バイドされる特定のサブフィーチャのセットを示すシンボルのリストであ ること。‘featurep’を使用して、サブフィーチャの存在をテストできる。 そのパッケージがロードされるかどうか、あるいは与えられるバージョン で存在するかどうか不明であるようなあるパッケージ(1つのFEATURE)にお いて、パッケージの種々の部分やパッケージ機能に命名することでそのパ ッケージを使いやすくするのが困難なほど複雑なときに使用するというの がサブフィーチャのアイデアである。*note Network Feature Testing::の 例を参照されたい。 features ⇒ (bar bish) (provide 'foo) ⇒ foo features ⇒ (foo bar bish) オートロードによりあるファイルがロードされて、その内容の評価エラー によりストップしたときは、そのロードの間に発生した関数定義や ‘provide’呼び出しはアンドゥされる。*note Autoload::を参照のこと。 -- Function: require feature &optional filename noerror この関数はカレントEmacsセッションにおいて、FEATUREが存在するかどう かを(‘(featurep FEATURE)’を使用する。以下参照)をチェックする。引数 FEATUREはシンボルでなければならない。 そのフィーチャが存在しなければ、‘require’は‘load’によってFILENAMEを ロードする。FILENAMEが与えられなければ、シンボルFEATUREの名前がロー ドするファイル名のベースとして使用される。しかしこの場合、 ‘require’はFEATUREを探すためにサフィックス‘.el’と‘.elc’の追加を強制 する(圧縮ファイルのサフィックスに拡張されるかもしれない)。名前がた だのFEATUREというファイルは使用されない(変数‘load-suffixes’は要求さ れるLispサフィックスを正確に指定する)。 NOERRORが非‘nil’なら、ファイルの実際のロードにおけるエラーを抑止す る。この場合はそのファイルのロードが失敗すると‘require’は‘nil’をリ ターンする。通常では‘require’はFEATUREをリターンする。 ファイルのロードは成功したがFEATUREをプロバイドしていなければ、 ‘require’は‘Required feature FEATURE was not provided’のようにエラ ーをシグナルする。 -- Function: featurep feature &optional subfeature この関数はカレントEmacsセッションでFEATUREがプロバイドされていれば (たとえばFEATUREが‘features’のメンバーなら)‘t’をリターンする。 SUBFEATUREが非‘nil’なら、この関数はサブフィーチャも同様にプロバイド されているとき(たとえばSUBFEATUREがシンボルFEATUREのプロパティ ‘subfeature’のメンバーのとき)だけ‘t’をリターンする。 -- Variable: features この変数の値はシンボルのリストであり、そのシンボルはカレントEmacsセ ッションにロードされたフィーチャである。シンボルはそれぞれ ‘provide’を呼び出すことにより、このリストにputされたものである。リ スト‘features’内の要素の順番に意味はない。 15.8 どのファイルで特定のシンボルが定義されているか =================================================== -- Function: symbol-file symbol &optional type この関数はSYMBOLを定義しているファイルの名前をリターンする。TYPEが ‘nil’なら、どのようなタイプの定義も受け入れる。TYPEが‘defun’なら関 数定義、‘defvar’は変数定義、‘defface’はフェイス定義だけを指定する。 値は通常は絶対ファイル名である。定義がどのファイルにも関係しなけれ ば‘nil’になることもある。SYMBOLがオートロード関数を指定するなら、値 が拡張子なしの相対ファイル名になることもある。 ‘symbol-file’は変数‘load-history’の値にもとづく。 -- Variable: load-history この変数の値はロードされたライブラリーファイルの名前を、それらが定 義する関数と変数の名前、およびそれらがプロバイドまたはリクワイアす るフィーチャに関連付けるalistである。 このalist内の各要素は、1つのロード済みライブラリー(スタートアップ時 にプリロードされたライブラリーを含む)を記述する。要素はCARがライブ ラリーの絶対ファイル名(文字列)であるようなリストである。残りのリス ト要素は以下の形式をもつ: ‘VAR’ シンボルVARが変数として定義された。 ‘(defun . FUN)’ 関数FUNが定義された。 ‘(t . FUN)’ 関数FUNはそのライブラリーが関数として再定義する前はオートロー ドとして定義されていた。後続の要素は常に‘(defun . FUN)’であり 、これはFUNを関数として定義する。 ‘(autoload . FUN)’ 関数FUNはオートロードとして定義された。 ‘(defface . FACE)’ フェイスFACEが定義された。 ‘(require . FEATURE)’ フィーチャFEATUREがリクワイアされた。 ‘(provide . FEATURE)’ フィーチャFEATUREがプロバイドされた。 ‘(cl-defmethod METHOD SPECIALIZERS)’ ‘cl-defmethod’を使用してスペシャライザーSPECIALIZERSとともに METHODという名前が定義された。 ‘(define-type . TYPE)’ 型TYPEが定義された。 ‘load-history’の値には、CARが‘nil’であるような要素が1つ含まれるかも しれない。この要素はファイルをvisitしていないバッファーで ‘eval-buffer’により作成された定義を記述する。 コマンド‘eval-region’は‘load-history’を更新しますが、要素を置き換えず に、visitされているファイルの要素にたいして定義されたシンボルを追加しま す。*note Eval::を参照してください。 15.9 アンロード =============== 他のLispオブジェクト用にメモリーを回収するために、ライブラリーによりロー ドされた関数や変数を破棄することができます。これを行うには関数 ‘unload-feature’を使用します: -- Command: unload-feature feature &optional force このコマンドはフィーチャFEATUREをプロバイドしていたライブラリーをア ンロードする。そのライブラリー内の‘defun’、‘defalias’、‘defsubst’、 ‘defmacro’、‘defconst’、‘defvar’、‘defcustom’によって定義されたすべ ての関数、マクロ、変数は未定義になる。その後に、それらのシンボルに たいして事前に関連付けられていたオートロードをリストアする(ロードは シンボルの‘autoload’プロパティにこれらを保存している)。 以前の定義をリストアする前に、特定のフックからそのライブラリー内の 関数を取り除くために、‘unload-feature’は‘remove-hook’を実行する。こ れらのフックには名前が‘-hook’(または廃止されたサフィックス ‘-hooks’)で終わる変数、加えて‘unload-feature-special-hooks’、同様に ‘auto-mode-alist’にリストされた変数も含まれる。これは重要なフックが すでに定義されていない関数を参照をすることにより、Emacsの機能が停止 することを防ぐためである。 標準的なアンロードアクティビティでは、そのライブラリー内の関数の ELPプロファイリング、そのライブラリーによりプロバイドされたフィーチ ャ、そのライブラリーで定義された変数に保持されたタイマーを取り消す 。 これらの基準が機能不全を防ぐのに十分でなければ、ライブラリーは ‘FEATURE-unload-function’という名前の明示的なアンローダーを定義でき る。そのシンボルが関数として定義されていたら、‘unload-feature’は何 かを行う前にまず引数なしでそれを呼び出す。これはライブラリーのアン ロードのために適切なすべてのことを行うことができる。これが‘nil’をリ ターンしたら、‘unload-feature’は通常のアンロードアクションを処理す る。それ以外ならアンロード処理は完了したとみなす。 ‘unload-feature’は通常は他のライブラリーが依存するライブラリーのア ンロードを拒絶する(ライブラリーBにたいする‘require’がライブラリー Aに含まれるなら、AはBに依存している)。オプション引数FORCEが非 ‘nil’なら依存関係は無視されて、どのようなライブラリーもアンロードで きる。 ‘unload-feature’関数はLispで記述されており、その動作は変数 ‘load-history’にもとづきます。 -- Variable: unload-feature-special-hooks この変数はライブラリー内で定義された関数を取り除くために、ライブラ リーをアンロードする前にスキャンするフックのリストを保持する。 15.10 ロードのためのフック ========================== 変数‘after-load-functions’を使用することにより、Emacsがライブラリーをロ ードするたびにコードを実行させることができます: -- Variable: after-load-functions このアブノーマルフック(abnormal hook)は、ファイルをロードした後に実 行される。フック内の各関数は1つの引数(ロードされたファイルの絶対フ ァイル名)で呼び出される。 _特定_のライブラリーのロード後にコードを実行したければ、マクロ ‘with-eval-after-load’を使用します: -- Macro: with-eval-after-load library body... このマクロはLIBRARYがロードされるたびに、ファイルLIBRARYのロードの 最後でBODYが評価されるよう準備する。LIBRARYがすでにロード済みなら即 座にBODYを評価する。 ファイル名LIBRARYにディレクトリーや拡張子を与える必要はない。通常は 以下のようにファイル名だけを与える: (with-eval-after-load "edebug" (def-edebug-spec c-point t)) どのファイルが評価をトリガーするか制限するには、ディレクトリーか拡 張子、またはその両方をLIBRARYに含める。実際のファイル名(シンボリッ クリンク名はすべて除外される)が、与えられた名前すべてにマッチするフ ァイルだけがマッチとなる。以下の例ではどこかのディレクトリー ‘..../foo/bar’にある‘my_inst.elc’や‘my_inst.elc.gz’は評価をトリガー するが、‘my_inst.el’は異なる。: (with-eval-after-load "foo/bar/my_inst.elc" ...) LIBRARYはフィーチャ(たとえばシンボル)でもよく、その場合には ‘(provide LIBRARY)’を呼び出す任意のファイルの最後にBODYが評価される 。 BODY内でのエラーはロードをアンドゥしないが、BODYの残りの実行を防げ る。 上手く設計されたLispプログラムは、通常は‘with-eval-after-load’を使用 するべきではありません。(外部からの使用を意図した)他のライブラリーで定義 された変数を調べたりセットする必要があるなら、それは即座に行うことができ ます −−− そのライブラリーがロードされるのを待つ必要はありまん。そのライ ブラリーで定義された関数を呼び出す必要があるならそのライブラリーをロード すべきであって、それには‘require’(*note Named Features::を参照)が適して います。 15.11 Emacs Dynamic Modules =========================== “ダイナミックEmacsミジュール(dynamic Emacs module)”とは、Emacs Lispで記 述されたパッケージのように、Emacs Lispプログラムで使用するための追加機能 を提供する共有ライブラリーです。 Emacs Lispパッケージをロードする関数は、ダイナミックモジュールのロー ドもできます。これらの関数はファイル名の拡張子、いわゆる“サフィックス”を 調べることによってダイナミックモジュールを認識します。 -- Variable: module-file-suffix この変数はモジュールファイルのファイル名拡張子の、システム依存な値 を保持する。Posixホストでは‘.so’、MS-Windowsでは‘.dll’。 すべてのダイナミックモジュールはCから呼び出し可能な ‘emacs_module_init’という名前の関数をエクスポートする必要があります。 ‘load’か‘require’でそのモジュールをロードする一部として、Emacsはその関数 を呼び出します。モジュールのコードがGPLまたはGPL互換のライセンスの下にリ リースされたことを示す、‘plugin_is_GPL_compatible’という名前のシンボルも エクスポートしてください。Emacsはこのようなシンボルをエクスポートしない モジュールのロードを拒絶するでしょう。 モジュールがEmacs関数を呼び出す必要があるなら、Emacsディストリビュー ションに含まれるヘッダーファイル‘emacs-module.h’で定義およびドキュメント されているAPIを通じてこれを行ってください。 モジュールは、そのモジールで定義されたC構造体にたいする埋め込みポイン ターである‘user-ptr’Lispオブジェクトを作成できます。これはモジュールで作 成されてそのモジュールの関数に渡される複雑なデータ構造を保持するために有 用です。user-ptrオブジェクトはそれに関連付けられる“ファイナライザー (finalizers)”をもつこともできます。ファイナライザーとはオブジェクトがガ ーベージコレクションされたときに実行される関数のことです。 -- Function: user-ptrp object この関数は引数が‘user-ptr’オブジェクトなら‘t’をリターンする。 Emacsのロード可能モジュールは、configure時にオプション ‘--with-modules’を使用することにより有効になります。 16 バイトコンパイル ******************* Emacs LispにはLispで記述された関数をより効率的に実行できる、“バイトコー ド(byte-code)”と呼ばれる特別な表現に翻訳する“コンパイラー(compiler)”があ ります。コンパイラーはLispの関数定義をバイトコードに置き換えます。バイト コード関数が呼び出されたとき、その定義は“バイトコードインタープリター (byte-code interpreter)”により評価されます。 バイトコンパイルされたコードは、(本当のコンパイル済みコードのように )そのマシンのハードウェアによって直接実行されるのではなく、バイトコンパ イラーによって評価されるため、バイトコードはリコンパイルしなくてもマシン 間での完全な可搬性を有します。しかし本当にコンパイルされたコードほど高速 ではありません。 一般的に任意のバージョンのEmacsはそれ以前のバージョンのEmacsにより生 成されたバイトコンパイル済みコードを実行できますが、その逆は成り立ちませ ん。 あるLispファイルを常にコンパイルせずに実行したい場合は、以下のように ‘no-byte-compile’をバインドするファイルローカル変数を配置します: ;; -*-no-byte-compile: t; -*- 16.1 バイトコンパイル済みコードのパフォーマンス =============================================== バイトコンパイルされた関数はCで記述されたプリミティブ関数ほど効率的では ありませんが、Lispで記述されたバージョンよりは高速に実行されます。以下は 例です: (defun silly-loop (n) "Return the time, in seconds, to run N iterations of a loop." (let ((t1 (float-time))) (while (> (setq n (1- n)) 0)) (- (float-time) t1))) ⇒ silly-loop (silly-loop 50000000) ⇒ 10.235304117202759 (byte-compile 'silly-loop) ⇒ [コンパイルされたコードは表示されない] (silly-loop 50000000) ⇒ 3.705854892730713 この例ではインタープリターによる実行には10秒を要しますが、バイトコン パイルされたコードは4秒未満です。これは典型的な結果例ですが、実際の結果 はさまざまでしょう。 16.2 バイトコンパイル関数 ========================= ‘byte-compile’により、関数やマクロを個別にバイトコンパイルできます。 ‘byte-compile-file’でファイル全体、‘byte-recompile-directory’または ‘batch-byte-compile’で複数ファイルをコンパイルできます。 バイトコンパイラーが警告、および/またはエラーメッセージを生成すること もあります(詳細は*note Compiler Errors::を参照)。これらのメッセージは Compilationモードが使用する‘*Compile-Log*’と呼ばれるバッファーに記録され ます。*note (emacs)Compilation Mode::を参照してください。 バイトコンパイルを意図したファイル内にマクロ呼び出しを記述する際には 注意が必要です。マクロ呼び出しはコンパイル時に展開されるので、そのマクロ はEmacsにロードされる必要があります(さもないとバイトコンパイラーが正しく 処理しないだろう)。これを処理する通常の方法は、必要なマクロ定義を含むフ ァイルを‘require’フォームで指定することです。バイトコンパイラーは通常は コンパイルするコードを評価しませんが、‘require’フォームは指定されたライ ブラリーをロードすることにより特別に扱われます。誰かがコンパイルされたプ ログラムを_実行_する際にマクロ定義ファイルのロードを回避するためには、 ‘require’呼び出しの周囲に‘eval-when-compile’を記述します(*note Eval During Compile::を参照)。詳細は*note Compiling Macros::を参照してくださ い。 インライン関数(‘defsubst’)はこれほど面倒ではありません。定義が判明す る前にそのような関数呼び出しをコンパイルした場合でも、その呼び出しは低速 になるだけで正しく機能するでしょう。 -- Function: byte-compile symbol この関数はSYMBOLの関数定義をバイトコンパイルして、以前の定義をコン パイルされた定義に置き換える。SYMBOLの関数定義は、その関数にたいす る実際のコードでなければならない。‘byte-compile’はインダイレクト関 数を処理しない。リターン値は、SYMBOLのコンパイルされた定義であるよ うなバイトコード関数ブジェクト(*note Byte-Code Objects::を参照)。 (defun factorial (integer) "INTEGERの階乗を計算する。" (if (= 1 integer) 1 (* integer (factorial (1- integer))))) ⇒ factorial (byte-compile 'factorial) ⇒ #[(integer) "^H\301U\203^H^@\301\207\302^H\303^HS!\"\207" [integer 1 * factorial] 4 "Compute factorial of INTEGER."] SYMBOLの定義がバイトコード関数オブジェクトなら、‘byte-compile’は何 も行わず‘nil’をリターンする。そのシンボルの関数セル内の(コンパイル されていない)オリジナルのコードはすでにバイトコンパイルされたコード に置き換えられているので、シンボルの定義の再コンパイルはしない。 ‘byte-compile’の引数として‘lambda’式も指定できる。この場合、関数は 対応するコンパイル済みコードをリターンするが、それはどこにも格納さ れない。 -- Command: compile-defun &optional arg このコマンドはポイントを含むdefunを読み取りそれをコンパイルして、結 果を評価します。実際に関数定義であるようなdefunでこれを使用した場合 は、その関数のコンパイル済みバージョンをインストールする効果があり ます。 ‘compile-defun’は通常は評価した結果をエコーエリアに表示するが、 ARGが非‘nil’なら、そのフォームをコンパイルした後にカレントバッファ ーに結果を挿入する。 -- Command: byte-compile-file filename &optional load この関数はFILENAMEという名前のLispコードファイルを、バイトコードの ファイルにコンパイルする。出力となるファイルの名前は、サフィックス ‘.el’を‘.elc’に変更することにより作成される。FILENAMEが‘.el’で終了 しない場合には、‘.elc’をFILENAMEの最後に付け足す。 コンパイルは入力ファイルから1つのフォームを逐次読み取ることにより機 能する。フォームが関数かマクロなら、コンパイル済みの関数かマクロが 書き込まれる。それ以外のフォームはまとめられて、まとめられたものご とにコンパイルされて、そのファイルが読まれたとき実行されるようにコ ンパイルされたコードが書き込まれる。入力ファイルを読み取る際には、 すべてのコメントは無視される。 このコマンドはエラーがなければ‘t’、それ以外は‘nil’をリターンする。 インタラクティブに呼び出されたときは、ファイル名の入力をもとめる。 LOADが非‘nil’なら、このコマンドはコンパイルした後にコンパイルしたフ ァイルをロードする。インタラクティブに呼び出された場合、LOADはプレ フィクス引数である。 $ ls -l push* -rw-r--r-- 1 lewis lewis 791 Oct 5 20:31 push.el (byte-compile-file "~/emacs/push.el") ⇒ t $ ls -l push* -rw-r--r-- 1 lewis lewis 791 Oct 5 20:31 push.el -rw-rw-rw- 1 lewis lewis 638 Oct 8 20:25 push.elc -- Command: byte-recompile-directory directory &optional flag force このコマンドはDIRECTORY(またはそのサブディレクトリー)内の、リコンパ イルを要するすべての‘.el’ファイルをリコンパイルする。‘.elc’ファイル が存在して、それが‘.el’より古いファイルは、リコンパイルが必要となる 。 ‘.el’ファイルに対応する‘.elc’ファイルが存在しない場合に何を行うかを FLAGで指定する。‘nil’なら、このコマンドはこれらのファイルを無視する 。FLAGが0なら、それらをコンパイルする。‘nil’と0以外なら、それらのフ ァイルをコンパイルするかユーザーに尋ねて、同様にそれぞれのサブディ レクトリーについても尋ねる。 インタラクティブに呼び出されると、‘byte-recompile-directory’は DIRECTORYの入力を求めて、FLAGはプレフィクス引数となる。 FORCEが非‘nil’なら、このコマンドは‘.elc’ファイルが存在するすべての ‘.el’ファイルをリコンパイルする。 リターン値は不定。 -- Function: batch-byte-compile &optional noforce この関数はコマンドラインで指定されたファイルにたいして ‘byte-compile-file’を実行する。この関数は処理が完了するとEmacsを killするので、Emacsのバッチ実行でのみ使用しなければならない。1つの ファイルでエラーが発生しても、それによって後続のファイルにたいする 処理が妨げられることはないが、そのファイルにたいする出力ファイルは 生成されず、Emacsプロセスは0以外のステータスコードで終了する。 NOFORCEが非‘nil’なら、この関数は最新の‘.elc’ファイルがあるファイル をリコンパイルしない。 $ emacs -batch -f batch-byte-compile *.el 16.3 ドキュメント文字列とコンパイル =================================== Emacsがバイトコンパイルされたファイルから関数や変数をロードする際、通常 はメモリー内にそれらのドキュメント文字列をロードしません。それぞれのドキ ュメント文字列は、必要なときだけバイトコンパイルされたファイルからダイナ ミック(dynamic: 動的)にロードされます。ドキュメント文字列の処理をスキッ プすることにより、メモリーが節約されてロードが高速になります。 この機能には欠点があります。コンパイル済みのファイルを削除や移動、ま たは(新しいバージョンのコンパイル等で)変更した場合、Emacsは以前にロード した関数や変数のドキュメント文字列にアクセスできなくなるでしょう。このよ うな問題は通常なら、あなた自身がEmacsをビルドしたときに、そのLispファイ ルを編集および/またはリコンパイルしたときだけ発生します。この問題は、リ コンパイル後にそれぞれのファイルをリロードするだけで解決します。 バイトコンパイルされたファイルからのドキュメント文字列のダイナミック ロードは、バイトコンパイルされたファイルごとにコンパイル時に解決されます 。これはオプション‘byte-compile-dynamic-docstrings’で無効にできます。 -- User Option: byte-compile-dynamic-docstrings これが非‘nil’なら、バイトコンパイラーはドキュメント文字列をダイナミ ックロードするようにセットアップしたコンパイル済みファイルを生成す る。 特定のファイルでダイナミックロード機能を無効にするには、以下のよう にヘッダー行でこのオプションに‘nil’をセットする(*note Local Variables in Files: (emacs)File Variables.を参照)。 -*-byte-compile-dynamic-docstrings: nil;-*- これは主として、あるファイルを変更しようとしていて、そのファイルを すでにロード済みのEmacsセッションがファイルを変更した際にも正しく機 能し続けることを望む場合に有用である。 内部的にはドキュメント文字列のダイナミックロードは、特殊なLispリーダ ー構文‘#@COUNT’とともにコンパイル済みファイルに書き込むことによって達成 される。この構文は次のCOUNT文字をスキップする。さらに‘#$’構文も使用され 、これはこのファイルの名前(文字列)を意味する。これらの構文をLispソースフ ァイル内で使用しないこと。これらは人間がファイルを読む際に明確であるよう にデザインされていない。 16.4 個別関数のダイナミックロード ================================= ファイルをコンパイルするとき、オプションで“ダイナミック関数ロード (dynamic function loading)”機能(“laxyロード(lazy loading)とも呼ばれる ”)を有効にできます。ダイナミック関数ロードでは、ファイルのロードでファイ ル内の関数定義は完全には読み込まれません。かわりに各関数定義にはそのファ イルを参照するプレースホルダーが含まれます。それぞれ関数が最初に呼び出さ れるときにそのプレースホルダーを置き換えるために、ファイルから完全な定義 が読み込まれます。 ダイナミック関数ロードの利点は、ファイルのロードがより高速になること です。ユーザーが呼び出せる関数を多く含むファイルにとって、それらの関数の うち1つを使用したら多分残りの関数も使用するというのでなければ、これは利 点になります。多くのキーボードコマンドを提供する特化したモードは、このパ ターンの使い方をする場合があります。ユーザーはそのモードを呼び出すかもし れませんが、使用するのはそのモードが提供するコマンドのわずか一部です。 ダイナミックロード機能には不利な点がいくつかあります: • ロード後にコンパイル済みファイルの削除や移動を行うと、Emacsはまだロ ードされていない残りの関数定義をロードできなくなる。 • (新しいバージョンのコンパイル等で)コンパイル済みファイルを変更した 場合に、まだロードされていない関数のロードを試みると通常は無意味な 結果となる。 このような問題は通常の状況でインストールされたEmacsファイルでは決して 発生しません。しかしあなたが変更したLispファイルでは発生し得ます。それぞ れのファイルをリコンパイルしたらすぐに新たなコンパイル済みファイルをリロ ードするのが、これらの問題を回避する一番簡単な方法です。 コンパイル時に変数‘byte-compile-dynamic’が非‘nil’なら、バイトコンパイ ラーはダイナミック関数ロード機能を使用します。ダイナミックロードが望まし いのは特定のファイルにたいしてだけなので、この変数をグローバルにセットし ないでください。そのかわりに、特定のソースファイルのファイルローカル変数 でこの機能を有効にしてください。たとえばソースファイルの最初の行に以下の テキストを記述することにより、これを行うことができます: -*-byte-compile-dynamic: t;-*- -- Variable: byte-compile-dynamic これが非‘nil’なら、バイトコンパイラーはダイナミック関数ロード用にセ ットアップされたコンパイル済みファイルを生成する。 -- Function: fetch-bytecode function FUNCTIONがバイトコード関数オブジェクトなら、それがまだ完全にロード されていなければ、バイトコンパイル済みのファイルからのFUNCTIONのバ イトコードのロードを完了させる。それ以外なら何も行わない。この関数 は常にFUNCTIONをリターンする。 16.5 コンパイル中の評価 ======================= これらの機能によりプログラムのコンパイル中に評価されるコードを記述できま す。 -- Special Form: eval-and-compile body... このフォームはそれを含むコードがコンパイルされるとき、および(コンパ イルされているかいないかに関わらず)実行されるときの両方で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”の警告は 抑制される)。 -- Special Form: eval-when-compile body... このフォームは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’と近いことを行う。 16.6 コンパイラーのエラー ========================= バイトコンパイルのエラーメッセージと警告メッセージは、‘*Compile-Log*’と いう名前のバッファーにプリントされます。これらのメッセージには、問題とな る箇所を示すファイル名と行番号が含まれます。これらのメッセージにたいして 、コンパイラー出力を操作する通常のEmacsコマンドが使用できます。 あるエラーがプログラムのシンタックスに由来する場合、バイトコンパイラ ーはエラーの正確な位置の取得に際して混乱するかもしれません。バッファー ‘ *Compiler Input*’.にスイッチするのは、これを調べ1つの方法です(このバッ ファー名はスペースで始まるので、Buffer Menuに表示されない)。このバッファ ーにはコンパイルされたプログラムと、バイトコンパイラーが読み取った箇所か らポイントがどれほど離れているかが含まれ、エラーの原因はその近傍の可能性 があります。シンタックスエラーを見つけるヒントについては、*note Syntax Errors::を参照してください。 定義されていない関数や変数の使用は、バイトコンパイラーにより報告され る警告のタイプとしては一般的です。そのような警告では、定義されていない関 数や変数を使用した位置ではなく、そのファイルの最後の行の行番号が報告され るので、それを見つけるには手作業で検索しなければなりません。 定義のない関数や変数の警告が間違いだと確信できる場合には、警告を抑制 する方法がいくつかあります: • 関数FUNCへの特定の呼び出しにたいする警告は、それを条件式‘fboundp’で テストすることで抑制できる: (if (fboundp 'FUNC) ...(FUNC ...)...) FUNCへの呼び出しは‘if’文のTHEN-FORM内になければならず、FUNCは ‘fboundp’呼び出し内でクォートされていなければならない(この機能は ‘cond’でも同様に機能する)。 • 同じように、変数VARIABLEの特定の使用についの警告を、条件式内の ‘boundp’テストで抑制できる: (if (boundp 'VARIABLE) ...VARIABLE...) VARIABLEへの参照は‘if’文のTHEN-FORM内になければならず、VARIABLEは ‘boundp’呼び出し内でクォートされていなければならない。 • コンパイラーに関数が‘declare-function’を使用して定義されていると告 げることができる。*note Declaring Functions::を参照のこと。 • 同じように、その変数が初期値なしの‘defvar’を使用して定義されている とコンパイラーに告げることができる(これはその変数を特別な変数として マークすることに注意。*note Defining Variables::を参照)。 ‘with-no-warnings’構文を使用して特定の式にたいするコンパイラーの任意 の警告をすべて抑制することもできます: -- Special Form: with-no-warnings body... これは実行時には‘(progn BODY...)’と等価だが、コンパイラーはBODYの中 で起こるいかなる事項にたいしても警告を発しない。 わたしたちは、あなたが抑制したいと意図する警告以外の警告を失わない ようにするために、可能な限り小さいコード断片にたいしてこの構文を使 用することを推奨する。 変数‘byte-compile-warnings’をセットすることにより、コンパイラーの警告 をより詳細に制御できます。詳細は変数のドキュメント文字列を参照してくださ い。 16.7 バイトコード関数オブジェクト ================================= バイトコンパイルされた関数は、“バイトコード関数オブジェクト(byte-code function objects)”という特別なデータ型をもちます。関数呼び出しとしてその ようなオブジェクトが出現したとき、Emacsはそのバイトコードを実行するため に、常にバイトコードインタープリターを使用します。 内部的にはバイトコード関数オブジェクトはベクターとよく似ています。バ イトコード関数オブジェクトの要素には‘aref’を通じてアクセスできます。バイ トコード関数オブジェクトのプリント表現(printed representation)はベクター と似ていて、開き‘[’の前に‘#’が追加されます。バイト関数オブジェクトは少な くとも4つの要素をもたねばならず、その要素数に上限はありません。しかし通 常使用されるのは最初の6要素です。これらは: ARGDESC 引数の記述子(descriptor)。これは*note Argument List::で説明されるよ うな引数のリスト、または要求される引数の個数をエンコードする整数の いずれかである。後者の場合、その記述子の値は0ビットから6ビットで引 数の最小個数、8ビットから14ビットで引数の最大個数を指定する。引数リ ストが‘&rest’を使用するなら7ビットがセットされて、それい以外ならク リアーされる。 ARGDESCがリストなら、そのバイトコード実行前に引数はダイナミックにバ インドされる。ARGDESCが整数なら、引数リストはそのバイトコード実行前 にバイトコーピンタープリンターのスタックにpushされる。 BYTE-CODE バイトコード命令を含む文字列。 CONSTANTS バイトコードにより参照されるLispオブジェクトのベクター。関数名と変 数名に使用されるシンボルが含まれる。 STACKSIZE この関数が要するスタックの最大サイズ。 DOCSTRING (もしあれば)ドキュメント文字列。それ以外は‘nil’。ドキュメント文字列 がファイルに格納されている場合、値は数字かリストかもしれない。本当 のドキュメント文字列の取得には、関数‘documentation’を使用する(*note Accessing Documentation::を参照)。 INTERACTIVE (もしあれば)インタラクティブ仕様。文字列かLisp式。インタラクティブ でない関数では‘nil’。 以下はバイトコード関数オブジェクトのプリント表現の例です。これはコマ ンド‘backward-sexp’の定義です。 #[256 "\211\204^G^@\300\262^A\301^A[!\207" [1 forward-sexp] 3 1793299 "^p"] バイトコードオブジェクトを作成するプリミティブな方法は ‘make-byte-code’です: -- Function: make-byte-code &rest elements この関数はELEMENTSを要素とするバイトコードオブジェクトを構築してリ ターンする。 あなた自身で要素を収集してバイトコード関数を構築しないでください。そ れらが矛盾する場合、その関数の呼び出しによりEmacsがクラッシュするかもし れません。これらのオブジェクトの作成は常にバイトコンパイラーにまかせてく ださい。(願わくば)バイトコンパイラーは要素を矛盾なく構築します。 16.8 逆アセンブルされたバイトコード =================================== 人はバイトコードを記述しません。それはバイトコンパイラーの仕事です。しか し好奇心を満たすために、わたしたちはディスアセンブラを提供しています。デ ィスアセンブラはバイトコードを人間が読めるフォームに変換します。 バイトコードインタープリターは、シンプルなスタックマシンとして実装さ れています。これは値を自身のスタックにpushして、計算で使用するためにそれ らをpopして取り出し、その結果を再びそのスタックにpushして戻します。バイ トコード関数がリターンするときは、スタックから値をpopして取り出し、その 関数の値としてリターンします。 それに加えてスタックとバイトコード関数は、値を変数とスタック間で転送 することにより、普通のLisp変数を使用したり、バインドやセットを行うことが できます。 -- Command: disassemble object &optional buffer-or-name このコマンドはOBJECTにたいするディスアセンブルされたコードを表示す る。インタラクティブに使用した場合、またはBUFFER-OR-NAMEが‘nil’か省 略された場合は、‘*Disassemble*’という名前のバッファーに出力します。 BUFFER-OR-NAMEが非‘nil’なら、それはバッファーもしくは既存のバッファ ーの名前でなければならない。その場合は、そのバッファーのポイント位 置に出力され、ポイントは出力の前に残りされる。 引数OBJECTには関数名、ラムダ式(*note Lambda Expressions::を参照)、 またはバイトコードオブジェクト(*note Byte-Code Objects::を参照)を指 定できる。ラムダ式なら‘disassemble’はそれをコンパイルしてから、その コンパイル済みコードをディスアセンブルする。 以下に‘disassemble’関数を使用した例を2つ示します。バイトコードと Lispソースを関連付ける助けとなるように、説明的なコメントを追加してありま す。これらのコメントは‘disassemble’の出力にはありません。 (defun factorial (integer) "Compute factorial of an integer." (if (= 1 integer) 1 (* integer (factorial (1- integer))))) ⇒ factorial (factorial 4) ⇒ 24 (disassemble 'factorial) ⊣ byte-code for factorial: doc: Compute factorial of an integer. args: (integer) 0 varref integer ; ‘integer’の値を取得して ; それをスタック上にpushする 1 constant 1 ; スタック上に1をpushする 2 eqlsign ; 2つの値をスタックからpopして取り出し、 ; それらを比較して結果をスタック上にpushする 3 goto-if-nil 1 ; スタックのトップをpopしてテストする ; ‘nil’なら1へ、それ以外はcontinue 6 constant 1 ; スタックのトップに1をpushする 7 return ; スタックのトップの要素をリターンする 8:1 varref integer ; ‘integer’の値をスタック上にpushする 9 constant factorial ; ‘factorial’をスタック上にpushする 10 varref integer ; ‘integer’の値をスタック上にpushする 11 sub1 ; ‘integer’をpopして値をデクリメントする ; スタック上に新しい値をpushする 12 call 1 ; スタックの最初(トップ)の要素を引数として ; 関数‘factorial’を呼び出す ; リターン値をスタック上にpushする 13 mult ; スタックのトップ2要素をpopして取り出し乗じ ; 結果をスタック上にpushする 14 return ; スタックのトップ要素をリターンする ‘silly-loop’は幾分複雑です: (defun silly-loop (n) "Return time before and after N iterations of a loop." (let ((t1 (current-time-string))) (while (> (setq n (1- n)) 0)) (list t1 (current-time-string)))) ⇒ silly-loop (disassemble 'silly-loop) ⊣ byte-code for silly-loop: doc: Return time before and after N iterations of a loop. args: (n) 0 constant current-time-string ; ‘current-time-string’を ; スタック上のトップにpushする 1 call 0 ; 引数なしで‘current-time-string’を呼び出し ; 結果をスタック上にpushする 2 varbind t1 ; スタックをpopして‘t1’にpopされた値をバインドする 3:1 varref n ; 環境から‘n’の値を取得して ; その値をスタック上にpushする 4 sub1 ; スタックのトップから1を減ずる 5 dup ; スタックのトップを複製する ; たとえばスタックのトップをコピーしてスタック上にpushする 6 varset n ; スタックのトップをpopして ; ‘n’をその値にバインドする ;; (要はシーケンス‘dup varset’はpopせずに ;; スタックのトップを‘n’の値にコピーする) 7 constant 0 ; スタック上に0をpushする 8 gtr ; スタックのトップ2値をpopして取り出し ; Nが0より大かテストし ; 結果をスタック上にpushする 9 goto-if-not-nil 1 ; ‘n’ > 0なら1へ ; (これはwhile-loopを継続する) ; それ以外はcontinue 12 varref t1 ; ‘t1’の値をスタック上にpushする 13 constant current-time-string ; ‘current-time-string’を ; スタックのトップにpushする 14 call 0 ; 再度‘current-time-string’を呼び出す 15 unbind 1 ; ローカル環境の‘t1’をアンバインドする 16 list2 ; スタックのトップ2要素をpopして取り出し ; それらのリストを作りスタック上にpushする 17 return ; スタックのトップの値をリターンする 17 Lispプログラムのデバッグ *************************** Emacs Lispプログラム内の問題を見つけて詳細に調べる方法がいくつかあります 。 • プログラム実行中に問題が発生した場合には、Lisp評価機能をサスペンド するためにビルトインのEmacs Lispデバッガを使用して評価機能の内部状 態の調査および/または変更を行なうことができる。 • Emacs LispにたいするソースレベルデバッガのEdebugを使用できる。 • 文法的な問題によりLispがプログラムを読むことさえできない場合には、 Lisp編集コマンドを使用して該当箇所を見つけることができる。 • バイトコンパイラーがプログラムをコンパイルするとき、コンパイラーに より生成されるエラーメッセージと警告メッセージを調べることができる 。*note Compiler Errors::を参照のこと。 • Testcoverパッケージを使用してプログラムのテストカバレッジを行なうこ とができる。 • ERTパッケージを使用してプログラムにたいするリグレッションテストを記 述できる。*note the ERT manual: (ert)Top.を参照のこと。 • プログラムをプロファイルしてプログラムをより効果的にするためのヒン トを取得できる。 入出力の問題をデバックする便利なその他のツールとして、ドリブルファイ ル(dribble file: *note Terminal Input::を参照)と、‘open-termscript’関数 (*note Terminal Output::)があります。 17.1 Lispデバッガ ================= 普通の“Lispデバッガ”は、フォーム評価のサスペンド機能を提供します。評価が サスペンド(一般的には“break”の状態として知られる)されている間、実行時ス タックを調べたり、ローカル変数やグローバル変数の値を調べたり変更すること ができます。breakは再帰編集(recursive edit)なので、Emacsの通常の編集機能 が利用可能です。デバッガにエンターするようにプログラムを実行することさえ 可能です。*note Recursive Editing::を参照してください。 17.1.1 エラーによるデバッガへのエンター --------------------------------------- デバッガに入るタイミングとして一番重要なのは、Lispエラーが発生したときで す。デバッガではエラーの直接原因を調査できます。 しかしデバッガへのエンターは、エラーによる通常の結末ではありません。 多くのコマンドは不適切に呼び出されたときにLispエラーをシグナルするので、 通常の編集の間にこれが発生するたびデバッガにエンターするのは、とても不便 でしょう。したがってエラーの際にデバッガにエンターしたいなら、変数 ‘debug-on-error’に非‘nil’をセットします(コマンド ‘toggle-debug-on-error’はこれを簡単に行う方法を提供する)。 -- User Option: debug-on-error この変数はエラーがシグナルされて、それがハンドルされていないときに デバッガを呼び出すかどうかを決定する。‘debug-on-error’が‘t’なら、 ‘debug-ignored-errors’(以下参照)にリストされているエラー以外の、す べての種類のエラーがデバッガを呼び出す。‘nil’ならデバッガを呼び出さ ない。 値にはエラー条件(*note Signaling Errors::を参照)のリストも指定でき る。その場合はこのリスト内のエラー条件だけによってデバッガが呼び出 される(‘debug-ignored-errors’にもリストされているエラー条件は除外さ れる)。たとえば‘debug-on-error’をリスト‘(void-variable)’にセットす ると、値をもたない変数に関するエラーにたいしてのみデバッガが呼び出 される。 ‘eval-expression-debug-on-error’がこの変数をオーバーライドするケー スがいくつかあることに注意(以下参照)。 この変数が非‘nil’のとき、Emacsはプロセスフィルター関数と番兵 (sentinel)の周囲にエラーハンドラーを作成しない。したがってこれらの 関数内でのエラーは、デバッガを呼び出す。*note Processes::を参照のこ と。 -- User Option: debug-ignored-errors この変数は‘debug-on-error’の値に関わらず、デバッガにエンターすべき でないエラーを指定する。変数の値はエラー条件のシンボルおよび/または 正規表現のリスト。エラーがこれら条件シンボルのいずれか、またはエラ ーメッセージが正規表現のいずれかにマッチすれば、そのエラーはデバッ ガにエンターしない。 この変数の通常の値には‘user-error’、および編集中に頻繁に発生するが Lispプログラムのバグに起因することは稀であるような、いくつかのエラ ーが含まれる。しかし“稀である”ことは“絶対ない”ということではない。 あなたのプログラムがこのリストにマッチするエラーによって機能しない なら、そのエラーをデバッグするためにこのリストの変更を試みるのもよ いだろう。通常は‘debug-ignored-errors’を‘nil’にセットしておくのが、 もっとも簡単な方法である。 -- User Option: eval-expression-debug-on-error この変数が非‘nil’値(デフォルト)なら、コマンド‘eval-expression’の実 行によって一時的に‘debug-on-error’が‘t’がバインドされる。*note Evaluating Emacs-Lisp Expressions: (emacs)Lisp Eval.を参照のこと。 ‘eval-expression-debug-on-error’が‘nil’なら、‘eval-expression’の間 も‘debug-on-error’の値は変更されない。 -- User Option: debug-on-signal ‘condition-case’でキャッチされたエラー、は通常は決してデバッガを呼 び出さない。‘condition-case’はデバッガがそのエラーをハンドルする前 にエラーをハンドルする機会を得る。 ‘debug-on-signal’を非‘nil’値に変更すると、‘condition-case’の存在如 何に関わらずすべてのエラーにおいてデバッガが最初に機会を得る(デバッ ガを呼び出すためには依然としてそのエラーが‘debug-on-error’と ‘debug-ignored-errors’で指定された条件を満たさなければならない)。 *警告:* この変数を非‘nil’にセットすると、芳しくない効果があるかもし れない。Emacsのさまざまな部分で処理の通常の過程としてエラーがキャッ チされており、そのエラーが発生したことに気づかないことさえあるかも しれない。‘condition-case’でラップされたコードをデバッグする必要が あるなら、‘condition-case-unless-debug’(*note Handling Errors::を参 照)の使用を考慮されたい。 -- User Option: debug-on-event ‘debug-on-event’をスペシャルイベント(*note Special Events::を参照 )にセットすると、Emacsは‘special-event-map’をバイパスしてこのイベン トを受け取ると即座にデバッガへのエンターを試みる。現在のところサポ ートされる値は、シグナル‘SIGUSR1’と‘SIGUSR2’に対応する値のみ(これが デフォルト)。これは‘inhibit-quit’がセットされていて、それ以外は Emacsが応答しない場合に有用かもしれない。 -- Variable: debug-on-message ‘debug-on-message’に正規表現をセットした場合は、それにマッチするメ ッセージがエコーエリアに表示されると、Emacsはデバッガにエンターする 。たとえばこれは特定のメッセージの原因を探すのに有用かもしれない。 initファイルロード中に発生したエラーをデバッグするには、オプション ‘--debug-init’を使用する。これはinitファイルロードの間に ‘debug-on-error’を‘t’にバインドして、通常はinitファイル内のエラーをキャ ッチする‘condition-case’をバイパスする。 17.1.2 無限ループのデバッグ --------------------------- プログラムが無限にループしてリターンできないとき、最初の問題はそのループ をいかに停止するかです。ほとんどのオペレーティングシステムでは、 (“quit”させる)‘C-g’でこれを行うことができます。*note Quitting::を参照し てください。 普通のquitでは、なぜそのプログラムがループしたかについての情報は与え られません。変数‘debug-on-quit’に非‘nil’をセットすることにより、より多く の情報を得ることができます。無限ループの途中でデバッガを実行すれば、デバ ッガからステップコマンドで先へ進むことができます。ループ全体をステップで 追えば、問題を解決するために十分な情報が得られるでしょう。 ‘C-g’によるquitはエラーとは判断されないので、‘C-g’のハンドルに ‘debug-on-error’は効果がありません。同じように‘debug-on-quit’はエラーに たいして効果がありません。 -- User Option: debug-on-quit この変数は‘quit’がシグナルされて、それがハンドルされていないときに デバッガを呼び出すかどうかを決定する。‘debug-on-quit’が非‘nil’なら 、quit(つまり‘C-g’をタイプ)したときは常にデバッガが呼び出される。 ‘debug-on-quit’が‘nil’(デフォルト)なら、quitしてもデバッガは呼び出 されない。 17.1.3 関数呼び出しによるデバッガへのエンター --------------------------------------------- プログラムの途中で発生する問題を調べるための有用なテクニックの1つは、特 定の関数が呼び出されたときデバッガにエンターする方法です。問題が発生した 関数にこれを行ってその関数をステップで追ったり、問題箇所の少し手前の関数 呼び出しでこれを行って、その関数をステップオーバーしてその後をステップで 追うことができます。 -- Command: debug-on-entry function-name この関数は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* ------ -- Command: cancel-debug-on-entry &optional function-name この関数はFUNCTION-NAMEにたいする‘debug-on-entry’の効果をアンドゥす る。インタラクティブに呼び出されたときは、ミニバッファーで FUNCTION-NAMEの入力を求める。FUNCTION-NAMEが省略または‘nil’なら、す べての関数にたいするbreak-on-entryをキャンセルする。エントリー時に breakするようセットアップされていない関数に ‘cancel-debug-on-entry’を呼び出したときは何も行わない。 17.1.4 明示的なデバッガへのエントリー ------------------------------------- プログラム内の特定箇所に式‘(debug)’を記述することによって、その箇所でデ バッガが呼び出されるようにできます。これを行うにはソースファイルを visitして、適切な箇所にテキスト‘(debug)’を挿入し、‘C-M-x’(Lispモードでの ‘eval-defun’にたいするキーバインド)をタイプします。*警告:* 一時的なデバ ッグ目的のためにこれを行なう場合には、ファイルを保存する前に確実にアンド ゥしてください! ‘(debug)’を挿入する箇所は追加フォームが評価されることができ、かつその 値を無視することができる箇所でなければなりません(‘(debug)’の値を無視しな いとプログラムの実行が変更されてしまうだろう!)。一般的にもっとも適した箇 所は、‘progn’または暗黙的な‘progn’(*note Sequencing::を参照)の内部です。 デバッグ命令を配置したいソースコード中の正確な箇所がわからないが、特 定のメッセージが表示されたときにバックトレースを表示したい場合には、意図 するメッセージにマッチする正規表現を‘debug-on-message’にセットできます。 17.1.5 デバッガの使用 --------------------- デバッガにエンターすると、その前に選択されていたウィンドウを1つのウィン ドウに表示して、他のウィンドウに‘*Backtrace*’という名前のバッファーを表 示します。backtraceバッファーには、現在実行されているLisp関数の各レベル が1行ずつ含まれます。このバッファーの先頭は、デバッガが呼び出された理由 を説明するメッセージ(デバッガがエラーにより呼び出された場合はエラーメッ セージや関連するデータなど)です。 backtraceバッファーは読み取り専用で、文字キーにデバッガコマンドが定義 されたDebuggerモードという特別なメジャーモードを使用します。通常の Emacs編集コマンドが利用できます。したがってエラー時に編集されていたバッ ファーを調べるためにウィンドウを切り替えたり、バッファーの切り替えやファ イルのvisit、その他一連の編集処理を行なうことができます。しかしデバッガ は再帰編集レベル(*note Recursive Editing::を参照)にあり、編集が終わった らそれはbacktraceバッファーに戻って、(‘q’コマンドで)デバッガをexitできま す。デバッガをexitすることによって再帰編集を抜け出し、backtraceバッファ ーはバリー(bury: 覆い隠す)されます(変数‘debugger-bury-or-killw’をセット することによってbacktraceバッファーで‘q’コマンドが何を行うかをカスタマイ ズできる。たとえばバッファーをバリーせずにkillしたいなら、この変数を ‘kill’にセットする。他の値については変数のドキュメントを調べてほしい)。 デバッガにエンターしたとき、‘eval-expression-debug-on-error’に一致す るように変数‘debug-on-error’が一時的にセットされます。変数 ‘eval-expression-debug-on-error’が非‘nil’なら、‘debug-on-error’は一時的 に‘t’にセットされます。これはデバッグセッション行っている間にさらにエラ ーが発生すると、(デフォルトでは)他のbacktraceがトリガーされることを意味 します。これが望ましくなければ、‘debugger-mode-hook’内で ‘eval-expression-debug-on-error’を‘nil’にセットするか、 ‘debug-on-error’を‘nil’にセットすることができます。 backtraceバッファーは実行されている関数と、その関数の引数の値を示しま す。そのフレームを示す行にポイントを移動して、スタックフレームを指定する こともできます(スタックフレームとは、Lispインタープリターがある関数への 特定の呼び出しを記録する場所のこと)。行ポイントがオンのフレームが、“カレ ントフレーム(current frame)”となります。デバッガコマンドのいくつかは、カ レントフレームを処理します。ある行がスター(star)で始まる場合は、そのフレ ームをexitすることによって再びデバッガが呼び出されることを意味します。こ れは関数のリターン値を調べるとき有用です。 関数名にアンダーラインが引かれている場合は、デバッガがその関数のソー スコードの位置を知っていることを意味します。その名前をマウスでクリックす るか、そこに移動してをタイプすれば、ソースコードをvisitできます。 デバッガはデバッガ自身のスタックフレーム数を想定するため、バイトコン パイルされて実行されなければなりません。デバッガがインタープリターに解釈 されて実行されているときは、これらの想定は正しくなくなります。 17.1.6 デバッガのコマンド ------------------------- (Debuggerモードの)debuggerバッファーでは、通常のEmacsコマンドに加えて特 別なコマンドが提供されます。デバッガでもっとも重要な使い方をするのは、制 御フローを見ることができるコードをステップ実行するコマンドです。デバッガ はインタープリターによって解釈された制御構造のステップ実行はできますが、 バイトコンパイル済みの関数ではできません。バイトコンパイル済み関数をステ ップ実行したいなら、同じ関数の解釈された定義に置き換えてください(これを 行なうにはその関数のソースをvisitして、関数の定義で‘C-M-x’とタイプする )。プリミティブ関数のステップ実行にLispデバッガは使用できません。 以下はDebuggerモードのコマンドのリストです: ‘c’ デバッガをexitして実行を継続する。これはあたかもデバッガにエンター しなかったかのようにプログラムの実行を再開する(デバッガ内で行った変 数値やデータ構造の変更などの副作用は除外)。 ‘d’ 実行を継続するが、次にLisp関数が何か呼び出されたときはデバッガにエ ンターする。これによりある式の下位の式をステップ実行して、下位の式 が計算する値や行うことを確認できる。 デバッガにエンターした関数呼び出しにたいして、この方法で作成された スタックフレームには自動的にフラグがつくため、そのフレームをexitす ると再びデバッガが呼び出される。このフラグは‘u’コマンドを使用してキ ャンセルできる。 ‘b’ カレントフレームにフラグをつけるので、そのフレームをexitするときデ バッガにエンターする。この方法でフラグがつけられたフレームは、 backtraceバッファーでスターのマークがつく。 ‘u’ カレントフレームをexitしたときデバッガにエンターしない。これはその フレームの‘b’コマンドをキャンセルする。目に見える効果としては backtraceバッファーの行からスターが削除される。 ‘j’ ‘b’と同じようにカレントフレームにフラグをつける。その後に‘c’のよう に実行を継続するが、‘debug-on-entry’によりセットアップされたすべて の関数にたいするbreak-on-entryを一時的に無効にする。 ‘e’ ミニバッファーのLisp式を読み取り、(関連するlexical環境が適切なら)そ れを評価してエコーエリアに値をプリントする。デバッガは特定の重要な 変数とバッファーを処理の一部として変更する。‘e’は一時的にデバッガの 外部からそれらの値をリストアするので、それらを調べて変更できる。こ れによりデバッガはより透過的になる。対照的にデバッガ内で‘M-:’は特別 なことを行わず、デバッガ内での変数の値を表示する。 ‘R’ ‘e’と同様だがバッファー‘*Debugger-record*’内の評価結果も保存する。 ‘q’ デバッグされているプログラムを終了して、Emacsコマンド実行のトップレ ベルにリターンする。 ‘C-g’によりデバッガにエンターしたが、実際はデバッグではなくquitした いときは‘q’コマンドを使用する。 ‘r’ デバッガから値をリターンする。ミニバッファーで式を読み取ってそれを 評価することにより値が計算される。 ‘d’コマンドは、(‘b’によるリクエストや‘d’によるそのフレームへのエン ターによる)Lisp呼び出しフレームからのexitでデバッガが呼び出されたと きに有用である。‘r’コマンドで指定された値は、そのフレームの値として 使用される。これは‘debug’を呼び出して、そのリターン値を使用するとき にも有用。それ以外は‘r’は‘c’と同じ効果をもち、指定されたリターン値 は問題とはならない。 エラーによりデバッガにエンターしたときは‘r’コマンドは使用できない。 ‘l’ 呼び出されたときにデバッガを呼び出す関数をリストする。これは ‘debug-on-entry’によりエントリー時にbreakするようセットされた関数の リストである。 ‘v’ カレントスタックフレームのローカル変数の表示を切り替える。 17.1.7 デバッガの呼び出し ------------------------- 以下ではデバッガを呼び出すために使用される関数‘debug’の完全な詳細を説明 します。 -- Command: debug &rest debugger-args この関数はデバッガにエンターする。この関数は‘*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’が呼び出され た条件を思い出すためのリマインダーとして — の表示にこの機能を 使用できる。 17.1.8 デバッガの内部 --------------------- このセクションではデバッガ内部で使用される関数と変数について説明します。 -- Variable: debugger この関数の値はデバッガを呼び出す関数呼び出しである。値には任意個数 の引数をとる関数、より具体的には関数の名前でなければならない。この 関数は何らかのデバッガを呼び出すこと。この変数のデフォルト値は ‘debug’。 関数にたいしてLispが渡す1つ目の引数は、その関数がなぜ呼び出されたか を示す。引数の慣習については‘debug’(*note Invoking the Debugger::)に 詳解がある。 -- Command: backtrace この関数は現在アクティブなLisp関数呼び出しのトレースをプリントする 。この関数は‘debug’が‘*Backtrace*’バッファーに書き込む内容を得るた めに使用される。どの関数呼び出しがアクティブか判断するためにスタッ クにアクセスしなければならないので、この関数はCで記述されている。リ ターン値は常に‘nil’。 以下の例ではLisp式で明示的に‘backtrace’を呼び出している。これはスト リーム‘standard-output’(この場合はバッファー‘backtrace-output’)に backtraceをプリントする。 backtraceの各行は、1つの関数呼び出しを表す。関数の引数が既知なら行 に値が表示され、まだ計算中の場合は行にその旨が示される。スペシャル フォームの引数は無視される。 (with-output-to-temp-buffer "backtrace-output" (let ((var 1)) (save-excursion (setq var (eval '(progn (1+ var) (list 'testing (backtrace)))))))) ⇒ (testing nil) ----------- Buffer: backtrace-output ------------ backtrace() (list ...computing arguments...) (progn ...) eval((progn (1+ var) (list (quote testing) (backtrace)))) (setq ...) (save-excursion ...) (let ...) (with-output-to-temp-buffer ...) eval((with-output-to-temp-buffer ...)) eval-last-sexp-1(nil) eval-last-sexp(nil) call-interactively(eval-last-sexp) ----------- Buffer: backtrace-output ------------ -- Variable: debug-on-next-call この変数が非‘nil’なら、それは次の‘eval’、‘apply’、‘funcall’の前にデ バッガを呼び出すよう指定する。デバッガへのエンターによって ‘debug-on-next-call’は‘nil’にセットされる。 デバッガの‘d’コマンドは、この変数をセットすることにより機能します。 -- Function: backtrace-debug level flag この関数はそのスタックフレームのLEVEL下位のスタックフレームの debug-on-exitフラグにFLAGに応じた値をセットする。FLAGが非‘nil’なら 、後でそのフレームをexitするときデバッガにエンターする。そのフレー ムを通じた非ローカルexitでも、デバッガにエンターする。 この関数はデバッガだけに使用される。 -- Variable: command-debug-status この変数はカレントのインタラクティブコマンドのデバッグ状態を記録す る。コマンドがインタラクティブに呼び出されるたびに、この変数は ‘nil’にバインドされる。デバッガは同じコマンドが呼び出されたときのデ バッガ呼び出しに情報を残すために、この変数をセットできる。 普通のグローバル変数ではなくこの変数を使用する利点は、そのデータが 後続のコマンド呼び出しに決して引き継がれないことである。 -- Function: backtrace-frame frame-number 関数‘backtrace-frame’はLispデバッガ内での使用を意図している。これは FRAME-NUMBERレベル下位のスタックフレームで、何の評価が行われている かに関する情報をリターンする。 そのフレームがまだ引数を評価していない、またはそのフレームがスペシ ャルフォームの場合、値は‘(nil FUNCTION ARG-FORMS...)’。 そのフレームが引数を評価して関数をすでに呼び出していたら、リターン 値は‘(t FUNCTION ARG-VALUES...)’。 リターン値のFUNCTIONは何であれ評価されたリストのCARとして提供される 。マクロ呼び出しの場合は‘lambda’式になる。その関数に‘&rest’引数があ ればリストARG-VALUESの末尾に示される。 FRAME-NUMBERが範囲外なら‘backtrace-frame’は‘nil’をリターンする。 17.2 Edebug =========== EdebugはEmacs Lispプログラムにたいするソースレベルデバッガです。これによ り以下のことができます: • 式の前後でストップして評価をステップで実行する。 • 条件付きまたは無条件のbreakpointのセット。 • 指定された条件がtrueならストップする(グローバルbreakpoint)。 • ストップポイントごとに停止したり、breakpointごとに簡単に停止して低 速または高速にトレースを行う。 • Edebug外部であるかのように式の結果を表示して、式を評価する。 • 式のリストを自動的に再評価して、Edebugがディスプレイを更新するたび にそれらの結果を表示する。 • 関数呼び出しとリターンのトレース情報を出力する。 • エラー発生時にストップする。 • Edebug自身のフレームを除外してbacktraceを表示する。 • マクロとフォームの定義で引数の評価を指定する。 • 初歩的なカバレッジテストと頻度数の取得。 以下の初めの3つのセクションは、Edebugの使用を開始するために十分な説明 を行います。 17.2.1 Edebugの使用 ------------------- EdebugでLispプログラムをデバッグするには、最初にデバッグしたいLispコード を“インストルメント(instrument: 計装)”しなければなりません。これを行なう もっともシンプルな方法は、関数またはマクロの定義に移動して‘C-u C-M-x’(プ レフィクス引数を指定した‘eval-defun’)を行います。コードをインストルメン トする他の手段については、*note Instrumenting::を参照してください。 一度関数をインストルメントすると、その関数にたいする任意の呼び出しに よってEdebugがアクティブになります。Edebugがアクティブになると、どの Edebug実行モードを選択したかに依存して、その関数をステップ実行できるよう に実行がストップされるか、ディスプレイを更新してデバッグコマンドにたいす るチェックの間、実行が継続されます。デフォルトの実行モードstepで、これは 実行をストップします。*note Edebug Execution Modes::を参照してください。 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コマンドで 次のストップポイントまで実行することができます。‘fac’にエントリーした後 に一度とタイプした場合は、以下のように表示されるでしょう: (defun fac (n) =>(if ★(< 0 n) (* n (fac (1- n))) 1)) 式の後でEdebugが実行をストップしたときは、エコーエリアにその式の値が 表示されます。 他にも頻繁に使用されるコマンドとして、ストップポイントにbreakpointを セットする‘b’、breakpointに達するまで実行する‘g’、Edebugをexitしてトップ レベルのコマンドループにリターンする‘q’があります。また‘?’とタイプすると すべてのEdebugコマンドがリストされます。 17.2.2 Edebugのためのインストルメント ------------------------------------- LispコードのデバッグにEdebugを使用するためには、最初にそのコードを“イン ストルメント(instrument: 計装)”しなければなりません。コードをインストル メントすると、適切な位置でEdebugを呼び出すために追加コードが挿入されます 。 関数定義でプレフィクス引数とともにコマンド‘C-M-x’ (‘eval-defun’)を呼 び出すと、それを評価する前にその定義をインストルメントします(ソースコー ド自体は変更しない)。変数‘edebug-all-defs’が非‘nil’ならプレフィクス引数 の意味を反転します。この場合は、‘C-M-x’はプレフィクス引数が_なければ_そ の定義をインストルメントします。‘edebug-all-defs’のデフォルト値は‘nil’で す。コマンド‘M-x edebug-all-defs’は変数‘edebug-all-defs’の値を切り替えま す。 ‘edebug-all-defs’が非‘nil’なら‘eval-region’、‘eval-current-buffer’、 ‘eval-buffer’もそれらが評価する定義をインストルメントします。同様に ‘edebug-all-forms’は、‘eval-region’が(非定義フォームさえ含む_あらゆる_フ ォームをインストルメントするべきかを制御します。これはミニバッファー内で のロードや評価には適用されません。コマンド‘M-x edebug-all-forms’はこのオ プションを切り替えます。 他にもコマンド‘M-x edebug-eval-top-level-form’が利用でき、これは ‘edebug-all-defs’や‘edebug-all-forms’の値に関わらずトップレベルのすべて のフォームをインストルメントします。‘edebug-defun’は ‘edebug-eval-top-level-form’のエイリアスです。 Edebugがアクティブのの間、コマンド‘I’(‘edebug-instrument-callee’)はポ イント後のリストフォームに呼び出される関数およびマクロ定義がまだインスト ルメントされていなければ、それらをインストルメントします。これはそのファ イルのソースの場所をEdebugが知っている場合だけ可能です。この理由により Edebugロード後は、たとえ評価する定義をインストルメントしない場合でも、 ‘eval-region’は評価するすべての定義の位置を記録します。インストルメント 済み関数呼び出しにステップインする‘i’コマンドも参照してください(*note Jumping::を参照)。 Edebugはすべての標準スペシャルフォーム、式引数をもつ‘interactive’フォ ーム、無名ラムダ式、およびその他の定義フォームのインストルメント方法を知 っています。しかしEdebugはユーザー定義マクロが引数にたいして何を行うかを 判断できないので、Edebug仕様を使用してその情報を与えなければなりません。 詳細は*note Edebug and Macros::を参照してください。 Edebugがセッション内で最初にコードをインストルメントしようとするとき は、フック‘edebug-setup-hook’を実行してからそれに‘nil’をセットします。使 おうとしているパッケージに結びつけてEdebug仕様をロードするためにこれを使 用できますが、それはEdebugを使用するときだけ機能します。 定義からインストルメントを削除するには、単にインストルメントを行わな い方法でその定義を再評価するだけです。フォームを絶対にインストルメントせ ずに評価するには2つの方法があります。それはファイルからの‘load’による評 価と、ミニバッファーからの‘eval-expression’(‘M-:’)による評価です。 Edebugがインストルメント中にシンタックスエラー(syntax error: 構文エラ ー)を検知した場合は、間違ったコードの箇所にポイントを残して ‘invalid-read-syntax’エラーをシグナルします。 Edebug内で利用可能な他の評価関数については、*note Edebug Eval::を参照 してください。 17.2.3 Edebugの実行モード ------------------------- Edebugはデバッグするプログラムの実行にたいして、いくつかの実行モードをサ ポートします。これらの実行モードを“Edebug実行モード(Edebug execution modes)”と呼びます。これらをメジャーモードやマイナーモードと混同しないで ください。カレントのEdebug実行モードは、プログラムをストップする前に Edebugがどれだけ実行を継続するか — たとえばストップポイントごとにストッ プ、あるいは次のbreakpointまで継続など — 、およびストップする前に Edebugがどれだけ進捗を表示するかを決定します。 Edebug実行モードは、通常はある特定のモードでプログラムを継続させるコ マンドをタイプすることによって指定します。以下はそれらのコマンドのテーブ ルです。‘S’以外のコマンドはプログラムの実行を再開して、少なくともある長 さの間だけは実行を継続します。 ‘S’ Stop(ストップ): これ以上プログラムを実行しないでEdebugのコマンドを 待つ(‘edebug-stop’)。 ‘’ Step(ステップ): 次のストップポイントでストップする (‘edebug-step-mode’)。 ‘n’ Next(次へ): 式の後にある次のストップポイントでストップする (‘edebug-next-mode’)。*note Jumping::の‘edebug-forward-sexp’も参照 のこと。 ‘t’ Trace(トレース): Edebugのストップポイントごとにpause(通常は1秒)する (‘edebug-trace-mode’)。 ‘T’ Rapid trace(高速でトレース):ストップポイントごとに表示を更新するが 、実際にpauseはしない(‘edebug-Trace-fast-mode’)。 ‘g’ Go(進む): 次のbreakpointまで実行する(‘edebug-go-mode’)。*note Breakpoints::を参照のこと。 ‘c’ Continue(継続): breakpointごとにpauseしてから継続する (‘edebug-continue-mode’)。 ‘C’ Rapid continue(高速で継続): ポイントを各breakpointへ移動するが pauseしない(‘edebug-Continue-fast-mode’)。 ‘G’ Go non-stop(ストップせず進む): breakpointを無視する (‘edebug-Go-nonstop-mode’)。まだ‘S’やその他の編集コマンドでプログラ ムをストップするのは可能。 一般的に上記リストの最初のほうにある実行モードは後のほうの実行モード に比べて、プログラムをより低速に実行するか、すぐにストップさせます。 新たなEdebugレベルにエンターしたとき、Edebugは通常は最初に遭遇したイ ンストルメント済みの関数でストップするでしょう。breakpointでのみストップ するか、(たとえばカバレッジデータ収集時など)ストップさせないようにするに は、‘edebug-initial-mode’の値をデフォルトの‘step’から‘go’か ‘Go-nonstop’、あるいはその他の値に変更してください(*note Edebug Options::を参照)。‘C-x C-a C-m’ (‘edebug-set-initial-mode’)でこれを容易 に行うことができます: -- Command: 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内部のコマンドに影響しま せん。通常これは利点です。*note Edebug Options::内の ‘edebug-continue-kbd-macro’オプションも参照してください。 -- User Option: edebug-sit-for-seconds このオプションはtraceモードとcontinueモードで実行ステップの間を何秒 待つか指定する。デフォルトは1秒。 17.2.4 ジャンプ --------------- このセクションで説明するコマンドは、指定された場所に達するまで実行を続け ます。‘i’を除くすべてのコマンドは、ストップ場所を確立するために一時的な breakpointを作成してからgoモードにスイッチします。意図されたストップポイ ントの前にある他のストップポイントに達した場合にも実行はストップします。 breakpointの詳細は、*note Breakpoints::を参照してください。 以下のコマンドでは、非ローカルexitはプログラムのストップを望む一時的 なbreakpointをバイパスできるので、期待どおり機能しないかもしれません。 ‘h’ ポイントがある場所の近くのストップポイントへ実行を進める (‘edebug-goto-here’)。 ‘f’ プログラムの式を1つ実行する(‘edebug-forward-sexp’)。 ‘o’ sexpを含む終端までプログラムを実行する(‘edebug-step-out’)。 ‘i’ ポイントの後のフォームから呼び出された関数かマクロにステップインす る(‘edebug-step-in’)。 ‘h’コマンドは一時的なbreakpointを使用してポイントのカレント位置、また はその後のストップポイントまで処理を進めます。 ‘f’コマンドは式を1つ飛び越してプログラムを実行します。より正確には ‘forward-sexp’により到達できる位置に一時的なbreakpointをセットしてから goモードで実行するので、プログラムはそのbreakpointでストップすることにな ります。 プレフィクス引数Nとともに使用すると、ポイントからN個の sexp(s-expression: S式)を超えた場所に一時的なbreakpointをセットします。 ポイントを含むリストがNより少ない要素で終わるような場合には、ストップ箇 所はポイントが含まれる式の後になります。 ‘forward-sexp’が見つける位置が、プログラムを実際にストップさせたい位 置なのかチェックしなければなりません。たとえば‘cond’内ではこれは正しくな いかもしれません。 ‘f’コマンドは柔軟性を与えるために、‘forward-sexp’をストップポイントで はなくポイント位置から開始します。_カレントのストップポイント_から1つの 式を実行したい場合には、まずそこにポイントを移動するために ‘w’(‘edebug-where’)をタイプして、それから‘f’をタイプしてください。 ‘o’コマンドは、式の外側で実行を継続します。これはポイントを含む式の最 後に一時的なbreakpointを配置します。ポイントを含むsexpが関数定義なら ‘o’はその定義内の最後のsexpの直前まで実行を継続します。もし定義内の最後 のsexpの直前にポイントがある場合は、その関数からリターンしてからストップ します。言い換えるとこのコマンドは最後のsexpの後にポイントがなければ、カ レントで実行中の関数からexitしません。 ‘i’コマンドは、ポイントの後のリストフォームに呼び出された関数やマクロ にステップインします。そのフォームは評価されようとしているものの1つであ る必要はないことに注意してください。しかしそのフォームが評価されようとし ている関数呼び出しなら、引数が何も評価されないうちにこのコマンドを使用し ないと、遅すぎることを覚えておいてください。 ‘i’コマンドはステップインしようとしている関数やマクロがまだインストル メントされていなければ、それらをインストルメントします。これは便利かもし れませんが、それらを明示的に非インストルメントしなければ、その関数やマク ロはインストルメントされたままになることを覚えておいてください。 17.2.5 その他のEdebugコマンド ----------------------------- ここではその他のEdebugコマンドを説明します。 ‘?’ Edebugのヘルプメッセージを表示する(‘edebug-help’)。 ‘C-]’ 1レベルを中断して以前のコマンドレベルへ戻る (‘abort-recursive-edit’)。 ‘q’ エディターのトップレベルのコマンドループにリターンする (‘top-level’)。これはすべてのレベルのEdebugアクティビティを含むすべ ての再帰編集レベルをexitする。しかしフォーム‘unwind-protect’か ‘condition-case’で保護されたインストルメント済みのコードはデバッグ を再開するかもしれない。 ‘Q’ ‘q’と同様だが、保護されたコードでもストップしない (‘edebug-top-level-nonstop’)。 ‘r’ エコーエリアにもっとも最近の既知のコマンドを再表示する (‘edebug-previous-result’)。 ‘d’ backtraceを表示するが、明確であるようにEdebug自身の関数は除外される (‘edebug-backtrace’)。 Edebugのbacktraceバッファーでは、標準デバッガ内のようにバッガコマン ドは使用できない。 実行を継続したときにbacktraceバッファーは自動的にkillされる。 Edebugから再帰的にEdebugをアクティブにするコマンドを呼び出すことがで きます。Edebugがアクティブなときは常に‘q’によトップレベルの終了、または ‘C-]’による再帰編集1レベルの中断ができます。‘d’によってすべての未解決な 評価のbacktraceを表示できます。 17.2.6 ブレーク --------------- Edebugのstepモードは、次のストップポイントに達したときに実行をストップし ます。一度開始されたEdebugの実行をストップするには、他に3つの方法があり ます。それはbreakpoint、グローバルbreak条件、およびソースbreakpointです 。 17.2.6.1 Edebugのブレークポイント ................................. Edebugを使用しているときは、テスト中のプログラム内に“breakpoint”を指定で きます。breakpointとは実行がストップされる場所のことです。*note Using Edebug::で定義されている任意のストップポイントにbreakpointをセットできま す。breakpointのセットと解除で影響を受けるストップポイントは、ソースコー ドバッファー内でポイント位置、またはポイント位置の後の最初のストップポイ ントです。以下はEdebugのbreakpoint用のコマンドです: ‘b’ ポイント位置、またはポイント位置の後のストップポイントに breakpointをセットする(‘edebug-set-breakpoint’)。プレフィクス引数を 使用すると、それは一時的なbreakpointとなり、プログラムが最初にそこ で停止したときに解除される。 ‘u’ (もしあれば)ポイント位置、またはポイント位置の後のストップポイント にあるbreakpointを解除(unset)する(‘edebug-unset-breakpoint’)。 ‘x CONDITION ’ CONDITIONを評価して非‘nil’値になる場合だけプログラムをストップする 条件付きbreakpointをセットする (‘edebug-set-conditional-breakpoint’)。プレフィクス引数を指定すると 一時的なbreakpointになる。 ‘B’ カレント定義内の次の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)にポイントを移動します。この コマンドは実行を継続せずに、単にバッファー内のポイントを移動します。 17.2.6.2 グローバルなブレーク条件 ................................. “グローバル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’にリセットするべきです。 17.2.6.3 ソースブレークポイント ............................... 定義内のすべての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’を呼び出します。 17.2.7 エラーのトラップ ----------------------- エラーがシグナルされて、それが‘condition-case’でハンドルされていないとき 、Emacsは通常はエラーメッセージを表示します。Edebugがアクティブでインス トルメント済みコードの実行中は、ハンドルされていないエラーには通常は Edebugが対応します。オプション‘edebug-on-error’と‘edebug-on-quit’でこれ をカスタマイズできます。*note Edebug Options::を参照してください。 Edebugがエラーに対応するときは、エラー発生箇所の前にある最後のストッ プポイントを表示します。この場所はインストルメントされていない関数の呼び 出しであったり、その関数内で実際にエラーが発生したのかもしれません。バイ ンドされていない変数に関するエラーの場合は、最後の既知のストップポイント は、その不正な変数参照から遠く離れた場所にあるかもしれません。そのような 場合には完全なbacktraceを表示したいと思うでしょう(*note Edebug Misc::を 参照)。 Edebugがアクティブの間に‘debug-on-error’か‘debug-on-quit’を変更すると 、それらの変更はEdebugが非アクティブになったとき失われます。さらに Edebugの再帰編集の間、これらの変数はEdebugの外部でもっていた値にバインド されます。 17.2.8 Edebugのビュー --------------------- これらのEdebugコマンドは、Edebugにエントリーする前のバッファーの外観とウ ィンドウの状態を調べるコマンドです。外部のウィンドウ構成はウィンドウのコ レクションとその内容であり、それらは実際にはEdebugの外部にあります。 ‘v’ 外部のウィンドウ構成ビューに切り替える(‘edebug-view-outside’)。 Edebugにリターンするには‘C-x X w’をタイプする。 ‘p’ 一時的に外部のカレントバッファーを表示して、ポイントもその外部の位 置になる(‘edebug-bounce-point’)。Edebugにリターンする前に1秒 pauseす る。プレフィクス引数Nを指定すると、かわりにN秒 pauseする。 ‘w’ ソースコードバッファー内のカレントストップポイントにポイントを戻す (‘edebug-where’)。 このコマンドを同じバッファーを表示する異なるウィンドウで使用すると 、そのウィンドウは将来カレント定義を表示するために代用される。 ‘W’ Edebugが外部のウィンドウ構成の保存とリストアを行うかどうかを切り替 える(‘edebug-toggle-save-windows’)。 プレフィクス引数を指定すると、‘W’は選択されたウィンドウの保存とリス トアだけを切り替える。ソースコードバッファーを表示していないウィン ドウを指定するには、グローバルキーマップから‘C-x X W’を使用しなけれ ばならない。 ‘v’、または単に‘p’でカレントバッファーにポイントを反跳させれば、たと え通常は表示されないウィンドウでも外部のウィンドウ構成を調べることができ ます。 ポイントを移動した後にストップポイントに戻りたいときがあるかもしれま せん。これはソースコードバッファーから‘w’で行うことができます。どのバッ ファーにいても‘C-x X w’を使用すれば、ソースコードバッファー内のストップ ポイントに戻ることができます。 保存を_オフ_にするために‘W’を使用するたびに、Edebugは外部のウィンドウ 構成を忘れます。そのためたとえ保存を_オン_に戻しても、(プログラムを実行 することによって)次にEdebugをexitしたとき、カレントウィンドウ構成は変更 されないまま残ります。しかし十分な数のウィンドウをオープンしていない場合 には、‘*edebug*’と‘*edebug-trace*’の再表示があなたが見たいバッファーと競 合するかもしれません。 17.2.9 評価 ----------- Edebug内では、まるでEdebugが実行されていないかのように式を評価できます。 式の評価とプリントに際して、Edebugは不可視になるよう試みます。副作用をも つ式の評価は、Edebugが明示的に保存とリストアを行うデータへの変更を除いて 期待したとおり機能するでしょう。このプロセスの詳細は、*note The Outside Context::を参照してください。 ‘e EXP ’ Edebugのコンテキスト外で式EXPを評価する(‘edebug-eval-expression’)。 つまり、Edebugはその式への干渉を最小限にしようと努める。 ‘M-: EXP ’ Edebug自身のコンテキスト内で式EXPを評価する(‘eval-expression’)。 ‘C-x C-e’ Edebugのコンテキスト外でポイントの前の式を評価する (‘edebug-eval-last-sexp’)。 Edebugは‘cl.el’内の構文(‘lexical-let’、‘macrolet’、 ‘symbol-macrolet’)によって作成された、レキシカル(lexical)にバインドされ たシンボルへの参照を含む式の評価をサポートします。 17.2.10 評価 List Buffer ------------------------ 式をインタラクティブに評価するために、‘*edebug*’と呼ばれる“評価リストバ ッファー(evaluation list buffer)”を使用できます。Edebugがディスプレイを 更新するたびに自動的に評価される、式の“評価リスト(evaluation list)”もセ ットアップできます。 ‘E’ 評価リストバッファー‘*edebug*’に切り替える (‘edebug-visit-eval-list’)。 ‘*edebug*’バッファーでは、以下の特別なコマンドと同様にLisp Interactionモード(*note (emacs)Lisp Interaction::を参照)のコマンドも使用 できます。 ‘C-j’ ポイントの前の式をコンテキスト外で評価して、その値をバッファーに挿 入する(‘edebug-eval-print-last-sexp’)。 ‘C-x C-e’ Edebugのコンテキスト外でポイントの前の式を評価する (‘edebug-eval-last-sexp’)。 ‘C-c C-u’ バッファー内のコンテンツから新たに評価リストを構築する (‘edebug-update-eval-list’)。 ‘C-c C-d’ ポイントのある評価リストグループを削除する (‘edebug-delete-eval-item’)。 ‘C-c C-w’ ソースコードバッファーに切り替えてカレントストップポイントに戻る (‘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) # ;--------------------------------------------------------------- (selected-window) # ;--------------------------------------------------------------- (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されて、次回必要となったとき に再作成されます。 17.2.11 Edebugでのプリント -------------------------- プログラム内の式が循環リスト構造(circular list structure)を含む値を生成 する場合は、Edebugがそれをプリントしようとしたときエラーとなるかもしれま せん。 循環構造への対処の1つとして、‘print-length’と‘print-level’にプリント の切り詰めをセットする方法があります。Edebugは変数 ‘edebug-print-length’と‘edebug-print-level’の値(非‘nil’値なら)を、これら の変数にバインドします。*note Output Variables::を参照してください。 -- User Option: edebug-print-length 非‘nil’なら結果をプリントするときEdebugは‘print-length’をこの値にバ インドする。デフォルト値は‘50’。 -- User Option: edebug-print-level 非‘nil’なら結果をプリントするときEdebugは‘print-level’をこの値にバ インドする。デフォルト値は‘50’。 ‘print-circle’を非‘nil’値にバインドして、循環構造や要素を共有する構造 にたいして、より参考になる情報をプリントするよういにすることもできます。 以下は循環構造を作成するコードの例です: (setq a '(x y)) (setcar a a) カスタムプリントはこれを‘Result: #1=(#1# y)’のようにプリントします。 ‘#1=’という表記はその後の構造をラベル‘1’とラベル付けして、‘#1#’表記はそ の前にラベル付けされた構造を参照しています。この表記はリストとベクターの 任意の共有要素に使用されます。 -- User Option: edebug-print-circle 非‘nil’なら結果をプリントするときEdebugは‘print-circle’をこの値にバ インドする。デフォルト値は‘t’。 他のプログラムもカスタムプリントを使用できます。詳細は ‘cust-print.el’を参照してください。 17.2.12 トレースバッファー -------------------------- Edebugは実行トレースを‘*edebug-trace*’という名前のバッファーに格納して記 録できます。実行トレースとは関数呼び出しとリターンのログのことで関数名と 引数、および値を確認できます。トレースレコードを有効にするには、 ‘edebug-trace’を非‘nil’値にセットしてください。 トレースバッファーの作成は実行モードのトレースの使用(*note Edebug Execution Modes::を参照)と同じではありません。 トレースレコードが有効なときは、関数へのエントリーとexitのたびにトレ ースバッファーに行が追加されます。関数エントリーレコードは‘::::{’、およ び関数名と引数の値によって構成されます。関数のexitレコードは‘::::}’、お よび関数名と関数の結果によって構成されます。 ‘:’の数は関数エントリーの再帰レベルを表します。トレースバッファーでは 関数呼び出しの開始と終了の検索に‘{’と‘}’を使用できます。 関数‘edebug-print-trace-before’と‘edebug-print-trace-after’を再定義す ることによって、関数エントリーと関数exitのトレースレコードをカスタマイズ できます。 -- Macro: edebug-tracing string body... このマクロはBODYフォームの実行活動にたいして追加のトレース情報をリ クエストする。引数STRINGはトレースバッファーに配置する‘{’と‘}’の後 のテキストを指定する。すべての引数は評価されて、‘edebug-tracing’は BODY内の最後のフォームの値をリターンする。 -- Function: edebug-trace format-string &rest format-args この関数はトレースバッファーにテキストを挿入する。テキストは‘(apply 'format FORMAT-STRING FORMAT-ARGS)’によって計算される。エントリー間 の区切りとして改行も付け加える。 ‘edebug-tracing’と‘edebug-trace’は、たとえEdebugが非アクティブでも、 呼び出されたときは常にトレースバッファーに行を挿入します。トレースバッフ ァーへのテキストの追加により、挿入された最後の行が見えるようにウィンドウ もスクロールします。 17.2.13 カバレッジテスト ------------------------ 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’)とすると、他のキーをタイプするまでの間 だけ一時的に同様の情報を表示します。 -- Command: edebug-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’の再帰呼び出しは結局リターンしません 。 17.2.14 コンテキスト外部 ------------------------ Edebugはデバッグ中のプログラムにたいして透過的であろうと努めますが完全に は達成されません。Edebugは‘e’や評価リストバッファーで式を評価するときに も、一時的に外部のコンテキストをリストアして透明化を試みます。このセクシ ョンではEdebugがリストアするコンテキストと、Edebugが完全に透過的になるの に失敗する理由を正確に説明します。 17.2.14.1 停止するかどうかのチェック .................................... Edebugにエンターするときは常に特定のデータの保存とリストアを行なう必要が あり、それはトレース情報を作成するか、あるいはプログラムを停止するかを決 定する前に行なう必要があります。 • ‘max-lisp-eval-depth’と‘max-specpdl-size’は、Edebugがスタックに与え る影響の低減効果を高める。しかしそれでもEdebug使用時にスタック空間 を使い切ってしまうことがあり得る。 • キーボードマクロの実行状態の保存とリストアが行われる。Edebugがアク ティブの間、‘edebug-continue-kbd-macro’が‘nil’なら ‘executing-kbd-macro’が‘nil’にバインドされる。 17.2.14.2 Edebugの表示の更新 ............................ (たとえばtraceモードなどで)Edebugが何かを表示する必要があるときは、 Edebugの外部からカレントウィンドウ構成(*note Window Configurations::を参 照)を保存します。Edebugをexitするときに、以前のウィンドウ構成がリストア されます。 Emacsはpause時だけ再表示を行います。通常は実行を継続すると、そのプロ グラムはbreakpointかステップ実行後にEdebugに再エンターして、その間に pauseや入力の読み取りはありません。そのような場合、Emacsが外部の構成を再 表示する機会は決してありません。結果としてユーザーが目にするウィンドウ構 成は、前回Edebugが中断なしでアクティブだったときのウィンドウ構成と同じに なります。 何かを表示するためにEdebugにエントリーすることにより、(たとえこれらの うちのいくつかは、エラーやquitがシグナルされたときは故意にリストアしない データだとしても)以下のデータも保存とリストアが行われます。 • カレントバッファー、およびカレントバッファー内のポイントとマークの 位置が保存およびリストアされる。 • ‘edebug-save-windows’が非‘nil’なら、外部のウィンドウ構成の保存とリ ストアが行われる(*note Edebug Options::を参照)。 エラーやquitではウィンドウ構成はリストアされないが、 ‘save-excursion’がアクティブなら、たとえエラーやquitのときでも外部 の選択されたウィンドウが_再選択される_。‘edebug-save-windows’の値が リストなら、それにリストされたウィンドウだけが保存およびリストアさ れる。 ただしソースコードバッファーのウィンドウの開始位置と水平スクロール はリストアされないので、表示はEdebug内で整合性が保たれたままとなる 。 • ‘edebug-save-displayed-buffer-points’が非‘nil’なら、表示されている それぞれのバッファー内のポイント値は保存およびリストアされる。 • 変数‘overlay-arrow-position’と‘overlay-arrow-string’は保存とリスト アが行われるので、同じバッファー内の他の場所の再帰編集から安全に Edebugを呼び出せる。 • ‘cursor-in-echo-area’は‘nil’にローカルにバインドされるのでカーソル はそのウィンドウ内に現れる。 17.2.14.3 Edebugの再帰編集 .......................... Edebugにエンターしてユーザーのコマンドが実際に読み取られるとき、Edebugは 以下の追加データを保存(および後でリストア)します: • カレントマッチデータ。*note Match Data::を参照のこと。 • 変数‘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にエンターすると、デバッグ中のプロ グラムの実行に干渉する可能性がある。 • Edebug内で実行された複雑なコマンドは変数‘command-history’に追加され る。これは稀に実行に影響を与える。 • Edebug内では再帰の深さがEdebug外部の再帰の深さより1つ深くなる。これ は自動的に更新される評価リストウィンドウでは異なる。 • ‘standard-output’と‘standard-input’は、‘recursive-edit’によって ‘nil’にバインドされるがEdebugは評価の間それらを一時的にリストアする 。 • キーボードマクロ定義の状態は保存およびリストアされる。Edebugがアク ティブの間、‘defining-kbd-macro’は‘edebug-continue-kbd-macro’にバイ ンドされる。 17.2.15 Edebugとマクロ ---------------------- Edebugが正しくマクロを呼び出す式をインストルメントするには、いくつかの特 定な配慮が必要になります。このサブセクションでは、その詳細を説明します。 17.2.15.1 マクロ呼び出しのインストルメント .......................................... EdebugがLispマクロを呼び出す式をインストルメントするときは、正しくインス トルメントを行なうために、そのマクロに関して追加の情報が必要になります。 これはマクロ呼び出しのどの部分式(subexpression)が評価されるフォームなの か推測する方法がないからです(評価はマクロのbodyで明示的に発生するかもし れないし、展開結果が評価されるとき、または任意のタイミングで行われるかも しれない)。 したがってEdebugが処理するかもしれないすべてのマクロにたいして、その マクロの呼び出しフォーマットを説明するためのEdebug仕様(Edebug specification)を定義しなければなりません。これを行なうにはマクロ定義に ‘debug’宣言を追加します。以下はマクロ例‘for’(*note Argument Evaluation::を参照)にたいする簡単な仕様の例です。 (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’フォームの詳細は*note Defining Macros::を参照して ください。 コードをインストルメントするときには、Edebugに仕様が確実に解るように 注意してください。マクロ定義を含む他のファイルを要求するために ‘eval-when-compile’を使用するファイルから関数をインストルメントする場合 には、そのファイルを明示的にロードする必要があるかもしれません。 ‘def-edebug-spec’によりマクロ定義から個々のマクロにたいしてEdebug仕様 を定義することもできます。Lispで記述されたマクロ定義にたいしては ‘debug’宣言を追加するほうが好ましく便利でもありますが、 ‘def-edebug-spec’ではCで実装されたスペシャルフォームにたいしてEdebug仕様 を定義することが可能になります。 -- Macro: def-edebug-spec macro specification マクロMACRO呼び出しのどの式が評価される式かを指定する。 SPECIFICATIONはEdebug仕様である。どちらの引数も評価されない。 引数MACROには単なるマクロ名ではない、任意の実シンボルを指定できる。 以下はSPECIFICATIONに指定できるシンボルと、引数を処理する方法のテーブ ルです。 ‘t’ すべての引数は評価のためにインストルメントされる。 ‘0’ 引数はインストルメントされない。 シンボル そのシンボルはかわりに使用されるEdebug仕様をもたなければならない。 このインダイレクションは他の種類の仕様が見つかるまで繰り返される。 これによって他のマクロの仕様を継承できる。 リスト リストの要素はフォーム呼び出しの引数の型を記述する。仕様リストに指 定できる要素については以降のセクションを参照のこと。 マクロがEdebug仕様をもたなければ、‘debug’宣言および ‘def-edebug-spec’呼び出しのどちらを介しても、変数 ‘edebug-eval-macro-args’が効果を発揮します。 -- User Option: edebug-eval-macro-args これはEdebugが明示的なEdebug仕様をもたないマクロ引数を扱う方法を制 御する。‘nil’(デフォルト)なら引数は評価のためにインストルメントされ ない。それ以外ばらすべての引数がインストルメントされる。 17.2.15.2 仕様リスト .................... あるマクロ呼び出しにおいて、いくつかの引数は評価されても、それ以外の引数 は評価されないような場合には、Edebug仕様のために“仕様リスト (specification list)”が必要となります。仕様リスト内のいくつかの要素は1つ 以上の引数にマッチしますが、それ以外の要素は以降に続くすべての引数の処理 を変更します。後者は“仕様キーワード(specification keywords)”と呼ばれ、 (‘&optional’のように)‘&’で始まるシンボルです。 仕様リストはそれ自身がリストであるような引数にマッチする部分リスト (sublist)、あるいはグループ化に使用されるベクターを含むかもしれません。 したがって部分式とグループは仕様リストをレベル階層に細分化します。仕様キ ーワードは部分式やグループを含むものの残りに適用されます。 仕様リストに選択肢や繰り返しが含まれる場合は、実際のマクロの呼び出し のマッチでバックトラックが要求されるかもしれません。詳細は*note Backtracking::を参照してください。 Edebug仕様はバランスのとれたカッコで括られた部分式へのマッチ、フォー ムの再帰処理、インダイレクト仕様を通じた再帰等の、正規表現によるマッチン グとコンテキストに依存しない文法構成を提供します。 以下は仕様リストに使用できる要素と、その意味についてのテーブルです(使 用例は*note Specification Examples::を参照): ‘sexp’ 評価されない単一のLispオブジェクト。インストルメントされない。 ‘form’ 評価される単一のLispオブジェクト。インストルメントされる。 ‘place’ 汎変数(generalized variable)。*note Generalized Variables::を参照の こと。 ‘body’ ‘&rest form’の省略形。以下の‘&rest’を参照のこと。 ‘function-form’ 関数フォーム。クォートされた関数シンボル、クォートされたラムダ式、 または(関数シンボルかラムダ式に評価される)フォームのいずれか。これ はラムダ式のbodyをいずれかの方法でインストルメントするので、 ‘function’よりも‘quote’でクォートされたラムダ式の引数にたいして有用 。 ‘lambda-expr’ クォートされないラムダ式。 ‘&optional’ 仕様リスト内の後続の要素はオプション。マッチしない要素が出現すると Edebugはこのレベルのマッチングを停止する。 後続が非オプションの要素であるような数個の要素をオプションにするだ けなら、‘[&optional SPECS...]’を使用する。複数の要素すべてのマッチ や非マッチを指定するには、‘&optional [SPECS...]’を使用する。 ‘defun’の例を参照のこと。 ‘&rest’ 仕様リスト内の後続のすべての要素は0回以上繰り返される。しかし最後の 繰り返しでは、仕様リスト内のすべての要素にたいするマッチングの前に 式が終了しても問題はない。 数個の要素を繰り返すには‘[&rest SPECS...]’を使用する。各繰り返しに おいてすべてマッチしなければならない複数要素を指定するには、‘&rest [SPECS...]’を使用する。 ‘&or’ 仕様リスト内の後続の各要素は選択肢である。選択肢の1つがマッチしなけ ればならず、マッチしなければ‘&or’仕様は失敗する。 ‘&or’に続く各リスト要素は単一の選択肢である。複数のリスト要素を単一 の選択肢にグループ化するには、それらを‘[...]’で括る。 ‘¬’ 後続の各要素は‘&or’が使用されたときのように選択肢にマッチするが、要 素がマッチしたら失敗となる。マッチする要素がなければ何もマッチされ ないが‘¬’仕様は成功となる。 ‘&define’ フォーム定義にたいする仕様であることを示す。フォーム定義自体はイン ストルメントされない(つまりEdebugはフォーム定義の前後でストップしな い)が、フォーム内部は通常はインストルメントされるであろう。 ‘&define’キーワードはリスト仕様の最初の要素であること。 ‘nil’ カレント引数レベルでマッチさせる引数が存在しなければ成功し、それ以 外は失敗する。部分リスト仕様とバッククォートの例を参照のこと。 ‘gate’ 引数はマッチされないがgateを通じたバックトラックは、このレベルの仕 様の残りをマッチングする間は無効にされる。これは主に特定の構文エラ ーメッセージを一般化するために使用される。詳細は*note Backtracking::、および‘let’の例も参照のこと。 ‘OTHER-SYMBOL’ 仕様リスト内のその他の要素は、述語(predicate)かインダイレクト仕様 (indirect specification)である。 シンボルがEdebug仕様をもつなら、“インダイレクト仕様(indirect specification)”はシンボル位置に使用されるリスト仕様か、引数を処理す るための関数のいずれかである。この仕様はマクロにたいする ‘def-edebug-spec’のように定義される。‘defun’の例を参照のこと。 それ以外ならシンボルは述語(predicate)である。述語は引数とともに呼び 出されて‘nil’をリターンしたら、その仕様は失敗して引数はインストルメ ントされない。 適切な述語としては‘symbolp’、‘integerp’、‘stringp’、‘vectorp’、 ‘atom’が含まれる。 ‘[ELEMENTS...]’ 要素のベクターは要素を単一の“グループ仕様(group specification)”にグ ループ化する。このグループ仕様はベクター自体には何も行わない。 ‘"STRING"’ 引数はSTRINGという名前のシンボルである。この仕様はSYMBOLの名前が STRINGであるようなクォートされたシンボル‘'SYMBOL’と等価だが、文字列 形式のほうが好ましい。 ‘(vector ELEMENTS...)’ 引数は要素が仕様内のELEMENTSにマッチするようなベクターである。バッ ククォートの例を参照のこと。 ‘(ELEMENTS...)’ 他のリストは“部分リスト仕様(sublist specification)”であり、引数は要 素が仕様のELEMENTSにマッチするリストでなければならない。 部分リスト仕様はドットリスト(dotted list)かもしれず、その場合対応す るリスト引数はドットリストである。かわりにドットリスト仕様の最後の CDRが、(グループ化やインダイレクト仕様による)他の部分リスト仕様かも しれない(たとえば要素が非ドットリストにマッチする‘(spec . [(more specs...)])’))。これはバッククォートの例のような再帰仕様に有用。こ のような再帰を終了させるには上述の‘nil’仕様も参照のこと。 ‘(specs . nil)’のように記述された部分リスト仕様は‘(specs)’、‘(specs . (sublist-elements...))’は‘(specs sublist-elements...)’と等価であ ることに注意。 以下は‘&define’の後だけに出現する追加仕様のリストです。‘defun’の例を 参照してください。 ‘name’ 引数(シンボル)は定義フォームの名前。 定義フォームは名前フィールドをもつ必要はなく、複数の名前フィールド をもつかもしれない。 ‘:name’ この構文は引数に実際のマッチは行わない。‘:name’の後の要素はシンボル であり、その定義の追加の名前要素として使用される。定義名に一意で静 的な要素を加えるためにこれを使用できる。複数回使用できる。 ‘arg’ 引数(シンボル)は定義フォームの引数の名前である。しかしlambda-listキ ーワード(‘&’で始まるシンボル)は許されない。 ‘lambda-list’ これはラムダリスト(ラムダ式の引数リスト)にマッチする。 ‘def-body’ 引数は定義内のコードのbodyである。これは上述の‘body’と似ているが、 定義のbodyはその定義に関連する情報を照会する別のEdebug呼び出しでイ ンストルメントされていなければならない。定義内のより高位レベルのフ ォームリストには‘def-body’を使用する。 ‘def-form’ 引数は定義内のもっとも高位レベルの単一フォームである。これは ‘def-body’と似ているが、フォームリストではなく単一フォームのマッチ に使用される。特別なケースとして‘def-form’はフォームが実行されると きトレース情報を出力しないことも意味する。‘interactive’の例を参照の こと。 17.2.15.3 仕様でのバックトレース ................................ あるポイント位置で仕様がマッチに失敗しても、構文エラーがシグナルされると は限りません。そのかわり“バックトラッッキング(backtracking)”が開始されま す。バックトラックはすべての選択肢をマッチングするまで行なわれます。最終 的に引数リストのすべての要素は仕様内の要素のいずれかとマッチしなければな らず、仕様内の必須要素は引数のいずれかとマッチしなければなりません。 構文エラーが検出されてもその時点では報告されず、より高位レベルの選択 肢のマッチングが終わった後、実際のエラー箇所から離れたポイント位置でエラ ーが報告されるかもしれません。しかしエラー発生時にバックトラックが無効な らエラーは即座に報告されるでしょう。ある状況ではバックトラックも自動的に 再有効化されることに注意してください。‘&optional’、‘&rest’、‘&or’により 新たな選択肢が設定されたとき、または部分リスト、グループ、インダイレクト 仕様が開始されたときはバックトラックが自動的に有効になります。バックトラ ックを有効、または無効にした場合の影響は、現在処理中のレベルの残り要素と 低位レベルに限定されます。 何らかのフォーム仕様(すなわち‘form’、‘body’、‘def-form’、 ‘def-body’)をマッチングする間、バックトラックは無効になっています。これ らの仕様は任意のフォームにマッチするので、何らかのエラーが発生するとした らそれは高位レベルではなく、そのフォーム自体の内部でなければなりません。 バックトラックはクォートされたシンボルや文字列仕様とのマッチに成功し た後にも無効になります。なぜなら通常これは構文成が認識されたことを示すか らです。しかし同じシンボルで始まる一連の選択肢構文がある場合には、たとえ ば‘["foo" &or [first case] [second case] ...]’のように、通常は選択肢の外 部にそのシンボルをファクタリングすることによりこの制約に対処できます。 ほとんどのニーズは、バックトラックを自動的に無効にする、これら2つの方 法で満足させることができますが、‘gate’仕様を使用して明示的にバックトラッ クを無効にするほうが便利なときもあります。これは高位に適用可能な選択肢が 存在しないことが分かっている場合に有用です。‘let’仕様の例を参照してくだ さい。 17.2.15.4 仕様の例 .................. 以下で提供する例から学ぶことにより、Edebug仕様の理解が容易になるでしょう 。 スペシャルフォーム‘let’は、バインディングとbodyのシーケンスをもちます 。各バインディングはそシンボル、またはシンボルとオプションの部分リストで す。以下の仕様では部分リストを見つけたらバックトラックを抑止するために、 部分リスト内の‘gate’があることに注目してください。 (def-edebug-spec let ((&rest &or symbolp (gate symbolp &optional form)) body)) Edebugは‘defun’および関連する引数リスト、‘interactive’仕様にたいして 以下の仕様を使用します。式の引数はその関数bodyの外部で実際に評価されるの で、interactiveフォームは特別に処理する必要があります。(‘defmacro’にたい する仕様は‘defun’にたいする仕様と酷似するが‘declare’命令文が許される) (def-edebug-spec defun (&define name lambda-list [&optional stringp] ; ドキュメント文字列が与えられた場合はマッチする。 [&optional ("interactive" interactive)] def-body)) (def-edebug-spec lambda-list (([&rest arg] [&optional ["&optional" arg &rest arg]] &optional ["&rest" arg] ))) (def-edebug-spec interactive (&optional &or stringp def-form)) ; ‘def-form’に注目 以下のバッククォートにたいする仕様はドットリストにマッチさせる方法と 、‘nil’を使用して再帰を終了させる方法を説明するための例です。またベクタ ーのコンポーネントをマッチさせる方法も示しています(Edebugにより定義され る実際の仕様は少し異なり、失敗するかもしれない非常に深い再帰を引き起こす ためドットリストについてはサポートしない)。 (def-edebug-spec \` (backquote-form)) ; 単なる明確化用エイリアス (def-edebug-spec backquote-form (&or ([&or "," ",@"] &or ("quote" backquote-form) form) (backquote-form . [&or nil backquote-form]) (vector &rest backquote-form) sexp)) 17.2.16 Edebugのオプション -------------------------- 以下のオプションはEdebugの動作に影響を与えます: -- User Option: edebug-setup-hook Edebugが使用される前に呼び出される関数。この関数は毎回新たな値をセ ットする。Edebugはこれらの関数を一度呼び出したら、その後に ‘edebug-setup-hook’を‘nil’にリセットする。使用するパッケージに関係 するEdebug仕様をロードするために使用でdきるがそれはEdebugを使用す るときだけである。*note Instrumenting::を参照のこと。 -- User Option: edebug-all-defs これが非‘nil’の場合に‘defun’や‘defmacro’のような定義フォームの普通 に評価すると、Edebug用にインストルメントされる。これは ‘eval-defun’、‘eval-region’、‘eval-buffer’、and ‘eval-current-buffer’に適用される。 このオプションの切り替えにはコマンド‘M-x edebug-all-defs’を使用する 。*note Instrumenting::を参照のこと。 -- User Option: edebug-all-forms これが非‘nil’の場合には‘eval-defun’、‘eval-region’、‘eval-buffer’、 ‘eval-current-buffer’はたとえフォームが何も定義していなくても、すべ てのフォームをインストルメントする。これはロードとミニバッファー内 の評価には適用されない。 このオプションの切り替えにはコマンド‘M-x edebug-all-forms’を使用す る。*note Instrumenting::を参照のこと。 -- User Option: edebug-save-windows これが非‘nil’なら、Edebugはウィンドウ構成の保存とリストアを行なう。 これにはある程度の時間を要するので、ウィンドウ構成に何が起こっても プログラムに関係なければ、この変数を‘nil’にセットしたほうがよい。 値がリストならリストされたウィンドウだけが保存およびリストアされる 。 Edebug内ではこの変数をインタラクティブに変更するために‘W’コマンドを 使用できる。*note Edebug Display Update::を参照のこと。 -- User Option: edebug-save-displayed-buffer-points これが非‘nil’ならEdebugは表示されているすべてのバッファー内のポイン トを保存およびリストアする。 選択されていないウィンドウ内に表示されているバッファーのポイントを 変更するコードをデバッグしている場合は、他のバッファーのポイントを 保存およびリストアする必要がある。その後にEdebugまたはユーザーがそ のウィンドウを選択した場合は、そのバッファー内のポイントはそのウィ ンドウのポイント値に移動される。 すべてのバッファー内のポイントの保存とリストアは、それぞれのウィン ドウを2回選択する必要があり高価な処理なので、必要なときだけ有効にす る。*note Edebug Display Update::を参照のこと。 -- User Option: edebug-initial-mode この変数が非‘nil’なら、Edebugが最初にアクティブになったときの Edebugの最初の実行モードを指定する。指定できる値は‘step’、‘next’、 ‘go’、‘Go-nonstop’、‘trace’、‘Trace-fast’、‘continue’、 ‘Continue-fast’。 デフォルト値は‘step’。この変数は‘C-x C-a C-m’でインタラクティブにセ ットできる。*note Edebug Execution Modes::を参照のこと。 -- User Option: edebug-trace これが非‘nil’なら各関数のエントリーとexitをトレースする。トレース出 力は関数のエントリーとexitを行ごとに、再帰レベルにしたがって ‘*edebug-trace*’という名前のバッファーに表示される。 *note Trace Buffer::の‘edebug-tracing’も参照されたい。 -- User Option: edebug-test-coverage 非‘nil’ならEdebugはデバッグされるすべての式のカバレッジをテストする 。*note Coverage Testing::を参照のこと。 -- User Option: edebug-continue-kbd-macro 非‘nil’ならEdebug外部で実行されている任意のキーボードマクロの定義ま たは実行を継続する。これはデバッグされないので慎重に使用すること。 *note Edebug Execution Modes::を参照されたい。 -- User Option: edebug-unwrap-results 非‘nil’ならEdebugは式の結果を表示するときに、その式自体のインストル メント結果の削除を試みる。マクロをデバッグするときは、式の結果自体 がインストルメントされた式になるということに関連するオプションであ る。実際的な例ではないが、サンプル例の関数‘fac’がインストルメントさ れたとき、そのフォームのマクロを考えてみるとよい。 (defmacro test () "Edebug example." (if (symbol-function 'fac) ...)) ‘test’マクロをインストルメントしてステップ実行すると、デフォルトで は‘symbol-function’呼び出しは多数の‘edebug-after’フォームと ‘edebug-before’フォームをもつことになり、それにより実際の結果の確認 が難しくなり得る。‘edebug-unwrap-results’が非‘nil’ならEdebugは結果 からこれらのフォームの削除を試みる。 -- User Option: edebug-on-error ‘debug-on-error’が以前‘nil’だったら、Edebugは‘debug-on-error’をこの 値にバインドする。*note Trapping Errors::を参照のこと。 -- User Option: edebug-on-quit ‘debug-on-quit’の以前の値が‘nil’なら、Edebugは‘debug-on-quit’にこの 値をバインドする。*note Trapping Errors::を参照のこと。 Edebugがアクティブな間に‘edebug-on-error’か‘edebug-on-quit’の値を変更 したら、_次回_に新たなコマンドを通じてEdebugが呼び出されるまでこれらの値 は使用されない。 -- User Option: edebug-global-break-condition 非‘nil’なら、値はすべてのステップポイントでテストされる式である。式 の結果が‘nil’ならbreakする。エラーは無視される。*note Global Break Condition::を参照のこと。 17.3 無効なLisp構文のデバッグ ============================= Lispリーダーは無効な構文(invalid syntax)について報告はしますが実際の問題 箇所は報告しません。たとえばある式を評価中のエラー‘End of file during parsing’は、開カッコまたは開角カッコ(open parenthese or open square bracket)が多いことを示しています。Lispリーダーはこの不一致をファイル終端 で検出しましたが、本来閉カッコがあるべき箇所を解決することはできません。 同様に‘Invalid read syntax: \")\"’は開カッコの欠落を示していますが、欠落 しているカッコが属すべき場所は告げません。ならばどうやって変更すべき箇所 を探せばよいのでしょうか? 問題が単なるカッコの不一致でない場合の便利なテクニックは、各defunの先 頭で‘C-M-e’とタイプして、そのdefunの最後と思われる箇所に移動するか確認す る方法です。もし移動しなければ、問題はそのdefunの内部にあります。 マッチしないカッコがLispにおいてもっとも一般的な構文エラーなので、こ れらのケースにたいしてさらにアドバイスすることができます(Show Parenモー ドを有効にしてコードにポイントを移動するだけでカッコの不一致を探しやすく なるだろう)。 17.3.1 過剰な開カッコ --------------------- カッコがマッチしないdefunを探すことが最初のステップです。過剰な開カッコ が存在する場合は、ファイルの終端に移動して‘C-u C-M-u’とタイプします。こ れによってカッコがマッチしない最初のdefunの先頭に移動するでしょう。 何が間違っているのか正確に判断するのが次のステップです。これを確実に 行なうには、そのプログラムを詳しく調べる以外に方法はありませんが、カッコ があるべき箇所を探すのに既存のインデントが手掛かりになることが多々ありま す。‘C-M-q’で再インデントして何が移動されるか確認するのが、この手掛かり を使用するもっとも簡単な方法です。*しかし、行うのはちょっと待ってくださ い!* まず続きを読んでからにしましょう。 これを行なう前にdefunに十分な閉カッコがあるか確認します。十分な閉カッ コがなければ‘C-M-q’がエラーとなるか、そのdefunからファイル終端までの残り すべてが再インデントされます。その場合はdefunの最後に移動して、そこに閉 カッコを挿入します。そのdefunのカッコの釣り合いがとれるまでは、defunの最 後に移動するのに‘C-M-e’は失敗するでしょうから使用できません。 これでdefunの先頭に移動して‘C-M-q’とタイプすることができます。通常は 一定のポイントからその関数の最後までのすべての行が、右へとシフトされるで しょう。これはおそらくそのポイント付近で閉カッコが欠落しているか不要な開 カッコがあります(しかしこれを真実と決め付けずコードを詳しく調べてること )。不一致箇所を見つけたら、元のインデントはおそらく意図されたカッコに適 しているはずなので、‘C-_’で‘C-M-q’をアンドゥしてください。 問題をfixできたと思った後に、再度‘C-M-q’を使用します。実際に元のイン デントが意図したカッコのネストに適合していて、足りないカッコを追加してい たら、‘C-M-q’は何も変更しないはずです。 17.3.2 過剰な閉カッコ --------------------- 過剰な閉カッコへの対処は、まずファイルの先頭に移動してから、カッコのマッ チしないdefunを探すために‘C-u -1 C-M-u’をタイプします。 それからそのdefunの先頭で‘C-M-f’をタイプして、実際にマッチする閉カッ コを探します。これによりそのdefunの終端より幾分手前の箇所に移動するはず です。その付近に間違った閉カッコが見つかるでしょう。 そのポイントに問題が見つからなければ、そのdefunの先頭で‘C-M-q’をタイ プするのが次のステップです。ある行範囲はおそらく左へシフトするでしょう。 その場合には欠落している開カッコまたは間違った閉カッコは、おそらくそれら の行の1行目付近にあるでしょう (しかしこれを真実と決め付けずコードを詳し く調べること)。不一致箇所を見つけたら、元のインデントはおそらく意図され たカッコに適しているはずなので、‘C-_’で‘C-M-q’をアンドゥしてください。 問題をfixできたと思った後に再度‘C-M-q’を使用します。実際に元のインデ ントが意図したカッコのネストに適合していて、足りないカッコを追加していた ら、‘C-M-q’は何も変更しないはずです。 17.4 カバレッジテスト ===================== ‘testcover’ライブラリーをロードしてコマンド‘M-x testcover-start FILE ’でコードをインストルメントすることにより、Lispコードのファイ ルにたいしてカバレッジテストを行なうことができます。コードを1回以上呼び 出すことによってテストが行なわれます。コマンド‘M-x testcover-mark-all’を 使用すれば、カバレッジが不十分な箇所が色付きでハイライト表示されます。コ マンド‘M-x testcover-next-mark’は次のハイライトされた箇所へポイントを前 方に移動します。 赤くハイライトされた箇所は通常はそのフォームが完全に評価されたことが 一度もないことを示し、茶色でハイライトされた箇所は常に同じ値に評価された (その結果にたいして少ししかテストされていない)ことを意味します。しかし ‘error’のように完全に評価するのが不可能なフォームにたいしては、赤いハイ ライトはスキップされます。‘(setq x 14)’のように常に同じ値に評価されるこ とが期待されるフォームにたいしては、茶色のハイライトはスキップされます。 難しいケースではテストカバレッジツールにアドバイスを与えるために、コ ードにdo-nothingマクロを追加することができます。 -- Macro: 1value form FORMを評価してその値をリターンするが、テストカバレッジにたいして FORMが常に同じ値だという情報を与える。 -- Macro: noreturn form FORMを評価してFORMが決してリターンしないという情報をカバレッジテス トに与える。もしリターンしたらrun-timeエラーとなる。 Edebugにもカバレッジテスト機能があります(*note Coverage Testing::を参 照)。これらの機能は部分的に重複しており、組み合わせることで明確になるで しょう。 17.5 プロファイリング ===================== プログラムは正常に機能しているものの、より高速または効率的に実行させたい 場合にまず行うべきは、そのプログラムがリソースをどのように使用するか知る ためにコードを“プロファイル(profile)”することです。ある特定の関数の実行 が、実行時間のうち無視できない割り合いを占めるようなら、その部分を最適化 する方法を探すことを開始できます。 このためにEmacsにはビルトインのサポートがあります。プロファイリングを 開始するには‘M-x profiler-start’をタイプします。プロファイルはプロセッサ ー使用(processor usage)とメモリー使用(memory usage)、またはその両方を選 択できます。何らかの処理を行った後に‘M-x profiler-report’とタイプすると 、プロファイルに選択した各リソースがsummaryバッファーに表示されます。 reportバッファーの名前にはそのレポートが生成された時刻が含まれるので、前 の結果を消去せずに後で他のレポートを生成できます。プロファイリングが終了 したら‘M-x profiler-stop’とタイプしてください(プロファイリングに関連する 多少のオーバーヘッドがあるため)。 profiler reportバッファーでは各行に呼び出された関数と、その後にプロフ ァイリングが開始されてから使用したリソース(プロセッサーまたはメモリー)の 絶対時間とパーセンテージ時間が表示されます。左側にシンボル‘+’のある行で はをタイプして行を展開して、高位レベルの関数に呼び出された関数を確 認できます。もう一度をタイプすると、元の状態へと行が折り畳まれます 。 ‘j’か‘mouse-2’を押下すると関数の定義にジャンプします。‘d’を押下すると 関数のドキュメントを閲覧できます。‘C-x C-w’を使用してプロファイルをファ イルに保存できます。‘=’を使用すれば2つのプロファイルを比較することができ ます。 ‘elp’ライブラリーは別のアプローチを提案します。使い方は‘elp.el’を参照 してください。 ‘benchmark’ライブラリーを使用してEmacs Lispフォームのスピードを個別に チェックできます。‘benchmark.el’内の関数‘benchmark-run’と ‘benchmark-run-compiled’を参照してください。 ‘configure’のオプションに‘--enable-profiling’を使用してビルドすること により、EmacsをCコードのレベルでプロファイルすることができます。こうして ビルドされたEmacsは、Emacsをexitするときに‘gprof’ユーティリティを使用し て検証できるファイル‘gmon.out’を生成します。この機能は主にEmacsのデバッ グに有用です。このEmacsは実行状態から上述の‘M-x profiler-...’コマンドに よりLispレベルで実際にストップします。 18 Lispオブジェクトの読み取りとプリント *************************************** “プリント(print)”と“読み取り(read)”はLispオブジェクトからテキスト形式へ の変換、またはその逆の変換を行なう操作です。これらは*note Lisp Data Types::で説明したプリント表現(printed representation)と入力構文(read syntax)を使用します。 このチャプターでは読み取りとプリントのためのLisp関数について説明しま す。このチャプターではさらに“ストリーム(stream)”についても説明します。ス トリームとは、(読み取りでは)テキストがどこから取得されるか、(プリントで は)テキストをどこに出力するかを指定します。 18.1 読み取りとプリントの概念 ============================= Lispオブジェクトの“読み取り”とは、テキスト形式のLisp式をパース(parse: 解 析)して、対応するLispオブジェクトを生成することを意味します。これは LLispプログラムがLispコードファイルからLispに取得される方法でもあります 。わたしたちはそのテキストのことを、そのオブジェクトの“入力構文(read syntax)”と呼んでいます。たとえばテキスト‘(a . 5)’は、CARが‘a’でCDRが数字 の5であるようなコンスセルにたいする入力構文です。 Lispオブジェクトの“プリント”とは、あるオブジェクトをそのオブジェクト の“プリント表現(printed representation)”に変換することによって、そのオブ ジェクトを表すテキストを生成することを意味します(*note Printed Representation::を参照)。上述のコンスセルをプリントするとテキスト‘(a . 5)’が生成されます。 読み取りとプリントは概ね逆の処理といえます。あるテキスト断片を読み取 った結果として生成されたオブジェクトをプリントすると、多くの場合は同じテ キストが生成され、あるオブジェクトをプリントした結果のテキストを読み取る と、通常は同じようなオブジェクトが生成されます。たとえばシンボル‘foo’を プリントするとテキスト‘foo’が生成されて、そのテキストを読み取るとシンボ ル‘foo’がリターンされます。要素が‘a’と‘b’のリストをプリントするとテキス ト‘(a b)’が生成されて、そのテキストを読み取ると、(同じリストではないが )要素が‘a’と‘b’のリストが生成されます。 しかし、これら2つの処理は互いにまったく逆の処理というわけではありませ ん。3つの例外があります: • プリントは読み取ることが不可能なテキストを生成できる。たとえばバッ ファー、フレーム、サブプロセス、マーカーは‘#’で始まるテキストとして プリントされる。このテキストの読み取りを試みるとエラーとなる。これ らのデータ型を読み取る方法は存在しない。 • 1つのオブジェクトが複数のテキスト的な表現をもつことができる。たとえ ば‘1’と‘01’は同じ整数を表し、‘(a b)’と‘(a . (b))’は同じリストを表す 。読み取りは複数の候補を受容するかもしれないが、プリントはそのうち のただ1つを選択しなければならない。 • あるオブジェクトの読み取りシーケンスの中間の特定ポイントに、読み取 り結果に影響を与えないコメントを置くことができる。 18.2 入力ストリーム =================== テキストを読み取るLisp関数の大部分は、引数として“入力ストリーム(input stream)”を受け取ります。入力ストリームは読み取られるテキストの文字をどこ から、どのように取得するかを指定します。以下は利用できる入力ストリーム型 です: BUFFER 入力文字はBUFFERのポイントの後の文字から直接読み取られる。文字の読 み取りとともにポイントが進む。 MARKER 入力文字はMARKERがあるバッファーの、マーカーの後の文字から直接読み 取られる。文字の読み取りとともにマーカーが進む。ストリームがマーカ ーならバッファー内のポイント値に影響はない。 STRING 入力文字はSTRINGの最初の文字から必要な文字数分が取得される。 FUNCTION 入力文字はFUNCTIONから生成され、その関数は2種類の呼び出しをサポート しなければならない: • 引数なしで呼び出されたときは次の文字をリターンする。 • 1つの引数(常に文字)で呼び出されたとき、FUNCTIONは引数を保存し て次の呼び出しでリターンするように準備する。これは文字の“読み 戻し(unreading)”と呼ばれ、Lispリーダーが1文字多く読みとったと き、それを‘読みとった場所に戻したいときに発生する。この場合に はFUNCTIONのリターン値と違いはない。 ‘t’ ‘t’はその入力がミニバッファーから読み取られるストリームであることを 意味する。実際にはミニバッファーが1回呼び出されて、ユーザーから与え られたテキストが、その後に入力ストリームとして使用される文字列とな る。Emacsがbatchモードで実行されている場合には、ミニバッファーのか わりに標準入力が使用される。たとえば、 (message "%s" (read t)) このような場合には標準入力からLisp式が読み取られて、結果は標準出力 にプリントされるだろう。 ‘nil’ 入力ストリームとして‘nil’が与えられた場合は、かわりに ‘standard-input’の値が使用されることを意味する。この値は“デフォルト の入力ストリーム(default input stream)”であり、非‘nil’の入力ストリ ームでなければならない。 SYMBOL 入力ストリームとしてのシンボルは、(もしあれば)そのシンボルの関数定 義と等価である。 以下の例ではバッファーストリームから読み込んで、読み取りの前後におけ るポイント位置を示しています: ---------- 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"))) ⇒ # (read m) ⇒ This m ⇒ # ;; 最初のスペースの前 以下では文字列のコンテンツから読み取っています: (read "(When in) the course") ⇒ (When in) 以下はミニバッファーから読み取る例です。プロンプトは ‘Lisp expression: ’です(このプロンプトはストリーム‘t’から読み取る際は常 に使用される)。ユーザーの入力はプロンプトの後に表示されます。 (read t) ⇒ 23 ---------- Buffer: Minibuffer ---------- Lisp expression: 23 ---------- 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’が リターンされます。 18.3 入力関数 ============= このセクションでは、読み取りに関係のあるLisp関数と変数について説明します 。 以下の関数ではSTREAMは入力ストリーム(前のセクションを参照)を意味しま す。STREAMが‘nil’または省略された場合のデフォルト値は‘standard-input’で す。 読み取りにおいて終端されていないリスト、ベクター、文字列に遭遇したら ‘end-of-file’がシグナルされます。 -- Function: read &optional stream この関数はSTREAMからテキスト表現されたLisp式を1つ読み取ってLispオブ ジェクトとしてリターンする。これは基本的なLisp入力関数である。 -- Function: read-from-string string &optional start end この関数は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) -- Variable: standard-input この変数はデフォルト入力ストリーム(引数STREAMが‘nil’のときに ‘read’が使用するストリーム)を保持する。デフォルトは‘t’で、これはミ ニバッファーを使用することを意味する。 -- Variable: read-circle 非‘nil’なら、この変数は循環構造(circular structure)と共有構造 (shared structures)の読み取りを有効にする。*note Circular Objects::を参照のこと。デフォルト値は‘t’。 batchモードでEmacsプロセスの標準入力ストリームや標準出力ストリームに たいして読み取りや書き込みを行う際には、任意のバイナリーデータにたいして そのまま読み取りや書き込みを行ったり、改行とCRLFの変換を行わないことが要 求されるときがあります。これはMS-WindowsとMS-DOSだけに存在し、Posixホス トには存在しない問題です。以下の関数によってEmacsプロセスの標準ストリー ムすべての入出力モードを制御できます。 -- Function: set-binary-mode stream mode STREAMの入出力モードのテキストとバイナリーを切り替える。MODEが非 ‘nil’ならバイナリーモード、それ以外ならテキストモードに切り替える。 STREAMの値は‘stdin’、‘stdout’、‘stderr’のいずれか。この関数は副作用 として保留されているSTREAMの出力データをすべてフラッシュして、 STREAMの以前の入出力モードをリターンする。Posixホストでは常に非 ‘nil’値をリターンして、保留中の出力のフラッシュ以外は何も行わない。 18.4 出力ストリーム =================== 出力ストリームはプリントによって生成された文字に何を行うかを指定します。 ほとんどのプリント関数は引数としてオプションで出力ストリームを受け取りま す。以下は利用できる出力ストリーム型です: BUFFER 出力文字はBUFFERのポイント位置に挿入される。文字が挿入された分だけ ポイントが進む。 MARKER 出力文字はMARKERがあるバッファーのマーカー位置に挿入される。文字が 挿入された分だけマーカー位置が進む。ストリームがマーカーのときは、 そのバッファー内のポイント位置にプリントは影響せず、この種のプリン トでポイントは移動しない(マーカー位置がポイント位置かポイント位置よ り前の場合は除く。通常はテキストの周囲にポイントが進む)。 FUNCTION 出力文字は文字を格納する役目をもつFUNCTIONに渡される。この関数は1つ の文字を引数に出力される文字の回数呼び出され、格納したい場所にその 文字を格納する役目をもつ。 ‘t’ 出力文字はエコーエリアに表示される。 ‘nil’ 出力ストリームに‘nil’が指定された場合は、かわりに ‘standard-output’の値が使用されることを意味する。この値は“デフォル トの出力ストリーム(default output stream)”であり、非‘nil’でなければ ならない。 SYMBOL 出力ストリームとしてのシンボルは、(もしあれば)そのシンボルの関数定 義と等価である。 有効な出力ストリームの多くは、入力ストリームとしても有効です。したが って入力ストリームと出力ストリームの違いは、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)) ⇒ # (print "More output for foo." m) ⇒ "More output for foo." ---------- Buffer: foo ---------- This is t "More output for foo." he ★output ---------- Buffer: foo ---------- m ⇒ # 以下はエコーエリアに出力を表示する例です: (print "Echo Area output" t) ⇒ "Echo Area output" ---------- Echo Area ---------- "Echo Area output" ---------- Echo Area ---------- 最後は関数を出力ストリームとして使用する例です。関数‘eat-output’は与 えられたそれぞれの文字を‘last-output’の先頭にconsします(*note Building Lists::を参照)。最後にはリストには出力されたすべての文字が逆順で含まれま す。 (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’を呼び出してリストを文字列に変換すれば、内容をより明解に確認でき ます。 18.5 出力関数 ============= このセクションではオブジェクトをオブジェクトのプリント表現に変換して、 LispオブジェクトをプリントするLisp関数を説明します。 Emacsプリント関数には、正しく読み取れるように必要なとき出力にクォート 文字を追加するものがあります。使用されるクォート文字は‘"’と‘\’です。これ らは文字列をシンボルと区別するとともに、文字列とシンボル内の区切り文字が 読み取りの際に区切り文字として扱われることを防ぎます。完全な詳細は*note Printed Representation::を参照してください。クォートするかしないかはプリ ント関数の選択によって指定できます。 そのテキストがLispに読み戻す場合、またはLispプログラマーにLispオブジ ェクトを明解に説明するのが目的の場合は、曖昧さを避けるためにクォート文字 をプリントするべきです。しかしプログラマー以外の人間にたいして出力の見栄 えを良くするのが目的なら、通常はクォートなしでプリントしたほうがよいでし ょう。 Lispオブジェクトは自己参照ができます。通常の方法で自己参照オブジェク トをプリントするにはテキストが無限に必要であり、その試みにより無限再帰が 発生する恐れがあります。Emacsはそのような再帰を検知して、すでにプリント されたオブジェクトを再帰的にプリントするかわりに、‘#LEVEL’をプリントしま す。たとえば以下はカレントのプリント処理において、レベル0のオブジェクト を再帰的に参照することを示しています: (setq foo (list nil)) ⇒ (nil) (setcar foo foo) ⇒ (#0) 以下の関数ではSTREAMは出力ストリームを意味します(出力ストリームの説明 は前のセクションを参照)。STREAMが‘nil’または省略された場合のデフォルトは ‘standard-output’の値になります。 -- Function: print object &optional stream ‘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" -- Function: prin1 object &optional stream この関数は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" -- Function: princ object &optional stream この関数はOBJECTのプリント表現をSTREAMに出力する。OBJECTをリターン する。 この関数は‘read’ではなく人間が読める出力を生成することを意図してい るので、クォート文字を挿入せず文字列のコンテンツの前後にダブルクォ ート文字を配置しない。各呼び出しの間にスペースを何も出力しない。 (progn (princ 'The\ cat) (princ " in the \"hat\"")) ⊣ The cat in the "hat" ⇒ " in the \"hat\"" -- Function: terpri &optional stream ensure この関数はSTREAMに改行を出力する。関数名は“terminate print”に由来す る。ENSUREが非‘nil’の場合は、もしSTREAMがすでに行頭にあれば何も改行 をプリントしない。この場合はSTREAMは関数であってはならず、もし関数 ならエラーがシグナルされることに注意。この関数は改行をプリントした ら‘t’をリターンする。 -- Function: write-char character &optional stream この関数はCHARACTERをSTREAMに出力する。CHARACTERをリターンする。 -- Function: prin1-to-string object &optional noescape この関数は同じ引数で‘prin1’がプリントするテキストを含む文字列をリタ ーンする。 (prin1-to-string 'foo) ⇒ "foo" (prin1-to-string (mark-marker)) ⇒ "#" NOESCAPEが非‘nil’なら出力中のクォート文字の使用を抑制する(この引数 はEmacsバージョン19以降でサポートされた)。 (prin1-to-string "foo") ⇒ "\"foo\"" (prin1-to-string "foo" t) ⇒ "foo" Lispオブジェクトのプリント表現を文字列として取得する別の手段につい ては、*note Formatting Strings::の‘format’を参照のこと。 -- Macro: with-output-to-string body... このマクロは出力を文字列に送るよう‘standard-output’をセットアップし てフォームBODYを実行する。その文字列をリターンする。 たとえばカレントバッファー名が‘foo’なら、 (with-output-to-string (princ "The buffer is ") (princ (buffer-name))) は‘"The buffer is foo"’をリターンする。 -- Function: pp object &optional stream この関数は‘prin1’と同じようにOBJECTをSTREAMに出力するが、より優雅 (pretty)な方法でこれを行う。すなわちこの関数は人間がより読みやすい ようにオブジェクトのインデントとパディングを行う。 batchモードでバイナリー入出力を使用する必要がある場合(このセクション で説明した非Posixホスト上で任意のバイナリーデータの書き込みや改行変換の 回避するために関数を使用する場合)には、*note set-binary-mode: Input Functions.を参照してください。 18.6 出力に影響する変数 ======================= -- Variable: standard-output この変数の値はデフォルト出力ストリーム(STREAM引数が‘nil’のときプリ ント関数が使用するストリーム)である。デフォルトは‘t’で、これはエコ ーエリアに表示することを意味する。 -- Variable: print-quoted これが非‘nil’なら、省略されたリーダー構文(たとえば‘(quote foo)’を ‘'foo’、‘(function foo)’を‘#'foo’のように)を使用してクォートされた フォームをプリントすることを意味する。 -- Variable: print-escape-newlines この変数が非‘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’のローカル バインドが効果をもつが、結果をプリントするときには効果がない。 -- Variable: print-escape-nonascii この変数が非‘nil’なら、クォートつきでプリントするプリント関数 ‘prin1’と‘print’は文字列内のユニバイトの非ASCII文字を無条件でバック スラッシュシーケンスとしてプリントする。 これらの関数は出力ストリームがマルチバイトバッファー、あるいはマー カーがマルチバイトバッファーをポイントするときは、この変数の値に関 わらずユニバイト非ASCII文字にたいしてバックスラッシュシーケンスを使 用する。 -- Variable: print-escape-multibyte この変数が非‘nil’なら、クォートつきでプリントするプリント関数 ‘prin1’と‘print’は、文字列内のマルチバイトの非ASCII文字を無条件でバ ックスラッシュシーケンスとしてプリントする。 これらの関数は出力ストリームがユニバイトバッファー、あるいはマーカ ーがユニバイトバッファーをポイントするときは、この変数の値に関わら ずマルチバイト非ASCII文字にたいしてバックスラッシュシーケンスを使用 する。 -- Variable: print-length この変数の値は任意のリスト、ベクター、ブールベクターをプリントする 際の最大要素数である。プリントされるオブジェクトがこれより多くの要 素をもつ場合は、省略記号(“...”)で省略される。 値が‘nil’(デフォルト)の場合は無制限。 (setq print-length 2) ⇒ 2 (print '(1 2 3 4 5)) ⊣ (1 2 ...) ⇒ (1 2 ...) -- Variable: print-level この変数の値はプリント時の丸カッコ(parentheses: “()”)と角カッコ (brackets: “[]"’)のネスト最大深さである。この制限を超える任意のリス トとベクターは省略記号(“...”)で省略される。値‘nil’(デフォルト)は無 制限を意味する。 -- User Option: eval-expression-print-length -- User Option: eval-expression-print-level これらは‘eval-expression’によって使用される‘print-length’と ‘print-level’の値であり、したがって間接的に多くのインタラクティブな 評価コマンドにより使用される(*note Evaluating Emacs-Lisp Expressions: (emacs)Lisp Eval.を参照)。 以下の変数は循環構造および共有構造の検出と報告に使用されます: -- Variable: print-circle 非‘nil’なら、この変数はプリント時の循環構造と共有構造の検出を有効に する。*note Circular Objects::を参照のこと。 -- Variable: print-gensym 非‘nil’なら、この変数はプリント時のインターンされていないシンボル (*note Creating Symbols::を参照)の検出を有効にする。これが有効なら 、インターンされていないシンボルはプレフィックス‘#:’とともにプリン トされる。このプレフィックスは、Lispリーダーにたいしてインターンさ れていないシンボルを生成するよう告げる。 -- Variable: print-continuous-numbering 非‘nil’なら、複数のプリント呼び出しを通じて通番が振られることを意味 する。これは‘#N=’ラベルと‘#M#’参照にたいしてプリントされる数字に影 響する。この変数を‘setq’でセットしてはならない。‘let’を使用して一時 的に‘t’にバインドすること。これを行う場合は‘print-number-table’も ‘nil’にバインドすること。 -- Variable: print-number-table この変数は‘print-circle’機能を実装するために、プリント処理で内部的 に使用されるベクターを保持する。‘print-continuous-numbering’をバイ ンドするときにこの変数を‘nil’にバインドする以外は、この変数を使用す るべきではない。 -- Variable: float-output-format この変数は浮動小数点数をプリントする方法を指定する。デフォルトは ‘nil’で、これは情報を失わずにその数値を表せるもっとも短い出力を使用 することを意味する。 出力フォーマットをより精密に制御するために、この変数に文字列をセッ トできる。この文字列にはCの‘sprintf’関数で使用される‘%’指定子をセッ トする。この変数で使用することのできる制限についての詳細は、この変 数のドキュメント文字列を参照のこと。 19 ミニバッファー ***************** “ミニバッファー(minibuffer)”とは、単一の数プレフィックス引数(numeric prefix argument)より複雑な引数を読み取るためにEmacsコマンドが使用する特 別なバッファーのことです。これらの引数にはファイル名、バッファー名、 (‘M-x’での)コマンド名が含まれます。ミニバッファーはフレームの最下行、エ コーエリア(*note The Echo Area::を参照)と同じ場所に表示されますが、引数 を読み取るときだけ使用されます。 19.1 ミニバッファーの概念 ========================= ほとんどの点においてミニバッファーは普通のEmacsバッファーです。編集コマ ンドのようなバッファーにたいする操作のほとんどはミニバッファーでも機能し ます。しかしバッファーを管理する操作の多くはミニバッファーに適用できませ ん。ミニバッファーは常に‘ *Minibuf-NUMBER*’という形式の名前をもち変更は できません。ミニバッファーはミニバッファー用の特殊なウィンドウだけに表示 されます。これらのウィンドウは常にフレーム最下に表示されます(フレームに ミニバッファーウィンドウがないときやミニバッファーウィンドウだけをもつ特 殊なフレームもある)。*note Minibuffers and Frames::を参照してください。 ミニバッファー内のテキストは常に“プロンプト文字列(prompt string)”で開 始されます。これはミニバッファーを使用しているプログラムが、ユーザーにた いしてどのような種類の入力が求められているか告げるために指定するテキスト です。このテキストは意図せずに変更してしまわないように、読み取り専用とし てマークされます。このテキストは‘beginning-of-line’、‘forward-word’、 ‘forward-sentence’、‘forward-paragraph’を含む特定の移動用関数が、プロン プトと実際のテキストの境界でストップするようにフィールド(*note Fields::を 参照)としてもマークされています。 ミニバッファーのウィンドウは通常は1行です。ミニバッファーのコンテンツ がより多くのスペースを要求する場合は自動的に拡張されます。ミニバッファー のウィンドウがアクティブな間は、ウィンドウのサイズ変更コマンドで一時的に ウィンドウのサイズを変更できます。サイズの変更はミニバッファーをexitした ときには、通常のサイズにリバートされます。ミニバッファーがアクティブでな いときはフレーム内の他のウィンドウでウィンドウのサイズ変更コマンドを使用 するか、マウスでモードラインをドラッグしてミニバッファーのサイズを永続的 に変更できます(現実装ではこれが機能するには‘resize-mini-windows’が ‘nil’でなければならない)。フレームがミニバッファーだけを含む場合は、その フレームのサイズを変更してミニバッファーのサイズを変更できます。 ミニバッファーの使用によって入力イベントが読み取られて、 ‘this-command’や‘last-command’のような変数の値が変更されます(*note Command Loop Info::を参照)。プログラムにそれらを変更させたくない場合は、 ミニバッファーを使用するコードの前後でそれらをバインドするべきです。 ある状況下では、アクティブなミニバッファーが存在するときでもコマンド がミニバッファーを使用できます。そのようなミニバッファーは“再帰ミニバッ ファー(recursive minibuffer)”と呼ばれます。この場合は最初のミニバッファ ーは‘ *Minibuf-1*’という名前になります。再帰ミニバッファーはミニバッファ ー名の最後の数字を増加することにより命名されます(名前はスペースで始まる ので通常のバッファーリストには表示されない)。再帰ミニバッファーが複数あ る場合は、最内の(もっとも最近にエンターされた)ミニバッファーがアクティブ なミニバッファーになります。このバッファーが、_いわゆる_ミニバッファーと 通常は呼ばれるバッファーです。変数‘enable-recursive-minibuffers’、または コマンドシンボルのその名前のプロパティをセットすることにより再帰ミニバッ ファーを許可したり禁止できます(*note Recursive Mini::を参照)。 他のバッファーと同様、ミニバッファーは特別なキーバインドを指定するた めにローカルキーマップ(*note Keymaps::を参照)を使用します。ミニバッファ ーを呼び出す関数も、処理を行うためにローカルマップをセットアップします。 補完なしのミニバッファーローカルマップについては*note Text from Minibuffer::を参照してください。補完つきのミニバッファーローカルマップに ついては*note Completion Commands::を参照してください。 ミニバッファーが非アクティブのときのメジャーモードは ‘minibuffer-inactive-mode’、キーマップは‘minibuffer-inactive-mode-map’で す。これらは実際にはミニバッファーが別フレームにある場合のみ有用です。 *note Minibuffers and Frames::を参照してください。 Emacsがバッチモードで実行されている場合には、ミニバッファーからの読み 取りリクエストは、実装にはEmacs開始時に提供された標準入力記述子から行を 読み取ります。これは基本的な入力だけをサポートします。特別なミニバッファ ーの機能(ヒストリー、補完など)はバッチモードでは利用できません。 19.2 ミニバッファーでのテキスト文字列の読み取り =============================================== ミニバッファー入力にたいする基本的なプリミティブは ‘read-from-minibuffer’で、これは文字列とLispオブジェクトの両方からテキス ト表現されたフォームを読み取ることができます。関数‘read-regexp’は特別な 種類の文字列である正規表現式(*note Regular Expressions::を参照)の読み取 りに使用されます。コマンドや変数、ファイル名などの読み取りに特化した関数 もあります(*note Completion::を参照)。 ほとんどの場合でにはLisp関数の途中でミニバッファー入力関数を呼び出す べきではありません。かわりに‘interactive’指定されたコマンドの引数の読み 取りの一環として、すべてのミニバッファー入力を行います。*note Defining Commands::を参照してください。 -- Function: read-from-minibuffer prompt &optional initial keymap read history default inherit-input-method この関数はミニバッファーから入力を取得するもっとも一般的な手段であ る。デフォルトでは任意のテキストを受け入れて、それを文字列としてリ ターンする。しかしREADが非‘nil’なら、テキストをLispオブジェクトに変 換するために‘read’を使用する(*note Input Functions::を参照)。 この関数が最初に行うのはミニバッファーをアクティブにして、プロンプ トにPROMPT(文字列でなければならない)を用いてミニバッファーを表示す ることである。その後にユーザーはミニバッファーでテキストを編集でき る。 ミニバッファーをexitするためにユーザーがコマンドをタイプするとき、 ‘read-from-minibuffer’はミニバッファー内のテキストからリターン値を 構築する。通常はそのテキストを含む文字列がリターンされる。しかし READが非‘nil’なら、‘read-from-minibuffer’はテキストを読み込んで結果 を未評価のLispオブジェクトでリターンする(読み取りについての詳細は *Note Input Functions::を参照)。 引数DEFAULTはヒストリーコマンドを通じて利用できるデフォルト値を指定 する。値には文字列、文字列リスト、または‘nil’を指定する。文字列と文 字列リストは、ユーザーが‘M-n’で利用可能な“未来のヒストリー(future history)”になる。 READが非‘nil’なら、ユーザーの入力が空のときの‘read’の入力としても DEFAULTが使用される。DEFAULTが文字列リストの!は、最初の文字列が入力 として使用される。DEFAULTが‘nil’なら、空の入力は‘end-of-file’エラー となる。しかし通常(READが‘nil’)の場合には、ユーザーの入力が空のとき ‘read-from-minibuffer’はDEFAULTを無視して空文字列‘""’をリターンする 。この点ではこの関数はこのチャプターの他のどのミニバッファー入力関 数とも異なる。 KEYMAPが非‘nil’なら、そのキーマップはミニバッファー内で使用されるロ ーカルキーマップとなる。KEYMAPが省略または‘nil’なら、 ‘minibuffer-local-map’の値がキーマップとして使用される。キーマップ の指定は補完のようなさまざまなアプリケーションにたいしてミニバッフ ァーをカスタマイズする、もっとも重要な方法である。 引数HISTORYは入力の保存やミニバッファー内で使用されるヒストリーコマ ンドが使用するヒストリーリスト変数を指定する。デフォルトは ‘minibuffer-history’。同様にオプションでヒストリーリスト内の開始位 置を指定できる。*note Minibuffer History::を参照のこと。 変数‘minibuffer-allow-text-properties’が非‘nil’なら、リターンされる 文字列にはミニバッファーでのすべてのテキストプロパティが含まれる。 それ以外なら、値がリターンされるときすべてのテキストプロパティが取 り除かれる。 引数INHERIT-INPUT-METHODが非‘nil’なら、ミニバッファーにエンターする 前にカレントだったバッファーが何であれ、カレントの入力メソッド (*note Input Methods::を参照)、および ‘enable-multibyte-characters’のセッティング(*note Text Representations::を参照)が継承される。 ほとんどの場合、INITIALの使用は推奨されない。非‘nil’値の使用は、 HISTORYにたいするコンスセル指定と組み合わせる場合のみ推奨する。 *note Initial Input::を参照のこと。 -- Function: read-string prompt &optional initial history default inherit-input-method この関数はミニバッファーから文字列を読み取ってそれをリターンする。 引数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)) -- Function: read-regexp prompt &optional defaults history この関数はミニバッファーから文字列として正規表現を読み取ってそれを リターンする。ミニバッファーのプロンプト文字列PROMPTが‘:’(とその後 にオプションの空白文字)で終端されていなければ、この関数はデフォルト のリターン値(空文字列でない場合。以下参照)の前に‘: ’を付加する。 オプション引数DEFAULTSは、入力が空の場合にリターンするデフォルト値 を制御する。値は文字列、‘nil’(空文字列と等価)、文字列リスト、シンボ ルのうちのいずれか。 DEFAULTSがシンボルの場合、‘read-regexp’は変数 ‘read-regexp-defaults-function’(以下参照)の値を調べて非‘nil’のとき はDEFAULTSよりそちらを優先的に使用する。この場合は値は以下のいずれ か: − ‘regexp-history-last’。これは適切なミニバッファーヒストリーリ スト(以下参照)の最初の要素を使用することを意味する。 − 引数なしの関数。リターン値(‘nil’、文字列、文字列リストのいずれ か)がDEFAULTSの値となる。 これで‘read-regexp’がDEFAULTSを処理した結果はリストに確定する(値が ‘nil’または文字列の場合は1要素のリストに変換する)。このリストにたい して‘read-regexp’は以下のような入力として有用な候補をいくつか追加す る: − ポイント位置の単語かシンボル。 − インクリメンタル検索で最後に使用されたregexp。 − インクリメンタル検索で最後に使用された文字列。 − 問い合わせつき置換コマンドで最後に使用された文字列またはパター ン。 これで関数はユーザー入力を取得するために‘read-from-minibuffer’に渡 す正規表現のリストを得た。リストの最初の要素は入力が空の場合のデフ ォルト値である。リストのすべての要素は“未来のミニバッファーヒストリ ー(future minibuffer history)”となるリスト(*note future list: (emacs)Minibuffer History.を参照)としてユーザーが利用可能になる。 オプション引数HISTORYが非‘nil’なら、それは使用するミニバッファーヒ ストリーリストを指定するシンボルである(*note Minibuffer History::を 参照)。これが省略または‘nil’なら、ヒストリーリストのデフォルトは ‘regexp-history’となる。 -- User Option: read-regexp-defaults-function 関数‘read-regexp’は、デフォルトの正規表現リストを決定するためにこの 変数の値を使用するかもしれない。非‘nil’なら、この変数は以下のいずれ かである: − シンボル‘regexp-history-last’。 − ‘nil’、文字列、文字列リストのいずれかをリターンする引数なしの 関数。 これらの変数の使い方についての詳細は、上述の‘read-regexp’を参照のこ と。 -- Variable: minibuffer-allow-text-properties この変数が‘nil’なら、‘read-from-minibuffer’と‘read-string’はミニバ ッファー入力をリターンする前にすべてのテキストプロパティを取り除く 。しかし‘read-no-blanks-input’(以下参照)、同様に補完つきでミニバッ ファー入力を行う‘read-minibuffer’とそれに関連する関数(*note Reading Lisp Objects With the Minibuffer: Object from Minibuffer.を参照)は 、この変数の値に関わらず無条件でテキストプロパティを破棄する。 -- Variable: minibuffer-local-map これはミニバッファーからの読み取りにたいするデフォルトローカルキー マップである。デフォルトでは以下のバインディングをもつ: ‘C-j’ ‘exit-minibuffer’ ‘exit-minibuffer’ ‘C-g’ ‘abort-recursive-edit’ ‘M-n’ ‘next-history-element’ ‘M-p’ ‘previous-history-element’ ‘M-s’ ‘next-matching-history-element’ ‘M-r’ ‘previous-matching-history-element’ -- Function: read-no-blanks-input prompt &optional initial inherit-input-method この関数はミニバッファーから文字列を読み取るが、入力の一部として空 白文字を認めず、そのかわりに空白文字は入力を終端させる。引数 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)) -- Variable: minibuffer-local-ns-map このビルトイン変数は関数‘read-no-blanks-input’内でミニバッファーロ ーカルキーマップとして使用されるキーマップである。デフォルトでは ‘minibuffer-local-map’のバインディングに加えて、以下のバインディン グが有効になる: ‘exit-minibuffer’ ‘exit-minibuffer’ ‘?’ ‘self-insert-and-exit’ 19.3 ミニバッファーでのLispオブジェクトの読み取り ================================================= このセクションではミニバッファーでLispオブジェクトを読み取る関数を説明し ます。 -- Function: read-minibuffer prompt &optional initial この関数はミニバッファーを使用して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 ---------- ユーザーはをタイプして初期入力をデフォルトとして利用したり入力 を編集することができる。 -- Function: eval-minibuffer prompt &optional initial この関数はミニバッファーを使用してLisp式を読み取り、それを評価して 結果をリターンする。引数PROMPTとINITIALの使い方は ‘read-from-minibuffer’と同様。 この関数は‘read-minibuffer’の呼び出し結果を単に評価する: (eval-minibuffer PROMPT INITIAL) ≡ (eval (read-minibuffer PROMPT INITIAL)) -- Function: edit-and-eval-command prompt form この関数はミニバッファーでLisp式を読み取り、それを評価して結果をリ ターンする。このコマンドと‘eval-minibuffer’の違いは、このコマンドで は初期値としてのFORMはオプションではなく、テキストの文字列ではない プリント表現に変換されたLispオブジェクトとして扱われることである。 これは‘prin1’でプリントされるので、文字列の場合はテキスト初期値内に ダブルクォート文字(‘"’)が含まれる。*note Output Functions::を参照の こと。 以下の例では、すでに有効なフォームであるようなテキスト初期値として 式をユーザーに提案している: (edit-and-eval-command "Please edit: " '(forward-word 1)) ;; 前の式を評価した後に、 ;; ミニバッファーに以下が表示される: ---------- Buffer: Minibuffer ---------- Please edit: (forward-word 1)★ ---------- Buffer: Minibuffer ---------- すぐに をタイプするとミニバッファーをexitして式を評価するので 、1単語分ポイントは前進する。 19.4 ミニバッファーのヒストリー =============================== “ミニバッファーヒストリーリスト(minibuffer history list)”は手軽に再利用 できるように以前のミニバッファー入力を記録します。ミニバッファーヒストリ ーリストは、(以前に入力された)文字列のリストであり、もっとも最近の文字列 が先頭になります。 多数のミニバッファーが個別に存在し、異なる入力の種類に使用されます。 それぞれのミニバッファー使用にたいして正しいヒストリーリストを指定するの はLispプログラマーの役目です。 ミニバッファーヒストリーリストは、‘read-from-minibuffer’と ‘completing-read’のオプション引数HISTORYに指定します。以下が利用できる値 です: VARIABLE ヒストリーリストとしてVARIABLE(シンボル)を使用する。 (VARIABLE . STARTPOS) ヒストリーリストとしてVARIABLE(シンボル)を使用して、ヒストリー位置 の初期値をSTARTPOS(負の整数)とみなす。 STARTPOSに0を指定するのは、単にシンボルVARIABLEだけを指定するのと等 価である。‘previous-history-element’はミニバッファー内のヒストリー リストの最新の要素を表示するだろう。 正のSTARTPOSを指定すると、ミニ バッファーヒストリー関数は‘(elt VARIABLE(1- STARTPOS))’がミニバッフ ァー内でカレントで表示されているヒストリー要素であるかのように振る 舞う。 一貫性を保つためにミニバッファー入力関数のINITIAL引数(*note Initial Input::を参照)を使用して、ミニバッファーの初期内容となるヒストリー 要素も指定すべきである。 HISTORYを指定しない場合には、デフォルトのヒストリーリスト ‘minibuffer-history’が使用されます。他の標準的なヒストリーリストについて は以下を参照してください。最初に使用する前に‘nil’に初期化するだけで、独 自のヒストリーリストを作成することもできます。 ‘read-from-minibuffer’と‘completing-read’は、どちらも新たな要素を自動 的にヒストリーリストに追加して、ユーザーがそのリストのアイテムを再使用す るためのコマンドを提供します。ヒストリーリストを使用するためにプログラム が行う必要があるのはリストの初期化と、使用するときに入力関数にリストの名 前を渡すだけです。しかしミニバッファー入力関数がリストを使用していないと きに手動でリストを変更しても問題はありません。 新たな要素をヒストリーリストに追加するEmacs関数は、リストが長くなりす ぎたときに古い要素の削除を行うこともできます。変数‘history-length’は、ほ とんどのヒストリーリストの最大長を指定する変数です。特定のヒストリーリス トにたいして異なる最大長を指定するには、そのヒストリーリストのシンボルの ‘history-length’プロパティにその最大長をセットします。変数 ‘history-delete-duplicates’にはヒストリー内の重複を削除するかどうかを指 定します。 -- Function: add-to-history history-var newelt &optional maxelt keep-all この関数はNEWELTが空文字列でなければ、それを新たな要素として変数 HISTORY-VARに格納されたヒストリーリストに追加して、更新されたヒスト リーリストをリターンする。これはMAXELTか‘history-length’がが非 ‘nil’なら、リストの長さをその変数の値に制限する(以下参照)。MAXELTに 指定できる値の意味は‘history-length’の値と同様。 ‘add-to-history’は通常は‘history-delete-duplicates’が非‘nil’ならば 、ヒストリーリスト内の重複メンバーを削除する。しかしKEEP-ALLが非 ‘nil’なら、それは重複を削除しないことを意味し、たとえNEWELTが空でも リストに追加する。 -- Variable: history-add-new-input この変数の値が‘nil’なら、ミニバッファーから読み取りを行う標準的な関 数はヒストリーリストに新たな要素を追加しない。これによりLispプログ ラムが‘add-to-history’を使用して明示的に入力ヒストリーを管理するこ とになる。デフォルト値は‘t’。 -- User Option: history-length この変数の値は、最大長を独自に指定しないすべてのヒストリーリストの 最大長を指定する。値が‘t’なら最大長がない(古い要素を削除しない)こと を意味する。ヒストリーリスト変数のシンボルの‘history-length’プロパ ティが非‘nil’なら、その特定のヒストリーリストにたいする最大長として 、そのプロパティ値がこの変数をオーバーライドする。 -- User Option: history-delete-duplicates この変数の値が‘t’なら、それは新たなヒストリー要素の追加時に以前から ある等しい要素が削除されることを意味する。 以下は標準的なミニバッファーヒストリーリスト変数です: -- Variable: minibuffer-history ミニバッファーヒストリー入力にたいするデフォルトのヒストリーリスト 。 -- Variable: query-replace-history ‘query-replace’の引数(と他のコマンドの同様の引数)にたいするヒストリ ーリスト。 -- Variable: file-name-history ファイル名引数にたいするヒストリーリスト。 -- Variable: buffer-name-history バッファー名引数にたいするヒストリーリスト。 -- Variable: regexp-history 正規表現引数にたいするヒストリーリスト。 -- Variable: extended-command-history 拡張コマンド名引数にたいするヒストリーリスト。 -- Variable: shell-command-history シェルコマンド引数にたいするヒストリーリスト。 -- Variable: read-expression-history 評価されるためのLisp式引数にたいするヒストリーリスト。 -- Variable: face-name-history フェイス引数にたいするヒストリーリスト。 19.5 入力の初期値 ================= ミニバッファー入力にたいする関数のいくつかには、INITIALと呼ばれる引数が あります。これは通常のように空の状態で開始されるのではなく、特定のテキス トとともにミニバッファーが開始されることを指定しますが、ほとんどの場合に おいては推奨されない機能です。 INITIALが文字列なら、ミニバッファーはその文字列のテキストを含む状態で 開始され、ユーザーがそのテキストの編集を開始するとき、ポイントはテキスト の終端にあります。ユーザーがミニバッファーをexitするために単にをタ イプした場合には、この入力文字列の初期値をリターン値だと判断します。 *INITIALにたいして非‘nil’値の使用には反対します。*なぜなら初期入力は 強要的なインターフェイスだからです。ユーザーにたいして有用なデフォルト入 力を提案するためには、ヒストリーリストやデフォルト値の提供のほうがより有 用です。 しかしINITIAL引数にたいして文字列を指定すべき状況が1つだけあります。 それはHISTORY引数にコンスセルを指定したときです。*note Minibuffer History::を参照してください。 INITIALは‘(STRING . POSITION)’という形式をとることもできます。これは STRINGをミニバッファーに挿入するが、その文字列のテキスト中のPOSITIONにポ イントを配置するという意味です。 歴史的な経緯により、POSITIONは異なる関数の間で実装が統一されていませ ん。‘completing-read’ではPOSITIONの値は0基準です。つまり値0は文字列の先 頭、1は最初の文字の次、...を意味します。しかし‘read-minibuffer’、および この引数をサポートする補完を行わない他のミニバッファー入力関数では、1は 文字列の先頭、2は最初の文字の次、...を意味します。 INITIALの値としてのコンスセルの使用は推奨されません。 19.6 補完 ========= “補完(complete, ompletion)”は省略された形式から始まる名前の残りを充填す る機能です。補完はユーザー入力と有効な名前リストを比較して、ユーザーが何 をタイプしたかで名前をどの程度一意に判定できるか判断することによって機能 します。たとえば‘C-x b’ (‘switch-to-buffer’)とタイプしてからスイッチした いバッファー名の最初の数文字をタイプして、その後に (‘minibuffer-complete’)をタイプすると、Emacsはその名前を可能な限り展開し ます。 標準的なEmacsコマンドはシンボル、ファイル、バッファー、プロセスの名前 にたいする補完を提案します。このセクションの関数により、他の種類の名前に たいしても補完を実装できます。 ‘try-completion’関数は補完にたいする基本的なプリミティブです。これは 初期文字列にたいして文字列セットをマッチして、最長と判定された補完をリタ ーンします。 関数‘completing-read’は補完にたいする高レベルなインターフェイスを提供 します。‘completing-read’の呼び出しによって有効な名前リストの判定方法が 指定されます。その後にこの関数は補完にたいして有用ないくつかのコマンドに キーバインドするローカルキーマップとともに、ミニバッファーをアクティブ化 します。その他の関数は特定の種類の名前を補完つきで読み取る、簡便なインタ ーフェイスを提供します。 19.6.1 基本的な補完関数 ----------------------- 以下の補完関数は、その関数自身ではミニバッファーで何も行いません。ここで はミニバッファーを使用する高レベルの補完機能とともに、これらの関数につい て説明します。 -- Function: try-completion string collection &optional predicate この関数はCOLLECTION内のSTRINGに可能なすべての補完の共通する最長部 分文字列をリターンする。 COLLECTIONは“補完テーブル(completion table)”と呼ばれる。値は文字列 リスト、コンスセル、obarray、ハッシュテーブル、または補完関数でなけ ればならない。 ‘try-completion’は補完テーブルにより指定された許容できる補完それぞ れにたいして、STRINGと比較を行う。許容できる補完マッチが存在しなけ れば‘nil’をリターンする。マッチする補完が1つだけで、それが完全一致 ならば‘t’をリターンする。それ以外は、すべてのマッチ可能な補完に共通 する最長の初期シーケンスをリターンする。 COLLECTIONがリストなら、許容できる補完(permissible completions)はそ のリストの要素によって指定される。リストの要素は文字列、またはCARが 文字列、または(‘symbol-name’によって文字列に変換される)シンボルであ るようなコンスセルである。リストに他の型の要素が含まれる場合は無視 される。 COLLECTIONがobarray(*note Creating Symbols::を参照)なら、その obarray内のすべてのシンボル名が許容できる補完セットを形成する。 COLLECTIONがハッシュテーブルの場合には、文字列かシンボルのキーが利 用可能な補完となる。他のキーは無視される。 COLLECTIONとして関数を使用することもできる。この場合にはその関数だ けが補完を処理する役目を担う。つまり‘try-completion’は、この関数が 何をリターンしようともそれをリターンする。この関数はSTRING、 PREDICATE、‘nil’の3つの引数で呼び出される(3つ目の引数は同じ関数を ‘all-completions’でも使用して、どちらの場合でも適切なことを行うため )。*note Programmed Completion::を参照のこと。 引数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" -- Function: all-completions string collection &optional predicate この関数はSTRINGの利用可能な補完すべてのリストをリターンする。この 関数の引数は‘try-completion’の引数と同じであり、‘try-completion’が 行うのと同じ方法で‘completion-regexp-list’を使用する。 COLLECTIONか関数ならSTRING、PREDICATE、‘t’の3つの引数で呼び出される 。この場合はその関数がリターンするのが何であれ、‘all-completions’は それをリターンする。*note Programmed Completion::を参照のこと。 以下の例は‘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") -- Function: test-completion string collection &optional predicate この関数は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’はそれをリ ターンする。 -- Function: completion-boundaries string collection predicate suffix この関数はポイントの前のテキストがSTRING、ポイントの後がSUFFIXと仮 定して、COLLECTIONが扱うフィールドの境界(boundary)をリターンする。 補完は通常は文字列(string)全体に作用するので、すべての普通のコレク ション(collection)にたいして、この関数は常に‘(0 . (length SUFFIX))’をリターンするだろう。しかしファイルにたいする補完などの、 より複雑な補完は1回に1フィールド行われる。たとえばたとえ ‘"/usr/share/doc"’が存在しても、‘"/usr/sh"’の補完に ‘"/usr/share/"’は含まれるが、‘"/usr/share/doc"’は含まれないだろう。 また‘"/usr/sh"’にたいする‘all-completions’に‘"/usr/share/"’は含まれ ず、‘"share/"’だけが含まれるだろう。STRINGが‘"/usr/sh"’、SUFFIXが ‘"e/doc"’なら、‘completion-boundaries’は‘(5 . 1)’をリターンするだろ う。これはCOLLECTIONが‘"/usr/"’の後ろにあり‘"/doc"’の前にある領域に 関する補完情報だけをリターンするであろうことを告げている。 補完alistを変数に格納した場合は、変数の‘risky-local-variable’プロパテ ィに非‘nil’をセットして、その変数がrisky(危険)だとマークすること。*note File Local Variables::を参照のこと。 -- Variable: completion-ignore-case この変数の値が非‘nil’なら、補完でのcase(大文字小文字)の違いは意味を もたない。‘read-file-name’では、この変数は ‘read-file-name-completion-ignore-case’ (*note Reading File Names::を参照)にオーバーライドされる。‘read-buffer’では、この変数は ‘read-buffer-completion-ignore-case’ (*note High-Level Completion::を参照)にオーバーライドされる。 -- Variable: completion-regexp-list これは正規表現のリストである。補完関数はこのリスト内のすべての正規 表現にマッチした場合のみ許容できる補完と判断する。 ‘case-fold-search’ (*note Searching and Case::を参照)では ‘completion-ignore-case’の値にバインドされる。 -- Macro: lazy-completion-table var fun この変数は変数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)を追加 します。 19.6.2 補完とミニバッファー --------------------------- このセクションでは補完つきでミニバッファーから読み取るための、基本的なイ ンターフェイスを説明します。 -- Function: completing-read prompt collection &optional predicate require-match initial history default inherit-input-method この関数は補完の提供によりユーザーを支援して、ミニバッファーから文 字列を読み取る。PROMPT (文字列でなければならない)のプロンプトととも にミニバッファーをアクティブ化する。 実際の補完は補完テーブルCOLLECTIONと補完述語PREDICATEを関数 ‘try-completion’ (*note Basic Completion::を参照)に渡すことにより行 われる。これは補完の使用されるローカルキーマップに特定のコマンドを バインドしたとき発生する。これらのコマンドのいくつかは ‘test-completion’も呼び出す。したがってPREDICATEが非‘nil’なら、 COLLECTIONと‘completion-ignore-case’が矛盾しないようにすること。 *note Definition of test-completion::を参照されたい。 COLLECTIONが関数のときの詳細な要件は*note Programmed Completion::を 参照のこと。 オプション引数REQUIRE-MATCHの値はユーザーがミニバッファーをexitする 方法を決定する。 • ‘nil’なら、通常のミニバッファーexitコマンドはミニバッファーの 入力と無関係に機能する。 • ‘t’なら、入力がCOLLECTIONの要素に補完されるまで通常のミニバッ ファーexitコマンドは機能しない。 • ‘confirm’なら、どのような入力でもユーザーはexitできるが、入力 が‘confirm’の要素に補完されていなければ確認を求められる。 • ‘confirm-after-completion’なら、どのような入力でもユーザーは exitできるが、前のコマンドが補完コマンド(たとえば ‘minibuffer-confirm-exit-commands’の中のコマンドのいずれか)で 、入力の結果がCOLLECTIONの要素でなければ確認を求められる。 *note Completion Commands::を参照のこと。 • REQUIRE-MATCHにたいする他の値は‘t’と同じだが、exitコマンドは補 完処理中はexitしない。 しかしREQUIRE-MATCHの値に関わらず、空の入力は常に許容される。この場 合‘completing-read’はDEFAULTがリストなら最初の要素、DEFAULTが ‘nil’なら‘""’、またはDEFAULTをリターンする。文字列とDEFAULT内の文字 列はヒストリーコマンドを通じてユーザーが利用できる。 関数‘completing-read’はREQUIRE-MATCHが‘nil’ならキーマップとして ‘minibuffer-local-completion-map’を、REQUIRE-MATCHが非‘nil’なら ‘minibuffer-local-must-match-map’を使用する。*note Completion Commands::を参照のこと。 引数HISTORYは入力の保存とミニバッファーヒストリーコマンドに、どのヒ ストリーリスト変数を使用するか指定する。デフォルトは ‘minibuffer-history’。*note Minibuffer History::を参照のこと。 INITIALはほとんどの場合は推奨されない。HISTORYにたいするコンスセル 指定と組み合わせた場合のみ非‘nil’値の使用を推奨する。*note Initial Input::を参照のこと。デフォルト入力にたいしてはかわりにDEFAULTを使 用すること。 引数INHERIT-INPUT-METHODが非‘nil’なら、ミニバッファーにエンターする 前にカレントだったバッファーが何であれ、カレントの入力メソッド (*note Input Methods::を参照)、および ‘enable-multibyte-characters’のセッティング(*note Text Representations::を参照)が継承される。 変数‘completion-ignore-case’が非‘nil’なら、利用可能なマッチにたいし て入力を比較するときの補完はcaseを区別しない。*note Basic Completion::を参照のこと。このモードでの操作では、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 ---------- その後ユーザーが‘ b ’をタイプすると、 ‘completing-read’は‘barfoo’をリターンする。 ‘completing-read’関数は、実際に補完を行うコマンドの情報を渡すために 変数をバインドする。これらの変数は以降のセクションで説明する。 -- Variable: completing-read-function この変数の値は関数でなければならず、補完つきの読み取りを実際に行う ために‘completing-read’から呼び出される。この関数は ‘completing-read’と同じ引数を受け入れる。他の関数のバインドして通常 の‘completing-read’の振る舞いを完全にオーバーライドすることができる 。 19.6.3 補完を行うミニバッファーコマンド --------------------------------------- このセクションでは補完のためにミニバッファーで使用されるキーマップ、コマ ンド、ユーザーオプションを説明します。 -- Variable: minibuffer-completion-table この変数の値はミニバッファー内の補完に使用される補完テーブルである 。これは‘completing-read’が‘try-completion’に渡す補完テーブルを含ん だグローバル変数である。‘minibuffer-complete-word’のようなミニバッ ファー補完コマンドにより使用される。 -- Variable: minibuffer-completion-predicate この変数の値は‘completing-read’が‘try-completion’に渡す述語 (predicate)である。この変数は他のミニバッファー補完関数にも使用され る。 -- Variable: minibuffer-completion-confirm この変数はミニバッファーをexitする前にEmacsが確認を求めるかどうかを 決定する。‘completing-read’はこの変数をバインドして、exitする前に関 数‘minibuffer-complete-and-exit’がこの値をチェックする。値が‘nil’な ら確認は求められない。値が‘confirm’の場合は、入力が有効な補完候補で なくてもユーザーはexitするかもしれないがEmacsは確認を求めない。値が ‘confirm-after-completion’の場合、入力が有効な補完候補でなくてもユ ーザーはexitするかもしれないが、ユーザーが ‘minibuffer-confirm-exit-commands’内の任意の補完コマンドの直後に入 力を確定した場合にはEmacsは確認を求める。 -- Variable: minibuffer-confirm-exit-commands この変数には、‘completing-read’の引数REQUIRE-MATCHが ‘confirm-after-completion’のときにミニバッファーexit前にEmacsに確認 を求めさせるコマンドのリストが保持されている。このリスト内のコマン ドを呼び出した直後にユーザーがミニバッファーのexitを試みるとEmacsは 確認を求める。 -- Command: minibuffer-complete-word この関数はせいぜい1つの単語からミニバッファーを補完する。たとえミニ バッファーのコンテンツが1つの補完しかもたない場合でも、 ‘minibuffer-complete-word’はその単語に属さない最初の文字を超えた追 加はしない。*note Syntax Tables::を参照のこと。 -- Command: minibuffer-complete この関数は可能な限りミニバッファーのコンテンツを補完する。 -- Command: minibuffer-complete-and-exit この関数はミニバッファーのコンテンツを補完して確認が要求されない場 合(たとえば‘minibuffer-completion-confirm’が‘nil’のとき)はexitする 。確認が_要求される_場合には、このコマンドを即座に繰り返すことによ って確認が行われないようにする。このコマンドは2回連続で実行された場 合は確認なしで機能するようにプログラムされている。 -- Command: minibuffer-completion-help この関数はカレントのミニバッファーのコンテンツで利用可能な補完のリ ストを作成する。これは‘all-completions’の引数COLLECTIONに変数 ‘minibuffer-completion-table’の値、引数PREDICATEに ‘minibuffer-completion-predicate’の値を使用して呼び出すことによって 機能する。補完リストは‘*Completions*’と呼ばれるバッファーのテキスト として表示される。 -- Function: display-completion-list completions この関数は‘standard-output’内のストリーム(通常はバッファー)に COMPLETIONSを表示する(ストリームについての詳細は*note Read and Print::を参照)。引数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))) -- User Option: completion-auto-help この変数が非‘nil’なら、次の文字が一意でなく決定できないために補完が 完了しないときは常に、補完コマンドは利用可能な補完リストを自動的に 表示する。 -- Variable: minibuffer-local-completion-map ‘completing-read’の値は、補完の1つが完全に一致することを要求されな いときにローカルキーマップとして使用される。デフォルトではこのキー マップは以下のバインディングを作成する: ‘?’ ‘minibuffer-completion-help’ ‘minibuffer-complete-word’ ‘minibuffer-complete’ 親キーマップとして‘minibuffer-local-map’を使用する(*note Definition of minibuffer-local-map::を参照)。 -- Variable: minibuffer-local-must-match-map ‘completing-read’は、1つの補完の完全な一致が要求されないときのロー カルキーマップとしてこの値を使用する。したがって‘exit-minibuffer’に キーがバインドされていなければ、無条件にミニバッファーをexitする。 デフォルトでは、このキーマップは以下のバインディングを作成する: ‘C-j’ ‘minibuffer-complete-and-exit’ ‘minibuffer-complete-and-exit’ 親キーマップは‘minibuffer-local-completion-map’を使用する。 -- Variable: minibuffer-local-filename-completion-map これは単にを非バインドするsparseキーマップ(sparse: 疎、希薄、 まばら)を作成する。これはファイル名にスペースを含めることができるか らである。関数‘read-file-name’は、このキーマップと ‘minibuffer-local-completion-map’か ‘minibuffer-local-must-match-map’のいずれかを組み合わせる。 19.6.4 高レベルの補完関数 ------------------------- このセクションでは特定の種類の名前を補完つきで読み取る便利な高レベル関数 を説明します。 ほとんどの場合は、Lisp関数の中盤でこれらの関数を呼び出すべきではあり ません。可能なときは‘interactive’指定の内部で呼び出して、ミニバッファー のすべての入力をコマンドの引数読み取りの一部にします。*note Defining Commands::を参照してください。 -- Function: read-buffer prompt &optional default require-match predicate この関数はバッファーの名前を読み取ってそれを文字列でリターンする。 プロンプトはPROMPT。引数DEFAULTはミニバッファーが空の状態でユーザー がexitした場合にリターンされるデフォルト名として使用される。非 ‘nil’なら文字列、文字列リスト、またはバッファーを指定する。リストな らリストの先頭の要素がデフォルト値になる。デフォルト値はプロンプト に示されるが、初期入力としてミニバッファーには挿入されない。 引数PROMPTはコロンかスペースで終わる文字列である。DEFAULTが非 ‘nil’なら、この関数はデフォルト値つきでミニバッファーから読み取る際 の慣習にしたがってコロンの前のPROMPTの中にこれを挿入する。 オプション引数REQUIRE-MATCHは‘completing-read’のときと同じ。*note Minibuffer Completion::を参照のこと。 オプション引数PREDICATEが非‘nil’なら、それは考慮すべきバッファーを フィルターする関数を指定する。この関数は可能性のある候補を引数とし て呼び出されて、候補を拒絶するなら‘nil’、許容するなら非‘nil’をリタ ーンすること。 以下の例ではユーザーが‘minibuffer.t’とエンターしてから、をタイ プしている。引数REQUIRE-MATCHは‘t’であり、与えられた入力で始まるバ ッファー名は‘minibuffer.texi’だけなので、その名前が値となる。 (read-buffer "Buffer name: " "foo" t) ;; 前の式を評価した後、 ;; 空のミニバッファーに ;; 以下のプロンプトが表示される: ---------- Buffer: Minibuffer ---------- Buffer name (default foo): ★ ---------- Buffer: Minibuffer ---------- ;; ユーザーが‘minibuffer.t ’とタイプする ⇒ "minibuffer.texi" -- User Option: read-buffer-function この変数が非‘nil’なら、それはバッファー名を読み取る関数を指定する。 ‘read-buffer’は通常行うことを行うかわりに、‘read-buffer’と同じ引数 でその関数を呼び出す。 -- User Option: read-buffer-completion-ignore-case この変数が非non-‘nil’なら、バッファー名の読み取りの補完処理において ‘read-buffer’はcaseを無視する。 -- Function: read-command prompt &optional default この関数はコマンドの名前を読み取って、Lispシンボルとしてそれをリタ ーンする。引数PROMPTは‘read-from-minibuffer’で使用される場合と同じ 。それが何であれ‘commandp’が‘t’をリターンすればコマンドであり、コマ ンド名とは‘commandp’が‘t’をリターンするシンボルだということを思い出 してほしい。*note Interactive Call::を参照のこと。 引数DEFAULTはユーザーがnull入力をエンターした場合に何をリターンする か指定する。シンボル、文字列、文字列リストを指定できる。文字列なら ‘read-command’はリターンする前にそれをinternする。リストなら ‘read-command’はリストの最初の要素をinternする。DEFAULTが‘nil’なら デフォルトが指定されなかったことを意味する。その場合もしユーザーが null入力をエンターすると、リターン値は‘(intern "")’、つまり名前が空 文字列のシンボルとなる。 (read-command "Command name? ") ;; 前の式を評価した後に、 ;; 空のミニバッファーに以下のプロンプトが表示される: ---------- Buffer: Minibuffer ---------- Command name? ---------- Buffer: Minibuffer ---------- ユーザーが‘forward-c ’とタイプすると、この関数は ‘forward-char’をリターンする。 ‘read-command’関数は‘completing-read’の簡略化されたインターフェイス である。実在するLisp変数のセットを補完するために変数‘obarray’、コマ ンド名だけを受け入れるために述語‘commandp’を使用する。 (read-command PROMPT) ≡ (intern (completing-read PROMPT obarray 'commandp t nil)) -- Function: read-variable prompt &optional default この変数はカスタマイズ可能な変数の名前を読み取って、それをシンボル としてリターンする。引数の形式は‘read-command’の引数と同じ。この関 数は‘commandp’のかわりに‘custom-variable-p’を述語に使用する点を除い て‘read-command’と同様に振る舞う。 -- Command: read-color &optional prompt convert allow-empty display この関数はカラー指定(カラー名、または‘#RRRGGGBBB’のような形式の RGB16進値)の文字列を読み取る。これはプロンプトにPROMPT(デフォルトは ‘"Color (name or #RGB triplet):"’)を表示して、カラー名にたいする補 完を提供する(16進RGB値は補完しない)。標準的なカラー名に加えて、補完 候補にはポイント位置のフォアグラウンドカラーとバックグラウンドカラ ーが含まれる。 Valid RGB values are described in *note Color Names::. この関数のリターン値はミニバッファー内でユーザーがタイプした文字列 である。しかしインタラクティブに呼び出されたとき、またはオプション 引数CONVERTが非‘nil’なら、入力されたカラー名のかわりにそれに対応す るRGB値文字列をリターンする。この関数は入力として有効なカラー指定を 求める。ALLOW-EMPTYが非‘nil’でユーザーがnull入力をエンターした場合 は空のカラー名が許容される。 インタラクティブに呼び出されたとき、またはDISPLAYが非‘nil’なら、エ コーエリアにもリターン値が表示される。 *note User-Chosen Coding Systems::の関数‘read-coding-system’と ‘read-non-nil-coding-system’、および*note Input Methods::の ‘read-input-method-name’も参照されたい。 19.6.5 ファイル名の読み取り --------------------------- 高レベル補完関数‘read-file-name’、‘read-directory-name’、 ‘read-shell-command’はそれぞれファイル名、ディレクトリー名、シェルコマン ドを読み取るようにデザインされています。これらはデフォルトディレクトリー の自動挿入を含む特別な機能を提供します。 -- Function: read-file-name prompt &optional directory default require-match initial predicate この関数はプロンプトPROMPTとともに補完つきでファイル名を読み取る。 例外として以下のすべてが真ならば、この関数はミニバッファーのかわり にグラフィカルなファイルダイアログを使用してファイル名を読み取る: 1. マウスコマンドを通じて呼び出された。 2. グラフィカルなディスプレイ上の選択されたフレームがこの種のダイ アログをサポートしている。 3. 変数‘use-dialog-box’が非‘nil’の場合。*note Dialog Boxes: (emacs)Dialog Boxes.を参照のこと。 4. DIRECTORY引数(以下参照)がリモートファイルを指定しない場合。 *note Remote Files: (emacs)Remote Files.を参照のこと。 グラフィカルなファイルダイアログを使用したときの正確な振る舞いはプ ラットホームに依存する。ここでは単にミニバッファーを使用したときの 振る舞いを示す。 ‘read-file-name’はリターンするファイル名を自動的に展開しない。絶対 ファイル名が必要なら、自分で‘expand-file-name’を呼び出さなければな らない。 オプション引数REQUIRE-MATCHは‘completing-read’のときと同じ。*note Minibuffer Completion::を参照のこと。 引数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していなければデフォルトは存在しない。この場合はユ ーザーが編集せずにをタイプすると、‘read-file-name’は前にミニバ ッファーに挿入されたコンテンツを単にリターンする。 空のミニバッファー内でユーザーがをタイプすると、この関数は 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 ’をタイプすると以下がリターンされる: ---------- Buffer: Minibuffer ---------- The file is /gp/gnu/elisp/manual.texi★ ---------- Buffer: Minibuffer ---------- ここでユーザーがをタイプすると、‘read-file-name’は文字列 ‘"/gp/gnu/elisp/manual.texi"’をファイル名としてリターンする。 -- Variable: read-file-name-function 非‘nil’なら、‘read-file-name’と同じ引数を受け取る関数である。 ‘read-file-name’が呼び出されたとき、‘read-file-name’は通常の処理を 行なうかわりに与えられた引数でこの関数を呼び出す。 -- User Option: read-file-name-completion-ignore-case この変数が非‘nil’なら、‘read-file-name’は補完を行なう際にcaseを無視 する。 -- Function: read-directory-name prompt &optional directory default require-match initial この関数は‘read-file-name’と似ているが補完候補としてディレクトリー だけを許す。 DEFAULTが‘nil’でINITIALが非‘nil’なら、‘read-directory-name’は DIRECTORY (DIRECTORYが‘nil’ならカレントバッファーのデフォルトディレ クトリー)とINITIALを組み合わせて代用のデフォルトを構築する。この関 数はDEFAULTとINITIALの両方が‘nil’ならDIRECTORY、DIRECTORYも‘nil’な らカレントバッファーのデフォルトディレクトリーを代用のデフォルトと して使用する。 -- User Option: insert-default-directory この変数は‘read-file-name’により使用されるため、ファイル名を読み取 るほとんどのコマンドにより間接的に使用される(これらのコマンドにはコ マンドのインタラクティブフォームに‘f’や‘F’のコードレター(code letter))をふくむすべてのコマンドが含まれる。*note Code Characters for interactive: Interactive Codes.を参照されたい)。この変数の値は 、(もしあれば)デフォルトディレクトリー名をミニバッファー内に配置し て‘read-file-name’を開始するかどうかを制御する。変数の値が‘nil’なら 、‘read-file-name’はミニバッファーに初期入力を何も配置しない(ただし INITIAL引数で初期入力を指定しない場合)。この場合には依然としてデフ ォルトディレクトリーが相対ファイル名の補完に使用されるが表示はされ ない。 この変数が‘nil’でミニバッファーの初期コンテンツが空なら、ユーザーは デフォルト値にアクセスするために次のヒストリー要素を明示的にフェッ チする必要があるだろう。この変数が非‘nil’ならミニバッファーの初期コ ンテンツは常に空以外となり、ミニバッファーで編集をおこなわず即座に をタイプすることによって、常にデフォルト値を要求できる(上記参 照)。 たとえば: ;; デフォルトディレクトリーとともにミニバッファーが開始 (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 ---------- -- Function: read-shell-command prompt &optional initial history &rest args この関数はプロンプトPROMPTとインテリジェントな補完を提供して、ミニ バッファーからシェルコマンドを読み取る。これはコマンド名にたいして 適切な候補を使用してコマンドの最初の単語を補完する。コマンドの残り の単語はファイル名として補完する。 この関数はミニバッファー入力にたいするキーマップとして ‘minibuffer-local-shell-command-map’を使用する。HISTORY引数は使用す るヒストリーリストを指定する。省略または‘nil’の場合のデフォルトは ‘shell-command-history’ (*note shell-command-history: Minibuffer History.を参照)。オプション引数INITIALはミニバッファーの初期コンテ ンツを指定する(*note Initial Input::を参照)。もしあれば残りのARGSは ‘read-from-minibuffer’内のDEFAULTとINHERIT-INPUT-METHODとして使用さ れる(*note Text from Minibuffer::を参照)。 -- Variable: minibuffer-local-shell-command-map このキーマップは‘read-shell-command’により、コマンドとシェルコマン ドの一部となるファイル名の補完のために使用される。これは親キーマッ プとして‘minibuffer-local-map’を使用して、を ‘completion-at-point’にバインドする。 19.6.6 補完変数 --------------- 補完のデフォルト動作を変更するために使用される変数がいくつかあります。 -- User Option: completion-styles この変数の値は補完を行うために使用される補完スタイル(シンボル)であ る。“補完スタイル(completion style)”とは、補完を生成するためのルー ルセットのこと。このリストにあるシンボルはそれぞれ、 ‘completion-styles-alist’内に対応するエントリーをもたなければならな い。 -- Variable: 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’ (*note Basic Completion::を参照 )のときと同様。引数POINTはSTRING内のポイント位置。各関数は自身の処 理を行ったら非‘nil’、行わなかった場合(たとえば補完スタイルに一致す るようにSTRINGを行う方法がない場合)は‘nil’をリターンする。 ユーザーが‘minibuffer-complete’ (*note Completion Commands::を参照 )のような補完コマンドを呼び出すと、Emacsは‘completion-styles’に最初 にリストされたスタイルを探して、そのスタイルのTRY-COMPLETION関数を 呼び出す。この関数が‘nil’をリターンしたら、Emacsは次にリストされた 補完スタイルに移動してそのスタイルのTRY-COMPLETION関数を呼び出すと いったように、TRY-COMPLETION関数の1つが補完の処理に成功して非 ‘nil’値をリターンするまで順次これを行なう。同様の手順は ALL-COMPLETIONS関数を通じて補完のリストにも行われる。 利用できる補完スタイルについては*note (emacs)Completion Styles::を 参照のこと。 -- User Option: completion-category-overrides この変数は特別な補完スタイルと、特定の種類のテキスト補完時に使用す るその他の補完動作を指定する。この変数の値は‘(CATEGORY . ALIST)’と いう形式の要素をもつようなalistである。CATEGORYは何が補完されるかを 記述するシンボルで、現在のところカテゴリーに‘buffer’、‘file’、 ‘unicode-name’が定義されているが、これに特化した補完関数(*note Programmed Completion::を参照)を通じて他のカテゴリーを定義できる。 ALISTはそのカテゴリーにたいして補完がどのように振る舞うべきかを記述 する連想リスト。alistのキーとして以下がサポートされる: ‘styles’ 値は補完スタイル(シンボル)のリスト。 ‘cycle’ 値はそのカテゴリーにたいする‘completion-cycle-threshold’ (*note (emacs)Completion Options::を参照)の値。 将来、さらにalistエントリーが定義されるかもしれない。 -- Variable: completion-extra-properties この変数はカレント補完コマンドの特別なプロパティの指定に使用される 。この変数は補完に特化したコマンドによりletバインドされることを意図 している。値はプロパティ/値ペアーのリスト。以下のプロパティがサポー トされる: ‘:annotation-function’ 値は補完バッファー内に注釈(annotation)を加える関数。この関数は 引数completionを1つ受け取り‘nil’、または補完の隣に表示する文字 列をリターンしなければならない。 ‘:exit-function’ 値は補完を行った後に実行する関数。この関数は2つの引数STRINGと STATUSを受け取る。STRINGは補完されたフィールドのテキストで、 STATUSは行われた操作の種類を示す。操作の種類はテキストの補完が 完了したなら‘finished’、それ以上補完できないが補完が完了してい なければ‘sole’、有効な補完だがさらに補完できるときは‘exact’と なる。 19.6.7 プログラムされた補完 --------------------------- 意図した利用可能な補完のすべてを含むalistかobarrayを事前に作成するのが不 可能または不便なことがあります。このような場合は与えられた文字列にたいす る補完を計算するために独自の関数を提供できます。これは“プログラム補完 (programmed completion)”と呼ばれます。Emacsは数あるケースの中でも特にフ ァイル名の補完(*note File Name Completion::を参照)でプログラム補完を使用 しています。 この機能を使用するためには、関数を‘completing-read’のCOLLECTION引数と して渡します。関数‘completing-read’はその補完関数が‘try-completion’、 ‘all-completions’などの基本的な補完関数に渡されて、その関数がすべてを行 えるよう取り計らいます。 補完関数は3つの引数を受け取ります: • 補完される文字列。 • 利用可能なマッチをフィルターする述語関数。もしなければ‘nil’。関数は 利用可能なマッチにたいしてこの述語(predicate)を呼び出して、述語が ‘nil’をリターンしたらそのマッチを無視する。 • 実行する補完操作のタイプを指定するフラグ。以下のいずれかを指定でき る: ‘nil’ ‘try-completion’を指定する。関数は指定された文字が一意かつ完全 一致なら‘t’をリターンする。マッチが複数なら、すべてのマッチに 共通する部分文字列をリターンする(文字列が補完候補の1つに完全一 致するが、より長い他の候補にもマッチするならリターン値はその文 字列)。マッチがなければ‘nil’をリターンする。 ‘t’ ‘all-completions’を指定する。関数は指定された文字列の利用可能 なすべての補完のリストをリターンする。 ‘lambda’ ‘test-completion’を指定する。関数は指定された文字列がいくつか の補完候補に完全一致するなら‘t’、それ以外は‘nil’をリターンする 。 ‘(boundaries . SUFFIX)’ ‘completion-boundaries’を指定する。関数は‘(boundaries START . END)’をリターンする。ここでSTARTは指定された文字列内の境界の開 始位置、ENDはSUFFIX内の境界の終了位置。 ‘metadata’ カレント補完の状態に関する情報の要求を指定する。リターン値は ‘(metadata . ALIST)’の形式をもち、ALISTは以下で説明する要素を もつ連想配列。 フラグに他の値が指定されたら、補完関数は‘nil’をリターンする。 以下は‘metadata’フラグ引数への応答として補完関数がリターンするかもし れないmetadataエントリーのリストです: ‘category’ 値は補完関数が補完を試みているテキストの種類を説明するシンボル。シ ンボルが‘completion-category-overrides’内のキーの1つにマッチする場 合、通常の補完動作はオーバーライドされる。*note Completion Variables::を参照のこと。 ‘annotation-function’ 値は補完に“注釈(annotation)”を付ける関数。この関数は1つの引数 STRINGを受け取り、これは利用可能な補完である。リターン値は文字列で 、‘*Completions*’バッファー内の補完STRINGの後に表示される。 ‘display-sort-function’ 値は補完をソートする関数。関数は1つの引数をとる。これは補完文字列の リストで、ソートされた補完文字列リストがリターンされる。その入力の リストは破壊的に変更することが許容される。 ‘cycle-sort-function’ 値は‘completion-cycle-threshold’が非‘nil’、かつユーザーが補完候補を 巡回するときに補完をソートする関数。引数のリストとリターン値は ‘display-sort-function’と同様。 -- Function: completion-table-dynamic function &optional switch-buffer This function is a convenient way to write a function that can act as a programmed completion function. The argument FUNCTION should be a function that takes one argument, a string, and returns an alist of possible completions of it. It is allowed to ignore the argument and return a full list of all possible completions. You can think of ‘completion-table-dynamic’ as a transducer between that interface and the interface for programmed completion functions. オプション引数SWITCH-BUFFERが非‘nil’、かつ補完がミニバッファーで行 われた場合、FUNCTIONはそのミニバッファーにエンターしたときのバッフ ァーをカレントバッファーにセットして呼び出される。 -- Function: completion-table-with-cache function &optional ignore-case これは前回の引数/結果ペアーを保存する‘completion-table-dynamic’にた いするラッパーである。これは同じ引数にたいする複数回の検査に必要な のが、1回のFUNCTION呼び出しだけであることを意味する。これは外部プロ セス呼び出しなど、処理が低速のとき有用かもしれない。 19.6.8 通常バッファーでの補完 ----------------------------- 補完は通常はミニバッファー内で行われますが、補完機能は通常のEmacsバッフ ァー内のテキストにも使用できます。多くのメジャーモードで、コマンド ‘C-M-i’または‘M-’によってバッファー内補完が行われ、それらは ‘completion-at-point’にバインドされています。*note (emacs)Symbol Completion::を参照してください。このコマンドはアブノーマルフック変数 ‘completion-at-point-functions’を使用します: -- Variable: completion-at-point-functions このアブノーマルフックの値は関数のリストである。これらの関数はポイ ント位置のテキストの補完にたいする補完テーブルの計算に使用される。 これはメジャーモードによるモード特有な補完テーブル(*note Major Mode Conventions::を参照)の提供に使用できる。 コマンド‘completion-at-point’が実行されると、引数なしでリスト内の関 数が1つずつ呼び出される。それぞれの関数はポイント位置のテキストにた いして補完テーブルを生成できないなら‘nil’をリターンする。生成できた ら以下の形式のリストをリターンする (START END COLLECTION . PROPS) ここでSTARTとENDは補完する(ポイントを取り囲む)テキストの区切りであ る。COLLECTIONはそのテキストを補完する補完テーブルであり、 ‘try-completion’ (*note Basic Completion::を参照)の2つ目の引数とし て渡すのに適した形式である。補完候補は‘completion-styles’ (*note Completion Variables::を参照)で定義された補完スタイルを通じて、この 補完テーブルを通常の方法で使用して生成されるだろう。PROPSは追加の情 報のためのプロパティリストである。‘completion-extra-properties’内の すべてのプロパティ(*note Completion Variables::を参照)と、以下の追 加のプロパティが認識される: ‘:predicate’ 値は補完候補が満足する必要がある述語。 ‘:exclusive’ 値が‘no’の場合は、もし補完テーブルがポイント位置のテキストのマ ッチに失敗したなら、補完の失敗を報告するかわりに ‘completion-at-point’は‘completion-at-point-functions’内の次の 関数へ移動する。 補完リスト生成が処理が高価なら、COLLECTIONにたいして関数の提供を推 奨する。Emacsは内部的に‘completion-at-point-functions’内の関数を多 数回呼び出すかもしれないが、それらの呼び出しのいくつかにたいしての みCOLLECTIONの値を考慮する。COLLECTIONにたいして関数を提供すること により、Emacsは必要になるまで補完の生成を遅延できる。ラッパー関数を 作成するためにCOMPLETION-TABLE-DYNAMICを使用できる: ;; このパターンは避けて (let ((beg ...) (end ...) (my-completions (my-make-completions))) (list beg end my-completions)) ;; かわりに以下を使用する (let ((beg ...) (end ...)) (list beg end (completion-table-dynamic (lambda (_) (my-make-completions))))) ‘completion-at-point-functions’内の関数も、上述したリストのかわりに 関数をリターンするかもしれない。その場合は引数なしでリターンされた 関数が呼び出されてその関数が補完処理の全責任を負う。この方法は推奨 されない。これは‘completion-at-point’を使用する古いコードの救済を意 図したものだからである。 非‘nil’値を最初にリターンした‘completion-at-point-functions’内の関 数が、‘completion-at-point’によって使用される。残りの関数は呼び出さ れない。例外は上述の‘:exclusive’指定があるとき。 以下の関数はEmacsバッファー内の任意に拡張されたテキストにたいして便利 な補完方法を提供します: -- Function: completion-in-region start end collection &optional predicate この関数はCOLLECTIONを使用してカレントバッファー内の位置STARTと ENDの間のテキストを補完する。引数COLLECTIONは‘try-completion’ (*note Basic Completion::を参照)のときと同じ意味をもつ。 この関数は補完テキストを直接カレントバッファーに挿入する。 ‘completing-read’ (*note Minibuffer Completion::を参照)とは異なり、 ミニバッファーをアクティブにしない。 この関数が機能するためには、ポイントがSTARTとENDの間になければなら ない。 19.7 Yes-or-Noによる問い合わせ ============================== このセクションではユーザーにyes-or-noの確認を求める関数を説明します。関 数‘y-or-n-p’は1文字での応答に使用できます。この関数は不注意による誤った 答えが深刻な結果を招かない場合に有用です。‘yes-or-no-p’は3文字から4文字 の答えを要求するので、より重大な問いに適しています。 3つの関数はいずれもマウスを使用して呼び出されたコマンドの場合、より正 確には‘last-nonmenu-event’ (*note Command Loop Info::を参照)が‘nil’かリ ストの場合は、問いに答えるためにダイアログボックスまたはポップアップメニ ューを使用します。それ以外の場合はキーボード入力を使用します。呼び出しの 周囲で‘last-nonmenu-event’に適切な値をバインドすることにより、マウスある いはキーボードの使用を強制できます。 厳密に言うと‘yes-or-no-p’はミニバッファーを使用して、‘y-or-n-p’は使用 しませんが、これらのコマンドは一緒に説明したほうがよいでしょう。 -- Function: y-or-n-p prompt この関数はユーザーに答えを尋ねてミニバッファーに入力を求める。ユー ザーが‘y’をタイプしたら‘t’、‘n’をタイプしたら‘nil’をリターンする。 この関数はyesの意味で、noの意味でも受け入れる。quitとして ‘C-g’と同様に‘C-]’も受け入れる。これは問いがミニバッファーのような 外見をもち、ミニバッファーを抜けるためにユーザーが‘C-]’の使用を試み るかもしれないという理由による。応答は1文字であり、問いを終了させる ためのは必要ない。大文字と小文字は等価である。 “答えを尋ねる”とはエコーエリアにPROMPT、その後に文字列‘(y or n) ’を プリントすることを意味する。期待される答え(‘y’、‘n’、‘’、 ‘’、もしくは質問を終了するその他のキー)以外が入力されると、こ の関数は‘Please answer y or n.’と応答して繰り返し答えの入力を要求す る。 この関数は答えの編集を許さないので、実際にはミニバッファーを使用し ない。実際に使用するのはミニバッファーと同じスクリーンスペースを使 用するエコーエリア(*note The Echo Area::を参照)である。問いが答えら れるまでカーソルはエコーエリアに移動される。 答えとその意味は、たとえ‘y’と‘n’であっても固定されたものではなく、 キーマップ‘query-replace-map’によって指定される(*note Search and Replace::を参照)。特にユーザーが‘recenter’、‘scroll-up’、 ‘scroll-down’、‘scroll-other-window’、‘scroll-other-window-down’(そ れぞれ‘query-replace-map’内で‘C-l’、‘C-v’、‘M-v’、‘C-M-v’、 ‘C-M-S-v’にバインドされている)のような特殊な応答をエンターした場合 、この関数はは指定されたウィンドウの再センタリングやスクロール操作 を処理してから再度答えを求める。 エコーエリアのメッセージを連続する行で示しているが、スクリーン上に 実際に表示されるのは一度に1行だけである。 -- Function: y-or-n-p-with-timeout prompt seconds default ‘y-or-n-p’と同様だがユーザーがSECONDS秒以内に答えないと、この関数は 待つのをやめてDEFAULTをリターンする。これはタイマーをセットアップす ることによって機能する。引数SECONDSは数字である。 -- Function: yes-or-no-p prompt この関数は質問してミニバッファーに答えの入力を求める。これはユーザ ーが‘yes’をエンターすると‘t’、‘no’をエンターすると‘nil’をリターンす る。ユーザーは応答を終えるためにをタイプしなければならない。大 文字と小文字は等価。 ‘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 ’とタイプしたら無効になる。なぜならこの関数 は‘yes’という単語全体を要求しているので、一時停止して以下のプロンプ トを説明のために表示する。 ---------- Buffer: minibuffer ---------- Please answer yes or no. Do you really want to remove everything? (yes or no) ---------- Buffer: minibuffer ---------- 19.8 複数のY-or-Nの問い合わせ ============================= 同じような連続する質問と答えがある場合、たとえば各バッファーにたいして順 に“Do you want to save this buffer?”と確認を求めるような場合には、個別に 質問するより‘map-y-or-n-p’を使用して質問のコレクションを尋ねるべきです。 これはユーザーにたいして、質問全体にたいして1回で答えられるような便利な 機能を提供します。 -- Function: map-y-or-n-p prompter actor list &optional help action-alist no-cursor-in-echo-area この関数はユーザーに一連の質問をし、それぞれの質問にたいしてエコー エリア内の1文字の答えを読み取る。 値LISTは質問をするオブジェクトを指定する。これはリスト、オブジェク ト、または生成関数(generator function)のいずれかである。関数の場合 は引数なしで次に質問するオブジェクト、または質問の中止を意味する ‘nil’のいずれかをリターンする。 引数PROMPTERは各質問について問い合わせ方法を指定する。PROMPTERが文 字列なら質問テキストは以下のようになる: (format PROMPTER OBJECT) ここでOBJECTは、(LISTから得られる)質問する次のオブジェクトである。 文字列でないければ、PROMPTERは1つの引数(質問する次のオブジェクト)を とる関数で、質問テキストをリターンする。値が文字列ならユーザーに問 う質問であること。関数は‘t’(ユーザーに尋ねずこのオブジェクトを処理 する)、または‘nil’(ユーザーに尋ねずこのオブジェクトを無視する)をリ ターンすることもできる。 引数ACTORはユーザーが与えた答えにたいして、どのように処理するかを指 定する。これは引数が1つの関数で、ユーザーがyesと答えたオブジェクト を引数として呼び出される。引数は常にLISTから取得したオブジェクトで ある。 引数HELPが与えられたら、それは以下の形式のリストである: (SINGULAR PLURAL ACTION) SINGULARはそのオブジェクトが概念的に何に作用するかを説明する単数形 の名詞を含む文字列、PLURALはそれに対応する複数形の名詞、ACTIONは ACTORが何を行うかを説明する他動詞である。 HELPを指定しない場合のデフォルトは‘("object" "objects" "act on")’。 質問のたびに、ユーザーはそのオブジェクトを処理するなら‘y’、‘Y’また は、そのオブジェクトをスキップするなら‘n’、‘N’、または、 以降のすべてのオブジェクトを処理するなら‘!’、exit(以降のすべてのオ ブジェクトをスキップ)するならか‘q’、カレントオブジェクトを処理 した後にexitするなら‘.’(ピリオド)、ヘルプを入手する場合は‘C-h’をエ ンターする。これらは‘query-replace’が受け入れるのと同じ答えである。 キーマップ‘query-replace-map’は‘map-y-or-n-p’にたいするそれらの意味 を定義して、‘query-replace’にたいしても同様に定義する。*note Search and Replace::を参照のこと。 ACTION-ALISTを使用して、利用できる追加の答えとそれらが何を意味する かを指定できる。これは要素が‘(CHAR FUNCTION HELP)’という形式の alistで、それぞれの要素が追加の答えを1つ定義する。要素の内容は CHARが文字(答え)、FUNCTIONが引数が1つ(LISTから取得するオブジェクト )の関数、HELPが文字列である。 ユーザーの応答がCHARなら、‘map-y-or-n-p’はFUNCTIONを呼び出す。これ が非‘nil’をリターンしたらそのオブジェクトが処理されたと判断して、 ‘map-y-or-n-p’はLIST内の次のオブジェクトに進む。‘nil’をリターンした ら同じオブジェクトにたいして質問を繰り返す。 確認を求める間、‘map-y-or-n-p’は通常は‘cursor-in-echo-area’をバイン ドする。しかしNO-CURSOR-IN-ECHO-AREAが非‘nil’ならバインドしない。 マウスを使用して呼び出されたコマンドから‘map-y-or-n-p’が呼び出され た場合(より正確には‘last-nonmenu-event’は非‘nil’かリストの場合。 *note Command Loop Info::を参照)には、確認を求めるためにダイアログ ボックスかポップアップメニューが使用される。この場合にはキーボード 入力やエコーエリアは使用されない。呼び出しの前後で ‘last-nonmenu-event’を適切な値にバインドすることによって、マウスあ るいはキーボードの入力を強制できる。 ‘map-y-or-n-p’のリターン値は処理したオブジェクトの個数である。 19.9 パスワードの読み取り ========================= 他のプログラムに渡すためのパスワードを読み取るために関数‘read-passwd’を 使用できます。 -- Function: read-passwd prompt &optional confirm default この関数はプロンプトPROMPTを表示してパスワードを読み取る。これはユ ーザーがタイプしたパスワードのかわりに、パスワード内の各文字を‘.’に 変更してエコーする。パスワードを隠すために別の文字を適用したければ 、その文字を‘read-hide-char’にletバインドすること。 オプション引数CONFIRMが非‘nil’なら、パスワードを2回読み取ることでそ れらが同じものであることを強制する。同じでなければ、2回の入力が同じ になるまで、ユーザーはパスワードを繰り返しタイプする必要がある。 オプション引数DEFAULTは、ユーザーが空入力をエンターした場合のデフォ ルトパスワードである。DEFAULTが‘nil’なら、‘read-passwd’はnull文字列 をリターンする。 19.10 ミニバッファーのコマンド ============================== このセクションではミニバッファー内で使用するコマンドを説明します。 -- Command: exit-minibuffer このコマンドはアクティブなミニバッファーをexitする。これは通常はミ ニバッファー内のローカルキーマップのキーにバインドされる。 -- Command: self-insert-and-exit このコマンドはキーボードでタイプされた最後の文字を挿入した後にアク ティブなミニバッファーをexitする。*note Command Loop Info::)を参照 のこと。 -- Command: previous-history-element n このコマンドはN個前(古い)のヒストリー要素の値でミニバッファー内のコ ンテンツを置換する。 -- Command: next-history-element n このコマンドはN個先(新しい)のヒストリー要素の値でミニバッファー内の コンテンツを置換する。 -- Command: previous-matching-history-element pattern n このコマンドはPATTERN(正規表現)にマッチするN個前(古い)のヒストリー 要素でミニバッファー内のコンテンツを置換する。 -- Command: next-matching-history-element pattern n このコマンドはPATTERN(正規表現)にマッチするN個先(新しい)のヒストリ ー要素でミニバッファー内のコンテンツを置換する。 -- Command: previous-complete-history-element n このコマンドはミニバッファー内のポイントの前のカレントコンテンツを 、N個前(古い)ヒストリー要素の値で置換する。 -- Command: next-complete-history-element n このコマンドはミニバッファー内のポイントの前のカレントコンテンツを 、N個先(新しい)ヒストリー要素の値で置換する。 19.11 ミニバッファーのウィンドウ ================================ 以下の関数はミニバッファーウィンドウにアクセスと選択を行い、それがアクテ ィブかどうかテストしてリサイズされる方法を制御します。 -- Function: active-minibuffer-window この関数はカレントでアクティブなミニバッファーウィンドウ、アクティ ブなウィンドウがなければ‘nil’をリターンする。 -- Function: minibuffer-window &optional frame この関数はフレームFRAMEにたいして使用されるミニバッファーウィンドウ をリターンする。FRAMEが‘nil’ならカレントフレームを意味する。フレー ムに使用されるミニバッファーウィンドウは、そのフレームの一部である 必要はないことに注意。自身のミニバッファーをもたないフレームは、必 然的に他のフレームのミニバッファーウィンドウを使用する。 -- Function: set-minibuffer-window window この関数はミニバッファーウィンドウとしてWINDOWを使用するよう指定す る。これは通常のミニバッファーコマンドを呼び出さずにミニバッファー にテキストを入力する場合には、そのミニバッファーがどこに表示される かに影響を及ぼす。通常のミニバッファー入力関数はすべてカレントフレ ームに対応するミニバッファーを選択して開始されるので影響はない。 -- Function: window-minibuffer-p &optional window この関数はWINDOWがミニバッファーウィンドウなら‘nil’をリターンする。 WINDOWのデフォルトは選択されたウィンドウ。 ‘(minibuffer-window)’の結果を比較して与えられたウィンドウがミニバッフ ァーかどうか判断するのは正しくない。なぜなら複数のフレームがある場合には 、ミニバッファーウィンドウも複数あり得るからである。 -- Function: minibuffer-window-active-p window この関数はWINDOWがカレントでアクティブなミニバッファーウィンドウな ら非‘nil’をリターンする。 以下の2つのオプションはミニバッファーウィンドウが自動的にリサイズされ るか否か、およびその処理でミニバッファーが大きくなり得るサイズを制御しま す。 -- User Option: resize-mini-windows このオプションはミニバッファーウィンドウが自動的にリサイズされるか どうかを指定する。デフォルト値は‘grow-only’で、これはミニバッファー が表示するテキストを収容するために、ミニバッファーウィンドウがデフ ォルトにより自動的に拡張されて、ミニバッファーが空になれば即座に1行 に縮小されることを意味する。値が‘t’ならEmacsは常にミニバッファーが 表示するテキストにミニバッファーウィンドウの高さをフィットさせるよ うに試みる。値が‘nil’ならミニバッファーウィンドウのサイズが自動的に 変更されることは決してない。この場合には、ミニバッファーウィンドウ の高さの調節のために、ウィンドウリサイズコマンドを使用できる(*note Resizing Windows::を参照)。 -- User Option: max-mini-window-height このオプションはミニバッファーウィンドウの自動的なリサイズにたいす る最大高さを提供する。浮動小数点数はフレーム高さにたいする割合、整 数は最大行数を指定する。デフォルト値は0.25。 19.12 ミニバッファーのコンテンツ ================================ 以下の関数はミニバッファーのプロンプトとコンテンツにアクセスします。 -- Function: minibuffer-prompt この関数はカレントでアクティブなミニバッファーのプロンプト文字列を リターンする。アクティブなミニバッファーがなければ‘nil’をリターンす る。 -- Function: minibuffer-prompt-end この関数はミニバッファーがカレントならミニバッファープロンプトの終 端のカレント位置をリターンする。それ以外はバッファーの有効な最小位 置をリターンする。 -- Function: minibuffer-prompt-width この関数はミニバッファーがカレントならミニバッファープロンプトのカ レントの表示幅をリターンする。それ以外は0をリターンする。 -- Function: minibuffer-contents この関数はミニバッファーがカレントなら、ミニバッファーの編集可能な コンテンツ(つまりプロンプト以外のすべて)を文字列でリターンする。そ れ以外はカレントバッファーのコンテンツ全体をリターンする。 -- Function: minibuffer-contents-no-properties これは‘minibuffer-contents’と同様だが、テキストプロパティをコピーせ ずに文字自身だけをリターンする。*note Text Properties::を参照のこと 。 -- Command: delete-minibuffer-contents このコマンドはミニバッファーがカレントなら、ミニバッファーの編集可 能なコンテンツ(つまりプロンプト以外のすべて)を削除する。それ以外は カレントバッファー全体を削除する。 19.13 再帰的なミニバッファー ============================ 以下の関数と変数は再帰ミニバッファーを処理します(*note Recursive Editing::を参照): -- Function: minibuffer-depth この関数はアクティブなミニバッファーのカレント再帰深さを正の整数で リターンする。アクティブなミニバッファーが存在しなければ0をリターン する。 -- User Option: enable-recursive-minibuffers この変数が非‘nil’ならミニバッファーウィンドウがアクティブでも、 (‘find-file’のような)ミニバッファーを使用するコマンドを呼び出すこと ができる。このような呼び出しは新たなミニバッファーにたいして再帰編 集レベル(recursive editing level)を生成する。内側レベルの編集の間、 外側レベルのミニバッファーは非表示になる。 この変数が‘nil’なら、ミニバッファーウィンドウがアクティブなときにた とえ他のウィンドウに切り替えても、ミニバッファーコマンドの呼び出し はできない。 コマンド名が非‘nil’のプロパティ‘enable-recursive-minibuffers’をもつ場 合には、たとえミニバッファーから呼び出された場合でも、そのコマンドは引数 の読み取りにミニバッファーを使用できる。コマンドのinteractive宣言内で ‘enable-recursive-minibuffers’を‘t’にしても、これを行うことができる (*note Using Interactive::を参照)。ミニバッファーコマンド ‘next-matching-history-element’ (ミニバッファー内では通常‘M-s’)は後者を 行う。 19.14 ミニバッファー、その他の事項 ================================== -- Function: minibufferp &optional buffer-or-name この関数はBUFFER-OR-NAMEがミニバッファーなら非‘nil’をリターンする。 BUFFER-OR-NAMEが省略されるとカレントバッファーをテストする。 -- Variable: minibuffer-setup-hook これはミニバッファーがエンターされたときは常に実行されるノーマルフ ックである。*note Hooks::を参照のこと。 -- Variable: minibuffer-exit-hook これはミニバッファーがexitされたときは常に実行されるノーマルフック である。 -- Variable: minibuffer-help-form この変数のカレント値はミニバッファー内で‘help-form’をローカルにリバ インドするために使用される(*note Help Functions::を参照)。 -- Variable: minibuffer-scroll-window この変数の値が非‘nil’なら、それはウィンドウオブジェクトである。ミニ バッファー内で関数‘scroll-other-window’が呼び出されたときは、このウ ィンドウをスクロールする。 -- Function: minibuffer-selected-window この関数はミニバッファーがエンターされたときに選択されていたウィン ドウをリターンする。選択されたウィンドウがミニバッファー以外のとき は‘nil’をリターンする。 -- User Option: max-mini-window-height この変数はミニバッファーウィンドウのリサイズにたいする最大高さを指 定する。浮動小数点数ならフレーム高さにたいする割り合いを指定する。 整数の場合は行数を指定する。 -- Function: minibuffer-message string &rest args この関数は数秒、あるいは次の入力イベントが到着するまでミニバッファ ーテキストの最後に一時的にSTRINGを表示する。変数 ‘minibuffer-message-timeout’は入力がない場合に待機する秒数を指定す る(デフォルトは2)。ARGSが非‘nil’なら、実際のメッセージは ‘format-message’にSTRINGとARGSを渡して作成される。*Note Formatting Strings::を参照のこと。 -- Command: minibuffer-inactive-mode これはインタラクティブなミニバッファー内で使用されるメジャーモード である。キーマップ‘minibuffer-inactive-mode-map’を使用する。ミニバ ッファーが別のフレームにある場合には有用かもしれない。*note Minibuffers and Frames::を参照のこと。 20 コマンドループ ***************** Emacsを実行すると、ほぼ即座に“エディターコマンドループ(editor command loop)”に移行します。このループはキーシーケンスを読み取り、それらの定義を 実行して結果を表示します。このチャプターではこれらが行われる方法と、 Lispプログラムがこれらを行えるようにするサブルーチンを説明します。 20.1 コマンドループの概要 ========================= コマンドループが最初に行わなければならないのはキーシーケンスの読み取りで す。キーシーケンスはコマンドに変換される入力イベントのシーケンスです。こ れは関数‘read-key-sequence’を呼び出すことによって行われます。Lispプログ ラムもこの関数を呼び出すことができます(*note Key Sequence Input::を参照 )。これらはより低レベルの‘read-key’や‘read-event’ (*note Reading One Event::)で入力を読み取ったり、‘discard-input’ (*note Event Input Misc::を 参照)で保留中の入力を無視することもできます。 キーシーケンスはカレントでアクティブなキーマップを通じてコマンドに変 換されます。これが行われる方法については*note Key Lookup::を参照してくだ さい。結果はキーボードマクロかインタラクティブに呼び出し可能な関数になり ます。キーが‘M-x’なら他のコマンドの名前を読み取って、それを呼び出します 。これはコマンド‘execute-extended-command’ (*note Interactive Call::を参 照)により行われます。 コマンドの実行に先立ち、Emacsはアンドゥ境界(undo boundary)を作成する ために‘undo-boundary’を実行します。*note Maintaining Undo::を参照してく ださい。 コマンドを実行するために、Emacsはまず‘command-execute’を呼び出してコ マンドの引数を読み取ります(*note Interactive Call::を参照)。Lispで記述さ れたコマンドについては、‘interactive’指定で引数を読み取る方法を指定しま す。これはプレフィクス引数(*note Prefix Command Arguments::を参照)を使用 したり、ミニバッファー内(*note Minibuffers::を参照)で確認を求めて読み取 りを行うかもしれません。たとえばコマンド‘find-file’には‘interactive’指定 があり、これはミニバッファーを使用してファイル名を読み取ることを指定しま す。‘find-file’の関数bodyはミニバッファーを使用しないので、Lispコードか ら関数として‘find-file’を呼び出す場合には、通常のLisp関数引数としてファ イル名を文字列で与えなければなりません。 コマンドがキーボードマクロ(文字列やベクター)なら、Emacsは ‘execute-kbd-macro’を使用してそれを実行します(*note Keyboard Macros::を 参照)。 -- Variable: pre-command-hook このノーマルフックはコマンドを実行する前に、エディターコマンドルー プにより実行される。その際、‘this-command’には実行しようとするコマ ンドが含まれ、‘last-command’には前のコマンドが記述される。*note Command Loop Info::を参照のこと。 -- Variable: post-command-hook このノーマルフックはコマンドを実行した後(quitやエラーにより早期に終 了させられたコマンドを含む)に、エディターコマンドループにより実行さ れる。その際、‘this-command’は正に実行されたコマンド、 ‘last-command’は前に実行されたコマンドを参照する。 このフックはEmacsが最初にコマンドループにエンターしたときにも実行さ れる(その時点では‘this-command’と‘last-command’はいずれも‘nil’)。 ‘pre-command-hook’と‘post-command-hook’の実行中は、quitは抑制されます 。これらのフックのいずれかを実行中にエラーが発生しても、そのエラーはフッ クの実行を終了させません。そのかわりにエラーは黙殺されて、エラーが発生し た関数はそのフックから取り除かれます。 Emacsサーバー(*note (emacs)Emacs Server::を参照)に届くリクエストは、 キーボードコマンドが行うのと同じように、これらの2つのフックを実行します 。 20.2 コマンドの定義 =================== スペシャルフォーム‘interactive’はLisp関数をコマンドに変更します。 ‘interactive’フォームは関数bodyのトップレベルに置かなければならず、通常 はbody内の最初のフォームとして記述されます。これはラムダ式(*note Lambda Expressions::を参照)と‘defun’ (*note Defining Functions::を参照)の両方を 受け入れます。このフォームはその関数が実際に実行される間は何も行いません 。このフォームの存在はフラグとしての役割りをもち、Emacsコマンドループに たいしてその関数がインタラクティブに呼び出せることを告げます。 ‘interactive’フォームの引数はインタラクティブな呼び出しが引数を読み取る 方法を指定します。 ‘interactive’フォームのかわりに、関数シンボルの‘interactive-form’プロ パティで指定されることもあります。このプロパティが非‘nil’値なら、関数 body内の‘interactive’フォームより優先されます。この機能はほとんど使用さ れません。 インタラクティブに呼び出されることだけを意図していて、決してLispから 直接呼び出されない関数が時折あります。この場合には、直接あるいは ‘declare’ (*note Declare Form::を参照)を通じて、その関数の ‘interactive-only’プロパティに非‘nil’を与えます。これにより、そのコマン ドがLispから呼び出されるとバイトコンパイラーが警告を発します。 ‘describe-function’の出力にはこれに類似する情報が含まれます。このプロパ ティの値には文字列、‘t’、または任意のシンボルを指定できます。文字列なら 、それはバイトコンパイラーによる警告内で直接使用されます(最初は大文字で なくピリオドで終端される文字列であること。たとえば‘\"use (system-name) instead.\"’)。シンボルなら、それはLispコード内で使用されるかわりの関数で す。 20.2.1 ‘interactive’の使用 -------------------------- このセクションでは、Lisp関数をインタラクティブに呼び出し可能なコマンドに する‘interactive’フォームの記述方法と、コマンドの‘interactive’フォームの 検証方法について説明します。 -- Special Form: interactive arg-descriptor このスペシャルフォームは関数がコマンドであり、したがって(‘M-x’を通 じて、またはそのコマンドにバインドされたキーシーケンスをエンターす ることにより)インタラクティブに呼び出すことができることを宣言する。 引数ARG-DESCRIPTORは、そのコマンドがインタラクティブに呼び出された ときに引数を計算する方法を宣言する。 コマンドは他の関数と同じようにLisp関数から呼び出されるかもしれない が、その場合には呼び出し側は引数を提供して、ARG-DESCRIPTORは効果を もたない。 ‘interactive’フォームは関数body内のトップレベルに置くか、関数シンボ ルの‘interactive-form’プロパティ((*note Symbol Properties::)を参照 )になければならない。これはコマンドループが関数を呼び出す前に interactiveフォームを調べることにより効果をもつ(*note Interactive Call::を参照)。一度関数が呼び出されると関数body内のすべてのフォーム が実行される。このときbody内に‘interactive’フォームが出現しても、そ のフォームは引数の評価さえされず単に‘nil’をリターンする。 慣例により‘interactive’フォームは関数body内の最初のトップレベルフォ ームとするべきである。‘interactive’フォームがシンボルの ‘interactive-form’プロパティと関数bodyの両方に存在する場合には前者 が優先される。‘interactive-form’フォームは既存の関数にinteractiveフ ォームを追加したり、その関数を再定義することなく引数をインタラクテ ィブに処理する方法を変更するために使用できる。 引数ARG-DESCRIPTORは以下の3つの可能性があります: • 省略または‘nil’ならコマンドは引数なしで呼び出される。コマンドが1つ 以上の引数を要求する場合は即座にエラーとなる。 • 文字列なら、その文字列の内容は改行で区切られた要素シーケンスであり 、1つの要素が1つの引数に対応する(1)。各要素はコード文字(*note Interactive Codes::を参照)と、オプションでその後のプロンプト(コード 文字として使用される文字やコード文字としては無視されるものもある)に より構成される。以下は例である: (interactive "P\nbFrobnicate buffer: ") コード文字‘P’はそのコマンドの1つ目の引数をrawコマンドプレフィクス (*note Prefix Command Arguments::を参照)にセットする。‘bFrobnicate buffer: ’は、ユーザーに‘Frobnicate buffer: ’のプロンプトを示して既 存のバッファーの名前の入力を促し、これは2つ目かつ最後の引数になる。 プロンプト文字列には、プロンプト内の前の引数(1つ目の引数から始まる )の値を含めるために‘%’を使用できる。これは‘format-message’ (*note Formatting Strings::を参照)を使用して行われる。たとえば以下は既存の バッファーの名前を読み取って、その後にそのバッファーに与える新たな 名前を読み取る例である: (interactive "bBuffer to rename: \nsRename buffer %s to: ") 文字列の先頭に‘*’がある場合、そのバッファーが読み取り専用ならエラー がシグナルされる。 文字列の先頭が‘@’で、そのコマンドの呼び出しに使用されたキーシーケン スに何らかのマウスイベントが含まれる場合は、そのコマンドを実行する 前に、それらのうち最初のイベントに結びつくウィンドウが選択される。 文字列の先頭が‘^’で、そのコマンドが“シフト転換 (shift-translation)”を通じて呼び出された場合は、そのコマンドを実行 する前にマークをセットして一時的にリージョンをアクティブにするか、 すでにアクティブなリージョンを拡張する。コマンドがシフト転換なしで 呼び出されて、リージョンが一時的にアクティブな場合は、コマンドを実 行する前にそのリージョンを非アクティブにする。シフト転換は ‘shift-select-mode’によりユーザーレベルで制御される。*note (emacs)Shift Selection::を参照のこと。 ‘*’、‘@’、‘^’は一緒に使用でき、その場合は順序に意味はない。実際の引 数の読み取りは残りのプロンプト文字列(‘*’、‘@’、‘^’以外の最初の文字 以降)により制御される。 • 文字列以外のLisp式なら、そのコマンドに渡す引数リストを取得するため に評価されるフォームである。このフォームは通常はユーザーから入力を 読み取るためにさまざまな関数を呼び出し、そのためにほとんどの場合は ミニバッファー(*note Minibuffers::を参照)を通じてか、キーボードから 直接読み取りを行う(*note Reading Input::を参照)。 引数値としてポイントやマークを提供するのも一般的だが、何かを行い_か つ_(ミニバッファー使用の有無に関わらず)入力を読み取る場合には、読み 取りの前にポイント値またはマーク値の整数を確実に取得しておくこと。 カレントバッファーはサブプロセスの出力を受信するかもしれず、コマン ドが入力を待つ間にサブプロセス出力が到着すると、ポイントやマークの 再配置が起こり得る。 以下は行っては_いけない_例である: (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-form function この関数はFUNCTIONの‘interactive’フォームをリターンする。FUNCTIONが インタラクティブに呼び出し可能な関数(*note Interactive Call::を参照 )なら、値はそのコマンドの引数を計算する方法を指定する ‘interactive’フォーム(‘(interactive SPEC)’)である。それ以外では値は ‘nil’である。FUNCTIONがシンボルなら、そのシンボルの関数定義が使用さ れる。 ---------- Footnotes ---------- (1) いくつかの要素は実際に2つの引数を提供します。 20.2.2 ‘interactive’にたいするコード文字 ---------------------------------------- ここで説明されているコード文字には、以下で定義されるいくつかのキーワード が含まれています: Completion 補完を提供する。は‘completing-read’ (*note Completion::を参照)を使用して引数を読み取って名前の補完を行う。 ‘?’で利用可能な補完リストを表示する。 Existing 既存オブジェクトの名前を要求する。無効な名前は受け付けられない。カ レント入力が有効でなければ、ミニバッファーをexitするコマンドは exitしない。 Default ユーザーがテキストを何もエンターしなければ、ある種のデフォルト値が 使用される。デフォルトはコード文字に依存する。 No I/O このコード文字は入力を読み取らずに引数を計算する。したがってプロン プト文字列を使用せず、与えられたプロンプト文字列は無視される。 たとえそのコード文字がプロンプト文字列を使用しなくても、それが文字 列内で最後のコード文字でなければ、その後に改行を付加しなければなら ない。 Prompt コード文字の直後にプロンプトが続く。プロンプトの終端は文字列の終端 、または改行。 Special このコード文字はインタラクティブ文字列の先頭にあるときのみ意味があ り、プロンプトと改行を要求しない。単一の独立した文字。 以下は‘interactive’で使用されるコード文字です: ‘*’ カレントバッファーが読み取り専用ならエラーをシグナルする。[Special] ‘@’ このコマンドを呼び出したキーシーケンス内の最初のマウスイベントに関 連するウィンドウを選択する。[Special] ‘^’ シフト転換を通じてコマンドが呼び出された場合はコマンドを実行する前 に、マークをセットして一時的にリージョンをアクティブにするか、すで にリージョンがアクティブならリージョンを拡張する。シフト転換を通じ ずにコマンドが呼び出されて、リージョンが一時的にアクティブならコマ ンドを実行する前にそのリージョンを非アクティブにする。[Special] ‘a’ 関数名(‘fboundp’を満足するシンボル)。[Existing]、[Completion]、 [Prompt] ‘b’ 既存バッファーの名前。デフォルトではカレントバッファー(*note Buffers::を参照)の名前を使用する。[Existing]、[Completion]、 [Default]、[Prompt] ‘B’ バッファー名。そのバッファーが存在する必要はない。デフォルトではカ レントバッファーではなくもっとも最近使用されたバッファーの名前を使 用する。[Completion]、[Default]、[Prompt] ‘c’ 文字。カーソルはエコーエリアに移動しない。[Prompt] ‘C’ コマンド名(‘commandp’を満足するシンボル)。[Existing]、 [Completion]、[Prompt] ‘d’ ポイント位置の整数(*note Point::を参照)。[No I/O] ‘D’ ディレクトリー名。デフォルトはカレントバッファーのカレントのデフォ ルトディレクトリー‘default-directory’ (*note File Name Expansion::を 参照)。[Existing]、[Completion]、[Default]、[Prompt] ‘e’ そのコマンドを呼び出したキーシーケンス内の1つ目か2つ目の非キーボー ドイベント。より正確には、‘e’はリストとしてイベントを取得するので、 リスト内のデータを調べることができる。*note Input Events::を参照の こと。[No I/O] ‘e’はマウスイベント、および特別なシステムイベント(*note Misc Events::を参照)にたいして使用する。コマンドが受け取るイベントリスト は、そのイベントに依存する。*note Input Events::ではそれぞれのイベ ントのリスト形式を、対応するサブセクションでそれぞれ説明しているの で参されたい。 1つのコマンドのinteractive仕様の中で‘e’を複数回使用できる。そのコマ ンドを呼び出したキーシーケンスがイベントN(リスト)をもつなら、‘e’の N番目がそのイベントを提供する。フンクションキーやASCII文字のような リスト以外のイベントは、‘e’に関連するイベントとしてカウントされない 。 ‘f’ 既存ファイルのファイル名(*note File Names::を参照)。デフォルトのデ ィレクトリーは‘default-directory’。[Existing]、[Completion]、 [Default]、[Prompt] ‘F’ ファイル名。ファイルが存在している必要はない。[Completion]、 [Default]、[Prompt] ‘G’ ファイル名。ファイルが存在している必要はない。ユーザーがディレクト リー名だけをエンターしたら値はそのディレクトリー名となり、そのディ レクトリー名にファイル名は追加されない。[Completion]、[Default]、 [Prompt] ‘i’ 無関係な引数。このコード文字は引数値として常に‘nil’を与える。[No I/O] ‘k’ キーシーケンス(*note Key Sequences::を参照)。これはカレントキーマッ プ内でコマンド(または未定義のコマンド)が見つかるまで、イベントを読 み取り続ける。キーシーケンス引数は文字列かベクターで表される。カー ソルはエコーエリアに移動しない。[Prompt] ‘k’が(マウスの)down-eventで終わるキーシーケンスを読み取ると、後続の (マウスの)up-eventも読み取ってそれを廃棄する。コード文字‘U’により up-eventへのアクセスを得られる。 この種の入力は‘describe-key’や‘global-set-key’のようなコマンドによ り使用される。 ‘K’ キーシーケンス。その定義は変更されることを意図している。これは‘k’と 同じように機能するが、キーシーケンス内の最後の入力イベントにたいし て、通常は(必要なら)使用される未定義キーから定義済みキーへの変換を 抑制する。 ‘m’ マーク位置の整数。[No I/O] ‘M’ 任意のテキスト。ミニバッファー内でカレントバッファーの入力メソッド (*note (emacs)Input Methods::を参照)を使用して読み取りを行い、それ を文字列でリターンする。[Prompt] ‘n’ 数字。ミニバッファーで読み取られる。入力が数字でなければユーザーは 再試行する必要がある。‘n’は決してプレフィクス引数を使用しない。 [Prompt] ‘N’ 数引数(numeric prefix argument)。ただしプレフィクス引数がなければ ‘n’のように数字を読み取る。値は常に数字。*note Prefix Command Arguments::を参照のこと。[Prompt] ‘p’ 数引数(小文字の‘p’であることに注意)。[No I/O] ‘P’ rawプレフィクス引数(大文字の‘P’であることに注意)。[No I/O] ‘r’ 2つの数引数(ポイントとマーク)。小さいほうが先。これは1つではなく連 続する2つの引数を指定する唯一のコード文字である。[No I/O] ‘s’ 任意のテキスト。ミニバッファー内で読み取りを行って文字列としてリタ ーンする(*note Text from Minibuffer::を参照)。‘C-j’かで入力を 終端する(これらの文字を入力に含めるために‘C-q’を使用できる)。 [Prompt] ‘S’ intern済みのシンボル。名前はミニバッファー内で読み取られる。‘C-j’か で入力を終端する。ここでは通常はシンボルを終端するその他の文字 (たとえば空白文字、丸カッコ、角カッコ)では終端されない。[Prompt] ‘U’ キーシーケンスか‘nil’。‘k’(または‘K’)が読み取った後に、(もしあれば )捨てられる(マウスの)up-eventを取得するために、引数‘k’(または‘K’)の 後で使用され得る。捨てられたup-eventが存在しなければ、‘U’は引数とし て‘nil’を提供する。[No I/O] ‘v’ ユーザーオプションとして宣言された変数(述語‘custom-variable-p’を満 足する)。これは‘read-variable’を使用して変数を読み取る。*note Definition of read-variable::を参照のこと。[Existing]、 [Completion]、[Prompt] ‘x’ Lispオブジェクト。そのオブジェクトの入力構文により指定され、‘C-j’か で終端される。オブジェクトは評価されない。*note Object from Minibuffer::を参照のこと。[Prompt] ‘X’ Lispフォームの値。‘X’は‘x’のように読み取りを行いフォームを評価して 、その値がコマンドの引数になる。[Prompt] ‘z’ コーディングシステム名(シンボル)。ユーザーがnull入力をエンターする と、引数値は‘nil’になる。*note Coding Systems::を参照のこと。 [Completion]、[Existing]、[Prompt] ‘Z’ コマンドにプレフィクス引数があればコーディングシステム名。プレフィ クス引数がなければ‘Z’は引数値として‘nil’を提供する。[Completion]、 [Existing]、[Prompt] 20.2.3 ‘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 20.2.4 コマンド候補からの選択 ----------------------------- マクロ‘define-alternatives’は“ジェネリックコマンド(generic command)”を定 義するために使用できます。これらはユーザーの選択により複数の候補から選択 可能なinteractive関数の実装です。 -- Macro: define-alternatives command &rest customizations 新たなコマンドCOMMAND(シンボル)を定義する。 最初にユーザーが‘M-x COMMAND ’を実行したとき、Emacsはコマンド が使用する実際のフォームにたいして確認を求めて、その選択をカスタム 変数として記録する。プレフィクス引数を使用すると選択肢の選択のプロ セスを繰り返す。 変数‘COMMAND-alternatives’には、COMMANDの実装候補がalistで含まれる 。この変数がセットされるまで‘define-alternatives’は効果をもたない。 CUSTOMIZATIONSが非‘nil’なら、‘defcustom’キーワード(典型的には ‘:group’と‘:version’)と、‘COMMAND-alternatives’の宣言に追加する値に より構成される選択肢。 20.3 interactiveな呼び出し ========================== コマンドループはキーシーケンスをコマンドに変換した後、関数 ‘command-execute’を使用してその関数を呼び出します。そのコマンドが関数な ら、‘command-execute’は引数を読み取りコマンドを呼び出す ‘call-interactively’を呼び出します。自分でこれらの関数を呼び出すこともで きます。 このコンテキストにおいて用語“command”はインタラクティブにコール可能な 関数(または関数likeなオブジェクト)やキーボードマクロを指すことに注意して ください。つまりコマンドを呼び出すキーシーケンスのことではありません (*note Keymaps::を参照)。 -- Function: commandp object &optional for-call-interactively この関数はOBJECTがコマンドなら‘t’、それ以外は‘nil’をリターンする。 コマンドには文字列とベクター(キーボードマクロとして扱われる)、トッ プレベルの‘interactive’フォーム(*note Using Interactive::を参照)を 含むラムダ式、そのようなラムダ式から作成されたバイトコンパイル関数 オブジェクト、interactiveとして宣言(‘autoload’の4つ目の引数が非 ‘nil’)されたautoloadオブジェクト、およびいくつかのプリミティブ関数 が含まれる。‘interactive-form’プロパティが非‘nil’のシンボル、および 関数定義が‘commandp’を満足するシンボルもコマンドとされる。 FOR-CALL-INTERACTIVELYが非‘nil’なら、‘call-interactively’が呼び出す ことができるオブジェクトにたいしてのみ‘commandp’は‘t’をリターンする 。したがってキーボードマクロは該当しなくなる。 ‘commandp’を使用する現実的な例については、*note Accessing Documentation::内の‘documentation’を参照のこと。 -- Function: call-interactively command &optional record-flag keys この関数はinteractive呼び出し仕様にしたがって引数を取得し、インタラ クティブに呼び出し可能な関数COMMANDを呼び出す。これはCOMMANDがリタ ーンするものが何であれ、それをリターンする。 たとえばもし以下の署名をもつ関数があり: (defun foo (begin end) (interactive "r") ...) 以下を行うと (call-interactively 'foo) これはリージョン(‘point’と‘mark’)を引数として‘foo’を呼び出すだろう 。 COMMANDが関数でない、またはインタラクティブに呼び出せない(コマンド でない)場合にはエラーをシグナルする。たとえコマンドだとしても、キー ボードマクロ(文字列かベクター)は関数ではないので許容されないことに 注意。COMMANDがシンボルなら‘call-interactively’はそれの関数定義を使 用する。 RECORD-FLAGが非‘nil’なら、このコマンドとコマンドの引数は無条件にリ スト‘command-history’に追加される。それ以外なら引数の読み取りにミニ バッファーを使用した場合のみコマンドが追加される。*note Command History::を参照のこと。 引数KEYSが与えらたら、それはコマンドを呼び出すためにどのイベントを 使用するかコマンドが問い合わせた場合に与えるべきイベントシーケンス を指定するベクターである。KEYSが‘nil’または省略された場合のデフォル トは、‘this-command-keys-vector’のリターン値である。*note Definition of this-command-keys-vector::を参照のこと。 -- Function: funcall-interactively function &rest arguments この関数は‘funcall’ (*note Calling Functions::を参照)と同様に機能す るが、インタラクティブな呼び出しのように見える呼び出しを生成する。 FUNCTION内部での‘called-interactively-p’の呼び出しは‘t’をリターンす るだろう。FUNCTIONがコマンドでなければ、エラーをシグラルすることな くそれを呼び出す。 -- Function: command-execute command &optional record-flag keys special この関数はCOMMANDを実行する。引数COMMANDは述語‘commandp’を満足しな ければならない。つまりインタラクティブに呼び出し可能な関数かキーボ ードマクロでなければならない。 COMMANDが文字列かベクターなら、‘execute-kbd-macro’により実行される 。関数はRECORD-FLAGおよびKEYS引数とともに‘call-interactively’に渡さ れる(上記参照)。 COMMANDがシンボルなら、その位置にシンボルの関数定義が使用される。 ‘autoload’定義のあるシンボルは、インタラクティブに呼び出し可能な関 数を意味するよう宣言されていればコマンドとして判断される。そのよう な宣言は指定されたライブラリーのロードと、シンボル定義の再チェック により処理される。 引数SPECIALが与えられたら、それはプレフィクス引数を無視して、それを クリアーしないという意味である。これはスペシャルイベント(*note Special Events::を参照)を実行する場合に使用される。 -- Command: execute-extended-command prefix-argument この関数は‘completing-read’(*note Completion::を参照)を使用して、ミ ニバッファーからコマンド名を読み取る。その後で指定されたコマンドを 呼び出すために‘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 20.4 interactiveな呼び出しの区別 ================================ 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’をテストすることによってこれを行うこともできます 。 -- Function: called-interactively-p kind この関数は呼び出された関数が‘call-interactively’を使用して呼び出さ れえいたら‘t’をリターンする。 引数KINDはシンボル‘interactive’かシンボル‘any’のいずれかである。こ れが‘interactive’なら、‘called-interactively-p’はユーザーから直接呼 び出しが行われたとき — たとえば関数呼び出しにバインドされたキーシー ケンスをユーザーがタイプした場合がそれに該当するが、ユーザーがその 関数を呼び出すキーボードマクロ(*note Keyboard Macros::を参照)を実行 中した場合は_該当しない_ — だけ‘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) 20.5 コマンドループからの情報 ============================= エディターコマンドループは自分自身と実行するコマンドのために、いくつかの Lisp変数にステータス記録を保持します。一般的に‘this-command’と ‘last-command’以外は、Lispプログラム内でこれらの変数を変更するのは良いア イデアではありません。 -- Variable: last-command この変数はコマンドループによって実行された以前のコマンド(前にカレン トだったコマンド)の名前を記録する。値は通常は関数定義をもつシンボル だが、その保証はない。 コマンドがコマンドループからリターンするとき、‘this-command’から値 がコピーされる。ただしそのコマンドが後続のコマンドにたいしてプレフ ィクス引数を指定されたときを除く。 この変数は常にカレント端末にたいしてローカルであり、バッファーロー カルにできない。*note Multiple Terminals::を参照のこと。 -- Variable: real-last-command この変数はEmacsにより‘last-command’と同様にセットアップされるが、 Lispプログラムから決して変更されない。 -- Variable: last-repeatable-command この変数は入力イベントの一部ではない、もっとも最近実行されたコマン ドを格納する。これはコマンド‘repeat’が再実行を試みるコマンドである 。*note (emacs)Repeating::を参照のこと。 -- Variable: this-command この変数はコマンドループにより現在実行中のコマンドの名前を記録する 。‘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’の機能は、わたし たちが正に避けたいと思っていることを行ってしまうでしょう。 -- Variable: this-original-command コマンドのリマップ(*note Remapping Commands::を参照)が発生したとき を除き、これは‘this-command’と同じ値をもつ。リマップが発生すると ‘this-command’は実際に実行されたコマンド、‘this-original-command’は 実行を指定されたが他のコマンドにリマップされたコマンドを与える。 -- Function: this-command-keys この関数は現在のコマンドを呼び出したキーシーケンスと、加えてそのコ マンドにたいするプレフィクス引数を生成した前のコマンドを含む文字列 かベクターをリターンする。‘read-event’を使用するコマンドにより、タ イムアウトせずに読み取られたすべてのイベントが最後に加えられる。 しかしそのコマンドが‘read-key-sequence’を呼び出していたら、最後に読 み取られたキーシーケンスをリターンする。*note Key Sequence Input::を 参照のこと。シーケンス内のすべてのイベントが文字列として適当な文字 なら文字列が値になる。*note Input Events::を参照のこと。 (this-command-keys) ;; これを評価するために‘C-u C-x C-e’を使用すると ⇒ "^U^X^E" -- Function: this-command-keys-vector ‘this-command-keys’と同様だが常にベクターでイベントをリターンするの で、入力イベントを文字列内に格納する複雑さを処理する必要がない (*note Strings of Events::を参照)。 -- Function: clear-this-command-keys &optional keep-record この関数は‘this-command-keys’がリターンするイベントテーブルを空にす る。KEEP-RECORDが‘nil’なら、その後に関数‘recent-keys’(*note Recording Input::を参照)がリターンするレコードも空にする。これは特 定のケースにおいてパスワードを読み取った後、次のコマンドの一部とし て不用意にパスワードがエコーされるのを防ぐために有用である。 -- Variable: last-nonmenu-event この変数はキーシーケンス(マウスメニューからのイベントは勘定しない )の一部として読み取られた最後の入力イベントを保持する。 この変数の1つの使い方は、‘x-popup-menu’にたいしてどこにメニューをポ ップアップすべきか告げる場合である。これは内部的に ‘y-or-n-p’(*note Yes-or-No Queries::を参照)にも使用されている。 -- Variable: last-command-event この変数にはコマンドの一部としてコマンドループに読み取られた最後の 入力イベントがセットされる。この変数は主に‘self-insert-command’内で どの文字が挿入されたか判断するために使用されている。 last-command-event ;; これを評価するために‘C-u C-x C-e’を使用すると ⇒ 5 ‘C-e’のASCIIコードの5が値になる。 -- Variable: last-event-frame この変数は最後の入力イベントが送られたフレームを記録する。これは通 常はそのイベントが生成されたときに選択されていたフレームだが、その フレームの入力が他のフレームにリダイレクトされていたら、そのリダイ レクトされていたフレームが値となる。*note Input Focus::を参照のこと 。 最後のイベントがキーボードマクロに由来する場合、値は‘macro’になる。 20.6 コマンド後のポイントの調整 =============================== プロパティ‘display’や‘composition’をもつテキストや、非表示のテキストシー ケンスの中間でポイント値を表示するのは簡単ではありません。したがってコマ ンドが終了した後にコマンドループにリターンするとき、そのようなシーケンス 中にポイントがあれば、コマンドループは通常ポイントをそのようなシーケンス の端に移動します。 変数‘disable-point-adjustment’をセットすることにより、コマンドはこの 機能を抑制できます: -- Variable: disable-point-adjustment この変数が非‘nil’ならコマンドがコマンドループにリターンするとき、コ マンドループはこれらのテキストプロパティをチェックせず、これらのプ ロパティをもつシーケンスの外にポイントを移動しない。 コマンドループは各コマンドを実行する前にこの変数を‘nil’にセットする ので、あるコマンドがこれをセットしても効果が適用されるのはそのコマ ンドにたいしてだけである。 -- Variable: global-disable-point-adjustment この変数を非‘nil’にセットするとシーケンス外にポイントを移動する、こ れらの機能は完全にオフになる。 20.7 入力イベント ================= Emacsコマンドループは“入力イベント(input events)”のシーケンスを読み取り ます。入力イベントとはキーボードやマウスのアクティビティ、またはEmacsに 送られるシステムイベントを表します。キーボードアクティビティにたいするイ ベントは文字かシンボルです。それ以外のイベントは常にリストになります。こ のセクションでは入力イベントの表現と意味について詳細を説明します。 -- Function: eventp object この関数はOBJECTが入力イベントかイベント型なら非‘nil’をリターンする 。 イベントとイベント型として任意のシンボルが使用されるかもしれないこ とに注意。‘eventp’は、あるシンボルがLispコードによりイベントとして 使用されることを意図しているか否か区別できない。そのかわりにカレン トEmacsセッション内で、そのシンボルが入力として読み取られたイベント 内で実際に使用されているか否かを区別する。シンボルがまだそのように 使用されていなければ‘eventp’は‘nil’をリターンする。 20.7.1 キーボードイベント ------------------------- キーボードから取得できる入力には2つの種類があります。それは通常のキーと ファンクションキーです。通常のキーは文字に対応し、それらが生成するイベン トはLisp内では文字で表現されます。文字イベントのイベント型は文字自身(整 数)です。*note Classifying Events::を参照してください。 入力文字イベントは0から524287までの“基本コード(basic code)”に加えて、 以下の“修飾ビット(modifier bits)”の一部、またはすべてによって構成されま す: meta 文字コードのビット 2**27 はメタキーが押下された状態で文字がタイプさ れたことを示す。 control 文字コードのビット 2**26 は非ASCIIコントロール文字を示す。 ‘C-a’のような非ASCIIコントロール文字は、自身が特別な基本コードをも つため、それらを示すためにEmacsは特別なビットを必要としない。つまり ‘C-a’のコードは単なる1である。 しかし‘%’のような非ASCIIとコントロールを組み合わせてタイプすると取 得される数値は‘%’に 2**26 を加えた値となる(端末が非ASCIIコントロー ル文字をサポートすると仮定する)。 shift 文字コードのビット 2**25 はシフトキーが押下された状態でASCIIコント ロール文字がタイプされたことを示す。 アルファベット文字にたいしては、基本コード自身が大文字か小文字かを 示す。数字と句読点文字にたいしてシフトキーは、異なる基本コードをも つ完全に違う文字を選択する。可能な限りASCII文字として保つために、 Emacsはこれらの文字にたいしてビット 2**25 を使用しない。 しかしASCIIは‘C-A’と‘C-a’を区別する方法を提供しないので、Emacsは ‘C-A’にたいしてビット 2**25 を使用し、‘C-a’には使用しない。 hyper 文字コードのビット 2**24 はハイパーキーが押下された状態で文字がタイ プされたことを示す。 super 文字コードのビット 2**23 はスーパーキーが押下された状態で文字がタイ プされたことを示す。 alt 文字コードのビット 2**22 はアルトキーが押下された状態で文字がタイプ されたことを示す(ほとんどのキーボードでとラベルされたキーは、 実際にはアルトキーではなくメタキーとして扱われる)。 プログラム内での特定のビット数値の記述は避けるのが最善の方法です。文 字の修飾ビットをテストするためには、関数‘event-modifiers’ (*note Classifying Events::を参照)を使用してください。キーバインディングを作成 するときは、修飾ビットつきの文字にたいする読み取り構文を使用できます (‘\C-’、‘\M-’、...など)。‘define-key’でのキーバインディング作成では、文 字を指定するために‘(control hyper ?x)’のようなリストを使用できます(*note Changing Key Bindings::を参照)。関数‘event-convert-list’はそのようなリス トをイベント型に変換します(*note Classifying Events::を参照)。 20.7.2 ファンクションキー ------------------------- ほとんどのキーボードには“ファンクションキー(function keys)”があります。 これは名前や文字以外のシンボルをもつキーです。Emacs Lispではファンクショ ンキーはシンボルとして表現されます。そのシンボル名はファンクションキーの ラベルの小文字です。たとえばとラベルされたキーを押下すると、シンボル ‘f1’で表される入力イベントが生成されます。 ファンクションキーのイベント型はイベントシンボル自身です。*note Classifying Events::を参照してください。 ファンクションキーにたいするシンボルの命名規約には、以下のような特別 なケースがいくつかあります: ‘backspace’、‘tab’、‘newline’、‘return’、‘delete’ これらのキーは、ほとんどのキーボードにおいて特別にキーをもつ、一般 的なASCIIコントロール文字に対応する。 ASCIIでは‘C-i’とは同じ文字である。端末がこれらを区別できるなら Emacsは前者を整数の9、後者をシンボル‘tab’で表現することによって Lispプログラムにこれらの違いを伝える。 ほとんどの場合はこれらの2つを区別するのは役に立たない。そのため ‘local-function-key-map’ (*note Translation Keymaps::を参照)は ‘tab’を9にマップするようセットアップされている。したがって文字コー ド9(文字‘C-i’)へのキーバインディングは‘tab’にも適用される。このグル ープ内の他のシンボルも同様である。関数‘read-char’がこれらのイベント を文字に変換する場合も同様である。 ASCIIではは実際は‘C-h’である。しかし‘backspace’は文字コード 8()ではなく、文字コード127()に変換される。ほとんどのユーザ ーにとってこれは好ましいだろう。 ‘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は通常こ れらを同じような名前の非キーパッドキーに変換する。 ファンクションキーにたいしても修飾キーを使用できます。シンボル名のプレフィクスとしてこ れらを表します: ‘A-’ アルト修飾。 ‘C-’ コントロール修飾。 ‘H-’ ハイパー修飾。 ‘M-’ メタ修飾。 ‘S-’ シフト修飾。 ‘s-’ スーパー修飾。 したがってを押下した場合のキーにたいするシンボルは‘M-f3’に なります。複雑のプレフィクスを使用する場合には、アルファベット順の記述を 推奨します。とはいえキーバインディングが修飾されたファンクションキーを探 す際に引数の順序は関係ありません。 20.7.3 マウスイベント --------------------- Emacsは4つの種類のマウスイベントをサポートします。それはクリックイベント 、ドラッグイベント、ボタンダウンイベント、モーションイベントです。すべて のマウスイベントはリストで表現されます。このリストのCARはイベント型です 。イベント型はどのマウスボタンが関与するのか、それにたいしてどの修飾キー が使用されたかを示します。イベント型によりダブル、あるいはトリプルでボタ ンが押されたかを区別することもできます(*note Repeat Events::を参照)。残 りのリスト要素は位置と時間の情報を提供します。 キーの照合ではイベント型だけが問題になります。2つのイベントが同じコマ ンドを実行するには同じイベント型が必要です。実行されるコマンドは interactiveのコード‘e’を使用して、これらのイベントの完全な値にアクセスで きます。*note Interactive Codes::を参照してください。 マウスイベントで開始されたキーシーケンスはカレントバッファーではなく 、マウスのあったウィンドウ内のバッファーのキーマップを使用して読み取られ ます。これはウィンドウ内でクリックすることによりそのウィンドウやそのウィ ンドウのバッファーが選択されることを意味しません。つまりそれは完全にその キーシーケンスのコマンドバインディングの制御下にあるのです。 20.7.4 クリックイベント ----------------------- ユーザーが同じ場所でマウスボタンを押してからリリース(release: 離す)する と、“click”イベントが生成されます。すべてのマウスクリックイベントは同じ フォーマットを共有します: (EVENT-TYPE POSITION CLICK-COUNT) EVENT-TYPE これはマウスボタンが使用されたことを示す。これはシンボル‘mouse-1’、 ‘mouse-2’、...のうちのいずれかで、マウスボタンは左から右に番号が付 される。 ファンクションキーにたいして行うのと同様にアルト、コントロール、ハ イパー、メタ、シフト、スーパーの修飾にたいしてプレフィクス‘A-’、 ‘C-’、‘H-’、‘M-’、‘S-’、‘s-’も使用できる。 このシンボルはイベントのイベント型としての役割りももつ。イベントの キーバインディングはこれらの型により示される。したがって‘mouse-1’に たいするキーバインディングが存在すれば、そのバインディングは EVENT-TYPEが‘mouse-1’であるようなすべてのイベントに適用されるだろう 。 POSITION これはマウスクリックがどこで発生したかを表す“マウス位置リスト(mouse position list)”である。詳細は以下を参照のこと。 CLICK-COUNT これは同じマウスボタンを素早く繰り返し押下したときの回数である。 *note Repeat Events::を参照のこと。 クリックイベントのPOSITIONスロット内にあるマウス位置リストの内容にア クセスするためには、一般的には*note Accessing Mouse::に記述された関数を 使用するべきです。このリストの明示的なフォーマットはどこでクリックが発生 したかに依存します。テキストエリア、モードライン、ヘッダーライン、フリン ジ、マージンエリアでのクリックにたいしてマウス位置リストは以下のフォーマ ットをもちます (WINDOW POS-OR-AREA (X . Y) TIMESTAMP OBJECT TEXT-POS (COL . ROW) IMAGE (DX . DY) (WIDTH . HEIGHT)) 以下はこれらのリスト要素がもつ意味です: WINDOW クリックが発生したウィンドウ。 POS-OR-AREA テキストエリア内でクリックされた文字のバッファー位置。またはテキス トエリア外がクリックされたなら、クリックが発生したウィンドウエリア 。これはシンボル‘mode-line’、‘header-line’、‘vertical-line’、 ‘left-margin’、‘right-margin’、‘left-fringe’、‘right-fringe’のいず れか。 特別なケースの1つとしてPOS-OR-AREAが単なるシンボルではなく、(上記シ ンボルのいずれか1つの)シンボルを含むリストのような場合がある。これ はEmacsにより登録されたイベントにたいする、イマジナリープレフィクス キー(imaginary prefix key)の後に発生する。*note Key Sequence Input::を参照のこと。 X, Y クリックの相対ピクセル座標(relative pixel coordinates)。あるウィン ドウのテキストエリア内でのクリックにたいする座標原点‘(0 . 0)’は、テ キストエリアの左上隅となる。*note Window Sizes::を参照のこと。モー ドラインやヘッダーライン内でのクリックにたいする座標原点は、そのウ ィンドウ自身の左上隅となる。フリンジ、マージン、垂直ボーダー (vertical border)ではXは有意なデータをもたない。フリンジ、マージン ではYはヘッダーラインの最下端からの相対位置である。すべてのケースに おいてXとYの座標はそれぞれ右方向と下方向で増加する。 TIMESTAMP そのイベントが発生した時刻をシステム依存の初期時刻(initial time)か らの経過ミリ秒で表す整数。 OBJECT クリック位置に文字列タイプのテキストプロパティが存在しなければ ‘nil’、存在すれば(STRING . STRING-POS)形式のコンスセル: STRING クリックされた文字列。すべてのテキストプロパティを含む。 STRING-POS クリックが発生した文字列内の位置。 TEXT-POS マージンエリアやフリンジにたいするクリックでは、そのウィンドウ内の 対応する行内の最初の可視な文字のバッファー位置となる。モードライン やヘッダーラインにたいするクリックでは‘nil’。他のイベントにたいして はクリックされたバッファーのクリックされた最寄りの位置となる。 COL, ROW これらはX、Yの位置にあるグリフ(gliph)の実際の行と列の座標数値である 。行Xがその行の実際のテキストの最後の列を超えるなら、COLはデフォル トの文字幅をもつ仮想的な追加列数を加えた値が報告される。そのウィン ドウがヘッダーラインをもつなら、行0はヘッダーラインとなり、ヘッダー ラインをもたなければテキストエリアの上端ラインが行0となる。ウィンド ウのテキストエリアのクリックにたいしては、テキストエリアの左端列が 列0となり、モードラインまたはヘッダーラインのクリックにたいしてはそ のラインの左端が列0となる。フリンジまたは垂直ボーダーのクリックにた いしては、これらは有意なデータをもたない。マージンのクリックにたい しては、COLはマージンエリアの左端、ROWはマージンエリアの上端から測 られる。 IMAGE これはクリックが発生した場所のイメージオブジェクトである。クリック された場所にイメージが存在しなければ‘nil’、イメージがクリックされた ら‘find-image’によりリターンされるイメージオブジェクト。 DX, DY これらはOBJECTの左上隅‘(0 . 0)’からの相対的ピクセル座標である。 OBJECTが‘nil’なら、クリックされた文字グリフの左上隅からの相対座標。 WIDTH, HEIGHT これらはOBJECTのピクセル幅とピクセル高さであり、OBJECTが‘nil’ならク リックされた文字グリフのピクセル幅とピクセル高さ。 スクロールバーへのクリックにたいして、POSITIONは以下の形式をもちます: (WINDOW AREA (PORTION . WHOLE) TIMESTAMP PART) WINDOW スクロールバーがクリックされたウィンドウ。 AREA これはシンボル‘vertical-scroll-bar’である。 PORTION スクロールバーの上端からクリック位置までのピクセル数。GTK+を含むい くつかのツールキットでは、Emacsがこれらのデータを抽出できないので値 は常に‘0’。 WHOLE スクロールバーの全長のピクセル数。GTK+を含むいくつかのツールキット では、Emacsがこれらのデータを抽出できないので値は常に‘0’。 TIMESTAMP イベントが発生したミリ秒時刻。GTK+を含むいくつかのツールキットでは 、Emacsがこれらのデータを抽出できないので値は常に‘0’。 PART クリックが発生したスクロールバー部分。これはシンボル‘handle’(スクロ ールバーのハンドル)、‘above-handle’(ハンドルの上側エリア)、 ‘below-handle’(ハンドルの下側エリア)、‘up’(スクロールバー端の上矢印 )、‘down’(スクロールバー端の下矢印)のいずれか。 20.7.5 ドラッグイベント ----------------------- Emacsでは特別なことをしなくてもドラッグイベントを取得できます。“ドラッグ イベント(drag event)”はユーザーがマウスボタンを押下して、ボタンをリリー スする前にマウスを異なる文字位置に移動すると毎回発生します。すべてのマウ スイベントと同じように、ドラッグイベントはLispではリストで表現されます。 このリストは以下のように開始マウス位置と最終位置ぼ両方を記録します: (EVENT-TYPE (WINDOW1 START-POSITION) (WINDOW2 END-POSITION)) ドラッグイベントにたいしては、シンボルEVENT-TYPEの名前にプレフィクス ‘drag-’が含まれます。たとえばボタン2を押下したままマウスをドラッグすると ‘drag-mouse-2’イベントが生成されます。このイベントの2つ目と3つ目の要素は 、マウス位置リスト(*note Click Events::を参照)としてドラッグの開始と終了 の位置を与えます。任意のマウスイベントの2つ目の要素に同じ方法でアクセス できます。しかしドラッグイベントは最初に選択されていたフレームの境界外で 終了するかもしれません。この場合のには3つ目の要素の位置リストに、ウィン ドウのかわりにそのフレームが含まれます。 ‘drag-’プレフィクスは、その後に‘C-’や‘M-’のような修飾キープレフィクス が続きます。 ‘read-key-sequence’がキーバインディングをもたず、対応するクリックイベ ントにキーバインディングがあるようなドラッグイベントを受け取ると、この関 数はそのドラッグイベントをドラッグ開始位置でのクリックイベントに変更しま す。これはもし望まなければクリックイベントとドラッグイベントを区別する必 要がないことを意味します。 20.7.6 ボタンダウンイベント --------------------------- クリックイベントとドラッグイベントは、ユーザーがマウスボタンをリリースし たときに発生します。ボタンがリリースされるまでクリックとドラッグを区別す ることはできないので、リリース前にイベントが発生することはありません。 ボタンが押下されたらすぐに何か処理したいなら、“ボタンダウン (button-down)”イベントを処理する必要があります(1)。これらはEVENT-TYPEの シンボル名に‘down-’が含まれることを除き、クリックイベントとまったく同じ ようなリストにより表現されます。‘down-’プレフィクスの後には‘C-’や‘M-’の ような修飾キープレフィクスが続きます。 関数‘read-key-sequence’はコマンドバインディングをもたないボタンダウン イベントを無視します。したがってEmacsコマンドループもこれらを無視します 。これはボタンダウンイベントで何かしたい場合以外は、ボタンダウンイベント の定義について配慮する必要がないことを意味します。ボタンダウンイベントを 定義する通常の理由は、ボタンがリリースされるまで(モーションイベントを読 み取ることにより)マウスモーションを追跡できるからです。*note Motion Events::を参照してください。 ---------- Footnotes ---------- (1) ボタンダウンはドラッグの保守的なアンチテーゼです。 訳注: 原文は“Button-down is the conservative antithesis of drag.”。 ちなみにIT用語で使用される前は"button-down"はボタンダウンシャツを表すと ともに「保守的、堅苦しい」という意味もあり、一方の"drag"はIT用語として使 用される前から「引っ張る、引きずる」という意味で用いられてきましたが「本 来は異性が着る洋服」という意味もあります。 20.7.7 リピートイベント ----------------------- マウスを移動せずに同じマウスボタンを素早く2回以上連続して押下すると、 Emacsは2回目とそれ以降の押下にたいして特別な“リピート(repeat)”マウスイベ ントを生成します。 もっとも一般的なリピートイベントは“ダブルクリック(double-click)”イベ ントです。Emacsはボタンを2回クリックしたときにダブルクリックイベントを生 成します。このイベントは、(すべてのクリックイベントが通常そうであるよう に)ボタンをリリースしたときに発生します。 ダブルクリックイベントのイベント型にはプレフィクス‘double-’が含まれま す。したがってを押しながら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連)、...等のイベントにた いして個別のイベント型をもちません。しかしボタンが何回押下されたかを正確 に調べるためにイベントリストを調べることができます。 -- Function: event-click-count event この関数はEVENTを誘因した連続するボタン押下の回数をリターンする。 EVENTがダブルダウン、ダブルクリック、ダブルドラッグなら値は2である 。EVENTがトリプルイベントなら値は3以上になる。EVENTが(リピートイベ ントではない)通常のマウスイベントなら値は1。 -- User Option: double-click-fuzz リピートイベントを生成するためには、ほぼ同じスクリーン位置で連続で マウスボタンを押下しなければならない。‘double-click-fuzz’の値はダブ ルクリックを生成するために連続する2回のクリック間で、マウスが移動 (水平と垂直)するかもしれない最大ピクセル数を指定する。 この変数はドラッグとみなされるマウスモーションの閾値でもある。 -- User Option: double-click-time リピートイベントを生成するためには、連続するボタン押下のミリ秒間隔 が‘double-click-time’の値より小さくなければならない。 ‘double-click-time’を‘nil’にセットすると複数回クリック検知が完全に 無効になる。‘t’にセットすると時間制限が取り除かれる。その場合は Emacsは位置だけで複数回のクリックを検知する。 20.7.8 モーションイベント ------------------------- Emacsは、ボタンアクティビティが何もないマウスのモーション(motion: 動き )を記述する“マウスモーション(mouse motion)”イベントを生成するときがあり ます。マウスモーションイベントは以下のようなリストによって表現されます: (mouse-movement POSITION) POSITIONはマウスカーソルのカレント位置を指定するマウス位置リスト(*note Click Events::を参照)です。ドラッグイベントの終了位置のように、この位置 リストは最初に選択されていた境界外の位置を表すかもしれず、その場合にはそ のフレーム内のその位置のウィンドウが含まれます。 スペシャルフォーム‘track-mouse’は、ボタン内でのモーションイベントの生 成を有効にします。‘track-mouse’フォームの外側では、Emacsはマウスの単なる モーションにたいするイベントは生成せず、これらのイベントは発生しません。 *note Mouse Tracking::を参照してください。 20.7.9 フォーカスイベント ------------------------- ウィンドウシステムはユーザーにたいしてどのウィンドウがキーボード入力を受 け取るか制御するための一般的な方法を提供します。このウィンドウ選択は“フ ォーカス(focus)”と呼ばれます。Emacsのフレームを切り替えるためにユーザー が何かを行うと、それは“フォーカスイベント(focus event)”を生成します。フ ォーカスイベントの通常の定義はグローバルキーマップ内にあり、ユーザーが期 待するようにEmacsで新たなフレームを選択するためのものです。*note Input Focus::ではフォーカスイベントに関連するフックも説明しています。 フォーカスイベントは以下のようにLispのリストで表現されます: (switch-frame NEW-FRAME) ここでNEW-FRAMEは切り替え先のフレームです。 Xウィンドウマネージャーには、あるウィンドウにマウスを移動するだけで、 そこにフォーカスされるようにセットアップするものがいくつかあります。通常 は他の種類の入力が到着するまで、Lispプログラムがフォーカスの変更を知る必 要はありません。Emacsはユーザーが新たなフレーム内で実際にキーボードのキ ーをタイプするかマウスボタンを押下したときしか、フォーカスイベントを生成 しません。つまりフレーム間でマウスを移動させても、フォーカスイベントは生 成されません。 キーシーケンスの途中におけるフォーカスイベントは、そのシーケンスを誤 ったものにするかもしれません。そのためEmacsは決してキーシーケンスの途中 でフォーカスイベントを生成しません。ユーザーがキーシーケンスの途中(つま りプレフィクス引数の後)でフォーカスを変更すると、複数イベントキーシーケ ンスの前か後にフォーカスイベントが到着するように、Emacsはフォーカスイベ ントを記録しておきます。 20.7.10 その他のシステムイベント -------------------------------- 他にもシステム内での出来事を表現するイベント型がいくつかあります。 ‘(delete-frame (FRAME))’ このイベントの種類はユーザーがウィンドウマネージャーに特定のウィン ドウを削除するコマンドを与えたことを示し、Emacsのフレームにたいして 発生する。 ‘フレーム削除(delete-frame)’イベントの標準的な定義ではFRAMEが削除さ れる。 ‘(iconify-frame (FRAME))’ このイベントの種類はウィンドウマネージャーを使用してユーザーが FRAMEをアイコン化したことを示す。標準的な定義は‘ignore’。これはその フレームがすでにアイコン化されているので、Emacsが行う必要のことは何 もないからである。このイベント型の目的は、望むならこのようなイベン トの追跡を可能にしておくためである。 ‘(make-frame-visible (FRAME))’ このイベントの種類はウィンドウマネージャーを使用してユーザーが FRAMEを非アイコン化したことを示す。標準的な定義は‘ignore’。これは、 そのフレームがすでに可視化されているので、Emacsが行う必要のことは何 もないからである。 ‘(wheel-up POSITION)’ ‘(wheel-down POSITION)’ この種類のイベントはマウスホイールを移動したことにより発生する。 POSITION要素はそのイベント発生時のマウスカーソル位置を指定するマウ ス位置リスト(*note Click Events::を参照)。 この種類のイベントはある種のシステムでのみ発生する。いくつかのシス テムでは、かわりに‘mouse-4’と‘mouse-5’が使用される。可搬性のあるコ ードとするためには、マウスホイールにたいしてどのイベント型が期待さ れるかを決定するために‘mwheel.el’内で定義されている変数 ‘mouse-wheel-up-event’と‘mouse-wheel-down-event’を使用すること。 ‘(drag-n-drop POSITION FILES)’ この種類のイベントはEmacs外部アプリケーション内でファイルグループが 選択されて、それがEmacsフレーム内にドラッグアンドドロップされたとき に発生する。 要素POSITIONは、そのイベント位置を記述しマウスクリックイベントで使 用されるフォーマット(*note Click Events::を参照)と同じ。要素FILESは ドラッグアンドドロップされたファイル名のリスト。通常はそれらのファ イルをvisitすることによってこのイベントは処理される。 この種類のイベントは現在のところある種のシステムでのみ生成される。 ‘help-echo’ この種類のイベントは、テキストプロパティ‘help-echo’をもつバッファー テキスト部分上にマウスポインターが移動したときに生成される。生成さ れるイベントは以下の形式をもつ: (help-echo FRAME HELP WINDOW OBJECT POS) イベントパラメーターの正確な意味とヘルプテキストを表示するためにこ れらのパラメーターを使用する方法は、*note Text help-echo::で説明さ れている。 ‘sigusr1’ ‘sigusr2’ これらのイベントはEmacsプロセスがシグナル‘SIGUSR1’や‘SIGUSR2’を受け 取ったときに生成される。シグナルは追加情報を運搬しないので追加デー タは含まれない。これらのシグナルはデバッグに有用(*note Error Debugging::を参照)。 ユーザーシグナルをcatchするためには、‘special-event-map’ (*note Active Keymaps::を参照)内で対応するイベントにバインドする。そのコマ ンドは引数なしで呼び出され、‘last-input-event’内の特定のシグナルイ ベントが利用できる。たとえば: (defun sigusr-handler () (interactive) (message "Caught signal %S" last-input-event)) (define-key special-event-map [sigusr1] 'sigusr-handler) シグナルハンドラーをテストするために、自身でEmacsにシグナルを送信で きる: (signal-process (emacs-pid) 'sigusr1) ‘language-change’ この種類のイベントはMS-Windows上で入力言語が変更されたときに生成さ れる。これは通常はキーボードキーが異なる言語の文字でEmacsに送られる ことを意味する。生成されるイベントは以下の形式をもつ: (language-change FRAME CODEPAGE LANGUAGE-ID) ここでFRAMEは言語が変更されたときカレントだったフレーム、CODEPAGEは 新たなコードページ番号(codepage number)、LANGUAGE-IDは新たな入力言 語の数値IDである。CODEPAGEに対応するコーディングシステム(*note Coding Systems::を参照)は、‘cpCODEPAGE’か‘windows-CODEPAGE’。 LANGUAGE-IDを文字列に変更する(たとえば‘set-language-environment’の ようなさまざまな言語依存機能にたいしこれを使用する)には、以下のよう に‘w32-get-locale-info’関数を使用する: ;; 英語にたいする"ENU"のような言語の省略形を取得する (w32-get-locale-info language-id) ;; "English (United States)"のような ;; その言語の完全な英語名を取得する (w32-get-locale-info language-id 4097) ;; その言語の完全なローカライズ名を取得する (w32-get-locale-info language-id t) キーシーケンスの途中、つまりプレフィクスキーの後にこれらのイベントの 1つが到着すると、複数イベントキー内ではなくその前か後にそのイベントが到 着するようにEmacsはそのイベントを記録する。 20.7.11 イベントの例 -------------------- ユーザーが同じ場所でマウス左ボタンを押して離すと、それは以下のようなイベ ントシーケンスを生成します: (down-mouse-1 (# 2613 (0 . 38) -864320)) (mouse-1 (# 2613 (0 . 38) -864180)) コントロールキーを押したままユーザーがマウス第2ボタンを押してマウスを ある行から次の行へドラッグすると、以下のような2つのイベントが生成されま す: (C-down-mouse-2 (# 3440 (0 . 27) -731219)) (C-drag-mouse-2 (# 3440 (0 . 27) -731219) (# 3510 (0 . 28) -729648)) メタキーとシフトキーを押したままユーザーがそのウィンドウのモードライ ン上でマウス第2ボタンを押して他ウィンドウへマウスをドラッグすると、以下 のようなイベントのペアが生成されます: (M-S-down-mouse-2 (# mode-line (33 . 31) -457844)) (M-S-drag-mouse-2 (# mode-line (33 . 31) -457844) (# 161 (33 . 3) -453816)) 全画面表示されていないフレームに入力フォーカスがあってユーザーがマウ スをそのフレームのスコープ外へマウスを移動すると、スペシャルフォーム ‘track-mouse’内では以下のようなイベントが生成されます: (mouse-movement (# nil (563 . 205) 532301936)) SIGUSR1シグナルを処理するためにはインタラクティブ関数を定義して、それ を‘signal usr1’イベントシーケンスにバインドします: (defun usr1-handler () (interactive) (message "Got USR1 signal")) (global-set-key [signal usr1] 'usr1-handler) 20.7.12 イベントの分類 ---------------------- すべてのイベントは“イベント型(event type)”をもっています。イベント型はキ ーバインディング目的でイベントをクラス分けします。キーボードイベントにた いするイベント型はイベント値と等しく、したがって文字のイベント型は文字、 ファンクションキーシンボルのイベント型はそのシンボル自身になります。リス トであるようなイベントのイベント型は、そのリストのCAR内のシンボルです。 したがってイベント型は常にシンボルか文字です。 同じ型の2つのイベントはキーバインディングに関する限りは同じものです。 したがってそれらは常に同じコマンドを実行します。これらが同じことを行う必 要があるという意味ではありませんが、イベント全体を調べてから何を行うか決 定するコマンドもいくつかあります。たとえばバッファー内でどこに作用するか 決定するためにマウスイベントの場所を使用するコマンドもいくつかあります。 広範なイベントのクラス分けが役に立つときもあります。たとえば他の修飾 キーやマウスボタンが使用されたかとは無関係に、キーとともに呼び出さ れたイベントを尋ねたいと思うかもしれません。 関数‘event-modifiers’や‘event-basic-type’は、そのような情報を手軽に取 得するために提供されています。 -- Function: event-modifiers event この関数は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’は含まれない。 -- Function: event-basic-type event この関数は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 -- Function: mouse-movement-p object OBJECTがマウス移動イベントなら、この関数は非‘nil’をリターンする。 *note Motion Events::を参照のこと。 -- Function: event-convert-list list この関数は修飾子名リストと基本イベント型(basic event type)を、それ らすべてを指定するイベント型に変換する。基本イベント型はそのリスト の最後の要素でなければならない。たとえば、 (event-convert-list '(control ?a)) ⇒ 1 (event-convert-list '(control meta ?a)) ⇒ -134217727 (event-convert-list '(control super f1)) ⇒ C-s-f1 20.7.13 マウスイベントへのアクセス ---------------------------------- このセクションではマウスボタンやモーションイベント内のデータアクセスに役 立つ関数を説明します。同じ関数を使用してキーボードイベントデータにもアク セスできますが、キーボードイベントに不適切なデータ要素は0か‘nil’になりま す。 以下の2つの関数は、マウスイベントの位置を指定するマウス位置リスト (*note Click Events::を参照)をリターンします。 -- Function: event-start event これはEVENTの開始位置をリターンする。 EVENTがクリックイベントかボタンダウンイベントなら、この関数はそのイ ベントの位置をリターンする。EVENTがドラッグイベントなら、そのドラッ グの開始位置をリターンする。 -- Function: event-end event これはEVENTの終了位置をリターンする。 EVENTがドラッグイベントなら、この関数はユーザーがマウスボタンをリリ ースした位置をリターンする。EVENTがクリックイベントかボタンダウンイ ベントなら、値はそのイベント固有の開始位置となる。 -- Function: posnp object この関数はOBJECTが*note Click Events::に記述されたいずれかのフォー マットのマウス位置リストなら非‘nil’、それ以外では‘nil’をリターンす る。 以下の関数は引数にマウス位置リストを受け取り、そのリストのさまざまな 部分をリターンします: -- Function: posn-window position POSITIONがあったウィンドウをリターンする。POSITIONが最初にイベント があったフレームの外部の位置を表す場合には、かわりにそのフレームを リターンする。 -- Function: posn-area position POSITION内に記録されたウィンドウエリアをリターンする。そのウィンド ウのテキストエリアでイベントが発生したときは‘nil’、それ以外ではイベ ントがどこで発生したかを識別するシンボルをリターンする。 -- Function: posn-point position POSITION内のバッファー位置をリターンする。ウィンドウのテキストエリ ア、マージンエリア、フリンジでイベントが発生したときはバッファー位 置を識別する整数値、それ以外では値は未定義。 -- Function: posn-x-y 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))))) -- Function: posn-col-row position この関数はPOSITION内のバッファー位置にたいして推定される列と行を含 んだコンスセル‘(COL . ROW)’をリターンする。リターン値はPOSITIONにた いするXとYの値より計算され、そのフレームのデフォルト文字幅とデフォ ルト行高(行間スペースを含む)の単位で与えられる(そのため実際の文字サ イズが非デフォルト値なら、実際の行と列はこれらの計算された値とは異 なるかもしれない)。 ROWはそのテキストエリアの上端から数えられることに注意。POSITIONによ り与えられるウィンドウがヘッダーライン(*note Header Lines::を参照 )をもつなら、そのヘッダーラインはROWの数に_含まれない_。 -- Function: posn-actual-col-row position POSITION内の実際の行と列をコンスセル‘(COL . ROW)’でリターンする。値 はPOSITIONで与えられるウィンドウの実際の行と列。*note Click Events::を参照のこと。POSITIONが実際のポジション値を含まなければ、 この関数は‘nil’をリターンする。この場合にはおおよその値を取得するた めに‘posn-col-row’を使用できる。 この関数はタブ文字やイメージによるビジュアル列数のように、ディスプ レイ上の文字のビジュアル幅を意味しない。標準的な文字単位の座標が必 要なら、かわりに‘posn-col-row’を使用すること。 -- Function: posn-string position POSITION内の文字列オブジェクトを‘nil’、またはコンスセル‘(STRING . STRING-POS)’でリターンする。 -- Function: posn-image position POSITION内のイメージオブジェクトを‘nil’、または‘(image ...)’でリタ ーンする。 -- Function: posn-object position POSITION内のイメージオブジェクト、または文字列オブジェクトを‘nil’、 イメージ‘(image ...)’、またはコンスセル‘(STRING . STRING-POS)’でリ ターンする。 -- Function: posn-object-x-y position POSITION内のオブジェクトの左上隅からのピクセル単位のxy座標をコンス セル‘(DX . DY)’でリターンする。POSITIONがバッファーテキストなら、そ の位置にもっとも近いバッファーテキストの相対位置をリターンする。 -- Function: posn-object-width-height position POSITION内のオブジェクトのピクセル幅とピクセル高さをコンスセル ‘(WIDTH . HEIGHT)’でリターンする。POSITIONがバッファー位置なら、そ の位置の文字のサイズをリターンする。 -- Function: posn-timestamp position POSITION内のタイムスタンプをリターンする。これはミリ秒で表されたイ ベント発生時刻である。 以下の関数は与えられた特定のバッファー、またはスクリーン位置によって 位置リストを計算します。上述の関数でこの位置リスト内のデータにアクセスで きます。 -- Function: posn-at-point &optional pos window この関数はWINDOW内の位置POSにたいする位置リストをリターンする。 POSのデフォルトはWINDOW内のポイント、WINDOWのデフォルトは選択された ウィンドウ。 WINDOW内でPOSが不可視なら、‘posn-at-point’は‘nil’をリターンする。 -- Function: posn-at-x-y x y &optional frame-or-window whole この関数は指定されたフレームかウィンドウFRAME-OR-WINDOW(デフォルト は選択されたウィンドウ)内のピクセル座標XとYに対応する位置情報をリタ ーンする。XとYは、使用されたフレームかウィンドウにたいする相対座標 である。WHOLEが‘nil’なら、座標はウィンドウのテキストエリアにたいす る相対座標、それ以外ではスクロールバー、マージン、フリンジを含むウ ィンドウエリア全体にたいする相対座標。 20.7.14 スクロールバーイベントへのアクセス ------------------------------------------ 以下の関数はスクロールバーイベントの解析に役立ちます。 -- Function: scroll-bar-event-ratio event この関数はスクロールバーで発生したスクロールバーイベントの位置の垂 直位置の割り合いをリターンする。値は位置の割り合いを表す2つの整数を 含むコンスセル‘(PORTION . WHOLE)’。 -- Function: scroll-bar-scale ratio total この関数は、(実質的には)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つ の整数をもつことを思い出してほしい。 20.7.15 文字列内へのキーボードイベントの配置 -------------------------------------------- 文字列が使用される場所のほとんどにおいて、わたしたちはテキスト文字を含む もの、つまりバッファーやファイル内で見出すのと同種のものとして文字列を概 念化します。Lispプログラムはときおりキーボード文字、たとえばキーシーケン スやキーボードマクロ定義かもしれないキーボード文字を概念的に含んだ文字列 を使用します。しかし文字列内へのキーボード文字の格納は、歴史的な互換性の 理由から複雑な問題であり、常に可能なわけではありません。 新たに記述するプログラムでは文字列内にキーボードイベントを格納しない ことによって、これらの複雑さを扱うことを避けるよう推奨します。以下はこれ を行う方法です: • ‘lookup-key’と‘define-key’の引数として使用するのでなければ、キーシ ーケンスにたいして文字列のかわりにベクターを使用する。たとえば ‘read-key-sequence’のかわりに‘read-key-sequence-vector’、 ‘this-command-keys’のかわりに‘this-command-keys-vector’を使用できる 。 • メタ文字を含むキーシーケンス定数を記述する際には、たとえそれを直接 ‘define-key’に渡す場合でもベクターを使用する。 • 文字列かもしれないキーシーケンスの内容を調べる必要があるときは、そ れをリストに変換するために最初に‘listify-key-sequence’ (*note Event Input Misc::を参照)を使用する。 複雑さはキーボード入力に含まれるかもしれない修飾ビットに起因します。 メタ修飾以外の修飾ビットは文字列に含めることができず、メタ文字も特別な場 合だけ許容されます。 GNU Emacsの初期のバージョンでは、メタ文字を128から255のコードで表して いました。その頃は基本的な文字コードの範囲は0から127だったので、すべての キーボード文字を文字列内に適合させることができました。Lispプログラムの多 くは、特に‘define-key’やその種の関数の引数として文字列定数内にメタ文字を 意味する‘\M-’を使用していて、キーシーケンスとイベントシーケンスは常に文 字列として表現されていました。 127超のより大きい基本文字コードと追加の修飾ビットにたいするサポートを 加えたとき、わたしたちはメタ文字の表現を変更する必要がありました。現在で は文字のメタ修飾を表すフラグは 2**27 であり、そのような値は文字列内に含 めることができません。 プログラムで文字列定数内の‘\M-’をサポートするために、文字列内に特定の メタ文字を含めるための特別なルールがあります。以下は入力文字シーケンスと して文字列を解釈するためのルールです: • キーボード文字の値の範囲が0から127なら、文字列を変更せずに含めるこ とができる。 • これらの 2**27 から 2**27+127, までの文字のコード範囲にあるメタ修飾 された変種も文字列に含めることができるが、それらの数値を変更しなけ ればならない。値が128から255の範囲となるように、ビット 2**7 のかわ りにビット 2**27 をセットしなければならない。ユニバイト文字列だけが これらの文字を含むことができる。 • 265を超える非ASCII文字はマルチバイト文字に含めることができる。 • その他のキーボード文字イベントは文字列に適合させられない。これには 128から255の範囲のキーボードイベントが含まれる。 キーボード入力文字の文字列定数を構築する‘read-key-sequence’のような関 数は、イベントが文字列内に適合しないときは文字列のかわりにベクターを構築 するというルールにしたがいます。 文字列内で入力構文‘\M-’を使用すると、それは128から255の範囲のコード、 つまり対応するキーボードイベントを文字列内に配すために変更するとき取得さ れるのと同じコードが生成されます。したがって文字列内のメタイベントは、そ れが文字列内にどのように配置されたかと無関係に一貫して機能します。 しかしほとんどのプログラムはこのセクションの冒頭の推奨にしたがって、 これらの問題を避けたほうがよいでしょう。 20.8 入力の読み取り =================== エディターコマンドループはキーシーケンスの読み取りに関数 ‘read-key-sequence’を使用して、この関数は‘read-event’を使用します。イベ ント入力にたいしてこれらの関数、およびその他の関数がLisp関数から利用でき ます。*note Temporary Displays::の‘momentary-string-display’、および *note Waiting::の‘sit-for’も参照してください。端末の入力モードの制御、お よび端末入力のデバッグに関する関数と変数については、*note Terminal Input::を参照してください。 高レベル入力機能については*note Minibuffers::を参照してください。 20.8.1 キーシーケンス入力 ------------------------- コマンドループは‘read-key-sequence’を呼び出すことによって、キーシーケン スの入力を一度に読み取ります。Lisp関数もこの関数を呼び出すことができます 。たとえば‘describe-key’はキーを記述するためにこの関数を使用します。 -- Function: read-key-sequence prompt &optional continue-echo dont-downcase-last switch-frame-ok command-loop この関数はキーシーケンスを読み取って、それを文字列かベクターでリタ ーンする。この関数は完全なキーシーケンスに蓄積されるまで、つまりカ レントでアクティブなキーマップを使用してプレフィクスなしでコマンド を指定するのに十分なキーシーケンスとなるまでイベントの読み取りを継 続する(マウスイベントで始まるキーシーケンスは、カレントバッファーで はなくマウスのあったウィンドウ内のバッファーのキーマップを使用して 読み取られることを思い出してほしい)。 イベントがすべて文字で、それらがすべて文字列に適合すれば、 ‘read-key-sequence’は文字列をリターンする(*note Strings of Events::を参照)。それ以外なら文字、シンボル、リストなどすべての種類 のイベントを保持できるベクターをリターンする。文字列やベクターの要 素は、キーシーケンス内のイベント。 キーシーケンスの読み取りには、そのイベントを変換するさまざまな方法 が含まれる。*note Translation Keymaps::を参照のこと。 引数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’をセッ トしない。*note Quitting::を参照のこと。 -- Function: read-key-sequence-vector prompt &optional continue-echo dont-downcase-last switch-frame-ok command-loop これは‘read-key-sequence’と同様だが、キーシーケンスを常にベクターで リターンして、文字列では決してリターンしない点が異なる。*note Strings of Events::を参照のこと。 入力文字が大文字(またはシフト修飾をもつ)で、キーバインディングをもた ないものの、等価な小文字はキーバインディングをもつ場合、 ‘read-key-sequence’はその文字を小文字に変換します。‘lookup-key’はこの方 法によるcase変換を行わないことに注意してください。 入力を読み取った結果が“シフト変換(shift-translation)”されていたら、 Emacsは変数‘this-command-keys-shift-translated’に非‘nil’値をセットします 。シフト変換されたキーにより呼びだされたときに挙動を変更する必要がある Lispプログラムは、この変数を調べることができます。たとえば関数 ‘handle-shift-selection’はリージョンをアクティブ、または非アクティブにす るかを判断するためにこの変数の値を調べます(*note handle-shift-selection: The Mark.を参照)。 関数‘read-key-sequence’もマウスイベントのいくつかを変換します。これは バインドされていないドラッグイベントをクリックイベントに変換して、バイン ドされていないボタンダウンイベントを完全に破棄します。さらにフォーカスイ ベントとさまざまなウィンドウイベントの再配置も行うため、これらのイベント はキーシーケンス中に他のイベントととも出現することは決してありません。 モードラインやスクロールバーのようなウィンドウの特別な箇所でマウスイ ベントが発生したとき、そのイベント型は特別なことは何も示さずにマウスボタ ンと修飾キーの組み合わせを通常表すのと同じシンボルになります。ウィンドウ の箇所についての情報はイベント内の別のどこか、すなわち座標に保持されてい ます。しかし‘read-key-sequence’はこの情報を仮想的なプレフィクスキーに変 換します。これらはすべてシンボルであり‘header-line’、 ‘horizontal-scroll-bar’、‘menu-bar’、‘mode-line’、‘vertical-line’、 ‘vertical-scroll-bar’です。これらの仮想的なプレフィクスキーを使用してキ ーシーケンスを定義することにより、ウィンドウの特別な部分でのカウスクリッ クにたいして意味を定義できます。 たとえば‘read-key-sequence’を呼び出した後にそのウィンドウのモードライ ンをマウスでクリックすると、以下のように2つのマウスイベントが取得されま す: (read-key-sequence "Click on the mode line: ") ⇒ [mode-line (mouse-1 (# mode-line (40 . 63) 5959987))] -- Variable: num-input-keys この変数の値は、そのEmacsセッション内で処理されたキーシーケンスの数 である。これには端末からのキーシーケンスと、実行されるキーボードマ クロによって読み取られたキーシーケンスが含まれる。 20.8.2 単一イベントの読み取り ----------------------------- ‘read-event’、‘read-char’、‘read-char-exclusive’はコマンド入力にたいする もっとも低レベルの関数です。 -- Function: read-event &optional prompt inherit-input-method seconds この関数はコマンド入力の次のイベントを読み取ってリターンする。必要 ならイベントが利用可能になるまで待機する。 リターンされるイベントはユーザーからの直接のイベントかもしれないし 、キーボードマクロからのイベントかもしれない。イベントはキーボード の入力コーディングシステム(*note Terminal I/O Encoding::を参照)によ りデコードされていない。 オプション引数PROMPTが非‘nil’なら、それはエコーエリアにプロンプトと して表示される文字列である。‘nil’なら‘read-event’は入力待ちを示すメ ッセージを何も表示せず、エコーを行うことによってプロンプトの代用と する。エコーに表示される記述はカレントコマンドに至ったイベントや読 み取られたイベント。*note The Echo Area::を参照のこと。 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’ (*note Idle Timers::を参照) — を実行できる。 しかしSECONDSが非‘nil’なら、非アイドル状態は変更されずに残る。 ‘read-event’が呼び出されたときEmacsが非アイドルだったら、 ‘read-event’の処理を通じて非アイドルのままとなる。Emacsがアイドルだ った場合(これはアイドルタイマー内部からその呼び出しが行われた場合に 起こり得る)は、アイドルのままとまる。 ‘read-event’がヘルプ文字として定義されたイベントを取得すると、ある 状況においては‘read-event’がリターンせずに直接イベントを処理するこ とがある。*note Help Functions::を参照のこと。その他の“スペシャルイ ベント(special events)”(*note Special Events::を参照)と呼ばれる特定 のイベントも‘read-event’で直接処理される。 以下は‘read-event’を呼び出してから右矢印キーを押下したとき何が起こ るかの例: (read-event) ⇒ right -- Function: read-char &optional prompt inherit-input-method seconds この関数はコマンド入力の文字を読み取ってそれをリターンする。ユーザ ーが文字以外(たとえばマウスクリックやファンクションキー)のイベント を生成すると、‘read-char’はエラーをシグナルする。引数は ‘read-event’と同じように機能する。 1つ目の例ではユーザーは文字‘1’(ASCIIコード49)をタイプしている。2つ 目の例では‘eval-expression’を使用してミニバッファーから ‘read-char’を呼び出すキーボード定義を示している。‘read-char’はキー ボードマクロの直後の文字‘1’を読み取る。その後で‘eval-expression’は リターン値をエコーエリアに表示する。 (read-char) ⇒ 49 ;; ‘M-:’を使用して以下を評価するものとする (symbol-function 'foo) ⇒ "^[:(read-char)^M1" (execute-kbd-macro 'foo) ⊣ 49 ⇒ nil -- Function: read-char-exclusive &optional prompt inherit-input-method seconds この関数はコマンド入力の文字を読み取ってそれをリターンする。ユーザ ーが文字以外のイベントを生成すると、‘read-char-exclusive’はそれを無 視して文字を取得するまで他のイベントを読み取る。引数は ‘read-event’と同じように機能する。 上記の関数でquitを抑制するものはありません。 -- Variable: num-nonmacro-input-events この変数は端末から受信した入力イベント(キーボードマクロにより生成さ れたイベントは勘定しない)の総数を保持する。 ‘read-key-sequence’と異なり関数‘read-event’、‘read-char’、 ‘read-char-exclusive’は*note Translation Keymaps::で説明した変換を行わな いことを強調しておきます。単一キー読み取りでこれらの変換を行いたければ関 数‘read-key’を使用してください。 -- Function: read-key &optional prompt この関数は1つのキーを読み取る。これは‘read-key-sequence’と ‘read-event’の間の中間的な関数である。‘read-key-sequence’と異なるの は、キーシーケンスではなく単一キーを読み取ることである。 ‘read-event’と異なるのは、rawイベントをリターンせずに ‘input-decode-map’、‘local-function-key-map’、‘key-translation-map’ (*note Translation Keymaps::を参照)に合わせてデコードと変換を行うこ とである。 引数PROMPTはプロンプトとしてエコーエリアに表示する文字列で、‘nil’は プロンプトを表示しないことを意味する。 -- Function: read-char-choice prompt chars &optional inhibit-quit この関数は1つの文字を読み取ってリターンするために‘read-key’を使用す る。これはCHARS(許容される文字のリスト)のメンバー以外の入力を無視す る。オプションで有効な入力を待つ間のquitイベントも無視する。 ‘read-char-choice’呼び出しの間に‘help-form’ (*note Help Functions::を参照)を非‘nil’値にバインドすると、‘help-char’の押下に より‘help-form’が評価され結果が表示される。その後で有効な入力文字、 またはキーボードquitの待機を継続する。 20.8.3 入力イベントの変更と変換 ------------------------------- Emacsは‘extra-keyboard-modifiers’に合わせて読み取ったすべてのイベントを 変更して‘read-event’からリターンする前に、(もし適切なら )‘keyboard-translate-table’を通じてそれを変換します。 -- Variable: extra-keyboard-modifiers この変数はLispプログラムにキーボード上の修飾キーを“押下”させる。値 は文字。文字の修飾子だけが対象となる。ユーザーがキーボードのキーを 押下するたびに、その修飾キーがすでに押下されたかのように処理される 。たとえば‘extra-keyboard-modifiers’を‘?\C-\M-a’にバインドすると、 このバインディングのスコープ内にある間、すべてのキーボード入力文字 はコントロール修飾とメタ修飾を適用されるだろう。文字‘?\C-@’は0と等 価なので、この目的にたいしてはコントロール文字として勘定されないが 、修飾無しの文字として扱われる。したがって ‘extra-keyboard-modifiers’を0にセットすることによって、すべての修飾 をキャンセルできる。 ウィンドウシステムを利用していれば、この方法によってプログラムが任 意の修飾キーを押下できる。それ以外ではのキーだけを仮想 的に押下できる。 この変数は実際にキーボードに由来するイベントだけに適用され、マウス イベントやその他のイベントには効果がないことに注意。 -- Variable: keyboard-translate-table この端末ローカルな変数はキーボード文字にたいする変換テーブルである 。これによりコマンドバインディングを変更することなく、キーボード上 のキーを再配置できる。値は通常は文字テーブル、または‘nil’(文字列か ベクターも指定できるが時代遅れとされている)。 ‘keyboard-translate-table’が文字テーブル(*note Char-Tables::を参照 )なら、キーボードから読み取られた各文字はその文字テーブルを調べる。 非‘nil’の値が見つかったら実際の入力文字のかわりにそれを使用する。 この変換は文字が端末から読み取られた後、最初に発生することに注意。 ‘recent-keys’のような記録保持機能や文字を記録するdribbleファイルは 、この変換の後に処理される。 さらにこの変換は入力メソッド(*note Input Methods::を参照)に文字を提 供する前に行われることにも注意。入力メソッド処理の後に文字を変換し たいなら‘translation-table-for-input’ (*note Translation of Characters::を参照)を使用すること。 -- Function: keyboard-translate from to この関数は文字コードFROMを文字コードTOに変換するために ‘keyboard-translate-table’を変更する。 必要ならキーボード変換テーブ ルを作成する。 以下は‘C-x’でカット、‘C-’でコピー、‘C-v’でペーストを処理するように ‘keyboard-translate-table’を使用する例: (keyboard-translate ?\C-x 'control-x) (keyboard-translate ?\C-c 'control-c) (keyboard-translate ?\C-v 'control-v) (global-set-key [control-x] 'kill-region) (global-set-key [control-c] 'kill-ring-save) (global-set-key [control-v] 'yank) 拡張ASCII入力をサポートするグラフィカルな端末上では、シフトキーとともに タイプすることによって、標準的なEmacsにおける意味をこれらの文字から依然 として取得することが可能です。これはキーボード変換が関与する文字とは異な りますが、それらは通常と同じ意味をもちます。 ‘read-key-sequence’のレベルでイベントシーケンスを変換するメカニズムに ついては、*note Translation Keymaps::を参照してください。 20.8.4 入力メソッドの呼び出し ----------------------------- イベント読み取り関数は、もしあればカレント入力メソッドを呼び出します (*note Input Methods::を参照)。‘input-method-function’の値が非‘nil’なら 関数を指定します。‘read-event’が修飾ビットのないプリント文字(を含む )を読み取ったときは、その文字を引数としてその関数を呼び出します。 -- Variable: input-method-function これが非‘nil’なら、その値はカレントの入力メソッド関数を指定する。 *警告:* この変数を‘let’でバインドしてはならない。この変数はバッファ ーローカルであることが多く、入力の前後(これは正にあなたがバインド _するであろう_タイミングである)でバインドすると、Emacsが待機中に非 同期にバッファーを切り替えた場合に、誤ったバッファーに値がリストア されてしまう。 入力メソッド関数は入力として使用されるイベントのリストをリターンする べきです(このリストが‘nil’なら、それは入力がないことを意味するので ‘read-event’は他のイベントを待機する)。これらのイベントは ‘unread-command-events’ (*note Event Input Misc::を参照)内のイベントの前 に処理されます。入力メソッドによってリターンされるイベントは、たとえそれ らが修飾ビットのないプリント文字であっても再度入力メソッドに渡されること はありません。 入力メソッド関数が‘read-event’や‘read-key-sequence’を呼び出したら、再 帰を防ぐために最初に‘input-method-function’を‘nil’にバインドするべきです 。 キーシーケンスの2つ目および後続のイベントを読み取るときは、入力メソッ ド関数は呼び出されません。したがってそれらの文字は入力メソッドの処理対象 外です。入力メソッド関数は‘overriding-local-map’と ‘overriding-terminal-local-map’の値をテストするべきです。これらの変数の いずれかが非‘nil’なら入力メソッドは引数をリストにputして、それ以上の処理 を行わずにそのリストをリターンするべきです。 20.8.5 クォートされた文字の入力 ------------------------------- ユーザーが手軽にコントロール文字やメタ文字、リテラルや8進文字コードを指 定できるように文字の指定をもとめることができます。コマンド ‘quoted-insert’はこの関数を使用しています。 -- Function: read-quoted-char &optional prompt この関数は‘read-char’と同様だが、最初に読み取った文字が8進数(0–7)な ら任意の個数の8進数(8進数以外の文字を見つけた時点でストップする)を 読み取って、その文字コードにより表される文字をリターンする。8進シー ケンスを終端させた文字がならそれは無視される。他の終端文字はこ の関数がリターンした後の入力として使用される。 最初の文字の読み取り時にはquitは抑制されるので、ユーザーはは‘C-g’を 入力できる。*note Quitting::を参照のこと。 PROMPTが与えられたら、それはユーザーへのプロンプトに使用する文字列 を指定する。プロンプト文字列はその後に1つの‘-’とともに常にエコーエ リアに表示される。 以下の例ではユーザーは8進数の177(10進数の127)をタイプしている。 (read-quoted-char "What character") ---------- Echo Area ---------- What character 1 7 7- ---------- Echo Area ---------- ⇒ 127 20.8.6 その他のイベント入力の機能 --------------------------------- このセクションではイベントを使い切らずに先読みする方法と、入力の保留や保 留の破棄の方法について説明します。*note Reading a Password::の関数 ‘read-passwd’も参照してください。 -- Variable: unread-command-events この変数はコマンド入力として読み取り待機中のイベントのリストを保持 する。イベントはこのリスト内の出現順に使用され、使用されるごとにリ ストから取り除かれる。 ある関数がイベントを読み取ってそれを使用するかどうか決定する場合が いくつかあるためにこの変数が必要になる。この変数にイベントを格納す るとコマンドループやコマンド入力を読み取る関数によってイベントは通 常のように処理される。 たとえば数引数を実装する関数は、任意の個数の数字を読み取る。数字イ ベントが見つからないとき、関数はそのイベントを読み戻す(unread)ので 、そのイベントはコマンドループによって通常通り読み取られることがで きる。同様にインクリメンタル検索は、検索において特別な意味をもたな いイベントを読み戻すためにこの機能を使用する。なぜならそれらのイベ ントは検索をexitして、通常どおり実行されるべきだからである。 ‘unread-command-events’にイベントを置くためにキーシーケンスからイベ ントを抽出するには、‘listify-key-sequence’ (以下参照)を使用するのが 簡単で信頼のおける方法である。 もっとも最近読み戻したイベントが最初に再読み取りされるように、通常 はこのリストの先頭にイベントを追加する。 このリストから読み取ったイベントは、通常はそのイベントが最初に読み 取られたときにすでに一度追加されたときのように、カレントコマンドの キーシーケンスに(たとえば‘this-command-keys’にリターンされたときの ように)追加される。フォーム‘(t . EVENT)’の要素はカレントコマンドの キーシーケンスにEVENTを強制的に追加する。 -- Function: listify-key-sequence key この関数は文字列かベクターのKEYを‘unread-command-events’にputするこ とができる個別のイベントのリストに変換する。 -- Function: input-pending-p &optional check-timers この関数はコマンド入力がカレントで読み取り可能かどうか判断する。入 力が利用可能なら‘t’、それ以外は‘nil’を即座にリターンする。非常に稀 だが入力が利用できないときは‘t’をリターンする。 オプション引数CHECK-TIMERSが非‘nil’なら、Emacsは準備ができるとすべ てのタイマーを実行する。*note Timers::を参照のこと。 -- Variable: last-input-event この変数は最後に読み取られた端末入力イベントがコマンドの一部なのか 、それとも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 -- Macro: while-no-input body... この構文は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))) -- Function: discard-input この関数は端末入力バッファーの内容を破棄して定義処理中かもしれない キーボードマクロをキャンセルする。この関数は‘nil’をリターンする。 以下の例ではフォームの評価開始直後にユーザーが数字か文字をタイプす るかもしれない。‘sleep-for’がスリープを終えた後に‘discard-input’は スリープ中にタイプされた文字を破棄する。 (progn (sleep-for 2) (discard-input)) ⇒ nil 20.9 スペシャルイベント ======================= 特定の“スペシャルイベント(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’ (*note Active Keymaps::を参照)の中にあります。 20.10 時間の経過や入力の待機 ============================ 待機関数(wait function)は特定の時間が経過するか、入力があるまで待機する ようにデザインされています。たとえば計算の途中でユーザーがディスプレイを 閲覧できるように一時停止したいときがあるかもしれません。‘sit-for’は一時 停止して画面を更新して、‘sleep-for’は画面を更新せずに一時停止して入力が 到着したら即座にリターンします。 -- Function: sit-for seconds &optional nodisp この関数は、(ユーザーからの保留中入力がければ)再描画を行ってから SECONDS秒、または入力が利用可能になるまで待機する。‘sit-for’の通常 の目的は、表示したテキストをユーザーが読み取る時間を与えるためであ る。入力が何も到着せず(*note Event Input Misc::を参照)、時間をフル に待機したら‘t’、それ以外は‘nil’が値となる。 引数SECONDSは整数である必要はない。浮動小数点数なら‘sit-for’は少数 点数の秒を待機する。整数の秒だけをサポートするいくつかのシステムで はSECONDSは切り捨てられる。 保留中の入力が存在しなければ、式‘(sit-for 0)’は遅延なしで再描画をリ クエストする‘(redisplay)’と等価である。*note Forcing Redisplay::を 参照のこと。 NODISPが非‘nil’なら‘sit-for’は再描画を行わないが、それでも入力が利 用可能になると(またはタイムアウト時間が経過すると)即座にリターンす る。 batchモード(*note Batch Mode::を参照)では、たとえ標準入力ディスクリ プタからの入力でも割り込みできない。これは以下で説明する ‘sleep-for’でも同様。 ‘(sit-for SECONDS MILLISEC NODISP)’のように3つの引数で‘sit-for’を呼 び出すことも可能だが、時代遅れだと考えられている。 -- Function: sleep-for seconds &optional millisec この関数は表示を更新せず単にSECONDS秒の間一時停止する。これは利用可 能な入力に注意を払わない。この関数は‘nil’をリターンする。 引数SECONDSは整数である必要はない。浮動小数点数なら‘sleep-for’は少 数点数の秒を待機する。整数の秒だけをサポートするいくつかのシステム ではSECONDSは切り捨てられる。 オプション引数MILLISECはミリ秒単位で追加の待機時間を指定する。これ はSECONDSで指定された時間に追加される。システムが小数点数の秒数をサ ポートしなければ、非0のMILLISECを指定するとエラーとなる。 遅延を保証したければ‘sleep-for’を使用すること。 現在時刻を取得する関数については*note Time of Day::を参照してください 。 20.11 quit ========== 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)) -- Variable: quit-flag この変数が非‘nil’で‘inhibit-quit’が‘nil’なら、Emacsは即座にquitする 。‘C-g’をタイプすると通常は‘inhibit-quit’とは無関係に‘quit-flag’を 非‘nil’にセットする。 -- Variable: inhibit-quit この変数は‘quit-flag’が非‘nil’にセットされているときEmacsがquitする かどうかを決定する。‘inhibit-quit’が非‘nil’なら‘quit-flag’に特に効 果はない。 -- Macro: with-local-quit body... このマクロは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’にバイドされている場所で役に立つ。 -- Command: keyboard-quit この関数は‘(signal 'quit nil)’によって‘quit’条件をシグナルする。こ れはquitが行うことと同じ(*note Errors::の‘signal’を参照)。 quitに使用する‘C-g’以外の文字を指定できます。*note Input Modes::内の 関数‘set-input-mode’を参照してください。 20.12 プレフィクスコマンド引数 ============================== ほとんどのEmacsコマンドは“プレフィクス引数(prefix argument)”を使用できま す。プレフィクス引数はコマンド自身の前に数字を指定するものです(プレフィ クス引数とプレフィクスキーを混同しないこと)。プレフィクス引数は常に値に より表され、‘nil’のときはカレントでプレフィクス引数が存在しないことを意 味します。すべてのコマンドはプレフィクス引数を使用するか、あるいは無視し ます。 プレフィクス引数には2つの表現があります。それは“raw(生の、加工してい ない、原料のままの、未加工の)”と“数字(numeric)”です。エディターコマンド ループは内部的にraw表現を使用し、Lisp変数もその情報を格納するのにこれを 使用しますが、コマンドはいずれかの表現を要求できます。 以下は利用できるrawプレフィクス引数の値です: • ‘nil’はプレフィクス引数がないことを意味する。これの数値的な値は1だ が多くのコマンドは‘nil’と整数1を区別する。 • 整数はそれ自身を意味する。 • 整数の要素を1つもつリスト。プレフィクス引数のこの形式は、1つまたは 数字無しの連続する‘C-u’の結果である。数値的な値はリスト内の整数だが 、そのようなリストと単独の整数を区別するコマンドがいくつかある。 • シンボル‘-’。これは後に数字をともなわない‘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と数 値のどちらの表現を使用するかを指定します(*note Using Interactive::を参照 )。そのかわりに関数は変数‘current-prefix-arg’内のプレフィクス引数の値を 直接調べるかもしれませんが、これは明確さで劣っています。 -- Function: prefix-numeric-value arg この関数はARGの有効なrawプレフィクス引数の数値的な意味をリターンす る。引数はシンボル、数字、またはリストかもしれない。これが‘nil’なら 値1、‘-’なら−1がリターンされる。これが数字なら、その数字がリターン される。リスト(数字であること)なら、そのリストのCARがリターンされる 。 -- Variable: current-prefix-arg この変数は_カレント_のコマンドにたいするrawプレフィクス引数を保持す る。コマンドはこの変数を直接調べるかもしれないが、この変数にたいす るアクセスには通常は‘(interactive "P")’を使用する。 -- Variable: prefix-arg この変数の値は_次_の編集コマンドにたいするrawプレフィクス引数である 。後続のコマンドにたいしてプレフィクス引数を指定する ‘universal-argument’のようなコマンドは、この変数をセットすることに よって機能する。 -- Variable: last-prefix-arg このrawプレフィクス引数の値は、前のコマンドにより使用された値である 。 以下のコマンドは、後続のコマンドにたいしてプレフィクス引数をセットア ップするために存在します。これらを他の用途で呼び出さないでください。 -- Command: universal-argument このコマンドは入力を読み取って、後続のコマンドにたいするプレフィク ス引数を指定する。何をしているかわかっているのでなければ、このコマ ンドを自分で呼び出してはならない。 -- Command: digit-argument arg このコマンドは、後続のコマンドにたいしてプレフィクス引数を追加する 。引数ARGはこのコマンドの前のrawプレフィクス引数であり、これはプレ フィクス引数を更新するために使用される。何をしているかわかっている のでなければ、このコマンドを自分で呼び出してはならない。 -- Command: negative-argument arg このコマンドは、次のコマンドにたいして数引数を追加する。引数ARGはこ のコマンドの前のrawプレフィクス引数であり、この値に負の符号が付され て新しいプレフィクス引数を構築する。何をしているかわかっているので なければ、このコマンドを自分で呼び出してはならない。 20.13 再帰編集 ============== Emacsはスタートアップ時に、自動的にEmacsコマンドループに移行します。この トップレベルのコマンドループ呼び出しは決してexitすることなく、Emacs実行 中は実行を継続します。Lispプログラムもコマンドループを呼び出せます。これ は複数のコマンドループを活性化するので、“再帰編集(recursive editing)”と 呼ばれています。再帰編集レベルは呼び出したコマンドが何であれそれをサスペ ンドして、そのコマンドを再開する前にユーザーが任意の編集を行うことを可能 にする効果をもちます。 再帰編集の間に利用可能なコマンドは、トップレベルの編集ループ内で利用 できるコマンドと同じでありキーマップ内で定義されます。数少ない特別なコマ ンドだけが再帰編集レベルをexitして、他のコマンドは再帰編集レベルが終了し たときに再帰編集レベルからリターンします(exitするための特別なコマンドは 常に利用できるが再帰編集が行われていないときは何も行わない)。 再帰コマンドループを含むすべてのコマンドループは、コマンドループから 実行されたコマンド内のエラーによってそのループをexitしないように、汎用エ ラーハンドラーをセットアップします。 ミニバッファー入力は特殊な再帰編集です。これはミニバッファーとミニバ ッファーウィンドウの表示を有効にするなどの欠点をもちますが、それはあなた が思うより少ないでしょう。ミニバッファー内では特定のキーの振る舞いが異な りますが、これははミニバッファーのローカルマップによるものです。ウィンド ウを切り替えれば通常のEmacsコマンドを使用できます。 再帰編集レベルを呼び出すには関数‘recursive-edit’を呼び出します。この 関数はコマンドループを含んでいます。さらに‘exit’をthrowすることにより再 帰編集レベルのexitを可能にする、タグ‘exit’をともなった‘catch’呼び出しも 含んでいます(*note Catch and Throw::を参照)。‘t’以外の値をthrowすると、 ‘recursive-edit’は通常はそれを呼び出した関数にリターンします。コマンド ‘C-M-c’ (‘exit-recursive-edit’)がこれを行います。値‘t’をthrowすることに よって‘recursive-edit’がquitされるので、1レベル上位のコマンドループに制 御がリターンされます。これは“abort”と呼ばれ、 ‘C-]’(‘abort-recursive-edit’)がこれを行います。 ほとんどのアプリケーションはミニバッファー使用の一部として使用する場 合を除き、再帰編集を使用するべきではありません。カレントバッファーのメジ ャーモードから特殊なメジャーモードに一時的に変更する場合に、そのモードに 戻るコマンドをもつ必要があるときは、通常は再帰編集のほうが便利です (Rmailの‘e’コマンドはこのテクニックを使用)。またはユーザーが新たなバッフ ァーの特殊なモードで、異なるテキストを再帰的に編集・作成・選択できるよう にしたい場合が該当します。このモードでは処理を完了させるコマンドを定義し て前のバッファーに戻ります(Rmailの‘m’コマンドはこれを使用)。 再帰編集はデバッグに便利です。一種のブレークポイントとして関数定義内 に‘debug’を挿入して、関数がそこに達したときにその箇所を調べることができ ます。‘debug’は再帰編集を呼び出しますが、デバッガのその他の機能も提供し ます。 ‘query-replace’内で‘C-r’をタイプしたときや‘C-x q’ (‘kbd-macro-query’)を使用したときにも再帰編集レベルが使用されます。 -- Command: recursive-edit この関数はエディターコマンドループを呼び出す。これはユーザーに編集 を開始させるために、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 -- Command: exit-recursive-edit この関数は最内の再帰編集(ミニバッファー入力を含む)からexitする。関 数の実質的な定義は‘(throw 'exit nil)’。 -- Command: abort-recursive-edit この関数は再帰編集をexitした後に‘quit’をシグナルすることにより、最 内の再帰編集(ミニバッファー入力を含む)を要求したコマンドをabortする 。関数の実質的な定義は‘(throw 'exit t)’。*note Quitting::を参照のこ と。 -- Command: top-level この関数はすべての再帰編集レベルをexitする。これはすべての計算を直 接抜け出してメインのコマンドループに戻って値をリターンしない。 -- Function: recursion-depth この関数は再帰編集のカレントの深さをリターンする。アクティブな再帰 編集が存在しなければ0をリターンする。 20.14 コマンドの無効化 ====================== “コマンドを無効化(disabling a command)”とは、それを実行可能にする前にユ ーザーによる確認を要求するようにコマンドをマークすることです。無効化は初 めてのユーザーを混乱させるかもしれないコマンドにたいして、意図せずそのコ マンドが使用されるのを防ぐために使用されます。 コマンド無効化の低レベルにおけるメカニズムは、そのコマンドにたいする Lispシンボルの‘disabled’プロパティに非‘nil’をputすることです。これらのプ ロパティは、通常はユーザーのinitファイル(*note Init File::を参照)で以下 のようなLisp式によりセットアップされます: (put 'upcase-region 'disabled t) いくつかのコマンドにたいしては、これらのプロパティがデフォルトで与えられ ています(これらを削除したければinitファイルで削除できる)。 ‘disabled’プロパティの値が文字列なら、そのコマンドが無効化されている ことを告げるメッセージにその文字列が含まれます。たとえば: (put 'delete-region 'disabled "この方法で削除されたテキストはyankで戻せない!\n") 無効化されたコマンドをインタラクティブに呼び出したときに何が起こるか の詳細は、*note (emacs)Disabling::を参照してください。コマンドの無効化は 、それをLispプログラムから関数として呼び出したときは効果がありません。 -- Command: enable-command command その時点から特別な確認なしでCOMMAND(シンボル)が実行されることを許す 。さらにユーザーのinitファイル(*note Init File::を参照)も修正するの で将来のセッションにもこれが適用される。 -- Command: disable-command command その時点からCOMMAND(シンボル)の実行に特別な確認を要求する。さらにユ ーザーのinitファイル(*note Init File::を参照)も修正するので将来のセ ッションにもこれが適用される。 -- Variable: disabled-command-function この変数の値は関数であること。ユーザーが無効化されたコマンドを呼び 出したときは無効化されたコマンドのかわりにその関数が呼び出される。 そのコマンドを実行するためにユーザーが何のキーをタイプしたかを判断 するために‘this-command-keys’を使用して、そのコマンド自体を探すこと ができる。 値は‘nil’もあり得る。その場合にはたとえ無効化されたコマンドでも、す べてのコマンドが通常のように機能する。 デフォルトでは値はユーザーに処理を行うかどうかを尋ねる関数。 20.15 コマンドのヒストリー ========================== コマンドループは複雑なコマンドを手軽に繰り返せるように、すでに実行された 複雑なコマンドのヒストリー(history: 履歴)を保持します。“複雑なコマンド (complex command)”とは、ミニバッファーを使用してinteractive引数を読み取 るコマンドです。これには‘M-x’コマンド、‘M-:’コマンド、および ‘interactive’指定によりミニバッファーから引数を読み取るすべてのコマンド が含まれます。コマンド自身の実行の間に明示的にミニバッファーを使用するも のは、複雑なコマンドとは判断されません。 -- Variable: command-history この変数の値は最近実行された複雑なコマンドのリストであり、それぞれ が評価されるべきフォームとして表現される。このリストは編集セッショ ンの間、すべての複雑なコマンドを蓄積するが、最大サイズ(*note Minibuffer History::を参照)に達したときは、もっとも古い要素が削除さ れて新たな要素が追加される。 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’はユーザー マニュアルに説明されています(*note (emacs)Repetition::を参照)。ミニバッ ファー内では通常のミニバッファーヒストリーコマンドが利用できます。 20.16 キーボードマクロ ====================== “キーボードマクロ(keyboard macro)”はコマンドとして考えることが可能な入力 イベントの記録されたシーケンスであり、キー定義によって作成されます。キー ボードマクロのLisp表現はイベントを含む文字列かベクターです。キーボードマ クロとLispマクロ(*note Macros::を参照)を混同しないでください。 -- Function: execute-kbd-macro kbdmacro &optional count loopfunc この関数はイベントシーケンスとしてKBDMACROを実行する。KBDMACROが文 字列かベクターなら、たとえそれがユーザーによる入力であっても、その 中のイベントは忠実に実行される。シーケンスは単一のキーシーケンスで あることを_要求されない_。キーボードマクロ定義は、通常は複数のキー シーケンスを結合して構成される。 KBDMACROがシンボルなら、そのシンボルの関数定義はKBDMACROの箇所に使 用される。それが別のシンボルならこのプロセスを繰り返す。最終的に結 果は文字列かベクターになる。結果がシンボル、文字列、ベクターでなけ ればエラーがシグナルされる。 引数COUNTは繰り返すカウントであり、KBDMACROがその回数実行される。 COUNTが省略または‘nil’なら1回実行される。0ならKBDMACROはエラーに遭 遇するか検索が失敗するまで何度も実行される。 LOOPFUNCが非‘nil’なら、それはマクロの繰り返しごとに呼び出される引数 なしの関数である。LOOPFUNCが‘nil’をリターンするとマクロの実行が停止 する。 ‘execute-kbd-macro’の使用例は*note Reading One Event::を参照のこと 。 -- Variable: executing-kbd-macro この変数はカレントで実行中のキーボードマクロを定義する文字列かベク ター。‘nil’ならカレントで実行中のマクロは存在しない。マクロの実行に より実行されたときに異なる振る舞いをするように、コマンドはこの変数 をテストできる。この変数を自分でセットしてはならない。 -- Variable: defining-kbd-macro この変数はキーボードマクロの定義中のときだけ非‘nil’である。マクロ定 義中の間は異なる振る舞いをするように、コマンドはこの変数をテストで きる。既存のマクロ定義に追加する間、値は‘append’になる。コマンド ‘start-kbd-macro’、‘kmacro-start-macro’、‘end-kbd-macro’はこの変数 をセットする。この変数を自分でセットしてはならない。 この変数は常にカレント端末にたいしてローカルであり、バッファーロー カルにできない。*note Multiple Terminals::を参照のこと。 -- Variable: last-kbd-macro この変数はもっとも最近定義されたキーボードマクロの定義である。値は 文字列、ベクター、または‘nil’。 この変数は常にカレント端末にたいしてローカルであり、バッファーロー カルにできない。*note Multiple Terminals::を参照のこと。 -- Variable: kbd-macro-termination-hook これはキーボードマクロが終了したときに実行されるノーマルフックであ り、何がキーボードマクロを終了させたか(マクロの最後に到達したのか、 あるいはエラーにより最後到達する前に終了したのか)は問わない。 21 キーマップ ************* 入力イベントのコマンドバインディングは“キーマップ(keymap)”と呼ばれるデー タ構造に記録されます。キーマップ内の各エントリーは個別のイベント型(他の キーマップ、またはコマンド)に関連づけ(または“バインド”)されます。イベン ト型がキーマップにバインドされていれば、そのキーマップは次の入力イベント を調べるために使用されます。これはコマンドが見つかるまで継続されます。こ のプロセス全体を“キールックアップ(key lookup: キーの照合)”と呼びます。 21.1 キーシーケンス =================== “キーシーケンス(key sequence)”、短くは“キー(key)”とは1つの単位を形成する 1つ以上の入力イベントのシーケンスです。入力イベントには文字、ファンクシ ョンキー、マウスアクション、または‘iconify-frame’のようなEmacs外部のシス テムイベントが含まれます(*note Input Events::を参照)。キーシーケンスにた いするEmacs Lispの表現は文字列かベクターです。特に明記しない限り、引数と してキーシーケンスを受け取るEmacs Lisp関数は両方の表現を処理することがで きます。 文字列表現ではたとえば‘"a"’は‘a’、‘"2"’は‘2’を表すといったように、英 数字はその文字自身を意味します。コントロール文字イベントは部分文字列 ‘"\C-"’、メタ文字は‘"\M-"’によりプレフィクスされます。たとえば‘"\C-x"’は キー‘C-x’を表します。それらに加えてなどのイベ ントはそれぞれ‘"\t"’、‘"\r"’、‘"\e"’、‘"\d"’で表されます。複雑なキーシー ケンスの文字列表現はイベント成分の文字列表現を結合したものです。したがっ て‘"\C-xl"’はキーシーケンス‘C-x l’を表します。 キーシーケンスにはファンクションキー、マウスボタンイベント、システム イベント、または‘C-=’や‘H-a’のような文字列で表現できない非ASCII文字が含 まれます。これらはベクターとして表現する必要があります。 ベクター表現ではベクターの各要素は1つの入力イベントをイベントのLisp形 式で表します。*note Input Events::を参照してください。たとえばベクター ‘[?\C-x ?l]’はキーシーケンス‘C-x l’を表します。 キーシーケンスを文字列やベクターによる表現で記述する例は、*note (emacs)Init Rebinding::を参照してください。 -- Function: kbd keyseq-text この関数はテキストKEYSEQ-TEXT(文字列定数)をキーシーケンス(文字列か ベクターの定数)に変換する。KEYSEQ-TEXTの内容は‘C-x C-k ’ (‘kmacro-edit-macro’)コマンドにより呼び出されたバッファー内と同じ構 文を使用するべきである。特にファンクションキーの名前は‘<...>’で囲ま なければならない。*note (emacs)Edit Keyboard Macro::を参照のこと。 (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 " SPC") ⇒ [f1 32] (kbd "C-M-") ⇒ [C-M-down] 21.2 キーマップの基礎 ===================== キーマップはさまざまなキーシーケンスにたいして“キーバインディング(key binding)”を指定するLispデータ構造です。 1つのキーマップが、個々のイベントにたいする定義を直接指定します。単一 のイベントでキーシーケンスが構成されるとき、そのキーシーケンスのキーマッ プ内でのバインディングは、そのイベントにたいするそのキーマップの定義です 。それより長いキーシーケンスのバインディングは対話的プロセスによって見つ け出されます。まず最初にイベント(それ自身がキーマップでなければならない )の定義を探します。そして次にそのキーマップ内で2つ目のイベントを探すとい ったように、そのキーシーケンス内のすべてのイベントが処理されるまで、これ を続けます。 あるキーシーケンスのバインディングがキーマップであるような場合、わた したちはそのキーシーケンスを“プレフィクスキー(prefix key)”と呼び、それ以 外の場合には(それ以上イベントを追加できないので)“コンプリートキー (complete keyl”と呼んでいます。バインディングが‘nil’の場合、わたしたちは そのキーを“未定義(undefined)”と呼びます。‘C-c’、‘C-x’、‘C-x 4’などはプレ フィクスキーの例です。‘X’、、‘C-x 4 C-f’などは定義されたコンプリー トキーの例です。‘C-x C-g’や‘C-c 3’などは未定義なコンプリートキーの例です 。詳細は*note Prefix Keys::を参照してください。 キーシーケンスのバインディングを見つけ出すルールは、(最後のイベントの 前までに見つかる)中間的なバインディングがすべてキーマップであると仮定し ます。もしそうでなければ、そのイベントシーケンスは単位を形成せず、実際の 単一キーシーケンスではありません。言い換えると任意の有効なキーシーケンス から1つ以上のイベントを取り除くと、常にプレフィクスキーにならなければな りません。たとえば‘C-f C-n’はキーシーケンスではありません。‘C-f’はプレフ ィクスキーではないので、‘C-f’で始まるこれより長いシーケンスは、キーシー ケンスではあり得ないからです。 利用可能な複数イベントキーシーケンスのセットは、プレフィクスキーにた いするバインディングに依存します。したがってこれはキーマップが異なれば異 なるかもしれず、バインディングが変更されたときに変更されるかもしれません 。しかし単一イベントキーシーケンスは整合性において任意のプレフィクスキー に依存しないので、常に単一のキーシーケンスです。 常に複数のプライマリーキーマップ(primary keymap: 主キーマップ)がアク ティブであり、これらはキーバインディングを見つけるために使用されます。す べてのバッファーで共有される“グローバルキーマップ(global map)”というキー マップが存在します。“ローカルキーマップ(local keymap)”は通常は特定のメジ ャーモードに関連します。そして0個以上の“マイナーモードキーマップ(minor mode keymap)”はカレントで有効なマイナーモードに属します(すべてのマイナー モードがキーマップをもつわけでなない)。ローカルキーマップは対応するグロ ーバルバインディングをshadow(訳注: 隠すという意味)します。マイナーモード キーマップは、ローカルキーマップとグローバルキーマップの両方をshadowしま す。詳細は*note Active Keymaps::を参照してください。 21.3 キーマップのフォーマット ============================= キーマップはそれぞれCARがシンボル‘keymap’であるようなリストです。このリ ストの残りの要素はそのキーマップのキーバインディングを定義します。関数定 義がキーマップであるようなシンボルもキーマップです。あるオブジェクトがキ ーマップかどうかテストするには、関数‘keymapp’(以下参照)を使用してくださ い。 キーマップを開始するシンボル‘keymap’の後には、いくつかの種類の要素が 出現します: ‘(TYPE . BINDING)’ これは型TYPEのイベントにたいする1つのバインディングを指定する。通常 のバインディングはそれぞれ、常に文字かシンボルであるような特定の“イ ベント型(event type)”のイベントに適用される。*note Classifying Events::を参照のこと。この種のバインディングでは、BINDINGはコマンド である。 ‘(TYPE ITEM-NAME . BINDING)’ これはメニュー内でITEM-NAMEとして表示されるシンプルなメニューアイテ ムでもあるようなバインディングを指定する。*note Simple Menu Items::を参照のこと。 ‘(TYPE ITEM-NAME HELP-STRING . BINDING)’ これはヘルプ文字列HELP-STRINGのシンプルなメニューアイテムである。 ‘(TYPE menu-item . DETAILS)’ これは拡張されたメニューアイテムでもあるようなバインディングを指定 する。これは他の機能も使用できる。*note Extended Menu Items::を参照 のこと。 ‘(t . BINDING)’ これは“デフォルトキーバインディング(default key binding)”を指定する 。キーマップの他の要素でバインドされないイベントは、バインディング としてBINDINGが与えられる。デフォルトバインディングにより、利用可能 なすべてのイベント型を列挙することなくバインドできる。デフォルトバ インディングをもつキーマップは、明示的に‘nil’にバインドされるイベン ト(以下参照)を除いて、より低い優先度にあるすべてのキーマップをマス クする。 ‘CHAR-TABLE’ キーマップのある要素が文字テーブル(char-table)なら、それは修飾ビッ トなしのすべての文字イベントにたいするバインディングを保持するとみ なされる(*note modifier bits::を参照)。インデックスCの要素は文字Cに たいしてバインドされる。これは多量のバインディングを記録するための コンパクトな方法である。そのような文字テーブルのキーマップは、 “fullキーマップ(full keymap: 完全なキーマップ)”と呼ばれる。それにた いして他のキーマップは“sparseキーマップ(sparse keymaps: 疎なキーマ ップ)”と呼ばれる。 ‘VECTOR’ この種の要素は文字テーブルと類似する。インデックスCの要素は文字Cに バインドされる。この方法でバインド可能な文字の範囲はそのベクターの サイズに制限され、かつベクターの作成により0からすべての文字コードま でスペースが割り当てられるので、バインディング自身が問題とならない メニューキーマップ(*note Menu Keymaps::を参照)の作成以外では、この フォーマットを使用しないこと。 ‘STRING’ キーにたいするバインディングを指定する要素は別として、キーマップは 要素として文字列ももつことができる。これは“overallプロンプト文字列 (overall prompt string: 全般的なプロンプト文字列)”と呼ばれ、メニュ ーとしてキーマップを使用することを可能にする。*note Defining Menus::を参照のこと。 ‘(keymap ...)’ キーマップのある要素それ自身がキーマップなら、外側のキーマップ内で これが内側のキーマップとしてinline指定されているかのようにみなされ る。これは‘make-composed-keymap’内で行なわれるような多重継承にたい して使用される。 バインディングが‘nil’なら、それは定義の構成要素ではありませんが、デフ ォルトバインディングや親キーマップ内のバインディングに優先されます。一方 ‘nil’のバインディングは、より低い優先度のキーマップを_オーバーライドしま せん_。したがってローカルマップで‘nil’のバインディングが与えられると、 Emacsはグローバルマップのバインディングを使用します。 キーマップはメタ文字にたいするバインディングを直接記録しません。かわ りにメタ文字は1文字目が(または何であれ‘meta-prefix-char’のカレント 値)であるような、2文字のキーシーケンスをルックアップするものとみなされま す。したがってキー‘M-a’は内部的には‘ a’で表され、そのグローバルバイ ンディングは‘esc-map’内の‘a’にたいするスロットで見つけることができます (*note Prefix Keys::を参照)。 この変換は文字にたいしてのみ適用され、ファンクションキーや他の入力イ ベントには適用されないので‘M-’は‘ ’と何も関係ありません。 以下に例としてLispモードにたいするローカルキーマップ(sparseキーマップ )を挙げます。以下では、‘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’は‘ C-x’として扱われる (24 . lisp-send-defun)) ;; この部分は‘lisp-mode-shared-map’から継承 keymap ;; (127 . backward-delete-char-untabify) (27 keymap ;; ‘C-M-q’は‘ C-q’として扱われる (17 . indent-sexp))) -- Function: keymapp object この関数はOBJECTがキーマップなら‘t’、それ以外は‘nil’をリターンする 。より正確にはこの関数はリストにたいしてそのCARが‘keymap’か、あるい はシンボルにたいしてその関数定義が‘keymapp’かどうかをテストする。 (keymapp '(keymap)) ⇒ t (fset 'foo '(keymap)) (keymapp 'foo) ⇒ t (keymapp (current-global-map)) ⇒ t 21.4 キーマップの作成 ===================== 以下はキーマップを作成する関数です。 -- Function: make-sparse-keymap &optional prompt この関数はエントリーをもたない新たなsparseキーマップを作成してそれ をリターンする(sparseキーマップはあなたが通常望む類のキーマップのこ と)。‘make-keymap’と異なり新たなキーマップは文字テーブルを含まず、 何のイベントもバインドしない。 (make-sparse-keymap) ⇒ (keymap) PROMPTを指定すると、それはキーマップにたいするoverallプロンプト文字 列になる。これはメニューキーマップ(*note Defining Menus::を参照)に たいしてのみ指定すべきである。overallプロンプト文字列をともなうキー マップがアクティブなら、次の入力イベントのルックアップにたいしてマ ウスメニューとキーボードメニューを常に提示する。これはコマンドルー プにたいして毎回キーボードメニューを提示するので、overallプロンプト 文字列をメインマップ、メジャーモードマップ、マイナーモードマップに 指定しないこと。 -- Function: make-keymap &optional prompt この関数は新たなfullキーマップを作成してそれをリターンする。このキ ーマップは修飾されないすべての文字にたいするスロットをもつ文字テー ブル(*note Char-Tables::を参照)を含む。この新たなキーマップは初期状 態ではすべての文字、およびその他の種類のイベントが‘nil’にバインドさ れている。引数PROMPTは‘make-sparse-keymap’のようにプロンプト文字列 を指定する。 (make-keymap) ⇒ (keymap #^[nil nil keymap nil nil nil ...]) fullキーマップは多くのスロットを保持するときはsparseキーマップより 効果的であり、少ししかスロットを保持しないときはsparseキーマップの ほうが適している。 -- Function: copy-keymap keymap この関数は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 21.5 継承とキーマップ ===================== キーマップは他のキーマップを継承することができ、この継承元のキーマップを “親キーマップ(parent keymap)”と呼びます。そのようなキーマップは以下のよ うなキーマップです: (keymap ELEMENTS... . PARENT-KEYMAP) これにはそのキーマップのキールックアップ時にPARENT-KEYMAPのすべてのバイ ンディングを継承するものの、それらにバインディングを追加したりELEMENTSで オーバーライドできるという効果があります。 ‘define-key’や他のキーバインディング関数を使用してPARENT-KEYMAP内のバ インディングを変更すると、変更されたバインディングはELEMENTSで作られたバ インディングにshadowされない限り継承されたキーマップ内で可視になります。 逆は真ではありません。‘define-key’を使用して継承されたキーマップ内のバイ ンディングを変更すると、これらの変更はELEMENTS内に記録されますが PARENT-KEYMAPに影響はありません。 親キーマップからキーマップを構築するには‘set-keymap-parent’を使用する のが正しい方法です。親キーマップから直接キーマップを構築するコードがある なら、かわりに‘set-keymap-parent’を使用するようにプログラムを変更してく ださい。 -- Function: keymap-parent keymap これはKEYMAPの親キーマップをリターンする。KEYMAPに親キーマップがな ければ‘keymap-parent’は‘nil’をリターンする。 -- Function: set-keymap-parent keymap parent これは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’が使用できます。 -- Function: make-composed-keymap maps &optional parent この関数は既存のキーマップから構成される新たなキーマップをリターン する。またオプションで親キーマップPARENTから継承を行う。MAPSには単 一のキーマップ、または複数のキーマップのリストを指定できる。リター ンされた新たなマップ内でキーをルックアップするとき、EmacsはMAPS内の キーマップを順に検索してからPARENT内を検索する。この検索は最初のマ ッチで停止する。MAPSのいずれか1つのキーマップ内の‘nil’バインディン グは、PARENT内のすべてのバインディングをオーバーライドするが、 MAPSにないキーマップの非‘nil’なバインディングはオーバーライドしない 。 たとえば以下は‘button-buffer-map’と‘special-mode-map’の両方を継承する ‘help-mode-map’のようなキーマップの親キーマップをEmacsがセットする方法で す: (defvar help-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map (make-composed-keymap button-buffer-map special-mode-map)) ... map) ... ) 21.6 プレフィクスキー ===================== “プレフィクスキー(prefix key)”とは、バインディングがキーマップであるよう なキーシーケンスです。このキーマップはプレフィクスキーを拡張するキーシー ケンスが何を行うかを定義します。たとえば‘C-x’はプレフィクスキーであり、 これはキーマップを使用してそのキーマップは変数‘ctl-x-map’にも格納されて います。このキーマップは‘C-x’で始まるキーシーケンスにたいするバインディ ングを定義します。 標準的なEmacsのプレフィクスキーのいくつかは、Lisp変数でも見い出すこと ができるキーマップを使用しています: • ‘esc-map’はプレフィクスキーにたいするグローバルキーマップであ る。したがってすべてのメタ文字にたいする定義は、このキーマップで見 い出すことができる。このマップは‘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 ’ にたいして使用されるグロ ーバルキーマップである。 • ‘ctl-x-4-map’はプレフィクスキー‘C-x 4’にたいして使用されるグローバ ルキーマップである。 • ‘ctl-x-5-map’はプレフィクスキー‘C-x 5’にたいして使用されるグローバ ルキーマップである。 • ‘2C-mode-map’はプレフィクスキー‘C-x 6’にたいして使用されるグローバ ルキーマップである。 • ‘vc-prefix-map’はプレフィクスキー‘C-x v’にたいして使用されるグロー バルキーマップである。 • ‘goto-map’はプレフィクスキー‘M-g’にたいして使用されるグローバルキー マップである。 • ‘search-map’はプレフィクスキー‘M-s’にたいして使用されるグローバルキ ーマップである。 • ‘facemenu-keymap’はプレフィクスキー‘M-o’にたいして使用されるグロー バルキーマップである。 • Emacsの他のプレフィクスキーには‘C-x @’、‘C-x a i’、‘C-x ’、 ‘ ’がある。これらは特別な名前をもたないキーマップを使用す る。 プレフィクスキーのキーマップバインディングは、プレフィクスキーに続く イベントをルックアップするために使用されます(これは関数定義がキーマップ であるようなシンボルかもしれない。効果は同じだがシンボルはプレフィクスキ ーにたいする名前の役割を果たす)。したがって‘C-x’のバインディングはシンボ ル‘Control-X-prefix’であり、このシンボルの関数セルが‘C-x’コマンドにたい するキーマップを保持します(‘ctl-x-map’の値も同じキーマップ)。 プレフィクスキー定義は任意のアクティブなキーマップ内に置くことができ ます。プレフィクスキーとしての‘C-c’、‘C-x’、‘C-h’、の定義はグローバ ルマップ内にもあるので、これらのプレフィクスキーは常に使用できます。メジ ャーモードとマイナーモードは、ローカルマップやマイナーモードのマップ内に プレフィクスキー定義を置くことによってキーをプレフィクスキーとして再定義 できます。*note Active Keymaps::を参照してください。 あるキーが複数のアクティブなマップ内でプレフィクスキーとして定義され ていると、それぞれの定義がマージされて効果をもちます。まずマイナーモード キーマップ内で定義されたコマンド、次にローカルマップのプレフィクス定義さ れたコマンド、そしてグローバルマップのコマンドが続きます。 以下の例ではローカルキーマップ内で‘C-p’を‘C-x’と等価なプレフィクスキ ーにしています。すると‘C-p C-f’にたいするバインディングは‘C-x C-f’と同様 に関数‘find-file’になります。キーシーケンス‘C-p 6’はすべてのアクティブな キーマップで見つけることができません。 (use-local-map (make-sparse-keymap)) ⇒ nil (local-set-key "\C-p" ctl-x-map) ⇒ nil (key-binding "\C-p\C-f") ⇒ find-file (key-binding "\C-p6") ⇒ nil -- Function: define-prefix-command symbol &optional mapvar prompt この関数はプレフィクスキーのバインディングとして使用するために SYMBOLを用意する。これはsparseキーマップを作成してそれをSYMBOLの関 数定義として格納する。その後はSYMBOLにキーシーケンスをバインディン グすると、そのキーシーケンスはプレフィクスキーになるだろう。リター ン値は‘symbol’。 この関数は値がそのキーマップであるような変数としてもSYMBOLをセット する。しかしMAPVARが非‘nil’なら、かわりにMAPVARを変数としてセットす る。 PROMPTが非‘nil’なら、これはそのキーマップにたいするoverallプロンプ ト文字列になる。プロンプト文字列はメニューキーマップにたいして与え らること(*note Defining Menus::を参照)。 21.7 アクティブなキーマップ =========================== Emacsには多くのキーマップを含まれていますが、常にいくつかのキーマップだ けが“アクティブ”です。Emacsがユーザー入力を受け取ったとき、それは入力イ ベントに変換されて(*note Translation Keymaps::を参照)、アクティブなキー マップ内でキーバインディングがルックアップされます。 アクティブなキーマップは通常は、(1) ‘keymap’プロパティにより指定され るキーマップ、(2) 有効なマイナーモードのキーマップ、(3) カレントバッファ ーのローカルキーマップ、(4) グローバルキーマップの順です。Emacsは入力キ ーシーケンスそれぞれにたいして、これらすべてのキーマップ内を検索します。 これらの通常のキーマップのうち最優先されるのは、もしあればポイント位 置の‘keymap’テキストにより指定されるキーマップかoverallプロパティです(マ ウス入力イベントにたいしてはEmacsはポイント位置のかわりにイベント位置を 使用する。 *note Searching Keymaps::を参照されたい)。 次に優先されるのは有効なマイナーモードにより指定されるキーマップです 。もしあればこれらのキーマップは変数‘emulation-mode-map-alists’、 ‘minor-mode-overriding-map-alist’、‘minor-mode-map-alist’により指定され ます。*note Controlling Active Maps::を参照してください。 次に優先されるのはバッファーの“ローカルキーマップ(local keymap)”で、 これにはそのバッファー特有なキーバインディングが含まれます。ミニバッファ ーもローカルキーマップをもちます(*note Intro to Minibuffers::を参照)。ポ イント位置に‘local-map’テキスト、またはoverlayプロパティがあるなら、それ はバッファーのデフォルトローカルキーマップのかわりに使用するローカルキー マップを指定します。 ローカルキーマップは通常はそのバッファーのメジャーモードによってセッ トされます。同じメジャーモードをもつすべてのバッファーは、同じローカルキ ーマップを共有します。したがってあるバッファーでローカルキーマップを変更 するために‘local-set-key’ (*note Key Binding Commands::を参照)を呼び出す と、それは同じメジャーモードをもつ他のバッファーのローカルキーマップにも 影響を与えます。 最後は‘C-f’のようなカレントバッファーとは関係なく定義されるキーバイン ディングを含んだ“グローバルキーマップ(global keymap)”です。このキーマッ プは常にアクティブであり変数‘global-map’にバインドされています。 これら通常のキーマップとは別に、Emacsはプログラムが他のキーマップをア クティブにするための特別な手段を提供します。1つ目はグローバルキーマップ 以外の通常アクティブなキーマップを置き換えるキーマップを指定する変数 ‘overriding-local-map’です。2つ目は他の_すべて_のキーマップより優先され るキーマップを指定する端末ローカル変数‘overriding-terminal-local-map’で す。この端末ローカル変数は通常はmodal(訳注: 他のキーマップを選択できない 状態)かつ一時的なキーバインディングに使用されます(ここの変数にたいして関 数‘set-transient-map’は便利なインターフェイスを提供する)。詳細は*note Controlling Active Maps::を参照してください。 これらを使用するのがキーマップをアクティブにする唯一の方法ではありま せん。キーマップは‘read-key-sequence’によるイベントの変換のような他の用 途にも使用されます。*note Translation Keymaps::を参照してください。 いくつかの標準的なキーマップのリストは*note Standard Keymaps::を参照 してください。 -- Function: current-active-maps &optional olp position これはカレント状況下でコマンドループによりキーシーケンスをルックア ップするために使用される、アクティブなキーマップのリストをリターン する。これは通常は‘overriding-local-map’と ‘overriding-terminal-local-map’を無視するが、OLPが非‘nil’なら、それ らのキーマップにも注意を払う。オプションでPOSITIONに‘event-start’に よってリターンされるイベント位置、またはバッファー位置を指定でき、 ‘key-binding’で説明されているようにキーマップを変更するかもしれない 。 -- Function: key-binding key &optional accept-defaults no-remap position この関数はカレントのアクティブキーマップでKEYにたいするバインディン グをリターンする。そのキーマップ内でKEYが未定義なら結果は‘nil’。 引数ACCEPT-DEFAULTSは‘lookup-key’ (*note Functions for Key Lookup::を参照)のようにデフォルトバインディングをチェックするかどう かを制御する。 コマンドがリマップ(remap: 再マップ。*note Remapping Commands::を参 照)されたとき、‘key-binding’が実際に実行されるであろうリマップされ たコマンドをリターンするように、通常のようにコマンドのリマップを行 う。しかしNO-REMAPが非‘nil’なら、‘key-binding’はリマップを無視して KEYにたいして直接指定されたバインディングをリターンする。 KEYがマウスイベント(もしかしたらプレフィクスイベントが先行するかも しれない)で始まるなら、照合されるマップはそのイベントの位置を元に決 定される。それ以外では、それらのマップはポイント値にもとづき決定さ れる。しかしPOSITIONを指定することによってこれらをオーバーライドで きる。POSITIONが非‘nil’なら、それはバッファー位置か‘event-start’の 値のようなイベント位置のいずれかである。その場合には照合されるマッ プはPOSITIONにもとづいて決定される。 KEYが文字列とベクターのいずれでもなければEmacsはエラーをシグナルす る。 (key-binding "\C-x\C-f") ⇒ find-file 21.8 アクティブなキーマップの検索 ================================= 以下はEmacsがアクティブなキーマップを検索する方法を示すLisp処理の概要で す: (or (if overriding-terminal-local-map (FIND-IN overriding-terminal-local-map)) (if overriding-local-map (FIND-IN overriding-local-map) (or (FIND-IN (get-char-property (point) 'keymap)) (FIND-IN-ANY emulation-mode-map-alists) (FIND-IN-ANY minor-mode-overriding-map-alist) (FIND-IN-ANY minor-mode-map-alist) (if (get-text-property (point) 'local-map) (FIND-IN (get-char-property (point) 'local-map)) (FIND-IN (current-local-map))))) (FIND-IN (current-global-map))) ここでFIND-INとFIND-IN-ANYはそれぞれ、1つのキーマップとキーマップの alistを検索する仮の関数です。関数‘set-transient-map’が ‘overriding-terminal-local-map’ (*note Controlling Active Maps::を参照 )をセットすることによって機能する点に注意してください。 上記の処理概要ではキーシーケンスがマウスイベント(*note Mouse Events::を参照)で始まる場合には、ポイント位置のかわりにそのイベント位置 、カレントバッファーのかわりにそのイベントのバッファーが使用されます。こ れは特にプロパティ‘keymap’と‘local-map’をルックアップする方法に影響を与 えます。‘display’、‘before-string’、‘after-string’プロパティ(*note Special Properties::を参照)が埋め込まれていて‘keymap’か‘local-map’プロパ ティが非‘nil’の文字列上でマウスイベントが発生すると、それは基調となるバ ッファーテキストの対応するプロパティをオーバーライドします(バッファーテ キストにより指定されたプロパティは無視される)。 アクティブなキーマップの1つでキーバインディングが見つかって、そのバイ ンディングがコマンドなら検索は終了してそのコマンドが実行されます。しかし そのバインディングが値をもつ変数か文字列なら、Emacsは入力キーシーケンス をその変数の値か文字列で置き換えて、アクティブなキーマップの検索を再開し ます。 *note Key Lookup::を参照してください。 最終的に見つかったコマンドもリマップされるかもしれません。*note Remapping Commands::を参照してください。 21.9 アクティブなキーマップの制御 ================================= -- Variable: global-map この変数はEmacsキーボード入力をコマンドにマップするデフォルトのグロ ーバルキーマップを含む。通常はこのキーマップがグローバルキーマップ である。デフォルトグローバルキーマップは‘self-insert-command’をすべ てのプリント文字にバインドするfullキーマップである。 これはグローバルキーマップ内のバインディングを変更する通常の手段だ が、この変数に開始時のキーマップ以外の値を割り当てるべきではない。 -- Function: current-global-map この関数はカレントのグローバルキーマップをリターンする。デフォルト グローバルキーマップとカレントグローバルキーマップのいずれも変更し ていなければ‘global-map’と同じ値。リターン値はコピーではなく参照で ある。これに‘define-key’などの関数を使用すると、グローバルバインデ ィングが変更されるだろう。 (current-global-map) ⇒ (keymap [set-mark-command beginning-of-line ... delete-backward-char]) -- Function: current-local-map この関数はカレントバッファーのローカルキーマップをリターンする。ロ ーカルキーマップがなければ‘nil’をリターンする。以下の例では、(Lisp Interactionモードを使用する)‘*scratch*’バッファーにたいするキーマッ プは、(ASCIIコード27)にたいするエントリーが別のsparseキーマッ プであるようなsparseキーマップである。 (current-local-map) ⇒ (keymap (10 . eval-print-last-sexp) (9 . lisp-indent-line) (127 . backward-delete-char-untabify) (27 keymap (24 . eval-defun) (17 . indent-sexp))) ‘current-local-map’はローカルキーマップのコピーではなく参照をリターン します。これに‘define-key’などの関数を使用するとローカルバインディングが 変更されるでしょう。 -- Function: current-minor-mode-maps この関数はカレントで有効なメジャーモードのキーマップリストをリター ンする。 -- Function: use-global-map keymap この関数はKEYMAPを新たなカレントグローバルキーマップにする。これは ‘nil’をリターンする。 グローバルキーマップの変更は異例である。 -- Function: use-local-map keymap この関数はKEYMAPをカレントバッファーの新たなローカルキーマップにす る。KEYMAPが‘nil’なら、そのバッファーはローカルキーマップをもたない 。‘use-local-map’は‘nil’をリターンする。ほとんどのメジャーモードコ マンドはこの関数を使用する。 -- Variable: minor-mode-map-alist この変数はアクティブかどうかに関わらず、特定の変数の値にたいするキ ーマップを示すalistである。要素は以下のようになる: (VARIABLE . KEYMAP) キーマップKEYMAPは VARIABLEが非‘nil’値をもつときはアクティブである 。VARIABLEは通常はメジャーモードを有効か無効にする変数である。*note Keymaps and Minor Modes::を参照のこと。 ‘minor-mode-map-alist’の要素が‘minor-mode-alist’の要素と異なる構造 をもつことに注意。マップは要素のCDRでなければならず、そうでなければ 2つ目の要素にマップリストは用いられないだろう。CDRはキーマップ(リス ト)、または関数定義がキーマップであるようなシンボルである。 1つ以上のマイナーモードキーマップがアクティブなとき、 ‘minor-mode-map-alist’内で前のキーマップが優先される。しかし互いが 干渉しないようにマイナーモードをデザインすること。これを正しく行え ば順序は問題にならない。 マイナーモードについての詳細な情報は、*note Keymaps and Minor Modes::を参照のこと。‘minor-mode-key-binding’ (*note Functions for Key Lookup::を参照)も確認されたい。 -- Variable: minor-mode-overriding-map-alist この変数はメジャーモードによる特定のマイナーモードにたいするキーバ インディングのオーバーライドを可能にする。このalistの要素は ‘minor-mode-map-alist’の要素のような‘(VARIABLE . KEYMAP)’という形式 である。 ある変数が‘minor-mode-overriding-map-alist’の要素として出現するなら 、その要素によって指定されるマップは‘minor-mode-map-alist’内の同じ 変数にたいして指定されるすべてのマップを完全に置き換える。 すべてのバッファーにおいて‘minor-mode-overriding-map-alist’は自動的 にバッファーローカルである。 -- Variable: overriding-local-map この変数が非‘nil’ならバッファーのローカルキーマップ、テキストプロパ ティまたはoverlayによるキーマップ、マイナーモードキーマップのかわり に使用されるするキーマップを保持する。このキーマップが指定されると 、カレントグローバルキーマップ以外のアクティブだった他のすべてのマ ップがオーバーライドされる。 -- Variable: overriding-terminal-local-map この変数が非‘nil’なら‘overriding-local-map’、バッファーのローカルキ ーマップ、テキストプロパティまたはoverlayによるキーマップ、およびす べてのマイナーモードキーマップのかわりに使用されるキーマップを保持 する。 この変数はカレント端末にたいして常にローカルでありバッファーローカ ルにできない。*note Multiple Terminals::を参照のこと。これはインク リメンタル検索モードの実装に使用される。 -- Variable: overriding-local-map-menu-flag この変数が非‘nil’なら、‘overriding-local-map’と ‘overriding-terminal-local-map’の値がメニューバーの表示に影響し得る 。デフォルト値は‘nil’なので、これらのマップ変数なメニューバーに影響 をもたない。 これら2つのマップ変数は、たとえこれらの変数がメニューバー表示に影響 し得るを与えない場合でも、メニューバーを使用してエンターされたキー シーケンスの実行には影響を与えることに注意。したがってもしメニュー バーキーシーケンスが到着したら、そのキーシーケンスをルックアップし て実行する前に変数をクリアーすること。この変数を使用するモードは通 常は何らかの手段でこれを行っている。これらのモードは通常は“読み戻し (unread)”とexitによって処理されないイベントに応答する。 -- Variable: special-event-map この変数はスペシャルイベントにたいするキーマップを保持する。あるイ ベント型がこのキーマップ内でバインディングをもつなら、それはスペシ ャルイベントであり、そのイベントにたいするバインディングは ‘read-event’によって直接実行される。*note Special Events::を参照の こと。 -- Variable: emulation-mode-map-alists この変数はエミュレーションモードにたいして使用するキーマップの alistのリストを保持する。この変数は複数マイナーモードキーマップを使 用するモードとパッケージを意図している。リストの各要素は ‘minor-mode-map-alist’と同じフォーマットと意味をもつキーマップの alistか、そのようなalist形式の変数バインディングをもつシンボルであ る。それぞれのalist内のアクティブなキーマップは ‘minor-mode-map-alist’と‘minor-mode-overriding-map-alist’の前に使用 される。 -- Function: set-transient-map keymap &optional keep-pred on-exit この関数は“一時的(transient)”なキーマップとしてKEYMAPを追加する。一 時的なキーマップは1つ以上の後続するキーにたいして、他のキーマップよ り優先される。 KEYMAPは通常は直後のキーをルックアップするために1回だけ使用される。 しかし、オプション引数KEEP-PREDが‘t’なら、そのマップはユーザーが KEYMAP内で定義されたキーをタイプするまでアクティブのままとなる。 KEYMAP内にないキーをユーザーがタイプしたとき一時的キーマップは非ア クティブとなり、そのキーにたいして通常のキールックアップが継続され る。 KEEP-PREDには関数も指定できる。この場合にはKEYMAPがアクティブの間は 、各コマンドの実行に優先してその関数が引数なしで呼び出される。 KEYMAPがアクティブの間、関数は非‘nil’をリターンすること。 オプション引数ON-EXITが非nilなら、それはKEYMAPが非アクティブになっ た後に引数なしで呼び出される関数を指定する。 この関数は他のすべてのアクティブなキーマップに優先される変数 ‘overriding-terminal-local-map’にたいして、KEYMAPを追加または削除す ることによって機能する(*note Searching Keymaps::を参照)。 21.10 キーの照合 ================ “キールックアップ(key lookup: キー照合)”とは与えられたキーマップからキー シーケンスのバインディングを見つけ出すことです。そのバインディングの使用 や実行はキールックアップの一部ではありません。 キールックアップはキーシーケンス内の各イベントのイベント型だけを使用 して、そのイベントの残りは無視します。実際のところキールックアップに使用 されるキーシーケンスは、マウスイベントをイベント全体(リスト)のかわりにイ ベント型のみ(シンボル)を用いるでしょう。*note Input Events::を参照してく ださい。そのようなキーシーケンスは‘command-execute’による実行には不十分 ですが、キーのルックアップやリバインドには十分です。 キーシーケンスが複数イベントから構成されるとき、キールックアップはイ ベントを順に処理します。最初のイベントのバインディングが見つかったとき、 それはキーマップでなければなりません。そのキーマップ内で2つ目のイベント を見つけ出して、そのキーシーケンス内のすべてのイベントが消費されるまで、 このプロセスを続けます(故に最後のイベントにたいして見つかったイベントは キーマップかどうかはわからない)。したがってキールックアッププロセスはキ ーマップ内で単一イベントを見つけ出す、よりシンプルなプロセスで定義されま す。これが行なわれる方法はキーマップ内でそのイベントに関連するオブジェク トの型に依存します。 キーマップ内のイベント型ルックアップによる値の発見を説明するために、 “キーマップエントリー(keymap entry)”という用語を導入しましょう(これには メニューアイテムにたいするキーマップ内のアイテム文字列や他の余計な要素は 含まれない。なぜなら‘lookup-key’や他のキーマップルックアップ関数がリター ン値にそれらを含まないから)。任意のLispオブジェクトがキーマップエントリ ーとしてキーマップに格納されるかもしれませんが、すべてがキールックアップ に意味をもつわけではありません。以下のテーブルはキーマップエントリーで重 要な型です: ‘nil’ ‘nil’はそれまでにルックアップに使用されたイベントが未定義キーを形成 することを意味する。最終的にキーマップがイベント型を調べるのに失敗 してデフォルトバインディングも存在しないときは、そのイベント型のバ インディングが‘nil’であるのと同じである。 COMMAND それまでにルックアップに使用されたイベントがコンプリートキーを形成 して、COMMANDがそのバインディングである。*note What Is a Function::を参照のこと。 ARRAY array(文字列かベクター)はキーボードマクロである。それまでにルックア ップに使用されたイベントはコンプリートキーを形成して、arrayがそのバ インディングである。詳細は*note Keyboard Macros::を参照のこと。 KEYMAP それまでにルックアップに使用されたイベントはプレフィクスキーを形成 する。そのキーシーケンスの次のイベントはKEYMAP内でルックアップされ る。 LIST listの意味はそのリストが何を含んでいるかに依存する: • LISTのCARがシンボル‘keymap’なら、そのリストはキーマップであり キーマップとして扱われる(上記参照)。 • LISTのCARが‘lambda’なら、そのリストはラムダ式である。これは関 数とみなされてそのように扱われる(上記参照)。キーバインディング として正しく実行されるために、この関数はコマンドでなければなら ず‘interactive’指定をもたなければならない。*note Defining Commands::を参照のこと。 SYMBOL SYMBOLの関数定義がSYMBOLのかわりに使用される。もし関数定義もシンボ ルなら、任意の回数このプロセスが繰り返される。これは最終的にキーマ ップであるようなオブジェクト、コマンド、またはキーボードマクロに行 き着くはずである。 キーマップとキーボードマクロ(文字列かベクター)は有効な関数ではない ので関数定義にキーマップ、文字列、ベクターをもつシンボルは関数とし ては無効であることに注意。しかしキーバインディングとしては有効であ る。その定義がキーボードマクロなら、そのシンボルは ‘command-execute’(*note Interactive Call::を参照)の引数としても有効 である。 シンボル‘undefined’は特記するに値する。これはそのキーを未定義として 扱うことを意味する。厳密に言うとそのキーは定義されているが、そのバ インディングがコマンド‘undefined’なのである。しかしこのコマンドは未 定義キーにたいして自動的に行われるのと同じことを行う。これは (‘ding’を呼び出して)bellを鳴らすがエラーはシグナルしない。 ‘undefined’はグローバルキーバインディングをオーバーライドして、その キーをローカルに未定義とするために使用される。‘nil’にローカルにバイ ンドしてもグローバルバインディングをオーバーライドしないであろうか ら、これを行うのに失敗するだろう。 ANYTHING ELSE オブジェクトの他の型が見つかったら、それまでにルックアップで使用さ れたイベントはコンプリートキーを形成してそのオブジェクトがバインデ ィングになるが、そのバインディングはコマンドとして実行不可能である 。 要約するとキーマップエントリーはキーマップ、コマンド、キーボードマク ロ、あるいはそれらに導出されるシンボル、あるいは‘nil’のいずれかです。 21.11 キー照合のための関数 ========================== 以下はキールックアップに関連する関数および変数です。 -- Function: lookup-key keymap key &optional accept-defaults この関数はKEYMAP内のKEYの定義をリターンする。このチャプターで説明さ れているキーをルックアップする他のすべての関数が‘lookup-key’を使用 する。以下は例: (lookup-key (current-global-map) "\C-x\C-f") ⇒ find-file (lookup-key (current-global-map) (kbd "C-x C-f")) ⇒ find-file (lookup-key (current-global-map) "\C-x\C-f12345") ⇒ 2 文字列かベクターのKEYがKEYMAP内で指定されるプレフィクスキーとして有 効なキーシーケンスでなければ、それは最後に余計なイベントをもった、 単一のキーシーケンスに適合しない長過ぎるキーのはずである。その場合 のリターン値は数となり、この数はコンプリートキーを構成するKEYの前に あるイベントの数である。 ACCEPT-DEFAULTSが非‘nil’なら、‘lookup-key’はKEY内の特定のイベントに たいするバインディングと同様にデフォルトバインディングも考慮する。 それ以外では‘lookup-key’は特定のKEYのシーケンスにたいするバインディ ングだけを報告して、明示的に指定したとき以外はデフォルトバインディ ングを無視する(これを行うにはKEYの要素として‘t’を与える。*note Format of Keymaps::を参照されたい)。 KEYがメタ文字(ファンクションキーではない)を含むなら、その文字は暗黙 に‘meta-prefix-char’の値と対応する非メタ文字からなる2文字シーケンス に置き換えられる。したがって以下の1つ目の例は2つ目の例に変換されて 処理される。 (lookup-key (current-global-map) "\M-f") ⇒ forward-word (lookup-key (current-global-map) "\ef") ⇒ forward-word ‘read-key-sequence’とは異なり、この関数は指定されたイベントの情報を 破棄する変更(*note Key Sequence Input::を参照)を行わない。特にこの 関数はアルファベット文字を小文字に変更せず、ドラッグイベントをクリ ックイベントに変更しない。 -- Command: undefined キーを未定義にするためにキーマップ内で使用される。これは‘ding’を呼 び出すがエラーを発生ささない。 -- Function: local-key-binding key &optional accept-defaults この関数はカレントのローカルキーマップ内のKEYにたいするバインディン グをリターンする。カレントのローカルキーマップ内で未定義なら‘nil’を リターンする。 引数ACCEPT-DEFAULTSは‘lookup-key’(上記)と同じようにデフォルトバイン ディングのチェックを制御する。 -- Function: global-key-binding key &optional accept-defaults この関数はカレントのグローバルキーマップ内でコマンドKEYにたいするバ インディングをリターンする。カレントのグローバルキーマップ内で未定 義なら‘nil’をリターンする。 引数ACCEPT-DEFAULTSは‘lookup-key’(上記)と同じようにデフォルトバイン ディングのチェックを制御する。 -- Function: minor-mode-key-binding key &optional accept-defaults この関数はアクティブなマイナーモードのKEYのバインディングをリストで リターンする。より正確にはこの関数は‘(MODENAME . BINDING)’のような ペアのalistをリターンする。ここでMODENAMEなそのマイナーモードを有効 にする変数、BINDINGはそのモードでのKEYのバインディングである。KEYが マイナーモードバインディングをもたなければ値は‘nil’。 最初に見つかったバインディングがプレフィクス定義(キーマップ、または キーマップとして定義されたシンボル)でなければ、他のマイナーモードに 由来するすべての後続するバインディングは完全にshadowされて省略され る。同様にこのリストはプレフィクスバインディングに後続する非プレフ ィクスバインディングは省略される。 引数ACCEPT-DEFAULTSは‘lookup-key’(上記)と同じようにデフォルトバイン ディングのチェックを制御する。 -- User Option: meta-prefix-char この変数はメタ/プレフィクス文字コードである。これはメタ文字をキーマ ップ内でルックアップできるように2文字シーケンスに変換する。有用な結 果を得るために値はプレフィクスイベント(*note Prefix Keys::を参照)で あること。デフォルト値は27で、これはにたいするASCIIコード。 ‘meta-prefix-char’の値が27であるような限り、キールックアップは通常 は‘backward-word’コマンドとして定義される‘M-b’を‘ 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-’は‘ ’に変換されない。 21.12 キーバインディングの変更 ============================== キーのリバインド(rebind: 再バインド、再束縛)は、キーマップ内でそのキーの バインディングエントリーを変更することによって行われます。グローバルキー マップ内のバインディングを変更すると、その変更は(たとえローカルバインデ ィングによりグローバルバインディングをshadowしているバッファーでは直接影 響しないとしても)すべてのバッファーに影響します。カレントバッファーのロ ーカルマップを変更すると、通常は同じメジャーモードを使用するすべてのバッ ファーに影響します。関数‘global-set-key’と‘local-set-key’は、これらの操 作のための使いやすいインターフェイスです(*note Key Binding Commands::を 参照)。より汎用的な関数‘define-key’を使用することもできます。その場合に は変更するマップを明示的に指定しなければなりません。 Lispプログラムでリバインドするキーシーケンスを選択するときは、さまざ まなキーの使用についてのEmacsの慣習にしたがってください(*note Key Binding Conventions::を参照)。 リバインドするキーシーケンスの記述では、コントロール文字とメタ文字に たいして特別なエスケープシーケンスを使用すると良いでしょう(*note String Type::を参照)。構文‘\C-’は後続する文字がコントロール文字でること、 ‘\M-’は後続する文字がメタ文字であることを意味します。したがって文字列 ‘"\M-x"’は1つの‘M-x’、‘"\C-f"’は1つの‘C-f’、‘"\M-\C-x"’と‘"\C-\M-x"’は 1つの‘C-M-x’として読み取られます。ベクター内でもこのエスケープシーケンス 、および文字列では使用できない他のエスケープシーケンスを使用できます。一 例は‘[?\C-\H-x home]’です。*note Character Type::を参照してください。 キー定義とルックアップ関数は、ベクターであるようなキーシーケンス内の イベント型にたいして別の構文を受け入れます。修飾名に基本イベント(文字か ファンクションキー名)を付加したものを含んだリストを使用できます。たとえ ば‘(control ?a)’は‘?\C-a’、‘(hyper control left)’は‘C-H-left’と等価です 。このようなリストの利点の1つは、コンパイル済みファイル内に修飾ビットの 正確な数値コードが出現しないことです。 以下の関数はKEYMAPがキーマップでない場合、およびKEYがキーシーケンスを 表す文字列やベクターでない場合にはエラーをシグナルします。リストであるよ うなイベントにたいする略記として、イベント型(シンボル)を使用できます。 ‘kbd’関数(*note Key Sequences::を参照)はキーシーケンスを指定するための便 利な方法です。 -- Function: define-key keymap key binding この関数はKEYMAP内でKEYにたいするバインディングをセットする(KEYが長 さ2以上のイベントなら、その変更は実際はKEYMAPから辿られる他のキーマ ップで行なわれる)。引数BINDINGには任意のLispオブジェクトを指定でき るが、意味があるのは特定のオブジェクトだけである(意味のある型のリス トは*note Key Lookup::を参照)。‘define-key’のリターン値はBINDINGで ある。 KEYが‘[t]’なら、それはKEYMAP内でデフォルトバインディングをセットす る。イベントが自身のバインディングをもたないとき、そのキーマップ内 にデフォルトバインディングが存在すればEmacsコマンドループはそれを使 用する。 KEYのすべてのプレフィクスは、プレフィクスキー(キーマップにバインド される)か、あるいは未定義でなけらばならず、それ以外ならエラーがシグ ナルされる。KEYのいくつかのプレフィクスが未定義なら、‘define-key’は それをプレフィクスキーとして定義するので、残りのKEYは指定されたよう に定義できる。 前にKEYMAP内でKEYにたいするバインディングが存在しなければ、新たなバ インディングがKEYMAPの先頭に追加される。キーマップ内のバインディン グの順序はキーボード入力にたいし影響を与えないが、メニューキーマッ プにたいしては問題となる(*note Menu Keymaps::を参照)。 以下はsparseキーマップを作成してその中にバインディングをいくつか作成 する例: (setq map (make-sparse-keymap)) ⇒ (keymap) (define-key map "\C-f" 'forward-char) ⇒ forward-char map ⇒ (keymap (6 . forward-char)) ;; ‘C-x’にたいしsparseサブマップを作成して ;; その中で‘f’をバインドする (define-key map (kbd "C-x f") 'forward-word) ⇒ forward-word map ⇒ (keymap (24 keymap ; C-x (102 . forward-word)) ; f (6 . forward-char)) ; C-f ;; ‘C-p’を‘ctl-x-map’にバインド (define-key map (kbd "C-p") ctl-x-map) ;; ctl-x-map ⇒ [nil ... find-file ... backward-kill-sentence] ;; ‘ctl-x-map’内で‘C-f’を‘foo’にバインド (define-key map (kbd "C-p C-f") 'foo) ⇒ 'foo map ⇒ (keymap ; ‘ctl-x-map’内の‘foo’に注目 (16 keymap [nil ... foo ... backward-kill-sentence]) (24 keymap (102 . forward-word)) (6 . forward-char)) ‘C-p C-f’にたいする新たなバインディングの格納は、実際には‘ctl-x-map’内の エントリーを変更することによって機能し、これはデフォルトグローバルマップ 内の‘C-p C-f’と‘C-x C-f’の両方のバインディングを変更する効果をもつことに 注意。 関数‘substitute-key-definition’はキーマップから特定のバインディングを もつキーをスキャンして、それらを異なるバインディングにリバインドする。よ り明快かつ多くの場合には同じ結果を生成できる他の機能として、あるコマンド から別のコマンドへのリマップがある(*note Remapping Commands::を参照)。 -- Function: substitute-key-definition olddef newdef keymap &optional oldmap この関数はKEYMAP内でOLDDEFにバインドされるすべてのキーについて OLDDEFをNEWDEFに置き換える。言い換えるとOLDDEFが出現する箇所のすべ てをNEWDEFに置き換える。この関数は‘nil’をリターンする。 たとえば以下をEmacsの標準バインディングで行うと‘C-x C-f’を再定義す る: (substitute-key-definition 'find-file 'find-file-read-only (current-global-map)) OLDMAPが非‘nil’なら、どのキーをリバインドするかをOLDMAP内のバインデ ィングが決定するように‘substitute-key-definition’の動作を変更する。 リバインディングは依然としてOLDMAPではなくKEYMAPで発生する。したが って他のマップ内のバインディングの制御下でマップを変更することがで きる。たとえば、 (substitute-key-definition 'delete-backward-char 'my-funny-delete my-map global-map) これは標準的な削除コマンドにグローバルにバインドされたキーにたいし て‘my-map’内の特別な削除コマンドを設定する。 以下はキーマップの置き換え(substitution)の前後を示した例: (setq map '(keymap (?1 . olddef-1) (?2 . olddef-2) (?3 . olddef-1))) ⇒ (keymap (49 . olddef-1) (50 . olddef-2) (51 . olddef-1)) (substitute-key-definition 'olddef-1 'newdef map) ⇒ nil map ⇒ (keymap (49 . newdef) (50 . olddef-2) (51 . newdef)) -- Function: suppress-keymap keymap &optional nodigits この関数は‘self-insert-command’をコマンド‘undefined’にリマップ (*note Remapping Commands::を参照)することによってfullキーマップの コンテンツを変更する。これはすべてのプリント文字を未定義にする効果 をもつので、通常のテキスト挿入は不可能になる。‘suppress-keymap’は ‘nil’をリターンする。 NODIGITSが‘nil’なら、‘suppress-keymap’は数字が‘digit-argument’、 ‘-’が‘negative-argument’を実行するように定義する。それ以外は残りの プリント文字と同じように、それらの文字も未定義にする。 ‘suppress-keymap’関数は‘yank’や‘quoted-insert’のようなコマンドを抑 制(suppress)しないのでバッファーの変更は可能。バッファーの変更を防 ぐには、バッファーを読み取り専用(read-only)にすること(*note Read Only Buffers::を参照)。 この関数はKEYMAPを変更するので、通常は新たに作成したキーマップにた いして使用するだろう。他の目的のために使用されている既存のキーマッ プに操作を行うと恐らくトラブルの原因となる。たとえば‘global-map’の 抑制はEmacsをほとんど使用不可能にするだろう。 この関数はテキストの挿入が望ましくないメジャーモードの、ローカルキ ーマップ初期化に使用され得る。しかしそのようなモードは通常は ‘special-mode’ (*note Basic Major Modes::を参照)から継承される。こ の場合にはそのモードのキーマップは既に抑制済みの ‘special-mode-map’から自動的に受け継がれる。以下に ‘special-mode-map’が定義される方法を示す: (defvar special-mode-map (let ((map (make-sparse-keymap))) (suppress-keymap map) (define-key map "q" 'quit-window) ... map)) 21.13 コマンドのリマップ ======================== あるコマンドから他のコマンドへの“リマップ(remap)”には、特別な種類のキー バインディングが使用できます。この機能を使用するためには、ダミーイベント ‘remap’で始まり、その後にリマップしたいコマンド名が続くようなキーシーケ ンスにたいするキーバインディングを作成します。そしてそのバインディングに たいしては、新たな定義(通常はコマンド名だがキーバインディングにたいして 有効な他の任意の定義を指定可能)を指定します。 たとえばMyモードというモードが、‘kill-line’のかわりに呼び出される ‘my-kill-line’という特別なコマンドを提供するとします。これを設定するには 、このモードのキーマップに以下のようなリマッピングが含まれるはずです: (define-key my-mode-map [remap kill-line] 'my-kill-line) その後は‘my-mode-map’がアクティブなときは常に、ユーザーが‘C-k’ (‘kill-line’にたいするデフォルトのグローバルキーシーケンス)をタイプする とEmacsはかわりに‘my-kill-line’を実行するでしょう。 リマップはアクティブなキーマップでのみ行なわれることに注意してくださ い。たとえば‘ctl-x-map’のようなプレフィクスキーマップ内にリマッピングを 置いても、そのようなキーマップはそれ自体がアクティブでないので通常は効果 がありません。それに加えてリマップは1レベルを通じてのみ機能します。以下 の例では、 (define-key my-mode-map [remap kill-line] 'my-kill-line) (define-key my-mode-map [remap my-kill-line] 'my-other-kill-line) これは‘kill-line’を‘my-other-kill-line’にリマップ_しません_。かわりに通 常のキーバインディングが‘kill-line’を指定する場合には、それが ‘my-kill-line’にリマップされます。通常のバインディングが‘my-kill-line’を 指定すると、‘my-other-kill-line’にリマップされます。 コマンドのリマップをアンドゥするには、以下のようにそれを‘nil’にリマッ プします: (define-key my-mode-map [remap kill-line] nil) -- Function: command-remapping command &optional position keymaps この関数はカレントアクティブキーマップによって与えられるCOMMAND(シ ンボル)にたいするリマッピングをリターンする。COMMANDがリマップされ ていない(これは普通の状況である)、あるいはシンボル以外なら、この関 数は‘nil’をリターンする。‘position’は‘key-binding’の場合と同様、使 用するキーマップを決定するためにバッファー位置かイベント位置をオプ ションで指定できる。 オプション引数‘keymaps’が非‘nil’なら、それは検索するキーマップのリ ストを指定する。この引数は‘position’が非‘nil’なら無視される。 21.14 イベントシーケンス変換のためのキーマップ ============================================== ‘read-key-sequence’関数がキーシーケンス(*note Key Sequence Input::を参照 )を読み取るときには、特定のイベントシーケンスを他のものに変換 (translate)するために“変換キーマップ(translation keymaps)”を使用します。 ‘input-decode-map’、‘local-function-key-map’、‘key-translation-map’(優先 順)は変換キーマップです。 変換キーマップは他のキーマップと同じ構造をもちますが使い方は異なりま す。変換キーマップはキーシーケンスを読み取るときに、コンプリートキーシー ケンスにたいするバインディングではなくキーシーケンスに行う変換を指定しま す。キーシーケンスが読み取られると、それらのキーシーケンスは変換キーマッ プにたいしてチェックされます。ある変換キーマップがKをベクターVにバインド するなら、キーシーケンス内の_どこか_にサブシーケンスとしてKが出現すると 、それはV内のイベントに置き換えられます。 たとえばキーパッドキーが押下されたとき、VT100端末は‘ O P’を 送信します。そのような端末ではEmacsはそのイベントシーケンスを単一イベン ト‘pf1’に変換しなければなりません。これは‘input-decode-map’内で‘ O P’を‘[pf1]’にバインドすることにより行われます。したがってその端末上で ‘C-c ’をタイプしたとき、端末は文字シーケンス‘C-c O P’を発行し て、‘read-key-sequence’がそれを‘C-c ’に変換、ベクター‘[?\C-c pf1]’と してリターンします。 変換キーマップは、(‘keyboard-coding-system’で指定された入力コーディン グシステムを通じて)Emacsがキーボード入力をデコードした直後だけ効果をもち ます。*note Terminal I/O Encoding::を参照してください。 -- Variable: input-decode-map この変数は通常の文字端末上のファンクションキーから送信された文字シ ーケンスを記述するキーマップを保持する。 ‘input-decode-map’の値は、通常はその端末のTerminfoかTermcapのエント リーに応じて自動的にセットアップされるが、Lispの端末仕様ファイルの 助けが必要なときもある。Emacsには一般的な多くの端末の端末仕様ファイ ルが同梱されている。これらのファイルの主な目的はTermcapやTerminfoか ら推定できないエントリーを‘input-decode-map’内に作成することである 。*note Terminal-Specific::を参照のこと。 -- Variable: local-function-key-map この変数は‘input-decode-map’と同じようにキーマップを保持するが、通 常は優先される解釈選択肢(alternative interpretation)に変換されるべ きキーシーケンスを記述するキーマップを保持する。このキーマップは ‘input-decode-map’の後、‘key-translation-map’の前に適用される。 ‘local-function-key-map’内のエントリーはマイナーモード、ローカルキ ーマップ、グローバルキーマップによるバインディングと衝突する場合に は無視される。つまり元のキーシーケンスが他にバインディングをもたな い場合だけリマッピングが適用される。 ‘local-function-key-map’は‘function-key-map’を継承するが ‘function-key-map’を直接使用しないこと。 -- Variable: key-translation-map この変数は入力イベントを他のイベントに変換するために、 ‘input-decode-map’と同じように使用される別のキーマップを保持する。 ‘input-decode-map’との違いは、‘local-function-key-map’の前ではなく 後に機能する点である。このキーマップは‘local-function-key-map’によ る変換結果を受け取る。 ‘input-decode-map’と同様だが‘local-function-key-map’とは異なり、こ のキーマップは入力キーシーケンスが通常のバインディングをもつかどう かかに関わらず適用される。しかしこのキーマップによりキーバインディ ングがオーバーライドされても、‘key-translation-map’では実際のキーバ インディングが効果をもち得ることに注意。確かに実際のキーバインディ ングは‘local-function-key-map’をオーバーライドし、したがって ‘key-translation-map’が受け取るキーシーケンスは変更されるだろう。明 確にするためにはこのような類の状況は避けたほうがよい。 ‘key-translation-map’は通常は‘self-insert-command’にバインディング されるような通常文字を含めて、ユーザーがある文字を他の文字にマップ することを意図している。 キーシーケンスのかわりにキーの変換として関数を使用することにより、シ ンプルなエイリアスより多くのことに‘input-decode-map’、 ‘local-function-key-map’、‘key-translation-map’を使用できます。その場合 にはこの関数はそのキーの変換を計算するために呼び出されます。 キー変換関数は引数を1つ受け取ります。この引数は‘read-key-sequence’内 で指定されるプロンプトです。キーシーケンスがエディターコマンドループに読 み取られる場合は‘nil’です。ほとんどの場合にはプロンプト値は無視できます 。 関数が自身で入力を読み取る場合、その関数は後続のイベントを変更する効 果をもつことができます。たとえば以下は‘C-c h’をハイパー文字に後続する文 字とするために定義する方法の例です: (defun hyperify (prompt) (let ((e (read-event))) (vector (if (numberp e) (logior (lsh 1 24) e) (if (memq 'hyper (event-modifiers e)) e (add-event-modifier "H-" e)))))) (defun add-event-modifier (string e) (let ((symbol (if (symbolp e) e (car e)))) (setq symbol (intern (concat string (symbol-name symbol)))) (if (symbolp e) symbol (cons symbol (cdr e))))) (define-key local-function-key-map "\C-ch" 'hyperify) 21.14.1 通常のキーマップとの対話 -------------------------------- そのキーシーケンスがコマンドにバインドされたとき、またはさらにイベントを 追加してもコマンドにバインドされるシーケンスにすることができないと Emacsが判断したときにキーシーケンスの終わりが検出されます。 これは元のキーシーケンスがバインディングをもつかどうかに関わらず、 ‘input-decode-map’や‘key-translation-map’を適用するときに、そのようなバ インディングが変換の開始を妨げることを意味します。たとえば前述のVT100の 例に戻って、グローバルマップに‘C-c ’を追加してみましょう。するとユ ーザーが‘C-c ’をタイプしたとき、Emacsは‘C-c O P’を‘C-c ’に変換するのに失敗するでしょう。これはEmacsが‘C-x ’の直後に読 み取りを停止して、‘O P’が読み取られずに残るからです。この場合にはユーザ ーが実際に‘C-c ’をタイプすると、ユーザーが実際に‘’を押下したの か、あるいは‘’を押下したのか判断するためにEmacsが待つべきではないの です。 この理由によりキーシーケンスの終わりがキー変換のプレフィクスであるよ うなキーシーケンスをコマンドにバインドするのは、避けたほうがよいでしょう 。そのような問題を起こす主なサフィックス、およびプレフィクスは‘’、 ‘M-O’ (実際は‘ O’)、‘M-[’ (実際は‘ [’)です。 21.15 キーのバインドのためのコマンド ==================================== このセクションではキーバインディングを変更するための便利な対話的インター フェイスを説明します。これらは‘define-key’を呼び出すことにより機能します 。 ユーザーはinitファイルにたいしてシンプルなカスタマイズを行うとき、し ばしば‘global-set-key’を使用します。たとえば、 (global-set-key (kbd "C-x C-\\") 'next-line) または (global-set-key [?\C-x ?\C-\\] 'next-line) または (global-set-key [(control ?x) (control ?\\)] 'next-line) は、次の行に移動するように‘C-x C-\’を再定義します。 (global-set-key [M-mouse-1] 'mouse-set-point) は、メタキーを押してマウスの第一ボタン(左ボタン)をクリックすると、クリッ クした箇所にポイントをセットするように再定義します。 バインドするキーのLisp指定に非ASCII文字のテキストを使用するときには注 意してください。マルチバイトとして読み取られたテキストがあるなら、Lispフ ァイル内でマルチバイトテキストが読み取られるときのように(*note Loading Non-ASCII::を参照)、マルチバイトとしてキーをタイプしなければなりません。 たとえば、 (global-set-key "ö" 'my-function) ; bind o-umlaut または (global-set-key ?ö 'my-function) ; bind o-umlaut をLatin-1のマルチバイト環境で使用すると、これらのコマンドはLatin-1端末か ら送信されたバイトコード246(‘M-v’)ではなく、コード246のマルチバイト文字 に実際にはバインドされます。このバインディングを使用するためには適切な入 力メソッド(*note Input Methods: (emacs)Input Methods.を参照)を使用して、 キーボードをデコードする方法をEmacsに教える必要があります。 -- Command: global-set-key key binding この関数はカレントグローバルマップ内でKEYのバインディングを BINDINGにセットする。 (global-set-key KEY BINDING) ≡ (define-key (current-global-map) KEY BINDING) -- Command: global-unset-key key この関数はカレントグローバルマップからKEYのバインディングを削除する 。 プレフィクスとしてKEYを使用する長いキーの定義の準備に使用するのもこ の関数の1つの用途である。KEYが非プレフィクスのようなバインディング をもつならこの使い方は許容されないだろう。たとえば、 (global-unset-key "\C-l") ⇒ nil (global-set-key "\C-l\C-l" 'redraw-display) ⇒ nil この関数は以下のように‘define-key’を使用するのと等しい: (global-unset-key KEY) ≡ (define-key (current-global-map) KEY nil) -- Command: local-set-key key binding この関数はカレントローカルキーマップ内のKEYのバインディングを BINDINGにセットする。 (local-set-key KEY BINDING) ≡ (define-key (current-local-map) KEY BINDING) -- Command: local-unset-key key この関数はカレントローカルキーマップからKEYのバインディングを削除す る。 (local-unset-key KEY) ≡ (define-key (current-local-map) KEY nil) 21.16 キーマップのスキャン ========================== このセクションではすべてのカレントキーマップをスキャンして、ヘルプ情報を プリントするために使用される関数を説明します。 -- Function: accessible-keymaps keymap &optional prefix この関数は、(0個以上のプレフィクスキーを通じて)KEYMAPから到達可能な すべてのキーマップのリストをリターンする。リターン値は‘(KEY . MAP)’のような形式の要素をもつ連想配列(alist)である。ここでKEYは KEYMAP内での定義がMAPであるようなプレフィクスキーである。 alistの要素はKEYの長さにたいして昇順にソートされている。1つ目の要素 は常に‘([] . KEYMAP)’。これは指定されたキーマップがイベントなしのプ レフィクスによって、自分自身からアクセス可能だからである。 PREFIXが与えられたら、それはプレフィクスキーシーケンスである。その 場合にはPREFIXで始まるプレフィクスキーをもつサブマップだけが ‘accessible-keymaps’に含まれる。これらの要素の意味は ‘(accessible-keymaps)’の値の場合と同様であり、いくつかの要素が省略 されている点だけが異なる。 以下の例ではリターンされるalistにより‘^[’と表示されるキーがプ レフィクスキーであり、その定義がsparseキーマップ‘(keymap (83 . center-paragraph) (115 . foo))’であることが示される。 (accessible-keymaps (current-local-map)) ⇒(([] keymap (27 keymap ; 以降にたいするこのキーマップが繰り返されることに注意 (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) ...)) これらが実際に目にするであろうキーマップのすべてではない。 -- Function: map-keymap function keymap 関数‘map-keymap’はKEYMAP内のバインディングそれぞれにたいして1回 FUNCTIONを呼び出す。呼び出す際の引数はイベント型と、そのバインディ ングの値の2つ。KEYMAPに親キーマップがあれば、その親キーマップのバイ ンディングも含まれる。これは再帰的に機能する。つまりその親キーマッ プ自身が親キーマップをもてば、それのバインディングも含まれる、とい った具合である。 これはキーマップ内のすべてのバインディングを検証するもっとも明快な 方法である。 -- Function: where-is-internal command &optional keymap firstonly noindirect no-remap この関数は‘where-is’コマンド(*note Help: (emacs)Help.を参照)により 使用されるサブルーチンである。これはキーマップのセット内で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はこの関数がコマンドリマッピング(*note Remapping Commands::を参照)を扱う方法を決定する。興味深いケースが2つある: コマンドOTHER-COMMANDがCOMMANDにリマップされる場合: NO-REMAPが‘nil’ならOTHER-COMMANDにたいするバインディングを探し て、COMMANDにたいするバインディングであるかのようにそれらを扱 う。NO-REMAPが非‘nil’ならそれらのバインディングを探すかわりに 、利用可能なキーシーケンスリストにベクター‘[remap OTHER-COMMAND]’を含める。 COMMANDがOTHER-COMMANDにリマップされる場合: NO-REMAPが‘nil’なら、COMMANDではなくOTHER-COMMANDにたいするバ インディングをリターンする。NO-REMAPが非‘nil’なら、リマップさ れていることを無視してCOMMANDにたいするバインディングをリター ンする。 -- Command: describe-bindings &optional prefix buffer-or-name この関数はすべてのカレントキーバインディングのリストを作成して、 ‘*Help*’という名前のバッファーにそれを表示する。テキストはモードご とにグループ化されて順番はマイナーモード、メジャーモード、グローバ ルバインディングの順である。 PREFIXが非‘nil’なら、それはプレフィクスキーである。その場合にはリス トに含まれるのはPREFIXで始まるキーだけになる。 複数の連続するASCIIコードが同じ定義をもつとき、それらは ‘FIRSTCHAR..LASTCHAR’のようにまとめて表示される。この場合にはそれが どの文字に該当するかを理解するには、そのASCIIコードを知っている必要 がある。たとえばデフォルトグローバルマップでは文字‘ .. ~’は1行 で記述される。はASCIIの32,‘~’はASCIIの126で、その間のすべての 文字には通常のプリント文字(アルファベット文字や数字、区切り文字等 )が含まれる。これらの文字はすべて‘self-insert-command’にバインドさ れる。 BUFFER-OR-NAMEが非‘nil’のならそれはバッファーかバッファー名である。 その場合は‘describe-bindings’はカレントバッファーのかわりに、そのバ ッファーのバインディングをリストする。 21.17 メニューキーアップ ======================== キーマップはキーボードキーやマウスボタンにたいするバインディング定義と同 様に、メニューとして操作することができます。メニューは通常はマウスにより 操作されますが、キーボードでも機能させことができます。次の入力イベントに たいしてメニューキーマップがアクティブならキーボードメニュー機能がアクテ ィブになります。 21.17.1 メニューの定義 ---------------------- キーマップが“overallプロンプト文字列(overall prompt string)”をもつ場合に は、そのキーマップはメニューとして動作します。overallプロンプト文字列は キーマップの要素として表される文字列です(*note Format of Keymaps::を参照 )。この文字列にはメニューコマンドの目的を記述します。(もしあれば)Emacsは メニュー表示に使用されるツールキットに応じて、メニュータイトルに overallメニュー文字列を表示します(1)。キーボードメニューもoverallプロン プト文字列を表示します。 プロンプト文字列をもつキーマップを構築するもっとも簡単な方法は ‘make-keymap’、‘make-sparse-keymap’ (*note Creating Keymaps::を参照)、 ‘define-prefix-command’ (*note Definition of define-prefix-command::を参 照)を呼び出すときに引数として文字列を指定する方法です。キーマップをメニ ューとして操作したくなければ、これらの関数にたいしてプロンプト文字列を指 定しないでください。 -- Function: keymap-prompt keymap この関数はKEYMAPのoverallプロンプト文字列、もしなければ‘nil’をリタ ーンする。 メニューのアイテムは、そのキーマップ内のバインディングです。各バイン ディングはイベント型と定義を関連付けますが、イベント型はメニューの外見に は何の意味ももっていません(通常はイベント型としてキーボードが生成できな い擬似イベントのシンボルをメニューアイテムのバインディングに使用する)。 メニュー全体はこれらのイベントにたいするキーマップ内のバインディングから 生成されます。 メニュー内のアイテムの順序はキーマップ内のバインディングの順序と同じ です。‘define-key’は新たなバインディングを先頭に配置するので、メニューア イテムの順序が重要ならメニューの最後から先頭へメニューアイテムを定義する 必要があります。既存のメニューにアイテムを追加するときには、 ‘define-key-after’を使用してメニュー内の位置を指定できます(*note Modifying Menus::を参照)。 ---------- Footnotes ---------- (1) これはテキスト端末のようなツールキットを使用しないメニューにたい して要求されます。 21.17.1.1 単純なメニューアイテム ................................ メニューアイテムを定義するシンプル(かつ初歩的)な方法は、何らかのイベント 型(何のイベント型かは問題ではない)を以下のようにバインドすることです: (ITEM-STRING . REAL-BINDING) CARのITEM-STRINGはメニュー内で表示される文字列です。これは短いほうが望ま しく、1個から3個の単語が望ましいでしょう。この文字列は対応するコマンドの 動作を記述します。すべてのグラフィカルツールキットが非ASCIIテキストを表 示できる訳ではないことに注意してください(キーボードメニューとGTK+ツール キットの大部分では機能するだろう)。 以下のようにヘルプ文字列と呼ばれる2つ目の文字列を与えることもできます : (ITEM-STRING HELP . REAL-BINDING) HELPはマウスがそのアイテム上にあるときに、‘help-echo’テキストプロパティ (*note 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’を呼び出してください (*note Mode Line Format::を参照)。 21.17.1.2 拡張メニューアイテム .............................. メニューアイテムの拡張フォーマットは、単純なフォーマットに比べてより柔軟 かつ明快です。拡張フォーマットではシンボル‘menu-item’で始まるリストでイ ベント型を定義します。選択できない文字列にたいしては以下のようなバインデ ィングになります: (menu-item ITEM-NAME) 2つ以上のダッシュで始まる文字列はリストのセパレーターを指定します。*note Menu Separators::を参照してください。 選択可能な実際のメニューアイテムを定義するには以下のような拡張フォー マットでバインドします: (menu-item ITEM-NAME REAL-BINDING . ITEM-PROPERTY-LIST) ここでITEM-NAMEはメニューアイテム文字列を評価する式です。つまり文字列は 定数である必要はありません。3つ目の引数REAL-BINDINGは実行するコマンドで す。リストの最後の要素ITEM-PROPERTY-LISTは、その他の情報を含んだプロパテ ィリストの形式です。 以下はサポートされるプロパティのテーブルです: ‘:enable FORM’ FORMの評価結果はそのアイテムを有効にするかどうかを決定する(非 ‘nil’なら有効)。アイテムが無効なら▽まったくクリックできない。 ‘:visible FORM’ FORMの評価結果はそのアイテムを実際にメニューに表示するかどうかを決 定する(非‘nil’なら表示)。アイテムが非表示ならそのアイテムが定義され ていないかのようにメニューが表示される。 ‘:help HELP’ このプロパティHELPの値はそのアイテム上にマウスがある間に表示する help-echo文字列を指定する。この文字列は‘help-echo’テキストプロパテ ィ(*note Help display::を参照)と同じ方法で表示される。これはテキス トやoverlayにたいする‘help-echo’プロパティとは異なり、文字列定数で なければならないことに注意。 ‘:button (TYPE . SELECTED)’ このプロパティはラジオボタンとトグルボタンを定義する手段を提供する 。CARのTYPEには、‘:toggle’か‘:radio’のいずれかを指定する。CDRの SELECTEDはフォームで、評価結果によってそのボタンがカレントで選択さ れているかどうかを指定する。 “トグル(toggle)”はSELECTEDの値に応じてonかoffのいずれかがラベルされ るメニューアイテムである。コマンド自身はSELECTEDが‘nil’なら‘t’、 ‘t’なら‘nil’にSELECTEDを切り替える(toggleする)こと。以下は ‘debug-on-error’フラグが定義されているときにメニューアイテムをトグ ルする方法の例: (menu-item "Debug on Error" toggle-debug-on-error :button (:toggle . (and (boundp 'debug-on-error) debug-on-error))) これは‘toggle-debug-on-error’が変数‘debug-on-error’をトグルするコマ ンドとして定義されていることによって機能する。 “ラジオボタン”とはメニューアイテムのグループであり、常にただ1つのメ ニューアイテムだけが選択される(selected)。そのためにはどのメニュー アイテムが選択されているかを示す変数が存在する必要がある。グループ 内の各ラジオボタンにたいするSELECTEDフォームは、そのボタンを選択す るためにその変数が正しい値をもつかどうかをチェックする。そしてボタ ンのクリックにより変数をセットして、クリックされたボタンが選択され る。 ‘:key-sequence KEY-SEQUENCE’ このプロパティはそのメニューアイテムによって呼び出されるのと同じコ マンドにバインドされるかもしれないキーシーケンスを指定する。正しい キーシーケンスを指定すればメニュー表示の準備がより高速になる。 間違ったキーシーケンスを指定すると何の効果もない。Emacsはメニュー内 のKEY-SEQUENCEの表示前に、実際にそのKEY-SEQUENCEがそのメニューアイ テムと等価なのか検証する。 ‘:key-sequence nil’ このプロパティはそのメニューアイテムには等価なキーバインディングが 通常は存在しないことを示す。このプロパティを使用することにより Emacsはそのメニューアイテムにたいして等価なキーボード入力をキーマッ プから検索する必要がなくなるので、メニュー表示の準備時間が短縮され る。 しかしユーザーがそのアイテムの定義をキーシーケンスにリバインドする と、Emacsは‘:keys’プロパティを無視して結局は等価なキーボード入力を 見つけ出す。 ‘:keys STRING’ このプロパティはそのメニューにたいする等価なキーボード入力として表 示される文字列STRINGを指定する。STRING内ではドキュメント構文 ‘\\[...]’を使用できる。 ‘:filter FILTER-FN’ このプロパティはメニューアイテムを直接計算する手段を提供する。この プロパティの値FILTER-FNは引数が1つの関数で、呼び出し時の引数は REAL-BINDING。この関数はかわりに使用するバインディングをリターンす ること。 Emacs、メニューデータ構造の再表示や操作を行うすべてのタイミングでこ の関数を呼び出すかもしれないので、いつ呼び出されても安全なように関 数を記述すること。 21.17.1.3 メニューセパレーター .............................. メニューセパレーターはテキストを表示するかわりに、水平ラインでメニューを サブパーツに分割するメニューアイテムの一種です。メニューキーマップ内でセ パレーターは以下のように見えるでしょう: (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)) いくつかのシステムとディスプレイツールキットは、これらすべてのセパレ ータータイプを実際に処理しません。サポートされていないタイプのセパレータ ーを使用すると、メニューはサポートされている似た種別のセパレーターを表示 します。 21.17.1.4 メニューアイテムのエイリアス ...................................... 同じコマンドを使用するものの有効条件が異なるメニューアイテムを作成できれ ば便利な場合が時折あります。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’のキーバインディングを表示します。 21.17.2 メニューとマウス ------------------------ メニューキーマップがメニューを生成する通常の方法は、それをプレフィクスキ ーの定義とすることです(Lispプログラムは明示的にメニューをポップアップし てユーザーの選択を受け取ることができる。*note Pop-Up Menus::を参照)。 プレフィクスキーがマウスイベントで終わる場合には、Emacsはユーザーがマ ウスで選択できるように可視なメニューをポップアップすることによってメニュ ーキーマップを処理します。ユーザーがメニューアイテムをクリックしたときは 、そのメニューアイテムによりもたらされるバインディングの文字やシンボルが 何であれイベントが生成されます(メニューが複数レベルをもつ場合やメニュー バー由来ならメニューアイテムは1連のイベントを生成するかもしれない)。 メニューのトリガーにbutton-downイベントを使用するのが最善な場合もしば しばあります。その場合にはユーザーはマウスボタンをリリースすることによっ てメニューアイテムを選択できます。 メニューキーマップがネストされたキーマップにたいするバインディングを 含む場合、そのネストされたキーマップは“サブメニュー(submenu)”を指定しま す。それはネストされたキーマップのアイテム文字列によってラベル付けされれ メニューアイテムをもち、そのアイテムをクリックすることによって指定された サブメニューが自動的にポップアップされます。特別な例外としてメニューキー マップが単一のネストされたキーマップを含み、それ以外のメニューアイテムを 含まなければ、そのメニューはネストされたキーマップの内容をサブメニューと してではなく直接メニューに表示します。 しかしXツールキットのサポートなしでEmacsをコンパイルした場合、または テキスト端末の場合にはサブメニューはサポートされません。ネストされたキー マップはメニューアイテムとして表示されますが、それをクリックしてもサブメ ニューは自動的にポップアップされません。サブメニューの効果を模倣したけれ ば、ネストされたキーマップに‘@’で始まるアイテム文字列を与えることによっ てこれを行うことができます。これによりEmacsは別個の“メニューペイン(menu pane)”を使用してネストされたキーマップを表示します。‘@’の後の残りのアイ テム文字列はそのペインのラベルです。XツールキットのサポートなしでEmacsを コンパイルした場合、またはメニューがテキスト端末で表示されている場合には メニューペインは使用されません。この場合はアイテム文字列の先頭の‘@’は、 メニューラベル表示時には省略されて他に効果はありません。 21.17.3 メニューとキーボード ---------------------------- キーボードイベント(文字かファンクションキー)で終わるプレフィクスキーがメ ニューキーマップであるような定義をもつときには、そのキーマップはキーボー ドメニューのように動作します。ユーザーはキーボードでメニューアイテムを選 択して次のイベントを指定します。 Emacsはエコーエリアにキーボードメニュー、そのマップのoverallプロンプ ト文字列、その後に選択肢(そのマップのバインディングのアイテム文字列)を表 示します。そのバインディングを一度に全部表示できない場合、ユーザーは をタイプして候補の次の行を確認できます。連続してを使用するとメ ニューの最後に達して、その後は先頭へ巡回します(変数 ‘menu-prompt-more-char’はこのために使用する文字を指定する。デフォルトは )。 ユーザーがメニューから望ましい候補を見つけたら、バインディングがその 候補であるような対応する文字をタイプする必要があります。 -- Variable: menu-prompt-more-char この変数はメニューの次の行を確認するために使用する文字を指定する。 初期値は32でこれはのコード。 21.17.4 メニューの例 -------------------- 以下はメニューキーマップを定義する完全な例です。これはメニューバー内の ‘Edit’メニューにサブメニュー‘Replace’を定義して、その定義内で拡張メニュ ーフォーマット(*note Extended Menu Items::を参照)を使用します。例ではま ずキーマップを作成してそれに名前をつけています: (defvar menu-bar-replace-menu (make-sparse-keymap "Replace")) 次にメニューアイテムを定義します: (define-key menu-bar-replace-menu [tags-repl-continue] '(menu-item "Continue Replace" tags-loop-continue :help "Continue last tags replace operation")) (define-key menu-bar-replace-menu [tags-repl] '(menu-item "Replace in tagged files" tags-query-replace :help "Interactively replace a regexp in all tagged files")) (define-key menu-bar-replace-menu [separator-replace-tags] '(menu-item "--")) ;; ... バインディングがそのシンボルのために作成されることに注意してください。こ れらのシンボルは定義されるキーシーケンス内の角カッコ内に記述されます。こ のシンボルはコマンド名と同じときもあれば異なることもあります。これらのシ ンボルはファンクションキーとして扱われますが、これらはキーボード上の実際 のファンクションキーではありません。これらはメニュー自体の機能に影響しま せんが、ユーザーがメニューから選択したときにエコーエリアにエコーされて、 ‘where-is’と‘apropos’の出力に現れます。 この例のメニューはマウスによる使用を意図しています。もしキーボードの 使用を意図したメニュー、つまりキーボードイベントで終了するキーシーケンス にバインドされたメニューの場合には、メニューアイテムはキーボードでタイプ できる文字、または本当のファンクションキーにバインドされるべきです。 定義が‘("--")’のバインディングはセパレーターラインです。実際のメニュ ーアイテムと同様にセパレーターはキーシンボルをもち、この例では ‘separator-replace-tags’です。1つのメニューが2つのセパレーターをもつ場合 には、それらは2つの異なるキーシンボルをもたなければなりません。 以下では親メニュー内のアイテムとしてこのメニューがどのように表示され るかを記述しています: (define-key menu-bar-edit-menu [replace] (list 'menu-item "Replace" menu-bar-replace-menu)) これはシンボル‘menu-bar-replace-menu’自体ではなく、変数 ‘menu-bar-replace-menu’の値であるサブメニューキーマップを組み込むことに 注意してください。‘menu-bar-replace-menu’はコマンドではないので親メニュ ーアイテムにそのシンボルを使用するのは無意味です。 同じreplaceメニューをマウスクリックに割り当てたければ以下のようにして これを行うことができます: (define-key global-map [C-S-down-mouse-1] menu-bar-replace-menu) 21.17.5 メニューバー Bar ------------------------ Emacsは通常は各フレームの最上部に“メニューバー(menu bar)”を表示します。 *note (emacs)Menu Bars::を参照してください。メニューバーのアイテムはアク ティブキーマップ内で定義される偽りのファンクションキー‘menu-bar’のサブコ マンドです。 メニューバーにアイテムを追加するには、自分で偽りのファンクションキー (これをKEYと呼ぶこととする)を創作して、キーシーケンス‘[menu-bar KEY]’に たいするキーバインディングを作成します。ほとんどの場合において、そのバイ ンディングはメニューキーマップなので、メニューバーアイテム上でボタンを押 下すると他のメニューに導かれます。 メニューバーにたいして同じファンクションキーを定義するアクティブなキ ーマップが1つ以上存在するとき、そのアイテムは一度だけ出現します。ユーザ ーがメニューバーのそのアイテムをクリックすると、そのアイテムのすべてのサ ブコマンド、すなわちグローバルサブコマンド、ローカルサブコマンド、マイナ ーモードサブコマンドが組み合わされた単一のメニューを表示します。 変数‘overriding-local-map’は通常はメニューバーのコンテンツを決定する 際は無視されます。つまりメニューバーは‘overriding-local-map’が‘nil’の場 合にアクティブになるであろうキーマップから計算されます。*note Active Keymaps::を参照してください。 以下はメニューバーのアイテムをセットアップする例です: ;; (プロンプト文字列とともに)メニューキーマップを作成して ;; それをメニューバーアイテムの定義にする (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’メニューバーアイテムにたいしてグローバルキーマップに より使用される偽ファンクションキーです。グローバルメニューバーアイテムを 抑制する主な理由は、モード特有のアイテム用にスペースを確保するためです。 -- Variable: menu-bar-final-items メニューバーは通常はローカルマップで定義されるアイテムを終端にもつ グローバルアイテムを表示する。 この変数は通常の順番による位置ではなく、メニューの最後に表示するア イテムのための偽ファンクションキーのリストを保持する。デフォルト値 は‘(help-menu)’。したがって‘Help’メニューアイテムはメニューバーの最 後、ローカルメニューアイテムの後に表示される。 -- Variable: menu-bar-update-hook このノーマルフックはメニューバーの再表示の前に、メニューバーのコン テンツ更新のための再表示によって実行される。コンテンツを変化させる 必要があるメニューの更新に使用できる。このフックは頻繁に実行される ので、フックが呼び出す関数は通常は長い時間を要さないことを確実にす るよう助言する。 Emacsはすべてのメニューバーアイテムの隣に、(もしそのようなキーバイン ディングが存在するなら)同じコマンドを実行するキーバインディングを表示し ます。これはキーバインディングを知らないユーザーにたいして有用なヒントを 与える役目をもちます。コマンドが複数のバインディングをもつ場合、Emacsは 通常は最初に見つけたバインディングを表示します。コマンドのシンボルプロパ ティ‘:advertised-binding’に割り当てることによって特定のキーバインディン グを指定できます。*note Keys in Documentation::を参照してください。 21.17.6 ツールバー ------------------ “ツールバー(tool bar)”とはフレームの最上部、メニューバー直下にあるクリッ ク可能なアイコンの行のことです。*note (emacs)Tool Bars::を参照してくださ い。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はそのアイテムを表示する方法とアイテムの振る舞いを示すメニューアイテ ムキーバインディングです(*note Extended Menu Items::を参照)。 メニューキーマップの通常のプロパティ‘:visible’、‘:enable’、 ‘:button’、‘:filter’はツールバーバインディングでも有用で、いずれのプロパ ティも通常通りの意味をもちます。アイテム内のREAL-BINDINGはキーマップでは なくコマンドでなければなりません。言い換えるとこれはツールバーアイコンを プレフィクスキーとして定義するようには機能しないということです。 ‘:help’プロパティは、そのアイテム上にマウスがある間表示する help-echo文字列を指定します。これはテキストプロパティ‘help-echo’と同じ方 法で表示されます(*note Help display::を参照)。 これらに加えて‘:image’プロパティも使用するべきでしょう。ツールバー内 にイメージを表示するにはこのプロパティを使用します。 ‘:image IMAGE’ IMAGEは単一イメージ様式(single image specification)か4ベクターイメ ージ様式(vector of four image specifications)で指定する(*note Images::を参照)。4ベクターを使用する場合には状況に応じて以下のいず れかが使用される: item 0 アイテムが有効かつ選択されているときに使用。 item 1 アイテムが有効かつ未選択のときに使用。 item 2 アイテムが無効かつ選択されているときに使用。 item 3 アイテムが無効かつ未選択のときに使用。 GTK+バージョンとNSバージョンのEmacsは、無効および/または未選択のイメ ージをitem0から自動的に計算するので、item1からitem3は無視されます。 IMAGEが単一イメージ様式なあ、Emacsはそのイメージにエッジ検出アルゴリ ズム(edge-detection algorithm)を適用することによってツールバーの無効な状 態のボタンを描画します。 ‘:rtl’プロパティには右から左に記述する言語のためのイメージ候補を指定 します。これをサポートするのは現在のところGTK+バージョンのEmacsだけです 。 メニューバーと同様、ツールバーはセパレーター(*note Menu Separators::を 参照)を表示できます。ツールバーのセパレーターは水平ラインではなく垂直ラ インであり、1つのスタイルだけがサポートされます。これらはツールバーキー マップ内では‘(menu-item "--")’エントリーで表されます。ツールバーのセパレ ーターでは、‘:visible’のようなプロパティはサポートされません。GTK+と Nextstepのツールバーでは、セパレーターはネイティブに描画されます。それ以 外ではセパレーターは垂直ラインイメージを使用して描画されます。 デフォルトツールバーはコマンドシンボルの‘mode-class’プロパティに ‘special’をもつメジャーモードにたいしては、編集に特化したアイテムは表示 しないよう定義されています(*note Major Mode Conventions::を参照)。メジャ ーモードは、ローカルマップ内でバインディング‘[tool-bar FOO]’によって、グ ローバルバーにアイテムを追加するかもしれません。デフォルトツールバーの多 くを適宜流用するのができないかもしれないので、デフォルトツールバーを完全 に置き換えることは、いくつかのメジャーモードにとっては有意義です。デフォ ルトバインディングで‘tool-bar-map’を通じてインダイレクトすることにより、 これを簡単に行うことができます。 -- Variable: tool-bar-map デフォルトではグローバルマップは‘[tool-bar]’を以下のようにバインド する: (global-set-key [tool-bar] `(menu-item ,(purecopy "tool bar") ignore :filter tool-bar-make-keymap)) 関数‘tool-bar-make-keymap’は、変数‘tool-bar-map’の値より順番に実際 のツールバーマップをダイナミックに継承する。したがって通常はそのマ ップを変更することにより、デフォルト(グローバル)ツールバーを調整す ること。Infoモードのようないくつかのメジャーモードは、 ‘tool-bar-map’をバッファーローカルにして、それに異なるキーマップを セットすることによりグローバルツールバーを完全に置き換える。 以下のようなツールバーアイテムを定義するのに便利な関数があります。 -- Function: tool-bar-add-item icon def key &rest props この関数は‘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)) -- Function: tool-bar-add-item-from-menu command icon &optional map &rest props この関数は既存のメニューバインディングと矛盾しないツールバーアイテ ムの定義に有用。COMMANDのバインディングはMAP(デフォルトは ‘global-map’)内よりルックアップ(lookup: 照合)され、ICONにたいするイ メージ仕様は‘tool-bar-add-item’と同じ方法で見つけ出される。結果のバ インディングは‘tool-bar-map’に配置されるので、この関数の使用はグロ ーバルツールバーアイテムに限定される。 MAPには‘[menu-bar]’にバインドされた適切なキーマップが含まれていなけ ればならない。残りの引数PROPSはメニューアイテム仕様に追加する追加の プロパティリスト要素。 -- Function: tool-bar-local-item-from-menu command icon in-map &optional from-map &rest props この関数は非グローバルツールバーアイテムの作成に使用される。 IN-MAPに定義を作成するローカルマップを指定する以外は ‘tool-bar-add-item-from-menu’と同じように使用する。引数FROM-MAPは ‘tool-bar-add-item-from-menu’のMAPと同様。 -- Variable: auto-resize-tool-bars この変数が非‘nil’なら定義されたすべてのツールバーアイテムを表示する ためにツールバーは自動的にリサイズされるが、そのフレーム高さの1/4を 超えてリサイズされることはない。 値が‘grow-only’ならツールバーは自動的に拡張されるが縮小はされない。 ツールバーを縮小するためにユーザーは‘C-l’をエンターしてフレームを再 描画する必要がある。 GTKやNextstepとともにEmacsがビルドされた場合、ツールバーが表示でき るのは1行だけでありこの変数に効果はない。 -- Variable: auto-raise-tool-bar-buttons この変数が非‘nil’ならツールバーアイテム上をマウスが通過したとき、浮 き上がった形式(raised form)で表示される。 -- Variable: tool-bar-button-margin この変数はツールバーアイテムの周囲に追加する余白(extra margin)を指 定する。値はピクセル数を整数で指定する。デフォルトは4。 -- Variable: tool-bar-button-relief この変数はツールバーアイテムの影(shadow)を指定する。値はピクセル数 を整数で指定する。デフォルトは1。 -- Variable: tool-bar-border この変数はツールバーエリアの下に描画するボーダー高さを指定する。値 が整数なら高さのピクセル数。値が‘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) ファンクションキーに修飾を追加する方法についての詳細な情報は、*note Function Keys::を参照してください。 21.17.7 メニューの変更 ---------------------- 既存のメニューに新たなアイテムを挿入するときは、そのメニューの既存のアイ テムの中の特定の位置にアイテムを追加したいと思うかもしれません。 ‘define-key’を使用してアイテムを追加すると、そのアイテムは通常はメニュー の先頭に追加されます。メニュー内の他の位置にアイテムを追加するには ‘define-key-after’を使用します: -- Function: define-key-after map key binding &optional after ‘define-key’と同じようにMAP内にKEYにたいする値BINDINGのバインディン グを定義するが、MAP内でのバインディング位置はイベントAFTERのバイン ディングの後になる。引数KEYは長さ1 — 1要素だけのベクターか文字列に すること。しかしAFTERは単一のイベント型 — シーケンスではないシンボ ルか文字にすること。新たなバインディングはAFTERのバインディングの後 に追加される。AFTERが‘t’または省略された場合には、新たなバインディ ングはそのキーマップの最後に追加される。しかし新たなバインディング は継承されたすべてのキーマップの前に追加される。 以下は例: (define-key-after my-menu [drink] '("Drink" . drink-command) 'eat) これは偽ファンクションキーのバインディングを作成して、 のバインディングの直後に追加する。 以下はShellモードの‘Signals’メニュー内のアイテム‘break’の後に ‘Work’と呼ばれるアイテムを追加する方法: (define-key-after (lookup-key shell-mode-map [menu-bar signals]) [work] '("Work" . work-command) 'break) 21.17.8 easy-menu ----------------- 以下のマクロはポップアップメニューおよび/またはメニューバーメニューを定 義する便利な方法を提供します。 -- Macro: easy-menu-define symbol maps doc menu このマクロはMENUにより与えるコンテンツのポップアップメニューおよび /またはメニューバーサブメニューを定義する。 SYMBOLが非‘nil’なら、それはシンボルである。その場合、このマクロはド キュメント文字列DOCをもつ、メニューをポップアップ(*note Pop-Up Menus::を参照)する関数としてSYMBOLを定義する。SYMBOLはクォートしな いこと。 SYMBOLの値とは関係なく、MAPSがキーマップならメニューはメニューバー のトップレベルのメニュー(*note Menu Bar::を参照)としてMAPSに追加さ れる。これにはキーマップのリストも指定でき、その場合メニューはそれ らのキーマップに個別に追加される。 MENUの最初の要素は文字列でなければならず、それはメニューラベルの役 割をもつ。値には以下のキーワード/引数ペアーが任意の個数続くかもしれ ない: ‘:filter FUNCTION’ FUNCTIONは1つの引数(他のメニューアイテムのリスト)で呼び出され る関数でなければならず、メニュー内に表示される実際のアイテムを リターンする。 ‘:visible INCLUDE’ INCLUDEには式を指定する。その式が‘nil’に評価されるとメニューは 不可視になる。‘:included’は‘:visible’にたいするエイリアス。 ‘:active ENABLE’ ENABLEは式を指定する。その式が‘nil’に評価されるとメニューは選 択不可になる。‘:enable’は‘:active’にたいするエイリアス。 MENU内の残りの要素はメニューアイテム。 メニューアイテムには3要素のベクター‘[NAME CALLBACK ENABLE]’を指定で きる。ここでNAMEはメニューアイテム名(文字列)、CALLBACKはアイテム選 択時に実行するコマンドか評価される式。ENABLEが式で‘nil’に評価される と、そのアイテムの選択は無効になる。 かわりにメニューアイテムは以下の形式をもつことができる: [ NAME CALLBACK [ KEYWORD ARG ]... ] ここでNAMEとCALLBACKは上記と同じ意味をもち、オプションのKEYWORDと ARGの各ペアーは以下のいずれかである: ‘:keys KEYS’ KEYSはメニューアイテムにたいする等価なキーボード入力(文字列)で ある。等価なキーボード入力は自動的に計算されるので通常は必要な い。KEYSは表示前に‘substitute-command-keys’により展開される (*note Keys in Documentation::を参照)。 ‘:key-sequence KEYS’ KEYSは最初にメニューを表示される際に、Emacsを高速化するヒント になる。等価なキーボード入力がないことが既知なら‘nil’を指定す ること。それ以外ならメニューアイテムにたいする等価なキーボード 入力を指定する文字列かベクターを指定すること。 ‘:active ENABLE’ ENABLEには式を指定する。その式が‘nil’に評価されるとアイテムは 選択不可になる。ENABLEは‘:active’にたいするエイリアス。 ‘:visible INCLUDE’ INCLUDEには式を指定する。その式が‘nil’に評価されるとアイテムは 不可視になる。‘:included’は‘:visible’にたいするエイリアス。 ‘:label FORM’ FORMはメニューアイテムのラベル(デフォルトはNAME)の役目をもつ値 を取得するために表示される式である。 ‘:suffix FORM’ FORMは動的に評価される式であり、値はメニューエントリーのラベル に結合される。 ‘:style STYLE’ STYLEはメニューアイテムの型を記述するシンボルであり、 ‘toggle’(チェックボックス)、‘radio’(ラジオボタン)、またはそれ 以外(通常のメニューアイテムであることを意味する)のいずれかであ る。 ‘:selected SELECTED’ SELECTEDには式を指定し、その式の値が非‘nil’のときはチェックボ ックスまたはラジオボタンが選択状態になる。 ‘:help HELP’ HELPはメニューアイテムを説明する文字列。 かわりにメニューアイテムに文字列を指定できる。その場合には文字列は 選択不可なテキストとしてメニューに表示される。ダッシュから構成され る文字列はセパレーターとして表示される(*note Menu Separators::を参 照) かわりにメニューアイテムにMENUと同じフォーマットのリストを指定でき る。これはサブメニューとなる。 以下は‘easy-menu-define’を使用して*note Menu Bar::内で定義したメニュ ーと同等なメニューを定義する例: (easy-menu-define words-menu global-map "単語単位コマンドにたいするメニュー" '("Words" ["Forward word" forward-word] ["Backward word" backward-word])) 22 メジャーモードとマイナーモード ********************************* “モード(mode)”とはEmacsをカスタマイズする定義セットであり、編集時にオン /オフを切り替えることができます。モードには2つの種類があります。“メジャ ーモード(major modes)”とは互いに排他なモードであり、特定の種類のテキスト の編集にたいして使用されます。“マイナーモード(minor modes)”はユーザーが 個別に有効にすることができる機能を提供します。 このチャプターではメジャーモードとマイナーモードを記述する方法、それ らをモードラインに示す方法、そしてそれらのモードがユーザーが提供するフッ クを実行する方法を説明します。キーマップ(keymaps)や構文テーブル(syntax tables)のような関連するトピックについては*note Keymaps::と*note Syntax Tables::を参照してください。 22.1 フック =========== “フック(hook)”とは既存のプログラムから特定のタイミングで呼び出される関数 (複数可)を格納できる変数のことです。Emacsはカスタマイズ用にフックを提供 します。ほとんどの場合にはinitファイル内(*note Init File::を参照)でフッ クをセットアップしますが、Lispプログラムもフックをセットできます。標準的 なフック変数のリストは*note Standard Hooks::を参照してください。 Emacsのほとんどのフックは“ノーマルフック(normal hooks)”です。これらの 変数は、引数なしで呼び出される関数のリストを含んでいます。慣習により名前 が‘-hook’で終わるフックは、そのフックがノーマルフックであることを意味し ます。わたしたちは一貫した方法でフックを使用できるように、すべてのフック が可能な限りノーマルフックとなるよう努力しています。 すべてのメジャーモードコマンドは、初期化の最終ステップの1つとして、 “モードフック(mode hook)”と呼ばれるノーマルフックを実行するとみなされま す。これによってそのモードですでに作成されたバッファーローカル変数割り当 てをオーバーライドすることにより、ユーザーがそのモードの動作をカスタマイ ズするのが簡単になります。ほとんどのマイナーモード関数も最後にモードフッ クを実行します。しかしフックは他のコンテキストでも使用されます。たとえば フック‘suspend-hook’は、Emacsが自身をサスペンド(*note Suspending Emacs::を参照)する直前に実行されます。 フックにフック関数を追加するには‘add-hook’(*note Setting Hooks::を参 照)を呼び出す方法が推奨されています。フック関数には‘funcall’(*note What Is a Function::を参照)が受け入れる任意の種類の関数を指定できます。ほとん どのフック変数の初期値はvoidです。‘add-hook’はこれを扱う方法を知っていま す。‘add-hook’によりグローバルフックやバッファーローカルフックのいずれも 追加することが可能です。 フック変数の名前が‘-hook’で終わらなければ、それが恐らく“アブノーマル フック(abnormal hook)”であることを示しています。これはフック関数が引数と ともに呼ぶ出されること、または何らかの方法によってそのリターン値が使用さ れることを意味します。その関数の呼び出し方はそのフックのドキュメントに記 載されています。アブノーマルフックとして関数を追加するために‘add-hook’を 使用できますが、その関数はフック呼び出しの慣習にしたがって記述しななけれ ばなりません。慣習によりアブノーマルフックの名前の最後は‘-functions’です 。 変数の名前が‘-function’で終われば、その値は関数のリストではなく単一の 関数です。‘add-hook’を_単一関数フック_のように修正して使用することはでき ないので、かわりに‘add-function’を使用します(*note Advising Functions::を 参照)。 22.1.1 フックの実行 ------------------- このセクションではノーマルフックを実行するために使用される‘run-hooks’に ついて説明します。またさまざまな種類のアブノーマルフックを実行する関数に ついても説明します。 -- Function: run-hooks &rest hookvars この関数は引数として1つ以上のノーマルフック変数名を受け取って、各フ ックを順に実行する。引数はそれぞれノーマルフック変数であるようなシ ンボルであること。これらの引数は指定された順に処理される。 フック変数の値が非‘nil’ならその値は関数のリストであること。 ‘run-hooks’はすべての関数を引数なしで1つずつ呼び出す。 フック変数の値には、単一の関数(ラムダ式、またはシンボルの関数定義 )も指定でき、その場合‘run-hooks’はそれを呼び出す。しかしこの使い方 は時代遅れである。 フック変数がバッファーローカルならグローバル変数のかわりにそのバッ ファーローカル変数が使用される。しかしそのバッファーローカル変数が 要素‘t’を含む場合には、そのグローバルフック変数も同様に実行されるだ ろう。 -- Function: run-hook-with-args hook &rest args この関数は、HOOK内のすべての関数に1つの引数ARGSを渡して呼び出すこと によってアブノーマルフックを実行する。 -- Function: run-hook-with-args-until-failure hook &rest args この関数は各フック関数を順に呼び出すことによりアブノーマルフック関 数を実行し、それらのうち1つが‘nil’をリターンして失敗すると停止する 。それぞれのフック関数は引数としてARGSを渡される。この関数はフック 関数の1つが失敗して停止したら‘nil’、それ以外は非‘nil’値をリターンす る。 -- Function: run-hook-with-args-until-success hook &rest args この関数は各フック関数を順に呼び出すことによりアブノーマルフック関 数を実行して、それらのうち1つが非‘nil’値をリターンして成功したら停 止する。それぞれのフック関数は引数としてARGSを渡される。この関数は フック関数の1つが失敗して停止したらその値、それ以外は‘nil’をリター ンする。 22.1.2 フックのセットSetting Hooks ---------------------------------- 以下はLisp Interactionモードのときにモードフックを使用してAuto Fillモー ドをオンに切り替える例です: (add-hook 'lisp-interaction-mode-hook 'auto-fill-mode) -- Function: add-hook hook function &optional append local この関数はフック変数に関数FUNCTIONを追加する手軽な方法である。ノー マルフックと同じようにアブノーマルフックにたいしてもこの関数を使用 できる。FUNCTIONには正しい数の引数を受け付ける任意のLisp関数を指定 できる。たとえば、 (add-hook 'text-mode-hook 'my-text-hook-function) は‘text-mode-hook’と呼ばれるフックに‘my-text-hook-function’を追加す る。 HOOK内にFUNCTIONがすでに存在する場合(比較には‘equal’を使用)、 ‘add-hook’は2回目の追加を行わない。 FUNCTIONのプロパティ‘permanent-local-hook’が非‘nil’なら ‘kill-all-local-variables’(またはメジャーモードを変更しても)はその フック変数のローカル値から関数を削除しない。 ノーマルフックにたいしてフック関数は実行される順序に無関係であるよ うにデザインされるべきである。順序への依存はトラブルを招く。とはい えその順序は予測可能である。FUNCTIONは通常はフックリストの先頭に追 加されるので、(他の‘add-hook’呼び出しがなければ)それは最初に実行さ れる。オプション引数APPENDが非‘nil’なら、新たなフック関数はフックリ ストの最後に追加されて、実行されるのも最後になる。 ‘add-hook’はHOOKがvoidのとき、または値が単一の関数の場合には、値を 関数リストにセットまたは変更してそれらを扱うことができる。 LOCALが非‘nil’なら、グローバルフックリストではなくバッファーローカ ルフックリストにFUNCTIONを追加する。これはフックをバッファーローカ ルにして、そのバッファーローカルな値に‘t’を追加する。バッファーロー カルな値への‘t’の追加は、ローカル値と同じようにデフォルト値でもフッ ク関数を実行するためのフラグである。 -- Function: remove-hook hook function &optional local この関数はフック変数HOOKからFUNCTIONを削除する。これは‘equal’を使用 してFUNCTIONとHOOK要素を比較するので、その比較はシンボルとラムダ式 の両方で機能する。 LOCALが非‘nil’なら、それはグローバルフックリストではなくバッファー ローカルフックリストからFUNCTIONを削除する。 22.2 メジャーモード =================== メジャーモードは特定の種類のテキスト編集にEmacsを特化します。すべてのバ ッファーは一度に1つのメジャーモードをもちます。すべてのメジャーモードは “メジャーモードコマンド(major mode command)”に関連付けられていて、そのコ マンド名は‘-mode’で終わるべきです。このコマンドはローカルキーマップのよ うなさまざまなバッファーローカル変数をセットすることにより、カレントバッ ファーないでそのモードに切り替える配慮をします。*note Major Mode Conventions::を参照してください。 “Fundamentalモード”と呼ばれるモードはもっとも特化されていないメジャー モードであり、モード特有な定義や変数セッティングをもちません。 -- Command: fundamental-mode これはFundamentalモードにたいするメジャーモードコマンドである。他の モードコマンドと異なり、このモードはカスタマイズしてはならないこと になっているので、モードフックは何も_実行されない_(*note Major Mode Conventions::を参照)。 メジャーモードを記述するもっとも簡単な方法はマクロ ‘define-derived-mode’を使用する方法です。これは既存のメジャーモードを変 形して新たなモードをセットアップします。*note Derived Modes::を参照して ください。‘define-derived-mode’は多くのコーディング規約を自動的に強要す るので、たとえ新たなモードが他のモードから明示的に派生されない場合でも、 わたしたちは‘define-derived-mode’の使用を推奨します。派生元とするための 一般的なモードについては*note Basic Major Modes::を参照してください。 標準的なGNU EmacsのLispディレクトリーツリーには、いくつかのメジャーモ ードが‘text-mode.el’、‘texinfo.el’、‘lisp-mode.el’、‘rmail.el’のようなフ ァイルとして含まれています。モードの記述方法を確認するために、これらのラ イブラリーを学ぶことができます。 -- User Option: major-mode この変数のバッファーローカル値はカレントのメジャーモードにたいする シンボルを保持する。この変数のデフォルト値は新たなバッファーにたい するデフォルトのメジャーモードを保持する。標準的なデフォルト値は ‘fundamental-mode’である。 デフォルト値が‘nil’なら、‘C-x b’ (‘switch-to-buffer’)のようなコマン ドを通じてEmacsが新たなバッファーを作成したとき、新たなバッファーは 以前カレントだったバッファーのメジャーモードになる。例外として以前 のバッファーのメジャーモードのシンボルプロパティ‘mode-class’が値 ‘special’をもつ場合には、新たなバッファーはFundamentalモードになる (*note Major Mode Conventions::を参照)。 22.2.1 メジャーモードの慣習 --------------------------- メジャーモードにたいするすべてのコードはさまざまなコーディング規約にした がうべきであり、それらの規約にはローカルキーマップおよび構文テーブルの初 期化、関数名や変数名、フックにたいする規約が含まれます。 ‘define-derived-mode’マクロを使用すれば、これらの規約を自動的に配慮し ます。*note Derived Modes::を参照してください。Fundamentalモードは Emacsのデフォルト状態を表すモードなので、これらの規約が該当しないことに 注意してください。 以下の規約リストはほんの一部です。一般的にすべてのメジャーモードは Emacs全体が首尾一貫するよう、他のEmacsメジャーモードとの一貫性を目指すべ きです。ここでこの問題を洗い出すすべての想定される要点をリストするのは不 可能です。自身の開発するメジャーモードが通常の規約を逸脱する領域を示すよ うな場合には、Emacs開発者は互換性を保つようにしてください。 • 名前が‘-mode’で終わるようにメジャーモードコマンドを定義する。引数な しで呼び出されたときこのコマンドはキーマップ、構文テーブル、既存バ ッファーのバッファーローカル変数をセットアップして、カレントバッフ ァーを新たなモードに切り替えること。そのバッファーのコンテンツを変 更しないこと。 • そのモードで利用できる特別なコマンドを説明するドキュメント文字列を 記述する。*note Mode Help::を参照のこと。 そのユーザー自身のキーバインディングに自動的に適合してヘルプが表示 されるように、ドキュメント文字列に特別なドキュメントサブストリング ‘\[COMMAND]’、‘\{KEYMAP}’、‘\’を含めるとよいかもしれない。 *note Keys in Documentation::を参照のこと。 • メジャーモードコマンドは‘kill-all-local-variables’を呼び出すことに よって開始すること。これはノーマルフック‘change-major-mode-hook’を 実行してから、前のメジャーモードで効力のあったバッファーローカル変 数を解放する。*note Creating Buffer-Local::を参照のこと。 • メジャーモードコマンドは変数‘major-mode’にメジャーモードコマンドの シンボルをセットすること。これは‘describe-mode’がプリントするドキュ メントを探す手掛かりとなる。 • メジャーモードコマンドは変数‘mode-name’にそのモードの“愛称(pretty name)”をセットすること(これは通常は文字列だが他の利用可能な形式につ いては*note Mode Line Data::を参照)。このモード名はモードラインに表 示される。 • すべてのグローバル名は同じネームスペースにあるので、モードの一部で あるようなすべてのグローバルな変数、定数、関数はメジャーモード名(メ ジャーモード名が長いようなら短縮名)で始まる名前をもつこと。*note Coding Conventions::を参照されたい。 • プログラム言語のようなある種の構造型テキストを編集するためのメジャ ーモードでは、その構造に応じたテキストのインデントがおそらく有用で あろう。したがってそのようなモードは‘indent-line-function’に適切な 関数をセットするとともに、インデント用のその他の変数をカスタマイズ するべきだろう。*note Auto-Indentation::を参照のこと。 • メジャーモードは、通常はそのモードにあるすべてのバッファーのローカ ルキーマップとして使用されるモード自身のキーマップをもつこと。メジ ャーモードコマンドはそのローカルマップをインストールするために、 ‘use-local-map’を呼び出すこと。詳細は*note Active Keymaps::を参照さ れたい。 このキーマップは‘MODENAME-mode-map’という名前のグローバル変数に永続 的に格納されること。そのモードを定義するライブラリーは、通常はこの 変数をセットする。 モード用のキーマップ変数をセットアップするコードの記述する方法に関 するアドバイスは*note Tips for Defining::を参照されたい。 • メジャーモードのキーマップ内でバインドされるキーシーケンスは、通常 は‘C-c’で始まってその後にコントロール文字、数字、‘{’、‘}’、‘<’、 ‘>’、‘:’、‘;’が続くこと。その他の記号文字(punctuation characters)は マイナーモード、通常のアルファベット文字はユーザー用に予約済みであ る。 メジャーモードは‘M-n’、‘M-p’、‘M-s’などのキーもリバインドできる。 ‘M-n’と‘M-p’にたいするバインディングは、通常は 前方か後方への移動を 意味するような類のものであるべきだが、これが必ずしもカーソル移動を 意味する必要はない。 そのモードにより適した方法でテキストに同じ処理を行うコマンドを提供 する場合に、メジャーモードが標準的なキーシーケンスをリバインドする のは正当性がある。たとえばプログラム言語を編集するためのメジャーモ ードは、その言語にとってより良く機能する方法で、‘C-M-a’を関数の先頭 に移動するように再定義できる。 ある標準的なキーシーケンスの標準的な意味がそのモードではほとんど役 に立たないような場合にも、メジャーモードが標準的なキーシーケンスを リバインドする正当性がある。たとえば‘M-r’の標準的な意味はミニバッフ ァーではほとんど使用されないので、このキーシーケンスをリバインドす る。テキストの自己挿入を許さないDiredやRmailのようなメジャーモード がアルファベット文字や、その他のプリント文字を特別なコマンドに再定 義することには正当性がある。 • テキストを編集するメジャーモードは改行の挿入以外の何かにを定義 すべきではない。しかしユーザーが直接テキストを編集しない、Diredや Infoのような特別なモードにたいしては完全に異なることを行うように を再定義しても構わない。 • メジャーモードは、たとえばAuto-Fillモードを有効にする等の、主にユー ザーの好みに関するオプションを変更しないこと。それらのオプションは ユーザーに選択に任せること。ただし_もし_ユーザーがAuto-Fillモードを 使用すると決定したら、それが便利に機能するように他の変数をカスタマ イズすること。 • モードは自身の構文テーブルをもつことができ、他の関連するモードと構 文テーブルを共有するかもすることもできる。モードが自身の構文テーブ ルをもつ場合には、‘MODENAME-mode-syntax-table’という名前の変数にそ れを格納すること。*note Syntax Tables::を参照されたい。 • コメントにたいする構文をもつ言語を扱うモードは、コメント構文を定義 する変数をセットすること。*note Options Controlling Comments: (emacs)Options for Comments.を参照されたい。 • モードは自身のabbrevテーブルをもつことができ、他の関連するモードと 構文テーブルを共有することもできる。モードが自身のabbrevテーブルを もつ場合には、‘MODENAME-mode-abbrev-table’という名前の変数にそれを 格納すること。メジャーモードコマンドが自身で何らかのabbrevを定義す る場合には、‘define-abbrev’のSYSTEM-FLAG引数に‘t’を渡すこと。*note Defining Abbrevs::を参照されたい。 • モードは変数‘font-lock-defaults’にバッファーローカルな値をセットす ることによって、Font Lockモードにたいしてハイライトする方法を指定す ること(*note Font Lock Mode::を参照)。 • モードが定義するすべてのフェイスは、もし可能なら既存のEmacsフェイス を継承すること。*note Basic Faces::と*note Faces for Font Lock::を 参照されたい。 • モードは変数‘imenu-generic-expression’、 ‘imenu-prev-index-position-function’と ‘imenu-extract-index-name-function’の2つの変数、または変数 ‘imenu-create-index-function’にバッファーローカルな値をセットするこ とによってImenuがバッファー内の定義やセクションを探す方法を指定する こと(*note Imenu::を参照)。 • モードは‘eldoc-documentation-function’にローカル値を指定して、 ElDocモードがそのモードを処理する方法を指定できる。 • モードはスペシャルフック‘completion-at-point-functions’に1つ以上の バッファーローカルエントリーを追加することにより、さまざまなキーワ ードの補完方法を指定できる。*note Completion in Buffers::を参照のこ と。 • Emacsのカスタマイズ変数にたいしてバッファーローカルなバインディング を作成するには、‘make-variable-buffer-local’ではなくメジャーモード コマンド内で‘make-local-variable’を使用すること。関数 ‘make-variable-buffer-local’はそれ以降にカスタマイズ変数をセットす るすべてのバッファーにたいしてその変数をローカルにして、そのモード を使用しないバッファーにたいしても影響があるだろう。そのようなグロ ーバルな効果はモードにとって好ましくない。*note Buffer-Local Variables::を参照のこと。 稀な例外としてLispパッケージ内で‘make-variable-buffer-local’を使用 する唯一の正当な方法は、そのパッケージ内でのみ使用される変数にたい して使用をする場合である。他のパッケージにより使用される変数にたい してこの関数を使用すると競合が発生するだろう。 • すべてのメジャーモードは‘MODENAME-mode-hook’という名前のノーマルな “モードフック(mode hook)”をもつこと。メジャーモードコマンドは ‘run-mode-hooks’の呼び出しを一番最後に行うこと。これはノーマルフッ ク‘change-major-mode-after-body-hook’、モードフック、その後に ‘after-change-major-mode-hook’を実行する。*note Mode Hooks::を参照 のこと。 • メジャーモードコマンドは“親モード(parent mode)”と呼ばれる他のいくつ かのメジャーモードを呼び出すことにより開始されるかもしれず、それら のセッティングのいくつかを変更するかもしれない。これを行うモードは “派生モード(derived mode)”と呼ばれる。派生モードを定義する推奨方法 は‘define-derived-mode’マクロの使用だが必須ではない。そのようなモー ドは‘delay-mode-hooks’フォーム内で親のモードコマンドを呼び出すこと (‘define-derived-mode’は自動的にこれを行う)。*note Derived Modes::と *note Mode Hooks::を参照されたい。 • ユーザーがそのモードのバッファーから他のモードのバッファーに切り替 える際に特別な何かを行う必要がある場合、モードは ‘change-major-mode-hook’にたいしてバッファーローカル値をセットアッ プできる(*note Creating Buffer-Local::を参照)。 • そのモードが、(ユーザーがキーボードでタイプしたテキストや外部ファイ ルのテキストではなく)モード自身が生成する特別に用意されたテキストに たいしてのみ適している場合、メジャーモードコマンドのシンボルは以下 のように‘mode-class’という名前のプロパティに値‘special’をputするこ と: (put 'funny-mode 'mode-class 'special) これはEmacsにたいしてカレントバッファーがFunnyモードのときに新たな バッファーを作成したとき、たとえ‘major-mode’のデフォルト値が‘nil’で あってもそのバッファーをFunnyモードにしないよう指示する。デフォルト では‘major-mode’にたいする値‘nil’は新たなバッファー作成時にカレント バッファーのメジャーモードを使用することを意味するが(*note Auto Major Mode::を参照)、‘special’なモードにたいしてはかわりに Fundamentalモードが使用される。Dired、Rmail、Buffer Listのようなモ ードはこの機能を使用する。 関数‘view-buffer’はmode-classがspecialであるようなバッファーでは Viewモードを有効にしない。そのようなモードは通常は自身でViewに相当 するバインディングを提供するからである。 ‘define-derived-mode’マクロは親モードがspecialなら、自動的に派生モ ードをspecialにマークする。親モードでspecialモードが有用ならそれを 継承したモードでも有用だろう。*note Basic Major Modes::を参照のこと 。 • 新たなモードを識別可能な特定のファイルにたいするデフォルトとしたけ れば、そのようなファイル名にたいしてそのモードを選択するために ‘auto-mode-alist’に要素を追加する。autoload用にモードコマンドを定義 する場合には、‘autoload’を呼び出すのと同じファイル内にその要素を追 加すること。モードコマンドにたいしてautoload cookieを使用する場合は に、その要素を追加するフォームにたいしてもautoload cookieを使用でき る(*note autoload cookie::を参照)。モードコマンドをautoloadしない場 合には、モード定義を含むファイル内で要素を追加すれば十分である。 • 悪影響を与えることなく1回以上評価されるように、モード定義はファイル 内のトップレベルのフォームとして記述すべきである。たとえばすでに値 をもつ変数が再初期化されないように、モードに関連した変数をセットす るときは‘defvar’か‘defcustom’を使用する(*note Defining Variables::を 参照)。 22.2.2 Emacsがメジャーモードを選択する方法 ------------------------------------------ Emacsはファイルをvisitするとき、ファイル名やファイル自体の内容などの情報 を元にそのバッファーにたいするメジャーモードを選択します。またファイルの テキスト内で指定されたローカル変数も処理します。 -- Command: normal-mode &optional find-file この関数はカレントバッファーにたいして適切なメジャーモード、および バッファーローカル変数のバインディングを設定する。これはまず ‘set-auto-mode’(以下参照)を呼び出して、その後に ‘hack-local-variables’を実行してパース処理を行い、そのファイルのロ ーカル変数(*note File Local Variables::を参照)を適切にバインドまた は評価する。 ‘normal-mode’のFIND-FILE引数が非‘nil’なら、‘normal-mode’は ‘find-file’関数が自身を呼び出したとみなす。この場合、 ‘normal-mode’はそのファイル内の‘-*-’行、またはファイルの最後にある ローカル変数を処理できる。これを行うかどうかは変数 ‘enable-local-variables’が制御する。ファイルのローカル変数セクショ ンの構文は*note Local Variables in Files: (emacs)File Variables.を 参照のこと。 インタラクティブに‘normal-mode’を実行すると、引数FIND-FILEは通常は ‘nil’である。この場合、‘normal-mode’は無条件に任意のファイルローカ ル変数を処理する。 この関数はメジャーモードを選択するために‘set-auto-mode’を呼び出す。 この関数がモードを特定しなければ、そのバッファーの‘major-mode’(以下 参照)のデフォルト値により決定されるメジャーモードに留まる。 ‘normal-mode’はメジャーモードコマンド呼び出しの周囲に ‘condition-case’を使用するのでエラーはcatchされて、‘File mode specification error’とともに元のエラーメッセージがその後に報告され る。 -- Function: set-auto-mode &optional keep-mode-if-same この関数はカレントバッファーにたいして適切なメジャーモードを選択す る。この選択は関数自身の(優先順位による)決定にもとづく。優先順位は ‘-*-’行、ファイル終端近傍の‘mode:’ローカル変数すべて、‘#!’行 (‘interpreter-mode-alist’を使用)、バッファーの先頭のテキスト (‘magic-mode-alist’を使用)、最後がvisitされるファイル名 (‘auto-mode-alist’を使用)の順である。*note How Major Modes are Chosen: (emacs)Choosing Modes.を参照のこと。 ‘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’にセットする。 -- Function: set-buffer-major-mode buffer この関数はBUFFERのメジャーモードを‘major-mode’のデフォルト値にセッ トする。‘major-mode’が‘nil’なら、(それが適切なら)カレントバッファー のメジャーモードを使用する。例外としてBUFFERの名前が‘*scratch*’なら 、モードを‘initial-major-mode’にセットする。 バッファーを作成する低レベルのプリミティブはこの関数を使用しないが 、‘switch-to-buffer’や‘find-file-noselect’のような中位レベルのコマ ンドは、バッファー作成時は常にこの関数を使用する。 -- User Option: initial-major-mode この変数の値は‘*scratch*’バッファーの初期のメジャーモードを決定する 。値はメジャーモードコマンドであるようなシンボルであること。デフォ ルト値は‘lisp-interaction-mode’。 -- Variable: interpreter-mode-alist この変数は‘#!’行内のコマンドインタープリターを指定するスクリプトに たいして使用するメジャーモードを指定する。変数の値は‘(REGEXP . MODE)’という形式の要素をもつalistである。これはそのファイルが ‘\\`REGEXP\\'’にマッチするインタープリターを指定する場合にはMODEを 使用することを意味する。たとえばデフォルト要素の1つは ‘("python[0-9.]*" . python-mode)’である。 -- Variable: magic-mode-alist この変数の値は‘(REGEXP FUNCTION)’という形式の要素をもつalistである 。ここでREGEXPは正規表現、FUNCTIONは関数、または‘nil’である。ファイ ルをvisitした後にバッファーの先頭のテキストがREGEXPにマッチした場合 、FUNCTIONが非‘nil’なら‘set-auto-mode’はFUNCTIONを呼び出す。 FUNCTIONが‘nil’なら‘auto-mode-alist’がモードを決定する。 -- Variable: magic-fallback-mode-alist これは‘magic-mode-alist’と同様に機能するが、そのファイルにたいして ‘auto-mode-alist’がモードを指定しない場合だけ処理される点が異なる。 -- Variable: 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’ (*note File Name Components::を参照)を使用して展開されたファイル名(*note File Name Expansion::を参照)から取り除かれてREGEXPとマッチされて、 ‘set-auto-mode’はそれに対応するMODE-FUNCTIONを呼び出す。この機能に よりほとんどのファイルにたいしてEmacsが適切なメジャーモードを選択す ることが可能になる。 ‘auto-mode-alist’の要素が‘(REGEXP FUNCTION t)’という形式なら、 FUNCTIONを呼び出した後にEmacsは前回マッチしなかったファイル名部分に たいしてマッチするために再度‘auto-mode-alist’を検索する。この機能は 圧縮されたパッケージにたいして有用である。‘("\\.gz\\'" FUNCTION t)’という形式のエントリーは、ファイルを解凍してから‘.gz’抜きのファ イル名の解凍されたファイルを適切なモードに置く。 以下は‘auto-mode-alist’の先頭に複数のパターンペアーを追加する方法の 例である(あなたはinitファイル内でこの種の式を使ったことがあるかもし れない)。 (setq auto-mode-alist (append ;; ドットで始まる(ディレクトリー名付きの)ファイル名 '(("/\\.[^/]*\\'" . fundamental-mode) ;; ドットのないファイル名 ("/[^\\./]*\\'" . fundamental-mode) ;; ‘.C’で終わるファイル名 ("\\.C\\'" . c++-mode)) auto-mode-alist)) 22.2.3 メジャーモードでのヘルプ入手 ----------------------------------- ‘describe-mode’関数はメジャーモードに関する情報を提供します。これは通常 は‘C-h m’にバインドされています。この関数は変数‘major-mode’ (*note Major Modes::を参照)の値を使用します。すべてのメジャーモードがこの変数をセット する必要があるのはこれが理由です。 -- Command: describe-mode &optional buffer このコマンドはカレントバッファーのメジャーモードとマイナーモードの ドキュメントを表示する。この関数はメジャーモードおよびマイナーモー ドのコマンドのドキュメント文字列を取得するために‘documentation’関数 を使用する(*note Accessing Documentation::を参照)。 BUFFER引数に非‘nil’を指定してLispから呼び出されると、この関数はカレ ントバッファーではなくそのバッファーのメジャーモードとマイナーモー ドのドキュメントを表示する。 22.2.4 派生モードの定義 ----------------------- 新しいメジャーモードを定義する推奨方法は、‘define-derived-mode’を使用し て既存のメジャーモードから派生させる方法です。それほど近いモードが存在し ない場合は‘text-mode’、‘special-mode’、または‘prog-mode’から継承するべき です。*note Basic Major Modes::を参照してください。これらがいずれも適切 でなければ、‘fundamental-mode’から継承することができます(*note Major Modes::を参照)。 -- Macro: define-derived-mode variant parent name docstring keyword-args... body... このマクロはVARIANTをメジャーモードコマンドとして定義して、NAMEをモ ード名の文字列形式とする。VARIANTとPARENTはクォートされていないシン ボルであること。 新たなコマンドVARIANTは関数PARENTを呼び出すよう定義されて、その後そ の親モードの特定の性質をオーバーライドする。 • 新たなモードは‘VARIANT-map’という名前の、自身のsparseキーマッ プ(疎キーマップ)をもつ。‘define-derived-mode’は‘VARIANT-map’が すでにセットされていて、かつすでに親をもつ場合を除いて親モード のキーマップを新たなマップの親キーマップにする。 • 新たなモードは自身の構文テーブル(syntax table)をもち、それは変 数‘VARIANT-syntax-table’に保持される。ただし‘:syntax-table’キ ーワード(以下参照)を使用してこれをオーバーライドした場合は異な る。‘define-derived-mode’は‘VARIANT-syntax-table’がすでにセッ トされていて、かつ標準的な構文テーブルよ異なる親をもつ場合を除 いて、親モードの構文テーブルを‘VARIANT-syntax-table’の親とする 。 • 新たなモードは自身のabbrevテーブル(略語テーブル)をもち、それは 変数‘VARIANT-abbrev-table’に保持される。ただし ‘:abbrev-table’キーワード(以下参照)を使用してこれをオーバーラ イドした場合は異なる。 • 新たなモードは自身のモードフック‘VARIANT-hook’をもつ。これはこ のフックを実行した後に、最後に‘run-mode-hooks’によって自身の祖 先となるモードのフックを実行する。 これらに加えてBODYでPARENTのその他の性質をオーバーライドする方法を 指定できます。コマンドVARIANTは通常のオーバーライドをセットアップし た後、そのモードのフックを実行する直前にBODY内のフォームを評価しま す。 PARENTが非‘nil’の‘mode-class’シンボルプロパティをもつ場合、 ‘define-derived-mode’はVARIANTの‘mode-class’プロパティに同じ値をセ ットします。これはたとえばPARENTがspecialモードならVARIANTも specialモードになることを保証します(*note Major Mode Conventions::を 参照)。 PARENTにたいして‘nil’を指定することもできます。これにより新たなモー ドは親をもたなくなります。その後に‘define-derived-mode’は上述のよう に振る舞いますが、当然PARENTにつながるすべてのアクションは省略され ます。 引数DOCSTRINGは新たなモードにたいするドキュメント文字列を指定します 。‘define-derived-mode’はこのドキュメント文字列の最後にそのモードフ ックに関する一般的な情報と、その後にそのモードのキーマップを追加し ます。DOCSTRINGを省略すると‘define-derived-mode’がドキュメント文字 列を生成します。 KEYWORD-ARGSはキーワードと値のペアです。値は評価されます。現在のと ころ以下のキーワードがサポートされています: ‘:syntax-table’ 新たなモードにたいする構文テーブルを明示的に指定するためにこれ を使用できる。‘nil’値を指定すると新たなモードはPARENTと同じ構 文テーブル、PARENTも‘nil’なら標準的な構文テーブルを使用する(こ れは‘nil’値の非キーワード引数は引数を指定しないのと同じという 通常の慣習には_したがわない_ことに注意)。 ‘:abbrev-table’ 新たなモードにたいするabbrevテーブルを明示的に指定するためにこ れを使用できる。‘nil’値を指定すると新たなモードはPARENTと同じ abbrevテーブル、PARENTも‘nil’なら ‘fundamental-mode-abbrev-table’を使用する(繰り返すが‘nil’値は このキーワードを指定しないことでは_ない_)。 ‘:group’ これが指定する場合、値はそのモードにたいするカスタマイズグルー プ(customization group)であること(すべてのメジャーモードがカス タマイズグループをもつ訳ではない)。‘customize-mode’コマンドは これを使用する。‘define-derived-mode’は指定されたカスタマイズ グループを自動的に_定義しない_。 以下は架空の例: (define-derived-mode hypertext-mode text-mode "Hypertext" "ハイパーテキスト用のメジャーモード \\{hypertext-mode-map}" (setq case-fold-search nil)) (define-key hypertext-mode-map [down-mouse-3] 'do-hyper-link) ‘define-derived-mode’が自動的に行うので、この定義内に ‘interactive’指定を記述してはならない。 -- Function: derived-mode-p &rest modes この関数はカレントメジャーモードがシンボルMODESで与えられたメジャー モードのいずれかから派生されていたら非‘nil’をリターンする。 22.2.5 基本的なメジャーモード ----------------------------- Fundamentalモードは別として他のメジャーモードの一般的な派生元となるメジ ャーモードが3つあります。それはTextモード、Progモード、およびSpecialモー ドです。Textモードはその本来もつ機能から有用なモードです(たとえば ‘.txt’ファイルの編集など)。一方、ProgモードとSpecialモードは主にそのよう なモード以外のモードの派生元とするために存在します。 新たなモードは直接と間接を問わず、可能な限りそれら3つのモードから派生 させるべきです。その理由の1つは関連のあるモードファミリー全体(たとえばす べてのプログラミング言語のモード)にたいして、ユーザーが単一のモードフッ クをカスタマイズできるからからです。 -- Command: text-mode Textモードは人間の言語を編集するためのメジャーモードである。このモ ードは文字‘"’と‘\’を区切り文字構文(punctuation syntax: *note Syntax Class Table::を参照)としてもち、‘M-’を‘ispell-complete-word’に バインドする(*note (emacs)Spelling::を参照)。 Textモードから派生されたメジャーモードの例としてHTMLモードがある。 *note SGML and HTML Modes: (emacs)HTML Mode.を参照のこと。 -- Command: prog-mode Progモードはプログラミング言語のソースコードを含むバッファーにたい する基本的なメジャーモードである。Emacsビルトインのプログラミング言 語用メジャーモードはこのモードから派生されている。 Progモードは‘parse-sexp-ignore-comments’を‘t’ (*note Motion via Parsing::を参照)、‘bidi-paragraph-direction’を‘left-to-right’ (*note Bidirectional Display::を参照)にバインドする。 -- Command: special-mode Specialモードはファイルから直接ではなく、Emacsにより特別 (specially)に生成されたテキストを含むバッファーにたいする基本的なメ ジャーモードである。Specialモードから派生されたメジャーモードは ‘mode-class’プロパティに‘special’が与えられる(*note Major Mode Conventions::を参照)。 Specialモードはバッファーを読み取り専用にセットする。このモードのキ ーマップはいくつかの一般的なバインディングを定義して、それには ‘quit-window’にたいする‘q’、‘revert-buffer’ (*note Reverting::を参 照)にたいする‘g’が含まれる。 Specialから派生されたメジャーモードの例としてはBuffer Menuモードが あり、これは‘*Buffer List*’バッファーにより使用される。*note Listing Existing Buffers: (emacs)List Buffers.を参照のこと。 これらに加えて表形式データのバッファーにたいするモードをTabulated Listモードから継承できます。このモードはSpecialモードから順に派生されて いるモードです。*note Tabulated List Mode::を参照してください。 22.2.6 モードフック ------------------- すべてのメジャーモードコマンドはモード独自のノーマルフック ‘change-major-mode-after-body-hook’、そのモードのモードフック、ノーマル フック‘after-change-major-mode-hook’を実行することによって終了すべきです 。これは‘run-mode-hooks’を呼び出すことにより行われます。もしそのモードが 派生モードなら自身のbody内で他のメジャーモード(親モード)を呼び出す場合に は、親モードが自身でこれらのフックを実行しないように‘delay-mode-hooks’の 中でこれを行うべきです。かわりに派生モードは親のモードフックも実行する ‘run-mode-hooks’を呼び出します。*note Major Mode Conventions::を参照して ください。 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’を使用 せずにメジャーモードを“手動”で定義したら、これらの慣習を自動的に処理する ように以下の関数を使用してください。 -- Function: run-mode-hooks &rest hookvars メジャーモードはこの関数を使用してそれらのモードフックを実行するこ と。これは‘run-hooks’ (*note Hooks::を参照)と似ているが、 ‘change-major-mode-after-body-hook’と ‘after-change-major-mode-hook’も実行する。 この関数が‘delay-mode-hooks’フォーム実行中に呼び出されたときはそれ らのフックを即座には実行しない。かわりに次の‘run-mode-hooks’呼び出 しでそれらを実行するようにアレンジする。 -- Macro: delay-mode-hooks body... あるメジャーモードコマンドが他のメジャーモードコマンドを呼び出すと きは‘delay-mode-hooks’の内部で行うこと。 このマクロはBODYを実行するが、BODY実行中はすべての ‘run-mode-hooks’呼び出しにたいしてそれらのフックの実行を遅延するよ う指示する。それらのフックは実際には‘delay-mode-hooks’構造の最後の 後、次の‘run-mode-hooks’呼び出しの間に実行されるだろう。 -- Variable: change-major-mode-after-body-hook これは‘run-mode-hooks’により実行されるノーマルフックである。これは そのモードのフックの前に実行される。 -- Variable: after-change-major-mode-hook これは‘run-mode-hooks’により実行されるノーマルフックである。これは すべての適切に記述されたメジャーモードコマンドの一番最後に実行され る。 22.2.7 Tabulated Listモード --------------------------- Tabulated Listモードとは、表形式データ(“エントリー”から構成されるデータ で各エントリーはそれぞれテキストの1行を占め、エントリーの内容は列に分割 されるようなデータ)を表示するためのメジャーモードです。Tabulated Listモ ードは行列の見栄えよくプリントする機能、および各列の値に応じて行をソート する機能を提供します。これはSpecialモードから派生されたモードです(*note Basic Major Modes::を参照)。 Tabulated Listモードは、より特化したメジャーモードの親モードとして使 用されることを意図しています。例としてはProcess Menuモード(*note Process Information::を参照)、Package Menuモード(*note (emacs)Package Menu::を参 照)が含まれます。 このような派生されたモードは‘tabulated-list-mode’を2つ目の引数に指定 して、通常の方法で‘define-derived-mode’を使用するべきです(*note Derived Modes::を参照)。‘define-derived-mode’フォームのbodyは以下にドキュメント されている変数に値を割り当てることにより、表形式データのフォーマットを指 定するべきです。その後にオプションで列名のヘッダーを挿入する関数 ‘tabulated-list-init-header’を呼び出すことができます。 派生されたモードは“リスティングコマンド(listing command)”も定義するべ きです。これはモードコマンドではなく、(‘M-x list-processes’のように)ユー ザーが呼び出すコマンドです。リスティングコマンドはバッファーを作成または 切り替えて、派生モードをオンにして表形式データを指定し、最後にそのバッフ ァーを事前設定(populate)するために‘tabulated-list-print’を呼び出すべきで す。 -- Variable: tabulated-list-format このバッファーローカル変数は表形式データのフォーマットを指定する。 値はベクターであり、ベクターの各要素はデータ列を表すリスト‘(NAME WIDTH SORT)’である。ここで • NAMEは列の名前(文字列)。 • WIDTHは列にたいして予約される文字数幅(整数)。最終列は各行の終 端までなので意味がない。 • SORTは列によりエントリーをソートする方法を指定する。‘nil’なら その列はソートに使用できない。‘t’なら列の文字列値を比較するこ とによりソートされる。それ以外なら‘tabulated-list-entries’の要 素と同じ形式の2つの引数をとる、‘sort’にたいする述語関数 (predicate function)であること。 -- Variable: tabulated-list-entries このバッファーローカル変数はTabulated Listバッファー内に表示される エントリーを指定する。値はリストか関数のいずれかであること。 値がリストなら各リスト要素は1つのエントリーに対応し、 ‘(ID CONTENTS)’という形式であること。ここで • IDは‘nil’、またはエントリーを識別するLispオブジェクト。Lispオ ブジェクトならエントリーを再ソートした際、カーソルは同じエント リー上に留まる。比較は‘equal’で行われる。 • CONTENTSは‘tabulated-list-format’と要素数が同じベクター。ベク ター要素は文字列かリスト。文字列ならバッファーにそのまま挿入さ れる。リスト‘(LABEL . PROPERTIES)’なら、LABELとPROPERTIESを引 数として‘insert-text-button’を呼び出すことによってテキストボタ ンを挿入することを意味する(*note Making Buttons::を参照)。 これらの文字列には改行を含めないこと。 それ以外なら、それは値は引数なしで呼び出されて上記形式のリストをリ ターンする関数であること。 -- Variable: tabulated-list-revert-hook このノーマルフックはTabulated Listバッファーのリバートに先立ち実行 される。派生モードは‘tabulated-list-entries’を再計算するためにこの フックに関数を追加できる。 -- Variable: tabulated-list-printer この変数の値はポイント位置にエントリー(エントリーを終端する改行を含 む)を挿入するために呼び出される関数である。この関数は ‘tabulated-list-entries’と同じ意味をもつ2つの引数IDとCONTENTSを受け 取る。デフォルト値はエントリーをそのまま挿入する関数である。より複 雑な方法でTabulated Listモードを使用するモードは別の関数を指定でき る。 -- Variable: tabulated-list-sort-key この変数の値はTabulated Listバッファーにたいするカレントのソートキ ーを指定する。‘nil’ならソートは行われない。それ以外なら‘(NAME . FLIP)’という形式の値をもつ。ここでNAMEは‘tabulated-list-format’内の 列目の1つとマッチする文字列、FLIPが非‘nil’なら逆順でのソートを意味 する。 -- Function: tabulated-list-init-header この関数はTabulated Listバッファーにたいする‘header-line-format’を 計算してセットし、列ヘッダー上でのクリックでソートを可能にするキー マップをヘッダー行に割り当てる。 Tabulated Listから派生したモードは、上記の変数(特に ‘tabulated-list-format’をセットした後のみ)をセットした後にこれを呼 び出すこと。 -- Function: tabulated-list-print &optional remember-pos update この関数はカレントバッファーにエントリーを挿入する。これをリスティ ングコマンドとして呼び出すこと。この関数はバッファーを消去して ‘tabulated-list-entries’で指定されるエントリーを ‘tabulated-list-sort-key’にしたがってソートした後、各エントリーを挿 入するために‘tabulated-list-printer’で指定される関数を呼び出す。 オプション引数REMEMBER-POSが非‘nil’なら、この関数はカレント行でID要 素を探して、もしあればすべてのエントリーを(再)挿入して、その後にそ のエントリーの移動を試みる。 オプション引数UPDATEが非‘nil’なら、この関数は最後のプリント以降に変 更されたエントリーの削除か追加だけを行う。この関数が最後に呼び出さ れて以降、ほとんどのエントリーが変更されていなければ、この関数は数 倍高速になる。結果の違いは‘tabulated-list-put-tag’を通じて配置され たタグが変更されていないエントリーから削除されないことだけである(通 常はすべてのタグが削除される)。 22.2.8 ジェネリックモード ------------------------- “genericモード(汎用モード)”とは、コメント構文にたいする基本的なサポート とFont Lockモードをもつシンプルなメジャーモードです。genericモードを定義 するにはマクロ‘define-generic-mode’を使用します。‘define-generic-mode’の 使い方の例は、ファイル‘generic-x.el’を参照してください。 -- Macro: define-generic-mode mode comment-list keyword-list font-lock-list auto-mode-list function-list &optional docstring このマクロはMODE (クォートされていないシンボル)という名前の genericモードコマンドを定義する。オプション引数DOCSTRINGは、そのモ ードコマンドにたいするドキュメント文字列。これを与えなければ ‘define-generic-mode’がデフォルトのドキュメント文字列を生成する。 引数COMMENT-LISTは要素が文字、2文字以下の文字列、またはコンスセルで ある。文字か文字列ならそのモードの構文テーブル内でコメント開始識別 子としてセットアップされる。エントリーがコンスセルならCARはコメント 開始識別子、CDRはコメント終了識別子としてセットアップされる(行末に よりコメントを終端させたければ後者に‘nil’を使用する)。構文テーブル のメカニズムには実際にコメントの開始および終了識別子に関する制限が あることに注意。 *note Syntax Tables::を参照のこと。 引数KEYWORD-LISTは‘font-lock-keyword-face’でハイライトするキーワー ドのリストである。キーワードは文字列であること。一方、 FONT-LOCK-LISTはハイライトするための追加の式リストである。このリス トの各要素は‘font-lock-keywords’の要素と同じ形式をもつこと。*note Search-based Fontification::を参照されたい。 引数AUTO-MODE-LISTは変数‘auto-mode-alist’に追加する正規表現のリスト である。これらのは、マクロ呼び出しの展開時ではなく、 ‘define-generic-mode’の実行時に追加される。 最後にFUNCTION-LISTは追加セットアップのためにモードコマンドに呼び出 される関数のリストである。これらの関数はモードフック変数 ‘MODE-hook’の実行の直前に呼び出される。 22.2.9 メジャーモードの例 ------------------------- おそらくTextモードは、Fundamentalを除いてもっともシンプルなモードです。 上述した慣習の多くを説明するために以下に‘text-mode.el’の抜粋を示します: ;; このモード用に構文テーブルを作成 (defvar text-mode-syntax-table (let ((st (make-syntax-table))) (modify-syntax-entry ?\" ". " st) (modify-syntax-entry ?\\ ". " st) ;; M-cで'hello'が'hello'でなく'Hello'になるよう'p'を追加 (modify-syntax-entry ?' "w p" st) st) "`text-mode'で使用される構文テーブル") ;; このモード用にキーマップを作成 (defvar text-mode-map (let ((map (make-sparse-keymap))) (define-key map "\e\t" 'ispell-complete-word) map) "`text-mode'のキーマップ `mail-mode'、`outline-mode'、`indented-text-mode'のような 他の多くのモードはこのマップ内で定義した全コマンドを継承する") そして実際にモードコマンドが定義される方法が以下になります: (define-derived-mode text-mode nil "Text" "人間が読むために記述されたテキストを編集するためのメジャーモード このモードではパラグラフを区切るのはブランク行か空白行だけである したがって適応型フィル(adaptive filling)の全恩恵を受けられる (変数`adaptive-fill-mode'を参照のこと) \\{text-mode-map} Textモードのオンによりノーマルフック`text-mode-hook'が実行される" (set (make-local-variable 'text-mode-variant) t) (set (make-local-variable 'require-final-newline) mode-require-final-newline) (set (make-local-variable 'indent-line-function) 'indent-relative)) (現在はデフォルト値が‘indent-relative’なので最後の行が冗長だが将来のバー ジョンで削除する予定。) 3つのLisp用モード(Lispモード、Emacs Lispモード、Lisp Interactionモー ド)はTextモードより多くの機能をもち、それにふさわしくコードもより複雑で す。そのようなモードの記述方法を説明するために‘lisp-mode.el’の抜粋を示し ます。 以下はLispモードの構文テーブルとabbrevテーブルを定義する方法です: ;; モード固有のテーブル変数の作成 (defvar lisp-mode-abbrev-table nil) (define-abbrev-table 'lisp-mode-abbrev-table ()) (defvar lisp-mode-syntax-table (let ((table (copy-syntax-table emacs-lisp-mode-syntax-table))) (modify-syntax-entry ?\[ "_ " table) (modify-syntax-entry ?\] "_ " table) (modify-syntax-entry ?# "' 14" table) (modify-syntax-entry ?| "\" 23bn" table) table) "`lisp-mode'で使用される構文テーブル") Lisp用の3つのモードは多くのコードを共有します。たとえば以下の関数呼び 出しによってさまざまな変数がセットされます: (defun lisp-mode-variables (&optional syntax keywords-case-insensitive) (when syntax (set-syntax-table lisp-mode-syntax-table)) (setq local-abbrev-table lisp-mode-abbrev-table) ... その中でも特に以下の関数はLispコメントを処理するために変数 ‘comment-start’をセットアップします: (make-local-variable 'comment-start) (setq comment-start ";") ... これらの異なるLisp用モードは、微妙に異なるキーマップをもちます。たと えばLispモードは‘C-c C-z’を‘run-lisp’にバインドしますが、他のLisp用モー ドはこれを行いません。とはいえすべてのLisp用モードに共通なコマンドがいく つかあります。以下のコードはそれらの共通コマンドをセットアップします: (defvar lisp-mode-shared-map (let ((map (make-sparse-keymap))) (define-key map "\e\C-q" 'indent-sexp) (define-key map "\177" 'backward-delete-char-untabify) map) "すべてのLisp用モードでコマンドを共有するためのキーマップ") そして以下がLispモードのためのキーマップをセットアップするコードです: (defvar lisp-mode-map (let ((map (make-sparse-keymap)) (menu-map (make-sparse-keymap "Lisp"))) (set-keymap-parent map lisp-mode-shared-map) (define-key map "\e\C-x" 'lisp-eval-defun) (define-key map "\C-c\C-z" 'run-lisp) ... map) "通常のLispモード用キーマップ `lisp-mode-shared-map'のすべてのコマンドはこのマップを継承する") 最後はLispモードのためのメジャーモードコマンドです: (define-derived-mode lisp-mode prog-mode "Lisp" "GNU Emacs Lisp以外のLispコードを編集するためのメジャーモード コマンド: あたかも後方に移動するようにタブをスペースに削除変換する パラグラフ区切りはブランク行でコメント開始はセミコロン \\{lisp-mode-map} `run-lisp'はinferior Lispジョブの開始と既存ジョブ から戻るための両方に使われるかもしれないことに注意 このモードへのエントリーによって `lisp-mode-hook'の値が非nilならそれを呼び出す" (lisp-mode-variables nil t) (set (make-local-variable 'find-tag-default-function) 'lisp-find-tag-default) (set (make-local-variable 'comment-start-skip) "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *") (setq imenu-case-fold-search t)) 22.3 マイナーモード =================== “マイナーモード(minor mode)”はメジャーモードの選択とは無関係にユーザーが 有効や無効にできるオプション機能の使用を提供します。マイナーモードは個別 、あるいは組み合わせて有効にできます。 ほとんどのマイナーモードはメジャーモードとは独立した機能を実装するの で、ほとんどのメジャーモードと一緒に使用することができます。たとえばAuto Fillモードはテキスト挿入を許容する任意のメジャーモードとともに機能します 。しかし少数ながら特定のメジャーモードに特化したマイナーモードもあります 。たとえばDiff Auto RefineモードはDiffモードとの使用だけを意図したマイナ ーモードです。 理想的にはマイナーモードは他のマイナーモードの効果と無関係に期待した 効果をもつべきです。任意の順序でマイナーモードをアクティブや非アクティブ にすることも可能であるべきです。 -- Variable: minor-mode-list この変数の値はすべてのマイナーモードコマンドのリスト。 22.3.1 マイナーモード記述の規約 ------------------------------- メジャーモードの記述に慣習があるように、マイナーモードの記述にも慣習があ ります。以下ではその慣習について説明します。これらの慣習にしたがうにはマ クロ‘define-minor-mode’を使用するのがもっとも簡単な方法です。*note Defining Minor Modes::を参照してください。 • 名前が‘-mode’で終わる変数を定義する。これを“モード変数(mode variable)”と呼ぶ。マイナーモードコマンドはこの変数をセットすること 。値はそのモードが無効なら‘nil’、有効なら非‘nil’になる。そのマイナ ーモードがバッファーローカルならこの変数もバッファーローカルである こと。 この変数はモードラインにマイナーモードの名前を表示するために ‘minor-mode-alist’と結合して使用される。これは ‘minor-mode-map-alist’を通じて、そのマイナーモードのキーマップがア クティブかどうかも判定する(*note Controlling Active Maps::を参照)。 個々のコマンドやフックもこの変数の値をチェックできる。 • モード変数と同じ名前をもつ“モードコマンド(mode command)”と呼ばれる コマンドを定義する。このコマンドの役目はモード変数の値のセットに加 えて、そのモードの機能を使用を実際に有効や無効にするために必要な他 のすべてを行うことである。 モードコマンドは1つのオプション引数を受け入れること。プレフィクス引 数なしでinteractiveに呼び出されたらモードをトグルする(toggle: 切り 替える。たとえば無効なら有効に、有効なら無効にする)こと。プレフィク ス引数とともにinteractiveに呼び出された場合にはその引数が正であれば モードを有効にして、それ以外なら無効にすること。 モードコマンドがLispから(つまり非interactiveに)呼び出された場合は、 引数が省略または‘nil’ならモードを有効にすること。引数がシンボル ‘toggle’ならモードをトグルして、それ以外なら上述の数引数とともに interactiveに呼び出されたときと同じ方法によってその引数を扱うこと。 以下はこの挙動の実装方法を示す例である(‘define-minor-mode’マクロが 生成するコードもこれに類似する)。 (interactive (list (or current-prefix-arg 'toggle))) (let ((enable (if (eq arg 'toggle) (not foo-mode) ; このモードのモード変数 (> (prefix-numeric-value arg) 0)))) (if enable DO-ENABLE DO-DISABLE)) やや複雑なこの挙動の理由は、ユーザーが簡単かつinteractiveにマイナー モードをトグルできることと、以下のようにモードフック内で簡単にマイ ナーモードを有効にできるからである: (add-hook 'text-mode-hook 'foo-mode) ‘foo-mode’モードコマンドは引数なしでLispから呼び出されたときは無条 件にそのマイナーモードを有効にするので、これは‘foo-mode’がすでに有 効でもそうでなくても正しく振る舞う。モードフック内でマイナーモード を無効にする場合は少々醜くなる: (add-hook 'text-mode-hook (lambda () (foo-mode -1))) しかしこれは頻繁には行われない。 • モードラインにマイナーモードを表示したければ、それぞれのマイナーモ ードにたいして要素を‘minor-mode-alist’に追加する(*note 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’(*note List Variables::を参照)を使用 すること: (add-to-list 'minor-mode-alist '(leif-mode " Leif")) これらに加えてメジャーモードにたいする慣習のいくつかはマイナーモード にたいしても同様に適用されます。それらの慣習はグローバルシンボルの名前、 初期化関数の最後でのフックの使用、キーマップおよびその他のテーブルの使用 です。 マイナーモードは、可能ならCustom(*note Customization::を参照)を通じた 有効化と無効化をサポートするべきです。これを行うには、モード変数は‘:type 'boolean’とともに‘defcustom’で通常は定義されるべきです。その変数をセット するだけではモードの有効化に不足なら、モードコマンドを呼び出すことにより モードを有効にする‘:set’メソッドも指定するべきです。そしてその変数のドキ ュメント文字列にCustomを通じて変数をセットしなければ効果がないことを注記 してください。さらにその定義をautoload cookie(*note 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) 22.3.2 キーマップとマイナーモード --------------------------------- マイナーモードはそれぞれ自身のキーマップをもつことができ、そのモードが有 効になるとそのキーマップがアクティブになります。マイナーモード用のキーマ ップをセットアップするには‘minor-mode-map-alist’というalistに要素を追加 します。*note 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’はユーザー用に予約済みです。*note Key Binding Conventions::を参照してください。 22.3.3 マイナーモードの定義 --------------------------- マクロ‘define-minor-mode’は、自己完結した単一定義内にモードを実装する便 利な方法を提供します。 -- Macro: define-minor-mode mode doc [init-value [lighter [keymap]]] keyword-args... body... このマクロは名前がMODE(シンボル)の新たなマイナーモードを定義する。 これはドキュメント文字列としてDOCをもつマイナーモードをトグルするた めにMODEという名前のコマンドを定義する。 トグルコマンドは1つのオプション(プレフィクス)引数を受け取る。引数な しでinteractiveに呼び出されると、そのモードのオンとオフをトグルする 。正のプレフィクス引数はモードを有効にして、それ以外のプレフィクス 引数はモードを無効にする。Lispから呼び出すと引数が‘toggle’ならモー ドをトグルして、引数が省略か‘nil’ならモードを有効にする。これはたと えばメジャーモードフック内でマイナーモードを有効にするのを簡便にす る。DOCが‘nil’なら、このマクロは上記を記述したデフォルトのドキュメ ント文字列を提供する。 デフォルトではこれはモードを有効にすると‘t’、無効にすると‘nil’にセ ットされる、MODEという名前の変数も定義する。この変数はINIT-VALUEに 初期化される。通常(以下参照)はこの値は‘nil’でなければならない。 文字列LIGHTERはモード有効時にモードライン内に何を表示するか指定する 。これが‘nil’ならこのモードはモードライン内に表示されない。 オプション引数KEYMAPはそのマイナーモードにたいするキーマップを指定 する。非‘nil’なら、それは(値がキーマップであるような)変数の名前かキ ーマップ、または以下の形式のalistであること (KEY-SEQUENCE . DEFINITION) ここでKEY-SEQUENCEとDEFINITIONは‘define-key’に渡すのに適した引数で ある(*note Changing Key Bindings::を参照)。KEYMAPはキーマップか alistであり、これは変数‘MODE-map’も定義する。 上記の3つの引数INIT-VALUE、LIGHTER、KEYMAPはKEYWORD-ARGSが使用され たときは(部分的に)省略できる。KEYWORD-ARGSはキーワードとその後の対 応する値により構成され、いくつかのキーワードは特別な意味をもつ: ‘:group GROUP’ 生成されるすべての‘defcustom’フォームで使用されるカスタムグル ープ名。MODE (後に‘-mode’がある場合はそれを除く)にたいするデフ ォルトである。*警告:* そのグループを定義するため‘defgroup’を正 しく記述していなければ、このデフォルトグループ名を使用してはな らない。*note Group Definitions::を参照のこと。 ‘:global GLOBAL’ 非‘nil’ならそのマイナーモードがバッファーローカルでなくグロー バルであることを指定する。デフォルトは‘nil’。 マイナーモードをグローバルにしたときの効果の1つは、MODE変数が カスタマイズ変数になることである。Customizeインターフェイスを 通じてこの変数をトグルするとモードがオンやオフになり、変数の値 は将来のEmacsセッション用に保存できるようになる(*note (emacs)Saving Customizations::を参照)。保存された変数が機能す るためにはEmacsが開始されるたびに‘define-minor-mode’フォームが 確実に評価されるようにすること。Emacsの一部ではないパッケージ にたいしては、‘:require’キーワードを指定するのがこれを行う一番 簡単な方法である。 ‘:init-value INIT-VALUE’ これはINIT-VALUE引数を指定するのと等しい。 ‘:lighter LIGHTER’ これはLIGHTER引数を指定するのと等しい。 ‘:keymap KEYMAP’ これはKEYMAP引数を指定するのと等しい。 ‘:variable PLACE’ これはそのモードの状態を格納するために使用されるデフォルトの変 数MODEを置き換える。これを指定するとMODE変数は定義されず、すべ てのINIT-VALUE引数は使用されない。PLACEは異なる名前の変数(あな た自身が定義しなければならない)、または‘setf’関数とともに使用 され得るすべてのもの(*note Generalized Variables::を参照)。 PLACEにはコンス‘(GET . SET)’も指定できる。ここでGETはカレント 状態をリターンする式であり、SETはそれをセットする1つの引数(状 態)をとる関数である。 ‘:after-hook AFTER-HOOK’ これはモードフック実行後に評価される単一のLispフォームを定義す る。これをクォートしないこと。 その他のすべてのキーワード引数は変数MODEにたいして生成された ‘defcustom’に直接渡される。 MODEという名前のコマンドは最初にMODEという名前の変数をセットする等 の標準的な動作を処理した後に、もしあればBODYフォームを実行する。そ れからモードフック変数‘MODE-hook’を実行してから‘:after-hook’内のフ ォームを評価して終了する。 INIT-VALUEの値は‘nil’でなければなりません。ただし、(1)Emacsによりその モードが事前ロードされている、または(2)たとえユーザーが要求しなくともモ ードを有効にするためにロードするのが容易な場合を除きます。たとえば他の何 かが有効でなければそのモードの効果がなく、常にそのタイミングでロードされ るような場合には、デフォルトでそのモードを有効にすることに害はありません 。しかしこの状況は通常はあり得ません。通常はINIT-VALUEの値は‘nil’でなけ ればなりません。 ‘easy-mmode-define-minor-mode’という名前はこのマクロにたいするエイリ アスです。 以下は‘define-minor-mode’の使い方の例です: (define-minor-mode hungry-mode "Hungryモードをトグルする 引数なしでinteractiveに呼び出すとモードをトグルする 正のプレフィクス引数でモードを有効に、その他のプレフィクス引数で 無効にする。Lispから呼び出す場合、引数を省略、またはnilなら モードを有効に、`toggle'なら状態をトグルする Hungryモードが有効なときは、C-DELキーは、 最後を除く先行するすべての空白を飲み込む コマンド \\[hungry-electric-delete] を参照" ;; 初期値 nil ;; モードラインの標示 " Hungry" ;; マイナーモードのバインディング '(([C-backspace] . hungry-electric-delete)) :group 'hunger) これは“Hungry mode”という名前のマイナーモード、モードをトグルする ‘hungry-mode’という名前のコマンド、モードが有効かどうかを示す ‘hungry-mode’という名前の変数、モードが有効なときそのキーマップを保持す る‘hungry-mode-map’という名前の変数を定義します。これは‘C-’にたいす るキーバインディングでキーマップを初期化します。また変数‘hungry-mode’を カスタムグループ‘hunger’に配置します。BODYフォームはありません — 多くの マイナーモードはそれを必要としません。 以下はこれを記述する等価な方法です: (define-minor-mode hungry-mode "Hungryモードをトグルする ...省略..." ;; 初期値 :init-value nil ;; モードラインへのインジケーター :lighter " Hungry" ;; マイナーモードのバインディング :keymap '(([C-backspace] . hungry-electric-delete) ([C-M-backspace] . (lambda () (interactive) (hungry-electric-delete t)))) :group 'hunger) -- Macro: define-globalized-minor-mode global-mode mode turn-on keyword-args... これはGLOBAL-MODEという名前をグローバルにトグルする。これはMODEとい う名前のバッファーローカルなマイナーモードをすべてのバッファーで有 効か無効にするということを意味する。あるバッファー内でそのマイナー モードをオンにするには関数TURN-ONを使用する。マイナーモードをオフに するには−1を引数としてMODEを呼び出す。 モードをグローバルに有効にすると、それ以降ファイルをvisitすることに よって作成されるバッファーやFundamental以外のメジャーモードを使用す るバッファーにも影響がある。しかしFundamentalで作成される新たなバッ ファーは検知しない。 これはCustomizeインターフェイス内でそのマイナーモードのオン/オフを 切り替えるカスタムオプションGLOBAL-MODE (*note Customization::)を定 義する。‘define-minor-mode’と同様に、たとえば‘:require’を与える等に よってEmacs開始時に毎回確実に‘define-globalized-minor-mode’フォーム が評価されるようにすること。 グローバルマイナーモードのモード変数にたいしてカスタムグループを指 定するにはKEYWORD-ARGS内で‘:group GROUP’を使用する。 一般的にはグローバル化されたマイナーモードを定義するときは、ユーザ ーがバッファーごとにモードを使用(または無効に)できるように非グロー バル版も定義すること。これにより特定のメジャーモード内でそのモード のフックを使用すればグローバルに有効化されたマイナーモードを無効に することができるようになる。 22.4 モードラインのフォーマット =============================== Emacsの各ウィンドウ(ミニバッファーウィンドウを除く)には、通常は最下部に モードラインがあってそのウィンドウ内に表示されたバッファーに関するステー タス情報がモードラインに表示されます。モードラインにはバッファー名、関連 するファイル、再帰編集の深さ、およびメジャーモードやマイナーモードなどの ようなそのバッファーに関する情報が含まれています。ウィンドウは“ヘッダー ライン(header line)”をもつこともでき、これはモードラインによく似ています がウィンドウの最上部に表示されます。 このセクションではモードラインおよびヘッダーラインのコンテンツの制御 の仕方について説明します。このチャプターにモードラインを含めた理由は、モ ードラインに表示される情報の多くが有効化されたメジャーモードとマイナーモ ードに関連があるからです。 22.4.1 モードラインの基礎 ------------------------- モードラインのコンテンツはそれぞれバッファーローカル変数 ‘mode-line-format’によって指定されます(*note Mode Line Top::を参照)。こ の変数は“モードライン構文(mode line construct)”を保持します。これはその バッファーのモードラインに何を表示するかを制御するテンプレートです。 ‘header-line-format’の値は、同じ方法によってそのバッファーのヘッダーライ ンを指定します。同一のバッファーにたいするすべてのウィンドウは同じ ‘mode-line-format’と‘header-line-format’を使用します。 効率的な理由によりEmacsは各ウィンドウのモードラインとヘッダーラインを 連続で再評価しません。たとえばウィンドウ設定(window configuration)の変更 やバッファーの切り替え、バッファーのナローイング(narrowing)やワイドニン グ(widening)、スクロールやバッファーの変更等、それを呼び出す状況が出現し たときにEmacsは再評価を行います。‘mode-line-format’や ‘header-line-format’(*note Mode Line Variables::を参照)により参照される すべての変数、またはテキストが表示される方法に影響を与えるデータ構造 (*note Display::を参照)を変更する場合には、表示を更新するために関数 ‘force-mode-line-update’を使用するべきです。 -- Function: force-mode-line-update &optional all この関数は次の再表示サイクルの間にすべての関連する変数の最新の値に もとづいて、カレントバッファーのモードラインとヘッダーラインの更新 をEmacsに強制する。オプション引数ALLが非‘nil’なら、すべてのモードラ インとヘッダーラインの更新を強制する。 この関数はメニューバーとフレームタイトルの更新も強制する。 選択されたウィンドウのモードラインは、通常はフェイス‘mode-line’を使用 して異なるカラーで表示されます。かわりに他のウィンドウのモードラインはフ ェイス‘mode-line-inactive’で表示されます。*note Faces::を参照してくださ い。 22.4.2 モードラインのデータ構造 ------------------------------- モードラインのコンテンツは“モードライン構文(mode line construct)”と呼ば れるデータ構造によって制御されます。モードライン構文はリストやシンボル、 数字を保持するバッファーローカル変数により構成されます。それぞれのデータ 型は以下で説明するようにモードラインの外見にたいして特別な意味をもちます 。フレームタイトル(*note Frame Titles::を参照)とヘッダーライン(*note Header Lines::を参照)にも同じデータ構造が使用されます。 固定文字列のようなシンプルなモードライン構文の場合もありますが、通常 はモードライン構文のテキストを構築するために固定文字列と変数の値を組み合 わせる方法を指定します。これらの変数の多くはその変数自体がその値によりモ ードライン構文を定義する変数です。 以下はモードライン構文における、さまざまなデータ型の意味です: ‘STRING’ モードライン構文における文字列は、文字列内に“‘%’構文 (‘%’-constructs)”を含む以外はそのまま表現される。これらは他のデータ による置換を意味する。*note %-Constructs::を参照のこと。 文字列の一部が‘face’プロパティをもつ場合には、バッファー内でそれら が表示されるときと同じようにテキスト表示を制御する。‘face’プロパテ ィをもたない文字はデフォルトのフェイス‘mode-line’、または ‘mode-line-inactive’で表示される(*note (emacs)Standard Faces::を参 照)。STRING内の‘help-echo’プロパティと‘keymap’プロパティは特別な意 味をもつ。*note Properties in Mode::を参照のこと。 ‘SYMBOL’ モードライン構文におけるシンボルはその値を意味する。モードライン構 文としては、SYMBOLの値はSYMBOLの位置に使用される。しかしシンボル ‘t’と‘nil’は値がvoidであるようなシンボルとして無視される。 例外が1つある。SYMBOLの値が文字列なら、それはそのまま表示されて ‘%’構成は認識されない。 SYMBOLがrisky(危険)とマークされていない(非‘nil’の ‘risky-local-variable’プロパティをもつ)場合には、SYMBOLの値中で指定 されたテキストプロパティはすべて無視される。これにはSYMBOLの値中の 文字列のテキストプロパティ、同様に文字列内の‘:eval’フォームと ‘:propertize’フォームすべてが含まれる(これはセキュリティー上の理由 による。危険とマークされていない変数は、ユーザーへの問い合わせなし でファイル変数から自動的にセットされ得る)。 ‘(STRING REST...)’ ‘(LIST REST...)’ 最初の要素が文字列かリストであるようなリストは、すべての要素を再帰 的に処理してその結果を結合することを意味する。これはモードライン構 文においてもっとも一般的なフォームである。 ‘(:eval FORM)’ 最初の要素がシンボル‘:eval’であるようなリストは、FORMを評価してその 結果を表示する文字列として使用するよう指示する。この評価が任意のフ ァイルをロードできないことを確認すること。ファイルをロードすると無 限再帰が発生するかもしれない。 ‘(:propertize ELT PROPS...)’ 最初の要素がシンボル‘:propertize’であるようなリストは、モードライン 構文ELTを再帰的に処理してPROPSで指定されるテキストプロパティに結果 を加えるよう指示する。引数PROPSは0個以上のTEXT-PROPERTYとVALUEのペ アーで構成されること。 ‘(SYMBOL THEN ELSE)’ 最初の要素がキーワード以外のシンボルであるようなリストは条件文を指 定する。その意味はSYMBOLの値に依存する。SYMBOLが非‘nil’値をもつ場合 は、モードライン構文として2つ目の要素THENが再帰的に処理され、それ以 外は3つ目の要素ELSEが再帰的に処理される。ELSEは省略でき、その場合に はSYMBOLの値が‘nil’かvoidならモードライン構文は何も表示しない。 ‘(WIDTH REST...)’ 最初の要素が整数であるようなリストはRESTの結果の切り詰め、またはパ ディングを指定する。残りの要素RESTはモードライン構文として再帰的に 処理されて互いに結合される。WIDTHが正で結果の幅がWIDTHより少なけれ ば右側にスペースがパディングされる。WIDTHが負で結果の幅が−WIDTHより 大きければ右側が切り詰められる。 たとえばウィンドウ最上部からのバッファー位置をパーセント表示するに は‘(-3 "%p")’のようなリストを使用すればよい。 22.4.3 モードライン制御のトップレベル ------------------------------------- 変数‘mode-line-format’はモードラインの全体的な制御を行います。 -- User Option: 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自体の変更を行う場合には、コンテンツを複製したり異 なる様式で情報を表示するのではなく、新たな値にはデフォルト値(*note Mode Line Variables::を参照)に出現する同じ変数を使用するべきです。この方法を 使用すればユーザーや(‘display-time’やメジャーモードのような)Lispプログラ ムにより行われたカスタマイズは、それらの変数への変更を通じて効力を保ちま す。 以下はShellモードにたいして有用かもしれない架空の‘mode-line-format’の 例です(実際にはShellモードは‘mode-line-format’をセットしない): (setq mode-line-format (list "-" 'mode-line-mule-info 'mode-line-modified 'mode-line-frame-identification "%b--" ;; これはリスト作成中に評価されることに注意 ;; これは単なる文字列のモードライン構文を作成する (getenv "HOST") ":" 'default-directory " " 'global-mode-string " %[(" '(:eval (mode-line-mode-name)) 'mode-line-process 'minor-mode-alist "%n" ")%]--" '(which-func-mode ("" which-func-format "--")) '(line-number-mode "L%l--") '(column-number-mode "C%c--") '(-3 "%p"))) (変数‘line-number-mode’、‘column-number-mode’、‘which-func-mode’は特定の マイナーモードを有効にする。これらの変数名は通常のようにマイナーモードコ マンド名でもある。) 22.4.4 モードラインで使用される変数 ----------------------------------- このセクションでは‘mode-line-format’の標準的な値としてモードラインテキス トに組み込まれる変数を説明します。これらの変数は本質的には特別なものでは ありません。‘mode-line-format’が使用する変数を他の変数に変更すれば、それ らはモードライン上で同様の効果をもちます。しかしEmacsのさまざまな部分は 、それらの変数がモードラインを制御するという認識の元でそれらの変数をセッ トします。したがって事実上モードラインでそれらの変数を使用するのは必須な のです。*note (emacs)Optional Mode Line::も参照してください。 -- Variable: mode-line-mule-info この変数は言語環境(language environment)、バッファーコーディングシ ステム、カレント入力メソッド(current input method)に関する情報のモ ードライン構文の値を保持する。*note Non-ASCII Characters::を参照の こと。 -- Variable: mode-line-modified この変数はカレントバッファーが変更されたかどうかを表示するモードラ イン構文の値を保持する。デフォルト値ではバッファーが変更されていれ ば‘**’、バッファーが変更されていなければ‘--’、バッファーが読み取り 専用なら‘%%’、読み取り専用だが変更されているときは‘%*’を表示する。 この変数を変更してもモードラインは強制的に更新されない。 -- Variable: mode-line-frame-identification この変数はカレントフレームを識別する。デフォルト値では複製フレーム を表示可能なウィンドウシステムを使用している場合は‘" "’、一度に1つ のフレームだけを表示する通常の端末では‘"-%F "’を表示する。 -- Variable: mode-line-buffer-identification この変数はそのウィンドウ内で表示されているバッファーを識別する。デ フォルト値では少なくとも12列になるようスペースパディングされたバッ ファー名を表示する。 -- Variable: mode-line-position この変数はバッファー内での位置を表示する。デフォルト値ではバッファ ーのパーセント位置、オプションでバッファーサイズ、行番号、列番号を 表示する。 -- Variable: vc-mode 変数‘vc-mode’は各バッファーにたいしてバッファーローカルであり、その バッファーがvisitしているファイルがバージョンコントロールで保守され ているかどうか、保守されている場合はバージョンコントロールシステム の種別を表示する。値はモードラインに表示される文字列、またはバージ ョンコントロールされていなければ‘nil’。 -- Variable: mode-line-modes この変数はそのバッファーのメジャーモードとマイナーモードを表示する 。デフォルト値では再帰編集レベル(recursive editing level)、プロセス 状態の情報、ナローイング(narrowing)効果の有無を表示する。 -- Variable: mode-line-remote この変数はカレントバッファーの‘default-directory’がリモートかどうか を表示するために使用される。 -- Variable: mode-line-client この変数は‘emacsclient’フレームを識別するために使用される。 以下の3つの変数は‘mode-line-modes’内で使用されます: -- Variable: mode-name このバッファーローカル変数はカレントバッファーのメジャーモードの“愛 称(pretty name)”を保持する。モードラインにモード名が表示されるよう に、すべてのメジャーモードはこの変数をセットすること。値は文字列で ある必要はなく、モードライン構文内で有効な任意のデータ型(*note Mode Line Data::を参照)を使用できる。モードライン内でモード名を識別する 文字列の計算には‘format-mode-line’を使用する(*note Emulating Mode Line::を参照)。 -- Variable: mode-line-process このバッファーローカル変数には、そのモードにおいてサブプロセスとの 通信にたいするプロセス状態のモードライン情報が含まれる。これはメジ ャーモード名の直後(間にスペースはない)に表示される。たとえば ‘*shell*’バッファーでの値は‘(":%s")’であり、これは‘(Shell:run)’のよ うに、メジャーモードとともにその状態を表示する。この変数は通常は ‘nil’。 -- Variable: mode-line-front-space この変数はモードラインの一番前に表示される。memory-fullメッセージが ある場合を除き、デフォルトではこの構文はモードライン先頭の右側に表 示される。 -- Variable: mode-line-end-spaces この変数はモードラインの終端に表示される。 -- Variable: mode-line-misc-info その他の情報にたいするモードライン構文。デフォルトでは ‘global-mode-string’で指定される情報を表示する。 -- Variable: minor-mode-alist この変数はアクティブなマイナーモードをモードラインに示す方法を指定 する要素をもった連想リスト(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内で参 照される各変数は、そのマイナーモードをバッファーごとに個別に有効に できるならバッファーローカルであること。 -- Variable: global-mode-string この変数はモードライン内でマイナーモード‘which-func-mode’がセットさ れていればその直後、セットされていなければ‘mode-line-modes’の後に表 示されるモードライン構文を保持する(デフォルト)。コマンド ‘display-time’は、」時間とロードの情報を含む文字列を保持する変数 ‘display-time-string’を参照する‘global-mode-string’をセットする。 ‘%M’構文は‘global-mode-string’の値を置き換えるが、この変数は ‘mode-line-format’からモードラインにincludeされるので時代遅れである 。 以下は‘mode-line-format’のデフォルト値の簡略化バージョンです。実際の デフォルト値には追加のテキストプロパティ指定も含まれます。 ("-" mode-line-mule-info mode-line-modified mode-line-frame-identification mode-line-buffer-identification " " mode-line-position (vc-mode vc-mode) " " mode-line-modes (which-func-mode ("" which-func-format "--")) (global-mode-string ("--" global-mode-string)) "-%-") 22.4.5 モードラインでの‘%’構造 ------------------------------ モードライン構文として使用される文字列では、さまざまな種類のデータを置き 換えるために‘%’構文を使用できます。以下は定義済みの‘%’構文と意味のリスト です。 ‘%%’以外の構文では、フィールドの最小幅を指定するために‘%’の後に10進整 数を追加できます。幅がそれより小さければそのフィールドは最小幅にパディン グされます。純粋に数値的な構文(‘c’、‘i’、‘I’、‘l’)は左側、それ以外は右側 にスペースを追加してパディングされます。 ‘%b’ ‘buffer-name’関数により取得されるカレントバッファー名。*note Buffer Names::を参照のこと。 ‘%c’ ポイント位置のカレント列番号。 ‘%e’ EmacsがLispオブジェクトにたいしてメモリー不足になりそうなときは、そ れを伝える簡略なメッセージを示す。それ以外の場合は空。 ‘%f’ ‘buffer-file-name’関数により取得されるvisit中のファイル名。*note Buffer File Name::を参照のこと。 ‘%F’ 選択されたフレームのタイトル(ウィンドウシステム上のみ)か名前。*note Basic Parameters::を参照のこと。 ‘%i’ カレントバッファーのアクセス可能な範囲のサイズ。基本的には‘(- (point-max) (point-min))’。 ‘%I’ ‘%i’と同様だが10^3は‘k’、10^6は‘M’、10^9は‘G’を使用して略記すること で、より読みやすい方法でサイズをプリントする。 ‘%l’ ポイント位置のカレント行番号。そのバッファーのアクセス可能な範囲内 でカウントされる。 ‘%n’ ナローイングが有効なときは‘Narrow’、それ以外は何も表示しない(*note Narrowing::の‘narrow-to-region’を参照)。 ‘%p’ ウィンドウの*最上部*より上にあるバッファーテキストのパーセント表示 、または‘Top’、‘Bottom’、‘All’のいずれか。デフォルトのモードライン 構文は、これを3文字に切り詰めることに注意。 ‘%P’ ウィンドウの*最下部*より上にあるバッファーテキスト(ウィンドウ内の可 視なテキストと最上部の上にあるテキスト)のパーセント表示、およびバッ ファーの最上部がスクリーン上で可視なら、それに加えて‘Top’。または ‘Bottom’か‘All’。 ‘%s’ ‘process-status’により取得されるカレントバッファーに属するサブプロ セスの状態。*note Process Information::を参照のこと。 ‘%z’ キーボード、端末、およびバッファーコーディングシステムのニーモニッ ク。 ‘%Z’ ‘%z’と同様だが、EOL形式(end-of-line format: 改行形式)を含む。 ‘%*’ バッファーが読み取り専用(‘buffer-read-only’を参照)なら‘%’、 変更(‘buffer-modified-p’を参照)されていればは‘*’、 それ以外は‘-’。*note Buffer Modification::を参照のこと。 ‘%+’ バッファーが変更(‘buffer-modified-p’を参照)されていれば‘*’ バッファーが読み取り専用(‘buffer-read-only’を参照)なら‘%’、 それ以外は‘-’。これは読み取り専用バッファーの変更にたいしてのみ ‘%*’と異なる。*note Buffer Modification::を参照のこと。 ‘%&’ バッファーが変更されてれば‘*’、それ以外は‘-’。 ‘%[’ 再帰編集レベルの深さを表示する(ミニバッファーレベルは勘定しない)編 集レベル1つが‘[’。*note Recursive Editing::を参照のこと。 ‘%]’ 編集レベル1つが‘]’(ミニバッファーレベルは勘定しない)。 ‘%-’ モードラインの残りを充填するのに十分なダッシュ。 ‘%%’ 文字‘%’。‘%’構文が許される文字列内にリテラル‘%’を含めるにはこの方法 を使用する。 以下の2つの‘%’構文はまだサポートされていますが、同じ結果を変数 ‘mode-name’と‘global-mode-string’で取得できるので時代遅れです。 ‘%m’ ‘mode-name’の値。 ‘%M’ ‘global-mode-string’の値。 22.4.6 モードラインでのプロパティ --------------------------------- モードライン内では特定のテキストプロパティが意味をもちます。‘face’プロパ ティはテキストの外見に影響します。‘help-echo’プロパティはそのテキストの ヘルプ文字列に関連し、‘keymap’によりテキストをマウスに感応させることがで きます。 モードライン内のテキストにたいしてテキストプロパティを指定するには4つ の方法があります: 1. モードラインデータ構造内にテキストプロパティをもつ文字列を直接配置 する。 2. ‘%12b’のようなモードライン%構文にテキストプロパティを配置する。その 場合には%構文を展開すると同じテキストプロパティをもつことになる。 3. PROPSで指定されるテキストプロパティをELTに与えるために‘(:propertize ELT PROPS...)’構文を使用する。 4. FORMがテキストプロパティをもつ文字列に評価されるようにモードライン データ構造内に‘:eval FORM’を含むリストを使用する。 キーマップを指定するために‘keymap’プロパティを使用できます。このキー マップはマウスクリックにたいしてのみ実際の効果をもちます。モードライン内 にポイントを移動させるのは不可能なので、これに文字キーやファンクションキ ーをバインドしても効果はありません。 ‘risky-local-variable’が非‘nil’であるようなプロパティをもつ変数をモー ドラインが参照する場合には、その変数の値から取得または指定されるテキスト プロパティはすべて無視されます。そのようなプロパティは呼び出される関数を 指定するかもしれず、その関数はファイルローカル変数に由来するかもしれない からです。 22.4.7 ウィンドウのヘッダーライン --------------------------------- 最下部にモードラインをもつことができるのと同じように、ウィンドウは最上部 に“ヘッダーライン(header line)”をもつことができます。ヘッダーライン機能 は、それが‘header-line-format’によって制御されることを除けばモードライン と同じように機能します。 -- Variable: header-line-format すべてのバッファーにたいしてローカルなこの変数は、そのバッファーを 表示するバッファーにたいしてヘッダーラインを表示する方法を指定する 。この変数の値のフォーマットは‘mode-line-format’にたいするフォーマ ットと同じ(*note Mode Line Data::を参照)。この変数は通常は‘nil’なの で、通常のバッファーはヘッダーラインをもたない。 -- Function: window-header-line-height &optional window この関数はWINDOWのヘッダーラインの高さをピクセルでリターンする。 WINDOWは生きたウィンドウでなければならずデフォルトは選択されたウィ ンドウ。 高さが1行しかないウィンドウがヘッダーラインを表示することは決してあり ません。また高さが2行しかないウィンドウは、同時にモードラインとヘッダー ラインを表示できません。そのようなウィンドウがモードラインをもつ場合には ヘッダーラインは表示されません。 22.4.8 モードラインのフォーマットのエミュレート ----------------------------------------------- 関数‘format-mode-line’を使用して、特定のモードライン構文にもとづいてモー ドラインやヘッダーラインに表示されるテキストを計算できます。 -- Function: format-mode-line format &optional face window buffer この関数は、あたかも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)’は、 各文字がヘッダーライン内でもつであろうフェイスをもつ同じテキストを リターンするとともに、それに加えてヘッダーラインの再描画も行う。 22.5 Imenu ========== “Imenu”とはバッファー内の定義やセクションをすべてリストするメニューをユ ーザーが選択することによって、バッファー内の該当箇所に直接移動する機能で す。Imenuは定義(またはバッファーのその他の名前つき範囲)の名前とその定義 のバッファー内での位置をリストするバッファーインデックスを構築して、ユー ザーがそれを選択すればポイントをそこに移動できるようにして機能します。メ ジャーモードは‘imenu-add-to-menubar’を使用して、メニューバーアイテムを追 加することができます。 -- Command: imenu-add-to-menubar name この関数はImenuを実行するためのNAMEという名前のローカルメニューバー を定義する。 Imenuを使用するためのユーザーレベルコマンドはEmacsマニュアルで説明さ れています(*note Imenu: (emacs)Imenu.を参照)。このセクションでは特定のメ ジャーモードにたいして定義や名前つき範囲を見つけるImenuメソッドのカスタ マイズ方法を説明します。 変数‘imenu-generic-expression’をセットするのが通常、かつもっともシン プルな方法です: -- Variable: imenu-generic-expression この変数が非‘nil’なら、それはImenuにたいして定義を探すための正規表 現を指定するリストである。シンプルな‘imenu-generic-expression’の要 素は以下のようになる: (MENU-TITLE REGEXP INDEX) ここでMENU-TITLEが非‘nil’なら、それはこの要素にたいするマッチがバッ ファーインデックスのサブメニューとなることを指示する。MENU-TITLE自 体はそのサブメニューにたいして名前を指定する。MENU-TITLEが‘nil’なら 、この要素にたいするマッチは直接トップレベルのバッファーインデック スとなる。 このリストの2つ目の要素REGEXPは正規表現である(*note Regular Expressions::を参照)。これはバッファー内でこれにマッチするものは定 義、あるいはバッファーインデックス内に記載すべき何かであると判断さ れる。3つ目の要素INDEXは0以上の整数なら、REGEXP内の部分式 (subexpression)が定義名にマッチすることを示す。 以下のような要素もある: (MENU-TITLE REGEXP INDEX FUNCTION ARGUMENTS...) この要素にたいする各マッチはインデックスアイテムを作成して、ユーザ ーにがそのインデックスアイテムを選択したときアイテム名、バッファー 位置、およびARGUMENTSから構成される引数でFUNCTIONを呼び出す。 Emacs Lispモードでは‘imenu-generic-expression’は以下のようになるだ ろう: ((nil "^\\s-*(def\\(un\\|subst\\|macro\\|advice\\)\ \\s-+\\([-A-Za-z0-9+]+\\)" 2) ("*Vars*" "^\\s-*(def\\(var\\|const\\)\ \\s-+\\([-A-Za-z0-9+]+\\)" 2) ("*Types*" "^\\s-*\ (def\\(type\\|struct\\|class\\|ine-condition\\)\ \\s-+\\([-A-Za-z0-9+]+\\)" 2)) この変数はセットによりカレントバッファーにたいしてバッファーローカ ルになる。 -- Variable: imenu-case-fold-search この変数は‘imenu-generic-expression’の値中の正規表現マッチがcase(大 文字小文字)を区別するかどうかを制御する。‘t’(デフォルト)ならcaseの 違いを無視することを意味する。 この変数はセットによりカレントバッファーにたいしてバッファーローカ ルになる。 -- Variable: imenu-syntax-alist この変数は‘imenu-generic-expression’処理中に、カレントバッファーの 構文テーブルをオーバーライドするために使用する構文テーブル変更用の alist。このalistの各要素は以下の形式をもつこと: (CHARACTERS . SYNTAX-DESCRIPTION) CARのCHARACTERSには文字か文字列を指定できる。この要素はその文字か文 字列がSYNTAX-DESCRIPTIONにより指定される構文であることを示し、 ‘modify-syntax-entry’に渡される(*note Syntax Table Functions::を参 照)。 典型的にはこの機能はシンボル構文(symbol syntax)をもつ文字にたいして 単語構文(word syntax)を与えるために通常は使用され、それにより ‘imenu-generic-expression’が単純になってマッチングのスピードも向上 する。たとえばFortranモードでは以下のようにこれを使用する: (setq imenu-syntax-alist '(("_$" . "w"))) ‘imenu-generic-expression’の正規表現は、‘\\(\\sw\\|\\s_\\)+’のかわ りに、‘\\sw+’を使用できる。このテクニックは名前をモード名として許容 されるより短い頭文字に制限する必要があるときは不便かもしれないこと に注意。 この変数はセットによりカレントバッファーにたいしてバッファーローカ ルになる。 あるメジャーモードにたいしてImenuをカスタマイズする別の方法として ‘imenu-prev-index-position-function’と ‘imenu-extract-index-name-function’があります: -- Variable: imenu-prev-index-position-function この変数が非‘nil’なら、その値はポイント位置からバッファーを後方にス キャンしてバッファーインデックスに配置すべき次の定義を探すための関 数であること。そしてポイントより前に他の定義が見つからなければ ‘nil’をリターンすること。見つかった場合には定義を見つけた場所にポイ ントを残して任意の非‘nil’値をリターンすること。 この変数はセットによりカレントバッファーにたいしてバッファーローカ ルになる。 -- Variable: imenu-extract-index-name-function この変数が非‘nil’なら、その値はポイントが定義中にある (‘imenu-prev-index-position-function’関数がポイントを残す場所)とい う想定にもとづき、その定義の名前をリターンする関数であること。 この変数はセットによりカレントバッファーにたいしてバッファーローカ ルになる。 メジャーモードにたいしてImenuをカスタマイズするための最後の方法は変数 ‘imenu-create-index-function’のセットです: -- Variable: imenu-create-index-function この変数はバッファーインデックスを作成するために使用する関数を指定 する。この関数は引数がを受け取らず、カレントバッファーにたいするイ ンデックスalist(index alist)をリターンすること。この関数は ‘save-excursion’内で呼び出されるので、どこにポイントを残しても違い はない。 このインデックスalistは3つのタイプの要素をもつことができる。以下は シンプル要素(simple element)の例: (INDEX-NAME . INDEX-POSITION) シンプル要素の選択はそのバッファー内の位置INDEX-POSITIONに移動する 効果をもつ。スペシャル要素(special element)は以下のようなもの: (INDEX-NAME INDEX-POSITION FUNCTION ARGUMENTS...) スペシャル要素の選択により以下が処理される: (funcall FUNCTION INDEX-NAME INDEX-POSITION ARGUMENTS...) ネストされたサブalist要素(nested sub-alist element)は以下のようなも の: (MENU-TITLE . SUB-ALIST) これはSUB-ALISTにより指定されるサブメニューMENU-TITLEを作成する。 ‘imenu-create-index-function’のデフォルト値は ‘imenu-default-create-index-function’。この関数はインデックス alistを生成するために‘imenu-prev-index-position-function’の値と ‘imenu-extract-index-name-function’の値を呼び出す。しかしこれら2つ 変数のいずれかが‘nil’なら、デフォルト関数はかわりに ‘imenu-generic-expression’を使用する。 この変数はセットによりカレントバッファーにたいしてバッファーローカ ルになる。 22.6 Font Lockモード ==================== “Font Lockモード”とはバッファーの特定の部分にたいして、それらの構文的役 割(syntactic role)にもとづき自動的に‘face’プロパティをアタッチするバッフ ァーローカルなマイナーモードです。このモードがバッファーをパースする方法 はそのメジャーモードに依存します。ほとんどのメジャーモードは、どのコンテ キストでどのフェイスを使用するかにたいして構文的条件(syntactic criteria)を定義します。このセクションでは特定のメジャーモードにたいして Font Lockをカスタマイズする方法を説明します。 Font Lockモードは2つの方法によりハイライトするテキストを探します。そ れは構文テーブル(syntax table)にもとづく構文解析と、(通常は正規表現にた いする)検索です。最初に構文的フォント表示(syntactic fontification)が発生 します。これはコメントと文字列定数を見つけてそれらをハイライトします。検 索ベースのフォント表示が発生するのは2番目です。 22.6.1 Font Lockの基礎 ---------------------- Font Lock機能はいくつかの基本的な関数にもとづきます。これらはそれぞれ対 応する変数により指定される関数を呼び出します。このインダイレクションによ りメジャーモードとマイナーモードはそのモードにあるバッファーのフォント表 示が機能する方法を変更したり、フォント表示を何も行わない機能にたいしてさ えFont Lockメカニズムを使用することが可能になります(以下の記述で関数が何 を行うか説明する際に“should(すること、するべき)”と表現しているのはこれが 理由。モードは完全に異なる何かを行うように対応する変数をカスタマイズでき る)。以下で言及される変数は*note Other Font Lock Variables::で説明されて います。 ‘font-lock-fontify-buffer’ この関数は‘font-lock-fontify-buffer-function’で指定される関数の呼び 出しにより、カレントバッファーのアクセス可能範囲をフォント表示する こと。 ‘font-lock-unfontify-buffer’ フォント表示削除のためにFont Lockをオフに切り替える際に使用する。 ‘font-lock-unfontify-buffer-function’で指定される関数を呼び出す。 ‘font-lock-fontify-region beg end &optional loudly’ BEGとENDの間のリージョンをフォント表示すること。LOUDLYが非‘nil’なら 、フォント表示中にステータスメッセージを表示すること。 ‘font-lock-fontify-region-function’で指定される関数を呼び出す。 ‘font-lock-unfontify-region beg end’ BEGとENDの間のリージョンのフォント表示を削除すること。 ‘font-lock-unfontify-region-function’で指定される関数を呼び出す。 ‘font-lock-flush &optional beg end’ この関数はBEGとENDの間のリージョンのフォント表示を期限切れ (outdated)とマークすること。BEGとENDが未指定または‘nil’なら、デフォ ルトはそのバッファーのアクセス可能範囲の先頭と終端。 ‘font-lock-flush-function’で指定される関数を呼び出す。 ‘font-lock-ensure &optional beg end’ この関数はBEGとENDの間のリージョンのフォント表示を保証すること。オ プション引数BEGとENDのデフォルトは、そのバッファーのアクセス可能範 囲の先頭と終端。‘font-lock-ensure-function’で指定される関数を呼び出 す。 Font Lockモードのテキストのハイライト方法を制御する変数がいくつかあり ます。しかしメジャーモードはこれらの変数を直接セットするべきではありませ ん。かわりにメジャーモードはバッファーローカル変数として ‘font-lock-defaults’をセットするべきです。Font Lockモードが有効なときは 、他のすべての変数をセットするためにこの変数に割り当てられた値が使用され ます。 -- Variable: font-lock-defaults この変数はそのモード内のテキストをフォント表示する方法を指定するた めにモードによりセットされる。この変数はセットした際に自動的にバッ ファーローカルになる。変数の値が‘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’値をもつとき使用され る。*note Levels of Font Lock::を参照のこと。 2つ目の要素KEYWORDS-ONLYは変数‘font-lock-keywords-only’の値を指定す る。これが省略または‘nil’なら、(文字列とコメントの)構文的フォント表 示も行われる。非‘nil’なら構文的フォント表示は行われない。*note Syntactic 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’関数によりリターンされる構文テーブルを使用する。*note Syntax Table Functions::を参照のこと。 (もしあれば)残りすべての要素はまとめてOTHER-VARSと呼ばれる。これら の要素はすべて‘(VARIABLE . VALUE)’という形式をもつこと。これは VARIABLEをバッファーローカルにしてから、それにVALUEをセットすること を意味する。これらOTHER-VARSを使用して、最初の5つの要素による制御と は別にフォント表示に影響する他の変数をセットできる。*note Other Font Lock Variables::を参照のこと。 モードが‘font-lock-face’プロパティ追加により明示的にテキストをフォン ト表示する場合には、自動的なフォント表示すべてをオフにするために ‘font-lock-defaults’に‘(nil t)’を指定できます。しかしこれは必須ではあり ません。‘font-lock-face’を使用して何かをフォント表示して、それ以外の部分 のテキストを自動的にフォント表示するようにセットアップすることが可能です 。 22.6.2 検索ベースのフォント化 ----------------------------- 検索ベースのフォント表示を直接制御する変数は‘font-lock-keywords’です。こ の変数は通常は‘font-lock-defaults’内の要素KEYWORDSを通じて指定されます。 -- Variable: font-lock-keywords この変数の値はハイライトするキーワードのリスト。Lispプログラムはこ の変数を直接セットしないこと。通常は‘font-lock-defaults’内の要素 KEYWORDSを使用してFont Lockモードが自動的に値をセットする。この値は 関数‘font-lock-add-keywords’と‘font-lock-remove-keywords’を使用して 変更することもできる(*note Customizing 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’をハイライトする "\\" これらの正規表現を作成するときは慎重に行うこと。下手に記述されたパ ターンによりスピードが劇的に低下し得る! 関数‘regexp-opt’ (*note Regexp Functions::を参照)は、いくつかのキーワードとマッチするために 最適な正規表現の計算に有用である。 ‘FUNCTION’ FUNCTIONを呼び出すことによりテキストを探し、 ‘font-lock-keyword-face’を使用して見つかったマッチをハイライトする 。 FUNCTIONは呼び出される際に1つの引数(検索のリミット)を受け取る。検索 はポイント位置から開始しリミットを超えた検索は行わないこと。これは 検索が成功したら非‘nil’をリターンして見つかったマッチを表すマッチデ ータをセットすること。‘nil’のリターンは検索の失敗を示す。 フォント表示は前の呼び出しでポイントが残された位置から同じリミット を用いてFUNCTIONを呼び出し、FUNCTIONが失敗するまでFUNCTIONを繰り返 し呼び出すだろう。検索が失敗しても何らかの特別な方法でFUNCTIONがポ イントをリセットする必要はない。 ‘(MATCHER . SUBEXP)’ この種の要素ではMATCHERは上述のregexpかfunctionのいずれかである。 CDRのSUBEXPは、(MATCHERがマッチするテキスト全体のかわりに)MATCHERの どの部分式(subexpression)がハイライトされるべきかを指定する。 ;; ‘font-lock-keyword-face’を使用して ;; ‘bar’が‘fubar’の一部のときに ;; ハイライトする ("fu\\(bar\\)" . 1) 正規表現MATCHERの生成に‘regexp-opt’を使用する場合には、SUBEXPにたい する値の計算に‘regexp-opt-depth’ (*note Regexp Functions::を参照)を 使用できる。 ‘(MATCHER . FACESPEC)’ この種の要素ではFACESPECの値がハイライトに使用するフェイスを指定す る。もっともシンプルな例ではFACESPECは値がフェイス名であるようなは Lisp変数(シンボル)。 ;; ‘fubar-face’の値のフェイスを使用して ;; ‘fubar’をハイライトする ("fubar" . fubar-face) しかしFACESPECは以下のような形式のリストに評価されてもよい: (face FACE PROP1 VAL1 PROP2 VAL2...) これはマッチしたテキストにフェイスFACEを指定し、さまざまなテキスト プロパティをputする。これを行う場合には、この方法によって ‘font-lock-extra-managed-props’に値をセットする、他テキストプロパテ ィ名を確実に追加すること。そうすればそれらのプロパティが妥当性を失 ったとき、それらのプロパティもクリアーされるだろう。これらのプロパ ティをクリアーする関数を変数‘font-lock-unfontify-region-function’に セットすることもできる。*note Other Font Lock Variables::を参照のこ と。 ‘(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’をハイライトする ("\\" "\\" 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’をハイライトする ("\\" (0 anchor-face) ("\\" nil nil (0 item-face))) ‘(eval . FORM)’ ここでFORMはバッファー内でこの‘font-lock-keywords’の値が最初に使用 されるときに評価される式である。この値は上述のテーブルで説明したい ずれかの形式をもつこと。 *警告:* 複数行にわたるテキストにマッチさせるために ‘font-lock-keywords’の要素をデザインしてはならない。これは確実に機能する とは言えない。詳細は*note Multiline Font Lock::を参照のこと。 検索ベースのフォント表示がcaseを区別すべきかどうかを告げる ‘font-lock-keywords-case-fold-search’の値を指定するために ‘font-lock-defaults’内でCASE-FOLDを使用できる。 -- Variable: font-lock-keywords-case-fold-search 非‘nil’は‘font-lock-keywords’のための正規表現マッチングがcaseを区別 すべきではないことを意味する。 22.6.3 検索ベースのフォント化のカスタマイズ ------------------------------------------- メジャーモードにたいして検索ベースフォント表示ルールを追加するために ‘font-lock-add-keywords’、削除には‘font-lock-remove-keywords’を使用する ことができます。 -- Function: font-lock-add-keywords mode keywords &optional how この関数はカレントバッファー、またはメジャーモード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’をセットするこ とにより、検索ベースフォント表示のルールをセットアップすること。 -- Function: font-lock-remove-keywords mode keywords この関数はカレントバッファー、またはメジャーモードMODEにたいして ‘font-lock-keywords’からKEYWORDSを削除する。 ‘font-lock-add-keywords’の場合と同様、MODEはメジャーモードコマンド 名または‘nil’であること。‘font-lock-add-keywords’にたいするすべての 制約と条件はこの関数にも適用される。 たとえば以下はCモードに2つのフォント表示パターンを追加するコードの例 である。フォント表示の1つはたとえコメント内であろうとも単語‘FIXME’をフォ ント表示し、もう1つは‘and’、‘or’、‘not’をキーワードとしてフォント表示す る。 (font-lock-add-keywords 'c-mode '(("\\<\\(FIXME\\):" 1 font-lock-warning-face prepend) ("\\<\\(and\\|or\\|not\\)\\>" . font-lock-keyword-face))) この例は厳密にCモードだけに効果がある。Cモード、_および_その派生モードに たいして同じパターンを追加するには、かわりに以下を行う: (add-hook 'c-mode-hook (lambda () (font-lock-add-keywords nil '(("\\<\\(FIXME\\):" 1 font-lock-warning-face prepend) ("\\<\\(and\\|or\\|not\\)\\>" . font-lock-keyword-face))))) 22.6.4 Font Lockのその他の変数 ------------------------------ このセクションでは‘font-lock-defaults’内のOTHER-VARSを用いて、メジャーモ ードがセットできる追加の変数について説明します(*note Font Lock Basics::を 参照)。 -- Variable: font-lock-mark-block-function この変数が非‘nil’なら、それはコマンド‘M-o M-o’ (‘font-lock-fontify-block’)で再フォント表示するテキスト範囲を選択す るために引数なしで呼び出される関数であること。 この関数は結果を報告するために選択されたテキスト範囲にリージョンを 配置すること。正しい結果を与えるのに十分、かつ再フォント表示が低速 にならない程度のテキスト範囲がよい選択である。典型的な値はプログラ ミングのモードにたいしては‘mark-defun’、テキストを扱うモードにたい しては‘mark-paragraph’。 -- Variable: font-lock-extra-managed-props この変数は、(‘font-lock-face’以外の)Font Lockにより管理される追加プ ロパティを指定する。これらの追加プロパティは通常は ‘font-lock-face’プロパティだけを管理する、 ‘font-lock-default-unfontify-region’により使用される。他のプロパテ ィも同様にFont Lockに管理させたければ、このリストに追加するのと同じ ように‘font-lock-keywords’内のFACESPEC内でもこれらを指定しなければ ならない。*note Search-based Fontification::を参照のこと。 -- Variable: font-lock-fontify-buffer-function そのバッファーをフォント表示するために使用する関数。デフォルト値は ‘font-lock-default-fontify-buffer’。 -- Variable: font-lock-unfontify-buffer-function そのバッファーを非フォント表示するために使用する関数。デフォルト値 は‘font-lock-default-unfontify-buffer’。 -- Variable: font-lock-fontify-region-function リージョンをフォント表示するための関数。この関数はリージョンの開始 と終了の2つを引数に受け取り、オプションで3つ目の引数VERBOSEを受け取 ること。VERBOSEが非‘nil’なら、その関数はステータスメッセージをプリ ントすべきである。デフォルト値は ‘font-lock-default-fontify-region’。 -- Variable: font-lock-unfontify-region-function リージョンを非フォント表示するための関数。この関数はリージョンの開 始と終了の2つを引数に受け取ること。デフォルト値は ‘font-lock-default-unfontify-region’。 -- Variable: font-lock-flush-function リージョンのフォント表示の期限切れの宣言に使用する関数。そのリージ ョンの開始と終了という2つの引数を受け取る。この変数のデフォルト値は ‘font-lock-after-change-function’。 -- Variable: font-lock-ensure-function カレントバッファーのリージョンのフォント表示の保証に使用する関数。 そのリージョンの開始と終了という2つの引数を受け取る。この変数のデフ ォルト値は、バッファーがフォント表示されていないときに ‘font-lock-default-fontify-buffer’を呼び出す関数。効果はそのバッフ ァーのアクセス可能範囲全体がフォント表示されることの保証。 -- Function: jit-lock-register function &optional contextual この関数はカレントバッファーの一部をフォント表示/非表示する必要があ る任意のタイミングで、Font LockモードがLisp関数FUNCTIONを実行するこ とを宣言する。これはデフォルトのフォント表示関数が呼び出される前に 、フォント表示/非表示するリージョンを指定する2つの引数STARTとENDで FUNCTIONを呼び出す。 オプション引数CONTEXTUALが非‘nil’なら、行が更新されたときに限らずそ のバッファーの構文的に関連する部分を常にフォント表示するようFont Lockモードに強制する。この引数は通常は省略できる。 -- Function: jit-lock-unregister function 以前に‘jit-lock-register’を使用してフォント表示関数としてFUNCTIONを 登録した場合は、その関数を未登録にする。 22.6.5 Font Lockのレベル ------------------------ フォント表示にたいして3つの異なるレベルを提供するモードがいくつかありま す。‘font-lock-defaults’内のKEYWORDSにたいしてシンボルのリストを使用する ことにより複数のレベルを定義できます。このリストのシンボルはそれぞれフォ ント表示の1レベルを指定します。これらのレベルの選択は、通常は ‘font-lock-maximum-decoration’をセットすることによりユーザーの責任で行わ れます(*note (emacs)Font Lock::を参照)。選択されたレベルのシンボルの値は ‘font-lock-keywords’の初期化に使用されます。 フォント表示レベルの定義方法に関する慣習を以下に挙げます: • レベル1: 関数宣言、(includeやimportのような)ファイルディレクティブ 、文字列、コメントをハイライトする。これは、もっとも重要かつトップ レベルのコンポーネントだけをフォント表示すれば高速になるという発想 である。 • レベル2: レベル1に加えて、すべての言語のキーワード(キーワードと同様 に作用する型名を含む)、および名前付き定数値をハイライトする。これは 、(構文的、または意味的な)すべてのキーワードは適切にフォント表示さ れるべきという発想である。 • レベル3: レベル2に加えて、関数内で定義されるシンボル、変数宣言、お よびすべてのビルトイン関数名にたいして、それがどこに出現しようとハ イライトする。 22.6.6 事前計算されたフォント化 ------------------------------- ‘list-buffers’や‘occur’のようないくつかのメジャーモードは、バッファーの テキストをプログラム的に構築します。これらにたいしてFont Lockモードをサ ポートするためには、そのバッファーにテキストを挿入するタイミングでテキス トのフェイスを指定するのがもっとも簡単な方法です。 これはスペシャルテキストプロパティ‘font-lock-face’ (*note Special Properties::を参照)により、テキスト内にフェイスを指定することによって行 われます。Font Lockモードが有効になったとき、このプロパティは‘face’と同 じように表示を制御します。Font Lockモードが無効になると ‘font-lock-face’は表示に効果をもちません。 モードが通常のFont Lockメカニズムとともに、あるテキストにたいして ‘font-lock-face’を使用しても問題はありません。しかしそのモードが通常の Font Lockメカニズムを使用しない場合には、変数‘font-lock-face’をセットす るべきではありません。 22.6.7 Font Lockのためのフェイス -------------------------------- Font Lockモードはハイライトに任意のフェイスを使用できますが、Emacsは特に FontLockがテキストのハイライトに使用するいくつかのフェイスを定義していま す。これらの“Font Lockフェイス(Font Lock faces)”を以下にリストします。こ れらのフェイスはFontLockモードの外部における構文的なハイライトでメジャー モードが使用することもできます(*note Major Mode Conventions::を参照)。 以下の各シンボルはフェイス名であり、かつデフォルト値がシンボル自身で あるような変数でもあります。つまり‘font-lock-comment-face’のデフォルト値 は‘font-lock-comment-face’です。 リストはそのフェイスの典型的な使い方の説明とともに、重要度が高い順に ソートされています。あるモードの構文的カテゴリーが以下の使い方の記述にう まく適合しない場合には、この並び順をガイドとして使用することによってフェ イスを割り当てることができるでしょう。 ‘font-lock-warning-face’ Emacs Lispの‘;;;###autoload’、Cの‘#error’のような特有な構文、または その他のテキストの意味を大きく変更する構文にたいして使用される。 ‘font-lock-function-name-face’ 定義、または宣言される関数の名前にたいして使用される。 ‘font-lock-variable-name-face’ 定義、または宣言される変数の名前にたいして使用される。 ‘font-lock-keyword-face’ Cの‘for’や‘if’のように、構文的に特別な意味をもつキーワードにたいし て使用される。 ‘font-lock-comment-face’ コメントにたいして使用される。 ‘font-lock-comment-delimiter-face’ Cの‘/*’と‘*/’のようなコメント区切りにたいして使用される。ほとんどの 端末ではこのフェイスは‘font-lock-comment-face’を継承する。 ‘font-lock-type-face’ ユーザー定義データ型にたいして使用される。 ‘font-lock-constant-face’ Cの‘NULL’のような定数の名前にたいして使用される。 ‘font-lock-builtin-face’ ビルトイン関数の名前にたいして使用される。 ‘font-lock-preprocessor-face’ プロセッサーコマンドにたいして使用される。デフォルトでは、 ‘font-lock-builtin-face’を継承する。 ‘font-lock-string-face’ 文字列定数にたいして使用される。 ‘font-lock-doc-face’ コード内のドキュメント文字列にたいして使用される。デフォルトでは ‘font-lock-string-face’を継承する。 ‘font-lock-negation-char-face’ 見逃しやすい否定文字にたいして使用される。 22.6.8 構文的なFont Lock ------------------------ 構文的フォント表示(syntactic fontification)は、構文的に関連性のあるテキ ストを探してハイライトするために構文テーブル(syntax table: *note Syntax Tables::を参照)を使用します。有効な場合には検索ベースのフォント表示に先 立って実行されます。以下で説明する変数 ‘font-lock-syntactic-face-function’はどの構文的構造をハイライトするかを 決定します。構文的フォント表示に影響を与える変数がいくつかあります。 ‘font-lock-defaults’のためにそれらをセットするべきです(*note Font Lock Basics::を参照)。 Font Lockモードが一連のテキストにたいして構文的フォント表示を処理する ときは、常に‘syntax-propertize-function’で指定される関数を最初に呼び出し ます。メジャーモードは特別なケースでは‘syntax-table’テキストプロパティを 適用してバッファーの構文テーブルをオーバーライドするために、これを使用す ることができます。*note Syntax Properties::を参照してください。 -- Variable: font-lock-keywords-only この変数の値が非‘nil’なら、Font Lockは構文的フォント表示を行わずに ‘font-lock-keywords’にもとづく検索ベースのフォント表示だけを行う。 これは通常は‘font-lock-defaults’内のKEYWORDS-ONLY要素にもとづいて Font Lockモードによりセットされる。 -- Variable: font-lock-syntax-table この変数はコメントと文字列のフォント表示に使用するための構文テーブ ルを保持する。これは通常は‘font-lock-defaults’内のSYNTAX-ALIST要素 にもとづいてFont Lockモードによりセットされる。この値が‘nil’なら、 構文的フォント表示はバッファーの構文テーブル(関数‘syntax-table’がリ ターンする構文テーブル。*note Syntax Table Functions::を参照)を使用 する。 -- Variable: font-lock-syntactic-face-function この変数が非‘nil’なら、それは与えられた構文的要素にどのフェイスを使 用するかを決定する関数であること。この値は通常は ‘font-lock-defaults’内のOTHER-VARS要素を通じてセットされる。 この関数は1つの引数で呼び出され、‘parse-partial-sexp’がリターンする ポイントの状態をパースしてフェイスをリターンすること。リターンされ るデフォルト値はコメントにたいしては‘font-lock-comment-face’、文字 列にたいしては‘font-lock-string-face’ (*note Faces for Font Lock::を 参照)。 22.6.9 複数行のFont Lock構造 ---------------------------- ‘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がハ イライトを試みる前の任意のタイミングで)、何らかの方法によりそれを正 しく認識して、Font Lockが複数行構造の途中で開始や終了しないように指 示する‘font-lock-multiline’でそれをマークする。 複数行構造の再ハイライトを行うには3つの方法があります: • その構造にたいして正しく‘font-lock-multiline’を配置する。これにより その構造の一部が変更されると構造全体が再ハイライトされるだろう。あ るケースにおいてはそれを参照する‘font-lock-multiline’変数をセットす ることにより自動的にこれを行うことができる。 • ‘jit-lock-contextually’を確実にセットしてそれが行う処理に委ねる。こ れにより、実際の変更に続いて構造の一部だけが若干の遅延の後に再ハイ ライトされるだろう。これは複数行構造のさまざまな箇所のハイライトが 後続行のテキストに依存しない場合のみ機能する。 ‘jit-lock-contextually’はデフォルトでアクティブなので、これは魅力的 な解決策になり得る。 • その構造上に正しく‘jit-lock-defer-multiline’を配置する。これは ‘jit-lock-contextually’が使用された場合のみ機能し、再ハイライト前に 同様の遅延を伴うが、‘font-lock-multiline’のように後続行に依存する箇 所のハイライトも処理する。 22.6.9.1 複数行のFont Lock .......................... 複数行構造のFont Lockを確実に再ハイライトする方法の1つは、それらをテキス トプロパティ‘font-lock-multiline’にputする方法です。複数行構造の一部であ るようなテキストには値が非‘nil’であるようなこのプロパティが存在するべき です。 Font Lockがテキスト範囲をハイライトしようとする際は、まずそれらが ‘font-lock-multiline’プロパティでマークされたテキストにならないように必 要に応じて範囲の境界を拡張します。それからその範囲のすべての ‘font-lock-multiline’を削除してハイライトします。ハイライト指定(大抵は ‘font-lock-keywords’)は、適宜このプロパティを毎回再インストールしなけれ ばなりません。 *警告:* ハイライトが低速になるので大きなテキスト範囲にたいして ‘font-lock-multiline’を使用してはならない。 -- Variable: 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’を使用しなければなりません。 22.6.9.2 バッファー変更後のリージョンのフォント化 ................................................. バッファーが変更されたときFont Lockが再フォント表示するリージョンは、デ フォルトではその変更に関連する最小の行全体からなるシーケンスです。これは ほとんどの場合は良好に機能しますが、うまく機能しないとき(たとえば変更が それより前の行のテキストの構文的な意味を変更してしまうとき)もあります。 以下の変数をセットすることにより、再フォント表示するリージョンを拡張 (または縮小さえ)することができます: -- Variable: font-lock-extend-after-change-region-function このバッファーローカル変数は‘nil’、またはFont Lockモードにたいして スキャンしてフォント表示すべきリージョンを決定するために呼び出され る関数である。 この関数には標準的なBEGとEND、および‘after-change-functions’の OLD-LEN (*note Change Hooks::を参照)という3つのパラメーターが渡され る。この関数はフォント表示するリージョンのバッファー位置の開始と終 了(この順)からなるコンスセル、または‘nil’ (標準的な方法でリージョン を選択することを意味する)のいずれかをリターンすること。この関数はポ イント位置、match-data、カレントのナローイングを保つ必要がある。こ れがリターンするリージョンは、行の途中で開始や終了するかもしれない 。 この関数はバッファーを変更するたびに呼び出されるので有意に高速であ ること。 22.7 コードの自動インデント =========================== プログラミング言語のメジャーモードにとって、自動的なインデントの提供は重 要な機能です。これには2つのパートがあります。1つ目は正しい行のインデント が何か、そして2つ目はいつ行を再インデントするかの判断です。デフォルトで は‘electric-indent-chars’に含まれる文字(デフォルトでは改行のみ)をタイプ したとき、Emacsは常に行を再インデントします。メジャーモードはその言語の 構文に合わせて‘electric-indent-chars’に文字を追加できます。 正しいインデントの決定は‘indent-line-function’によりEmacs内で制御され ます(*note Mode-Specific Indent::を参照)。いくつかのモードでは_右_へのイ ンデントは信頼性がないことが知られています。これは通常は複数のインデント が有効であり、それぞれが異なる意味をもつのでインデント自体が重要だからで す。そのような場合には、そのモードは行が常にユーザーの意に反して行が毎回 再インデントされないことを保証するために‘electric-indent-inhibit’をセッ トするべきです。 よいインデント関数の記述は難しく、その広範な領域において未だ黒魔術の 域を脱していません。メジャーモード作者の多くは、単純なケース(たとえば前 のテキスト行のインデントとの比較)にたいして機能する、単純な関数の記述か らスタートすることでしょう。実際には行ベースではないほとんどのプログラミ ング言語にたいして、これは貧弱なスケールになりがちです。そのような関数に たいして、より多様な状況を処理するような改良を行うと関数はより一層複雑に なり、最終的な結果は誰にも触れようとする気を起こさせない、巨大で複雑な保 守不可能のインデント関数になる傾向があります。 よいインデント関数は、通常はその言語の構文に応じて実際にテキストをパ ースする必要があるでしょう。幸運なことにこのテキストパースはコンパイラー が要するほど詳細である必要はないでしょうが、その一方でインデントコードに 埋め込まれたパーサーは構文的に不正なコードにたいして、コンパイラーより幾 分寛容な振る舞いを求められるでしょう。 保守可能なよいインデント関数は、通常は2つのカテゴリーに落ち着きます。 どちらも何らかの安全な開始ポイントから、関心のある位置まで前方か後方へパ ースを行います。この2つの方法は、いずれも一方が他方に明快に優る選択では ありません。後方へのパースはプログラミング言語が前方にパースされるようデ ザインされているため、前方へのパースに比べて難しいことが多々ありますが、 インデントという目的においては安全な開始ポイントを推測する必要がないとい う利点があり、一般的にある行のインデントの判断のために分析を要するのは最 小限のテキストだけという特性に恵まれているので、前の無関係なコード片内に ある何らかの構文エラーの影響をインデントが受けにくくなる傾向があります。 一方で前方へのパースは通常はより簡単であり、一度のパースでリージョン全体 を効果的に再インデントすることが可能になるという利点があります。 インデント関数をスクラッチから記述するよりも、既存のインデント関数の 使用と再利用、または一般的なインデントエンジンに委ねるほうが優る場合がし ばしばあります。しかしそのようなエンジンは悲しむべきほど少数しかありませ ん。(C、C++、Java、Awk、およびその類のモードに使用される)CCモードのイン デントコードは年月を経てより一般化されてきているので、あなたの言語にこれ らの言語と何らかの類似点があるなら、このエンジンの使用を試みるかもしれま せん。もう一方のSMIEはLispのsexp精神によるアプローチを採用して、それを非 Lisp言語に適応します。 22.7.1 SMIE: 無邪気なインデントエンジン --------------------------------------- SMIEは一般的な操作とインデントを提供するエンジンです。これは演算子順位文 法(operator precedence grammar)を使用する非常にシンプルなパーサーにもと づいたエンジンであり、メジャーモードがLispのS式ベースの操作を非Lisp言語 に拡張するのを助けるとともにシンプルに使用できるにも関わらず、信頼できる 自動インデントを提供します。 演算子順位文法はコンパイラー内で使用されるより一般的なパーサーと比較 すると非常に原始的なパーステクノロジーです。このパーサーには次のような特 徴があります。このパーサーのパース能力は非常に限定的で構文エラーを大概は 検出できません。しかしアルゴリズム的に前方パースと同様に後方パースを効果 的に行うことが可能です。実際にそれはSMIEが後方パースにもとづくインデント を使用でき、‘forward-sexp’と‘backward-sexp’の両方の機能を提供できるとと もに、特別な努力を要さずに構文的に不正なコードにたいして自然に機能するで あろうことを意味します。欠点はほとんどのプログラミング言語は、少なくとも 何らかの特別なトリック(*note SMIE Tricks::を参照)で再分類しなければ SMIEを使用して正しくパースできないことをも意味することです。 22.7.1.1 SMIEのセットアップと機能 ................................. SMIEは構造的な操作とコードの構造的構造にもとづくその他さまざまな機能、特 に自動インデントにたいするワンストップショップ(一カ所で必要な全ての買い 物ができる店やそのような場所)であることを意図しています。メインのエント リーポイントは‘smie-setup’で、これは通常はメジャーモードセットアップの間 に呼び出される関数です。 -- Function: smie-setup grammar rules-function &rest keywords SMIEの操作とインデントをセットアップする。GRAMMARは ‘smie-prec2->grammar’により生成される文法テーブル(grammar table)、 RULES-FUNCTIONは‘smie-rules-function’で使用されるインデントルールの セット、KEYWORDSは追加の引数であり以下のキーワードを含むことができ る: • ‘:forward-token’ FUN: 使用する前方lexer(lexer=lexical analyzer: 字句解析プログラム)を指定する。 • ‘:backward-token’ FUN: 使用する後方lexerを指定する。 この関数を呼び出せば‘forward-sexp’、‘backward-sexp’、 ‘transpose-sexps’のようなコマンドが、すでに構文テーブルにより処理されて いる単なるカッコのペア以外の、構造的な要素を正しく扱うことができるように なります。たとえば与えられた文法が十分に明快ならば、‘transpose-sexps’は その言語の優先順位のルールを考慮して‘+’演算子の2つの引数を正しく入れ替え ることができます。 ‘smie-setup’を呼び出すことにより、TABによるインデントを期待通り機能さ せるとともに、‘begin...end’のような要素に適用するために ‘blink-matching-paren’を拡張して、そのメジャーモードのキーマップ内でバイ ンドできるいくつかのコマンドを提供することも満足されます。 -- Command: smie-close-block このコマンドは、もっとも最近オープンされた(まだクローズされていない )ブロックをクローズする。 -- Command: smie-down-list &optional arg このコマンドは‘down-list’と似ているが、‘begin...end’のようなカッコ 以外のネストされたトークンにも注意を払う。 22.7.1.2 演算子順位文法 ....................... 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)を表現するのに十分です。 -- Function: smie-prec2->grammar table この関数は_prec2_文法TABLEを引数に受け取り、‘smie-setup’で使用する のに適したalistをリターンする。_prec2_文法TABLEは、それ自体が以下の 関数のいずれかによりビルドされることを意図している。 -- Function: smie-merge-prec2s &rest tables この関数は複数の_prec2_文法TABLESを、新たな_prec2_テーブルにマージ する。 -- Function: smie-precs->prec2 precs この関数は順位テーブルPRECSから_prec2_テーブルをビルドする。PRECSは 優先順(たとえば‘"+"’は‘"*"’より前にくる)にソートされたリストであり 、要素は‘(ASSOC OP ...)’の形式であること。ここでOPは演算子として振 る舞うトークン、ASSOCはそれらの結合法則であり‘left’、‘right’、 ‘assoc’、‘nonassoc’のいずれかである。与えられた要素内のすべての演算 子は同じ優先レベルと結合法則を共有する。 -- Function: smie-bnf->prec2 bnf &rest resolvers この関数によりBNF記法を使用した文法を指定することができる。これはそ の文法のBNF表記と、同様に競合解決ルールRESOLVERSを受け取って _prec2_テーブルをリターンする。 BNFは‘(NONTERM RHS1 RHS2 ...)’という形式の非終端定義、各RHSは終端記 号(トークンとも呼ばれる)、または非終端記号の(空でない)リストである 。 すべての文法が許容される訳ではない: • RHSに空のリストは指定できない(いずれにせよSMIEは空文字列にマッ チさせるためにすべての非終端記号を許容するので空リストが必要に なることは決してない)。 • RHSの後に連続する2つの非終端記号は指定できない。非終端記号の各 ペアは終端記号(かトークン)で区切られる必要がある。これは演算子 順位文法の基本的な制約である。 さらに競合が発生し得る: • リターンされる_prec2_テーブルはトークンのペア間の制約を保持し 、与えられた任意のペアはT1 < T2、T1 = T2、T1 > T2のいずれかの うち1つの制約をだけ与えることができる。 • トークンは‘opener’(開カッコに似た何か)、‘closer’(閉カッコのよ うなもの)、またはこれら2つのいずれでもない‘neither’(2項演算子 や‘"else"’のようなinnerトークン)である。 順位の競合はRESOLVERSを通じて解決され得る。これは_precs_テーブル (‘smie-precs->prec2’を参照)のリストである。それぞれの順位競合にたい して、これらの‘precs’テーブルが特定の制約を指定している場合は、かわ りにこの制約により競合が解決され、それ以外は競合する制約のうち任意 の1つが報告されて他は単に無視される。 22.7.1.3 言語の文法の定義 ......................... ある言語にたいして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 "*"))))) 注意すべき点がいくつかあります: • 上記の文法は関数呼び出しの構文に明示的に言及していない。SMIEは識別 子、対応がとれたカッコ(balanced parentheses)、または‘begin ... end’ブロックのようなsexpの任意のシーケンスがどこに、どのように出現 しても自動的にそれを許容するだろう。 • 文法カテゴリー‘id’は右側に何ももたない。これは‘id’が空文字列だけに マッチ可能なことを意味しない。なぜなら上述のように任意のsexpシーケ ンスはどこに、どのような方法でも出現するからである。 • BNF文法では非終端記号が連続して出現し得ないので、終端記号として作用 するトークンを正しく扱うのが困難なため、上述の文法ではSMIEが容易に 扱える‘";"’を_セパレーター(separator)_ステートメントのかわりとして 扱っている。 • シーケンス内で使用される、(上記の‘","’や‘";"’のような)セパレーター は、BNFルールでは‘(foo (foo "separator" foo) ...)’のように定義する のが最善である。これは順位の競合を生成するが、明示的に‘(assoc "separator")’を与えることにより解決される、 • SMIEは構文テーブル(syntax table)内でカッコ構文(paren syntax)をもつ ようにマークされた任意の文字をペアにするだろうから、‘("(" exps ")")’ルールにカッコをペアにする必要はなかった。(‘exps’の定義と併せ て)これはかわりに‘","’がカッコの外に出現すべきではないことを明確に するためのルール。 • 競合解決のための_precs_テーブルは単一のテーブルより複数のテーブルを もつほうが、可能な場合は文法のBNF部分が関連する順位を指定できるので 優れている。 • ‘left’や‘right’を選択することが優るという明白な理由がなければ、通常 は‘assoc’を使用して演算子を結合演算子(associative)とマークするほう が優れている。この理由により上述の‘"+"’と‘"*"’は、たとえその言語が それらを形式上は左結合(left associative)と定義していても‘assoc’とし て定義されている。 22.7.1.4 トークンの定義 ....................... 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として処理 します。 22.7.1.5 非力なパーサーの使用 ............................. 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は特別な手がか りを見つけるために周囲のテキストを調べる必要があるでしょう。 22.7.1.6 インデントルールの指定 ............................... 提供された文法にもとづき、他に特別なことを行わなくても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にインデントする。 • NUMBER: 基本トークン(base token: ‘:after’にたいするカレントトークン であり、かつ‘:before’にたいしてparentであるようなトークン)にたいし て相対的なNUMBERによるオフセット。 22.7.1.7 インデントルールにたいするヘルパー関数 ............................................... SMIEはインデントを決定する関数内で使用するために特別にデザインされたさま ざまな関数を提供します(これらの関数のうちのいくつかは異なるコンテキスト 内で使用された場合に中断する)。これらの関数はすべてプレフィックス ‘smie-rule-’で始まります。 -- Function: smie-rule-bolp カレントトークンが行の先頭にあれば非‘nil’をリターンする。 -- Function: smie-rule-hanging-p カレントトークンが_hanging(ぶら下がり)_なら非‘nil’をリターンする。 トークンがその行の最後のトークンであり、他のトークンが先行する場合 、そのトークンは_hanging_である。行に単独のトークンはhangingではな い。 -- Function: smie-rule-next-p &rest tokens 次のトークンがTOKENS内にあれば非‘nil’をリターンする。 -- Function: smie-rule-prev-p &rest tokens 前のトークンがTOKENS内にあれば非‘nil’をリターンする。 -- Function: smie-rule-parent-p &rest parents カレントトークンのparentがPARENTS内にあれば非‘nil’をリターンする。 -- Function: smie-rule-sibling-p カレントトークンのparentが実際はsibling(兄弟)なら非‘nil’をリターン する。たとえば‘","’のparentが直前の‘","’のような場合が該当。 -- Function: smie-rule-parent &optional offset カレントトークンをparentとアライン(align: 桁揃え)するための適切なオ フセットをリターンする。OFFSETが非‘nil’なら、それは追加オフセットと して適用される整数であること。 -- Function: smie-rule-separator method _セパレーター(separator)_としてカレントトークンをインデントする。 ここでの_セパレーター_とは周囲を取り囲む何らかの構文構造内でさまざ まな要素を区切ることを唯一の目的とするトークンであり、それ自体は何 も意味をもたないトークン(通常は抽象構文木内でノードとして存在しない こと)を意味する。 このようなトークンは結合構文をもち、その構文的parentと密に結び付け られることが期待される。典型的な例としては引数リスト内の‘","’ (カッ コで括られた内部)、または命令文シーケンス内の‘";"’ (‘{...}’や ‘begin...end’で括られたブロックの内部)が挙げられる。 METHODは‘smie-rules-function’に渡されるメソッド名であること。 22.7.1.8 インデントルールの例 ............................. 以下はインデント関数の例です: (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))))) 注意すべき点がいくつかあります: • 最初のcaseは使用する基本的なインデントの増分を示す。 ‘sample-indent-basic’が‘nil’なら、SMIEはグローバルセッティング ‘smie-indent-basic’を使用する。メジャーモードがかわりに ‘smie-indent-basic’をバッファーローカルにセットするかもしれないが推 奨しない。 • トークン‘","’にたいするルールによってカンマセパレーターが行頭にある 場合にSMIEをより賢明に振る舞わせようとしている。これはセパレーター のインデントを解除(outdent)、カンマの後のコードにアラインされるよう 試みる。たとえば: x = longfunctionname ( arg1 , arg2 ); • そうしなければSMIEが‘":="’を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"’のインデントを再利用することである。 22.7.1.9 インデントのカスタマイズ ................................. SMIEにより提供されるインデントを使用するモードを使っている場合には、好み に合わせてインデントをカスタマイズできます。これはモードごと(オプション ‘smie-config’を使用)、またはファイルごと(ファイルローカル変数指定内で関 数‘smie-config-local’を使用)に行うことができます。 -- User Option: smie-config このオプションによりモードごとにインデントをカスタマイズできる。こ れは‘(MODE . RULES)’という形式の要素をもつalist。rulesの正確な形式 については変数のドキュメントを参照のこと。しかしコマンド ‘smie-config-guess’を使用したほうが、より簡単に見つけられるかもしれ ない。 -- Command: smie-config-guess このコマンドは好みのスタイルのインデントを生成する適切セッティング の解決を試みる。あなたのスタイルでインデントされたファイルをvisitし ているときに単にこのコマンドを呼び出せばよい。 -- Command: smie-config-save ‘smie-config-guess’を使用した後にこのコマンドを呼び出すと将来のセッ ション用にセッティングを保存する。 -- Command: smie-config-show-indent &optional move このコマンドはカレント行のインデントに使用されているルールを表示す る。 -- Command: smie-config-set-indent このコマンドはカレント行のインデントに合わせてローカルルールを追加 する。 -- Function: smie-config-local rules この関数はカレントバッファーにたいするインデントルールとしてRULESを 追加する。これらのルールは‘smie-config’オプションにより定義された任 意のモード固有ルールに追加される。特定のファイルにたいしてカスタム インデントルールを指定するには、‘eval: (smie-config-local '(RULES))’の形式のエントリーをそのファイルのローカル変数に追加する 。 22.8 Desktop Saveモード ======================= “Desktop Saveモード”とは、あるセッションから別のセッションへEmacs状態を 保存する機能です。Desktop Saveモードの使用に関するユーザーレベルのコマン ドについては、GNU Emacsマニュアルに記載されています(*note (emacs)Saving Emacs Sessions::を参照)。バッファーでファイルをvisitしているモードでは、 この機能を使うために何も行う必要はありません。 ファイルをvisitしていないバッファーについて状態を保存するには、そのメ ジャーモードがバッファーローカル変数‘desktop-save-buffer’を非‘nil’値にバ インドしなければなりません。 -- Variable: desktop-save-buffer このバッファーローカル変数が非‘nil’なら、デスクトップ保存時にそのバ ッファー状態がdesktopファイルに保存される。値が関数なら、その関数は デスクトップ保存時に引数DESKTOP-DIRNAMEで呼び出されて、関数が呼び出 されたバッファーの状態とともに関数の値がdesktopファイルに保存される 。補助的な情報の一部としてファイル名がリターンされたとき、それらは 以下を呼び出してフォーマットされること (desktop-file-name FILE-NAME DESKTOP-DIRNAME) ファイルをvisitしていないバッファーがリストアされるようにするには、メ ジャーモードがその処理を行う関数を定義しなければならず、その関数は連想配 列‘desktop-buffer-mode-handlers’にリストされなければならない。 -- Variable: 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’にバインド される関数がリターンする値。 23 ドキュメント *************** GNU Emacsには便利なビルトインのヘルプ機能があり、それらのほとんどは関数 や変数のドキュメント文字列に付属するドキュメント文字列の情報が由来のもの です。このチャプターではLispプログラムからドキュメント文字列にアクセスす る方法について説明します。 ドキュメント文字列のコンテンツはある種の慣習にしたがう必要があります 。特に最初の行はその関数や変数を簡単に説明する1つか2つの完全なセンテンス であるべきです。よいドキュメント文字列を記述する方法については*note Documentation Tips::を参照してください。 Emacs向けのドキュメント文字列はEmacsマニュアルと同じものではないこと に注意してください。マニュアルはTexinfo言語で記述された独自のソースファ イルをもちます。それにたいしドキュメント文字列はそれが適用される関数と変 数の定義内で指定されたものです。ドキュメント文字列を収集してもそれはマニ ュアルとしては不十分です。なぜならよいマニュアルはそのやり方でまとめられ たものではなく、議論にたいするトピックという観点でまとめられたものだから です。 ドキュメント文字列を表示するコマンドについては、*note Help: (emacs)Help.を参照してください。 23.1 ドキュメントの基礎 ======================= ドキュメント文字列はテキストをダブルクォート文字で囲んだ文字列にたいする Lisp構文を使用して記述されます。実はこれは実際のLisp文字列です。関数また は変数の定義内の適切な箇所に文字列があると、それは関数や変数のドキュメン トの役割を果たします。 関数定義(‘lambda’や‘defun’フォーム)の中では、ドキュメント文字列は引数 リストの後に指定され、通常は関数オブジェクト内に直接格納されます。*note Function Documentation::を参照してください。関数名の ‘function-documentation’プロパティに関数ドキュメントをputすることもでき ます(*note Accessing Documentation::を参照)。 変数定義(‘defvar’フォーム)の中では、ドキュメント文字列は初期値の後に 指定されます。*note Defining Variables::を参照してください。この文字列は その変数の‘variable-documentation’プロパティに格納されます。 Emacsがメモリー内にドキュメント文字列を保持しないときがあります。それ には、これには2つの状況があります。1つ目はメモリーを節約するためで、事前 ロードされた関数と変数(プリミティブを含む)のドキュメントは、 ‘doc-directory’で指定されたディレクトリー内の‘DOC’という名前のファイルに 保持されます(*note Accessing Documentation::を参照)。2つ目は関数や変数が バイトコンパイルされたファイルからロードされたときで、Emacsはそれらのド キュメント文字列のロードを無効にします(*note Docs and Compilation::を参 照)。どちらの場合も、ある関数にたいしてユーザーが‘C-h f’(‘describe-function’)を呼び出したとき等の必要なときだけEmacsはファイル のドキュメント文字列を照会します。 ドキュメント文字列にはユーザーがドキュメントを閲覧するときのみルック アップされるキーバインディングを参照する、特別な“キー置換シーケンス(key substitution sequences)”を含めることができます。これにより、たとえユーザ ーがデフォルトのキーバインディングを変更していてもヘルプコマンドが正しい キーを表示できるようになります。 オートロードされたコマンド(*note Autoload::を参照)のドキュメント文字 列ではこれらのキー置換シーケンスは特別な効果をもち、そのコマンドにたいす る‘C-h f’によってオートロードをトリガーします(これは‘*Help*’バッファー内 のハイパーリンクを正しくセットアップするために必要となる)。 23.2 ドキュメント文字列へのアクセス =================================== -- Function: documentation-property symbol property &optional verbatim この関数はプロパティPROPERTY配下のSYMBOLのプロパティリスト内に記録 されたドキュメント文字列をリターンする。これはほとんどの場合 PROPERTYを‘variable-documentation’にして、変数のドキュメント文字列 の照会に使用される。しかしカスタマイゼーショングループのような他の 種類のドキュメント照会にも使用できる(が関数のドキュメントには以下の ‘documentation’関数を使用する)。 そのプロパティの値が‘DOC’ファイルやバイトコンパイル済みファイルに格 納されたドキュメント文字列を参照する場合、この関数はその文字列を照 会してそれをリターンする。 プロパティの値が‘nil’や文字列以外でファイル内のテキストも参照しなけ れば、文字列を取得するLisp式として評価される。 最終的にこの関数はキーバインディングを置換するために、文字列を ‘substitute-command-keys’に引き渡す(*note Keys in Documentation::を 参照)。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: documentation function &optional verbatim この関数はFUNCTIONのドキュメント文字列をリターンする。この関数はマ クロ、名前付きキーボードマクロ、およびスペシャルフォームも通常の関 数と同様に処理する。 FUNCTIONがシンボルならそのシンボルの‘function-documentation’プロパ ティを最初に調べる。それが非‘nil’値をもつなら、その値(プロパティの 値が文字列以外ならそれを評価した値)がドキュメントとなる。 FUNCTIONがシンボル以外、あるいは‘function-documentation’プロパティ をもたなければ、‘documentation’は必要ならファイルを読み込んで実際の 関数定義のドキュメント文字列を抽出する。 最後にVERBATIMが‘nil’なら、この関数は‘substitute-command-keys’を呼 び出す。結果はリターンするための文字列。 ‘documentation’関数はFUNCTIONが関数定義をもたなければ ‘void-function’エラーをシグナルする。しかし関数定義がドキュメントを もたない場合は問題ない。その場合は‘documentation’は‘nil’をリターン する。 -- Function: face-documentation face この関数はFACEのドキュメント文字列をフェイスとしてリターンする。 以下は‘documentation’と‘documentation-property’を使用した例で、いくつ かのシンボルのドキュメント文字列を‘*Help*’バッファー内に表示します。 (defun describe-symbols (pattern) "Describe the Emacs Lisp symbols matching PATTERN. All symbols that have PATTERN in their name are described in the *Help* buffer." (interactive "sDescribe symbols matching: ") (let ((describe-func (function (lambda (s) ;; シンボルの説明をプリントする (if (fboundp s) ; これは関数 (princ (format "%s\t%s\n%s\n\n" s (if (commandp s) (let ((keys (where-is-internal s))) (if keys (concat "Keys: " (mapconcat 'key-description keys " ")) "Keys: none")) "Function") (or (documentation s) "not documented")))) (if (boundp s) ; これは変数 (princ (format "%s\t%s\n%s\n\n" s (if (custom-variable-p s) "Option " "Variable") (or (documentation-property s 'variable-documentation) "not documented"))))))) sym-list) ;; PATTERNにマッチするシンボルのリストを構築 (mapatoms (function (lambda (sym) (if (string-match pattern (symbol-name sym)) (setq sym-list (cons sym sym-list)))))) ;; データを表示 (help-setup-xref (list 'describe-symbols pattern) (interactive-p)) (with-help-window (help-buffer) (mapcar describe-func (sort sym-list 'string<))))) ‘describe-symbols’関数は‘apropos’のように機能しますが、より多くの情報 を提供します。 (describe-symbols "goal") ---------- Buffer: *Help* ---------- goal-column Option Semipermanent goal column for vertical motion, as set by ... minibuffer-temporary-goal-position Variable not documented set-goal-column Keys: C-x C-n Set the current horizontal position as a goal for C-n and C-p. Those commands will move to this position in the line moved to rather than trying to keep the same horizontal position. With a non-nil argument ARG, clears out the goal column so that C-n and C-p resume vertical motion. The goal column is stored in the variable ‘goal-column’. msgid "" "(defun describe-symbols (pattern)\n" " \"Describe the Emacs Lisp symbols matching PATTERN.\n" "All symbols that have PATTERN in their name are described\n" "in the `*Help*' buffer.\"\n" " (interactive \"sDescribe symbols matching: \")\n" " (let ((describe-func\n" " (function\n" " (lambda (s)\n" temporary-goal-column Variable Current goal column for vertical motion. It is the column where point was at the start of the current run of vertical motion commands. When moving by visual lines via the function ‘line-move-visual’, it is a cons cell (COL . HSCROLL), where COL is the x-position, in pixels, divided by the default column width, and HSCROLL is the number of columns by which window is scrolled from left margin. When the ‘track-eol’ feature is doing its job, the value is ‘most-positive-fixnum’. ---------- Buffer: *Help* ---------- -- Function: Snarf-documentation filename この関数はEmacsビルド時の実行可能なEmacsダンプ直前に使用される。こ れはファイルFILENAME内に格納されたドキュメント文字列の位置を探して 、メモリー上の関数定義および変数のプロパティリスト内にそれらの位置 を記録する。*note Building Emacs::を参照のこと。 Emacsは‘emacs/etc’ディレクトリーからファイルFILENAMEを読み込む。そ の後ダンプされたEmacs実行時に、ディレクトリー‘doc-directory’内の同 じファイルを照会する。FILENAMEは通常は‘"DOC"’。 -- Variable: doc-directory この変数はビルトインおよび事前ロードされた関数と変数のドキュメント 文字列を含んだファイル‘"DOC"’があるべきディレクトリーの名前を保持す る。 これはほとんどの場合は‘data-directory’と同一。実際にインストールし たEmacsではなくEmacsをビルドしたディレクトリーからEmacsを実行したと きは異なるかもしれない。*note Definition of data-directory::を参照 のこと。 23.3 ドキュメント内でのキーバインディングの置き換え =================================================== ドキュメント文字列がキーシーケンスを参照する際、それらはカレントである実 際のキーバインディングを使用するべきです。これらは以下で説明する特別なキ ーシーケンスを使用して行うことができます。通常の方法によるドキュメント文 字列へのアクセスは、これらの特別なキーシーケンスをカレントキーバインディ ングに置き換えます。これは‘substitute-command-keys’を呼び出すことにより 行われます。あなた自身がこの関数を呼び出すこともできます。 以下はそれら特別なシーケンスと、その意味についてのリストです: ‘\[COMMAND]’ これはCOMMANDを呼び出すキーシーケンス、またはCOMMANDがキーバインデ ィングをもたなければ‘M-x COMMAND’。 ‘\{MAPVAR}’ これは変数MAPVARの値であるようなキーマップの要約(summary)を意味する 。この要約は‘describe-bindings’を用いて作成される。 ‘\’ これ自体は何のテキストも意味せず副作用のためだけに使用される。これ はこのドキュメント文字列内にある、後続のすべての‘\[COMMAND]’にたい するキーマップとしてMAPVARの値を指定する。 ‘‘’ ‘`’ この両者(左シングルクォーテーションマークとグレーブアクセント)は左 クォートを意味する。これは‘text-quoting-style’の値に応じて左シング ルクォーテーションマーク、アポストロフィー、グレーブアクセントのい ずれかを生成する。 ‘’’ ‘'’ この両者(右シングルクォーテーションマークとアポストロフィー)は右ク ォートを意味する。これは‘text-quoting-style’の値に応じてアポストロ フィー)はシングルクォーテーションマークかアポストロフィーのいずれか を生成する。 ‘\=’ これは後続の文字をクォートして無効にする。したがって‘\=\[’は‘\[’、 ‘\=\=’は‘\=’を出力する。 *注意してください:* Emacs Lisp内の文字列として記述する際は‘\’を2つ記 述しなければなりません。 -- Variable: text-quoting-style この変数の値はEmacsがヘルプとメッセージの文言でシングルクォートに使 用するべきスタイルを指定するシンボルである。この変数の値が‘curve’な ら‘like this’のようなcurved single quotesスタイル。値が‘straight’な ら'like this'のようなstraight apostrophesスタイル。値が‘grave’なら `like this'のようなEmacsのバージョン25以前の標準であるgrave accentと apostropheのスタイル。デフォルト値の‘nil’はcurved single quotesが表 示可能なら‘curve’、それ以外なら‘grave’と同様に振る舞う。 この変数はcurved quotesに問題のあるプラットフォームでエキスパートが 使用可能。通常の使用を意図していないのでユーザーオプションではない 。 -- Function: substitute-command-keys string この関数は上述の特別なシーケンスをSTRINGからスキャンして、それらが 意味するもので置き換えてその結果を文字列としてリターンする。これに よりそのユーザー自身がカスタマイズした実際のキーシーケンスを参照す るドキュメントが表示できる。 あるコマンドが複数のバインディングをもつ場合、通常この関数は最初に 見つかったバインディングを使用する。以下のようにしてコマンドのシン ボルプロパティ‘:advertised-binding’に割り当てることにより、特定のキ ーバインディングを指定できる: (put 'undo :advertised-binding [?\C-/]) ‘:advertised-binding’プロパティはメニューアイテム(*note Menu Bar::を 参照)に表示されるバインディングにも影響する。コマンドが実際にもたな いキーバインディングを指定するとこのプロパティは無視される。 以下は特別なキーシーケンスの例: (substitute-command-keys "To abort recursive edit, type `\\[abort-recursive-edit]'.") ⇒ "To abort recursive edit, type ‘C-]’." (substitute-command-keys "The keys that are defined for the minibuffer here are: \\{minibuffer-local-must-match-map}") ⇒ "The keys that are defined for the minibuffer here are: ? minibuffer-completion-help SPC minibuffer-complete-word TAB minibuffer-complete C-j minibuffer-complete-and-exit RET minibuffer-complete-and-exit C-g abort-recursive-edit " (substitute-command-keys "To abort a recursive edit from the minibuffer, type \ `\\\\[abort-recursive-edit]'.") ⇒ "To abort a recursive edit from the minibuffer, type ‘C-g’." ドキュメント文字列内のテキストにたいしては他にも特別な慣習があります 。それらはたとえばこのマニュアルの関数、変数、およびセクションで参照でき ます。詳細は*note Documentation Tips::を参照してください。 23.4 ヘルプメッセージの文字記述 =============================== 以下の関数はイベント、キーシーケンス、文字をテキスト表記(textual descriptions)に変換します。これらの変換された表記は、メッセージ内に任意 のテキスト文字やキーシーケンスを含める場合に有用です。なぜなら非プリント 文字や空白文字はプリント文字シーケンスに変換されるからです。空白文字以外 のプリント文字はその文字自身が表記になります。 -- Function: key-description sequence &optional prefix この関数はSEQUENCE内の入力イベントにたいしてEmacsの標準表記を含んだ 文字列をリターンする。PREFIXが非‘nil’なら、それはSEQUENCEに前置され る入力イベントシーケンスであり、リターン値にも含まれる。引数には文 字列、ベクター、またはリストを指定できる。有効なイベントに関する詳 細は*note Input Events::を参照のこと。 (key-description [?\M-3 delete]) ⇒ "M-3 " (key-description [delete] "\M-3") ⇒ "M-3 " 以下の‘single-key-description’の例も参照のこと。 -- Function: single-key-description event &optional no-angles この関数はキーボード入力にたいする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) ⇒ "" (single-key-description 'C-mouse-1) ⇒ "" (single-key-description 'C-mouse-1 t) ⇒ "C-mouse-1" -- Function: text-char-description character この関数はテキスト内に出現する文字にたいするEmacsの標準表記として CHARACTERを表記する文字列をリターンする。これは ‘single-key-description’と似ているが、コントロール文字にカレットが 前置されて表される点が異なる(これはEmacsバッファー内でコントロール 文字を表示する通常の方法である)。他にも‘single-key-description’が 2**27ビットをメタ文字とするのにたいし、‘text-char-description’は 2**7ビットをメタ文字とする点が異なる。 (text-char-description ?\C-c) ⇒ "^C" (text-char-description ?\M-m) ⇒ "\xed" (text-char-description ?\C-\M-m) ⇒ "\x8d" (text-char-description (+ 128 ?m)) ⇒ "M-m" (text-char-description (+ 128 ?\C-m)) ⇒ "M-^M" -- Command: read-kbd-macro string &optional need-vector この関数は主にキーボードマクロを操作するために使用されるが、大雑把 な意味で‘key-description’の逆の処理にも使用できる。キー表記を含むス ペース区切りの文字列でこれを呼び出すと、それに対応するイベントを含 む文字列かベクターをリターンする(これは単一の有効なキーシーケンスで あるか否かは問わず何のイベントを使用するかに依存する。*note Key Sequences::を参照のこと)。NEED-VECTORが非‘nil’ならリターン値は常に ベクター。 23.5 ヘルプ関数 =============== Emacsはさまざまなビルトインのヘルプ関数を提供しており、それらはすべてプ レフィックス‘C-h’のサブコマンドとしてユーザーがアクセスできます。それら についての詳細は*note Help: (emacs)Help.を参照してください。ここでは同様 な情報に関するプログラムレベルのインターフェイスを説明します。 -- Command: apropos pattern &optional do-all この関数は名前に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された_すべて_のシンボルも表示 する(同様にリターン値としてもそれらをリストする)。 -- Variable: help-map この変数の値はHelpキー‘C-h’に続く文字にたいするローカルキーマップで ある。 -- Prefix Command: help-command このシンボルは関数ではなく関数定義セルには‘help-map’としてキーマッ プを保持する。これは‘help.el’内で以下のように定義されている: (define-key global-map (string help-char) 'help-command) (fset 'help-command help-map) -- User Option: help-char この変数の値はヘルプ文字(help character: Helpを意味する文字として Emacsが認識する文字)。デフォルトの値は‘C-h’を意味する8。この文字を 読み取った際に‘help-form’が非‘nil’のLisp式なら、Emacsはその式を評価 して結果が文字列の場合はウィンドウ内にそれを表示する。 ‘help-form’の値は通常は‘nil’。その場合にはヘルプ文字はコマンド入力 のレベルにおいて特別な意味を有さず、通常の方法におけるキーシーケン スの一部となる。‘C-h’の標準的なキーバインディングは、複数の汎用目的 をもつヘルプ機能のプレフィックスキー。 ヘルプ文字はプレフィックスキーの後でも特別な意味をもつ。ヘルプ文字 がプレフィックスキーのサブコマンドとしてバインディングをもたなけれ ば、そのプレフィックスキーのすべてのサブコマンドのリストを表示する ‘describe-prefix-bindings’を実行する。 -- User Option: help-event-list この変数の値はヘルプ文字の選択肢の役割を果たすイベント型のリスト。 これらのイベントは‘help-char’で指定されるイベントと同様に処理される 。 -- Variable: help-form この変数が非‘nil’なら、その値は文字‘help-char’が読み取られるたびに 評価されるフォームであること。そのフォームの評価によって文字列が生 成されたらその文字列が表示される。 ‘read-event’、‘read-char-choice’、‘read-char’を呼び出すコマンドは、 それが入力を行う間は恐らく‘help-form’を非‘nil’にバインドするべきだ ろう(‘C-h’が他の意味をもつなら行わないこと)。この式を評価した結果は 、それが何にたいする入力なのかと、それを正しくエンターする方法を説 明する文字列であること。 ミニバッファーへのエントリーにより、この変数は ‘minibuffer-help-form’の値にバインドされる(*note Definition of minibuffer-help-form::を参照)。 -- Variable: prefix-help-command この変数はプレフィックスキーにたいするヘルプをプリントする関数を保 持する。その関数はユーザーが後にヘルプ文字を伴うプレフィックスキー をタイプして、そのヘルプ文字がプレフィックスの後のバインディングを もたないたときに呼び出される。この変数のデフォルト値は ‘describe-prefix-bindings’。 -- Command: describe-prefix-bindings この関数はもっとも最近のプレフィックスキーのサブコマンドすべてにた いするリストを表示する‘describe-bindings’を呼び出す。記述されるプレ フィックスは、そのキーシーケンスの最後のイベントを除くすべてから構 成される(最後のイベントは恐らくヘルプ文字)。 以下の2つの関数はelectricモードのように制御を放棄せずにヘルプを提供し たいモードを意図しています。これらは通常のヘルプ関数と区別するために名前 が‘Helper’で始まります。 -- Command: Helper-describe-bindings このコマンドはローカルキーマップとグローバルキーマップの両方のキー バインディングすべてのリストを含むヘルプバッファーを表示するウィン ドウをポップアップする。これは‘describe-bindings’を呼び出すことによ って機能する。 -- Command: Helper-help このコマンドはカレントモードにたいするヘルプを提供する。これはミニ バッファー内でメッセージ‘Help (Type ? for further options)’とともに ユーザーに入力を求めて、その後キーバインディングが何か、何を意図す るモードなのかを探すための助けを提供する。これは‘nil’をリターンする 。 これはマップ‘Helper-help-map’を変更することによってカスタマイズでき る。 -- Variable: data-directory この変数はEmacsに付随する特定のドキュメントおよびテキストファイルを 探すディレクトリーの名前を保持する。 -- Function: help-buffer この関数はヘルプバッファーの名前(通常は‘*Help*’)をリターンする。そ のようなバッファーが存在しなければ最初にそれを作成する。 -- Macro: with-help-window buffer-name body... このマクロは‘with-output-to-temp-buffer’ (*note Temporary Displays::を参照)のようにBODYを評価して、そのフォームが生成したすべ ての出力をBUFFER-NAMEという名前のバッファーに挿入する(BUFFER-NAMEは 通常は関数‘help-buffer’によりリターンされる値であること)。これは指 定されたバッファーをHelpモードにして、ヘルプウィンドウのquitやスク ロールする方法を告げるメッセージを表示する。これはユーザーオプショ ン‘help-window-select’のカレント値が適切にセットされていればヘルプ ウィンドウの選択も行う。これはBODY内の最後の値をリターンする。 -- Function: help-setup-xref item interactive-p この関数は‘*Help*’バッファー内のクロスリファレンスデータを更新する 。このクロスリファレンスはユーザーが‘Back’ボタンか‘Forward’ボタン上 でクリックした際のヘルプ情報の再生成に使用される。‘*Help*’バッファ ーを使用するほとんどのコマンドは、バッファーをクリアーする前にこの 関数を呼び出すべきである。ITEM引数は‘(FUNCTION . ARGS)’という形式で あること。ここでFUNCTIONは引数リストARGSで呼び出されるヘルプバッフ ァーを再生成する関数。コマンド呼び出しがinteractiveに行われた場合、 INTERACTIVE-P引数は非‘nil’。この場合には‘*Help*’バッファーの ‘Back’ボタンにたいするitemのスタックはクリアーされる。 ‘help-buffer’、‘with-help-window’、‘help-setup-xref’の使用例は*note describe-symbols example::を参照してください。 -- Macro: make-help-screen fname help-line help-text help-map このマクロは提供するサブコマンドのリストを表示するプレフィックスキ ーのように振る舞う、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’内で使 用される。 -- User Option: three-step-help この変数が非‘nil’なら、‘make-help-screen’で定義されたコマンドは最初 にエコーエリア内に自身のHELP-LINE文字列を表示して、ユーザーが再度ヘ ルプ文字をタイプした場合のみ長いHELP-TEXT文字列を表示する。 24 ファイル *********** このチャプターでは検索、作成、閲覧、保存、その他ファイルとディレクトリー にたいして機能するEmacs Lispの関数と変数について説明します。その他のいく つかのファイルに関する関数については*note Buffers::、バックアップと auto-save(自動保存)に関する関数については*note Backups and Auto-Saving::で説明されています。 ファイル関数の多くはファイル名であるような引数を1つ以上受け取ります。 このファイル名は文字列です。これらの関数のほとんどは関数 ‘expand-file-name’を使用してファイル名引数を展開するので、‘~’は相対ファ イル名(‘../’を含む)として正しく処理されます。*note File Name Expansion::を参照してください。 加えて特定の“magic”ファイル名は特別に扱われます。たとえばリモートファ イル名が指定された際、Emacsは適切なプロトコルを通じてネットワーク越しに ファイルにアクセスします。*note Remote Files: (emacs)Remote Files.を参照 してください。この処理は非常に低レベルで行われるので、特に注記されたもの を除いて、このチャプターで説明するすべての関数がファイル名引数として magicファイル名を受け入れると想定しても良いでしょう。詳細は*Note Magic File Names::を参照してください。 ファイルI/O関数がLispエラーをシグナルする際、通常はコンディション ‘file-error’を使用します(*note Handling Errors::を参照)。ほとんどの場合 にはオペレーティングシステムからロケール‘system-messages-locale’に応じた エラーメッセージが取得されて、コーディングシステム ‘locale-coding-system’を使用してデコードされます(*note Locales::を参照 )。 24.1 ファイルのvisit ==================== ファイルのvisitとはファイルをバッファーに読み込むことを意味します。一度 これを行うと、わたしたちはバッファーがファイルを“visit(訪問)”していると 言い、ファイルのことをバッファーのvisitされたファイルと呼んでいます。 ファイルとバッファーは2つの異なる事柄です。ファイルとは、(削除しない 限り)コンピューター内に永続的に記録された情報です。一方バッファーとは編 集セッションの終了(またはバッファーのkill)とともに消滅する、Emacs内部の 情報です。あるバッファーがファイルをvistしているとき、バッファーにはファ イルからコピーされた情報が含まれます。編集コマンドにより変更されるのはバ ッファー内のコピーです。バッファーへの変更によってファイルは変更されませ ん。その変更を永続化するためにはバッファーを“保存(save)”しなければなりま せん。これは変更されたバッファーのコンテンツをファイルにコピーして書き戻 すことを意味します。 ファイルとバッファーは異なるにも関わらず、人はバッファーという意味で ファイルを呼んだり、その逆を行うことが多々あります。実際のところ、“わた しはまもなく同じ名前のファイルに保存するためのバッファーを編集している ”ではなく、“わたしはファイルを編集している”と言います。人間がこの違いを 明確にする必要は通常はありません。しかしコンピュータープログラムで対処す る際には、この違いを心に留めておくのが良いでしょう。 24.1.1 ファイルをvisitする関数 ------------------------------ このセクションではファイルのvisitに通常使用される関数を説明します。歴史 的な理由によりこれらの関数は‘visit-’ではなく、‘find-’で始まる名前をもち ます。バッファーをvisitしているファイルの名前へのアクセスや、visitされた ファイル名から既存のバッファーを見つける関数および変数については*note Buffer File Name::を参照してください。 ファイル内容を見たいものの変更したくない場合にはテンポラリーバッファ ー(temporary buffer: 一時的なバッファー)で‘insert-file-contents’を使用例 するのが、Lispプログラム内ではもっとも高速な方法です。時間を要するファイ ルのvisitは必要ありません。*note Reading from Files::を参照してください 。 -- Command: find-file filename &optional wildcards このコマンドはファイルFILENAMEをvisitしているバッファーを選択する。 visitしている既存のバッファーがあればそのバッファー、なければバッフ ァーを新たに作成してそのバッファーにファイルを読み込む。これはその バッファーをリターンする。 技術的な詳細を除けば‘find-file’関数のbodyは基本的には以下と等価: (switch-to-buffer (find-file-noselect filename nil nil wildcards)) (*note Switching Buffers::の‘switch-to-buffer’を参照されたい。) WILDCARDSが非‘nil’ (interactiveに呼び出された場合は常に真)の場合、 ‘find-file’はFILENAME内のワイルドカード文字を展開してマッチするすべ てのファイルをvisitする。 ‘find-file’がinteractiveに呼び出された際にはミニバッファー内で FILENAMEの入力を求める。 -- Command: find-file-literally filename このコマンドは‘find-file’が行うようにFILENAMEをvisitするが、フォー マット変換(*note Format Conversion::を参照)、文字コード変換(*note Coding Systems::を参照)、EOL変換(*note End of line conversion: Coding System Basics.を参照)を何も行わない。ファイルをvisitしている バッファーはunibyteになり、ファイル名とは無関係にバッファーのメジャ ーモードはFundamentalモードになる。ファイル内で指定されたファイルロ ーカル変数(*note File Local Variables::を参照)は無視され、自動的な 解凍と‘require-final-newline’によるファイル終端への改行追加(*note require-final-newline: Saving Buffers.を参照)も無効になる。 Emacsがすでにリテラリー(literally: 文字通り、そのまま)でない方法で 同じファイルをvisitしているバッファーをもつ場合には、Emacsはその同 じファイルをリテラリーにvisitせず、単に既存のバッファーに切り替える ことに注意。あるファイルのコンテンツにたいして確実にリテラリーにア クセスしたければテンポラリーバッファーを作成して、 ‘insert-file-contents-literally’を使用してファイルのコンテンツを読 み込むこと(*note Reading from Files::を参照)。 -- Function: find-file-noselect filename &optional nowarn rawfile wildcards これはファイルをvisitするすべての関数の要となる関数である。これはフ ァイルFILENAMEをvisitしているバッファーをリターンする。望むならその バッファーをカレントにしたり、あるウィンドウ内に表示することができ るだろうがこの関数はそれを行わない。 関数は既存のバッファーがあればそれをリターンし、なければ新たにバッ ファーを作成してそれにファイルを読み込む。‘find-file-noselect’が既 存のバッファーを使用する際は、まずファイルがそのバッファーに最後に visit、または保存したときから変更されていないことを検証する。ファイ ルが変更されていれば、この関数は変更されたファイルを再読み込みする かどうかをユーザーに尋ねる。ユーザーが‘yes’と応えたら、以前に行われ たそのバッファー内での編集は失われる。 ファイルの読み込みはEOL変換、フォーマット変換(*note Format Conversion::を参照)を含むファイルコンテンツのデコードを要する(*note Coding Systems::を参照)。WILDCARDSが非‘nil’なら、 ‘find-file-noselect’はFILENAME内のワイルドカード文字を展開してマッ チするすべてのファイルをvisitする。 この関数はオプション引数NOWARNが‘nil’なら、さまざまな特殊ケースにお いて警告メッセージ(warning message)、および注意メッセージ(advisory message)を表示する。たとえば関数がバッファーの作成を必要とし、かつ FILENAMEという名前のファイルが存在しなければ、エコーエリア内にメッ セージ‘(New file)’を表示してそのバッファーを空のままに留める。 ‘find-file-noselect’関数は、ファイルを読み込んだ後に通常は ‘after-find-file’を呼び出す(*note Subroutines of Visiting::を参照 )。この関数はバッファーのメジャーモードのセット、ローカル変数のパー ス、正に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") ⇒ # -- Command: find-file-other-window filename &optional wildcards このコマンドはファイルFILENAMEをvisitしているバッファーを選択するが 、選択されたウィンドウではない他のウィンドウでこれを行う。これは別 の既存ウィンドウを使用したり、ウィンドウを分割するかもしれない。 *note Switching Buffers::lを参照のこと。 このコマンドがinteractiveに呼び出された際はFILENAMEの入力を求める。 -- Command: find-file-read-only filename &optional wildcards このコマンドは‘find-file’のようにファイルFILENAMEをvisitしているバ ッファーを選択するが、そのバッファーを読み取り専用(read-only)とマー クする。関連する関数と変数については*note Read Only Buffers::を参照 のこと。 このコマンドがinteractiveに呼び出された際はFILENAMEの入力を求める。 -- User Option: find-file-wildcards この変数が非‘nil’なら、各種‘find-file’コマンドはワイルドカード文字 をチェックして、それらにマッチするすべてのファイルをvisitする (interactiveに呼び出されたときやWILDCARDS引数が非‘nil’のとき)。この オプションが‘nil’なら、‘find-file’コマンドはそれらのWILDCARDS引数を 無視してワイルドカード文字を特別に扱うことは決してない。 -- User Option: find-file-hook この変数の値はファイルがvisitされた後に呼び出される関数のリスト。フ ァイルのローカル変数指定は、(もしあれば)このフックが実行される前に 処理されるだろう。フック関数実行時はそのファイルをvisitしているバッ ファーがカレントになる。 この変数はノーマルフックである。*note Hooks::を参照のこと。 -- Variable: find-file-not-found-functions この変数の値は‘find-file’や‘find-file-noselect’が存在しないファイル 名を受け取った際に呼び出される関数のリスト。存在しないファイルを検 知すると‘find-file-noselect’は直ちにこれらの関数を呼び出す。これら のいずれかが非‘nil’をリターンするまで、リスト順に関数を呼び出す。 ‘buffer-file-name’はすでにセットアップ済みである。 関数の値が使用されること、および多くの場合いくつかの関数だけが呼び 出されるので、これはノーマルフックではない。 -- Variable: find-file-literally このバッファーローカル変数が非‘nil’値にセットされると、 ‘save-buffer’はあたかもそのバッファーがリテラリー、つまり何の変換も 行わずにファイルをvisitしていたかのように振る舞う。コマンド ‘find-file-literally’はこの変数のローカル値をセットするが、その他の 等価な関数およびコマンドも、たとえばファイル終端への改行の自動追加 を避けるためにこれを同様に行うことができる。この変数は恒久的にロー カルなのでメジャーモードの変更による影響を受けない。 24.1.2 visitのためのサブルーチン -------------------------------- ‘find-file-noselect’関数は、2つの重要なサブルーチン ‘create-file-buffer’と‘after-find-file’を使用します。これらはユーザーの Lispコードでも役に立つことがあります。このセクションではそれらの使い方に ついて説明します。 -- Function: create-file-buffer filename この関数はFILENAMEのvisitにたいして適切な名前のバッファーを作成して それをリターンする。これはFILENAME (ディレクトリーを含まず)の名前が フリーならバッファー名にそれを使用し、フリーでなければ未使用の名前 を取得するために‘<2>’のような文字列を付加する。*note Creating Buffers::も参照のこと。‘uniquify’ライブラリーはこの関数の結果に影響 を与えることに注意。*note (emacs)Uniquify::を参照のこと。 *注意されたい:* ‘create-file-buffer’はファイルに新たなバッファーを _関連付けない_。バッファーの選択もせず、さらにデフォルトのメジャー モードも使用しない。 (create-file-buffer "foo") ⇒ # (create-file-buffer "foo") ⇒ #> (create-file-buffer "foo") ⇒ #> この関数は‘find-file-noselect’により使用される。この関数自身は ‘generate-new-buffer’を使用する(*note Creating Buffers::を参照)。 -- Function: after-find-file &optional error warn noauto after-find-file-from-revert-buffer nomodes この関数はバッファーのメジャーモードをセットして、ローカル変数をパ ースする(*note Auto Major Mode::を参照)。これは ‘find-file-noselect’、およびデフォルトのリバート関数(*note Reverting::を参照)により呼び出される。 ファイルが存在しないという理由によりファイルの読み込みがエラーを受 け取るがディレクトリーは存在するなら、呼び出し側は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’内のすべての関数を最後に呼 び出す。 24.2 バッファーの保存 ===================== Emacs内でファイルを編集するとき、実際にはそのファイルをvisitしているバッ ファーにたいして編集を行っています。つまりファイルのコンテンツをバッファ ーにコピーして、編集しているのはそのコピーなのです。そのバッファーにを変 更してもバッファーを“保存(save)”するまでファイルは変更されません。保存と はバッファーのコンテンツをファイルにコピーすることを意味します。 -- Command: save-buffer &optional backup-option この関数はバッファーが最後にvisitされたときや保存されたときから変更 されていれば、カレントバッファーのコンテンツをバッファーによって visitされているファイルに保存、変更されていなければ何も行わない。 ‘save-buffer’はバックアップファイルの作成に責任を負う。 BACKUP-OPTIONは通常は‘nil’であり、‘save-buffer’はファイルのvisit以 降、それが最初の保存の場合のみバックアップファイルを作成する。 BACKUP-OPTIONにたいする他の値は、別の条件によるバックアップファイル 作成を要求する: • 引数4は1つの‘C-u’、引数64は3つの‘C-u’を意味するので、 ‘save-buffer’はバッファーの次回保存時にこのバージョンのファイ ルがバックアップされるようマークする。 • 引数16は2つの‘C-u’、引数64は3つの‘C-u’を意味するので、 ‘save-buffer’関数はそれを保存する前に前バージョンのファイルを 無条件にバックアップする。 • 引数0は無条件にバックアップファイルを何も_作成しない_。 -- Command: save-some-buffers &optional save-silently-p pred このコマンドはファイルをvisitしている変更されたバッファーのいくつか を保存する。これは通常は各バッファーごとにユーザーに確認を求める。 しかしSAVE-SILENTLY-Pが非‘nil’なら、ユーザーに質問せずにファイルを visitしているすべてのバッファーを保存する。 オプション引数PREDは、どのバッファーで確認を求めるか(または SAVE-SILENTLY-Pが非‘nil’ならどのバッファーで確認せずに保存するか)を 制御する。これが‘nil’なら、それはファイルをvisitしているバッファー にたいしてのみ確認を求めることを意味する。‘t’なら、それは ‘buffer-offer-save’のバッファーローカル値が‘nil’であるような非ファ イルバッファー以外の特定のバッファーの保存も提案することを意味する (*note Killing Buffers::を参照)。ユーザーが非ファイルバッファーの保 存にたいして‘yes’と応えると、保存に使用するファイル名の指定を求める 。‘save-buffers-kill-emacs’関数はPREDにたいして値‘t’を渡す。 PREDが‘t’と‘nil’のいずれでもなければ、それは引数なしの関数であるこ と。その関数はそのバッファーの保存を提案するか否かを決定するために バッファーごとに呼び出されるだろう。これが特定のバッファーで非 ‘nil’値をリターンした場合は、バッファーの保存を提案することを意味す る。 -- Command: write-file filename &optional confirm この関数はカレントバッファーをファイルFILENAMEに書き込んで、バッフ ァーがそのファイルをvisitしていることにして未変更とマークする。次に FILENAMEにもとづいてバッファー名をリネームする。バッファー名を一意 にするため、必要なら‘<2>’のような文字列を付加する。処理のほとんどは ‘set-visited-file-name’ (*note Buffer File Name::を参照)、および ‘save-buffer’を呼び出すことにより行われる。 CONFIRMが非‘nil’なら、それは既存のファイルを上書きする前に確認を求 めることを意味する。ユーザーがプレフィックス引数を与えなければ interactiveに確認が求められる。 FILENAMEが既存のディレクトリーや既存のディレクトリーへのシンボリッ クリンクなら、‘write-file’はディレクトリーFILENAME内でvisitされてい るファイルの名前を使用する。そのバッファーがファイルをvisitしていな ければ、かわりにバッファーの名前を使用する。 バッファーの保存によって複数のフックが実行される。これはフォーマット 変換も処理する(*note Format Conversion::を参照)。 -- Variable: write-file-functions この変数の値はvisitされているファイルをバッファーに書き出す前に呼び 出される関数のリスト。それらのうちのいずれかが非‘nil’をリターンした ら、そのファイルは書き込み済みだと判断されて残りの関数は呼び出され ないし、ファイルを書き込むための通常のコードも実行されない。 ‘write-file-functions’内の関数が非‘nil’をリターンしたら、(それが適 切なら)その関数はファイルをバックアップする責任を負う。これを行うに は以下のコードを実行する: (or buffer-backed-up (backup-buffer)) ‘backup-buffer’によりリターンされるファイルモードの値を保存して、 (もし非‘nil’なら)書き込むファイルのモードビットをセットしたいと思う かもしれない。これは正に‘save-buffer’が通常行うことである。*note Making Backup Files: Making Backups.を参照のこと。 ‘write-file-functions’内のフック関数は、データのエンコード(が望まし ければ)にも責任を負う。これらは適切なコーディングシステムと改行規則 (*note Lisp and Coding Systems::を参照)を選択してエンコード(*note Explicit Encoding::を参照)を処理して、使用されていたコーディングシ ステム(*note Encoding and I/O::を参照)を‘last-coding-system-used’に セットしなければならない。 バッファー内でこのフックをローカルにセットすると、バッファーはその ファイル、またはバッファーのコンテンツを取得したファイルに類するも のに関連付けられる。このようにして変数は恒久的にローカルとマークさ れるので、メジャーモードの変更がバッファーローカルな値を変更するこ とはない。その一方で‘set-visited-file-name’を呼び出すことによって変 数はリセットされるだろう。これを望まなければ、かわりに ‘write-contents-functions’を使用したいと思うかもしれない。 たとえこれがノーマルフックでなくても、このリストを操作するために ‘add-hook’と‘remove-hook’を使用することはできる。*note Hooks::を参 照のこと。 -- Variable: write-contents-functions これは正に‘write-file-functions’と同様に機能するが、こちらはvisitし ている特定のファイルやファイルの場所ではなくバッファーのコンテンツ に関連するフックを意図している。そのようなフックはこの変数にたいす るバッファーローカルなバインディングとして、通常はメジャーモードに より作成される。この変数がセットされた際には、常に自動的にバッファ ーローカルになる。新たなメジャーモードへの切り替えは常にこの変数を リセットするが、‘set-visited-file-name’の呼び出しではリセットされな い。 このフック内の関数のいずれかが非‘nil’をリターンすると、そのファイル はすでに書き込み済みとみなされて、残りの関数は呼び出されず ‘write-file-functions’内の関数も呼び出されない。 -- User Option: before-save-hook このノーマルフックはvisitしているファイルにバッファーが保存される前 に実行される。保存が通常の方法で行われるか、あるいは上述のフックの いずれかで行われたかは問題ではない。たとえば‘copyright.el’プログラ ムは、ファイルの保存においてそれの著作権表示が今年であることを確認 するためにこのフックを使用する。 -- User Option: after-save-hook このノーマルフックはvisitしているファイルにバッファーを保存した後に 実行される。このフックの使用例の1つはFast Lockモードにある。このモ ードはキャッシュファイルにハイライト情報を保存するためにこのフック を使用している。 -- User Option: file-precious-flag この変数が非‘nil’なら、‘save-buffer’は保存ファイルがもつ名前のかわ りに一時的な名前で新たなファイルに書き込み、エラーがないことが明確 になった後にファイルを意図する名前にリネームすることによって保存中 のI/Oエラーから防御する。この手順は無効なファイルが原因となるディス ク容量逼迫のような問題を防ぐ。 副作用としてバックアップ作成にコピーが必要になる。*note Rename or Copy::を参照のこと。しかし同時にこの高価なファイル保存によって保存 したファイルと他のファイル名との間のすべてのハードリンクは切断され る。 いくつかのモードは特定のバッファーにおいてこの変数に非‘nil’のバッフ ァーローカル値を与える。 -- User Option: require-final-newline この変数はファイルが改行で_終わらない_ように書き込まれるかどうかを 決定する。変数の値が‘t’なら、‘save-buffer’はバッファーの終端に改行 がなければ暗黙理に改行を追加する。値が‘visit’なら、Emacsはファイル をvisitした直後に不足している改行を追加する。値が‘visit-save’なら、 Emacsはvisitと保存の両方のタイミングで不足している改行を追加する。 その他の非‘nil’値にたいしては、そのようなケースが生じるたびに改行を 追加するかどうか‘save-buffer’がユーザーに尋ねる。 変数の値が‘nil’なら‘save-buffer’は改行を追加しない。デフォルト値は ‘nil’だが、特定のバッファーでこれを‘t’にセットするメジャーモードも 少数存在する。 *note Buffer File Name::の関数‘set-visited-file-name’も参照されたい。 24.3 ファイルの読み込み ======================= ファイルのコンテンツをバッファーにコピーするためには関数 ‘insert-file-contents’を使用します(マークをセットするのでLispプログラム 内でコマンド‘insert-file’は使用してはならない)。 -- Function: insert-file-contents filename &optional visit beg end replace この関数はファイルFILENAMEのコンテンツをカレントバッファーのポイン トの後に挿入する。これは絶対ファイル名と挿入だれたデータの長さから なるリストをリターンする。FILENAMEが読み取り可能なファイルの名前で なければエラーがシグナルされる。 この関数は定義されたファイルフォーマットに照らしてファイルのコンテ ンツをチェックして、適切ならそのコンテンツの変換、およびリスト ‘after-insert-file-functions’内の関数の呼び出しも行う。*note Format Conversion::を参照のこと。通常はリスト ‘after-insert-file-functions’内のいずれかの関数がEOL変換を含むファ イルコンテンツのデコードに使用されるコーディングシステム(*note Coding Systems::を参照)を判断する。しかしファイルにnullバイトが含ま れる場合には、デフォルトではコード変換なしでvisitされる。*note inhibit-null-byte-detection: Lisp and Coding Systems.を参照のこと。 VISITが非‘nil’なら、この関数は追加でそのバッファーを未変更とマーク してそのバッファーのさまざまなフィールドをセットアップして、バッフ ァーがファイルFILENAMEをvisitしているようにする。これらのフィールド にはバッファーがvisitしたファイルの名前、最終保存したファイルの modtimeが含まれる。これらの機能は‘find-file-noselect’により使用され るものであり、恐らくあなた自身が使用するべきではない。 BEGとENDが非‘nil’なら、それらはファイル挿入範囲を指定するバイトオフ セット数値であること。この場合、VISITは‘nil’でなければならない。た とえば、 (insert-file-contents filename nil 0 500) これはファイルの先頭500文字(バイト)を挿入する。 引数REPLACEが非‘nil’なら、それはバッファーのコンテンツ(実際にはアク セス可能な範囲)をファイルのコンテンツで置き換えることを意味する。こ れは単にバッファーのコンテンツを削除してファイル全体を挿入するより 優れている。なぜなら、(1)マーカー位置を維持して、(2)undoリストに配 置するデータも少ないからである。 REPLACEとVISITが‘nil’なら、‘insert-file-contents’で(FIFOやI/Oデバイ スのような)スペシャルファイルの読み取りが可能。 -- Function: insert-file-contents-literally filename &optional visit beg end replace この関数は‘insert-file-contents’のように機能するが、 ‘find-file-hook’を実行せず、フォーマットのデコード、文字コード変換 、自動解凍、...などを行わない点が異なる。 他のプログラムがファイルを読めるように他プロセスにファイル名を渡した ければ関数‘file-local-copy’を使用します。*note Magic File Names::を参照 してください。 24.4 ファイルの書き込み ======================= 関数‘append-to-file’と‘write-region’を使用することによってディスク上のフ ァイルにバッファーのコンテンツやバッファーの一部を直接書き込むことができ ます。visitされているファイルに書き込むためにこれらの関数を使用しないで ください。これによってvisitにたいするメカニズムが混乱するかもしれません 。 -- Command: append-to-file start end filename この関数はカレントバッファー内でSTARTとENDによるリージョンのコンテ ンツをファイルFILENAMEの終端に追加する。そのファイルが存在しなけれ ば作成する。この関数は‘nil’をリターンする。 FILENAMEに書込不可能なファイルやファイルを作成不可なディレクトリー 内の存在しないファイルを指定するとエラーがシグナルされる。 Lispから呼び出した場合、この関数は以下と完全に等価: (write-region start end filename t) -- Command: write-region start end filename &optional append visit lockname mustbenew この関数はカレントバッファー内のSTARTとENDで区切られたリージョンを FILENAMEで指定されたファイルに書き込む。 STARTが‘nil’なら、このコマンドはバッファーのコンテンツ全体(アクセス 可能な_範囲だけではない_)をファイルに書き込んでENDは無視する。 STARTが文字列なら、‘write-region’はバッファーのテキストではなくその 文字列を追加する。その場合にはENDは無視される。 APPENDが非‘nil’なら、指定されたテキストが(もしあれば)既存のファイル コンテンツに追加される。APPENDが数字なら‘write-region’はファイル開 始位置からそのバイトオフセットをseekしてデータをそこに書き込む。 MUSTBENEWが非‘nil’の場合、もしFILENAMEが既存ファイルの名前なら ‘write-region’は確認を求める。MUSTBENEWがシンボル‘excl’の場合、ファ イルがすでに存在すれば‘write-region’は確認を求めるかわりにエラー ‘file-already-exists’をシグナルする。 MUSTBENEWが‘excl’のときは、存在するファイルのテストに特別なシステム 機能を使用する。少なくともローカルディスク上のファイルにたいしては 、Emacsがファイルを作成する前にEmacsに通知せずに他のプログラムが同 じ名前のファイルを作成することはありえない。 VISITが‘t’なら、Emacsはバッファーとファイルの関連付けを設定してその バッファーがそのファイルをvictiする。またカレントバッファーにたいす る最終ファイル変更日時にFILENAMEをセットして、そのバッファーを未変 更としてマークする。この機能は‘save-buffer’により使用されるが、おそ らくあなた自身が使用するべきではないだろう。 VISITが文字列なら、それはvisitするファイルの名前を指定する。この方 法を使えば、そのバッファーが別のファイルをvisitしていると記録しつつ 1つのファイル(FILENAME)にデータを書き込むことができる。引数VISITは エコーエリアに使用される他にファイルのロックにも使用され、VISITが ‘buffer-file-name’に格納される。この機能は‘file-precious-flag’の実 装に使用される。自分が何をしているか本当にわかっているのでなければ これを使用してはならない。 オプション引数LOCKNAMEが非‘nil’なら、それはロックとアンロックの目的 に使用するFILENAMEとVISITをオーバーライドするファイル名を指定する。 関数‘write-region’は書き込むデータを‘buffer-file-format’によって指 定される適切なファイルフォーマットに変換しするとともに、リスト ‘write-region-annotate-functions’内の関数の呼び出しも行う。*note Format Conversion::を参照のこと。 ‘write-region’は通常はエコーエリア内にメッセージ‘Wrote FILENAME’を 表示する。VISITが‘t’、‘nil’、文字列のいずれでもない場合、こまたは Emacsがbatchモード(*note Batch Mode::を参照)で処理中ならこのメッセ ージは抑制される。この機能は内部的な目的のためにユーザーが知る必要 がないファイルを使用したり、Emacsがbatchモードで処理中に有用である 。 -- Macro: with-temp-file file body... ‘with-temp-file’マクロは一時バッファー(temporary buffer)をカレント バッファーとしてBODYフォームを評価して、最後にそのバッファーのコン テンツをFILEに書き込む。これは終了時に一時バッファーをkillして、 ‘with-temp-file’フォームの前にカレントだったバッファーをリストアす る。その後にBODY内の最後のフォームの値をリターンする。 ‘throw’やエラーによる異常なexit(abnormal exit)でも、カレントバッフ ァーはリストアされる(*note Nonlocal Exits::を参照)。 *note The Current Buffer: Definition of with-temp-buffer.の ‘with-temp-buffer’も参照のこと。 24.5 ファイルのロック ===================== 2人のユーザーが同時に同じファイルを編集する際、おそらく彼らは互いに干渉 しあうことになるでしょう。Emacsはファイルが変更される際に“ファイルロック (file lock)”を記録することによって、このような状況の発生を防ぎます。そし てEmacsは他のEmacsジョブにロックされているファイルをvisitしているバッフ ァーへの変更の最初の試みを検知して、ユーザーに何を行うか尋ねます。このフ ァイルロックの実態は、編集中のファイルと同じディレクトリーに格納される特 別な名前をもつシンボリックリンクです(シンボリックリンクをサポートしない ファイルシステムでは通常ファイルが使用される)。 ファイルのアクセスにNFSを使用する際には、可能性は小さいものの他のユー ザーと同じファイルを同時にロックするかもしれません。これが発生すると2人 のユーザーが同時にファイルを変更することが可能になりますが、それでも Emacsは2番目に保存するユーザーにたいして警告を発するでしょう。たファイル をvisitしているバッファーでディスク上でファイルの変更を検知することによ り、ある種の同時編集を捕捉できます。*note Modification Time::を参照して ください。 -- Function: file-locked-p filename この関数はファイルFILENAMEがロックされていなければ‘nil’をリターンす る。このEmacsプロセスによりロックされていれば‘t’、他のEmacsジョブに よりロックされている場合はロックしたユーザーの名前をリターンする。 (file-locked-p "foo") ⇒ nil -- Function: lock-buffer &optional filename この関数はカレントバッファーが変更されていればファイルFILENAMEをロ ックする。引数FILENAMEのデフォルトはカレントバッファーがvisitしてい るファイル。カレントバッファーがファイルをvisitしていない、バッファ ーが変更されていない、または‘create-lockfiles’が‘nil’なら何もしない 。 -- Function: unlock-buffer この関数はカレントバッファーが変更されていればバッファーにより visitされているファイルをアンロックする。バッファーが変更されていな ければ、そのファイルをロックしてはならないのでこの関数は何もしない 。カレントバッファーがファイルをvisitしていない、またはファイルがロ ックされていなければこの関数は何もしない。 -- User Option: create-lockfiles この変数が‘nil’ならEmacsはファイルをロックしない。 -- Function: ask-user-about-lock file other-user この関数はユーザーがFILEの変更を試みたが、それが名前OTHER-USERのユ ーザーにロックされていたとき呼び出される。この関数のデフォルト定義 は何を行うかユーザーに尋ねる関数。この関数がリターンする値はEmacsが 次に何を行うかを決定する: • 値‘t’はそのファイルのロックを奪うことを意味する。その場合には OTHER-USERはロックを失い、そのユーザーがファイルを編集すること ができる。 • 値‘nil’はロックを無視して、とにかくユーザーがファイルを編集で きるようにすることを意味する。 • この関数はかわりにエラー‘file-locked’をシグナルする。この場合 には、ユーザーが行おうとしていた変更は行われない。 このエラーにたいするエラーメッセージは以下のようになる: error→ File is locked: FILE OTHER-USER ここで‘file’はファイル名、OTHER-USERはそのファイルのロックを所 有するユーザーの名前。 望むなら他の方法で判定を行う独自バージョンで‘ask-user-about-lock’関 数を置き換えることができる。 24.6 ファイルの情報 =================== このセクションではファイル(またはディレクトリーやシンボリックリンク)に関 してファイルが読み込み可能か、書き込み可能か、あるいはファイルのサイズの ようなさまざまなタイプの情報を取得する関数を説明します。これらの関数はす べて引数にファイルの名前を受け取ります。特に注記した場合を除きこれらの引 数には既存のファイルを指定する必要があり、ファイルが存在しなければエラー をシグナルします。 スペースで終わるファイル名には気をつけてください。いくつかのファイル システム(特にMS-Windows)では、ファイル名の末尾の空白文字は暗黙かつ自動的 に無視されます。 24.6.1 アクセシビリティのテスト ------------------------------- 以下の関数はあるファイルの読み取りや書き込み、実行するためのパーミッショ ンをテストします。明示しない限りこれらの関数はファイル名引数にたいするシ ンボリックリンクをすべてのレベル(ファイル自身のレベルと親ディレクトリー のレベル)において再帰的にフォロー(follow: 辿る)します。 いくつかのオペレーティングシステムではACL(Access Control Lists: アク セス制御リスト)のような機構を通じて、より複雑なアクセスパーミッションセ ットが指定できます。それらのパーミッションにたいする問い合わせやセットの 方法については*note Extended Attributes::を参照してください。 -- Function: file-exists-p filename この関数はファイル名FILENAMEが存在すれば‘t’をリターンする。これはそ のファイルが読み取り可能である必要はなく、ファイルの属性を調べるこ とが可能なこと意味する(UnixとGNU/Linu以外で、そのファイルが存在して 、かつそのファイルを含むディレクトリーの実行パーミッションをもつ場 合には‘t’となり、そのファイル自体のパーミッションは無関係である)。 ファイルが存在しない、またはACLポリシーがファイル属性を調べることを 禁止する場合には、この関数は‘nil’をリターンする。 ディレクトリーはファイルなので、ディレクトリー名が与えられると ‘file-exists-p’は‘t’をリターンする。しかしシンボリックリンクは特別 に扱われる。‘file-exists-p’はターゲットファイルが存在する場合のみシ ンボリックリンクにたいして‘t’をリターンする。 -- Function: file-readable-p filename この関数はFILENAMEという名前のファイルが存在して、それを読み取るこ とが可能なら‘t’、それ以外は‘nil’をリターンする。 -- Function: file-executable-p filename この関数はFILENAMEという名前のファイルが存在して、それを実行するこ とが可能なら‘t’、それ以外は‘nil’をリターンする。UnixとGNU/Linuxシス テムでは、そのファイルがディレクトリーなら実行パーミッションはディ レクトリー内のファイルの存在と属性をチェックでき、ファイルのモード が許容すればオープンできることを意味する。 -- Function: file-writable-p filename この関数はFILENAMEという名前のファイルが書き込み可能か作成可能可能 なら‘t’、それ以外は‘nil’をリターンする。ファイルが存在してそれに書 き込むことができるならファイルは書き込み可能。ファイルが存在せず、 指定されたディレクトリーが存在して、そのディレクトリーに書き込むこ とができるなら書き込み可能。 以下の例では、‘foo’は親ディレクトリーが存在しないので、たとえユーザ ーがそのディレクトリーを作成可能であってもファイルは書き込み可能で はない。 (file-writable-p "~/no-such-dir/foo") ⇒ nil -- Function: file-accessible-directory-p dirname この関数はファイルとしての名前がDIRNAMEであるようなディレクトリー内 にある既存のファイルをオープンするパーミッションをもつ場合は‘t’、そ れ以外(またはそのようなディレクトリーが存在しない場合)は‘nil’をリタ ーンする。DIRNAMEの値はディレクトリー名(‘/foo/’など)、または名前が ディレクトリー(最後のスラッシュがない‘/foo’など)であるようなファイ ル。 たとえば以下では‘/foo/’内の任意のファイルを読み取る試みはエラーにな ると推測できる: (file-accessible-directory-p "/foo") ⇒ nil -- Function: access-file filename string この関数は読み取り用にファイルFILENAMEをオープンして、クローズした 後に‘nil’をリターンする。しかしオープンに失敗すると、STRINGをエラー メッセージのテキストに使用してエラーをシグナルする。 -- Function: file-ownership-preserved-p filename &optional group この関数はファイルFILENAMEを削除後に新たに作成してもファイルの所有 者が変更されずに維持されるようなら‘t’をリターンする。これは存在しな いファイルにたいしても‘t’をリターンする。 オプション引数GROUPが非‘nil’なら、この関数はファイルのグループが変 更されないこともチェックする。 FILENAMEがシンボリックリンクなら、‘file-ownership-preserved-p’はこ こで述べる他の関数と異なりFILENAMEをターゲットで_置き換えない_。し かしこの関数は親ディレクトリーのすべての階層においてシンボリックリ ンクを再帰的にフォローする。 -- Function: file-modes filename この関数はFILENAMEの“モードビット(mode bits)”をリターンする。これは 読み取り、書き込み、実行パーミッションを要約する整数である。 FILENAMEでのシンボリックリンクは、すべての階層において再帰的にフォ ローされる。ファイルが存在しない場合のリターン値は‘nil’。 モードビットの説明は*note (coreutils)File permissions::を参照のこと 。たとえば最下位ビットが1ならそのファイルは実行可能、2ビット目が1な ら書き込み可能、...となる。設定できる最大の値は4095(8進の7777)であ り、これはすべてのユーザーが読み取り、書き込み、実行のパーミッショ ンをもち、他のユーザーとグループにたいしてSUIDビット、および stickyビットがセットされる。 これらのパーミッションのセットに使用される‘set-file-modes’関数につ いては*note Changing Files::を参照のこと。 (file-modes "~/junk/diffs") ⇒ 492 ; 10進整数 (format "%o" 492) ⇒ "754" ; 8進に変換した値 (set-file-modes "~/junk/diffs" #o666) ⇒ nil $ ls -l diffs -rw-rw-rw- 1 lewis lewis 3063 Oct 30 16:00 diffs *MS-DOSにたいする注意:* MS-DOSでは実行可能を表すようなファイルのモ ードビットは存在しない。そのため‘file-modes’はファイル名が‘.com’、 ‘.bat’、‘.exe’などのような標準的な実行可能な拡張子のいずれかで終わ ればファイルを実行可能だと判断する。Unix標準の‘#!’署名で始まる shellスクリプトやPerlスクリプトも実行可能と判断される。Unixとの互換 性のためにディレクトリーも実行可能と報告される。‘file-attributes’ (*note File Attributes::を参照)もこれらの慣習にしたがう。 24.6.2 ファイル種別の区別 ------------------------- このセクションではディレクトリー、シンボリックリンク、および通常ファイル のようなさまざまな種類のファイルを区別する方法を説明します。 -- Function: file-symlink-p filename ファイルFILENAMEがシンボリックリンクなら、‘file-symlink-p’関数は(非 再帰的な)リンクターゲットを文字列としてリターンする(リンクターゲッ ト文字列は、そのターゲットの完全な絶対ファイル名である必要はない。 リンクが指すのが完全なファイル名かどうかを判断するのは簡単な処理で はない。以下参照)。FILENAMEのディレクトリー部分(leading directory)に シンボリックリンクが含まれていれば、この関数はそれらを再帰的にフォ ローする。 ファイルFILENAMEがシンボリックリンクではない、または存在しなければ ‘file-symlink-p’は‘nil’をリターンする。 この関数の使用例をいくつか示す: (file-symlink-p "not-a-symlink") ⇒ nil (file-symlink-p "sym-link") ⇒ "not-a-symlink" (file-symlink-p "sym-link2") ⇒ "sym-link" (file-symlink-p "/bin") ⇒ "/pub/bin" 3つ目の例では関数は‘sym-link’をリターンするものの、たとえそれ自体が シンボリックリンクであっても、リンク先の解決を行わないことに注意。 これが上述した“非再帰的(non-recursive)”の意味するところであり、シン ボリックリンクをフォローする処理はそのリンクターゲット自体がリンク なら再帰的に行われない。 この関数がリターンするのはそのシンボリックリンクに何が記録されてい るかを示す文字列であり、それにディレクトリー部分が含まれているかど うかは構わない。この関数は完全修飾されたファイル名を生成するために リンクターゲットを_展開しない_し、リンクターゲットが絶対ファイル名 でなければ、(もしあっても)FILENAME引数のディレクトリー部分は使用し ない。以下に例を示す: (file-symlink-p "/foo/bar/baz") ⇒ "some-file" ここでは、たとえ与えられた‘/foo/bar/baz’が完全修飾されたファイル名 であるにも関わらずその結果は異なり、実際には何のディレクトリー部分 ももたない。‘some-file’自体がシンボリックリンクかもしれないので、単 にその前に先行ディレクトリーを追加することはできず、絶対ファイル名 を生成するために単に‘expand-file-name’ (*note File Name Expansion::を参照)を使用することもできないからである。 この理由により、あるファイルがシンボリックリンクか否かという単一の 事実よりも多くを判定する必要がある場合にこの関数が有用であることは 稀である。実際にリンクターゲットのファイル名が必要なら、*note Truenames::で説明する‘file-chase-links’や‘file-truename’を使用する こと。 以下の2つの関数はFILENAMEにたいしてシンボリックリンクを全階層において 再帰的にフォローする。 -- Function: file-directory-p filename この関数はFILENAMEが既存のディレクトリー名なら‘t’、それ以外は ‘nil’をリターンする。 (file-directory-p "~rms") ⇒ t (file-directory-p "~rms/lewis/files.texi") ⇒ nil (file-directory-p "~rms/lewis/no-such-file") ⇒ nil (file-directory-p "$HOME") ⇒ nil (file-directory-p (substitute-in-file-name "$HOME")) ⇒ t -- Function: file-regular-p filename この関数はファイルFILENAMEが存在して、かつそれが通常ファイル(ディレ クトリー、名前付きパイプ、端末、その他I/Oデバイス以外)なら‘t’をリタ ーンする。 24.6.3 本当の名前 ----------------- ファイルの“実名(truename)”とは、全階層においてシンボリックリンクを残らず フォローした後に名前コンポーネントに出現する‘.’と‘..’を除いて簡略化した 名前のことです。これはそのファイルにたいする正規名(canonical name)の一種 です。ファイルが常に一意な実名をもつ訳ではありません。あるファイルにたい する異なる実名の個数は、そのファイルにたいするハードリンクの個数と同じで す。しかし実名はシンボリックリンクによる名前の変動を解消するのに有用です 。 -- Function: file-truename filename この関数はファイルFILENAMEの実名をリターンする。引数が絶対ファイル 名でなければ、この関数は最初に‘default-directory’にたいしてこれを展 開する。 この関数は環境変数を展開しない。これを行うのは ‘substitute-in-file-name’のみ。*note Definition of substitute-in-file-name::を参照のこと。 名前コンポーネントに出現する‘..’に先行するシンボリックリンクをフォ ローする必要があるなら、直接間接を問わず‘expand-file-name’を呼び出 す前に‘file-truename’を呼び出すこと。そうしないと‘..’の直前にある名 前コンポーネントは、‘file-truename’が呼び出される前に簡略化によって 取り除かれてしまう。‘expand-file-name’呼び出しの必要を無くすため、 ‘file-truename’は‘expand-file-name’が行うのと同じ方法で‘~’を扱う。 *note Functions that Expand Filenames: File Name Expansion.を参照の こと。 -- Function: file-chase-links filename &optional limit この関数は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" -- Function: file-equal-p file1 file2 この関数はファイルFILE1とFILE2の名前が同じファイルなら‘t’をリターン する。これはリモートファイル名も適切な方法で処理することを除いて実 名の比較と似ている。FILE1かFILE2が存在しなければリターン値は不定。 -- Function: file-in-directory-p file dir この関数は、FILEがディレクトリーDIR内のファイルかサブディレクトリー なら‘t’をリターンする。またFILEとDIRが同じディレクトリーの場合も ‘t’をリターンする。この関数は2つのディレクトリーの実名を比較する。 DIRが既存のディレクトリーの名前でなければリターン値は‘nil’。 24.6.4 ファイルの属性 --------------------- このセクションではファイルの詳細な情報を取得する関数について説明します。 それらの情報にはファイルの所有者やグループの番号、ファイル名の個数、 inode番号、サイズやアクセス日時、変更日時が含まれます。 -- Function: file-newer-than-file-p filename1 filename2 この関数はファイルFILENAME1がファイルFILENAME2より新しければ‘t’をリ ターンする。FILENAME1が存在しなければ‘nil’、FILENAME1は存在するが FILENAME2が存在しなければ‘t’をリターンする。 以下の例では、‘aug-19’の書き込みが19日、‘aug-20’の書き込みが20日、 ファイル‘no-file’は存在しないものとする。 (file-newer-than-file-p "aug-19" "aug-20") ⇒ nil (file-newer-than-file-p "aug-20" "aug-19") ⇒ t (file-newer-than-file-p "aug-19" "no-file") ⇒ t (file-newer-than-file-p "no-file" "aug-19") ⇒ nil 以下の2つの関数のFILENAME引数がシンボリックリンクなら、これらの関数は それをリンクターゲットで_置き換えません_。しかしどちらの関数も、親ディレ クトリーのすべての階層においてシンボリックリンクを再帰的にフォローします 。 -- Function: file-attributes filename &optional id-format この関数はファイルFILENAMEの属性(attributes)のリストをリターンする 。オープンできないファイルが指定されると‘nil’をリターンする。オプシ ョン引数ID-FORMATは属性UIDとGID(以下参照)にたいして望ましいフォーマ ットを指定する。有効な値は‘'string’と‘'integer’。デフォルトは ‘'integer’だが、わたしたちはこれの変更を計画しているので、リターン されるUIDやGIDを使用する場合には、ID-FORMATにたいして非‘nil’値を指 定すること。 リストの要素は順に: 0. ディレクトリーにたいしては‘t’、シンボリックリンクにたいしては 文字列(リンクされる名前)、テキストファイルにたいしては‘nil’。 1. そのファイルがもつ名前の個数。ハードリンクとして知られる代替え 名は、関数‘add-name-to-file’を使用して作成できる(*note Changing Files::を参照)。 2. ファイルのUIDであり通常は文字列。しかし名前をもつユーザーに対 応しなければ値は整数。 3. 同様にファイルのGID。 4. 最終アクセス時刻を表す4つの整数‘(SEC-HIGH SEC-LOW MICROSEC PICOSEC)’からなるリスト(これは‘current-time’の値と似ている。 *note Time of Day::を参照)。いくつかのFATベースのファイルシス テムでは最終アクセスの日付だけが記録されるので、この時刻には常 に最終アクセス日の真夜中が保持されることに注意。 5. 最終変更時刻を表す4つの整数からなるリスト(上記参照)。これはフ ァイルのコンテンツが変更された最終時刻。 6. ステータスの最終変更時刻を表す4つの整数からなるリスト(上記参照 )。これはファイルのアクセスモードビット、所有者とグループ、お よびファイルにたいしてファイルのコンテンツ以外にファイルシステ ムが記録するその他の情報にたいする最終変更時刻。 7. ファイルのサイズ(バイト)。Lisp整数の範囲を超える大きさのサイズ では浮動小数点数。 8. ‘ls -l’で表示されるような10個の文字、またはダッシュからなる文 字列で表されるファイルのモード。 9. 後方互換のために提供される不定値。 10. ファイルのinode番号。可能な場合は整数。Emacs Lispの整数として 表せる範囲より大きいinode番号は整数で表現可能な値を得るために 2^{16}で除されて‘(HIGH . LOW)’という形式の値になる。ここで LOWは下位16ビット。それにたいしてすらinode番号が大きければ、値 は‘(HIGH MIDDLE . LOW)’という形式になる。ここで‘high’は上位ビ ット、MIDDLEは中位24ビット、LOWは下位16ビットを保持する。 11. そのファイルがあるデバイスのファイルシステム番号。その大きさ により値は整数、またはinode番号と同じ様式のコンスセル。この要 素とファイルのinode番号を併せれば、システム上の2つを区別するに 足る情報が得られる(2つのファイルがこれら両方の番号で同じ値をも つことはできない)。 たとえば以下は‘files.texi’のファイル属性: (file-attributes "files.texi" 'string) ⇒ (nil 1 "lh" "users" (20614 64019 50040 152000) (20000 23 0 0) (20614 64555 902289 872000) 122295 "-rw-rw-rw-" t (5888 2 . 43978) (15479 . 46724)) この結果を解釈すると: ‘nil’ ディレクトリーでもシンボリックリンクでもない。 ‘1’ (カレントデフォルトディレクトリー内で名前‘files.texi’は)単一の 名前をもつ。 ‘"lh"’ 名前"lh"のユーザーにより所有される。 ‘"users"’ 名前"users"のグループ。 ‘(20614 64019 50040 152000)’ 最終アクセスがOctober 23, 2012, at 20:12:03.050040152 UTC。 ‘(20000 23 0 0)’ 最終更新がJuly 15, 2001, at 08:53:43 UTC。 ‘(20614 64555 902289 872000)’ 最終ステータス変更がOctober 23, 2012, at 20:20:59.902289872 UTC。 ‘122295’ バイト長は122295バイト(しかしマルチバイトシーケンスが含まれて いたり、EOLフォーマットがCRLFなら122295文字は含まれないかもし れない)。 ‘"-rw-rw-rw-"’ 所有者、グループ、その他にたいして読み取り、書き込みアクセスの モードをもつ。 ‘t’ 単なるプレースホルダーであり何の情報ももたない。 ‘(5888 2 . 43978)’ inode番号は6473924464520138。 ‘(15479 . 46724)’ ファイルシステムのデバイス番号は1014478468。 -- Function: file-nlinks filename この関数はファイル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 24.6.5 拡張されたファイル属性 ----------------------------- いくつかのオペレーティングシステムでは、それぞれのファイルを任意の“拡張 ファイル属性(extended file attributes)”に関連付けることができます。現在 のところEmacsは拡張ファイル属性のうち2つの特定セット(ACL: Access Control List、およびSELinuxコンテキスト)にたいする問い合わせと設定をサポートしま す。これらの拡張ファイル属性は、前のセクションで議論したUnixスタイルの基 本的なパーミッションより洗練されたファイルアクセス制御を強制するために、 いくつかのシステムで利用されます。 ACLとSELinuxについての詳細な解説はこのマニュアルの範囲を超えています 。わたしたちの目的のためには、それぞれのファイルは“ACL” (ACLベースのファ イル制御システムの元でACLのプロパティを指定)および/または“SELinuxコンテ キスト” (SELinuxシステムの元でSELinuxのプロパティを指定)に割り当てること ができるという理解で問題ないでしょう。 -- Function: file-acl filename この関数はファイルFILENAMEにたいするACLをリターンする。ACLにたいす る正確なLisp表現は不確定(かつ将来のEmacsバージョンで変更され得る)だ が、これは‘set-file-acl’が引数ACLにとる値と同じである(*note Changing Files::を参照)。 根底にあるACL実装はプラットフォームに固有である。EmacsはGNU/Linuxと BSDではPOSIX ACLインターフェイスを使用して、MS-Windowsではネイティ ブのファイルセキュリティAPIをPOSIX ACLインターフェイスでエミュレー トする。 ACLサポートなしでEmacsがコンパイルされた場合には、ファイルが存在し ないかアクセス不能な場合、またはその他の理由によりEmacsがACLエント リーを判断できなければリターン値は‘nil’。 -- Function: file-selinux-context filename この関数はファイルFILENAMEのSELinuxコンテキストを‘(USER ROLE TYPE RANGE)’という形式のリストでリターンする。リストの要素はそのコンテキ ストのユーザー、ロール、タイプ、レンジを文字列として表す値である。 これらの実際の意味についての詳細はSELinuxのドキュメントを参照のこと 。リターン値は‘set-file-selinux-context’がCONTEXT引数で受け取るのと 同じ形式(*note Changing Files::を参照)。 SELinuxサポートなしでEmacsがコンパイルされた場合、ファイルが存在し ないかアクセス不能な場合、またはシステムがSELinuxをサポートしなけれ ばリターン値は‘(nil nil nil nil)’。 -- Function: file-extended-attributes filename この関数はEmacsが認識するファイルFILENAMEの拡張属性をalistでリター ンする。現在のところこの関数はACLとSELinuxの両方を取得するための便 利な方法としての役目を果たす。他のファイルに同じファイルアクセス属 性を適用するためにリターンされたalistを2つ目の引数として ‘set-file-extended-attributes’を呼び出すことができる(*note Changing Files::を参照)。 要素のうちの1つは‘(acl . ACL)’で、ACLは‘file-acl’がリターンするのと 同じ形式。 他の要素は‘(selinux-context . CONTEXT)’で、CONTEXTは ‘file-selinux-context’がリターンするのと同じ形式。 24.6.6 標準的な場所へのファイルの配置 ------------------------------------- このセクションではディレクトリーのリスト(“パス(path)”)からファイルを検索 したり、標準の実行可能ファイル用ディレクトリーから実行可能ファイルを検索 する方法を説明します。 ユーザー固有の設定ファイル(configuration file)の検索については*note Standard File Names::の関数‘locate-user-emacs-file’を参照してください。 -- Function: locate-file filename path &optional suffixes predicate この関数はPATHで与えられるディレクトリーリスト内でFILENAMEという名 前のファイルを検索して、SUFFIXES内のサフィックスの検索を試みる。そ のようなファイルが見つかったらファイルの絶対ファイル名(*note Relative File Names::を参照)、それ以外は‘nil’をリターンする。 オプション引数SUFFIXESは検索時にFILENAMEに追加するファイル名サフィ ックスのリストを与える。‘locate-file’は検索するディレクトリーごとに それらのサフィックスを試みる。SUFFIXESが‘nil’や‘("")’なら、サフィッ クスなしでFILENAMEだけがそのまま使用される。SUFFIXESの典型的な値は ‘exec-suffixes’ (*note Subprocess Creation::を参照)、 ‘load-suffixes’、‘load-file-rep-suffixes’、および関数 ‘get-load-suffixes’ (*note Load Suffixes::を参照)。 実行可能プログラムを探すときは‘exec-path’ (*note Subprocess Creation::を参照)、Lispファイルを探すときは‘load-path’ (*note Library Search::を参照)がPATHの典型的な値である。FILENAMEが絶対ファ イル名ならPATHの効果はないが、サフィックスにたいするSUFFIXESは依然 として試行される。 オプション引数PREDICATEが非‘nil’なら、それは候補ファイルが適切かど うかテストする述語関数を指定する。述語関数には単一の引数として候補 ファイル名が渡される。PREDICATEが‘nil’か省略なら述語として ‘file-readable-p’を使用する。‘file-executable-p’や ‘file-directory-p’など、その他の有用な述語については*note Kinds of Files::を参照のこと。 互換性のためにPREDICATEには‘executable’、‘readable’、‘writable’、 ‘exists’、またはこれらシンボルの1つ以上のリストも指定できる。 -- Function: executable-find program この関数はPROGRAMという名前の実行可能ファイルを検索して、その実行可 能ファイルの絶対ファイル名と、もしあればファイル名の拡張子も含めて リターンする。ファイルが見つからなければ‘nil’をリターンする。この関 数は‘exec-path’内のすべてのディレクトリーを検索して、 ‘exec-suffixes’内のすべてのファイル名拡張子の検索も試みる(*note Subprocess Creation::を参照)。 24.7 ファイルの名前と属性の変更 =============================== このセクションの関数はファイルのリネーム、コピー、リンク、(権限)モードの セットを行います。これらの関数はすべて処理に失敗すると、失敗した理由を記 述するシステム固有ッセージを報告するために‘file-error’エラーをシグナルし ます。 NEWNAMEという引数をもつ関数では、NEWNAMEという名前のファイルが既に存 在する場合には、その挙動が引数OK-IF-ALREADY-EXISTSの値に依存します。 • OK-IF-ALREADY-EXISTSが‘nil’なら‘file-already-exists’エラーがシグナ ルされる。 • OK-IF-ALREADY-EXISTSが数字なら確認を求める。 • OK-IF-ALREADY-EXISTSが他の値なら確認なしで古いファイルを置き換える 。 以下の4つのコマンドはすべて1つ目の引数にたいして親ディレクトリーの全 階層のシンボリックリンクを再帰的にフォローしますが、その引数自体がシンボ リックリンクなら‘copy-file’だけが(再帰的な)ターゲットを置き換えます。 -- Command: add-name-to-file oldname newname &optional ok-if-already-exists この関数は、OLDNAMEという名前のファイルにNEWNAMEという名前を追加で 与える。これはNEWNAMEという名前がOLDNAMEにたいする新たなハードリン クになることを意味する。 以下の例の最初の部分では2つのファイル‘foo’と‘foo3’をリストする。 $ ls -li fo* 81908 -rw-rw-rw- 1 rms rms 29 Aug 18 20:32 foo 84302 -rw-rw-rw- 1 rms rms 24 Aug 18 20:31 foo3 ここで‘add-name-to-file’を呼び出してハードリンクを作成して再度ファ イルをリストする。このリストには1つのファイルにたいして2つの名前 ‘foo’と‘foo2’が表示される。 (add-name-to-file "foo" "foo2") ⇒ nil $ ls -li fo* 81908 -rw-rw-rw- 2 rms rms 29 Aug 18 20:32 foo 81908 -rw-rw-rw- 2 rms rms 29 Aug 18 20:32 foo2 84302 -rw-rw-rw- 1 rms rms 24 Aug 18 20:31 foo3 最後に以下を評価する: (add-name-to-file "foo" "foo3" t) そしてファイルを再度リストする。今度は1つのファイルにたいして3つの 名前‘foo’、‘foo2’、‘foo3’がある。‘foo3’の古いコンテンツは失われた。 (add-name-to-file "foo1" "foo3") ⇒ nil $ ls -li fo* 81908 -rw-rw-rw- 3 rms rms 29 Aug 18 20:32 foo 81908 -rw-rw-rw- 3 rms rms 29 Aug 18 20:32 foo2 81908 -rw-rw-rw- 3 rms rms 29 Aug 18 20:32 foo3 この関数は1つのファイルにたいして複数の名前をもつことが許されないオ ペレーティングシステムでは無意味である。いくつかのシステムでは、か わりにファイルをコピーすることにより複数の名前を実装している。 *note File Attributes::の‘file-nlinks’も参照のこと。 -- Command: rename-file filename newname &optional ok-if-already-exists このコマンドはFILENAMEをNEWNAMEにリネームする。 FILENAMEがFILENAMEとは別に追加の名前をもつなら、それらは自身の名前 をもち続ける。実際のところ‘add-name-to-file’で名前NEWNAMEを追加して からFILENAMEを削除するのは、瞬間的な遷移状態を別とするとリネームと 同じ効果がある。 -- Command: copy-file oldname newname &optional ok-if-exists time preserve-uid-gid preserve-extended-attributes このコマンドはファイルOLDNAMEをNEWNAMEにコピーする。OLDNAMEが存在し なければエラーをシグナルする。NEWNAMEがディレクトリーなら、その最後 の名前コンポーネントを保持するようにそのディレクトリーの中に OLDNAMEをコピーする。 TIMEが非‘nil’なら、この関数は新たなファイルにたいして古いファイルと 同じ最終変更時刻を与える(これはいくつかの限られたオペレーティングシ ステムでのみ機能する)。時刻のセットでエラーが発生すると、 ‘copy-file’は‘file-date-error’エラーをシグナルする。インタラクティ ブに呼び出された場合には、プレフィックス引数はTIMEにたいして非 ‘nil’値を指定する。 引数PRESERVE-UID-GIDが‘nil’なら、新たなファイルのユーザーとグループ の所有権の決定をオペレーティングシステムに委ねる(通常はEmacsを実行 中のユーザー)。PRESERVE-UID-GIDが非‘nil’なら、そのファイルのユーザ ーとグループの所有権のコピーを試みる。これはいくつかのオペレーティ ングシステムで、かつそれを行うための正しいパーミッションをもつ場合 のみ機能する。 オプション引数PRESERVE-PERMISSIONSが非‘nil’なら、この関数は OLDNAMEのファイルモード(または“パーミッション”)、同様にACL(Access Control List)とSELinuxコンテキストをNEWNAMEにコピーする。*note Information about Files::を参照のこと。 それ以外では、NEWNAMEが既存ファイルならファイルモードは変更されず、 新たに作成された場合はデフォルトのファイルパーミッション(以下の ‘set-default-file-modes’を参照)によりマスクされる。どちらの場合でも ACLやSELinuxコンテキストはコピーされない。 -- Command: make-symbolic-link filename newname &optional ok-if-exists このコマンドはFILENAMEにたいしてNEWNAMEという名前のシンボリックリン クを作成する。これはコマンド‘ln -s FILENAME NEWNAME’と似ている。 この関数はシンボリックリンクをサポートしないシステムでは利用できな い。 -- Command: delete-file filename &optional trash このコマンドはファイルFILENAMEを削除する。ファイルが複数の名前をも つ場合には、他の名前で存在し続ける。FILENAMEがシンボリックリンクな ら、‘delete-file’はシンボリックリンクだけを削除して、(たとえこれが 親ディレクトリーの全階層のシンボリックリンクをフォローするとしても )ターゲットは削除しない。 ファイルが存在しない、または削除できなければ適切な種類の ‘file-error’エラーがシグナルされる(UnixとGNU/Linuxではファイルのデ ィレクトリーが書き込み可能ならファイルは削除可能)。 オプション引数TRASHが非‘nil’、かつ変数‘delete-by-moving-to-trash’が 非‘nil’なら、このコマンドはファイルを削除するかわりにシステムの Trash(ゴミ箱)にファイルを移動する。*note Miscellaneous File Operations: (emacs)Misc File Ops.を参照のこと。インタラクティブに呼 び出された際には、プレフィックス引数がなければTRASHは‘t’、それ以外 は‘nil’。 *note Create/Delete Dirs::の‘delete-directory’も参照のこと。 -- Command: set-file-modes filename mode この関数はFILENAMEの“ファイルモード”(または“パーミッション”)を MODEにセットする。この関数はFILENAMEにたいして全階層でシンボリック リンクをフォローする。 非インタラクティブに呼び出された場合には、MODEは整数でなければなら ない。その整数の下位12ビットだけが使用される。ほとんどのシステムで は意味があるのは下位9ビットのみ。MODEを入力するLisp構文を使用できる 。たとえば、 (set-file-modes #o644) これはそのファイルにたいして所有者による読み取りと書き込み、グルー プメンバーによる読み取り、その他のユーザーによる読み取り可能である ことを指定する。モードビットの仕様の説明は*note (coreutils)File permissions::を参照のこと。 インタラクティブに呼び出されると、MODEは‘read-file-modes’(以下参照 )を使用してミニバッファーから読み取られる。この場合にはユーザーは整 数、またはパーミッションをシンボルで表現する文字列をタイプできる。 ファイルのパーミッションをリターンする関数‘file-modes’については *note File Attributes::を参照のこと。 -- Function: set-default-file-modes mode この関数はEmacsとEmacsのサブプロセスが新たに作成するファイルに、デ フォルトのパーミッションをセットする。Emacsにより作成されたすべての ファイルはこれらのパーミッション、およびそれらのサブセットとなるパ ーミッションをもつ(デフォルトファイルパーミッションが実行を許可して も‘write-region’は実行パーミッションを付与しないだろう)。Unixと GNU/Linuxでは、デフォルトのパーミッションは‘umask’の値のビット単位 の補数で与えられる。 引数MODEは上記の‘set-file-modes’と同様、パーミッションを指定する整 数であること。意味があるのは下位9ビットのみ。 デフォルトのファイルパーミッションは、既存ファイルの変更されたバー ジョンを保存する際は効果がない。ファイルの保存では既存のパーミッシ ョンが保持される。 -- Macro: with-file-modes mode body... このマクロは新たなファイルにたいするデフォルトのパーミッションを一 時的にMODES (値は)‘set-file-modes’にたいする値と同様)にセットしてフ ォームBODYを評価する。終了時には元にデフォルトのファイルノパーミッ ションをリストアして、BODYの最後のフォームの値をリターンする。 これはたとえばプライベートファイルの作成に有用である。 -- Function: default-file-modes この関数はデフォルトのファイルのパーミッションを整数でリターンする 。 -- Function: read-file-modes &optional prompt base-file この関数はミニバッファーからファイルモードのビットのセットを読み取 る。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"’のよう に組み合わせることができる。ファイルモード指定の説明は*note (coreutils)File permissions::を参照のこと。 -- Function: file-modes-symbolic-to-number modes &optional base-modes この関数はMODES内のシンボルによるファイルモード指定を等価な整数に変 換する。シンボル指定が既存ファイルにもとづく場合には、オプション引 数BASE-MODESからそのファイルのモードビットが取得される。その引数が 省略または‘nil’なら、0(すべてのアクセスが許可されない)がデフォルト になる。 -- Function: set-file-times filename &optional time この関数はFILENAMEのアクセス時刻と変更時刻をTIMEにセットする。時刻 が正しくセットされれば‘t’、それ以外は‘nil’がリターン値となる。 TIMEのデフォルトはカレント時刻であり、‘current-time’がリターンする フォーマットでなければならない(*note Time of Day::を参照)。 -- Function: set-file-extended-attributes filename attribute-alist この関数は‘filename’にたいしてEmacsが認識する拡張ファイル属性をセッ トする。2つ目の引数ATTRIBUTE-ALISTは‘file-extended-attributes’がリ ターンするalistと同じ形式であること。属性のセットが成功したら‘t’、 それ以外は‘nil’がリターン値となる。*note Extended Attributes::を参 照のこと。 -- Function: set-file-selinux-context filename context この関数はFILENAMEにたいするSELinuxセキュリティコンテキストに CONTEXTをセットする。CONTEXT引数は各要素が文字列であるような‘(USER ROLE TYPE RANGE)’というリストであること。*note Extended Attributes::を参照のこと。 この関数はFILENAMEのSELinuxコンテキストのセットに成功したら‘t’をリ ターンする。コンテキストがセットされなかった場合(SELinuxが無効、ま たはEmacsがSELinuxサポートなしでコンパイルされた場合等)には‘nil’を リターンする。 -- Function: set-file-acl filename acl この関数はFILENAMEにたいするACLにACLをセットする。ACL引数は関数 ‘file-acl’がリターンするのと同じ形式であること。*note Extended Attributes::を参照のこと。 この関数はFILENAMEのACLのセットに成功したら‘t’、それ以外は‘nil’をリ ターンする。 24.8 ファイルの名前 =================== ファイルは一般的に名前で参照され、これはEmacsでも他と同様です。Emacsでは ファイル名は文字列で表現されます。ファイルを操作する関数はすべてファイル 名引数に文字列を期待します。 ファイル自体の操作に加えて、Emacs Lispプログラムでファイル名を処理す る必要(ファイル名の一部を取得して関連するファイル名構築にその一部を使用 する等)がしばしばあります。このセクションではファイル名を扱う方法を説明 します。 このセクションの関数は実際にファイルにアクセスする訳ではないので、既 存のファイルやディレクトリーを参照しないファイル名を処理できます。 MS-DOSとMS-Windowsでは、これらの関数は(実際にファイルを操作する関数と 同様)、MS-DOSとMS-Windowsのファイル名構文を受け入れます。この構文は Unix構文のようにバックスラッシュでコンポーネントを区切りますが、これらの 関数は常にUnix構文をリターンします。これによりUnix構文でファイル名を指定 するLispプログラムが、変更なしですべてのシステムで正しく機能することが可 能になるのです。(1) ---------- Footnotes ---------- (1) MS-WindowsバージョンのEmacsはCygwin環境用にコンパイルされており、 2つのファイル名構文の変換に‘cygwin-convert-file-name-to-windows’と ‘cygwin-convert-file-name-from-windows’を使用できます。 24.8.1 ファイル名の構成要素 --------------------------- オペレーティングシステムはファイルをディレクトリーにグループ化します。あ るファイルを指定するためには、ディレクトリーとそのディレクトリー内でのフ ァイルの名前を指定しなければなりません。それゆえEmacsはファイル名を“ディ レクトリー名”パートと“非ディレクトリー”(または“ディレクトリー内ファイル 名”)パートという、2つの主要パートから判断します。どちらのパートも空の場 合があり得ます。これら2つのパートを結合することによって元のファイル名が 再構築されます。 ほとんどのシステムでは最後のスラッシュ(MS-DOSとMS-Windowsではバックス ラッシュも許される)までのすべてがディレクトリーパートです。残りが非ディ レクトリーパートです。 ある目的のために、非ディレクトリーパートはさらに正式名称(the name proper)と“バージョン番号”に細分されます。ほとんどのシステムでは、名前に バージョン番号をもつのはバックアップファイルだけです。 -- Function: file-name-directory filename この関数はFILENAMEのディレクトリーパートをディレクトリー名(*note Directory Names::を参照)としてリターンする。FILENAMEがディレクトリ ーパートを含まなければ‘nil’をリターンする。 GNUとUnixシステムでは、この関数がリターンする文字列は常にスラッシュ で終わる。MS-DOSではコロンで終わることもあり得る。 (file-name-directory "lewis/foo") ; Unixの例 ⇒ "lewis/" (file-name-directory "foo") ; Unixの例 ⇒ nil -- Function: file-name-nondirectory filename この関数はFILENAMEの非ディレクトリーパートをリターンする。 (file-name-nondirectory "lewis/foo") ⇒ "foo" (file-name-nondirectory "foo") ⇒ "foo" (file-name-nondirectory "lewis/") ⇒ "" -- Function: file-name-sans-versions filename &optional keep-backup-version この関数は、任意のファイルバージョン番号、バックアップバージョン番 号、末尾のチルダを取り除いた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" -- Function: file-name-extension filename &optional period この関数はFILENAMEから、もしあればすべてのバージョン番号とバックア ップ番号を取り除いた後の、終端の拡張子(extension)をリターンする。フ ァイル名の拡張子とは最後の名前コンポーネント(からすべてのバージョン 番号とバックアップ番号を取り去った後)の最後の‘.’に後続するパートの こと。 この関数は‘foo’のような拡張子のないファイル名にたいしては‘nil’、 ‘foo.’のようなnull拡張子にたいしては‘""’をリターンする。ファイル名 の最終コンポーネントが‘.’で始まる場合には、その‘.’は拡張子の開始と はみなされない。したがって‘.emacs’の拡張子は‘.emacs’ではなく‘nil’。 PERIODが非‘nil’なら、拡張子を区切るピリオドもリターン値に含まれる。 その場合には、もしFILENAMEが拡張子をもたなければリターン値は‘""’。 -- Function: file-name-sans-extension filename この関数は、もしあればFILENAMEから拡張子を除いてリターンする。もし バージョン番号やバックアップ番号があるなら、ファイルが拡張子をもつ 場合のみそれを削除する。たとえば、 (file-name-sans-extension "foo.lose.c") ⇒ "foo.lose" (file-name-sans-extension "big.hack/foo") ⇒ "big.hack/foo" (file-name-sans-extension "/my/home/.emacs") ⇒ "/my/home/.emacs" (file-name-sans-extension "/my/home/.emacs.el") ⇒ "/my/home/.emacs" (file-name-sans-extension "~/foo.el.~3~") ⇒ "~/foo" (file-name-sans-extension "~/foo.~3~") ⇒ "~/foo.~3~" 最後の2つの例の‘.~3~’は拡張子ではなくバックアップ番号であることに注 意。 -- Function: file-name-base &optional filename これは‘file-name-sans-extension’と‘file-name-nondirectory’を組み合 わせた関数。たとえば、 (file-name-base "/my/home/foo.c") ⇒ "foo" 引数FILENAMEのデフォルトは‘buffer-file-name’。 24.8.2 絶対ファイル名と相対ファイル名 ------------------------------------- ファイルシステム内のすべてのディレクトリーはルートディレクトリーから開始 されるツリーを形成します。このツリーのルートから開始されるすべてのディレ クトリー名によってファイル名を指定することができ、それを“絶対 (absolute)”ファイル名と呼びます。デフォルトディレクトリーからの相対的な ツリー中の位置でファイルを指定することもでき、それは“相対(relative)”ファ イル名と呼ばれます。UnixとGNU/Linuxでは、絶対ファイル名は‘/’か‘~’で始ま り、相対ファイル名は異なります(*note abbreviate-file-name::を参照)。 MS-DOSとMS-Windowsでは絶対ファイル名はスラッシュ、バックスラッシュ、また はドライブ指定‘X:/’で始まります。ここでXは“ドライブ文字(drive letter)”で す。 -- Function: file-name-absolute-p filename この関数はFILENAMEが絶対ファイル名なら‘t’、それ以外は‘nil’をリター ンする。 (file-name-absolute-p "~rms/foo") ⇒ t (file-name-absolute-p "rms/foo") ⇒ nil (file-name-absolute-p "/user/rms/foo") ⇒ t 相対ファイル名が与えられると‘expand-file-name’を使用して、それを絶対 ファイル名に変換できます(*note File Name Expansion::を参照)。以下の関数 は絶対ファイル名を相対ファイル名に変換します: -- Function: file-relative-name filename &optional directory この関数は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" 24.8.3 ディレクトリーの名前 --------------------------- “ディレクトリー名(directory name)”とは、ディレクトリーの名前のことです。 ディレクトリーは実際にはファイルの一種なので、“ディレクトリーファイル名 (directory file name)”と呼ばれるファイル名をもちます。これはディレクトリ ー名と関連がありますが同一ではありません(これはUnixの通常の用語とは異な る)。同じ実体にたいするこれら2つの異なる名前は、構文的な変換により関連付 けられます。GNUとUnixシステムでは事は単純です。ディレクトリーファイル名 はスラッシュで終わり、ファイルとしてのディレクトリーの名前にはそのスラッ シュがありません。MS-DOSではこの関連付けはより複雑です。 ディレクトリー名とディレクトリーファイル名の違いは些細ですが重要です 。Emacsの変数や関数の引数を記述する際には、引数がディレクトリーだとみな しており、ディレクトリーファイル名は許容されません。 ‘file-name-directory’が文字列をリターンするときは、常にディレクトリー名 をリターンします。 以下の2つの関数は、ディレクトリー名とディレクトリーファイル名の間で変 換を行います。これらの関数は‘$HOME’のような環境変数や‘~’、‘.’、‘..’など の構文にたいして、特別なことは何も行いません。 -- Function: file-name-as-directory filename この関数はオペレーティングシステムがディレクトリーの名前(ディレクト リー名)と解釈する形式でFILENAMEを表す文字列をリターンする。これはほ とんどのシステムでは、(もし終端にそれがなければ)これは文字列にスラ ッシュを追加することを意味する。 (file-name-as-directory "~rms/lewis") ⇒ "~rms/lewis/" -- Function: directory-name-p filename この関数はFILENAMEがディレクトリー区切り文字で終れば非‘nil’をリター ンする。これはUnixとGNUシステムでは順スラッシュ‘/’、MS-Windowsと MS-DOSでは順スラッシュとバックスラッシュ‘\’の両方がディレクトリー区 切り文字として認識される。 -- Function: directory-file-name dirname この関数は、オペレーティングシステムがファイルの名前(ディレクトリー ファイル名)として解釈する形式でDIRNAMEを表す文字列をリターンする。 ほとんどのシステムでは、これは文字列から最後のスラッシュ(またはバッ クスラッシュ)を削除することを意味する。 (directory-file-name "~lewis/") ⇒ "~lewis" ディレクトリー名にたいしては‘concat’を使用して相対ファイルと組み合わ せることができます: (concat DIRNAME RELFILE) これを行う前にファイル名が相対的であることを確認してください。絶対ファイ ル名を使用すると構文的に不正な結果となったり、間違ったファイルを参照する 可能性があります。 ディレクトリーファイル名の作成にこのような組み合わせを使用しなければ 、最初に‘file-name-as-directory’を使用してそれをディレクトリー名に変換し なければなりません: (concat (file-name-as-directory DIRFILE) RELFILE) 以下のように手動でスラッシュの結合を試みてはなりません ;;; 間違い! (concat DIRFILE "/" RELFILE) なぜならこれには可搬性がないからです。常に‘file-name-as-directory’を使用 してください。 上述の問題の回避や(たとえば‘load-path’の要素のように)DIRNAMEの値が nilかもしれない場合には、以下を使用してください: (expand-file-name RELFILE DIRNAME) ディレクトリー名をディレクトリーの省略名に変換するには以下の関数を使 用します: -- Function: abbreviate-file-name filename この関数はFILENAMEの省略された形式をリターンする。 これは ‘directory-abbrev-alist’ (*note File Aliases: (emacs)File Aliases.を 参照)で指定される省略名を適用して、引数で与えられるファイル名ががホ ームディレクトリーかそのサブディレクトリーにあれば、ユーザーのホー ムディレクトリーを‘~’に置換する。ホームディレクトリーがルートディレ クトリーなの場合には、多くのシステムでは結果が短縮されないので‘~’で 置き換えない。 これは名前の一部であるような省略形さえも認識するので、ディレクトリ ー名とファイル名にも使用できる。 24.8.4 ファイル名を展開する関数 ------------------------------- ファイル名の“展開(expanding)”とは相対ファイル名を絶対ファイル名に変換す ることを意味します。これはデフォルトディレクトリーから相対的に行われるた め、展開されるファイル名と同様にデフォルトディレクトリーも指定しなければ なりません。これは‘~/’のような省略形 (*note abbreviate-file-name::を参照 )、 の展開、および‘./’や‘NAME/../’のような冗長さの排除も行います。 -- Function: expand-file-name filename &optional directory この関数はFILENAMEを絶対ファイル名に変換する。DIRECTORYが与えられた なら、それはFILENAMEが相対的な場合に開始点となるデフォルトディレク トリーであること。それ以外ならカレントバッファーの ‘default-directory’の値が使用される。たとえば: (expand-file-name "foo") ⇒ "/xcssun/users/rms/lewis/foo" (expand-file-name "../foo") ⇒ "/xcssun/users/rms/foo" (expand-file-name "foo" "/usr/spool/") ⇒ "/usr/spool/foo" 結合されたファイル名の最初のスラッシュの前が‘~’なら、環境変数‘HOME’ (通常はユーザーのホームディレクトリー)の値に展開される。最初のスラ ッシュの前が‘~USER’で、かつUSERが有効なログイン名なら、USERのホーム ディレクトリーに展開される。 ‘.’や‘..’を含むファイル名は正規化形式に簡略化される: (expand-file-name "bar/../foo") ⇒ "/xcssun/users/rms/lewis/foo" 出力に‘..’部分が残り得る場合もある: (expand-file-name "../home" "/") ⇒ "/../home" これはルートディレクトリー‘/’の上位のスーパールート(superroot)とい う概念をもつファイルシステムのためのものである。その他のファイルシ ステムでは‘/../’は‘/’とまったく同じに解釈される。 ‘expand-file-name’は環境変数を_展開しない_ことに注意。それを行うの は‘substitute-in-file-name’のみ。 (expand-file-name "$HOME/foo") ⇒ "/xcssun/users/rms/lewis/$HOME/foo" ‘expand-file-name’はあらゆる階層においてシンボリックリンクをフォロ ーしないことにも注意。これは‘..’の扱いが‘file-truename’と ‘expand-file-name’で異なることに起因する。‘/tmp/bar’がディレクトリ ー‘/tmp/foo/bar’にたいするシンボリックリンクであると仮定すると: (file-truename "/tmp/bar/../myfile") ⇒ "/tmp/foo/myfile" (expand-file-name "/tmp/bar/../myfile") ⇒ "/tmp/myfile" 直接間接を問わず事前に‘expand-file-name’を呼び出さずに‘..’に先行す るシンボリックリンクをフォローする必要があるかもしれない場合には、 それを呼び出さずに確実に‘file-truename’を呼び出すこと。*note Truenames::を参照されたい。 -- Variable: default-directory このバッファーローカル変数の値はカレントバッファーにたいするデフォ ルトディレクトリー。これは絶対ディレクトリー名であること。これは ‘~’で始まるかもしれない。この変数はすべてのバッファーにおいてバッフ ァーローカル。 2つ目の引数が‘nil’なら、‘expand-file-name’はデフォルトディレクトリ ーを使用する。 値は常にスラッシュで終わる文字列。 default-directory ⇒ "/user/lewis/manual/" -- Function: substitute-in-file-name filename この関数は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/’は破棄された 24.8.5 一意なファイル名の生成 ----------------------------- 一時ファイルに書き込む必要があるプログラムがいくつかあります。以下は、そ のようなファイルを構築する便利な方法です: (make-temp-file NAME-OF-APPLICATION) ‘make-temp-file’の役目は、2人の異なるユーザーやジョブが完全に一致する名 前のファイルの使用を防ぐことです。 -- Function: make-temp-file prefix &optional dir-flag suffix この関数は一時ファイルを作成してその名前をリターンする。Emacsは Emacsの各ジョブごとに異なるランダムないくつかの文字をPREFIXに追加す ることによって一時ファイルの名前を作成する。結果として新たに空のフ ァイルが作成されることが保障される。MS-DOSでは8+3のファイル名制限に 適合するように、文字列STRINGは切り詰められる可能性がある。PREFIXが 相対ファイル名なら、それは‘temporary-file-directory’にたいして展開 される。 (make-temp-file "foo") ⇒ "/tmp/foo232J6v" ‘make-temp-file’がリターンした際には、一時ファイルは空で作成される 。この時点でそのファイルに意図するコンテンツを書き込むこと。 DIR-FLAGが‘nil’なら、‘make-temp-file’は空のファイルのかわりに空のデ ィレクトリーを作成する。これはディレクトリー名ではなく、ディレクト リーのファイル名をリターンする。*note Directory Names::を参照のこと 。 SUFFIXが非‘nil’なら、‘make-temp-file’はそれをファイル名の最後に追加 する。 同じEmacs内で実行される異なるライブラリー間での競合を防ぐために、 ‘make-temp-file’を使用する各Lispプログラムがプログラム自身の PREFIXを使用すること。PREFIXの最後に追加される数字は、異なるEmacsジ ョブ内で実行される同じアプリケーションを区別する。追加される文字に より、同一のEmacsジョブ内でも多数の名前を区別することが可能になる。 一時ファイル用のデフォルトディレクトリーは変数 ‘temporary-file-directory’により制御されます。この変数によりすべての一時 ファイルにたいして、ユーザーがディレクトリーを指定する一貫した方法が与え られます。‘small-temporary-file-directory’が非‘nil’なら、かわりにそれを 使うプログラムもいくつかあります。これを使う場合には、‘make-temp-file’を 呼び出す前に正しいディレクトリーにたいしてプレフィックスを展開するべきで す。 -- User Option: temporary-file-directory この変数は一時ファイル作成用のディレクトリー名を指定する。値はディ レクトリー名であるべきだが、もし値がディレクトリーのファイル名 (*note Directory Names::を参照)ならば、Lispプログラムがかわりに対処 すればよい。‘expand-file-name’の2つ目の引数としてその値を使用するの は、それを達成するよい方法である。 デフォルト値はオペレーティングシステムにたいして適切な方法により決 定される。これは環境変数‘TMPDIR’、‘TMP’、‘TEMP’にもとづく値で、これ らの変数が定義されていなければシステム依存の名前にフォールバックす る。 一時ファイルの作成に‘make-temp-file’を使用しない場合でも、一時ファ イルを置くディレクトリーを判断するために依然としてこの変数を使用す るべきである。しかし一時ファイルが小さくなることを求める場合には、 ‘small-temporary-file-directory’が非‘nil’ならそれを使用すること。 -- User Option: small-temporary-file-directory この変数はサイズが小さいと予想される特定の一時ファイル作成用のディ レクトリー名を指定する。 小さくなるかもしれない一時ファイルに書き込みたいなら、以下のように ディレクトリーを計算すること: (make-temp-file (expand-file-name PREFIX (or small-temporary-file-directory temporary-file-directory))) -- Function: make-temp-name base-name この関数は一意なファイル名として使用できる文字列を生成する。この名 前はBASE-NAMEで始まり、それに各Emacsジョブごとに異なる複数のランダ ムな文字を追加したものである。これは‘make-temp-file’と似ているが、 (i) 名前だけを作成してファイルは作成しない、(ii) BASE-NAMEは絶対フ ァイル名であること、という点が異なる(MS-DOSシステムでは8+3ファイル 名制限に適合するようにBASE-NAMEが切り詰められる)。 *警告:* この関数を使用するべきではない。かわりに‘make-temp-file’を 使用すること! この関数は競合状態の影響を受けやすい。 ‘make-temp-name’呼び出しと一時ファイル作成のタイムラグはセキュリテ ィーホールとなり得る。 24.8.6 ファイル名の補完 ----------------------- このセクションではファイル名を補完するための低レベルサブルーチンについて 説明します。より高レベルの関数については*note Reading File Names::を参照 してください。 -- Function: file-name-all-completions partial-filename directory この関数はディレクトリー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") -- Function: file-name-completion filename directory &optional predicate この関数はディレクトリー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 -- User Option: completion-ignored-extensions ‘file-name-completion’はこのリスト内の任意の文字列で終わるファイル 名を通常は無視する。すべての可能な補完がこれらのサフィックスのいず れか1つで終わるときはそれらを無視しない。この変数は ‘file-name-all-completions’に影響しない。 以下は典型的な値: completion-ignored-extensions ⇒ (".o" ".elc" "~" ".dvi") ‘completion-ignored-extensions’のある要素がスラッシュ‘/’で終わる場 合には、それはディレクトリーを示す。スラッシュで_終わらない_要素が ディレクトリーにマッチすることは決してない。したがって上記の値は ‘foo.elc’という名前のディレクトリーを除外しないだろう。 24.8.7 標準的なファイル名 ------------------------- Emacs Lispプログラムが特定の用途のために標準的なファイル名を指定すること が必要な場合があります。典型的にはカレントユーザーによって指定された設定 データを保持する場合が該当します。そのようなファイルは、通常は ‘user-emacs-directory’により指定されるディレクトリーに配置され、デフォル トでは‘~/.emacs.d’です(*note Init File::を参照)。たとえば abbrev(abbreviation: 省略形)の定義は、デフォルトでは ‘~/.emacs.d/abbrev_defs’に格納されます。このようなファイル名を指定するた めには、関数‘locate-user-emacs-file’を使用するのがもっとも簡単な方法です 。 -- Function: locate-user-emacs-file base-name &optional old-name この関数は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’により使用されます。 -- Function: convert-standard-filename filename この関数はFILENAMEにもとづいたカレントオペレーティングシステムの慣 習に適合するファイル名をリターンする。 GNUとUnixシステムでは、これは単にFILENAMEをリターンする。その他のオ ペレーティングシステムでは、システム固有のファイル名規約にしたがう だろう。たとえばMS-DOSでは、この関数はMS-DOSファイル名制限にしたが うように先頭の‘.’を‘_’に変換したり、‘.’の後続の文字を3文字に切り詰 める等、さまざまな変更を行う。 この関数でGNUとUnixシステムの慣習に適合する名前を指定して、それを ‘convert-standard-filename’に渡すのが推奨される使用方法である。 24.9 ディレクトリーのコンテンツ =============================== ディレクトリーとはファイルの一種であり、さまざまな名前のファイルを含んで います。ディレクトリーはファイルシステムの機能です。 Emacsはディレクトリー内のファイル名をLispのリストとして一覧したり、シ ェルコマンド‘ls’を使用してバッファー内にファイル名を表示することができま す。後者の場合には、Emacsはオプションで各ファイルに関する情報も表示でき 、それは‘ls’コマンドに渡すオプションに依存します。 -- Function: directory-files directory &optional full-name match-regexp nosort この関数はディレクトリーDIRECTORY内のファイルの名前のリストをリター ンする。デフォルトではリストはアルファベット順。 この関数はFULL-NAMEが非‘nil’ならファイルの絶対ファイル名、それ以外 なら指定されたディレクトリーにたいする相対ファイル名をリターンする 。 MATCH-REGEXPが非‘nil’なら、この関数はその正規表現にたいするマッチを 含むファイル名だけをリターンして、それ以外のファイル名はリストから 除外される。case(大文字小文字)を区別するファイルシステムでは、 caseを区別する正規表現マッチングが行われる。 NOSORTが非‘nil’なら‘directory-files’はリストをソートしないので、取 得するファイル名に特定の順序はない。最大限の可能なスピードを得る必 要がありファイル処理順を気にしなければこれを使用する。ユーザーから 処理順が可視なら、名前をソートすれば多分ユーザーはより幸せになるだ ろう。 (directory-files "~lewis") ⇒ ("#foo#" "#foo.el#" "." ".." "dired-mods.el" "files.texi" "files.texi.~1~") DIRECTORYが読み取り可能なディレクトリー名でなければエラーがシグナル される。 -- Function: directory-files-recursively directory regexp &optional include-directories REGEXPにマッチする名前をもつDIRECTORY配下のすべてのファイルをリター ンする。この関数はベースネーム(basename: 先行するディレクトリー部分 を除外したファイル名)がREGEXPにマッチするファイルを、DIRECTORYとそ のサブディレクトリーを再帰的に検索して、マッチしたファイルの絶対フ ァイル名(*note absolute file names: Relative File Names.を参照)のリ ストをリターンする。ファイル名は深さ優先順でリターンされ、それは親 ディレクトリーの前に任意のサブディレクトリー内のファイルが配置され ることを意味する。加えて各ディレクトリー内で見つかったファイルはベ ースネームにもとづいてソートされる。デフォルトではREGEXPにマッチす る名前のディレクトリーはリストから省略されるが、オプション引数 INCLUDE-DIRECTORIESが非‘nil’ならそれらも含まれる。 -- Function: directory-files-and-attributes directory &optional full-name match-regexp nosort id-format これはどのファイルを報告するかとファイル名を報告する方法において ‘directory-files’と似ている。しかしこの関数はファイル名のリストをリ ターンするかわりに、各ファイルごとにリスト‘(FILENAME . ATTRIBUTES)’をリターンする。ここでATTRIBUTESはそのファイルにたいし て‘file-attributes’がリターンするであろう値。オプション引数 ID-FORMATは‘file-attributes’の対応する引数と同じ意味をもつ(*note Definition of file-attributes::を参照)。 -- Function: file-expand-wildcards pattern &optional full この関数はワイルドカードパターンPATTERNを展開して、それにマッチする ファイル名のリストをリターンする。 絶対ファイル名としてPATTERNが記述されると値も絶対ファイル名になる。 PATTERNが相対ファイル名で記述されていれば、それはカレントデフォルト ディレクトリーにたいして相対的に解釈される。通常はリターンされるフ ァイル名もカレントデフォルトディレクトリーにたいする相対ファイル名 になる。しかしFULLが非‘nil’なら絶対ファイル名がリターンされる。 -- Function: insert-directory file switches &optional wildcard full-directory-p この関数は‘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’に渡されるだけである。 -- Variable: insert-directory-program この変数の値は関数‘insert-directory’用にディレクトリーリストを生成 するプログラムである。この値はLispコードでこのリストを生成するシス テムでは無視される。 24.10 ディレクトリーの作成・コピー・削除 ======================================== Emacs Lispのファイル操作関数のほとんどは、ディレクトリーであるようなファ イルに使用されたときはエラーとなります。たとえば‘delete-file’でディレク トリーの削除はできません。以下のスペシャル関数はディレクトリーの作成と削 除を行うために存在します。 -- Command: make-directory dirname &optional parents このコマンドはDIRNAMEという名前のディレクトリーを作成する。 PARENTSが非‘nil’の場合(インタラクティブな呼び出しでは常に非‘nil’)に は、その親ディレクトリーがまだ存在しなければ最初にそれを作成するこ とを意味する。 ‘mkdir’はこれにたいするエイリアス。 -- Command: copy-directory dirname newname &optional keep-time parents copy-contents このコマンドはDIRNAMEという名前のディレクトリーをNEWNAMEにコピーす る。NEWNAMEが既存のディレクトリーなら、DIRNAMEはそのサブディレクト リーにコピーされるだろう。 これは常にコピーされるファイルのファイルモードを、対応する元のファ イルモードと一致させる。 3つ目の引数KEEP-TIMEが非‘nil’なら、それはコピーされるファイルの修正 時刻を保持することを意味する。プレフィックス引数を与えると、 KEEP-TIMEは非‘nil’になる。 4つ目の引数PARENTSは、親ディレクトリーが存在しない場合に作成するか どうかを指定する。インタラクティブな場合には、これはデフォルトで発 生する。 5つ目の引数COPY-CONTENTSが非‘nil’なら、それはNEWNAMEが既存のディレ クトリーならば、そのサブディレクトリーとしてDIRNAMEをコピーするかわ りにDIRNAMEのコンテンツをNEWNAMEにコピーする。 -- Command: delete-directory dirname &optional recursive trash このコマンドはDIRNAMEという名前のディレクトリーを削除する。関数 ‘delete-file’はディレクトリーであるようなファイルにたいして機能しな い。それらにたいしては‘delete-directory’を使用しなければならない。 RECURSIVEが‘nil’でディレクトリー内にファイルが存在する場合には、 ‘delete-directory’はエラーをシグナルする。 ‘delete-directory’は親ディレクトリーの階層のシンボリックリンクだけ をフォローする。 オプション引数TRASHが非‘nil’、かつ変数‘delete-by-moving-to-trash’が 非‘nil’なら、このコマンドはファイルを削除するかわりにシステムの Trash(ゴミ箱)にファイルを移動する。*note Miscellaneous File Operations: (emacs)Misc File Ops.を参照のこと。インタラクティブに呼 び出された際には、プレフィックス引数がなければTRASHは‘t’、それ以外 は‘nil’。 24.11 特定のファイル名の“Magic”の作成 ===================================== 特定のファイル名にたいして特別な処理を実装できます。これはそれらの名前に たいする“magic”化と呼ばれます。この機能は主にリモートファイルにたいする アクセスの実装用に使用されます(*note Remote Files: (emacs)Remote Files.を 参照)。 magicファイル名を定義するには、名前クラスを定義するための正規表現とそ れにマッチするファイル名用のEmacsファイル操作プリミティブすべてを実装す るハンドラーを定義しなければなりません。 変数‘file-name-handler-alist’は各ハンドラーに適用するときを決定する正 規表現とともにハンドラーのリストを保持します。各要素は以下の形式をもちま す: (REGEXP . HANDLER) ファイルアクセスとファイル名変換にたいするすべてのEmacsプリミティブは、 ‘file-name-handler-alist’にたいして与えられたファイル名をチェックします 。そのファイル名がREGEXPにマッチしたら、そのプリミティブがHANDLERを呼び 出してファイルを処理します。 HANDLERの1つ目の引数には、プリミティブの名前をシンボルとして与えます 。残りの引数はそのプリミティブに引数として渡されます(これらの引数の1つ目 はほとんどの場合はファイル名自身)。たとえば以下を行って: (file-exists-p FILENAME) FILENAMEがハンドラーHANDLERをもつなら、HANDLERは以下のように呼び出されま す: (funcall HANDLER 'file-exists-p FILENAME) 関数が2つ以上の引数を受け取る場合には、それらはファイル名でなければな らず、関数はそれらのファイル名それぞれにたいしてハンドラーをチェックしま す。たとえば、 (expand-file-name FILENAME DIRNAME) 以下を行うと、FILENAMEにたいするハンドラーをチェックした後にDIRNAMEにた いするハンドラーをチェックします。どちらの場合でもHANDLERは以下のように 呼び出されます: (funcall HANDLER 'expand-file-name FILENAME DIRNAME) その後にHANDLERはFILENAMEとDIRNAMEのいずれかを処理するか解決する必要があ ります。 指定されたファイル名が2つ以上のハンドラーにマッチする場合には、ファイ ル名の中で最後に開始するマッチが優先されます。リモートファイルアクセスの ようなジョブにたいするハンドラーに先立って、解凍のようなジョブにたいする ハンドラーが最初に処理されるようにこのルールが選択されました。 以下はmagicファイル名ハンドラーが処理する操作です: ‘access-file’、‘add-name-to-file’、‘byte-compiler-base-file-name’, ‘copy-directory’、‘copy-file’、‘delete-directory’、‘delete-file’、 ‘diff-latest-backup-file’、‘directory-file-name’、‘directory-files’、 ‘directory-files-and-attributes’、‘dired-compress-file’、 ‘dired-uncache’, ‘expand-file-name’、‘file-accessible-directory-p’、‘file-acl’、 ‘file-attributes’、‘file-directory-p’、‘file-equal-p’、 ‘file-executable-p’、‘file-exists-p’、‘file-in-directory-p’、 ‘file-local-copy’、‘file-modes’、‘file-name-all-completions’、 ‘file-name-as-directory’、‘file-name-completion’、 ‘file-name-directory’、‘file-name-nondirectory’、 ‘file-name-sans-versions’、‘file-newer-than-file-p’、 ‘file-notify-add-watch’、‘file-notify-rm-watch’、‘file-notify-valid-p’、 ‘file-ownership-preserved-p’、‘file-readable-p’、‘file-regular-p’、 ‘file-remote-p’、‘file-selinux-context’、‘file-symlink-p’、 ‘file-truename’、‘file-writable-p’、‘find-backup-file-name’、 ‘get-file-buffer’、‘insert-directory’、‘insert-file-contents’, ‘load’、‘make-auto-save-file-name’、‘make-directory’、 ‘make-directory-internal’、‘make-symbolic-link’, ‘process-file’、‘rename-file’、‘set-file-acl’、‘set-file-modes’、 ‘set-file-selinux-context’、‘set-file-times’、 ‘set-visited-file-modtime’、‘shell-command’、‘start-file-process’、 ‘substitute-in-file-name’, ‘unhandled-file-name-directory’、‘vc-registered’、 ‘verify-visited-file-modtime’、 ‘write-region’. ‘insert-file-contents’にたいするハンドラーはVISIT引数が非‘nil’なら、 通常は‘(set-buffer-modified-p nil)’によりそのバッファーの変更フラグをク リアーする必要があります。これにはもしそのバッファーがロックされていたら 、ロックを解除する効果もあります。 ハンドラー関数は上記すべての操作を処理しなければならず、他の操作が将 来追加される可能性もあります。これらの操作自体すべてを実装する必要はあり ません — 特定の操作にたいして特別なことを行う必要がないときには、その操 作を通常の方法で処理するように、そのプリミティブを再呼び出しできます。認 識できない操作にたいしては、常にそのプリミティブを再呼び出しするべきです 。以下はこれを行う方法の1つです: (defun my-file-handler (operation &rest args) ;; 特別に処理する必要がある、 ;; 特別な操作を最初にチェックする (cond ((eq operation 'insert-file-contents) ...) ((eq operation 'write-region) ...) ... ;; 関知しないその他の操作を処理する (t (let ((inhibit-file-name-handlers (cons 'my-file-handler (and (eq inhibit-file-name-operation operation) inhibit-file-name-handlers))) (inhibit-file-name-operation operation)) (apply operation args))))) ハンドラー関数が通常のEmacsプリミティブを呼び出す決定をした際には、無 限再帰を引き起こすような同一ハンドラーからのプリミティブの再呼び出しを防 ぐ必要があります。上記の例では変数‘inhibit-file-name-handlers’と ‘inhibit-file-name-operation’によって、これを行う方法を示しています。上 記の例のように、これらを正確に使用するよう注意してください。複数ハンドラ ーの正しい振る舞いと、それぞれがハンドラーをもつかもしれない2つのファイ ル名にたいする操作にたいする詳細は非常に重要です。 ファイルへの実アクセスにたいして実際には特別なことを行わないハンドラ ー(たとえばリモートファイル名にたいしてホスト名の補完を実装するハンドラ ー等)は、‘safe-magic’プロパティに非‘nil’をもつべきです。たとえばEmacsは 通常は‘PATH’内で見い出されるようなディレクトリーがプレフィックス‘/:’によ ってmagicファイル名に見えるようなら、magicファイル名にならないように保護 します。しかし‘safe-magic’プロパティに非‘nil’をもつハンドラーがそれらに たいして使用された場合には、‘/:’は追加されません。 ファイル名ハンドラーは普通とは異なる方法でそれを処理(handle)するのが どの操作(operation)なのかを宣言するために、‘operations’プロパティをもつ ことができます。このプロパティが非‘nil’値をもつなら、それは操作のリスト であるべきです。その場合には、それらの操作だけがハンドラーを呼び出すでし ょう。これは無駄を省きますが、主な目的はオートロードされるハンドラー関数 が実際に処理を行うとき以外はロードされないようにすることです。 通常のプリミティブにたいして単にすべての操作を延期しても機能しません 。たとえばファイル名ハンドラーが‘file-exists-p’にたいして適用された場合 には、通常の‘load’コードは正しく機能しないでしょうから、ハンドラー自身で ‘load’を処理しなければなりません。しかしハンドラーが‘file-exists-p’プロ パティを使用して‘file-exists-p’を処理しないことを宣言した場合には、普通 とは異なる方法で‘load’を処理する必要はなくなります。 -- Variable: inhibit-file-name-handlers この変数は特定の操作にたいして現在のところ使用を抑制されているハン ドラーのリストを保持する。 -- Variable: inhibit-file-name-operation 特定のハンドラーにたいしてその時点で抑制されている操作。 -- Function: find-file-name-handler file operation この関数はFILEというファイル名にたいするハンドラー関数、それが存在 しなければ‘nil’をリターンする。引数OPERATIONはそのファイルを処理す る操作であること。これはハンドラー呼び出し時に1つ目の引数として渡す ことになる値である。OPERATIONが‘inhibit-file-name-operation’と等し いか、そのハンドラーの‘operations’内に存在しなければ、この関数は ‘nil’をリターンする。 -- Function: file-local-copy filename この関数はファイルFILENAMEがまだローカルマシン上になければ、それを ローカルマシン上の通常の非magicファイルにコピーする。magicファイル 名は、それらが他のマシン上のファイルを参照する場合には、 ‘file-local-copy’操作を処理するべきである。リモートファイルアクセス 以外の目的にたいして使用されるmagicファイル名は、 ‘file-local-copy’を処理するべきではない。この場合には関数はそのファ イルをローカルファイルとして扱うだろう。 FILENAMEがローカルなら、それがmagicか否かにかかわらずこの関数は何も 行わずに‘nil’をリターンする。それ以外ならローカルコピーファイルのフ ァイル名をリターンする。 -- Function: file-remote-p filename &optional identification connected この関数は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’をリターンする 。これは接続が存在しない際の接続の遅延を回避したいときに有用。 -- Function: unhandled-file-name-directory filename この関数は非magicのディレクトリーの名前をリターンする。これは非 magicのFILENAMEには対応するディレクトリー名(*note Directory Names::を参照)をリターンする。magicのFILENAMEには、何の値をリターン するかを決定するためにファイル名ハンドラーを呼び出す。FILENAMEがロ ーカルプロセスからアクセス不能なら、ファイル名ハンドラーは‘nil’をリ ターンすることによってそれを示すこと。 これはサブプロセスの実行に有用。すべてのサブプロセスは自身が所属す るカレントディレクトリーとして非magicディレクトリーをもたなければな らず、この関数はそれを導出するよい手段である。 -- User Option: remote-file-name-inhibit-cache リモートファイルの属性は、よりよいパフォーマンスのためにキャッシュ することができる。キャッシュがEmacsの制御外で変更されると、そのキャ ッシュ値は無効になり再読込しなければならない。 この変数が‘nil’にセットされているとキャッシュ値は決して失効しない。 このセッティングはEmacs以外にリモートファイルを変更するものがないこ とが確実な場合のみ慎重に使用すること。これが‘t’にセットされていると キャッシュ値は決して使用されない。これはもっとも安全な値であるがパ フォーマンスは低下するかもしれない。 折衷的な値としてはこれを正の数字にセットする。これはキャッシュされ てからその数字の秒数の間は、ャッシュ値を使用することを意味する。リ モートファイルが定期的にチェックされる場合には、この変数を定期的な チェックの間隔より小さい値にletバインドするのは、よい考えかもしれな い。たとえば: (defun display-time-file-nonempty-p (file) (let ((remote-file-name-inhibit-cache (- display-time-interval 5))) (and (file-exists-p file) (< 0 (nth 7 (file-attributes (file-chase-links file))))))) 24.12 ファイルのフォーマット変換 ================================ Emacsはバッファー内のデータ(テキスト、テキストプロパティ、あるいはその他 の情報)とファイルへの格納に適した表現との間で双方向の変換をするために複 数のステップを処理します。このセクションでは、この“フォーマット変換 (format conversion)”を行う基本的な関数、すなわちファイルをバッファーに読 み込む‘insert-file-contents’と、バッファーをファイルに書き込む ‘write-region’を説明します。 24.12.1 概要 ------------ 関数‘insert-file-contents’: • 最初に、ファイルからバイトをバッファーに挿入して • バイトを適切な文字にデコードした後に • ‘format-alist’のエントリーで定義されているようにフォーマット処理し てから • ‘after-insert-file-functions’内の関数を呼び出す。 関数‘write-region’: • 最初に‘write-region-annotate-functions’内の関数を呼び出して • ‘format-alist’のエントリーで定義されているようにフォーマット処理し てから • 文字を適切なバイトにエンコードした後に • そのバイトでファイルを変更する。 これはもっとも低レベルでの操作を対照的に示したもので、対象の読み取り と書き込みの処理が逆順で対応しています。このセクションの残りの部分では、 上記で名前を挙げた3つの変数を取り巻く2つの機能と、関連するいくつかの関数 を説明します。文字のエンコードとデコードについての詳細は*note Coding Systems::を参照してください。 24.12.2 ラウンドトリップ仕様 ---------------------------- 読み取りと書き込みのもっとも一般的な機能は変数‘format-alist’で制御されま す。これは“ファイルフォーマット(file format)”仕様のリストで、Emacsバッフ ァー内のデータにたいしてファイル内で使用されるテキスト表現を記述します。 読み取りと書き込みの仕様記述はペアーになっており、わたしたちがそれを“ラ ウンドトリップ(round-trip)”仕様と呼ぶのはこれが理由です(非ペアー仕様につ いては*note Format Conversion Piecemeal::を参照)。 -- Variable: format-alist このリストには定義されるファイルフォーマットごとに1つのフォーマット 定義が含まれる。フォーマット定義はそれぞれ以下の形式のリスト: (NAME DOC-STRING REGEXP FROM-FN TO-FN MODIFY MODE-FN PRESERVE) 以下はフォーマット定義内で要素がもつ意味: NAME フォーマットの名前。 DOC-STRING フォーマットのドキュメント文字列。 REGEXP このフォーマットで表現されるファイルの認識に使用される正規表現。 ‘nil’ならフォーマットが自動的に適用されることは決してない。 FROM-FN このフォーマットのデータをデコードする、(ファイルデータを通常の Emacsデータ表現に変換するための)シェルコマンドか関数。 シェルコマンドは文字列として表され、Emacsはそのコマンドを変換処理用 のフィルターとして実行する。 FROM-FNが関数なら、それは変換するべきバッファー部分を指定する2つの 引数BEGINとENDで呼び出される。これはインプレースでテキストを編集す ることにより変換を行うこと。これはテキスト長を変更する可能性がある のでFROM-FNは変更されたend位置をリターンすること。 ファイルの先頭がこの変換によりREGEXPにマッチしないようにするのは FROM-FNの役目の1つである。そうしないとおそらく再度変換が呼び出され る。 TO-FN このフォーマットのデータをエンコード、すなわち通常のEmacsデータ表現 をこのフォーマットに変換するためのシェルコマンドか関数。 TO-FNが文字列ならそれはシェルコマンドである。Emacsは変換処理のため のフィルターとしてこのコマンドを実行する。 TO-FNが関数なら、それは3つの引数で呼び出される。BEGINとENDは変換さ れるべきバッファー部分、BUFFERでそれがどのバッファーかを指定する。 変換を行うには2つの方法がある: • そのバッファー内でインプレースで編集を行う。TO-FNはこの場合は 変更にしたがいテキスト範囲のend位置をリターンすること。 • 注釈(annotation)のリストをリターンする。これは‘(POSITION . STRING)’という形式の要素をもつリストで、POSITIONは書き込まれる テキスト内での相対位置を指定する整数、STRINGはそこに追加される 注釈である。このリストはTO-FNがそれをリターンする際には、位置 順でソートされていなければならない。 ‘write-region’が実際にバッファーからファイルにテキストを書き込 む際には、指定された注釈を対応する位置に混合する。これはすべて バッファーを変更せずに行われる。 MODIFY フラグ。エンコード関数がバッファーを変更するなら‘t’、注釈リストをリ ターンすることによって機能するなら‘nil’。 MODE-FN このフォーマットから変換されたファイルをvisit後に呼び出されるマイナ ーモード関数。この関数は1つの引数で呼び出されて、それが整数1ならマ イナーモード関数はそのモードを有効にする。 PRESERVE フラグ。‘format-write-file’が‘buffer-file-format’からこのフォーマッ トを取り除くべきでなければ‘t’。 関数‘insert-file-contents’は指定されたファイルを読み込む際にファイル フォーマットを自動的に認識します。これはフォーマット定義の正規表現にたい してファイルの先頭テキストをチェックして、マッチが見つかったら、そのフォ ーマットにたいするデコード関数を呼び出します。その後は再度すべての既知の フォーマットをチェックします。適用できるフォーマットがない間はチェックを 続行します。 ‘find-file-noselect’やそれを使用するコマンドでファイルをvisitすること により、同じように変換が行われます(内部で‘insert-file-contents’を呼び出 すため)。さらにそれをデコードする各フォーマットのモード関数も呼び出しま す。これはバッファーローカル変数‘buffer-file-format’内にフォーマット名の リストを格納します。 -- Variable: buffer-file-format この変数はvisitしているファイルのフォーマットを表す。より正確にはこ れはカレントバッファーのファイルをvisitに起因するデコードのファイル フォーマット名のリストである。これはすべてのバッファーにたいして常 にローカル。 ‘write-region’がデータをファイルに書き込む際には、まず ‘buffer-file-format’にリストされたフォーマットにたいするエンコード関数を リスト内での出現順に呼び出します。 -- Command: format-write-file file format &optional confirm このコマンドはカレントバッファーのコンテンツをフォーマット名のリス トFORMATにもとづいたフォーマットでファイルFILEに書き込む。これは FORMATを起点に、‘buffer-file-format’の値からPRESERVEフラグ(上記参照 )が非‘nil’の要素にたいして、それがまだFORMAT内に存在しなければ任意 の個数それらを追加する。その後に将来の保存においてデフォルトとなる ように、このフォーマットで‘buffer-file-format’を更新する。FORMAT引 数を除けばこのコマンドは‘write-file’と似ている。特にCONFIRMは ‘write-file’での対応する引数と、意味やinteractiveでの扱いが同じであ る。*note Definition of write-file::を参照のこと。 -- Command: format-find-file file format このコマンドはファイルFILEを探してそれをフォーマットFORMATにしたが って変換する。これは後でそのバッファーを保存する場合にFORMATをデフ ォルトにすることも行う。 引数FORMATはフォーマット名のリスト。FORMATが‘nil’なら何の変換も行わ れない。interactiveに呼び出した場合には、FORMATにたいして単に をタイプすると‘nil’が指定される。 -- Command: format-insert-file file format &optional beg end このコマンドはファイルFILEのコンテンツをフォーマットFORMATにしたが って変換して挿入する。BEGとENDが非‘nil’なら、それは ‘insert-file-contents’と同様、ファイルのどの部分を読み込むかを指定 する(*note Reading from Files::を参照)。 リターン値は絶対ファイル名のリスト、および挿入されたデータの長さ(変 換後)であり、これは‘insert-file-contents’がリターンするものと同様。 引数FORMATはフォーマット名のリスト。FORMATが‘nil’なら何の変換も行わ れない。interactiveに呼び出した場合には、FORMATにたいして単に をタイプすると‘nil’が指定される。 -- Variable: buffer-auto-save-file-format この変数は自動保存(auto-saving)にたいして使用するフォーマットを指定 する。値は‘buffer-file-format’と同様、ファイル名のリストだが、これ はauto-saveファイルへの書き込みで‘buffer-file-format’のかわりに使用 される。値が‘t’(デフォルト)なら自動保存は当バッファーの通常の保存時 と同じフォーマットを使用する。この変数はすべてのバッファーにおいて 常にバッファーローカル。 24.12.3 漸次仕様 ---------------- 前のサブセクション(*note Format Conversion Round-Trip::を参照)で説明した ラウンドトリップ指定とは対照的に、変数‘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つの関数によりリターン された値は次の関数への引数になります。 -- Variable: write-region-annotate-functions ‘write-region’にたいして呼び出す関数のリスト。リスト内の各関数は書 き込まれるリージョンの開始と終了の2つの引数で呼び出される。これらの 関数はそのバッファーのコンテンツを変更するべきではない。かわりに注 釈をリターンすること。 特別なケースとして、関数がカレントと異なるバッファーをリターンする かもしれない。Emacsはこれを、出力される変更されたテキストをカレント バッファーが含むものとして理解する。つまりEmacsは‘write-region’呼び 出しの引数STARTとENDを、新たなバッファーの‘point-min’と ‘point-max’に変更して与える。さらに以前のすべての注釈はこの関数によ り処理されるのでEmacsはそれらの破棄も行う。 -- Variable: write-region-post-annotation-function この変数の値が非‘nil’なら、それは関数であること。この関数は ‘write-region’完了後に引数なしで呼び出される。 ‘write-region-annotate-functions’内のある関数がカレントと異なるバッ ファーをリターンした場合には、Emacsは ‘write-region-post-annotation-function’を複数回呼び出す。Emacsは最 後にカレントだったバッファーでそれを呼び出し、その前にカレントだっ たバッファーで再度これを呼び出す、...のようにして元のバッファーに戻 る。 したがって‘write-region-annotate-functions’内の関数は、バッファーを 作成して、‘kill-buffer’のそのバッファーでのローカル値にこの変数を与 え、変更されたテキストでそのバッファーをセットアップして、そのバッ ファーをカレントにすることができる。そのバッファーは、 ‘write-region’完了後にkillされるだろう。 -- Variable: after-insert-file-functions このリスト内の各関数は、挿入されるテキストの先頭にポイントがある状 態で、挿入される文字数を1つの引数として‘insert-file-contents’によ り呼び出される。すべての関数はポイントを未変更のまま、その関数によ って変更された挿入後テキストの新たな文字数をリターンすること。 わたしたちは、ユーザーがファイル内にテキストプロパティを格納したりそ れらを取得するために、そしてさまざまなデータフォーマットを体験することに より適切なフォーマットを見つけるために、これらのフックを使用してLispプロ グラムを記述することを推奨します。最終的にはわたしたちがEmacs内にインス トールできる、良質で汎用性のある拡張をユーザーが開発することを望みます。 わたしたちはテキストプロパティの名前や値として、任意のLispオブジェク トの処理を試みることは推奨しません — なぜなら汎用的なプログラムはおそら く記述が困難かつ低速だからです。かわりに十分な柔軟性をもちエンコードが難 しすぎない、想定されるデータ型のセットを選択してください。 25 バックアップと自動保存 ************************* バックアップファイルとauto-save(自動保存)ファイルは、Emacsのクラッシュや ユーザー自身のエラーからユーザーの保護を試みるための2つの手段です。自動 保存(auto-saving)はカレントの編集セッションを開始した以降のテキストを保 存します。一方バックアップファイルはカレントセッションの前のファイルコン テンツを保存します。 25.1 ファイルのバックアップ =========================== “バックアップファイル(backup file)”とは編集中ファイルの古いコンテンツの コピーです。Emacsはvisitされているファイルにバッファーを最初に保存すると きにバックアップファイルを作成します。したがってバックアップファイルには 、通常はカレント編集セッションの前にあったファイルのコンテンツが含まれて います。バックアップファイルを一度存在したら、そのコンテンツは変更されず に残ります。 バックアップは通常はvisitされているファイルを新たな名前にリネームする ことによって作成されます。オプションでバックアップファイルがvisitされて いるファイルをコピーすることにより作成されるように指定できます。この選択 により、複数の名前をもつファイルの場合に違いが生じます。また編集中のファ イルの所有者が元のオーナーのままか、それとも編集ユーザーになるかにも影響 し得ます。 デフォルトではEmacsは編集中のファイルごとに単一のバックアップファイル を作成します。かわりに番号付きバックアップ(numbered backup)を要求するこ ともできます。その場合には新たなバックアップファイルそれぞれが新たな名前 を得ます。必要なくなったときには古い番号付きバックアップを削除したり、 Emacsにそれらを自動的に削除させることもできます。 25.1.1 バックアップファイルの作成 --------------------------------- -- Function: backup-buffer この関数は、もしそれが適切ならカレントバッファーにvisitされているフ ァイルのバックアップを作成する。これは最初のバッファー保存を行う前 に‘save-buffer’により呼び出される。 リネームによりバックアップが作成されると、リターン値は(MODES EXTRA-ALIST BACKUPNAME)という形式のコンスセルになる。ここでMODESは ‘file-modes’ (*note Testing Accessibility::を参照)でリターンされる ような元ファイルのモードビット、EXTRA-ALISTは ‘file-extended-attributes’ (*note Extended Attributes::を参照)によ りリターンされるような元ファイルの拡張属性を示すalist、そして BACKUPNAMEはバックアップの名前。 他のすべての場合(コピーによりバックアップが作成された、またはバック アップが作成されなかった)には、この関数は‘nil’をリターンする。 -- Variable: buffer-backed-up このバッファーローカル変数は、そのバッファーのファイルがバッファー によりバックアップされたかどうかを明示する。非‘nil’ならバックアップ ファイルは書き込み済み、それ以外なら(バックアップが有効なら)次回保 存時にファイルはバックアップされる。この変数は永続的にローカルであ り‘kill-all-local-variables’はこれを変更しない。 -- User Option: make-backup-files この変数はバックアップファイルを作成するかどうかを決定する。非 ‘nil’なら、Emacsは初回保存時にすべてのファイルのバックアップを作成 する — ただし‘backup-inhibited’が‘nil’の場合(以下参照)。 以下の例はRmailバッファーだけで変数‘make-backup-files’を変更して、 それ以外では変更しない方法を示す。この変数を‘nil’にセットすると、 Emacsはそれらのファイルのバックアップ作成をストップするのでディスク 容量の消費を節約するだろう(あなたはこのコードをinitファイルに配置し たいと思うかもしれない)。 (add-hook 'rmail-mode-hook (lambda () (setq-local make-backup-files nil))) -- Variable: backup-enable-predicate この変数の値は、あるファイルがバックアップファイルをもつべきかどう かを決定するために、特定のタイミングで呼び出される関数ある。この関 数は判断対象の絶対ファイル名という1つの引数を受け取る。この関数が ‘nil’をリターンすると、そのファイルにたいするバックアップは無効にな る。それ以外なら、このセクション内の他の変数がバックアップ作成の是 非と方法を指定する。 デフォルト値は‘normal-backup-enable-predicate’で、これは ‘temporary-file-directory’と‘small-temporary-file-directory’内のフ ァイルをチェックする。 -- Variable: backup-inhibited この変数が非‘nil’ならバックアップは抑制される。これはvisitされてい るファイル名にたいする‘backup-enable-predicate’のテスト結果を記録す る。さらにvisitされているファイルにたいするバックアップ抑制にもとづ いたその他の機構からも使用され得る。たとえばVCはバージョンコントロ ールシステムに管理されるファイルのバックアップを防ぐために、この変 数を非‘nil’にセットする。 これは永続的にローカルなのでメジャーモード変更により値は失われない 。メジャーモードはこの変数ではなく、かわりに‘make-backup-files’をセ ットすること。 -- User Option: backup-directory-alist この変数の値はファイル名パターンとバックアップディレクトリー名の alist。各要素は以下の形式 (REGEXP . DIRECTORY) この場合には名前がREGEXPにマッチするファイルのバックアップが、 DIRECTORY内に作成されるだろう。DIRECTORYには相対ディレクトリーか絶 対ディレクトリーを指定できる。絶対ディレクトリーなら、マッチするす べてのファイルが同じディレクトリー内にバックアップされる。このディ レクトリー内でのファイル名はクラッシュを避けるために、バックアップ されるファイルの完全名のすべてのディレクトリー区切りが‘!’に変更され る。結果の名前を切り詰めるファイルシステムでは、これは正しく機能し ないだろう。 すべてのバックアップが単一のディレクトリーで行われる一般的なケース では、このalistには‘"."’と適切なディレクトリーのペアという単一の要 素が含まれるべきである。 この変数が‘nil’(デフォルト)、またはファイル名のマッチに失敗するとバ ックアップは元のファイルのディレクトリーに作成される。 長いファイル名がないMS-DOSファイルシステムでは、この変数は常に無視 される。 -- User Option: make-backup-file-name-function この変数の値はバックアップファイル名を作成する関数。関数 ‘make-backup-file-name’はこれを呼び出す。*note Naming Backup Files: Backup Names.を参照のこと。 特定のファイルにたいして特別なことを行うために、これをバッファーロ ーカルにすることもできる。変更する場合には、‘backup-file-name-p’と ‘file-name-sans-versions’を変更する必要もあるかもしれない。 25.1.2 リネームかコピーのどちらでバックアップするか? ---------------------------------------------------- Emacsのバックアップファイル作成には2つの方法があります: • Emacsは元のファイルをリネームすることができ、それがバックアップファ イルになる。その後、バッファーの保存は新たなファイルに書き込まれる 。この手順の後には、元ファイルの他のすべての名前(ハードリンク)はバ ックアップファイルを参照することになる。新たなファイルの所有者は編 集を行っているユーザーになり、グループはそのディレクトリー内でその ユーザーが新たなファイルを書き込んだときのデフォルトのグループにな る。 • Emacsは元のファイルをバックアップファイルにコピーでき、新たな内容は その後は元のファイルに上書きされる。この手順の後は、元のファイルの 他のすべての名前(ハードリンク)は、そのファイルの(更新された)カレン トバージョンを参照し続ける。ファイルの所有者とグループは変更されな い。 デフォルトの方法は1つ目のリネームです。 変数‘backup-by-copying’が非‘nil’なら、それは2つ目の方法、つまり元のフ ァイルをコピーして新たなバッファー内容で上書きすることを意味します。変数 ‘file-precious-flag’が非‘nil’の場合にも、(メイン機能の副作用として)この 効果があります。*note Saving Buffers::を参照してください。 -- User Option: backup-by-copying この変数が非‘nil’なら、Emacsは常にコピーによりバックアップファイル を作成する。デフォルトは‘nil’。 以下の3つの変数が非‘nil’の際は、ある特定のケースに2つ目の方法が使用さ れます。その特定のケースに該当しないファイルの処理には影響はありません。 -- User Option: backup-by-copying-when-linked この変数が非‘nil’なら、Emacsは複数名(ハードリンク)をもつファイルに たいしてコピーによりバックアップを作成する。デフォルトは‘nil’。 ‘backup-by-copying’が非‘nil’なら常にコピーによりバックアップが作成 されるので、この変数は‘backup-by-copying’が‘nil’のときだけ意味があ る。 -- User Option: backup-by-copying-when-mismatch この変数が非‘nil’(デフォルト)なら、リネームによりファイルの所有者や グループが変更されるケースではEmacsはコピーによりバックアップを作成 する。 リネームによりファイルの所有者やグループが変更されなければ、値に効 果はない。つまり、そのディレクトリーで新たに作成されるファイルにた いするデフォルトのグループに属するユーザーにより所有されるファイル が該当する。 ‘backup-by-copying’が非‘nil’なら常にコピーによりバックアップが作成 されるので、この変数は‘backup-by-copying’が‘nil’のときだけ意味があ る。 -- User Option: backup-by-copying-when-privileged-mismatch この変数が非‘nil’なら、特定のユーザーID値(具体的には特定の値以下の ID数値)にたいしてのみ、‘backup-by-copying-when-mismatch’と同じよう に振る舞うことを指定する。変数にはその数値をセットする。 したがってファイル所有者の変更を防ぐ必要がある際には、 ‘backup-by-copying-when-privileged-mismatch’を0にセットすればスーパ ーユーザーだけがコピーによるバックアップを行うことができる。 デフォルトは200。 25.1.3 番号つきバックアップファイルの作成と削除 ----------------------------------------------- ファイルの名前が‘foo’なら、番号付きバックアップのバージョン名は ‘foo.~V~’となります。Vは‘foo.~1~’、‘foo.~2~’、‘foo.~3~’、...、 ‘foo.~259~’のように、さまざまな整数です。 -- User Option: version-control この変数は単一の非番号付きバックアップファイルを作成するか、それと も複数の番号付きバックアップを作成するかを制御する。 ‘nil’ visitされたファイルが番号付きバックアップなら番号付きバックア ップを作成して、それ以外は作成しない。これがデフォルト。 ‘never’ 番号付きバックアップを作成しない。 ANYTHING ELSE 番号付きバックアップを作成する。 番号付きバックアップを使用することにより、バックアップのバージョン番 号は最終的には非常に大きな番号になるので、それらを削除しなければなりませ ん。Emacsはこれを自動で行うことができ、ユーザーに削除するか確認すること もできます。 -- User Option: kept-new-versions この変数の値は新たな番号付きバックアップが作成された際に保持するべ き、もっとも新しいバージョンの個数。新たに作成されたバックアップも カウントされる。デフォルトは2。 -- User Option: kept-old-versions この変数の値は新たな番号付きバックアップが作成された際に保持するべ き、もっとも古いバージョンの個数。デフォルトは2。 番号が1、2、3、5、7のバックアップがあり、かつこれらの変数が値2をもつ 場合には、番号が1と2のバックアップは古いバージョンとして保持されて、番号 が5と7のバックアップは新しいバージョンとして保持される。そして番号が3の バックアップは余分なバックアップとなる。関数‘find-backup-file-name’ (*note Backup Names::を参照)は、どのバージョンのバックアップを削除するか を決定する役目を負うが、この関数自身がバックアップを削除する訳ではない。 -- User Option: delete-old-versions この変数が‘t’なら、ファイルの保存により余分なバージョンのバックアッ プは暗黙に削除される。‘nil’なら余分なバックアップの削除前に確認を求 めるて、それ以外なら余分なバックアップは削除されないことを意味する 。 -- User Option: dired-kept-versions この変数はDired内のコマンド‘.’ (ピリオド。 ‘dired-clean-directory’)で、もっとも新しいバージョンのバックアップ をいくつ保持するかを指定する。これは新たにバックアップファイルを作 成する際に‘kept-new-versions’を指定するのと同等。デフォルトは2。 25.1.4 バックアップファイルの命名 --------------------------------- このセクションでは、主にバックアップファイルの命名規則を再定義してカスタ マイズできる関数を記載します。これらの1つを変更した場合には、おそらく残 りも変更する必要があります。 -- Function: backup-file-name-p filename この関数は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行目でバックスラッシュを使 用しているが、これはドキュメント文字列内で単一行を生成する)。 この単純な式はカスタマイズのための再定義を簡便にするために、個々の 関数内に配置されている。 -- Function: make-backup-file-name filename この関数はファイルFILENAMEの非番号付きバックアップファイル名として 使用される文字列をリターンする。Unixではこれは単にFILENAMEにチルダ を追加する。 ほとんどのオペレーティングシステムでは、この関数の標準的な定義は以 下のようになる: (defun make-backup-file-name (file) "FILEにたいして非番号付きバックアップファイル名を作成する" (concat file "~")) この関数を再定義することにより、バックアップファイルの命名規則を変 更できる。以下はチルダの追加に加えて、先頭に‘.’を追加するように ‘make-backup-file-name’を再定義する例: (defun make-backup-file-name (filename) (expand-file-name (concat "." (file-name-nondirectory filename) "~") (file-name-directory filename))) (make-backup-file-name "backups.texi") ⇒ ".backups.texi~" Diredコマンドのいくつかを含むEmacsの一部では、バックアップファイル 名が‘~’で終わることを仮定している。この規則にしたがわない場合、深刻 な問題とはならないだろうが、それらのコマンドが若干好ましくない結果 をもたらすかもしれない。 -- Function: find-backup-file-name filename この関数はFILENAMEの新たなバックアップファイル用のファイル名を計算 する。これは特定の既存バックアップファイルにたいする削除の提案も行 うかもしれない。‘find-backup-file-name’はCARが新たなバックアップフ ァイル名、CDRが削除を提案するバックアップファイルのリストであるよう なリストをリターンする。値には‘nil’も指定でき、これはバックアップが 作成されないことを意味する。 ‘kept-old-versions’と‘kept-new-versions’の2つの変数は、どのバージョ ンのバックアップを保持するべきかを決定する。この関数は値のCDRから該 当するバージョンを除外することによってそれらを保持する。*note Numbered Backups::を参照のこと。 以下の例の値は新しいバックアップファイルに使用する名前が ‘~rms/foo.~5~’、‘~rms/foo.~3~’は呼び出し側が削除を検討するべき余分 なバージョンであることを示している。 (find-backup-file-name "~rms/foo") ⇒ ("~rms/foo.~5~" "~rms/foo.~3~") -- Function: file-newest-backup filename この関数はFILENAMEにたいするもっとも最近のバックアップファイル名、 バックアップファイルがなければ‘nil’をリターンする。 ファイル比較関数のいくつかは、自動的にもっとも最近のバックアップを 比較できるようにこの関数を使用している。 25.2 自動保存 ============= Emacsは、visitしているすべてのファイルを定期的に保存します。これは“自動 保存(auto-saving)”と呼ばれます。自動保存はシステムがクラッシュした場合に 失われる作業量を、一定の作業量以下にします。デフォルトでは自動保存は 300キーストロークごと、またはidleになった30秒後に発生します。自動保存に 関するユーザー向けの情報については*note Auto Save: (emacs)Auto Save.を参 照してください。ここでは自動保存の実装に使用される関数と、それらを制御す る変数について説明します。 -- Variable: buffer-auto-save-file-name このバッファーローカル変数はカレントバッファーの自動保存に使用され るファイル名。そのバッファーが自動保存されるべきでなければ‘nil’。 buffer-auto-save-file-name ⇒ "/xcssun/users/rms/lewis/#backups.texi#" -- Command: auto-save-mode arg これはバッファーローカルなマイナーモードであるAuto Saveモードにたい するモードコマンド。Auto Saveモードが有効なときはそのバッファーで自 動保存が有効。呼び出し方法は他のマイナーモードと同様(*note Minor Mode Conventions::を参照)。 ほとんどのマイナーモードと異なり‘auto-save-mode’変数は存在しない。 ‘buffer-auto-save-file-name’が非‘nil’で‘buffer-saved-size’(以下参照 )が非0ならAuto Saveモードが有効。 -- Function: auto-save-file-name-p filename この関数はFILENAMEがauto-saveファイルのような文字列なら非‘nil’をリ ターンする。先頭と末尾がハッシュマーク(‘#’)であるような名前は auto-saveファイルの可能性があるという、auto-saveファイルにたいする 通常の命名規則を想定する。引数FILENAMEはディレクトリーパートを含ま ないこと。 (make-auto-save-file-name) ⇒ "/xcssun/users/rms/lewis/#backups.texi#" (auto-save-file-name-p "#backups.texi#") ⇒ 0 (auto-save-file-name-p "backups.texi") ⇒ nil この関数の標準的な定義は、以下のようになる: (defun auto-save-file-name-p (filename) "FILENAMEが以下を満たすなら非nilをリターンする" (string-match "^#.*#$" filename)) この関数はauto-saveファイルの命名規則規則を変更したいときにカスタマ イズできるようにするために存在する。これを再定義するなら、それに対 応して関数‘make-auto-save-file-name’も忘れずに再定義すること。 -- Function: make-auto-save-file-name この関数はカレントバッファーの自動保存に使用されるファイル名をリタ ーンする。これはファイル名の先頭と末尾にハッシュマーク(‘#’)を単に追 加する。この関数は変数‘auto-save-visited-file-name’(以下参照)を調べ ない。呼び出し側はまずその変数をチェックすること。 (make-auto-save-file-name) ⇒ "/xcssun/users/rms/lewis/#backups.texi#" 以下はこの関数の標準的な定義の簡略版: (defun make-auto-save-file-name () "カレントバッファーの自動保存に使用される\ ファイル名をリターンする" (if buffer-file-name (concat (file-name-directory buffer-file-name) "#" (file-name-nondirectory buffer-file-name) "#") (expand-file-name (concat "#%" (buffer-name) "#")))) auto-saveファイルの命名規則をカスタマイズして再定義できるように、こ れは独立した関数として存在している。ただしこれに対応した方法で ‘auto-save-file-name-p’も忘れずに変更すること。 -- User Option: auto-save-visited-file-name この変数が非‘nil’ならEmacsはvisit中のファイルにバッファーを自動保存 する。つまり自動保存は編集中ファイルと同じファイルにたいして行われ る。この変数は通常は‘nil’なので、auto-saveファイルは ‘make-auto-save-file-name’で作成された別の名前をもつ。 この変数の値を変更した際、バッファー内でauto-saveモードを再度有効に するまで、既存バッファーにたいして新たな値は効果をもたない。すでに auto-saveモードが有効なら、再度‘auto-save-mode’が呼び出されるまで同 じファイルに自動保存が行われる。 -- Function: recent-auto-save-p この関数はカレントバッファーが最後に読み込み、または保存されて以降 に自動保存されていれば‘t’をリターンする。 -- Function: set-buffer-auto-saved この関数はカレントバッファーを自動保存済みとマークする。そのバッフ ァーは、バッファーテキストが再度変更されるまで自動保存されないだろ う。この関数は‘nil’をリターンする。 -- User Option: auto-save-interval この変数の値は自動保存の頻度を入力イベント数で指定する。この分の入 力イベント読み取りごとに、Emacsは自動保存が有効なすべてのバッファー にたいして自動保存を行う。これを0にするとタイプした文字数にもとづい た自動保存は無効になる。 -- User Option: auto-save-timeout この変数の値は自動保存が発生すべきidle時間の秒数。この秒数分ユーザ ーが休止するたびに、Emacsは自動保存が有効なすべてのバッファーにたい して自動保存を行う(カレントバッファーが非常に大きければ、指定された タイムアウトはサイズ増加とともに増加される因子で乗ぜられる。この因 子は1MBのバッファーにたいしておよそ4)。 値が0か‘nil’ならidle時間にもとづいた自動保存は行われず、 ‘auto-save-interval’で指定される入力イベント数の後のみ自動保存が行 われる。 -- Variable: auto-save-hook このノーマルフックは自動保存が行われようとするたびに毎回実行される 。 -- User Option: auto-save-default この変数が非‘nil’ならファイルをvisitするバッファーの自動保存がデフ ォルトで有効になり、それ以外では有効にならない。 -- Command: do-auto-save &optional no-message current-only この関数は自動保存される必要があるすべてのバッファーを自動保存する 。これは自動保存が有効なバッファーであり、かつ前回の自動保存以降に 変更されたすべてのバッファーを保存する。 いずれかのバッファーが自動保存される場合には、‘do-auto-save’は自動 保存が行われる間、通常はそれを示すメッセージ‘Auto-saving...’をエコ ーエリアに表示する。しかしNO-MESSAGEが非‘nil’ならこのメッセージは抑 制される。 CURRENT-ONLYが非‘nil’なら、カレントバッファーだけが自動保存される。 -- Function: delete-auto-save-file-if-necessary &optional force この関数は‘delete-auto-save-files’が非‘nil’ならカレントバッファーの auto-saveファイルを削除する。これはバッファー保存時に毎回呼び出され る。 この関数はFORCEが‘nil’なら最後に本当の保存が行われて以降、カレント Emacsセッションにより書き込まれたファイルだけを削除する。 -- User Option: delete-auto-save-files この変数は関数‘delete-auto-save-file-if-necessary’により使用される 。これが非‘nil’なら、Emacsは(visitされているファイルに)本当に保存が 行われたときにauto-saveファイルを削除する。これはディスク容量を節約 してディレクトリーを整理する。 -- Function: rename-auto-save-file この関数はvisitされているファイルの名前が変更されていればカレントバ ッファーのauto-saveファイルの名前を調整する。これはカレントEmacsセ ッションでauto-saveファイルが作成されていれば、既存のauto-saveファ イルのリネームも行う。visitされているファイルの名前が変更されていな ければ、この関数は何も行わない。 -- Variable: buffer-saved-size このバッファーローカル変数の値はカレントバッファーが最後に読み取り 、保存、または自動保存されたときのバッファーの長さ。これはサイズの 大幅な減少の検知に使用され、それに応じて自動保存がオフに切り替えら れる。 −1なら、それはサイズの大幅な減少によりそのバッファーの自動保存が一 時的に停止されていることを意味する。明示的な保存によりこの変数に正 の値が格納されて、自動保存が再び有効になる。自動保存をオフやオンに 切り替えることによってもこの変数は更新されるので、サイズの大幅な減 少は忘れられさられる。 −2なら、特にバッファーサイズの変更により一時的に自動保存を停止され ないように、そのバッファーがバッファーサイズの変更を無視することを 意味する。。 -- Variable: auto-save-list-file-name この変数は、(非‘nil’なら)すべてのauto-saveファイルの名前を記録する ファイルを指定する。Emacsが自動保存を行うたびには自動保存が有効な各 バッファーごとに2行ずつ書き込みを行う。1行目はvisitされているファイ ルの名前(ファイルをvisitしないバッファーの場合は空)、2行目は auto-saveファイルの名前を示す。 Emacsを正常にexitした際にこのファイルは削除される。Emacsがクラッシ ュした場合にはこのファイルを調べることにより、失われるはずだった作 業を含んだすべてのauto-saveファイルを探すことができる。 ‘recover-session’コマンドはそれらを見つけるためにこのファイルを使用 する。 このファイルにたいするデフォルト名は、ユーザーのホームディレクトリ ーにある‘.saves-’で始まるファイルを指定する。この名前にはEmacsのプ ロセスIDとホスト名も含まれる。 -- User Option: auto-save-list-file-prefix initファイルを読み込んだ後、(‘nil’にセット済みでなければ)Emacsはこ のプレフィックスにもとづいたホスト名とプロセスIDを追加して、 ‘auto-save-list-file-name’を初期化する。initファイル内でこれを ‘nil’にセットした場合には、Emacsは‘auto-save-list-file-name’を初期 化しない。 25.3 リバート ============= あるファイルにたいして大きな変更を行った後、気が変わって元に戻したくなっ た場合は、‘revert-buffer’コマンドでそのファイルの以前のバージョンを読み 込むことにより、それらの変更を取り消すことができます。詳細は、*note Reverting a Buffer: (emacs)Reverting.を参照してください。 -- Command: revert-buffer &optional ignore-auto noconfirm preserve-modes このコマンドはバッファーのテキストをディスク上の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’の置き換え 機能を使用することにより、バッファー内のマーカー位置の保持を試みる 。バッファーのコンテンツとファイルのコンテンツがリバート操作を行う 前と等しければリバートはすべてのマーカーを保持する。等しくなければ リバートによってバッファーは変更される。この場合は、(もしあれば)バ ッファーの最初と最後にある未変更のテキスト内にあるマーカーは保持さ れる。他のマーカーを保持してもそれらは正しくないだろう。 -- Variable: revert-buffer-in-progress-p ‘revert-buffer’は処理を行っている間、この変数を非‘nil’値にバインド する。 このセクションの残りの部分で説明する変数をセットすることにより、 ‘revert-buffer’が処理方法をカスタマイズできます。 -- User Option: revert-without-query この変数は問い合わせなしでリバートされるファイルのリストを保持する 。値は正規表現のリスト。visitされているファイルの名前がこれらの正規 表現のいずれかにマッチし、かつバッファーが未変更だがディスク上のフ ァイルは変更されていれば、‘revert-buffer’はユーザーに確認を求めるこ となくファイルをリバートする。 いくつかのメジャーモードは以下の変数をローカルにバインドすることによ り‘revert-buffer’をカスタマイズします: -- Variable: revert-buffer-function この変数の値はそのバッファーをリバートするために使用する関数。これ はリバート処理を行うために2つのオプション引数をとる関数であること。 2つのオプション引数IGNORE-AUTOとNOCONFIRMは‘revert-buffer’が受け取 る引数である。 Diredモードのような編集されるテキストにファイルのコンテンツが含まれ ず他の方式によって再生成され得るモードは、この変数のバッファーロー カル値にコンテンツを再生成する特別な関数を与えることができる。 -- Variable: revert-buffer-insert-file-contents-function この変数の値はそのバッファーをリバートする際に更新されたコンテンツ の挿入に使用される関数を指定する。その関数は2つの引数を受け取る。 1つ目は使用するファイル名で2つ目が‘t’なら、ユーザーはauto-saveファ イルの読み込みにたいして確認を求められる。 ‘revert-buffer-function’のかわりにこの変数をモードが変更する理由は 、‘revert-buffer’が行残りの処理(ユーザーへの確認、アンドゥリストの クリアー、適切なメジャーモードの決定、以下のフックの実行)にたいする 重複や置き換えを避けるためである。 -- Variable: before-revert-hook このノーマルフックは変更されたコンテンツを挿入する前に、デフォルト の‘revert-buffer-function’により実行される。カスタマイズした ‘revert-buffer-function’は、このフックを実行するかどうか判らない。 -- Variable: after-revert-hook このノーマルフックは変更されたコンテンツを挿入した後に、デフォルト の‘revert-buffer-function’によって実行される。カスタマイズした ‘revert-buffer-function’は、このフックを実行するかどうか判らない。 -- Variable: buffer-stale-function この変数の値は、バッファーがリバートを要するかどうかをチェックする ために呼び出される関数を指定する。デフォルト値では、修正時刻をチェ ックすることによってファイルをvisitするバッファーだけを処理する。フ ァイルをvisitしないバッファーにはカスタム関数が必要 (*note (emacs)Supporting additional buffers::を参照)。 26 バッファー ************* “バッファー(buffer)”とは編集されるテキストを含んだLispオブジェクトのこと です。バッファーはvisitされるファイルのコンテンツを保持するために使用さ れます。しかしファイルをvisitしないバッファーも存在します。一度に複数の バッファーが存在するかもしれませんが、“カレントバッファー(current buffer)”に指定できるのは常に1つのバッファーだけです。ほとんどの編集コマ ンドはカレントバッファーのコンテンツにたいして作用します。カレントバッフ ァーを含むすべてのバッファーは任意のウィンドウ内に表示されるときもあれば 、表示されない場合もあります。 26.1 バッファーの基礎 ===================== “バッファー(buffer)”とは編集されるテキストを含むLispオブジェクトのことで す。バッファーはvisitされるファイルのコンテンツを保持するために使用され ます。しかしファイルをvisitしないバッファーも存在します。一度に複数のバ ッファーが存在するかもしれませんが、“カレントバッファー(current buffer)”に指定できるのは常に1つのバッファーだけです。ほとんどの編集コマ ンドはカレントバッファーのコンテンツにたいして作用します。カレントバッフ ァーを含むすべてのバッファーは、いずれかのウィンドウ内に表示されるときも あるし、表示されない場合もあります。 Emacs編集におけるバッファーとは個別に名前をもち、編集可能なテキストを 保持するオブジェクトです。Lispプログラムにおけるバッファーはスペシャルデ ータ型として表されます。バッファーのコンテンツを拡張可能な文字列と考える ことができます。挿入と削除はバッファー内の任意の箇所で発生し得ます。 *note Text::を参照してください。 Lispのバッファーオブジェクトは多くの情報要素を含んでいます。これらの 情報のいくつかは変数を通じてプログラマーが直接アクセスできるのにたいして 、その他の情報は特殊な目的のための関数を通じてのみアクセスすることができ ます。たとえばvisitされているファイルの名前は変数を通じて直接アクセスで きますが、ポイント値はプリミティブ関数からのみアクセスできます。 直接アクセス可能なバッファー固有の情報は、“バッファーローカル (buffer-local)”な変数バインディング内に格納されます。これは特定のバッフ ァー内だけで効力のある変数値のことです。この機能により、それぞれのバッフ ァーは特定の変数の値をオーバーライドすることができます。ほとんどのメジャ ーモードはこの方法で‘fill-column’や‘comment-column’のような変数をオーバ ーライドしています。バッファーローカルな変数、およびそれらに関連する関数 についての詳細は*note Buffer-Local Variables::を参照してください。 バッファーからファイルをvisitする関数および変数については*note Visiting Files::と*note Saving Buffers::を参照してください。ウィンドウ内 へのバッファー表示に関連する関数および変数については*note Buffers and Windows::を参照してください。 -- Function: bufferp object この関数はOBJECTがバッファーなら‘t’、それ以外は‘nil’をリターンする 。 26.2 カレントバッファー ======================= 一般的に1つのEmacsセッション内には多くのバッファーが存在します。常にそれ らのうちの1つが“カレントバッファー(current buffer)”に指定されます。カレ ントバッファーとは、ほとんどの編集が行われるバッファーのことです。テキス トを調べたり変更するプリミティブのほとんどは暗黙にカレントバッファーにた いして処理を行います(*note Text::を参照)。 通常は選択されたウィンドウ内に表示されるバッファーがカレントバッファ ーですが、常にそうではありません。Lispプログラムはバッファーのコンテンツ を処理するために、スクリーン上に表示されているものを変更することなく任意 のバッファーを一時的にカレントに指定できます。カレントバッファーの指定に たいするもっとも基本的な関数は‘set-buffer’です。 -- Function: current-buffer この関数はカレントバッファーをリターンする。 (current-buffer) ⇒ # -- Function: set-buffer buffer-or-name この関数はBUFFER-OR-NAMEをカレントバッファーにする。 BUFFER-OR-NAMEは既存のバッファー、または既存のバッファーの名前でな ければならない。リターン値はカレントになったバッファー。 この関数はそのバッファーをどのウィンドウにも表示しないので、必然的 にユーザーはそのバッファーを見ることはできない。しかしLispプログラ ムはその後に、そのバッファーにたいして処理を行うことになるだろう。 編集コマンドがエディターコマンドループにリターンする際、Emacsは選択さ れたウィンドウ内に表示されているバッファーにたいして、自動的に ‘set-buffer’を呼び出します。これは混乱を防ぐためであり、これにより Emacsがコマンドを読み取るときにカーソルのあるバッファーが、コマンドを適 用されるバッファーになることが保証されます(*note Command Loop::を参照)。 したがって異なるバッファーを指示して切り替える場合には‘set-buffer’を使用 するべきではありません。これを行うためには*note Switching Buffers::で説 明されている関数を使用してください。 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’を通常の評価と同様に処理できます。 -- Special Form: save-current-buffer body... スペシャルフォーム‘save-current-buffer’はカレントバッファーの識別を 保存してBODYフォームを評価し、最後にそのバッファーをカレントにリス トアする。リターン値はBODY内の最後のフォームの値。‘throw’やエラーを 通じた異常exitの場合にもカレントバッファーはリストアされる(*note Nonlocal Exits::を参照)。 カレントとして使用されていたバッファーが‘save-current-buffer’による exit時にkillされていたら、当然それが再びカレントとなることはない。 かわりにexit直前にカレントバッファーが何であれ、それがカレントにな る。 -- Macro: with-current-buffer buffer-or-name body... ‘with-current-buffer’マクロはカレントバッファーの識別を保存して BUFFER-OR-NAMEをカレントにし、BODYフォームを評価してから最後にカレ ントバッファーをリストアする。BUFFER-OR-NAMEには既存のバッファー、 または既存のバッファー名を指定しなければならない。 リターン値はBODY内の最後のフォームの値。‘throw’やエラーを通じた異常 exitの場合にも、カレントバッファーはリストアされる(*note Nonlocal Exits::を参照)。 -- Macro: with-temp-buffer body... ‘with-temp-buffer’マクロは一時的なバッファーをカレントバッファーと してBODYフォームを評価する。これはカレントバッファーの識別を保存し て一時的なバッファーを作成、それをカレントとしてBODYフォームを評価 して、一時バッファーをkillする間に以前のカレントバッファーをリスト アする。デフォルトではこのマクロにより作成されたバッファー内のアン ドゥ情報(*note Undo::を参照)は記録されない(が必要ならBODYでそれを有 効にできる)。 リターン値はBODY内の最後のフォームの値。最後のフォームとして ‘(buffer-string)’を使用することにより、一時バッファーのコンテンツを リターンできる。 ‘throw’やエラーを通じた異常exitの場合にも、カレントバッファーはリス トアされる(*note Nonlocal Exits::を参照)。 *note Writing to Files: Definition of with-temp-file.の ‘with-temp-file’も参照のこと。 26.3 バッファーの名前 ===================== それぞれのバッファーは文字列で表される一意な名前をもちます。バッファーに たいして機能する関数の多くは、引数としてバッファーとバッファー名の両方を 受け入れます。BUFFER-OR-NAMEという名前の引数がこのタイプであり、それが文 字列でもバッファーでもなければエラーがシグナルされます。BUFFERという名前 の引数は名前ではなく実際のバッファーオブジェクトでなければなりません。 短命でユーザーが関心をもたないようなバッファーは名前がスペースで始ま り、それらについては‘list-buffers’と‘buffer-menu’コマンドは無視します(が ファイルをvisitしているようなバッファーは*無視されない*)。スペースで始ま る名前は初期状態ではアンドゥ情報の記録も無効になっています。*note Undo::を参照してください。 -- Function: buffer-name &optional buffer この関数はBUFFERの名前を文字列としてリターンする。BUFFERのデフォル トはカレントバッファー。 ‘buffer-name’が‘nil’をリターンした場合、それはBUFFERがkillされてい ることを意味する。*note Killing Buffers::を参照のこと。 (buffer-name) ⇒ "buffers.texi" (setq foo (get-buffer "temp")) ⇒ # (kill-buffer foo) ⇒ nil (buffer-name foo) ⇒ nil foo ⇒ # -- Command: rename-buffer newname &optional unique この関数はカレントバッファーをNEWNAMEにリネームする。NEWNAMEが文字 列でなければエラーをシグナルする。 NEWNAMEがすでに使用済みなら、‘rename-buffer’は通常はエラーをシグナ ルする。しかしUNIQUEが非‘nil’なら、未使用の名前となるように NEWNAMEを変更する。interactiveに呼び出した場合は、プレフィックス数 引数によりUNIQUEに非‘nil’を指定できる(この方法によってコマンド ‘rename-uniquely’は実装される)。 この関数は実際にバッファーに与えられた名前をリターンする。 -- Function: get-buffer buffer-or-name この関数はBUFFER-OR-NAMEで指定されたバッファーをリターンする。 BUFFER-OR-NAMEが文字列で、かつそのような名前のバッファーが存在しな ければ値は‘nil’。BUFFER-OR-NAMEがバッファーなら与えられたバッファー をリターンする。これは有用とは言い難く、引数は通常は名前である。た とえば: (setq b (get-buffer "lewis")) ⇒ # (get-buffer b) ⇒ # (get-buffer "Frazzle-nots") ⇒ nil *note Creating Buffers::の関数‘get-buffer-create’も参照のこと。 -- Function: generate-new-buffer-name starting-name &optional ignore この関数は新たなバッファーにたいして一意となるような名前をリターン する — がバッファーは作成しない。この名前は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>" *note Creating Buffers::の関連する関数‘generate-new-buffer’も参照の こと。 26.4 バッファーのファイル名 =========================== “バッファーファイル名(buffer file name)”とは、そのバッファーにvisitされ ているファイルの名前です。バッファーがファイルをvisitしていなければ、バ ッファーファイル名は‘nil’です。バッファー名は大抵はバッファーファイル名 の非ディレクトリーパートと同じですが、バッファーファイル名とバッファー名 は別物であり個別にセットすることができます。*note Visiting Files::を参照 してください。 -- Function: buffer-file-name &optional buffer この関数はBUFFERがvisitしているファイルの絶対ファイル名をリターンす る。BUFFERがファイルをvisitしていなければ、‘buffer-file-name’は ‘nil’をリターンする。BUFFERが与えられない場合のデフォルトはカレント バッファー。 (buffer-file-name (other-buffer)) ⇒ "/usr/user/lewis/manual/files.texi" -- Variable: buffer-file-name このバッファーローカル変数はカレントバッファーにvisitされているファ イルの名前、ファイルをvisitしていなければ‘nil’。これは永続的なロー カル変数であり‘kill-all-local-variables’の影響を受けない。 buffer-file-name ⇒ "/usr/user/lewis/manual/buffers.texi" 他のさまざまな事項を変更せずにこの変数を変更するのは危険である。通 常は‘set-visited-file-name’を使用するほうがよい(以下参照)。バッファ ー名の変更などのような、そこで行われることのいくつかは絶対必要とい う訳ではないが、その他の事項はEmacsが混乱するのを防ぐために必要不可 欠である。 -- Variable: buffer-file-truename このバッファーローカル変数はカレントバッファーにvisitされているファ イルの省略された形式の実名(truename)、ファイルをvisitしていなければ ‘nil’を保持する。これは永続的にローカルであり ‘kill-all-local-variables’の影響を受けない。*Note Truenames::と *note abbreviate-file-name::を参照のこと。 -- Variable: buffer-file-number このバッファーローカル変数はカレントバッファーにvisitされているファ イルのファイル番号(file number)とデバイス番号(device number)、ファ イルをvisitしていなければ‘nil’を保持する。これは永続的にローカルで あり‘kill-all-local-variables’の影響を受けない。 値は通常は‘(FILENUM DEVNUM)’のような形式のリスト。この番号ペアはシ ステム上でアクセス可能なすべてのファイルの中からファイルを一意に識 別する。より詳細な情報は*note File Attributes::の ‘file-attributes’を参照のこと。 ‘buffer-file-name’がシンボリックリンク名なら、いずれの番号も再帰的 なターゲットを参照する。 -- Function: get-file-buffer filename この関数はファイルFILENAMEをvisitしているバッファーをリターンする。 そのようなバッファーが存在しなければ‘nil’をリターンする。引数 FILENAMEは文字列でなければならず、展開(*note File Name Expansion::を 参照)された後に、killされていないすべてのバッファーがvisitしている ファイル名と比較される。バッファーの‘buffer-file-name’はFILENAMEの 展開形と正確にマッチしなければならないことに注意。この関数は同じフ ァイルにたいする他の名前は認識しないだろう。 (get-file-buffer "buffers.texi") ⇒ # 特殊な状況下では、複数のバッファーが同じファイル名をvisitすることが あり得る。そのような場合には、この関数はバッファーリスト内の最初に 該当するバッファーをリターンする。 -- Function: find-buffer-visiting filename &optional predicate これは‘get-file-buffer’と似ているが、そのファイルを_違う名前_で visitしているかもしれないすべてのバッファーをリターンする。つまりバ ッファーの‘buffer-file-name’はFILENAMEの展開形式と正確にマッチする 必要はなく、同じファイルを参照することだけが要求される。PREDICATEが 非‘nil’なら、それはFILENAMEをvisitしているバッファーを1つの引数とす る関数であること。そのバッファーにたいしてPREDICATEが非‘nil’をリタ ーンした場合のみ適切なリターン値と判断される。リターンすべき適切な バッファーが見つからなければ、‘find-buffer-visiting’は‘nil’をリター ンする。 -- Command: set-visited-file-name filename &optional no-query along-with-file 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’が報告する時刻(*note Modification Time::を参照)で変更することもしない。ALONG-WITH-FILEが ‘nil’なら、この関数は‘visited-file-modtime’が0をリターンした後に、 記録済みの最終ファイル変更時刻をクリアーする。 関数‘set-visited-file-name’がinteractiveに呼び出されたときはミニバ ッファー内でFILENAMEの入力を求める。 -- Variable: list-buffers-directory このバッファーローカル変数はvisitしているファイル名をもたないバッフ ァーにたいして、バッファーリスト中のvisitしているファイル名を表示す る場所に表示する文字列を指定する。Diredバッファーはこの変数を使用す る。 26.5 バッファーの変更 ===================== Emacsは各バッファーにたいしてバッファーのテキストを変更したかどうかを記 録するために、“変更フラグ(modified flag)”と呼ばれるフラグを管理していま す。このフラグはバッファーのコンテンツを変更すると常に‘t’にセットされ、 バッファーを保存したとき‘nil’にクリアーされます。したがってこのフラグは 保存されていない変更があるかどうかを表します。フラグの値は通常はモードラ イン内(*note Mode Line Variables::を参照)に表示され、保存(*note Saving Buffers::を参照)と自動保存(*note Auto-Saving::を参照)を制御します。 いくつかのLispプログラムは、このフラグを明示的にセットします。たとえ ば、関数‘set-visited-file-name’は、このフラグを‘t’にセットします。なぜな ら、たとえその前にvisitしていたファイルが変更されていなくても、テキスト は新たにvisitされたファイルとマッチしないからです。 バッファーのコンテンツを変更する関数は*note Text::で説明されています 。 -- Function: buffer-modified-p &optional buffer この関数はバッファーBUFFERが最後にファイルから読み込まれたか、ある いは保存されてから変更されていれば‘t’、それ以外では‘nil’をリターン する。BUFFERが与えられなければカレントバッファーがテストされる。 -- Function: set-buffer-modified-p flag この関数はFLAGが非‘nil’ならカレントバッファーを変更済みとして、 ‘nil’なら未変更としてマークする。 この関数を呼び出すことによる別の効果は、それがカレントバッファーの モードラインの無条件な再表示を引き起こすことである。実際のところ関 数‘force-mode-line-update’は以下を行うことにより機能する: (set-buffer-modified-p (buffer-modified-p)) -- Function: restore-buffer-modified-p flag ‘set-buffer-modified-p’と同様だがモードラインにたいする強制的な再表 示を行わない点が異なる。 -- Command: not-modified &optional arg このコマンドはカレントバッファーが変更されておらず保存する必要がな いとマークする。ARGが非‘nil’なら変更されているとマークするので、次 回の適切なタイミングでバッファーは保存されるだろう。interactiveに呼 び出された場合には、ARGはプレフィックス引数。 この関数はエコーエリア内にメッセージをプリントするのでプログラム内 で使用してはならない。かわりに‘set-buffer-modified-p’ (上述)を使用 すること。 -- Function: buffer-modified-tick &optional buffer この関数はBUFFERの変更カウント(modification-count)をリターンする。 これはバッファーが変更されるたびに増加されるカウンター。BUFFERが ‘nil’ (または省略)ならカレントバッファーが使用される。このカウンタ ー0にラップアラウンド(wrap around: 最初に戻る )され得る。 -- Function: buffer-chars-modified-tick &optional buffer この関数はBUFFERの文字変更に関わる変更カウントをリターンする。テキ ストプロパティを変更してもこのカウンターは変化しない。しかしそのバ ッファーにテキストが挿入または削除されるたびに、このカウンターは ‘buffer-modified-tick’によりリターンされるであろう値にリセットされ る。‘buffer-chars-modified-tick’を2回呼び出してリターンされる値を比 較することにより、その呼び出しの間にバッファー内で文字変更があった かどうかを知ることができる。BUFFERが‘nil’ (または省略)ならカレント バッファーが使用される。 26.6 バッファーの変更 Time ========================== あるファイルをvisitしてそのバッファー内で変更を行い、その一方ではディス ク上でファイル自身が変更されたとします。この時点でバッファーを保存すると ファイル内の変更は上書きされるでしょう。これが正に望んでいる動作のときも ありますが、通常は有用な情報が失われてしまいます。したがってEmacsはファ イルを保存する前に、以下で説明する関数を使用してファイルの変更時刻をチェ ックします(ファイルの変更時刻を調べる方法は*note File Attributes::を参照 )。 -- Function: verify-visited-file-modtime &optional buffer この関数は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’をリターンする。 -- Function: clear-visited-file-modtime この関数はカレントバッファーによりvisitされているファイルの最終変更 時刻の記録をクリアーする。結果としてこのバッファーにを次回の保存で はファイルの変更時刻の食い違いは報告されなくなる。 この関数は‘set-visited-file-name’、および変更済みファイルの上書きを 防ぐための通常テストを行わない例外的な箇所で呼び出される。 -- Function: visited-file-modtime この関数はカレントバッファーにたいして記録された最終ファイル変更時 刻を‘(HIGH LOW MICROSEC PICOSEC)’のような形式のリストでリターンする (これは‘file-attributes’が時刻値をリターンするために使用するフォー マットと同じ。*note File Attributes::を参照)。 バッファーが最終変更時刻の記録をもたなければこの関数は0をリターンす る。これが発生するのは、たとえばバッファーがファイルをvisitしていな かったり、‘clear-visited-file-modtime’で最終変更時刻が明示的にクリ アーされた場合。しかし‘visited-file-modtime’は、いくつかの非ファイ ルバッファーにたいするリストをリターンすることに注意。たとえばディ レクトリーをリストするDiredバッファーでは、Diredが記録するそのディ レクトリーの最終変更時刻がリターンされる。 バッファーがファイルをvisitしていなければ、この関数は-1をリターンす る。 -- Function: set-visited-file-modtime &optional time この関数はバッファーがvisitしているファイルの最終変更時刻の記録を、 TIMEが非‘nil’ならTIME、それ以外はvisitしているファイルの最終変更時 刻に更新する。 TIMEが‘nil’や0でなければ、それは‘current-time’で使用される形式 ‘(HIGH LOW MICROSEC PICOSEC)’というフォーマットであること(*note Time of Day::を参照)。 この関数はバッファーが通常のようにファイルから読み取られたものでな い場合や、ファイル自身が害のない既知の理由により変更されている場合 に有用。 -- Function: ask-user-about-supersession-threat filename これはvisitしているファイルFILENAMEがバッファーのテキストより新しい ときにバッファーの変更を試みた後、ユーザーに処理方法を尋ねるために 使用する関数。Emacsはディスク上のファイルの変更時刻が、バッファーを 最後に保存した時刻より新しいかどうかでこれを検知する。これはおそら く他のプログラムがそのファイルを変更したことを意味する。 この関数が正常にリターンするかどうかは、ユーザーの応答に依存する。 関数はバッファーの変更が処理された場合は正常にリターンし、バッファ ーの変更が許可されなかった場合はデータ‘(FILENAME)’とともにエラー ‘file-supersession’をシグナルする。 この関数は適切なタイミングでEmacsにより自動的に呼び出される。これは 再定義することによりEmacsをカスタマイズ可能にするために存在する。標 準的な定義はファイル‘userlock.el’を参照のこと。 *note File Locks::のファイルロックのメカニズムも参照されたい。 26.7 読み取り専用のバッファー ============================= あるバッファーが“読み取り専用(read-only)”の場合には、たとえスクロールや ナローイングによってファイルのコンテンツのビューを変更しても、そのコンテ ンツを変更することはできません。 読み取り専用バッファーは、2つのタイプの状況において使用されます: • 書き込み保護されたファイルをvisitするバッファーは、通常は読み取り専 用になる。 ここでの目的はユーザーにたいしてそのファイルへの保存を意図したバッ ファーの編集が無益、または望ましくないかもしれないことを伝えること である。それにも関わらずバッファーのテキストの変更を望むユーザーは 、‘C-x C-q’で読み取り専用フラグをクリアーした後にこれを行うことがで きる。 • DiredやRmailのようなモードは、通常の編集コマンドによるコンテンツの 変更がおそらく間違いであるようなときにバッファーを読み取り専用にす る。 このようなモードのスペシャルコマンドは、‘buffer-read-only’を (‘let’によって)‘nil’にバインドしたり、テキストを変更する箇所では ‘inhibit-read-only’を‘t’にバインドする。 -- Variable: buffer-read-only このバッファーローカル変数は、そのバッファーが読み取り専用かどうか を指定する。この変数が非‘nil’ならそのバッファーは読み取り専用。しか しテキストプロパティ‘inhibit-read-only’をもつ文字は依然として編集可 能。*note inhibit-read-only: Special Properties.を参照のこと。 -- Variable: inhibit-read-only この変数が非‘nil’なら、読み取り専用バッファー、およびその実際の値に 依存して、一部もしくはすべての読み取り専用文字が変更されている。バ ッファー内の読み取り専用文字とはテキストプロパティ‘read-only’が非 ‘nil’の文字。テキストプロパティについての詳細は*note Special Properties::を参照のこと。 ‘inhibit-read-only’が‘t’なら、すべての‘read-only’文字プロパティは効 果がなくなる。‘inhibit-read-only’がリストの場合には、‘read-only’文 字プロパティがリストのメンバーなら効果がなくなる(比較は‘eq’で行われ る)。 -- Command: read-only-mode &optional arg これはバッファーローカルなマイナーモードRead Onlyモードにたいするモ ードコマンド。このモードが有効なときは、そのバッファーの ‘buffer-read-only’は非‘nil’。無効なときは、そのバッファーの ‘buffer-read-only’は‘nil’。呼び出す際の慣習は、他のマイナーモードコ マンドの慣習と同じ(*note Minor Mode Conventions::を参照)。 このマイナーモードは他のマイナーモードとは異なり、主に ‘buffer-read-only’にたいするラッパーの役目を果たし、別個に ‘read-only-mode’変数は存在しない。Read Onlyモードが無効なときでも、 ‘read-only’テキストプロパティが非‘nil’の文字は読み取り専用のままで ある。一時的にすべての読み取り専用ステータスを無視するには上述の ‘inhibit-read-only’をバインドすること。 Read Onlyモードを有効にする際、このモードコマンドはオプション ‘view-read-only’が非‘nil’ならViewモードも有効にする。*note Miscellaneous Buffer Operations: (emacs)Misc Buffer.を参照のこと。 Read Onlyモードを無効にする際に、もしもViewモードが有効ならViewモー ドも無効にする。 -- Function: barf-if-buffer-read-only &optional position この関数はカレントバッファーが読み取り専用なら‘buffer-read-only’エ ラーをシグナルする。POSITION (デフォルトはポイント位置)のテキストの テキストプロパティ‘inhibit-read-only’がセットされていればエラーは発 生しないだろう。 カレントバッファーが読み取り専用の場合にエラーをシグナルする他の方 法については、*note Using Interactive::を参照のこと。 26.8 バッファーリスト ===================== “バッファーリスト(buffer list)”とは、すべての生きた(killされていない)バ ッファーのリストです。このリスト内のバッファーの順序は主に、それぞれのバ ッファーがウィンドウに表示されたのがどれほど最近なのかにもとづきます。い くつかの関数、特に‘other-buffer’はこの順序を使用します。ユーザーに表示さ れるバッファーリストもこの順序にしたがいます。 バッファーを作成するとそれはバッファーリストの最後に追加され バッファ ーをkillすることによってそのリストから削除されます。ウィンドウに表示する ためにバッファーが選択されたとき(*note Switching Buffers::を参照)、ある いはバッファーを表示するウィンドウが選択されたとき(*note Selecting Windows::を参照)、そのバッファーは常にこのリストの先頭に移動します。バッ ファーがバリー(以下の‘bury-buffer’を参照)されたときは、このリストの最後 に移動します。バッファーリストを直接操作するために利用できるLispプログラ マー向けの関数は存在しません。 説明した基本バッファーリスト(fundamental buffer list)に加えて、 Emacsはそれぞれのフレームにたいしてローカルバッファーリスト(local buffer list)を保守します。ローカルバッファーリストでは、そのフレーム内で表示さ れていた(または選択されたウィンドウの)バッファーが先頭になります(この順 序はそのフレームのフレームパラメーター‘buffer-list’に記録される。*note Buffer Parameters::を参照)。並び順は基本バッファーリストにならい、そのフ レームでは表示されていないフレームは後になになります。。 -- Function: buffer-list &optional frame この関数はすべてのバッファーを含むバッファーリストをリターンする(名 前がスペースで始まるバッファーも含む)。リストの要素はバッファーの名 前ではなく実際のバッファー。 FRAMEがフレームなら、FRAMEのローカルバッファーリストをリターンする 。FRAMEが‘nil’か省略された場合は、基本バッファーリストが使用される 。その場合には、そのバッファーを表示するフレームがどれかとは無関係 に、もっとも最近に表示または選択されたバッファーの順になる。 (buffer-list) ⇒ (# # # # #) ;; ミニバッファーの名前が ;; スペースで始まることに注意! (mapcar (function buffer-name) (buffer-list)) ⇒ ("buffers.texi" " *Minibuf-1*" "buffer.c" "*Help*" "TAGS") ‘buffer-list’からリターンされるリストはそれ専用に構築されたリストであ って、Emacsの内部的なデータ構造ではなく、それを変更してもバッファーの並 び順に影響はありません。基本バッファーリスト内のバッファーの並び順を変更 したい場合に簡単なのは以下の方法です: (defun reorder-buffer-list (new-list) (while new-list (bury-buffer (car new-list)) (setq new-list (cdr new-list)))) この方法により、バッファーを失ったり有効な生きたバッファー以外の何か を追加する危険を犯さずにリストに任意の並び順を指定できます。 特定のフレームのバッファーリストの並び順や値を変更するには、 ‘modify-frame-parameters’でそのフレームの‘buffer-list’パラメーターをセッ トしてください(*note Parameter Access::を参照)。 -- Function: other-buffer &optional buffer visible-ok frame この関数はバッファーリスト中でBUFFER以外の最初のバッファーをリター ンする。これは通常は選択されたウィンドウ(フレームFRAME、または選択 されたフレーム(*note Input Focus::を参照)にもっとも最近表示された BUFFER以外のバッファーである。名前がスペースで始まるバッファーは考 慮されない。 BUFFERが与えられない(または生きたバッファーでない)場合には、 ‘other-buffer’は選択されたフレームのローカルバッファーリスト内の最 初のバッファーをリターンする(FRAMEが非‘nil’ならFRAMEのローカルバッ ファーリスト内の最初のバッファーをリターンする)。 FRAMEが非‘nil’の‘buffer-predicate’パラメーターをもつ場合には、どの バッファーを考慮すべきかを決定するために‘other-buffer’はその述語を 使用する。これはそれぞれのバッファーごとにその述語を一度呼び出して 、値が‘nil’ならそのバッファーは無視される。*note Buffer Parameters::を参照のこと。 VISIBLE-OKが‘nil’なら‘other-buffer’はやむを得ない場合を除き、任意の 可視のフレーム上のウィンドウ内で可視のバッファーをリターンすること を避ける。VISIBLE-OKが非‘nil’なら、バッファーがどこかで表示されてい るかどうかは問題にしない。 適切なバッファーが存在しなければ、バッファー‘*scratch*’を(必要なら 作成して)リターンする。 -- Function: last-buffer &optional buffer visible-ok frame この関数はFRAMEのバッファーリスト内からBUFFER以外の最後のバッファー をリターンする。FRAMEが省略または‘nil’なら選択されたフレームのバッ ファーリストを使用する。 引数VISIBLE-OKは上述した‘other-buffer’と同様に扱われる。適切なバッ ファーを見つけられなければバッファー‘*scratch*’がリターンされる。 -- Command: bury-buffer &optional buffer-or-name このコマンドはバッファーリスト内の他のバッファーの並び順を変更する ことなく、BUFFER-OR-NAMEをバッファーリストの最後に配置する。つまり このバッファーは‘other-buffer’がリターンする候補でもっとも期待度が 低くなる。引数はバッファー自身かバッファーの名前を指定できる。 この関数は基本バッファーリストと同様にそれぞれのフレームの ‘buffer-list’パラメーターを操作する。したがってバリー(bury: 埋める 、隠す)したバッファーは、‘(buffer-list FRAME)’や‘(buffer-list)’の値 の最後に置かれるだろう。さらにそのバッファーが選択されたウィンドウ に表示されていれば、そのウィンドウのバッファーリストの最後にバッフ ァーを配置することも行う(*note Window History::を参照)。 BUFFER-OR-NAMEが‘nil’または省略された場合には、カレントバッファーを バリーすることを意味する。加えてカレントバッファーが選択されたウィ ンドウに表示されていれば、そのウィンドウを削除するか他のバッファー を表示する。より正確には選択されたウィンドウが専用(dedicated)のウィ ンドウ(*note Dedicated Windows::)であり、かつそのフレーム上に他のウ ィンドウが存在する場合には専用ウィンドウは削除される。それがフレー ム上で唯一のウィンドウであり、かつそのフレームが端末上で唯一のフレ ームでなければ、そのフレームは‘frame-auto-hide-function’で指定され る関数を呼び出すことにより開放される(*note Quitting Windows::を参照 )。それ以外の場合はに、他のバッファーをそのウィンドウ内に表示するた めに‘switch-to-prev-buffer’を呼び出す(*note Window History::を参照 )。BUFFER-OR-NAMEが他のウィンドウで表示されていれば、そのまま表示さ れ続ける。 あるバッファーにたいして、それを表示するすべてのウィンドウでバッフ ァーを置き換えるには‘replace-buffer-in-windows’を使用する。*note Buffers and Windows::を参照のこと。 -- Command: unbury-buffer このコマンドは選択されたフレームのローカルバッファーリストの最後の バッファーに切り替える。より正確には選択されたウィンドウ内で、 ‘last-buffer’ (上記参照)がリターンするバッファーを表示するために関 数‘switch-to-buffer’を呼び出す(*note Switching Buffers::を参照)。 -- Variable: buffer-list-update-hook これはバッファーリストが変更されたときに常に実行されるノーマルフッ ク。(暗黙に)このフックを実行する関数は‘get-buffer-create’ (*note Creating Buffers::を参照)、‘rename-buffer’ (*note Buffer Names::を 参照)、‘kill-buffer’ (*note Killing Buffers::を参照)、‘bury-buffer’ (上記参照)、‘select-window’ (*note Selecting Windows::を参照)。 26.9 バッファーの作成 ===================== このセクションではバッファーを作成する2つのプリミティブについて説明しま す。‘get-buffer-create’は指定された名前の既存バッファーが見つからなけれ ば作成します。‘generate-new-buffer’は常に新たにバッファーを作成してそれ に一意な名前を与えます。 バッファーを作成するために使用できる他の関数には ‘with-output-to-temp-buffer’ (*note Temporary Displays::を参照)、および ‘create-file-buffer’ (*note Visiting Files::を参照)が含まれます。サブプ ロセスの開始によってもバッファーを作成することができます(*note Processes::を参照)。 -- Function: get-buffer-create buffer-or-name この関数はBUFFER-OR-NAMEという名前のバッファーをリターンする。リタ ーンされたバッファーはカレントにならない — この関数はカレントがどの バッファーであるかを変更しない。 BUFFER-OR-NAMEは文字列、または既存バッファーのいずれかでなければな らない。これが文字列で、かつ既存の生きたバッファーの名前なら、 ‘get-buffer-create’はそのバッファーをリターンする。そのようなバッフ ァーが存在しなければ、新たにバッファーを作成する。BUFFER-OR-NAMEが 文字列ではなくバッファーなら、たとえそのバッファーが生きていなくて も与えられたバッファーをリターンする。 (get-buffer-create "foo") ⇒ # 新たに作成されたバッファーにたいするメジャーモードはFundamentalモー ドにセットされる(変数‘major-mode’のデフォルト値はより高いレベルで処 理される。*note Auto Major Mode::を参照)。名前がスペースで始まる場 合には、そのバッファーのアンドゥ情報の記録は初期状態では無効である (*note Undo::を参照)。 -- Function: generate-new-buffer name この関数は新たに空のバッファーを作成してリターンするが、それをカレ ントにはしない。バッファーの名前は関数‘generate-new-buffer-name’に NAMEを渡すことにより生成される(*note Buffer Names::を参照)。つまり NAMEという名前のバッファーが存在しなければ、それが新たなバッファー の名前になり、その名前が使用されていたら‘’という形式のサフィック スがNAMEに追加される。ここでNは整数。 NAMEが文字列でなければエラーがシグナルされる。 (generate-new-buffer "bar") ⇒ # (generate-new-buffer "bar") ⇒ #> (generate-new-buffer "bar") ⇒ #> 新たなバッファーにたいするメジャーモードはFundamentalモードにセット される。変数‘major-mode’のデフォルト値は、より高いレベルで処理され る。*note Auto Major Mode::を参照のこと。 26.10 バッファーのkill ====================== “バッファーのkill(Killing a buffer)”により、 そのバッファーの名前は Emacsにとって未知の名前となり、そのバッファーが占めていたメモリースペー スは他の用途に使用できるようになります。 バッファーに対応するバッファーオブジェクトは、それを参照するものがあ ればkillされても存在し続けますが、それをカレントにしたり表示することがで きないように特別にマークされます。とはいえkillされたバッファーの同一性は 保たれるので、2つの識別可能なバッファーをkillした場合には、たとえ両方死 んだバッファーであっても‘eq’による同一性は残ります。 あるウィンドウ内においてカレント、あるいは表示されているバッファーを killした場合、Emacsはかわりに他の何らかのバッファーを自動的に選択または 表示します。これはバッファーのkillによってカレントバッファーが変更される ことを意味します。したがってバッファーをkillする際には、(killされるバッ ファーがカレントを偶然知っていた場合を除き)カレントバッファーの変更に関 しても事前に注意を払うべきです。*note Current Buffer::を参照してください 。 1つ以上のインダイレクト バッファー(*note Indirect Buffers::を参照) の ベースとなるバッファーをkillした場合には、同様にインダイレクトバッファー も自動的にkillされます。 バッファーの‘buffer-name’が‘nil’の場合のみバッファーはkillされます。 killされていないバッファーは“生きた(live)”バッファーと呼ばれます。あるバ ッファーにたいして、そのバッファーが生きているか、またはkillされているか を確認するには‘buffer-live-p’を使用します(下記参照)。 -- Command: kill-buffer &optional buffer-or-name この関数はバッファーBUFFER-OR-NAMEをkillして、そのバッファーのメモ リーを他の用途のために開放、またはオペレーティングシステムに返却す る。BUFFER-OR-NAMEが‘nil’または省略された場合にはカレントバッファー をkillする。 そのバッファーを‘process-buffer’として所有するすべてのプロセスには 、通常はプロセスを終了させるシグナル‘SIGHUP’ (hangup)が送信される。 *note Signals to Processes::を参照のこと。 バッファーがファイルをvisitしていて、かつ保存されていない変更が含ま れる場合には、‘kill-buffer’はバッファーをkillする前にユーザーにたい して確認を求める。これは‘kill-buffer’がinteractiveに呼び出されてい なくても行われる。この確認要求を抑制するには‘kill-buffer’の呼び出し 前に、変更フラグ(modified flag)をクリアーすればよい。*note Buffer Modification::を参照のこと。 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 -- Variable: kill-buffer-query-functions 保存されていない変更について確認を求める前に、‘kill-buffer’はリスト ‘kill-buffer-query-functions’内の関数を出現順に引数なしで呼び出す。 それらが呼び出される際にはkillされるバッファーがカレントになる。こ の機能はこれらの関数がユーザーに確認を求めるというアイデアが元とな っている。これらの関数のいずれかが‘nil’をリターンしたら、 ‘kill-buffer’はそのバッファーを殺さない。 -- Variable: kill-buffer-hook これは尋ねることになっている質問をすべて終えた後、実際にバッファー をkillする直前に‘kill-buffer’により実行されるノーマルフック。この変 数は永続的にローカルであり、メジャーモードの変更により、そのローカ ルバインディングはクリアーされない。 -- User Option: buffer-offer-save 特定のバッファーにおいてこの変数が非‘nil’なら、 ‘save-buffers-kill-emacs’と‘save-some-buffers’ (この関数の2つ目のオ プション引数が‘t’の場合)は、ファイルをvisitしているバッファーと同じ ようにそのバッファーの保存を提案する。*note Definition of save-some-buffers::を参照のこと。何らかの理由により変数 ‘buffer-offer-save’をセットする際には自動的にバッファーローカルにな る。*note Buffer-Local Variables::を参照のこと。 -- Variable: buffer-save-without-query 特定のバッファーにおいてこの変数が非‘nil’なら、 ‘save-buffers-kill-emacs’と‘save-some-buffers’は、(バッファーが変更 されていれば)ユーザーに確認を求めることなくそのバッファーを保存する 。何らかの理由によりこの変数をセットする際には自動的にバッファーロ ーカルになる。 -- Function: buffer-live-p object この関数はOBJECTが生きたバッファー(killされていないバッファー)なら ‘t’、それ以外は‘nil’をリターンする。 26.11 インダイレクトバッファー ============================== “インダイレクトバッファー(indirect buffer: 間接バッファー)”とは、“ベース バッファー(base buffer)”と呼ばれる他のバッファーとテキストを共有します。 いくつかの点においてインダイレクトバッファーはファイル間でのシンボリック リンクに類似しています。ベースバッファー自身はインダイレクトバッファーで はない可能性があります。 インダイレクトバッファーのテキストは、常にベースバッファーのテキスト と同一です。編集により一方が変更されると、それは即座に他方のバッファーか ら可視になります。これには文字自体に加えてテキストプロパティも同様に含ま れます。 他のすべての観点において、インダイレクトバッファーとそのベースバッフ ァーは完全に別物です。それらは別の名前、独自のポイント値、ナローイング、 マーカー、オーバーレイ、メジャーモード、バッファーローカルな変数バインデ ィングをもちます(ただしどちらかのバッファーでのテキストの挿入や削除を行 うと両方のバッファーでマーカーとオーバーレイが再配置される)。 インダイレクトバッファーはファイルをvisitできませんがベースバッファー には可能です。インダイレクトバッファーの保存を試みると、実際にはベースバ ッファーが保存されます。 インダイレクトバッファーをkillしてもベースバッファーに影響はありませ ん。ベースバッファーをkillするとインダイレクトバッファーはkillされて再び カレントバッファーにすることはできません。 -- Command: make-indirect-buffer base-buffer name &optional clone これはベースバッファーがBASE-BUFFERであるような、NAMEという名前のイ ンダイレクトバッファーを作成してリターンする。引数BASE-BUFFERは生き たバッファー、または既存バッファーの名前(文字列)を指定できる。 NAMEが既存バッファーの名前ならエラーがシグナルされる。 CLONEが非‘nil’ならインダイレクトバッファーは最初はBASE-BUFFERのメジ ャーモード、マイナーモード、バッファーローカル変数等の状態を共有す る。CLONEが省略または‘nil’なら、インダイレクトバッファーの情報は新 たなバッファーにたいするデフォルト状態にセットされる。 BASE-BUFFERがインダイレクトバッファーなら、新たなバッファーのベース としてそれのベースバッファーが使用される。さらにCLONEが非‘nil’なら 、初期状態はBASE-BUFFERではなく実際のベースバッファーからコピーされ る。 -- Command: clone-indirect-buffer newname display-flag &optional norecord この関数はカレントバッファーのベースバッファーを共有するインダイレ クトバッファーを新たに作成して、カレントバッファーの残りの属性をコ ピーしてリターンする(カレントバッファーがインダイレクトバッファーで なければそれがベースバッファーとして使用される)。 DISPLAY-FLAGが非‘nil’なら、それは‘pop-to-buffer’を呼び出すことによ り新しいバッファーを表示することを意味する。NORECORDが非‘nil’なら、 それは新しいバッファーをバッファーリストの先頭に置かないことを意味 する。 -- Function: buffer-base-buffer &optional buffer この関数はBUFFER (デフォルトはカレントバッファー)のベースバッファー をリターンする。BUFFERがインダイレクトバッファーでなければ値は ‘nil’、それ以外では値は他のバッファーとなり、そのバッファーがインダ イレクトバッファーであることは決してない。 26.12 2つのバッファー間でのテキストの交換 ========================================= 特別なモードでは、ユーザーが同一のバッファーから複数の非常に異なったテキ ストにアクセスできるようにしなければならない場合があります。たとえばバッ ファーのテキストのサマリーを表示して、ユーザーがそのテキストにアクセスで きるようにする場合です。 これは、(ユーザーがテキストを編集した際には同期を保つ)複数バッファー や、ナローイング(*note Narrowing::を参照)により実装することができるかも しれません。しかしこれらの候補案はときに退屈になりがちであり、特にそれぞ れのテキストタイプが正しい表示と編集コマンドを提供するために高価なバッフ ァーグローバル操作を要求する場合には、飛び抜けて高価になる場合があります 。 Emacsはそのようなモードにたいして別の機能を提供します。 ‘buffer-swap-text’を使用すれば、2つのバッファー間でバッファーテキストを 素早く交換することができます。この関数はテキストの移動は行わずに異なるテ キスト塊(text chunk)をポイントするように、バッファーオブジェクトの内部的 なデータ構造だけを変更するため非常に高速です。これを使用することにより、 2つ以上のバッファーグループから個々のバッファーのコンテンツすべてを併せ もつような、単一の仮想バッファー(virtual buffer)が実在するように見せかけ ることができます。 -- Function: buffer-swap-text buffer この関数はカレントバッファーのテキストと、引数BUFFERのテキストを交 換する。2つのバッファーのいずれか一方がインダイレクトバッファー (*note Indirect Buffers::を参照)、またはインダイレクトバッファーの ベースバッファーの場合はエラーをシグナルする。 バッファーテキストに関連するすべてのバッファープロパティ、つまりポ イントとマークの位置、すべてのマーカーとオーバーレイ、テキストプロ パティ、アンドゥリスト、‘enable-multibyte-characters’フラグの値 (*note enable-multibyte-characters: Text Representations.を参照)等 も同様に交換される。 *警告:* この関数を‘save-excursion’内部で呼び出すと、位置とバッファ ーを保存するために‘save-excursion’が使用するマーカーも同様に交換さ れるので、そのフォームを抜ける際にはカレントバッファーはBUFFERにセ ットされるだろう。 ファイルをvisitしているバッファーに‘buffer-swap-text’を使用する場合に は、交換されたテキストではなくそのバッファーの元のテキストを保存するよう にフックをセットアップするべきです。‘write-region-annotate-functions’は 正にこの目的のために機能します。そのバッファーの‘buffer-saved-size’を、 おそらく交換されたテキストにたいする変更が自動保存に干渉しないであろう、 −2にセットするべきです。 26.13 バッファーのギャップ ========================== Emacsのバッファーは挿入と削除を高速にするために不可視の“ギャップ(gap)”を 使用して実装されています。挿入はギャップ部分を充填、削除はギャップを追加 することにより機能します。もちろんこれは最初にギャップを挿入や削除の部位 (locus)に移動しなければならないことを意味します。Emacsはユーザーが挿入か 削除を試みたときだけギャップを移動します。大きなバッファー内の遠く離れた 位置で編集した後に、他の箇所での最初の編集コマンドに無視できない遅延が発 生する場合があるのはこれが理由です。 このメカニズムは暗黙に機能するものであり、Lispコードはギャップのカレ ント位置に影響されるべきでは決してありませんが、以下の関数はギャップ状態 に関する情報の取得に利用できます。 -- Function: gap-position この関数はカレントバッファー内のギャップのカレント位置をリターンす る。 -- Function: gap-size この関数はカレントバッファー内のギャップのサイズをリターンする。 27 ウィンドウ ************* このチャプターではEmacsのウィンドウに関連する関数と変数について説明しま す。Emacsが利用可能なスクリーン領域にウィンドウが割り当てられる方法につ いては*note Frames::を参照してください。ウィンドウ内にテキストが表示され る方法についての情報は*note Display::を参照してください。 27.1 Emacsウィンドウの基本概念 ============================== “ウィンドウ(window)”とは任意のバッファーを表示するために使用されるスクリ ーン領域です。Emacs LispではウィンドウはスペシャルLispオブジェクトとして 表現されます。 ウィンドウはフレームへとグループ化されます(*note Frames::を参照)。そ れぞれのフレームは最低でも1つのウィンドウを含みます。ユーザーは複数のバ ッファーを一度に閲覧するために、それを複数のオーバーラップしないウィンド ウに分割することができます。Lispプログラムはさまざまな目的にたいして複数 のウィンドウを使用できます。たとえばRmailでは1つのウィンドウでメッセージ タイトル、もう一方のウィンドウで選択したメッセージのコンテンツを閲覧でき ます。 Emacsはグラフィカルなデスクトップ環境やX Window Systemのようなウィン ドウシステムとは異なる意味で“ウィンドウ(window)”という単語を使用します。 EmacsがX上で実行されているときはXのグラフィカルなXウィンドウは、Emacsで の(1つ以上のEmacsウィンドウを含んだ)フレームになります。Emacsがテキスト 端末上で実行されているときはフレームが端末スクリーン全体を占有します。 Xのウィンドウとは異なり、Emacsのウィンドウは“タイル表示(tiled)”される ので、フレームの領域内でオーバーラップされることは決してありません。ある ウィンドウが作成、リサイズ、削除されるとき変更されたウィンドウスペースの 変更は各ウィンドウの調整により取得・譲与されるので、そのフレームの総領域 に変化はありません。 -- Function: windowp object この関数はOBJECTがウィンドウ(バッファーの表示有無に関わらず)なら ‘t’、それ以外は‘nil’をリターンする。 “生きたウィンドウ(live window)”とは、あるフレーム内で実際にバッファー を表示しているウィンドウのことです。 -- Function: window-live-p object この関数はOBJECTが生きたウィンドウなら‘t’、それ以外は‘nil’をリター ンする。生きたウィンドウとはバッファーを表示するウィンドウのこと。 各フレーム内のウィンドウは“ウィンドウツリー(window tree)”内へと組織化 されます。*note Windows and Frames::を参照してください。それぞれのウィン ドウツリーのリーフノード(leaf nodes)は、実際にバッファーを表示している生 きたウィンドウです。ウィンドウツリーの内部ノード(internal node)は“内部ウ ィンドウ(internal windows)”と呼ばれ、これらは生きたウィンドウではありま せん。 “有効なウィンドウ(valid window)”とは、生きたウィンドウか内部ウィンド ウのいずれかです。有効なウィンドウにたいしては、それを“削除(delete)”、す なわちそのウィンドウのフレームから削除することができます(*note Deleting Windows::を参照)。その場合、それは有効なウィンドウではなくなりますが、そ れを表すLispオブジェクトは依然として他のLispオブジェクトから参照されたま まかもしれません。削除されたウィンドウは保存されたウィンドウ設定(window configuration)をリストアすることにより再び有効にすることができます(*note Window Configurations::を参照)。 ‘window-valid-p’により、削除されたウィンドウから有効なウィンドウを区 別できます。 -- Function: window-valid-p object この関数はOBJECTが生きたウィンドウかウィンドウツリー内の内部ウィン ドウなら‘t’をリターンする。それ以外(OBJECTが削除されたウィンドウの 場合も含む)は‘nil’をリターンする。 それぞれのフレーム内において、常にただ1つのEmacsウィンドウが“そのフレ ームで選択されている(selected within the frame)”ウィンドウとして指定され ます。選択されたフレームにたいして、そのウィンドウは“選択されたウィンド ウ(selected window)”と呼ばれます。選択されたウィンドウは編集のほとんどが 行われるウィンドウであり、カーソルはその選択されたウィンドウに表示されま す(*note Cursor Parameters::を参照)。選択されたウィンドウのバッファーは 、通常は‘set-buffer’が使用された場合を除きカレントバッファーでもあります (*note Current Buffer::を参照)。選択されていないフレームでは、そのフレー ムが選択されたときはそのフレームで選択されていたウィンドウが選択されたウ ィンドウになります。*note Selecting Windows::を参照してください。 -- Function: selected-window この関数は選択されたウィンドウをリターンする(これは常に生きたウィン ドウ)。 たとえばFollowモード(*note (emacs)Follow Mode::を参照)の管理下では、 あるウィンドウが単独で表示可能な部分より大きい部分をそのウィンドウにまと めて表示するように、複数のウィンドウが集合かつ協調してバッファーを表示す ることがあります。そのような“ウィンドウグループ(window group)”を1つのエ ンティティーとしてとらえると便利なことがよくあります。 ‘window-group-start’ (*note Window Start and End::を参照)のようないくつ かの関数では、グループ全体としてウィンドウの1つを引数に与えることにより 、これを行うことができます。 -- Function: selected-window-group 選択されたウィンドウがウィンドウグループのメンバーなら、この関数は そのバッファーの最前箇所を表示するウィンドウが先頭になる順序で、グ ループ内のウィンドウのリストをリターンする。それ以外なら、この関数 は選択されたウィンドウだけを含むリストをリターンする。 バッファーローカル変数‘selected-window-group-function’が関数にセッ トされているときは、選択されたウィンドウはグループの一部とみなされ る。この場合には、‘selected-window-group’はその関数を引数なしで呼び 出し、その結果をリターンする(これはそのグループ内のウィンドウのリス トであること)。 27.2 ウィンドウとフレーム ========================= ウィンドウはそれぞれ厳密に1つのフレームに属します(*note Frames::を参照 )。 -- Function: window-frame &optional window この関数はウィンドウWINDOWが属するフレームをリターンする。WINDOWが ‘nil’の場合のデフォルトは選択されたウィンドウ。 -- Function: window-list &optional frame minibuffer window この関数はフレームFRAMEに属する生きたウィンドウのリストをリターンす る。FRAMEが省略または‘nil’の場合のデフォルトは選択されたフレーム。 オプション引数MINIBUFFERはリターンされるリストにミニバッファーウィ ンドウを含めるべきかどうかを指定する。MINIBUFFERが‘t’ならミニバッフ ァーウィンドウが含まれ、MINIBUFFERが‘nil’または省略された場合にはミ ニバッファーウィンドウがアクティブのときだけ含まれる。MINIBUFFERが ‘nil’と‘t’以外ならミニバッファーウィンドウは含まれない。 オプション引数WINDOWが非‘nil’なら、それは指定されたフレーム上の生き たウィンドウであること。その場合にはWINDOWがリターンされるリストの 最初の要素になる。WINDOWが省略または‘nil’なら、そのフレームの選択さ れたウィンドウが最初の要素になる。 同一フレーム内のウィンドウは、リーフノード(leaf nodes)が生きたウィン ドウであるような“ウィンドウツリー(window tree)”内に組織化されます。ウィ ンドウツリーの内部ノード(internal nodes)は生きたウィンドウではありません 。これらのウィンドウは生きたウィンドウ間の関係を組織化するという目的のた めに存在します。ウィンドウツリーのルートノード(root node)は“ルートウィン ドウ(root window)”と呼ばれます。ルートノードは生きたウィンドウ(そのフレ ームにウィンドウが1つだけの場合)、または内部ウィンドウのいずれかです。 ミニバッファーウィンドウ(*note Minibuffer Windows::を参照)は、そのフ レームがミニバッファーだけのフレームでない限り、そのフレームのウィンドウ ツリーの一部にはなりません。にもかかわらず、このセクションのほとんどの関 数は引数としてミニバッファーウィンドウを許容します。さらにこのセクション の最後に説明する関数‘window-tree’は、実際のウィンドウツリーと並べてミニ バッファーウィンドウをリストします。 -- Function: frame-root-window &optional frame-or-window この関数はFRAME-OR-WINDOWにたいするルートウィンドウをリターンする。 引数FRAME-OR-WINDOWはウィンドウかフレームのいずれかであること。これ が省略または‘nil’の場合のデフォルトは選択されたフレーム。 FRAME-OR-WINDOWがウィンドウなら、リターン値はそのウィンドウのフレー ムのルートウィンドウ。 ウィンドウが分割(split)されているときは、以前は1つだった2つの生きたウ ィンドウが存在します。これらのうちの一方は、元のウィンドウと同じLispウィ ンドウオブジェクトとして表され、もう一方は新たに作成されたLispウィンドウ オブジェクトとして表されます。これらの生きたウィンドウはいずれも単一の内 部ウィンドウの“子ウィンドウ(child windows)”として、ウィンドウツリーのリ ーフノードになります。もし必要ならEmacsはこの内部ウィンドウを自動的に作 成します。この内部ウィンドウは“親ウィンドウ(parent window)”とも呼ばれ、 ウィンドウツリー内の適切な位置に配置されます。同じ親を共有するウィンドウ セットは“兄弟(sibling)”と呼ばれます。 -- Function: window-parent &optional window この関数はWINDOWの親ウィンドウ(parent window)をリターンする。 WINDOWが省略または‘nil’の場合のデフォルトは選択されたウィンドウ。 WINDOWが親をもたない場合(ミニバッファーウィンドウやそのフレームのル ートウィンドウ)にはリターン値は‘nil’。 内部ウィンドウはそれぞれ、常に最低でも2つの子ウィンドウをもちます。ウ ィンドウ削除によりこの数値が1になるとEmacsは自動的に内部ウィンドウを削除 して、その残った単一の子ウィンドウがウィンドウツリー内のその位置に配置さ れます。 子ウィンドウはそれぞれ生きたウィンドウ、または(次に自身の子ウィンドウ をもつであろう)内部ウィンドウのいずれかです。したがって各内部ウィンドウ は、最終的にはその内部ウィンドウの子孫であるような生きたウィンドウにより 占有される領域を結合した、特定の矩形“スクリーン領域(screen area)”を占有 すると考えることができます。 内部ウィンドウそれぞれにたいして、近接する子たちのスクリーン領域は垂 直(vertically)か水平(horizontally)のいずれかにより整列されます(両方で整 列されることはない)。子ウィンドウが他の子ウィンドウと上下に整列される場 合、それらは“垂直コンビネーション(vertical combination)”、左右に整列され る場合は“水平コンビネーション(horizontal combination)”を形成すると表現さ れます。以下の例で考えてみましょう: ______________________________________ | ______ ____________________________ | || || __________________________ || || ||| ||| || ||| ||| || ||| ||| || |||____________W4____________||| || || __________________________ || || ||| ||| || ||| ||| || |||____________W5____________||| ||__W2__||_____________W3_____________ | |__________________W1__________________| このフレームのルートウィンドウは内部ウィンドウW1です。これの子ウィンドウ は、生きたウィンドウW2と内部ウィンドウW3からなる水平コンビネーションを形 成します。W3の子ウィンドウは、生きたウィンドウW4とW5からなる垂直コンビネ ーションを形成します。したがって、このウィンドウツリー内の生きたウィンド ウはW2、W4、およびW5です。 以下の関数は内部ウィンドウの子ウィンドウ、および子ウィンドウの兄弟を 取得するために使用できます。 -- Function: window-top-child &optional window この関数は内部ウィンドウWINDOWの子ウィンドウが垂直コンビネーション を形成する場合には、WINDOWの一番上の子ウィンドウをリターンする。他 のタイプのウィンドウにたいするリターン値は‘nil’。 -- Function: window-left-child &optional window この関数は内部ウィンドウWINDOWの子ウィンドウが水平コンビネーション を形成する場合には、WINDOWの一番左の子ウィンドウをリターンする。他 のタイプのウィンドウにたいするリターン値は‘nil’。 -- Function: window-child window この関数は内部ウィンドウWINDOWの最初の子ウィンドウをリターンする。 これは垂直コンビネーションにたいしては一番上、水平コンビネーション にたいしては一番左の子ウィンドウ。WINDOWが生きたウィンドウならリタ ーン値は‘nil’。 -- Function: window-combined-p &optional window horizontal この関数はWINDOWが垂直コンビネーションの一部である場合のみ非‘nil’を リターンする。WINDOWが省略または‘nil’の場合のデフォルトは選択された ウィンドウ。 オプション引数HORIZONTALが非‘nil’なら、WINDOWが水平コンビネーション の一部である場合のみ非‘nil’をリターンすることを意味する。 -- Function: window-next-sibling &optional window この関数はウィンドウWINDOWの次の兄弟をリターンする。省略または ‘nil’なら、WINDOWのデフォルトは選択されたウィンドウ。WINDOWがその親 の最後の子ならリターン値は‘nil’。 -- Function: window-prev-sibling &optional window この関数はウィンドウWINDOWの前の兄弟をリターンする。省略または ‘nil’なら、WINDOWのデフォルトは選択されたウィンドウ。WINDOWがその親 の最初の子ならリターン値は‘nil’。 関数‘window-next-sibling’と‘window-prev-sibling’を、ウィンドウのサイ クル順(*note Cyclic Window Ordering::を参照)で次や前のウィンドウをリター ンする関数‘next-window’と‘previous-window’と混同しないでください。 任意のフレーム上の最初の生きたウィンドウや与えられたウィンドウにもっ とも近いウィンドウを探すために以下の関数を使用できます。 -- Function: frame-first-window &optional frame-or-window この関数はFRAME-OR-WINDOWにより指定されたフレームの左上隅の生きたウ ィンドウをリターンする。引数FRAME-OR-WINDOWはウィンドウか生きたフレ ームを指定しなければならず、デフォルトは選択されたフレーム。 FRAME-OR-WINDOWがウィンドウを指定する場合には、この関数はそのウィン ドウのフレームの最初のウィンドウをリターンする。前の例のフレームが ‘(frame-first-window)’で選択されたとするとW2がリターンされる。 -- Function: window-in-direction direction &optional window ignore sign wrap mini この関数はウィンドウWINDOW内の位置‘window-point’から、方向 DIRECTIONにあるもっとも近い生きたウィンドウをリターンする。引数 DIRECTIONは‘above’、‘below’、‘left’、‘right’のいずれかでなければな らない。オプション引数WINDOWは生きたウィンドウでなければならず、デ フォルトは選択されたウィンドウ。 この関数はパラメーター‘no-other-window’が非‘nil’のウィンドウをリタ ーンしない(*note Window Parameters::を参照)。もっとも近いウィンドウ の‘no-other-window’パラメーターが非‘nil’なら、この関数は指定された 方向で‘no-other-window’パラメーターが‘nil’であるような他のウィンド ウを探す。オプション引数IGNOREが非‘nil’なら、たとえ ‘no-other-window’パラメーターが非‘nil’のウィンドウでもリターンされ るだろう。 オプション引数SIGNが負の数値なら、それは参照位置として ‘window-point’のかわりにWINDOWの右端、または下端を使用することを意 味する。SIGNが正の数値なら、それは参照位置としてWINDOWの左端か上端 を使用することを意味する。 オプション引数WRAPが非‘nil’なら、それはフレームのボーダー(borders: 枠線)をDIRECTIONがラップアラウンド(wrap around: 最後に達したら最初 に戻る)することを意味する。たとえばWINDOWはフレームの最上にあり DIRECTIONが‘above’なら、そのフレームのミニバッファーウィンドウがア クティブでそれがフレームの他のウィンドウの最下にある場合には、この 関数は通常はミニバッファーウィンドウをリターンする。 オプション引数MINIが‘nil’なら、それはミニバッファーがカレントでアク ティブな場合のみミニバッファーウィンドウをリターンすることを意味す る。MINIが非‘nil’なら、たとえ非アクティブなときでも、この関数はミニ バッファーウィンドウをリターンする。しかしWRAPが非‘nil’なら、常に MINIが‘nil’であるかのように振る舞う。 適切なウィンドウが見つからなければ、この関数は‘nil’をリターンする。 以下の関数によりフレームのウィンドウツリー全体を取得できます: -- Function: window-tree &optional frame この関数はフレームFRAMEにたいするウィンドウツリーを表すリストをリタ ーンする。FRAMEが省略‘nil’の場合のデフォルトは選択されたフレーム。 リターン値は‘(ROOT MINI)’という形式のリスト。ここでROOTはそのフレー ムのウィンドウツリーのルートウィンドウ、MINIはそのフレームのミニバ ッファーウィンドウを表す。 ルートウィンドウが生きていればROOTはそのウィンドウ自身、それ以外な らROOTはリスト‘(DIR EDGES W1 W2 ...)’。ここでDIRは水平コンビネーシ ョンなら‘nil’、垂直コンビネーションなら‘t’となり、EDGESはそのコンビ ネーションのサイズと位置を与え、残りの要素は子ウィンドウである。子 ウィンドウはそれぞれ、同じようにウィンドウオブジェクト(生きたウィン ドウにたいして)、または上記フォーマットと同じ形式のリスト(内部ウィ ンドウにたいして)かもしれない。EDGES要素は‘window-edges’がリターン する値のようなリスト‘(LEFT TOP RIGHT BOTTOM)’ (*note Coordinates and Windows::を参照)。 27.3 ウィンドウのサイズ ======================= 以下の図は生きたウィンドウの構造を示しています: ____________________________________________ |______________ Header Line ______________|RD| ^ ^ |LS|LM|LF| |RF|RM|RS| | | | | | | | | | | | | | Window | | | | Text Area | | | | | Window Body | | | | | (Window Body) | | | | | Total Height | | | | | | | | | Height | | | | |<- Window Body Width ->| | | | | | v |__|__|__|_______________________|__|__|__| | | |_________ Horizontal Scroll Bar _________| | | |_______________ Mode Line _______________|__| | |_____________ Bottom Divider _______________| v <---------- Window Total Width ------------> ウィンドウの中央は“テキストエリア(text area: テキスト領域)”、または “ボディー(body: 本体、本文)”と呼ばれるバッファーテキストが表示される場所 です。テキストエリアは一連のオプションエリアで囲まれている可能性がありま す。左右には内側から外側に向かって図中にLFとRFで示される左右のフリンジ (*note Fringes::を参照)、LMとRMで示される左右のマージン(*note Display Margins::を参照)、そしてLSとRSはスクロールバー(*note Scroll Bars::を参照 )で、これは常に表示されるのはいずれか一方だけです。さらにRDで示されるの が右ディバイダー(*note Window Dividers::を参照)です。ウィンドウ上端には ヘッダーライン(*note Header Lines::を参照)、ウィンドウ下端には水平スクロ ールバー(*note Scroll Bars::を参照)、モードライン(*note Mode Line Format::を参照)、下端ディバイダー(*note Window Dividers::を参照)がありま す。 Emacsはウィンドウの高さと幅を求めるためのさまざまな関数を提供します。 これらの関数がリターンする値の多くはピクセル単位、または行単位と列単位の いずれかにより指定できます。グラフィカルなディスプレイでは後者は実際には ‘frame-char-height’と‘frame-char-width’ (*note Frame Font::を参照)により リターンされる、そのフレームのデフォルトフォントが指定するデフォルト文字 の高さと幅に対応します。したがってあるウィンドウが異なるフォントやサイズ でテキストを表示していると、そのウィンドウにたいして報告される行高さと列 幅は、実際にウィンドウ内で表示されるテキスト行数と列数とは異なるかもしれ ません。 “トータル高さ(total height)”とは、そのウィンドウのボディーを構成する 行数、ヘッダーライン、水平スクロールバー、モードライン、(もしあれば)下端 ディバイダーです。 -- Function: window-total-height &optional window round この関数はウィンドウWINDOWのトータル高さを行数でリターンする。 WINDOWが省略‘nil’の場合のデフォルトは選択されたウィンドウ。WINDOWが 内部ウィンドウなら、リターン値はそのウィンドウの子孫となるウィンド ウにより占有されるトータル高さになる。 ウィンドウのピクセル高さがそのウィンドウがあるフレームのデフォルト 文字高さの整数倍でなければ、そのウィンドウが占有する行数が内部で丸 められる。これはそのウィンドウが親ウィンドウの場合には、すべての子 ウィンドウのトータル高さの合計が、親ウィンドウのトータル高さと内部 的に等しくなるような方法により行われる。これはたとえ2つのウィンドウ のピクセル高さが等しくでも、内部的なトータル高さは1行分異なるかもし れないことを意味する。さらにこれはそのウィンドウが垂直コンビネーシ ョンされていて、かつ次の兄弟をもつ場合には、その兄弟の上端行は、こ のウィンドウの上端行とトータル高さから計算されるかもしれないことも 意味する(*note Coordinates and Windows::を参照)。 オプション引数ROUNDが‘ceiling’なら、この関数はWINDOWのピクセル高さ をそのフレームの文字高さで除した数より大であるような最小の整数、 ‘floor’なら除した数より小であるような最大の整数、それ以外のROUNDに たいしてはWINDOWSのトータル高さの内部値をリターンする。 “トータル幅(total width)”とはそのウィンドウのボディーを構成する列数、 マージン、フリンジ、スクロールバー、(もしあれば)右ディバイダーです。 -- Function: window-total-width &optional window round この関数はウィンドウWINDOWのトータル幅を列でリターンする。WINDOWが 省略‘nil’の場合のデフォルトは選択されたウィンドウ。WINDOWが内部ウィ ンドウならリターン値はその子孫のウィンドウが占有するトータル幅にな る。 ウィンドウのピクセル幅がそのウィンドウがあるフレームのデフォルト文 字幅の整数倍でなければ、そのウィンドウが占有する列数が内部で丸めら れる。これはそのウィンドウが親ウィンドウの場合には、すべての子ウィ ンドウのトータル幅の合計が親ウィンドウのトータル幅と内部的に等しく なるような方法により行われる。これはたとえ2つのウィンドウのピクセル 幅が等しくでも、内部的なトータル幅は1列分異なるかもしれないことを意 味する。さらにこれはそのウィンドウが水平コンビネーションされていて 、かつ次の兄弟をもつ場合、その兄弟の左端行はこのウィンドウの左端行 とトータル幅から計算されるかもしれないことも意味する(*note Coordinates and Windows::を参照)。オプション引数ROUNDは ‘window-total-height’の場合と同様に振る舞う。 -- Function: window-total-size &optional window horizontal round この関数はウィンドウWINDOWのトータル高さを行数、またはトータル幅を 列数でリターンする。HORIZONTALが省略または‘nil’ならWINDOWにたいして ‘window-total-height’を呼び出すのと等価、それ以外ではWINDOWにたいし て‘window-total-width’を呼び出すのと等価である。オプション引数 ROUNDは‘window-total-height’の場合と同様に振る舞う。 以下の2つの関数はウィンドウのトータルサイズをピクセル単位で取得するた めに使用できます。 -- Function: window-pixel-height &optional window この関数はウィンドウWINDOWのトータル高さをピクセル単位でリターンす る。WINDOWは有効なウィンドウでなければならずデフォルトは選択された ウィンドウ。 リターン値には、(もしあれば)モードライン、ヘッダーライン、水平スク ロールバー、下端ディバイダーが含まれる。WINDOWが内部ウィンドウなら 、そのピクセル高さは子ウィンドウたちによりスパンされるスクリーン領 域のピクセル高さになる。 -- Function: window-pixel-width &optional Lisp_Object &optional window この関数はウィンドウWINDOWの幅をピクセル単位でリターンする。 WINDOWは有効なウィンドウでなければならずデフォルトは選択されたウィ ンドウ。 リターン値にはフリンジ、WINDOWのマージン、同様にWINDOWに属する垂直 ディバイダーとスクロールバーが含まれる。WINDOWが内部ウィンドウなら 、そのピクセル幅は子ウィンドウたちにより占有されるスクリーン領域の 幅になる。 以下の関数は与えられたウィンドウに隣接するウィンドウがあるかどうかを 判断するために使用できます。 -- Function: window-full-height-p &optional window この関数はフレーム内でWINDOWの上下に他のウィンドウがなければ非 ‘nil’をリターンする。より正確には、WINDOWのトータル高さがそのフレー ムのルートウィンドウの高さに等しいことを意味する。WINDOWが省略また は‘nil’の場合のデフォルトは選択されたウィンドウ。 -- Function: window-full-width-p &optional window この関数はフレーム内でWINDOWの左右に他のウィンドウがなければ非 ‘nil’をリターンする(トータル幅がそのフレーム上のルートウィンドウと 等しい)。WINDOWが省略または‘nil’の場合のデフォルトは選択されたウィ ンドウ。 ウィンドウの“ボディー高さ(body height)”とはモードライン、ヘッダーライ ン、水平スクロールバー、下端ディバイダーを含まないテキスト領域の高さです 。 -- Function: window-body-height &optional window pixelwise この関数はウィンドウWINDOWのボディーの高さを行数でリターンする。 WINDOWが省略または‘nil’の場合のデフォルトは選択されたウィンドウ、そ れ以外なら生きたウィンドウでなければならない。 オプション引数PIXELWISEが非‘nil’なら、この関数はピクセルで計算 WINDOWのボディー高さをリターンする。 PIXELWISEが‘nil’の場合には、必要ならリターン値はもっとも近い整数に 切り下げられる。これはテキスト領域の下端行が部分的に可視の場合にそ の行は計数されないこと、さらに任意のウィンドウのボディー高さは ‘window-total-height’によりリターンされるそのウィンドウのトータル高 さ決して超過し得ないことも意味する。 ウィンドウの“ボディー幅(body width)”とはスクロールバー、フリンジ、マ ージン、右ディバイダーを含まないテキスト領域の幅です。(幅を0にセットする ことにより)一方または両方のフリンジが削除されたときには、継続と切り詰め のグリフを表示するためにディスプレーエンジンが文字セル2つを予約するので 、テキスト表示にたいして2列少なくなることに注意してください(以下で説明す る‘window-max-chars-per-line’はこの特性を考慮する)。 -- Function: window-body-width &optional window pixelwise この関数はウィンドウWINDOWのボディーの幅を列数でリターンする。 WINDOWが省略または‘nil’の場合のデフォルトは選択されたウィンドウ、そ れ以外なら生きたウィンドウでなければならない。 オプション引数PIXELWISEが非‘nil’なら、この関数はWINDOWのボディーの 幅をピクセル単位でリターンする。 PIXELWISEが‘nil’なら、リターン値は必要に応じてもっとも近い整数に切 り下げられる。これはテキスト領域の右端の列が部分的に可視な場合にそ の列が計数されないことを意味する。さらにこれはウィンドウのボディー の幅が‘window-total-width’によりリターンされるウィンドウのトータル 幅を決して超過し得ないことをも意味する。 -- Function: window-body-size &optional window horizontal pixelwise この関数はWINDOWのボディーの高さか幅をリターンする。HORIZONTALが省 略または‘nil’ならWINDOWにたいして‘window-body-height’、それ以外なら ‘window-body-width’を呼び出すのと同じ。いずれの場合もオプション引数 PIXELWISEは呼び出された関数に渡される。 以前のバージョンのEmacsとの互換性のために‘window-height’は ‘window-total-height’、‘window-width’は‘window-body-width’にたいするエイ リアスです。これらのエイリアス時代遅れと考えられていて将来は削除されるで しょう。 ウィンドウのモードラインとヘッダーラインのピクセル高さは以下の関数に より取得できます。それらのリターン値は、そのウィンドウが以前に表示されて いない場合を除いて通常は加算されます。その場合のリターン値はそのウィンド ウのフレームにたいして使用を予想されるフォントが元になります。 -- Function: window-mode-line-height &optional window この関数はWINDOWモードラインの高さをピクセルでリターンする。 WINDOWは生きたウィンドウでなければならずデフォルトは選択されたウィ ンドウ。WINDOWにモードラインがなければリターン値は0。 -- Function: window-header-line-height &optional window この関数はWINDOWのヘッダーラインの高さをピクセル単位でリターンする 。WINDOWは生きたウィンドウでなければならずデフォルトは選択されたウ ィンドウ。WINDOWにヘッダーラインがない場合のリターン値は0。 ウィンドウディバイダー(*note Window Dividers::を参照)、フリンジ(*note Fringes::を参照)、スクロールバー(*note Scroll Bars::を参照)、ディスプレ イマージン(*note Display Margins::を参照)を取得する関数については、それ ぞれ対応するセクションで説明されています。 Lispプログラムでレイアウト上の判断を要する場合には、以下の関数を有用 と思うでしょう: -- Function: window-max-chars-per-line &optional window face この関数は指定されたウィンドウWINDOW (生きたウィンドウであること)内 で、指定されたフェイスFACEで表示される文字数をリターンする。FACEが リマップ(*note Face Remapping::を参照)されていたらリマップされたフ ェイスの情報がリターンされる。省略または‘nil’の場合、FACEのデフォル トはデフォルトフェイス、WINDOWのデフォルトは選択されたウィンドウ。 この関数は‘window-body-width’と異なり、WINDOWのフレームの正準文字幅 (canonical character width)の単位ではなく、FACEのフォントの実サイズ を考慮する。またWINDOWの一方または両方のフリンジがなければ、継続グ リフに使用されるスペースも考慮する。 ウィンドウのサイズを変更(*note Resizing Windows::を参照)したりウィン ドウを分割(split)するコマンド(*note Splitting Windows::を参照)は、指定で きるウィンドウの最小の高さと幅を指定する変数‘window-min-height’と ‘window-min-width’にしたがう。これらのコマンドはウィンドウのサイズが “fixed(固定)”になる変数‘window-size-fixed’にもしたがう(*note Preserving Window Sizes::を参照)。 -- User Option: window-min-height このオプションは任意のウィンドウの最小のトータル高さを行で指定する 。この値は最低でも1つのテキスト行、同様に(もしあれば)モードライン、 ヘッダーライン、水平スクロールバー、下端ディバイダーに対応する必要 がある。 -- User Option: window-min-width このオプションはすべてのウィンドウの最小のトータル幅を列で指定する 。この値は2つのテキスト列、同様に(もしあれば)マージン、フリンジ、ス クロールバー、右ディバイダーに対応する必要がある。 以下の関数は、ある特定の大きさのウィンドウにたいして、それの ‘window-min-height’と‘window-min-width’、および‘window-size-fixed’ (*note Preserving Window Sizes::を参照)の値と領域のサイズを示す。 -- Function: window-min-size &optional window horizontal ignore pixelwise この関数はWINDOWの最小のサイズをリターンする。WINDOWは有効なウィン ドウでなければならず、デフォルトは選択されたウィンドウ。オプション 引数HORIZONTALが非‘nil’ならWINDOWの最小の列数、それ以外はWINDOWの最 小の行数をリターンすることを意味する。 このリターン値によってWINDOWのサイズが実際にその値にセットされた場 合にWINDOWのすべてのコンポーネントが完全に可視にとどまることが保証 される。HORIZONTALが‘nil’なら、(もしあれば)モードライン、ヘッダーラ イン、水平スクロールバー、下端ディバイダーが含まれる。HORIZONTALが 非‘nil’なら、(もしあれば)マージン、フリンジ、垂直スクロールバー、右 ディバイダーが含まれる。 オプション引数IGNOREが非‘nil’なら、‘window-min-height’や ‘window-min-width’によりセットされる固定サイズのウィンドウに強いら れる制限を無視することを意味する。IGNOREが‘safe’なら、生きたウィン ドウは可能な限り小さな‘window-safe-min-height’の行、および ‘window-safe-min-width’の列を得る。IGNOREにウィンドウが指定されると 、そのウィンドウにたいする制限だけを無視する。その他の非‘nil’値では 、すべてのウィンドウにたいする上記制限のすべてが無視されることを意 味する。 オプション引数PIXELWISEが非‘nil’なら、WINDOWの最小サイズがピクセル で計数されてリターンされることを意味する。 27.4 ウィンドウのリサイズ ========================= このセクションでは、フレームのサイズを変更せずにウィンドウのサイズを変更 する関数について説明します。生きたウィンドウはオーバーラップしないので、 これらの関数は2つ以上のウィンドウを含む関数上でのみ意味があります(ウィン ドウのリサイズにより隣接するウィンドウのサイズも変更される)。フレーム上 に単一のウィンドウしか存在しなければ、フレームの変更以外にウィンドウのサ イズ変更はできません(*note Size and Position::を参照)。 注記した場合を除き、これらの関数は引数として内部ウィンドウも許容しま す。内部ウィンドウのリサイズにより、同じスペースにフィットするように子ウ ィンドウもリサイズされます。 -- Function: window-resizable window delta &optional horizontal ignore pixelwise この関数はWINDOWのサイズがDELTA行により垂直に変更され得る場合には DELTAをリターンする。オプション引数HORIZONTALが非‘nil’の場合には、 WINDOWがDELTA列単位に水平方向にリサイズ可能ならかわりにDELTAをリタ ーンする。これは実際にはウィンドウのサイズを変更しない。 WINDOWが‘nil’の場合のデフォルトは選択されたウィンドウ。 DELTAが正の値ならそのウィンドウが行または列の単位で拡張可能かどうか をチェックすることを意味し、DELTAが負の値ならそのウィンドウが行また は列の単位で縮小可能かどうかをチェックすることを意味する。DELTAが非 0の場合のリターン値0は、そのウィンドウがリサイズ可能であることを意 味する。 変数‘window-min-height’と‘window-min-width’には通常は許容される最小 のウィンドウサイズを指定する(*note Window Sizes::を参照)。しかしオ プション引数IGNOREが非‘nil’なら、この関数は‘window-size-fixed’と同 様に‘window-min-height’と‘window-min-width’を無視する。そのかわりに (もしあれば)ヘッダーライン、モードライン、水平スクロールバー、下端 ディバイダーに加えて1行分の高さのテキストエリアから構成されるウィン ドウを最小高さのウィンドウとし、(もしあれば)フリンジ、マージン、ス クロールバー、右ディバイダーに加えて1列分の幅のテキストエリアから構 成されるウィンドウを最小幅のウィンドウと判断する。 オプション引数PIXELWISEが非‘nil’ならDELTAはピクセル単位として解釈さ れる。 -- Function: window-resize window delta &optional horizontal ignore pixelwise この関数はWINDOWをDELTA増加することによりリサイズを行う。 HORIZONTALが‘nil’なら高さをDELTA行、それ以外は幅をDELTA行変更する。 正のDELTAはウィンドウの拡大、負のDELTAは縮小を意味する。 WINDOWが‘nil’の場合のデフォルトは選択されたウィンドウ。要求されたよ うにウィンドウをリサイズできなければエラーをシグナルする。 オプション引数IGNOREは上述の関数‘window-resizable’の場合と同じ意味 をもつ。 オプション引数PIXELWISEが非‘nil’ならDELTAはピクセル単位として解釈さ れる。 この関数がどのウィンドウのエッジを変更するかの選択はオプション ‘window-combination-resize’の値、および関連するウィンドウのコンビネ ーションリミット(combination limits: 組み合わせ制限)に依存し、両方 のエッジを変更するような場合もいくつかある。*note Recombining Windows::を参照のこと。ウィンドウの下端か右端のエッジを移動すること だけでリサイズするには関数‘adjust-window-trailing-edge’を使用するこ と。 -- Function: adjust-window-trailing-edge window delta &optional horizontal pixelwise この関数はWINDOWの下端エッジをDELTA行分移動する。オプション引数 HORIZONTALが非‘nil’なら、かわりに右端エッジをDELTA列分移動する。 WINDOWが‘nil’の場合のデフォルトは選択されたウィンドウ。 オプション引数PIXELWISEが非‘nil’ならDELTAはピクセル単位として解釈さ れる。 正のDELTAはエッジを下方か右方へ移動し、負のDELTAはエッジを上方か左 方へ移動する。DELTAで指定された範囲までエッジを移動できなければ、こ の関数はエラーをシグナルすることなく可能な限りエッジを移動する。 この関数は移動されたエッジに隣接するウィンドウのリサイズを試みる。 何らかの理由(隣接するウィンドウが固定サイズの場合等)によりそれが不 可能なら、他のウィンドウをリサイズするかもしれない。 -- User Option: window-resize-pixelwise このオプションの値が非‘nil’ならEmacsはウィンドウをピクセル単位でリ サイズする。これは現在のところ‘split-window’ (*note Splitting Windows::を参照)、‘maximize-window’、‘minimize-window’、 ‘fit-window-to-buffer’、‘fit-frame-to-buffer’、 ‘shrink-window-if-larger-than-buffer’ (すべて以下に記述)のような関 数に影響を与える。 あるフレームのピクセルサイズがそのフレームの文字サイズの整数倍でな いときは、たとえこのオプションが‘nil’であっても少なくとも1つのウィ ンドウがピクセル単位でリサイズされるであろうことに注意。デフォルト 値は‘nil’。 以下のコマンドは、より具体的な方法でウィンドウをリサイズします。これ らがインタラクティブに呼び出されたときは選択されたウィンドウにたいして作 用します。 -- Command: fit-window-to-buffer &optional window max-height min-height max-width min-width preserve-size このコマンドはWINDOWの高さか幅をウィンドウ内のテキストにフィットす るように調整する。WINDOWがリサイズできたら非‘nil’、それ以外は ‘nil’をリターンする。WINDOWが省略または‘nil’の場合のデフォルトは選 択されたウィンドウ、それ以外の場合には生きたウィンドウであること。 WINDOWが垂直コンビネーションの一部なら、この関数はWINDOWの高さを調 整する。新たな高さはそのウィンドウのバッファーのアクセス可能な範囲 の実際の高さから計算される。オプション引数MAX-HEIGHTが非‘nil’なら、 それはこの関数がWINDOWに与えることができる最大のトータル高さを指定 する。オプション引数MIN-HEIGHTが非‘nil’なら、それは与えることができ る最小のトータル高さを指定して、それは変数‘window-min-height’をオー バーライドする。MAX-HEIGHTとMIN-HEIGHTはいずれも、(もしあれば)モー ドライン、ヘッダーライン、下端ディバイダーを含む行数で指定する。 WINDOWが水平コンビネーションの一部で、かつオプション ‘fit-window-to-buffer-horizontally’ (以下参照)の値が非‘nil’なら、こ の関数はWINDOWの幅を調整する。新たな幅はWINDOWのカレントのスタート 位置以降のバッファーの最長の行から計算される。オプション引数 MAX-WIDTHは最大幅を指定し、デフォルトはWINDOWのフレーム幅。オプショ ン引数MIN-WIDTHは最小幅を指定し、デフォルトは‘window-min-width’。 MAX-WIDTHとMIN-WIDTHはいずれも、(もしあれば)フリンジ、マージン、ス クロールバーを含む列数で指定する。 オプション引数PRESERVE-SIZEが非‘nil’なら、将来のリサイズ操作の間の WINDOWのサイズを予約するパラメーターをインストールする(*note Preserving Window Sizes::を参照)。 オプション‘fit-frame-to-buffer’ (以下参照)が非‘nil’なら、この関数は ‘fit-frame-to-buffer’ (以下参照)を呼び出すことにより、WINDOWのコン テンツにフィットするようにWINDOWのフレームのリサイズを試みるだろう 。 -- User Option: fit-window-to-buffer-horizontally これが非‘nil’なら、‘fit-window-to-buffer’はウィンドウを水平方向にリ サイズできる。これが‘nil’ (デフォルト)なら‘fit-window-to-buffer’は ウィンドウ決して水平方向にリサイズしない。これが‘only’ならウィンド ウを水平方向だけにリサイズできる。その他の値では ‘fit-window-to-buffer’がウィンドウをどちらの方向にもリサイズできる ことを意味する。 -- User Option: fit-frame-to-buffer このオプションが非‘nil’なら、‘fit-window-to-buffer’はフレームをフレ ームのコンテンツにフィットさせることができる。フレームは、フレーム のルートウィンドウが生きたウィンドウで、かつこのオプションが非 ‘nil’の場合のみフィットされる。‘horizontally’ならフレームは水平方向 にのみフィットされる。‘vertically’ならフレームは垂直方向にのみフィ ットされる。その他の非‘nil’値はフレームがどちらの方向にもフィットで きることを意味する。 単一のウィンドウだけを表示するフレームではコマンド ‘fit-frame-to-buffer’を使用してそのバッファーにフレームをフィットできま す。 -- Command: fit-frame-to-buffer &optional frame max-height min-height max-width min-width only このコマンドはFRAMEのサイズを、表示しているバッファーのコテンツに正 確に調整する。FRAMEには任意の生きたフレームを指定できデフォルトは選 択されたフレーム。FRAMEのルートウィンドウが生きている場合のみフィッ トが行われる。引数MAX-HEIGHT、MIN-HEIGHT、MAX-WIDTH、MIN-WIDTHは FRAMEのルートウィンドウの新たなトータルサイズの境界を指定する。 MIN-HEIGHTとMIN-WIDTHのデフォルトはそれぞれ‘window-min-height’と ‘window-min-width’。 この関数はオプション引数ONLYが‘vertically’なら垂直方向のみ、ONLYが ‘horizontally’なら水平方向のみフレームをリサイズする。 ‘fit-frame-to-buffer’の振る舞いは次にリストする2つのオプションで制御 可能です。 -- User Option: fit-frame-to-buffer-margins このオプションは‘fit-frame-to-buffer’によりフィットされるフレーム周 囲のマージンの指定に使用できる。このようなマージンは、たとえばフレ ームとタスクバーが重なることを回避するために有用。 これはフィットされるフレームの左右上下にフリーとして残されるピクセ ル数を指定する。デフォルトの‘nil’はそれぞれにたいしてマージンを使用 しないことを指定する。ここで指定した値は、特定のフレームにたいして もしそのフレームの‘fit-frame-to-buffer-margins’が与えられればオーバ ーライドされ得る。 -- User Option: fit-frame-to-buffer-sizes このオプションは‘fit-frame-to-buffer’にたいしてサイズ境界を指定する 。これは自身のバッファーにフィットされる任意のフレームのルートウィ ンドウの最大行と最小行、最大列と最小列のトータルを指定する。これら の値のいずれかが非‘nil’なら、‘fit-frame-to-buffer’の対応する引数を オーバーライドする。 -- Command: shrink-window-if-larger-than-buffer &optional window このコマンドはWINDOWにたいしてそのバッファーを完全に表示できるが、 ‘window-min-height’以上の行を表示できるまで可能な限りWINDOWの高さを 縮小する。リターン値はそのウィンドウがリサイズされれば非‘nil’、それ 以外なら非‘nil’。WINDOWが省略または‘nil’の場合のデフォルトは選択さ れたウィンドウ。それ以外では生きたウィンドウであること。 このコマンドはそのウィンドウがバッファーのすべてを表示するにはすで に高さが低すぎる場合、バッファーのどこかがスクリーンからスクロール オフされている場合、またはそのウィンドウがフレーム内で唯一の生きた ウィンドウの場合は何も行わない。 このコマンドは自身の処理を行うために‘fit-window-to-buffer’ (上記参 照)を呼び出す。 -- Command: balance-windows &optional window-or-frame この関数は各ウィンドウにたいして完全な幅、および/または完全な高さを 与えるような方法によって各ウィンドウのバランスをとる。 WINDOW-OR-FRAMEにフレームを指定すると、そのフレーム上のすべてのウィ ンドウのバランスをとる。WINDOW-OR-FRAMEにウィンドウを指定すると、そ のウィンドウとウィンドウのsiblings(兄弟)にたいしてのみのバランスを とる(*note Windows and Frames::を参照)。 -- Command: balance-windows-area この関数は選択されたフレーム上のすべてのウィンドウにたいして、おお よそ同じスクリーンエリアを与えようと試みる。完全な幅か高さをもつウ ィンドウにたいしては、他のウィンドウと比較してより多くのスペースは 与えられない。 -- Command: maximize-window &optional window この関数は、WINDOWにたいして、そのフレームをリサイズしたり他のウィ ンドウを削除することなく、水平垂直の両方向で可能な限り大きくなるよ うに試みる。WINDOWが省略または‘nil’の場合のデフォルトは選択されたウ ィンドウ。 -- Command: minimize-window &optional window この関数はWINDOWにたいして、そのフレームをリサイズしたりそのウィン ドウを削除することなく、水平垂直の両方向で可能な限り小さくなるよう に試みる。WINDOWが省略または‘nil’の場合のデフォルトは選択されたウィ ンドウ。 27.5 Preserving Window Sizes ============================ ウィンドウは前セクションのいずれかの関数を使用して明示的にリサイズされた り、たとえばウィンドウの調整、ウィンドウの分割(*note Splitting Windows::を参照)や削除(*note Deleting Windows::を参照)、またはウィンドウ のフレームのリサイズ(*note Size and Position::を参照)の際に暗黙にリサイ ズされるかもしれません。 同一フレーム上に1つ以上のリサイズ可能なウィンドウが他に存在する際には 、特定のウィンドウにたいして暗黙のリサイズを避けることが可能です。この目 的にたいして、Emacsにそのウィンドウのサイズの“予約(preserve)”をアドバイ スしなければなりません。これを行うための基本的な方法が2つあります。 -- Variable: window-size-fixed このバッファーローカル変数が非‘nil’なら、通常はそのバッファーを表示 するすべてのウィンドウのサイズが変更できなくなる。ウィンドウ削除や そのフレームのサイズ変更により、それ以外に方法がなければ依然として ウィンドウのサイズは変更され得る。 値が‘height’ならそのウィンドウの高さのみ、値が‘width’ならそのウィン ドウの幅のみが固定される。その他の非‘nil’値では幅と高さの両方が固定 される。 この変数が‘nil’でも、そのバッファーを表示している任意のウィンドウを 任意の方向にリサイズできるとはいえない。これを判断するには関数 ‘window-resizable’を使用する。*note Resizing Windows::を参照のこと 。 影響を受けるウィンドウにたいする明示的なリサイズや分割の試みも同様に 抑制するので、‘window-size-fixed’の積極性が過度な場合が多々あります。こ れはたとえそのウィンドウが暗黙にリサイズされた後にも、たとえば隣接するウ ィンドウの削除やウィンドウのフレームのリサイズの際に発生するかもしれませ ん。以下の関数では、そのようなウィンドウのリサイズを絶対禁止としないよう 試みます: -- Function: window-preserve-size &optional window horizontal preserve この関数は将来のリサイズ操作用にウィンドウ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’なら、この関数により 確保されたサイズは予約される(*note Resizing Windows::を参照)。 ‘display-buffer’ この関数のALIST引数に‘preserve-size’エントリーがあれば、この関数に より生成されるウィンドウサイズは予約される(*note Choosing Window::を 参照)。 ‘window-preserve-size’はウィンドウリサイズ関数に参照される、 ‘preserved-size’と呼ばれるウィンドウパラメーター(*note Window Parameters::を参照)をインストールする。ウィンドウが ‘window-preserve-size’呼び出し時に表示していたバッファーと異なるバッファ ーを表示していたり、呼び出し後にサイズが変更されていたら、このパラメータ ーはウィンドウのリサイズを妨げない。 以下の関数は特定のウィンドウの高さが予約済みかどうかチェックするため に使用できます: -- Function: window-preserved-size &optional window horizontal この関数はウィンドウWINDOWの予約済み高さをピクセル単位でリターンす る。WINDOWは生きたウィンドウでなければならずデフォルトは選択された ウィンドウ。オプション引数HORIZONTALが非‘nil’ならWINDOWの予約済み幅 をリターンする。WINDOWのサイズが予約されていなければ‘nil’をリターン する。 27.6 ウィンドウの分割 ===================== このセクションでは既存のウィンドウを“分割(split: スプリット”することによ って新たにウィンドウを作成する関数について説明します。 -- Function: split-window &optional window size side pixelwise この関数はウィンドウWINDOWの隣に生きたウィンドウを新たに作成する。 WINDOWが省略または‘nil’の場合のデフォルトは選択されたウィンドウ。そ のウィンドウは分割(split)されてサイズは縮小される。そのスペースはリ ターンされる新たなウィンドウによって吸収される。 オプションの第2引数SIZEは、WINDOWおよび/または新たなウィンドウのサ イズを決定する。これが省略または‘nil’なら、両方のウィンドウに同じサ イズが割り当てられる。行数が奇数なら、余りの1行は新たなウィンドウに 割り当てられる。SIZEが正の数値なら、WINDOWにSIZEの行数(SIDEの値によ っては列数)が与えられる。SIZEが負の数値なら、新たなウィンドウに −SIZEの行数(または列数)が与えられる。 SIZEが‘nil’なら、この関数は変数‘window-min-height’と ‘window-min-width’にしたがう(*note Window Sizes::を参照)。つまり分 割によりこれらの変数の指定より小さいウィンドウが作成されるようなら エラーをシグナルする。しかしSIZEにたいして非‘nil’値を指定すると、こ れらの変数は無視される。その場合には許容される最小のウィンドウはテ キストエリアの高さが1行、および/または幅が2列のウィンドウとみなされ る。 したがってSIZEが指定された場合には、生成されるウィンドウがモードラ インやスクロールバー等すべてのエリアを含むのに十分な大きさがあるか どうかチェックするのは呼び出し側の責任である。これに関して必要最小 限のWINDOWを決定するために関数‘window-min-size’ (*note Window Sizes::を参照)を使用できる。新たなウィンドウは通常はモードラインや スクロールバー等のエリアを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’にしたがう。*note Window Parameters::を参照のこと。 例として*note Windows and Frames::で議論したウィンドウ構成(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’を呼び出して います。 -- Command: split-window-right &optional size この関数は選択されたウィンドウが左となるように、横並びの2つのウィン ドウに分割する。SIZEが正ならば左のウィンドウがSIZE列、負ならば右の ウィンドウが−SIZE列を与えられる。 -- Command: split-window-below &optional size この関数は選択されたウィンドウが上となるような、縦並びの2つのウィン ドウに分割する。SIZEが正ならば上のウィンドウがSIZE行、負ならば下の ウィンドウが−SIZE行を与えられる。 -- User Option: split-window-keep-point この変数の値が非‘nil’ (デフォルト)なら‘split-window-below’は上述の ように振る舞う。 ‘nil’なら‘split-window-below’は再表示が最小となるように、2つのウィ ンドウの各ポイントを調節する(これは低速な端末で有用)。これは何であ れ、以前ポイントがあったスクリーン行(screen line)を含むウィンドウを 選択する。これは低レベル‘split-window’関数ではなく ‘split-window-below’だけに影響することに注意。 27.7 ウィンドウの削除 ===================== ウィンドウを“削除(delete)”することにより、フレームのウィンドウツリーから ウィンドウが取り除かれます。それが生きたウィンドウならスクリーンに表示さ れなくなります。内部ウィンドウならその子ウィンドウも削除されます。 ウィンドウを削除した後であっても、それへの参照が残っている限りは Lispオブジェクトとして存在し続けます。ウィンドウ構成(window configuration)をリストアすることにより、ウィンドウの削除は取り消すことが できます(*note Window Configurations::を参照)。 -- Command: delete-window &optional window この関数は表示からWINDOWを削除して‘nil’をリターンする。WINDOWが省略 または‘nil’の場合のデフォルトは選択されたウィンドウ。そのウィンドウ を削除するとウィンドウツリーにウィンドウが存在しなくなるような場合 (それがフレーム内で唯一の生きたウィンドウである場合等)はエラーをシ グナルする。 デフォルトではWINDOWが占めていたスペースは、(もしあれば)隣接する兄 弟ウィンドウのうちの1つに与えられる。しかし変数 ‘window-combination-resize’が非‘nil’なら、そのスペースは同一ウィン ドウコンビネーション内の残りのすべてのウィンドウに比例的に分配され る。*Note Recombining Windows::を参照のこと。 変数‘ignore-window-parameters’が‘nil’の場合に限り、この関数の振る舞 いはWINDOWのウィンドウパラメーターにより変更される可能性がある。ウ ィンドウパラメーター‘delete-window’の値が‘t’なら、この関数はその他 すべてのウィンドウパラメーターを無視する。ウィンドウパラメーター ‘delete-window’が関数なら、通常の‘delete-window’のかわりに引数 WINDOWでその関数が呼び出される。それ以外では、この関数は(もしあれば )ウィンドウパラメーター‘window-atom’または‘window-side’にしたがう。 *note Window Parameters::を参照のこと。 -- Command: delete-other-windows &optional window この関数は必要に応じて他のウィンドウを削除することによりWINDOWでフ レームを充填する。WINDOWが省略または‘nil’の場合のデフォルトは選択さ れたウィンドウ。リターン値は‘nil’。 変数‘ignore-window-parameters’が‘nil’の場合に限り、この関数の振る舞 いは変更される可能性がある。ウィンドウパラメーター ‘delete-other-windows’の値が‘t’なら、この関数は他のすべてのウィンド ウパラメーターを無視する。ウィンドウパラメーター ‘delete-other-windows’の値が関数なら、‘delete-other-windows’の通常 の動作のかわりに引数WINDOWでその関数が呼び出される。それ以外では、 この関数は(もしあれば)ウィンドウパラメーター‘window-atom’または ‘window-side’にしたがう。*note Window Parameters::を参照のこと。 -- Command: delete-windows-on &optional buffer-or-name frame この関数はBUFFER-OR-NAMEを表示しているすべてのウィンドウにたいして ‘delete-window’を呼び出すことによってそれらを削除する。 BUFFER-OR-NAMEはバッファー、またはバッファー名であること。省略また は‘nil’の場合のデフォルトはカレントバッファー。指定されたバッファー を表示するウィンドウが存在しなければ、この関数は何も行わない。ミニ バッファーが指定されるとエラーをシグナルする。 そのバッファーの表示に専用(dedicated)のウィンドウがあり、フレーム上 でそれが唯一のウィンドウの場合には、それが端末上で唯一のフレームで なければこの関数はそのフレームも削除する。 オプション引数FRAMEは操作を行うフレームがどれかを指定する: • ‘nil’ すべてのフレームを処理することを意味する。 • ‘t’ 選択されたフレームを処理することを意味する。 • ‘visible’ 可視なすべてのフレームを処理することを意味する。 • ‘0’ 可視またはアイコン化されたすべてのフレームを処理することを 意味する。 • フレーム そのフレームを処理することを意味する。 この引数の意味は、すべての生きたウィンドウを走査する他の関数(*note Cyclic Window Ordering::を参照)の場合とは異なることに注意。特にここ での‘t’と‘nil’のもつ意味は、これら他の関数の場合とは逆になる。 27.8 ウィンドウの再結合 ======================= ウィンドウ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が一時的にバッファーを表示するために使用されていて(*note Temporary Displays::を参照)、かつ初期のレイアウトで作業を継続したい場合 には直感に反するかもしれません。 この振る舞いはW2を分割する際に新たな親ウィンドウを作成することにより 解決できます。 -- User Option: window-combination-limit この変数はウィンドウ分割により新たに親ウィンドウを作成させるかどう かを制御する。以下の値が認識される: ‘nil’ これは既存のウィンドウコンビネーションと同じ方向で分割が発生し た場合(これ以外の場合には、いずれにせよ内部ウィンドウが新たに 作成される)は、既存の親ウィンドウが存在するなら新たな生きたウ ィンドウがそれを共有できることを意味する。 ‘window-size’ この場合には、‘display-buffer’はALIST引数内のエントリー ‘window-height’または‘window-width’に親ウィンドウが渡されれば 、新たに親ウィンドウを作成する(*note Display Action Functions::を参照)。 ‘temp-buffer’ この値は一時的なバッファーを表示するウィンドウの分割に際し新た に親ウィンドウを作成する。 ‘display-buffer’ これは‘display-buffer’ (*note Choosing Window::を参照)がウィン ドウを分割する際に常に親ウィンドウを新たに作成することを意味す る。 ‘t’ この場合にはウィンドウを分割する際、常に親ウィンドウが新たに作 成される。したがってこの変数の値が常に‘t’なら、すべてのウィン ドウツリーは常に2分木(ルートウィンドウ以外のすべてのウィンドウ が正確に1つの兄弟をもつようなツリー)になる。 デフォルトは‘nil’で、これら以外の値は将来のために予約済み。 この変数のセッティングの結果として‘split-window’が新たに親ウィンド ウを作成したら、新たに作成された内部ウィンドウにたいして ‘set-window-combination-limit’ (以下参照)も呼び出す。これは子ウィン ドウが削除された際のウィンドウツリーの再配置に影響する(以下参照)。 ‘window-combination-limit’が‘t’なら、このシナリオの初期構成では以下の ようになるでしょう: ______________________________________ | ____________________________________ | || __________________________________ || ||| ||| |||________________W2________________||| || __________________________________ || ||| ||| |||________________W4________________||| ||_________________W5_________________|| | ____________________________________ | || || || || ||_________________W3_________________|| |__________________W1__________________| 子としてW2と新たな生きたウィンドウをもつ内部ウィンドウW5が新たに作成され ます。ここでW2はW4の唯一の兄弟なので、W4を拡大するとW3は変更せずにW2の縮 小を試みるでしょう。W5は垂直コンビネーションW1に埋め込まれた2つのウィン ドウからなる垂直コンビネーションを表すことに注意してください。 -- Function: set-window-combination-limit window limit この関数はウィンドウWINDOWの“コンビネーションリミット(combination limit: 結合限界)”をLIMITにセットする。この値は関数 ‘window-combination-limit’を通じて取得できる。効果については以下を 参照のこと。これは内部ウィンドウにたいしてのみ意味をもつことに注意 。‘split-window’は呼び出された際に変数‘window-combination-limit’が ‘t’なら、‘t’をLIMITとしてこの関数を呼び出す。 -- Function: window-combination-limit window この関数はWINDOWにたいするコンビネーションリミットをリターンする。 コンビネーションリミットは内部ウィンドウにたいしてのみ意味をもつ。 これが‘nil’ならEmacsはウィンドウ削除に応じて、兄弟同士で新たなウィ ンドウコンビネーションを形成することによりWINDOWの子ウィンドウをグ ループ化するために、WINDOWの自動的な削除を許す。コンビネーションリ ミットが‘t’ならWINDOWの子ウィンドウがその兄弟と自動的に再結合される ことは決してない。 このセクションの冒頭で示した構成の場合は、W4 (W6とW7の親ウィンドウ )のコンビネーションリミットは‘t’なので‘t’を削除しても暗黙でW4も削除 されることはない。 かわりに同じ構成内の中の1つのウィンドウが分割や削除されたときは、常に 構成内のすべてのウィンドウをリサイズすることにより上記で示した問題を避け ることができます。これはそのような操作にたいして、この方法以外では小さす ぎるようなウィンドウの分割も可能にします。 -- User Option: window-combination-resize この変数が‘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つの生きたウィンドウに相対的に分配されます。 27.9 ウィンドウの選択 ===================== -- Function: select-window window &optional norecord この関数はWINDOWを選択されたウィンドウにして、そのフレーム内で選択 されたウィンドウ(*note Basic Windows::を参照)にしてそのフレームを選 択する。またWINDOWのバッファー(*note Buffers and Windows::を参照)を カレントにして、そのバッファーの‘point’の値(*note Window Point::を 参照)をWINDOWの‘window-point’の値にセットする。WINDOWは生きたウィン ドウでなければならない。リターン値はWINDOW。 この関数はデフォルトではWINDOWのバッファーをバッファーリストの先頭 (*note Buffer List::を参照)に移動して、WINDOWをもっとも最近選択され たウィンドウにする。しかしオプション引数NORECORDが非‘nil’ならこれら の追加処理は省略される。 この関数はNORECORDが‘nil’なら‘buffer-list-update-hook’ (*note Buffer List::)を実行する。コーディングを単純化するためにアプリケー ションや内部ルーチンは、しばしばウィンドウを一時的に選択することが あることに注意。一般的にはそのような選択(以下のマクロ ‘save-selected-window’と‘with-selected-window’による選択も含む)は記 録されないので、‘buffer-list-update-hook’の汚染は避けられる。選択を 実際にカウントするのはWINDOWのフレームの次回表示時に可視の変更が発 生したときで、それらは常に記録されるべきである。これは、あるウィン ドウが選択されるたびに関数を実行するためには、それを ‘buffer-list-update-hook’に配置するのが良い選択であることも意味して いる。 引数NORECORDに非‘nil’を指定した‘select-window’の連続呼び出しは、ウィ ンドウの並び順を選択時刻により決定します。関数‘get-lru-window’は、もっと も昔に選択された生きたウィンドウ(*note Cyclic Window Ordering::を参照)を 取得するために使用できます。 -- Macro: save-selected-window forms... このマクロは選択されたフレーム、同様に各フレームの選択されたウィン ドウを記録して、FORMSを順に実行してから以前に選択されていたフレーム とウィンドウをリストアする。これはカレントバッファーの保存とリスト アも行う。リターン値はFORMS内の最後のフォームの値。 このマクロはウィンドウのサイズ、コンテンツ、配置についての保存やリ ストアは何も行わない。したがってFORMSがそれらを変更すると、その変更 は永続化される。あるフレームにおいて以前に選択されていたウィンドウ がFORMSのexit時にすでに生きていなければ、そのフレームの選択されたウ ィンドウはそのまま放置される。以前に選択されていたウィンドウがすで に生きていなければFORMSの最後に選択されていたウィンドウが何であれ、 それが選択されたままになる。カレントバッファーFORMSのexit時にそれが 生きている場合のみリストアされる。 このマクロは、もっとも最近に選択されたウィンドウとバッファーリスト の順番をいずれも変更しない。 -- Macro: with-selected-window window forms... このマクロはWINDOWを選択して、FORMSを順に実行してから以前に選択され ていたウィンドウとカレントバッファーをリストアする。たとえば引数 NORECORDを‘nil’で‘select-window’を呼び出す等、FORMS内で故意に変更し ない限り、もっとも最近に選択されたウィンドウとバッファーリストの順 番は変更されない。 このマクロは、もっとも最近に選択されたウィンドウとバッファーリスト の順番を変更しない。 -- Function: frame-selected-window &optional frame この関数はフレームFRAME内で選択されているウィンドウをリターンする。 FRAMEは生きたフレームであること。省略または‘nil’の場合のデフォルト は選択されたフレーム。 -- Function: set-frame-selected-window frame window &optional norecord この関数はWINDOWをフレームFRAME内で選択されたウィンドウにする。 FRAMEは生きたフレームであること。省略または‘nil’の場合のデフォルト は選択されたフレーム。WINDOWは生きたウィンドウであること。省略また は‘nil’の場合のデフォルトは選択されたウィンドウ。 FRAMEが選択されたフレームなら、WINDOWを選択されたウィンドウにする。 オプション引数NORECORDが非‘nil’なら、この関数はもっとも最近に選択さ れたウィンドウのリストとバッファーリストをいずれも変更しない。 -- Function: window-use-time &optional window この関数はウィンドウWINDOWの使用回数をリターンする。WINDOWは生きた ウィンドウでなければならずデフォルトは選択されたウィンドウ。 ウィンドウの“使用回数(use time)”は実際にはtime値ではなく、‘nil’の NORECORD引数による‘select-window’の呼び出しごとに毎回単調に増加する 整数。通常は最小の使用回数をもつウィンドウはもっとも最近使用されて いないウィンドウ(the least recently used window)、最大の使用回数を もつウィンドウはもっとも最近使用されたウィンドウ(the most recently used window)と呼ばれる(*note Cyclic Window Ordering::を参照)。 27.10 ウィンドウのサイクル順 ============================ 他のウィンドウを選択するためにコマンド‘C-x o’ (‘other-window’)を使う際に は、特定の順番で生きたウィンドウを巡回します。与えられた任意のウィンドウ 構成にたいして、この順序は決して変更されません。これは“ウィンドウのサイ クル順序(cyclic ordering of windows)”と呼ばれます。 この順序は各フレームのリーフノードである生きたウィンドウを取得するた めに、ツリーを深さ優先で走査することにより決定されます(*note Windows and Frames::を参照)。ミニバッファーがアクティブならミニバッファーウィンドウ も含まれます。この順序は巡回的(cyclic)なので、この順序の最後のウィンドウ の次には最初のウィンドウが配置されます。 -- Function: next-window &optional window minibuf all-frames この関数はウィンドウのサイクル順でWINDOWの次の生きたウィンドウをリ ターンする。WINDOWは生きたウィンドウであること。省略または‘nil’の場 合のデフォルトは選択されたウィンドウ。 オプション引数MINIBUFは、サイクル順にミニバッファーウィンドウを含め るべきかどうかを指定する。MINIBUFが‘nil’のときは、通常はミニバッフ ァーウィンドウがカレントでアクティブな場合のみミニバッファーウィン ドウが含まれる。これは‘C-x o’の振る舞いと合致する(ミニバッファーが 使用されている限りミニバッファーウィンドウはアクティブであることに 注意。*note Minibuffers::を参照)。 MINIBUFが‘t’なら、サイクル順にはすべてのミニバッファーウィンドウが 含まれる。MINIBUFが‘t’と‘nil’のいずれとも異なる場合には、たとえアク ティブであってもミニバッファーウィンドウは含まれない。 オプション引数ALL-FRAMESは考慮にするフレームを指定する: • ‘nil’ はWINDOWのフレーム上にあるウィンドウを考慮することを意味 する。(MINIBUF引数で指定されたことにより)ミニバッファーウィン ドウが考慮される場合には、ミニバッファーウィンドウを共有するフ レームも考慮される。 • ‘t’ はすべての既存フレーム上のウィンドウを考慮することを意味す る。 • ‘visible’ はすべての可視フレーム上のウィンドウを考慮することを 意味する。 • 0 は可視またはアイコン化されたすべてのフレーム上のウィンドウを 考慮することを意味する。 • フレーム は指定されたフレーム上のウィンドウを考慮することを意 味する。 • その他 はWINDOWのあるフレーム上のウィンドウを考慮して、それ以 外は考慮しないことを意味する。 複数のフレームが考慮される場合は、すべての生きたフレームのリストの 順にしたがってそれらのフレームを順に追加することによりサイクル順を 取得する(*note Finding All Frames::を参照)。 -- Function: previous-window &optional window minibuf all-frames この関数はウィンドウのサイクル順においてWINDOWの前に位置する生きた ウィンドウをリターンする。その他の引数は‘next-window’の場合と同様に 処理される。 -- Command: other-window count &optional all-frames この関数はウィンドウのサイクル順において、選択されたウィンドウから COUNT番目に位置する生きたウィンドウをリターンする。COUNTが正の数な らCOUNT個のウィンドウを前方にスキップし、負の数なら−COUNT個のウィン ドウを後方にスキップする。COUNTが0なら選択されたウィンドウを単に再 選択する.インタラクティブに呼び出された場合には、COUNTはプレフィッ クス数引数。 オプション引数ALL-FRAMESは、‘nil’のMINIBUF引数を指定したときの ‘next-window’の場合と同じ意味をもつ。 この関数は非‘nil’のウィンドウパラメーター‘no-other-window’をもつウ ィンドウを選択しない。 -- Function: walk-windows fun &optional minibuf all-frames この関数は生きたウィンドウそれぞれにたいしてウィンドウを引数に関数 FUNを呼び出す。 これはウィンドウのサイクル順にしたがう。オプション引数MINIBUFと ALL-FRAMESには、含まれるウィンドウセットを指定する。これらは ‘next-window’の引数の場合と同じ意味をもつ。ALL-FRAMESがフレームを指 定する場合には、最初に処理されるのはそのフレームの最初のウィンドウ (‘frame-first-window’がリターンするウィンドウ)であり、選択されたウ ィンドウである必要はない。 FUNがウィンドウの分割や削除によりウィンドウ構成を変更する場合でも、 処理するウィンドウセットは初回のFUN呼び出しに先立ち決定されるため変 更されない。 -- Function: one-window-p &optional no-mini all-frames この関数は選択されたウィンドウが唯一の生きたウィンドウなら‘t’、それ 以外は‘nil’をリターンする。 ミニバッファーウィンドウがアクティブなら、ミニバッファーウィンドウ は通常は考慮される(そのためこの関数は‘nil’をリターンする)。しかしオ プション引数NO-MINIが非‘nil’なら、たとえアクティブであってもミニバ ッファーウィンドウは無視される。オプション引数ALL-FRAMESは ‘next-window’の場合と同じ意味をもつ。 以下は何らかの条件を満足するウィンドウを、それらを選択することなくリ ターンする関数です: -- Function: get-lru-window &optional all-frames dedicated not-selected この関数は発見的に最近もっとも使用されていない生きたウィンドウをリ ターンする。オプション引数ALL-FRAMESは‘next-window’の場合と同じ意味 をもつ。 フル幅のウィンドウが存在する場合にはは、それらのウィンドウだけが考 慮される。ミニバッファーが候補になることは決してない。オプション引 数DEDICATEDが‘nil’なら、専用バッファー(*note Dedicated Windows::を 参照)が候補になることは決してない。唯一の候補が選択されたウィンドウ である場合以外は選択されたウィンドウを決してリターンしない。しかし オプション引数NOT-SELECTEDが非‘nil’なら、そのような場合でもこの関数 は‘nil’をリターンする。 -- Function: get-mru-window &optional all-frames dedicated not-selected この関数は‘get-lru-window’と同様だが、かわりにもっとも最近使用され たウィンドウをリターンする。引数の意味は‘get-lru-window’で説明と同 様。 -- Function: get-largest-window &optional all-frames dedicated not-selected この関数は、もっとも大きいエリア(高さと幅の乗)をもつウィンドウをリ ターンする。オプション引数ALL-FRAMESは検索するウィンドウを指定する 。意味は‘next-window’の場合と同様。 ミニバッファーウィンドウは決して候補とならない。オプション引数 DEDICATEDが‘nil’なら、専用ウィンドウ(*note Dedicated Windows::ウィ ンドウを参照)は決して候補とならない。オプション引数NOT-SELECTEDが非 ‘nil’なら、選択されたウィンドウは決して候補にならない。オプション引 数NOT-SELECTEDが非‘nil’、かつ唯一の候補が選択されたウィンドウなら、 この関数は‘nil’をリターンする。 同サイズの候補ウィンドウが2つある場合には、この関数はウィンドウのサ イクル順で選択されたウィンドウから数えて最初にあるウィンドウを優先 する。 -- Function: get-window-with-predicate predicate &optional minibuf all-frames default この関数はウィンドウのサイクル順内の各ウィンドウにたいして、そのウ ィンドウを引数として関数PREDICATEを順に呼び出す。いずれかのウィンド ウにたいしてPREDICATEが非‘nil’をリターンすると、この関数は処理を停 止してそのウィンドウをリターンする。そのようなウィンドウが見つから なければリターン値はDEFAULT (これのデフォルトは‘nil’)。 オプション引数 MINIBUFとALL-FRAMESは検索するウィンドウを指定する。 意味は‘next-window’の場合と同様。 27.11 バッファーとウィンドウ ============================ このセクションではウィンドウのコンテンツを調べたりセットするための低レベ ルな関数を説明します。ウィンドウ内に特定のバッファーを表示するための高レ ベルな関数については*note Switching Buffers::を参照してください。 -- Function: window-buffer &optional window この関数はWINDOWが表示しているバッファーをリターンする。WINDOWが省 略または‘nil’の場合のデフォルトは選択されたウィンドウ。WINDOWが内部 ウィンドウならこの関数は‘nil’をリターンする。 -- Function: set-window-buffer window buffer-or-name &optional keep-margins この関数はWINDOWにBUFFER-OR-NAMEを表示させる。WINDOWは生きたウィン ドウであること。‘nil’の場合のデフォルトは選択されたウィンドウ。 BUFFER-OR-NAMEはバッファー、あるいは既存のバッファー名であること。 この関数は選択されていたウィンドウを変更せず、カレントバッファーも 直接変更しない(*note Current Buffer::を参照)。リターン値は‘nil’。 WINDOWがあるバッファーにたいして“特に専用(strongly dedicated)”であ り、かつBUFFER-OR-NAMEがそのバッファーを指定しなければ、この関数は エラーをシグナルする。*note Dedicated Windows::を参照のこと。 デフォルトでは、この関数は指定されたバッファーのローカル変数にもと づいてWINDOWの位置、ディスプレイマージン、フリンジ幅、スクロールバ ーのセッティングをリセットする。しかしオプション引数KEEP-MARGINSが 非‘nil’ならディスプレイマージンとフリンジ幅は未変更のままにする。 アプリケーションを記述する際には直接‘set-window-buffer’を呼び出さず に、通常は*note Switching Buffers::で説明する高レベルの関数を使用す ること。 これは‘window-scroll-functions’の後に ‘window-configuration-change-hook’を実行する。*note Window Hooks::を 参照のこと。 -- Variable: buffer-display-count このバッファーローカル変数はウィンドウ内にバッファーが表示された回 数を記録する。。これはそのバッファーにたいして‘set-window-buffer’が 呼び出されるたびに増分される -- Variable: buffer-display-time このバッファーローカル変数はバッファーがウィンドウに最後に表示され た時刻を記録する。バッファーが表示されたことがなければ‘nil’をリター ンする。これはそのバッファーにたいして‘set-window-buffer’が呼び出さ れるたびに‘current-time’がリターンする値により更新される(*note Time of Day::を参照)。 -- Function: get-buffer-window &optional buffer-or-name all-frames この関数はウィンドウのサイクル順内で選択されたウィンドウを起点に、 BUFFER-OR-NAMEを表示する最初のウィンドウをリターンする(*note Cyclic Window Ordering::を参照)。そのようなウィンドウが存在しなければリタ ーン値は‘nil’。 BUFFER-OR-NAMEはバッファーかバッファーの名前であること。省略または ‘nil’の場合のデフォルトはカレントバッファー。オプション引数 ALL-FRAMESには考慮するウィンドウを指定する。 • ‘t’はすべての既存フレーム上のウィンドウを考慮することを意味す る。 • ‘visible’はすべての可視フレーム上のウィンドウを考慮することを 意味する。 • 0はすべての可視またはアイコン化されたフレーム上のウィンドウを 考慮することを意味する。 • フレームを指定すると、そのフレーム上のウィンドウだけを考慮する ことを意味する。 • その他の値は選択されたフレーム上のウィンドウを考慮することを意 味する。 これらの意味は‘next-window’のALL-FRAMES引数の場合とは若干異なること に注意(*note Cyclic Window Ordering::を参照)。この不一致の解消のた めにEmacsの将来のバージョンにおいて、この関数は変更されるかもしれな い。 -- Function: get-buffer-window-list &optional buffer-or-name minibuf all-frames この関数はその時点でBUFFER-OR-NAMEを表示している、すべてのウィンド ウのリストをリターンする。BUFFER-OR-NAMEはバッファーまたは既存バッ ファーの名前であること。省略または‘nil’の場合のデフォルトはカレント バッファー。カレントで選択されたウィンドウがBUFFER-OR-NAMEを表示し ていれば、それはこの関数がリターンするリストの先頭となる。 引数MINIBUFとALL-FRAMESは、関数‘next-window’の場合と同じ意味をもつ (*note Cyclic Window Ordering::を参照)。ALL-FRAMES引数は、 ‘get-buffer-window’の場合と正確に同じようには_振る舞わない_ことに注 意。 -- Command: replace-buffer-in-windows &optional buffer-or-name このコマンドはBUFFER-OR-NAMEを表示しているすべてのウィンドウで、そ れを他の何らかのバッファーに置き換える。BUFFER-OR-NAMEはバッファー または既存のバッファーの名前であること。省略または‘nil’の場合のデフ ォルトはカレントバッファー。 各ウィンドウで置き換えられるバッファーは‘switch-to-prev-buffer’を通 じて選択される(*note Window History::を参照)。BUFFER-OR-NAMEを表示 している専用ウィンドウは可能ならすべて削除される(*note Dedicated Windows::を参照)。そのようなウィンドウがそのフレームで唯一のウィン ドウで、かつ同一端末上に他のフレームが存在する場合には、そのフレー ムも同様に削除される。その端末上の唯一のフレームの唯一のウィンドウ の場合は、いずれにせよそのバッファーは置き換えられる。 27.12 ウィンドウ内のバッファーへの切り替え ========================================== このセクションでは、あるウィンドウ内で特定のバッファーにスイッチするため の高レベルな関数について説明します。“バッファーをスイッチする”とは一般的 に、(1)そのバッファーをあるウィンドウに表示して、(2)そのウィンドウを選択 されたウィンドウとし(かつそのフレームを選択されたフレームとし)、(3)その バッファーウィンドウカレントバッファーにすることを意味します。 Lispプログラムがアクセスや変更できるように、バッファーを一時的にカレ ントにするためにこれらの関数を_使用しないでください_。これらはウィンドウ ヒストリー(*note Window History::を参照)の変更のような副作用をもつので、 そのような方法での使用はユーザーを驚かせることになるでしょう。バッファー をLispで変更するためにカレントにしたければ‘with-current-buffer’、 ‘save-current-buffer’、‘set-buffer’を使用してください。*note Current Buffer::を参照してください。 -- Command: switch-to-buffer buffer-or-name &optional norecord force-same-window このコマンドは選択されたウィンドウ内でBUFFER-OR-NAMEを表示して、そ れをカレントバッファーにしようと試みる。これはよくインタラクティブ (‘C-x b’のバインディングで)に使用され、同様にLispプログラムでも使用 される。リターン値はスイッチしたバッファー。 BUFFER-OR-NAMEが‘nil’の場合のデフォルトは‘other-buffer’によりリター ンされるバッファー(*note Buffer List::を参照)。BUFFER-OR-NAMEが既存 のバッファーの名前でない文字列なら、この関数はその名前で新たにバッ ファーを作成する。新たなバッファーのメジャーモードは変数 ‘major-mode’により決定される(*note Major Modes::を参照)。 通常は指定されたバッファーはバッファーリスト — グローバルバッファー リストと選択されたフレームのバッファーリストの両方の先頭に置かれる (*note Buffer List::を参照)。しかしオプション引数NORECORDが非 ‘nil’なら、これは行われない。 選択されたウィンドウにそのバッファーを表示することが不適切なことも あるだろう。これは選択されたウィンドウがミニバッファーウィンドウの 場合、および選択されたウィンドウがそのバッファーに特に専用(*note Dedicated Windows::を参照)な場合に発生する。そのようなケースでは、 このコマンドは‘pop-to-buffer’ (以下参照)を呼び出すことにより、通常 は別のウィンドウにバッファーの表示を試みる。 オプション引数FORCE-SAME-WINDOWが非‘nil’、かつ選択されたウィンドウ がそのバッファーの表示に不適切なら、非インタラクティブに呼び出され た際にはこの関数は常にエラーをシグナルする。インタクラクティブな使 用においては、もし選択されたウィンドウがミニバッファーウィンドウな ら、この関数はかわりに別のウィンドウの使用を試みる。選択されたウィ ンドウがそのバッファーにたいして特に専用なら、次に説明するオプショ ン‘switch-to-buffer-in-dedicated-window’が使用される。 -- User Option: switch-to-buffer-in-dedicated-window このオプションが非‘nil’なら、‘switch-to-buffer’がインタラクティブに 呼び出されて、かつ選択されたウィンドウがそのバッファーに特に専用な 際に、処理を先に進めることが許される、 以下の値が許される: ‘nil’ 切り替えを許さず非インタラクティブな使用ではエラーをシグナルす る。 ‘prompt’ 切り替えを許すかどうかユーザーに確認を求める。 ‘pop’ 処理を行うために‘pop-to-buffer’を呼び出す。 ‘t’ 選択されたウィンドウを非専用としてマークして処理を進める。 このオプションは非インタラクティブな‘switch-to-buffer’の呼び出しに は影響しない。 デフォルトでは‘switch-to-buffer’はバッファーの‘point’位置でバッファー を表示します。この振る舞いは以下のオプションを使用して調整可能です。 -- User Option: switch-to-buffer-preserve-window-point この変数が‘nil’なら、‘switch-to-buffer’はBUFFER-OR-NAMEにより指定さ れたバッファーを、そのバッファーの‘point’位置で表示する。この変数が ‘already-displayed’なら、そのバッファーが任意の可視またはアイコン化 されたフレーム上の他のウィンドウで表示されていれば、選択されたウィ ンドウ内の以前の位置でバッファーの表示を試みる。この変数が‘t’なら、 ‘switch-to-buffer’は選択されたウィンドウ内の以前の位置でそのバッフ ァーを表示しようと試みる。 この変数はバッファーがすでに選択されたウィンドウに表示されている、 これまで表示されたことがない、またはバッファーを表示するために ‘switch-to-buffer’が‘pop-to-buffer’を呼び出した場合には無視される。 以下の2つのコマンドは、説明している機能以外は‘switch-to-buffer’と類似 しています。 -- Command: switch-to-buffer-other-window buffer-or-name &optional norecord この関数はBUFFER-OR-NAMEで指定されたバッファーを、選択されたウィン ドウ以外の別のウィンドウに表示する。これは関数‘pop-to-buffer’(以下 参照)を内部で使用する。 選択されたウィンドウが指定されたバッファーをすでに表示していれば表 示を続けるが、見つかった他のウィンドウも同様にそのバッファーを表示 する。 引数BUFFER-OR-NAMEとNORECORDは‘switch-to-buffer’の場合と同じ意味を もつ。 -- Command: switch-to-buffer-other-frame buffer-or-name &optional norecord この関数は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’の ドキュメントについては*note Choosing Window::を参照してください。 -- Command: pop-to-buffer buffer-or-name &optional action norecord この関数はBUFFER-OR-NAMEをカレントバッファーにして、なるべくカレン トで選択されていたウィンドウではないウィンドウにそれを表示する。そ してその後に表示しているウィンドウを選択する。そのウィンドウが別の グラフィカルなフレーム上にある場合には、可能ならそのフレームが入力 フォーカスを与えられる(*note Input Focus::を参照)。リターン値は切り 替えたバッファー。 BUFFER-OR-NAMEが‘nil’の場合のデフォルトは‘other-buffer’によりリター ンされるバッファー(*note Buffer List::を参照)。BUFFER-OR-NAMEが既存 のバッファーの名前でない文字列なら、この関数はその名前で新たにバッ ファーを作成する。新たなバッファーのメジャーモードは変数 ‘major-mode’により決定される(*note Major Modes::を参照)。 ACTIONが非‘nil’なら、それは‘display-buffer’に渡すディスプレイアクシ ョン(display action)であること(*note Choosing Window::を参照)。非 ‘nil’か非リスト値なら、たとえそのバッファーがすでに選択されたウィン ドウに表示されていたとしても、選択されたウィンドウではなく別のウィ ンドウをポップ(pop)することを意味する。 この関数は‘switch-to-buffer’と同じように、NORECORDが‘nil’ならバッフ ァーリストを更新する。 27.13 表示するウィンドウの選択 ============================== コマンド‘display-buffer’は表示のために柔軟にウィンドウを選択して、そのウ ィンドウ内に指定されたバッファーを表示します。これはキーバインディング ‘C-x 4 C-o’を通じてインタラクティブに呼び出すことができます。また ‘switch-to-buffer’や‘pop-to-buffer’を含む多くの関数やコマンドにからサブ ルーチンとしても使用されます(*note Switching Buffers::を参照)。 このコマンドはウィンドウ内に表示するウィンドウを探すために、いくつか の複雑なステップを実行します。これらのステップは“ディスプレイアクション (display actions)”を用いて記述されます。ディスプレイアクションは ‘(FUNCTION . ALIST)’という形式をもちます。ここで、FUNCTIONは関数か関数リ ストであり、わたしたちはこれを“アクション関数(action functions)”として参 照します。ALISTは連想リスト(association list)で、わたしたちはこれを“アク ションalist(action alist)”として参照します。 アクション関数は表示するバッファーとアクションalistという、2つの引数 を受け取ります。これは自身の条件にしたがってウィンドウウィンドウ選択また は作成して、バッファーをウィンドウ内に表示します。成功した場合はそのウィ ンドウ、それ以外は‘nil’をリターンします。事前定義されたアクション関数に ついては*note Display Action Functions::を参照してください。 ‘display-buffer’は複数ソースからのディスプレイアクションを組み合わせ て、アクション関数のいずれか1つがバッファーの表示を管理して非‘nil’値をリ ターンするまでアクション関数を順に呼び出します。 -- Command: display-buffer buffer-or-name &optional action frame このコマンドは、ウィンドウウィンドウ選択したり、そのバッファーをカ レントにすることなく、BUFFER-OR-NAMEをウィンドウに表示させる。引数 BUFFER-OR-NAMEはバッファー既存のバッファーの名前でなければならない 。リターン値はそのバッファーを表示するために選ばれたウィンドウ。 オプション引数ACTIONが非‘nil’なら、それは通常はディスプレイアクショ ン(上述)であること。‘display-buffer’は以下のソース(記載順)からディ スプレイアクションを集約して、アクション関数リストとアクション alistを構築する: • 変数‘display-buffer-overriding-action’。 • ユーザーオプション‘display-buffer-alist’。 • ACTION引数。 • ユーザーオプション‘display-buffer-base-action’。 • 定数‘display-buffer-fallback-action’。 各アクション関数は、いずれかが非‘nil’をリターンするまで第1引数にバ ッファー、第2引数に組み合わせられたアクションalistで順番に呼び出さ れる。呼び出し側はウィンドウ内にバッファーを表示しない場合を処理す る用意があることを示すために、アクションalistの要素として ‘(allow-no-window . t)’を渡すことができる。 引数ACTIONには非‘nil’の非list値も指定できる。これはたとえ選択された ウィンドウがすでにそのバッファーを表示していても、選択されたウィン ドウではない別のウィンドウにバッファーが表示されるべきだという特別 な意味をもつ。プレフィックス引数とともにインタラクティブに呼び出さ れた場合には、ACTIONは‘t’である。 オプション引数FRAMEが非‘nil’なら、そのバッファーがすでに表示されて いるか判断する際に、どのフレームをチェックするかを指定する。これは ACTIONのアクションalistに要素‘(reusable-frames . FRAME)’を追加する のと等価。*note Display Action Functions::を参照のこと。 -- Variable: display-buffer-overriding-action この変数の値は、‘display-buffer’により最高の優先順で扱われるディス プレイアクションであること。デフォルト値は空(つまり‘(nil . nil)’)。 -- User Option: display-buffer-alist このオプションの値はディスプレイアクションにコンディション (condition: 状態)をマップするalist。コンディションはそれぞれバッフ ァー名にマッチする正規表現か2つの引数をとる関数であり、引数はバッフ ァー名と‘display-buffer’に渡すACTION引数である。‘display-buffer’に 渡されたバッファー名がこのalist内の正規表現にマッチするか、コンディ ションで指定された関数が非‘nil’をリターンした場合、 ‘display-buffer’はバッファーを表示すために対応するディスプレイアク ションを使用する。 -- User Option: display-buffer-base-action このオプションの値はディスプレイアクションであること。このオプショ ンは‘display-buffer’呼び出しにたいする標準のディスプレイアクション を定義するために使用できる。 -- Constant: display-buffer-fallback-action このディスプレイアクションは‘display-buffer’にたいして、他のディス プレイアクションが与えられなかった場合の代替え処理を指定する。 27.14 ‘display-buffer’にたいするアクション関数 ============================================== 以下の基本的なアクション関数がEmacs内で定義されています。これらの関数は それぞれ表示するバッファーBUFFERとアクションalistという2つの引数をとりま す。それぞれのアクション関数は成功したらウィンドウ、失敗したら‘nil’をリ ターンします。 -- Function: display-buffer-same-window buffer alist この関数は選択されたウィンドウ内にBUFFERの表示を試みる。選択された ウィンドウがミニバッファーウィンドウや他のバッファー専用(*note Dedicated Windows::を参照)の場合には失敗する。ALISTに非‘nil’の ‘inhibit-same-window’エントリーがある場合にも失敗する。 -- Function: display-buffer-reuse-window buffer alist この関数はすでにBUFFERを表示しているウィンドウを探すことによりバッ ファーの表示を試みる。 ALISTに非‘nil’の‘inhibit-same-window’エントリーがある場合には、選択 されたウィンドウは再利用に適さない。ALISTに‘reusable-frames’エント リーが含まれる場合には、その値により再利用可能なウィンドウをどのフ レームで検索するか決定される: • ‘nil’は選択されたフレーム(実際には最後の非ミニバッファーフレー ム)上のウィンドウを考慮することを意味する。 • ‘t’はすべてのフレーム上のウィンドウを考慮することを意味する。 • ‘visible’はすべての可視フレーム上のウィンドウを考慮することを 意味する。 • 0はすべての可視またはアイコン化されたフレーム上のウィンドウを 考慮することを意味する。 • フレームを指定すると、そのフレーム上のウィンドウだけを考慮する ことを意味する。 これらは‘next-window’にたいするALL-FRAMES引数の場合とは若干異なるこ とに注意(*note Cyclic Window Ordering::を参照)。 ALISTに‘reusable-frames’エントリーが含まれなければ、この関数は通常 は選択されたフレームだけを検索する。しかし変数‘pop-up-frames’が非 ‘nil’ならカレント端末上のすべてのフレームを検索する。*note Choosing Window Options::を参照。 この関数が他のフレーム上のウィンドウを選択した場合には、そのフレー ムを可視にするとともに、ALISTが‘inhibit-switch-frame’エントリー (*note Choosing Window Options::を参照)を含んでいなければ必要ならそ のフレームを最前面に移動(raise)する。 -- Function: display-buffer-pop-up-frame buffer alist この関数は新たにフレームを作成して、そのフレームのウィンドウ内にバ ッファーを表示する。これは実際には‘pop-up-frame-function’ (*note Choosing Window Options::を参照)内で指定された関数を呼び出すことに よりフレーム作成の処理を行う。ALISTが‘pop-up-frame-parameters’エン トリーを含む場合には、その連想値(associated value)が新たに作成され たフレームのパラメーターに追加される。 -- Function: display-buffer-use-some-frame buffer alist この関数は述語(デフォルトではカレント以外のすべてのフレーム)に合致 するフレームを探すことによりBUFFERの表示を試みる。 この関数が他のフレーム上のウィンドウを選択した場合には、そのフレー ムを可視にするとともに、ALISTが‘inhibit-switch-frame’エントリー (*note Choosing Window Options::を参照)を含んでいなければ必要ならそ のフレームを最前面に移動(raise)する。 ALISTに非‘nil’の‘frame-predicate’エントリーがあれば、その値は1つの 引数(フレーム)を受け取ってそのフレームが候補なら非‘nil’をリターンす る、デフォルトの述語を置き換える関数。 ALISTに非‘nil’の‘inhibit-same-window’エントリーがあれば、選択された ウィンドウが使用される。つまり選択されたフレームにウィンドウが1つし かなければ、それは使用しない。 -- Function: display-buffer-pop-up-window buffer alist この関数は、最大のウィンドウ、もしくはもっとも長い間参照されていな い(LRU: least recently-used)ウィンドウを分割することによりBUFFERの 表示を試みる。これは実際には‘split-window-preferred-function’ (*note Choosing Window Options::を参照)内で指定された関数を呼び出す ことによって分割を行う。 新たなウィンドウのサイズはALISTにエントリー‘window-height’と ‘window-width’を与えることにより調整できる。ウィンドウの高さを調整 するにはCARが‘window-height’、CDRが以下のいずれかであるようなエント リーを使用する: • ‘nil’は新たなウィンドウの高さを変更しないことを意味する。 • 数字は新たなウィンドウの高さを指定する。整数はウィンドウの行数 、浮動小数点数はそのフレームのルートウィンドウにたいするウィン ドウの高さの割合を与える。 • CDRが関数を指定する場合、その関数は新たなウィンドウを引数とし て呼び出される関数である。この関数はそのウィンドウの高さを調整 することを期待されておりリターン値は無視される。これに適した関 数は‘shrink-window-if-larger-than-buffer’と ‘fit-window-to-buffer’。*note Resizing Windows::を参照のこと。 ウィンドウの幅を調整するにはCARが‘window-width’、CDRが以下のいずれ かであるようなエントリーを使用する: • ‘nil’は新たなウィンドウの幅を変更しないことを意味する。 • 数字は新たなウィンドウの幅を指定する。整数はウィンドウの列数、 浮動小数点数はそのフレームのルートウィンドウにたいするウィンド ウの幅の割合を与える。 • CDRが関数を指定する場合、その関数は新たなウィンドウを引数とし て呼び出される関数である。この関数はそのウィンドウの幅を調整す ることを期待されておりリターン値は無視される。 ALISTに‘preserve-size’エントリーが含まれるなら、Emacsは将来のリサイ ズ操作における、新たなウィンドウのサイズの予約を試みる(*note Preserving Window Sizes::を参照)。このエントリーのCDRはコンスセルで なければならない。このコンスセルのCARが非‘nil’ならウィンドウの幅を 予約し、CDRが非‘nil’ならウィンドウの高さを予約することを意味する。 この関数は何らかの理由により分割を行えるウィンドウが存在しなければ 失敗する可能性がある(選択されたフレームがフレームパラメーター ‘unsplittable’をもつ場合等。*note Buffer Parameters::を参照)。 -- Function: display-buffer-below-selected buffer alist この関数は選択されたウィンドウの下のウィンドウ内にBUFFERの表示を試 みる。これは選択されたウィンドウの分割、または選択されたウィンドウ の下のウィンドウの使用を意味する。新たにウィンドウを作成した場合に は、ALISTに適切な‘window-height’または‘window-width’エントリーが含 まれていればサイズの調整も行うだろう。上記を参照のこと。 -- Function: display-buffer-in-previous-window buffer alist この関数は以前にBUFFERを表示していたウィンドウ内にそのバッファーの 表示を試みる。ALISTに非‘nil’の‘inhibit-same-window’エントリーがある 場合には、選択されたウィンドウは再利用に適さない。ALISTに ‘reusable-frames’エントリーが含まれる場合には、 ‘display-buffer-reuse-window’と同様に、その値は適正なウィンドウをど のフレームから検索するかを決定する。 ALISTに‘previous-window’エントリーがある場合には、そのエントリーに より指定されたウィンドウは、たとえそのウィンドウが以前にBUFFERを表 示したことが一度もなくても、上記メソッドが見つけた他のすべてのウィ ンドウをオーバーライドするだろう。 -- Function: display-buffer-at-bottom buffer alist この関数は選択されたフレームの最下にあるウィンドウ内にBUFFERの表示 を試みる。 これはフレーム最下のウィンドウまたはフレームのルートウィンドウを分 割するか、選択されたフレーム最下の既存ウィンドウを再利用する。 -- Function: display-buffer-use-some-window buffer alist この関数は既存のウィンドウを選択して、そのウィンドウ内にBUFFERを表 示することによりバッファーの表示を試みる。すべてのウィンドウが他の バッファー専用なら、この関数は失敗する可能性がある(*note Dedicated Windows::を参照)。 -- Function: display-buffer-no-window buffer alist この関数はALISTに非‘nil’の‘allow-no-window’エントリーがある場合には ‘buffer’を表示しない。これによりデフォルトの動作をオーバーライドし てバッファーの表示を避けることができる。これは呼び出し側が ‘allow-no-window’に非‘nil’値を指定して‘display-buffer’からリターン された‘nil’値を処理するようなケースを想定している。 アクション関数を説明するために以下の例を考えてみましょう。 (display-buffer (get-buffer-create "*foo*") '((display-buffer-reuse-window display-buffer-pop-up-window display-buffer-pop-up-frame) (reusable-frames . 0) (window-height . 10) (window-width . 40))) 上記のフォームを評価することにより、以下のように‘display-buffer’が実行さ れます: (1)*foo*と呼ばれるバッファーがすでに可視またはアイコン化されたフ レームに表示されていればそのウィンドウを再利用する。 (2)それ以外なら新た なウィンドウをポップアップ、それが不可能なら新たなフレームでバッファーを 表示する。(3) すべてのステップが失敗すると、それが何であれ ‘display-buffer-base-action’と‘display-buffer-fallback-action’が指示する ものを使用して処理を行う。 さらに‘display-buffer’は、(‘display-buffer’により*foo*が前からそこに 配置されていたら)再使用されるウィンドウ、およびポップアップされたウィン ドウにたいして調整を試みます。そのウィンドウが垂直コンビネーションの一部 なら高さはその行数にセットされるでしょう。数字10のかわりに関数 ‘fit-window-to-buffer’を指定すると、‘display-buffer’は空のバッファーにフ ィットするようにウィンドウを1行にセットするでしょう。ウィンドウが水平コ ンビネーションの一部なら列数を40にセットします。新たなウィンドウが垂直ま たは水平のどちらに組み合わせられるかは、ウィンドウの分割方向と ‘split-window-preferred-function’、‘split-height-threshold’、 ‘split-width-threshold’の値に依存します(*note Choosing Window Options::を 参照)。 事前に以下のような‘display-buffer-alist’にたいするセットアップがあり 、この呼び出しを組み合わせたとしましょう。 (let ((display-buffer-alist (cons '("\\*foo\\*" (display-buffer-reuse-window display-buffer-below-selected) (reusable-frames) (window-height . 5)) display-buffer-alist))) (display-buffer (get-buffer-create "*foo*") '((display-buffer-reuse-window display-buffer-pop-up-window display-buffer-pop-up-frame) (reusable-frames . 0) (window-height . 10) (window-width . 40)))) このフォームはまず選択されたフレーム上で*foo*を表示しているウィンドウを 再利用するように‘display-buffer’に試行させます。そのようなウィンドウが存 在しなければ、選択されたウィンドウの分割を試みるか、それが不可能なら選択 されたウィンドウの下のウィンドウを使用します。 選択されたウィンドウの下にウィンドウがないか、下のウィンドウがそれの バッファーに専用なら、‘display-buffer’は前の例で説明したように処理を行う でしょう。しかし再利用されたウィンドウやポップアップされたウィンドウの高 さ調整を試みる場合には、‘display-buffer’のACTION引数内の行数に対応する指 定をオーバーライドする行数5へのセットを試みることに注意してください。 27.15 バッファー表示の追加オプション ==================================== さまざまなユーザーオプションにより‘display-buffer’の標準のディスプレイア クション(*note Choosing Window::を参照)を変更できます。 -- User Option: pop-up-windows この変数の値が非‘nil’なら、‘display-buffer’は表示のために既存のバッ ファーを分割して新たなウィンドウを作成できる。 この変数は主に後方互換のために提供される。値が‘nil’のときはアクショ ン関数‘display-buffer-pop-up-window’ (*note Display Action Functions::を参照)を呼び出すだけの ‘display-buffer-fallback-action’内の特別なメカニズムを経由して ‘display-buffer’にしたがう。この変数は‘display-buffer-alist’等によ り直接指定できる、‘display-buffer-pop-up-window’自体からは参照され ない。 -- User Option: split-window-preferred-function この変数はバッファーを表示する新たなウィンドウを作成するためにウィ ンドウを分割する関数を指定する。これは実際にウィンドウを分割するた めにアクション関数‘display-buffer-pop-up-window’により使用される (*note Display Action Functions::を参照)。 デフォルト値‘split-window-sensibly’は以下で説明する。値はウィンドウ を引数とする関数でなければならず、(要求されたバッファーを表示するた めに使用されるであろう)新たなウィンドウ、または‘nil’ (分割の失敗を 意味する)をリターンしなければならない。 -- Function: split-window-sensibly &optional window この関数はWINDOWを分割して新たに作成したウィンドウをリターンする。 WINDOWを分割できなければ‘nil’をリターンする。WINDOWが省略または ‘nil’の場合のデフォルトは選択されたウィンドウ。 この関数はウィンドウが分割できるかどうか判断する際の通常のルールに したがう(*note Splitting Windows::を参照)。最初にまず ‘split-height-threshold’ (以下参照)とその他が課す制約の下に新たなウ ィンドウが下になるように分割を試みる。これが失敗したら ‘split-width-threshold’ (以下参照)が課す制約の下に新たなウィンドウ が右になるように分割を試みる。これが失敗かつそのウィンドウがそのフ レームの唯一のウィンドウなら、この関数は‘split-height-threshold’を 無視して新たなウィンドウが下になるように再度分割を試みる。これも同 様に失敗したら、この関数は諦めて‘nil’をリターンする。 -- User Option: split-height-threshold これは‘split-window-sensibly’により使用される変数であり、ウィンドウ を分割して新たなウィンドウを下に配置するかどうかを指定する。整数な ら元のウィンドウが最低でもその行数なければ分割せず、‘nil’ならこの方 法では分割しないことを意味する。 -- User Option: split-width-threshold これは‘split-window-sensibly’により使用される変数であり、ウィンドウ を分割して新たなウィンドウを右に配置するかどうかを指定する。整数な ら元のウィンドウが最低でもその列数なければ分割せず、‘nil’ならこの方 法では分割しないことを意味する。 -- User Option: even-window-sizes この変数が非‘nil’なら、‘display-buffer’が既存ウィンドウを再利用する 際は常にウィンドウサイズを選択されたウィンドウを均等にして、そのウ ィンドウを選択されたウィンドウに隣接させる。 値が‘width-only’なら再利用されるウィンドウが選択されたウィンドウの 左か右にあり、かつ選択されたウィンドウが再利用されるウィンドウより 広い場合のみサイズは均等になる。値が‘height-only’なら再利用されるウ ィンドウが選択されたウィンドウの上か下にあり、かつ選択されたウィン ドウが再利用されるウィンドウより高い場合のみサイズは均等になる。そ の他の非‘nil’値は、選択されたウィンドウと再利用されるウィンドウをコ ンビネーション的に比較して選択されたウィンドウの方が大ならサイズを 均等にすることを意味する。 -- User Option: pop-up-frames この変数の値が非‘nil’なら、新たにフレームを作成することにより ‘display-buffer’がバッファーを表示できることを意味する。デフォルト は‘nil’。 非‘nil’値は‘display-buffer’がすでにBUFFER-OR-NAMEを表示しているウィ ンドウを探す際に、選択されたフレームだけでなく可視およびアイコン化 されたフレームを検索できることも意味する。 この変数は主に後方互換のために提供されている。値が非‘nil’のときはア クション関数‘display-buffer-pop-up-frame’ (*note Display Action Functions::を参照)を呼び出すだけの ‘display-buffer-fallback-action’内の特別なメカニズムを経由して ‘display-buffer’にしたがう。この変数は‘display-buffer-alist’等によ り直接指定できる、‘display-buffer-pop-up-window’自体からは参照され ない(これはウィンドウの分割前に行われる)。この変数は ‘display-buffer-alist’等により直接指定できる ‘display-buffer-pop-up-frame’自体からは参照されない。 -- User Option: pop-up-frame-function この変数はバッファーを表示する新たなウィンドウを作成するためにフレ ームを作成する関数を指定する。これはアクション関数 ‘display-buffer-pop-up-frame’により使用される(*note Display Action Functions::を参照)。 値はフレーム、またはフレームを作成できなかったら‘nil’をリターンする 引数をとらない関数であること。デフォルト値は‘pop-up-frame-alist’ (以 下参照)により指定されるパラメーターを使用してフレームを作成する関数 。 -- User Option: pop-up-frame-alist この変数はフレームを新たに作成するための‘pop-up-frame-function’のデ フォルト関数により使用されるフレームパラメーター(*note Frame Parameters::を参照)のalistを保持する。デフォルトは‘nil’。 -- User Option: same-window-buffer-names 選択されたウィンドウ内に表示されるべきバッファー名のリスト。このリ スト内にバッファーの名前があれば、‘display-buffer’は選択されたウィ ンドウ内にそのバッファーを表示することによりそのバッファーを処理す る。 -- User Option: same-window-regexps 選択されたウィンドウ内に表示されるバッファーを指定する正規表現のリ スト。バッファー名がこのリスト内の正規表現のいずれかにマッチする場 合には、‘display-buffer’は選択されたウィンドウ内にそのバッファーを 表示することによりそのバッファーを処理する。 -- Function: same-window-p buffer-name この関数はBUFFER-NAMEという名前のバッファーを‘display-buffer’で表示 する場合に、それが選択されたウィンドウ内に表示されるバッファーなら ‘t’をリターンする。 27.16 ウィンドウのヒストリー ============================ ウィンドウはそれぞれリスト内に以前表示されていたバッファーと、それらのバ ッファーがウィンドウから削除された順序を記憶しています。このヒストリーが 、たとえば‘replace-buffer-in-windows’ (*note Buffers and Windows::を参照 )により使用されます。このリストはEmacsにより自動的に保守されますが、これ を明示的に調べたり変更するために以下の関数を使用できます: -- Function: window-prev-buffers &optional window この関数はWINDOWの前のコンテンツを指定するリストをリターンする。オ プション引数WINDOWには生きたウィンドウを指定すること。デフォルトは 選択されたウィンドウ。 リスト要素はそれぞれ‘(BUFFER WINDOW-START WINDOW-POS)’という形式を もつ。ここでBUFFERはそのウィンドウで前に表示されていたウィンドウ、 WINDOW-STARTはそのバッファーが最後に表示されていたときのウィンドウ のスタート位置(*note Window Start and End::を参照)、WINDOW-POSは WINDOW内にそのバッファーが最後に表示されていたときのポイント位置 (*note Window Point::を参照)。 このリストは順序付きであり、より前の要素がより最近に表示されたバッ ファーに対応してして、通常は最初の要素がそのウィンドウからもっとも 最近削除されたバッファーに対応する。 -- Function: set-window-prev-buffers window prev-buffers この関数はWINDOWの前のバッファーをPREV-BUFFERSの値にセットする。引 数WINDOWは生きたウィンドウでなければならず、デフォルトは選択された ウィンドウ。引数PREV-BUFFERSは‘window-prev-buffers’によりリターンさ れるリストと同じ形式であること。 これらに加えて、それぞれのバッファーは“次バッファー(next buffers)”の リストを保守します。これは‘switch-to-prev-buffer’ (以下参照)により再表示 されたバッファーのリストです。このリストは主に切り替えるバッファーを選択 するために、‘switch-to-prev-buffer’と‘switch-to-next-buffer’により使用さ れます。 -- Function: window-next-buffers &optional window この関数は‘switch-to-prev-buffer’を通じてWINDOW内に最近表示されたバ ッファーのリストをリターンする。WINDOW引数は生きたウィンドウか‘nil’ (選択されたウィンドウの意)でなければならない。 -- Function: set-window-next-buffers window next-buffers この関数はWINDOWの次バッファーリストをNEXT-BUFFERSにセットする。 WINDOW引数は生きたウィンドウか‘nil’ (選択されたウィンドウの意)、引 数NEXT-BUFFERSはバッファーのリストであること。 以下のコマンドは‘bury-buffer’や‘unbury-buffer’のように、グローバルバ ッファーリストを巡回するために使用できます。ただしこれらはグローバルバッ ファーリストではなく、指定されたウィンドウのヒストリーリストのしたがって 巡回します。それに加えてこれらはウィンドウ固有なウィンドウのスタート位置 とポイント位置をリストアして、すでに他のウィンドウに表示されているバッフ ァーをも表示できます。特に‘switch-to-prev-buffer’コマンドは、ウィンドウ にたいする置き換えバッファーを探すために‘replace-buffer-in-windows’、 ‘bury-buffer’、‘quit-window’により使用されます。 -- Command: switch-to-prev-buffer &optional window bury-or-kill このコマンドはWINDOW内に前のバッファーを表示する。引数WINDOWは生き たウィンドウか‘nil’ (選択されたウィンドウの意)であること。オプショ ン引数BURY-OR-KILLが非‘nil’なら、それはWINDOW内にカレントで表示され ているバッファーは今まさにバリーもしくはkillされるバッファーであり 、したがって将来におけるこのコマンドの呼び出しでこのバッファーに切 り替えるべきではないことを意味する。 前のバッファーとは、通常はWINDOW内にカレントで表示されているバッフ ァーの前に表示されていたバッファーである。しかしバリーやkillされた バッファー、または直近の‘switch-to-prev-buffer’呼び出しですでに表示 されたバッファーは前のバッファーとしては不適格となる。 このコマンドを繰り返して呼び出すことによりWINDOW内で前に表示された すべてのバッファーが表示されてしまったら、将来の呼び出しでは WINDOWが表示されているフレームのバッファーリスト(*note Buffer List::を参照)から、そのフレームの他のウィンドウで表示済みのバッファ ーをスキップしてバッファーの表示を試みる。 -- Command: switch-to-next-buffer &optional window このコマンドはWINDOW内の次バッファーに切り替える。つまりWINDOW内で の最後の‘switch-to-prev-buffer’コマンドの効果をアンドゥする。引数 WINDOWは生きたウィンドウであること。デフォルトは選択されたウィンド ウ。 アンドゥ可能な‘switch-to-prev-buffer’の直近の呼び出しが存在しなけれ ば、この関数はWINDOWが表示されているフレームのバッファーリスト (*note Buffer List::を参照)からバッファーの表示を試みる。 デフォルトでは、‘switch-to-prev-buffer’と‘switch-to-next-buffer’は同 一フレーム上の他のウィンドウで表示済みのバッファーに切り替えることができ ます。この挙動をオーバーライドするために以下のオプションを使用できます。 -- User Option: switch-to-visible-buffer この変数が非‘nil’なら、そのバッファーが当該ウィンドウで過去に表示さ れていれば、‘switch-to-prev-buffer’と‘switch-to-next-buffer’は同一 フレーム上ですでに可視のバッファーに切り替えることができる。‘nil’な ら、‘switch-to-prev-buffer’と‘switch-to-next-buffer’は同一フレーム 上ですでに可視なバッファーへの切り替えを常に避けるよう試みる。デフ ォルトは‘t’。 27.17 専用のウィンドウ ====================== 特定のウィンドウがそのウィンドウのバッファーにたいして“専用 (dedicated)”であるとマークすることにより、バッファーを表示する関数にその ウィンドウを使用しないように告げることができます。‘display-buffer’ (*note Choosing Window::を参照)は、他のバッファーの表示に専用バッファー を決して使用しません。 ‘get-lru-window’と‘get-largest-window’ (*note Cyclic Window Ordering::を参照)は、DEDICATED引数が非‘nil’のときは専用ウ ィンドウを候補とはみなしません。専用ウィンドウにたいする配慮に関して ‘set-window-buffer’ (*note Buffers and Windows::を参照)の挙動は若干異な ります。以下を参照してください。 ウィンドウからのバッファー削除、およびフレームからのウィンドウ削除を 意図した関数は、処理するウィンドウが専用ウィンドウのときは特別な挙動を示 す可能性があります。ここでは3つの基本ケース、すなわち(1)そのウィンドウが フレーム上で唯一のウィンドウの場合、(2)ウィンドウはフレーム上で唯一のウ ィンドウだが同一端末上に別のフレームがある場合、(3)そのウィンドウが同一 端末上で唯一のフレームの唯一のウィンドウの場合、を明確に区別することにし ます。 特に‘delete-windows-on’ (*note Deleting Windows::を参照)は関連するフ レームを削除する際にケース(2)を、フレーム上で唯一のウィンドウに他のバッ ファーを表示する際にケース(3)を処理します。バッファーがkillされる際に呼 び出される関数‘replace-buffer-in-windows’(*note Buffers and Windows::を 参照)は、ケース(1)ではウィンドウを削除して、それ以外では ‘delete-windows-on’のように振る舞います。 ‘bury-buffer’ (*note Buffer List::を参照)が選択されたウィンドウを操作 する際は、選択されたフレームを処理するために‘frame-auto-hide-function’ (*note Quitting Windows::を参照)を呼び出すことによってケース(2)を取り扱 います。他の2つのケースは‘replace-buffer-in-windows’と同様に処理されます 。 -- Function: window-dedicated-p &optional window この関数はWINDOWがそのバッファーにたいして専用なら非‘nil’、それ以外 は‘nil’をリターンする。より正確には最後の‘set-window-dedicated-p’呼 び出しで割り当てられた値、‘set-window-dedicated-p’がWINDOWを引数と して呼び出されたことがなければ‘nil’がリターン値となる。WINDOWのデフ ォルトは選択されたウィンドウ。 -- Function: set-window-dedicated-p window flag この関数はFLAGが非‘nil’ならWINDOWがそのバッファーに専用、それ以外は 非専用とマークする。 特別なケースとしてFLAGが‘t’の場合には、WINDOWはそのバッファーにたい して“特に専用(strongly dedicated)”になる。‘set-window-buffer’は処理 対象のウィンドウが特に専用のウィンドウで、かつ表示を要求されたバッ ファーが表示済みでなければエラーをシグナルする。その他の関数は‘t’を 他の非‘nil’値と区別して扱わない。 27.18 ウィンドウのquit ====================== バッファーを表示するために使用しているウィンドウを削除したいときには、フ レームからそのウィンドウを削除するために‘delete-window’や ‘delete-windows-on’を呼び出すことができます(*note Deleting Windows::を参 照)。そのバッファーが別フレームで表示されているときには、かわりに ‘delete-frame’を呼び出したいと思うかもしれません(*note Deleting Frames::を参照)。その一方でバッファーを表示するためにウィンドウが再利用 されている場合には、関数‘switch-to-prev-buffer’を呼び出して前に表示され ていたバッファーを表示したいと思うかもしれません(*note Window History::を 参照)。最終的にはそのウィンドウのバッファーをバリー(*note Buffer List::を 参照)やkill(*note Killing Buffers::を参照)したいと思うかもしれません。 以下のコマンドは、最初にどのようにバッファーを表示するウィンドウを取 得するかという情報を使用して、上述で説明した処理の自動化を試みます。 -- Command: quit-window &optional kill window このコマンドはWINDOWをquitしてそのバッファーをバリーする。引数 WINDOWは生きたウィンドウでなければならずデフォルトは選択されたウィ ンドウ。プレフィックス引数KILLが非‘nil’ならバッファーをバリーするか わりにkillする。これはウィンドウとそのバッファーを処理するために、 次に説明する関数‘quit-restore-window’を呼び出す。 -- Function: quit-restore-window &optional window bury-or-kill この関数はWINDOWにたいして、そのバッファーが表示される前に存在した 状態へのリストアを試みる。オプション引数WINDOWは生きたウィンドウで なければならずデフォルトは選択されたウィンドウ。 WINDOWがそのバッファーを表示するために特別に作成されたバッファーな ら、この関数はそのフレームに他に少なくとも1つの生きたウィンドウがな ければWINDOWを削除しない。WINDOWがそのフレームで唯一のウィンドウで あり、かつそのフレームの端末上に他のフレームが存在する場合には、オ プション引数BURY-OR-KILLがそのウィンドウをどうするかを決定する。 BURY-OR-KILLが‘kill’なら無条件でフレームは削除される。それ以外では フレームの運命はそのフレームを単一の引数とする ‘frame-auto-hide-function’ (以下参照)呼び出しにより決定される。 特別に作成されたウィンドウでなければ、この関数はWINDOW内で前に表示 されていたバッファーの再表示を試みる。これは前に表示されていたバッ ファーのウィンドウのスタート位置(*note Window Start and End::を参照 )とポイント位置(*note Window Point::を参照)のリストアも試みる。加え てWINDOWのバッファーが過去に一時的にリサイズされていたら、この関数 はWINDOWの元の高さのリストアも試みる。 これまで説明したケースでは、WINDOW内で表示されているバッファーは依 然としてそのウィンドウにたいする最後のバッファー表示関数で表示され たバッファーである。その時点で他のバッファーが表示されているか、前 に表示されていたバッファーがもはや存在しなければ、この関数はかわり に何か他のバッファーを表示するために‘switch-to-prev-buffer’(*note Window History::を参照)を呼び出す。 オプション引数BURY-OR-KILLにはWINDOWを処理する方法を指定し、以下の 値が処理される。 ‘nil’ これはバッファーを特別な方法で処理しないことを意味する。その結 果としてWINDOWが削除されない場合には、 ‘switch-to-prev-buffer’の呼び出しにより通常はそのバッファーが 再び表示されるだろう。 ‘append’ これはWINDOWが削除されない場合には、そのバッファーをWINDOWの前 のバッファーリストの最後に移動するので、将来の ‘switch-to-prev-buffer’呼び出しでこのバッファーには切り替わる ことは少なくなる。これはそのバッファーをフレームのバッファーリ ストの最後への移動も行う。 ‘bury’ これはWINDOWが削除されない場合には、そのバッファーをWINDOWの前 のバッファーリストから削除する。これはそのバッファーをフレーム のバッファーリストの最後への移動も行う。この値はバッファーを killすることなく‘switch-to-prev-buffer’がこのバッファーに再び 切り替えさせないようにする、もっとも信頼できる解決手段を提供す る。 ‘kill’ これはWINDOWのバッファーをkillすることを意味する。 ‘quit-restore-window’はWINDOWの‘quit-restore’ウィンドウパラメーター (*note Window Parameters::を参照)の情報にもとづいて判定を行い、処理 後にそれを‘nil’にリセットしている。 以下のオプションはquitすべきウィンドウ、あるいはバリーすべきバッファ ーをもつウィンドウを1つだけ含むフレームを処理する方法を指定します。 -- User Option: frame-auto-hide-function このオプションで指定された関数は自動的にフレームを隠すために呼び出 される。この関数はフレームを唯一の引数として呼び出される。 ここで指定される関数は選択されたウィンドウが専用(dedicated)であり、 かつバリーされるバッファーを表示しているときに‘bury-buffer’ (*note Buffer List::を参照)から呼び出される。またquitされるウィンドウのフ レームがそのウィンドウのバッファーを表示するために特別に作成された フレームで、かつそのバッファーがkillされないときにも ‘quit-restore-window’ (上記)から呼び出される。 デフォルトでは‘iconify-frame’ (*note Visibility of Frames::を参照 )を呼び出す。かわりにフレームをディスプレイから削除する ‘delete-frame’ (*note Deleting Frames::を参照)、フレームを変更せず に残す‘ignore’、またはフレームを唯一の引数とする任意の関数のいずれ かを指定できる。 このオプションで指定された関数は指定されたフレームが生きたウィンド ウただ1つを含み、かつ同一端末上に少なくとも1つ他のフレームが存在す る場合のみ呼び出されることに注意。 27.19 ウィンドウとポイント ========================== それぞれのウィンドウは独自のポイント値(*note Point::を参照)をもち、同じ バッファーを表示する他のウィンドウの間でも、ポイント値はそれぞれ独立して います。これは1つのバッファーを複数ウィンドウで表示するのに有用です。 • ウィンドウポイント(window point)は、ウィンドウが最初に作成されたと きに設定される。ウィンドウポイントはバッファーのポイント、またはそ のバッファーからオープンされたウィンドウがあればそのウィンドウのウ ィンドウポイントにより初期化される。 • ウィンドウの選択により、ウィンドウのポイント値からそのバッファーの ポイント値がセットされる。反対にウィンドウの非選択により、ウィンド ウのポイント値にバッファーのポイント値がセットされる。つまり与えら れたバッファーを表示するウィンドウ間で切り替えを行ったときには、そ のバッファーでは選択されたウィンドウのポイント値が効力をもつが、他 のウィンドウのポイント値はそのウィンドウに格納される。 • 選択されたウィンドウがカレントバッファーの表示を続ける限り、そのウ ィンドウのポイントとバッファーのポイントは常に連動して移動して等し く保たれる。 ユーザーが関与し続ける限りポイントはカーソル位置にあり、ユーザーが他 のバッファーに切り替えた際には、カーソルはそのバッファーのポイント位置へ とジャンプします。 -- Function: window-point &optional window この関数はWINDOW内のカレントのポイント位置をリターンする。選択され ていないウィンドウでは、そのウィンドウが選択された場合の、(そのウィ ンドウのバッファーの)ポイント値である。WINDOWにたいするデフォルトは 選択されたウィンドウ。 WINDOWが選択されたウィンドウのときのリターン値は、そのウィンドウの バッファーのポイント値。厳密にはすべての‘save-excursion’フォームの 外側のトップレベルのポイント値のほうがより正確であろう。しかしこの 値は見つけるのが困難である。 -- Function: set-window-point window position この関数はWINDOW内のポイントをWINDOWのバッファー内の位置POSITIONに 配置する。リターン値はPOSITION。 WINDOWが選択されていれば単にWINDOW内で‘goto-char’を行う。 -- Variable: window-point-insertion-type この変数は‘window-point’のマーカー挿入型(*note Marker Insertion Types::を参照)を指定する。デフォルトは‘nil’で、‘window-point’は挿入 されたテキストの後に留まるだろう。 27.20 ウィンドウの開始位置と終了位置 ==================================== ウィンドウはそれぞれバッファー位置を追跡するために、バッファー内で表示を 開始すべき位置を指定するマーカーを保守しています。この位置はそのウィンド ウの“display-start(表示開始)”、または単に“start(開始)”と呼ばれます。この 位置の後の文字がウィンドウの左上隅に表示される文字となります。これは通常 はテキスト行の先頭になりますが必須ではありません。 ウィンドウやバッファーの切り替え後やいくつかのケースにおいては、ウィ ンドウが行の途中で開始される場合にEmacsがィンドウの開始を行の開始に調整 します。これは行中で無意味な位置のウィンドウ開始のまま特定の操作が行われ るのを防ぐためです。この機能はLispモードのコマンドを使用して実行すること によりある種のLispコードをテストする場合には、それらのコマンドがこの再調 整を誘発してしまうので邪魔かもしれません。そのようなコードをテストするた めには、それをコマンド内に記述して何らかのキーにバインドしてください。 -- Function: window-start &optional window この関数はウィンドウWINDOWの表示開始位置をリターンする。WINDOWが ‘nil’なら選択されたウィンドウが使用される。 ウィンドウを作成したり他のバッファーをウィンドウ内に表示する際、 display-start位置は同じバッファーにたいしてもっとも最近に使用された display-start位置、そのバッファーがそれをもたなければ‘point-min’に セットされる。 ポイントがスクリーン上に確実に現れるように、再表示はwindow-start位 置を更新する(前の再表示以降にwindow-start位置を明示的に指定していな い場合)。再表示以外にwindow-start位置を自動的に変更するものはない。 ポイントを移動した場合には、次の再表示後までポイントの移動に応じて window-startが変更されることを期待してはならない。 -- Function: window-group-start &optional window この関数は‘window-start’と同様だが、WINDOWがウィンドウグループ (*note Window Group::を参照)の一部なら、‘window-group-start’はグル ープ全体の開始位置をリターンする点が異なる。この条件はバッファーロ ーカル変数‘window-group-start-function’に関数がセットされている際に 保持される。この場合には、‘window-group-start’はその関数を単一の引 数WINDOWで呼び出して結果をリターンする。 -- Function: window-end &optional window update この関数は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がどこかを報告する。 -- Function: window-group-end &optional window update この関数は‘window-end’と同様だが、WINDOWがウィンドウグループ(*note Window Group::を参照)の一部なら、‘window-group-end’はグループ全体の 終了位置をリターンする点が異なる。この条件はバッファーローカル変数 ‘window-group-end-function’に関数がセットされている際に保持される。 この場合には、‘window-group-end’はその関数を2つの引数WINDOWと UPDATEで呼び出して結果をリターンする。引数UPDATEは‘window-end’の場 合と同じ意味をもつ。 -- Function: set-window-start window position &optional noforce この関数はWINDOWのdisplay-start位置をWINDOWのバッファーのPOSITIONに セットする。リターン値はPOSITION。 バッファーが表示されたときに表示ルーチンはポイント位置が可視になる ことを強要する。これらはポイントを可視にするために必要なときは、通 常は常にdisplay-start位置を変更(つまりウィンドウをスクロール)する。 しかしこの関数でNOFORCEに‘nil’を使用してstart位置を指定すると、たと えポイントを画面外になるような場所に配置したとしてもPOSITIONでの表 示開始を望むことを意味する。これによりポイントが画面外に配置される と、表示ルーチンはポイントをウィンドウ内の中央行の左マージンに移動 する。 たとえばポイントが1のときにウィンドウのstartを次行の開始37にセット すると、ポイントはウィンドウの最上端より上になるだろう。表示ルーチ ンは再表示が発生したときにポイントが1のままならポイントを動かすこと になる。以下は例: ;; 以下は式‘set-window-start’実行前 ;; ‘foo’の様子 ---------- Buffer: foo ---------- ★This is the contents of buffer foo. 2 3 4 5 6 ---------- Buffer: foo ---------- (set-window-start (selected-window) (save-excursion (goto-char 1) (forward-line 1) (point))) ⇒ 37 ;; 以下は式‘set-window-start’実行後の ;; ‘foo’の様子 ---------- Buffer: foo ---------- 2 3 ★4 5 6 ---------- Buffer: foo ---------- NOFORCEが非‘nil’で、かつ次回の再表示でポイントが画面外に配される場 合、再表示はポイントと協調して機能する位置となるような新たな window-startを計算するので、POSITIONは使用されない。 -- Function: set-window-group-start window position &optional noforce この関数は‘set-window-start’と同様だが、WINDOWがウィンドウグループ (*note Window Group::を参照)の一部なら、‘set-window-group-start’は グループ全体の開始位置をリターンする点が異なる。この条件はバッファ ーローカル変数‘set-window-group-start-function’に関数がセットされて いる際に保持される。この場合には、‘set-window-group-start’はその関 数を3つの引数WINDOW、POSITION、NOFORCEで呼び出して結果をリターンす る。この関数の引数POSITIONとNOFORCEは‘set-window-start’の場合と同じ 意味をもつ。 -- Function: pos-visible-in-window-p &optional position window partially この関数は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’をリターンする。*note Horizontal Scrolling::を参照のこと。 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)) -- Function: pos-visible-in-window-group-p &optional position window partially この関数は‘pos-visible-in-window-p’と同様だが、WINDOWがウィンドウグ ループ(*note 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’の場合と同じ意味をもつ。 -- Function: window-line-height &optional line window この関数は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は 負となる。 27.21 テキスト的なスクロール ============================ “テキスト的なスクロール(textual scrolling)”とは、ウィンドウ内のテキスト を上や下に移動することを意味します。これはそのウィンドウの display-startを変更することにより機能します。これはポイントを画面上に維 持するために‘window-point’の値も変更するかもしれません(*note Window Point::を参照)。 テキスト的なスクロールの基本的な関数は、(前方にスクロールする) ‘scroll-up’、および(後方にスクロールする) ‘scroll-down’です。これらの関 数の名前の“up”と“down”は、バッファーテキストのそのウィンドウにたいする相 対的な移動方向を示しています。そのテキストが長いロール紙に記述されていて 、スクロールコマンドはその上を上下に移動すると想像してみてください。つま りバッファーの中央に注目している場合には、繰り返して‘scroll-down’を呼び 出すと最終的にはバッファーの先頭を目にすることになるでしょう。 これは残念なことに時折混乱を招きます。なぜならある人はこれを逆の慣習 にもとづいて考える傾向があるからです。彼らはテキストがその場所に留まりウ ィンドウが移動して、“down”コマンドによりバッファー終端に移動するだろうと 想像します。この慣習はそのようなコマンドが現代風のキーボード上の という名前のキーにバインドされているという事実と一致しています 。 選択されたウィンドウ内で表示されているバッファーがカレントバッファー でなければ、(‘scroll-other-window’以外の)テキスト的スクロール関数の結果 は予測できません。*note Current Buffer::を参照してください。 (たとえば大きなイメージがある等で)ウィンドウにウィンドウの高さより高 い行が含まれる場合には、スクロール関数は部分的に可視な行をスクロールする ためにそのウィンドウの垂直スクロール位置を調整します。Lisp呼び出し側は変 数‘auto-window-vscroll’を‘nil’にバインドすることにより、この機能を無効に できます(*note Vertical Scrolling::を参照)。 -- Command: scroll-up &optional count この関数は選択されたウィンドウ内でCOUNT行前方にスクロールする。 COUNTが負ならかわりに後方へスクロールする。COUNTが‘nil’ (または省略 )ならスクロールされる距離は、そのウィンドウのテキストエリアの高さよ り小さい‘next-screen-context-lines’となる。 この関数は選択されたウィンドウがそれ以上スクロールできなければエラ ーをシグナルして、それ以外は‘nil’をリターンする。 -- Command: scroll-down &optional count この関数は選択されたウィンドウ内でCOUNT行後方にスクロールする。 COUNTが負ならかわりに前方へスクロールする。それ以外の点ではこれは ‘scroll-up’と同様に振る舞う。 -- Command: scroll-up-command &optional count これは‘scroll-up’と同様に振る舞うが選択されたウィンドウがそれ以上ス クロールできず、かつ変数‘scroll-error-top-bottom’の値が‘t’なら、か わりにそのバッファーの終端への移動を試みる。ポイントがすでに終端に あればエラーをシグナルする。 -- Command: scroll-down-command &optional count これは‘scroll-down’と同様に振る舞うが選択されたウィンドウがそれ以上 スクロールできず、かつ変数‘scroll-error-top-bottom’の値が‘t’なら、 かわりにそのバッファーの先頭への移動を試みる。ポイントがすでに先頭 にあればエラーをシグナルする。 -- Command: scroll-other-window &optional count この関数は他のウィンドウ内のテキストを上方にCOUNT行スクロールする。 COUNTが負か‘nil’なら‘scroll-up’のように処理される。 変数‘other-window-scroll-buffer’にバッファーをセットすることにより 、どのバッファーをスクロールするかを指定できる。そのバッファーが表 示されていなければ、‘scroll-other-window’はそれを何らかのウィンドウ にそれを表示する。 選択されたウィンドウがミニバッファーのとき、次ウィンドウは通常はそ のウィンドウの直上最左のウィンドウである。変数 ‘minibuffer-scroll-window’をセットすることにより、スクロールする別 のウィンドウを指定できる。この変数はミニバッファー以外のウィンドウ が選択されているときは効果がない。これが非‘nil’、かつミニバッファー が選択されているときには‘other-window-scroll-buffer’より優先される 。*note Definition of minibuffer-scroll-window::を参照のこと。 ミニバッファーがアクティブのとき選択されたウィンドウが下端右角のウ ィンドウなら、ミニバッファーが次ウィンドウになる。この場合には ‘scroll-other-window’はミニバッファーのスクロールを試みる。ミニバッ ファーに含まれるのが1行だけならどこにもスクロールできないので、エコ ーエリアにメッセージ‘End of buffer’を瞬時表示した後にその行を再表示 する。 -- Variable: other-window-scroll-buffer この変数が非‘nil’なら、それは‘scroll-other-window’がどのバッファー のウィンドウをスクロールするかを指定する。 -- User Option: scroll-margin このオプションはスクロールマージン(ポイントとウィンドウの上端/下端 との最小行数)のサイズを指定する。ポイントがウィンドウの上端/下端か らその行数になったとき、(可能なら)再表示はポイントをそのマージン外 のウィンドウ中央付近に移動するためにテキストを自動的にスクロールす る。 -- User Option: scroll-conservatively この変数はポイントがスクリーン外(またはスクロールマージン内)に移動 したときに自動的にスクロールを行う方法を指定する。値が正の整数Nなら 再表示はそれが正しい表示範囲内にポイントを戻すなら、いずれかの方向 にN行以下のテキストをスクロールする。この振る舞いは“保守的なスクロ ール(conservative scrolling)”と呼ばれる。それ以外ならスクロールは ‘scroll-up-aggressively’や‘scroll-down-aggressively’のような他の変 数の制御の下に通常の方法で発生する。 デフォルトの値は0でこれは保守的スクロールが発生し得ないことを意味す る。 -- User Option: scroll-down-aggressively この変数の値は‘nil’、または0から1までの小数点数Fであること。小数点 数ならスクリーン上でポイントが置かれたとき下にスクロールする場所を 指定する。より正確にはポイントがウィンドウstartより上という理由でウ ィンドウが下にスクロールされるときには、新たなstart位置がウィンドウ 上端からウィンドウ高さのFの箇所にポイントが置かれるように選択される 。より大きなFなら、よりaggressive(積極的)にスクロールする。 その効果はポイントを中央に配置することであり、値‘nil’は.5と等価であ る。どのような方法によりセットされたときでも、この変数は自動的にバ ッファーローカルになる。 -- User Option: scroll-up-aggressively ‘scroll-up-aggressively’と同様。値Fはポイントがウィンドウ下端からど れほどの位置に置かれるべきかを指定する。つまり ‘scroll-up-aggressively’と同じように大きな値ではよりaggressive(積極 的)になる。 -- User Option: scroll-step この変数は‘scroll-conservatively’の古い変種である。違いは値がNなら N以下の値ではなく、正確にNだけのスクロールを許容することである。こ の機能は‘scroll-margin’とは共に機能しない。デフォルトは0。 -- User Option: scroll-preserve-screen-position このオプションが‘t’なら、スクロールによりポイントがウィンドウ外に移 動したとき、Emacsは常にポイントがポイントの上下端ではなくカーソルが そのウィンドウ内の元の垂直位置に保たれるようポイントの調整を試みる 。 値が非‘nil’かつ非‘t’なら、たとえスクロールコマンドによりポイントが ウィンドウ外に移動していなくとも、Emacsはカーソルが同じ垂直位置に保 たれるようにポイントを調整する。 このオプションはシンボルプロパティ‘scroll-command’が非‘nil’であるよ うな、すべてのスクロールコマンドに影響する。 -- User Option: next-screen-context-lines この変数の値は全画面スクロールされたときに継続して残される行数を指 定する。たとえば引数が‘nil’の‘scroll-up’はウィンドウ上端ではなく下 端に残される行数でスクロールする。デフォルト値は‘2’。 -- User Option: scroll-error-top-bottom このオプションが‘nil’(デフォルト)なら、それ以上のスクロールが不可能 な際に‘scroll-up-command’と‘scroll-down-command’は単にエラーをシグ ナルする。 値が‘t’なら、これらのコマンドはかわりにポイントをバッファーの先頭か 終端(スクロール方向に依存する)に移動する。ポイントがすでにその位置 にある場合のみエラーをシグナルする。 -- Command: recenter &optional count この関数は選択されたウィンドウ内の指定された垂直位置にポイントを表 示するようにウィンドウ内のテキストをスクロールする。これはテキスト に応じたポイント移動を行わない。 COUNTが非負の数なら、そのウィンドウ上端からCOUNT行下にポイントを含 む行を配置する。COUNTが負ならウィンドウ下端から上に数えるので、−1は そのウィンドウ内で最後の利用可能な行となる。 COUNTが‘nil’ (または非‘nil’のリスト)なら、‘recenter’はポイントを含 む行をウィンドウの中央に配置する。COUNTが‘nil’なら、この関数は ‘recenter-redisplay’の値に応じてフレームを再描画するかもしれない。 ‘recenter’がインタラクティブに呼び出されたときはrawプレフィックス引 数がCOUNTとなる。したがってプレフィックスとして‘C-u’をタイプすると COUNTに非‘nil’、‘C-u 4’ではCOUNTに4がセットされte、後者ではカレント 行を上端から4行目にセットする。 引数0では‘recenter’はカレント行をウィンドウ上端に配置する。コマンド ‘recenter-top-bottom’はこれを達成するためにより簡便な方法を提供する 。 -- Function: recenter-window-group &optional count この関数は‘recenter’と同様だが、選択されたウィンドウがウィンドウグ ループ(*note Window Group::を参照)の一部の際には、 ‘recenter-window-group’がグループ全体をスクロールする点が異なる。こ の条件はバッファーローカル変数‘recenter-window-group-function’が関 数にセットされている際に保持される。この場合には ‘recenter-window-group’はその関数を引数COUNTで呼び出して結果をリタ ーンする。引数COUNTは‘recenter’の場合と同様の意味をもつが、ウィンド ウグループ全体に作用する。 -- User Option: recenter-redisplay この変数が非‘nil’なら引数‘nil’で‘recenter’を呼び出すことによりフレ ームを再描画する。デフォルト値は‘tty’で、これはフレームがttyフレー ムのときだけフレームを再描画することを意味する。 -- Command: recenter-top-bottom &optional count デフォルトでは‘C-l’にバインドされているこのコマンドは、‘recenter’と 同様に動作するが引数なしで呼び出されたときの動作が異なる。この場合 には連続して呼び出すことにより変数‘recenter-positions’で定義される サイクル順に応じてポイントを配置する。 -- User Option: recenter-positions これは‘recenter-top-bottom’を引数なしで呼び出したときの挙動を制御す る。デフォルト値は‘(middle top bottom)’で、これは引数なしで ‘recenter-top-bottom’を連続して呼び出すとポイントをウィンドウの中央 、上端、下端と巡回して配置することを意味する。 27.22 割り合いによる垂直スクロール ================================== “垂直フラクショナルスクロール(vertical fractional scrolling)”とは、指定 された値を行に乗ずるることによりウィンドウ内のテキストを上下にシフトする ことを意味します。ウィンドウはそれぞれ、決して0より小さくなることはない “垂直スクロール位置(vertical scroll position)”という数値をもっています。 これはウィンドウのコンテンツをどこから表示開始(raise)するかを指定します 。ウィンドウのコンテンツの表示開始により一般的には上端の何行かすべて、ま たは一部が表示されなくなり、他の何行かのすべて、または一部が下端に表示さ れるようになります。通常の値は0です。 垂直スクロール位置は通常行の高さ(デフォルトフォントの高さ)の単位で数 えられます。したがって値が.5なら、それはウィンドウのコンテンツが通常行の 半分の高さで上にスクロールされていること、3.3なら通常行の3倍を若干超える 高さで上にスクロールされていることを意味します。 垂直スクロールが覆い隠す(cover)のがどれほどの行断片(fraction of a line)なのか、あるいは行数かはそれらの行に何が含まれるかに依存します。 3.3という値により高い行やイメージの一部だけを画面外にスクロールできるこ ともあれば、.5という値が非常に小さい高さの行を画面外にスクロールできるこ ともあります。 -- Function: window-vscroll &optional window pixels-p この関数はWINDOWのカレントの垂直スクロール位置をリターンする。 WINDOWのデフォルトは選択されたウィンドウ。PIXELS-Pが非‘nil’ならリタ ーン値は通常行高さ単位ではなくピクセル単位で測定される。 (window-vscroll) ⇒ 0 -- Function: set-window-vscroll window lines &optional pixels-p この関数はWINDOWの垂直スクロール位置をLINESにセットする。WINDOWが ‘nil’なら選択されたウィンドウが使用される。引数LINESは0または正であ ること。それ以外は0として扱われる。 実際の垂直スクロール位置は常にピクセルの整数に対応しなければならな いため、指定した値はそれに応じて丸められる。 この丸め結果がリターン値となる。 (set-window-vscroll (selected-window) 1.2) ⇒ 1.13 PIXELS-Pが非‘nil’ならLINESはピクセル数を指定する。この場合にはリタ ーン値はLINES。 -- Variable: auto-window-vscroll この変数が非‘nil’なら関数‘line-move’、‘scroll-up’、‘scroll-down’は 、たとえば大きなイメージが存在する等でウィンドウ高さより高いディス プレイ行をスクロールするために垂直スクロール位置を自動的に変更する だろう。 27.23 水平スクロール ==================== “水平スクロール(horizontal scrolling)”とは指定された通常文字幅の倍数でウ ィンドウ内のイメージを左右にシフトすることを意味します。ウィンドウはそれ ぞれ、決して0より小さくなることはない“水平スクロール位置(horizontal scroll position)”という数値をもっています。これはコンテンツをどれほど左 にシフトするかを指定します。ウィンドウのコンテンツを左にシフトすることに より一般的には左にある文字のすべて、または一部が表示されなくなり右にある 文字のすべて、または一部が表示されることを意味します。通常の値は0です。 水平スクロール位置は通常の文字幅を単位として数えられます。したがって 値が5なら、それはウィンドウのコンテンツは通常文字幅の5倍左にスクロールさ れることを意味します。左の何文字が表示されなくなるかは、それらの文字の文 字幅とに依存していて、それは行ごとに異なります。 読み取りを行う際には内側のループ(inner loop)で横方向、外側のループ (outer loop)で上から下に読み取るため、水平スクロールの効果はテキスト的ス クロールや垂直スクロールとは異なります。テキスト的スクロールは表示するた めのテキスト範囲の選択を引き起こし、垂直スクロールはウィンドウコンテンツ を連続して移動します。しかし水平スクロールは_すべての行_の一部をスクリー ン外へスクロールします。 通常は水平スクロールは行われないので、ウィンドウ左端には最左列があり ます。この状態では右スクロールにより左端に新たに表示されるデータは存在し ないので、右へのスクロールはできません。左スクロールによってテキストの 1列目がウィンドウ端からウィンドウ外にスクロールされ、右端にはその前は切 り詰められていた(truncated)列が新たに表示されるので左へのスクロールはで きます。ウィンドウが左へ非0の値で水平スクロールされていれば右スクロール してそれを戻すことができますが、正味の水平スクロールが0に減少するまでの 間のみ右スクロールができます。左へどれほどスクロールできるかに制限はあり ませんが、最終的にはすべてのテキストが左端の外に消えるでしょう。 ‘auto-hscroll-mode’がセットされている場合には、再表示はポイントが常に 可視となることを保証するために必要に応じて水平スクロールを自動的に変更す る。とはいえ依然として水平スクロール位置を明示的に指定するのは可能である 。指定した値は自動スクロールの下限値としての役目を果たす(自動スクロール は指定された値より小さい列にウィンドウをスクロールしない)。 -- Command: scroll-left &optional count set-minimum この関数は選択されたウィンドウを左( COUNTが負なら右)にCOUNT列スクロ ールする。COUNTのデフォルトはウィンドウ幅から2を減じた値。 リターン値は‘window-hscroll’(以下参照)がリターンする値と同じように 、変更後に実際に左に水平スクロールされたトータル量。 基本方向がR2L(*note Bidirectional Display::を参照)のパラグラフ内の テキストは、正のCOUNT値で‘scroll-left’が呼び出された際には右へと移 動するように、反対方向に移動することに注意。 ウィンドウを可能な限り右にスクロールした後は、左スクロールの合計が 0であるような通常の位置に戻り、右へのそれ以上のスクロールの試みは効 果をもたない。 SET-MINIMUMが非‘nil’なら新たなスクロール量は自動スクロールの下限値 となる。つまり自動スクロールはこの関数がリターンする値より小さい列 にウィンドウをスクロールしないだろう。インタラクティブに呼び出すと SET-MINIMUMに非‘nil’を渡す。 -- Command: scroll-right &optional count set-minimum この関数は選択されたウィンドウを右( COUNTが負なら左)にCOUNT列スクロ ールする。COUNTのデフォルトはウィンドウ幅から2を減じた値。スクロー ル方向を除けばこれは‘scroll-left’と同様に機能する。 -- Function: window-hscroll &optional window この関数はWINDOWの左への水平スクロールのトータル(左マージンを超えて 左にスクロールされたWINDOW内のテキスト列数)をリターンする(R2Lパラグ ラフでの値はかわりに右方向への総スクロール量となる)。WINDOWのデフォ ルトは選択されたウィンドウ。 リターン値が負になることは決してない。WINDOWで水平スクロールが行わ れていない場合(これが通常)にはリターン値は0。 (window-hscroll) ⇒ 0 (scroll-left 5) ⇒ 5 (window-hscroll) ⇒ 5 -- Function: set-window-hscroll window columns この関数は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))))) 27.24 座標とウィンドウ ====================== このセクションではウィンドウ位置をレポートする関数について説明します。こ れらの関数はそのウィンドウのフレームのネイティブ位置(*note Frame Geometry::を参照)を原点とする相対的な位置をレポートすることに注意してく ださい。そのウィンドウのフレームのディスプレーを原点とする相対位置をレポ ートする関数もいくつかあります。どのような場合でも原点は座標(0, 0)、右方 向でX座標、下方向でY座標が増加します。 以下の関数ではX座標とY座標は整数の文字単位(行数と列数)で報告されます 。グラフィカルなディスプレイ上での“行”と“列”はそれぞれ、そのフレームのデ フォルトフォントにより指定されるデフォルト文字の高さと幅に対応します (*note Frame Font::を参照)。 -- Function: window-edges &optional window body absolute pixelwise この関数は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’となる。 -- Function: window-body-edges &optional window この関数はWINDOWのボディーの端をリターンする(*note Window Sizes::を 参照)。‘(window-body-edges window)’の呼び出しは‘(window-edges window t)’ (上記参照)の呼び出しと等価。 以下の関数は一連のフレーム相対座標(frame-relative coordinates)からウ ィンドウへの関連付けに使用できます: -- Function: window-at x y &optional frame この関数はFRAMEのネイティブ位置(*note Frame Geometry::を参照)から相 対的に、デフォルト文字単位(*note Frame Font::を参照)で与えられる座 標XとYにある生きたウィンドウをリターンする。 その位置にウィンドウがなければリターン値は‘nil’。FRAMEが省略または ‘nil’の場合のデフォルトは選択されたフレーム。 -- Function: coordinates-in-window-p coordinates window この関数はウィンドウWINDOWがフレーム相対座標COORDINATESを占有するか どうかをチェックして、もしそうならウィンドウのどの部分かをチェック する。WINDOWは生きたウィンドウであること。 COORDINATESは‘(X . Y)’という形式のコンスセルであること。ここでXと YはWINDOWのフレームのネイティブ位置(*note Frame Geometry::を参照)か ら相対的に、デフォルト文字サイズ(*note Frame Font::を参照)の単位で 与えられる。 指定された位置にウィンドウが存在しなければリターン値は‘nil’。それ以 外ではリターン値は以下のいずれか: ‘(RELX . RELY)’ その座標はWINDOW内にある。数値RELXとRELYは指定された位置にたい する、ウィンドウ左上隅を原点に0から数えたウィンドウ相対座標と 等価。 ‘mode-line’ その座標はWINDOWのモードライン内にある。 ‘header-line’ その座標はWINDOWのヘッダーライン内にある。 ‘right-divider’ その座標はWINDOWと右に隣接するウィンドウを分けるディバイダー内 にある。 ‘bottom-divider’ その座標はWINDOWと下にあるウィンドウを分けるディバイダー内にあ る。 ‘vertical-line’ その座標はWINDOWと右に隣接するウィンドウを分ける垂直ライン内に ある。この値はウィンドウにスクロールバーがないときのみ発生し得 る。スクロールバー内の位置はこれらの目的にたいしてはウィンドウ 外側と判断される。 ‘left-fringe’ ‘right-fringe’ その座標はウィンドウの左か右のフリンジ内にある。 ‘left-margin’ ‘right-margin’ その座標はウィンドウの左か右のマージン内にある。 ‘nil’ その座標はWINDOWのいずれの部分でもない。 関数‘coordinates-in-window-p’はWINDOWのあるフレームを使用するので引 数としてフレームを要求しない。 以下の関数は文字単位ではなくピクセル単位でウィンドウ位置をリターンし ます。主にグラフィカルなディスプレイで有用ですがテキスト端末上でも呼び出 すことができ、その場合は各文字の占めるスクリーン領域が1ピクセルとなりま す。 -- Function: window-pixel-edges &optional window この関数はWINDOW端にたいするピクセル座標のリストをリターンする。 ‘(window-pixel-edges window)’の呼び出しは、‘(window-edges window nil nil t)’ (上記参照)の呼び出しと等価。 -- Function: window-body-pixel-edges &optional window この関数はWINDOWのボディー端をピクセルでリターンする。 ‘(window-body-pixel-edges window)’の呼び出しは、‘(window-edges window t nil t)’ (上記参照)の呼び出しと等価。 以下の関数はフレーム原点ではなく、ディスプレイ画面(display screen)の 原点に相対的なウィンドウ位置をピクセルでリターンします。 -- Function: window-absolute-pixel-edges &optional window この関数はWINDOWのフレームのディスプレーの原点(0, 0)から相対的な WINDOWのピクセル座標をリターンする。 ‘(window-absolute-pixel-edges)’の呼び出しは、‘(window-edges window nil t t)’ (上記参照)の呼び出しと等価。 -- Function: window-absolute-body-pixel-edges &optional window この関数はWINDOWのフレームのディスプレーの原点(0, 0)から相対的な WINDOWのボディーのピクセル座標をリターンする。 ‘(window-absolute-body-pixel-edges window)’の呼び出しは、 ‘(window-edges window t t t)’ (上記参照)の呼び出しと等価。 ‘set-mouse-absolute-pixel-position’と組み合わせることにより、あるウ ィンドウ内で可視な任意のバッファー位置にマウスポインターを移動する ためにこの関数を使用できる。 (let ((edges (window-absolute-body-pixel-edges)) (position (pos-visible-in-window-p nil nil t))) (set-mouse-absolute-pixel-position (+ (nth 0 edges) (nth 0 position)) (+ (nth 1 edges) (nth 1 position)))) グラフィカルな端末では上記フォームは選択されたウィンドウのポイント にあるグリフ左上隅にマウスカーソルを“ワープ”させる。この方法で計算 される位置は、そこにツールチップウィンドウを表示するためにも使用で きる。 以下の関数はウィンドウ内で可視なバッファー位置のスクリーン座標をリタ ーンします。 -- Function: window-absolute-pixel-position &optional position window バッファー位置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))) 27.25 ウィンドウの構成 ====================== “ウィンドウ構成(window configuration)”とは1つのフレーム上全体のレイアウ ト — すべてのウィンドウとサイズ、どんなバッファーを含んでいるか、それら のバッファーがスクロールされる方法、およびポイント値を記録して、更にフリ ンジ、マージン、スクロールバーのセッティングも記録します。これには ‘minibuffer-scroll-window’の値も含まれます。特別な例外としてウィンドウ構 成には選択されたウィンドウのカレントバッファーのポイント値は記録されませ ん。 以前に保存されたウィンドウ構成をリストアすることにより、フレーム全体 のレイアウトをリストアすることができます。1つだけではなくすべてのフレー ムのレイアウトを記録したければ、ウィンドウ構成のかわりにフレーム構成 (frame configuration)を使用します。*note Frame Configurations::を参照し てください。 -- Function: current-window-configuration &optional frame この関数はFRAMEのカレントのウィンドウ構成を表す新たなオブジェクトを リターンする。FRAMEのデフォルトは選択されたフレーム。変数 ‘window-persistent-parameters’はこの関数により保存されるウィンドウ パラメーター(もしあれば)を指定する。*note Window Parameters::を参照 のこと。 -- Function: set-window-configuration configuration この関数はCONFIGURATIONが作成されたフレームにたいして、ウィンドウと バッファーの構成をCONFIGURATIONで指定された構成にリストアする。 引数CONFIGURATIONは以前に‘current-window-configuration’がリターンし た値でなければならない。この構成はそのフレームが選択されているか否 かに関わらず、CONFIGURATIONが作成時のフレームから当該フレームにリス トアされる。これは常にウィンドウのサイズ変更とみなされて、 ‘window-size-change-functions’ (*note Window Hooks::を参照)の実行を トリガーする。なぜなら‘set-window-configuration’は新たな構成が古い 構成と実際に異なるかを示す方法を知らないからである。 CONFIGURATIONが保存されたフレームが死んでいる(生きていない)場合には 、この関数が行うのは3つの変数‘window-min-height’、 ‘window-min-width’、‘minibuffer-scroll-window’のリストアのみ。この 場合には関数は‘nil’、それ以外は‘t’をリターンする。 以下は‘save-window-excursion’と同様な効果を得るためにこの関数を使用 する例: (let ((config (current-window-configuration))) (unwind-protect (progn (split-window-below nil) ...) (set-window-configuration config))) -- Macro: save-window-excursion forms... このマクロは選択されたフレームのウィンドウ構成を記録して、FORMSを順 に実行してから以前のウィンドウ構成をリストアする。リターン値は FORMS内の最後のフォームの値。 Lispコードのほとんどはこのマクロを使用するべきではない。大抵は ‘save-selected-window’で十分であろう。特にこのマクロはFORMS内で新た なウィンドウをオープンするコードを確実に防ぐことができず、新たなウ ィンドウは別のフレーム内でオープンされるかもしれないが(*note Choosing Window::を参照)、‘save-window-excursion’が保存とリストアす るのはカレントフレーム上のウィンドウ構成だけだからである。 このマクロを‘window-size-change-functions’内で使用してはならない。 このマクロをexitすることにより‘window-size-change-functions’の実行 がトリガーされるが無限ループを引き起こす。 -- Function: window-configuration-p object この関数はOBJECTがウィンドウ構成なら‘t’をリターンする。 -- Function: compare-window-configurations config1 config2 この関数はポイント値、保存されたスクロール位置を無視して(つまりこれ らの観点が異なっても‘t’をリターンし得る)、ウィンドウ構造の観点から 2つのウィンドウ構成を比較する。 関数‘equal’も2つのウィンドウ構成を比較できる。これはすべての点から たとえ1つでも異なるものがあれば等しい構成とはみなさず、たとえ保存さ れたポイント値が異なるだけでも等しくないとみなす。 -- Function: window-configuration-frame config この関数はウィンドウ構成CONFIGが作成されたフレームをリターンする。 ウィンドウ構成の内部を調べる他のプリミティブも有用かもしれませんが、 わたしたちはこれらを必要としないので実装されていません。ウィンドウ構成に たいしてより多くの操作を知りたければ、ファイル‘winner.el’を参照してくだ さい。 ‘current-window-configuration’がリターンするオブジェクトはEmacsプロセ スとともに死滅します。ウィンドウ構成をディスク上に格納してそれを別の Emacsセッションに読み戻すために、次に説明する関数を使用できます。これら の関数はフレームの状態を任意の生きたウィンドウにクローンする場合にも有用 です(‘set-window-configuration’はフレームのウィンドウをそのフレームのル ートウィンドウだけに効果的にクローンする)。 -- Function: window-state-get &optional window writable この関数はWINDOWの状態をLispオブジェクトとしてリターンする。引数 WINDOWは有効なウィンドウでなければならずデフォルトは選択されたフレ ームのルートウィンドウ。 オプション引数WRITABLEが非‘nil’なら、それは‘window-point’や ‘window-start’のようなサンプリング位置にたいするマーカーを使用しな いことを意味する。この状態をディスクに書き込んで別のセッションに読 み戻すなら、この引数は非‘nil’であること。 この関数によりどのウィンドウパラメーターが保存されるかは、引数 WRITABLEと変数‘window-persistent-parameters’の両方で指定する。*note Window Parameters::を参照のこと。 ‘window-state-get’によりリターンされる値は、同一セッション内の他のウ ィンドウ内にあるウィンドウのクローンを作成するために使用できます。これは ディスクに書き込んで別のセッションに読み戻すこともできます。いずれの場合 にもウィンドウの状態をリストアするためには以下の関数を使用します。 -- Function: window-state-put state &optional window ignore この関数はウィンドウ状態STATEをWINDOW内にputする。引数STATEは以前に 呼び出した‘window-state-get’がリターンしたウィンドウ状態であること 。オプション引数WINDOWには生きたウィンドウか内部ウィンドウ(*note Windows and Frames::を参照)のいずれかを指定でき、デフォルトは選択さ れたウィンドウ。WINDOWが生きていなければ、STATEをputする前に生きた ウィンドウに置き換える。 オプション引数IGNOREが非‘nil’なら、それは最小ウィンドウサイズと固定 サイズの制限を無視することを意味する。IGNOREが‘safe’なら、それは1行 および/または2列までできる限り小さくできることを意味する。 27.26 ウィンドウのパラメーター ============================== このセクションではウィンドウに追加の情報を関連付けるためにウィンドウパラ メーターを使用する方法を説明します。 -- Function: window-parameter window parameter この関数はWINDOWのPARAMETERの値をリターンする。WINDOWのデフォルトは 選択されたウィンドウ。WINDOWにPARAMETERにたいするセッティングがなけ れば、この関数は‘nil’をリターンする。 -- Function: window-parameters &optional window この関数はWINDOWのすべてのパラメーターと値をリターンする。WINDOWの デフォルトは選択されたウィンドウ。リターン値は‘nil’、または ‘(PARAMETER . VALUE)’という形式をもつ要素からなる連想リスト。 -- Function: set-window-parameter window parameter value この関数はWINDOWのPARAMETERの値にVALUEをセットしてVALUEをリターンす る。WINDOWのデフォルトは選択されたウィンドウ。 デフォルトではウィンドウ構成(window configuration)やウィンドウ状態 (states of windows)の保存とリストアを行う関数は、ウィンドウパラメーター については関知しません(*note Window Configurations::を参照)。これは ‘save-window-excursion’のbody内でパラメーターの値を変更したときは、その マクロのexit時に以前の値がリストアされないことを意味します。これはまた以 前に‘window-state-get’で保存されたウィンドウ状態を‘window-state-put’でリ ストアしたときは、クローンされたすべてのウィンドウのパラメーターが ‘nil’にリセットされることも意味します。以下の変数によってこの標準の挙動 をオーバーライドできます: -- Variable: window-persistent-parameters この変数は‘current-window-configuration’と‘window-state-get’により 保存、‘set-window-configuration’と‘window-state-put’によりリストア されるパラメーターを指定するalistである。*note Window Configurations::を参照のこと。 この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’値にバインドすることにより、 そのような特別な挙動をオーバーライドできます: -- Variable: ignore-window-parameters この変数が非‘nil’なら、いくつかの標準関数はウィンドウパラメーターを 処理しない。現在のところ影響を受ける関数は‘split-window’、 ‘delete-window’、‘delete-other-windows’、‘other-window’。 これらの関数の呼び出し周辺でアプリケーションはこの変数を非‘nil’にバ インドできる。これを行うと、そのアプリケーションはその関数のexit時 に関連するすべてのウィンドウのパラメーターを正しく割り当てる責任を もつ。 以下のパラメーターは現在のところウィンドウ管理コードにより使用されて います: ‘delete-window’ このパラメーターは‘delete-window’の実行に影響する(*note Deleting Windows::を参照)。 ‘delete-other-windows’ このパラメーターは‘delete-other-windows’の実行に影響する(*note Deleting Windows::を参照)。 ‘split-window’ このパラメーターは‘split-window’の実行に影響する(*note Splitting Windows::を参照)。 ‘other-window’ このパラメーターは‘other-window’の実行に影響する(*note Cyclic Window Ordering::を参照)。 ‘no-other-window’ このパラメーターはそのウィンドウを‘other-window’による選択が不可だ とマークする(*note Cyclic Window Ordering::を参照)。 ‘clone-of’ このパラメーターはそのウィンドウがクローンされたことを指定する。こ れは‘window-state-get’によりインストールされる(*note Window Configurations::を参照)。 ‘preserved-size’ このパラメーターはバッファー、方向(‘nil’は垂直で‘t’は水平)、ピクセ ル単位のサイズを指定する。そのウィンドウが指定されたバッファーを表 示していて、かつ指示された方向のサイズがこのパラメーターで指定され たサイズと等しければ、Emacsはそのウィンドウの指示された方向のサイズ を予約する。関数‘window-preserve-size’によりこのパラメーターのイン ストールと更新が行われる(*note Preserving Window Sizes::を参照)。 ‘quit-restore’ このパラメーターはバッファー表示関数によりインストールされて、 ‘quit-restore-window’により参照される(*note Quitting Windows::を参 照)。これは4つの要素を含む: 1つ目の要素は‘window’ (ウィンドウは‘display-buffer’により特別に作成 される)、‘frame’ (別フレームを作成する)、‘same’ (ウィンドウは前と同 じバッファーを表示する)、‘other’ (ウィンドウは前と異なるバッファー を表示する)のシンボルのいずれかである。 2つ目の要素はシンボル‘window’、‘frame’、または要素がそのウィンドウ に前に表示されていたバッファー、そのときのウィンドウstart位置、ウィ ンドウポイント位置、ウィンドウの高さであるようなリストのいずれか。 3つ目の要素はそのパラメーター作成時点に選択されていたウィンドウ。関 数‘quit-restore-window’は、その引数としてこのウィンドウが渡された際 にはそのウィンドウの再選択を試みる。 4つ目の要素はその表示がこのパラメーターの生成を引き起こしたバッファ ー。‘quit-restore-window’は指定されたウィンドウがまだそのバッファー を表示している場合のみそれを削除する。 ‘min-margins’ このパラメーターの値は、(非‘nil’なら) CARとCDRがそのウィンドウの左 右のマージンの最小値(列数)を指定するようなコンスセル。与えられた際 には、Emacsはウィンドウを水平方向に分割または縮小できるかを決定する ために、実際のマージン幅のかわりにこれらの値を使用するだろう。 すべてのウィンドウにたいして、分割やリサイズ後にEmacsがマージンの自 動調整をすることは決してない。これはそのウィンドウト分割のためにこ のウィンドウのマージンを継承する新たなウィンドウニタイシテ、マージ ンを調整するためにこのパラメーターをセットするすべてのアプリケーシ ョン単独の責任である。‘window-configuration-change-hook’と ‘window-size-change-functions’はいずれもこの用途に使用すること (*note Window Hooks::を参照)。 これはウィンドウ内でバッファーをセンタリングするために大きなマージ ンを使用するアプリケーションのサポート用にEmacsのバージョン25.1から 導入されたパラメーターであり、それらのアプリケーションと排他となる よう留意して使用すること。Emacsの将来のバージョンで改善策により置換 され得る。 追加のパラメーターとして‘window-atom’と‘window-side’があります。これ らは予約済みでアプリケーションが使用するべきではありません。 27.27 ウィンドウのスクロールと変更のためのフック ================================================ このセクションでは、あるウィンドウがそのバッファーの違う部分を表示したり 、別のバッファーを表示したとき常にLispプログラムを実行可能にする方法につ いて説明します。これを変更できる3つのアクションがあります。それはウィン ドウのスクロール、ウィンドウ内でのバッファーの切り替え、ウィンドウのサイ ズ変更です。最初の2つのアクションは‘window-scroll-functions’、最後のアク ションは‘window-size-change-functions’を実行します。 -- Variable: window-scroll-functions この変数はウィンドウのスクロールによりEmacsが再表示前に呼び出すべき 関数のリストを保持する。そのウィンドウ内に異なるバッファーを表示し たときもこれらの関数が実行される。 この変数はそれぞれの関数が2つの引数、ウィンドウとウィンドウの新たな display-start位置で呼び出されるのでノーマルフックではない。 これらの関数は‘window-end’ (*note Window Start and End::を参照)を使 用する際には気をつけなければならない。最新の値が必要なら、それを確 実に入力するためにUPDATE引数を使用しなければならない。 *警告:* ウィンドウのスクロール方法を変更するためにこの機能を使用し てはならない。これはそのような用途のためにデザインされておらず、そ のような使用では機能しないだろう。 -- Variable: window-size-change-functions この変数は、理由は何であれ任意のウィンドウのサイズが変更された場合 に呼び出される関数のリストを保持する。これらの関数は、再表示サイク ルの先頭、およびサイズ変更が発生したフレーム上で1回呼び出される。 それぞれの関数はフレームを唯一の引数として呼び出される。そのフレー ム上のどのウィンドウのサイズが変更されたか、および変更された正確な 方法を直接探す方法はない。とはいえ各呼び出しにおいてsize-change関数 が既存のウィンドウとサイズを記録すれば、現在のサイズと以前のサイズ を比較することも可能である。 ウィンドウの作成と削除はサイズの変更とみなされるので、これらの関数 の呼び出しを引き起こす。フレームのサイズ変更は既存のウィンドウのサ イズを変更するので、これも変更とみなされる。 これらの関数内で‘save-selected-window’を使用できる(*note Selecting Windows::を参照)。しかし‘save-window-excursion’ (*note Window Configurations::を参照)を使用してはならない。このマクロのexitはサイ ズ変更とみなされ、それはこれらの関数の際限ない呼び出しを引き起こす だろう。 -- Variable: window-configuration-change-hook 既存フレームのウィンドウ構成を変更するたびに毎回実行されるノーマル フック。これにはウィンドウの分割と削除、ウィンドウのサイズ変更、ウ ィンドウ内への異なるバッファーの表示が含まれる。 このフックのバッファーローカルな部分は影響を受けるフレーム上の各ウ ィンドウにたいして、関係するウィンドウを選択およびそのバッファーを カレントにして1回実行される。グローバルな部分は変更されたフレームに たいして、そのフレームを選択して1回実行される。 加えてFont Lockフォント表示関数(Font Lock fontification function)を登 録するために‘jit-lock-register’を使用できる。バッファーの一部が(再)フォ ント表示されたときは、ウィンドウがスクロールまたはサイズ変更されたという 理由で、これが常に呼び出されるだろう。*note Other Font Lock Variables::を 参照のこと。 28 フレーム *********** “フレーム(frame)”とは、1つ以上のEmacsウィンドウを含むスクリーンオブジェ クトです(*note Windows::を参照)。これはグラフィカル環境では“ウィンドウ ”と呼ばれる類のオブジェクトです。しかしEmacsはこの単語を異なる方法で使用 しているので、ここではそれを“ウィンドウ”と呼ぶことはできません。Emacs Lispにおいて“フレームオブジェクト(frame object)”とは、スクリーン上のフレ ームを表すLispオブジェクトです。*note Frame Type::を参照してください。 フレームには最初は1つのメインウィンドウおよび/またはミニバッファーウ ィンドウが含まれます。メインウィンドウは、より小さいウィンドウに垂直か水 平に分割することができます。*note Splitting Windows::を参照してください 。 “端末(terminal)”とは1つ以上のEmacsフレームを表示する能力のあるデバイ スのことです。Emacs Lispにおいて“端末オブジェクト(terminal object)”とは 端末を表すLispオブジェクトです。*note Terminal Type::を参照してください 。 端末には“テキスト端末(text terminals)”と“グラフィカル端末(graphical terminals)”という2つのクラスがあります。テキスト端末はグラフィック能力を もたないディスプレイであり、‘xterm’やその他の端末エミュレーターが含まれ ます。テキスト端末上ではそれぞれのEmacsフレームはその端末のスクリーン全 体を占有します。たとえ追加のフレームを作成してそれらを切り替えることがで きたとしても、端末が表示するのは一度に1つのフレームだけです。一方でグラ フィカル端末はXウィンドウシステムのようなグラフィカルディスプレイシステ ムにより管理されています。これによりEmacsは同一ディスプレイ上に複数のフ レームを同時に表示することができます。 GNUおよびUnix systemsシステムでは、単一のEmacsセッション内でその Emacsがテキスト端末とグラフィカル端末のいずれで開始されたかに関わらず、 任意の利用可能な端末上で追加のフレームを作成することができます。Emacsは 、グラフィカル端末とテキスト端末の両方を同時に表示することができます。 こ れはたとえばリモートから同じセッションに接続する際などに便利でしょう。 *note Multiple Terminals::を参照してください。 -- Function: framep object この述語(predicate)はOBJECTがフレームなら非‘nil’、それ以外は‘nil’を リターンする。フレームにたいしてはフレームが使用するディスプレイの 種類が値: ‘t’ そのフレームはテキスト端末上で表示されている。 ‘x’ そのフレームはXグラフィカル端末上で表示されている。 ‘w32’ そのフレームはMS-Windowsグラフィカル端末上で表示されている。 ‘ns’ そのフレームはGNUstepかMacintosh Cocoaグラフィカル端末上で表示 されている。 ‘pc’ そのフレームはMS-DOS端末上で表示されている。 -- Function: frame-terminal &optional frame この関数はFRAMEを表示する端末オブジェクトをリターンする。FRAMEが ‘nil’または未指定の場合のデフォルトは選択されたフレーム。 -- Function: terminal-live-p object この述語はOBJECTが生きた(削除されていない)端末なら非‘nil’、それ以外 は‘nil’をリターンする。生きた端末にたいしては、リターン値はその端末 上で表示されているフレームの種類を示す。可能な値は上述の‘framep’と 同様。 28.1 フレームの作成 =================== 新たにフレームを作成するためには関数‘make-frame’を呼び出します。 -- Command: make-frame &optional alist この関数はカレントバッファーを表示するフレームを作成してそれをリタ ーンする。 ALIST引数は新たなフレームのフレームパラメーターを指定するalist。 *note Frame Parameters::を参照のこと。ALIST内で‘terminal’パラメータ ーを指定すると新たなフレームはその端末上で作成される。それ以外なら ALIST内で‘window-system’フレームパラメーターを指定した場合には、そ れはフレームがテキスト端末とグラフィカル端末のどちらで表示されるべ きかを決定する。*note Window Systems::を参照のこと。どちらも指定さ れなければ新たなフレームは選択されたフレームと同じ端末上に作成され る。 ALISTで指定されなかったパラメーターのデフォルトは、 ‘default-frame-alist’というalist内の値。そこでも指定されないパラメ ーターのデフォルトはXリソース、またはそのオペレーティングシステムで 同等のものの値となる(*note X Resources: (emacs)X Resources.を参照 )。フレームが作成された後にEmacsは‘frame-inherited-parameters’ (以 下参照)内にリストされたすべてのパラメーターを適用して、引数にないも のは‘make-frame’呼び出し時に選択されていたフレームから値を取得する 。 マルチモニターディスプレイ(*note Multiple Terminals::を参照)では、 ウィンドウマネージャーがALIST内の位置パラメーター(*note Position Parameters::を参照)の指定とは異なる位置にフレームを配置するかもしれ ないことに注意。たとえばウィンドウの大きな部分、いわゆる“支配モニタ ー(dominating monitor)”上のフレームを表示するポリシーをもつウィンド ウマネージャーがいくつかあります。 この関数自体が新たなフレームを選択されたフレームにする訳ではない。 *note Input Focus::を参照のこと。以前に選択されていたフレームは選択 されたままである。しかしグラフィカル端末上ではウィンドウシステム自 身の理由によって新たなフレームが選択されるかもしれない。 -- Variable: before-make-frame-hook ‘make-frame’がフレームを作成する前に、それにより実行されるノーマル フック。 -- Variable: after-make-frame-functions ‘make-frame’がフレームを作成した後に、それにより実行されるアブノー マルフック。‘after-make-frame-functions’内の各関数は作成された直後 のフレームを単一の引数として受け取る。 -- Variable: frame-inherited-parameters この変数はカレントで選択されているフレームから継承して新たに作成さ れたフレームのフレームパラメーターのリストを指定する。リスト内の各 要素は‘make-frame’の引数として与えられなかったパラメーター(シンボル )であり、‘make-frame’は新たに作成されたフレームのそのパラメーターに 選択されたフレームのパラメーターの値をセットする。 28.2 複数の端末 =============== Emacsはそれぞれの端末を“端末オブジェクト(terminal object)”というデータ型 で表します(*note Terminal Type::を参照)。GNUおよびUnixシステムでは Emacsはそれぞれのセッション内で複数の端末を同時に実行できます。その他の システムでは単一の端末だけが使用できます。端末オブジェクトはそれぞれ以下 の属性をもちます: • その端末により使用されるデバイスの名前(たとえば‘:0.0’や‘/dev/tty’ )。 • その端末により使用される端末とキーボードのコーディングシステム。 *note Terminal I/O Encoding::を参照のこと。 • その端末に関連付けられたディスプレイの種類。これは関数 ‘terminal-live-p’によりリターンされるシンボル(たとえば‘x’、‘t’、 ‘w32’、‘ns’、‘pc’ )。*note Frames::を参照のこと。 • 端末パラメーターのリスト。*note Terminal Parameters::を参照のこと。 端末オブジェクトを作成するプリミティブはありません。 ‘make-frame-on-display’ (以下参照)を呼び出したときなどに、Emacsが必要に 応じてそれらを作成します。 -- Function: terminal-name &optional terminal この関数はTERMINALにより使用されるデバイスのファイル名をリターンす る。TERMINALが省略または‘nil’の場合のデフォルトは選択されたフレーム の端末。TERMINALはフレームでもよく、その場合はそのフレームの端末。 -- Function: terminal-list この関数はすべての生きた端末オブジェクトのリストをリターンする。 -- Function: get-device-terminal device この関数はDEVICEにより与えられたデバイス名の端末をリターンする。 DEVICEが文字列なら端末デバイス名、または‘HOST:SERVER.SCREEN’という 形式のXディスプレイのいずれかを指定できる。DEVICEならこの関数はその フレームの端末をリターンする。‘nil’は選択されたフレームを意味する。 最後にもしDEVICEが生きた端末を表す端末オブジェクトなら、その端末が リターンされる。引数がこれらのいずれとも異なれば、この関数はエラー をシグナルする。 -- Function: delete-terminal &optional terminal force この関数はTERMINAL上のすべてのフレームを削除して、それらが使用して いたリソースを解放する。これらはアブノーマルフック ‘delete-terminal-functions’を実行して、各関数の引数としてTERMINALを 渡す。 TERMINALが省略または‘nil’の場合のデフォルトは選択されたフレームの端 末。TERMINALはフレームでもよく、その場合はそのフレームの端末を意味 する。 この関数は通常は唯一アクティブな端末の削除を試みるとエラーをシグナ ルするが、FORCEが非‘nil’ならこれを行うことができる。端末上で最後の フレームを削除した際には、Emacsは自動的にこの関数を呼び出す(*note Deleting Frames::を参照)。 -- Variable: delete-terminal-functions ‘delete-terminal’により実行されるアブノーマルフック。各関数は ‘delete-terminal’に渡されたTERMINALを唯一の引数として受け取る。技術 的な詳細により、この関数は端末の削除の直前または直後のいずれかに呼 び出される。 数は多くありませんが、Lisp変数のいくつかは“端末ローカル (terminal-local)”です。つまりそれらは端末それぞれにたいして個別にバイン ディングをもちます。いかなるときも実際に効果をもつバインディングはカレン トで選択されたフレームに属する端末にたいして1つだけです。これらの変数に は‘default-minibuffer-frame’、‘defining-kbd-macro’、‘last-kbd-macro’、 ‘system-key-alist’が含まれます。これらは常に端末ローカルであり、決してバ ッファーローカル(*note Buffer-Local Variables::を参照)にはできません。 GNUおよびUnixシステムでは、Xディスプレイはそれぞれ別のグラフィカル端 末になります。Xウィンドウシステム内でEmacsが開始された際は環境変数 ‘DISPLAY’、または‘--display’オプション(*note (emacs)Initial Options::を 参照)により指定されたXディスプレイを使用します。Emacsはコマンド ‘make-frame-on-display’を通じて別のXディスプレイに接続できます。それぞれ のXディスプレイは、それぞれが選択されたフレームとミニバッファーをもちま す。しかしあらゆる瞬間(*note Input Focus::を参照)において、それらのフレ ームのうちの1つだけが、_いわゆる_選択されたフレームになります。 ‘emacsclient’との対話により、Emacsが別のテキスト端末と接続することさえ可 能です。*note (emacs)Emacs Server::を参照してください。 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’です。これは互換性のために存在するものであり、ディスプレイ名を 期待する関数にこれを渡すことができます。 -- Command: make-frame-on-display display &optional parameters この関数はDISPLAY上に新たにフレームを作成してそれをリターンする。そ の他のフレームパラメーターは、PARAMETERSというalistから取得する。 DISPLAYはXディスプレイの名前(文字列)であること。 この関数はフレーム作成前にEmacsがグラフィックを表示するためにセット アップされることを保証する。(テキスト端末上で開始された等で)たとえ ばEmacsがXリソースを未処理ならこの時点で処理を行う。他のすべての点 においては、この関数は‘make-frame’(*note Creating Frames::を参照)と 同様に振る舞う。 -- Function: x-display-list この関数はEmacsがどのXディスプレイに接続したかを識別するリストをリ ターンする。このリストの要素は文字列で、それぞれがディスプレイ名を 表す。 -- Function: x-open-connection display &optional xrm-string must-succeed この関数はディスプレイ上にフレームを作成することなく、Xディスプレイ DISPLAYへの接続をオープンする。通常は‘make-frame-on-display’が自動 的に呼び出すので、Emacs Lispプログラムがこの関数を呼び出す必要はな い。これを呼び出す唯一の理由は、与えられたXディスプレイにたいして通 信を確立できるかどうかチェックするためである。 オプション引数XRM-STRINGが非‘nil’なら、それは‘.Xresources’ファイル 内で使用されるフォーマットと同一なリソース名とリソース値。*note X Resources: (emacs)X Resources.を参照のこと。これらの値はそのXサーバ ー上で記録されたリソース値をオーバーライドして、このディスプレイ上 で作成されるすべてのEmacsフレームにたいして適用される。以下はこの文 字列がどのようなものかを示す例: "*BorderWidth: 3\n*InternalBorder: 2\n" MUST-SUCCEEDが非‘nil’なら、接続オープンの失敗によりEmacsが終了させ られる。それ以外なら通常のLispエラーとなる。 -- Function: x-close-connection display この関数はディスプレイDISPLAYへの接続をクローズする。これを行う前に は、まずそのディスプレイ上でオープンしたすべてのフレームを削除しな ければならない(*note Deleting Frames::を参照)。 マルチモニターのセットアップにおいて、単一のXディスプレイが複数の物理 モニターに出力される場合があります。そのようなセットアップを取得するため に関数‘display-monitor-attributes-list’と‘frame-monitor-attributes’を使 用できます。 -- Function: display-monitor-attributes-list &optional display この関数はDISPLAY上の物理モニターの属性のリストをリターンする。 DISPLAYにはディスプレイ名(文字列)、端末、フレームを指定でき、省略ま たは‘nil’の場合のデフォルトは選択されたフレームのディスプレイ。この リストの各要素は物理モニターの属性を表す連想リスト。1つ目の要素はプ ライマリーモニターである。以下は属性のキーと値: ‘geometry’ ‘(X Y WIDTH HEIGHT)’のようなピクセル単位でのそのモニターのスク リーンの左上隅の位置とサイズ。そのモニターがプライマリーモニタ ーでなければ、いくつかの座標が負になり得る。 ‘workarea’ ‘(X Y WIDTH HEIGHT)’のようなピクセル単位でのワークエリア(使用 可能なスペース)の左上隅の位置とサイズ。ウィンドウマネージャー のさまざまな機能(dock、taskbar等)によりそのスペースが占有され る‘geometry’とは異なり、これはワークエリアから除外され得る。そ のような機能が実際にワークエリアから差し引かれるかどうかは、そ のプラットフォームと環境に依存する。繰り返しになるが、そのモニ ターがプライマリーモニターでなければ、いくつかの座標は負になり 得る。 ‘mm-size’ ‘(WIDTH HEIGHT)’<のようなミリメートル単位での幅と高さ。 ‘frames’ その物理モニターが支配(dominate)するフレームのリスト(以下参照 )。 ‘name’ STRINGのようなその物理モニターの名前。 ‘source’ STRINGのようなマルチモニターの情報ソース(例: ‘XRandr’、 ‘Xinerama’等)。 X、Y、WIDTH、HEIGHTは整数。‘name’と‘source’は欠落しているかもしれな い。 あるモニター内にフレームの最大領域がある、または(フレームがどの物理 モニターにも跨がらないなら)そのモニターがフレームに最も近いとき、フ レームは物理モニターにより“支配(dominate)”される。グラフィカルなデ ィスプレイ内の(ツールチップではない)すべてのフレームは、たとえその フレームが複数の物理モニターに跨がる(または物理モニター上にない)と しても、(可視か否かによらず)正確に1つの物理モニターにより支配される 。 以下は2つのモニターディスプレイ上でこの関数により生成されたデータの 例: (display-monitor-attributes-list) ⇒ (((geometry 0 0 1920 1080) ;; 左手側プライマリーモニター (workarea 0 0 1920 1050) ;; タスクバーが幾分かの高さを占有 (mm-size 677 381) (name . "DISPLAY1") (frames # #)) ((geometry 1920 0 1680 1050) ;; 右手側モニター (workarea 1920 0 1680 1050) ;; スクリーン全体を使用可 (mm-size 593 370) (name . "DISPLAY2") (frames))) -- Function: frame-monitor-attributes &optional frame この関数はFRAMEを支配(上記参照)する物理モニターの属性をリターンする 。 FRAMEのデフォルトは選択されたフレーム。 28.3 Frame Geometry =================== フレームのジオメトリー(geometry)は、そのEmacsインスタンスのビルドに使用 されたツールキット、およびそのフレームを表示する端末に依存します。このチ ャプターではこれらの依存関係とそれらを処理するいくつかの関数を説明します 。これらの関数すべてにたいして、FRAME引数には生きたフレームを指定する必 要があることに注意してください(*note Deleting Frames::を参照)。省略また は‘nil’なら選択されたフレーム(*note Input Focus::を参照)が指定されます。 28.3.1 Frame Layout ------------------- 以下にグラフィカル端末上のフレームレイアウトを図示します: <------------ Outer Frame Width -----------> ___________________________________________ ^(0) ___________ External Border __________ | | | |_____________ Title Bar ______________| | | | (1)_____________ Menu Bar ______________| | ^ | | (2)_____________ Tool Bar ______________| | ^ | | (3) _________ Internal Border ________ | | ^ | | | | ^ | | | | | | | | | | | | | Outer | | | Inner | | | Native Frame | | | Frame | | | Frame Height | | | Height | | | Height | | | | | | | | | | | | |<--+--- Inner Frame Width ------->| | | | | | | | | | | | | | | | |___v______________________________| | | | | | |___________ Internal Border __________| | v v |______________ External Border _____________| <-------- Native Frame Width --------> 図示したすべての領域が実際に存在するわけではありません。これらの領域 はそれぞれ以下を意味しています: ‘アウターフレーム(Outer Frame)’ “アウターフレーム(outer frame)”とは上図で示すすべての領域を網羅する 矩形。この矩形の端はそのフレームの“アウターエッジ(outer edges)”と呼 ばれる。フレームの“アウター幅(outer width)”と“アウター高さ(outer height)”はこの矩形のサイズを指定する。 (上図‘(0)’で示される)アウターフレームの左上隅はフレームの“アウター 位置(outer position)”。これはフレームパラメーター‘left’と‘top’によ る指定(*note Position Parameters::を参照)、同様に関数 ‘frame-position’と‘set-frame-position’ (*note Size and Position::を 参照)を通じてセットできる。 ‘エクスターナルボーダー(External Border)’ “エクスターナルボーダー(external border)”はウィンドウマネージャーに より供給される装飾の一部。マウスによるフレームのリサイズで典型的に 使用される。エクスターナルボーダーは、通常は“全画面化(fullboth)”お よび最大化されたフレームでは表示されず(*note Size Parameters::を参 照)、テキスト端末のフレームには存在しない。 フレームパラメーター‘border-width’ (*note Layout Parameters::を参照 )で指定される“アウターボーダー(outer border)”とエクスターナルボーダ ーを混同しないこと。アウターボーダーはほとんどのプラットフォームで 通常は無視されるので、ここでは説明しない。 ‘タイトルバー(Title Bar)’ “タイトルバー(title bar)”もウィンドウマネージャーによる装飾の一部で あり、典型的にはフレームタイトルの表示(*note Frame Titles::を参照 )、フレームの最小化や最大化、削除のためのボタン表示に使用される。タ イトルバーは全画面表示(*note Size Parameters::を参照やツールチップ フレームでは通常は表示されない。テキスト端末フレームではタイトルバ ーは存在しない。 ‘メニューバー(Menu Bar)’ メニューバー(*note Menu Bar::を参照)にはインターナル(Emacs自身が描 画)とエクスターナル(ツールキットが描画)がある。ほとんどのビルド (GTK+、Lucid、Motif、Windows)にはエクスターナルメニューバーが存在す る。NSでもエクスターナルメニューバーを使用するがアウターフレームの 一部ではない。非ツールキットのビルドではインターナルメニューバーが 提供可能。テキスト端末のフレームでは、メニューバーはフレームのルー トウィンドウの(*note Windows and Frames::を参照)一部である。 ‘ツールバー(Tool Bar)’ メニューバーのように、ツールバー(*note Tool Bar::を参照)にもインタ ーナル(Emacs自身が描画)とエクスターナル(ツールキットが描画)がある。 GTK+とNSのビルドには、そのツールキットが描画するツールバーがある。 その他のビルドはインターナルツールバーを使用する。GTK+ではツールバ ーはフレーム側面かインターナルボーダー(以下参照)の外側にのいずれか に配置され得る。 ‘ネイティブフレーム(Native Frame)’ “ネイティブフレーム(native frame)”はアウターフレーム内全体に配置さ れる矩形。エクスターナルボーダーとタイトルバー、およびエクスターナ ルメニューとエクスターナルツールバーが占有する領域は除外される。ネ イティブフレームで囲まれた領域は、そのフレームの“ディスプレー領域 (display area)”として参照されることもある。ネイティブフレームのエッ ジは、そのフレームの“ネイティブエッジ(native edges)”と呼ばれる。フ レームの“ネイティブ幅(native width)”と“ネイティブ高さ(native height)”は、この矩形のサイズを指定する。 ネイティブフレームの左上隅は、そのフレームの“ネイティブ位置(native position)”を指定する。上図(1)から(3)では種々ビルドにたいする位置を 示す: (1) 非ツールキットと端末フレーム (2) Lucid、Motif、Windowsのフレーム (3) GTK+とNSのフレーム これに応じてフレームのネイティブ高さにはツールバーの高さが含まれる がメニューバーの高さ(Lucid、Motif、Windows)や、メニューバーとツール バーの高さ(非ツールキットとテキスト端末のフレーム)は含まれない。 フレームのネイティブ位置はマウスのカレント位置のセットやリターンを 行う関数(*note Mouse Position::を参照)、および‘window-edges’、 ‘window-at’、‘coordinates-in-window-p’のようなウィンドウの位置を扱 う関数(*note Coordinates and Windows::を参照)にたいして基準となる位 置である。 ‘インターナルボーダー(Internal Border)’ インターナルボーダー(*note Layout Parameters::を参照)はEmacsがイン ナーフレーム(以下参照)周囲に描画するボーダー。 ‘インナーフレーム(Inner Frame)’ “インナーフレーム(inner frame)”はフレームのウィンドウが確保する矩形 。インターナルボーダーに囲まれているが、それはインナーフレームの一 部ではない。それのエッジはフレームの“インナーエッジ(inner edges)”と 呼ばれる。“インナー幅(inner width)”と“インナー高さ(inner height)”は 、その矩形のサイズを指定する。 ルールとしてインナーフレームはフレームのルートウィンドウ(*note Windows and Frames::を参照)とミニバッファーウィンドウ(*note Minibuffer Windows::を参照)に細分される。この2つには注目すべき2つの 例外がある。それはミニバッファーウィンドウをもたないルートウィンド ウのみの“ミニバッファーlessフレーム(minibuffer-less frame)”と、ミニ バッファーウィンドウだけをもち、それがフレームのルートウィンドウの 役目も果たす“ミニバッファーonlyウィンドウ(minibuffer-only frame)”で ある。そのようなフレーム構成を作成する方法は*note Initial Parameters::を参照のこと。 ‘テキストエリア(Text Area)’ フレームの“テキストエリア(text area)”とは、ネイティブフレーム内に全 体が配置される架空な類のエリアである。このエリアはネイティブフレー ムからすべてのインターナルボーダー、垂直スクロールバーと水平スクロ ールバー、およびそのフレームにたいして指定された左右のフリンジを取 り除くことにより取得できる。*note Layout Parameters::を参照のこと。 フレームやフレームのエッジの“絶対位置(absolute position)”とは、通常は そのフレームのディスプレーの位置(0, 0)にある原点から計測したピクセル単位 で与えられます。複数モニターの原点は、使用可能なディスプレーエリア全体の 左上隅と一致する必要はないことに注意してください。そのため、そのような環 境ではフレームの絶対アウター位置やアウターフレーム、ネイティブフレーム、 インナーフレームのエッジの絶対位置は、たとえそのフレームが完全に可視であ っても負になり得ます。 以下の関数はグラフィカル端末上のフレームにたいして上述したエリアのサ イズをリターンします: -- Function: frame-geometry &optional frame この関数はFRAMEのジオメトリーに関する属性をリターンする。リターン値 は属性の連想配列。すべての座標、高さ、幅はピクセル単位の整数。 ‘outer-position’ FRAMEのディスプレー位置(0, 0)にある原点から相対的なFRAMEのアウ ター位置を表す、絶対X座標と絶対Y座標によるコンス。 ‘outer-size’ FRAMEのアウター幅とアウター高さを表すコンス。 ‘external-border-size’ ウィンドウマネージャーにより与えられる、FRAMEエクスターナルボ ーダーの水平幅と垂直幅を表すコンス。ウィンドウマネージャーによ りこれらの値が提供されなければ、Emacsはアウターフレームとイン ナーフレームの座標からそれらの推測を試みる。 ‘title-bar-size’ ウィンドウマネージャーまたはオペレーティングシステムが与える、 FRAMEのタイトルバーの幅と高さを表すコンス。いずれも0なら、その フレームにタイトルバーはない。幅だけが0なら、Emacsが幅の情報を 取得できなかったことを意味する。 ‘menu-bar-external’ 非‘nil’なら、それはメニューバーがエクスターナルである(FRAMEの ネイティブフレームの一部ではない)ことを意味する。 ‘menu-bar-size’ FRAMEのメニューバーの幅と高さを表すコンス。 ‘tool-bar-external’ 非‘nil’なら、それはツールバーがエクスターナルである(FRAMEのネ イティブフレームの一部ではない)ことを意味する。 ‘tool-bar-position’ これはツールバーがFRAMEのどの端に配置されているかを示し ‘left’、‘top’、‘right’、‘bottom’のいずれか。現在のところ ‘top’以外の値をサポートするツールキットはGTK+のみ。 ‘tool-bar-size’ FRAMEのツールバーの幅と高さを表すコンス。 ‘internal-border-width’ FRAMEのインターナルボーダーの幅。 以下の関数はフレームにたいするアウター、ネイティブ、インナーのエッジ の取得に使用できます。 -- Function: frame-edges &optional frame type この関数はFRAMEのアウターフレーム、ネイティブフレーム、インナーフレ ームのエッジをリターンする。FRAMEは生きたフレームでなければならずデ フォルトは選択されたフレーム。リターンされるリストは(LEFT TOP RIGHT BOTTOM)という形式をもち、すべての値はFRAMEのディスプレーの位置(0, 0)から相対的なピクセル値。端末フレームではLEFTとTOPはいずれも0。 オプション引数TYPEはリターンするエッジのタイプを指定する。 ‘outer-edges’はFRAMEのアウターエッジ、‘native-edges’ (または‘nil’ )はネイティブエッジ、‘inner-edges’はインナーエッジをリターンするこ とを意味する。 BOTTOMおよびRIGHTの位置のピクセルは、対応するフレームのすぐ外側にな ることに注目。これはたとえば、左フレームの右アウターエッジが右フレ ームの左アウターエッジと等しいような横並びの2つのフレームがあるよう な場合には、そのエッジを表すピクセルは右フレームの一部であることを 意味する。 28.3.2 Frame Font ----------------- フレームにはそれぞれ、そのフレームにたいするデフォルト文字サイズを指定す る“デフォルトフォント(default font)”があります。このサイズは、行や列の単 位でのフレームサイズの取得や変更での使用を意図したものです(*note Size Parameters::を参照)。これはウィンドウのリサイズ(*note Window Sizes::を参 照)や分割(*note Splitting Windows::を参照)の際にも使用されます。 “デフォルト文字高さ(default character height)t”のかわりに“行高さ(line height)”や“正準文字高さ(canonical character height)”という用語を使用する ときがあります。同様に“デフォルト文字幅(default character width)”のかわ りに“列幅(column width)”や“正準文字幅(canonical character width)”という 用語も使用されます。 -- Function: frame-char-height &optional frame -- Function: frame-char-width &optional frame これらの関数はピクセルで測ったFRAME内の文字のデフォルトの高さまたは 幅をリターンする。両者をあわせたサイズによりFRAMEのFRAMEのサイズが 確立される。値はFRAMEにたいして選択されたフォントに依存する。*note Font and Color Parameters::を参照のこと。 以下の関数でデフォルトフォントを直接セットすることもできます: -- Command: set-frame-font font &optional keep-size frames これはデフォルトフォントにFONTをセットする。インタラクティブに呼び 出された際にはフォント名の入力を求めて、選択されたフレームにそのフ ォントを使用する。Lispから呼び出す際には、FONTはフォント名(文字列 )、フォントオブジェクト、フォントエンティティー、フォントspecのいず れかであること。 オプション引数KEEP-SIZEが‘nil’ならフレームの行数と列数を固定に保つ (非‘nil’なら次セクションで説明するオプション ‘frame-inhibit-implied-resize’がこれをオーバーライドするだろう)。 KEEP-SIZEが非‘nil’ (またはプレフィクス引数を指定)なら行数と列数を調 節することにより、カレントフレームのディスプレーエリアのサイズの維 持を試みる。 オプション引数FRAMESが‘nil’なら、そのフォントは選択されたフレームだ けに適用される。FRAMESが非‘nil’ならそれは作用するフレームのリスト、 またはすべての既存フレームおよび将来のすべてのグラフィカルフレーム を意味する‘t’のいずれかであること。 28.3.3 Size and Position ------------------------ フレームパラメーター‘left’と‘top’ (*note Position Parameters::を参照)を 使用してフレームの位置、およびパラメーター‘height’と‘width’ (*note Size Parameters::を参照)を使用してフレームのサイズの読み取りや変更ができます 。サイズと位置を処理するために特別な機能があります。これらの関数すべてに たいして、引数FRAMEは生きたフレームでなければならず、デフォルトは選択さ れたフレームです。 -- Function: frame-position &optional Lisp_Object &optional frame この関数はFRAMEのアウター位置(*note Frame Layout::を参照)のピクセル 単位でリターンする。値はFRAMEのアウターフレームの左上隅にたいして、 フレームのディスプレーの位置(0, 0)から相対的な座標を与えるコンス。 テキスト端末フレームではいずれも0。 -- Function: set-frame-position frame X Y この関数はFRAMEのアウターフレームの位置をXとYにセットする。後者の引 数はピクセル単位で、通常はFRAMEのディスプレーの位置(0, 0)にある原点 から計測される。 負のパラメーター値はスクリーン右エッジから-Xピクセルのアウターフレ ームの右エッジ、またはスクリーン下エッジから-Yピクセルのアウターフ レームの下エッジを指す。 この関数はテキスト端末フレームでは効果がない。 -- Function: frame-pixel-height &optional frame -- Function: frame-pixel-width &optional frame これらの関数はFRAMEのインナー高さやインナー幅(ディスプレーエリアの 高さと幅。*note Frame Layout::を参照)をピクセル単位でリターンする。 テキスト端末では結果はピクセル単位ではなく文字単位。 -- Function: frame-text-height &optional frame -- Function: frame-text-width &optional frame これらの関数はピクセルで測ったFRAMEのテキストエリア(*note Frame Layout::を参照)の高さや幅をリターンする。テキスト端末では結果はピク セルではなく文字単位。 ‘frame-text-height’がリターンする値はすべてのインターナルなツールバ ーとメニューバーの高さ、水平スクロールバーの高さやインターナルボー ダーの幅を含まないので、‘frame-pixel-height’のリターン値とは異なる 。 ‘frame-text-width’垂直スクロールバーの幅や左右フリンジの幅、および インターナルボーダーの幅を含まないので、‘frame-pixel-width’のリター ン値とは異なる。 -- Function: frame-height &optional frame -- Function: frame-width &optional frame これらの関数はFRAMEのテキストエリアの高さと幅を、FRAMEのデフォルト フォントの高さと幅を単位に計測してリターンする。これらの関数は単に ‘(frame-parameter frame 'height)’と‘(frame-parameter frame 'width)’を略記したもの。 ピクセルで計測したFRAMEのテキストエリアがデフォルトフォントサイズの 倍数でなければ、これらの関数がリターンする値はテキストエリアに完全 に収まるデフォルトフォントの文字数に切り捨てられる。 -- User Option: frame-resize-pixelwise このオプションが‘nil’なら、通常はフレームリサイズ時にサイズがそのフ レームの‘frame-char-height’と‘frame-char-width’のカレント値の倍数に 丸められる。非‘nil’なら丸めは行われず、フレームのサイズはピクセル単 位で増加/減少が可能になる。 この変数をセットすることにより次回のリサイズ処理では、通常はウィン ドウマネージャーにこれに相当するサイズのヒントを渡す。これはユーザ ーの初期ファイル内でのみこの変数をセットすべきで、アプリケーション が一時的にこれをバインドすべきではないことを意味する。 このオプションにたいして‘nil’値がもつ正確な意味は使用されるツールキ ットに依存する。マウスによるエクスターナルボーダーのドラッグは、ウ ィンドウマネージャーが対応するサイズヒントを処理する意思があれば文 字単位で行われる。文字サイズの整数倍ではないフレームサイズを引数と して‘set-frame-size’ (以下参照)を呼び出すと、もしかしたら丸められた り(GTK+)、あるいは受容される(Lucid、Motif、MS-Windows)かもしれない 。 いくつかのウィンドウマネージャーでは、フレームを本当に最大化や全画 面で表示させるために、これを非‘nil’にセットする必要があるかもしれな い。 -- Function: set-frame-size frame width height &optional pixelwise この関数はFRAMEのテキストエリアのサイズを、FRAMEの文字の正準高さと 正準幅で計測した単位でセトする(*note Frame Font::を参照)。 オプション引数PIXELWISEが非‘nil’なら、かわりにピクセル単位で新たな 幅と高さを測ることを意味する。‘frame-resize-pixelwise’が‘nil’の場合 には、それが文字の整数倍でフレームサイズを増加や減少させないなら、 この要求を完全には尊重せずに拒絶するツールキットがいくつかあること に注意。 -- Function: set-frame-height frame height &optional pretend pixelwise この関数はFRAMEのテキストエリアをHEIGHT行の高さにリサイズする。 FRAME内の既存ウィンドウのサイズはフレームにフィットするよう比例して 変更される。 PRETENDが非‘nil’なら、EmacsはFRAME内でHEIGHT行の出力を表示するが、 そのフレームの実際の高さにたいする値は変更しない。これはテキスト端 末上でのみ有用。端末が実際に実装するより小さい高さの使用は、より小 さいスクリーン上での振る舞いの再現したり、スクリーン全体を使用時の 端末の誤動作を観察するとき有用かもしれない。フレームの高さの直接セ ットは常に機能するとは限らない。なぜならテキスト端末上でのカーソル を正しく配置するために、正確な実サイズを知る必要があるかもしれない からである。 オプションの第4引数PIXELWISEが非‘nil’なら、それはFRAMEの高さが HEIGHTピクセル高くなることを意味する。‘frame-resize-pixelwise’が ‘nil’なら、それが文字の整数倍でフレームサイズを増加や減少させない場 合には、この要求を完全には尊重せずに拒絶するツールキットがいくつか あることに注意。 -- Function: set-frame-width frame width &optional pretend pixelwise この関数は文字単位でFRAMEのテキストエリアの幅をセットする。引数 PRETENDは‘set-frame-height’のときと同じ意味をもつ。 オプションの第4引数PIXELWISEが非‘nil’なら、それはFRAMEの幅が HEIGHTピクセル広くなることを意味する。‘frame-resize-pixelwise’が ‘nil’なら、それが文字の整数倍でフレームサイズを増加あるいは減少させ ない場合には、この要求を完全には尊重せずに拒絶するツールキットがい くつかあることに注意。 これら3つの関数のうち、すべてのウィンドウとともにスクロールバー、フリ ンジ、マージン、ディバイダー、モードライン、ヘッダーラインを表示するため に必要なサイズよりフレームを小さくする関数はありません。これはたとえばマ ウスによるフレームのエクスターナルボーダーのドラッグのようなウィンドウマ ネージャーのリクエストとは対照的です。フレーム右下隅にある表示できない部 分は必要に応じてクリッピングするとにより、そのようなリクエストは常に尊重 されます。 28.3.4 Implied Frame Resizing ----------------------------- たとえばメニューバーの追加や削除、デフォルトフォントの変更、フレームのス クロールバーの幅のセットの際、Emacsはデフォルトではフレームのテキストエ リアの行数と列数を未変更に保つように試みます。しかしこれはそのような場合 のサイズ変更を調停するために、Emacsがウィンドウマネージャーに依頼しなけ ればならないことを意味します。メニューバーやツールバーのでは、通常はフレ ームのフレームサイズをリサイズしないので、表示される行数に変更はないこと に注意してください。 たとえばフレームの最大化や全画面化の際のように、そのような“暗黙なフレ ームのリサイズ(implied frame resizing)”がおそらく望ましくないケースもあ ります(デフォルトではオフになっている)。それ以外のケースでは以下のオプシ ョンで暗黙のリサイズを無効にできます。 -- User Option: frame-inhibit-implied-resize このオプションが‘nil’ならフレームが表示する列数と行数を確保するため に特定フレームのフォント、メニューバー、ツールバー、インターナルボ ーダー、フリンジ、スクロールバーの変更によってフレームのディスプレ ーエリアを暗黙に変更できる。このオプションが非‘nil’なら暗黙のリサイ ズは行われない。 このオプションの値はフレームパラメーターのリストかもしれない。この 場合には、このリスト内に出現するパラメーター変更時の暗黙のリサイズ は抑制される。このオプションで処理されるフレームパラメーター現在の ところ‘font’、‘font-backend’、‘internal-border-width’、 ‘menu-bar-lines’、‘tool-bar-lines’。 フレームパラメーター‘scroll-bar-width’、‘scroll-bar-height’、 ‘vertical-scroll-bars’、‘horizontal-scroll-bars’、‘left-fringe’、 ‘right-fringe’のいずれかにたいする変更は、あたかもそのフレームが単 一の生きたウィンドウを含むかのように処理される。これはたとえば複数 の横並びのウィンドウをフレームで垂直スクロールバーを削除すると、こ のオプションが‘nil’なら‘nil’はスクロールバーの幅の分だけ縮小されて 、‘t’や‘vertical-scroll-bars’を含む場合には未変更に保たれることを意 味する。 デフォルト値はLucid、Motif、Windowsにたいしては‘'(tool-bar-lines)’ (ツールバーの追加や削除でアウターフレーム高さを変更しない)、GTK+を 含むその他のウィンドウシステムでは‘nil’ (上述したすべてのパラメータ ーの変更によりアウターフレームのサイズは変更され得る)、それ以外なら ‘t’ (ウィンドウシステムのサポートがないときには暗黙に変更が行われる ことはない)。 フレームが上述のいずれかのパラメーターにたいする変更の調停に不十分 な際には、たとえこのオプションが非‘nil’でもEmacsがフレームの拡大を 試みるかもしれないことに注意。 28.4 フレームのパラメーター =========================== フレームにはその外見と挙動を制御する多くのパラメーターがあります。フレー ムがどのようなパラメーターをもつかは、そのフレームが使用するディスプレイ のメカニズムに依存します。 フレームパラメーターは主にグラフィカルディスプレイのために存在します 。ほとんどのフレームパラメーターはテキスト端末上のフレームへの適用時には 効果がありません。テキスト端末上のフレームで何か特別なことを行うパラメー ターは‘height’、‘width’、‘name’、‘title’、‘menu-bar-lines’、 ‘buffer-list’、‘buffer-predicate’だけです。その端末がカラーをサポートす る場合には‘foreground-color’、‘background-color’、‘background-mode’、 ‘display-type’などのパラメーターも意味をもちます。その端末が透過フレーム (frame transparency)をサポートする場合には、パラメーター‘alpha’にも意味 があります。 28.4.1 フレームパラメーターへのアクセス --------------------------------------- 以下の関数でフレームのパラメーター値の読み取りと変更ができます。 -- Function: frame-parameter frame parameter この関数はFRAMEのパラメーターPARAMETER (シンボル)の値をリターンする 。FRAMEが‘nil’なら選択されたフレームのパラメーターをリターンする。 FRAMEがPARAMETERにたいするセッティングをもたなければ、この関数は ‘nil’をリターンする。 -- Function: frame-parameters &optional frame 関数‘frame-parameters’はFRAMEのすべてのパラメーターとその値をリスト するalistをリターンする。FRAMEが省略または‘nil’なら選択されたフレー ムのパラメーターをリターンする。 -- Function: modify-frame-parameters frame alist この関数はALISTの要素にもとづきフレームFRAMEを変更する。ALIST内の要 素はそれぞれ‘(PARM . VALUE)’という形式をもつ。ここでPARMはパラメー ターを名付けるシンボルである。 ALIST内に指定されないパラメーターの 値は変更されない。FRAMEが‘nil’の場合のデフォルトは選択されたフレー ム。 いくつかのパラメーターは特定の種類のディスプレー上のフレーム(*note Frames::を参照)でのみ意味がある。FRAMEのディスプレーで意味をもたな いパラメーターがALISTに含まれているようなら、この関数はそのフレーム のパラメーターリスト内の値を変更するが、その他の値を変更しないパラ メーターは無視するだろう。 FRAMEの新たなサイズに影響し得る値をもつようなパラメーターがALISTで 複数指定されている際には、フレームの最終的なサイズは使用しているツ ールキットに応じて異なるかもしれない。たとえばあるフレームにたいし てメニューバーおよび/またはツールバーをもたない状態から保有するよう に指定して、同時に新たなフレーム高さを指定すると、必然的にフレーム の高さの再計算を招くだろう。そのようなケースでは、概念的にはこの関 数は明示的な高さ指定を優先するよう試みる。しかしツールキットにより その後に処理されるメニューバーやツールバーの追加(や削除)を除外する ことはできないので、高さ指定を優先するという意図は打ち消されてしま うだろう。 ここで概略した問題は、この関数の呼び出し前後に ‘frame-inhibit-implied-resize’ (*note Implied Frame Resizing::を参 照)を非‘nil’値にバインドすることで訂正できる場合がある。しかしその ようなバインディングが正に問題を引き起こす場合もある。 -- Function: set-frame-parameter frame parm value この関数はフレームパラメーターPARMに指定されたVALUEをセットする。 FRAMEが‘nil’の場合のデフォルトは選択されたフレーム。 -- Function: modify-all-frames-parameters alist この関数は ALISTに応じて既存のフレームすべてのフレームパラメーター を変更してから、今後に作成されるフレームに同じパラメーター値を適用 するために、‘default-frame-alist’ (必要なら‘initial-frame-alist’も )を変更する。 28.4.2 フレームの初期パラメーター --------------------------------- initファイル(*note Init File::を参照)の内部で‘initial-frame-alist’をセッ トすることにより、フレームの初期スタートアップにパラメーターを指定できま す。 -- User Option: initial-frame-alist この変数の値は初期フレーム作成時に使用されるパラメーター値のalist。 以降のフレームを変更することなく初期フレームの外見を指定するために この変数を使用できる。要素はそれぞれ以下の形式をもつ: (PARAMETER . VALUE) Emacsはinitファイル読み取り前に初期フレームを作成する。Emacsはこの ファイル読み取り後に‘initial-frame-alist’をチェックして、変更する値 に含まれるパラメーターのセッティングを作成済みの初期フレームに適用 する。 これらのセッティングがフレームのジオメトリーと外見に影響する場合に は、間違った外見のフレームを目にした後に、指定した外見に変更される 様を目にするだろう。これが煩わしければ、Xリソースで同じジオメトリー と外見を指定できる。これらはフレーム作成前に効果をもつ。*note X Resources: (emacs)X Resources.を参照のこと。 Xリソースセッティングは、通常はすべてのフレームに適用される。初期フ レームのためにあるXリソースを単独で指定して、それ以降のフレームには 適用したくなければ、次の方法によりこれを達成できる。それ以降のフレ ームにたいするXリソースをオーバーライドするために ‘default-frame-alist’内でパラメーターを指定してから、それらが初期フ レームに影響するのを防ぐために‘initial-frame-alist’内の同じパラメー ターにたいしてXリソースにマッチする値を指定すればよい。 これらのパラメーターに‘(minibuffer . nil)’が含まれていれば、それは初 期フレームがミニバッファーをもつべきではないことを示しています。この場合 には、Emacsは同じように“ミニバッファーonlyフレーム(minibuffer-only frame)”を個別に作成します。 -- User Option: minibuffer-frame-alist この変数の値は、初期ミニバッファーonlyフレーム( ‘initial-frame-alist’がミニバッファーのないフレームを指定する場合に Emacsが作成するミニバッファーonlyフレーム)を作成時に使用されるパラ メーター値のalist。 -- User Option: default-frame-alist これはすべてのEmacsフレーム(最初のフレームとそれ以降のフレーム)にた いしてフレームパラメーターのデフォルト値を指定するalist。Xウィンド ウシステム使用時には、大抵はXリソースで同じ結果を得られる。 この変数のセットは既存フレームに影響しない。さらに別フレームにバッ ファーを表示する関数は、自身のパラメーターを提供することによりデフ ォルトパラメーターをオーバーライドできる。 フレームの外見を指定するコマンドラインオプションとともにEmacsを呼び出 すと、これらのオプションは‘initial-frame-alist’か‘default-frame-alist’の いずれかに要素を追加することにより効果を発揮します。‘--geometry’や ‘--maximized’のような初期フレームだけに影響するオプションは ‘initial-frame-alist’、その他のオプションは‘default-frame-alist’に要素を 追加します。*note Command Line Arguments for Emacs Invocation: (emacs)Emacs Invocation.を参照してください。 28.4.3 ウィンドウフレームパラメーター ------------------------------------- フレームがどんなパラメーターをもつかは、どのようなディスプレイのメカニズ ムがそれを使用するかに依存します。このセクションでは一部、またはすべての 端末種類において特別な意味をもつパラメーターを説明します。これらのうち ‘name’、‘title’、‘height’、‘width’、‘buffer-list’、‘buffer-predicate’は 端末フレームにおいて意味をもつ情報を提供し、‘tty-color-mode’はテキスト端 末上のフレームにたいしてのみ意味があります。 28.4.3.1 基本パラメーター ......................... 以下のフレームパラメーターはフレームに関するっとも基本的な情報を提供しま す。‘title’と‘name’はすべての端末において意味をもちます。 ‘display’ このフレームをオープンするためのディスプレイ。これは環境変数 ‘DISPLAY’のような‘HOST:DPY.SCREEN’という形式の文字列であること。デ ィスプレイ名についての詳細は、*note Multiple Terminals::を参照のこ と。 ‘display-type’ このパラメーターはこのフレーム内で使用できる利用可能なカラーの範囲 を記述する。値は‘color’、‘grayscale’、‘mono’のいずれか。 ‘title’ フレームが非‘nil’のtitleをもつ場合には、それはフレーム上端にあるウ ィンドウシステムのタイトルバーに表示され、 ‘mode-line-frame-identification’に‘%F’ (*note %-Constructs::を参照 )を使用していればそのフレーム内のウィンドウのモードラインにも表示さ れる。これは通常はEmacsがウィンドウシステムを使用しておらず、かつ同 時に1つのフレームのみ表示可能なケースが該当する。*note Frame Titles::を参照のこと。 ‘name’ そのフレームの名前。‘title’が未指定か‘nil’ならフレーム名はフレーム タイトルにたいしてデフォルトの役割りを果たす。nameを指定しなければ Emacsは自動的にフレーム名をセットする(*note Frame Titles::を参照)。 フレーム作成時に明示的にフレーム名を指定すると、そのフレームにたい してXリソースを照合する際にも、(Emacs実行可能形式名のかわりに)その 名前が使用される。 ‘explicit-name’ フレーム作成時にフレーム名が明示的に指定されると、このパラメーター はその名前。明示的に名付けられなかったら、このパラメーターは‘nil’。 28.4.3.2 位置のパラメーター ........................... 位置のパラメーターの値はピクセル単位で計測されます(以下のパラメーターは TTYフレームには存在しないことに注意)。 ‘left’ スクリーンの左(右)エッジからフレームの左(右)エッジまでの、ピクセル 単位での位置。値は: 整数 正の整数はスクリーン左エッジをフレーム左エッジに、負の整数はフ レーム右エッジをスクリーン右エッジに関連付ける。 ‘(+ POS)’ これはスクリーン左エッジにたいしフレーム左エッジの相対的位置を 指定する。整数POSは正か負の値をとり得る。負の値はスクリーン外 側、または(マルチモニターディスプレイにたいしては)プライマリー モニター以外のモニター上の位置を指定する。 ‘(- POS)’ これはスクリーン右エッジにたいしフレーム右エッジの相対的位置を 指定する。整数POSは正か負の値をとり得る。負の値はスクリーン外 側、または(マルチモニターディスプレイにたいしては)プライマリー モニター以外のモニター上の位置を指定する。 プログラムで指定した位置を無視するウィンドウマネージャーがいくつか ある。指定した位置が無視されないことを保証したければ、パラメーター ‘user-position’にも同様に非‘nil’値を指定すること。 ウィンドウマネージャがスクリーン左右のエッジにあるフレームの位置揃 えを拒絶するようなら、以下のように位置指定と‘user-position’を組み合 わせる (modify-frame-parameters nil '((user-position . t) (left . (+ -4)))) このようにすれば、そのような挙動をオーバーライドする助けとなるだろ う。 ‘top’ スクリーン上(下)エッジにたいして、上(下)エッジのスクリーン位置をピ クセル単位で指定する。方向が水平ではなく垂直である点を除き、これは ‘left’と同様に機能する。 ‘icon-left’ スクリーン左エッジから数えた、フレームアイコン左エッジのピクセル単 位のスクリーン位置。ウィンドウマネージャーがこの機能をサポートすれ ば、これはフレームをアイコン化したとき効果を発揮する。このパラメー ターに値を指定する場合には‘icon-top’にも値を指定しなければならず、 その逆も真。 ‘icon-top’ スクリーン上端から数えたフレームアイコン上端のピクセル単位のスクリ ーン位置。ウィンドウマネージャーがこの機能をサポートすれば、これは フレームをアイコン化したときに効果を発揮する。 ‘user-position’ フレームを作成してパラメーター‘left’と‘top’で位置を指定する際は、指 定した位置がユーザー指定(人間であるユーザーにより明示的に要求された 位置)なのか、それとも単なるプログラム指定(プログラムにより選択され た位置)なのかを告げるためにこのパラメーターを使用する。非‘nil’値は それがユーザー指定の位置であることを告げる。 ウィンドウマネージャーは一般的にユーザー指定位置に留意するとともに 、プログラム指定位置にも幾分か留意する。しかし多くのウィンドウマネ ージャーはプログラム指定位置を無視して、ウィンドウをウィンドウマネ ージャーのデフォルトの方法で配置するかユーザーのマウスによる配置に 任せる。‘twm’を含むウィンドウマネージャーのいくつかは、プログラム指 定位置にしたがうか無視するかをユーザーの指定に任せる。 ‘make-frame’を呼び出す際にパラメーター‘left’や‘top’の値がそのユーザ ーにより示される嗜好を表すなら、このパラメーターに非‘nil’値、それ以 外は‘nil’を指定すること。 28.4.3.3 サイズのパラメーター ............................. フレームパラメーターはフレームのサイズを文字単位で指定します。グラフィカ ルなディスプレイ上では、‘default’フェイスがこれら文字単位の実際のピクセ ルサイズを決定します(*note Face Attributes::を参照)。 ‘height’ フレームのテキストエリアの文字単位の高さ(*note Frame Geometry::を参 照)。 ‘width’ フレームのテキストエリアの文字単位の幅(*note Frame Geometry::を参照 )。 ‘user-size’ これはサイズパラメーター‘height’と‘width’にたいして、 ‘user-position’ (*note user-position: Position Parameters.を参照)が ‘top’と‘left’が行うのと同じことを行う。 ‘fullscreen’ このパラメータはフレームの幅、高さ、またはその両方を最大化するかど うかを指定する。値は‘fullwidth’、‘fullheight’、‘fullboth’、または ‘maximized’。フレームが“fullwidth”なら幅、“fullheight”なら高さ、 “fullboth”まら幅と高さが可能なかぎり大きくなる。“maximized”は “fullboth”と同様だが、通常はタイトルバーとフレームのリサイズやクロ ーズ用のボタンが維持される点が異なる。同様に最大化されたフレームで は、デスクトップ上に表示されているタスクバーやパネルが見えなくなる こと通常はない。一方で“fullboth(全画面)”のフレームは、通常はタイト ルバーは省略されて、利用可能なスクリーンスペース全体を占有する。 この点ではfullheightやfullwidthのフレームは最大化されたフレームと類 似している。しかしこれらは通常は最大化フレームでは存在しないエクス ターナルボーダーを表示する。したがって最大化されたフレームの高さと 幅は、fullheightのフレームの高さやfullwidthのフレームの幅とあ数ピク セル異なることがある。 いくつかのウィンドウマネージャでは、フレームを真に最大化または全画 面で表示させるために、変数‘frame-resize-pixelwise’ (*note Size and Position::を参照)のカスタマイズが必要になる。更に全画面や最大化の種 々の状態間での円滑な繊維をサポートしないウィンドウマネージャもいく つかあるだろう。これらに対処するために変数 ‘x-frame-normalize-before-maximize’のカスタマイズが助けとなるだろう 。 ‘fullscreen-restore’ このパラメータは‘toggle-frame-fullscreen’コマンド (*note (emacs)Frame Commands::を参照)呼び出し後の“fullboth”状態での、望ま しい全画面状態を指定する。このパラメーターは*note (emacs)Frame Commands::の切り替え時に、このコマンドによって自動的にインストール される。しかしEmacsが“fullboth”の状態で開始された場合には、以下の例 のように初期ファイル内で望ましい挙動を指定する必要がある (setq default-frame-alist '((fullscreen . fullboth) (fullscreen-restore . fullheight))) これはの初回タイプ後に、フレームに新たにfullheightを与えるだろ う。 28.4.3.4 レイアウトのパラメーター ................................. 以下のフレームパラメーターによりフレームのさまざまなパーツを有効または無 効にしたりサイズを制御できます。 ‘border-width’ ピクセル単位でのフレームのボーダー幅。 ‘internal-border-width’ テキスト(またはフリンジ)とフレームボーダーとのピクセル単位による距 離。 ‘vertical-scroll-bars’ フレームが垂直スクロール用のスクロールバーをもつべきかと、スクロー ルバーをフレームのどちら側に置くか。可能な値は‘left’、‘right’、スク ロールバーなしは‘nil’。 ‘horizontal-scroll-bars’ フレームが水平スクロール用のスクロールバーをもつべきかと、スクロー ルバーをフレームのどちら側に置くか(‘t’と‘bottom’はスクロールバーあ り、‘nil’はスクロールバーなしを意味する)。 ‘scroll-bar-width’ 垂直スクロールバーのピクセル単位による幅。‘nil’はデフォルト幅の使用 を意味する。 ‘scroll-bar-height’ 垂直スクロールバーのピクセル単位による高さ。‘nil’はデフォルト高さの 使用を意味する。 ‘left-fringe’ ‘right-fringe’ そのフレーム内のウィンドウの左右フリンジのデフォルト幅(*note Fringes::を参照)。いずれかが0なら対応するフリンジを削除する効果があ る。 これら2つのフレームパラメーターの値を問い合わせるために ‘frame-parameter’を使用する際のリターン値は常に整数。‘nil’値を渡し て‘set-frame-parameter’を使用する際には、実際のデフォルト値8ピクセ ルが課せられる。 ‘right-divider-width’ フレーム上のすべてのウィンドウの右ディバイダー(*note Window Dividers::を参照)用に予約されるピクセル単位の幅(厚さ)。値0は右ディ バイダーを描画しないことを意味する。 ‘bottom-divider-width’ フレーム上のすべてのウィンドウの下ディバイダー(*note Window Dividers::を参照)用に予約されるピクセル単位の幅(厚さ)。値0は下ディ バイダーを描画しないことを意味する。 ‘menu-bar-lines’ メニューバー用にフレーム上端に割り当てる行数。Menu Barモードが有効 の場合のデフォルトは1、それ以外は0。*note (emacs)Menu Bars::を参照 のこと。 ‘tool-bar-lines’ ツールバー用に使用する行数。Tool Barモードが有効の場合のデフォルト は1、それ以外は0であ。*note (emacs)Tool Bars::を参照のこと。 ‘tool-bar-position’ ツールバーの位置。現在のところGTKツールバーのみ。可能な値は‘top’、 ‘bottom’、‘left’、‘right’。デフォルトは‘top’。 ‘line-spacing’ 各テキスト行の下に残すピクセル単位の追加スペース(正の整数)。詳細は *note Line Height::を参照のこと。 28.4.3.5 バッファーのパラメーター ................................. 以下はフレーム内でどのバッファーが表示されているか、表示されるべきかを扱 うためのフレームパラメーターであり、すべての種類の端末上で意味があります 。 ‘minibuffer’ そのフレームが自身のミニバッファーをもつか否か。もつ場合には‘t’、も たない場合は‘nil’、‘only’ならそのフレームが正にミニバッファーである ことを意味する。値が(別フレーム内の)ミニバッファーウィンドウなら、 そのフレームはそのミニバッファーを使用する。 このフレームパラメーターはフレーム作成時に効果があち、その後は変更 できない。 ‘buffer-predicate’ このフレームにたいするバッファー述語関数。関数‘other-buffer’はこの 述語が非‘nil’なら、(選択されたフレームから)どのバッファーを考慮すべ きか決定するためにこれを使用する。これは各バッファーにたいして、そ のバッファーを唯一の引数としてこの述語を1回呼び出す。この述語が非 ‘nil’値をリターンしたら、そのバッファーは考慮される。 ‘buffer-list’ そのフレーム内で選択されたことのあるバッファーにたいする、もっとも 最近選択されたバッファーが先頭になるような順のリスト。 ‘unsplittable’ 非‘nil’なら、このフレームのウィンドウは決して自動的に分割されること はない。 28.4.3.6 ウィンドウ管理のパラメーター ..................................... 以下のフレームパラメーターは、ウィンドウマネージャーとフレームとの相互作 用に関するさまざまな側面を制御します。これらはテキスト端末上では効果があ りません。 ‘visibility’ フレームの可視性(visibility)の状態。可能な値は3つあり‘nil’は不可視 、‘t’は可視、‘icon’はアイコン化されていることを意味する。*note Visibility of Frames::を参照のこと。 ‘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’なら仮想デスクトップを伴うシステム上のすべての仮想デスクトッ プ上でそのフレームが可視になる。 28.4.3.7 カーソルのパラメーター ............................... このフレームパラメーターはカーソルの外見を制御します。 ‘cursor-type’ カーソルの表示方法。適正な値は: ‘box’ 塗りつぶされた四角形(filled box)を表示する(デフォルト)。 ‘hollow’ 中抜きの四角形(hollow box)を表示する。 ‘nil’ カーソルを表示しない。 ‘bar’ 文字間に垂直バー(vertical bar)を表示する。 ‘(bar . WIDTH)’ 文字間に幅がWIDTHピクセルの垂直バー(vertical bar)を表示する。 ‘hbar’ 文字間に水平バー(horizontal bar)を表示する。 ‘(hbar . HEIGHT)’ 文字間に高さがHEIGHTピクセルの水平バー(horizontal bar)を表示す る。 フレームパラメーター‘cursor-type’は変数‘cursor-type’と ‘cursor-in-non-selected-windows’によりオーバーライドされるかもしれません 。 -- Variable: cursor-type このバッファーローカル変数は選択されたウィンドウ内で表示されている そのバッファーのカーソルの外見を制御する。この値が‘t’なら、それはフ レームパラメーター‘cursor-type’で指定されたカーソルのーを使用するこ とを意味する。それ以外では値は上記リストのカーソルタイプのいずれか であるべきであり、これはフレームパラメーター‘cursor-type’をオーバー ライドする。 -- User Option: cursor-in-non-selected-windows このバッファーローカル変数は選択されていないウィンドウ内でのカーソ ルの外見を制御する。これはフレームパラメーター‘cursor-type’と同じ値 をサポートする。さらに‘nil’は選択されていないウィンドウ内にはカーソ ルを表示せず、‘t’は通常のカーソルタイプの標準的な変更(塗りつぶされ た四角形は中抜きの四角形、バーはより細いバーになる)の使用を意味する 。 -- User Option: x-stretch-cursor この変数はタブや伸長された空白文字のようなエクストラワイドグリフで 表示されるblockカーソルの幅を制御する。デフォルトではそのフォントの デルト文字だけの幅で、これはカーソル一のグリフがエクストラワイドな ら幅を完全にカバーしないだろう。この変数にたいする非‘nil’値はカーソ ル位置のグリフの幅に応じてblockカーソルを描画することを意味する。デ フォルト値は‘nil’。 テキストモードのフレームではEmacsの制御外部の端末によりカーソルが描 画されるので、この変数に効果はない。 -- User Option: blink-cursor-alist この変数はカーソルのブリンク(blink: 点滅)方法を指定する。各要素は ‘(ON-STATE . OFF-STATE)’という形式をもつ。カーソルタイプが ON-STATEと等しい(‘equal’を用いて比較)ときは、これに対応する OFF-STATEがブリンクが“off”の際のカーソルの外見を指定する。 ON-STATEとOFF-STATEはどちらもフレームパラメーター‘cursor-type’に適 した値であること。 それぞれのカーソルタイプのブリンク方法にたいして、そのタイプがここ でON-STATEとして指定されていなければ、さまざまなデフォルトが存在す る。フレームパラメーター‘cursor-type’で指定した際に限り、この変数内 での変更は即座に効果を発揮しない。 28.4.3.8 フォントとカラーのパラメーター ....................................... 以下のフレームパラメーターはフォントとカラーの使用を制御します。 ‘font-backend’ フレーム内でフォントの描画に使用するための“フォントバックエンド (font backends)”を指定するシンボルの優先順のリスト。Xでは現在のとこ ろ‘x’ (X core font driver)と‘xft’ (Xft font driver)の2つの利用可能 なフォントバックエンドがある。MS-Windowsでは現在のところ‘gdi’と ‘uniscribe’の2つの利用可能なフォントバックエンドがある(*note (emacs)Windows Fonts::を参照)。その他のシステムでは利用可能なフォン トバックエンドは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’は未 選択時の透明度。 以下は特定のフェイスの特定のフェイス属性と自動的に等しくなるので、ほ ぼ時代遅れとなったフレームパラメーターです(*note (emacs)Standard Faces::を参照)。 ‘font’ フレーム内でテキストを表示するためのフォントの名前。これはシステム で有効なフォント名か、Emacsフォントセット名(*note Fontsets::を参照 )のいずれかであるような文字列。これは‘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’属性と等価。 28.4.4 ジオメトリー ------------------- 以下はXスタイルのウィンドウジオメトリー指定によるアクションのデータを調 べる方法です: -- Function: x-parse-geometry geom 関数‘x-parse-geometry’は標準的なXウィンドウのジオメトリー文字列を ‘make-frame’の引数の一部として使用できるalistに変換する。 このalistはGEOM内で指定されたパラメーターと、そのパラメーターに指定 された値を記述する。各要素は‘(PARAMETER . VALUE)’のような形式。可能 なPARAMETERの値は‘left’、‘top’、‘width’、‘height’。 サイズのパラメーターの値は整数でなければならない。位置のパラメータ ー‘left’と‘top’の名前に関しては、かわりに右端または下端の位置を示す 値もいくつかあるので完全に正確ではない。位置パラメーターにたいして 可能なVALUEは前述したような整数(*note Position Parameters::を参照 )、リスト‘(+ POS)’、リスト‘(- POS)’である。 以下は例: (x-parse-geometry "35x70+0-0") ⇒ ((height . 70) (width . 35) (top - 0) (left . 0)) 28.5 端末のパラメーター ======================= 端末はそれぞれ関連するパラメーターのリストをもっています。これら“端末パ ラメーター(terminal parameters)”は主に端末ローカル変数を格納するための便 利な手段ですが、いくつかの端末パラメーターは特別な意味をもっています。 このセクションでは端末のパラメーター値の読み取りや変更を行う関数を説 明します。これらはすべて引数として端末かフレームいずれかを受け入れます。 フレームならそれはそのフレームの端末の使用を意味します。引数‘nil’は選択 されたフレームの端末という意味です。 -- Function: terminal-parameters &optional terminal この関数はTERMINALnのすべてのパラメーターとその値をリストする alistをリターンする。 -- Function: terminal-parameter terminal parameter この関数はTERMINALのパラメーターPARAMETER (シンボル)の値をリターン する。TERMINALがPARAMETERにたいするセッティングをもたなければ、この 関数は‘nil’をリターンする。 -- Function: set-terminal-parameter terminal parameter value This function sets the parameter PARAMETER of TERMINAL to the specified VALUE, and returns the previous value of that parameter. 以下は特別な意味をもついくつかの端末パラメーターのリストです: ‘background-mode’ 端末のバックグラウンドカラーの区分で‘light’か‘dark’のいずれか。 ‘normal-erase-is-backspace’ 値は1か0で、これはその端末上で‘normal-erase-is-backspace-mode’がオ ンまたはオフのいずれに切り替えられたかに依存する。*note (emacs)DEL Does Not Delete::を参照のこと。 ‘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自身のサスペンド の際にそれらの文字列を発行する。 28.6 フレームのタイトル ======================= フレームにはそれぞれ‘name’というパラメーターがあります。これはウィンドウ システムが通常フレーム上端に表示するフレームタイトルにたいするデフォルト としての役割をもちます。フレームプロパティ‘name’をセットすることにより明 示的に名前を指定できます。 通常は名前を明示的に指定せずに、Emacsが変数‘frame-title-format’に格納 されたテンプレートにもとづいて自動的にフレーム名を計算します。Emacsはフ レームが再表示されるたびに名前を再計算します。 -- Variable: frame-title-format この変数はフレーム名が明示的に指定されないときにフレーム名を計算す る方法を指定する。この変数の値は実際には‘mode-line-format’のような モードライン構文(mode line construct)だが、‘%c’と‘%l’の構文は無視さ れる。*note Mode Line Data::を参照のこと。 -- Variable: icon-title-format この変数はフレームタイトルを明示的に指定しないときの、アイコン化さ れたフレームの名前の計算方法を指定する。このタイトルはアイコン自体 に表示される。 -- Variable: multiple-frames この変数はEmacsにより自動的にセットされる。フレームが2つ以上(ミニバ ッファーのみのフレームと不可視のフレームは勘定に入らない)のとき、値 は‘t’となる。‘frame-title-format’のデフォルト値はフレームが複数存在 する場合のみ、フレーム名にバッファー名を入れるために ‘multiple-frames’を使用する。 この変数の値は‘frame-title-format’と‘icon-title-format’の処理中を除 き正確である保証はない。 28.7 フレームの削除 =================== “生きたフレーム(live frame)”とは削除されていないフレームのことです。フレ ームが削除される際には、たとえそれへの参照元がなくなるまでLispオブジェク トとして存在し続けるとしても端末ディスプレイからは削除されます。 -- Command: delete-frame &optional frame force この関数はフレームFRAMEを削除する。FRAMEがツールチップでなければ、 まずフック‘delete-frame-functions’を実行する(フックの各関数は唯一の 引数としてFRAMEを受け取る)。デフォルトではFRAMEは選択されたフレーム 。 フレームのミニバッファーが別のフレームの代替えミニバッファー (surrogate minibuffer)としての役割をもつかぎり削除することはできな い。他のフレームがすべて不可視なら通常はフレームを削除できないが、 FORCEが非‘nil’なら削除が可能。 -- Function: frame-live-p frame 関数‘frame-live-p’はフレームFRAMEが削除されていなければ非‘nil’をリ ターンする。リターンされ得る非‘nil’の値は‘framep’と同様。*note Frames::を参照のこと。 いくつかのウィンドウマネージャーはウィンドウを削除するコマンドを提供 します。これらはそのウィンドウを操作するプログラムに特別なメッセージを送 ることにより機能します。Emacsがそれらメッセージのいずれかを受け取ったと きは‘delete-frame’イベントを生成します。このイベントの通常の定義は関数 ‘delete-frame’を呼び出すコマンドです。*note Misc Events::を参照してくだ さい。 28.8 すべてのフレームを探す =========================== -- Function: frame-list この関数はすべての生きたフレーム(削除されていないフレーム)のリスト をリターンする。これはバッファーにたいする‘buffer-list’に類似してお り、すべての端末上のフレームが含まれる。リターンされるリストは新た に作成されたものであり、このリストを変更してもEmacs内部への影響はな い。 -- Function: visible-frame-list この関数はカレントで可視なフレームだけのリストをリターンする。*Note Visibility of Frames::を参照のこと。テキスト端末上のフレームは、実 際に表示されるのが選択されたフレームだけだとしても常に可視であると みなされる。 -- Function: next-frame &optional frame minibuf この関数はカレントディスプレイ上のすべてのフレームを、任意のフレー ムを開始点としいて巡回するのに有用。これはそのその巡回サイクル上で FRAMEの次に該当するフレームをリターンする。FRAMEが省略または‘nil’の 場合のデフォルトは選択されたフレーム(*note Input Focus::を参照)。 2つ目の引数MINIBUFはどのフレームを考慮するかを示す: ‘nil’ ミニバッファーのみのフレームを除外。 ‘visible’ すべての可視フレームを考慮する。 0 すべての可視フレームとアイコン化されたフレームを考慮する。 ウィンドウ 特定のウィンドウをミニバッファーとして使用するフレームだけを考 慮する。 その他 すべてのフレームを考慮する。 -- Function: previous-frame &optional frame minibuf ‘next-frame’と同様だがすべてのフレームを逆方向に巡回する。 *note Cyclic Window Ordering::の‘next-window’と‘previous-window’も参 照してください。 28.9 ミニバッファーとフレーム ============================= それぞれのフレームは通常は下端に自身のミニバッファーウィンドウをもち、そ のフレームが選択された際には常にそれを使用します。フレームにミニバッファ ーがある場合には、‘minibuffer-window’でそれを取得できます(*note Minibuffer Windows::を参照)。 しかしミニバッファーをもたないフレームも作成できます。そのようなフレ ームは、別のフレームのミニバッファーを使用しなければなりません。この別フ レームはそのフレームにたいする“代替えミニバッファーフレーム(surrogate minibuffer frame)”としての役目を果たし、そのフレームが生きているかぎり ‘delete-frame’で削除することはできなくなります(*note Deleting Frames::を 参照)。 フレーム作成時に、(別フレーム上にある)使用するミニバッファーを明示的 に指定できます。これを行わない場合には、変数‘default-minibuffer-frame’の 値のフレーム内でミニバッファーを探します。この値はミニバッファーをもつフ レームにしてください。 ミニバッファーのみのフレームを使用する場合には、ミニバッファーにエン ター時にそのフレームを前面に移動(raise)したいと思うかもしれません。その 場合には変数‘minibuffer-auto-raise’に‘t’をセットします。*note Raising and Lowering::を参照してください。 -- Variable: default-minibuffer-frame この変数はデフォルトでミニバッファーウィンドウとして使用するフレー ムを指定する。これは既存のフレームには影響しない。これはカレント端 末にたいして常にローカルであり、バッファーローカルにはできない。 *note Multiple Terminals::を参照のこと。 28.10 入力のフォーカス ====================== どんなときでもEmacs内のただ1つのフレームが“選択されたフレーム(selected frame)”です。選択されたウィンドウは常に選択されたフレーム上にあります。 Emacsがフレームを複数端末(*note Multiple Terminals::を参照)上に表示す る際には、各端末は自身の選択されたフレームをもちます。しかしそれらのうち 1つだけが、_いわゆる_選択されたフレームであり、それはもっとも最近に入力 があった端末に属すフレームです。つまり特定の端末からのコマンドをEmacsが 実行する際には、その端末上の1つが選択されたフレームです。Emacsが実行する コマンドは常に1つだけなので、選択されたフレームは常に1つだけだと考える必 要があります。このフレームこそが、このマニュアルで“選択されたフレーム”と 呼ぶフレームです。選択されたフレームを表示するディスプレイは、“選択され たフレームのディスプレイ(selected frame’s display)”です。 -- Function: selected-frame この関数は選択されたフレームをリターンする。 いくつかのウィンドウシステムおよびウィンドウマネージャーは、マウスが あるウィンドウオブジェクトにキーボード入力をダイレクトします。それ以外は 、さまざまなウィンドウオブジェクトに“フォーカスをシフト(shift the focus)”するために、明示的なクリックやコマンドを要求します。どちらの方法 でもEmacsはフォーカスをもつフレームを自動的に追跡します。Lisp関数から別 フレームに明示的に切り替えるためには、‘select-frame-set-input-focus’を呼 び出します。 関数‘select-frame’を呼び出すことにより、Lispプログラムが一時的にフレ ームを切り替えることもできます。これはそのウィンドウシステムのフォーカス 概念を変更はしません。変更ではなく何らかの方法により制御が再確認 (reasserted)されるまで、ウィンドウマネージャーの制御から抜け出す (escape)のです。 テキスト端末使用時はその端末上で一度に表示できるフレームは1つだけなの で、‘select-frame’呼び出し後に次回の再表示で新たに選択されたフレームが実 際に表示されます。このフレームは次の‘select-frame’呼び出しまで選択された ままです。テキスト端末上の各フレームはバッファー名の前に表示される番号を もちます(*note Mode Line Variables::を参照)。 -- Function: select-frame-set-input-focus frame &optional norecord この関数はFRAMEを選択して、(他のフレームのせいで不明瞭な場合には)そ れを前面に移動(raise)してXサーバーのフォーカス授与を試みる。テキス ト端末上では、次回再表示時に端末スクリーン全体に新たにフレームが表 示される。オプション引数NORECORDは‘select-frame’(下記参照)のときと 同じ意味をもつ。この関数のリターン値に意味はない。 -- Command: select-frame frame &optional norecord この関数はフレームFRAMEを選択して、Xサーバーのフォーカスがあればそ れを一時的に無視する。FRAMEにたいする選択は次回ユーザーが別フレーム に何かを行うか、この関数の次回呼び出しまで継続する(ウィンドウシステ ムを使用する場合には以前に選択されていたフレームに依然としてウィン ドウシステムの入力フォーカスがあるかもしれないので、コマンドループ からリターン後にそのフレームが選択されたフレームとしてリストアされ るかもしれない)。 指定されたFRAMEは選択されたフレームとなり、その端末が選択された端末 になる。その後でこの関数はFRAME内で選択されていたウィンドウを第1引 数、NORECORDを第2引数として、サブルーチンとして‘select-window’を呼 び出す(したがってNORECORDが非‘nil’ならもっとも最近に選択されたウィ ンドウとバッファーリストの変更を避ける)。*note Selecting Windows::を 参照のこと。 この関数はFRAME、FRAMEが削除されていれば‘nil’をリターンする。 一般的には実行後に端末を戻すよう切り替えることなく、別の端末に切り 替えるのが可能な手段として‘select-frame’を決して使用しないこと。 Emacsはサーバーやウィンドウマネージャーのリクエストとしてフレーム選択 をアレンジすることによりウィンドウシステムと協調します。これは適切なとき に“フォーカス(focus)”と呼ばれる特殊な入力イベントを生成することにより行 われます。コマンドループは‘handle-switch-frame’を呼び出してフォーカスイ ベントを処理します。*note Focus Events::を参照してください。 -- Command: handle-switch-frame frame この関数はフレームFRAME選択によりフォーカスイベントを処理する。 フォーカスイベントは、通常はこのコマンドを呼び出すことによりその処 理を行う。他の理由でこれを呼び出しではならない。 -- Function: redirect-frame-focus frame &optional focus-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’が呼び出されるまで継続する。 -- Variable: focus-in-hook これはEmacsフレームが入力フォーカスを得た際に実行されるノーマルフッ ク。 -- Variable: focus-out-hook これはEmacsフレームが入力フォーカスを失った際に実行されるノーマルフ ック。 -- User Option: focus-follows-mouse これはユーザーがマウスを移動した際に、ウィンドウマネージャーがフォ ーカスを転送するかどうかをEmacsに告げるためのオプション。非‘nil’な らフォーカスは転送される。その場合にはコマンド‘other-frame’は新たに 選択されたフレームと一貫性のある位置にマウスを移動する。 28.11 フレームの可視性 ====================== グラフィカルなディスプレイ上のフレームは“可視(visible)”、“不可視 (invisible)”、または“アイコン化(iconified)”されているかもしれません。可 視ならそのコンテンツは通常の方法により表示されます。アイコン化されている 場合にはそのコンテンツは表示されませんが、ビュー内にフレームを戻すための 小さいアイコンがどこかにあります(いくつかのウィンドウマネージャーはこの 状態を“アイコン化”ではなく“最小化”と呼ぶがEmacsの見地ではこれらは同等で ある)。フレームが不可視ならまったく表示されません。 テキスト端末では実際に表示されるのは常にただ1つの選択されたフレームだ けなので、可視性に意味はありません。 -- Function: frame-visible-p frame この関数はフレームFRAMEの可視性の状態をリターンする。値はFRAMEが可 視なら‘t’、不可視なら‘nil’、アイコン化されていれば‘icon’。 テキスト端末上ではたとえ1つのフレームだけが表示されているとしても、 この関数の目的にたいしてはすべてのフレームが可視とみなされる。*note Raising and Lowering::を参照のこと。 -- Command: iconify-frame &optional frame この関数はフレームFRAMEをアイコン化する。FRAMEを省略すると選択され たフレームをアイコン化する。 -- Command: make-frame-visible &optional frame この関数はフレームFRAMEを可視にする。FRAMEを省略すると選択されたフ レームを可視にする。これはフレームを前面に移動しないが、望むなら ‘raise-frame’でこれを行うことができる(*note Raising and Lowering::を 参照)。 -- Command: make-frame-invisible &optional frame force この関数はフレームFRAMEを不可視にする。FRAMEを省略すると選択された フレームを不可視にする。 FORCEが‘nil’なら、この関数は他のすべてのフレームが不可視の場合に FRAMEを不可視にすることを拒絶する。 フレームの可視性の状態はフレームパラメーターとしても利用可能である。 つまりフレームパラメーターとして読み取りと変更ができる。*note Management Parameters::を参照のこと。ウィンドウマネージャーによりユーザーがフレーム のアイコン化や非アイコン化を行うこともできる。これはEmacsが何らかの制御 を及ぼすのが可能なレベルより下のレベルにおいて発生するが、Emacsはそのよ うな変化を追跡するために使用するイベントを提供する。*note Misc Events::を 参照のこと。 28.12 フレームを前面や背面に移動する ==================================== ほとんどのウィンドウシステムでは、デスクトップというメタファー(metaphor: 比喩的概念)は使用されます。このメタファーの一部はシステムレベルのウィン ドウ(Emacsではフレーム)がスクリーン表面に向かって、概念的な3次元の垂直方 向に積まれていくというアイデアです。2つが重なる箇所では、より高い一方が より低い一方を覆い隠します。関数‘raise-frame’や‘lower-frame’を使用して、 フレームを“前面に移動(raise: より高い位置へ上げる)”したり“背面に移動 (lower: より低い位置へ移動)”したりすることができます。 -- Command: raise-frame &optional frame この関数はフレームFRAME (デフォルトは選択されたフレーム)を前面に移 動する。FRAMEが不可視もしくはアイコン化されていればそれを可視にする 。 -- Command: lower-frame &optional frame この関数はフレームFRAME (デフォルトは選択されたフレーム)を背面に移 動する。 -- User Option: minibuffer-auto-raise これが非‘nil’ならミニバッファーをアクティブにすることにより、ミニバ ッファーウィンドウのあるフレームが前面に移動される。 ウィンドウシステム上ではフレームパラメーターを使用して、(フレーム選択 時に)auto-raising、(フレーム選択解除時に)auto-loweringを有効にできます。 *note Management Parameters::を参照してください。 フレームを前面や背面に移動するという概念は、テキスト端末のフレームに も適用できます。各テキスト端末上では一度に表示されるのは常に最前面のフレ ームだけです。 -- Function: tty-top-frame &optional terminal この関数はTERMINAL上の最前面のフレームをリターンする。TERMINALは端 末オブジェクト、フレーム(そのフレームの端末を意味する)、または‘nil’ (選択されたフレームの端末を意味する)であること。これがテキスト端末 を参照しなければリターン値は‘nil’。 28.13 フレーム構成 ================== “フレーム構成(frame configuration)”はフレームのカレント配置、すべてのプ ロパティ、および各ウィンドウのウィンドウ構成(*note Window Configurations::を参照)を記録します。 -- Function: current-frame-configuration この関数はフレームのカレント配置とそのコンテンツを記述するフレーム 構成のリストをリターンする。 -- Function: set-frame-configuration configuration &optional nodelete この関数はフレームの状態をCONFIGURATIONの記述にリストアする。ただし この関数は削除されたフレームはリストアしない。 この関数は通常はCONFIGURATION内にリストされない既存フレームすべてを 削除する。しかしNODELETEが非‘nil’なら、それらのフレームはかわりにア イコン化される。 28.14 マウスの追跡 ================== マウスを“トラック(track: 追跡)”するのが有用なことが時折あります。マウス のトラックとはマウスの位置を示す何かを表示して、マウス移動とともにそのイ ンジケーターを移動するという意味です。効果的にマウスをトラックするために は、マウスが実際に移動するまで待機する手段が必要になります。 マウスをトラックするためには、マウスのモーション(motion: 移動)を表す イベントを問い合わせるのが便利な方法です。その後はそのイベントを待機する ことによりモーションを待機できます。それに加えて発生し得る他の類のイベン トも簡単に処理できます。ボタンのリリースのような何か他のイベントだけを待 機してマウスを永久にトラックすることは、通常は望ましくないのでこれは有用 です。 -- Special Form: track-mouse body... このスペシャルフォームはマウスモーションイベントの生成を有効にして BODYを実行する。BODYはモーションイベントを読み取るために通常は ‘read-event’を使用して、それに対応して表示を変更する。マウスモーシ ョンイベントのフォーマットについては*note Motion Events::を参照のこ と。 ‘track-mouse’の値はBODY内の最後のフォームの値。ボタンのリリースを示 すup-event、またはトラックを止めるべきタイミングを意味する類のイベ ントを確認した際にはリターンするようにBODYをデザインすること。 ‘track-mouse’フォームでは変数‘track-mouse’を非‘nil’値にバインドする ことにより、Emacsにマウスモーションイベントを生成させる。この変数が 特別な値‘dragging’をもつなら、ディスプレーエンジンにマウスポインタ ーのシェイプ(形状)の変更を控えるように追加で指示する。これはEmacsが 表示する大きな範囲を横断するマウスドラッグを要するLispプログラムで は、そうしなければ表示箇所に応じてマウスポインターのシェイプが変更 されてしまうので望ましいだろう(*note Pointer Shape::を参照)。したが ってドラッグ中にオリジナルのマウスポインターシェイプを保つ必要があ るLispプログラムは、BODYの先頭で‘track-mouse’を値‘dragging’にバイン ドすること。 マウスモーションをトラックする通常の目的は、それ以降に発生するボタン のプッシュやリリースをカレント位置に示すことです。 多くの場合はテキストプロパティ‘mouse-face’(*note Special Properties::を参照)を使用することにより、マウスをトラックする必要性を回 避できます。これはより低レベルで機能して、かつLispレベルのマウストラッキ ングよりスムーズに実行されます。 28.15 マウスの位置 ================== 関数‘mouse-position’と‘set-mouse-position’はマウスのカレント位置にたいす るアクセスを提供します。 -- Function: mouse-position この関数はマウス位置の記述子をリターンする。値は‘(FRAME X . Y)’のよ うな形式であり、XとYはFRAMEのネイティブ位置(*note Frame Geometry::を 参照)から相対的に、FRAMEのデフォルト文字サイズ(*note Frame Font::を 参照)の単位で位置を与える整数(丸められている可能性あり)。 -- Variable: mouse-position-function この変数の値は非‘nil’なら‘mouse-position’にたいして呼び出される関数 。‘mouse-position’はリターン直前に、自身の通常のリターン値を唯一の 引数としてこの関数を呼び出して、それが何であれその関数がリターンし た値をリターンする。 このアブノーマルフックは‘xt-mouse.el’のようにLispレベルでマウス処理 を行う必要があるパッケージのために存在する。 -- Function: set-mouse-position frame x y この関数はフレームFRAME内の位置X、Yに“マウスをワープ(warps the mouse)”する。引数XとYはFRAMEのネイティブ位置(*note Frame Geometry::を参照)から相対的に、FRAMEのデフォルト文字サイズ(*note Frame Font::を参照)の単位で位置を与える整数(丸められている可能性あ り)。 結果となるマウス位置はFRAMEのネイティブフレームに拘束される。この関 数はFRAMEが不可視なら何も行わない。リターン値に意味はない。 -- Function: mouse-pixel-position この関数は‘mouse-position’と似ているが文字単位ではなくピクセル単位 の座標をリターンする。 -- Function: set-mouse-pixel-position frame x y この関数は‘set-mouse-position’のようにマウスをワープするが、XとYが 文字単位ではなくピクセル単位である点が異なる。 結果となるマウス位置はFRAMEのネイティブフレームに拘束される。この関 数はFRAMEが不可視なら何も行わない。リターン値に意味はない。 フラフィカルな端末上では、以下の2つの関数によりマウスカーソルの絶対位 置の取得とセットができます。 -- Function: mouse-absolute-pixel-position この関数は選択されたフレームのディスプレーの位(0, 0)から相対的に、 マウスカーソルの位置の座標をピクセル単位のコンスセル(X . Y)でリタ ーンする。 -- Function: set-mouse-absolute-pixel-position x y この関数はマウスカーソルを位置(X, Y)に移動する。座標XとYは、選択さ れたフレームのディスプレーの位置(0, 0)から相対的なピクセル値と解釈 される。 以下の関数はフレーム上のマウスカーソルがレントで可視かどうかを確認し ます: -- Function: frame-pointer-visible-p &optional frame この述語関数はFRAME上に表示されたマウスポインターが可視なら非 ‘nil’、それ以外は‘nil’をリターンする。FRAMEが省略または‘nil’ならそ れは選択されたフレームを意味する。これは‘make-pointer-invisible’が ‘t’にセットされているときに有用。これによりポインターが隠されている ことを知ることができる。*note (emacs)Mouse Avoidance::を参照のこと 。 28.16 ポップアップメニュー ========================== Lispプログラムがポップアップメニューを表示して、ユーザーがマウスで候補を 選択できます。テキスト端末上では、マウスが利用不可ならキーボードのモーシ ョンキー‘C-n’や‘C-p’、上矢印キーや下矢印キーで候補を選択できます。 -- Function: x-popup-menu position menu この関数はポップアップメニューを表示して、ユーザーが何を選択したか の指標をリターンする。 引数POSITIONには、メニュー左上隅をスクリーン上のどこに置くか指定す る。これはマウスボタンイベント(ユーザーがボタンを操作した位置にメニ ューを置くよう指示する)、または以下の形式のリストのいずれか: ((XOFFSET YOFFSET) WINDOW) ここでXOFFSETとYOFFSETはWINDOWの左上隅からピクセル単位で測られた座 標である。WINDOWはウィンドウかフレーム。 POSITIONが‘t’なら、それはマウスのカレント位置の使用を意味する(テキ スト端末上でマウスが利用不可ならフレーム左上隅)。POSITIONが‘nil’な ら、それは実際にメニューをポップアップせずに、MENU内で指定されたキ ーマップと等価なキーバインディングを事前に計算することを意味する。 引数MENUはメニュー内で何を表示するかを意味する。これはキーマップか キーマップのリストを指定できる(*note Menu Keymaps::を参照)。この場 合にはリターン値はユーザー選択に対応するイベントのリスト。選択がサ ブメニュー内で発生した場合には、このリストには複数の要素がある (‘x-popup-menu’はそのイベントシーケンスにバインドされたコマンドを実 際には実行しないことに注意)。テキスト端末やメニュータイトルをサポー トするツールキットでは、MENUがキーマップならタイトルはMENUのプロン プト文字列、MENUがキーマップのリストなら最初のキーマップのプロンプ ト文字列から取得される(*note Defining Menus::を参照)。 かわりに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’で実装されないのはこれが理由です。*note Menu Bar::を参照してください。 メニューバーのサブメニューのコンテンツを変化させたい場合にも、その実 装には依然としてメニューキーマップを使用するべきです。コンテンツを変化さ せるためには、必要に応じてメニューキーマップのコンテンツを更新するために フック関数を‘menu-bar-update-hook’に追加してください。 28.17 ダイアログボックス ======================== ダイアログボックスとはポップアップメニューの一種です。外見は多少異なり常 にフレーム中央に表示されて、階層を1つしかもたず1つ以上のボタンがあります 。ユーザーが“yes”、“no”、および別のいくつかの候補で応答ができる質問を尋 ねるのがダイアログボックスの主な用途です。単一のボタンではユーザーに重要 な情報の確認を強いることもできます。関数‘y-or-n-p’や‘yes-or-no-p’は、マ ウスのクリックで呼び出されたコマンドから呼び出された際には、キーボードの かわりにダイアログボックスを使用します。 -- Function: x-popup-dialog position contents &optional header この関数はポップアップダイアログボックスを表示してユーザーが何を選 択したかの指標をリターンする。引数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’ (*note message-box::を 参照)にたいして使用される(テキスト端末上ではボックスタイトルは表示 されない)。 いくつかの構成ではEmacsは本当のダイアログボックスを表示できないので 、かわりにフレーム中央のポップアップメニュー内に同じアイテムを表示 する。 たとえばウィンドウマネージャーを使用して有効な選択を行うことなくユ ーザーがダイアログボックスを取り除いた場合には、通常はquitして ‘x-popup-dialog’はリターンしない。 28.18 ポインターの形状 ====================== テキストプロパティ‘pointer’や、イメージならイメージプロパティ ‘:pointer’と‘:map’を使用して、特定のテキストやイメージにたいしてマウスポ インターのスタイルを指定できます。これらのプロパティに使用できる値は ‘text’ (または‘nil’)、‘arrow’、‘hand’、‘vdrag’、‘hdrag’、‘modeline’、 ‘hourglass’です。‘text’はテキスト上で使用される通常のマウスポインタース タイルを意味します。 ウィンドウの空部分(void parts: バッファーコンテンツのどの部分にも対応 しない部分)の上では、マウスポインターは通常‘arrow’スタイルを使用しますが 、‘void-text-area-pointer’をセットすることにより異なるスタイルを指定でき ます。 -- User Option: void-text-area-pointer この変数は空テキストエリアにたいするマウスポインタースタイルを指定 する。このエリアには行末の後やバッファー終端行の下が含まれる。デフ ォルトでは‘arrow’(non-text)ポインタースタイルを使用する。 Xを使用する際は変数‘x-pointer-shape’をセットすることにより‘text’の実 際の外見を指定できます。 -- Variable: x-pointer-shape この変数はEmacsフレーム内でポインタースタイル‘text’に通常使用するポ インターシェイプを指定する。 -- Variable: x-sensitive-text-pointer-shape この変数はマウスがマウスセンシティブテキスト上にあるときのポインタ ーシェイプを指定する。 これらの変数は新たに作成されるフレームに影響します。これらは通常は既 存のフレームに効果はありませんが、フレームのマウスカラーのインストール時 にはこれら2つ変数のカレント値もインストールされます。*note Font and Color Parameters::を参照してください。 これらのポインターシェイプのいずれかを指定するために使用可能な値はフ ァイル‘lisp/term/x-win.el’内で定義されています。それらのリストを確認する には‘M-x apropos x-pointer ’を使用してください。 28.19 ウィンドウシステムによる選択 ================================== Xのようなウィンドウシステムでは、異なるアプリケーション間のデータ転送は “選択(selections)”により行われます。Xは任意の数の“選択タイプ(selection types)”を定義し、それぞれが独自にデータを格納できます。しかし一般的に使 用されるのは“クリップボード(clipboard)”、“プライマリー選択(primary selection)”、“セカンダリー選択(secondary selection)”の3つだけです。それ 以外のウィンドウシステムではクリップボードだけがサポートされます。これら 3つの選択を使用するEmacsコマンドについては*note Cut and Paste: (emacs)Cut and Paste.を参照してください。このセクションではウィンドウシ ステムによる選択の読み取りとセットを行う低レベル関数について説明します。 -- Command: gui-set-selection type data この関数はウィンドウシステムの選択をセットする。これは選択タイプ TYPE、それに割り当てる値DATAという2つの引数を受け取る。 TYPEはシンボルであること。通常は‘PRIMARY’、‘SECONDARY’、 ‘CLIPBOARD’のいずれかである。これらはXウィンドウシステムの慣例に対 応する大文字のシンボル名である。TYPEが‘nil’ならそれは‘PRIMARY’を意 味する。 DATAが‘nil’なら、それはその選択をクリアーすることを意味する。それ以 外ならDATAは文字列、シンボル、整数(2つの整数からなるコンスかリスト )、オーバーレイ、同じバッファーを指す2つのマーカーのコンスを指定で きる。オーバーレイとマーカーのペアは、そのオーバーレイまたはマーカ ー間のテキストを意味する。引数DATAには有効な非ベクターの選択のベク ターも指定できる。 この関数はDATAをリターンする。 -- Function: gui-get-selection &optional type data-type この関数は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’に加えて、少数の部分集合だけをサポートする。 -- User Option: selection-coding-system この変数は選択やクリップボードに読み書きする際のコーディングシステ ムを指定する。*note Coding Systems::を参照のこと。デフォルトは ‘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’が時代遅れのエ イリアスとして存在します。 28.20 ドラッグアンドドロップ ============================ ユーザーが別のアプリケーションからEmacsに何かをドラッグをした際には、そ の別アプリケーションはEmacsがドラッグされたデータを処理可能か告げること を期待します。変数‘x-dnd-test-function’は何を応答するか決定するために Emacsにより使用されます。デフォルト値は‘x-dnd-default-test-function’で、 これはドロップされたデータのタイプが‘x-dnd-known-types’内にあればドロッ プを受け入れます。何か別の条件にもとづいてEmacsにドロップを許容または拒 絶させたければ、‘x-dnd-test-function’および/または‘x-dnd-known-types’を カスタマイズできます。 Emacsが異なるタイプのドロップを処理する方法を変更したり新たなタイプを 追加したければ‘x-dnd-types-alist’をカスタマイズします。これには他のアプ リケーションがドラッグアンドドロップに使用するタイプが何なのか詳細な知識 が要求されます。 EmacsにURLがドロップされたとき、それはファイルかもしれませんが他の URLタイプ(ftp、http、...)であるかもしれません。EmacsはまずそのURLに何を 行うべきか判断するために、‘dnd-protocol-alist’をチェックします。それにマ ッチがなく、かつ‘browse-url-browser-function’がalistならEmacsはそこでマ ッチを探します。それでもマッチが見つからなければ、そのURLにたいするテキ ストを挿入します。これらの変数をカスタマイズすればEmacsの挙動を変更でき ます。 28.21 カラー名 ============== カラー名(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)”に依存 する場合があります。“選択されたフレーム”という用語の意味については*note Input Focus::を参照してください。 補完付きでカラー名のユーザー入力を読み取るには‘read-color’を使用しま す(*note read-color: High-Level Completion.を参照)。 -- Function: color-defined-p color &optional frame この関数はカラー名が有意かどうかを報告する。もし有意なら‘t’、それ以 外は‘nil’をリターンする。引数FRAMEはどのフレームのディスプレイにた いして問い合わせるかを指定する。FRAMEが省略または‘nil’の場合は選択 されたフレームが使用される。 これは使用しているディスプレイがそのカラーをサポートするかどうかは 告げないことに注意。X使用時にはすべての種類のディスプレイ上のすべて の定義されたカラーを問い合わせることができ、何らかの結果(通常は可能 な限り近いカラー)を得ることができるだろう。あるフレームが特定のカラ ーを実際に表示できるかどうか判断するためには‘color-supported-p’ (以 下参照)を使用する。 この関数は以前は‘x-color-defined-p’と呼ばれており、その名前は今でも エイリアスとしてサポートされている。 -- Function: defined-colors &optional frame この関数はFRAME(デフォルトは選択されたフレーム)上で定義されていて、 かつサポートされるカラー名のリストをリターンする。FRAMEがカラーをサ ポートしなければ値は‘nil’。 この関数は以前は‘x-defined-colors’と呼ばれており、その名前は今でも エイリアスとしてサポートされている。 -- Function: color-supported-p color &optional frame background-p これは、FRAMEが実際にカラーCOLOR (または最低でもそれに近いカラー)を 表示可能なら‘t’をリターンする。FRAMEが省略または‘nil’ならこの問いは 選択されたフレームに適用される。 フォアグラウンドとバックグラウンドにたいして異なるカラーセットをサ ポートする端末がいくつかある。BACKGROUND-Pが非‘nil’なら、それは COLORがバックグラウンドとして、それ以外はフォアグラウンドとして使用 可能かどうかを問うことを意味する。 引数COLORは有効なカラー名でなければならない。 -- Function: color-gray-p color &optional frame これはCOLORがFRAMEのディスプレイ上の定義としてグレイスケールなら ‘t’をリターンする。FRAMEが省略または‘nil’なら、この問いは選択された フレームに適用される。COLORが有効なカラー名でなければ、この関数は ‘nil’をリターンする。 -- Function: color-values color &optional frame この関数はFRAME上で理想的にはCOLORがどのように見えるべきかを記述す る値をリターンする。COLORが定義済みなら値は赤、緑、青の割合を与える 3つの整数からなるリストとなる。それぞれの整数の範囲は原則として0か ら65535だが、この範囲全体を使用しないディスプレイもいくつか存在する だろう。この3要素のリストはカラーの“RGB値(rgb values)”と呼ばれる。 COLORが未定義なら値は‘nil’。 (color-values "black") ⇒ (0 0 0) (color-values "white") ⇒ (65280 65280 65280) (color-values "red") ⇒ (65280 0 0) (color-values "pink") ⇒ (65280 49152 51968) (color-values "hungry") ⇒ nil カラーの値はFRAMEのディスプレイにたいしてリターンされる。FRAMEが省 略または‘nil’の場合には、この情報は選択されたフレームのディスプレイ にたいしてリターンされる。このフレームがカラーを表示できなければ値 は‘nil’。 この関数は以前は‘x-color-values’と呼ばれており、その名前は今でもエ イリアスとしてサポートされている。 28.22 テキスト端末のカラー ========================== テキスト端末は通常は少しのカラーしかサポートせず、コンピューターはカラー 選択に小さい整数を使用します。これは選択したカラーがどのように見えるかコ ンピューターが信頼性をもって告げることができず、どのカラーがどのような小 さい整数に対応するかという情報をアプリケーションに伝える必要があることを 意味します。しかしEmacsは標準的なカラーセットを知っており、それらの自動 的な使用を試みるでしょう。 このセクションで説明する関数はEmacsが端末カラーを使用する方法を制御し ます。 これらの関数のうちのいくつかは*note Color Names::で説明した“RGB値(rgb values)”を使用またはリターンします。 これらの関数はオプション引数としてディスプレイ(フレームまたは端末名の いずれか)を受け取ります。わたしたちは将来には異なる端末上で異なるカラー をEmacsにサポートさせたいと望んでいます。そうすればこの引数はどの端末を 処理するか(デフォルトは選択されたフレームの端末。*note Input Focus::を参 照)を指定するようになるでしょう。しかし現在のところFRAME引数に効果はあり ません。 -- Function: tty-color-define name number &optional rgb frame この関数はカラー名NAMEをその端末上のカラー値NUMBERに関連付ける。 オプション引数RGBが指定された場合、それはそのカラーが実際にどのよう に見えるかを指定する3つの数値のリストからなるRGB値である。RGBを指定 しなければEmacsはそれがどのように見えるか知らないので、そのカラーを 他のカラーに近似するために‘tty-color-approximate’で使用することがで きない。 -- Function: tty-color-clear &optional frame この関数はテキスト端末の定義済みカラーのテーブルをクリアーする。 -- Function: tty-color-alist &optional frame この関数はテキスト端末がサポートする既知のカラーを記録したalistをリ ターンする。 それぞれの要素は‘(NAME NUMBER . RGB)’、または‘(NAME NUMBER)’という 形式をもつ。ここでNAMEはカラー名、NUMBERはその端末でカラー指定に使 用される数値。RGBが与えられたら、それはそのカラーが実際にどのように 見えるかを告げる3つのカラー値(赤、緑、青)のリストである。 -- Function: tty-color-approximate rgb &optional frame この関数はDISPLAYにたいしてサポートされた既知のカラーの中から、 RGB値RGB (カラー値のリスト)で記述されたもっとも近いカラーを探す。リ ターン値は‘tty-color-alist’の要素。 -- Function: tty-color-translate color &optional frame この関数はDISPLAYにたいしてサポートされた既知のカラーの中から、もっ とも近いカラーのインデックス(整数)をリターンする。名前COLORが未定義 なら値は‘nil’。 28.23 Xリソース =============== このセクションではXリソース、または他のオペレーティングシステム上での等 価物を問い合わせたり使用する関数および変数をいくつか説明します。Xリソー スにたいする詳細な情報は*note X Resources: (emacs)X Resources.を参照して ください。 -- Function: x-get-resource attribute class &optional component subclass 関数‘x-get-resource’はXウィンドウのデフォルトデータベースからリソー ス値を取得する。 リソースは“キー(key)”と“クラス(class)”の組み合わせによりインデック ス付けされている。この関数は‘INSTANCE.ATTRIBUTE’という形式をキー (INSTANCEはEmacsが呼び出されたときの名前)、クラスとして ‘Emacs.CLASS’として使用することにより検索を行う。 オプション引数COMPONENTとSUBCLASSは、それぞれキーとクラスを追加する 。指定する場合には両方を指定するか、さもなくばどちらも指定してはな らない。これらを指定した場合にはキーは ‘INSTANCE.COMPONENT.ATTRIBUTE’、クラスは‘Emacs.CLASS.SUBCLASS’とな る。 -- Variable: x-resource-class この変数は‘x-get-resource’が照会すべきアプリケーション名を指定する 。デフォルト値は‘"Emacs"’。‘x-get-resource’の呼び出し周辺で、この変 数を他のアプリケーション名の文字列にバインドすることにより、アプリ ケーション名にたいしてXリソースを調べることができる。 -- Variable: x-resource-name この変数は‘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" -- Variable: inhibit-x-resources この変数が非‘nil’ならEmacsはXリソースを照会せず、新たなフレーム作成 時にXリソースは何も効果をもたない。 28.24 ディスプレー機能のテスト ============================== このセクションの関数は特定のディスプレイの基本的な能力を説明します。 Lispプログラムはそのディスプレイが行えることに挙動を合わせるために、それ らを使用できます。たとえばポップアップメニューがサポートされなければ、通 常はポップアップメニューを使用するプログラムはミニバッファーを使用できま す。 これらの関数のオプション引数DISPLAYは問い合わせるディスプレイを指定し ます。これにはディスプレイ名、フレーム(フレームがあるディスプレイを指定 )、または‘nil’ (選択されたフレームのディスプレイを参照する。*note Input Focus::を参照)を指定できます。 ディスプレイに関する情報を取得するその他の関数については*note Color Names::を参照してください。 -- Function: display-popup-menus-p &optional display この関数はDISPLAY上でポップアップメニューがサポートされていれば ‘t’、それ以外は‘nil’をリターンする。Emacsディスプレイのある部分をマ ウスでクリックすることによりメニューがポップアップするので、ポップ アップメニューのサポートにはマウスが利用可能であることが要求される 。 -- Function: display-graphic-p &optional display この関数はDISPLAYが一度に複数フレームおよび複数の異なるフォントを表 示する能力を有すグラフィックディスプレイなら‘t’をリターンする。これ はXのようなウィンドウシステムのディスプレイにたいしては真、テキスト 端末にたいしては偽となる。 -- Function: display-mouse-p &optional display この関数はDISPLAYでマウスが利用可能なら‘t’、それ以外は‘nil’をリター ンする。 -- Function: display-color-p &optional display この関数はそのスクリーンがカラースクリーンなら‘t’をリターンする。こ れは以前は‘x-display-color-p’と呼ばれており、その名前はエイリアスと して今でもサポートされる。 -- Function: display-grayscale-p &optional display この関数はスクリーンがグレースケールを表示可能なら‘t’をリターンする (カラーディスプレイはすべてこれを行うことができる)。 -- Function: display-supports-face-attributes-p attributes &optional display この関数はATTRIBUTES内のすべてのフェイス属性がサポートされていれば 非‘nil’をリターンする(*note Face Attributes::を参照)。 幾分発見的ではあるが“サポートされる”という言葉は、基本的にはあるフ ェイスがATTRIBUTES内のすべての属性を含み、ディスプレイにたいしてデ フォルトフェイスにマージ時に、 1. デフォルトフェイスとは異なる外見で表示でき、かつ 2. 指定した属性と正確に一致しない場合はより近い(close in spirit)外 見で表示する 2つ目のポイントによると属性‘:weight black’は太字(bold)表示可能、同 様に属性‘:foreground "yellow"’は黄色がかった何らかのカラーを表示可 能なすべてのディスプレイで満たされるだろうが、属性‘:slant italic’は 斜体(italic)を自動的に淡色(dim)に置き換えるttyの表示コードでは_満た されない_であろうことを暗示している。 -- Function: display-selections-p &optional display この関数はDISPLAYが選択(selections)をサポートすれば‘t’をリターンす る。ウィンドウ化されたディスプレイでは通常は選択がサポートされるが 、他の場合にもサポートされ得る。 -- Function: display-images-p &optional display この関数はDISPLAYがイメージを表示可能なら‘t’をリターンする。ウィン ドウ化されたディスプレイは原則イメージを処理するが、イメージにたい するサポートを欠くシステムもいくつかある。イメージをサポートしない ディスプレイ上ではEmacsはツールバーを表示できない。 -- Function: display-screens &optional display この関数はそのディスプレイに割り当てられたスクリーンの数をリターン する。 -- Function: display-pixel-height &optional display この関数はスクリーンの高さをピクセルでリターンする。文字端末では文 字数で高さを与える。 マルチモニターにセットアップされているグラフィカル端末では、 DISPLAYに割り当てられたすべての物理モニターのピクセル幅を参照するこ とに注意。*note Multiple Terminals::を参照のこと。 -- Function: display-pixel-width &optional display この関数はスクリーンの幅をピクセルでリターンする。文字端末では文字 数で幅を与える。 マルチモニターにセットアップされているグラフィカル端末では、 DISPLAYに割り当てられたすべての物理モニターのピクセル幅を参照するこ とに注意。*note Multiple Terminals::を参照のこと。 -- Function: display-mm-height &optional display この関数はスクリーンの高さをミリメートルでリターンする。‘nil’なら Emacsがその情報を取得できなかったことを意味する。 マルチモニターにセットアップされているグラフィカル端末では、 DISPLAYに割り当てられたすべての物理モニターのピクセル幅を参照するこ とに注意。*note Multiple Terminals::を参照のこと。 -- Function: display-mm-width &optional display この関数はスクリーンの幅をミリメートルでリターンする。‘nil’なら Emacsがその情報を取得できなかったことを意味する。 マルチモニターにセットアップされているグラフィカル端末では、 DISPLAYに割り当てられたすべての物理モニターのピクセル幅を参照するこ とに注意。*note Multiple Terminals::を参照のこと。 -- User Option: display-mm-dimensions-alist この変数はシステムの提供する値が不正な場合に‘display-mm-height’と ‘display-mm-width’がリターンするグラフィカルなディスプレイのサイズ をユーザーが指定できるようにする。 -- Function: display-backing-store &optional display この関数はそのディスプレイのバッキングストアー(backing store)の能力 をリターンする。バッキングストアーとは非露出ウィンドウ(およびウィン ドウの一部)のピクセルを記録しておいて、露出時に素早く表示できるよう にすることを意味する。 値はシンボル‘always’、‘when-mapped’、‘not-useful’。特定の種類のディ スプレイにたいしてこの問いが適用外の際には、この関数は‘nil’をリター ンすることもある。 -- Function: display-save-under &optional display この関数はそのディスプレイがSaveUnder機能をサポートすれば非‘nil’を リターンする。この機能はポップアップウィンドウに隠されるピクセルを 保存して素早くポップダウンができるようにするために使用される。 -- Function: display-planes &optional display この関数はそのディスプレイがサポートする平面数(number of planes)を リターンする。これは通常はピクセルごとのビット数(bits per pixel: 色 深度[bpp])。ttyディスプレイではサポートされるカラー数の2進対数(log to base two)。 -- Function: display-visual-class &optional display この関数はそのスクリーンのビジュアルクラスをリターンする。値はシン ボル‘static-gray’ (カラー数変更不可の限定されたグレイ)、 ‘gray-scale’ (フルレンジのグレイ)、‘static-color’ (カラー数変更不可 の限定されたカラー)、‘pseudo-color’ (限定されたカラー数のカラー)、 ‘true-color’ (フルレンジのカラー)、および‘direct-color’ (フルレンジ のカラー)のいずれか。 -- Function: display-color-cells &optional display この関数はそのスクリーンがサポートするカラーのセル数をリターンする 。 以下の関数はEmacsが指定されたDISPLAYを表示する場所に使用されるウィン ドウシステムの追加情報を取得します(関数名先頭の‘x-’は歴史的理由による)。 -- Function: x-server-version &optional display この関数はGNUおよびUnixシステム上のXサーバーのような、DISPLAY上で実 行されているGUIウィンドウシステムのバージョン番号のリストをリターン する。値は3つの整数からなるリストで、1つ目と2つ目の整数はそのプロト コルのメジャーバージョン番号とマイナーバージョン番号、3つ目の整数は ウィンドウシステムソフトウェア自体のディストリビューター固有のリリ ース番号。GNUおよびUnixシステムでは、通常これらはXプロトコルのバー ジョン番号と、Xサーバーソフトウェアのディストリビューター固有のリリ ース番号。MS-WindowsではWidowsのOSバージョン番号。 -- Function: x-server-vendor &optional display この関数はウィンドウシステムソフトウェアを提供するベンダー(文字列 )をリターンする。GNUおよびUnixシステムでは、それが誰であれそのXサー バーを配布するベンダーを意味する。MS-WindowsではWidows OSのベンダー ID文字列(Microsoft)。 X開発者がソフトウェア配布者を“vendors”とラベル付けしたことは、いか なるシステムも非商業的に開発および配布できないと彼らが誤って仮定し たことを示している。 29 ポジション ************* “位置(position)”とは、バッファーのテキストの文字のインデックスです。より 正確には、位置とは2つの文字間(または最初の文字の前か最後の文字の後)の箇 所を識別して、与えられた位置の前あるいは後の文字のように表現することがで きます。しかし“ある位置にある文字”のように表現することもあり、その場合に はその位置の後にある文字を意味します。 位置は通常は1から始まる整数として表されますが、“マーカー(markers)”と して表現することもできます。関数は引数に位置(整数)を期待しますが、代替と してマーカーも受け入れ、通常はそのマーカーが指すのがどのバッファーなのか は無視します。これらの関数はマーカーを整数に変換して、たとえそのマーカー が誤ったバッファーを指していたとしても、まるで引数として単にその整数が渡 されたかのようにその整数を使用します。整数に変換できない場所を指すマーカ ーを整数のかわりに使用するとエラーとなります。*note Markers::を参照して ください。 多くのカーソルモーションコマンドにより使用される関数を提供するフィー ルド(field)機能も参照してください(*note Fields::を参照)。 29.1 ポイント ============= “ポイント(point)”とは多くの編集コマンドにより使用されるバッファーの特別 な位置のことです。これらのコマンドには自己挿入型のタイプ文字やテキスト挿 入関数が含まれます。その他のコマンドは別の箇所でテキストの編集や挿入がで きるようにポイントを移動します。 ポイントは他の位置と同様に特定の文字ではなく、2つの文字の間(または最 初の文字の前か最後の文字の後)を指します。端末では通常はポイント直後の文 字の上にカーソルを表示します。つまりポイントは実際はカーソルのある文字の 前にあります。 ポイントの値は1より小さくなることはなく、そのバッファーのサイズに1を 加えた値より大きくなることはありません。ナローイング(*note Narrowing::を 参照)が効力をもつ場合には、ポイントはそのバッファーのアクセス可能な範囲 内(範囲の境界はバッファーの先頭か終端のいずれかの可能性がある)に拘束され ます。 バッファーはそれぞれ自身のポイント値をもち、それは他のバッファーのポ イント値とは無関係です。ウィンドウもそれぞれポイント値をもち、他のウィン ドウ内の同じバッファー上のポイント値とは無関係です。同じバッファーを表示 する種々のウィンドウが異なるポイント値をもてるのはこれが理由です。あるバ ッファーがただ1つのウィンドウに表示されているときは、そのバッファーのポ イントとそのウィンドウのポイントは通常は同じ値をもち、区別が重要になるこ とは稀です。詳細は*note Window Point::を参照してください。 -- Function: point この関数はカレントバッファー内のポイントの値を整数でリターンする。 (point) ⇒ 175 -- Function: point-min この関数はカレントバッファー内のアクセス可能なポイントの最小値をリ ターンする。これは通常は1だがナローイングが効力をもつ場合は、ナロー イングしたリージョンの開始位置となる(*note Narrowing::を参照)。 -- Function: point-max この関数はカレントバッファー内のアクセス可能なポイントの最大値をリ ターンする。これはナローイングされていなければは‘(1+ (buffer-size))’だが、ナローイングが効力をもつ場合は、ナローイングし たリージョンの終端位置となる(*note Narrowing::を参照)。 -- Function: buffer-end flag この関数はFLAGが0より大なら‘(point-max)’、それ以外は‘(point-min)’を リターンする。引数FLAGは数値でなければならない。 -- Function: buffer-size &optional buffer この関数はカレントバッファー内の文字数のトータルをリターンする。ナ ローイング(*note Narrowing::を参照)されていなければ、‘point-max’は これに1を加えた値をリターンする。 BUFFERにバッファーを指定すると値はBUFFERのサイズになる。 (buffer-size) ⇒ 35 (point-max) ⇒ 36 29.2 モーション =============== モーション関数はポイントのカレント値、バッファーの先頭か終端、または選択 されたウィンドウ端のいずれかより相対的にポイントの値を変更します。*note Point::を参照してください。 29.2.1 文字単位の移動 --------------------- 以下の関数は文字数にもとづいてポイントを移動します。 ‘goto-char’は基本的 なプリミティブであり、その他の関数はこれを使用しています。 -- Command: goto-char position この関数はカレントバッファー内のポイントの値をPOSITIONにセットする 。 ナローイングが効力をもつ場合でもPOSITIONは依然としてバッファー先頭 から数えられるが、ポイントをアクセス可能な範囲外に移動することはで きない。POSITIONが範囲外なら、‘goto-char’はアクセス可能な範囲の先頭 または終端にポイントを移動する。 この関数がインタラクティブに呼び出された際は、POSITIONの値は数プレ フィクス引数、プレフィクス引数が与えられなかった場合はミニバッファ ーから値を読み取る。 ‘goto-char’はPOSITIONをリターンする。 -- Command: forward-char &optional count この関数は前方、すなわちバッファーの終端方向にポイントをCOUNT文字移 動する(COUNTが負なら後方、すなわちバッファーの先頭方向にポイントを 移動する)。COUNTが‘nil’の場合のデフォルトは1。 バッファー(ナローイングが効力をもつ場合はアクセス可能な範囲の境界 )の先頭か終端を超えて移動を試みるとエラーシンボル ‘beginning-of-buffer’か‘end-of-buffer’のエラーをシグナルする。 インタラクティブな呼び出しでは数プレフィクス引数がCOUNTとなる。 -- Command: backward-char &optional count 移動方向が逆であることを除いて、これは‘forward-char’と同様。 29.2.2 単語単位の移動 --------------------- 以下で説明する単語をパースする関数は、与えられた文字が単語の一部かどうか を判断するために構文テーブルと‘char-script-table’を使用します。*note Syntax Tables::と*note Character Properties::を参照してください。 -- Command: forward-word &optional count この関数はCOUNTの単語数分ポイントを前方に移動する。(COUNTが負なら後 方に移動する)。COUNTが省略または‘nil’の場合のデフォルトは1。インタ ラクティブな呼び出しでは、COUNTは数プレフィクス引数により指定される 。 “単語1つ移動”とは単語構成文字を横断して、単語の先頭を示す単語区切り 文字に遭遇するまでポイントを移動することを意味する。“単語境界(word boundaries)”として知られる単語の開始と終了の文字は、デフォルトでは カレントバッファーの構文テーブル(*note Syntax Class Table::を参照 )により定義されるが、以下で説明する ‘find-word-boundary-function-table’を適切にセットすることによりモー ドはこれをオーバーライドできる。(‘char-syntax-table’で定義される)異 なるスクリプトに属するも単語境界を定義する(*note Character Properties::を参照)。いくつかのケースでは、この関数はバッファーのア クセス可能範囲の境界およびフィールド境界(*note Fields::を参照)を超 えてポイントを移動できない。フィールド境界のもっとも一般的な例は、 ミニバッファー内のプロンプト終端である。 バッファー境界やフィールド境界により途中で停止することなく単語 COUNT個分の移動が可能なら値は‘t’となる。それ以外ではリターン値は ‘nil’となり、ポイントはバッファー境界またはフィールド境界で停止する 。 ‘inhibit-field-text-motion’が非‘nil’なら、この関数はフィールド境界 を無視する。 -- Command: backward-word &optional count この関数は単語の前に遭遇するまで前方ではなく後方に移動することを除 いて‘forward-word’と同様。 -- User Option: words-include-escapes この変数は、‘forward-word’と‘backward-word’、およびそれらを使用する すべての関数の挙動に影響する。これが非‘nil’なら、構文クラスescapeと character-quote内の文字は単語の一部とみなされる。それ以外なら単語の 一部とはみなされない。 -- Variable: inhibit-field-text-motion この変数が非‘nil’なら‘forward-word’、‘forward-sentence’、 ‘forward-paragraph’を含む特定のモーション関数はフィールド境界を無視 する。 -- Variable: find-word-boundary-function-table この変数は‘forward-word’と‘backward-word’、およびそれらを使用するす べての挙動に影響する。値は単語境界を検索するための関数の文字テーブ ル(*note Char-Tables::を参照)。このテーブル内である文字が非‘nil’の エントリーをもつ場合には、単語がその文字で開始または終了する際に対 応する関数が2つの引数POSとLIMITで呼び出される。この関数は別の単語境 界の位置をリターンすること。具体的には、POSがLIMITより小さければ POSは単語の先頭にあり関数はその単語の最後の文字の後の位置、それ以外 ならPOSは単語の最後の文字にあり関数はその単語の最初の文字の位置をリ ターンすること。 -- Function: forward-word-strictly &optional count この関数は‘forward-word’と同様だが ‘find-word-boundary-function-table’による影響を受けない点が異なる。 このテーブルをセットする‘subword-mode’のようなモードにより単語単位 の移動が変更されている際に挙動を変えるべきではないLispプログラムは 、‘forward-word’のかわりにこの関数を使用すること。 -- Function: backward-word-strictly &optional count この関数は‘backward-word’と同様だが、 ‘find-word-boundary-function-table’の影響を受けない点が異なる。 ‘forward-word-strictly’と同様に、構文テーブルだけを考慮して単語単位 の移動を行う必要がある際には、‘backward-word’のかわりにこの関数を使 用すること。 29.2.3 バッファー終端への移動 ----------------------------- バッファーの先頭にポイントを移動するには以下のように記述します: (goto-char (point-min)) 同様にバッファーの終端に移動するには以下を使用します: (goto-char (point-max)) 以下の2つのコマンドは、ユーザーがこれらを行うためのコマンドです。これ らはマークをセットしてメッセージをエコーエリアに表示するため、Lispプログ ラム内で使用しないよう警告するためにここに記述します。 -- Command: beginning-of-buffer &optional n この関数はバッファー(ナローイングが効力をもつ場合はアクセス可能範囲 の境界)の先頭にポイントを移動して、以前の位置にマークをセットする (Transient Markモードの場合にはマークがすでにアクティブならマークは セットしない)。 Nが非‘nil’ならバッファーのアクセス可能範囲の先頭からN/10の位置にポ イントを配置する。インタラクティブな呼び出しではNは数プレフィクス引 数が与えられればその値、それ以外でのデフォルトは‘nil’。 *警告:* この関数をLispプログラム内で使用してはならない。 -- Command: end-of-buffer &optional n この関数はバッファー(ナローイングが効力をもつ場合はアクセス可能範囲 の境界)の終端にポイントを移動して、以前の位置にマークをセットする (Transient Markモードの場合にはマークがすでにアクティブならマークは セットしない)。Nが非‘nil’ならバッファーのアクセス可能範囲の終端から N/10の位置にポイントを配置する。 インタラクティブな呼び出しではNは数プレフィクス引数が与えられればそ の値、それ以外でのデフォルトは‘nil’。 *警告:* この関数をLispプログラム内で使用してはならない。 29.2.4 テキスト行単位の移動 --------------------------- テキスト行とは改行で区切られたバッファーの範囲です。改行は前の行の一部と みなされます。最初のテキスト行はバッファー先頭で始まり、最後のテキスト行 は最後の文字が改行かどうかは関係なくバッファー終端で終わります。バッファ ーからテキスト行への分割はそのウィンドウの幅、表示の行継続、タブやその他 の制御文字の表示方法に影響されません。 -- Command: beginning-of-line &optional count この関数はカレント行の先頭にポイントを移動する。引数COUNTが非 ‘nil’または1以外なら前方にCOUNT−1行移動してから、その行の先頭に移動 する。 この関数は別の行に移動する場合を除いてフィールド境界(*note Fields::を参照)を超えてポイントを移動しない。したがってCOUNTが ‘nil’か1で、かつポイントがフィールド境界で開始される場合にはポイン トを移動しない。フィールド境界を無視させるには ‘inhibit-field-text-motion’を‘t’にバインドするか、かわりに ‘forward-line’関数を使用する。たとえばフィールド境界を無視すること を除けば、‘(forward-line 0)’は‘(beginning-of-line)’と同じことを行う 。 この関数がバッファー(ナローイングが効力をもつ場合はアクセス可能範囲 )の終端に到達したらポイントをその位置に配置する。エラーはシグナルさ れない。 -- Function: line-beginning-position &optional count ‘(beginning-of-line COUNT)’が移動するであろう位置をリターンする。 -- Command: end-of-line &optional count この関数は、カレント行の終端にポイントを移動する。引数COUNTが非 ‘nil’または1以外なら前方にCOUNT−1行移動してから、その行の終端に移動 する。 この関数は別の行に移動する場合を除いてフィールド境界(*note Fields::を参照)を超えてポイントを移動しない。したがってCOUNTが ‘nil’または1で、かつポイントがフィールド境界で開始される場合にはポ イントを移動しない。フィールド境界を無視させるには ‘inhibit-field-text-motion’を‘t’にバインドする。 この関数がバッファー(ナローイングが効力をもつ場合はアクセス可能範囲 )の終端に到達したらポイントをその位置に配置する。エラーはシグナルさ れない。 -- Function: line-end-position &optional count ‘(end-of-line COUNT)’が移動するであろう位置をリターンする。 -- Command: forward-line &optional count この関数は後続行へ前方にCOUNT行移動して、その行の先頭にポイントを移 動する。COUNTが負なら先行行へ後方に−COUNT行移動して、その行の先頭に ポイントを移動する。COUNTが0ならカレント行の先頭にポイントを移動す る。COUNTが‘nil’ならそれは1を意味する。 ‘forward-line’が指定された行数を移動する前にバッファー(またはアクセ ス可能範囲)の先頭か終端に遭遇したら、そこにポイントをセットする。エ ラーはシグナルされない。 ‘forward-line’はCOUNTと実際に移動した行数の差をリターンする。3行し かないバッファーの先頭から5行下方への移動を試みると、ポイントは最終 行の終端で停止して値は2となるだろう。明示的な例外としてアクセス可能 な最終行が空ではなく改行がなければ(バッファーが改行で終わらない場合 )、この関数はその行の終端にポイントをセットして、この関数がリターン する値はその行を移動に成功した1行として計数する。 インタラクティブな呼び出しでは数プレフィクス引数がCOUNTとなる。 -- Function: count-lines start end この関数はカレントバッファー内の位置STARTとENDの間の行数をリターン する。STARTとENDが等しければリターン値は0。それ以外は、たとえ STARTとENDが同一行にあっても最小でも1をリターンする。これらの間にあ るテキストは、それだけを孤立して考えたると、それが空でない限りは最 小でも1行を含まなければならないからである。 -- Command: count-words start end この関数はカレントバッファー内の位置STARTとENDの間にある単語の数を リターンする。 この関数はインタラクティブに呼び出すこともできる。その場合はバッフ ァー、またはリージョンがアクティブならリージョン内の行数、単語数、 文字数を報告するメッセージをプリントする。 -- Function: line-number-at-pos &optional pos この関数はカレントバッファー内のバッファー位置POSに対応する行番号を リターンする。POSが‘nil’または省略されるとカレントのバッファー位置 が使用される。 *note Near Point::の関数‘bolp’と‘eolp’も参照してください。これらの関 数はポイントを移動しませんが、ポイントがすでに行頭または行末にあるかどう かをテストします。 29.2.5 スクリーン行単位の移動 ----------------------------- 前のセクションの行関数は、改行文字で区切られたテキスト行だけを数えました 。それらとは対照的に以下の関数はスクリーン行を数えます。スクリーン行はス クリーン上でテキストが表示される方法にしたがって定義されます。あるテキス ト行1行が選択されたウィンドウの幅にフィット可能な程に十分短ければそれは スクリーン行で1行になりますが、それ以外は複数のスクリーン行になり得ます 。 テキスト行が追加スクリーン行に継続されずに、そのスクリーンで切り詰め られる(truncated)場合があります。そのような場合には‘vertical-motion’で ‘forward-line’のようにポイントを移動します。*note Truncation::を参照して ください。 文字列が与えられると、その幅は文字の外見を制御するフラグに依存するた めに与えられたテキスト断片にたいして、たとえそれが選択されたウィンドウ上 でさえも(幅、切り詰めの有無、ディスプレイテーブルはウィンドウごとに異な り得るので)、そのテキストがあるバッファーに応じて‘vertical-motion’の挙動 は異なります。*note Usual Display::を参照してください。 以下の関数はスクリーン行のブレーク位置を判断するためにテキストをスキ ャンするために、スキャンする長さに比例して時間を要します。 -- Function: vertical-motion count &optional window cur-col この関数はポイントのあるスクリーン行からスクリーン行でCOUNT行下方に 移動して、そのスクリーン行の先頭にポイントを移動する。COUNTが負なら かわりに上方に移動する。 COUNT引数には整数のかわりにコンスセル‘(COLS . LINES)’を指定できる。 その場合には関数はスクリーン行でLINES行移動して、そのスクリーン行の 視覚的な行頭(visual start)からCOLS列目にポイントを配置する。COLSは その行の_視覚的(visual)_な開始から数えられることに注意。そのウィン ドウが水平スクロール(*note Horizontal Scrolling::を参照)されていれ ば、ポイントが配置される列は、スクロールされたテキストの列数が加え られるだろう。 リターン値はポイントが移動したスクリーン行の行数。バッファーの先頭 か終端に到達していたら、この値は絶対値ではCOUNTより小になるかもしれ ない。 ウィンドウWINDOWは幅、水平スクロール、ディスプレイテーブルのような パラメーターの取得に使用される。しかし‘vertical-motion’は、たとえ WINDOWがカレントで他のバッファーを表示していたとしても、常にカレン トバッファーにたいして処理を行う。 オプション引数CUR-COLはこの関数呼び出しの際のカレント列を指定する。 これはそのフレームのデフォルトフェイスのフォント幅を単位として計測 される、ウィンドウに相対的なポイントの水平座標でる。カレント列の判 定のために戻る必要がないので、特に長い行における関数の高速化を提供 する。CUR-COLも行の視覚的な開始から計数されることに注意。 -- Function: count-screen-lines &optional beg end count-final-newline window この関数はBEGからENDのテキスト内のスクリーン行の行数をリターンする 。スクリーン行数は行継続やディスプレイテーブル等により実際の行数と は異なるかもしれない。BEGとENDが‘nil’、または省略された場合のデフォ ルトは、そのバッファーのアクセス可能範囲の先頭と終端。 そのリージョンが改行で終わる場合には、オプションの第3引数 COUNT-FINAL-NEWLINEが‘nil’ならそれは無視される。 オプションの第4引数WINDOWは幅や水平スクロール等のパラメーターを取得 するウィンドウを指定する。デフォルトは選択されたウィンドウのパラメ ーターを使用する。 ‘vertical-motion’と同じうように、‘count-screen-lines’はWINDOW内にど のバッファーが表示されていようと常にカレントバッファーを使用する。 これによりバッファーが何らかのウィンドウにカレントで表示されている か否かにかかわらず、任意にバッファーにたいして ‘count-screen-lines’の使用が可能になる。 -- Command: move-to-window-line count この関数は選択されたウィンドウ内にカレントで表示されているテキスト に応じてポイントを移動する。これはウィンドウ上端からスクリーン行で COUNT行目の先頭にポイントを移動する。COUNTが負なら、それはバッファ ー下端(バッファーが指定されたスクリーン位置の上で終わる場合はバッフ ァーの最終行)から、−COUNT行目の位置を指定する。 COUNTが‘nil’ならポイントはウィンドウ中央の行の先頭に移動する。 COUNTの絶対値がウィンドウサイズより大の場合には、ウィンドウが十分に 高かったらそのスクリーン行は表示されていたであろう位置にポイントを 移動する。これはおそらく次回の再表示の際に、その箇所がスクリーン上 になるようなスクロールを発生させるだろう。 インタラクティブな呼び出しでは数プレフィクス引数がCOUNTとなる。 リターン値はウィンドウ上端行の番号を0とする、ポイントが移動した先の 行番号。 -- Function: move-to-window-group-line count この関数は‘move-to-window-line’と同様だが、選択されたウィンドウがウ ィンドウグループ(*note Window Group::を参照)の一部なら、 ‘move-to-window-group-line’は単一のウィンドウではなくグループ全体に たいする位置に移動する。この条件はバッファーローカル変数 ‘move-to-window-group-line-function’に関数がセットされている際に保 持される。この場合には‘move-to-window-group-line’は引数COUNTでその 関数を呼び出して、その結果をリターンする。 -- Function: compute-motion from frompos to topos width offsets window この関数はカレントバッファーをスキャンしてスクリーン位置を計算する 。これは位置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’を使 用する必要がある。 29.2.6 バランスのとれたカッコを越えた移動 ----------------------------------------- 以下はバランスの取れたカッコ式(balanced-parenthesis。これらの式を横断し て移動することと関連してEmacsでは“sexp(S式)”とも呼ばれる)と関係のあるい くつかの関数です。これらの関数がさまざまな文字を処理する方法は構文テーブ ル(syntax table)が制御します。*note Syntax Tables::を参照してください。 sexpやその一部にたいする低レベルのプリミティブについては*note Parsing Expressions::を参照してください。ユーザーレベルのコマンドについては*note Commands for Editing with Parentheses: (emacs)Parentheses.を参照してくだ さい。 -- Command: forward-list &optional arg この関数はバランスの取れたカッコのグループをARG (デフォルトは1)グル ープ前方に移動する(単語やクォート文字のペアーでクォートされた文字列 は無視される)。 -- Command: backward-list &optional arg この関数はバランスの取れたカッコのグループをARG (デフォルトは1)グル ープ後方に移動する(単語やクォート文字のペアーでクォートされた文字列 は無視される)。 -- Command: up-list &optional arg escape-strings no-syntax-crossing この関数はARG (デフォルトは1)の外側のカッコへ前方に移動する。負の引 数では後方へ移動するが、それでもより浅いスポットへと移動する。 ESCAPE-STRINGSが非‘nil’ (インタラクティブ時が該当)なら、取り囲まれ た文字列の外側にも同様に移動する。NO-SYNTAX-CROSSINGが非‘nil’ (イン タラクティブ時が該当)なら、複数の文字列を横断してリスト先頭に移動す るかわりに、取り囲む文字列から脱け出すことを優先する。エラー時には ポイントの位置は未定義。 -- Command: backward-up-list &optional arg escape-strings no-syntax-crossing この関数は‘up-list’とど同様だが引数の正負が逆。 -- Command: down-list &optional arg この関数はカッコをARG (デフォルトは1)レベル内側、前方に移動する。負 の引数では後方に移動するが、それでも深いレベル(−ARGレベル)に移動す る。 -- Command: forward-sexp &optional arg この関数はバランスの取れた式(balanced expressions)をARG (デフォルト は1)前方に移動する。バランスの取れた式にはカッコ等で区切られた式、 および単語や文字列定数のようなものも含まれる。*note Parsing Expressions::を参照のこと。たとえば、 ---------- Buffer: foo ---------- (concat★ "foo " (car x) y z) ---------- Buffer: foo ---------- (forward-sexp 3) ⇒ nil ---------- Buffer: foo ---------- (concat "foo " (car x) y★ z) ---------- Buffer: foo ---------- -- Command: backward-sexp &optional arg この関数はバランスの取れた式(balanced expressions)を、ARG (デフォル トは1)後方に移動する。 -- Command: beginning-of-defun &optional arg この関数は後方にARG番目のdefunの先頭に移動する。ARGが負なら実際には 前方に移動するが、defunの終端ではなく先頭に移動することは変わらない 。ARGのデフォルトは1。 -- Command: end-of-defun &optional arg この関数は前方にARG番目のdefunの終端に移動する。ARGが負なら実際には 後方に移動するが、defunの先頭ではなく終端に移動することは変わらない 。ARGのデフォルトは1。 -- User Option: defun-prompt-regexp このバッファーローカル変数は非‘nil’ならdefunの始まりとなる開きカッ コの前に出現し得るテキストを指定する正規表現を保持する。つまりこの 正規表現にたいするマッチで始まり、その後に開きカッコ構文 (open-parenthesis syntax)が続くものがdefunである。 -- User Option: open-paren-in-column-0-is-defun-start この変数の値が非‘nil’なら列0にある開きカッコはdefunの始まりとみなさ れる。‘nil’なら列0の開きカッコは特別な意味をもたない。デフォルトは ‘t’。 -- Variable: beginning-of-defun-function この変数は非‘nil’ならdefunの開始を見つける関数を保持する。関数 ‘beginning-of-defun’は通常の手法を使うかわりに、この関数に自身のオ プション引数を渡して呼び出す。引数が非‘nil’なら、その関数はその回数 分の関数呼び出しによって‘beginning-of-defun’が行うように後方に移動 すること。 -- Variable: end-of-defun-function この変数は非‘nil’ならdefunの終端を見つける関数を保持する。関数 ‘end-of-defun’は、通常の手法を使うかわりにその関数を呼び出す。 29.2.7 文字のスキップ --------------------- 以下の2つの関数は指定された文字セットを超えてポイントを移動します。これ らの関数は、たとえば空白文字をスキップするためによく使用されます。関連す る関数については*note Motion and Syntax::を参照してください。 これらの関数は検索関数(*note Searching and Matching::を参照)が行うよ うに、そのバッファーがマルチバイト(multibyte)ならマルチバイトに、ユニバ イト(unibyte)ならユニバイトにその文字列セットを変換します。 -- Function: skip-chars-forward character-set &optional limit この関数は与えられた文字セットをスキップしてカレントバッファー内の ポイント前方に移動する。これはポイントの後の文字を調べて、その文字 がCHARACTER-SETにマッチすればポイントを進める。そしてマッチしない文 字に到達するまでこれを継続する。この関数は飛び超えて移動した文字数 をリターンする。 引数CHARACTER-SETは文字列であり正規表現での‘[...]’内部と同様だが、 ‘]’で終端されず‘\’が‘^’、‘-’、‘\’をクォートする点が異なる。つまり ‘"a-zA-Z"’はすべての英字をスキップして最初の非英字の前で停止、 ‘"^a-zA-Z"’はすべての非英字をスキップして最初の英字の前で停止する。 *note Regular Expressions::を参照のこと。‘"[:alnum:]"’のような文字 クラスも使用できる。*note Char Classes::を参照のこと。 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 ---------- -- Function: skip-chars-backward character-set &optional limit この関数はLIMITに至るまでCHARACTER-SETにマッチする文字をスキップし てポイントを後方に移動する。これは‘skip-chars-forward’と同様だがポ イントを移動する方向が異なる。 リターン値は移動した距離を示す。これは0以上の整数。 29.3 エクスカーション ===================== プログラム中の限定された部分でポイントを一時的に移動するのが便利なことが 時折あります。これは“エクスカーション(excursion: 遠足、小旅行)”と呼ばれ るもので、スペシャルフォーム‘save-excursion’により行われます。この構文は 初期のカレントバッファー自体とポイントの値を記憶して、そのエクスカーショ ン完了時にそれらをリストアします。これはプログラムのある部分においてプロ グラムの他の部分に影響を与えることなくポイントを移動する標準的な手段であ り、EmacsのLispソース内では何度も使用されています。 カレントバッファー自体のみの保存やリストアが必要なら、かわりに ‘save-current-buffer’や‘with-current-buffer’を使用してください(*note Current Buffer::を参照)。ウィンドウ構成の保存やリストアが必要なら、*note Window Configurations::と*note Frame Configurations::で説明されているフ ォームを参照してください。 -- Special Form: save-excursion body... このスペシャルフォームはカレントバッファー自体とポイント値を保存、 BODYを評価してから最後にバッファーと保存したポイントとマークの値を リストアする。‘throw’やエラーを通じたアブノーマルexit(*note Nonlocal Exits::を参照)の場合にも、保存されたいずれの値もリストアさ れる。 ‘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’のマーカーです。*note Marker Insertion Types::を参照してください。したがって保存されたポイント 値は、リストア時には通常は挿入されたテキストの直前になります。 -- Macro: save-mark-and-excursion body... このマクロは‘save-excursion’と同様だが、マークの位置と ‘mark-active’の保存とリストアも行う点が異なる。このマクロはEmacsの バージョン25.1以前に‘save-excursion’が行っていたことを行う。 29.4 ナローイング ================= “ナローイング(narrowing)”とはEmacs編集コマンドがアドレス指定可能なテキス トを、あるバッファー内の制限された文字範囲に限定することを意味します。ア ドレス可能なテキストは、そのバッファーの“アクセス可能範囲(accessible portion)”と呼ばれます。 ナローイングは2つのバッファー位置により指定されるもので、それらの位置 がアクセス可能範囲の開始と終了になります。ほとんどの編集コマンドやプリミ ティブにたいして、これらの位置はそれぞれそのバッファーの先頭と終端に置き 換えられます。ナローイングが効果をもつ間にはアクセス可能範囲外のテキスト は表示されず、その外部にポイントを移動することはできません。ナローイング は実際のバッファー位置(*note Point::を参照)を変更しないことに注意してく ださい。ほとんどの関数はアクセス可能範囲外のテキストにたいする操作を受け 入れません。 バッファーを保存するコマンドはナローイングの影響を受けません。どんな ナローイングであろうと、それらはバッファー全体を保存します。 単一バッファー内にタイプが大きく異なるテキストを複数表示する必要があ る場合には、*note Swapping Text::で説明する代替機能の使用を考慮してくだ さい。 -- Command: narrow-to-region start end この関数はアクセス可能範囲の開始と終了にカレントバッファーのSTARTと ENDをセットする。どちらの引数も文字位置で指定すること。 インタラクティブな呼び出しでは、STARTとENDはカレントリージョンにセ ットされる(ポイントとマークで小さいほうが前者)。 -- Command: narrow-to-page &optional move-count この関数はカレントページだけを含むようにカレントバッファーのアクセ ス可能範囲をセットする。1つ目のオプション引数MOVE-COUNTが非‘nil’な ら、MOVE-COUNTで前方か後方へ移動後に1ページにナローすることを意味す る。変数‘page-delimiter’はページの開始と終了の位置を指定する(*note Standard Regexps::を参照)。 インタラクティブな呼び出しではMOVE-COUNTには数プレフィクス引数がセ ットされる。 -- Command: widen この関数はカレントバッファーにたいするすべてのナローイングをキャン セルする。これは“ワイドニング(widening)”と呼ばれる。これは以下の式 と等価: (narrow-to-region 1 (1+ (buffer-size))) -- Function: buffer-narrowed-p この関数はそのバッファーがナローされていれば非‘nil’、それ以外は ‘nil’をリターンする。 -- Special Form: save-restriction body... このスペシャルフォームはアクセス可能範囲のカレントのバインドを保存 してBODYを評価、その後に以前有効だったナローイング(またはナローイン グがない状態)と同じ状態になるように、最後に保存された境界をリストア する。ナローイングの状態は、‘throw’やエラーを通じたアブノーマル exit(*note Nonlocal Exits::を参照)イベント内においてもリストアされ る。したがってこの構文は一時的にバッファーをナローする明快な手段で ある。 ‘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 ---------- 30 マーカー *********** “マーカー(marker)”とは、あるバッファー内で取り囲んでいるテキストにたいし て相対的な位置を指定するために使用されるオブジェクトです。テキストが挿入 や削除される際には、常にマーカーは自動的にそのバッファーの先頭からのオフ セットを自動的に変更して自身の左右にある文字の間に留まります。 30.1 マーカーの概要 =================== マーカーはバッファーとそのバッファー内の位置を指定します。マーカーは位置 を要求する関数内において、整数と同じように位置を表すために使用することが できます。その場合には、そのマーカーのバッファーは通常は無視されます。こ の方法で使用されるマーカーは、通常はその関数が処理するバッファー内の位置 を指しますが、それは完全にプログラマーの責任です。位置についての完全な説 明は*note Positions::を参照してください。 マーカーはマーカー位置(marker position)、マーカーバッファー(marker buffer)、挿入タイプ(insertion type)という3つの属性をもちます。マーカー位 置はそのバッファー内の位置としてのマーカーと(その時点において)等しい整数 です。しかしマーカー位置はマーカーの生存期間中に変化し得るものであり頻繁 に変更されます。バッファー内でのテキストの挿入や削除によってマーカーは再 配置されます。マーカー前後の2文字以外の場所で挿入や削除がおこなわれても 、マーカー位置はその2文字間に留まるというのがこのアイデアです。再配置に よってマーカーと等価な整数は変更されます。 マーカー位置周辺のテキストを削除することにより、そのマーカーは削除さ れたテキストの直前と直後にある文字の間に残されます。マーカー位置へのテキ スト挿入では、マーカーは通常は新たなテキストの前か後のいずれかに配置され ます。その挿入が‘insert-before-markers’ (*note Insertion::を参照)で行わ れたものでなければ、どちらに配置されるかはマーカーの“挿入タイプ”(*note Marker Insertion Types::を参照)に依存します。 バッファーでの挿入と削除では、すべてのマーカーをチェックして必要なら それらを再配置しなければなりません。これは多数のマーカーをもつバッファー での処理を低速にします。この理由によりそれ以上マーカーが不必要なことが確 信できるなら、存在しない場所を指さないようにマーカーを設定することはよい アイデアといえるでしょう。それ以上アクセスされる可能性がないマーカーは最 終的には削除されます(*note Garbage Collection::を参照)。 マーカー位置にたいして算術演算を行うことは一般的なので、それらの演算 子のほとんど(‘+’や‘-’を含む)が引数としてマーカーに渡すことができます。そ のような場合でのマーカーはカレント位置を意味します。 以下ではマーカーの作成とセットを行ってポイントをマーカーに移動してい ます: ;; 最初はどこも指さない新たなマーカーを作成: (setq m1 (make-marker)) ⇒ # ;; カレントバッファーの99と100番目の ;; 文字間を指すよう‘m1’をセット: (set-marker m1 100) ⇒ # ;; ここでバッファー先頭に1文字挿入: (goto-char (point-min)) ⇒ 1 (insert "Q") ⇒ nil ;; ‘m1’は適切に更新された m1 ⇒ # ;; 同じ位置を指す2つのマーカーは ;; ‘equal’だが‘eq’に非ず (setq m2 (copy-marker m1)) ⇒ # (eq m1 m2) ⇒ nil (equal m1 m2) ⇒ t ;; マーカー使用終了時、存在しない場所を指すようセット (set-marker m1 nil) ⇒ # 30.2 マーカーのための述語 ========================= あるオブジェクトがマーカーなのか、それとも整数かマーカーのいずれかである かを確認するためのテストを行うことができます。後者のテストはマーカーと整 数の両方にたいして機能する算術関数において有用です。 -- Function: markerp object この関数はOBJECTがマーカーなら‘nil’、それ以外は‘t’をリターンする。 多くの関数はマーカーか整数のいずれかを受け入れるだろうが、整数はマ ーカーとは異なることに注意。 -- Function: integer-or-marker-p object この関数はOBJECTが整数かマーカーなら‘t’、それ以外は‘nil’をリターン する。 -- Function: number-or-marker-p object この関数はOBJECTが数値(整数か浮動小数点数)またはマーカーなら‘t’、そ れ以外は‘nil’をリターンする。 30.3 マーカーを作成する関数 =========================== マーカーを新たに作成する際には存在しない場所、ポイントの現在位置、バッフ ァーのアクセス可能範囲の先頭や終端、または別の与えられたマーカーと同じ箇 所を指すようにすることができます。 以下の4つの関数はすべて挿入タイプ‘nil’のマーカーをリターンします。 *note Marker Insertion Types::を参照してください。 -- Function: make-marker この関数はどこも指さないマーカーを新たに作成してリターンする。 (make-marker) ⇒ # -- Function: point-marker この関数はカレントバッファーのポイント現在位置を指すマーカーを新た に作成してリターンする。*note Point::を参照のこと。例は以下の ‘copy-marker’を参照のこと。 -- Function: point-min-marker この関数はバッファーのアクセス可能範囲の先頭を指すマーカーを新たに 作成してリターンする。ナローイングが効力をもたなければ、これはバッ ファーの先頭になるだろう。*note Narrowing::を参照のこと。 -- Function: point-max-marker この関数はバッファーのアクセス可能範囲の終端を指すマーカーを新たに 作成してリターンする。ナローイングが効力をもたなければ、これはバッ ファーの終端になるだろう。*note Narrowing::を参照のこと。 以下はこのチャプターのテキストのソースファイルのバージョンを含むバ ッファーにたいして、この関数と‘point-min-marker’を使用する例。 (point-min-marker) ⇒ # (point-max-marker) ⇒ # (narrow-to-region 100 200) ⇒ nil (point-min-marker) ⇒ # (point-max-marker) ⇒ # -- Function: copy-marker &optional marker-or-integer insertion-type 引数としてマーカーを渡されると、‘copy-marker’はMARKER-OR-INTEGERが 行うように同じバッファーの同じ位置を指すマーカーを新たに作成してリ ターンする。整数を渡されると、‘copy-marker’はカレントバッファーの位 置MARKER-OR-INTEGERを指すマーカーを新たに作成してリターンする。 新たなマーカーの挿入タイプは引数INSERTION-TYPEにより指定される。 *note Marker Insertion Types::を参照のこと。 (copy-marker 0) ⇒ # (copy-marker 90000) ⇒ # MARKERがマーカーと整数のいずれでもなければエラーがシグナルされる。 2つのマーカーはそれらが同じバッファーの同じ位置、またはどちらも存在し ない場所を指す場合には、(‘eq’ではないが)‘equal’とみなされます。 (setq p (point-marker)) ⇒ # (setq q (copy-marker p)) ⇒ # (eq p q) ⇒ nil (equal p q) ⇒ t 30.4 マーカーからの情報 ======================= このセクションではマーカーオブジェクトの構成要素にアクセスする関数を説明 します。 -- Function: marker-position marker この関数はMARKERが指す位置、存在しない場所なら‘nil’をリターンする。 -- Function: marker-buffer marker この関数はMARKERがその内部を指すバッファー、存在しない場所を指す場 合には‘nil’をリターンする。 (setq m (make-marker)) ⇒ # (marker-position m) ⇒ nil (marker-buffer m) ⇒ nil (set-marker m 3770 (current-buffer)) ⇒ # (marker-buffer m) ⇒ # (marker-position m) ⇒ 3770 30.5 Marker 挿入タイプ ====================== マーカーが指す位置に直接テキストを挿入する際には、そのマーカーを再配置す るために利用可能な手段が2つあります。そのマーカーは挿入されたテキストの 前か後を指すことができます。マーカーの“挿入タイプ(insertion type)”を指定 することにより、マーカーがどちらを行うか指定できます。 ‘insert-before-markers’を使用する場合には、マーカーの挿入タイプを無視し て常にマーカーが挿入されたテキストの後を指すよう再配置されることに注意し てください。 -- Function: set-marker-insertion-type marker type この関数はマーカーMARKERの挿入タイプをTYPEにセットする。TYPEが‘t’な ら、テキスト挿入時にMARKERはその位置まで進められるだろう。TYPEが ‘nil’なら、テキスト挿入時にMARKERはそこまで進められることはない。 -- Function: marker-insertion-type marker この関数はMARKERのカレント挿入タイプを報告する。 挿入タイプを指定するための引数を受け取らずにマーカーを作成するすべて の関数は、挿入タイプ‘nil’でマーカーを作成します。マークもデフォルトでは 挿入タイプ‘nil’をもちます。 30.6 マーカー位置の移動 ======================= このセクションでは既存マーカーの位置を変更する方法について説明します。こ れを行う際にはそのマーカーがあなたのプログラム外部に使用されているかどう か、もし使用されているならマーカーを移動した結果どのような影響が生じるか を確実に理解する必要があります。さもないとEmacsの他の部分で混乱した出来 事が発生するかもしれません。 -- Function: set-marker marker position &optional buffer この関数はBUFFER内でMARKERをPOSITIONに移動する。BUFFERが与えられな かった場合のデフォルトはカレントバッファー。 POSITIONが‘nil’、または存在しない場所を指すマーカーなら、MARKERは存 在しない場所を指すようにセットされる。 リターン値はMARKER。 (setq m (point-marker)) ⇒ # (set-marker m 55) ⇒ # (setq b (get-buffer "foo")) ⇒ # (set-marker m 0 b) ⇒ # -- Function: move-marker marker position &optional buffer これは‘set-marker’の別名。 30.7 マーク =========== バッファーはそれぞれ“マーク(mark)”というバッファー専用の特別なマーカーを もちます。バッファーが新たに作成される際には、このマーカーはすでに存在し ていますがどこも指していません。これはそのバッファーにはまだマークが存在 しないことを意味します。それ以降のコマンドがマークをセットできます。 マークは‘kill-region’や‘indent-rigidly’のような多くのコマンドにたいし てテキスト範囲をバインドするための位置を指定します。これらのコマンドは、 通常はポイントとマークの間の“リージョン(region)”と呼ばれるテキストに作用 します。リージョンを操作するコマンドを記述する場合にはマークを直接調べず 、かわりに‘r’指定とともに‘interactive’を使用してください。このようにすれ ばインタラクティブな呼び出しではコマンドの引数としてポイントとマークの値 が提供され、かつ他のLispプログラムは引数を明示的に指定できます。*note Interactive Codes::を参照してください。 いくつかのコマンドは副作用(side-effect)としてマークをセットします。コ マンドはユーザーがそれを使用する可能性がある場合のみマークをセットするべ きであって、決してコマンドの内部的な目的にたいして使用してはなりません。 たとえば‘replace-regexp’コマンドは何らかの置換を行う前にマークにポイント の値をセットしますが、その理由はこれによりユーザーが置換を終えた後に簡単 にその位置に戻ることが可能になるからです。 一度バッファー内にマークが存在すれば、その存在は通常は決して消えるこ とはありません。しかしTransient Markモードが有効だとマークが“非アクティ ブ(inactive)”になることはあります。バッファーローカル変数‘mark-active’が 非‘nil’なら、それはマークがアクティブであることを意味します。コマンドは マークを直接非アクティブにするために関数‘deactivate-mark’を呼び出すこと ができ、変数‘deactivate-mark’を非‘nil’値にセットすることにより、エディタ ーコマンドループ(editor command loop)にリターン時にマークの非アクティブ 化を要求できます。 Transient Markモードが有効だと、通常ならポイント近傍に適用される特定 の編集コマンドはマークがアクティブなときはかわりにリージョンに適用されま す。これがTransient Markモードを使用する主な動機です(他にもマークアクテ ィブ時にはリージョンのハイライトが有効になるという理由もある。*note Display::を参照)。 マークに加えてバッファーはそれぞれ“マークリング(mark ring)”をもってい ます。これは以前のマーク値を含むマーカーのリストです。編集コマンドがマー クを変更する際には、それらのコマンドは通常はマークの旧値をマークリングに 保存するべきです。変数‘mark-ring-max’はマークリング内のエントリー最大数 を指定します。リストがこの長さに達すると最後の要素を削除して新たな要素が 追加されます。 これとは別にグローバルマークリング(global mark ring)がありますが、そ れは少数の特定のユーザーレベルコマンドでのみ使用されて、Lispプログラムと は関連しないのでここでは説明しません。 -- Function: mark &optional force この関数はカレントバッファーのマーク位置を整数でリターンする。その バッファー内でそれまでマークがセットされていなければ‘nil’をリターン する。 Transient Markモードが有効、かつ‘mark-even-if-inactive’が‘nil’の場 合、マークが非アクティブなら‘mark’はエラーをシグナルする。しかし、 FORCEが非‘nil’なら、‘mark’はマークの非アクティブ性を無視して、何に せよマーク位置(か‘nil’)をリターンする。 -- Function: mark-marker この関数はカレントバッファーのマークを表すマーカーをリターンする。 これはコピーではなく内部的に使用されるマーカー。したがってこのマー カー位置にたいする変更は、そのバッファーのマークに直接影響する。そ れが望む効果でなければこれを行ってはならない。 (setq m (mark-marker)) ⇒ # (set-marker m 100) ⇒ # (mark-marker) ⇒ # 他のマーカー同じように、このマーカーを任意のバッファー位置にセット できる。このマーカーにたいして、これがマークする以外のバッファーを 指すようにすると、完全に整合性があるものの、いささか奇妙な結果を得 ることになるだろう。わたしたちはこれを行わないことを推奨する! -- Function: set-mark position この関数はマークを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))) -- Function: push-mark &optional position nomsg activate この関数はカレントバッファーのマークをPOSITIONにセットして、前のマ ークを‘mark-ring’にpushする。POSITIONが‘nil’ならポイントの値を使用 する。 関数‘push-mark’は通常はマークをアクティブに_しない_。アクティブにす る場合には引数ACTIVATEに‘t’を指定する。 NOMSGが‘nil’ならメッセージ‘Mark set’が表示される。 -- Function: pop-mark この関数は‘mark-ring’のトップ要素をpopして、そのマークをバッファー の実際のマークにする。これはバッファー内のポイントを移動せず、 ‘mark-ring’が空なら何も行わない。これはマークを非アクティブ化する。 -- User Option: transient-mark-mode この変数が非‘nil’ならTransient Markモードを有効にする。Transient Markモードでは、すべてのバッファー変更プリミティブが ‘deactivate-mark’をセットする。結果としてバッファーを変更するほとん どのコマンドもマークを非アクティブにする。 Transient Markモードが有効かつマークがアクティブなら、通常はポイン ト近傍に適用されるコマンドの多くは、かわりにリージョンに適用される 。そのようなコマンド、リージョンを処理すべきかどうかをテストするた めに、関数‘use-region-p’を使用すること。*note The Region::を参照の こと。 Lispプログラムは一時的にTransient Markモードを有効にするために、 ‘transient-mark-mode’を‘nil’でも‘t’でもない値にセットできる。値が ‘lambda’なら、通常ならマークを非アクティブ化するバッファー変更よう な操作の後に、Transient Markモードを自動的にオフに切り替える。値が ‘(only . OLDVAL)’なら後続のコマンドがポイントを移動かつシフト変換 (*note shift-translation: Key Sequence Input.を参照)されていない場 合、あるいは通常はマークを非アクティブにするその他の操作の場合にに 、‘transient-mark-mode’に値OLDVALをセットする。 -- User Option: mark-even-if-inactive これが非‘nil’なLispプログラムおよびEmacsユーザーは、たとえ非アクテ ィブでもマークを使用できる。このオプションはTransient Markモードの 動作に影響を及ぼす。このオプションが非‘nil’ならマークの非アクティブ 化によりリージョンのハイライトはオフに切り替えられるが、マークを使 用するコマンドは、あたかもマークがアクティブであるかのように振る舞 う。 -- Variable: deactivate-mark エディターコマンドがこの変数を非‘nil’にセットすると、エディターコマ ンドループはコマンドのリターン後に、(Transient Markモードが有効なら )マークを非アクティブにする。バッファーを変更するすべてのプリミティ ブは、コマンド終了時にマークを非アクティブにするために ‘deactivate-mark’をセットする。この変数はセットすらことによりバッフ ァーローカルになる。 コマンド終了時にマークを非アクティブにすることなくバッファーを変更 するLispコードを記述するためには、変更を行うコードの周辺で ‘deactivate-mark’を‘nil’にバインドすること。たとえば: (let (deactivate-mark) (insert " ")) -- Function: deactivate-mark &optional force Transient Markモードが有効、またはFORCEが非‘nil’なら、この関数はマ ークを非アクティブにしてノーマルフック‘deactivate-mark-hook’を実行 して、それ以外は何も行わない。 -- Variable: mark-active この変数が非‘nil’ならマークはアクティブ。この変数はそれぞれのバッフ ァーにたいして常にローカル。通常はポイント近傍を操作するコマンドが 、かわりにリージョンを操作すべきかどうかを判断するためにこの変数の 値を_使用してはならない_。その目的にたいしては関数‘use-region-p’を 使用すること(*note The Region::を参照)。 -- Variable: activate-mark-hook -- Variable: deactivate-mark-hook これらのノーマルフックはマークがアクティブや非アクティブになった際 に順次実行される。マークがアクティブかつリージョンが変更された可能 性があるなら、コマンドループの最後にフック‘activate-mark-hook’も実 行される。 -- Function: handle-shift-selection この関数はポイント移動コマンドのシフト選択(shift-selection)の動作を 実装する。*note (emacs)Shift Selection::を参照のこと。これは ‘interactive’指定に文字‘^’を含むコマンドの呼び出し時は常に、そのコ マンド自身を実行する前にEmacsコマンドループにより自動的に呼び出され る(*note ^: Interactive Codes.を参照)。 ‘shift-select-mode’が非‘nil’、かつカレントコマンドがシフト変換 (*note shift-translation: Key Sequence Input.を参照)を通じて呼び出 された場合には、この関数はマークをセットして一時的にリージョンをア クティブにする(すでにこの方法によりリージョンが一時的にアクティブに されている場合を除く)。それ以外ではリージョンが一時的にアクティブに されていればマークを非アクティブにして、変数‘transient-mark-mode’に 前の値をリストアする。 -- Variable: mark-ring このバッファーローカル変数の値は、もっとも最近のものが先頭となるよ うな、以前に保存されたカレントバッファーのマークのリスト。 mark-ring ⇒ (# # ...) -- User Option: mark-ring-max この変数の値は‘mark-ring’の最大サイズ。これより多くのマークが ‘mark-ring’にpushされると、‘push-mark’新たなマーク追加時には古いマ ークを破棄する。 Delete Selectionモード(*note Delete Selection: (emacs)Using Region.を 参照)が有効な際には、アクティブリージョン(いわゆる“選択”)を操作するコマ ンドは若干異なる振る舞いをします。これは‘pre-command-hook’に関数 ‘delete-selection-pre-hook’を追加することにより機能します(*note Command Overview::を参照)。この関数はそのコマンドにたいして適切なように選択を削 除するために‘delete-selection-helper’を呼び出します。コマンドをDelete Selectionモードに適応させたければ、その関数シンボルの ‘delete-selection’プロパティにputしてください(*note Symbol Plists::を参 照)。シンボルにこのプロパティをもたないコマンドは選択を削除しません。そ のコマンドに期待される挙動を調整するために、このプロパティはいくつかの値 のいずれかをもつことができます。詳細は‘delete-selection-pre-hook’と ‘delete-selection-helper’のドキュメント文字列を参照してください。 30.8 リージョン =============== ポイントとマークの間のテキストは、“リージョン(region)”という名で知られて います。さまざまな関数がポイントとマークで区切られたテキストを操作します が、ここではリージョンそのものに特に関連する関数だけを説明します。 以下の2つの関数はマークが何処も指していなければエラーをシグナルします 。Transient Markモードが有効、かつ‘mark-even-if-inactive’が‘nil’な、マー クが非アクティブな場合にエラーをシグナルします。 -- Function: region-beginning この関数はリージョンの先頭位置を、(整数として)リターンする。これは ポイントかマークのいずれか小さいほうの位置。 -- Function: region-end この関数はリージョンの終端位置を、(整数として)リターンする。これは ポイントかマークのいずれか大きいほうの位置。 リージョンにたいして操作を行うようにデザインされたコマンドがリージョ ンの先頭と終端を探すためには、‘region-beginning’や‘region-end’を使用する かわりに、通常は‘r’指定とともに‘interactive’を使用するべきです。これによ り他のLispプログラムが引数として明示的にリージョンの境界を指定できるよう になります。*note Interactive Codes::を参照してください。。 -- Function: use-region-p この関数はTransient Markモードが有効でマークがアクティブであり、か つバッファー内に有効なリージョンがあれば‘t’をリターンする。この関数 はマークアクティブ時にはポイント近傍のテキストのかわりにリージョン を操作するコマンドにより使用されることを意図している。 リージョンはそれが非0のサイズをもつか、あるいはユーザーオプション ‘use-empty-active-region’が非‘nil’ (デフォルトは‘nil’)なら有効。関 数‘region-active-p’は‘use-region-p’と同様だが、すべてのリージョンを 有効とみなす。リージョンが空ならポイントにたいして操作を行うほうが 適切な場合が多いために、ほとんどの場合は‘region-active-p’を使用する べきではない。 31 テキスト *********** このチャプターではバッファー内のテキストを扱う関数を説明します。ほとんど はカレントバッファー内のテキストにたいして検査、挿入、削除を行ってポイン ト位置やポイントに隣接するテキストを操作することが多々あります。その多く はインタラクティブ(interactive: 対話的)です。テキストを変更するすべての 関数は、その変更にたいするundo(アンドゥ、取り消し)を提供します(*note Undo::を参照)。 テキストに関連する関数の多くが、STARTとENDという名前の引数として渡さ れた2つのバッファー位置により定義されるテキストのリージョンを操作します 。これらの引数はマーカー(*note Markers::を参照)か数値的な文字位置(*note Positions::を参照)のいずれかであるべきです。これらの引数の順序は関係あり ません。STARTがリージョンの終端でENDがリージョンの先頭であっても問題はあ りません。たとえば‘(delete-region 1 10)’と‘(delete-region 10 1)’は等価で す。STARTとENDのいずれかがバッファーのアクセス可能範囲の外部なら ‘args-out-of-range’エラーがシグナルされます。インタラクティブな呼び出し では、これらの引数にポイントとマークが使用されます。 このチャプターを通じて、“テキスト(text)”とは(関係あるときは)そのプロ パティも含めたバッファー内の文字を意味します。ポイントは常に2つの文字の 間にあり、カーソルはポイントの後の文字上に表示されることを覚えておいてく ださい。 31.1 ポイント周辺のテキストを調べる =================================== ポイント付近にある文字を調べるための関数が数多く提供されています。簡単な 関数のいくつかはここで説明します。*note Regexp Search::の‘looking-at’も 参照してください。 以下の4つの関数でのバッファーの“先頭(beginning)”と“終端(end)”はそれぞ れ、アクセス可能範囲の先頭と終端を意味します。 -- Function: char-after &optional position この関数はカレントバッファーの位置POSITION (つまり直後)の文字をリタ ーンする。POSITIONがこの目的にたいする範囲の外にある場合、すなわち バッファーの先頭より前、またはバッファーの終端以降にあるなら値は ‘nil’。POSITIONのデフォルトはポイント。 以下の例ではバッファーの最初の文字が‘@’であると仮定する: (string (char-after 1)) ⇒ "@" -- Function: char-before &optional position この関数はカレントバッファーの位置POSITIONの直前の文字をリターンす る。POSITIONがこの目的にたいする範囲の外にある場合、すなわちバッフ ァーの先頭より前、またはバッファーの終端より後にあるなら値は‘nil’。 POSITIONのデフォルトはポイント。 -- Function: following-char この関数はカレントバッファーのポイントの後にある文字をリターンする 。これは‘(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" -- Function: preceding-char この関数はカレントバッファーのポイントの前の文字をリターンする。上 記‘following-char’の下の例を参照のこと。ポイントがバッファー先頭に あれば、‘preceding-char’は0をリターンする。 -- Function: bobp この関数はポイントがバッファー先頭にあれば‘t’をリターンする。ナロー イングが効力をもつなら、これはテキストのアクセス可能範囲の先頭を意 味する。*note Point::の‘point-min’も参照のこと。 -- Function: eobp この関数はポイントがバッファー終端にあれば‘t’をリターンする。ナロー イングが効力をもつなら、これはテキストのアクセス可能範囲の終端を意 味する。*note Point::の‘point-max’も参照のこと。 -- Function: bolp この関数はポイントが行の先頭にあれば‘t’をリターンする。*note Text Lines::を参照のこと。バッファー(またはアクセス可能範囲)の先頭は、常 に行の先頭とみなされる。 -- Function: eolp この関数はポイントが行の終端にあれば‘t’をリターンする。*note Text Lines::を参照のこと。バッファー(またはアクセス可能範囲)の終端は常に 行の先頭とみなされる。 31.2 バッファーのコンテンツを調べる =================================== このセクションではLispプログラムがバッファー内の任意の範囲にあるテキスト を文字列に変換するための関数を説明します。 -- Function: buffer-substring start end この関数はカレントバッファー内の位置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" コピーされるテキストが何らかのテキストプロパティをもっていたら、そ れらのプロパティが属する文字とともに文字列にコピーされる。しかしバ ッファー内のオーバーレイ(*note Overlays::を参照)、およびそれらのプ ロパティは無視されるためコピーされない。 たとえばFont-Lockモードが有効なら以下のような結果を得るだろう: (buffer-substring 1 10) ⇒ #("This is t" 0 1 (fontified t) 1 9 (fontified t)) -- Function: buffer-substring-no-properties start end これは‘buffer-substring’と同様だが、テキストプロパティはコピーせず に文字自体だけをコピーする点が異なる。*note Text Properties::を参照 のこと。 -- Function: buffer-string この関数はカレントバッファーのアクセス可能範囲全体のコンテンツを文 字列としてリターンする。 異なる場所からのコピー時に双方向テキストの再配置によって結果の文字列 の視覚的外見が変更されないように保証する必要があるなら、 ‘buffer-substring-with-bidi-context’関数を使用すること(*note buffer-substring-with-bidi-context: Bidirectional Display.を参照)。 -- Function: filter-buffer-substring start end &optional delete この関数は変数‘filter-buffer-substring-function’により指定された関 数を使用して、STARTとENDの間のバッファーテキストをフィルターしてそ の結果をリターンする。 デフォルトのフィルター関数は時代遅れとなったラッパーフック ‘filter-buffer-substring-functions’、および同様に時代遅れとなった変 数‘buffer-substring-filters’を参照する。これらがいずれも‘nil’ならバ ッファーから未変更のテキスト、すなわち‘buffer-substring’がリターン するであろうテキストをリターンする。 DELETEが非‘nil’なら、この関数は‘delete-and-extract-region’と同じよ うに、コピー後にSTARTとENDの間のテキストを削除する。 Lispコードはkillリング、Xクリップボード、レジスターのようなユーザー がアクセス可能なデータ構造内にコピーする際には‘buffer-substring’、 ‘buffer-substring-no-properties’、‘delete-and-extract-region’のかわ りにこの関数を使用すること。メジャーモードとマイナーモードはバッフ ァー外部にコピーするテキストを変更するために ‘filter-buffer-substring-function’を変更することができる。 -- Variable: filter-buffer-substring-function この変数の値は実際の処理を行うために‘filter-buffer-substring’が呼び 出す関数。その関数は‘filter-buffer-substring’と同じように3つの引数 を受けとり、それらは‘filter-buffer-substring’にドキュメントされてい るように扱うこと。関数はフィルターされたテキストをリターン(およびオ プションでソーステキストを削除)すること。 以下の2つの変数は‘filter-buffer-substring-function’により時代遅れになり ましたが、後方互換のために依然としてサポートされます。 -- Variable: filter-buffer-substring-functions これは時代遅れとなったラッパーフックであり、このフックのメンバーは FUN、START、END、DELETEの4つの引数を受け取る関数であること。FUNは 3つの引数(START、END、DELETE)を受け取り、文字列をリターンする関数。 いずれも引数START、END、DELETEは‘filter-buffer-substring’のときと同 様の意味をもつ。 1つ目のフック関数は‘filter-buffer-substring’のデフォルトの処理と同 じくSTARTとENDの間の(任意の‘buffer-substring-filters’により処理され た)バッファー部分文字列をリターン、オプションでバッファーから元テキ ストを削除する関数であり、それがFUNに渡される。ほとんどの場合にはフ ック関数はFUNを1回だけ呼び出してから、その結果にたいして自身の処理 を行う。次のフック関数はこれと等しいFUNを受け取って、それが順次繰り 返されていく。実際のリターン値はすべてのフック関数が順次処理した結 果。 -- Variable: buffer-substring-filters 時代遅れとなったこの変数の値は、文字列を唯一の引数ちして別の文字列 をリターンする関数のリストであること。デフォルトの ‘filter-buffer-substring’関数は、バッファー部分文字列をこのリストの 1つ目の関数に渡して、そのリターン値を次の関数に渡して、これがそれぞ れの関数にたいして順次繰り返される。最後の関数のリターン値は ‘filter-buffer-substring-functions’に渡される。 -- Function: current-word &optional strict really-word この関数はポイント位置またはその付近のシンボル(または単語)を文字列 としてリターンする。リターン値にテキストプロパティは含まれない。 オプション引数REALLY-WORDが非‘nil’なら単語、それ以外はシンボル(単語 文字とシンボル構成文字の両方を含む)を探す。 オプション引数STRICTが非‘nil’のならポイントは単語(またはシンボル)の 内部にあるか隣接しなければならない。そこに単語(またはシンボル)がな ければ、この関数は‘nil’をリターンする。STRICTが‘nil’ならポイントと 同一行にある近接する単語(またはシンボル)を許容する。 -- Function: thing-at-point thing &optional no-properties ポイントに隣接または周辺にあるTHINGを文字列としてリターンする。 引数THINGは構文エンティティの種別を指定するシンボルである。可能なシ ンボルとしては‘symbol’、‘list’、‘sexp’、‘defun’、‘filename’、 ‘url’、‘word’、‘sentence’、‘whitespace’、‘line’、‘page’、および他が 含まれる。 オプション引数NO-PROPERTIESは非‘nil’なら、この関数はリターン値から テキストプロパティを取り除く。 ---------- Buffer: foo ---------- Gentlemen may cry ``Pea★ce! Peace!,'' but there is no peace. ---------- Buffer: foo ---------- (thing-at-point 'word) ⇒ "Peace" (thing-at-point 'line) ⇒ "Gentlemen may cry ``Peace! Peace!,''\n" (thing-at-point 'whitespace) ⇒ nil 31.3 テキストの比較 =================== 以下の関数により最初にバッファー内のテキストを文字列内にコピーすることな く、バッファー内のテキスト断片を比較することが可能になります。 -- Function: compare-buffer-substrings buffer1 start1 end1 buffer2 start2 end2 この関数により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 31.4 テキストの挿入 =================== “挿入(insertion)”とはバッファーへの新たなテキストの追加を意味します。テ キストはポイント位置、すなわちポイント前の文字とポイント後の文字の間に追 加されます。挿入関数は挿入されたテキストの後にポイントを残しますが、前に ポイントを残す関数もいくつかあります。前者の挿入を“ポイント後挿入(after point)”、後者を“ポイント前挿入(before point)”と呼びます。 挿入により挿入位置の後にあったマーカーは、テキストを取り囲むように移 動されます(*note Markers::を参照)。マーカーが挿入箇所をさしている際には 、挿入によるマーカーの再配置の有無はそのマーカーの挿入タイプに依存します (*note Marker Insertion Types::を参照)。‘insert-before-markers’のような 特定のスペシャル関数は、マーカーの挿入タイプとは関係なく挿入されたテキス トの後にそのようなすべてのマーカーを再配置します。 カレントバッファーが読み取り専用(*note Read Only Buffers::を参照)、ま たは読み取り専用テキスト(*note Special Properties::を参照)を挿入しようと すると、挿入関数はエラーをシグナルします。 以下の関数は文字列やバッファーからプロパティとともにテキスト文字をコ ピーします。挿入される文字はコピー元の文字と完全に同一のプロパティをもち ます。それとは対照的に文字列やバッファーの一部ではない個別の引数として指 定された文字は、隣接するテキストからテキストプロパティを継承します。 テキストが文字列かバッファー由来なら、マルチバイトバッファーに挿入す るために挿入関数はユニバイトからマルチバイトへの変換、およびその逆も行い ます。しかしたとえカレントバッファーがマルチバイトバッファーであったとし ても、コード128から255までのユニバイトはマルチバイトに変換しません。 *note Converting Representations::を参照してください。 -- Function: insert &rest args この関数は文字列および/または1つ以上の文字ARGSをカレントバッファー のポイント位置に挿入して、ポイントを前方に移動する。言い換えるとポ イントの前にテキストを挿入する。すべてのARGSが文字列が文字列と文字 のいずれでもなければエラーをシグナルする。値は‘nil’。 -- Function: insert-before-markers &rest args この関数は文字列および/または1つ以上の文字ARGSをカレントバッファー のポイント位置に挿入して、ポイントを前方に移動する。すべてのARGSが 文字列が文字列と文字のいずれでもなければエラーをシグナルする。値は ‘nil’。 この関数は他の挿入関数と異なり、挿入されたテキストの後を指すように 、まずマーカーが挿入位置を指すよう再配置する。挿入位置からオーバー レイが開始される場合には、挿入されたテキストはそのオーバーレイの外 側に出される。空でないオーバーレイが挿入位置で終わる場合には、挿入 されたテキストはそのオーバーレイの内側に入れられる。 -- Command: insert-char character &optional count inherit このコマンドはカレントバッファーのポイントの前に、CHARACTERのインス タンスをCOUNT個挿入する。引数COUNTは整数、CHARACTERは文字でなければ ならない。 インタラクティブに呼び出された際には、このコマンドはCHARACTERにたい してコードポイントかUnicode名による入力を求める。*note (emacs)Inserting Text::を参照のこと。 この関数はたとえカレントバッファーがマルチバイトバッファーであって も、コード128から255のユニバイト文字をマルチバイト文字に変換しない 。*note Converting Representations::を参照のこと。 INHERITが非‘nil’なら、挿入された文字は挿入位置前後の2文字からステッ キーテキストプロパティ(sticky text properties)を継承する。*note Sticky Properties::を参照のこと。 -- Function: insert-buffer-substring from-buffer-or-name &optional start end この関数はカレントバッファーのポイント前に、バッファー FROM-BUFFER-OR-NAMEの一部を挿入する。挿入されるテキストはSTART (を 含む)からEND (を含まない)の間のリージョン(これらの引数のデフォルト は、そのバッファーのアクセス可能範囲の先頭と終端)。この関数は ‘nil’をリターンする。 以下の例ではバッファー‘bar’をカレントバッファーとしてフォームを実行 する。バッファー‘bar’は最初は空であるものとする。 ---------- Buffer: foo ---------- We hold these truths to be self-evident, that all ---------- Buffer: foo ---------- (insert-buffer-substring "foo" 1 20) ⇒ nil ---------- Buffer: bar ---------- We hold these truth★ ---------- Buffer: bar ---------- -- Function: insert-buffer-substring-no-properties from-buffer-or-name &optional start end これは‘insert-buffer-substring’と似ているが、テキストプロパティをコ ピーしない点が異なる。 テキスト挿入に加えて、隣接するテキストからテキストプロパティを継承す る他の関数については*note Sticky Properties::を参照のこと。インデント関 数により挿入された空白文字もテキストプロパティを継承する。 31.5 ユーザーレベルの挿入コマンド ================================= このセクションではテキスト挿入のための高レベルコマンド、ユーザーによる使 用を意図しているがLispプログラムでも有用なコマンドについて説明します。 -- Command: insert-buffer from-buffer-or-name このコマンドはFROM-BUFFER-OR-NAME (存在しなければならない)のアクセ ス可能範囲全体をカレントバッファーのポイントの後に挿入する。マーク は挿入されたテキストの後に残される。値は‘nil’。 -- Command: self-insert-command count このコマンドはタイプされた最後の文字を挿入する。これをポイント前で COUNT回繰り返して‘nil’をリターンする。ほとんどのプリント文字はこの コマンドにバインドされる。通常の使用では‘self-insert-command’は Emacsでもっとも頻繁に呼び出される関数だが、Lispプログラムではそれを キーマップにインストールする場合を除いて使用されるのは稀。 インタラクティブな呼び出しではCOUNTは数プレフィクス引数。 自己挿入では入力文字は‘translation-table-for-input’を通じて変換され る。*note Translation of Characters::を参照のこと。 これは、入力文字がテーブル‘auto-fill-chars’内にあり、 ‘auto-fill-function’が非‘nil’なら常にそれを呼び出す(*note Auto Filling::を参照)。 このコマンドはAbbrevモードが有効で、かつ入力文字が単語構成構文をも たなければabbrev展開を行う(*note Abbrevs::と*note Syntax Class Table::を参照)。さらに入力文字が閉カッコ構文(close parenthesis syntax)をもつ場合には‘blink-paren-function’を呼び出す責任もある (*note Blinking::を参照)。 このコマンドは最後にフック‘post-self-insert-hook’を実行する。たとえ ばタイプされたテキストにしたがい自動インデントするためにこれを使用 できる。 ‘self-insert-command’の標準的な定義にたいして、独自の定義による置き 換えを試みてはならない。エディターコマンドループはこのコマンドを特 別に扱うからだ。 -- Command: newline &optional number-of-newlines このコマンドはカレントバッファーのポイントの前に改行を挿入する。 NUMBER-OF-NEWLINESが与えられたら、その個数の改行文字が挿入される。 この関数はカレント列数が‘fill-column’より大、かつ NUMBER-OF-NEWLINESが‘nil’なら‘auto-fill-function’を呼び出す。 ‘auto-fill-function’が通常行うのは改行の挿入であり、最終的な結果と してはポイント位置と、その行のより前方の位置という2つの異なる箇所に 改行を挿入する。NUMBER-OF-NEWLINESが非‘nil’なら‘newline’は auto-fillを行わない。 このコマンドは左マージンが0でなければ、左マージンにインデントする。 *note Margins::を参照のこと。 リターン値は‘nil’。インタラクティブな呼び出しではCOUNTは数プレフィ クス引数。 -- Variable: overwrite-mode この変数はoverwriteモードが効力をもつかどうかを制御する。値は ‘overwrite-mode-textual’、‘overwrite-mode-binary’、または‘nil’。 ‘overwrite-mode-textual’はテキスト的なoverwriteモード(改行とタブを 特別に扱う)、‘overwrite-mode-binary’はバイナリーoverwriteモード(改 行とタブを普通の文字と同様に扱う)を指定する。 31.6 テキストの削除 =================== 削除とはバッファー内のテキストの一部をkillリングに保存せずに取り除くこと を意味します(*note The Kill Ring::を参照)。削除されたテキストをyankする ことはできませんが、undoメカニズム(*note Undo::を参照)を使用すれば再挿入 が可能です。特別なケースにおいてはkillリングにテキストの保存を行う削除関 数がいくつかあります。 削除関数はすべてカレントバッファーにたいして処理を行います。 -- Command: erase-buffer この関数はカレントバッファーのテキスト全体(アクセス可能範囲だけでは _ない_)を削除してバッファーが読み取り専用なら‘buffer-read-only’、バ ッファー内の一部テキストが読み取り専用なら‘text-read-only’をシグナ ルする。それ以外では確認なしでテキストを削除する。リターン値は ‘nil’。 バッファーからの大量テキストの削除では、バッファーが大幅に縮小され たという理由により、通常はさらなる自動保存が抑制される。しかし ‘erase-buffer’は将来のテキストが以前のテキストと関連があるのは稀で あり、以前のテキストのサイズと比較されるべきではないというアイデア にもとづいてこれを行わない。 -- Command: delete-region start end このコマンドはカレントバッファー内の位置STARTからENDまでの間のテキ ストを削除して‘nil’をリターンする。削除されるリージョン内にポイント があれば、リージョン削除後のポイントの値はSTART。それ以外の場合は、 マーカーが行うようにポイントはテキストを取り囲むように再配置される 。 -- Function: delete-and-extract-region start end この関数はカレントバッファー内の位置STARTからENDまでの間のテキスト を削除して、削除されたテキストを含む文字列をリターンする。 削除されるリージョン内にポイントがあれば、リージョン削除後のポイン トの値はSTART。それ以外ならマーカーが行うようにポイントはテキストを 取り囲むように再配置される。 -- Command: delete-char count &optional killp このコマンドはポイント直後のCOUNT文字、COUNTが負なら直前のCOUNT文字 を削除する。KILLPが非‘nil’なら削除した文字をkillリングに保存する。 インタラクティブな呼び出しでは、COUNTは数プレフィクス引数、KILLPは 未処理プレフィクス引数(unprocessed prefix argument)。すなわちプレフ ィクス引数が与えられたらそのテキストはkillリングに保存され、与えら れなければ1文字が削除されて、それはkillリングに保存されない。 リターン値は常に‘nil’。 -- Command: delete-backward-char count &optional killp このコマンドはポイント直前のCOUNT文字、COUNTが負なら直後のCOUNT文字 を削除する。KILLPが非‘nil’なら、削除した文字をkillリングに保存する 。 インタラクティブな呼び出しでは、COUNTは数プレフィクス引数、KILLPは 未処理プレフィクス引数(unprocessed prefix argument)。すなわちプレフ ィクス引数が与えられたらそのテキストはkillリングに保存され、与えら れなければ1文字が削除されて、それはkillリングに保存されない。 リターン値は常に‘nil’。 -- Command: backward-delete-char-untabify count &optional killp このコマンドはタブをスペースに変換しながら、後方にCOUNT文字を削除す る。次に削除する文字がタブなら、まず適正な位置を保つような数のスペ ースに変換してから、それらのうちのスペース1つをタブのかわりに削除す る。KILLPが非‘nil’なら、このコマンドは削除した文字をkillリングに保 存する。 タブからスペースへの変換はCOUNTが正の場合のみ発生する。負の場合はポ イント後の正確に−COUNT文字が削除される。 インタラクティブな呼び出しでは、COUNTは数プレフィクス引数、KILLPは 未処理プレフィクス引数(unprocessed prefix argument)。すなわちプレフ ィクス引数が与えられたらそのテキストはkillリングに保存され、与えら れなければ1文字が削除されて、それはkillリングに保存されない。 リターン値は常に‘nil’。 -- User Option: backward-delete-char-untabify-method このオプションは‘backward-delete-char-untabify’が空白文字を扱う方法 を指定する。可能な値には‘untabify’ (タブを個数分のスペースに変換し てスペースを1つ削除。これがデフォルト)、‘hungry’ (1コマンドでポイン ト前のタブとスペースすべてを削除する)、‘all’ (ポイント前のタブとス ペース、および改行すべてを削除する)、‘nil’ (空白文字にたいして特に 何もしない)。 31.7 ユーザーレベルの削除コマンド ================================= このセクションでは、主にユーザーにたいして有用ですがLispプログラムでも有 用なテキストを削除するための高レベルのコマンドを説明します。 -- Command: delete-horizontal-space &optional backward-only この関数はポイント近辺のすべてのスペースとタブを削除する。リターン 値は‘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 ---------- -- Command: delete-indentation &optional join-following-p この関数はポイントのある行をその前の行に結合(join)する。結合におい てはすべての空白文字を削除、特定のケースにおいてはそれらを1つのスペ ースに置き換える。JOIN-FOLLOWING-Pが非‘nil’なら、 ‘delete-indentation’はかわりに後続行と結合を行う。この関数は‘nil’を リターンする。 fillプレフィクスがあり、結合される2つ目の行もそのプレフィクスで始ま る場合には、行の結合前に‘delete-indentation’はそのfillプレフィクス を削除する。*note Margins::を参照のこと。 以下の例では‘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’の責任である。 -- Command: fixup-whitespace この関数はポイントを取り囲むすべての水平スペースを、コンテキストに 応じて1つのスペースまたはスペースなしに置き換える。リターン値は ‘nil’。 行の先頭や末尾において、スペースの適正な数は0。閉カッコ構文(close parenthesis syntax)の前の文字、開カッコの後の文字、式プレフィクス構 文(expression-prefix syntax)においても、スペースの適正な数は0。それ 以外ではスペースの適正な数は1。*note Syntax Class Table::を参照のこ と。 以下の例では最初に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 ---------- -- Command: just-one-space &optional n このコマンドはポイントを取り囲むすべてのスペースを1つのスペース、 Nが指定された場合はN個のスペースで置き換える。リターン値は‘nil’。 -- Command: delete-blank-lines この関数はポイントを取り囲む空行を削除する。ポイントが前後に1行以上 の空行がある空の行にある場合には、1行を除いてそれらすべてを削除する 。ポイントが孤立した空行にあればその行を削除する。ポイントが空でな い行にあれば、その直後にあるすべての空白を削除する。 空行とはタブまたはスペースのみを含む行として定義される。 ‘delete-blank-lines’は‘nil’をリターンする。 -- Command: delete-trailing-whitespace &optional start end STARTとENDで定義されるリージョン内から末尾の空白文字を削除する。 このコマンドはリージョン内の各行の最後の非空白文字後にある空白文字 を削除する。 このコマンドがバッファー全体(マークが非アクティブな状態で呼び出され た場合やLispからENDと‘nil’で呼び出された場合)にたいして動作する場合 には、変数‘delete-trailing-lines’が非‘nil’ならバッファーの終端行の 末尾の行も削除する。 31.8 killリング =============== “kill関数(kill functions)”は削除関数のようにテキストを削除しますが、ユー ザーが“yank”により再挿入できるようにそれらを保存する点が異なります。これ らの関数のほとんどは‘kill-’という名前をもちます。対照的に名前が ‘delete-’で始まる関数は、(たとえ削除をundoできるとしても)通常はyank用に テキストを保存しません。それらは削除(deletion)関数です。 ほとんどのkillコマンドは主にインタラクティブな使用を意図しており、こ こでは説明しません。ここで説明するのは、そのようなコマンドの記述に使用さ れるために提供される関数です。テキストをkillするために、これらの関数を使 用できます。Lisp関数の内部的な目的のためにテキストの削除を要するときは、 killリング内のコンテンツに影響を与えないように通常は削除関数を使用するべ きでしょう。*note Deletion::を参照してください。 killされたテキストは後のyank用に“killリング(kill ring)”内に保存されま す。これは直前のkillだけでなく直近のkillのいくつかを保持するリストです。 yankがそれをサイクル順に要素をもつリストとして扱うので、これを“リング (ring)”と称しています。このリストは変数‘kill-ring’に保持されており、リス ト用の通常関数で操作可能です。このセクションで説明する、これをリングとし て扱うために特化された関数も存在します。 特にkillされた実体が_破壊_されてしまわないような操作を参照するという 理由から、“kill”という単語の使用が不適切だと考える人もいます。これは通常 の生活において死は永遠であり、killされた実体は生活に戻ることはないことと 対照的です。したがって他の比喩表現も提案されてきました。たとえば、“cutリ ング(cut ring)”という用語は、コンピューター誕生前に原稿を再配置するため にハサミで切り取って貼り付けていたような人に意味があるでしょう。しかし今 となってはこの用語を変更するのは困難です。 31.8.1 killリングの概念 ----------------------- 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)させます。しかしこの仮想的回転はリ スト自身を変更しません。もっとも最近のエントリーが、常にリスト内の最初に 配置されます。 31.8.2 killリングのための関数 ----------------------------- ‘kill-region’はテキストkill用の通常サブルーチンです。この関数を呼び出す すべてのコマンドはkillコマンドです(そして恐らくは名前に‘kill’が含まれる )。‘kill-region’は新たにkillされたテキストをkillリング内の最初の要素内に 置くか、それをもっとも最近の要素に追加します。これは前のコマンドがkillコ マンドか否かを、(‘last-command’を使用して)自動的に判別して、もしkillコマ ンドならkillされたテキストをもっとも最近のエントリーに追加します。 以下で説明するコマンドはkillされるテキストがkillリングに保存される前 に、それらをフィルターできます。これらの関数は、このフィルタリングを行う ために‘filter-buffer-substring’を呼び出します(*note Buffer Contents::を 参照)。デフォルトではこれらはフィルタリングを行いませんが、バッファーに あったときと異なるようにテキストをkillリングに保存するために、マイナーモ ードとフック関数はフィルタリングをセットアップできます。 -- Command: kill-region start end &optional region この関数はSTARTとENDの間のテキスト範囲をkillするが、オプション引数 REGIONが非‘nil’なら、かわりにカレントリージョンのテキストをkillする 。そのテキストは削除されるが、そのテキストプロパティと共にkillリン グに保存される。値は常に‘nil’。 インタラクティブな呼び出しではSTARTとENDはポイントとマークで REGIONは常に非‘nil’なので、このコマンドは常にカレントリージョン内の テキストをkillする。 バッファーまたはテキストが読み取り専用なら、‘kill-region’は同じよう にkillリングを変更後に、バッファーを変更せずにエラーをシグナルする 。これはユーザーが一連のkillコマンドで、読み取り専用バッファーから killリングにテキストをコピーするのに有用。 -- User Option: kill-read-only-ok このオプションが非‘nil’なら、バッファーやテキストが読み取り専用でも ‘kill-region’はエラーをシグナルしない。かわりにバッファーを変更せず にkillリングを更新して単にリターンする。 -- Command: copy-region-as-kill start end &optional region この関数はSTARTとENDの間のテキスト範囲(テキストプロパティを含む)を killリングに保存するが、バッファーからそのテキストを削除しない。し かしオプション引数REGIONが非‘nil’なら、この関数はSTARTとENDを無視し て、かわりにカレントリージョンを保存する。この関数は常に‘nil’をリタ ーンする。 インタラクティブな呼び出しではSTARTとENDはポイントとマークで REGIONは常に非‘nil’なので、このコマンドは常にカレントリージョン内の テキストをkillする。 このコマンドは後続のkillコマンドが同一のkillリングエントリーに追加 しないように、‘this-command’に‘kill-region’をセットしない。 31.8.3 yank ----------- yankとはkillリングからテキストを挿入しますが、それが単なる挿入ではないこ とを意味します。‘yank’とそれに関連するコマンドは、テキスト挿入前に特別な 処理を施すために‘insert-for-yank’を使用します。 -- Function: insert-for-yank string この関数は‘insert’と同様に機能するが、結果をカレントバッファーに挿 入する前にテキストプロパティ‘yank-handler’、同様に変数 ‘yank-handled-properties’と‘yank-excluded-properties’に応じて STRING内のテキストを処理する点が異なる。 -- Function: insert-buffer-substring-as-yank buf &optional start end この関数は‘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 FUNCTIONが非‘nil’なら、‘insert’のかわりに文字列を挿入するために、挿 入する文字列を単一の引数として、その関数が呼び出される。 PARAM 非‘nil’のPARAMが与えられた場合には、それはSTRING (または処理される STRINGの部分文字列)を置き換えるオブジェクトとしてFUNCTION (または ‘insert’)に渡される。たとえばFUNCTIONが‘yank-rectangle’なら、 PARAMは矩形(rectangle)として挿入されるべき文字列のリスト。 NOEXCLUDE 非‘nil’のNOEXCLUDEが与えられたら、挿入される文字列にたいする ‘yank-handled-properties’と‘yank-excluded-properties’の通常の動作を 無効にする。 UNDO 非‘nil’のUNDOが与えられたら、それはカレントオブジェクトの挿入を undoするために‘yank-pop’が呼び出す関数。この関数はカレントリージョ ンのstartとendという2つの引数で呼び出される。FUNCTIONは ‘yank-undo-function’をセットすることによりUNDOの値をオーバーライド できる。 -- User Option: yank-handled-properties この変数はyankされるテキストの状態を処理するスペシャルテキストプロ パティを指定する。これは(通常の方法、または‘yank-handler’を通じた )テキストの挿入後、‘yank-excluded-properties’が効力をもつ前に効果を 発揮する。 値は要素が‘(PROP . FUN)’であるようなalistであること。alistの各要素 は順番に処理される。挿入されるテキストはテキスト範囲にたいして、テ キストプロパティがPROPと‘eq’なものがスキャンされる。そのような範囲 にたいしてプロパティの値、そのテキストの開始と終了の位置という3つの 引数によりFUNが呼び出される。 -- User Option: yank-excluded-properties この変数の値は挿入されるテキストから削除するためのプロパティのリス ト。デフォルト値にはマウスに応答したりキーバインディングの指定を引 き起こすテキストのような、煩わしい結果をもたらすかもしれないプロパ ティが含まれる。これは‘yank-handled-properties’の後に効果を発揮する 。 31.8.4 yankのための関数 ----------------------- このセクションではyank用の高レベルなコマンドを説明します。これらのコマン ドは主にユーザー用に意図されたものですが、Lispプログラム内での使用にたい しても有用です。‘yank’と‘yank-pop’はいずれも、変数 ‘yank-excluded-properties’とテキストプロパティ‘yank-handler’にしたがいま す(*note Yanking::を参照)。 -- Command: yank &optional arg このコマンドはkillリングの先頭にあるテキストをポイントの前に挿入す る。これは‘push-mark’(*note The 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’をリターンする。 -- Command: yank-pop &optional arg このコマンドはkillリング上の正にyankされたばかりのエントリーを killリングの別エントリーで置き換える。 このコマンドは‘yank’か別の‘yank-pop’の直後のみ許される。そのような 際にそのリージョンには、yankにより正に挿入されたテキストが含まれる 。‘yank-pop’はそのテキストを削除して、killされた別のテキスト片をそ の位置に挿入する。そのテキスト片はすでにkillリング内のどこか別の箇 所にあるので、これは削除されたテキストをkillリングに追加しない。し かし新たにyankされたテキストが先頭になるように、killリングの転回は 行う。 ARGが‘nil’なら置換テキストはkillリングの1つ前の要素。ARGが数字なら 置換テキストはkillリングのARG個前の要素である。ARGが負なら、より最 近のkillが置換される。 killリング内のkillされたエントリーの順序はラップする。すなわちもっ とも古いkillの次にもっとも新しいkill、もっとも新しいkillの前はもっ とも古いkillとなる。 リターン値は常に‘nil’である。 -- Variable: yank-undo-function この変数が非‘nil’なら、関数‘yank-pop’は前の‘yank’や‘yank-pop’により 挿入されたテキストを削除するために、‘delete-region’のかわりにこの変 数の値を使用する。値はカレントリージョンの開始と終了という2つの引数 をとる関数でなければならない。 関数‘insert-for-yank’はテキストプロパティ‘yank-handler’の要素UNDOに 対応して、この変数を自動的にセットする。 31.8.5 低レベルのkillリング --------------------------- 以下の関数と変数はkillリングにたいして低レベルなアクセスを提供しますが、 それらはウィンドウシステムの選択(*note Window System Selections::を参照 )との相互作用にも留意するので、Lispプログラム内での使用に関しても依然と して有用です。 -- Function: current-kill n &optional do-not-move 関数‘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ポインターの移動は行わない。 -- Function: kill-new string &optional replace この関数はテキストSTRINGをkillリング上にpushして、yankポインターが それを指すようにセットする。それが適切ならもっとも古いエントリーを 破棄する。‘interprogram-cut-function’ (以下参照)の呼び出しも行う。 REPLACEが非‘nil’なら‘kill-new’はkillリング上にSTRINGをpushせずに、 killリングの1つ目の要素をSTRINGに置き換える。 -- Function: kill-append string before-p この関数はkillリング内の最初のエントリーにテキストSTRINGを追加して 、その結合されたエントリーを指すようにyankポインターをセットする。 通常はそのエントリーの終端にSTRINGが追加されるが、BEFORE-Pが非 ‘nil’ならエントリーの先頭に追加される。この関数は ‘interprogram-cut-function’ (以下参照)の呼び出しも行う。 -- Variable: interprogram-paste-function この変数は他のプログラムからkillリングへkillされたテキストを転送す る方法を提供する。値は‘nil’、または引数のない関数であること。 値が関数なら、もっとも最近のkillを取得するために‘current-kill’はそ れを呼び出す。その関数が非‘nil’値をリターンすると、その値がもっとも 最近のkillとして使用される。‘nil’をリターンしたらkillリングの先頭が 使用される。 複数選択をサポートするウィンドウシステムのサポートを容易にするため に、この関数は文字列のリストをリターンすることもある。その場合には 1つ目の文字列がもっとも最近のkillとして使用され、その他の文字列はす べて‘yank-pop’によるアクセスを容易にするためにkillリング上にpushさ れる。 この関数の通常の用途は、たとえそれが他アプリケーションに属する選択 であっても、もっとも最近のkillとしてウィンドウシステムのクリップボ ードからそれを取得することである。しかしクリップボードのコンテンツ がカレントEmacsセッションに由来するなら、この関数は‘nil’をリターン する筈である。 -- Variable: interprogram-cut-function この変数はウィンドウシステム使用時に、他のプログラムにkillされたテ キストを転送する方法を提供する。値は‘nil’、または1つの引数を要求す る関数であること。 値が関数なら‘kill-new’と‘kill-append’はkillリングの新たな1つ目要素 を引数としてそれを呼び出す。 この関数の通常の用途は、新たにkillされたテキストをウィンドウシステ ムのクリップボードに配置することである。*note Window System Selections::を参照のこと。 31.8.6 killリングの内部 ----------------------- 変数‘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’)を行うことにより発生し 得ます。 -- Variable: kill-ring この変数はもっとも最近にkillされたテキストが先頭になるように、 killされたテキストのシーケンスのリストを保持する。 -- Variable: kill-ring-yank-pointer この変数の値は、yankにたいして使用されるkillリングの先頭にある要素 を示す。より正確には値は‘kill-ring’の値のtail値であり、そのCARが ‘C-y’によりyankされるはずのkill文字列。 -- User Option: kill-ring-max この変数の値は、リング終端の要素を破棄する前にkillリングが成長し得 る最大長。‘kill-ring-max’のデフォルト値は60。 31.9 アンドゥ ============= ほとんどのバッファーは、バッファーのテキストにたいして行われた変更を undoできるように、すべての変更を記録する“undoリスト(undo list)”をもって います(undoリストをもたないバッファーとは通常はEmacsがundoを有用とみなさ ない特殊用途のバッファーである。特に名前がスペースで始まるバッファーはす べてundoの記録がデフォルトでオフになっている。*note Buffer Names::を参照 )。バッファー内でテキストを変更するすべてのプリミティブはundoリストの先 頭に自動的に要素を追加して、それは変数‘buffer-undo-list’に格納されます。 -- Variable: buffer-undo-list このバッファーローカル変数の値は、カレントバッファーのundoリスト。 値が‘t’ならundo情報の記録を無効にする。 以下はundoリストが保有可能な要素の種類です: ‘POSITION’ この種の要素は前のポイント値を記録する。この要素をundoすることによ りポイントはPOSITIONに移動する。通常のカーソル移動はどのような類の undo記録も作成しないが、削除操作はそのコマンド以前にポイントがあっ た場所を記録するためにこのエントリーを使用する。 ‘(BEG . END)’ この種の要素は挿入されたテキストを削除する方法を示す。挿入において そのテキストはバッファー内の範囲BEGからENDを占める。 ‘(TEXT . POSITION)’ この種の要素は削除されたテキストを再度挿入する方法を示す。文字列 TEXTは削除されたテキストそのもの。削除されたテキストを再挿入する位 置は‘(abs POSITION)’。POSITIONが正ならポイントがあったのは削除され たテキストの先頭、それ以外では末尾。この要素の直後に0個以上の (MARKER . ADJUSTMENT)要素が続く。 ‘(t . TIME-FLAG)’ この種の要素は未変更のバッファーが変更されたことを示す。‘(SEC-HIGH SEC-LOW MICROSEC PICOSEC)’という形式のTIME-FLAGは、visitされたファ イルにたいしてそれが以前にvisitや保存されたときの更新時刻 (modification time)を、‘current-time’と同じ形式を用いて表す。*note Time of Day::を参照のこと。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を行う。 -- Function: undo-boundary この関数はundoリスト内に境界を配置する。このような境界ごとにundoコ マンドは停止して、連続するundoコマンドは、より以前の境界へとundoを 行っていく。この関数は‘nil’をリターンする。 この関数を明示的に呼び出すことは、あるコマンドの効果を複数単位に分 割するために有用である。たとえば‘query-replace’はユーザーが個別に置 換をundoできるように、それぞれの置換後に‘undo-boundary’を呼び出して いる。 しかしほとんどの場合には、この関数は適切なタイミングで自動的に呼び 出される。 -- Function: undo-auto-amalgamate エディターコマンドループは各アンドゥがが通常はそれぞれ1つのコマンド の効果をアンドゥするように、各キーシーケンスを実行する直前に ‘undo-boundary’を呼び出す。少数の例外は“融合(amalgamating)”コマンド である。これらのコマンドは一般的にバッファーにたいして小さい変更を 発生させるので、変更をグループとしてアンドゥできるように、20回目の コマンドごとに境界が挿入される。デフォルトでは自己挿入入力文字を生 成するコマンド‘self-insert-command’ (*note Commands for Insertion::を参照)、文字を削除するコマンド‘delete-char’ (*note Deletion::を参照)は融合コマンドである。複数バッファーのコンテンツに 影響するコマンド、たとえば発生し得るとすれば‘post-command-hook’上の 関数が‘current-buffer’以外のバッファーに影響を及ぼす場合には、影響 を受ける各バッファーごとに‘undo-boundary’が呼び出されるだろう。 -- Variable: undo-auto-current-boundary-timer プロセスバッファーのようないくつかのバッファーでは、何もコマンドを 実行していなくても変更が発生し得る。このような場合には、通常は ‘undo-boundary’この変数内のタイマーにより定期的に呼び出される。この 挙動を抑制するには、この変数を非‘nil’にセットすること。 -- Variable: undo-in-progress この変数は通常は‘nil’だが、undoコマンドはこれを‘t’にバインドする。 これによりさまざまな種類の変更フックがundoにより呼び出された際に、 それを告げることが可能になる。 -- Function: primitive-undo count list これはundoリストの要素のundoにたいする基本的な関数。これはLISTの最 初のCOUNT要素をundoしてLISTの残りをリターンする。 ‘primitive-undo’はバッファー変更時に、そのバッファーのundoリストに 要素を追加する。undoコマンドは混乱を避けるためにundo操作シーケンス 冒頭にundoリストの値を保存する。その後でundo操作は保存された値の使 用と更新を行う。undoにより追加された新たな要素はこの保存値の一部で ないので継続するundoと干渉しない。 この関数は‘undo-in-progress’をバインドしない。 31.10 アンドゥリストの保守 ========================== このセクションでは与えられたバッファーにたいしてundo情報を有効や無効にす る方法を説明します。undoリストが巨大化しないようにundoリストを切り詰める 方法も説明します。 新たに作成されたバッファー内のundo情報記録は、通常は開始とともに有効 になります。しかしバッファー名がスペースで始まる場合には、undoの記録は初 期状態では無効になっています。以下の2つの関数、または自身で ‘buffer-undo-list’をセットすることにより、undo記録の有効化や無効化を明示 的に行うことができます。 -- Command: buffer-enable-undo &optional buffer-or-name このコマンドは以降の変更をundo可能にするように、バッファー BUFFER-OR-NAMEのundo情報記録を有効にする。引数が与えられなければカ レントバッファーを使用する。そのバッファー内のundo記録がすでに有効 ならこの関数は何も行わない。リターン値は‘nil’。 インタラクティブな呼び出しではBUFFER-OR-NAMEはカレントバッファーで あり、他のバッファーを指定することはできない。 -- Command: buffer-disable-undo &optional 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つの変数は、許容できるサイズの範囲を制御します。これらの変数においてサ イズは専有するバイト数で計数され、それには保存されたテキストとその他デー タが含まれます。 -- User Option: undo-limit これは許容できるundoリストサイズのソフトリミット。このサイズを超過 した箇所の変更グループは最新の変更グループ1つが保持される。 -- User Option: undo-strong-limit これはundoリストの許容できるサイズの上限。このサイズを超過する箇所 の変更グループは(その他すべてのより古い変更グループとともに)自身を 破棄する。1つ例外があり‘undo-outer-limit’を超過すると最新の変更グル ープだけが破棄される。 -- User Option: undo-outer-limit ガベージコレクション時にカレントコマンドのundo情報がこの制限を超過 したら、Emacsはその情報を破棄して警告を表示する。これはメモリーオー バーフローを防ぐための最後の回避用リミットである。 -- User Option: undo-ask-before-discard この変数が非‘nil’ならundo情報の‘undo-outer-limit’超過時に、Emacsは その情報を破棄するかどうかをエコーエリアで尋ねる。デフォルト値は ‘nil’でこれは自動的な破棄を意味する。 このオプションは主にデバッグを意図している。これを尋ねる際にはガベ ージコレクションは抑制されており、もしユーザーがその問にたいして答 えるのをあまりに長くかかるなら、Emacsがメモリーリークを起こすかもし れないことを意味する。 31.11 fill ========== “フィル(fill: 充填)”とは、指定された最大幅付近(ただし超過せず)に、(行ブ レークを移動することにより)行の長さを調整することを意味します。加えて複 数行を“位置揃え(justify)”することもできます。位置揃えとはスペースを挿入 して左および/または右マージンを正確に整列させることを意味します。その幅 は変数‘fill-column’により制御されます。読みやすくするために行の長さは 70列程度を超えないようにするべきです。 テキストの挿入とともに自動的にテキストをフィルするAuto Fillモードを使 用できますが、既存テキストの変更では不適切にフィルされたままになるかもし れません。その場合にはテキストを明示的にフィルしなければなりません。 このセクションのコマンドのほとんどは有意な値をリターンしません。フィ ルを行うすべての関数はカレント左マージン、カレント右マージン、カレント位 置揃えスタイルに留意します(*note Margins::を参照)。カレント位置揃えスタ イルが‘none’なら、フィル関数は実際には何も行いません。 フィル関数のいくつかは引数JUSTIFYを受け取ります。これが非‘nil’なら、 それは何らかの類の位置揃えを要求します。特定の位置揃えスタイルを要求する ために‘left’、‘right’、‘full’、‘center’を指定できます。これが‘t’なら、そ れはそのテキスト部分にたいしてカレント位置揃えスタイルを使用することを意 味します(以下の‘current-justification’を参照)。その他すべての値は ‘full’として扱われます。 インタラクティブにフィル関数を呼び出すには際、プレフィクス引数の使用 はJUSTIFYにたいして暗に値‘full’を指定します。 -- Command: fill-paragraph &optional justify region このコマンドはポイント位置、またはその後のパラグラフ(paragraph: 段 落)をフィルする。JUSTIFYが非‘nil’なら、同様に各行が位置揃えされる。 これはパラグラフ境界を探すために、通常のパラグラフ移動コマンドを使 用する。*note (emacs)Paragraphs::を参照のこと。 もしREGIONが非‘nil’で、Transient Markモードが有効かつマークがアクテ ィブなら、このコマンドはカレントパラグラフのみフィルするかわりに、 リージョン内すべてのパラグラフをフィルするためにコマンド ‘fill-region’を呼び出す。このコマンドがインタラクティブに呼び出され た際は、REGIONは‘t’。 -- Command: fill-region start end &optional justify nosqueeze to-eop このコマンドはSTARTからENDのリージョン内のすべてのパラグラフをフィ ルする。JUSTIFYが非‘nil’なら同様に位置揃えも行う。 NOSQUEEZEが非‘nil’なら、それは行ブレーク以外の空白文字を残すことを 意味する。TO-EOPが非‘nil’なら、それはパラグラフ終端(以下の ‘use-hard-newlines’が有効なら次のhard改行)までのフィルを維持するこ とを意味する。 変数‘paragraph-separate’はパラグラフを分割する方法を制御する。*note Standard Regexps::を参照のこと。 -- Command: fill-individual-paragraphs start end &optional justify citation-regexp このコマンドはリージョン内の各パラグラフを、それの固有なフィルプレ フィクスに応じてフィルする。したがってパラグラフの行がスペースでイ ンデントされていれば、フィルされたパラグラフは同じ様式でインデント された状態に保たれるだろう。 最初の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’ならセ パレーターラインだけがパラグラフを分割する。その場合には、最初の行 からさらにインデントが追加されたパラグラフを処理することが可能にな る。 -- User Option: fill-individual-varying-indent この変数は上述のように‘fill-individual-paragraphs’の動作を変更する 。 -- Command: fill-region-as-paragraph start end &optional justify nosqueeze squeeze-after このコマンドはテキストのリージョンを1つのパラグラフとみなしてそれを フィルする。そのリージョンが多数のパラグラフから構成されていたらパ ラグラフ間の空行は削除される。JUSTIFYが非‘nil’ならフィルとともに位 置揃えも行う。 NOSQUEEZEが非‘nil’なら、それは改行以外の空白に手を加えずに残すこと を意味する。SQUEEZE-AFTERが非‘nil’なら、それはリージョン内の位置を 指定して、その位置より前にあるスペースについては標準化を行わないこ とを意味する。 Adaptive Fillモードでは、このコマンドはフィルプレフィクスを選択する ためにデフォルトで‘fill-context-prefix’を呼び出す。*note Adaptive Fill::を参照のこと。 -- Command: justify-current-line &optional how eop nosqueeze このコマンドはその行が正確に‘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’なら、それは内部のスペースを変更しないことを意味 する。 -- User Option: default-justification この変数の値は位置揃えに使用するスタイルをテキストプロパティで指定 しないテキストにたいするスタイルを指定する。可能な値は‘left’、 ‘right’、‘full’、‘center’、または‘none’。デフォルト値は‘left’。 -- Function: current-justification この関数はポイント周辺のフィルに使用するための適正な位置揃えスタイ ルをリターンする。 これはポイント位置のテキストプロパティ‘justification’の値、そのよう なテキストプロパティが存在しなければ変数DEFAULT-JUSTIFICATIONの値を リターンする。しかし、“位置揃えなし”の場合には、‘none’ではなく ‘nil’をリターンする。 -- User Option: sentence-end-double-space この変数が非‘nil’ならピリオドの後の単一のスペースをセンテンスの終わ りとみなさず、フィル関数はそのような箇所でのラインブレークを行わな い。 -- User Option: sentence-end-without-period この変数が非‘nil’なら、ピリオドなしでセンテンスは終了できる。これは たとえばピリオドなしの2連スペースでセンテンスが終わるタイ語などに使 用される。 -- User Option: sentence-end-without-space この変数が非‘nil’なら、それは後にスペースをともなうことなくセンテン スを終了させ得る文字列であること。 -- Variable: fill-paragraph-function この変数はパラグラフのフィルをオーバーライドする手段を提供する。こ の値が非‘nil’なら、‘fill-paragraph’はその処理を行うためにその関数を 呼び出す。その関数が非‘nil’値をリターンすると、‘fill-paragraph’は処 理が終了したとみなして即座にその値をリターンする。 この機能の通常の用途はプログラミング言語のモードにおいてコメントを フィルすることである。通常の方法でその関数がパラグラフをフィルする 必要があるなら、以下のようにそれを行うことができる: (let ((fill-paragraph-function nil)) (fill-paragraph arg)) -- Variable: fill-forward-paragraph-function この変数は‘fill-region’や‘fill-paragraph’のようなフィル関数が次のパ ラグラフへ前方に移動する方法をオーバーライドするための手段を提供す る。値は移動するパラグラフの数Nを唯一の引数として呼び出される関数で あり、Nと実際に移動したパラグラフ数の差をリターンすること。この変数 のデフォルト値は‘forward-paragraph’。*note (emacs)Paragraphs::を参 照のこと。 -- Variable: use-hard-newlines この変数が非‘nil’なら、フィル関数はテキストプロパティ‘hard’をもつ改 行を削除しない。これらのhard改行、パラグラフのセパレーターとして機 能する。*note Hard and Soft Newlines: (emacs)Hard and Soft Newlines.を参照のこと。 31.12 fillのマージン ==================== -- User Option: fill-prefix このバッファーローカル変数が非‘nil’なら、それは通常のテキスト行の先 頭に出現して、それらのテキスト行をフィルする際には無視されるべきテ キスト文字列を指定する。そのフィルプレフィクスで始まらない行はパラ グラフの開始とみなされ、フィルプレフィクスで始まる行はその後にスペ ースが追加される。フィルプレフィクスで始まりその後に追加のスペース がない行はフィル可能な通常のテキスト行。結果となるフィル済みの行も フィルプレフィクスで開始される。 もしあればフィルプレフィクスは左マージンのスペースの後になる。 -- User Option: fill-column このバッファーローカル変数はフィルされる行の最大幅を指定する。値は 列数を表す整数であること。Auto Fillモード(*note Auto Filling::を参 照)を含むフィル、位置揃え、センタリングを行うすべてのコマンドがこの 変数の影響を受ける。 実際の問題として他の人が読むためのテキストを記述する場合には、 ‘fill-column’を70より大きくするべきではない。これにしたがわないと人 が快適に読むには行が長くなり過ぎてしまい、下手に記述されたテキスト に見えてしまうだろう。 ‘fill-column’のデフォルト値は70。 -- Command: set-left-margin from to margin これはFROMからTOのテキストの‘left-margin’プロパティに値MARGINをセッ トする。Auto Fillモードが有効なら、このコマンドは新たなマージンにフ ィットするようにリージョンの再フィルも行う。 -- Command: set-right-margin from to margin これはFROMからTOのテキストの‘right-margin’プロパティに値MARGINをセ ットする。Auto Fillモードが有効なら、このコマンドは新たなマージンに フィットするようにリージョンの再フィルも行う。 -- Function: current-left-margin この関数はポイント周辺をフィルするために使用する、適切な左マージン 値をリターンする。値はカレント行開始文字の‘left-margin’プロパティの 値(なければ0)と変数‘left-margin’の値の合計。 -- Function: current-fill-column この関数はポイント周辺のテキストをフィルするために使用する、適切な フィル列値をリターンする。値は変数‘fill-column’からポイント後の文字 の‘right-margin’プロパティの値を減じた値。 -- Command: move-to-left-margin &optional n force この関数はカレント行の左マージンにポイントを移動する。移動先の列は 関数‘current-left-margin’により決定される。引数Nが非‘nil’なら、まず ‘move-to-left-margin’はN行前方に移動する。 FORCEが非‘nil’なら、それは行のインデントが左マージン値とマッチしな ければインデントを修正するように指定する。 -- Function: delete-to-left-margin &optional from to この関数はFROMからTOの間のテキストから左マージンのインデントを取り 除く。削除するインデントの量は‘current-left-margin’を呼び出すことに より決定される。この関数が非空白文字を削除することはない。FROMと TOが省略された場合のデフォルトはそのバッファー全体。 -- Function: indent-to-left-margin この関数はカレント行の先頭のインデントを変数‘left-margin’に指定され た値に調整する(これにより空白文字の挿入や削除が起こるかもしれない )。Paragraph-Indent Textモード内の変数‘indent-line-function’の値は この関数。 -- User Option: left-margin この変数は左マージンの基本列を指定する。Fundamentalモードでは、 はこの列にインデントする。この変数は手段の如何を問わずセットさ れると自動的にバッファーローカルになる。 -- User Option: fill-nobreak-predicate この変数はメジャーモードにたいして、特定の箇所で行ブレークしないよ うに指定する手段を提供する。値は関数のリストであること。フィルがバ ッファー内の特定箇所で行ブレークすると判断されるときは、常にその箇 所にポイントを置いた状態でこれらの関数を引数なしで呼び出す。これら の関数のいずれかが非‘nil’をリターンすると、その行のその箇所では行ブ レークしない。 31.13 Adaptive Fillモード ========================= “Adaptive Fillモード”が有効なとき、Emacsは事前定義された値を使用するので はなく、フィルされる各パラグラフのテキストから自動的にフィルプレフィクス を決定します。*note Filling::と*note Auto Filling::で説明されているよう に、このフィルプレフィクスはフィルの間にそのパラグラフの2行目以降の行頭 に挿入されます。 -- User Option: adaptive-fill-mode この変数が非‘nil’ならAdaptive Fillモードは有効。デフォルトは‘t’。 -- Function: fill-context-prefix from to この関数はAdaptive Fillモード実装の肝である。これはFROMからTO、通常 はパラグラフの開始から終了にあるテキストにもとづいてフィルプレフィ クスを選択する。これは以下で説明する変数にもとづき、そのパラグラフ の最初の2行を調べることによりこれを行う。 この関数は通常は文字列としてフィルプレフィクスをリターンする。しか しこれを行う前に、この関数はそのプレフィクスで始まる行がパラグラフ の開始とは見えないだろうか、最終チェックを行う(以降では特に明記しな い)。これが発生した場合には、この関数はかわりに‘nil’をリターンする ことにより異常を通知する。 以下は‘fill-context-prefix’が行う詳細: 1. 1行目からフィルプレフィクス候補を取得するために、(もしあれば )まず‘adaptive-fill-function’内の関数、次に ‘adaptive-fill-regexp’ (以下参照)の正規表現を試みる。これらの 非‘nil’の最初の結果、いずれも‘nil’なら空文字列が1行目の候補と なる。 2. そのパラグラフが1行だけなら、関数は見つかったプレフィクス候補 の妥当性をテストする。その後でこの関数はそれが妥当ならその候補 を、それ以外はスペース文字列をリターンする(以下の ‘adaptive-fill-first-line-regexp’の説明を参照)。 3. すでにそのパラグラフが2行以上なら、この関数は次に1行目にたいし て行なったのとまったく同じ方法で2行目でプレフィクス候補を探す 。見つからなければ‘nil’をリターンする。 4. ここでこの関数は発見的手法により2つのプレフィクス候補を比較す る。2行目の候補の非空白文字の並びが1行目の候補と同じなら、この 関数は2行目の候補をリターンする。それ以外では2つの候補に共通す るもっとも長い先頭の部分文字列(これは空文字列かもしれない)をリ ターンする。 -- User Option: adaptive-fill-regexp Adaptive Fillモードは、(もしあれば)行の左マージン空白文字の後から開 始されるテキストにたいしてこの正規表現をマッチする。マッチする文字 列がその行のフィルプレフィクス候補。 デフォルト値は空白文字と特定の句読点文字が混在した文字列にマッチす る。 -- User Option: adaptive-fill-first-line-regexp この正規表現は1行だけのパラグラフに使用され、1つの可能なフィルプレ フィクス候補の追加の妥当性評価として機能する。その候補はこの正規表 現にマッチするか、‘comment-start-skip’にマッチしなければならない。 マッチしなければ‘fill-context-prefix’はその候補を同じ幅のスペース文 字列に置き換える。 この変数のデフォルト値は ‘"\\`[ \t]*\\'"’であり、これは空白文字列だ けにマッチする。このデフォルトの効果は1行パラグラフで見つかったフィ ルプレフィクスが、常に純粋な空白文字となるよう強制することである。 -- User Option: adaptive-fill-function この変数に関数をセットすることにより、自動的なフィルプレフィクス選 択にたいしてより複雑な方法を指定することが可能になる。その関数は、 (もしあれば)行の左マージンの後のポイントで呼び出され、かつポイント を保たなければならない。その関数はその行のフィルプレフィクス、また はプレフィクスの判断に失敗したことを意味する‘nil’のいずれかをリター ンすること。 31.14 オートfill ================ Auto Fillモードはテキスト挿入とともに自動的に行をフィルするマイナーモー ドです。このセクションではAuto Fillモードにより使用されるフックを説明し ます。既存テキストを明示的にフィルしたり位置揃えすることができる関数の説 明は*note Filling::を参照してください。 Auto Fillモードではテキスの一部を再フィルするためにマージンや位置揃え を変更する関数も利用できます。*note Margins::を参照してください。 -- Variable: auto-fill-function このバッファーローカル変数の値は、テーブル‘auto-fill-chars’の文字の 自己挿入後に呼び出される関数(引数なし)であること。‘nil’も可であり、 その場合は特に何もしない。 Auto-Fillモードが有効なら‘auto-fill-function’の値は‘do-auto-fill’。 これは行ブレークにたいする通常の戦略を実装することを唯一の目的とす る関数。 -- Variable: normal-auto-fill-function この変数はAuto Fillがオンのときは‘auto-fill-function’にたいして使用 する関数を指定する。Auto Fillの動作方法を変更するためにメジャーモー ドはこの変数にバッファーローカル値をセットできる。 -- Variable: auto-fill-chars 文字が自己挿入された際に‘auto-fill-function’を呼び出す文字からなる 文字テーブル(ほとんどの言語環境においてはスペースと改行)。 31.15 テキストのソート ====================== このセクションで説明するソート関数は、すべてバッファー内のテキストを再配 置します。これはリスト要素を再配置する‘sort’関数とは対照的です(*note Rearrangement::)。これらの関数がリターンする値に意味はありません。 -- Function: sort-subr reverse nextrecfun endrecfun &optional startkeyfun endkeyfun predicate この関数はバッファーをレコードに細分してそれらをソートする一般的な テキストソートルーチン。このセクションのコマンドのほとんどは、この 関数を使用する。 ‘sort-subr’が機能する方法を理解するためには、バッファーのアクセス可 能範囲を“ソートレコード(sort records)”と呼ばれる分離された断片に分 割すると考えればよい。レコードは連続、あるいは非連続かもしれないが オーバーラップしてはならない。各ソートレコードの一部(全体かもしれな い)はソートキーとして指定される。これらソートキーによるソートにより レコードは再配置される。 レコードは通常はソートキー昇順で再配置される。‘sort-subr’の1つ目の 引数REVERSEが非‘nil’ならレコードはソートキー降順にソートされて再配 置される。 ‘sort-subr’にたいする以下の4つの引数は、ソートレコード間でポイント を移動するために呼び出される。これらは‘sort-subr’内で頻繁に呼び出さ れる。 1. NEXTRECFUNはレコード終端のポイントで呼び出される。この関数は次 のレコードの先頭にポイントを移動する。‘sort-subr’が呼び出され た際には、ポイント位置が1つ目のレコードの開始とみなされる。し たがって‘sort-subr’を呼び出す前は、通常はそのバッファーの先頭 にポイントを移動すること。 この関数はバッファー終端にポイントを残すことにより、それ以上の ソートレコードがないことを示すことができるできる。 2. ENDRECFUNはレコード内にあるポイントで呼び出される。これはレコ ード終端にポイントを移動する。 3. STARTKEYFUNはポイントをレコード先頭からソートキー先頭に移動す る。この引数はオプションで、省略された場合はレコード全体がソー トキーとなる。もし与えられた場合には、その関数はソートキーとし て使用する非‘nil’値、または‘nil’ (ソートキーはそのバッファー内 のポイント位置から始まることを示す)のいずれかをリターンするこ と。後者の場合にはソートキー終端を見るけるためにENDKEYFUNが呼 び出される。 4. ENDKEYFUNはソートキー先頭からソートキー終端にポイントを移動す るために呼び出される。引数はオプション。STARTKEYFUNが‘nil’をリ ターンし、かつこの引数が省略(または‘nil’)の場合には、そのソー トキーはレコード終端まで拡張される。STARTKEYFUNが非‘nil’値をリ ターンした場合にはENDKEYFUNは不要。 引数PREDICATEはキーを比較するために使用される関数。キーが数字の場合 のデフォルトは‘<’、それ以外では‘string<’がデフォルト。 ‘sort-subr’の例として以下は‘sort-lines’関数の完全な定義である: ;; ドキュメント文字列の冒頭2行は ;; ユーザー閲覧時には1行となることに注意 (defun sort-lines (reverse beg end) "リージョン内の行をアルファベット順にソート;\ 引数は降順を意味する プログラムから呼び出す場合は、以下の3つの引数がある: REVERSE(非nilは逆順の意)、\ およびBEGとEND(ソートするリージョン) 変数`sort-fold-case'は英字\ 大文字小文字の違いが ソート順に影響するかどうかを決定する" (interactive "P\nr") (save-excursion (save-restriction (narrow-to-region beg end) (goto-char (point-min)) (let ((inhibit-field-text-motion t)) (sort-subr reverse 'forward-line 'end-of-line))))) ここで‘forward-line’は次のレコードの先頭にポイントを移動して、 ‘end-of-line’はレコードの終端にポイントを移動する。レコード全体をソ ートキーとするので引数STARTKEYFUNとENDKEYFUNは渡していない。 ‘sort-paragraphs’はほとんど同じだが、‘sort-subr’の呼び出しが以下の ようになる: (sort-subr reverse (function (lambda () (while (and (not (eobp)) (looking-at paragraph-separate)) (forward-line 1)))) 'forward-paragraph) ソートレコード内を指す任意のマーカーは、‘sort-subr’リターン後は無意 味なマーカー位置のまま取り残される。 -- User Option: sort-fold-case この変数が非‘nil’なら、‘sort-subr’とその他のバッファーソート関数は 文字列比較時にcase(大文字小文字)の違いを無視する。 -- Command: sort-regexp-fields reverse record-regexp key-regexp start end このコマンドはSTARTからENDの間のリージョンを、RECORD-REGEXPと KEY-REGEXPで指定されたようにアルファベット順にソートする。REVERSEが 負の整数なら逆順にソートする。 アルファベット順のソートとは2つのソートキーにたいして、それぞれの 1つ目の文字同士、2つ目の文字同士、...のように比較することにより、キ ーを比較することを意味する。文字が一致しなければ、それはソートキー が不等なことを意味する。最初の不一致箇所で文字が小さいソートキーが 小さいソートキーとなる。個別の文字はEmacs文字セット内の文字コードの 数値に応じて比較される。 引数RECORD-REGEXPの値はバッファーをソートレコードに分割する方法を指 定する。各レコードの終端で、この正規表現にたいする検索は完了して、 これにマッチするテキストが次のレコードとして採用される。たとえば改 行の前に少なくとも1つの文字がある行にマッチする正規表現‘^.+$’は、そ のような行をソートレコードとするだろう。正規表現の構文と意味につい ては*note Regular Expressions::を参照のこと。 引数KEY-REGEXPの値は各レコードのどの部分がソートキーかを指定する。 KEY-REGEXPはレコード全体、またはその一部にマッチすることができる。 後者の場合にはレコードの残りの部分はソート順に影響しないが、レコー ドが新たな位置に移動される際はともに移動される。 引数KEY-REGEXPはRECORD-REGEXPの部分式(subexpression)、またはその正 規表現自体にマッチしたテキストを参照できる。 KEY-REGEXPには以下を指定できる: ‘\DIGIT’ RECORD-REGEXP内でDIGIT番目のカッコ‘\(...\)’でグループ化により マッチしたテキストがソートキーになる。 ‘\&’ レコード全体がソートキーとなる。 正規表現 ‘sort-regexp-fields’は、そのレコード内で正規表現にたいするマッ チを検索する。そのようなマッチがあればそれがソートキー。レコー ド内にKEY-REGEXPにたいするマッチがなければそのレコードは無視さ れて、そのバッファー内でのレコードの位置は変更されないことを意 味する(他のレコードがそのレコードを移動するかもしれない)。 たとえばリージョン内のすべての行にたいして、最初の単語が文字‘f’で始 まる行をソートすることを目論むなら、RECORD-REGEXPを‘^.*$’、 KEY-REGEXPを‘\’にセットすること。結果は以下のような式になる (sort-regexp-fields nil "^.*$" "\\" (region-beginning) (region-end)) ‘sort-regexp-fields’をインタラクティブに呼び出した場合にはミニバッ ファー内でRECORD-REGEXPとKEY-REGEXPの入力を求める。 -- Command: sort-lines reverse start end このコマンドはSTARTとENDの間のリージョン内の行をアルファベット順に ソートする。REVERSEが非‘nil’なら逆順にソートする。 -- Command: sort-paragraphs reverse start end このコマンドはSTARTとENDの間のリージョン内のパラグラフをアルファベ ット順にソートする。REVERSEが非‘nil’なら逆順にソートする。 -- Command: sort-pages reverse start end このコマンドはSTARTとENDの間のリージョン内のページをアルファベット 順にソートする。REVERSEが非‘nil’なら逆順にソートする。 -- Command: sort-fields field start end このコマンドはSTARTとENDの間のリージョン内の行にたいして、各行の FIELD番目のフィールドをアルファベット順に比較することに行をソートす る。FIELDは空白文字により区切られて、1から数えられる。FIELDが負なら 行の終端から−FIELD番目のフィールドでソートする。このコマンドはテー ブルのソートに有用。 -- Command: sort-numeric-fields field start end このコマンドはSTARTとENDの間のリージョン内の行にたいして、各行の FIELD番目のフィールドを数値的に比較することにより行をソートする。 FIELDは空白文字により区切られて、1から数えられる。リージョン内の各 行の指定されたフィールドは数字を含んでいなければならない。0で始まる 数字は8進数、‘0x’で始まる数字は16進数として扱われる。 FIELDが負なら行の終端から−FIELD番目のフィールドでソートする。このコ マンドはテーブルのソートに有用。 -- User Option: sort-numeric-base この変数は‘sort-numeric-fields’にたいして数字を解析するための基本基 数を指定する。 -- Command: sort-columns reverse &optional beg end このコマンドはBEGとENDの間にある行にたいして特定の列範囲をアルファ ベット順に比較することによりソートする。BEGとENDの列位置はソートが 行われる列範囲にバインドされる。 REVERSEが非‘nil’なら逆順にソートする。 このコマンドが通常と異なるのは、位置BEGを含む行全体と位置ENDを含む 行全体がソートされるリージョンに含まれることである。 タブは指定された列に分割される可能性があるので、‘sort-columns’はタ ブを含むテキストを受け付けないことに注意。ソート前に‘M-x untabify’を 使用してタブをスペースに変換すること。 可能ならユーティリティプログラム‘sort’を呼び出すことにより、このコ マンドは実際に機能する。 31.16 列を数える ================ 列関数は文字位置(バッファー先頭から数えた文字数)と列位置(行先頭から数え たスクリーン文字数)を変換する関数です。 これら列関数はスクリーン上占める列数に応じて各文字を数えます。これは コントロール文字は‘ctl-arrow’の値に応じて2列または4列を、タブは ‘tab-width’の値と、タブが始まる列の位置に依存する列数を占めるものとして 数えられることを意味します。*note Usual Display::を参照してください。 列数計算はウィンドウ幅と水平スクロール量を無視します。結果として列値 は任意に大きくなる可能性があります。最初(または左端)の列は0と数えられま す。列値は不可視性を別としてオーバーレイとテキストプロパティを無視します 。 -- Function: current-column この関数は左マージンを0として列単位で数えたポイントの水平位置をリタ ーンする。列の位置はカレント行の開始からポイントまでの間の文字の表 示上の表現すべての幅の和。 -- Command: move-to-column column &optional force この関数はカレント行のCOLUMNにポイントを移動する。COLUMNの計算には 行の開始からポイントまでの文字の表示上の表現の幅が考慮される。 インタラクティブに呼び出された際には、COLUMNはプレフィクス数引数の 値。COLUMNが整数でなければエラーがシグナルされる。 列COLUMNがタブのような複数列を占める文字の中間にあるために列を移動 することが不可能なら、ポイントはその文字の終端に移動される。しかし FORCEが非‘nil’、かつCOLUMNがタブの中間にあるなら、 ‘move-to-column’はタブをスペースに変換して正確に列COLUMNに移動する ことができる。それ以外の複数列文字については、それらを分割する手段 がないのでFORCE指定に関わらず異常を引き起こす恐れがある。 その行が列COLUMNに達するほど長くない場合にも引数FORCEは効果をもつ。 COLUMNが‘t’ならその列に達するよう行端に空白を追加することを意味する 。 リターン値は実際に移動した列番号。 31.17 インデント ================ インデント関数は行の先頭にある空白文字の調査、移動、変更に使用されます。 行の他の箇所にある空白文字を変更できる関数もいくつかあります。列とインデ ントは左マージンを0として数えられます。 31.17.1 インデント用のプリミティブ ---------------------------------- このセクションではインデントのカウントと挿入に使用されるプリミティブ関数 について説明します。以降のセクションの関数はこれらのプリミティブを使用し ます。関連する関数については*note Size of Displayed Text::を参照してくだ さい。 -- Function: current-indentation この関数はカレント行のインデント、すなわち最初の非ブランク文字の水 平位置をリターンする。行のコンテンツ全体がブランクなら、それは行終 端の水平位置である。 -- Command: indent-to column &optional minimum この関数はポイントからCOLUMNに達するまでタブとスペースでインデント を行う。MINIMUMが指定されて、かつそれが非‘nil’なら、たとえCOLUMNを 超えることが要求される場合であっても、少なくともその個数のスペース が挿入される。それ以外ではポイントがすでにCOLUMNを超える場合には、 この関数は何も行わない。値は挿入されたインデントの終端列。 挿入される空白文字は周囲のテキスト(通常は先行するテキストのみ)のテ キストプロパティを継承する。*note Sticky Properties::を参照のこと。 -- User Option: indent-tabs-mode この変数が非‘nil’なら、インデント関数はスペースと同じようにタブを挿 入でき、それ以外ではスペースだけを挿入できる。この変数はセットする ことにより自動的にカレントバッファー内でバッファーローカルになる。 31.17.2 メジャーモードが制御するインデント ------------------------------------------ すべてのメジャーモードにとって重要な関数は、編集対象の言語にたいして正し くインデントを行うようにキーをカスタマイズします。このセクションで はキーのメカニズムと、それを制御する方法について説明します。このセ クションの関数は予期せぬ値をリターンします。 -- Command: indent-for-tab-command &optional rigid これはほとんどの編集用モードでにバインドされるコマンド。これの 通常の動作はカレント行のインデントだが、かわりにタブ文字の挿入やリ ージョンのインデントを行うこともできる。 これは以下のことを行う: • まずTransient Markモードが有効か、そしてリージョンがアクティブ かどうかをチェックする。もしそうならリージョン内のテキストすべ てをインデントするために‘indent-region’を呼び出す(*note Region Indent::を参照)。 • それ以外なら‘indent-line-function’内のインデント関数が ‘indent-to-left-margin’の場合、または変数‘tab-always-indent’が 挿入する文字としてタブ文字を指定する場合(以下参照)にはタブ文字 を挿入する。 • それ以外ならカレント行をインデントする。これは ‘indent-line-function’内の関数を呼び出すことにより行われる。そ の行がすでにインデント済みで、かつ‘tab-always-indent’の値が ‘complete’(以下参照)ならポイント位置のテキストの補完を試みる。 RIGIDが非‘nil’ (インタラクティブな場合はプレフィクス引数)なら、この コマンドが行をインデントした後、あるいはタブを挿入後に新たなインデ ントを反映するために、このコマンドはカレント行先頭にあるバランスさ れた式全体も厳正にインデントする。この引数はコマンドがリージョンを インデントする場合は無視される。 -- Variable: indent-line-function この変数の値はカレント行をインデントするために ‘indent-for-tab-command’、およびその他種々のインデントコマンドによ り使用される関数。これは通常はメジャーモードにより割り当てられ、た とえばLispモードはこれを‘lisp-indent-line’、Cモードは ‘c-indent-line’のようにセットする。デフォルト値は ‘indent-relative’。*note Auto-Indentation::を参照のこと。 -- Command: indent-according-to-mode このコマンドはカレントのメジャーモードに適した方法でカレント行をイ ンデントするために‘indent-line-function’内の関数を呼び出す。 -- Command: newline-and-indent この関数は改行を挿入後に、メジャーモードに応じて新たな行(挿入した改 行の次の行)をインデントする。これは‘indent-according-to-mode’を呼び 出すことによりインデントを行う。 -- Command: reindent-then-newline-and-indent このコマンドはカレント行の再インデント、ポイント位置への改行の挿入 、その後に新たな行(挿入した改行の次の行)のインデントを行う。これは ‘indent-according-to-mode’を呼び出すことにより両方の行をインデント する。 -- User Option: tab-always-indent この変数は (‘indent-for-tab-command’)コマンドの挙動のカスタマ イズに使用できる。値が‘t’(デフォルト)ならコマンドは通常はカレント行 だけをインデントする。値が‘nil’ならコマンドはポイントが左マージン、 またはその行のインデント内ににあるときのみカレント行をインデントし て、それ以外はタブ文字を挿入する。値が‘complete’ならコマンドはまず カレント行のインデントを試みて、その行がすでにインデント済みならポ イント位置のテキストを補完するために‘completion-at-point’を呼び出す (*note Completion in Buffers::を参照)。 31.17.3 リージョン全体のインデント ---------------------------------- このセクションではリージョン内すべての行をインデントするコマンドを説明し ます。これらは予期せぬ値をリターンします。 -- Command: indent-region start end &optional to-column このコマンドはSTART (含む)からEND (含まず)で始まる非ブランク行すべ てをインデントする。TO-COLUMNが‘nil’なら‘indent-region’はカレントモ ードのインデント関数、すなわち‘indent-line-function’の値を呼び出す ことにより非ブランク行すべてをインデントする。 TO-COLUMNが非‘nil’なら、それはインデントの列数を指定する整数である こと。その場合には、この関数は空白文字を追加か削除することにより正 確にその量のインデントを各行に与える。 フィルプレフィクスがある場合には、‘indent-region’はそのフィルプレフ ィクスで開始されるように各行をインデントする。 -- Variable: indent-region-function この変数の値はショートカットとして‘indent-region’により使用されるか もしれない関数。その関数はリージョンの開始と終了という2つの引数を受 け取ること。その関数はリージョンの行を1行ずつインデントするときと同 じような結果を生成するようにデザインするべきだが、おそらくより高速 になるであろう。 値が‘nil’ならショートカットは存在せず‘indent-region’は実際に1行ずつ 機能する。 ショートカット関数は‘indent-line-function’が関数定義先頭をスキャン しなければならないCモードやLispモードのようなモードにたいして有用で あり、それを各行に適用するためには行数の2乗に比例する時間を要するだ ろう。ショートカットは各行のインデントとともに移動してスキャン情報 を更新でき、それは線形時間である。行を個別にインデントするのが高速 なモードではショートカットの必要性はない。 引数TO-COLUMNが非‘nil’の‘indent-region’では意味は異なり、この変数は 使用しない。 -- Command: indent-rigidly start end count この関数はSTART (含む)からEND (含まず)までのすべての行を横にCOUNT列 インデントする。これは影響を受けるリージョンの外観を保ち、それを厳 密な単位として移動する。 これはインデントされていないテキストリージョンのインデントだけでな く、フォーマット済みコードのリージョンにたいするインデントにも有用 。たとえばCOUNTが3なら、このコマンドは指定されたリージョン内で始ま るすべての行のインデントに3を追加する。 プレフィクス引数なしでインタラクティブに呼び出された場合には、この コマンドはインデントを厳密に調整するためにTransient Markモードを呼 び出す。*note (emacs)Indentation Commands::を参照のこと。 -- Command: indent-code-rigidly start end columns &optional nochange-regexp これは‘indent-rigidly’と似ているが文字列やコメントで始まる行を変更 しない点が異なる。 加えて( NOCHANGE-REGEXPが非‘nil’なら) NOCHANGE-REGEXPが行先頭にマッ チする場合にはその行を変更しない。 31.17.4 前行に相対的なインデント -------------------------------- このセクションでは前の行のコンテンツにもとづいてカレント行をインデントす るコマンドを2つ説明します。 -- Command: indent-relative &optional unindented-ok このコマンドは前の非ブランク行の次の“インデントポイント(indent point)”と同じ列に拡張されるように、ポイント位置に空白文字を挿入する 。インデントポイントとは後に空白文字をともなった非空白文字。次のイ ンデントポイントはポイントのカレント列より大きい、最初のインデント ポイントになる。たとえばポイントがテキスト行の最初の非ブランク文字 の下と左にある場合には、空白文字を挿入してその列に移動する。 前の非ブランク行に次のインデントポイントがない(列の位置が十分大きく ない)場合には、( UNINDENTED-OKが非‘nil’なら)何もしないか、あるいは ‘tab-to-tab-stop’を呼び出す。したがってポイントが短いテキスト行の最 後の列の下と右にある場合には、このコマンドは通常は空白文字を挿入す ることにより次のタブストップにポイントを移動する。 ‘indent-relative’のリターン値は予測できない。 以下の例ではポイントは2行目の先頭にある: This line is indented twelve spaces. ★The quick brown fox jumped. 式‘(indent-relative nil)’の評価により以下が生成される: This line is indented twelve spaces. ★The quick brown fox jumped. 次の例ではポイントは‘jumped’の‘m’と‘p’の間にある: This line is indented twelve spaces. The quick brown fox jum★ped. 式‘(indent-relative nil)’の評価により以下が生成される: This line is indented twelve spaces. The quick brown fox jum ★ped. -- Command: indent-relative-maybe このコマンドは引数UNINDENTED-OKに‘t’を指定して‘indent-relative’を呼 び出すことにより、前の非ブランク行に倣ってカレント行をインデントす る。リターン値は予測できない。 カレント列より先のインデントポイントが前の非ブランク行に存在しなけ ればこのコマンドは何もしない。 31.17.5 Adjustable Tab Stops ---------------------------- このセクションではユーザー指定のタブストップ(tab stops)と、それらの使用 やセットするメカニズムについて説明します。“タブストップ”という名前はタイ プライターのタブストップと機能が類似しているため使用されています。この機 能は次のタブストップ列に到達するために、適切な数のスペースとタブを挿入す ることにより機能します。これはバッファー内のタブ文字の表示に影響を与えま せん(*note Usual Display::を参照)。Textモードのような少数のメジャーモー ドだけが、文字を入力としてこのタブストップ機能を使用することに注意 してください。*note (emacs)Tab Stops::を参照してください。 -- Command: tab-to-tab-stop このコマンドは‘tab-stop-list’により定義される次のタブストップ列まで ポイント前にスペースかタブを挿入する。 -- User Option: tab-stop-list この変数は‘tab-to-tab-stop’により使用されるタブストップ列を定義する 。これは‘nil’、もしくは増加(均等に増加する必要はない)していく整数の リストであること。このリストは暗黙に、最後の要素と最後から2番目の要 素の間隔(またはリストの要素が2未満なら‘tab-width’)を繰り返すことに より無限に拡張される。値‘nil’は列‘tab-width’ごとにタブストップする ことを意味する。 インタラクティブにタブストップの位置を編集するには‘M-x edit-tab-stops’を使用すればよい。 31.17.6 インデントにもとづくモーションコマンド ---------------------------------------------- 以下は主にインタラクティブに使用されるコマンドであり、テキスト内のインデ ントにもとづいて動作します。 -- Command: back-to-indentation このコマンドはカレント行(ポイントのある行のこと)の最初の非空白文字 にポイントを移動する。リターン値は‘nil’。 -- Command: backward-to-indentation &optional arg このコマンドは後方へARG行ポイントを移動した後に、その行の最初の非ブ ランク文字にポイントを移動する。リターン値は‘nil’。ARGが省略または ‘nil’のときのデフォルトは1。 -- Command: forward-to-indentation &optional arg このコマンドは前方へARG行ポイントを移動した後に、その行の最初の非ブ ランク文字にポイントを移動する。リターン値は‘nil’。ARGが省略または ‘nil’のときのデフォルトは1。 31.18 大文字小文字の変更 ======================== ここで説明するcase(大文字小文字)変換コマンドはカレントバッファー内のテキ ストに作用します。文字列と文字のcase変換コマンドは*note Case Conversion::、大文字や小文字に変換する文字やその変換方法のカスタマイズは *note Case Tables::を参照してください。 -- Command: capitalize-region start end この関数は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 ---------- -- Command: downcase-region start end この関数はSTARTとENDで定義されるリージョン内のすべての英文字を小文 字に変換する。この関数は‘nil’をリターンする。 インタラクティブに‘downcase-region’が呼び出された際には、STARTと ENDはポイントとマークになり小さいほうが先になる。 -- Command: upcase-region start end この関数はSTARTとENDで定義されるリージョン内のすべての英文字を大文 字に変換する。この関数は‘nil’をリターンする。 インタラクティブに‘upcase-region’が呼び出された際には、STARTとENDは ポイントとマークになり小さいほうが先になる。 -- Command: capitalize-word count この関数はポイントの後のCOUNT単語をcapitalizeして、変換後その後にポ イントを移動する。capitalizeとは各単語の先頭を大文字、残りを小文字 に変換することを意味する。COUNTが負なら、この関数は前の−COUNT単語を capitalizeするがポイントは移動しない。値は‘nil’。 ポイントが単語の中間にある場合には、ポイントの前にある単語部分は前 方に移動する際は無視される。そして残りの部分が単語全体として扱われ る。 インタラクティブに‘capitalize-word’が呼び出された際には、COUNTに数 プレフィクス引数がセットされる。 -- Command: downcase-word count この関数はポイントの後のCOUNT単語を小文字に変換して、変換後その後に ポイントを移動する。COUNTが負なら、この関数は前の−COUNT単語を小文字 に変換するがポイントは移動しない。値は‘nil’。 インタラクティブに‘downcase-word’が呼び出された際には、COUNTに数プ レフィクス引数がセットされる。 -- Command: upcase-word count この関数はポイントの後のCOUNT単語を大文字に変換して、変換後その後に ポイントを移動する。COUNTが負なら、この関数は前の−COUNT単語を小文字 に変換するがポイントは移動しない。値は‘nil’。 インタラクティブに‘upcase-word’が呼び出された際には、COUNTに数プレ フィクス引数がセットされる。 31.19 テキストのプロパティ ========================== バッファーや文字列内の各文字位置は、シンボルにおけるプロパティリスト (*note Property Lists::を参照)のように“テキストプロパティリスト(text property list)”をもつことができます。特定の位置の特定の文字に属するプロ パティ、たとえばこのセンテンス先頭の文字‘T’ (訳注: 翻訳前のセンテンスは "The properties belong to a ..."で始まる)、または‘foo’の最初の‘o’など、 もし同じ文字が異なる2箇所に存在する場合には、2つの文字は一般的に異なるプ ロパティをもちます。 それぞれのプロパティには名前と値があります。どちらも任意のLispオブジ ェクトをもつことができますが、名前は通常はシンボルです。典型的にはそれぞ れのプロパティ名シンボルは特定の目的のために使用されます。たとえばテキス トプロパティ‘face’は、文字を表示するためのフェイスを指定します(*note Special Properties::を参照)。名前を指定してそれに対応する値を尋ねるのが 、このプロパティリストにアクセスするための通常の方法です。 ある文字が‘category’プロパティをもつ場合は、それをその文字の“プロパテ ィカテゴリー(property category)”と呼びます。これはシンボルであるべきです 。そのシンボルのプロパティはその文字のプロパティにたいしてデフォルトとし ての役割をもちます。 文字列とバッファーの間でのテキストのコピーでは、文字とともにそのプロ パティが保持されます。これには‘substring’、‘insert’、 ‘buffer-substring’のようなさまざまな関数が含まれます。 31.19.1 テキストプロパティを調べる ---------------------------------- テキストプロパティを調べるもっともシンプルな方法は、特定の文字の特定のプ ロパティの値を尋ねる方法です。これを行うには‘get-text-property’を使用し ます。ある文字のプロパティリスト全体を取得するには‘text-properties-at’を 使用します。複数の文字のプロパティを一度に調べる関数については*note Property Search::を参照してください。 以下の関数は文字列とバッファーの両方を処理します。バッファー内の位置 は1から始まりますが、文字列内の位置は0から始まることに留意してください。 -- Function: get-text-property pos prop &optional object この関数はOBJECT (バッファーか文字列)内の位置POSの後にある文字のプ ロパティPROPの値をリターンする。引数OBJECTはオプションでありデフォ ルトはカレントバッファー。 厳密な意味でPROPプロパティは存在しないが、その文字がシンボルのプロ パティカテゴリーをもつなら、‘get-text-property’はそのシンボルの PROPプロパティをリターンする。 -- Function: get-char-property position prop &optional object この関数は‘get-text-property’と似ているが、まずオーバーレイをチェッ クして次にテキストプロパティをチェックする点が異なる。*note Overlays::を参照のこと。 引数OBJECTは文字列、バッファー、あるいはウィンドウかもしれない。ウ ィンドウならそのウィンドウ内に表示されているバッファーのテキストプ ロパティとオーバーレイが使用されるが、そのウィンドウにたいしてアク ティブなオーバーレイだけが考慮される。OBJECTがバッファーなら、その バッファー内のオーバーレイがまず優先的に考慮されて、その後にテキス トプロパティが考慮される。OBJECTが文字列なら文字列がオーバーレイを もつことは決してないのでテキストプロパティだけが考慮される。 -- Function: get-pos-property position prop &optional object この関数は‘get-char-property’と似ているが、POSITION (すぐ右)にある 文字のプロパティのかわりにプロパティのstickiness(粘着性)とオーバー レイのadvancement(前向的)のセッティングに注意を払う点が異なる。 -- Function: get-char-property-and-overlay position prop &optional object これは‘get-char-property’と似ているが、そのプロパティ値が由来するオ ーバーレイについて追加情報を与える点が異なる。 値はCARがプロパティ値であるようなコンスセルであり、これは同じ引数に より‘get-char-property’がリターンするであろう値と同じ。CDRはそのプ ロパティが見つかった箇所のオーバーレイ、テキストプロパティとして見 つかった場合や見つからなかった場合には‘nil’。 POSITIONがOBJECTの終端ならCARとCDRの値はどちらも‘nil’。 -- Variable: char-property-alias-alist この変数はプロパティ名と代替となるプロパティ名リストをマップする alistを保持する。文字があるプロパティにたいして直接値を指定しなけれ ば、順に代替プロパティ名が調べられて最初の非‘nil’値が使用される。こ の変数は‘default-text-properties’より優先されて、この変数より ‘category’プロパティが優先される。 -- Function: text-properties-at position &optional object この関数は文字列かバッファーOBJECT内の位置POSITIONにある文字のプロ パティリスト全体をリターンする。OBJECTが‘nil’ならデフォルトはカレン トバッファー。 -- Variable: default-text-properties この変数はテキストプロパティにたいしてデフォルト値を与えるプロパテ ィリストを保持する。あるプロパティにたいして文字が直接、あるいはカ テゴリーシンボルや‘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 31.19.2 テキストプロパティの変更 -------------------------------- プロパティを変更するプリミティブは、バッファーや文字列内の指定されたテキ スト範囲に適用されます。関数‘set-text-properties’ (セクションの最後を参 照)は、その範囲内のテキストのプロパティリスト全体をセットします。名前を 指定することにより特定のプロパティだけを追加、変更、削除するためにも有用 です。 テキストプロパティはバッファー(か文字列)のコンテンツの一部とみなされ 、かつスクリーン上でのバッファーの見栄えに影響を与えることができるので、 バッファー内のテキストプロパティの変更はすべてバッファーを変更済みとマー クします。バッファーテキストプロパティの変更もアンドゥできます(*note Undo::を参照)。バッファー内の位置は1から始まりますが、文字列内の位置は 0から始まります。 -- Function: put-text-property start end prop value &optional object この関数は文字列かバッファーOBJECT内のSTARTとENDの間のテキストにた いして、プロパティPROPにVALUEをセットする。OBJECTが‘nil’ならデフォ ルトはカレントバッファー。 -- Function: add-text-properties start end props &optional object この関数は文字列かバッファーOBJECT内のSTARTとENDの間のテキストにた いして、テキストプロパティを追加またはオーバーライドする。OBJECTが ‘nil’ならデフォルトはカレントバッファー。 引数PROPSには追加するプロパティを指定する。これはプロパティリストの 形式(*note Property Lists::を参照)、つまりプロパティ名と対応する値 が交互に出現するような要素を含むリストであること。 関数が実際に何らかのプロパティの値を変更したら‘t’、それ以外( PROPSが ‘nil’、またはプロパティの値がテキスト内のプロパティの値と一致してい る場合)は‘nil’がリターン値となる。 たとえば以下はテキストの範囲に‘comment’と‘face’のプロパティをセット する例: (add-text-properties START END '(comment t face highlight)) -- Function: remove-text-properties start end props &optional object この関数は文字列かバッファーOBJECT内のSTARTとENDの間のテキストから 、指定されたテキストプロパティを削除する。OBJECTが‘nil’ならデフォル トはカレントバッファー。 引数PROPSは削除するプロパティを指定する。これはプロパティリストの形 式(*note Property Lists::を参照)、つまりプロパティ名と対応する値が 交互に出現するような要素を含むリストであること。しかし問題となるの は名前であって付随する値は無視される。たとえば‘face’プロパティを削 除するには以下のようにすればよい。 (remove-text-properties START END '(face nil)) 関数が実際に何らかのプロパティの値を変更したら‘t’、それ以外( PROPSが ‘nil’、または指定されたテキスト内にそれらのプロパティをもつ文字がな い場合)は‘nil’がリターン値となる。 特定のテキストからすべてのテキストプロパティを削除するには、新たな プロパティリストに‘nil’を指定して‘set-text-properties’を使用すれば よい。 -- Function: remove-list-of-text-properties start end list-of-properties &optional object ‘remove-text-properties’と同様だが、LIST-OF-PROPERTIESがプロパティ 名と値が交互になったリストではなくプロパティ名だけのリストである点 が異なる。 -- Function: set-text-properties start end props &optional object この関数は文字列かバッファーOBJECT内のSTARTからENDの間のテキストに たいするテキストプロパティリストを完全に置き換える。OBJECTが‘nil’な らデフォルトはカレントバッファー。 引数PROPSは新たなプロパティリスト。これはプロパティ名と対応する値が 交互となるような要素のリストであること。 ‘set-text-properties’のリターン後には、指定された範囲内のすべての文 字は等しいプロパティをもつ。 PROPSが‘nil’なら、指定されたテキスト範囲からすべてのプロパティを取 り除く効果がある。以下は例: (set-text-properties START END nil) この関数のリターン値を信用してはならない。 -- Function: add-face-text-property start end face &optional appendp object この関数はSTARTとENDの間のテキストのテキストプロパティ‘face’にフェ イスFACEを追加するように動作する。FACEはフェイス名、もしくは anonymousフェイス(anonymous face: 無名フェイス)のような‘face’プロパ ティ(*note Special Properties::を参照)にたいして有効な値であること (*note Faces::を参照)。 リージョン内の任意のテキストがすでに非‘nil’の‘face’プロパティをもつ なら、それらのフェイスは保たれる。この関数は‘face’プロパティに、最 初の要素(デフォルト)がFACE、以前に存在していたフェイスが残りの要素 であるようなフェイスのリストをセットする。オプション引数APPENDが非 ‘nil’なら、FACEはかわりにリストの最後に追加される。フェイスリスト内 では各属性にたいして最初に出現する値が優先されることに注意。 たとえば以下のコードではSTARTとENDの間のテキストにグリーン斜体のフ ェイスを割り当てるだろう: (add-face-text-property START END 'italic) (add-face-text-property START END '(:foreground "red")) (add-face-text-property START END '(:foreground "green")) オプション引数OBJECTが非‘nil’なら、それはカレントバッファーではなく 動作するバッファーか文字列を指定する。OBJECTが文字列ならSTARTと ENDは0基準で文字列内をインデックス付けする。 文字列にテキストプロパティを付するもっとも簡単な方法は‘propertize’で す: -- Function: propertize string &rest properties この関数はテキストプロパティ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’については*note Buffer Contents::を参照 してください。 バッファーを未変更のままバッファーにテキストプロパティの追加や削除を 行いたければ、上記の呼出を‘with-silent-modifications’で囲むことができま す。 31.19.3 テキストプロパティの検索関数 ------------------------------------ テキストプロパティの通常の使用では、ほとんどの場合は複数または多くの連続 する文字が同じ値のプロパティをもちます。文字を1つずつ調べるプログラムを 記述するよりも、同じプロパティ値をもつテキスト塊(chunks of text)を処理す るほうがより高速です。 以下はこれを行うことに使用できる関数です。これらはプロパティ値の比較 に‘eq’を使用します。すべての関数においてOBJECTのデフォルトはカレントバッ ファーです。 より良いパフォーマンスのためには、特に単一のプロパティを検索する関数 におけるLIMIT引数の使用が重要です。さもないと興味のあるプロパティが変化 しない場合に、バッファー終端までのスキャンで長い時間を要するでしょう。 これらの関数はポイントを移動しません。そのかわりに位置(または‘nil’ )を リターンします。ポイントは常に文字と文字の間にあることを思い出してくださ い。これらの関数によりリターンされる位置は、異なるプロパティをもつ2つの 文字の間にあります。 -- Function: next-property-change pos &optional object limit この関数は文字列かバッファー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))) -- Function: previous-property-change pos &optional object limit これは‘next-property-change’と似ているが、POSから前方ではなく後方に スキャンする点が異なる。値が非‘nil’なら、それはPOS以下の位置。 LIMITとPOSが等しい場合のみPOSをリターンする。 -- Function: next-single-property-change pos prop &optional object limit この関数はプロパティPROP内の変化にたいしてテキストをスキャンして、 変化があった位置をリターンする。このスキャンは文字列かバッファー OBJECT内の位置POSから前方に行われる。言い換えるとPOSの直後の文字と プロパティPROPが等しくない、POSの先にある最初の文字の位置をリターン する。 LIMITが非‘nil’ならスキャンは位置LIMITで終了する。そのポイントより前 にプロパティの変化がなければ、‘next-single-property-change’は LIMITをリターンする。 プロパティがOBJECT終端まで変化せず、かつLIMITが‘nil’なら値は‘nil’。 値が非‘nil’なら、それはPOS以上の位置。LIMITがPOSと等しいときのみ値 はPOSになる。 -- Function: previous-single-property-change pos prop &optional object limit これは‘next-single-property-change’と似ているが、POSから前方ではな く後方にスキャンする点が異なる。値が非‘nil’なら、それはPOS以下の位 置。LIMITとPOSが等しい場合のみPOSをリターンする。 -- Function: next-char-property-change pos &optional limit ‘next-property-change’と似ているが、これはテキストプロパティと同様 にオーバーレイも考慮して、バッファー終端より前に変化が見つからなけ れば、‘nil’ではなくバッファー位置の最大をリターンする点が異なる(こ の点では‘next-property-change’よりも対応するオーバーレイ関数 ‘next-overlay-change’と似ている)。この関数はカレントバッファーだけ を処理するのでOBJECTオペランドは存在しない。これはいずれかの種類の プロパティが変化した、次のアドレスをリターンする。 -- Function: previous-char-property-change pos &optional limit これは‘next-char-property-change’と似ているが、POSから前方ではなく 後方へスキャンすること、および変化が見つからなければバッファー位置 の最小をリターンする点が異なる。 -- Function: next-single-char-property-change pos prop &optional object limit ‘next-single-property-change’と似ているが、これはテキストプロパティ と同様にオーバーレイも考慮して、OBJECT終端より前に変化が見つからな ければ、‘nil’ではなくOBJECT内の有効な位置の最大をリターンする点が異 なる。‘next-char-property-change’と異なり、この関数はOBJECTオペラン ドを_もつ_。OBJECTが非バッファーならテキストプロパティだけが考慮さ れる。 -- Function: previous-single-char-property-change pos prop &optional object limit これは‘next-single-char-property-change’と似ているが、POSから前方で はなく後方へスキャンすること、および変化が見つからなければOBJECT内 の有効な位置の最小をリターンする点が異なる。 -- Function: text-property-any start end prop value &optional object この関数はSTARTとENDの間に少なくともプロパティPROPに値VALUEをもつ文 字が1つあれば非‘nil’をリターンする。より正確には、これはそのような 最初の文字の位置、それ以外は‘nil’をリターンする。 5つ目のオプション引数OBJECTはスキャンする文字列かバッファーを指定す る。位置はOBJECTにたいして相対的。OBJECTのデフォルトはカレントバッ ファー。 -- Function: text-property-not-all start end prop value &optional object この関数はSTARTとENDの間に少なくともプロパティPROPに値VALUEをもたな い文字が1つあれば非‘nil’をリターンする。より正確には、これはそのよ うな最初の文字の位置、それ以外は‘nil’をリターンする。 5つ目のオプション引数OBJECTはスキャンする文字列かバッファーを指定す る。位置はOBJECTにたいして相対的。OBJECTのデフォルトはカレントバッ ファー。 31.19.4 特殊な意味をもつプロパティ ---------------------------------- 以下はビルトインで特別な意味をもつテキストプロパティ名のテーブルです。以 降のセクションではフィルとプロパティ継承を制御する特別なプロパティ名をい くつか追加でリストしています。これ以外のすべての名前は特別な意味をもたず 自由に使用できます。 注意: プロパティ‘composition’、‘display’、‘invisible’、‘intangible’は すべてのEmacsコマンドの後に好ましい箇所にポイントを移動させることもでき ます。*note Adjusting Point::を参照してください。 ‘category’ ある文字が‘category’プロパティをもつ場合には、それをその文字の“プロ パティカテゴリー(property category)”と呼ぶ。これはシンボルであるこ と。このシンボルのプロパティはその文字のプロパティのデフォルトとし ての役割をもつ。 ‘face’ ‘face’プロパティはその文字の外観を制御する(*note Faces::を参照)。こ のプロパティの値は以下が可能: • フェイス名(シンボルか文字列)。 • anonymousフェイス: ‘(KEYWORD VALUE ...)’形式のプロパティリスト 。KEYWORDはそれぞれフェイス属性名、VALUEはその属性の値。 • フェイスのリスト。各リスト要素はフェイス名かanonymousフェイス であること。これはリストされた各フェイス属性を集計したフェイス を指定する。このリスト内で最初にあるフェイスがより高い優先度を もつ。 • ‘(foreground-color . COLOR-NAME)’または‘(background-color . COLOR-NAME)’形式のコンスセル。これは‘(:foreground COLOR-NAME)’や‘(:background COLOR-NAME)’と同じようにフォアグラ ウンドやバックグラウンドを指定する。この形式は後方互換のためだ けにサポートされており無視すること。 Font Lockモード(*note Font Lock Mode::を参照)はほとんどのバッファー において、コンテキストにもとづき文字の‘face’プロパティを動的に更新 することにより機能する。 ‘add-face-text-property’関数は、このプロパティをセットする便利な手 段を提供する。*note Changing Properties::を参照のこと。 ‘font-lock-face’ このプロパティはFont Lockモードが配下にあるテキストに適用すべき ‘face’プロパティにたいして値を指定する。これはFont Lockモードに使用 されるフォント表示手法の1つであり、独自のハイライトを実装する特別な モードにたいして有用。*note Precalculated Fontification::を参照のこ と。Font Lockモードが無効なら‘font-lock-face’に効果はない。 ‘mouse-face’ このプロパティは文字上または近傍にマウスがあるとき、‘face’のかわり に使用される。この目的にたいして“近傍”とは文字とマウス位置の間のす べてのテキストが同じ‘mouse-face’プロパティの値をもつことを意味する 。 Emacsはテキストサイズ(‘:height’、‘:weight’、‘:slant’)を変更する ‘mouse-face’プロパティ由来の属性すべてを無視する。これらの属性はハ イライトされていないテキストと常に等しい。 ‘fontified’ このプロパティはそのテキストの表示準備が整っているかどうかを告げる 。‘nil’ならEmacsの再表示ルーチンはバッファーの該当部分を表示する前 に、準備のために‘fontification-functions’ (*note Auto Faces::を参照 )の中の関数を呼び出す。これはフォントロックのコードのjust-in-timeに より内部的に使用される。 ‘display’ このプロパティはテキストが表示される方法を変更するさまざまな機能を アクティブ化する。たとえばこれによりテキスト外観を縦長(taller)また は縦短(short)したり、高く(higher)または低く(lower)、太く(wider)また は細く(narrower)したり、あるいはイメージに置き換えることができる。 *note Display Property::を参照のこと。 ‘help-echo’ テキストが‘help-echo’プロパティに文字列をもつ場合には、そのテキスト 上にマウスを移動した際にEmacsはエコーエリアかツールチップウィンドウ (*note Tooltips::を参照)にその文字列を表示する。 ‘help-echo’プロパティの値が関数なら、その関数はWINDOW、OBJECT、 POSの3つの引数で呼び出されてヘルプ文字列、ヘルプ文字列が存在しなけ れば‘nil’をリターンすること。1つ目の引数WINDOWはそのヘルプが見つか ったウィンドウ。2つ目の引数OBJECTは‘help-echo’プロパティをもつバッ ファー、オーバーレイ、または文字列。POS引数は以下のとおり: • OBJECTがバッファーならPOSはそのバッファー内の位置。 • OBJECTがオーバーレイなら、そのオーバーレイは‘help-echo’プロパ ティをもちPOSはそのオーバーレイのバッファー内の位置。 • OBJECTが文字列(オーバーレイ文字列、または‘display’プロパティに より表示された文字列)ならPOSはその文字列内の位置。 ‘help-echo’プロパティの値が関数と文字列のいずれでもなければ、それは ヘルプ文字列を得るために評価される。 変数‘show-help-function’をセットすることにより、ヘルプテキストが表 示される方法を変更できる(*note Help display::を参照)。 この機能はモードライン内、およびその他のアクティブテキストにたいし て使用される。 ‘keymap’ ‘keymap’プロパティはコマンドにたいして追加のキーマップを指定する。 このキーマップを適用する際には、マイナーモードキーマップとバッファ ーのローカルマップの前に、このマップがキー照合のために使用される。 *note Active Keymaps::を参照のこと。プロパティ値がシンボルなら、そ のシンボルの関数定義がキーマップとして使用される。 ポイントの前の文字のプロパティの値は、それが非‘nil’でrear-stickyで あり、かつポイントの後の文字のプロパティ値が非‘nil’でfront-stickyな ら適用される(マウスクリックではポイント位置のかわりにクリック位置が 使用される)。 ‘local-map’ このプロパティは‘keymap’と同じように機能するが、これはそのバッファ ーのローカルマップの_かわりに_使用するキーマップを指定する点が異な る。ほとんど(もしかするとすべて)の目的にたいしては‘keymap’を使用す るほうが良いだろう。 ‘syntax-table’ ‘syntax-table’プロパティは特定の文字にたいしてどのシンタックステー ブルがオーバーライドするかを告げる。*note Syntax Properties::を参照 のこと。 ‘read-only’ ある文字がプロパティ‘read-only’をもつなら、その文字の変更は許可され ない。これを行おうとするすべてのコマンドは‘text-read-only’エラーを 受け取る。プロパティの値が文字列ならその文字列がエラーメッセージと して使用される。 read-only文字に隣接する箇所への挿入は、そこに通常のテキストの行うこ とがstickinessによる‘read-only’プロパティを継承するならエラーとなる 。つまりstickinessを制御することによりread-onlyテキストに隣接する挿 入の権限を制御することができる。*note Sticky Properties::を参照のこ と。 プロパティ変更はバッファー変更とみなされるので、特別なトリック (‘inhibit-read-only’を非‘nil’にバインドしてからプロパティを削除する )を知らないかぎり、‘read-only’プロパティを取り除くことは不可能。 *note Read Only Buffers::を参照のこと。 ‘inhibit-read-only’ プロパティ‘inhibit-read-only’をもつ文字はたとえ読み取り専用バッファ ーでも編集できる。*note Read Only Buffers::を参照のこと。 ‘invisible’ 非‘nil’の‘invisible’プロパティにより、スクリーン上で文字を不可視に できる。詳細は*note Invisible Text::を参照のこと。 ‘intangible’ 連続する文字のグループが非‘nil’の等しい‘intangible’プロパティをもつ なら、それらの文字の間にポイントを置くことは不可能。そのグループ内 に前方へポイントの移動を試みると、ポイントは実際にはそのグループの 終端に移動する。そのグループ内に後方へポイントの移動を試みると、ポ イントは実際にはそのグループの先頭に移動する。 連続する文字のグループが非‘nil’の等しくない‘intangible’プロパティを もつなら、それらの文字は個別のグループに属して、各グループは上述の ように別のグループとして扱われる。 変数‘inhibit-point-motion-hooks’が非‘nil’ (デフォルト)なら ‘intangible’プロパティは無視される。 注意せよ: このプロパティは非常に低レベルで処理されて、予想外の方法 により多くのコードに影響する。そのため使用に際しては特別な注意を要 する。誤った使用方法としては不可視のテキストにintangibleプロパティ をputするのが一般的な誤りであり、コマンドループは各コマンドの終わり に不可視テキストの外部へポイントを移動するだろうから、これは実際に は必要ない。*note Adjusting Point::を参照のこと。これらの理由により このプロパティは時代遅れであり、かわりに‘cursor-intangible’プロパテ ィを使用すること。 ‘cursor-intangible’ マイナーモード‘cursor-intangible-mode’がオンの際には、非‘nil’の ‘cursor-intangible’プロパティをもつすべての位置から、再表示の発生直 前にポイントが移動させられる。 ‘field’ 同じ‘field’プロパティをもつ連続する文字は“フィールド”を構成する。 ‘forward-word’や‘beginning-of-line’を含むいくつかの移動関数はフィー ルド境界で移動を停止する。*note Fields::を参照のこと。 ‘cursor’ カーソルは通常はカレントバッファー位置にあるオーバーレイ、およびテ キストプロパティ文字列の先頭か終端に表示される。文字に非‘nil’の ‘cursor’テキストプロパティを与えることにより、それら文字列内の任意 の望む文字にカーソルを置くことができる。加えて‘cursor’プロパティの 値が整数なら、それはカーソルがその文字上に表示されるようにオーバー レイまたは‘display’プロパティが始まる位置から数えたバッファーの文字 位置の数字を指定する。特にある文字の‘cursor’プロパティの値が数字Nな ら、カーソルは範囲‘[OVPOS..OVPOS+N)’内の任意のバッファー位置にある その文字上に表示されるだろう。ここでOVPOSは‘overlay-start’ (*note Managing Overlays::を参照)により与えられるオーバーレイ開始位置、ま たはそのバッファー内で‘display’プロパティが始まる位置である。 言い換えると文字列の非‘nil’値の‘cursor’プロパティをもつ文字はカーソ ルが表示される文字である。このプロパティの値はカーソルを表示するバ ッファーの位置を告げる。値が整数ならオーバーレイまたは‘display’プロ パティの始まりからN後ろの位置までの間にポイントがあるとき、カーソル はそこに表示される。値がそれ以外の非‘nil’ならポイントが‘display’プ ロパティの先頭、または‘overlay-start’の位置だけに表示される。 バッファーのテキストを網羅するオーバーレイ文字列(*note before-string: Overlay Properties.を参照)や文字列であるような ‘display’プロパティがバッファーに多くある場合には、それらの文字列を 走査する間にカーソルを置く箇所をEmacsに合図するために、‘cursor’プロ パティを使用するのはよいアイデアである。これはdisplayやオーバーレイ 文字列に“カバー”された何らかのバッファー位置にポイントがある際に、 Lispプログラムやユーザーがカーソルを配置したい箇所でディスプレイエ ンジンと直接通信する。 ‘pointer’ これはそのテキストやイメージ上にマウスポインターがあるときの特定の マウスシェイプを指定する。利用できるポインターシェイプについては *note Pointer Shape::を参照のこと。 ‘line-spacing’ 改行は改行で終わるディスプレイ行の高さを制御するテキストプロパティ やオーバーレイプロパティ‘line-spacing’をもつことができる。このプロ パティ値はデフォルトのフレーム行スペーシングと、バッファーローカル 変数‘line-spacing’をオーバーライドする。*note Line Height::を参照の こと。 ‘line-height’ 改行は改行で終わるディスプレイ行のトータル高さを制御するテキストプ ロパティ、またはオーバーレイプロパティ‘line-height’をもつことができ る。*note Line Height::を参照のこと。 ‘wrap-prefix’ テキストが‘wrap-prefix’プロパティをもつなら、それが定義するプレフィ クスはテキストラッピング(text wrapping: テキスト折り返し)に由来する すべての継続行の先頭に表示時に追加されるだろう(行が切り詰められた場 合にはwrap-prefixが使用されることはない)。これは文字列、イメージ (*note Other Display Specs::を参照)、あるいはディスプレイプロパティ ‘:width’や‘:align-to’ (*note Specified Space::を参照)により指定され た空白文字範囲かもしれない。 wrap-prefixはバッファーローカル変数‘wrap-prefix’を使用して、バッフ ァー全体にも指定され得る(が‘wrap-prefix’テキストプロパティは ‘wrap-prefix’変数の値より優先される)。*note Truncation::を参照のこ と。 ‘line-prefix’ テキストが‘line-prefix’プロパティをもつなら、それが定義するプレフィ クスは表示時にすべての非継続行の先頭に追加されるだろう。これは文字 列、イメージ(*note Other Display Specs::を参照)、あるいはディスプレ イプロパティ‘:width’や‘:align-to’ (*note Specified Space::を参照)に より指定された空白文字範囲かもしれない。 line-prefixはバッファーローカル変数‘line-prefix’を使用して、バッフ ァー全体にも指定され得る(が‘line-prefix’テキストプロパティは ‘line-prefix’変数の値より優先される)。*note Truncation::を参照のこ と。 ‘modification-hooks’ ある文字がプロパティ‘modification-hooks’をもつなら、その値は関数の リストであること。その文字の変更により、実際の変更前にそれらの関数 すべてが呼び出される。それぞれの関数は、変更されようとするバッファ ー部分の先頭と終端という2つの引数を受け取る。特定のmodificationフッ ク関数が単一のプリミティブにより変更されつつある複数の文字に出現す る場合は、その関数が呼び出される回数を予測することはできない。さら に挿入は既存の文字を変更しないので、このフックは文字の削除、他の文 字への置換、またはそれらのテキストプロパティ変更時のみ実行されるだ ろう。 これらの関数がバッファーを変更する場合には、これらのフックを呼び出 す内部的メカニズムの混乱を避けるために、それらの関数はそれを行う前 後に‘inhibit-modification-hooks’を‘t’にバインドすること。 オーバーレイも‘modification-hooks’プロパティをサポートするが詳細は 若干異なる(*note Overlay Properties::を参照)。 ‘insert-in-front-hooks’ ‘insert-behind-hooks’ あるバッファーへの挿入操作は後続文字の‘insert-in-front-hooks’プロパ ティ、および先行文字の‘insert-behind-hooks’プロパティにリストされる 関数の呼び出しも行う。これらの関数は挿入されるテキストの先頭と終端 という2つの引数を受け取る。関数は優先される実際の挿入が行われた_後 に_呼び出される。 バッファー内のテキスト変更時にに呼び出される他のフックについては *note Change Hooks::も参照のこと。 ‘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’のフック実行を抑制する。*note Inhibit point motion hooks::を参照のこと。 これらのプロパティは時代遅れであり、かわりに ‘cursor-sensor-functions’を使用してほしい。 ‘cursor-sensor-functions’ このスペシャルプロパティはカーソル移動に反応する関数リストを記録す る。このリスト内の各関数は影響を受けるウィンドウ、既知のカーソルの 以前の位置、このプロパティをもつテキストにカーソルが入ったか離れた かに依存するシンボル‘entered’か‘left’という3つの受け取って再表示の 直前に呼び出される。関数はマイナーモード‘cursor-sensor-mode’がオン のときのみ呼び出される。 ‘composition’ このテキストプロパティは文字シーケンスをコンポーネントから構成され る単一グリフ(single glyph)として表示するために使用される。しかしこ のプロパティの値自身は完全にEmacsの内部的なものであり、たとえば ‘put-text-property’などで直接操作しないこと。 -- Variable: inhibit-point-motion-hooks この時代遅れの変数が非‘nil’のときは、‘point-left’と ‘point-entered’のフックは実行されず‘intangible’プロパティは効果をも たない。この変数はグローバルにセットせず‘let’でバインドすること。こ の変数の影響を受けるプロパティは時代遅れなので、それらを効果的に無 効にするためにデフォルト値は‘t’。 -- Variable: show-help-function この変数が非‘nil’なら、それはヘルプ文字列を表示するために呼び出され る関数を指定する。これらは‘help-echo’プロパティ、メニューヘルプ文字 列(*note Simple Menu Items::と*note Extended Menu Items::を参照)、 ツールバーヘルプ文字列(*note Tool Bar::を参照)かもしれない。指定さ れた関数は表示するためのヘルプ文字列(この関数に与えられる前に ‘substitute-command-keys’に渡される。*note Keys in Documentation::を 参照)という単一の引数とともに呼び出される。Tooltipモード(*note (emacs)Tooltips::を参照)が例を提供している。 31.19.5 Formatted Text Properties --------------------------------- 以下のテキストプロパティはフィルコマンドの挙動に影響を与えます。これらは フォーマットされたテキストを表すために使用されます。*note Filling::と *note Margins::を参照してください。 ‘hard’ 改行文字がこのプロパティをもつならそれは“hard”改行。フィルコマンド はhard改行を変更せずそれらを横断して単語を移動しない。しかしこのプ ロパティはマイナーモード‘use-hard-newlines’が有効な場合のみ影響を与 える。*note Hard and Soft Newlines: (emacs)Hard and Soft Newlines.を 参照のこと。 ‘right-margin’ このプロパティはその部分のテキストのフィルにたいして余分な右マージ ンを指定する。 ‘left-margin’ このプロパティはその部分のテキストのフィルにたいして余分な左マージ ンを指定する。 ‘justification’ このプロパティはその部分のテキストのフィルにたいして位置揃え (justification)のスタイルを指定する。 31.19.6 テキストプロパティの粘着性 ---------------------------------- ユーザーがそれらをタイプした際にはバッファーに挿入される自己挿入文字 (*note Commands for Insertion::を参照)は、通常は先行する文字と同じプロパ ティをもちます。これはプロパティの“継承(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なプロパティは名 前がそのリスト内に_ない_プロパティです。 -- Variable: text-property-default-nonsticky この変数はさまざまなテキストプロパティのデフォルトの 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より優先される。 以下はプロパティ継承つきでテキストを挿入する関数です: -- Function: insert-and-inherit &rest strings 関数‘insert’と同じように文字列STRINGSを挿入するが、隣接するテキスト からすべてのstickyなプロパティを継承する。 -- Function: insert-before-markers-and-inherit &rest strings 関数‘insert-before-markers’と同じように文字列STRINGSを挿入するが、 隣接するテキストからすべてのstickyなプロパティを継承する。 継承を行わない通常の挿入関数については*note Insertion::を参照してくだ さい。 31.19.7 テキストプロパティのlazyな計算 -------------------------------------- バッファー内のすべてのテキストにたいしてテキストプロパティを計算するかわ りに、何かがテキスト範囲に依存している場合にはテキストプロパティを計算す るようにアレンジできます。 プロパティとともにバッファーからテキストを抽出するプリミティブは ‘buffer-substring’です。この関数はプロパティを調べる前にアブノーマルフッ ク‘buffer-access-fontify-functions’を実行します。 -- Variable: buffer-access-fontify-functions この変数はテキストプロパティ計算用の関数のリストを保持する。 ‘buffer-substring’がバッファーの一部のテキストとテキストプロパティ をコピーする前にこのリスト内の関数すべてを呼び出す。各関数はアクセ スされるバッファー範囲を指定する2つの引数を受け取る(バッファーは常 にカレントバッファー)。 関数‘buffer-substring-no-properties’はいずれにせよテキストプロパティ を無視するので、これらの関数を呼び出さない。 同じバッファー部分にたいして複数回フック関数が呼び出されるのを防ぐた めに変数‘buffer-access-fontified-property’を使用できる。 -- Variable: buffer-access-fontified-property この変数の値が非‘nil’なら、それはテキストプロパティ名として使用され るシンボル。そのテキストプロパティにたいする非‘nil’値は、その文字に たいする他のテキストプロパティはすでに計算済みであることを意味する 。 ‘buffer-substring’にたいして指定された範囲内のすべての文字、このプ ロパティにたいする値として非‘nil’をもつなら、‘buffer-substring’は ‘buffer-access-fontify-functions’の関数を呼び出さない。それらの文字 がすでに正しいテキストプロパティをもつとみなして、それらがすでに所 有するプロパティを単にコピーする。 ‘buffer-access-fontify-functions’の関数にこのプロパティ、同様に他の プロパティを処理対象の文字に追加させることがこの機能の通常の用途で ある。この方法では同じテキストにたいして、それらの関数が何度も呼び 出されるのを防ぐことができる。 31.19.8 クリック可能なテキストの定義 ------------------------------------ “クリック可能テキスト(clickable text)”とは何らかの結果を生成するためにマ ウスやキーボードコマンドを通じてクリックできるテキストです。多くのメジャ ーモードがテキスト的なハイパーリンク、略して“リンク(link)”を実装するため にクリック可能テキストを使用しています。 リンクの挿入や操作を行うもっとも簡単な方法は‘button’パッケージの使用 です。*note Buttons::を参照してください。このセクションではテキストプロ パティを使用してバッファー内に手作業でクリック可能テキストをセットアップ する方法を説明します。簡略にするためにクリック可能テキストを“リンク”と呼 ぶことにします。 リンクの実装には、(1)リンク上にマウスが移動した際にクリック可能である ことを示し、(2)そのリンク上のか‘mouse-2’で何かを行うようにして、 (3)そのリンクが‘mouse-1-click-follows-link’にしたがうよう‘follow-link’を セットアップする、という3つのステップが含まれます。 クリック可能なことを示すためには、そのリンクのテキストに ‘mouse-face’プロパティを追加します。するとEmacsはそれ以降マウスがその上 に移動した際にリンクをハイライトするでしょう。加えて‘help-echo’テキスト プロパティを使用してツールチップかエコーエリアメッセージを定義するべきで す。*note Special Properties::を参照してください。たとえば以下は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"))) リンクをクリック可能にするためには、 と‘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’プロパティ(*note Special Properties::を参照)を使用してリンクテキ スト内でバインドできます。たとえば: (let ((map (make-sparse-keymap))) (define-key map [mouse-2] 'operate-this-button) (put-text-property link-start link-end 'keymap map)) この手法により異なるリンクに異なるコマンドを簡単に定義できます。さらにそ のバッファー内の残りのテキストにたいしては、と‘mouse-2’のグローバル 定義を利用可能なまま残すことができます。 リンク上でのクリックにたいするEmacsの基本コマンドは‘mouse-2’です。し かし他のグラフィカルなアプリケーションとの互換性のために、ユーザーがマウ スを動かさずに素早くリンクをクリックするという条件の下で、Emacsはリンク 上での‘mouse-1’クリックも認識します。この振る舞いはユーザーオプション ‘mouse-1-click-follows-link’により制御されます。*note (emacs)Mouse References::を参照してください。 ‘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モードがを処理する例: (define-key Info-mode-map [follow-link] 'mouse-face) 関数 コンディションが関数FUNCの場合には、‘(FUNC POS)’が非‘nil’に評価され れば、位置POSはリンクの内側。FUNCがリターンする値はアクションコード として機能する。 以下はpcvsがファイル名の上でのみ‘mouse-1’によるリンクのフォローを有 効にする方法の例: (define-key map [follow-link] (lambda (pos) (eq (get-char-property pos 'face) 'cvs-filename-face))) その他 コンディション値がそれ以外の場合には、その位置はリンク内側であり、 そのコンディション自体がアクションコード。(バッファー全体に適用され ないように)リンクテキストのテキストプロパティかオーバーレイプロパテ ィを通じてコンディションを適用するときのみ、この類のコンディション を指定すべきなのは明確である。 アクションコードは‘mouse-1’がリンクをフォローする方法を告げます: 文字列かベクター アクションコードが文字列かベクターなら、‘mouse-1’イベントは文字列か ベクターの最初の要素に変換される。つまり‘mouse-1’クリックのアクショ ンはその文字、またはシンボルのローカルかグローバルのバインディング 。したがってアクションコードが‘"foo"’なら、‘mouse-1’は‘f’、 ‘[foo]’なら‘mouse-1’はに変換される。 その他 その他の非‘nil’のアクションコードでは、‘mouse-1’イベントは同じ位置 の‘mouse-2’イベントに変換される。 ‘define-button-type’で定義されるボタンをアクティブにするように ‘mouse-1’を定義するには、そのボタンに‘follow-link’プロパティを与えます。 このプロパティの値は上述したリンクのアクションコンディションであるべきで す。*note Buttons::を参照のこと。たとえば以下はHelpモードが‘Mouse-1’を処 理する例です。 (define-button-type 'help-xref 'follow-link t 'action #'help-button-action) ‘define-widget’で定義されたウィジェットに‘mouse-1’を定義するには、そ のウィジェットに‘:follow-link’プロパティを与えます。このプロパティの値は 、上述したようなリンクのアクションコンディションであるべきです。たとえば 以下はクリックがに変換されるように‘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%]") -- Function: mouse-on-link-p pos この関数はカレントバッファー内の位置POSがリンク上なら非‘nil’をリタ ーンする。POSは‘event-start’がリターンするようなマウスイベント位置 でもよい(*note Accessing Mouse::を参照)。 31.19.9 フィールドの定義と使用 ------------------------------ フィールドとはバッファー内にある連続する文字範囲であり、‘field’プロパテ ィ(テキストプロパティかオーバーレイプロパティ)に同じ値(‘eq’で比較)をもつ ことにより識別されます。このセクションではフィールドの操作に利用できるス ペシャル関数を説明します。 フィールドはバッファー位置POSで指定します。各フィールドはバッファー位 置の範囲を含むと考えて、指定した位置はその位置を含むフィールドを表します 。 POSの前後の文字は同じフィールドに属し、どのフィールドがPOSを含むかと いう疑問はありません。それらの文字が属するフィールドがそのフィールドです 。POSがフィールド境界のときは、それがどのフィールドに属すかは、取り囲む 2つの文字の‘field’プロパティのstickinessに依存します(*note Sticky Properties::を参照)。POSに挿入されたテキストからプロパティが継承されたフ ィールドがPOSを含むフィールドです。 POSに新たに挿入されたテキストが、いずれの側からも‘field’プロパティを 継承しない異常なケースがあります。これは前の文字の‘field’プロパティが rear-stickyでなく、後の文字の‘field’プロパティがfront-stickyでもない場合 に発生します。このケースではPOSは前後のフィールドいずれにも属しません。 フィールド関数はそれを、開始と終了がPOSであるような空フィールドに属する ものとして扱います。 以下のすべての関数では、POSが省略か‘nil’ならポイントの値がデフォルト として使用されます。ナローイング(narrowing)が効力をもつ場合には、POSはア クセス可能部分にあるはずです。*note Narrowing::を参照してください。 -- Function: field-beginning &optional pos escape-from-edge limit この関数はPOSで指定されたフィールドの先頭をリターンする。 POSが自身のフィールド先頭にあり、かつESCAPE-FROM-EDGEが非‘nil’なら 、POS周辺の‘field’プロパティのstickinessに関わらず、リターン値は常 にPOSが終端であるような、前にあるフィールドの先頭になる。 LIMITが非‘nil’なら、それはバッファーの位置。そのフィールドの先頭が LIMITより前なら、かわりにLIMITがリターンされるだろう。 -- Function: field-end &optional pos escape-from-edge limit この関数はPOSで指定されるフィールドの終端をリターンする。 POSが自身のフィールド終端にあり、かつESCAPE-FROM-EDGEが非‘nil’なら 、POS周辺の‘field’プロパティのstickinessに関わらず、リターン値は常 にPOSが_先頭_であるような後のフィールドの終端になる。 LIMITが非‘nil’なら、それはバッファーの位置である。そのフィールドの 終端がLIMITより後なら、かわりにLIMITがリターンされるだろう。 -- Function: field-string &optional pos この関数はPOSで指定されるフィールドのコンテンツを文字列としてリター ンする。 -- Function: field-string-no-properties &optional pos この関数はPOSで指定されるフィールドのコンテンツを、テキストプロパテ ィを無視して文字列としてリターンする。 -- Function: delete-field &optional pos この関数はPOSで指定されるフィールドのテキストを削除する。 -- Function: constrain-to-field new-pos old-pos &optional escape-from-edge only-in-line inhibit-capture-property この関数は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’にすべてのフィールド境界を無視(何者にも拘束さ れることがない)させることができる。 31.19.10 なぜテキストプロパティはインターバルではないのか --------------------------------------------------------- ユーザーにテキスト内のインターバル(訳注: 原文のインターバルはIT用語とし ては時間や距離などの間隔を示す用語として用いれることが多いと思いますが、 ここでは『範囲』を示す言葉として用いられているようです。他の箇所で『範囲 』と訳したrange等と異なる機能なので、ここではそのまま『インターバル』と しました)を指定させて、そのインターバルにプロパティを追加するために、バ ッファー内のテキストへの属性の追加をサポートするエディターがいくつかあり ます。それらのエディターはユーザーやプログラマーが個別にインターバルの開 始と終了を決定することを許可します。わたしたちはテキスト変更に関連する特 定の逆説的振る舞いを避けるために、故意に異なる種類のインターフェイスを Emacs Lisp内に提供しました。 複数のインターバルに細分化することが実際に意味をもつなら、それは特定 のプロパティをもつ単一のインターバルのバッファーと、同じテキストをもち両 方が同じプロパティをもつ2つのインターバルに分割されたバッファーを区別で きることを意味します。 インターバルを1つだけもつバッファーがあり、その一部をkillすることを考 えてみてください。そのそのバッファーに残されるのは1つのインターバルであ り、killリング(とundoリスト)内のコピーは別個のインターバルになります。そ のkillされたテキストをyankで戻すと、同じプロパティをもつ2つのインターバ ルを得ることになります。したがって編集では1つのインターバルと2つのインタ ーバルの違いは保たれません。 テキスト挿入時に2つのインターバルを結合することにより、この問題に“対 応”したとします。これはそのバッファーが元々単一のインターバルだったなら 上手く機能します。 しかしかわりに同じプロパティをもつ隣接する2つのインタ ーバルがあり、そのうちの1つのインターバルからテキストをkillしてyankで戻 すことを考えてみてください。あるケースを解決する同じインターバル結合機能 が、他のケースにおいては問題を引き起こすのです。このyank後にインターバル はただ1つとなります。繰り返します、編集では1つのインターバルと2つのイン ターバルの違いは保たれないのです。 インターバルの間の境界上へのテキスト挿入においても満足できる回答が存 在しないような問題が発生します。 しかし“バッファーにあるテキスト位置または文字列位置のプロパティは何か ?”という形式の問にたいして、編集が一貫した振る舞いをするようアレンジする のは簡単です。そこでわたしたちはこれらが合理的な唯一の問いであると判断し たのです。わたしたちはインターバルの開始と終了の場所を問うような実装をし ませんでした。 実際には明白にインターバル境界であるような箇所では、通常はテキストプ ロパティ検索関数を使用できます。可能であるならインターバルは常に結合され るとみなすことにより、それらがインターバル境界を探すと考えることができま す。*note Property Search::を参照してください。 Emacsはプレゼンテーション機能として明示的なインターバルも提供します。 *note Overlays::を参照してください。 31.20 文字コードの置き換え ========================== 以下の関数は文字コードにもとづいて指定されたリージョン内の文字を置き換え ます。 -- Function: subst-char-in-region start end old-char new-char &optional noundo この関数はSTARTとENDで定義されるカレントバッファーのリージョン内に 出現する文字OLD-CHARをNEW-CHARに置き換える。 NOUNDOが非‘nil’なら‘subst-char-in-region’はundo用に変更を記録せず、 バッファーを変更済みとマークしない。これは古い機能である選択的ディ スプレイ(*note Selective Display::を参照)にとって有用だった。 ‘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 ---------- -- Command: translate-region start end table この関数はバッファー内の位置STARTとENDの間の文字にたいして、変換テ ーブル(translation table)を適用する。 変換テーブルTABLEは文字列か文字テーブル。‘(aref TABLE OCHAR)’は OCHARに対応した変換後の文字を与える。TABLEが文字列なら、TABLEの長さ より大きいコードの文字はこの変更により変更されない。 ‘translate-region’のリターン値は、その変換により実際に変更された文 字数。変換テーブル内でその文字自身にマップされる文字は勘定に入らな い。 31.21 レジスター ================ レジスター(register)とは、Emacs内の編集においてさまざまな異なる種類の値 を保持できる一種の変数です。レジスターはそれぞれ1文字で命名されます。す べてのASCII文字、およびそれらのメタ修飾された変種(ただし‘C-g’は例外)をレ ジスターの命名に使用できます。したがって利用可能なレジスター数は255にな ります。Emacs Lispではレジスターは自身の名前となるその文字により指定され ます。 -- Variable: register-alist この変数は要素が‘(NAME .CONTENTS)’という形式のalist。使用中の Emacsレジスターごとに通常は1つの要素が存在する。 オブジェクトNAMEはレジスターを識別する文字(整数)。 レジスターのCONTENTSには、いくつかのタイプがある: 数字 数字はそれ自身を意味する。‘insert-register’はレジスター内の数字を探 して10進数に変換する。 マーカー マーカーはジャンプ先のバッファー位置を表す。 文字列 文字列の場合はレジスター内に保存されたテキスト。 矩形(rectangle) 矩形は文字列のリストを表す。 ‘(WINDOW-CONFIGURATION POSITION)’ これは1つのフレームにリストアされるウィンドウ構成、およびカレントバ ッファー内のジャンプ先の位置を表す。 ‘(FRAME-CONFIGURATION POSITION)’ これはリストア用のフレーム構成とカレントバッファー内のジャンプ先の 位置。 (file FILENAME) これはvisitするファイルを表し、この値にジャンプすることによりファイ ルFILENAMEをvisitする。 (file-query FILENAME POSITION) これはvisitするファイルとファイル内の位置を表す。この値にジャンプす ることによりファイルFILENAMEをvisitしてバッファー位置POSITIONに移動 する。このタイプの位置をリストアすると、まずユーザーにたいして確認 を求める。 このセクションの関数は特に明記しない限り予期せぬ値をリターンします。 -- Function: get-register reg この関数はレジスターREGのコンテンツ、コンテンツがなければ‘nil’をリ ターンする。 -- Function: set-register reg value この関数はレジスターREGのコンテンツにVALUEをセットする。レジスター には任意の値をセットできるが、その他のレジスター関数は特定のデータ 型を期待する。リターン値はVALUE。 -- Command: view-register reg このコマンドはレジスターREGに何が含まれているかを表示する。 -- Command: insert-register reg &optional beforep このコマンドはカレントバッファーにレジスターREGのコンテンツを挿入す る。 このコマンドは通常は挿入したテキストの前にポイント、後にマークを配 置する。しかしオプションの第2引数BEFOREPが非‘nil’ならマークを前、ポ イントを後に配置する。インタラクティブな呼び出しでは、プレフィクス 引数を与えることにより2つ目の引数BEFOREPに‘nil’を渡すことができる。 このコマンドはインタラクティブに呼び出された際には、デフォルトでは テキストの後にポイントを配置して、プレフィクス引数を与えるとこの反 対の振る舞いを行う。 レジスターに矩形が含まれる場合には、その矩形はポイントの左上隅に挿 入される。これはそのテキストがカレント行と、その下に続く行に挿入さ れることを意味する。 レジスターが保存されたテキスト(文字列)または矩形(リスク)以外の何か を含む場合には、現在のところは役に立つようなことは起きない。これは 将来変更されるかもしれない。 -- Function: register-read-with-preview prompt この関数はPROMPT、およびもしかしたら既存レジスターとそのコンテンツ をプレビューしてレジスターの名前を読み取ってレジスター名をリターン する。このプレビューはユーザーオプション‘register-preview-delay’と ‘register-alist’がいずれも非‘nil’なら、‘register-preview-delay’で指 定された遅延の後に一時ウィンドウ内に表示される。このプレビューはユ ーザーが(たとえばヘルプ文字のタイプにより)ヘルプを要求した場合にも 表示される。レジスター名を読み取るンタラクティブな関数には、この関 数の使用を推奨する。 31.22 テキストの交換 ==================== 以下の関数はテキストの一部を置き換えるために使用できます: -- Function: transpose-regions start1 end1 start2 end2 &optional leave-markers この関数はバッファーの重複しない2つの部分を交換する。引数START1と END1は一方の部分の両端、引数START2とEND2はもう一方の部分の両端を指 定する。 ‘transpose-regions’は通常は置き換えたテキストにともないマーカーを再 配置する。以前は2つの置き換えたテキストのうちの一方の部分に位置して いたマーカーは、その部分とともに移動されるので、それを挟む2つの文字 の新たな位置の間に留まることになる。しかしLEAVE-MARKERSが非‘nil’な ら、‘transpose-regions’はこれを行わず、すべてのマーカーを再配置せず に残す。 31.23 圧縮されたデータの処理 ============================ ‘auto-compression-mode’が有効なときは、Emacsは圧縮されたファイルを visitする際に自動的に解凍して、それを変更して保存する際は自動的に再圧縮 します。*note (emacs)Compressed Files::を参照してください。 上記の機能は外部の実行可能ファイル(例: ‘gzip’)を呼び出すことにより機 能します。zlibライブラリーを使用したビルトインの解凍サポートつきで Emacsをコンパイルすることもでき、これは外部プログラムの実行に比べて高速 です。 -- Function: zlib-available-p この関数はビルトインzlib解凍が利用可能なら非‘nil’をリターンする。 -- Function: zlib-decompress-region start end この関数はビルトインのzlib解凍を使用してSTARTとENDの間のリージョン を解凍する。このリージョンにはgzipかzlibで圧縮されたデータが含まれ ていなければならない。成功したら、この関数はリージョンのコンテンツ を解凍されたデータに置き換える。失敗すると関数はリージョンを未変更 のまま‘nil’をリターンする。この関数はユニバイトバッファーでのみ呼び 出すことができる。 31.24 Base 64エンコーディング ============================= Base64コードは8ビットシーケンスをより長いASCIIグラフィック文字シーケンス にエンコードするためにemail内で使用されます。これはインターネット RFC2045で定義されます(1)。このセクションでは、このコードへの変換および逆 変換を行う関数について説明します。 -- Command: base64-encode-region beg end &optional no-line-break この関数はBEGからENDのリージョンをBase64コードに変換する。これはエ ンコードされたテキストの長さをリターンする。リージョン内の文字がマ ルチバイトならエラーをシグナルする(マルチバイトバッファーではリージ ョンには‘ascii’、‘eight-bit-control’、‘eight-bit-graphic’の文字以外 は含まれてはならない)。 この関数は通常は行が長くなりすぎるのを防ぐために、エンコードされた テキストに改行を挿入する。しかしオプション引数NO-LINE-BREAKが非 ‘nil’なら、これらの改行は追加されず出力は長い単一の行となる。 -- Function: base64-encode-string string &optional no-line-break この関数は文字列STRINGをBase64コードに変換する。これはエンコードさ れたテキストを含む文字列をリターンする。‘base64-encode-region’と同 じように文字列内の文字がマルチバイトならエラーをシグナルする。 この関数は通常は行が長くなりすぎるのを防ぐためにエンコードされたテ キストに改行を挿入する。しかしオプション引数NO-LINE-BREAKが非 ‘nil’なら、これらの改行は追加されず結果となる文字列は長い単一の行と なる。 -- Command: base64-decode-region beg end この関数はBEGからENDのリージョンのBase64コードを対応するデコードさ れたテキストに変換する。これはデコードされたテキストの長さをリター ンする。 デコード関数はエンコード済みテキスト内の改行文字を無視する。 -- Function: base64-decode-string string この関数は文字列STRINGを、Base64コードから対応するデコード済みテキ ストに変換する。これはデコード済みテキストを含むユニバイトをリター ンする。 デコード関数はエンコード済みテキスト内の改行文字を無視する。 ---------- Footnotes ---------- (1) RFC(“Request for Comments”の略)とは標準を記述するナンバーが付与さ れたインターネット情報提供ドキュメントです。RFCは通常は自身が先駆的に活 動する技術エキスパートによって記述され、伝統として現実的で経験主導で記述 されます。 31.25 チェックサムとハッシュ ============================ Emacsには“暗号化ハッシュ(cryptographic hashes)”計算用のビルトインのサポ ートがあります。暗号化ハッシュ、または“チェックサム(checksum)”とはデータ 断片にたいするデジタルな指紋(fingerprint)であり、そのデータが変更されて いないかチェックするために使用できます。 EmacsはMD5、SHA-1、SHA-2、SHA-224、SHA-256、SHA-384、SHA-512のような 一般的な暗号化ハッシュアルゴリズムをサポートします。これらのアルゴリズム のうちMD5はもっとも古く、ネットワーク越しに転送されたメッセージの整合性 をチェックするために一般的には“メッセージダイジェスト(message digests)”内 で使用されています。MD5は‘衝突耐性(collision resistant)をもたない(同じ MD5ハッシュをもつ異なるデータ片を故意にデザインすることが可能)ので、セキ ュリティに関連することに使用するべきではありません。同様な理論上の欠点は SHA-1にも存在します。したがってセキュリティに関連するアプリケーションに たいしては、SHA-2のような他のハッシュタイプを使用するべきです。 -- Function: secure-hash algorithm object &optional start end binary この関数はOBJECTにたいするハッシュをリターンする。引数ALGORITHMはど のハッシュを計算するかを示すシンボルで‘md5’、‘sha1’、‘sha224’、 ‘sha256’、‘sha384’、‘sha512’のいずれか。引数OBJECTはバッファーまた は文字列であること。 オプション引数STARTとENDは、メッセージダイジェストを計算する OBJECT部分を指定する文字位置。これらが‘nil’か省略なら、OBJECT全体に たいしてハッシュを計算する。 引数BINARYが省略か‘nil’なら、通常のLisp文字列としてハッシュの“テキ スト形式(text form)”をリターンする。BINARYが非‘nil’なら、ユニバイト 文字列に格納されたバイトシーケンスとしてハッシュの“バイナリー形式 (binary form)”をリターンする。 この関数はOBJECTのテキストの内部表現(*note Text Representations::を 参照)からハッシュを直接計算しない。かわりにコーディングシステム (*note Coding Systems::を参照)を使用してテキストをエンコードして、 そのエンコード済みテキストからハッシュを計算する。OBJECTがバッファ ーなら使用されているコーディングが、そのテキストをファイルに書き込 むためのデフォルトとして選択される。OBJECTが文字列ならユーザーの好 むコーディングシステムが使用される(*note (emacs)Recognize Coding::を 参照)。 -- Function: md5 object &optional start end coding-system noerror この関数はMD5ハッシュをリターンする。これはほとんどの目的において、 ALGORITHM引数に‘md5’を指定して‘secure-hash’を呼び出すのと等価であり 半ば時代遅れである。引数のOBJECT、START、ENDは‘secure-hash’のときと 同じ意味をもつ。 CODING-SYSTEMが非‘nil’なら、それはテキストをエンコードするために使 用するコーディングシステムを指定する。省略または‘nil’なら、 ‘secure-hash’と同様にデフォルトコーディングシステムが使用される。 ‘md5’は通常は指定や選択されたコーディングシステムを使用してテキスト をエンコードできなければエラーをシグナルする。しかしNOERRORが非 ‘nil’なら、かわりに黙って‘raw-text’コーディングシステムを使用する。 31.26 HTMLとXMLの解析 ===================== Emacsがlibxml2サポートつきでコンパイルされたときは、HTMLやXMLのテキスト をLispオブジェクトツリーにパースするために以下の関数が利用可能です。 -- Function: libxml-parse-html-region start end &optional base-url discard-comments この関数はSTARTとENDの間のテキストをHTMLとしてパースして、HTML“パー スツリー(parse tree)”を表すリストをリターンする。これは構文誤りにた いして強力に対処することにより、現実世界のHTMLの処理を試みる。 オプション引数BASE-URLが非‘nil’なら、それはリンク内に出現する相対 URLにたいするベースURLを指定する文字列であること。 オプション引数DISCARD-COMMENTSが非‘nil’なら、パースツリーはコメント なしで作成される。 パースツリー内では各HTMLノードは1つ目の要素がノード名を表すシンボル 、2つ目の要素がノード属性のalist、残りの要素はサブノードであるよう なリストにより表される。 以下の例でこれを示す。以下の(不正な)HTMLドキュメントを与えると:
Foo
Yes ‘libxml-parse-html-region’呼び出しにより以下のDOM (document object model)がリターンされる: (html nil (head nil) (body ((width . "101")) (div ((class . "thing")) "Foo" (div nil "Yes")))) -- Function: shr-insert-document dom この関数はDOM内のパース済みHTMLをカレントバッファー内に描画する。引 数DOMは‘libxml-parse-html-region’で生成されるようなリストであること 。この関数はたとえば*note EWW: (eww)Top.により使用される。 -- Function: libxml-parse-xml-region start end &optional base-url discard-comments この関数は‘libxml-parse-html-region’と同様だが、HTMLではなくXML(構 文についてより厳格)としてテキストをパースする点が異なる。 31.26.1 Document Object Model ----------------------------- ‘libxml-parse-html-region’ (およびその他のXMLパース関数)がリターンする DOMはツリー構造です。このツリー構造ではそれぞれのノードがノード名(“タグ (tag)”と呼ばれる)をもち、オプションでkey/value値からなる“属性 (attribute)”リスト、その後に“子ノード(child nodes)”が続きます。子ノード は文字列かDOMオブジェクトのいずれかです。 (body ((width . "101")) (div ((class . "thing")) "Foo" (div nil "Yes"))) -- Function: dom-node tag &optional attributes &rest children この関数はタイプTAGのDOMノードを作成する。もしATTRIBUTESが与えられ たら、それはkey/valueペアのリストであること。もしCHILDRENが与えられ たら、それはDOMノードであること。 この構造を処理するために以下の関数を使用できます。それぞれの関数は DOMノードかノードのリストを受け取ります。後者の場合には、そのリストの最 初のノードだけが使用されます。 シンプルなアクセサー ‘dom-tag NODE’ ノードの“タグ” (“ノード名”とも呼ばれる)をリターンする。 ‘dom-attr NODE ATTRIBUTE’ ノードの属性の値をリターンする。以下は一般的な使用例: (dom-attr img 'href) => "http://fsf.org/logo.png" ‘dom-children NODE’ ノードのすべての子をリターンする。 ‘dom-non-text-children NODE’ ノードのすべての非文字列の子をリターンする。 ‘dom-attributes NODE’ ノードの属性のkey/valueペアのリストをリターンする。 ‘dom-text NODE’ ノードのすべてのテキスト的な要素を連結された文字列としてリターンす る。 ‘dom-texts NODE’ ノードのすべてのテキスト的な要素、およびノードのすべての子のテキス ト的な要素を、連結された文字列として再帰的にリターンする。この関数 はテキスト的な要素の間に挿入するオプションのセパレーターも受け取る 。 ‘dom-parent DOM NODE’ DOM内でのNODEの親をリターンする。 以下はDOMを変更するための関数です。 ‘dom-set-attribute NODE ATTRIBUTE VALUE’ ノードのATTRIBUTEにVALUEをセットする。 ‘dom-append-child NODE CHILD’ NODEの最後の子としてCHILDを追加する。 ‘dom-add-child-before NODE CHILD BEFORE’ NODEの子リストのノードBEFOREの前にCHILDを追加する。BEFOREが‘nil’な ら、CHILDが最初の子になる。 ‘dom-set-attributes NODE ATTRIBUTES’ ノードのすべての属性を新たなkey/valueリストに置き換える。 以下はDOM内の要素を検索する関数です。これらはマッチしたノードのリスト をリターンします。 ‘dom-by-tag DOM TAG’ DOM内のタイプがTAGのすべてのノードをリターンする。典型的な使用例は: (dom-by-tag dom 'td) => '((td ...) (td ...) (td ...)) ‘dom-by-class DOM MATCH’ DOM内のクラス名が正規表現MATCHにマッチするすべてのノードをリターン する。 ‘dom-by-style DOM STYLE’ DOM内のスタイルが正規表現MATCHにマッチするすべてのノードをリターン する。 ‘dom-by-id DOM STYLE’ DOM内のIDが正規表現MATCHにマッチするすべてのノードをリターンする。 ‘dom-strings DOM’ DOM内のすべての文字列をリターンする。 ユーティリティ関数: ‘dom-pp DOM &optional REMOVE-EMPTY’ ポイント位置のDOMにたいしてプリティプリント(pp: 優雅なプリント)を行 う。REMOVE-EMPTYなら空白文字だけを含むテキスト的ノードはプリントし ない。 31.27 グループのアトミックな変更 ================================ データベース用語においての“アトミック(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’が使用す る、より低レベルな関数を直接呼び出さなければなりません。 -- Function: prepare-change-group &optional buffer この関数はBUFFER (デフォルトはカレントバッファー)にたいする変更グル ープをセットアップする。これはその変更グループを表すhandleをリター ンする。変更グループをactivateしたり、その後でそれを完了するために はこのhandleを使用しなければならない。 変更グループを使用するためには、それを“activate(アクティブ化)”しなけ ればなりません。これはBUFFERのテキストを変更する前に行わなければなりませ ん。 -- Function: activate-change-group handle これはHANDLEが指定する変更グループをactiveにする。 変更グループをactivateした後には、そのバッファー内で行ったすべての変 更は変更グループの一部となります。そのバッファー内で目論んでいたすべての 変更を行ったら、変更グループを“finish(完了)”しなければなりません。すべて の変更を受け入れる(確定する)か、すべてをキャンセルするという2つの方法に より、これを行うことができます。 -- Function: accept-change-group handle この関数はHANDLEにより指定される変更グループ内のすべての変更にたい して、finalizeすることにより変更を受け入れる。 -- Function: cancel-change-group handle この関数はHANDLEにより指定される変更グループ内のすべての変更をキャ ンセルしてundoする。 グループが常に確実にfinishされるようにするために、コードでは ‘unwind-protect’を使用するべきです。‘activate-change-group’の呼び出しは 、実行直後にユーザーが‘C-g’をタイプする場合に備えて‘unwind-protect’内部 にあるべきです(これが‘prepare-change-group’と‘activate-change-group’が別 関数となっている1つの理由。なぜなら通常は‘unwind-protect’開始前に ‘prepare-change-group’を呼び出すであろうから)。グループを一度finishした ら、そのhandleを再度使用してはなりません。特に同じ変更グループを2回 finishしないでください。 複数バッファー変更グループ(multibuffer change group)を作成するために は、カバーしたいバッファーそれぞれで‘prepare-change-group’を一度呼び出し てから、以下のようにリターン値を結合するために‘nconc’を使用してください: (nconc (prepare-change-group buffer-1) (prepare-change-group buffer-2)) その後は1回の‘activate-change-group’呼び出しで複数変更グループをアク ティブにして、1回の‘accept-change-group’か‘cancel-change-group’呼び出し でそれをfinishしてください。 同一バッファーにたいするネストされた複数の変更グループ使用は、あなた が期待するであろう通りに機能します。同一バッファーにたいするネストされて いない変更グループの使用によりEmacsが混乱した状態になるので、これが発生 しないようにしてください。与えられた何らかのバッファーにたいして最初に開 始した変更グループは最後にfinishする変更グループです。 31.28 フックの変更 ================== 以下のフック変数によりバッファー(これらをバッファーローカルにした場合に は特定のバッファー)での変更にたいして、通知を受け取るようにアレンジする ことができます。テキストの特定部分にたいする変更の検出方法については *note Special Properties::も参照してください。 これらのフック内で使用する関数は、もしそれらが正規表現を使用して何か を行う場合にはマッチしたデータの保存とリストアを行うべきです。さもないと それらが呼び出す編集処理に奇妙な方法で干渉するでしょう。 -- Variable: before-change-functions この変数はEmacsがバッファー変更を行おうとする際に呼び出す関数のリス トを保持する。各関数は変更されようとするリージョンの先頭と終端を整 数で表す2つの引数を受け取る。変更されようとするバッファーは関数の呼 び出しの際には常にカレントバッファーである。 -- Variable: after-change-functions この変数はEmacsがバッファー変更を行った後に呼び出す関数のリストを保 持する。各関数は正に変更されたリージョンの先頭と終端、およびその変 更前に存在したテキストの長さという3つの引数を受け取る。これら3つの 変数は、すべて整数。変更されたバッファーは関数の呼び出しの際には常 にカレントバッファーである。 古いテキストの長さは、変更される前のテキストでのテキストの前後のバ ッファー位置の差で与えられる。変更されたテキストでは、その長さは単 に最初の2つの引数の差で与えられる。 これらの関数は‘*Messages*’バッファーへのメッセージの出力では呼び出さ れず、特定の処理用にEmacsが作成する内部的なバッファーのようなLispプログ ラムからは可視であるべきではないバッファーへの変更でも呼び出されません。 バッファーへのそれぞれの変更の周辺で、before-changeフックと after-changeフックが釣り合いの取れたペアであることを_期待しないでくださ い_。またEmacsが削除しようとするテキスト塊(chunk of text)ごとに before-changeフックが呼び出されることも期待してはなりません。これらのフ ックはLispプログラムがbefore-changeかafter-changeの両方ではなく、いずれ かを使用するという想定で提供されており、その変更が発生したリージョン境界 には実際に変更があったテキストだけではなく、少量にたいして行われた変更を 複数集めて一塊とした変更さえ含まれるかもしれません。 -- Macro: combine-after-change-calls body... このマクロは普通にBODYを実行するが、もしそれが安全なように見えるな ら一連の複数の変更にたいして正に一度、after-change関数を呼び出すよ うにアレンジする。 そのバッファーの同じ領域内でプログラムが複数のテキスト変更を行う場 合には、その部分のプログラムの周囲でマクロ ‘combine-after-change-calls’を使用することにより、after-changeフッ ク使用中の実行がかなり高速になり得る。after-changeフックが最終的に 呼び出される際には、その引数は‘combine-after-change-calls’のbody内 で行われたすべての変更にたいして含むバッファーの範囲を指定する。 *警告:* フォーム‘combine-after-change-calls’のbody内で ‘after-change-functions’の値を変更してはならない。 *警告:* 組み合わされた変更がバッファーの広い範囲に点在してに出現す る場合でも、これは依然として機能するが推奨できない。なぜならこれは 、ある変更フック関数を非効率的な挙動へと導くかもしれないからである 。 -- Variable: first-change-hook この変数は以前は未変更の状態だったバッファーが変更された際は常に実 行されるノーマルフック。 -- Variable: inhibit-modification-hooks この変数が非‘nil’ならすべての変更フックは無効。それらは何も実行され ない。これはこのセクションで説明したすべてのフック変数、同様に特定 のスペシャルテキストプロパティ(*note Special Properties::を参照)と オーバーレイプロパティ(*note Overlay Properties::を参照)にアタッチ されたフックに影響を与える。 これらの同一フック変数上の関数の実行の間、バッファー変更によるデフ ォルトの変更フックが他の変更フック実行中に実行されないように、この 変数は非‘nil’にバインドされる。それ自体が変更フックから実行される特 定のコード断片内で変更フックを実行したければ、 ‘inhibit-modification-hooks’を‘nil’にローカルに再バインドすること。 32 非ASCII文字 ************** このチャプターは文字に関する特別な問題と、それらが文字列やバッファーに格 納される方法について網羅しています。 32.1 テキストの表現方法 ======================= 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ビットのバイトシーケンスとして格納する ものです(1)。たとえばすべての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’のバッファーローカルな 値が使用する表現を指定します。文字列での表現は文字列構築時に判断して、そ れを文字列内に記録します。 -- Variable: enable-multibyte-characters この変数はカレントバッファーのテキスト表現を指定する。非‘nil’ならバ ッファーはマルチバイトテキスト、それ以外ならエンコード済みユニバイ トテキスト、またはバイナリー非テキストデータが含れる。 この変数は直接セットできない。バッファーの表現の変更には、かわりに 関数‘set-buffer-multibyte’を使用すること。 -- Function: position-bytes position バッファー位置は文字単位で測られる。この関数はカレントバッファー内 のバッファー位置を、それに対応するバイト位置でリターンする。これは バッファー先頭を1としてバイト単位で増加方向に数えられる。POSITIONが 範囲外なら値は‘nil’。 -- Function: byte-to-position byte-position カレントバッファー内で与えられたBYTE-POSITIONに対応するバッファー位 置を文字単位でリターンする。BYTE-POSITIONが範囲外なら値は‘nil’。マ ルチバイトバッファーではBYTE-POSITIONの任意の値が文字境界上になく、 1文字として表現されたマルチバイトシーケンス内にあるかもしれない。こ の場合には関数はその文字のマルチバイトシーケンスがBYTE-POSITIONを含 むようなバッファー位置をリターンする。言い換えるとこの値は同じ文字 に属するすべてのバイト位置にたいして変化しない。 以下の2つの関数はバッファーにvisitされているファイル内でのバイトオフ セットとバッファー位置をLispプログラムがマッピングする際に有用です。 -- Function: bufferpos-to-filepos position &optional quality coding-system この関数は‘position-bytes’と似ているがカレントバッファー内でのバイ ト位置ではなく、バッファー内のPOSITIONにより与えられる文字に対応す るカレントバッファーのファイル先頭からのオフセットをリターンする点 が異なる。この変換にはバッファーのファイル内でテキストがエンコード される方法を知ることが要求される。これがCODING-SYSTEM引数の存在意義 であり、デフォルトは‘buffer-file-coding-system’の値。オプション引数 QUALITYは結果のあるべき正確さを指定する。これは以下いずれかであるこ と: ‘exact’ 結果は正確でなければならない。関数はバッファーの大きな範囲をエ ンコードおよびデコードする必要があるだろう。 ‘approximate’ 近似的な値が可能。関数は高価な処理を回避して不正確な結果をリタ ーンするかもしれない。 ‘nil’ 正確な結果に高価な処理を要するなら、関数は近似値ではなく ‘nil’をリターンするだろう。これは引数が省略された場合のデフォ ルト。 -- Function: filepos-to-bufferpos byte &optional quality coding-system この関数はBYTE (ファイル先頭からの0基準のバイトオフセット)が指定す るファイル位置に対応するバッファー位置をリターンする。この関数は ‘bufferpos-to-filepos’が行う変換と逆の処理を行う。オプション引数 QUALITYとCODING-SYSTEMのもつ意味と値は‘bufferpos-to-filepos’の場合 と同様。 -- Function: multibyte-string-p string STRINGがマルチバイト文字列なら‘t’、それ以外は‘nil’をリターンする。 この関数はSTRINGが文字列以外でも‘nil’をリターンする。 -- Function: string-bytes string この関数はSTRING内のバイト数をリターンする。STRINGがマルチバイト文 字列なら、これは‘(length STRING)’より大きいかもしれない。 -- Function: unibyte-string &rest bytes この関数は引数BYTESをすべて結合して、その結果をユニバイト文字列で作 成する。 ---------- Footnotes ---------- (1) この内部表現は任意のUnicodeコードポイントを表すための、“UTF-8”と 呼ばれるUnicode標準によるエンコーディングの1つにもとづいたものですが、 8ビットrawバイトおよびUnicodeに統一されていない文字を使用する追加のコー ドポイントを表現するためにEmacsはUTF-8を拡張しています。 32.2 マルチバイト文字の無効化 ============================= デフォルトではEmacsはマルチバイトモードで開始されます。Emacsはマルチバイ トシーケンスを使用して非ASCII文字を表現する内部エンコーディングを使用す ることにより、バッファーや文字列のコンテンツを格納します。マルチバイトモ ードでは、サポートされるすべての言語とスクリプトを使用できます。 非常に特別な状況下においては、特定のバッファーでマルチバイト文字のサ ポートを無効にしたいときがあるかもしれません。あるバッファーにおいてマル チバイト文字が無効になっているときには、それを“ユニバイトモード(unibyte mode)”と呼びます。ユニバイトモードではバッファー内の各文字は0から255(8進 の0377)の範囲の文字コードをもちます。0から127(8進の0177)はASCII文字、 128から255(8進の0377)は非ASCII文字を表します。 特定のファイルをユニバイト表現で編集するためには、 ‘find-file-literally’を使用してファイルをvisitします。*note Visiting Functions::を参照してください。マルチバイトバッファーをファイルに保存し てバッファーをkillした後に、再びそのファイルを‘find-file-literally’で visitすることによりマルチバイトバッファーをユニバイトに変換できます。か わりに‘C-x c’(‘universal-coding-system-argument’)を使用して、ファ イルをvisitまたは保存するコーディングシステムとして‘raw-text’を指定する こともできます。*note Specifying a Coding System for File Text: (emacs)Text Coding.を参照してください。‘find-file-literally’とは異なり、 ‘raw-text’としてファイルをvisitしてもフォーマット変換、解凍、自動的なモ ード選択は無効になりません。 バッファーローカル変数‘enable-multibyte-characters’はマルチバイトバッ ファーなら非‘nil’、ユニバイトバッファーなら‘nil’です。マルチバイトバッフ ァーかどうかはモードラインにも示されます。グラフィカルなディスプレイでの マルチバイトバッファーには文字セットを示すモードライン部分と、そのバッフ ァーがマルチバイトであること(とそれ以外の事項)を告げるツールチップがあり ます。ユニバイトバッファーでは文字セットのインジケーターはありません。し たがって(グラフィカルなディスプレイ使用時の)ユニバイトバッファーでは入力 メソッドを使用していなければ、visitしているファイルの行末変換(コロン、バ ックスラッシュ等)の標識の前には通常は何も標識がありません。 特定のバッファーでマルチバイトサポートをオフに切り替えるには、そのバ ッファー内でコマンド‘toggle-enable-multibyte-characters’を呼び出してくだ さい。 32.3 テキスト表現の変換 ======================= Emacsはユニバイトテキストをマルチバイトに変換できます。マルチバイトテキ ストに含まれるのがASCIIと8ビットrawバイトだけという条件つきでマルチバイ トテキストからユニバイトへの変換もできます。一般的にこれらの変換はバッフ ァーへのテキスト挿入時、または複数の文字列を1つの文字列に合成してテキス トにputするときに発生します。文字列のコンテンツを明示的にいずれかの表現 に変換することもできます。 Emacsはそのテキストの構成にもとづいて文字列の表現を選択します。一般的 なルールではユニバイトテキストが他のマルチバイトテキストと組み合わされて いればマルチバイト表現のほうがより一般的であり、ユニバイトテキストのすべ ての文字を保有できるのでユニバイトテキストをマルチバイトテキストに変換し ます。 バッファーへのテキスト挿入時にEmacsはそのバッファーの ‘enable-multibyte-characters’の指定にしたがってテキストをそのバッファー の表現に変換します。特にユニバイトバッファーにマルチバイトテキストを挿入 する際には、たとえ一般的にはマルチバイトテキスト内のすべての文字を保持す ることはできなくてもEmacsはテキストをユニバイトに変換します。バッファー コンテンツをマルチバイトに変換するという自然な代替方法は、そのバッファー の表現が自動的にオーバーライドできないユーザーによる選択にもとづく表現で あるため許容されません。 ユニバイトテキストからマルチバイトテキストへの変換ではASCII文字は未変 更のまま残されて、128から255のコードをもつバイトが8ビットrawバイトのマル チバイト表現に変換されます。 マルチバイトテキストからユニバイトテキストへの変換では、すべての ASCIIと8ビット文字が、それらの1バイト形式に変換されますが、各文字のコー ドポイントの下位8ビット以外は破棄されるために非ASCII文字の情報は失われま す。ユニバイトテキストからマルチバイトテキストに変換してそれをユニバイト に戻せば、元のユニバイトテキストが再生成されます。 以下の2つの関数は引数STRING、またはテキストプロパティをもたない新たに 作成された文字列のいずれかをリターンします。 -- Function: string-to-multibyte string この関数はSTRINGと同じ文字シーケンスを含むマルチバイト文字列をリタ ーンする。STRINGがマルチバイト文字列なら未変更のままそれがリターン される。この関数はSTRINGがASCII文字と8ビットrawバイトだけを含むと仮 定する。後者は‘#x3FFF80’から‘#x3FFFFF’(両端を含む)に対応する8ビット rawバイトのマルチバイト表現に変換される(*note codepoints: Text Representations.を参照)。 -- Function: string-to-unibyte string この関数はSTRINGと同じ文字シーケンスを含むユニバイト文字列をリター ンする。STRINGに非ASCII文字が含まれる場合にはエラーをシグナルする。 STRINGがユニバイト文字列なら未変更のままそれがリターンされる。 ASCII文字と8ビット文字だけを含むSTRING引数にたいしてのみこの関数を 使用すること。 -- Function: byte-to-string byte この関数は文字データBYTEの単一バイトを含むユニバイト文字列をリター ンする。BYTEが0から255までの整数でなければエラーをシグナルする。 -- Function: multibyte-char-to-unibyte char これはマルチバイト文字CHARをユニバイト文字に変換してその文字をリタ ーンする。CHARがASCIIと8ビットのいずれでもなければこの関数は−1をリ ターンする。 -- Function: unibyte-char-to-multibyte char これはCHARがASCIIか8ビットrawバイトのいずれかであると仮定してユニバ イト文字ASCIIをマルチバイト文字に変換する。 32.4 表現の選択 =============== 既存のバッファーや文字列がユニバイトの際に、それらをマルチバイトとして調 べたり、その逆を行うことが有用なときがあります。 -- Function: set-buffer-multibyte multibyte カレントバッファーの表現タイプをセットする。MULTIBYTEが非‘nil’なら バッファーはマルチバイト、‘nil’ならユニバイト。 この関数はバイトシーケンスとして認識時にはバッファーを未変更のまま とする。結果として文字として認識時にはコンテンツを変更できる。たと えばマルチバイト表現では1文字として扱われる3バイトのシーケンスは、 ユニバイト表現では3文字として数えられるだろう。例外はrawバイトを表 す8ビット文字。これらはユニバイトバッファーでは1バイトで表現される が、バッファーをマルチバイトにセットした際は2バイトのシーケンスに変 換されて、その逆の変換も行われる。 この関数はどの表現が使用されているかを記録するために ‘enable-multibyte-characters’をセットする。これは以前の同じテキスト をカバーするように、バッファー内のさまざまなデータ(オーバーレイ、テ キストプロパティ、マーカーを含む)を調整する。 ナローイングはマルチバイト文字シーケンス中間で発生するかもしれない ので、この関数はバッファーがナローイングされている場合はエラーをシ グナルする。 そのバッファーがインダイレクトバッファー(indirect buffer: 間接バッ ファー)の場合にもエラーをシグナルする。インダイレクトバッファーは常 にベースバッファー(base buffer: 基底バッファー)の表現を継承する。 -- Function: string-as-unibyte string STRINGがすでにユニバイト文字列なら、この関数はSTRING自身をリターン する。それ以外はSTRINGと同じバイトだが、それぞれの文字を個別の文字 としてとして扱って新たな文字列をリターンする(値はSTRINGより多くの文 字をもつかもしれない)。例外としてrawバイトを表す8ビット文字は、それ ぞれ単一のバイトに変換される。新たに作成された文字列にテキストプロ パティは含まれない。 -- Function: string-as-multibyte string STRINGがすでにマルチバイト文字列なら、この関数はSTRING自身をリター ンする。それ以外はSTRINGと同じバイトだが、それぞれのマルチバイトシ ーケンスを1つの文字としてとして扱って新たな文字列をリターンする。こ れは値がSTRINGより少ない文字をもつかもしれないことを意味する。 STRING内のバイトシーケンスが単一文字のマルチバイト表現として無効な ら、そのシーケンスないの各バイトは8ビットrawバイトとして扱われる。 新たに作成された文字列にはテキストプロパティは含まれない 32.5 文字コード =============== ユニバイトやマルチバイトによるテキスト表現は異なる文字コードを使用します 。ユニバイト表現にたいして有効な文字コードの範囲は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バ イトを表します。 -- Function: characterp charcode これはCHARCODEが有効な文字なら‘t’、それ以外は‘nil’をリターンする。 (characterp 65) ⇒ t (characterp 4194303) ⇒ t (characterp 4194304) ⇒ nil -- Function: max-char この関数は有効な文字コードポイントが保有し得る最大の値をリターンす る。 (characterp (max-char)) ⇒ t (characterp (1+ (max-char))) ⇒ nil -- Function: get-byte &optional pos string この関数はカレントバッファー内の文字位置POSにあるバイトをリターンす る。カレントバッファーがユニバイトなら、その位置のバイトをそのまま リターンする。バッファーがマルチバイトなら、8ビットrawバイトは8ビッ トコードに変換される一方で、ASCII文字のバ値は文字コードポイントと同 じになる。この関数はPOSにある文字が非ASCIIならエラーをシグナルする 。 オプション引数STRINGはカレントバッファーのかわりに文字列からバイト 値を得ることを意味する。 32.6 文字のプロパティ ===================== “文字プロパティ(character property”とは、その文字の振る舞いとテキストが 処理や表示される間にどのように処理されるべきかを指定する名前つきの文字属 性です。したがって文字プロパティはその文字の意味を指定するための重要な一 部です。 全体としてEmacsは自身の文字プロパティ実装においてはUnicode標準にした がいます。特にEmacsはUnicode Character Property Model (http://www.unicode.org/reports/tr23/)をサポートしており、Emacs文字プロ パティデータベースはUnicode文字データベース(UCD: Unicode Character Database)から派生したものです。Unicode文字プロパティとその意味についての 詳細な説明はCharacter Properties chapter of the Unicode Standard (http://www.unicode.org/versions/Unicode6.2.0/ch04.pdf)を参照してくださ い。このセクションでは、あなたがすでに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は表示の ために双方向テキストを並び替える際にこのプロパティを使用する(*note Bidirectional Display::を参照)。未割り当てのコードポイントにたいす る値はそのコードポイントが属するコードブロックに依存する。未割り当 てのコードポイントのほとんどは‘L’(強い左方向)だが、‘AL’ ( Arabic letter: アラビア文字)や‘R’ (強い右方向)を受け取るコースポイントもい くつかある。 ‘decomposition’ Unicodeプロパティの‘Decomposition_Type’と‘Decomposition_Value’に対 応する。値は最初の要素が‘small’のような互換性のあるフォーマットタグ (compatibility formatting tag)であるかもしれないリスト(1)。分割シー ケンス(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は適切な際は鏡像 を表示するためにこのプロパティを使用する(*note Bidirectional Display::を参照)。未割り当てのコードポイントにたいする値は‘nil’。 ‘paired-bracket’ Unicodeプロパティ‘Bidi_Paired_Bracket’に対応する。このプロパティの 値は文字の“paired bracket(カッコのペア)”のコードポイント、その文字 がbracket文字でなければ‘nil’。これはUnicode双方向アルゴリズム (Unicode Bidirectional Algorithm)によりカッコのペアとして扱われる文 字間のマッピングを確立する。 Emacsは丸カッコ(parentheses)や角カッコ (braces)、およびその類の文字を再配置する方法を決定する際にこのプロ パティを使用する(*note Bidirectional Display::を参照)。 ‘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’であり、これはその文字自 身を意味する。 -- Function: get-char-code-property char propname この関数はCHARのプロパティPROPNAMEの値をリターンする。 (get-char-code-property ?\s 'general-category) ⇒ Zs (get-char-code-property ?1 'general-category) ⇒ Nd ;; U+2084 SUBSCRIPT FOUR (get-char-code-property ?\u2084 'digit-value) ⇒ 4 ;; U+2155 VULGAR FRACTION ONE FIFTH (get-char-code-property ?\u2155 'numeric-value) ⇒ 0.2 ;; U+2163 ROMAN NUMERAL FOUR (get-char-code-property ?\u2163 'numeric-value) ⇒ 4 (get-char-code-property ?\( 'paired-bracket) ⇒ 41 ;; closing parenthesis (get-char-code-property ?\) 'bracket-type) ⇒ c -- Function: char-code-property-description prop value この関数はプロパティ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 -- Function: put-char-code-property char propname value この関数は文字CHARのプロパティPROPNAMEの値としてVALUEを格納する。 -- Variable: unicode-category-table この変数の値は、それぞれの文字にたいしてそのUnicodeプロパティ ‘General_Category’をシンボルとして指定する文字テーブル(*note Char-Tables::を参照)。 -- Variable: char-script-table この変数の値は、それぞれの文字がシンボルを指定するような文字テーブ ル。シンボルの名前はUnicodeコードスペースからスクリプト固有ブロック へのUnicode標準分類にしたがうような、その文字が属するスクリプト。こ の文字テーブルは余分のスロットを1つもち、値はすべてのスクリプトシ ンボルのリスト。 -- Variable: char-width-table この変数の値は、それぞれの文字がスクリーン上で占めるであろう幅を列 単位で指定する文字テーブル。 -- Variable: printable-chars この変数の値は、それぞれの文字にたいしてそれがプリント可能かどうか を指定する文字テーブル。すなわち‘(aref printable-chars char)’を評価 した結果が‘t’ならプリント可、‘nil’なら不可。 ---------- Footnotes ---------- (1) Unicode仕様ではこれらのタグ名を‘<..>’カッコ内に記述しますが Emacsでのタグ名にはカッコは含まれません。Unicodeでの‘’指定は Emacsでは‘small’となります。 32.7 文字セット =============== 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はこれを使用します。 -- Function: charsetp object OBJECTは文字セットを命名するシンボルなら‘t’、それ以外は‘nil’をリタ ーンする。 -- Variable: charset-list 値はすべての定義済み文字セットの名前のリスト。 -- Function: charset-priority-list &optional highestp この関数はすべての定義済み文字セットの優先順にソートされたリストを リターンする。HIGHESTPが非‘nil’なら、この関数はもっとも優先度の高い 文字セット1つをリターンする。 -- Function: set-charset-priority &rest charsets この関数はCHARSETSをもっとも高い優先度の文字セットにする。 -- Function: char-charset character &optional restriction この関数はCHARACTERが属する文字セットで、もっとも優先度の高い文字セ ットの名前をリターンする。ただしASCII文字は例外であり、この関数は常 に‘ascii’をリターンする。 RESTRICTIONが非‘nil’なら、それは検索する文字セットのリストであるこ と。かわりにコーディングシステムも指定でき、その場合にはそのコーデ ィングシステムによりサポートされている必要がある(*note Coding Systems::を参照)。 -- Function: charset-plist charset この関数は文字セットCHARSETのプロパティをリターンする。たとえ CHARSETがシンボルだったとしても、これはそのシンボルのプロパティリス トと同じではない。文字セットプロパティにはドキュメント文字列、短い 名前等、その文字セットに関する重要な情報が含まれる。 -- Function: put-charset-property charset propname value この関数はCHARSETのプロパティPROPNAMEに与えられたVALUEをセットする 。 -- Function: get-charset-property charset propname この関数はCHARSETのプロパティPROPNAMEの値をリターンする。 -- Command: list-charset-chars charset このコマンドは文字セットCHARSET内の文字のリストを表示する。 Emacsは文字の内部的な表現と、その文字の特定の文字セット内でのコードポ イントを相互に変換することができます。以下はこれらをサポートするための関 数です。 -- Function: decode-char charset code-point この関数はCHARSET内でCODE-POINTに割り当てられた文字をEmacsの対応す る文字にデコードしてリターンする。そのコードポイントの文字が CHARSETに含まれなければ値は‘nil’。CODE-POINTがLisp整数(*note most-positive-fixnum: Integer Basics.を参照)に収まらなければ、コン スセル‘(HIGH . LOW)’で指定できる。ここでLOWはその値の下位来る16ビッ ト、HIGHは上位16ビット。 -- Function: encode-char char charset この関数はCHARSET内で文字CHARに割り当てられたコードポイントをリター ンする。結果がLisp整数に収まらなければ、上述の‘decode-char’の2つ目 の引数のようにコンスセル‘(HIGH . LOW)’としてリターンされる。 CHARSETがCHARにたいするコードポイントをもたなければ値は‘nil’。 以下の関数は文字セット内の文字の一部、またはすべてにたいして特定の関 数を適用するのに有用です。 -- Function: map-charset-chars function charset &optional arg from-code to-code CHARSET内の文字にたいしてFUNCTIONを呼び出す。FUNCTIONは2つの引数で 呼び出される。1つ目はコンスセル‘(FROM . TO)’であり、FROMとTOは文字 セット内に含まれる文字の範囲。ARGは2つ目の引数としてFUNCTIONに渡さ れる。 デフォルトではFUNCTIONに渡されるコードポイントの範囲にはCHARSET内の すべての文字が含まれるが、オプション引数FROM-CODEとTO-CODEにより、 それはCHARSETの2つのコードポイント間にある文字範囲に制限される。 FROM-CODEかTO-CODEのいずれかが‘nil’の場合のデフォルトは、CHARSETの コードポイントの最初か最後。 32.8 文字セットのスキャン ========================= 特定の文字がどの文字セットに属するか調べられると便利なときがあります。こ れの用途の1つは、どのコーディングシステム(*note Coding Systems::を参照 )が問題となっているテキストすべてを表現可能か判断することです。他にもそ のテキストを表示するフォントの判断があります。 -- Function: charset-after &optional pos この関数は、カレントバッファー内の位置POSにある文字を含む、もっとも 高い優先度の文字セットをリターンする。POSが省略または‘nil’の場合の デフォルトはポイントのカレント値。POSが範囲外なら値は‘nil’。 -- Function: find-charset-region beg end &optional translation この関数はカレントバッファー内の位置BEGからENDの間の文字を含む、も っとも優先度の高い文字セットのリストをリターンする。 オプション引数TRANSLATIONはテキストのスキャンに使用するための変換テ ーブルを指定する(*note Translation of Characters::を参照)。これが非 ‘nil’ならリージョン内の各文字はそのテーブルを通じて変換され、リター ンされる値にはバッファーの実際の文字ではなく変換された文字が記述さ れる。 -- Function: find-charset-string string &optional translation この関数はSTRING内の文字を含む、もっとも優先度の高い文字セットのリ ストをリターンする。これは‘find-charset-region’と似ているが、カレン トバッファーの一部ではなくSTRINGのコンテンツに適用される点が異なる 。 32.9 文字の変換 =============== “変換テーブル(translation table)”とは文字から文字へのマッピングを指定す る文字テーブルです(*note Char-Tables::を参照)。これらのテーブルはエンコ ーディング、デコーディング、および他の用途にも使用されます。独自に変換テ ーブルを指定するコーディングシステムもいくつかあります。他のすべてのコー ディングシステムに適用されるデフォルトの変換テーブルも存在します。 変換テーブルには余分のスロット(extra slots)が2つあります。1つ目のスロ ットは‘nil’、または逆の変換を処理する変換テーブルです。2つ目のスロットは 変換する文字シーケンスを照合する際の最大文字数です(以下の ‘make-translation-table-from-alist’の説明を参照)。 -- Function: make-translation-table &rest translations この関数は引数TRANSLATIONSにもとづいて変換テーブルをリターンする。 TRANSLATIONSの各要素は‘(FROM . TO)’という形式のリストであること。こ れはFROMからTOへの文字の変換を指示する。 各引数内の引数とフォームは順に処理され、もし前のフォームですでに TOがたとえばTO-ALTに変換されていればFROMもTO-ALTに変換される。 デコードを行う間、その変換テーブルの変換は通常のデコーディングの結果 の文字に適用されます。あるコーディングシステムがプロパティ ‘:decode-translation-table’をもつなら、それは使用する変換テーブル、また は順に適用するべき変換テーブルのリストを指定します(これはコーディングシ ステムの名前であるようなシンボルのプロパティではなく、 ‘coding-system-get’がリターンするようなコーディングシステムのプロパティ 。*note Basic Concepts of Coding Systems: Coding System Basics.を参照)。 最後にもし‘standard-translation-table-for-decode’が非‘nil’なら、結果とな る文字はそのテーブルにより変換されます。 エンコードを行う間は、その変換テーブルの変換はバッファー内の文字に適 用されて、変換結果は実際にエンコードされます。あるコーディングシステムが プロパティ‘:encode-translation-table’をもつならそれは使用する変換テーブ ル、または順に適用するべき変換テーブルのリストを指定します。加えてもし変 数‘standard-translation-table-for-encode’が非‘nil’なら、それは変換結果に たいして使用するべき変換テーブルを指定します。 -- Variable: standard-translation-table-for-decode これはデコード用のデフォルトの変換テーブル。あるコーディングシステ ムが独自に変換テーブルを指定する場合には、この変数の値が非‘nil’なら 、それら独自のテーブルを適用後にこの変数の変換テーブルが適用される 。 -- Variable: standard-translation-table-for-encode これはエンコード用のデフォルトの変換テーブル。あるコーディングシス テムが独自に変換テーブルを指定する場合には、この変数の値が非‘nil’な らそれら独自のテーブル適用後にこの変数の変換テーブルが適用される。 -- Variable: translation-table-for-input 自己挿入文字は挿入前にこの変換テーブルを通じて変換が行われる。検索 コマンドもバッファー内の内容とより信頼性のある比較ができるようにこ のテーブルを通じて入力を変換する。 この変数はセット時に自動的にバッファーローカルになる。 -- Function: make-translation-table-from-vector vec この関数はバイト(値は0から#xFF)から文字にマップする256要素の配列で あるような、VECから作成した変換テーブルをリターンする。未変換のバイ トにたいする要素は‘nil’かもしれない。リターンされるテーブルは余分な 1つ目のスロットにそのマッピングを保持する変換テーブル、2つ目の余分 なスロットに値‘1’をもつ。 この関数は各バイトを特定の文字にマップするようなプライベートなコー ディングシステムを簡単に作成する手段を提供する。 ‘define-coding-system’のPROPS引数のプロパティ ‘:decode-translation-table’と‘:encode-translation-table’に、リター ンされるテーブルと逆変換テーブルを指定できる。 -- Function: make-translation-table-from-alist alist この関数は‘make-translation-table’と似ているが、シンプルな1対1のマ ッピングを行う変換テーブルではなく、より複雑な変換テーブルをリター ンする。ALISTの各要素は‘(FROM . TO)’という形式をもち、ここでFROMお よびTOは文字または文字シーケンスを指定するベクター。FROMが文字なら 、その文字はTO(文字か文字シーケンス)に変換される。FROMが文字のベク ターならそのシーケンスはTOに変換される。リターンされるテーブルは1つ 目の余分なスロットに逆のマッピングを行う変換テーブル、2つ目の余分な スロットには文字シーケンスFROMすべての最大長をもつ。 32.10 コーディングシステム ========================== Emacsがファイルにたいして読み書きをしたりサブプロセスとテキストの送受信 を行う際には、通常は特定の“コーディングシステム(coding system)”の指定に したがって文字コード変換や行末変換を行います。 コーディングシステムの定義は難解な問題であり、ここには記述しません。 32.10.1 コーディングシステムの基本概念 -------------------------------------- “文字コード変換(character code conversion)”により、Emacs内部で使用される 文字の内部表現と他のエンコーディングの間で変換が行われます。Emacsは多く の異なるエンコーディングをサポートしており、それらは双方向に変換が可能で す。たとえばLatin 1、Latin 2、Latin 3、Latin 4、Latin 5、およびいくつか のISO 2022の変種等のようなエンコーディングにたいしてテキストを双方向に変 換できます。あるケースにおいては同じ文字にたいしてEmacsは複数のエンコー ディング候補をサポートします。たとえばキリル(ロシア語)のアルファベットに たいしてはISO、Alternativnyj、KOI8のように3つにコーディングシステムが存 在します。 コーディングシステムはそれぞれ特定の文字コード変換セットを指定します が、‘undecided’というコーディングシステムは特別です。これはそれぞれのフ ァイルにたいして、そのファイルのデータにもとづいて発見的に選択が行われる ように選択を未指定のままに留めます。 コーディングシステムは一般的に可逆的な同一性を保証しません。あるコー ディングシステムを使用してバイトシーケンスをデコードしてから、同じコーデ ィングシステムで結果テキストをエンコードしても異なるバイトシーケンスが生 成される可能性があります。しかしデコードされたオリジナルのバイトシーケン スとなることを保証するコーディングシステムもいくつかあります。以下にいく つかの例を挙げます: iso-8859-1、utf-8、big5、shift_jis、euc-jp バッファーテキストのエンコードと結果のデコードでもオリジナルテキスト の再生成に失敗する可能性があります。たとえばその文字をサポートしないコー ディングシステムで文字をエンコードした場合の結果は予測できず、したがって 同じコーディングシステムを使用してそれをデコードしても異なるテキストが生 成されるでしょう。現在のところEmacsは未サポート文字のエンコーディングに よる結果をエラーとして報告できません。 “行末変換(end of line conversion: 改行変換)”はファイル内の行末を表す ために、さまざまなシステム上で使用される3つの異なる慣例を扱います。GNUや Unixシステムで使用されるUnixの慣例ではLF文字(linefeed文字、改行とも呼ば れる)が使用されます。MS-WindowsやMS-DOSシステムで使用されるDOSの慣例では 行末にCR文字(carriage-return文字、復帰文字とも呼ばれる)とLF文字が使用さ れます。Macの慣例ではCR文字だけが使用されます(これはOS X以前の Macintoshシステムで使用されていた慣例)。 ‘latin-1’のような“ベースコーディングシステム(base coding systems: 基 本コーディングシステム)”では、データにもとづいて選択されるように行末変換 は未指定となっています。‘latin-1-unix’、‘latin-1-dos’、‘latin-1-mac’のよ うな“バリアントコーディングシステム(variant coding systems: 変種コーディ ングシステム)”では行末変換を明示的に指定します。ほとんどのベースコーディ ングシステムは‘-unix’、‘-dos’、‘-mac’を追加した3つの対応する形式の変種を もちます。 ‘raw-text’は文字コード変換を抑制して、このコーディングシステムで visitされたバッファーがユニバイトバッファーとなる点において特殊なコーデ ィングシステムです。歴史的な理由によりこのコーディングシステムによりユニ バイトとマルチバイト両方のテキストを保存できます。マルチバイトテキストの エンコードに‘raw-text’を使用した際には1文字コード変換を行います。8ビット 文字は1バイトの外部表現に変換されます。‘raw-text’は通常のようにデータに より判断できるように行末変換を指定せず、通常のように行末変換を指定する 3つの変種をもちます。 ‘no-conversion’ (とエイリアスの‘binary’)は‘raw-text-unix’と等価です。 これは文字コードおよび行末にたいする変換をいずれも指定しません。 ‘utf-8-emacs’はデータがEmacsの内部エンコーディング(*note Text Representations::を参照)で表されることを指定するコーディングシステムです 。コード変換が何も発生しない点ではこれは‘raw-text’と似ていますが、結果が マルチバイトデータである点が異なります。‘emacs-internal’という名前は ‘utf-8-emacs’にたいするエイリアスです。 -- Function: coding-system-get coding-system property この関数はコーディングシステム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’プロパティの値はそのコーディングシステムにたいするエ イリアスとしても定義されている。 -- Function: coding-system-aliases coding-system この関数はCODING-SYSTEMのエイリアスのリストをリターンする。 32.10.2 エンコーディングとI/O ----------------------------- コーディングシステムの主な目的はファイルの読み込みと書き込みへの使用です 。関数‘insert-file-contents’はファイルデータのデコードにコーディングシス テムを使用して、‘write-region’はバッファーコンテンツのエンコードにコーデ ィングシステムを使用します。 使用するコーディングシステムは明示的(*note Specifying Coding Systems::を参照)、またはデフォルトメカニズム(*note Default Coding Systems::を参照)を使用して暗黙的に指定できます。しかしこれらの手法は何を 行うかを完全には指定しないかもしれません。たとえばこれらはデータから文字 コード変換を行わない‘undefined’のようなコーディングシステムを選択するか もしれません。このような場合にはI/O処理はコーディングシステム選択によっ て処理を完了します。後でどのコーディングシステムが選択されたか調べたいこ とが頻繁にあるでしょう。 -- Variable: buffer-file-coding-system このバッファーローカル変数はバッファーの保存、および ‘write-region’によるバッファー部分のファイルへの書き出しに使用され るコーディングシステムを記録する。書き込まれるテキストがこの変数で 指定されたコーディングシステムを使用して安全にエンコードできない場 合には、これらの操作は関数‘select-safe-coding-system’を呼び出すこと により代替となるエンコーディングを選択する(*note User-Chosen Coding Systems::を参照)。異なるエンコーディングの選択がユーザーによるコー ディングシステムの指定を要するなら、‘buffer-file-coding-system’は新 たに選択されたコーディングシステムに更新される。 ‘buffer-file-coding-system’はサブプロセスへのテキスト送信に_影響し ない_。 -- Variable: save-buffer-coding-system この変数は、(‘buffer-file-coding-system’をオーバーライドして)バッフ ァーを保存するためのコーディングシステムを指定する。これは ‘write-region’には使用されないことに注意。 あるコマンドがバッファーを保存するために‘buffer-file-coding-system’ (または‘save-buffer-coding-system’)の使用を開始して、そのコーディン グシステムがバッファー内の実際のテキストを処理できなければ、 (‘select-safe-coding-system’を呼び出すことにより)そのコマンドは他の コーディングシステムの選択をユーザーに求める。これが発生した後はコ マンドはユーザー指定のコーディングシステムを表すために ‘buffer-file-coding-system’の更新も行う。 -- Variable: last-coding-system-used ファイルやサブプロセスにたいするI/O操作は、使用したコーディングシス テムの名前をこの変数にセットする。明示的にエンコードとデコードを行 う関数(*note Explicit Encoding::を参照)もこの変数をセットする。 *警告:* サブプロセス出力の受信によりこの変数がセットされるため、こ の変数はEmacsがwaitしている際は常に変更され得る。したがって興味対象 となる値を格納する関数呼び出し後は、間を空けずにその値をコピーする こと。 変数‘selection-coding-system’はウィンドウシステムにたいして選択 (selection)をエンコードする方法を指定します。*note Window System Selections::を参照してください。 -- Variable: file-name-coding-system 変数‘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により内部的に処理される。 32.10.3 Lispでのコーディングシステム ------------------------------------ 以下はコーディングシステムと連携するLisp機能です: -- Function: coding-system-list &optional base-only この関数はすべてのコーディングシステムの名前(シンボル)をリターンす る。BASE-ONLYが非‘nil’なら、値にはベースコーディングシステムだけが 含まれる。それ以外ならエイリアス、およびバリアントコーディングシス テムも同様に含まれる。 -- Function: coding-system-p object この関数はOBJECTがコーディングシステムの名前なら‘t’、または‘nil’を リターンする。 -- Function: check-coding-system coding-system この関数はCODING-SYSTEMの有効性をチェックする。有効なら CODING-SYSTEMをリターンする。CODING-SYSTEMが‘nil’なら、この関数は ‘nil’をリターンする。それ以外の値にたいしては‘error-symbol’が ‘coding-system-error’であるようなエラーをシグナルする(*note signal: Signaling Errors.を参照)。 -- Function: coding-system-eol-type coding-system この関数は行末(“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変換が採用される。 -- Function: coding-system-change-eol-conversion coding-system eol-type この関数はCODING-SYSTEMと似ているが‘eol-type’で指定されたeol変換の 異なるコーディングシステムをリターンする。EOL-TYPEは‘unix’、‘dos’、 ‘mac’、または‘nil’であること。これが‘nil’ならリターンされるコーディ ングシステムは、データのeol変換により決定される。 EOL-TYPEは‘unix’、‘dos’、‘mac’を意味する0、1、2でもよい。 -- Function: coding-system-change-text-conversion eol-coding text-coding この関数はEOL-CODINGの行末変換と、TEXT-CODINGのテキスト変換を使用す るコーディングシステムをリターンする。TEXT-CODINGが‘nil’ならこれは ‘undecided’、またはEOL-CODINGに対応するバリアントの1つをリターンす る。 -- Function: find-coding-systems-region from to この関数はFROMとTOの間のテキストのエンコードに使用可能なコーディン グシステムのリストをリターンする。このリスト内のすべてのリストは、 そのテキスト範囲内にあるすべてのマルチバイト文字を安全にエンコード できる。 そのテキストがマルチバイト文字を含まれなければ、この関数はリスト ‘(undecided)’をリターンする。 -- Function: find-coding-systems-string string この関数はSTRINGのテキストのエンコードに使用可能な、コーディングシ ステムのリストをリターンする。このリスト内のすべてのリストは STRINGにあるすべてのマルチバイト文字を安全にエンコードできる。その テキストがマルチバイト文字を含まれなければ、この関数はリスト ‘(undecided)’をリターンする。 -- Function: find-coding-systems-for-charsets charsets この関数はリストCHARSETS内のすべての文字セットのエンコードに使用可 能なコーディングシステムのリストをリターンする。 -- Function: check-coding-systems-region start end coding-system-list この関数はリスト‘coding-system-list’内のコーディングシステムが STARTとENDの間のリージョン内にあるすべての文字をエンコード可能かど うかをチェックする。このリスト内のすべてのコーディングシステムが指 定されたテキストをエンコード可能なら、この関数は‘nil’をリターンする 。ある文字をエンコードできないコーディングシステムがある場合には、 各要素が‘(CODING-SYSTEM1 POS1 POS2 ...)’という形式のalistが値となる 。これはCODING-SYSTEM1がバッファーの位置POS1、POS2、...にある文字を エンコードできないことを意味する。 STARTは文字列かもしれず、その場合にはENDは無視されてリターン値はバ ッファー位置のかわりに文字列のインデックスを参照することになる。 -- Function: detect-coding-region start end &optional highest この関数はSTARTからENDのテキストのデコードに適したコーディングシス テムを選択する。このテキストはバイトシーケンス、すなわちユニバイト テキスト、ASCIIのみのマルチバイトテキスト、8ビット文字のシーケンス であること(*note Explicit Encoding::を参照)。 この関数は通常はスキャンしたテキストのデコーディングを処理可能なコ ーディングシステムのリストをリターンする。これらのコーディングシス テムは優先度降順でリストされる。しかしHIGHESTが非‘nil’なら、リター ン値はもっとも高い優先度のコーディングシステムただ1つとなる。 リージョンにISO-2022の‘ESC’のようなISO-2022制御文字を除いてASCII文 字だけが含まれる場合には値は‘undecided’、‘(undecided)’、またはテキ ストから推論可能ならeol変換を指定するバリアントとなる。 リージョンにnullバイトが含まれる場合には、あるコーディングシステム によりエンコードされたテキストがリージョン内に含まれる場合でも値は ‘no-conversion’となる。 -- Function: detect-coding-string string &optional highest この関数は‘detect-coding-region’と似ているがバッファー内のバイトの かわりにSTRINGのコンテンツを処理する点が異なる。 -- Variable: inhibit-null-byte-detection この変数が非‘nil’値をもつなら、リージョンや文字列のエンコーディング 検出時にnullバイトを無視する。これによりIndexノードをもつInfoファイ ルのようなnullバイトを含むテキストのエンコーディングを正しく検出で きる。 -- Variable: inhibit-iso-escape-detection この変数が非‘nil’値をもつなら、リージョンや文字列のエンコーディング 検出時にISO-2022エスケープシーケンスを無視する。結果としてこれまで いくつかのISO-2022エンコーディングにおいてエンコード済みと検出され ていたテキストがなくなり、バッファー内ですべてのエスケープシーケン スが可視になる。*警告:* この変数の使用には特に注意を払うこと。なぜ ならEmacsディストリビューション内で多くのファイルがISO-2022エンコー ディングを使用するからである。 -- Function: coding-system-charset-list coding-system この関数はCODING-SYSTEMがサポートする文字セット(*note Character Sets::を参照)のリストをリターンする。リストすべき文字セットを非常に 多くサポートするいくつかのコーディングシステムでは特別な値がリスト される: • CODING-SYSTEMがすべてのEmacs文字をサポートするなら値は ‘(emacs)’。 • CODING-SYSTEMがすべてのUnicode文字をサポートするなら値は ‘(unicode)’。 • CODING-SYSTEMがすべてのISO-2022文字をサポートするなら値は ‘iso-2022’。 • CODING-SYSTEMがEmacsバージョン21(Unicodeサポートの内部的な実装 以前)で使用される内部的コーディングシステム内のすべての文字を サポートするなら値は‘emacs-mule’。 サブプロセスへの入出力に使用されるコーディングシステムのチェックやセ ットの方法については*note Process Information: Coding systems for a subprocess.、特に関数‘process-coding-system’や ‘set-process-coding-system’の説明を参照してください。 32.10.4 ユーザー選択のコーディングシステム ------------------------------------------ -- Function: select-safe-coding-system from to &optional default-coding-system accept-default-p file この関数は指定されたテキストをエンコードするために、必要ならユーザ ーに選択を求めてコーディングシステムを選択する。指定されるテキスト は通常はカレントバッファーのFROMとTOの間のテキスト。FROMが文字列な ら、その文字列がエンコードするテキストを指定して、TOは無視される。 指定されたテキストにrawバイト(*note Text Representations::を参照)が 含まれる場合には、‘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’でセットできる最優先されるコーディングシ ステム)を試みる(*note Recognizing Coding Systems: (emacs)Recognize Coding.を参照)。 これらのうちいずれかのコーディングシステムが指定されたテキストすべ てを安全にエンコード可能なら、‘select-safe-coding-system’はそれを選 択およびリターンする。それ以外ならコーディングシステムのリストから すべてのテキストをエンコードできるコーディングシステムの選択をユー ザーに求めてユーザーの選択をリターンする。 DEFAULT-CODING-SYSTEMは最初の要素がtで、他の要素がコーディングシス テムであるようなリストかもしれない。その場合には、もしリスト内にテ キストを処理できるコーディングシステムがなければ、 ‘select-safe-coding-system’は上述した3つの代替えいずれを試みること なく即座にユーザーに問い合わせる。 オプション引数ACCEPT-DEFAULT-Pが非‘nil’なら、それはユーザーとの対話 なしで選択されたコーディングシステムが許容できるかどうかを判断する 関数であること。‘select-safe-coding-system’は選択されたコーディング システムのベースコーディングシステムを唯一の引数としてこの関数を呼 び出す。ACCEPT-DEFAULT-Pが‘nil’をリターンしたら、 ‘select-safe-coding-system’は選択されたコーディングシステムを暗黙に 拒絶して、可能な候補リストからコーディングシステムの選択をユーザー に求める。 変数‘select-safe-coding-system-accept-defaultf-p’が非‘nil’なら、そ れは1つの引数をとる関数であること。これはACCEPT-DEFAULT-P引数に与え られた値をオーバーライドすることによりACCEPT-DEFAULT-Pのかわりに使 用される。 最後のステップとして選択されたコーディングシステムをリターンする前 に、‘select-safe-coding-system’はもしリージョンのコンテンツがファイ ルから読み込まれたものだったとしたなら選択されたであろうコーディン グシステムと、そのコーディングシステムが一致するかどうかをチェック する(異なるならその後の再visitと編集でファイル内のデータ汚染が起こ り得る)。‘select-safe-coding-system’は通常はこの目的のためのファイ ルとして‘buffer-file-name’を使用するが、FILEが非‘nil’ならかわりにそ のファイルを使用する(これは‘write-region’や類似の関数に関連し得る )。明らかな不一致が検出された場合には‘select-safe-coding-system’は そのコーディングシステムを選択する前にユーザーに問い合わせる。 以下の2つの関数は補完つきでユーザーにコーディングシステムの選択を求め るために使用できます。*note Completion::を参照してください。 -- Function: read-coding-system prompt &optional default この関数は文字列PROMPTをプロンプトにミニバッファーを使用してコーデ ィングシステムを読み取り、そのコーディングシステムの名前をシンボル としてリターンする。DEFAULTはユーザーの入力が空の場合にリターンする べきコーディングシステムを指定する。これはシンボルか文字列であるこ と。 -- Function: read-non-nil-coding-system prompt この関数は文字列PROMPTをプロンプトにミニバッファーを使用してコーデ ィングシステムを読み取り、そのコーディングシステムの名前をシンボル としてリターンする。ユーザーが空の入力を試みると再度ユーザーに問い 合わせを行う。*note Coding Systems::を参照のこと。 32.10.5 デフォルトのコーディングシステム ---------------------------------------- このセクションでは特定のファイルや特定のサブプロセス実行時のデフォルトコ ーディングシステムを指定する変数、およびそれらへアクセスするためのI/O処 理が使用する関数について説明します。 これらの変数は希望するデフォルトにそれらすべてを一度セットして、その 後は再びそれを変更しないというアイデアにもとづいています。Lispプログラム 内の特定の処理で特定のコーディングシステムを指定するために、これらの変数 を変更しないでください。かわりに‘coding-system-for-read’や ‘coding-system-for-write’を使用して、それらをオーバーライドしてください (*note Specifying Coding Systems::を参照)。 -- User Option: auto-coding-regexp-alist この変数はテキストパターンと対応するコーディングシステムのalist。要 素はそれぞれ‘(REGEXP . CODING-SYSTEM)’という形式をもつ。冒頭の数キ ロバイトがREGEXPにマッチするファイルは、そのコンテンツをバッファー に読み込む際にCODING-SYSTEMによりデコードされる。このalist内のセッ ティングはファイル内の‘coding:’タグ、および ‘file-coding-system-alist’ (以下参照)の内容より優先される。デフォル ト値は、Emacsが自動的にBabylフォーマットのメールファイルを認識して コード変換なしでそれらを読み取れるようにセットされている。 -- User Option: file-coding-system-alist この変数は特定のファイルの読み書きに使用するコーディングシステムを 指定するalist。要素はそれぞれ‘(PATTERN . CODING)’という形式をもち、 PATTERNは特定のファイル名にマッチする正規表現。この要素はPATTERNに マッチするファイル名に適用される。 要素のCDRとなるCODINGはコーディングシステム、2つのコーディングシス テムを含むコンスセル、または関数名(関数定義をもつシンボル)であるこ と。CODINGがコーディングシステムなら、そのコーディングシステムはフ ァイルの読み込みと書き込みの両方で使用される。CODINGが2つのコーディ ングシステムを含むコンスセルなら、CARはデコード用のコーディングシス テム、CDRはエンコード用のコーディングシステムを指定する。 CODINGが関数名なら、それは‘find-operation-coding-system’に渡された すべての引数からなるリストを唯一の引数とする関数であること。これは コーディングシステム、または2つのコーディングシステムを含むコンスセ ルをリターンしなければならない。この値は上記と同じ意味をもつ。 CODING (または上記関数のリターン値)が‘undecided’なら通常のコード検 出が行われる。 -- User Option: auto-coding-alist この変数は特定のファイルの読み書きに使用するコーディングシステムを 指定するalist。この変数の形式は‘file-coding-system-alist’の形式と似 ているが、後者と異なるのはこの変数がファイル内の‘coding:’タグより優 先されること。 -- Variable: process-coding-system-alist この変数は何のプログラムがサブプロセス内で実行中かによって、そのサ ブプロセスにたいしてどのコーディングシステムを使用するかを指定する alist。これは‘file-coding-system-alist’と同じように機能するが、 PATTERNがそのサブプロセスを開始するために使用されたプログラム名にた いしてマッチされる点が異なる。コーディングシステム、またはalist内で 指定されたコーディングシステムは、そのサブプロセスへのI/Oに使用され るコーディングシステムの初期化に使用されるが、 ‘set-process-coding-system’を使用して後から他のコーディングシステム を指定できる。 *警告:* データからコーディングシステムを判断する‘undecided’のようなコ ーディングシステムは、非同期のサブプロセスでは完全な信頼性をもって機能は しない。これはEmacsが非同期サブプロセスの出力を到着によりバッチ処理する ためである。そのコーディングシステムが文字コード変換や行末変換を未指定に しておくと、Emacsは一度に1バッチから正しい変換の検出を試みなければならず 、これは常に機能するとは限らない。 したがって非同期サブプロセスでは可能なら文字コード変換と行末変換の両 方を判断するコーディングシステム、つまり‘undecided’や‘latin-1’ではなく ‘latin-1-unix’のようなコーディングシステムを使用すること。 -- Variable: network-coding-system-alist この変数はネットワークストリームに使用するコーディングシステムを指 定するalist。これは‘file-coding-system-alist’と同じように機能するが 、要素内のPATTERNがポート番号、または正規表現かもしれない点が異なる 。正規表現ならそのネットワークストリームのオープンに使用されたネッ トワークサービス名にたいしてマッチされる。 -- Variable: default-process-coding-system この変数は他に何を行うか指定されていない際に、サブプロセス(とネット ワークストリーム)への入出力に使用するコーディングシステムを指定する 。 値は‘(INPUT-CODING . OUTPUT-CODING)’という形式のコンスセルであるこ と。ここでINPUT-CODINGはサブプロセスからの入力、OUTPUT-CODINGはサブ プロセスへの出力に適用される。 -- User Option: auto-coding-functions この変数はファイルのデコードされていないコンテンツにもとづいて、フ ァイルにたいするコーディングシステムの判断を試みる関数のリストを保 持する。 このリスト内の各関数は、いかなる方法にせよそれを変更しないようにカ レントバッファー内のテキストを調べるように記述されていること。その バッファーはファイルの一部であるデコードされていないテキストを含む だろう。各関数はポイントを始点に何文字を調べるかを指定する唯一の引 数SIZEを受け取ること。関数がそのファイルにたいするコーディングシス テムの決定に成功したら、そのコーディングシステムをリターンすること 。それ以外は‘nil’をリターンすること。 ファイルに‘coding:’タグがある場合にはそれが優先されるので、これらの 関数が呼び出されることはないだろう。 -- Function: find-auto-coding filename size この関数はFILENAMEに適するコーディングシステムの判定を試みる。これ は上記で説明した変数により指定されたルールのいずれかにマッチするま で、それらの変数を順に使用してファイルをvisitするバッファーを調べる 。そして‘(CODING . SOURCE)’という形式のコンスセルをリターンする。こ こでCODINGは使用するコーディングシステム、SOURCEは ‘auto-coding-alist’、‘auto-coding-regexp-alist’、‘:coding’、 ‘auto-coding-functions’のいずれかであるようなシンボルであり、マッチ ングルールとして提供されるルールを示す。値‘:coding’はファイル内の ‘coding:’タグによりコーディングシステムが指定されたことを意味する (*note coding tag: (emacs)Specify Coding.を参照)。マッチングルール を調べる順序は‘auto-coding-alist’、‘auto-coding-regexp-alist’、 ‘coding:’、‘auto-coding-functions’の順。マッチングルールが見つから なければこの関数は‘nil’をリターンする。 2つ目の引数SIZEはポイントの後のテキストの文字単位のサイズ。この関数 はポイントの後のSIZE文字のテキストだけを調べる。‘coding:’タグが置か れる箇所としてはファイルの先頭2行が想定される箇所の1つなので、通常 はバッファーの先頭位置でこの関数を呼び出すこと。その場合にはSIZEは そのバッファーのサイズであること。 -- Function: set-auto-coding filename size この関数はファイルFILENAMEに適するコーディングシステムをリターンす る。これはコーディングシステムを探すために‘find-auto-coding’を使用 する。コーディングシステムを決定できなかったら、この関数は‘nil’をリ ターンする。引数SIZEの意味は‘find-auto-coding’と同様。 -- Function: find-operation-coding-system operation &rest arguments この関数は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のコンテンツを 調べること。 32.10.6 単一の操作にたいするコーディングシステムの指定 ------------------------------------------------------ 変数‘coding-system-for-read’および/または‘coding-system-for-write’をバイ ンドすることにより、特定の操作にたいしてコーディングシステムを指定できま す。 -- Variable: coding-system-for-read この変数が非‘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’を含む 、入力にたいして使用するコーディングシステムを指定するすべてのメソ ッドよりこの変数が優先される。 -- Variable: coding-system-for-write これは‘coding-system-for-read’と同じように機能するが、入力ではなく 出力に適用される点が異なる。これはファイルへの書き込み、同様にサブ プロセスおよびネットワークストリームへの出力の送信にも適用される。 単一の操作が‘call-process-region’や‘start-process’のように入力と出 力の両方を行う際には、‘coding-system-for-read’と ‘coding-system-for-write’の両方がそれに影響する。 -- User Option: inhibit-eol-conversion この変数が非‘nil’なら、どのコーディングシステムが指定されたかに関わ らず行末変換は何も行われない。これはEmacsすべてのI/Oやサブプロセス にたいするプリミティブ、および明示的なエンコード関数(*note Explicit Encoding::を参照)とデコード関数に適用される。 ある操作にたいして固定された1つのコーディングシステムではなく複数のコ ーディングシステムを選択する必要があることがあります。Emacsでは使用する コーディングシステムにたいして優先順位を指定できます。これは ‘find-coding-systems-region’(*note Lisp and Coding Systems::を参照)のよ うな関数によりリターンされるコーディングシステムのリストのソート順に影響 します。 -- Function: coding-system-priority-list &optional highestp この関数はコーディングシステムのカレント優先順にコーディングシステ ムのリストをリターンする。オプション引数HIGHESTPが非‘nil’なら、それ はもっとも高い優先度のコーディングシステムだけをリターンすることを 意味する。 -- Function: set-coding-system-priority &rest coding-systems この関数はコーディングシステムの優先リストの先頭にCODING-SYSTEMSを 配置して、それらを他のコーディングシステムすべてより高い優先度とす る。 -- Macro: with-coding-priority coding-systems &rest body... このマクロはCODING-SYSTEMSをコーディングシステム優先リスト先頭に配 置して、‘progn’ (*note progn: Sequencing.を参照)が行うようにBODYを 実行する。CODING-SYSTEMSはBODY実行中に選択するコーディングシステム のリストであること。 32.10.7 明示的なエンコードとデコード ------------------------------------ Emacs内外へテキストを転送するすべての操作は、そのテキストをエンコードま たはデコードする能力をもっています。このセクション内の関数を使用してテキ ストの明示的なエンコードやデコードを行うことができます。 エンコード結果やデコーディングへの入力は通常のテキストではありません 。これらは理論的には一連のバイト値から構成されており、すなわち一連の ASCII文字と8ビット文字から構成されます。ユニバイトのバッファーや文字列で は、これらの文字は0から#xFF(255)の範囲のコードをもちます。マルチバイトの バッファーや文字列では8ビット文字は#xFFより大きい文字コードをもちますが (*note Text Representations::を参照)、そのようなテキストのエンコードやデ コードの際にEmacsは透過的にそれらを単一バイト値に変換します。 コンテンツを明示的にデコードできるようにバイトシーケンスとしてバッフ ァーにファイルを読み込むには、‘insert-file-contents-literally’ (*note Reading from Files::を参照)を使用するのが通常の方法です。あるいは ‘find-file-noselect’でファイルをvisitする際には、引数RAWFILEに非‘nil’を 指定することもできます。これらのメソッドの結果はユニバイトバッファーにな ります。 テキストを明示的にエンコードした結果であるバイトシーケンスは、たとえ ばそれを‘write-region’ (*note Writing to Files::を参照)で書き込み、 ‘coding-system-for-write’を‘no-conversion’にバインドすることによりエンコ ードを抑制する等、それをファイルまたはプロセスへコピーするのが通常の使い 方です。 以下はエンコードやデコードを明示的に行う関数です。エンコード関数とは バイトシーケンスを生成し、デコード関数とはバイトシーケンスを操作する関数 のことを意味します。これらの関数はすべてテキストプロパティを破棄します。 これらは自身が使用したコーディングシステムを、正確に ‘last-coding-system-used’にセットすることも行います。 -- Command: encode-coding-region start end coding-system &optional destination このコマンドはSTARTからENDのテキストをコーディングシステム CODING-SYSTEMでエンコードする。バッファー内の元テキストは通常はエン コードされたテキストで置き換えられるが、オプション引数DESTINATIONで それを変更できる。DESTINATIONがバッファーなら、エンコードされたテキ ストはそのバッファーのポイントの後に挿入される(ポイントは移動しない )。‘t’ならこのコマンドはエンコードされたテキストを挿入せずにユニバ イトとしてリターンする。 エンコードされたテキストが何らかのバッファーに挿入された場合には、 このコマンドはエンコードされたテキストの長さをリターンする。 エンコードされた結果は理論的にはバイトシーケンスだが、バッファーが 以前マルチバイトだったならマルチバイトのまま留まり、すべての8ビット のバイトはマルチバイト表現に変換される(*note Text Representations::を参照)。 期待しない結果となる恐れがあるので、テキストをエンコードする際には CODING-SYSTEMに‘undecided’を_使用してはならない_。CODING-SYSTEMにた いして自明な適値が存在しなければ適切なエンコードを提案させるために 、かわりに‘select-safe-coding-system’を使用すること(*note select-safe-coding-system: User-Chosen Coding Systems.を参照)。 -- Function: encode-coding-string string coding-system &optional nocopy buffer この関数はコーディングシステムCODING-SYSTEMでSTRING内のテキストをエ ンコードする。これはエンコードされたテキストを含む新たな文字列をリ ターンするが、NOCOPYが非‘nil’の場合には、それが些細なエンコード処理 ならこの関数はSTRING自身をリターンする。エンコード結果はユニバイト 文字列。 -- Command: decode-coding-region start end coding-system &optional destination このコマンドはコーディングシステムCODING-SYSTEMで、STARTからENDのテ キストをデコードする。明示的なデコードを使いやすくするためにデコー ド前のテキストはバイトシーケンス値であるべきだが、マルチバイトとユ ニバイトのバッファーいずれでも許すようになっている(マルチバイトバッ ファーの場合rawバイト値は8ビット文字で表現されていること)。デコード されたテキストにより通常はバッファー内の元のテキストは置き換えられ るが、オプション引数DESTINATIONはそれを変更する。DESTINATIONがバッ ファーなら、デコードされたテキストはそのバッファーのポイントの後に 挿入される(ポイントは移動しない)。これが‘t’ならこのコマンドはデコー ドされたテキストを挿入せずにマルチバイト文字列としてリターンする。 デコードされたテキストが何らかのバッファーに挿入された場合には、こ のコマンドはデコードされたテキストの長さをリターンする。 このコマンドはデコードされたテキストにテキストプロパティ‘charset’を putする。このプロパティの値は元のテキストのデコードに使用された文字 セットを示す。 -- Function: decode-coding-string string coding-system &optional nocopy buffer この関数はCODING-SYSTEMでSTRING内のテキストをデコードする。これはデ コードされたテキストを含む新たな文字列をリターンするが、NOCOPYが非 ‘nil’の場合には、それが些細なデコード処理ならSTRING自体をリターンす るかもしれない。明示的なデコードを使いやすくするために、STRINGのコ ンテンツはバイトシーケンス値をもつユニバイト文字列であるべきだが、 マルチバイト文字列も許すようになっている(マルチバイト形式で8ビット バイトを含むと仮定する)。 オプション引数BUFFERがバッファーを指定する場合には、デコードされた テキストはそのバッファー内のポイントの後に挿入される(ポイントは移動 しない)。この場合にはリターン値はデコードされたテキストの長さとなる 。 この関数はデコードされたテキストにテキストプロパティ‘charset’を putする。このプロパティの値は元のテキストのデコードに使用された文字 セットを示す。 (decode-coding-string "Gr\374ss Gott" 'latin-1) ⇒ #("Grüss Gott" 0 9 (charset iso-8859-1)) -- Function: decode-coding-inserted-region from to filename &optional visit beg end replace この関数はFROMからTOのテキストを、あたかも与えられた残りの引数で ‘insert-file-contents’を使用してファイルFILENAMEから読み込んだかの ようにデコードする。 デコードせずにファイルからテキストを読み込んだ後で、やはりデコード することを決心したときに使用するのがこの関数の通常の使い方である。 テキストを削除して再度読み込むかわりに、この関数を呼び出せばデコー ドして読み込むことができる。 32.10.8 端末I/Oのエンコーディング --------------------------------- Emacsはキーボード入力のデコード、および端末出力のエンコードにコーディン グシステムを使用できます。これはLatin-1のような特定のエンコーディングを 使用したテキストの送信や表示を行う端末にとって有用です。端末I/Oをエンコ ードまたはデコードする際には、Emacsは‘last-coding-system-used’をセットし ません。 -- Function: keyboard-coding-system &optional terminal この関数はTERMINALからのキーボード入力をデコードするために使用する コーディングシステムをリターンする。‘no-conversion’という値は何のデ コーディングも行われていないことを意味する。TERMINALが省略または ‘nil’なら、それは選択されたフレームの端末を意味する。*note Multiple Terminals::を参照のこと。 -- Command: set-keyboard-coding-system coding-system &optional terminal このコマンドはTERMINALからのキーボード入力のデコードに使用するコー ディングシステムとしてCODING-SYSTEMを指定する。CODING-SYSTEMが ‘nil’なら、キーボード入力をデコードしないことを意味する。TERMINALが フレームなら、それはそのフレームの端末を意味する。‘nil’ならそれはカ レントで選択されたフレームの端末を意味する。*note Multiple Terminals::を参照のこと。 -- Function: terminal-coding-system &optional terminal この関数はTERMINALからの端末出力のエンコードに使用中のコーディング システムをリターンする。‘no-conversion’という値は何のデコーディング も行われていないことを意味する。TERMINALがフレームならそれはそのフ レームの端末を意味する。‘nil’ならそれはカレントで選択されたフレーム の端末を意味する。 -- Command: set-terminal-coding-system coding-system &optional terminal この関数はTERMINALからの端末出力のエンコードに使用するためのコーデ ィングシステムとしてCODING-SYSTEMを指定する。CODING-SYSTEMが‘nil’な ら端末出力をエンコードしないことを意味する。TERMINALがフレームなら それはそのフレームの端末を意味する。‘nil’ならそれはカレントで選択さ れたフレームの端末を意味する。 32.11 入力メソッド ================== “入力メソッド(input methods)”はキーボードから非ASCII文字を簡単に入力する 手段を提供します。プログラムが読み取ることを意図して非ASCII文字とエンコ ーディングを相互に変換するコーディングシステムとは異なり、入力メソッドは ヒューマンフレンドリーなコマンドを提供します(テキストを入力するためにユ ーザーが入力メソッドを使う方法については*note (emacs)Input Methods::を参 照)。入力メソッドの定義方法はまだこのマニュアルにはありませんが、ここで はそれらの使い方について説明します。 現在のところ入力メソッドは文字列で名前をもっていますが、将来的には入 力メソッド名としてシンボルも利用可能になるかもしれません。 -- Variable: current-input-method この変数はカレントバッファーで現在アクティブな、入力メソッドの名前 を保持する(方法に関わらずセット時には各バッファーで自動的にローカル になる)。バッファーで現在アクティブな入力メソッドがなければ値は ‘nil’。 -- User Option: default-input-method この変数は入力メソッドを選択するコマンドにたいしてデフォルトの入力 メソッドを保持する。‘current-input-method’と異なり、この変数は通常 はグローバルである。 -- Command: set-input-method input-method このコマンドはカレントバッファーで入力メソッドINPUT-METHODをアクテ ィブにする。同様に‘default-input-method’にINPUT-METHODのセットも行 う。INPUT-METHODが‘nil’なら、このコマンドはカレントバッファーで入力 メソッドを非アクティブにする。 -- Function: read-input-method-name prompt &optional default inhibit-null この関数はプロンプトPROMPTとともにミニバッファーで入力メソッドの名 前を読み取る。DEFAULTが非‘nil’の場合には、ユーザーの入力が空ならそ れがデフォルトとしてリターンされる。しかしINHIBIT-NULLが非‘nil’なら 空の入力はエラーをシグナルする。 リターン値は文字列。 -- Variable: input-method-alist この変数はサポートされているすべての入力メソッドを定義する。各要素 は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’です。*note Reading One Event::と*note Invoking the Input Method::を参照してください。 32.12 locale ============ POSIXでは、言語に関連する機能において使用する言語を制御するために localeという概念があります。以下のEmacs変数はEmacsがこれらの機能と相互作 用する方法を制御します。 -- Variable: locale-coding-system この変数は標準出力とエラーストリームへのバッチ出力の送信、 ‘format-time-string’にたいするformat引数のエンコーディング、 ‘format-time-string’のリターン値のデコーディングに際してシステムエ ラーメッセージ(およびXウィンドウシステムに限りキーボード入力)をデコ ーディングするコーディングシステムを指定する。 -- Variable: system-messages-locale この変数はシステムエラーメッセージを生成するために使用するlocaleを 指定する。locale変更によりメッセージが異なる言語になったり異なる表 記になり得る。この変数が‘nil’なら通常のPOSIX方式のようにlocaleは環 境変数により指定される。 -- Variable: system-time-locale この変数はタイムバリューをフォーマットするために使用するlocaleを指 定する。locale変更により異なる慣習によりメッセージが表示され得る。 この変数が‘nil’なら通常のPOSIX方式のようにlocaleは環境変数により指 定される。 -- Function: locale-info item この変数は、もし利用可能ならカレントPOSIX localeにたいするlocaleデ ータITEMをリターンする。ITEMは以下のシンボルのいずれかであること: ‘codeset’ 文字列として文字セットをリターンする(localeアイテムの ‘CODESET’)。 ‘days’ 曜日名からなる7要素のベクターをリターンする(localeアイテムの ‘DAY_1’から‘DAY_7’)。 ‘months’ 月の名前からなる12要素のベクターをリターンする(localeアイテム の‘MON_1’から‘MON_12’)。 ‘paper’ ‘(WIDTH HEIGHT)’というリストで、デフォルト用紙サイズをmm単位で リターンする(localeアイテム‘PAPER_WIDTH’と‘PAPER_HEIGHT’)。 システムが要求された情報を提供できなかったり、ITEMが上記いずれのシ ンボルでもなければ値は‘nil’。リターン値内のすべての文字列は ‘locale-coding-system’を使用してデコードされる。localeとlocaleアイ テムについての詳細な情報は*note (libc)Locales::を参照のこと。 33 検索とマッチング ******************* GNU Emacsはバッファーから指定されたテキストを検索するために2つの手段を提 供します。それは文字列の正確一致検索(exact string search)と正規表現検索 (regular expression search)です。正規表現検索の後で、マッチしたテキスト が正規表現全体にマッチしたのか、それとも正規表現のさまざまな部分に一致し たかを判断するために“マッチデータ(match data)”を調べることができます。 ‘skip-chars...’関連の関数もある種の検索を行います。*note Skipping Characters::を参照してください。文字プロパティ内の変更の検索は*note Property Search::を参照してください。 33.1 文字列の検索 ================= バッファー内のテキストを検索するためのプリミティブ関数が存在します。これ らはプログラム内での使用を意図したものですがインタラクティブに呼び出すこ ともできます。これらをインタラクティブに呼び出すと検索文字列の入力を求め て、引数LIMITとNOERRORは‘nil’、REPEATは1になります。インタラクティブ検索 に関するより詳細な情報は*note Searching and Replacement: (emacs)Search.を 参照してください。 以下の検索関数はバッファーがマルチバイトバッファーならマルチバイト、 ユニバイトバッファーならユニバイトに検索文字列を変換します。*note Text Representations::を参照してください。 -- Command: search-forward string &optional limit noerror count この関数はSTRINGにたいする正確なマッチをポイントから前方に検索する 。成功したら見つかったマッチの終端にポイントをセットしてポイントの 新たな値をリターンする。マッチが見つからない場合の値と副作用は NOERROR (以下参照)に依存する。 以下の例ではポイントは最初は行の先頭にある。その後の ‘(search-forward "fox")’によってポイントは‘fox’の最後の文字の後に移 動する: ---------- Buffer: foo ---------- ★The quick brown fox jumped over the lazy dog. ---------- Buffer: foo ---------- (search-forward "fox") ⇒ 20 ---------- Buffer: foo ---------- The quick brown fox★ jumped over the lazy dog. ---------- Buffer: foo ---------- 引数LIMITは検索の境界を指定するもので、それはカレントバッファー内の 位置であること。その位置を超えるようなマッチは受け入れられない。 LIMITが省略または‘nil’の場合のデフォルトは、そのバッファーのアクセ ス可能範囲の終端。 検索失敗時に何が起こるかはNOERRORの値に依存する。NOERRORが‘nil’なら ‘search-failed’はエラーをシグナルする。NOERRORが‘t’なら ‘search-forward’は‘nil’をリターンして何も行わない。NOERRORが‘nil’と ‘t’いずれでもなければ、‘search-forward’はポイントを境界上限に移動し て‘nil’をリターンする。 引数NOERRORはマッチに失敗した有効な検索だけに影響する。無効な引数は NOERRORとは無関係にエラーとなる。 REPEATが正の数Nなら検索はN回繰り返される。一連の検索は前回のマッチ の終端から毎回検索が開始される。これらの一連の検索が成功すると、関 数呼び出しは成功となりポイントを移動して新たな値をリターンする。そ れ以外は関数の呼び出しは失敗となり、結果は上述のようにNOERRORの値に 依存する。REPEATが負の数-Nなら検索は逆方向(後方)へN回行われる。 -- Command: search-backward string &optional limit noerror count この関数はポイントから後方にSTRINGを検索する。これは ‘search-forward’と似ているが、前方ではなく後方に検索する点が異なる 。後方への検索ではポイントはマッチの先頭に残される。 -- Command: word-search-forward string &optional limit noerror count この関数はポイントから前方に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’を使 用する。 -- Command: word-search-forward-lax string &optional limit noerror count このコマンドは‘word-search-forward’と同じだが、STRINGが空白で開始か 終了していなければ、STRINGの先頭か終端が単語境界にマッチする必要が ない点が異なる。たとえば‘ball boy’の検索は‘ball boyee’にはマッチす るが、‘balls boy’にはマッチしない。 -- Command: word-search-backward string &optional limit noerror count この関数はポイントから後方へSTRINGにマッチする単語を検索する。この 関数は‘word-search-forward’と同様だが、後方に検索して通常はマッチの 先頭にポイントを残す点が異なる。 -- Command: word-search-backward-lax string &optional limit noerror count このコマンドは‘word-search-backward’と同じだが、文字列が空白で開始 か終了していなければ、STRINGの先頭か終端が単語境界にマッチする必要 がない点が異なる。 33.2 検索と大文字小文字 ======================= デフォルトのEmacs検索では検索するテキストのcase(大文字と小文字)は無視さ れます。検索対象に‘FOO’を指定すると、‘Foo’や‘foo’もマッチとみなされます 。これは正規表現にも適用されます。つまり‘[aB]’は‘a’、‘A’、‘b’、‘B’にもマ ッチするでしょう。 この機能が望ましくなければ変数‘case-fold-search’に‘nil’をセットしてく ださい。その場合にはすべての文字はcaseを含めて正確にマッチしなければなり ません。これはバッファーローカル変数です。この変数の変更はカレントバッフ ァーだけに影響を与えます(*note Intro to Buffer-Local::を参照)。かわりに デフォルト値を変更することもできます。Lispコードでは‘let’を使用して ‘case-fold-search’を望む値にバインドするほうが、より一般的でしょう。 ユーザーレベルのインクリメンタル検索機能ではcaseの区別が異なることに 注意してください。検索文字列に含まれるのが小文字だけなら検索はcaseを無視 しますが、検索文字列に1つ以上の大文字が含まれれば検索はcaseを区別するよ うになります。しかしLispコード内で使用される検索関数では、これは何も行い ません。*note (emacs)Incremental Search::を参照してください。 -- User Option: case-fold-search このバッファーローカル変数は検索がcaseを無視するべきかどうかを決定 する。この変数が‘nil’なら検索はcaseを無視しない。それ以外(とデフォ ルト)ではcaseを無視する。 -- User Option: case-replace この変数は高レベルの置換関数がcaseを保持するべきかどうかを決定する 。この変数が‘nil’なら、それは置換テキストをそのまま使用することを意 味する。非‘nil’値は置換されるテキストに応じて、置換テキストのcaseを 変換することを意味する。 この変数は関数‘replace-match’の引数として渡すことにより使用される。 *note Replacing Match::を参照のこと。 33.3 正規表現 ============= “正規表現(regular expression)”、略して“regexp”は文字列の(もしかしたら無 限の)セットを表すパターンのことです。regexpにたいするマッチの検索はとて も強力な処理です。このセクションではregexpの記述方法、それ以降のセクショ ンではそれらを検索する方法を示します。 正規表現を対話的に開発するために‘M-x re-builder’コマンドを使用できま す。このコマンドは別のバッファーに即座に視覚的なフィードバックを表示する ことにより、正規表現を作成するための便利なインターフェースを提供します。 regexp編集とともにターゲットとなるバッファーのすべてのマッチがハイライト されます。カッコで括られたregexpの部分式(sub-expression)は別のフェイスで 表示され、非常に複雑なregexpを簡単に検証することが可能になります。 33.3.1 正規表現の構文 --------------------- 正規表現は少数の文字が特別な構成要素であり、残りは“通常”の文字であるよう な構文をもちます。通常の文字はその文字自身だけにマッチするシンプルな正規 表現です。特別な文字は‘.’、‘*’、‘+’、‘?’、‘[’、‘^’、‘$’、および‘\’です。 将来に新たなスペシャル文字が定義されることはないでしょう。文字候補で終わ る場合には‘]’はスペシャル文字です。文字候補の間では‘-’はスペシャル文字で す。‘[:’と対応する‘:]’は文字候補内の文字クラスです。正規表現内に出現する 他の文字は‘\’が前置されていない限り通常の文字です。 たとえば‘f’はスペシャル文字ではなく通常文字なので、‘f’は文字列‘f’にマ ッチして他の文字にはマッチしない正規表現です(これは文字列‘fg’には_マッチ しない_が、その文字列の_部分_にマッチする)。同様に‘o’は‘o’だけにマッチし ます。 任意の2つの正規表現AとBを結合することができます。結合した結果は文字列 の先頭からある長さの文字列がAにマッチして、残りの文字列がBにマッチするよ うな文字列にマッチする正規表現になります。 単純な例として文字列‘fo’だけにマッチする正規表現の構成要素‘fo’を取得 するために正規表現‘f’と‘o’を結合できます。 33.3.1.1 正規表現内の特殊文字 ............................. 以下は正規表現内で特別な文字のリストです: ‘.’ (Period) これは改行を除く1文字にマッチする。結合を使用して‘a.b’のような正規 表現を作成できる。これは‘a’で始まり‘b’で終わる3文字の文字列にマッチ する。 ‘*’ これはそれ自身が構成要素ではない。これは前置された正規表現を可能な 限り繰り返したものにマッチすることを意味する後置演算子である。した がって‘o*’は任意の個数の‘o’にマッチする(‘o’を含まない場合にもマッチ する)。 ‘*’は常に前置された表現の_最小_の表現に適用される。つまり‘fo*’は ‘o’の繰り返しであり‘fo’の繰り返しではない。これは‘f’、‘fo’、‘foo’、 ...にマッチする。 マッチを行う処理は構成要素‘*’を、マッチングにより即座に見つけ得る回 数分処理して、その後にパターンの残りを継続する。これが失敗したら残 りのパターンのマッチが可能になるかもしれないという期待のもとに、 ‘*’の変更された構成のうちいくつかのマッチを破棄することによるバック トラッキングが発生する。たとえば文字列‘caaar’にたいして‘ca*ar’をマ ッチングすると、‘a*’はまず3つすべての‘a’へのマッチを試みる。しかし 残りのパターンは‘ar’でありマッチ対象に残されているのは‘r’だけなので この試みは失敗する。‘a*’にたいする次の代替策は2つの‘a’だけへのマッ チである。この選択では残りのregexpのマッチは成功する。 *警告:* ネストされた繰り返し処理は、それらが曖昧なマッチとなるよう な場合には無期限な長時間の実行となり得る。たとえば文字列 ‘xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz’にたいして正規表現 ‘\(x+y*\)*a’のマッチを試みると、それが最終的に失敗するまでに数時間 を要す可能性がある。Emacsはその試みのいずれも機能しないと結論する前 に、‘x’のグループ化のそれぞれを試みなければならない。さらに悪いこと に‘\(x*\)*’は無数の方法でnull文字列にマッチ可能なので無限ループを引 き起こす。これらの問題を避けるにはネストされた繰り返しがバックトラ ッキングでの組み合わせ爆発(combinatorial explosion)が発生しないこと を確実にするために注意深くチェックすること。 ‘+’ これは‘*’のような後置演算子だが前置された表現に少なくとも1回マッチ しなければならない点が異なる。たとえば‘ca+r’は文字列‘car’や ‘caaaar’にマッチするが文字列‘cr’にはマッチせず、その一方で‘ca*r’は これら3つすべての文字列にマッチする。 ‘?’ これは‘*’のような後置演算子だが前置された表現に1回、またはマッチし ないかのいずれかでなければならない点が異なる。例えば‘ca?r’は‘car’と ‘cr’にマッチするが他にはマッチしない。 ‘*?’, ‘+?’, ‘??’ 演算子 ‘*’、‘+’、‘?’には“非欲張り(non-greedy)”な変種が存在する。こ れらの演算子が可能な最長の部分文字列(含まれる表現全体へのマッチと等 しい)とマッチするのにたいして、非欲張りな変種は可能な最短の部分文字 列(含まれる表現全体と等しい)にマッチする。 たとえば正規表現‘c[ad]*a’を文字列‘cdaaada’に適用すると文字列全体に マッチするが、正規表現‘c[ad]*?a’を同じ文字列に適用すると‘cda’だけに マッチする(ここでマッチが許された表現全体にたいする‘[ad]*?’の可能な 最短マッチは‘d’)。 ‘[ ... ]’ これは‘[’で始まり‘]’で終端される“文字候補(character alternative)”。 もっとも単純なケースでは、この2つのカッコ(brackets)の間にある文字 が、この文字候補がマッチ可能な文字。 したがって‘[ad]’は1つの‘a’と1つの‘d’の両方にマッチし、‘[ad]*’は ‘a’と‘d’だけで構成された任意の文字列(空文字列を含む)にマッチする。 つまり‘c[ad]*r’は‘cr’、‘car’、‘cdr’、‘caddaar’等にマッチする。 開始文字と終了文字の間に‘-’を記述することにより、文字候補内に文字範 囲を含めることができる。つまり‘[a-z]’は小文字のASCIIアルファベット 文字にマッチする。範囲は‘[a-z$%.]’のように個別の文字と自由に組み合 わせることができる。これは任意のASCII小文字アルファベットと‘$’、 ‘%’、またはピリオドとマッチする。 ‘case-fold-search’が非‘nil’なら、‘[a-z]’は大文字アルファベットにも マッチする。‘[a-z]’のような範囲はそのlocaleの照合順に影響されず、常 にASCII順のシーケンスを表すことに注意。 さらに通常のregexpスペシャル文字は文字候補内では特別ではないことに も注意。文字候補内部では‘]’、‘-’、‘^’という完全に異なる文字セットが 特別に扱われる。 文字候補内に‘]’を含めるには、それを最初の文字にしなければならない。 たとえば‘[]a]’は‘]’と‘a’にマッチする。‘-’を含めるには文字候補の最初 または最後の文字として‘-’を記述するか、範囲の後に配置すること。つま り‘[]-]’は‘]’と‘-’の両方にマッチする(以下で説明するように、ここでは ‘\’は特別ではないので、文字候補内に‘]’を含めるために‘\]’は使用でき ない)。 文字候補内に‘^’を含めるには先頭以外のいずれかの場所に置くこと。 ある範囲がユニバイト文字Cで始まり、マルチバイト文字C2で終われば、そ の範囲は2つの部分に分割される。1つはユニバイト文字‘C..?\377’、もう 1つはマルチバイト文字‘C1..C2’。ここでC1はC2が属する文字セットの最初 の文字。 文字候補には名前付き文字クラスも指定できる(*note Char Classes::を参 照)。これはPOSIXの機能である。たとえば‘[[:ascii:]]’は任意のASCII文 字にマッチする。文字クラスの使用は、そのクラス内すべての文字を記述 するのと等しい。しかし異なる文字を数千含むクラスもあるので、後者は 実際は実現可能ではない。 ‘[^ ... ]’ ‘[^’は“補完文字候補(complemented character alternative)”を開始する 。これは指定された以外の任意の文字とマッチする。つまり ‘[^a-z0-9A-Z]’はアルファベットと数字_以外_の、すべての文字にマッチ する。 ‘^’は文字クラス内では先頭に記述されない限り特別ではない。‘^’に続く 文字は、あたかもそれが先頭にあるかのように扱われる(言い換えると ‘-’や‘]’はここでは特別ではない)。 マッチしない文字の1つとして改行が記述されていなければ、補完文字候補 は改行にマッチできる。これは‘grep’のようなプログラム内でのregexpの 扱いとは対照的である。 文字候補のように名前付き文字クラスを指定できる。たとえば ‘[^[:ascii:]]’は任意の非ASCII文字にマッチする。*note Char Classes::を参照のこと。 ‘^’ バッファーのマッチングの際には‘^’は空文字列、ただしマッチ対象のテキ スト内にある行の先頭(またはバッファーのアクセス可能範囲の先頭)だけ にマッチする。それ以外のマッチはすべて失敗する。つまり‘^foo’は行の 先頭に出現する‘foo’にマッチする。 バッファーではなく文字列とマッチする際には、‘^’は文字列の先頭か改行 文字の後にマッチする。 歴史的な互換性という理由により‘^’は正規表現の先頭、または‘\(’、 ‘\(?:’、‘\|’の後でのみ使用できる。 ‘$’ これは‘^’と似ているが、行の終端(またはバッファーのアクセス可能範囲 の終端)だけにマッチする。つまり‘x+$’は行末にある1つ以上の‘x’からな る文字列にマッチする。 バッファーではなく文字列とマッチする際には、‘$’は文字列の終端か改行 文字の前にマッチする。 歴史的な互換性という理由により‘$’は正規表現の先頭、または‘\(’、 ‘\(?:’、‘\|’の前でのみ使用できる。 ‘\’ これはスペシャル文字(‘\’を含む)のクォートと、追加のスペシャル文字の 導入という2つの機能をもつ。 ‘\’はスペシャル文字をクォートするので‘\$’は‘$’、‘\[’は‘[’だけにマッ チする正規表現のようになる。 ‘\’はLisp文字列(*note String Type::を参照)の入力構文(read syntax)内 でも特別な意味をもち、‘\’でクォートしなければならないことに注意。た とえば文字‘\’にマッチする正規表現は‘\\’。文字‘\\’を含むLisp文字列を 記述するには、別の‘\\’で‘\\’をクォートすることをLisp構文は要求する 。したがって‘\’にマッチする正規表現にたいする入力構文は‘"\\\\"’とな る。 *注意してください:* 歴史的な互換性のために、スペシャル文字はそれらが もつ特別な意味が意味を成さないコンテキスト内にある場合には通常の文字とし て扱われます。たとえば‘*foo’は‘*’が作用可能な前置された表現がないので、 通常の‘*’として扱われます。この挙動に依存するのは悪い習慣です。どこにそ れが出現しようとスペシャル文字はすべてクォートしてください。 文字候補内で‘\’は何ら特別ではないので、‘-’や‘]’の特別な意味を取り除く ことは決してありません。特別な意味をもたないような場合でも、これらの文字 をクォートするべきではありません。バックスラッシュ以外の任意の1文字にマ ッチする‘[^\]’ (Lisp文字列構文では‘"[^\\]"’)内でのように、これらの文字が _特別な意味_をもつ箇所では、これらの文字にバックスラッシュを前置すること には正当性があるので、何もそれほど明解にはしないでしょう。 実際には正規表現内に出現する‘]’は文字候補に近接しており、それ故そのほ とんどがスペシャル文字です。しかしリテラルの‘[’と‘]’の複雑なパターンにた いしてマッチを試みることも時にはあるかもしれません。そのような状況では文 字候補を囲う角カッコがどれなのかを判断するために、regexpを最初から注意深 く解析することが必要なときもあるかもしれません。たとえば‘[^][]]’は補完文 字候補‘[^][]’ (角カッコ以外の任意の1文字とマッチする)と、その後のリテラ ルの‘]’により構成されます。 厳密にはregexp先頭の‘[’は特別で、‘]’は特別ではないというのがルールで す。これはクォートされていない最初の‘[’で終わり、その後は文字候補になり ます。(文字クラス開始を除き)‘[’はもはや特別ではありませんが、‘]’は直後に スペシャル文字‘[’があるか、その‘[’の後に‘^’がある場合を除いて特別です。 これは文字クラス終了ではない次のスペシャル文字‘]’まで続きます。これは文 字候補を終了させて、通常の正規表現の構文をリストアします。クォートされて いない‘[’は再び特別となり、‘]’は特別ではなくなります。 33.3.1.2 文字クラス ................... 以下は文字候補内で使用できるクラスと、その意味についてのテーブルです: ‘[:ascii:]’ これは任意のASCII文字(コード0 – 127)にマッチする。 ‘[:alnum:]’ これは任意の英数字にマッチする。マルチバイト文字では、アルファベッ ト文字か数字であることを示すUnicodeプロパティ‘general-category’ (*note Character Properties::を参照)をもつ文字にマッチする。 ‘[:alpha:]’ これは任意のアルファベットにマッチする。マルチバイト文字では、アル ファベット文字であることを示すUnicodeプロパティ‘general-category’ (*note Character Properties::を参照)をもつ文字にマッチする。 ‘[:blank:]’ これはスペースとタブだけにマッチする。 ‘[:cntrl:]’ これはASCII制御文字にマッチする。 ‘[:digit:]’ これは‘0’から‘9’までにマッチする。つまり‘[-+[:digit:]]’は‘+’と‘-’、 同様に任意の数にマッチする。 ‘[:graph:]’ これはUnicodeの‘general-category’プロパティで示されるようなグラフィ ック文字(空白文字、ASCIIと非ASCIIの制御文字、サロゲートードポイント 、Unicodeで未割り当てのコードポイントを除くすべて)にマッチする (*note Character Properties::を参照)。 ‘[:lower:]’ これはカレントのcaseテーブル(*note Case Tables::を参照)で小文字と判 断される文字すべてにマッチする。‘case-fold-search’が非‘nil’なら大文 字にもマッチする。 ‘[:multibyte:]’ これは任意のマルチバイト文字にマッチする(*note Text Representations::を参照)。 ‘[:nonascii:]’ これは非ASCII文字にマッチする。 ‘[:print:]’ これは任意のプリント文字(空白文字か‘[:graph:]’でマッチされるグラフ ィック文字のいずれか)にマッチする。 ‘[:punct:]’ これは任意の句読点文字(punctuation character)にマッチする(現在のと ころマルチバイト文字では単語構文以外のすべてにマッチする)。 ‘[:space:]’ これは空白文字構文(*note Syntax Class Table::を参照)をもつ任意の文 字にマッチする。 ‘[:unibyte:]’ これは任意のユニバイト文字(*note Text Representations::を参照)にマ ッチする。 ‘[:upper:]’ これはカレントのcaseテーブル(*note Case Tables::を参照)で大文字と判 断される文字すべてにマッチする。‘case-fold-search’が非‘nil’ならこれ は小文字にもマッチする。 ‘[:word:]’ これは単語構文(*note Syntax Class Table::を参照)をもつ任意の文字に マッチする。 ‘[:xdigit:]’ これは16進数の数字‘0’から‘9’、‘a’から‘f’と‘A’から‘F’にマッチする。 33.3.1.3 正規表現内のバッククラッシュ構造 ......................................... ほとんどの場合では、‘\’の後の任意の文字はその文字だけにマッチします。し かし例外もいくつかあります。‘\’で始まる特定のシーケンスには、特別な意味 をもつものがあります。以下は特別な‘\’構成要素のテーブルです。 ‘\|’ これは選択肢を指定する。2つの正規表現AとB、その間にある‘\|’により、 AかBのいずれかにマッチする表現が形成される。 つまり‘foo\|bar’は、‘foo’か‘bar’のいずれかにマッチして他の文字列に はマッチしない。 ‘\|’は周囲の適用可能な最大の表現に適用される。‘\|’を取り囲む‘\( ... \)’でグループ化することによりグループ化の効力を制限できる。 複数の‘\|’の処理するための完全なバックトラッキング互換が必要なら、 POSIX正規表現関数を使用すること(*note POSIX Regexps::を参照)。 ‘\{M\}’ これは前のパターンを正確にM回繰り返す後置演算子。つまり‘x\{5\}’は文 字列‘xxxxx’にマッチして、それ以外にはマッチしない。‘c[ad]\{3\}r’は ‘caaar’、‘cdddr’、‘cadar’等にマッチする。 ‘\{M,N\}’ これは最小でM回、最大でN回の繰り返しを表す、より一般的な後置演算子 。M省略時の最小は0、N省略時の最大は存在しない。 たとえば‘c[ad]\{1,2\}r’は文字列‘car’、‘cdr’、‘caar’、‘cadr’、 ‘cdar’、‘cddr’にマッチして、それ以外にはマッチしない。 ‘\{0,1\}’や‘\{,1\}’は‘?’と同じ。 ‘\{0,\}’や‘\{,\}’は‘*’と同じ。 ‘\{1,\}’は‘+’と同じ。 ‘\( ... \)’ これは以下の3つの目的を果たす役目をもつグループ化構成要素: 1. 他の操作のために一連の‘\|’選択肢を囲う。つまり正規表現 ‘\(foo\|bar\)x’は、‘foox’か‘barx’のいずれかにマッチする。 2. 後置演算子‘*’、‘+’、‘?’による複雑な表現を囲う。つまり ‘ba\(na\)*’は‘ba’、‘bana’、‘banana’、‘bananana’、...等の任意の 数(0以上)の文字列‘na’にマッチする。 3. ‘\DIGIT’ (以下参照)による将来の参照にたいして、マッチする部分 文字列を記録する。 この最後の目的はカッコによるグループ化というアイデアによるものでは ない。これは同じ構成要素‘\( ... \)’にたいする2つ目の目的に割当てら れた別の機能だが、実際のところ2つの意味は衝突しない。しかし稀に衝突 が発生することがあり、それが内気(shy)なグループの導入をもたらした。 ‘\(?: ... \)’ これは“内気なグループ(shy group)”の構成要素。内気なグループは通常の グループの最初の2つの役目(他の演算子のネスト制御)を果たすが、これは 番号を取得せず‘\DIGIT’でその値を後方参照できない。内気なグループは 通常の非内気なグループを変更することなく自動的に追加できるので、機 械的に正規表現を構築するのに特に適している。 内気なグループ化は“非キャプチャリング(non-capturing)”、“番号なしグ ループ(unnumbered groups)”とも呼ばれる。 ‘\(?NUM: ... \)’ これは“明示的番号付きグループ(explicitly numbered group)”の構成要素 。通常のグループ化では位置をもとに番号が暗黙で取得されるが、これが 不便な場合もあるだろう。この構成要素により特定のグループに番号を強 制できる。番号の付与に特別な制限はなく、複数のグループに同じ番号を 付与でき、その場合は最後の1つ(もっとも右のマッチ)がマッチとして採用 される。暗黙に番号付けされたグループは、常に前のグループより大きい 最小の整数となる番号を取得する。 ‘\DIGIT’ これはグループ構成要素(‘\( ... \)’)の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’にマッチするのでマッチが可能になる。 ‘\w’ これは任意の単語構成文字にマッチする。エディターの構文テーブルが、 どの文字が単語構成文字かを決定する。*note Syntax Tables::を参照のこ と。 ‘\W’ これは任意の非単語構成文字にマッチする。 ‘\sCODE’ これは構文がCODEであるような任意の文字にマッチする。ここでCODEは、 構文コードを表す文字。‘w’は単語構成要素、‘-’は空白文字、‘(’は開カッ コ、...等。空白文字構文を表すには、‘-’かスペース文字のいずれかを使 用する。構文コードとそれらを意味する文字のリストは*note Syntax Class Table::を参照のこと。 ‘\SCODE’ これは構文がCODEでないような任意の文字にマッチする。 ‘\cC’ これはカテゴリーがCであるような任意の文字にマッチする。ここでCはカ テゴリーを表す文字。つまり標準カテゴリーテーブルで‘c’はChinese(中国 語)、‘g’はGreek(ギリシャ語)の文字となる。‘M-x describe-categories ’で現在定義済みの全カテゴリーのリストを確認できる。 ‘define-category’関数を使用すれば、標準カテゴリーに加えてカテゴリー を独自に定義することもできる(*note Categories::を参照)。 ‘\CC’ これはカテゴリーがCではない任意の文字にマッチする。 以下は空文字列にマッチ(つまり文字を何も消費しない)しますが、マッチす るかどうかはコンテキストに依存するような正規表現を構築します。これらすべ てにたいして、そのバッファーのアクセス可能範囲の先頭と終端は、あたかもそ のバッファーの実際の先頭と終端のように扱われます。 ‘\`’ これは空文字列、ただしバッファー先頭またはマッチ対象の文字列の先頭 だけにマッチする。 ‘\'’ これは空文字列、ただしバッファー終端またはマッチ対象の文字列の終端 だけにマッチする。 ‘\=’ これは空文字列、ただしポイント位置だけにマッチする(この構成要素はマ ッチ対象が文字列なら定義されない)。 ‘\b’ これは空文字列、ただし単語の先頭だけにマッチする。つまり‘\bfoo\b’は 個別の単語として出現する‘foo’だけにマッチする。‘\bballs?\b’は、個別 の単語として‘ball’か‘balls’にマッチする。 ‘\b’は、隣接するテキストが何であるかと無関係に、バッファー(か文字列 )の先頭または終端にマッチする。 ‘\B’ これは空文字列、単語の先頭や終端、またはバッファー(か文字列)の先頭 や終端_以外_にマッチする。 ‘\<’ これは空文字列、ただし単語の先頭だけにマッチする。‘\<’は後に単語構 成文字が続く場合のみバッファー(か文字列)の先頭にマッチする。 ‘\>’ これは空文字列、ただし単語の終端だけにマッチする。‘\<’はコンテンツ が単語構成文字で終わる場合のみバッファー(か文字列)の終端にマッチす る。 ‘\_<’ これは空文字列、ただしシンボルの先頭だけにマッチする。シンボルとは 1つ以上の単語かシンボル構成文字のシーケンス。‘\_<’は後にシンボル構 成文字が続く場合のみバッファー(か文字列)の先頭にマッチする。 ‘\_>’ これは空文字列、ただし単語の終端だけにマッチする。‘\_>’はコンテンツ がシンボル構成文字で終わる場合のみバッファー(か文字列)の終端にマッ チする。 すべての文字列が、有効な正規表現な訳ではありません。たとえば終端の ‘]’がない文字選択肢の内側で終わる文字列は無効であり、単一の‘\’で終わる文 字列も同様です。いずれかの検索関数にたいして無効な正規表現が渡されると ‘invalid-regexp’エラーがシグナルされます。 33.3.2 正規表現の複雑な例 ------------------------- 以下は後続の空白文字とともにセンテンスの終わりを認識するために、以前の Emacsで使用されていた複雑な正規表現の例です(現在のEmacsは関数 ‘sentence-end’により構築される、同様のより複雑なregexpを使用する。*note Standard Regexps::を参照)。 以下ではまず、(スペースとタブ文字を区別するために)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]*’ 最後にパターンの最終パートはセンテンスを終端させるために必要とされ る以上の、余分な空白文字にマッチする。 33.3.3 正規表現の関数 --------------------- 以下の関数は正規表現を扱います。 -- Function: regexp-quote string この関数はSTRINGだけに正確にマッチするような正規表現をリターンする 。‘looking-at’内でこの正規表現を使用すると、そのバッファー内の次の 文字がSTRINGのときだけ成功するだろう。検索関数でのこの正規表現の使 用は、検索されるテキストがSTRINGを含むなら成功するだろう。*note Regexp Search::を参照のこと。 これにより、その正規表現を求める関数呼び出し時に正確な文字列マッチ や検索を要求できる。 (regexp-quote "^The cat$") ⇒ "\\^The cat\\$" 正規表現として記述されたコンテキストにおいて、正確な文字列マッチを 結合することが‘regexp-quote’の1つの使い方である。たとえば以下は空白 文で囲まれたSTRINGの値であるような文字列を検索する: (re-search-forward (concat "\\s-" (regexp-quote string) "\\s-")) -- Function: regexp-opt strings &optional paren この関数はリストSTRINGSの文字列だけにマッチする効果的な正規表現をリ ターンする。これはマッチングや検索を可能な限り高速にする必要がある とき、たとえばFont Lockモードで有用である(1)。 オプション引数PARENには以下のいずれかを指定できる: 文字列なら結果regexpはPARENと後の‘\)’により生成される。つまり番号付 きグループを明示的に生成するためには‘"\\(?1:"’を使用する。 ‘words’なら結果regexpは‘\<\(’と‘\)\>’で囲まれる。 ‘symbols’ならなら結果regexpは‘\_<\(’と‘\)\_>’で囲まれる(これはプロ グラミング言語のキーワードやその類のマッチング時に適切なことが多い )。 非‘nil’ならなら結果regexpは‘\(’と‘\)’で囲まれる。 ‘nil’なら、追加される後置演算子が式全体に確実に適用させるために必要 な場合には、結果regexpは‘\(?:’と‘\)’で囲まれる。 ‘regexp-opt’の結果regexpはその単純化されたバージョンと等価だが、通 常はより効果的である。 (defun simplified-regexp-opt (strings &optional paren) (let ((parens (cond ((stringp paren) (cons paren "\\)")) ((eq paren 'words) '("\\<\\(" . "\\)\\>")) ((eq paren 'symbols) '("\\_<\\(" . "\\)\\_>")) ((null paren) '("\\(?:" . "\\)")) (t '("\\(" . "\\)"))))) (concat (car paren) (mapconcat 'regexp-quote strings "\\|") (cdr paren)))) -- Function: regexp-opt-depth regexp この関数はREGEXP内のグループ化された構成要素(カッコで囲まれた正規表 現)の総数をリターンする。これには内気なグループは含まれない(*note Regexp Backslash::を参照)。 -- Function: regexp-opt-charset chars この関数は文字リストCHARS内の文字にマッチする正規表現をリターンする 。 (regexp-opt-charset '(?a ?b ?c ?d ?e)) ⇒ "[a-e]" ---------- Footnotes ---------- (1) ‘regexp-opt’の結果が絶対的にもっとも効率的であるという保証はない ことに注意してください。手作業でチューニングした正規表現のほうがわずかに 効率的なこともありますが、これに努力する価値はほとんどないでしょう。 33.4 正規表現の検索 =================== GNU Emacsではインクリメンタルと非インクリメンタルの両方で正規表現(*note Syntax of Regexps::を参照)にたいする次のマッチを検索できます。インクリメ ンタル検索コマンドについては*note Regular Expression Search: (emacs)Regexp Search.を参照してください。ここではプログラム内で有用な検 索関数だけを説明します。重要な関数は‘re-search-forward’です。 これらの検索関数はバッファーがマルチバイトならルチバイト、ユニバイト ならユニバイトに正規表現を変換します。*note Text Representations::を参照 してください。 -- Command: re-search-forward regexp &optional limit noerror count この関数はカレントバッファー内で、正規表現REGEXPにマッチするテキス ト文字列を前方へ検索する。この関数はREGEXPにマッチしない任意の量の テキストをスキップして、見つかった最初のマッチの終端にポイントを残 す。これはポイントの新たな値をリターンする。 引数LIMITは検索の境界を指定し、それはカレントバッファー内の位置であ ること。LIMITが非‘nil’ならカレントバッファー内の位置でなければなら ない。これは検索の上限位置を指定するその位置を超えるようなマッチは 、受け入れられない。LIMITが省略または‘nil’の場合のデフォルトは、そ のバッファーのアクセス可能範囲の終端である。 検索失敗時に‘re-search-forward’が何を行うかはNOERRORの値に依存する 。 ‘nil’ ‘search-failed’エラーをシグナルする。 ‘t’ 何もせず‘nil’をリターンする。 その他 ポイントをLIMIT (またはバッファーのアクセス可能範囲の終端)に移 動して‘nil’をリターンする。 引数NOERRORはマッチに失敗した有効な検索だけに影響する。無効な引数は NOERRORとは無関係にエラーとなる。 REPEATが正の数Nなら検索はN回繰り返される。一連の検索は前回のマッチ の終端から毎回検索が開始される。これらの一連の検索が成功すると、関 数呼び出しは成功となりポイントを移動して新たな値をリターンする。そ れ以外は関数の呼び出しは失敗となり、結果は上述のようにNOERRORの値に 依存する。REPEATが負の数-Nなら検索は逆方向(後方)へN回行われる。 以下の例ではポイントは最初は‘T’の前にある。この検索を評価することに より、その行の終端( ‘hat’の‘t’と改行の間)にポイントは移動する。 ---------- Buffer: foo ---------- I read "★The cat in the hat comes back" twice. ---------- Buffer: foo ---------- (re-search-forward "[a-z]+" nil t 5) ⇒ 27 ---------- Buffer: foo ---------- I read "The cat in the hat★ comes back" twice. ---------- Buffer: foo ---------- -- Command: re-search-backward regexp &optional limit noerror count この関数はカレントバッファー内で正規表現REGEXPにマッチするテキスト 文字列を後方へ検索して、見つかった最初のマッチの先頭にポイントを残 す。 この関数は‘re-search-forward’と似ているが単なるミラーイメージ (mirror-image: 鏡像)ではない。‘re-search-forward’は先頭が開始ポイン トと可能な限り近いマッチを探す。‘re-search-backward’が完全なミラー イメージなら終端が可能な限り近いマッチを探すだろう。しかし実際には 先頭が可能な限り近い(かつ開始ポイントの前で終わる)マッチを探す。こ れは与えられた位置にたいする正規表現マッチングが常に正規表現の先頭 から終端に機能して、指定された開始位置から開始されることが理由。 ‘re-search-forward’の真のミラーイメージには、正規表現を終端から先頭 へマッチする特別な機能が要求されるだろう。それを実装することによる 問題と比較して、値する価値はない。 -- Function: string-match regexp string &optional start この関数は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)’で利用できる。*note Match Data::を参照のこと。 (string-match "quick" "The quick brown fox jumped quickly." 8) ⇒ 27 (match-end 0) ⇒ 32 -- Function: string-match-p regexp string &optional start この述語関数は‘string-match’と同じことを行うが、マッチデータの変更 を避ける。 -- Function: looking-at regexp この関数はカレントバッファー内のポイント直後のテキストが正規表現 REGEXPにマッチするかどうかを判断する。“直後”の正確な意味は、その検 索が“固定”されていて、ポイントの後の最初の文字からマッチが開始する 場合のみ成功するということ。成功なら結果は‘t’、それ以外は‘nil’。 この関数はポイントを移動しないがマッチデータは更新する。*note Match Data::を参照のこと。マッチデータを変更せずにテストする必要があるな ら、以下で説明する‘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 -- Function: looking-back regexp limit &optional greedy この関数はポイントの直前の(ポイントで終わる)テキストが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’の追加は計画されていない。 -- Function: looking-at-p regexp この述語関数は‘looking-at’と同様に機能するがマッチデータを更新しな い。 -- Variable: search-spaces-regexp この変数が非‘nil’なら、それは空白文字を検索する方法を告げる正規表現 であること。この場合には検索される正規表現内のすべてのスペース属は 、この正規表現を使用することを意味する。しかし‘[...]’、‘*’‘+’、 ‘?’のような構文要素内のスペースは‘search-spaces-regexp’の影響を受け ない。 この変数はすべての正規表現検索とマッチ構文要素に影響するので、コー ドの可能な限り狭い範囲にたいして一時的にバインドすること。 33.5 POSIX正規表現の検索 ======================== 通常の正規表現関数は、‘\|’や繰り返しの構文要素を処理するために必要なとき だけバックトラッキングを行いますが、_何らか_のマッチが見つかるまでの間だ けこれを継続します。そして成功した後に見つかった最初のマッチを報告します 。 このセクションでは正規表現にたいしてPOSIX標準で指定された完全なバック トラッキングを処理する他の検索関数を説明します。これらはPOSIXが要求する 最長マッチを報告できるようにすべての可能なマッチを試みて、すべてのマッチ が見つかるまでバックトラッキングを継続します。これは非常に低速なので、本 当に最長マッチが必要なときだけこれらの関数を使用してください。 POSIXの検索とマッチ関数は、非欲張りな繰り返し演算子(*note non-greedy: Regexp Special.を参照)を正しくサポートしません。これはPOSIXのバックトラ ッキングが非欲張りな繰り返しのセマンチックと競合するからです。 -- Command: posix-search-forward regexp &optional limit noerror count これは‘re-search-forward’と似ているが、正規表現マッチングにたいして POSIX標準が指定する完全なバックトラッキングを行う点が異なる。 -- Command: posix-search-backward regexp &optional limit noerror count これは‘re-search-backward’と似ているが、正規表現マッチングにたいし てPOSIX標準が指定する完全なバックトラッキングを行う点が異なる。 -- Function: posix-looking-at regexp これは‘looking-at’と似ているが、正規表現マッチングにたいしてPOSIX標 準が指定する完全なバックトラッキングを行う点が異なる。 -- Function: posix-string-match regexp string &optional start これは‘string-match’と似ているが、正規表現にたいしてPOSIX標準が指定 する完全なバックトラッキングを行う点が異なる。 33.6 マッチデータ ================= Emacsは検索の間に見つかったテキスト片の開始と終了の位置を追跡します。こ れは“マッチデータ(match data)”と呼ばれます。このマッチデータのおかげで、 メールメッセージ内のデータのような複雑なパターンを検索した後に、そのパタ ーンの制御下でマッチ部分を抽出できるのです。 マッチデータには通常はもっとも最近の検索だけが記述されるので、後で参 照したい検索とそのマッチデータの使用の間に誤って別の検索を行わないように 注意しなければなりません。誤って別の検索を避けるのが不可能な場合には、マ ッチデータの上書きを防ぐために前後でマッチデータの保存とリストアを行わな ければなりません。 上書きを行わないと明記されていない限り、すべての関数は上書きを許され ていることに注意してください。結果としてバックグラウンド(*note Timers::と *note Idle Timers::を参照)で暗黙に実行される関数は、おそらく明示的にマッ チデータの保存とリストアを行うべきでしょう。 33.6.1 マッチしたテキストの置換 ------------------------------- 以下の関数は、最後の検索でマッチされたテキストのすべて、または一部を置換 します。これはマッチデータにより機能します。 -- Function: replace-match replacement &optional fixedcase literal string subexp この関数はバッファーや文字列にたいして置換処理を行う。 あるバッファーで最後の検索を行った場合には、STRING引数を省略または ‘nil’を指定すること。また最後に検索を行ったバッファーがカレントバッ ファーであることを確認すること。その場合には、この関数はマッチした テキストをREPLACEMENTで置換することにより、そのバッファーを編集する 。これは置換したテキスト終端にポイントを残す。 文字列にたいして最後の検索を行った場合には、同じ文字列がSTRINGに渡 される。その場合には、この関数はマッチしたテキストがREPLACEMENTに置 き換えられた新たなテキストをリターンする。 FIXEDCASEが非‘nil’なら‘replace-match’は大文字小文字を変更せずに置換 テキストを使用して、それ以外は置換されるテキストがcapitalize(先頭が 大文字)されているかどうかに応じて、置換テキストを変換する。元のテキ ストがすべて大文字なら置換テキストを大文字に変換する。元のテキスト の単語すべてがcapitalizeされていたら置換テキストのすべての単語を capitalizeする。すべての単語が1文字かつ大文字なら、それらはすべて大 文字の単語ではなくcapitalizeされた単語として扱われる。 LITERALが非‘nil’ならREPLACEMENTはそのまま挿入されるが、必要に応じて caseの変更だけが行われる。これが‘nil’(デフォルト)なら文字‘\’は特別 に扱われる。REPLACEMENT内に‘\’が出現した場合には、それは以下のシー ケンスのいずれかの一部でなければならない: ‘\&’ これは置換されるテキスト全体を意味する。 ‘\N’ (Nは数字) これは元のregexpのN番目の部分式にマッチするテキストを意味する 。この部分式とは‘\(...\)’の内部にグループかされた式のこと。N番 目のマッチがなければ空文字列が代用される。 ‘\\’ これは置換テキスト内で単一の‘\’を意味する。 ‘\?’ これはそれ自身を意味する(‘replace-regexp’と関連するコマンドの 互換用。*note (emacs)Regexp Replace::を参照)。 これら以外の‘\’に続く文字はエラーをシグナルする。 ‘\&’や‘\N’により行われる代替えは、もしあればcase変換の後に発生する 。したがって代替えする文字列は決してcase変換されない。 SUBEXPが非‘nil’なら、それは全体のマッチではなくマッチされたregexpの 部分式番号SUBEXPだけを置換することを指定する。たとえば‘foo \(ba*r\)’のマッチング後に‘replace-match’を呼び出すと、SUBEXPが1なら ‘\(ba*r\)’にマッチしたテキストだけを置換することを意味する。 -- Function: match-substitute-replacement replacement &optional fixedcase literal string subexp この関数は‘replace-match’によりバッファーに挿入されるであろうテキス トをリターンするがバッファーを変更しない。これは‘\N’や‘\&’のような 構文要素をマッチしたグループで置き換えた実際の結果をユーザーに示し たいとき有用。引数REPLACEMENT、およびオプションのFIXEDCASE、 LITERAL、STRING、SUBEXPは‘replace-match’のときと同じ意味をもつ。 33.6.2 単純なマッチデータへのアクセス ------------------------------------- このセクションでは最後の検索やマッチング操作で、それが成功した場合に何が マッチされたのかを調べるために、マッチデータを使用する方法について説明し ます。 マッチしたテキスト全体または正規表現のカッコで括られた特定の部分式に たいして問い合わせることができます。以下の関数では、COUNTによりどの部分 式かを指定できます。COUNTが0ならマッチ全体、COUNTが正なら望む部分式を指 定します。 正規表現での部分式とは、エスケープされたカッコ‘\(...\)’でグループ化さ れた表現だったことを思い出してください。COUNT番目の部分式は正規表現全体 の先頭から‘\(’を数えることで見つけられます。最初の部分式が1、2つ目が2、 ...となります。正規表現だけが部分式をもつことができ、単純な文字列検索の 後で利用できるのはマッチ全体の情報だけです。 成功したすべての検索はマッチデータをセットします。したがって検索後は 別の検索を行うかもしれない関数を呼び出す前に、検索の直後にマッチデータを 問い合わせるべきです。別の検索を呼び出すかもしれない関数の前後で、かわり にマッチデータの保存とリストアすることもできます(*note Saving Match Data::を参照)。または‘string-match-p’のようなマッチデータを変更しないと 明示されている関数を使用してください。 検索が成功しようと失敗しようとマッチデータは変更されます。現在はこの ように実装されていますが、これは将来変更されるかもしれません。失敗した後 のマッチデータを信用しないでください。 -- Function: match-string count &optional in-string この関数は最後の検索やマッチ処理でマッチしたテキストを文字列として リターンする。これはCOUNTが0ならテキスト全体、COUNTが正ならCOUNT番 目のカッコで括られた部分式に対応する部分だけをリターンする。 そのような最後の処理が文字列にたいする‘string-match’呼び出しなら、 引数IN-STRINGには同じ文字列を渡すこと。バッファーの検索やマッチの後 は、IN-STRINGを省略するか‘nil’を渡すこと。しかし最後に検索やマッチ を行ったバッファーが、‘match-string’呼び出し時にカレントバッファー であることを確認すること。このアドバイスにしたがわなければ誤った結 果となるだろう。 COUNTが範囲外、‘\|’選択肢内部の部分式が使用されない、または0回の繰 り返しなら値は‘nil’。 -- Function: match-string-no-properties count &optional in-string この関数は‘match-string’と似ているが結果がテキストプロパティをもた ない点が異なる。 -- Function: match-beginning count 最後の正規表現検索がマッチを見つけたら、この関数はマッチしたテキス トか部分式の開始位置をリターンする。 COUNTが0なら値はマッチ全体の開始位置。それ以外ならCOUNTは正規表現内 の部分式を指定するので、この関数の値はその部分式にたいするマッチの 開始位置。 使用されない、あるいは0回の繰り返しであるような‘\|’選択肢内部の部分 式にたいしての値は‘nil’。 -- Function: match-end count この関数は‘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と数える。) 33.6.3 マッチデータ全体へのアクセス ----------------------------------- 関数‘match-data’と‘set-match-data’は、マッチデータ全体にたいして一度に読 み取り、または書き込みを行います。 -- Function: match-data &optional integers reuse reseat この関数は最後の検索によりマッチしたテキストのすべての情報を記録す る位置(マーカーか整数)をリターンする。要素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) ⇒ (# # # #) -- Function: set-match-data match-list &optional reseat この関数はMATCH-LISTの要素からマッチデータをセットする。 MATCH-LISTは前の‘match-data’呼び出しの値であるようなリストであるこ と(正確には同じフォーマットなら他のものでも機能するだろう)。 MATCH-LISTが存在しないバッファーを参照する場合でもエラーとはならな い。これは無意味だが害のない方法でマッチデータをセットする。 RESEATが非‘nil’なら、リストMATCH-LIST内のすべてのマーカーは存在しな い場所を指すよう再設定される。 ‘store-match-data’は‘set-match-data’の半ば時代遅れなエイリアス。 33.6.4 マッチデータの保存とリストア ----------------------------------- 以前に行った検索にたいするマッチデータを後で使用するために保護する必要が あるなら、検索を行うかもしれない関数の呼び出し時に呼び出しの前後でマッチ データの保存とリストアを行う必要があるでしょう。以下はマッチデータ保存に 失敗した場合に発生する問題を示す例です: (re-search-forward "The \\(cat \\)") ⇒ 48 (foo) ; ‘foo’が他の検索を行うと (match-end 0) ⇒ 61 ; 結果は期待する48と異なる! ‘save-match-data’でマッチデータの保存とリストアができます: -- Macro: save-match-data body... このマクロはBODYを実行して、その前後のマッチデータの保存とリストア を行う。リターン値はBODY内の最後のフォームの値。 ‘set-match-data’と‘match-data’を一緒に使用して、‘save-match-data’の効 果を模倣することができます。以下はその方法です: (let ((data (match-data))) (unwind-protect ... ; 元のマッチデータを変更してもOK (set-match-data data))) プロセスフィルター関数(*note Filter Functions::を参照)、およびプロセ スセンチネル(*note Sentinels::を参照)の実行時には、Emacsが自動的にマッチ データの保存とリストアを行います。 33.7 検索と置換 =============== バッファーのある部分でregexpにたいするすべてのマッチを見つけてそれらを置 換したい場合には、以下のように‘re-search-forward’と‘replace-match’を使用 して明示的なループを記述するのが最良の方法です: (while (re-search-forward "foo[ \t]+bar" nil t) (replace-match "foobar")) ‘replace-match’の説明は*note Replacing the Text that Matched: Replacing Match.を参照してください。 しかし文字列内のマッチの置換、特に置換を効果的に行いたい場合には、よ り複雑になります。そのためにEmacsはこれを行うための関数を提供します。 -- Function: replace-regexp-in-string regexp rep string &optional fixedcase literal subexp start この関数はSTRINGをコピーしてREGEXPにたいするマッチを検索、それらを REPに置き換える。これは変更されたコピーをリターンする。STARTが非 ‘nil’ならマッチにたいする検索はSTRING内のそのインデックスから開始さ れて、そのインデックスより前で始まるマッチは変更されない。 この関数は置換を行うためにオプション引数FIXEDCASE、LITERAL、 SUBEXPを渡して‘replace-match’を使用する。 REPは文字列のかわりに関数でもよい。この場合には ‘replace-regexp-in-string’はそれぞれのマッチにたいして、そのテキス トを単一の引数としてREPを呼び出す。これはREPがリターンする値を収集 して、それを置換文字列として‘replace-match’に渡す。この時点でのマッ チデータはSTRINGの部分文字列にたいするREGEXPのマッチ結果。 ‘query-replace’の行に関するコマンドを記述したい場合には、 ‘perform-replace’を使用してこれを行うことができます。 -- Function: perform-replace from-string replacements query-flag regexp-flag delimited-flag &optional repeat-count map start end これは‘query-replace’と関連するコマンドの根幹となる関数。これは位置 STARTとENDの間にあるテキスト内に出現するFROM-STRINGの一部またはすべ てを置換する。STARTが‘nil’ (または省略)ならかわりにポイント、ENDに はそのバッファーのアクセス可能範囲の終端が使用される。 QUERY-FLAGが‘nil’ならすべてのマッチを置換する。それ以外なら、それぞ れにたいしてユーザーにたいして何をすべきか問い合わせる。 REGEXP-FLAGが非‘nil’ならFROM-STRINGは正規表現、それ以外はリテラルと してマッチしなければならない。DELIMITED-FLAGが非‘nil’なら単語境界に 囲まれた置換だけが考慮される。 引数REPLACEMENTSはマッチを何で置き換えるかを指定する。文字列ならそ の文字列を使用する。サイクル順に使用される文字列リストでもよい。 REPLACEMENTSがコンスセル‘(FUNCTION . DATA)’なら、置換テキストを取得 するためにそれぞれのマッチ後にFUNCTIONを呼び出すことを意味する。こ の関数はDATAとすでに置換された個数という、2つの引数で呼び出される。 REPEAT-COUNTが非‘nil’なら、それは整数であること。その場合にはサイク ルを次に進める前に、REPLACEMENTSリスト内の各文字列を何度使用するか を指定する。 FROM-STRINGが大文字アルファベットを含む場合には、 ‘perform-replace’は‘case-fold-search’を‘nil’にバインドして大文字小 文字を変換せずにREPLACEMENTSを使用する。 キーマップ‘query-replace-map’は通常は問い合わせにたいして可能なユー ザー応答を定義する。引数MAPが非‘nil’なら、それは ‘query-replace-map’のかわりに使用するキーマップを指定する。 この関数はFROM-STRINGの次のマッチを検索するために2つの関数のうちい ずれか1つを使用する。これらの関数は2つの変数 ‘replace-re-search-function’と‘replace-search-function’により指定さ れる。引数REGEXP-FLAGが非‘nil’なら前者、‘nil’なら後者が呼び出される 。 -- Variable: query-replace-map この変数は‘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’にたいして押下されたキー を追加する(*note Event Input Misc::を参照)。 ‘act-and-exit’ この問いにたいして“yes”を答えて、さらに一連の問いすべてにたいして後 続の問いに“no”が応答されるとみなして問い合わせをあきらめる。 ‘act-and-show’ この問いに“yes”を答えるが、結果を表示してまだ次の問いへ進まない。 ‘automatic’ これ以上のユーザーとの対話を行わず、この問いと後続の問いにたいして “yes”を答える。 ‘backup’ 前に問い合わせた以前の場所に戻る。 ‘edit’ この問いに対処するために、通常とられるアクションのかわりに再帰編集 にエンターする。 ‘edit-replacement’ ミニバッファー内で、この問いにたいする置換を編集する。 ‘delete-and-edit’ 検討中のテキストを削除して、それを置換するために再帰編集にエンター する。 ‘recenter’ ‘scroll-up’ ‘scroll-down’ ‘scroll-other-window’ ‘scroll-other-window-down’ 指定されたウィンドウスクロール操作を行って同じ問いを再度尋ねる。こ の問いには‘y-or-n-p’と関連する関数だけが使用される。 ‘quit’ 即座にquitを行う。この問いには‘y-or-n-p’と関連する関数だけが使用さ れる。 ‘help’ ヘルプを表示して再度尋ねる。 -- Variable: multi-query-replace-map この変数はマルチバッファー置換で有用な追加キーバインディングを提供 することにより‘query-replace-map’を拡張するキーマップを保持する。追 加されるバインディングは以下のとおり: ‘automatic-all’ 残りすべてのバッファーにたいして、それ以上の対話をせずその問い と後続のすべての問いに“yes”を答える。 ‘exit-current’ この問いに“no”を答えてカレントバッファーにたいする一連の問いす べてをあきらめる。そしてシーケンス内の次のバッファーへ問いを継 続する。 -- Variable: replace-search-function この変数は置換する次の文字列を検索するために‘perform-replace’が呼び 出す関数を指定する。デフォルト値は‘search-forward’。それ以外の値の 場合には‘search-forward’の最初の3つの引数を引数とする関数を指定する こと(*note String Search::を参照)。 -- Variable: replace-re-search-function この変数は置換する次のregexpを検索するために‘perform-replace’が呼び 出す関数を指定する。デフォルト値は‘re-search-forward’。それ以外の値 の場合には‘re-search-forward’の最初の3つの引数を引数とする関数を指 定すること(*note Regexp Search::を参照)。 33.8 編集で使用される標準的な正規表現 ===================================== このセクションでは、編集において特定の目的のために使用される正規表現を保 持するいくつかの変数を説明します。 -- User Option: page-delimiter これはページを分割する行開始を記述する正規表現。デフォルト値は ‘"^\014"’ (‘"^^L"’または‘"^\C-l"’)。これはフォームフィード文字(改頁 文字)で始まる行とマッチする。 以下の2つの正規表現が、常に行頭からマッチが始まる正規表現とみなすべき では_ありません_。これらを‘^’にマッチするアンカーとして使用するべきでは ありません。ほとんどの場合では、パラグラフコマンドは行頭にたいしてのみマ ッチのチェックを行うので、これは‘^’が不要であることを意味します。非0の左 マージンが存在する場合には、これらは左マージンの後から始まるマッチに適用 されます。その場合には、‘^’は不適切でしょう。しかし左マージンを決して使 用しないモードでは‘^’は無害でしょう。 -- User Option: paragraph-separate これはパラグラフを分割する行の開始を認識する正規表現(これを変更する 場合は‘paragraph-start’も変更する必要があるかもしれない)。デフォル ト値は‘"[ \t\f]*$"’であり、これは(左マージン以降)すべてがスペース、 タブ、フォームフィードで構成される行とマッチする。 -- User Option: paragraph-start これはパラグラフを開始_または_分割する行の開始を認識する正規表現。 デフォルト値は‘"\f\\|[ \t]*$"’であり、これは(左マージン以降)すべて が空白文字で構成される行やフォームフィードで始まる行とマッチする。 -- User Option: sentence-end 非‘nil’なら、以降に続く空白文字を含めてセンテンスの終わりを記述する 正規表現であること(これとは無関係にパラグラフ境界もセンテンスを終了 させる)。 値が‘nil’ (デフォルト)なら、関数‘sentence-end’がregexpを構築する。 センテンス終端の認識に使用するregexpを得るために常に関数 ‘sentence-end’を使用するべきなのはこれが理由。 -- Function: sentence-end この関数は変数‘sentence-end’が非‘nil’ならその値をリターンする。それ 以外なら変数‘sentence-end-double-space’ (*note Definition of sentence-end-double-space::を参照)、‘sentence-end-without-period’、 ‘sentence-end-without-space’にもとづくデフォルト値をリターンする。 34 構文テーブル *************** “構文テーブル(syntax table)”はバッファー内のそれぞれの文字にたいして構文 的な役割を指定します。単語、シンボル、その他の構文要素の開始と終了の判定 にこれを使用できます。この情報はFont Lockモード(*note Font Lock Mode::を 参照)や、種々の複雑な移動コマンド(*note Motion::を参照)を含む多くの Emacs機能により使用されます。 34.1 構文テーブルの概念 ======================= 構文テーブルは、それぞれの文字の“構文クラス(syntax class)”やその他の構文 的プロパティを照合するために使用できるデータ構造です。構文テーブルはテキ ストを横断したスキャンや移動のためにLispプログラムから使用されます。 構文テーブルは内部的には文字テーブルです(*note Char-Tables::を参照)。 インデックスCの要素はコードCの文字を記述します。値は該当する文字の構文を 指定するコンスセルです。詳細は*note Syntax Table Internals::を参照してく ださい。しかし構文テーブルの内容を変更や確認するために‘aset’や‘aref’を使 用するかわりに、通常は高レベルな関数‘char-syntax’や ‘modify-syntax-entry’を使用するべきです。これらについては*note Syntax Table Functions::で説明します。 -- Function: syntax-table-p object この関数はOBJECTが構文テーブルなら‘t’をリターンする。 バッファーはそれぞれ自身のメジャーモードをもち、それぞれのメジャーモ ードはさまざまな文字の構文クラスにたいして独自の考えをもっています。たと えばLisモードでは文字‘;’はコメントの開始ですが、Cモードでは命令文の終端 になります。これらのバリエーションをサポートするために、構文テーブルはそ れぞれのバッファーにたいしてローカルです。一般的に各メジャーモードは自身 の構文テーブルをもち、そのモードを使用するすべてのバッファーにそれがイン ストールされます。たとえば変数‘emacs-lisp-mode-syntax-table’はEmacsの Lispモードが使用する構文テーブル、‘c-mode-syntax-table’はCモードが使用す る構文テーブルを保持します。あるメジャーモードの構文テーブルを変更すると 、そのモードのバッファー、およびその後でそのモードに置かれるすべてのバッ ファーの構文も同様に変更されます。複数の類似するモードが1つの構文テーブ ルを共有することがときおりあります。構文テーブルをセットアップする方法の 例は*note Example Major Modes::を参照してください。 別の構文テーブルから構文テールを“継承(inherit)”できます。これを“親構 文テーブル(parent syntax table)”と呼びます。構文テーブルは、ある文字にた いして構文クラス“inherit”を与えることにより、構文クラスを未指定にしてお くことができます。そのような文字は親構文テーブルが指定する構文クラスを取 得します(*note Syntax Class Table::を参照)。Emacsは“標準構文テーブル (standard syntax table)”を定義します。これはデフォルトとなる親構文テーブ ルであり、Fundamentalモードが使用する構文テーブルでもあります。 -- Function: standard-syntax-table この関数は標準構文テーブルをリターンする。これはFundamentalモードが 使用する構文テーブルである。 Emacs Lispリーダーは変更不可な独自のビルトイン構文ルールをもつので、 構文テーブルは使用しません(いくつかのLispシステムはリード構文を再定義す る手段を提供するが、わたしたちは単純化のためこの機能をEmacs Lisp外部に留 める決定をした)。 34.2 構文記述子 =============== “構文クラス(syntax class)”の文字は、その文字の構文的な役割を記述します。 各構文テーブルは、それぞれの文字の構文クラスを指定します。ある構文テーブ ルでの文字のクラスと、別のテーブルにおけるその文字のクラスとの間に関連性 がある必要はありません。 構文テーブルはそれぞれニーモニック文字(mnemonic character)により選別 され、クラスを指定する必要がある際にはそのクラスの名前としての役割を果た します。この指定子文字(designator character)は通常はそのクラスに割当てら れることが多々あります。しかしその指定子としての意味は不変であり、その文 字がカレントでもつ構文とは独立しています。つまりカレント構文テーブルにお いて実際に文字‘\’が構文をもつかどうかに関係なく、指定子文字としての‘\’は 常にエスケープ文字(escape character)を意味します。 構文クラスとそれらの 指定子文字のリストは*note Syntax Class Table::を参照してください。 “構文記述子(syntax descriptor)”とは文字の構文クラスと、その他の構文的 なプロパティを記述するLisp文字列です。ある文字の構文を変更したい際には、 関数‘modify-syntax-entry’を呼び出して引数に構文記述子を渡すことにより行 います(*note Syntax Table Functions::を参照)。 構文記述子の1つ目の文字は構文クラスの指定子文字でなければなりません。 2つ目の文字がもしあれば、マッチング文字を指定します(Lispでは‘(’にたいす るマッチング文字は‘)’)。スペースはマッチング文字が存在しないことを指定し ます。その後に続く文字は追加の構文プロパティを指定します(*note Syntax Flags::を参照)。 マッチング文字やフラグが必要なければ、(構文クラスを指定する)1つの文字 だけで十分です。 たとえばCモードでの文字‘*’の構文記述子は‘". 23"’ (区切り記号、マッチ ング文字用スロットは未使用、コメント開始記号の2つ目の文字、コメント終了 記号の1つ目の文字)、‘/’にたいするエントリーは‘. 14’ (区切り記号、マッチ ング文字用スロットは未使用、コメント開始記号の1つ目の文字、コメント終了 記号の2つ目の文字)です。 Emacsは低レベルでの構文クラスを記述するために使用される“raw構文記述子 (raw syntax descriptors)”も定義しています。*note Syntax Table Internals::を参照してください。 34.2.1 構文クラスのテーブル --------------------------- 以下は構文クラス、それらの指定子となる文字と意味、および使用例を示すテー ブルです。 空白文字: ‘ ’か‘-’ シンボルや単語を区別する文字。空白文字は通常は他の構文的な意義をも たず、複数の空白文字は構文的には単一の空白文字と等しい。スペース、 タブ、フォームフィードは、ほとんどすべてのメジャーモードにおいて空 白文字にクラス分けされる。 この構文クラスは‘ ’か‘-’により指定できる。両指定子は等価。 単語構成文字: ‘w’ 人間の言語における単語の一部。これらは通常はプログラム内において変 数やコマンドの名前として使用される。すべての大文字と小文字、および 数字は通常は単語構成文字。 シンボル構成文字: ‘_’ 単語構成文字とともに変数やコマンドの名前で使用される追加の文字。例 としてはLispモードの文字‘$&*+-_<>’が含まれ、これらはたとえ英単語の 一部ではないとしてもシンボルの名前の一部となり得る。標準Cではシンボ ル内において非単語構成文字で有効な文字はアンダースコア(‘_’)のみ。 区切り文字: ‘.’ 人間の言語において句読点として使用される文字、またはプログラミング 言語でシンボルを別のシンボルと区別するために使用される文字。Emacs Lispモードのようないくつかのプログラミング言語のモードでは、単語構 成文字およびシンボル構成文字のいずれでもないいくつかの文字はすべて 他の用途をもつので、このクラスの文字をもたない。Cモードのような他の プログラミング言語のモードでは演算子にたいして区切り文字構文が使用 される。 開カッコ文字: ‘(’ 閉カッコ文字: ‘)’ 文や式を囲うために異なるペアとして使用される文字。そのようなグルー プ化は開カッコで開始され、閉カッコで終了する。開カッコ文字はそれぞ れ特定の閉カッコ文字にマッチして、その逆も成り立つ。Emacsは通常は閉 カッコ挿入時にマッチする開カッコを示す。*note Blinking::を参照のこ と。 人間の言語やCのコードでは、カッコのペアは‘()’、‘[]’、‘{}’。Emacs Lispではリストとベクターにたいする区切り文字(‘()’と‘[]’)はカッコ文 字としてクラス分けされる。 文字列クォート: ‘"’ 文字列定数を区切るために使用される文字。文字列の先頭と終端に同じ文 字列クォート文字が出現する。このようなクォート文字列はネストされな い。 Emacsのパース機能は文字列を単一のトークンとみなす。文字列内ではその 文字の通常の構文的な意味は抑制される。 Lispモードはダブルクォーテーション(‘"’)と垂直バー(‘|’)とう2つの文字 列クォート文字をもつ。Emacs Lispでは‘|’は使用しないがCommon Lispで は使用される。Cも文字列にたいするダブルクォート文字、および文字定数 にたいするシングルアポストロフィ(‘'’)という2つのクォート文字をもつ 。 人間用のテキストには文字列クォート文字がない。そのクォーテーション 内の別の文字の通常の構文的プロパティを、クォーテーションマークがオ フに切り替えることを、わたしたちは望まない。 エスケープ構文文字: ‘\’ 文字列や文字定数内で使用されるようなエスケープシーケンスで始まる文 字。CとLispの両方で文字‘\’はこのクラスに属する(Cでは文字列内でのみ 使用されるが、Cコード中を通じてこのように扱っても問題ないことがわか った)。 ‘words-include-escapes’が非‘nil’なら、このクラスの文字は単語の一部 とみなされる。*note Word Motion::を参照のこと。 文字クォート: ‘/’ その文字の通常の構文的な意義を失うように、後続の文字をクォートする ために使用される文字。これは直後に続く文字だけに影響する点がエスケ ープ文字と異なる。 ‘words-include-escapes’が非‘nil’なら、このクラスの文字は単語の一部 とみなされる。*note Word Motion::を参照のこと。 このクラスはTeXモードのバックスラッシュにたいして使用される。 区切りペアー: ‘$’ 文字列クォート文字と似ているが、この区切りの間にある文字の構文的な プロパティは抑制されない点が異なる。現在のところTeXモードだけが区切 りペアを使用する(‘$’によりmathモードに出入りする)。 式プレフィクス: ‘'’ 式に隣接して出現した場合には式の一部とみなされる構文的演算子にたい して使用される文字。Lispモードではアポストロフィー‘'’ (クォートに使 用)、カンマ‘,’ (マクロに使用)、‘#’ (特定のデータ型にたいするリード 構文として使用)が、これらの文字に含まれる。 コメント開始文字: ‘<’ コメント終了文字: ‘>’ さまざまな言語においてコメントを区切るために使用する文字。人間用の テキストはコメント文字をもたない。Lispではセミコロン(‘;’)がコメント の開始、改行かフォームフィードで終了する。 標準構文の継承: ‘@’ この構文クラスは特定の構文を指定しない。これはその文字の構文を探す ために標準構文テーブルを照合するよう告げる。 汎用コメント区切り: ‘!’ 特殊なコメントを開始または終了させる文字。_任意_の汎用コメント区切 りは_任意_の汎用コメント区切りにマッチするが、コメント開始とコメン ト終了はマッチできない。汎用コメント区切りは汎用コメント区切り同士 としかマッチできない。 この構文クラスは主として‘syntax-table’テキストプロパティ(*note Syntax Properties::を参照)とともに使用することを意図している。任意 の文字範囲の最初と最後の文字にたいして、それらが汎用コメント区切り であることを示す‘syntax-table’プロパティを付与することにより、その 範囲がコメントを形成するとマークすることができる。 汎用文字列区切り: ‘|’ 文字列を開始や終了させる文字。_任意_の汎用文字列区切りは_任意_の汎 用文字列区切りにマッチするが、通常の文字列クォート文字とはマッチで きない。 この構文クラスは主として‘syntax-table’テキストプロパティ(*note Syntax Properties::を参照)とともに使用することを意図している。任意 の文字範囲の最初と最後の文字にたいして、それらが汎用文字列区切りで あることを示す‘syntax-table’プロパティを付与することにより、その範 囲が文字列定数を形成するとマークすることができる。 34.2.2 構文フラグ ----------------- 構文テーブル内の文字全体にたいして構文クラスに加えてフラグを指定できます 。利用できる8つのフラグがあり、それらは文字‘1’、‘2’、‘3’、‘4’、‘b’、 ‘c’、‘n’、‘p’で表されます。 ‘p’を除くすべてのフラグはコメント区切りを記述するために使用されます。 数字のフラグは2文字から構成されるコメント区切りにたいして使用されます。 これらは文字の文字クラスに関連付けられた構文的プロパティに加えて、その文 字も_同様_にコメントシーケンスの一部となれることを示します。Cモードでは 区切り文字であり、_かつ_コメントシーケンス開始(‘/*’)の2文字目であり、_か つ_コメントシーケンス終了(‘*/’)の1文字目である‘*’のような文字のためにフ ラグとクラスは互いに独立しています。フラグ‘b’、‘c’、‘n’は対応するコメン ト区切りを限定するために使用されます。 以下は文字Cにたいして利用できるフラグと意味を示すテーブルです: • ‘1’はCが2文字からなるコメント開始シーケンスの開始であることを意味す る。 • ‘2’はCがそのようなシーケンスの2文字目であることを意味する。 • ‘3’はCが2文字からなるコメント終了シーケンスの開始であることを意味す る。 • ‘4’はCがそのようなシーケンスの2文字目であることを意味する。 • ‘b’はCが代替えのコメントスタイル“b”に属するコメント区切りであること を意味する。このフラグは2文字のコメント開始では2文字目、2文字のコメ ント終了では1文字目にたいしてのみ意味をもつ。 • ‘c’はCが代替えのコメントスタイル“c”に属するコメント区切りであること を意味する。2文字からなるコメント区切りにたいしては、そのいずれかが ‘c’であればスタイル“c”となる。 • コメント区切り文字での‘n’は、この種のコメントがネスト可能であること を指定する。2文字からなるコメント区切りにたいしては、そのいずれかが ‘n’であればネスト可能となる。 Emacsは任意の構文テーブル1つにたいして、同時に複数のコメントスタイ ルをサポートする。コメントスタイルはフラグ‘b’、‘c’、‘n’の組み合わせ なので8個の異なるコメントスタイルが可能である。コメント区切りはそれ ぞれスタイルをもち、同じスタイルのコメント区切りとのみマッチできる 。つまりコメントがスタイル“bn”のコメント開始シーケンスで開始される なら、そのコメントは次のスタイル“bn”のコメント終了シーケンスにマッ チするまで拡張されるだろう。 C++にたいして適切なコメント構文は以下のようになる: ‘/’ ‘124’ ‘*’ ‘23b’ newline ‘>’ これは4つのコメント区切りシーケンスを定義する: ‘/*’ これは2文字目の‘*’が‘b’フラグをもつので、“b”スタイルのコメント 開始シーケンス。 ‘//’ これは2文字目の‘/’が‘b’フラグをもたないので、“a”スタイルのコメ ント開始シーケンス。 ‘*/’ これは1文字目の‘*’が‘b’フラグをもつので、“b”スタイルのコメント 終了シーケンス。 newline これは改行文字が‘b’フラグをもたないので、“a”スタイルのコメント 終了シーケンス。 • ‘p’はLisp構文にたいして追加のプレフィクス文字を識別する。これらが式 の間に出現した際には空白文字として扱われる。これらが式の内部に出現 したときは、それらの通常の構文クラスに応じて処理される。 関数‘backward-prefix-chars’はこれらの文字、同様にメインの構文クラス がプレフィクスであるような文字(‘'’)を超えて後方に移動する。*note Motion and Syntax::を参照のこと。 34.3 構文テーブルの関数 ======================= このセクションでは構文テーブルの作成、アクセス、変更を行う関数を説明しま す。 -- Function: make-syntax-table &optional table この関数は新たに構文テーブルを作成する。TABLEが非‘nil’なら新たな構 文テーブルの親はTABLE、それ以外なら標準構文テーブルが親になる。 新たな構文テーブルでは最初はすべての文字に構文クラス “inherit”(‘@’)が与えられて、それらの構文は親テーブルから継承される (*note Syntax Class Table::を参照)。 -- Function: copy-syntax-table &optional table この関数はTABLEのコピーを構築してそれをリターンする。TABLEが省略ま たは‘nil’なら標準構文テーブルのコピーをリターンする。それ以外の場合 には、TABLEが構文テーブルでなければエラーをシグナルする。 -- Command: modify-syntax-entry char syntax-descriptor &optional table この関数はSYNTAX-DESCRIPTORに応じてCHARの構文エントリーをセットする 。CHARは文字、または‘(MIN . MAX)’という形式のコンスセルでなければな らない。後者の場合には、この関数はMINとMAX (両端を含む)の間のすべて の文字にたいして構文エントリーをセットする。 構文はTABLE (デフォルトはカレントバッファーの構文テーブル)にたいし てのみ変更されて、他のすべての構文テーブルにたいしては変更されない 。 引数SYNTAX-DESCRIPTORは構文記述子、すなわち1文字目が構文クラス指定 子、2文字目以降がオプションでマッチング文字と構文フラグを指定する文 字列。*note Syntax Descriptors::を参照のこと。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 -- Function: char-syntax character この関数は指定子文字(*note Syntax Class Table::を参照)の表現で CHARACTERの構文クラスをリターンする。これはクラス_だけ_をリターンし て、マッチング文字や構文フラグはリターンしない。 以下の例はCモードにたいして適用する( ‘char-syntax’がリターンする文 字を確認しやすいように‘string’を使用する)。 ;; スペース文字は空白文字構文クラスをもつ (string (char-syntax ?\s)) ⇒ " " ;; スラッシュ文字は区切り文字構文をもつ。 ;; コメント開始やコメント終了シーケンスの一部でもある場合、 ;; char-syntax呼び出しはこれを明らかにしないことに注意。 (string (char-syntax ?/)) ⇒ "." ;; 開カッコ文字は開カッコ構文をもつ。 ;; これがマッチング文字‘)’をもつことは ;; char-syntax呼び出しでは自明ではないことに注意。 (string (char-syntax ?\()) ⇒ "(" -- Function: set-syntax-table table この関数はカレントバッファーの構文テーブルをTABLEにする。これは TABLEをリターンする。 -- Function: syntax-table この関数はカレント構文テーブル(カレントバッファーのテーブル)をリタ ーンする。 -- Command: describe-syntax &optional buffer このコマンドはBUFFER (デフォルトはカレントバッファー)の構文テーブル のコンテンツをhelpバッファーに表示する。 -- Macro: with-syntax-table table body... このマクロはTABLEをカレント構文テーブルとして使用してBODYを実行する 。これは古いカレント構文テーブルのリストア後にBODYの最後のフォーム の値をリターンする。 各バッファーは独自にカレント構文テーブルをもつので、マクロはこれを 入念に行うべきだろう。‘with-syntax-table’はマクロの実行開始時には、 そのときカレントのバッファーが何であれカレント構文テーブルを一時的 に変更する。他のバッファーは影響を受けない。 34.4 構文プロパティ =================== ある言語の構文を指定するのに構文テーブルが十分に柔軟でないときは、 バッ ファー内に出現する特定の文字にたいしてテキストプロパティ‘syntax-table’を 適用することにより構文テーブルをオーバーライドできます。テキストプロパテ ィを適用する方法については*note Text Properties::を参照してください。 以下はテキストプロパティ‘syntax-table’の有効な値です: SYNTAX-TABLE プロパティの値が構文テーブルなら、根底となるテキスト文字の構文を決 定するカレントバッファーの構文テーブルのかわりにそのテーブルが使用 される。 ‘(SYNTAX-CODE . MATCHING-CHAR)’ この形式のコンスセルは根底となるテキスト文字の構文クラスを直接指定 するraw構文テーブル(*note Syntax Table Internals::を参照)。 ‘nil’ このプロパティが‘nil’なら、その文字の構文はカレント構文テーブルによ り通常の方法で決定される。 -- Variable: parse-sexp-lookup-properties これが非‘nil’なら‘forward-sexp’のような構文をスキャンする関数は、 syntax-tableテキストプロパティに注意を払い、それ以外ならカレント構 文テーブルだけを使用する。 -- Variable: syntax-propertize-function この変数が非‘nil’なら特定のテキスト範囲にたいして‘syntax-table’プロ パティを適用する関数を格納すること。これはモードに適した方法で ‘syntax-table’プロパティを適用する関数をインストールするようにメジ ャーモードで使用されることを意図している。 この関数は‘syntax-ppss’ (*note Position Parse::を参照)、および構文 フォント表示化(*note Syntactic Font Lock::を参照)の間にFont Lockモ ードにより呼び出される。これは作用すべきテキスト部分の開始STARTと終 了ENDという2つの引数で呼び出される。これはENDの前の任意の位置で ‘syntax-ppss’を呼び出すことが許されている。しかし ‘syntax-ppss-flush-cache’を呼び出すべきではなく、そのためある位置で ‘syntax-ppss’を呼び出して後からバッファー内の前の位置を変更すること は許されていない。 -- Variable: syntax-propertize-extend-region-functions このアブノーマルフックは‘syntax-propertize-function’呼び出しに先立 ち構文解析コードにより実行される。これは ‘syntax-propertize-function’に渡すために安全なバッファーの開始と終 了の位置を見つける助けをする役割をもつ。たとえばメジャーモードは複 数行の構文構成を識別して、境界が複数行の中間にならないようにこのフ ックに関数を追加できる。 このフック内の各関数は引数STARTとENDを受け取ること。これは2つのバッ ファー位置を調整するコンスセル‘(NEW-START . NEW-END)’、調整が必要な ければ‘nil’をリターンするべきである。フック関数はそれらすべてが ‘nil’をリターンするまで順番に繰り返し実行される。 34.5 モーションと構文 ===================== このセクションでは、特定の構文クラスをもつ文字間を横断して移動する関数を 説明します。 -- Function: skip-syntax-forward syntaxes &optional limit この関数はSYNTAXESで指定された構文クラス(構文クラスの文字列)をもつ 文字を横断してポイントを前方に移動する。バッファー終端か、(与えられ た場合は)位置LIMITに到達、もしくはスキップしない文字に達した際に停 止する。 SYNTAXESが‘^’で始まる場合には、この関数は構文がSYNTAXESでは_ない_文 字をスキップする。 リターン値は移動した距離を表す非負の整数。 -- Function: skip-syntax-backward syntaxes &optional limit この関数はSYNTAXESで指定された構文クラスをもつ文字を横断してポイン トを後方に移動する。バッファー先頭か、(与えられた場合は)位置LIMITに 到達、もしくはスキップしない文字に達した際に停止する。 SYNTAXESが‘^’で始まる場合には、この関数は構文がSYNTAXESでは_ない_文 字をスキップする。 リターン値は移動した距離を表す0以下の整数。 -- Function: backward-prefix-chars この関数は式プレフィクス構文の任意個数の文字を横断して後方にポイン トを移動する。これには式プレフィクス構文クラスとフラグ‘p’の文字の両 方が含まれる。 34.6 式のパース =============== このセクションではバランスのとれた式の解析やスキャンを行う関数を説明しま す。たとえこれらの関数がLisp以外の言語にたいして作用可能であったとしても 、Lisp用語にしたがってそのような式のことを“sexps”という用語で参照するこ とにします。基本的にsexpはバランスのとれたカッコによるグループ化、または 文字列、シンボル(構文が単語構成要素かシンボル構成要素である文字シーケン ス)のいずれかです。しかし式プレフィクス構文(*note Syntax Class Table::を 参照)の文字は、それらがsexpに隣接する場合にはsexpの一部として扱われます 。 構文テーブルは文字の解釈を制御するので、これらの関数はLispモードでの Lisp式、CモードでのCの式にたいして使用できます。バランスのとれた式にたい して有用な高レベル関数については*note List Motion::を参照してください。 ある文字の構文はパーサー自身の状態の記述ではなくパーサー状態の変更方 法を制御します。たとえば文字列区切り文字はin-stringとin-codeの間でパーサ ー状態をトグルしますが、文字の構文が直接文字列内部にあるかどうかを告げる ことはありません。たとえば(15は汎用文字列区切りの構文コードであることに 注意)、 (put-text-property 1 9 'syntax-table '(15 . nil)) これはEmacsにたいしてカレントバッファーの最初の8文字が文字列であることを 告げますが、それらはすべて文字列区切りです。結果としてEmacsはそれらを連 続する4つの空文字列定数として扱います。 34.6.1 パースにもとづくモーションコマンド ----------------------------------------- このセクションでは式のパースにもとづいて処理を行うシンプルなポイント移動 関数を説明します。 -- Function: scan-lists from count depth この関数は位置FROMからバランスのとれたカッコのグループを前方に COUNT個スキャンする。これはスキャンが停止した位置をリターンする。 COUNTが負ならスキャンは後方に移動する。 DEPTHが非0なら開始位置のカッコのネスト深さをDEPTHとして扱う。スキャ ナーはネスト深さが0になるまで繰り返してCOUNT回、前方か後方に移動す る。そのため正のDEPTHは開始位置からカッコをDEPTHレベル抜け出して移 動する効果があり、負のDEPTHはカッコがDEPTHレベル深くなるよう移動す る効果をもつ。 ‘parse-sexp-ignore-comments’が非‘nil’ならスキャンはコメントを無視す る。 COUNT個のカッコのグループをスキャンする前にスキャンがバッファーのア クセス可能範囲の先頭か終端に達した場合には、そのポイントのネスト深 さが0なら値‘nil’をリターンする。ネスト深さが非0なら‘scan-error’エラ ーをシグナルする。 -- Function: scan-sexps from count この関数は位置FROMからCOUNT個のsexpを前方にスキャンする。これはスキ ャンが停止した位置をリターンする。COUNTが負ならスキャンは後方へ移動 する。 ‘parse-sexp-ignore-comments’が非‘nil’ならスキャンはコメントを無視す る。 カッコのグループの中間でバッファー(のアクセス可能範囲)の先頭か終端 に達したらエラーをシグナルする。COUNT個を消費する前にカッコのグルー プの間でバッファーの先頭か終端に達したら‘nil’をリターンする。 -- Function: forward-comment count この関数はCOUNT個の完全なコメント(すなわち、もしあれば開始区切りと 終了区切りを含む)、および途中で遭遇する任意の空白文字を横断してポイ ントを前方に移動する。COUNTが負なら後方に移動する。コメントまたは空 白文字以外のものに遭遇したら停止して停止位置にポイントを残す。これ には、(たとえば)前方に移動してコメント開始を調べる際にコメント終了 を探すことも含まれる。この関数は指定された個数の完全なコメントを横 断して移動した後にも即座に停止する。空白以外のものがコメント間に存 在せずに期待どおりCOUNT個のコメントが見つかったら‘t’、それ以外は ‘nil’をリターンする。 この関数はコメントを横断する際に、それが文字列内に埋め込まれている かどうか区別できない。それらがコメントのように見えればコメントとし て扱われる。 ポイントの後のすべてのコメントと空白文字を飛び越して移動するには ‘(forward-comment (buffer-size))’を使用する。バッファー内のコメント 数は‘(buffer-size)’を超えることはできないので、これは引数としての使 用に適している。 34.6.2 ある位置のパース状態を調べる ----------------------------------- インデントのような構文分析にとっては、与えられたバッファー位置に応じた構 文状態の計算が有用なことが多々あります。それを手軽に行うのが以下の関数で す。 -- Function: syntax-ppss &optional pos この関数はパーサーがバッファー先頭から開始して位置POSで停止するだろ うというパーサー状態をリターンする。 パーサー状態の説明は*note Parser State::を参照のこと 。 リターン値はバッファー先頭からPOSまでパースするために低レベル関数 ‘parse-partial-sexp’(*note Low-Level Parsing::を参照)を呼び出した場 合と同じようになる。しかし‘syntax-ppss’は計算速度向上のためにキャッ シュを使用する。この最適化のために、リターンされるパーサー状態のう ち2つ目の値(前の完全な部分式)と6つ目の値(最小のカッコ深さ)は意味を もたない。 この関数は‘syntax-ppss-flush-cache’ (以下参照)にたいして、 ‘before-change-functions’ (*note Change Hooks::を参照)にバッファー ローカルなエントリーを追加するという副作用をもつ。このエントリーは バッファー変更にたいしてキャッシュの一貫性を保つ。とはいえ ‘before-change-functions’が一時的にletでバインドされている間に ‘syntax-ppss’が呼び出された場合、または ‘inhibit-modification-hooks’使用時のようにバッファーがフックを実行 せずに変更される場合にはキャッシュは更新されないかもしれない。その ような場合には明示的に‘syntax-ppss-flush-cache’を呼び出す必要がある 。 -- Function: syntax-ppss-flush-cache beg &rest ignored-args この関数は‘syntax-ppss’が使用するキャッシュを位置BEGからフラッシュ する。残りの引数IGNORED-ARGSは無視される。‘before-change-functions’ (*note Change Hooks::を参照)のような関数で直接使用できるように、こ の関数はそれらの引数を受け入れる。 34.6.3 パーサー状態 ------------------- “パーサー状態(parser state)”とはバッファー内の指定された開始位置と終了位 置の間のテキストをパースした後の構文パーサーの状態を記述する10要素のリス トです。‘syntax-ppss’のようなパース関数 (*note Position Parse::を参照) は 値としてパーサー状態をリターンします。いくつかのパース関数はパースを再開 するために引数としてパーサー状態を受け取ります。 以下はパーサー状態の要素の意味です: 0. 0から数えたカッコの深さ。*警告:* パーサーの開始位置と終了位置の間に 開カッコより多くの閉カッコがあれば負になることもある。 1. 停止位置を含む最内のカッコグループの開始文字位置。なければ‘nil’。 2. 最後の終端された完全な部分式の開始文字位置。なければ‘nil’。 3. 文字列内部なら非‘nil’。より正確には文字列を終端させるであろう文字、 または汎用文字列区切りが終端すべきような場合には‘t’。 4. ネスト不可なコメント(または任意のコメントスタイル。*note Syntax Flags::を参照)の内部なら‘t’、ネスト可なコメントの内部ならコメントの ネストレベル。 5. 終了位置がクォート文字直後なら‘t’。 6. 当該スキャン中に遭遇した最小のカッコ深さ。 7. アクティブなコメントの種類。コメント以外、またはスタイル‘a’のコメン ト内なら‘nil’、スタイル‘b’のコメントなら1、スタイル‘c’のコメントな ら2、汎用コメント区切り文字で終端されるべきコメントなら ‘syntax-table’。 8. 文字列やコメントの開始位置。コメント内部ならコメントが始まる位置。 文字列内部なら文字列が始まる位置。文字列やコメントの外部ならこの要 素は‘nil’。 9. パースを継続するための内部データ。このデータのもつ意味は変更される かもしれない。これは他の呼び出しのSTATE引数としてこのリストを渡す場 合に使用される。 パース継続のために渡す場合には要素1、2、6は無視されて要素8と9は特に重 要ではない場面でのみ使用されます。これらの要素は主にパーサーコードにより 内部的に使用されます。 以下の関数を使用することにより追加でさらにパーサー状態から有用な情報 を利用できます: -- Function: syntax-ppss-toplevel-pos state この関数はパーサー状態STATEから文法構造上トップレベルでのパースでの スキャンした最後の位置をリターンする。“トップレベル”とはすべてのカ ッコ、コメント、文字列の外部であることを意味する。 STATEがトップレベルの位置に到達したパースを表す場合には値は‘nil’。 34.6.4 低レベルのパース ----------------------- 式パーサーを使用するもっとも基本的な方法は特定の状態で与えられた位置から パースを開始して、指定した位置でパースを終了するよう指示する方法です。 -- Function: parse-partial-sexp start limit &optional target-depth stop-before state stop-comment この関数はカレントバッファー内のsexpを、STARTから開始してLIMITを超 えてスキャンしないようパースを行う。これは位置LIMIT、または以下に記 述する特定の条件に適合したら停止してパースが停止した位置にポイント をセットする。これはポイントが停止した位置でのパースの状態を記述す るパーサー状態 (*note Parser State::を参照) をリターンする。 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’呼び出しでリター ンされた値で、これをうまく行うことができるだろう。 34.6.5 パースを制御するためのパラメーター ----------------------------------------- -- Variable: multibyte-syntax-as-symbol この変数が非‘nil’なら構文テーブルがそれらについて何と言っているかに 関わらず、‘scan-sexps’はすべての非ASCII文字をシンボル構成要素として 扱う(とはいえ依然としてテキストプロパティは構文をオーバーラードでき るが)。 -- User Option: parse-sexp-ignore-comments この値が非‘nil’ならこのセクション内の関数、および‘forward-sexp’、 ‘scan-lists’、‘scan-sexps’はコメントを空白文字として扱う。 ‘parse-partial-sexp’の振る舞いも‘parse-sexp-lookup-properties’の影響 を受けます(*note Syntax Properties::を参照)。 -- Variable: comment-end-can-be-escaped このバッファーローカル変数が非‘nil’なら、通常ならコメントを終端する ような単一の文字は、エスケープ時にはコメントを終端しない。これはCと C++のモードにおいて‘\’でエスケープされた改行により、‘//’で開始され る行コメントを次行に継続させるために使用される。 1つ、または複数のコメントを横断して前方や後方に移動するには ‘forward-comment’を使用できます。 34.7 構文テーブルの内部 ======================= 構文テーブルは文字テーブル(*note Char-Tables::を参照)として実装されてい ますが、ほとんどのLispプログラムが直接それらの要素に作用することはありま せん。構文テーブルは構文データとして構文記述子を格納しません(*note Syntax Descriptors::を参照)。それらは内部的なフォーマットを使用しており 、それについてはこのセクションで説明します。この内部的フォーマットは構文 プロパティとして割り当てることもできます(*note Syntax Properties::を参照 )。 構文テーブル内の各要素は“raw構文記述子(raw syntax descriptor)”という ‘(SYNTAX-CODE . MATCHING-CHAR)’という形式のコンスセルです。SYNTAX-CODEは 下記のテーブルに応じて構文クラスと構文フラグをエンコードする整数です。 MATCHING-CHARが非‘nil’なら、それはマッチング文字(構文記述子内の2つ目の文 字と同様)を指定します。 以下はさまざまな構文クラスに対応する構文コードです。 Code Class Code Class 0 空白文字 8 区切り文字ペアー 1 句読点 9 エスケープ 2 単語 10 文字クォート 3 シンボル 11 コメント開始 4 開カッコ 12 コメント終了 5 閉カッコ 13 継承 6 式プレフィクス 14 汎用コメント 7 文字列クォート 15 汎用文字列 たとえば標準構文テーブルでは‘(’にたいするエントリーは‘(4 . 41)’、41は ‘)’の文字コードです。 構文フラグは最下位ビットから16ビット目より始まる高位ビットにエンコー ドされます。以下のテーブルは対応する各構文フラグにたいして2のべき乗を与 えます。 Prefix Flag Prefix Flag ‘1’ ‘(lsh 1 16)’ ‘p’ ‘(lsh 1 20)’ ‘2’ ‘(lsh 1 17)’ ‘b’ ‘(lsh 1 21)’ ‘3’ ‘(lsh 1 18)’ ‘n’ ‘(lsh 1 22)’ ‘4’ ‘(lsh 1 19)’ -- Function: string-to-syntax desc 与えられた構文記述子DESC(文字列)にたいして、この関数は対応するraw構 文記述子をリターンする。 -- Function: syntax-after pos この関数はバッファー内の位置POSの後の文字にたいして、構文テーブルと 同様に構文プロパティも考慮したraw構文記述子をリターンする。POSがバ ッファーのアクセス可能範囲(*note accessible portion: Narrowing.を参 照)の外部ならリターン値は‘nil’。 -- Function: syntax-class syntax この関数はraw構文記述子SYNTAXにたいする構文コードをリターンする。よ り正確にはこれはraw構文記述子のSYNTAX-CODE要素から構文フラグを記録 する高位16ビットをマスクして、その結果の整数をリターンする。 SYNTAXが‘nil’ならリターン値は‘nil’。これは以下の式 (syntax-class (syntax-after pos)) は‘pos’がバッファーのアクセス可能範囲外部なら、エラーをthrowしたり 不正なコードをリターンすることなく‘nil’に評価されるため。 34.8 カテゴリー =============== “カテゴリー(categories)”は構文的に文字をクラス分けする別の手段を提供しま す。必要に応じて複数のカテゴリーを定義して、それぞれの文字に独立して1つ 以上のカテゴリーを割り当てることができます。構文クラスと異なりカテゴリー は互いに排他ではありません。1つの文字が複数のカテゴリーに属すのは普通の ことです。 バッファーはそれぞれ“カテゴリーテーブル(category table)”をもっていま す。これはどのカテゴリーが定義されていて、各カテゴリーにどの文字が属すか を記録しています。カテゴリーテールは自身のカテゴリーを定義しますが、標準 カテゴリーはすべてのモードで利用可能なので、これらは通常は標準カテゴリー テーブルをコピーすることにより初期化されます。 カテゴリーはそれぞれ‘ ’から‘~’の範囲のASCIIプリント文字による名前をも ちます。‘define-category’で定義する際にはカテゴリーの名前を指定します。 カテゴリーテーブルは実際には文字テーブルです(*note Char-Tables::を参 照)。カテゴリーテーブルのインデックスCの要素は、文字Cが属するカテゴリー を示す“カテゴリーセット(category set)”というブールベクターです。このカテ ゴリーセット内で、もしインデックスCATの要素が‘t’ならCATはそのセットのメ ンバーであり、その文字CはカテゴリーCATに属することを意味します。 以下の3つの関数のオプション引数TABLEのデフォルトは、カレントバッファ ーのカテゴリーテーブルです。 -- Function: define-category char docstring &optional table この関数はカテゴリーテーブルTABLEにたいして名前がCHAR、ドキュメント がDOCSTRINGであるような新たなカテゴリーを定義する。 以下ではR2L(right-to-left: 右から左)への強い方向性 (directionality)をもつ文字(*note Bidirectional Display::を参照)にた いするカテゴリーを新たに定義して、それを特別なカテゴリーテーブル内 で使用する例を示す。文字の方向性に関する情報を取得するために、コー ド例ではUnicodeプロパティ‘bidi-class’ (*note bidi-class: Character Properties.を参照)を使用する。 (defvar special-category-table-for-bidi ;; Make an empty category-table. (let ((category-table (make-category-table)) ;; Create a char-table which gives the 'bidi-class' Unicode ;; property for each character. (uniprop-table (unicode-property-table-internal 'bidi-class))) (define-category ?R "Characters of bidi-class R, AL, or RLO" category-table) ;; Modify the category entry of each character whose 'bidi-class' ;; Unicode property is R, AL, or RLO -- these have a ;; right-to-left directionality. (map-char-table #'(lambda (key val) (if (memq val '(R AL RLO)) (modify-category-entry key ?R category-table))) uniprop-table) category-table)) -- Function: category-docstring category &optional table この関数はカテゴリーテーブルTABLE内のカテゴリーCATEGORYのドキュメン ト文字列をリターンする。 (category-docstring ?a) ⇒ "ASCII" (category-docstring ?l) ⇒ "Latin" -- Function: get-unused-category &optional table この関数はTABLE内で現在のところ未定義なカテゴリーの名前(文字)をリタ ーンする。TABLE内で利用可能なカテゴリーがすべて使用済みなら‘nil’を リターンする。 -- Function: category-table この関数はカレントバッファーのカテゴリーテーブルをリターンする。 -- Function: category-table-p object この関数はOBJECTがカテゴリーテーブルなら‘t’、それ以外は‘nil’をリタ ーンする。 -- Function: standard-category-table この関数は標準カテゴリーテーブルをリターンする。 -- Function: copy-category-table &optional table この関数はTABLEのコピーを構築してリターンする。TABLEが与えられない (または‘nil’)なら、標準カテゴリーテーブルのコピーをリターンする。そ れ以外の場合には、もしTABLEがカテゴリーテーブルでなければエラーをシ グナルする。 -- Function: set-category-table table この関数はTABLEをカレントバッファーのカテゴリーテーブルにする。リタ ーン値はTABLE。 -- Function: make-category-table これは空のカテゴリーテーブルを作成してリターンする。空のカテゴリー テーブルでは、どのカテゴリーも割り当てられておらず何らかのカテゴリ ーに属する文字もない。 -- Function: make-category-set categories この関数は初期内容が文字列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" -- Function: char-category-set char この関数はカレントバッファーのカテゴリーテーブル内で、文字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" -- Function: category-set-mnemonics category-set この関数はカテゴリーセットCATEGORY-SETを、そのセットのメンバーのカ テゴリーを指定する文字を含む文字列に変換する。 (category-set-mnemonics (char-category-set ?a)) ⇒ "al" -- Function: modify-category-entry char category &optional table reset この関数はカテゴリーテーブルTABLE (デフォルトはカレントバッファーの カテゴリーテーブル)内のCHARのカテゴリーセットを変更する。CHARには文 字、または‘(MIN . MAX)’という形式のコンスセルを指定できる。後者の場 合には、この関数はMINとMAXの間(両端を含む)の範囲にあるすべての文字 のカテゴリーセットを変更する。 これは通常はカテゴリーセットにCATEGORYを追加することにより変更を行 う。しかしRESETが非‘nil’なら、かわりにCATEGORYを削除する。 -- Command: describe-categories &optional buffer-or-name この関数はカレントカテゴリーテーブル内のカテゴリー仕様を説明する。 これはその説明をバッファーに挿入してから、そのバッファーを表示する 。BUFFER-OR-NAMEが非‘nil’なら、かわりにそのバッファーのカテゴリーテ ーブルを説明する。 35 abbrevとabbrev展開 ********************* 略語(abbreviationまたは“abbrev”は、より長い文字列へと展開される文字列で す。ユーザーはabbrev文字列を挿入して、それを探して自動的にabbrevの展開形 に置換できます。これによりタイプ量を節約できます。 カレントで効果をもつabbrevsのセットは“abbrevテーブル(abbrev table)”内 に記録されます。バッファーはそれぞれローカルにabbrevテーブルをもちますが 、通常は同一のメジャーモードにあるすべてのバッファーが1つのabbrevテーブ ルを共有します。グローバルabbrevテーブルも存在します。通常は両者が使用さ れます。 abbrevテーブルはobarrayとして表されます。obarraysについての情報は *note Creating Symbols::を参照してください。abbrevはそれぞれobarray内の シンボルとして表現されます。そのシンボルの名前がabbrevであり、値が展開形 になります。シンボルの関数定義は展開を行うフック関数です(*note Defining Abbrevs::を参照)。またシンボルのプロパティセルには使用回数やそのabbrevが 展開された回数を含む、さまざまな追加プロパティが含まれます(*note Abbrev Properties::を参照)。 “システムabbrev(system abbrevs)”と呼ばれる特定のabbrevは、ユーザーで はなくメジャーモードにより定義されます。システムabbrevは非‘nil’の ‘:system’プロパティにより識別されます(*note Abbrev Properties::を参照)。 abbrevがabbrevファイルに保存される際には、システムabbrevは省略されます。 *note Abbrev Files::を参照してください。 abbrevに使用されるシンボルは通常のobarrayにinternされないので、Lisp式 の読み取り結果として現れることは決してありません。実際のところ通常は abbrevを扱うコードを除いて、それらが使用されることはありません。したがっ てそれらを非標準的な方法で使用しても安全なのです。 マイナーモードであるAbbrevモードが有効な場合には、バッファーローカル 変数‘abbrev-mode’は非‘nil’となり、そのバッファー内でabbrevは自動的に展開 されます。abbrev用のユーザーレベルのコマンドについては*note Abbrev Mode: (emacs)Abbrevs.を参照してください。 35.1 abbrevテーブル =================== このセクションではabbrevテーブルの作成と操作を行う方法について説明します 。 -- Function: make-abbrev-table &optional props この関数は空のabbrevテーブル(シンボルを含まないobarray)を作成してリ ターンする。これは0で充填されたベクター。PROPSは新たなテーブルに適 用されるプロパティリスト(*note Abbrev Table Properties::を参照)。 -- Function: abbrev-table-p object この関数はOBJECTがabbrevテーブルなら非‘nil’をリターンする。 -- Function: clear-abbrev-table abbrev-table この関数はABBREV-TABLE内のabbrevをすべて未定義として空のまま残す。 -- Function: copy-abbrev-table abbrev-table この関数はABBREV-TABLEのコピー(同じabbrev定義を含む新たなabbrevテー ブル)をリターンする。これは名前、値、関数だけをコピーしてプロパティ リストは何も_コピーしない_。 -- Function: define-abbrev-table tabname definitions &optional docstring &rest props この関数はabbrevテーブル名(値がabbrevテーブルであるような変数)とし てTABNAME (シンボル)を定義する。これはそのテーブル内にDEFINITIONSに 応じて、abbrevを定義する。DEFINITIONSは‘(ABBREVNAME EXPANSION [HOOK] [PROPS...])’という形式の要素をもつリスト。これらの要素は引数 として‘define-abbrev’に渡される。 オプション文字列DOCSTRINGは変数TABNAMEのドキュメント文字列。プロパ ティリストPROPSはabbrevテーブルに適用される(*note Abbrev Table Properties::を参照)。 同一のTABNAMEにたいしてこの関数が複数回呼び出されれると、元のコンテ ンツ全体を上書きせずに後続の呼び出しはDEFINITIONS内の定義を TABNAMEに追加する(後続の呼び出しではDEFINITIONS内で明示的に再定義ま たは未定義にした場合のみabbrevを上書きできる)。 -- Variable: abbrev-table-name-list これは値がabbrevテーブルであるようなシンボルのリスト。 ‘define-abbrev-table’はこのリストに新たなabbrevテーブル名を追加する 。 -- Function: insert-abbrev-table-description name &optional human この関数はポイントの前に名前がNAMEのabbrevテーブルの説明を挿入する 。引数NAMEは値がabbrevテーブルであるようなシンボル。 HUMANが非‘nil’なら人間向けの説明になる。システムabbrevはそのように リストされて識別される。それ以外なら説明はLisp式(カレントで定義され ているようにNAMEを定義するがシステムabbrevとしては定義しないような ‘define-abbrev-table’呼び出し)となる(NAMEを使用するモードまたはパッ ケージはそれらを個別にNAMEに追加すると想定されている)。 35.2 abbrevの定義 ================= ‘define-abbrev’はabbrevテーブル内にabbrevを定義するための基本的な低レベ ル関数です。 メジャーモードがシステムabbrevを定義する際には、‘:system’プロパティに ‘t’を指定して‘define-abbrev’を呼び出すべきです。すべての保存された非シス テムabbrevは起動時(何らかのメジャーモードがロードされる前)にリストアされ ることに注意してください。したがってメジャーモードは最初にそのモードがロ ードされた際には、それらのモードのabbrevテーブルが空であると仮定するべき ではありません。 -- Function: define-abbrev abbrev-table name expansion &optional hook &rest props この関数はABBREV-TABLE内にNAMEという名前でEXPANSIONに展開されて、 HOOKを呼び出すabbrevをプロパティPROPS (*note Abbrev Properties::を 参照)とともに定義する。リターン値は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にたいしてこれは行われない。 -- User Option: only-global-abbrevs この変数が非‘nil’なら、それはユーザーがグローバルabbrevのみの使用を 計画していることを意味する。これはモード固有のabbrevを定義するコマ ンドにたいして、かわりにグローバルabbrevを定義するよう指示する。こ の変数はこのセクション内の関数の振る舞いを変更しない。それは呼び出 し側により検証される。 35.3 ファイルへのabbrevの保存 ============================= abbrev定義が保存されたファイルは実際にはLispコードのファイルです。 abbrevは同じコンテンツの同じabbrevテーブルを定義するLispプログラムの形式 で保存されます。したがってそのファイルは‘load’によってロードすることがで きます(*note How Programs Do Loading::を参照)。しかしより簡便なインター フェースとして関数‘quietly-read-abbrev-file’が提供されています。Emacsは 起動時に自動的にこの関数を呼び出します。 ‘save-some-buffers’のようなユーザーレベルの機能は、ここで説明する変数 の制御下で自動的にabbrevをファイルに保存できます。 -- User Option: abbrev-file-name これはabbrevの読み込みと保存にたいするデフォルトのファイル名。デフ ォルトではEmacsは‘~/.emacs.d/abbrev_defs’を探して、見つからなければ ‘~/.abbrev_defs’を探して、いずれにもファイルが存在しなければ ‘~/.emacs.d/abbrev_defs’を作成する。 -- Function: quietly-read-abbrev-file &optional filename この関数は以前に‘write-abbrev-file’で書き込まれたFILENAMEという名前 のファイルからabbrevの定義を読み込む。FILENAMEが省略または‘nil’なら ‘abbrev-file-name’内で指定されているファイルが使用される。 関数の名前が暗示するようにこの関数は何のメッセージも表示しない。 -- User Option: save-abbrevs ‘save-abbrevs’にたいする非‘nil’値はファイル保存時に、(もし何か変更 されていれば)Emacsがabbrevの保存を提案するべきであることを意味する 。値が‘silently’ならEmacsはユーザーに尋ねることなくabbrevを保存する 。‘abbrev-file-name’はabbrevを保存するファイルを指定する。デフォル ト値は‘t’。 -- Variable: abbrevs-changed この変数はabbrev(システムabbrevを除く)の定義や変更によりセットされ る。さまざまなEmacsコマンドにとって、これはユーザーにabbrevの保存を 提案するためのフラグとしての役目をもつ。 -- Command: write-abbrev-file &optional filename ‘abbrev-table-name-list’内にリストされたすべてのabbrevテーブルにた いして、ロード時に同じabbrevを定義するであろうLispプログラム形式で 、すべてのabbrev定義(システムabbrevを除く)をファイルFILENAME内に保 存する。FILENAMEが‘nil’なら‘abbrev-file-name’が使用される。この関数 は‘nil’をリターンする。 35.4 略語の照会と展開 ===================== abbrevは通常は‘self-insert-command’を含む特定のinteractiveなコマンドによ り展開されます。このセクションではそのようなコマンドの記述に使用されるサ ブルーチン、並びに通信のために使用される変数について説明します。 -- Function: abbrev-symbol abbrev &optional table この関数はABBREVという名前のabbrevを表すシンボルをリターンする。そ のabbrevが定義されていなければ‘nil’をリターンする。オプションの2つ 目の引数TABLEはそれを照合するためのabbrevテーブル。TABLEが‘nil’なら この関数はまずカレントバッファーのローカルabbrevテーブル、次にグロ ーバルabbrevテーブルを試みる。 -- Function: abbrev-expansion abbrev &optional table この関数はABBREVが展開されるであろう文字列(カレントバッファーにたい して使用されるabbrevテーブルで定義される文字列)をリターンする。これ はABBREVが有効なabbrevでなければ‘nil’をリターンする。オプション引数 TABLEは‘abbrev-symbol’の場合と同じように使用するabbrevテーブルを指 定する。 -- Command: expand-abbrev このコマンドは、(もしあれば)ポイントの前のabbrevを展開する。ポイン トがabbrevの後になければこのコマンドは何もしない。展開を行うために これは変数‘abbrev-expand-function’の値となっている関数を引数なしで 呼び出して、何であれその関数がリターンしたものをリターンする。 デフォルトの展開関数は展開を行ったらabbrevのシンボル、それ以外は ‘nil’をリターンする。そのabbrevシンボルが‘no-self-insert’プロパティ が非‘nil’のシンボルであるようなフック関数をもち、そのフック関数が値 として‘nil’をリターンした場合には、たとえ展開が行われたとしてもデフ ォルト展開関数は‘nil’をリターンする。 -- Function: abbrev-insert abbrev &optional name start end この関数は‘start’と‘end’の間のテキストを置換することにより ‘abbrev’のabbrev展開形を挿入する。‘start’が省略された場合のデフォル トはポイント。‘name’が非‘nil’なら、それはこのabbrevが見つかった名前 (文字列)であること。これは展開形のcapitalizationを調整するかどうか を判断するために使用される。この関数はabbrevの挿入に成功したら ‘abbrev’、それ以外は‘nil’をリターンする。 -- Command: abbrev-prefix-mark &optional arg このコマンドはポイントのカレント位置をabbrevの開始としてマークする 。‘expand-abbrev’の次回呼び出しでは、通常のように以前の単語ではなく 、ここからポイント(その時点での位置)にあるテキストが展開するべき abbrevとして使用される。 このコマンドは、まずARGが‘nil’ならポイントの前の任意のabbrevを展開 する(インタラクティブな呼び出しではARGはプレフィクス引数)。それから 展開する次のabbrevの開始を示すためにポイントの前にハイフンを挿入す る。実際の展開ではハイフンは削除される。 -- User Option: abbrev-all-caps これが非‘nil’にセットされているときは、すべて大文字で入力された abbrevはすべて大文字を使用して展開される。それ以外ならすべて大文字 で入力されたabbrevは、展開形の単語ごとにcapitalizeして展開される。 -- Variable: abbrev-start-location この変数の値は次にabbrevを展開する開始位置として‘expand-abbrev’に使 用されるバッファー位置。値は‘nil’も可能であり、それはかわりにポイン トの前の単語を使用することを意味する。‘abbrev-start-location’は ‘expand-abbrev’の呼び出しごとに毎回‘nil’にセットされる。この変数は ‘abbrev-prefix-mark’からもセットされる。 -- Variable: abbrev-start-location-buffer この変数の値は‘abbrev-start-location’がセットされたバッファー。他の バッファーでabbrev展開を試みることにより‘abbrev-start-location’はク リアーされる。この変数は‘abbrev-prefix-mark’によりセットされる。 -- Variable: last-abbrev これは直近のabbrev展開の‘abbrev-symbol’。これは‘unexpand-abbrev’コ マンド(*note Expanding Abbrevs: (emacs)Expanding Abbrevs.を参照)の ために‘expand-abbrev’により残された情報である。 -- Variable: last-abbrev-location これは直近の.abbrev展開の場所。これには‘unexpand-abbrev’コマンドの ために‘expand-abbrev’により残された情報が含まれる。 -- Variable: last-abbrev-text これは直近のabbrev展開の正確な展開形を、(もしあれば)大文字小文字変 換した後のテキストである。そのabbrevがすでに非展開されていれば値は ‘nil’。これには‘unexpand-abbrev’コマンドのために‘expand-abbrev’ga残 sita情報が含まれる。 -- Variable: abbrev-expand-function この変数の値は展開を行うために‘expand-abbrev’が引数なしで呼び出すで あろう関数。この関数では展開を行う前後に行いたいことを行うことがで きる。展開が行われた場合にはそのabbrevシンボルをリターンすること。 以下のサンプルコードでは‘abbrev-expand-function’のシンプルな使い方を 示します。このサンプルでは‘foo-mode’が‘#’で始まる行がコメントであるよう な特定のファイルを編集するためのモードであるとします。それらコメント行に たいしてはTextモードのabbrevの使用が望ましく、その他すべての行にたいして は正規のローカルabbrevテーブル‘foo-mode-abbrev-table’が適しています。 ‘local-abbrev-table’と‘text-mode-abbrev-table’の定義については、*note Standard Abbrev Tables::を参照してください。‘add-function’についての詳細 は*note Advising Functions::を参照してください。 (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))) 35.5 標準的なabbrevテーブル =========================== 以下はEmacsの事前ロードされるメジャーモード用のabbrevテーブルを保持する 変数のリストです。 -- Variable: global-abbrev-table これはモードに非依存なabbrev用のabbrevテーブル。この中で定義される abbrevはすべてのバッファーに適用される。各バッファーはローカル abbrevテーブルももつかもしれず、それのabbrev定義はグローバルテーブ ル内のabbrev定義より優先される。 -- Variable: local-abbrev-table このバッファーローカル変数の値はカレントバッファーの(モード固有な )abbrevテーブルである。これはそのようなテーブルのリストでもあり得る 。 -- Variable: abbrev-minor-mode-table-alist この変数の値は‘(MODE . ABBREV-TABLE)’という形式のリスト。ここで MODEは変数の名前。その変数が非‘nil’にバインドされていれば ABBREV-TABLEはアクティブ、それ以外なら無視される。ABBREV-TABLEは abbrevテーブルのリストでもあり得る。 -- Variable: fundamental-mode-abbrev-table これはFundamentalモードで使用されるローカルabbrevテーブル。言い換え るとこれはFundamentalモードにあるすべてのバッファーのローカル abbrevテーブルである。 -- Variable: text-mode-abbrev-table これはTextモードで使用されるローカルabbrevテーブル。 -- Variable: lisp-mode-abbrev-table これはLispモードで使用されるローカルabbrevテーブルであり、Emacs Lispモードで使用されるローカルabbrevテーブルの親テーブル。*note Abbrev Table Properties::を参照のこと。 35.6 abbrevプロパティー ======================= abbrevはプロパティをもち、それらのいくつかはabbrevの働きに影響します。こ れらのプロパティを‘define-abbrev’の引数として提供して以下の関数で操作で きます: -- Function: abbrev-put abbrev prop val ABBREVのプロパティPROPに値VALをセットする。 -- Function: abbrev-get abbrev prop ABBREVのプロパティPROP、そのabbrevがそのようなプロパティをもたなけ れば‘nil’をリターンする。 以下のプロパティには特別な意味があります: ‘:count’ このプロパティはそのabbrevが展開された回数を計数する。明示的にセッ トしなければ‘define-abbrev’により0に初期化される。 ‘:system’ 非‘nil’ならこのプロパティはシステムabbrevとしてそのabbrevをマスクす る。そのようなabbrevは保存されない(*note Abbrev Files::を参照)。 ‘:enable-function’ 非‘nil’の場合には、そのabbrevが使用されるべきでなければ‘nil’、それ 以外なら‘t’をリターンするような引数なしの関数であること。 ‘:case-fixed’ 非‘nil’なら、このプロパティはそのabbrevのcase(大文字小文字)には意味 があり、同じパターンにcapitalizeされたテキストだけにマッチすべきこ とを示す。これは展開のcapitalizationを変更するコードも無効にする。 35.7 abbrevテーブルのプロパティー ================================= abbrevと同じようにabbrevテーブルもプロパティをもち、それらのいくつかは abbrevテーブルの働きに影響を与えます。これらのプロパティを ‘define-abbrev-table’の引数として提供して、それらを関数で操作できます: -- Function: abbrev-table-put table prop val abbrevテーブルTABLEのプロパティPROPに値VALをセットする。 -- Function: abbrev-table-get table prop abbrevテーブルのプロパティPROP、そのabbrevテーブルがそのようなをプ ロパティもたなければ‘nil’をリターンする。 以下のプロパティには特別な意味があります: ‘:enable-function’ abbrevプロパティ‘:enable-function’と似ているが、そのテーブル内のす べてのabbrevに適用される点が異なる。これはポイントの前のabbrevを探 すことを試みる前にも使用されるのでabbrevテーブルを動的に変更するこ とが可能。 ‘:case-fixed’ これはabbrevプロパティ‘:case-fixed’と似ているが、そのテーブル内のす べてのabbrevに適用される点が異なる。 ‘:regexp’ 非‘nil’なら、このプロパティはそのテーブルを照合する前にポイント前の abbrev名を抽出するための方法を示す正規表現。その正規表現がポイント の前にマッチしたときは、そのabbrev名はsubmatchの1と期待される。この プロパティが‘nil’ならデフォルトは‘backward-word’と‘forward-word’を 使用してabbrevの名前を探す。このプロパティにより単語構文以外の文字 を含む名前のabbrevが使用できる。 ‘:parents’ このプロパティは他のabbrevを継承したテーブルのリストを保持する。 ‘:abbrev-table-modiff’ このプロパティはそのテーブルにabbrevが追加される度に増分されるカウ ンターを保持する。 36 プロセス *********** オペレーティングシステムの用語では“プロセス(process)”とはプログラムを実 行できるスペースのことです。Emacsはプロセス内で実行されます。Emacs Lispプ ログラムは別のプログラムをそれら自身のプロセス内で呼び出すことができます 。これらは“親プロセス(parent process)”であるEmacsプロセスの“サブプロセス (subprocesses)”、または“子プロセス(child processes)”と呼ばれます。 Emacsのサブプロセスは“同期(synchronous)”か“非同期(asynchronous)”であ り、それはそれらが作成された方法に依存します。同期サブプロセスを作成した 際には、Lispプログラムは実行を継続する前にそのサブプロセスの終了を待機し ます。非同期サブプロセスを作成したときには、それをLispプログラムと並行し て実行できます。この種のサブプロセスはEmacsではLispオブジェクととして表 現され、そのオブジェクトも“プロセス”と呼ばれています。Lispプログラムはサ ブプロセスとのやり取りやサブプロセスの制御のためにこのオブジェクトを使用 できます。たとえばシグナル送信、ステータス情報の取得、プロセス出力の受信 やプロセスへ入力を送信することができます。 プログラムを実行するプロセスに加えて、Lispプログラムは同一または他の マシン上で実行中のデバイスやプロセスにたいして、いくつかのタイプの接続を オープンできます。サポートされる接続タイプはネットワーク接続のTCPとUDP、 シリアルポート接続、およびパイプ接続です。そのような接続はそれぞれプロセ スオブジェクトとしても表現されます。 -- Function: processp object この関数は、OBJECTがEmacsのプロセスオブジェクトを表すなら‘t’、それ 以外は‘nil’をリターンする。プロセスオブジェクトはプログラム実行中の サブプロセスやサポートされた任意のタイプの接続を表すことができる。 カレントEmacsセッションのサブプロセスに加えて、そのマシン上で実行中の 他のプロセスにアクセスすることもできます。*note System Processes::を参照 してください。 36.1 サブプロセスを作成する関数 =============================== 内部でプログラムを実行するサブプロセスを作成するために3つのプリミティブ が存在します。それらの1つは‘make-process’であり、これは非同期プロセスを 作成してプロセスオブジェクトをリターンします(*note Asynchronous Processes::を参照)。他の2つは‘call-process’と‘call-process-region’です。 これらは同期プロセスを作成してプロセスオブジェクとをリターンしません (*note Synchronous Processes::を参照)。特定のタイプのプロセスを実行する ために、これらのプリミティブを利用するさまざまな高レベル関数が存在します 。 同期プロセスと非同期プロセスについては、以降のセクションで説明します 。この3つの関数はすべて類似した様式で呼び出されるので、ここではそれらに 共通の引数について説明します。 すべての場合において、関数は実行するプログラムを指定します。ファイル が見つからなかったり実行できなければエラーがシグナルされます。ファイル名 が相対的なら、検索するディレクトリーのリストは変数‘exec-path’に格納され ています。Emacsは起動の際に環境変数‘PATH’の値にもとづいて‘exec-path’を初 期化します。‘exec-path’内では標準的なファイル名構成要素‘~’、‘.’、‘..’は 通常どおりに解釈されますが、環境変数の置換(‘$HOME’等)は認識されません。 それらの置換を行うには‘substitute-in-file-name’を使用してください(*note File Name Expansion::を参照)。このリスト内で‘nil’は‘default-directory’を 参照します。 プログラムの実行では指定された名前にサフィックスの追加を試みることも できます: -- User Option: exec-suffixes この変数は指定されたプログラムファイル名への追加を試みるためのサフ ィックス(文字列)のリスト。指定されたとおりの名前を試みたいならリス トに‘""’を含めること。デフォルト値はシステム依存。 *注意してください:* 引数PROGRAMにはプログラムのファイル名だけが含まれ て、コマンドライン引数を含めることはできない。これらを提供するために以下 で説明する別の引数ARGSを使用しなければならない。 サブプロセス作成関数にはそれぞれBUFFER-OR-NAME引数があります。これは プログラムの出力の行き先を指定します。これはバッファーかバッファー名であ るべきです。バッファー名の場合には、もしそのバッファーがまだ作成されてい なければバッファーを作成します。‘nil’を指定することもでき、その場合には カスタム製のフィルター関数が出力を処理するのでなければ出力を破棄するよう 指示します(*note Filter Functions::と*note Read and Print::を参照)。通常 は出力がランダムに混在してしまうために、同一バッファーに複数プロセスの出 力を送信するのは避けるべきです。同期プロセスにたいしてはバッファーのかわ りにファイルに出力を送信できます(したがって対応する引数はより適切な DESTINATIONという名前で呼ばれる)。デフォルトでは標準出力と標準エラーの両 ストリームの行き先(destination)は同じだが、3つのプリミティブはすべてオプ ションで標準エラーストリームに別の行き先を指定できる。 これら3つのサブプロセス作成関数は、すべて実行するプロセスにコマンドラ イン引数を指定できます。‘call-process’と‘call-process-region’では、これ らは‘&rest’形式の引数ARGSで与えられます。‘make-process’では実行するプロ グラムとコマンドライン引数はいずれも文字列のリストとして指定されます。コ マンドライン引数はすべて文字列でなければならず、それらは別個の引数文字列 としてプログラムに与えられます。文字列は指定されたプログラムに直接渡され るので、ワイルドカード文字やその他のshell構文はこれらの文字列内では特別 な意味をもちません。 サブプロセスはその環境をEmacsから継承しますが、 ‘process-environment’でそれをオーバーラードするよう指定することができま す。*note System Environment::を参照してください。サブプロセスは自身のカ レントディレクトリーを‘default-directory’の値から取得します。 -- Variable: exec-directory この変数の値はGNU Emacsとともに配布されて、Emacsにより呼び出される ことを意図したプログラムを含むディレクトリーの名前(文字列)。プログ ラム‘movemail’はそのようなプログラムの例であり、Rmailはinboxから新 しいメールを読み込むためにこのプログラムを使用する。 -- User Option: exec-path この変数の値はサブプロセス内で実行するためのプログラムを検索するた めのディレクトリーのリスト。要素はそれぞれディレクトリーの名前(文字 列)、または‘nil’のいずれか。‘nil’はデフォルトディレクトリー (‘default-directory’の値)を意味する。この検索の詳細は*note executable-find: Locating Files.を参照のこと。 ‘exec-path’の値は、PROGRAM引数が絶対ファイル名でないときに ‘call-process’と‘start-process’により使用される。 一般的には‘exec-path’を直接変更するべきではない。かわりにEmacs起動 前に環境変数‘PATH’が適切にセットされているか確認すること。‘PATH’と は独立に‘exec-path’の変更を試みると混乱した結果へと導かれ得る。 36.2 shell引数 ============== Lispプログラムがshellを実行して、ユーザーが指定したファイル名を含むコマ ンドを与える必要がある場合が時折あります。これらのプログラムは任意の有効 なファイル名をサポート可能であるはずです。しかしshellは特定の文字を特別 に扱い、それらの文字がファイル名に含まれているとshellを混乱させるでしょ う。これらの文字を処理するためには関数‘shell-quote-argument’を使用します 。 -- Function: shell-quote-argument argument この関数は実際のコンテンツがARGUMENTであるような引数を表す文字列を shellの構文でリターンする。リターン値をshellコマンドに結合して実行 のためにそれをshellに渡すことにより、信頼性をもって機能するはずであ る。 この関数が正確に何を行うかはオペレーティングシステムに依存する。こ の関数はそのシステムの標準shellの構文で機能するようデザインされてい る。非標準のshellを使用する場合には、この関数を再定義する必要がある だろう。*note Security Considerations::を参照のこと。 ;; この例はGNUおよびUnixシステムでの挙動を示す (shell-quote-argument "foo > bar") ⇒ "foo\\ \\>\\ bar" ;; この例はMS-DOSおよびMS-Windowsでの挙動を示す (shell-quote-argument "foo > bar") ⇒ "\"foo > bar\"" 以下は‘shell-quote-argument’を使用してshellコマンドを構築する例: (concat "diff -u " (shell-quote-argument oldfile) " " (shell-quote-argument newfile)) 以下の2つの関数はコマンドライン引数の文字列のリストを単一の文字列に結 合したり、単一の文字列を個別のコマンドライン引数のリストへ分割するために 有用です。これらの関数は主にミニバッファーでのユーザー入力であるLisp文字 列を‘make-process’、‘call-process’や‘start-process’に渡す文字列引数のリ ストへ変換したり、そのような引数のリストをミニバッファーやエコーエリアに 表示するためのLisp文字列に変換することを意図しています。 (‘call-process-shell-command’を使用して)shellが呼び出される場合には、引 数を依然として‘shell-quote-argument’で保護する必要があることに注意。 ‘combine-and-quote-strings’はshellの評価から特殊文字を保護することを_意 図していない_。 -- Function: split-string-and-unquote string &optional separators この関数は‘split-string’(*note Creating Strings::を参照)が行うよう に、正規表現SEPARATORSにたいするマッチでSTRINGを部分文字列に分割す る。さらに加えてその部分文字列からクォートを削除する。それから部分 文字列のリストを作成してリターンする。 SEPARATORSが省略または‘nil’の場合のデフォルトは‘"\\s-+"’であり、こ れは空白文字構文(*note Syntax Class Table::を参照)をもつ1つ以上の文 字にマッチする正規表現である。 この関数は2つのタイプのクォートをサポートする。1つは文字列全体をダ ブルクォートで囲う‘"..."’のようなクォートで、もう1つはバックスラッ シュ‘\’によるエスケープで文字を個別にクォートするタイプである。後者 はLisp文字列内でも使用されるので、この関数はそれらも同様に扱うこと ができる。 -- Function: combine-and-quote-strings list-of-strings &optional separator この関数はLIST-OF-STRINGSの各文字を必要に応じてクォートして単一の文 字列に結合する。これはさらに各文字ペアーの間にSEPARATOR文字列も挿入 する。SEPARATORが省略または‘nil’の場合のデフォルトは‘" "’。リターン 値はその結果の文字列。 LIST-OF-STRINGS内のクォートを要する文字列には、部分文字列として SEPARATORを含むものが該当する。文字列のクォートはそれをダブルクォー トで‘"..."’のように囲う。もっとも単純な例では、たとえば個別のコマン ドライン引数からコマンドをコンス(cons)する場合には、埋め込まれたブ ランクを含む文字列はそれぞれクォートされるだろう。 36.3 同期プロセスの作成 ======================= “同期プロセス(synchronous process)”の作成後、Emacsは継続する前にそのプロ セスの終了を待機します。GNUやUnix(1)でのDiredの起動が例です。プロセスは 同期的なので、Emacsがそれにたいして何か行おうと試みる前にディレクトリー のリスト全体がバッファーに到着します。 同期サブプロセス終了をEmacsが待機する間に、ユーザーは‘C-g’をタイプす ることでquitが可能です。最初の‘C-g’は‘SIGINT’シグナルによりサブプロセス のkillを試みます。しかしこれはquitする前に実際にそのサブプロセスが終了さ れるまで待機します。その間にユーザーがさらに‘C-g’をタイプするとそれは ‘SIGKILL’で即座にサブプロセスをkillしてquitします(別プロセスにたいする killが機能しないMS-DOSを除く)。*note Quitting::を参照してください。 同期サブプロセス関数はプロセスがどのように終了したかの識別をリターン します。 同期サブプロセスからの出力はファイルからのテキスト読み込みと同じよう に、一般的にはコーディングシステムを使用してデコードされます。 ‘call-process-region’によりサブプロセスに送信された入力は、ファイルへの テキスト書き込みと同じようにコーディングシステムを使用してエンコードされ ます。*note Coding Systems::を参照してください。 -- Function: call-process program &optional infile destination display &rest args この関数はPROGRAMを呼び出して完了するまで待機する。 サブプロセスのカレントワーキングディレクトリーは ‘default-directory’。 新たなプロセスの標準入力はINFILEが非‘nil’ならファイルINFILE、それ以 外ならnullデバイス。引数DESTINATIONはプロセスの出力をどこに送るかを 指定する。以下は可能な値: バッファー そのバッファーのポイントの前に出力を挿入する。これにはプロセス の標準出力ストリームと標準エラーストリームの両方が含まれる。 バッファー名(文字列) その名前のバッファーのポイントの前に出力を挿入する。 ‘t’ カレントバッファーのポイントの前に出力を挿入する。 ‘nil’ 出力を破棄する。 0 出力を破棄してサブプロセス完了を待機せずに即座に‘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に一度遭遇すると再表示が継続不能になること がある。これを修正するのが困難な根本的理由が存在する。*note Output from Processes::を参照)。 それ以外なら関数‘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)) -- Function: process-file program &optional infile buffer display &rest args この関数は別プロセス内でファイルを同期的に処理する。これは ‘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’はそのような相対ファイル名の構築に有用。 -- Variable: process-file-side-effects この変数は‘process-file’呼び出しがリモートファイルを変更するかどう かを示す。 この変数はデフォルトでは‘process-file’呼び出しがリモートホスト上の 任意のファイルを潜在的に変更し得ることを意味する‘t’に常にセットされ る。‘nil’にセットされた際には、リモートファイル属性のキャッシュにし たがうことによりファイルハンドラーの挙動を最適化できる可能性がある 。 この変数は決して‘setq’ではなく、常にletバインディングでのみ変更する こと。 -- Function: call-process-region start end program &optional delete destination display &rest args この関数はSTARTからENDのテキストを、実行中のプロセスPROGRAMに標準入 力として送信する。これはDELETEが非‘nil’なら送信したテキストを削除す る。これは出力をカレントバッファーの入力箇所に挿入するために、 DESTINATIONを‘t’に指定している際に有用。 引数DESTINATIONとDISPLAYはサブロセスからの出力にたいして何を行うか 、および出力の到着にともない表示を更新するかどうかを制御する。詳細 は上述の‘call-process’の説明を参照のこと。DESTINATIONが整数の0なら ‘call-process-region’は出力を破棄して、サブプロセス完了を待機せずに 即座に‘nil’をリターンする(これは非同期サブプロセスがサポートされる 場合、つまりMS-DOS以外でのみ機能する)。 残りの引数ARGSはそのプログラムにたいしてコマンドライン引数を指定す る文字列です。 ‘call-process-region’のリターン値は‘call-process’の場合と同様。待機 せずにリターンするよう指示した場合には‘nil’、数字か文字列ならそれは サブプロセスが終了した方法を表す。 以下の例ではバッファー‘foo’内の最初の5文字(単語‘input’)を標準入力と して、‘call-process-region’を使用して‘cat’ユーティリティを実行する 。‘cat’は自身の標準入力を標準出力へコピーする。引数DESTINATIONが ‘t’なので出力はカレントバッファーに挿入される。 ---------- Buffer: foo ---------- input★ ---------- Buffer: foo ---------- (call-process-region 1 6 "cat" nil t) ⇒ 0 ---------- Buffer: foo ---------- inputinput★ ---------- Buffer: foo ---------- たとえば‘shell-command-on-region’コマンドは以下のような方法で ‘call-process-region’を使用する: (call-process-region start end shell-file-name ; プログラム名 nil ; リージョンを削除しない buffer ; 出力を‘buffer’に送信 nil ; 出力中に再表示を行わない "-c" command) ; shellへの引数 -- Function: call-process-shell-command command &optional infile destination display この関数はshellコマンドCOMMANDを非同期に実行する。他の引数は ‘call-process’の場合と同様に処理される。古い呼び出し規約はDISPLAYの 後に任意個数の追加引数を許容して、これはCOMMANDに結合される。これは まだサポートされるものの使用しないことを強く推奨する。 -- Function: process-file-shell-command command &optional infile destination display この関数は‘call-process-shell-command’と同様だが内部的に ‘process-file’を使用する点が異なる。‘default-directory’に依存して COMMANDはリモートホスト上でも実行可能。古い呼び出し規約はDISPLAYの 後に任意個数の追加引数を許容して、これはCOMMANDに結合される。これは まだサポートされるものの使用しないことを強く推奨する。 -- Function: shell-command-to-string command この関数はshellコマンドとしてCOMMAND (文字列)を実行してコマンドの出 力を文字列としてリターンする。 -- Function: process-lines program &rest args この関数はPROGRAMを実行して完了を待機して、出力を文字列のリストとし てリターンする。リスト内の各文字列はプログラムのテキスト出力の1つの 行を保持する。各行のEOL文字(行末文字)は取り除かれる。PROGRAMの後の 引数ARGSはそのプログラム実行に際して、コマンドライン引数を指定する 文字列。 PROGRAMが非0のexitステータスでexitすると、この関数はエラーをシグナ ルする。 この関数は‘call-process’を呼び出すことにより機能して、プログラムの 出力は‘call-process’の場合と同じ方法でデコードされる。 ---------- Footnotes ---------- (1) 他のシステムではEmacsは‘ls’のLispエミュレーションを使用します。 *note Contents of Directories::を参照してください。 36.4 非同期プロセスの作成 ========================= このセクションでは“非同期プロセス(asynchronous process)”を作成する方法に ついて説明します。非同期プロセスは作成後はEmacsと並列に実行されて、 Emacsは以降のセクション(*note Input to Processes::と*note Output from Processes::を参照)で説明する関数を使用してプロセスとコミュニケーションが できます。プロセスコミュニケーションは部分的に非同期なだけであることに注 意してください。Emacsは特定の関数を呼び出したときだけプロセスにデータを 送信でき、Emacsは入力の待機中か一定の遅延時間の後にのみプロセスのデータ を受け取ることができます。 非同期プロセスは“pty(pseudo-terminal: 疑似端末)”かたは“pipe”のいずれ かを通じて制御されます。ptyかpipeの選択は、デフォルトでは変数 ‘process-connection-type’ (以下参照)の値にもとづいてプロセス作成時に行わ れます。ptyが利用可能なら、通常はShellモード内のようにユーザーから可視な プロセスに適しています。ptyではプロセスとその子プロセスとの間でジョブ制 御(‘C-c’、‘C-z’、...等)が可能であり、対話的なプログラムはptyを端末デバイ スとして扱いますが、これらはpipeではサポートされない機能だからです。 Lispプログラムの内部的な目的のために使用されるサブプロセスにたいしては、 pipeのほうが適している場合が多々あります。それはpipeがより効率的であり、 ptyが大量の文字(500byte前後)にたいして導入する迷入文字インジェクション (stray character injections)にたいして免疫があるのが理由です。さらに多く のシステムではptyの合計数に制限があり、それを浪費するのは得策ではありま せん。 -- Function: make-process &rest args この関数は非同期サブプロセスを開始するための基本的な低レベルなプリ ミティブである。これはサブプロセスを表すプロセスオブジェクトをリタ ーンする。以下で説明するより高レベルな‘start-process’と比較すると、 この関数はキーワード引数を受け取り、より柔軟であり、単独の呼び出し でプロセスフィルターやセンチネルを指定できる。 引数ARGSはkeyword/argumentペアのリスト。キーワードの省略は値‘nil’で それを指定することと常に等価。以下は意味のあるキーワード: :name NAME プロセス名として文字列NAMEを使用する。その名前のプロセスがすで に存在すれば、(‘<1>’、...の追加により)一意となるようにNAMEを修 正する。 :buffer BUFFER プロセスバッファーとしてBUFFERを使用する。値が‘nil’なら、その サブプロセスには何のバッファーも関連付けられない。 :command COMMAND プロセスのコマドラインとしてCOMMANDを使用する。値はプログラム の実行可能ファイル名で始まり、後にプログラムの引数として与える 文字列が続くリストであること。リストの最初の要素が‘nil’なら、 Emacsは新たな擬似端末(pty)を作成して、実際には何もプログラムを 実行せずに入出力をBUFFERに関連付ける。この場合には残りのリスト 要素は無視される。 :coding CODING CODINGがシンボルなら、それはその接続にたいする読み取りと書き込 みの両方で使用するコーディングシステムを指定する。CODINGがコン スセル‘(DECODING . ENCODING)’なら読み取りにDECODING、書き込み にENCODINGが使用される。プログラムに書き込むデータのエンコーデ ィングに使用されるコーディングシステムは、コマンドライン引数の エンコーディングにも使用される(しかしプログラム自身にたいして ファイル名を別のファイル名にエンコードすることはない。*note file-name-coding-system: Encoding and I/O.を参照)。 CODINGが‘nil’なら、デフォルトのコーディングシステム検出ルール を適用する。*note Default Coding Systems::を参照のこと。 :connection-type TYPE サブプロセスとの対話に使用するデバイスのタイプを初期化する。指 定できる値はptyを使用する‘pty’、pipeを使用する‘pipe’、または ‘process-connection-type’変数の値のデフォルトデバイスを使用す る‘nil’。‘:stderr’パラメーターに非‘nil’値が指定されると、この パラメーターと‘process-connection-type’の値は無視される。この 場合にはタイプは常に‘pipe’になる。 :noquery QUERY-FLAG プロセスqueryフラグをQUERY-FLAGに初期化する。*note Query Before Exit::を参照のこと。 :stop STOPPED STOPPEDが非‘nil’なら、停止状態でプロセスを開始する。 :filter FILTER プロセスフィルターをFILTERに初期化する。未指定ならデフォルトフ ィルターが提供されるが、これは後からオーバーライドできる。 *note Filter Functions::を参照のこと。 :sentinel SENTINEL プロセスセンチネルをSENTINELに初期化する。未指定ならデフォルト センチネルが使用されるが、これは後からオーバーライドできる。 *note Sentinels::を参照のこと。 :stderr STDERR プロセスの標準エラーにSTDERRを割り当てる。値が非‘nil’ならバッ ファー、または以下で説明する‘make-pipe-process’で作成された pipeのいずれかであること。 実際の接続情報で修正されたオリジナルの引数リストは ‘process-contact’を通じて利用できる。 -- Function: make-pipe-process &rest args この関数は子プロセスにアタッチ可能な双方向のpipeを作成する。これは ‘make-process’の‘:stderr’キーワードと併用することで有用。この関数は プロセスオブジェクトをリターンする。 引数ARGSはkeyword/argumentペアのリスト。キーワードの省略はそのキー ワードに値‘nil’を指定することと常に等価。 以下は意味のあるキーワード。 :name NAME プロセス名として文字列NAMEを使用する。‘make-process’の場合のよ うに、一意にするために必要に応じて変更され得る。 :buffer BUFFER プロセスバッファーとしてBUFFERを使用する。 :coding CODING CODINGがシンボルなら、それはその接続にたいする読み取りと書き込 みの両方で使用するコーディングシステムを指定する。CODINGがコン スセル‘(DECODING . ENCODING)’なら読み取りにDECODING、書き込み にENCODINGが使用される。 CODINGが‘nil’なら、デフォルトのコーディングシステム検出ルール を適用する。*note Default Coding Systems::を参照のこと。 :noquery QUERY-FLAG プロセスqueryフラグをQUERY-FLAGに初期化する。*note Query Before Exit::を参照のこと。 :stop STOPPED STOPPEDが非‘nil’なら、停止状態でプロセスを開始する。 :filter FILTER プロセスフィルターをFILTERに初期化する。未指定ならデフォルトフ ィルターが提供されるが後で変更できる。*note Filter Functions::を参照のこと。 :sentinel SENTINEL プロセスセンチネルをSENTINELに初期化する。未指定ならデフォルト センチネルが使用されるが後で変更できる。*note Sentinels::を参 照のこと。 実際の接続情報で修正されたオリジナルの引数リストは ‘process-contact’を通じて利用できる。 -- Function: start-process name buffer-or-name program &rest args この関数は‘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") ⇒ # (start-process "my-process" "foo" "ls" "-l" "/bin") ⇒ #> ---------- 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 ---------- -- Function: start-file-process name buffer-or-name program &rest args ‘start-process’と同じようにこの関数は非同期サブプロセスを開始して、 その内部でPROGRAMを実行してそのプロセスオブジェクトをリターンする。 ‘start-process’との違いは、この関数が‘default-directory’の値にもと づいてファイルハンドラーを呼び出すかもしれないという点である。この ハンドラーはローカルホスト上、あるいは‘default-directory’に応じたリ モートホスト上でPROGRAMを実行すること。後者の場合には、 ‘default-directory’のローカル部分はそのプロセスのワーキングディレク トリーになる。 この関数はPROGRAM、またはARGSの残りにたいしてファイル名ハンドラーの 呼び出しを試みない。 そのファイルハンドラーの実装によっては、リターン結果のプロセスオブ ジェクトに‘process-filter’や‘process-sentinel’を適用することができ ないかもしれない。*note Filter Functions::と*note Sentinels::を参照 のこと。 いくつかのファイルハンドラーは‘start-file-process’をサポートしない かもしれない(たとえば‘ange-ftp-hook-function’関数)。そのような場合 には、この関数は何も行わずに‘nil’をリターンする。 -- Function: start-process-shell-command name buffer-or-name command この関数は‘start-process’と同様だが、指定されたCOMMANDの実行に shellを使用する点が異なる。引数COMMANDはshellコマンド文字列。変数 ‘shell-file-name’はどのshellを使用するかを指定する。 ‘make-process’や‘start-process’でプログラムを実行せずにshellを通じ て実行することの要点は、引数内のワイルドカード展開のようなshell機能 を利用可能にするためである。そのためにはコマンド内に任意のユーザー 指定引数を含めるなら、任意の特別なshell文字がshellでの特別な意味を _もたない_ように、まず‘shell-quote-argument’でそれらをクォートする べきである。*note Shell Arguments::を参照のこと。ユーザー入力にもと づいたコマンド実行時には当然セキュリティ上の影響も考慮するべきであ る。 -- Function: start-file-process-shell-command name buffer-or-name command この関数は‘start-process-shell-command’と似ているが、内部的に ‘start-file-process’を使用する点が異なる。これにより ‘default-directory’に応じてリモートホスト上でもCOMMANDを実行できる 。 -- Variable: process-connection-type この変数は非同期サブプロセスと対話するために使用するデバイスタイプ を制御する。これが非‘nil’の場合には利用可能ならpty、それ以外なら pipeが使用される。 ‘process-connection-type’の値は‘make-process’や‘start-process’の呼 び出し時に効果を発揮する。そのためにこれらの関数の呼び出し前後でこ の変数をバインドすることにより、サブプロセスとやり取りする方法を指 定できる。 この変数の値は‘make-process’が非‘nil’値の‘:stderr’パラメーターで呼 び出された際には無視される。この場合には、Emacsはpipeを使用してプロ セスと対話する。 (let ((process-connection-type nil)) ; pipeを使用 (start-process ...)) 与えられたサブプロセスが実際にはpipeとptyのどちらを取得したかを判断 するには関数‘process-tty-name’を使用する(*note Process Information::を参照)。 36.5 プロセスの削除 =================== “プロセス削除(deleting a process)”とはEmacsをサブプロセスから即座に切断 することです。プロセスは終了後に自動的に削除されますが即座に削除される必 要はありません。任意のタイミングで明示的にプロセスを削除できます。終了し たプロセスが自動的に削除される前に明示的に削除しても害はありません。実行 中のプロセスの削除はプロセス(もしあれば子プロセスにも)を終了するためにシ グナルを送信してプロセスセンチネルを呼び出します。*note Sentinels::を参 照してください。 プロセスが削除される際、そのプロセスオブジェクト自体はそれを参照する 別のLispオブジェクトが存在する限り継続し続けます。プロセスオブジェクトに 作用するすべてのLispプリミティブはプロセスの削除を受け入れますが、I/Oを 行ったりシグナルを送信するプリミティブはエラーを報告するでしょう。プロセ スマークは通常はプロセスからの出力がバッファーに挿入される箇所となる、以 前と同じ箇所をポイントし続けます。 -- User Option: delete-exited-processes この変数は、(‘exit’呼び出しやシグナルにより)終了したプロセスの自動 的な削除を制御する。これが‘nil’ならユーザーが‘list-processes’を実行 するまでプロセスは存在し続けて、それ以外ならexit後に即座に削除され る。 -- Function: delete-process process この関数はプロセスがプログラムを実行していたら‘SIGKILL’シグナルで killすることによりプロセスを削除する。引数はプロセス、プロセスの名 前、バッファー、バッファーの名前かもしれない(バッファーやバッファー 名なら‘get-buffer-process’がリターンするプロセスを意味する)。実行中 のプロセスに‘delete-process’を呼び出すことによりプロセスを終了して プロセス状態を更新して即座にセンチネルを実行する。そのプロセスがす でに終了していれば、‘delete-process’呼び出しはプロセス状態、または (遅かれ早かれ発生するであろう)プロセスセンチネルの実行に影響を与え ない。 プロセスオブジェクトがネットワーク接続、シリアル接続、pipe接続を表 す場合には状態は‘closed’、それ以外ならそのプロセスがexit済みでなけ れば‘signal’に変更される。*note process-status: Process Information.を参照のこと。 (delete-process "*shell*") ⇒ nil 36.6 プロセスの情報 =================== プロセスの状態に関する情報をリターンする関数がいくつかあり。 -- Command: list-processes &optional query-only buffer このコマンドは、すべての生きたプロセスのリストを表示する。加えてこ れは最後に、状態が‘Exited’か‘Signaled’だったすべてのプロセスを削除 する。このコマンドは‘nil’をリターンする。 プロセスはメジャーモードがProcess Menuモードであるような、‘*Process List*’という名前のバッファーに表示される(オプション引数BUFFERで他の 名前を指定していない場合)。 QUERY-ONLYが非‘nil’なら、queryフラグが非‘nil’のプロセスだけをリスト する。*note Query Before Exit::を参照のこと。 -- Function: process-list この関数は削除されていないすべてのプロセスのリストをリターンする。 (process-list) ⇒ (# #) -- Function: get-process name この関数はNAME (文字列)というプロセス、存在しなければ‘nil’をリター ンする。引数NAMEはプロセスオブジェクトでもよく、この場合にはそれが リターンされる。 (get-process "shell") ⇒ # -- Function: process-command process この関数はPROCESSを開始するために実行されたコマンドをリターンする。 これは文字列のリストで1つ目の文字列は実行されたプログラム、残りの文 字列はそのプログラムに与えられた引数。ネットワーク接続、シリアル接 続、pipe接続にたいしては‘nil’ (プロセスは実行中)か‘t’ (プロセスは停 止中)のいずれか。 (process-command (get-process "shell")) ⇒ ("bash" "-i") -- Function: process-contact process &optional key この関数はネットワーク接続、シリアル接続、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’ 値にはプロセスのフィルター関数が割り当てられる。*note Filter Functions::を参照のこと。 ‘:sentinel’ 値にはプロセスのセンチネル関数が割り当てられる。*note Sentinels::を参照のこと。 ‘:remote’ 接続にたいしては内部的なフォーマットによるリモートピアーのアド レス。 ‘:local’ 内部的なフォーマットによるローカルアドレス。 ‘:service’ この値はサーバーではSERVICEに‘t’を指定すると実際のポート番号。 ‘make-network-process’内で明示的に指定されていなくても‘:local’と ‘:remote’は値に含まれる。 シリアル接続については‘make-serial-process’、キーのリストは ‘serial-process-configure’を参照のこと。pipe接続については ‘make-pipe-process’を参照のこと。 KEYがキーワードなら、この関数はそのキーワードに対応する値をリターン する。 -- Function: process-id process この関数はPROCESSのPIDをリターンする。これは同じコンピューター上で カレント時に実行中の他のすべてのプロセスからプロセスPROCESSを区別す るための整数。プロセスのPIDはプロセスの開始時にオペレーティングシス テムのカーネルにより選択されて、そのプロセスが存在する限り定数とし て保たれる。この関数はネットワーク接続、シリアル接続、pipe接続には ‘nil’をリターンする。 -- Function: process-name process この関数はPROCESSの名前を文字列としてリターンする。 -- Function: process-status process-name この関数は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’が呼び出されたことを意味する。 -- Function: process-live-p process この関数はPROCESSがアクティブなら、非‘nil’をリターンする。状態が ‘run’、‘open’、‘listen’、‘connect’、‘stop’のプロセスはアクティブと みなされる。 -- Function: process-type process この関数はネットワーク接続やサーバーにたいしては‘network’、シリアル ポート接続にたいしては‘serial’、pipe接続にたいしては‘pipe’、プログ ラム実行用に作成されたサブプロセスにたいしては‘real’というシンボル をリターンする。 -- Function: process-exit-status process この関数はPROCESSのexitステータス、またはプロセスをkillしたシグナル 番号をリターンする(いずれであるかの判定には‘process-status’の結果を 使用)。PROCESSがまだ終了していなければ値は0。すでにcloseされたネッ トワーク接続、シリアル接続、pipe接続についての値は接続のcloseが正常 か異常かによって0か256のいずれかとなる。 -- Function: process-tty-name process この関数はPROCESSがEmacsとの対話に使用する端末名、ptyではなくpipeを 使用する場合には‘nil’をリターンする(*note Asynchronous Processes::の ‘process-connection-type’を参照)。PROCESSがリモートホスト上で実行中 のプログラムを表す場合には、プロセスの‘remote-tty’プロパティとして リモートホスト上でそのプログラムに使用される端末名が提供される。 PROCESSがネットワーク接続、シリアル接続、pipe接続を表す場合には値は ‘nil’。 -- Function: process-coding-system process この関数はPROCESSからの出力のデコードに使用するコーディングシステム と、PROCESSへの入力のエンコードに使用するコーディングシステムを記述 するコンスセル‘(DECODE . ENCODE)’をリターンする(*note Coding Systems::を参照)。 -- Function: set-process-coding-system process &optional decoding-system encoding-system この関数はPROCESSにたいする後続の入出力に使用するコーディングシステ ムを指定する。これはサブプロセスの出力のデコードにDECODING-SYSTEM、 入力のエンコードにENCODING-SYSTEMを使用する。 すべてのプロセスには、そのプロセスに関連するさまざまな値を格納するた めに使用できるプロパティリストもあります。 -- Function: process-get process propname この関数はPROCESSのプロパティPROPNAMEの値をリターンする。 -- Function: process-put process propname value この関数はPROCESSのプロパティPROPNAMEの値にVALUEをセットする。 -- Function: process-plist process この関数はPROCESSのプロセスplistをリターンする。 -- Function: set-process-plist process plist この関数はPROCESSのプロセスplistにPLISTをセットする。 36.7 プロセスへの入力の送信 =========================== 非同期サブプロセスはEmacsにより入力が送信されたときに入力を受信して、そ れはこのセクション内の関数で行われます。これを行うには入力を送信するプロ セスと送信するための入力データを指定しなければなりません。サブプロセスが プログラムを実行していたら、データはプログラムの標準入力として出現します 。接続にたいしては、データは接続されたデバイスかプログラムに送信されます 。 オペレーティングシステムにはptyのバッファーされた入力にたいして制限を もつものがいくつかあります。それらのシステムでは、Emacsは他の文字列の間 に定期的かつ強制的にEOFを送信します。ほとんどのプログラムにたいして、こ れらのEOFは無害です。 サブプロセスの入力はテキストをファイルに書き込むときと同じように、通 常はサブプロセスが受信する前、コーディングシステムを使用してエンコードさ れます。どのコーディングシステムを使用するかを指定するには ‘set-process-coding-system’を使用できます(*note Process Information::を 参照)。それ以外の場合には、非‘nil’なら‘coding-system-for-write’がコーデ ィングシステムとなり、さもなくばデフォルトのメカニズムがコーディングシス テムを決定します(*note Default Coding Systems::を参照)。 入力バッファーが一杯でシステムがプロセスからの入力を受け取ることがで きないことがあります。これが発生したときには送信関数はしばらく待機してか らサブプロセスの出力を受け取って再度送信を試みます。これは保留となってい る更なる入力を読み取ってバッファーに空きを作る機会をサブプロセスに与えま す。これはフィルター、センチネル、タイマーの実行も可能にするのでコードを 記述する際はそれを考慮してください。 以下の関数ではPROCESS引数はプロセス、プロセス名、またはバッファー、バ ッファー名(‘get-buffer-process’で取得されるプロセス)、‘nil’はカレントバ ッファーのプロセスを意味します。 -- Function: process-send-string process string この関数はSTRINGのコンテンツを標準入力としてPROCESSに送信する。たと えばファイルをリストするShellバッファーを作成するには: (process-send-string "shell<1>" "ls\n") ⇒ nil -- Function: process-send-region process start end この関数はSTARTとENDで定義されるリージョンのテキストを標準入力とし てPROCESSに送信する。 STARTとENDが、カレントバッファー内の位置を示す整数かマーカーでなけ ればエラーがシグナルされる(いずれかの大小は重要ではない)。 -- Function: process-send-eof &optional process この関数はPROCESSが入力内のEOF (end-of-file)を見ることを可能にする 。EOFはすべての送信済みテキストの後になる。この関数はPROCESSをリタ ーンする。 (process-send-eof "shell") ⇒ "shell" -- Function: process-running-child-p &optional process この関数はPROCESSが接続ではない実際のサブプロセスであり、端末の制御 を自身の子プロセスに与えたかどうかを示す。これが真なら関数は PROCESSのフォアグラウンドプロセスグループの数値ID、これが真ではない とEmacsが判断すれば‘nil’をリターンする。これが真かどうかをEmacsが判 断できなければ値は‘t’。PROCESSがネットワーク接続、シリアル接続、 pipe接続、またはサブプロセスが非アクティブなら関数はエラーをシグナ ルする。 36.8 プロセスへのシグナルの送信 =============================== サブプロセスへの“シグナル送信(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は機能しないで しょう。*note Asynchronous Processes::の‘process-connection-type’を参照 してください。 -- Function: interrupt-process &optional process current-group この関数はシグナル‘SIGINT’を送信することによりプロセスPROCESSに割り 込む。Emacs外部ではinterrupt character(割り込み文字。いくつかのシス テムでは通常は‘C-c’、それ以外のシステムでは)をタイプすることに よりシグナルが送信される。引数CURRENT-GROUPが非‘nil’のときは、 Emacsがサブプロセスと対話する端末上で‘C-c’がタイプされたと考えるこ とができる。 -- Function: kill-process &optional process current-group この関数はシグナル‘SIGKILL’を送信することにより、プロセスPROCESSを killする。このシグナルは即座にサブプロセスをkillしてサブプロセスで ハンドルすることはできない。 -- Function: quit-process &optional process current-group この関数はプロセスPROCESSにシグナル‘SIGQUIT’を送信する。これは Emacs外部ではquit character(通常は‘C-\’)により送信されるシグナル。 -- Function: stop-process &optional process current-group この関数は指定したPROCESSを停止する。それがプログラムを実行中の実際 のサブプロセスなら、そのサブプロセスにシグナル‘SIGTSTP’を送信する。 PROCESSがネットワーク接続、シリアル接続、pipe接続を表す場合には、こ の関数はその接続から到達するデータのハンドリングを抑制する。ネット ワークサーバーでは、これは新たな接続をacceptしないことを意味する。 通常の実行の再開には‘continue-process’を使用すること。 ジョブ制御をもつシステム上のEmacs外部ではstop character(通常は ‘C-z’)が‘SIGTSTP’シグナルを送信する。CURRENT-GROUPが非‘nil’なら、こ の関数をサブプロセスとの対話にEmacsが使用する端末上で‘C-z’がタイプ されたと考えることができる。 -- Function: continue-process &optional process current-group この関数はプロセスPROCESSの実行を再開する。それがプログラムを実行中 の実際のサブプロセスなら、そのサブプロセスにシグナル‘SIGCONT’を送信 する。この関数はPROCESSが以前に停止されたとみなす。PROCESSがネット ワーク接続、シリアル接続、pipe接続を表す場合には、この関数はその接 続から到達するデータのハンドリングを再開する。シリアル接続ではプロ セス停止中に到達したデータは失われるかもしれない。 -- Command: signal-process process signal この関数はプロセスPROCESSにシグナルを送信する。引数SIGNALはどのシグ ナルを送信するかを指定する。これは整数、または名前がシグナルである ようなシンボルであること。 PROCESS引数にはシステムプロセスID (整数)を指定できる。これにより Emacsの子プロセス以外のプロセスにシグナルを送信できる。*note System Processes::を参照のこと。 36.9 プロセスからの出力の受信 ============================= 非同期サブプロセスが自身の標準出力に書き込んだ出力は“フィルター関数 (filter function)”と呼ばれる関数に渡されます。デフォルトのフィルター関数 は単に出力をバッファーに挿入します。このバッファーをプロセスに関連付けら れたバッファーと呼びます(*note Process Buffers::を参照)。プロセスがバッ ファーをもたなければデフォルトフィルターは出力を破棄します。 サブプロセスが標準エラーストリームに書き込む場合には、デフォルトでは エラー出力もフィルター関数に渡されて処理されます。Emacsがサブプロセスと の対話に疑似端末(pty: pseudo-TTY)を使用する場合には、疑似端末は出力チャ ンネルを1つしかもてないので、サブプロセスの標準出力ストリームと標準エラ ーストリームを区別するのは不可能です。それらのストリームの出力を区別して 保ちたい場合は、たとえば ‘start-process-shell-command’や類似コマンドを通 じて適当なshellコマンドを使用することにより、いずれか1つをファイルにリダ イレクトする必要があります。 エラー出力先を標準出力から区別するためには、かわりに非‘nil’の ‘:stderr’パラメーターで‘make-process’ (*note make-process: Asynchronous Processes.を参照)を呼び出すことができます。この場合には、サブプロセスと の対話にEmacsはpipeを使用することになります。 サブプロセス終了時にEmacsは保留中の出力を読み取って、その後そのサブプ ロセスからの出力の読み取りを停止します。したがってそのサブプロセスに生き た子プロセスがあり、まだ出力を生成するような場合には、Emacsはその出力を 受け取らないでしょう。 サブプロセスからの出力はEmacsが待機している間の端末入力読み取り時(関 数‘waiting-for-user-input-p’、*note Waiting::の‘sit-for’と‘sleep-for’、 および*note Accepting Output::の‘accept-process-output’を参照)のみ到着可 能です。これは並列プログラミングで普遍的に悩みの種であるタイミングエラー の問題を最小化します。たとえば安全にプロセスを作成して、その後でのみプロ セスのバッファーやフィルター関数を指定できます。その間にあるコードが待機 するプリミティブを何も呼び出さなければ完了するまで到達可能な出力はありま せん。 -- Variable: process-adaptive-read-buffering いくつかのシステムではEmacsがサブプロセスの出力を読み取る際に出力デ ータを非常に小さいブロックで読み取るために、結果として潜在的に非常 に貧弱なパフォーマンスとなることがる。この挙動は変数 ‘process-adaptive-read-buffering’を非‘nil’値(デフォルト)にセットし て拡張することにより改善し得る。これにより、そのようなプロセスから の読み取りを自動的に遅延して、Emacsが読み取りを試みる前に出力がより 多く生成されるようになる。 36.9.1 プロセスのバッファー --------------------------- プロセスは“関連付けられたバッファー(associated buffer)”をもつことができ ます(通常はもつ)。これは普通のEmacsバッファーであり、2つの目的のために使 用されます。1つはプロセスからの出力の格納、もう1つはプロセスをkillする時 期を判断するためです。通常の習慣では任意の与えられたバッファーにたいして 関連付けられるプロセスは1つだけなので、処理対象のプロセスを識別するため にそのバッファーを使用することもできます。プロセス使用の多くはプロセスに 送信する入力を編集するためにもこのバッファーを使用しますが、これはEmacs Lispの組み込みではありません。 デフォルトでは、プロセスの出力は関連付けられたバッファーに挿入されま す(カスタムフィルター関数の定義により変更可能。*note Filter Functions::を 参照)。出力を挿入する位置は‘process-mark’により決定されます。これは正に 挿入されたテキストの終端にポイントを更新します。通常(常にではない)は ‘process-mark’はバッファーの終端になります。 プロセスに関連付けられたバッファーをkillすることによりプロセスも killされます。そのプロセスの‘process-query-on-exit-flag’が非‘nil’なら、 Emacsはまず確認を求めます(*note Query Before Exit::を参照)。この確認は関 数‘process-kill-buffer-query-function’により行われて、これは ‘kill-buffer-query-functions’から実行されます(*note Killing Buffers::を 参照)。 -- Function: process-buffer process この関数は指定されたPROCESSの関連付けられたバッファーをリターンする 。 (process-buffer (get-process "shell")) ⇒ # -- Function: process-mark process この関数はPROCESSにたいするプロセスマーカーをリターンする。これはプ ロセスからの出力をどこに挿入するかを示すマーカー。 PROCESSがバッファーをもたなければ、‘process-mark’は存在しない場所を 指すマーカーをリターンする。 デフォルトのフィルター関数はプロセス出力の挿入場所の決定にこのマー カーを使用して、挿入したテキストの後にポイントを更新する。連続する バッチ出力が連続して挿入されるのはこれが理由。 カスタムフィルター関数はこのマーカーを通常は同じ方式で使用すること 。‘process-mark’を使用するフィルター関数の例は*note Process Filter Example::を参照のこと。 ユーザーにプロセスバッファー内でプロセスに送信するための入力を期待 する際には、プロセスマーカーは以前の出力から新たな入力を区別する。 -- Function: set-process-buffer process buffer この関数はPROCESSに関連付けられたバッファーにBUFFERをセットする。 BUFFERが‘nil’ならプロセスはバッファーに関連付けられない。 -- Function: get-buffer-process buffer-or-name この関数はBUFFER-OR-NAMEで指定されるバッファーに関連付けられた、削 除されていないプロセスをリターンする。そのバッファーに複数のプロセ スが関連付けられている場合には、この関数はいずれか1つ(現在のところ もっとも最近作成されたプロセスだがこれを期待しないこと)を選択する。 プロセスの削除(‘delete-process’を参照)により、そのプロセスはこの関 数がリターンするプロセスとしては不適格となる。 同一のバッファーに複数のプロセスを関連付けるのは、通常は悪いアイデ アである。 (get-buffer-process "*shell*") ⇒ # プロセスのバッファーをkillすることにより、‘SIGHUP’シグナルでサブプ ロセスをkillしてプロセスを削除する(*note Signals to Processes::を参 照)。 プロセスのバッファーがウィンドウに表示されている場合には、プロセスが 出力をスクリーンのサイズに適応させるのと同様に、Lispプログラムでウィンド ウのサイズにプロセス出力を適応させるようにプロセスに指示したいと思うでし ょう。以下の関数によりプロセスにたいしてこの種の情報をやり取りできます。 しかしすべてのシステムが基礎となる機能をサポートする訳ではないので、コマ ンドライン引数や環境変数を通じたフォールバックを提供するのが最良です。 -- Function: set-process-window-size process height width PROCESSにたいして、その論理ウィンドウサイズが文字単位でWIDTHと HEIGHTのサイズであることを告げる。関数がこの情報をプロセスとやり取 りすることに成功したら‘t’、それ以外は‘nil’をリターンする。 プロセスに関連付けられたバッファーを表示するウィンドウがサイズを変更 された際には、影響を受けるプロセスはその変更にたいして通知される必要があ ります。デフォルトではウィンドウ構成(window configuration)が変更されると 、ウィンドウにバッファーが表示されている各プロセスにかわり、プロセスのバ ッファーを表示するすべてのウィンドウのうち最小のサイズのウィンドウを引数 として、Emacsが自動的に‘set-process-window-size’を呼び出します。これはバ ッファーが少なくとも1つのウィンドウに表示されているプセスそれぞれにたい して、変数‘window-adjust-process-window-size-function’の値である関数を呼 び出すように指定する‘window-configuration-change-hook’ (*note Window Hooks::を参照)を通じて機能します。この変数をセットすることにより、この振 る舞いをカスマイズできます。 -- User Option: window-adjust-process-window-size-function この変数の値はプロセスとプロセスのバッファーを表示するウィンドウの リストという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’プロパティ(*note Process Information::を参照)をもつ場合には、その値は ‘window-adjust-process-window-size-function’のグローバル値とバッファーロ ール値をオーバーライドします。 36.9.2 プロセスのフィルター関数 ------------------------------- プロセスの“フィルター関数(filter function)”は、関連付けられたプロセスか らの標準出力を受信します。そのプロセスの_すべて_の出力はそのフィルターに 渡されます。デフォルトのフィルターは単にプロセスバッファーに直接出力しま す。 デフォルトではプロセス作成時にエラーストリームの出力先が標準出力と分 離されていなければ(*note Output from Processes::を参照)、プロセスからの エラー出力があればそれはフィルター関数にも渡されます。 サブプロセスからの出力はEmacsが何かを待機している間だけ到着するので、 フィルター関数はそのようなときだけ呼び出し可能です。Emacsは端末入力読み 取り時(関数‘waiting-for-user-input-p’、*note Waiting::の‘sit-for’と ‘sleep-for’、および*note Accepting Output::の‘accept-process-output’を参 照)に待機します。 フィルター関数は関連付けられたプロセス、およびそのプロセスから正に受 信した出力である文字列という2つの引数を受け取らなければなりません。関数 はその後に出力にたいして何であれ自由に行うことができます。 quitは通常はフィルター関数内では抑制されます。さもないとコマンドレベ ルでの‘C-g’のタイプ、またはユーザーコマンドのquitは予測できません。フィ ルター関数内部でのquitを許可したければ‘inhibit-quit’を‘nil’にバインドし てください。ほとんどの場合において、これを行う正しい方法はマクロ ‘with-local-quit’です。*note Quitting::を参照してください。 フィルター関数の実行中にエラーが発生すると、フィルター開始時に実行中 だったプログラムが何であれ実行を停止しないように自動的にcatchされます。 しかし‘debug-on-error’が非‘nil’ならエラーはcatchされません。これにより Lispデバッガーを使用したフィルター関数のデバッグが可能になります。*note Debugger::を参照してください。 多くのフィルター関数は時折(または常に)、デフォルトフィルターの動作を 真似てプロセスのバッファーにその出力を挿入します。そのようなフィルター関 数は確実にカレントバッファーの保存と、(もし異なるなら)出力を挿入する前に 正しいバッファーを選択して、その後に元のバッファーをリストアする必要があ ります。またそのバッファーがまだ生きているか、プロセスマーカーを更新して いるか、そしていくつかのケースにおいてはポイントの値を更新しているかもチ ェックするべきです。以下はこれらを行う方法です: (defun ordinary-insertion-filter (proc string) (when (buffer-live-p (process-buffer proc)) (with-current-buffer (process-buffer proc) (let ((moving (= (point) (process-mark proc)))) (save-excursion ;; テキストを挿入してプロセスマーカーを進める (goto-char (process-mark proc)) (insert string) (set-marker (process-mark proc) (point))) (if moving (goto-char (process-mark proc))))))) 新たなテキスト到着時にフィルターが強制的にプロセスバッファーを可視に するために‘with-current-buffer’構成の直前に以下のような行を挿入できます: (display-buffer (process-buffer proc)) 以前の位置に関わらず新たな出力の終端にポイントを強制するには、例から 変数‘moving’を削除して無条件で‘goto-char’を呼び出してください。 フィルター関数の実行中には、Emacsが自動的にマッチデータの保存とリスト アを行うことに注意してください。*note Match Data::を参照してください。 フィルターへの出力は任意のサイズのchunkで到着する可能性があります。同 じ出力を連続して2回生成するプログラムは一度に200文字を1回のバッチで送信 して、次に40文字を5回のバッチで送信するかもしれません。フィルターが特定 のテキスト文字列をサブプロセスの出力から探す場合には、それらの文字列が 2回以上のバッチ出力を横断するケースに留意して処理してください。これを行 うには受信したテキストを一時的なバッファーに挿入してから検索するのが1つ の方法です。 -- Function: set-process-filter process filter この関数はPROCESSにフィルター関数FILTERを与える。FILTERが‘nil’なら 、そのプロセスにたいしてプロセスバッファーにプロセス出力を挿入する デフォルトフィルターを与える。 -- Function: process-filter process この関数はPROCESSのフィルター関数をリターンする。 そのプロセスの出力を複数のフィルターに渡す必要がある場合には、既存の フィルターに新たなフィルターを組み合わせるために‘add-function’を使用でき る。*note Advising Functions::を参照のこと。 以下はフィルター関数の使用例: (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 ") 36.9.3 プロセス出力のデコード ----------------------------- Emacsが直接マルチバイトバッファーにプロセス出力を書き込む際には、プロセ ス出力のコーディングシステムに応じて出力をデコードします。コーディングシ ステムが‘raw-text’か‘no-conversion’ならEmacsは‘string-to-multibyte’を使 用してユニバイト出力をマルチバイトに変換して、その結果のマルチバイトテキ ストを挿入します。 どのコーディングシステムを使用するかは‘set-process-coding-system’を使 用して指定できます(*note Process Information::を参照)。それ以外では ‘coding-system-for-read’が非‘nil’ならそのコーディングシステム、‘nil’なら デフォルトのメカニズムが使用されます(*note Default Coding Systems::を参 照)。プロセスのテキスト出力にnullバイトが含まれる場合には、Emacsはそれに たいしてデフォルトでは‘no-conversion’を使用します。この挙動を制御する方 法については*note inhibit-null-byte-detection: Lisp and Coding Systems.を 参照してください。 *警告:* データからコーディングシステムを判断する‘undecided’のようなコ ーディングシステムは、非同期サブプロセスの出力にたいして完全な信頼性をも って機能しません。これはEmacsが到着に応じて非同期サブプロセスの出力をバ ッチで処理する必要があるからです。Emacsは1つのバッチが到着するたびに正し いコーディングシステムを検出しなければならずこれは常に機能するわけではあ りません。したがって可能であれば文字コード変換とEOL変換の両方を決定する コーディングシステムつまり‘latin-1-unix’、‘undecided’、‘latin-1’のような コーディングシステムを指定してください。 Emacsがプロセスフィルター関数を呼び出す際には、そのプロセスのフィルタ ーのコーディングシステムに応じてEmacsはプロセス出力をマルチバイト文字列 、またはユニバイト文字列で提供します。Emacsはプロセス出力のコーディング システムに応じて出力をデコードします。これは‘binary’や‘raw-text’のような コーディングシステムを除いて、通常はマルチバイト文字列を生成します。 36.9.4 プロセスからの出力を受け入れる ------------------------------------- 非同期サブプロセスからの出力は、通常はEmacsが時間の経過や端末入力のよう な、ある種の外部イベントを待機する間だけ到着します。特定のポイントで出力 の到着を明示的に許可したり、あるいはプロセスからの出力が到着するまで待機 することでさえ、Lispプログラムでは有用な場合が時折あります。 -- Function: accept-process-output &optional process seconds millisec just-this-one この関数はプロセスからの保留中の出力をEmacsが読み取ることを許す。こ の出力はプロセスのフィルター関数により与えられる。PROCESSが非 ‘nil’なら、この関数はPROCESSから何らかの出力を受け取るまでリターン しない。 引数SECONDSとMILLISECによりタイムアウトの長さを指定できる。前者は秒 単位、後者はミリ秒単位でタイムアウトを指定する。この2つの秒数は、互 いに足し合わせることによりタイムアウトを指定して、その秒数経過後は サブプロセスの出力が存在しなくてもリターンする。 SECONDSに浮動小数点数を指定することにより秒を少数点で指定できるので 引数MILLISECは時代遅れ(であり使用するべきではない)。SECONDSが0なら この関数は保留中の出力が何であれ受け取り待機しない。 PROCESSがプロセスで引数JUST-THIS-ONEが非‘nil’ならプロセスからの出力 だけが処理され、そのプロセスからの出力を受信するかタイムアウトとな るまで他のプロセスの出力は停止される。JUST-THIS-ONEが整数ならタイマ ーの実行も抑制される。この機能は一般的には推奨されないが、音声合成 のような特定のアプリケーションにとっては必要かもしれない。 関数‘accept-process-output’はPROCESS、PROCESSが‘nil’なら任意のプロ セスから出力を取得したら非‘nil’をリターンする。出力の到着前にタイム アウトが到来したら‘nil’をリターンする。 36.10 センチネル: プロセス状態の変更の検知 ========================================== “プロセスセンチネル(process sentinel: プロセス番兵)”とは、(Emacsにより送 信されたか、そのプロセス自身の動作が原因で送信された)プロセスを終了、停 止、継続するシグナルを含む、何らかの理由により関連付けられたプロセスの状 態が変化した際には常に呼び出される関数のことです。プロセスがexitする際に もプロセスセンチネルが呼び出されます。センチネルはイベントが発生したプロ セスとイベントのタイプを記述する文字列という2つの引数を受け取ります。 プロセスにたいして何もセンチネル関数が指定されていなければ、プロセス のバッファーにプロセス名とイベントを記述する文字列とともにメッセージを挿 入するデフォルトのセンチネル関数を使用します。 イベントを記述する文字列は以下のいずれかのような外見をもちます: • ‘"finished\n"’. • ‘"deleted\n"’. • ‘"exited abnormally with code EXITCODE (core dumped)\n"’. “core dumped”の部分はオプションであり、プロセスがコアをダンプした場 合のみ出現する。 • ‘"failed with code FAIL-CODE\n"’. • ‘"SIGNAL-DESCRIPTION (core dumped)\n"’. SIGNAL-DESCRIPTIONは‘SIGKILL’にたいする‘"killed"’のようなシステム依 存の説明テキスト。“core dumped”の部分はオプションであり、プロセスが コアをダンプした場合のみ出現する。 • ‘"open from HOST-NAME\n"’. • ‘"open\n"’. • ‘"connection broken by remote peer\n"’. センチネルはEmacsが(端末入力や時間経過、またはプロセス出力を)待機して いる間だけ実行されます。これは他のLispプログラムの途中のランダムな箇所で 実行されるセンチネルが原因となるタイミングエラーを無視します。プログラム はセンチネルが実行されるように、‘sit-for’や‘sleep-for’(*note Waiting::を 参照)、または‘accept-process-output’(*note Accepting 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’です。*note Quitting::を参照してください。 センチネルの実行中にエラーが発生した場合には、センチネル開始時に実行 中だったプログラムが何であれ実行を停止しないように自動的にcatchされます 。しかし‘debug-on-error’が非‘nil’ならエラーはcatchされません。これにより Lispデバッガーを使用したセンチネルのデバッグが可能になります。*note Debugger::を参照してください。 センチネルの実行中にはセンチネルが再帰的に実行されないように、プロセ スセンチネルは一時的に‘nil’にセットされます。この理由によりセンチネルが 新たにセンチネルを指定することはできません。 センチネル実行中にはEmacsが自動的にマッチデータの保存とリストアを行う ことに注意してください。*note Match Data::を参照してください。 -- Function: set-process-sentinel process sentinel この関数は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: # had the event 'killed' ⇒ # -- Function: process-sentinel process この関数はPROCESSのセンチネルをリターンする。 あるプロセス状態の変化を複数のセンチネルに渡す必要がある場合には、既 存のセンチネルと新たなセンチネルを組み合わせるために‘add-function’を使用 できます。*note Advising Functions::を参照してください。 -- Function: waiting-for-user-input-p この関数はセンチネルやフィルター関数の実行中に、もしEmacsがセンチネ ルやフィルター関数呼び出し時にユーザーのキーボード入力を待機してい たら非‘nil’、そうでなければ‘nil’をリターンする。 36.11 exit前の問い合わせ ======================== Emacsがexitする際にはすべてのサブプロセスを終了します。プログラムを実行 しているサブプロセスには‘SIGHUP’を送信して、接続は単にcloseされます。そ れらのサブプロセスはさまざまな処理を行っているかもしれないので、Emacsは 通常ユーザーにたいしてそれらを終了しても大丈夫かどうか確認を求めます。各 プロセスはquery(問い合わせ)のためのフラグをもち、これが非‘nil’なら Emacsはプロセスをkillしてexitする前に確認を行うべきであることを示します 。queryフラグにたいするデフォルトは‘t’で、これは問い合わせを_行う_ことを 意味しています。 -- Function: process-query-on-exit-flag process これはPROCESSのqueryフラグをリターンする。 -- Function: set-process-query-on-exit-flag process flag この関数はPROCESSのqueryフラグをFLAGにセットする。これはFLAGをリタ ーンする。 以下はshellプロセス上で問い合わせを回避するために ‘set-process-query-on-exit-flag’を使用する例: (set-process-query-on-exit-flag (get-process "shell") nil) ⇒ nil 36.12 別のプセスへのアクセス ============================ カレントEmacsセッションのサブプロセスにたいするアクセスと操作に加えて、 同一マシン上で実行中の他のプロセスにたいしてEmacs Lispプログラムがアクセ スすることもできます。Emacsのサブプロセスと区別するために、わたしたちは これらを“システムプロセス(system processes)”と呼んでいます。 Emacsはシステムプロセスへのアクセス用のプリミティブをいくつか提供しま す。これらのプリミティブはすべてのプラットフォームではサポートされません 。これらのプリミティブはサポートされないシステムでは‘nil’をリターンしま す。 -- Function: list-system-processes この関数はそのシステム上で実行中のすべてのプロセスのリストをリター ンする。各プロセスはPIDというOSから割り当てられた数値によるプロセス IDにより識別され、同一時に同一マシン上で実行中の他のプロセスと区別 される。 -- Function: process-attributes pid この関数はプロセスID PIDで指定されるプロセスにたいする属性のalistを リターンする。このalist内の各属性は‘(KEY . VALUE)’という形式であり KEYは属性、VALUEはその属性の値である。この関数がリターン可能なさま ざまな属性にたいするKEYを以下にリストした。これらすべての属性をすべ てのプラットフォームがサポートする訳ではない。ある属性がサポートさ れていなければ、その連想値はリターンされるalist内に出現しない。数値 であるような値は整数か浮動小数点数のいずれかが可能であり、それは値 の大小に依存する。 ‘euid’ そのプロセスを呼び出したユーザーの実効ユーザーID(effective user ID)。対応するVALUEは数値。プロセスがカレントEmacsセッショ ンを実行したユーザーと同じなら値は‘user-uid’がリターンする値と 等しくなる(*note User Identification::を参照)。 ‘user’ そのプロセスの実効ユーザーIDに対応するユーザー名であるような文 字列。 ‘egid’ 実行ユーザーIDのグループIDであるような数値。 ‘group’ 実効ユーザーのグループIDに対応するグループ名であるような文字列 。 ‘comm’ そのプロセス内で実効したコマンドの名前。これは通常は先行するデ ィレクトリーを除いた実行可能ファイル名を指定する文字列。しかし いくつかの特別なシステムプロセスは、実行可能ファイルやプログラ ムに対応しない文字列を報告する可能性がある。 ‘state’ そのプロセスの状態コード。これはそのプロセスのスケジューリング 状態をエンコードする短い文字列。以下は頻繁に目にするコードのリ スト: ‘"D"’ 割り込み不可のsleep(通常はI/Oによる) ‘"R"’ 実行中 ‘"S"’ 割り込み可能なsleep(何らかのイベント待ち) ‘"T"’ ジョブ制御シグナルにより停止された ‘"Z"’ zombie: 終了したが親プロセスに回収されていないプロセス 可能な状態の完全なリストは‘ps’コマンドのman pageを参照のこと。 ‘ppid’ 親プロセスのプロセスIDであるような数値。 ‘pgrp’ そのプロセスのプロセスグループIDであるような数値。 ‘sess’ そのプロセスのセッションID。これはそのプロセスの“セッションリ ーダー(session leader)”のプロセスIDであるような数値。 ‘ttname’ そのプロセスの制御端末の名前であるような文字列。これはUnixや GNUシステムでは通常は‘/dev/pts65’のような対応する端末デバイス のファイル名。 ‘tpgid’ そのプロセスの端末を使用するフォアグラウンドプロセスグループの プロセスグループIDであるような数値。 ‘minflt’ そのプロセス開始以降に発生したマイナーなページフォルト数(マイ ナーなページフォルトとはディスクからの読み込みを発生させないペ ージフォルト)。 ‘majflt’ そのプロセス開始以降に発生したメジャーなページフォルト数(メジ ャーなページフォルトとはディスクからの読み込みを要し、それ故に マイナーページフォルトより高価なページフォルト)。 ‘cminflt’ ‘cmajflt’ ‘minflt’や‘majflt’と似ているが与えられたプロセスのすべての子プ ロセスのページフォルト数を含む。 ‘utime’ アプリケーションのコード実行にたいしてユーザーコンテキスト内で プロセスに消費された時間。対応するVALUEは ‘(HIGH LOW MICROSEC PICOSEC)’というフォーマットであり、これは 関数‘current-time’が使用するフォーマットと同じ(*note current-time: Time of Day.)と*note File Attributes::の ‘file-attributes’を参照)。 ‘stime’ システムコールの処理にたいしてシステム(kernel)コンテキスト内で プロセスに消費された時間。対応するVALUEは‘utime’と同じフォーマ ット。 ‘time’ ‘utime’と‘stime’の和。対応するVALUEは‘utime’と同じフォーマット 。 ‘cutime’ ‘cstime’ ‘ctime’ ‘utime’や‘stime’と同様だが与えられたプロセスのすべての子プロセ スの時間が含まれる点が異なる。 ‘pri’ そのプロセスの数値的な優先度。 ‘nice’ そのプロセスの“nice値(nice value)”であるような数値(小さい nice値のプロセスがより優先的にスケジュールされる)。 ‘thcount’ そのプロセス内のスレッド数。 ‘start’ ‘file-attributes’や‘current-time’が使用するのと同じフォーマッ ト‘(HIGH LOW MICROSEC PICOSEC)’による、そのプロセスが開始され た時刻。 ‘etime’ ‘(HIGH LOW MICROSEC PICOSEC)’というフォーマットによる、そのプ ロセスが開始されてから経過した時間。 ‘vsize’ そのプロセスの仮想メモリーのKB単位でのサイズ。 ‘rss’ そのプロセスがマシンの物理メモリー内で占める“常駐セット (resident set)”のKB単位でのサイズ。 ‘pcpu’ プロセス開始以降に使用されたCPU時間のパーセンテージ。対応する VALUEは0から100の間の浮動小数点数。 ‘pmem’ マシンにインストールされた物理メモリー合計のうち、そのプロセス の常駐セットのパーセンテージ。値は0から100の間の浮動小数点数。 ‘args’ そのプロセスが呼び出されたときのコマンドライン。これは個々のコ マンドライン引数がブランクで区切られた文字列。引数に埋め込まれ た空白文字はシステムに応じて適切にクォートされる。GNUやUnixで はバックスラッシュ文字によるエスケープ、Windowsではダブルクォ ート文字で囲まれる。つまりこのコマンドライン文字列は ‘shell-command’のようなプリミティブにより直接使用できる。 36.13 トランザクションキュー ============================ トランザクションを用いてサブプロセスと対話するために“トランザクションキ ュー(transaction queue)”を使用できます。まず‘tq-create’を使用して指定し たプロセスと対話するためのトランザクションキューを作成します。それからト ランザクションを送信するために‘tq-enqueue’を呼び出すことができます。 -- Function: tq-create process この関数はPROCESSと対話するトランザクションキューを作成してリターン する。引数PROCESSはバイトストリームを送受信する能力をもつサブプロセ スであること。これは子プロセス、または(おそらく別のマシン上の)サー バーへのTCP接続かもしれない。 -- Function: tq-enqueue queue question regexp closure fn &optional delay-question この関数はキューQUEUEにトランザクションを送信する。キューの指定は対 話するサブプロセスを指定する効果をもつ。 引数QUESTIONはトランザクションを開始するために発信するメッセージ。 引数FNは、それにたいする応答が返信された際に呼び出す関数。これは CLOSUREと受信した応答という2つの引数で呼び出される。 引数REGEXPは応答全体の終端にマッチして、それより前にはマッチしない 正規表現であること。これは‘tq-enqueue’が応答の終わりを決定する方法 である。 引数DELAY-QUESTIONが非‘nil’なら、そのプロセスが以前に発信したすべて のメッセージへの返信が完了するまでメッセージの送信を遅延する。これ によりいくつかのプロセスにたいして、より信頼性のある結果が生成され る。 -- Function: tq-close queue 保留中のすべてのトランザクションの完了を待機して、トランザクション キューQUEUEをシャットダウンして、それから接続または子プロセスを終了 する。 トランザクションキューはフィルター関数により実装されています。*note Filter Functions::を参照してください。 36.14 ネットワーク接続 ====================== Emacs Lispプログラムは同一マシンまたは他のマシン上の別プロセスにたいして ストリーム(TCP)やデータグラム(UDP)のネットワーク接続(*note Datagrams::を 参照)をオープンできます。ネットワーク接続はLispによりサブプロセスと同様 に処理されて、プロセスオブジェクトとして表されます。しかし対話を行うその プロセスはEmacsの子プロセスではなく、プロセスIDをもたず、それをkillした りシグナルを送信することはできません。行うことができるのはデータの送信と 受信だけです。‘delete-process’は接続をクローズしますが、他方の端のプログ ラムをkillしません。そのプログラムは接続のクローズについて何を行うか決定 しなければなりません。 ネットワークサーバーを作成することによりLispプログラムは接続を listenできます。ネットワークサーバーもある種のプロセスオブジェクトとして 表されますが、ネットワーク接続とは異なりネットワークサーバーがデータ自体 を転送することは決してありません。接続リクエストを受信したときは、それに たいして作成した接続を表す新たなネットワーク接続を作成します(そのネット ワーク接続はサーバーからプロセスplistを含む特定の情報を継承する)。その後 でネットワークサーバーは更なる接続リクエストのlistenに戻ります。 ネットワーク接続とサーバーは、キーワード/引数のペアーで構成される引数 リストで‘make-network-process’を呼び出すことにより作成されます。たとえば ‘:server t’はサーバープロセス、‘:type 'datagram’はデータグラム接続を作成 します。詳細は*note Low-Level Network::を参照してください。以下で説明す る‘open-network-stream’を使用することもできます。 異なるプロセスのタイプを区別するために‘process-type’関数はネットワー ク接続とサーバーには‘network’、シリアルポート接続は‘serial’、pipe接続に は‘pipe’、実際のサブプロセスには‘real’をリターンします。 ネットワーク接続にたいして‘process-status’関数は‘open’、‘closed’、 ‘connect’、‘stop’、または‘failed’をリターンします。ネットワークサーバー にたいしては状態は常に‘listen’になります。実際のサブプロセスにたいしては ‘stop’以外の値はリターンされません。*note Process Information::を参照し てください。 ‘stop-process’と‘continue-process’を呼び出すことにより、ネットワーク プロセスの処理の停止と再開が可能です。サーバープロセスにたいする停止は新 たな接続の受け付けないことを意味します(サーバー再開時は5つまでの接続リク エストがキューされる。これがOSによる制限でなければこの制限は増やすことが できる。*note Network Processes::の‘make-network-process’の‘:server’を参 照)。ネットワークストリーム接続にたいしては、停止は入力の処理を行わない ことを意味します(到着するすべての入力は接続の再開まで待つ)。データグラム 接続にたいしては、いくらかのパケットはキューされますが入力は失われるかも しれません。ネットワーク接続またはサーバーが停止しているかどうかを判断す るために、関数‘process-command’を使用できます。これが非‘nil’なら停止して います。 ビルトインや外部のサポートを使用することによりEmacsは暗号化されたネッ トワーク接続を作成できます。ビルトインのサポートはGnuTLSライブラリー (TLS: Transport Layer Security)を使用します。the GnuTLS project page (http://www.gnu.org/software/gnutls/)を参照してください。GnuTLSサポート つきでEmacsをコンパイルした場合には関数‘gnutls-available-p’が定義されて 非‘nil’をリターンします。詳細は*note Overview: (emacs-gnutls)Top.を参照 してください。外部のサポートの場合は‘starttls.el’ライブラリーを使用しま す。これはシステム上に‘gnutls-cli’のようなヘルパーユーティリティーのイン ストールを必要とします。‘open-network-stream’関数は利用可能なサポートを 何であれ使用して暗号化接続作成の詳細を透過的に処理できます。 -- Function: open-network-stream name buffer host service &rest parameters この関数はオプションで暗号つきでTCP接続をオープンして、その接続を表 すプロセスオブジェクトをリターンする。 NAME引数はプロセスオブジェクトの名前を指定する。これは必要に応じて 一意になるよう変更される。 BUFFER引数はその接続に関連付けるバッファー。その接続からの出力は出 力を処理する独自のフィルター関数を指定していない場合には、BUFFERが ‘nil’ならその接続はバッファーに関連付けられない。 引数HOSTとSERVICEはどこに接続するかを指定する。HOSTはホスト名(文字 列)、SERVICEは定義済みのネットワークサービス名(文字列)、またはポー ト番号(数字)。 残りの引数PARAMETERSは主に暗号化された接続に関連するキーワード/引数 のペアー: ‘:nowait BOOLEAN’ 非‘nil’なら非同期接続を試みる。 ‘:type TYPE’ 接続のタイプ。オプションは以下のとおり: ‘plain’ 通常の暗号化されていない接続。 ‘tls’ ‘ssl’ TLS (Transport Layer Security)接続。 ‘nil’ ‘network’ plain接続を開始してパラメーター‘:success’と ‘:capability-command’が与えられたら、STARTTLSを通じて暗号 化接続への更新を試みる。これが失敗したら暗号化されていな い接続のまま留まる。 ‘starttls’ ‘nil’と同様だがSTARTTLSが失敗したらその接続を切断する。 ‘shell’ shell接続。 ‘:always-query-capabilities BOOLEAN’ 非‘nil’なら、たとえ‘plain’な接続を行っているときでも常にサーバ ーの能力を問い合わせる。 ‘:capability-command CAPABILITY-COMMAND’ ホストの能力を問い合わせるためのコマンド文字列。 ‘:end-of-command REGEXP’ ‘:end-of-capability REGEXP’ コマンドの終端、またはコマンドCAPABILITY-COMMANDの終端にマッチ する正規表現。前者は後者のデフォルト。 ‘:starttls-function FUNCTION’ 単一の引数(CAPABILITY-COMMANDにたいする応答)をとり‘nil’、また はサポートされていればSTARTTLSをアクティブにするコマンドをリタ ーンする関数。 ‘:success REGEXP’ 成功したSTARTTLSネゴシェーションにマッチする正規表現。 ‘:use-starttls-if-possible BOOLEAN’ 非‘nil’なら、たとえEmacsがビルトインのTLSサポートをもっていな くても、日和見的(opportunistic)にSTARTTLSアップグレードを行う 。 ‘:warn-unless-encrypted BOOLEAN’ 非‘nil’、かつ‘:return-value’も非‘nil’なら、接続が暗号化されて いない場合にはEmacsは警告するだろう。これはほとんどのユーザー がネットワークトラフィックが暗号化されているこを期待するであろ うIMAPやその類のプロトコルにたいして有用。 ‘:client-certificate LIST-OR-T’ 証明書(certificate)のキーと、証明書のファイル自身を命名する ‘(KEY-FILE CERT-FILE)’という形式のリスト、またはこの情報にたい して‘auth-source’を尋ねることを意味する‘t’のいずれか(*note Overview: (auth)Top.を参照)。TLSやSTARTTLSにたいしてのみ使用さ れる。 ‘:return-list CONS-OR-NIL’ この関数のリターン値。省略または‘nil’ならプロセスオブジェクト をリターンする。それ以外なら‘(PROCESS-OBJECT . PLIST)’という形 式のコンスセルをリターンする。ここでPLISTは以下のキーワード: ‘:greeting STRING-OR-NIL’ 非‘nil’ならホストからリターンされたgreeting(挨拶)文字列。 ‘:capabilities STRING-OR-NIL’ 非‘nil’ならホストの能力(capability)文字列。 ‘:type SYMBOL’ 接続タイプであり、‘plain’か‘tls’のいずれか。 36.15 ネットワークサーバー ========================== ‘:server t’で‘make-network-process’を呼び出すことによりサーバーが作成さ れます(*note Network Processes::を参照)。そのサーバーはクライアントから の接続リクエストをlistenするでしょう。クライアントの接続リクエストを accept(受け入れる)する際は以下のようなパラメーターで、それ自体がプロセス オブジェクトであるようなネットワーク接続を作成します。 • その接続のプロセス名はサーバープロセスのNAMEとクライアント識別文字 列を結合して構築される。IPv4接続にたいするクライアント識別文字列は アドレスとポート番号を表す‘’のような文字列。それ以外なら ‘’のようにカッコで囲まれた一意な数字。この数字はそのEmacsセッ ション内のそれぞれの接続にたいして一意。 • サーバーが非デフォルトのフィルターをもつ場合には、その接続プロセス は別個にプロセスバッファーを取得しない。それ以外ならEmacsはその目的 のために新たにバッファーを作成する。サーバーのバッファー名かプロセ ス名にクライアント識別文字列に結合したものがバッファー名になる。 サーバーのプロセスバッファーの値が直接使用されることは決してないが 、log関数は接続のログを記録するためにそれを取得して、そこにテキスト を挿入して使用することができる。 • 通信タイプ(communication type)、プロセスフィルター、およびセンチネ ルはそれぞれサーバーのものから継承される。サーバーが直接フィルター とセンチネルを使用することは決してない。それらの唯一の目的はサーバ ーへの接続を初期化することである。 • その接続のプロセスコンタクト情報は、クライアントのアドレス情報(通常 はIPアドレスとポート番号)に応じてセットされる。この情報は ‘process-contact’のキーワード‘:host’、‘:service’、‘:remote’に関連付 けられる。 • その接続のローカルアドレスは使用するポート番号に応じてセットアップ される。 • クライアントプロセスのplistはサーバーのplistからインストールされる 。 36.16 データグラム ================== “データグラム(datagram)”接続は、データストリームではなく個別のパッケージ で対話します。‘process-send’を呼び出すたびに1つのデータグラムパケット (*note Input to Processes::を参照)が送信されて、受信されたデータグラムご とに1回フィルター関数が呼び出されます。 データグラム接続は毎回同じリモートピア(remote peer)と対話する必要はあ りません。データグラム接続はデータグラムの送信先を指定する“リモートピア アドレス(remote peer address)”をもちます。フィルター関数にたいして受信さ れたデータグラムが渡されるたびに、そのデータグラムの送信元アドレスがピア アドレスにセットされます。このようにもしフィルター関数がデータグラムを送 信したら、それは元の場所へ戻ることになります。‘:remote’キーワードを使用 してデータグラム接続を作成する際にはリモートピアアドレスを指定できます。 ‘set-process-datagram-address’を呼び出すことにより後からそれを変更できま す。 -- Function: process-datagram-address process PROCESSがデータグラム接続かサーバーなら、この関数はそれのリモートピ アアドレスをリターンする。 -- Function: set-process-datagram-address process address PROCESSがデータグラム接続かサーバーなら、この関数はそのリモートピア アドレスにADDRESSをセットする。 36.17 低レベルのネットワークアクセス ==================================== ‘make-network-process’を使用することにより、‘open-network-stream’より低 レベルでの処理からネットワーク接続を作成することもできます。 36.17.1 ‘make-network-process’ ------------------------------ ネットワーク接続やネットワークサーバーを作成する基本的な関数は ‘make-network-process’です。これは与えられた引数に応じて、これらの仕事の いずれかを行うことができます。 -- Function: make-network-process &rest args この関数はネットワーク接続やサーバーを作成して、それを表すプロセス オブジェクトをリターンする。引数ARGSはキーワード/引数のペアからなる リスト。キーワードの省略は‘:coding’、‘:filter-multibyte’、 ‘:reuseaddr’を除いて、常に値として‘nil’を指定したのと同じことになる 。重要なキーワードを以下に示す(ネットワークオプションに対応するキー ワードを以降のセクションにリストする)。 :name NAME プロセス名として文字列NAMEを使用する。一意にするために必要に応 じて変更され得る。 :type TYPE コミュニケーションのタイプを指定する。値‘nil’はストリーム接続 (デフォルト)、‘datagram’はデータグラム接続、‘seqpacket’はシー ケンスパケットストリーム(sequenced packet stream)による接続を 指定する。接続およびサーバーの両方でこれらのタイプを指定できる 。 :server SERVER-FLAG SERVER-FLAGが非‘nil’ならサーバー、それ以外なら接続を作成する。 ストリームタイプのサーバーではSERVER-FLAGはそのサーバーへの保 留中の接続キューの長さを指定する整数を指定できる。キューのデフ ォルト長は5。 :host HOST 接続するホストを指定する。HOSTはホスト名かインターネットアドレ スを表す文字列、またはローカルホストを表すシンボル‘local’であ ること。サーバーのときにHOSTを指定する場合には有効なローカルホ ストのアドレスを指定しなければならず、そのアドレスに接続するク ライアントだけが受け入れられるだろう。 :service SERVICE SERVICEは接続先のポート番号、またはサーバーにたいしては listenするポート番号。これはポート番号に変換されるようなサービ ス名、または直接ポート番号を指定する整数であること。サーバーに たいしては‘t’も指定でき、これは未使用のポート番号をシステムに 選択させることを意味する。 :family FAMILY FAMILYは接続のアドレス(またはプロトコル)のファミリーを指定する 。‘nil’は与えられたHOSTとSERVICEにたいして自動的に適切なアドレ スファミリーを決定する。‘local’はUnixのsocketを指定して、この 場合にはHOSTは無視される。‘ipv4’と‘ipv6’はそれぞれIPv4とIPv6の 使用を指定する。 :local LOCAL-ADDRESS サーバープロセスではLOCAL-ADDRESSはlistenするアドレスである。 これはFAMILY、HOST、SERVICEをオーバーライドするので、これらを 指定しないこともできる。 :remote REMOTE-ADDRESS 接続プロセスではREMOTE-ADDRESSは接続先のアドレス。これは FAMILY、HOST、SERVICEをオーバーライドするので、これらを指定し ないこともできる。 データグラムサーバーではREMOTE-ADDRESSはリモートデータグラムア ドレスの初期セッティングを指定する。 LOCAL-ADDRESSとREMOTE-ADDRESSのフォーマットはアドレスファミリ ーに依存する: - IPv4アドレスは4つの8ビット整数と1つの16ビット整数からなる 5要素のベクター‘[A B C D P]’で表され、それぞれ数値的な IPv4アドレスA.B.C.D、およびポート番号Pに対応する。 - IPv6アドレスは9要素の16ビット整数ベクター‘[A B C D E F G H P]’で表され、それぞれ数値的なIPv6アドレス A:B:C:D:E:F:G:H、およびポート番号Pに対応する。 - ローカルアドレスはローカルアドレススペース内でアドレスを 指定する文字列として表される。 - 未サポートファミリー(unsupported family)のアドレスはコン スセル‘(F . AV)’で表される。ここでFはファミリー名、AVはア ドレスデータバイトごとに1つの要素を使用するソケットアドレ スを指定するベクター。可搬性のあるコードでこのフォーマッ トを信頼してはならない。これは実装定義の定数、データサイ ズ、データ構造のアライメントに依存する可能性があるからだ 。 :nowait BOOL ストリーム接続にたいしてBOOLが非‘nil’なら、その接続の完了を待 機せずにリターンする。接続の成功や失敗時には、Emacsは‘"open"’ (成功時)、または‘"failed"’ (失敗時)にマッチするような第2引数に よりセンチネル関数を呼び出すだろう。デフォルトではwaitせずに blockするので、‘make-network-process’はその接続が成功または失 敗するまでリターンしない。 :stop STOPPED STOPPEDが非‘nil’ならstopped(停止)の状態でネットワーク接続、ま たはサーバーを開始する。 :buffer BUFFER プロセスバッファーとしてBUFFERを使用する。 :coding CODING このプロセスにたいするコーディングシステムとしてCODINGを使用す る。接続からのデータのデコードおよび接続への送信データのエンコ ードに異なるコーディングシステムを指定するには、CODINGにたいし て‘(DECODING . ENCODING)’と指定する。 このキーワードをまったく指定しないかった場合のデフォルトは、そ のデータからコーディングシステムを判断する。 :noquery QUERY-FLAG プロセスqueryフラグをQUERY-FLAGに初期化する。*note Query Before Exit::を参照のこと。 :filter FILTER プロセスフィルターをFILTERに初期化する。 :filter-multibyte MULTIBYTE MULTIBYTEが非‘nil’ならマルチバイト文字列、それ以外ならユニバイ ト文字列がプロセスフィルターに与えられるデフォルトは ‘enable-multibyte-characters’のデフォルト値。 :sentinel SENTINEL プロセスセンチネルをSENTINELに初期化する。 :log LOG サーバープロセスのlog関数をLOGに初期化する。サーバーがクライア ントからネットワーク接続をacceptするたびにそのlog関数が呼び出 される。log関数に渡される引数はSERVER、CONNECTION、MESSAGE。こ こでSERVERはサーバープロセス、CONNECTIONはその接続にたいする新 たなプロセス、MESSAGEは何が発生したかを説明する文字列。 :plist PLIST プロセスplistをPLISTに初期化する。 実際の接続情報で修正されたオリジナルの引数リストは ‘process-contact’を通じて利用できる。 36.17.2 ネットワークのオプション -------------------------------- 以下のネットワークオプションはネットワークプロセス作成時に指定できます。 ‘:reuseaddr’を除き、‘set-network-process-option’を使用してこれらのオプシ ョンを後からセットや変更することもできます。 サーバープロセスにたいしては、‘make-network-process’で指定されたオプ ションはクライアントに継承されないので、子接続が作成されるたびに必要なオ プションをセットする必要があるでしょう。 :bindtodevice DEVICE-NAME DEVICE-NAMEがネットワークインターフェースを指定する空でない文字列な ら、そのインターフェースで受信したパケットだけを処理する。 DEVICE-NAMEが‘nil’(デフォルト)なら任意のインターフェースが受信した パケットを処理する。 このオプションの使用にたいして特別な特権を要求するシステムがいくつ かあるかもしれない。 :broadcast BROADCAST-FLAG データグラムプロセスにたいしてBROADCAST-FLAGが非‘nil’なら、そのプロ セスはブロードキャストアドレスに送信されたデータグラムパケットを受 信して、ブロードキャストアドレスにパケットを送信できるだろう。これ はストリーム接続では無視される。 :dontroute DONTROUTE-FLAG DONTROUTE-FLAGが非‘nil’ならプロセスはローカルホストと同一ネットワー ク上のホストだけに送信することができる。 :keepalive KEEPALIVE-FLAG ストリーム接続にたいしてKEEPALIVE-FLAGが非‘nil’なら、低レベルの keep-aliveメッセージの交換が有効になる。 :linger LINGER-ARG LINGER-ARGが非‘nil’なら、接続を削除(‘delete-process’を参照)する前に キューされたすべてのパケットの送信が成功するまで待機する。 LINGER-ARGが整数なら、接続クローズ前のキュー済みパケット送信のため に待機する最大の秒数を指定する。デフォルトは‘nil’で、これはプロセス 削除時に未送信のキュー済みパケットを破棄することを意味する。 :oobinline OOBINLINE-FLAG ストリーム接続にたいしてOOBINLINE-FLAGが非‘nil’なら、通常のデータス トリーム内の帯域外(out-of-band)データを受信して、それ以外なら帯域外 データは破棄する。 :priority PRIORITY この接続で送信するパケットの優先順位を整数PRIORITYにセットする。た とえばこの接続で送信するIPパケットのTOS(type of service)フィールド にセットする等、この数字の解釈はプロトコルに固有である。またそのネ ットワークインターフェース上で特定の出力キューを選択する等、これに はシステム依存の効果もある。 :reuseaddr REUSEADDR-FLAG ストリームプロセスサーバーにたいしてREUSEADDR-FLAGが非‘nil’ (デフォ ルト)なら、そのホスト上の別プロセスがそのポートですでにlistenしてい なければ、このサーバーは特定のポート番号(‘:service’を参照)を再使用 できる。REUSEADDR-FLAGが‘nil’なら、(そのホスト上の任意のプロセスが )そのポートを最後に使用した後、そのポート上で新たなサーバーを作成す るのが不可能となるような一定の期間が存在するかもしれない。 -- Function: set-network-process-option process option value &optional no-error この関数はネットワークプロセスPROCESSにたいしてネットワークオプショ ンのセットや変更を行う。指定できるオプションは ‘make-network-process’と同様。NO-ERRORが非‘nil’なら、OPTIONがサポー トされないオプションの場合に、この関数はエラーをシグナルせずに ‘nil’をリターンする。この関数が成功裏に完了したら‘t’をリターンする 。 あるオプションのカレントのセッティングは‘process-contact’関数を通じ て利用できる。 36.17.3 ネットワーク機能の可用性のテスト ---------------------------------------- 与えられネットワーク機能が利用可能かテストするためには以下のように ‘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’等です。完全なリストは*note Network Options::を参照してください。このフォームは ‘make-network-process’ (または‘set-network-process-option’)が特定のネッ トワークオプションをサポートしていれば非‘nil’をリターンします。 36.18 その他のネットワーク機能 ============================== 以下の追加の関数はネットワーク接続の作成や操作に有用です。これらはいくつ かのシステムでのみサポートされることに注意してください。 -- Function: network-interface-list この関数は使用しているマシン上のネットワークインターフェースを記述 するリストをリターンする。値は要素が‘(NAME . ADDRESS)’という形式を もつようなalist。ADDRESSは‘make-network-process’の引数 LOCAL-ADDRESSやREMOTE-ADDRESSと同じ形式。 -- Function: network-interface-info ifname この関数はIFNAMEという名前のネットワークインターフェースに関する情 報をリターンする。値は‘(ADDR BCAST NETMASK HWADDR FLAGS)’という形式 をもつリスト。 ADDR インターネットプロトコルアドレス。 BCAST ブロードキャストアドレス。 NETMASK ネットワークマスク。 HWADDR レイヤー2アドレス(たとえばイーサネットMACアドレス)。 FLAGS そのインターフェースのカレントのフラグ。 -- Function: format-network-address address &optional omit-port この関数はネットワークアドレスの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’は含まれない。 36.19 シリアルポートとの対話 ============================ 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のシステムで利用でき ます。 -- Command: serial-term port speed 新たなバッファー内でシリアルポートにたいする端末エミュレーターを開 始する。PORTは接続先のシリアルポートの名前。たとえばUnixではこれは ‘/dev/ttyS0’のようになるだろう。MS Windowsでは‘COM1’や‘\\.\COM10’の ようになるかもしれない(Lisp文字列ではバックスラッシュは2重にするこ と)。 SPEEDはビット毎秒でのシリアルポートのスピード。一般的な値は9600。そ のバッファーはTermモードになる。このバッファーで使用するコマンドに ついては*note (emacs)Term Mode::を参照のこと。モードラインメニュー からスピードと設定を変更できる。 -- Function: make-serial-process &rest args この関数はプロセスとバッファーを作成する。引数はキーワード/引数ペア ーで指定する。以下は意味のあるキーワードのリストで、最初の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に初期化する。*note Query Before 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) -- Function: serial-process-configure &rest args この関数はシリアルポート接続を設定する。引数はキーワード/引数ペアー で指定する。与えられない属性はそのプロセスのカレントの設定(関数 ‘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’を呼び出す。 36.20 バイト配列のpackとunpack ============================== このセクションでは通常はバイナリーのネットワークプロトコル用のバイト配列 をpackやunpackする方法を説明します。以下の関数はバイト配列とalistとの間 で相互に変換を行います。バイト配列はユニバイト文字列、または整数ベクター として表現することができます。一方でalistはシンボルを固定サイズのオブジ ェクト、または再帰的な副alistのいずれかに関連付けます。このセクションで 参照する関数を使用するためには‘bindat’ライブラリーをロードしてください。 バイト配列からネストされたalistへの変換は逆方向への変換が“シリアライ ズ化(serializing)”または“pack化(packing)”として呼ばれることから、“非シリ アル化【deserializing)”または“unpack化(unpacking)”として知られています。 36.20.1 データレイアウトの記述 ------------------------------ unpackとpackを制御するためには“データレイアウト仕様(data layout specification)”を記述します。これは名前付きかつタイプ付けされた“フィール ド(field)”を記述する特別なネスト化リストです。これは処理する各フィールド の長さ、およびそれをpackおよびunpackする方法を制御します。わたしたちは名 前が‘-bindat-spec’で終わる変数ではbindatの仕様を遵守します。この類の変数 名は自動的にrisky(危険)だと認識されます。 フィールドの“タイプ(type)”はフィールドが表すオブジェクトのサイズ(バイ ト単位)、およびそれがマルチバイトフィールドならフィールがバイトオーダー される方法を記述します。可能なオーダーはビッグエンディアン(big endian。 ネットワークバイトオーダーとも呼ばれる)、およびリトルエンディアン(little endian)の2つです。たとえば数字‘#x23cd’ (10進の9165)のビッグエンディアン は‘#x23’ ‘#xcd’の2バイト、リトルエンディアンは‘#xcd’ ‘#x23’になるでしょ う。以下は可能なタイプの値です: ‘u8’ ‘byte’ 長さ1の符号なしタイプ。 ‘u16’ ‘word’ ‘short’ 長さ2のネットワークバイトオーダーによる符号なし整数。 ‘u24’ 長さ3のネットワークバイトオーダーによる符号なし整数。 ‘u32’ ‘dword’ ‘long’ 長さ4のネットワークバイトオーダーによる符号なし整数。注意: これらの 値はEmacsの整数の実装に制限されるだろう。 ‘u16r’ ‘u24r’ ‘u32r’ それぞれ長さ2、3、4のリトルエンディアンオーダーによる符号なし整数。 ‘str LEN’ 長さLENの文字列。 ‘strz LEN’ 長さLENの固定長フィールド内のNUL終端された文字列。 ‘vec LEN [TYPE]’ タイプTYPE (デフォルトはbyte)のLEN要素のベクター。TYPEは上述した単 純なタイプのいずれか、あるいは‘(vec LEN [TYPE])’という形式のリスト による別ベクターの指定。 ‘ip’ インターネットアドレスを表す4つのbyteのベクター。たとえば localhostは‘[127 0 0 1]’。 ‘bits LEN’ LENバイト内のセットされたビット位置のリスト。バイトはビッグエンディ アンでビット位置は‘8 * LEN − 1’で始まり0で終わるよう番号が付与され る。たとえば‘bits 2’では、‘#x28’ ‘#x1c’は‘(2 3 4 11 13)’、‘#x1c’ ‘#x28’は‘(3 5 10 11 12)’にunpackされる。 ‘(eval FORM)’ FORMはフィールドがpackやunpackされた瞬間に評価されるLisp式。評価し た結果は上記にリストしたタイプ使用のいずれかであること。 固定長フィールドでは長さLENがフィールド内のバイト数を指定する整数とし て与えられます。 フィールド長が固定でなければ通常は先行するフィールドの値に依存します 。この場合には長さLENは後述の‘bindat-get-field’のフォーマット指定により “フィールド名(field name)”を指定するリスト‘(NAME ...)’、または式‘(eval FORM)’ (FORMはフィールド長を指定する整数に評価されること)のいずれかで与 えることもできます。 フィールド仕様は一般的に‘([NAME] HANDLER)’という形式をもち、NAMEはオ プションです。紛らわしくなるのでタイプ仕様(上述)やハンドラー仕様(後述)で 意味をもつシンボルの名前は使用しないでください。NAMEはシンボルまたは式 ‘(eval FORM)’でもよく、この場合にはFORMはシンボルに評価される必要があり ます。 HANDLERはそのフィールドがpackやunpackされる方法を記述して、以下のいず れかを指定できます: ‘TYPE’ タイプ仕様TYPEに応じてこのフィールドのunpack/packを行う。 ‘eval FORM’ 副作用のためだけにLisp式FORMを評価する。フィールド名が指定されたら 値はそのフィールド名にバインドされる。 ‘fill LEN’ LENバイトをスキップする。pack化ではそれらを未変更のままとして、通常 それらは0のままとなることを意味する。unpack化ではそれらが無視される ことを意味する。 ‘align LEN’ LENバイトの次の倍数にスキップする。 ‘struct SPEC-NAME’ 副仕様(sub-specification)としてSPEC-NAMEを処理する。これは別の構造 体内にネストされる構造体を記述する。 ‘union FORM (TAG SPEC)...’ Lisp式FORMを評価、それにマッチする最初のTAGを探して、それに関連付け られたレイアウト仕様SPECを処理する。マッチングは以下の3つのいずれか で発生し得る: • TAGが‘(eval EXPR)’という形式をもつ場合には、変数‘tag’を動的に FORMの値にバインドしてEXPRを評価する。結果が非‘nil’ならマッチ を示す。 • TAGがFORMの値と‘equal’ならマッチ。 • TAGが‘t’なら無条件にマッチ。 ‘repeat COUNT FIELD-SPECS...’ FIELD-SPECSを再帰的に順次処理した後に、最初のものから繰り返して、す べての仕様全体をCOUNT回処理する。COUNTはフィールド長と同じフォーマ ットを使用して与えられる。‘eval’フォームが使用された場合には1回だけ 評価される。正しく処理されるためには、FIELD-SPECS内の各仕様が名前を 含まなければならない。 bindat仕様内で仕様される‘(eval FORM)’フォームでは、評価の間にFORMはこ れらの動的にバインドされた変数へのアクセスと更新が可能である。 ‘last’ 最後に処理されたフィールドの値。 ‘bindat-raw’ バイト配列のデータ。 ‘bindat-idx’ unpack化/pack化にたいする、(‘bindat-raw’での)カレントインデックス。 ‘struct’ これまでにunpackされた構造化データ、またはpackされた構造体全体を含 むalist。この構造体の特定のフィールドにアクセスするために ‘bindat-get-field’を使用できる。 ‘count’ ‘index’ ‘repeat’ブロック内部では、これらは(COUNTパラメーターで指定された)繰 り返しの最大回数、および(0から数えた)カレント繰り返し回数を含む。 ‘count’を0にセットすることにより、カレントの繰り返し終了後に最内繰 り返しブロックを終了する。 36.20.2 バイトのunpackとpackのための関数 ---------------------------------------- 以降のドキュメントではSPECはデータレイアウト仕様、‘bindat-raw’はバイト配 列、STRUCTはunpackされたフィールドデータを表すalistを参照します。 -- Function: bindat-unpack spec bindat-raw &optional bindat-idx この関数はユニバイト文字列、またはバイト配列‘bindat-raw’のデータを SPECに応じてunpackする。これは通常はバイト配列の先頭からunpack化を 開始するが、BINDAT-IDXが非‘nil’ならかわりに使用する0基準の開始位置 を指定する。 値はそれぞれの要素がunpackされたフィールドを記述するalistかネストさ れたalist。 -- Function: bindat-get-field struct &rest name この関数はネストされたalistであるSTRUCTからフィールドのデータを選択 する。STRUCTは通常は‘bindat-unpack’がリターンしたもの。NAMEが単一の 引数に対応する場合にはトップレベルのフィールド値を抽出することを意 味する。複数のNAME引数は副構造体を繰り返して照合することを指定する 。整数の名前は配列のインデックスとして動作する。 たとえばNAMEが‘(a b 2 c)’なら、それはフィールド‘a’の副フィールド ‘b’の3番目の要素内のフィールド‘c’ (Cでは‘struct.a.b[2].c’に相当)を 意味する。 packやunpackの処理をすることによりメモリー内でデータ構造が変化しても 、そのデータの全フィールド長の合計バイト数である“トータル長(total length)”は保たれます。この値は一般的に仕様またはalist単独では固有ではあ りません。そのかわりこれら両方の情報がこの計算に役立ちます。同様に unpackされる文字列や配列の長さは仕様の記述にしたがってデータのトータル長 より長くなるかもしれません。 -- Function: bindat-length spec struct この関数はSTRUCT内のデータのSPECに応じたトータル長をリターンする。 -- Function: bindat-pack spec struct &optional bindat-raw bindat-idx この関数はalist STRUCT内のデータからSPECに応じてpackされたバイト配 列をリターンする。これは通常は先頭から充填された新たなバイト配列を 作成する。しかしBINDAT-RAWが非‘nil’なら、それはpack先として事前に割 り当てられたユニバイト文字列かベクターを指定する。BINDAT-IDXが非 ‘nil’なら‘bindat-raw’へpackする開始オフセットを指定する。 事前に割り当てる際にはout-of-rangeエラーを避けるために、‘(length BINDAT-RAW)’がトータル長またはそれ以上であることを確認すること。 -- Function: bindat-ip-to-string ip インターネットアドレスのベクターIPを通常のドット表記による文字列に 変換する。 (bindat-ip-to-string [127 0 0 1]) ⇒ "127.0.0.1" 36.20.3 バイトのunpackとpackの例 -------------------------------- 以下はバイトにたいしてunpackおよびpackを行う完全な例です: (require 'bindat) (defvar fcookie-index-spec '((:version u32) (:count u32) (:longest u32) (:shortest u32) (:flags u32) (:delim u8) (:ignored fill 3) (:offset repeat (:count) (:foo u32))) "fortuneクッキーのインデックスファイル内容") (defun fcookie (cookies &optional index) "ファイルCOOKIESからランダムなfortuneクッキーを表示する。 オプションの第2引数INDEXは関連付けられるインデックス ファイル名を指定し、デフォルトは\"COOKIES.dat\"。 バッファー\"*Fortune Cookie: BASENAME*\"内にクッキーを表示。 BASENAMEはディレクトリー部分を除いたCOOKIES" (interactive "fCookies file: ") (let* ((info (with-temp-buffer (insert-file-contents-literally (or index (concat cookies ".dat"))) (bindat-unpack fcookie-index-spec (buffer-string)))) (sel (random (bindat-get-field info :count))) (beg (cdar (bindat-get-field info :offset sel))) (end (or (cdar (bindat-get-field info :offset (1+ sel))) (nth 7 (file-attributes cookies))))) (switch-to-buffer (get-buffer-create (format "*Fortune Cookie: %s*" (file-name-nondirectory cookies)))) (erase-buffer) (insert-file-contents-literally cookies nil beg (- end 3)))) (defun fcookie-create-index (cookies &optional index delim) "ファイルCOOKIESをスキャンしてインデックスファイルに書き込む。 オプション引数INDEXは、インデックスファイル名を指定。デフォルトは\"COOKIES.dat\"。 オプション引数DELIMはユニバイト文字で、それがCOOKIES内 のある行で見つかったら、その行はエントリー間の境界を示す。" (interactive "fCookies file: ") (setq delim (or delim ?%)) (let ((delim-line (format "\n%c\n" delim)) (count 0) (max 0) min p q len offsets) (unless (= 3 (string-bytes delim-line)) (error "Delimiter cannot be represented in one byte")) (with-temp-buffer (insert-file-contents-literally cookies) (while (and (setq p (point)) (search-forward delim-line (point-max) t) (setq len (- (point) 3 p))) (setq count (1+ count) max (max max len) min (min (or min max) len) offsets (cons (1- p) offsets)))) (with-temp-buffer (set-buffer-multibyte nil) (insert (bindat-pack fcookie-index-spec `((:version . 2) (:count . ,count) (:longest . ,max) (:shortest . ,min) (:flags . 0) (:delim . ,delim) (:offset . ,(mapcar (lambda (o) (list (cons :foo o))) (nreverse offsets)))))) (let ((coding-system-for-write 'raw-text-unix)) (write-file (or index (concat cookies ".dat"))))))) 以下は複雑な構造体を定義してunpackする例です。以下のようなCの構造体が あるものとします: struct header { unsigned long dest_ip; unsigned long src_ip; unsigned short dest_port; unsigned short src_port; }; struct data { unsigned char type; unsigned char opcode; unsigned short length; /* ネットワークバイトオーダー */ unsigned char id[8]; /* NUL終端文字列 */ unsigned char data[/* (length + 3) & ~3 */]; }; struct packet { struct header header; unsigned long counters[2]; /* リトルエンディアンオーダー */ unsigned char items; unsigned char filler[3]; struct data item[/* items */]; }; 対応するデータレイアウト仕様が以下です: (setq header-spec '((dest-ip ip) (src-ip ip) (dest-port u16) (src-port u16))) (setq data-spec '((type u8) (opcode u8) (length u16) ; ネットワークバイトオーダー (id strz 8) (data vec (length)) (align 4))) (setq packet-spec '((header struct header-spec) (counters vec 2 u32r) ; リトルエンディアンオーダー (items u8) (fill 3) (item repeat (items) (struct data-spec)))) バイナリーデータによる表現は: (setq binary-data [ 192 168 1 100 192 168 1 101 01 28 21 32 160 134 1 0 5 1 0 0 2 0 0 0 2 3 0 5 ?A ?B ?C ?D ?E ?F 0 0 1 2 3 4 5 0 0 0 1 4 0 7 ?B ?C ?D ?E ?F ?G 0 0 6 7 8 9 10 11 12 0 ]) 対応するデコードされた構造体は: (setq decoded (bindat-unpack packet-spec binary-data)) ⇒ ((header (dest-ip . [192 168 1 100]) (src-ip . [192 168 1 101]) (dest-port . 284) (src-port . 5408)) (counters . [100000 261]) (items . 2) (item ((data . [1 2 3 4 5]) (id . "ABCDEF") (length . 5) (opcode . 3) (type . 2)) ((data . [6 7 8 9 10 11 12]) (id . "BCDEFG") (length . 7) (opcode . 4) (type . 1)))) 以下はこの構造体からデータを取得する例です: (bindat-get-field decoded 'item 1 'id) ⇒ "BCDEFG" 37 Emacsのディスプレー表示 ************************** このチャプターではEmacsによるユーザーへのプレゼンテーションとなる、表示 に関連するいくつかの機能を説明します。 37.1 スクリーンのリフレッシュ ============================= 関数‘redraw-frame’は与えられたフレーム(*note Frames::を参照)のコンテンツ 全体にたいしてクリアーと再描画を行います。これはスクリーンが壊れている (corrupted)場合に有用です。 -- Function: redraw-frame &optional frame この関数はフレームFRAMEのクリアーと再表示を行う。FRAMEが省略または nilの場合のデフォルトは選択されたフレーム。 更に強力なのは‘redraw-display’です: -- Command: redraw-display この関数はすべての可視なフレームのクリアーと再描画を行う。 Emacsではユーザー入力は再描画より優先されます。入力が可能なときにこれ らの関数を呼び出すと、これらはすぐに再描画はしませんが、要求された再描画 はすべての入力処理後に行われます。 テキスト端末では通常はEmacsのサスペントと再開によりスクリーンのリフレ ッシュも行われます。Emacsのようなディスプレイ指向のプログラムと通常のシ ーケンシャル表示のプログラムで、コンテンツを区別して記録する端末エミュレ ーターがいくつかあります。そのような端末を使用する場合には、おそらく再開 時の再表示を抑制したいでしょう。 -- User Option: no-redraw-on-reenter この変数はEmacsがサスペンドや再開された後にスクリーン全体を再描画す るかどうかを制御する。非‘nil’なら再描画は不要、‘nil’なら再描画が必 要であることを意味する。デフォルトは‘nil’。 37.2 強制的な再表示 =================== Emacsは入力の待機時は常に再表示を試みます。以下の関数により実際に入力を 待機することなく、Lispコードの中から即座に再表示を試みることを要求できま す。 -- Function: redisplay &optional force この関数は即座に再表示を試みる。オプション引数FORCEが非‘nil’の場合 には、入力が保留中なら横取りされるかわりに強制的に再表示が行われる 。 この関数は実際に再表示が試行されたなら‘t’、それ以外は‘nil’をリター ンする。‘t’という値は再表示の試行が完了したことを意味しない。新たに 到着した入力に横取りされた可能性がある。 ‘redisplay’が即座に再表示を試みたとしても、Emacsがフレーム(複数可)の どの部分を再表示するか決定する方法が変更されるわけではありません。それと は対照的に以下の関数は特定のウィンドウを、(あたかもコンテンツが完全に変 更されたかのように)保留中の再表示処理に追加します。しかし再描画を即座に は試みません。 -- Function: force-window-update &optional object この関数はEmacsが次に再表示を行う際にいくつか、あるいはすべてのウィ ンドウが更新されるよう強制する。OBJECTがウィンドウならそのウィンド ウ、バッファーやバッファー名ならそのバッファーを表示するすべてのウ ィンドウ、‘nil’ (または省略)ならすべてのウィンドウが更新される。 この関数は即座に再表示を行わない。再表示はEmacsが入力を待機時、また は関数‘redisplay’呼び出し時に行われる。 -- Variable: pre-redisplay-function 再表示の直前に実行される関数。これは再表示されるウィンドウセットを 単一の引数として呼び出される。ウィンドウセットは選択されたウィンド ウを意味する‘nil’、すべてのウィンドウを意味する‘t’を指定できる。 -- Variable: pre-redisplay-functions このフックは再表示の直前に実行される。これは再表示されようとするウ ィンドウそれぞれにたいして、そのウィンドウに表示されているバッファ ーを‘current-buffer’にセットして1回呼び出される。 37.3 切り詰め ============= Emacsはテキスト行がウィンドウ右端を超過する際には、その行を“継続 (continue)”させる(次のスクリーン行へwrap、すなわち折り返す)か、あるいは その行を“切り詰め(truncate)”て表示(その行をスクリーン行の1行に制限)する ことができます。長いテキスト行を表示するために使用される追加のスクリーン 行は“継続(continuation)”行と呼ばれます。継続はフィルとは異なります。継続 はバッファーのコンテンツ内ではなくスクリーン上でのみ発生して、単語境界で はなく正確に右マージンで行をブレークします。*note Filling::を参照してく ださい。 グラフィカルなディスプレイでは切り詰めと継続はウィンドウフリンジ内の 小さな矢印イメージで示されます(*note Fringes::を参照)。テキスト端末では 切り詰めはそのウィンドウの最右列の‘$’、折り返しは最右列の‘\’で示されます (ディスプレイテーブルでこれを行うための代替え文字を指定できる。*note Display Tables::を参照)。 -- User Option: truncate-lines このバッファーローカル変数が非‘nil’ならウィンドウ右端を超過する行は 切り詰められて、それ以外なら継続される。特別な例外として“部分幅 (partial-width)”ウィンドウ(フレーム全体の幅を占有しないウィンドウ )では変数‘truncate-partial-width-windows’が優先される。 -- User Option: truncate-partial-width-windows この変数は“部分幅(partial-width)”ウィンドウ内の行の切り詰めを制御す る。部分幅ウィンドウとはフレーム全体の幅を占有しないウィンドウ (*note Splitting Windows::を参照)。値が‘nil’なら行の切り詰めは変数 ‘truncate-lines’ (上記参照)により決定される。値が整数Nの場合には、 部分幅ウィンドウの列数がNより小さければ‘truncate-lines’の値とは無関 係に行は切り詰められて、部分幅ウィンドウの列数がN以上なら行の切り詰 めは‘truncate-lines’により決定される。それ以外の非‘nil’値では ‘truncate-lines’の値とは無関係にすべての部分幅ウィンドウで行は切り 詰められる。 ウィンドウ内で水平スクロール(*note Horizontal Scrolling::を参照)を使 用中は切り詰めが強制されます。 -- Variable: wrap-prefix このバッファーローカル変数が非‘nil’なら、それはEmacsが各継続行の先 頭に表示する“折り返しプレフィックス(wrap prefix)”を定義する(行を切 り詰めている場合には‘wrap-prefix’は使用されない)。この値は文字列、 またはイメージ(*note Other Display Specs::を参照)やディスプレイプロ パティ‘:width’や‘:align-to’で指定されるような伸長された空白文字を指 定できる(*note Specified Space::を参照)。値はテキストプロパティ ‘display’と同じ方法で解釈される。*note Display Property::を参照のこ と。 折り返しプレフィックスはテキストプロパティかオーバーレイプロパティ ‘wrap-prefix’を使用することにより、テキストのリージョンにたいして指 定することもできる。これは‘wrap-prefix’変数より優先される。*note Special Properties::を参照のこと。 -- Variable: line-prefix このバッファーローカル変数が非‘nil’なら、それはEmacsがすべての非継 続行の先頭に表示する“行プレフィックス(line prefix)”を定義する。この 値は文字列、イメージ(*note Other Display Specs::を参照)、またはディ スプレイプロパティ‘:width’や‘:align-to’で指定されるような伸長された 空白文字を指定できる(*note Specified Space::を参照)。値はテキストプ ロパティ‘display’と同じ方法で解釈される。*note Display Property::を 参照のこと。 行プレフィックスはテキストプロパティまたはオーバーレイプロパティ ‘line-prefix’を使用することにより、テキストのリージョンにたいして指 定することもできる。これは‘line-prefix’変数より優先される。*note Special Properties::を参照のこと。 37.4 エコーエリア ================= “エコーエリア(echo area)”はエラーメッセージ(*note Errors::)や‘message’プ リミティブで作成されたメッセージの表示、およびキーストロークをエコーする ために使用されます。(アクティブ時には)ミニバッファーがスクリーン上のエコ ーエリアと同じ場所に表示されるという事実にも関わらずエコーエリアはミニバ ッファーと同じではありません。*note The Minibuffer: (emacs)Minibuffer.を 参照してください。 このセクションに記述された関数とは別に、出力ストリームとして‘t’を指定 することによりエコーエリアにLispオブジェクトをプリントできます。*note Output Streams::を参照してください。 37.4.1 エコーエリアへのメッセージの表示 --------------------------------------- このセクションではエコーエリア内にメッセージを表示する標準的な関数を説明 します。 -- Function: message format-string &rest arguments この関数はエコーエリア内にメッセージを表示する。‘format-message’関 数(*note Formatting Strings::を参照)の場合と同じように FORMAT-STRINGはフォーマット文字列、ARGUMENTSはそのフォーマット仕様 にたいするオブジェクトである。フォーマットされた結果文字列はエコー エリア内に表示される。それに‘face’テキストプロパティが含まれる場合 には指定されたフェイスにより表示される(*note Faces::を参照)。この文 字列は‘*Messages*’バッファーにも追加されるがテキストプロパティは含 まれない(*note Logging Messages::を参照)。 変数‘text-quoting-style’は何のクォートを生成するかを制御する。*note Keys in Documentation::を参照のこと。"Missing `%s'"のようなgrave accentとapostropheをもつフォーマットを使用する呼び出しは、典型的に は"Missing ‘foo’のようにマッチするcurved quoをもつメッセージを生成 する。対照的に"Missing '%s'"のようにapostropheだけをもつフォーマッ トを使用した呼び出しでは、英語では普通は使用されないclosing curved quoteだけをもつ"Missing ’foo’"のようなメッセージが生成される。 バッチモードでは後に改行が付加されたメッセージが標準エラーストリー ムにプリントされる。 ‘inhibit-message’が非‘nil’のときはエコーエリアにはメッセージを何も 表示せずに‘*Messages*’へのロギングだけとなる。 FORMAT-STRINGが‘nil’か空文字列なら、‘message’はエコーエリアをクリア ーする。エコーエリアが自動的に拡張されていたら、これにより通常のサ イズに復元される。ミニバッファーがアクティブなら、これによりスクリ ーン上に即座にミニバッファーのコンテンツが復元される。 (message "Reverting `%s'..." (buffer-name)) ⊣ Reverting ‘subr.el’... ⇒ "Reverting ‘subr.el’..." ---------- Echo Area ---------- Reverting ‘subr.el’... ---------- Echo Area ---------- エコーエリアやポップバッファー内に自動的にメッセージを表示するには 、そのサイズに応じて‘display-message-or-buffer’ (以下参照)を使用す る。 *警告:* 逐語的なメッセージとして独自の文字列を使用したければ、単に ‘(message STRING)’と記述してはならない。STRINGに‘%’、‘`’、‘'’が含ま れていると望まぬ結果に再フォーマットされるかもしれない。かわりに ‘(message "%s" STRING)’を使用すること。 -- Variable: inhibit-message この変数が非‘nil’なら、‘message’および関連する関数はメッセージの表 示にエコーエリアを使用しない。 -- Macro: with-temp-message message &rest body この構文はBODY実行の間にエコーエリア内にメッセージを一時的に表示す る。これはMESSAGEを表示してBODYを実行して、それからエコーエリアの前 のコンテンツをリストアするとともにbodyの最後のフォームの値をリター ンする。 -- Function: message-or-box format-string &rest arguments この関数は‘message’と同様にメッセージを表示するが、エコーエリアでは なくダイアログボックスにメッセージを表示するかもしれない。この関数 があるコマンド内からマウスを使用して呼び出されると — より正確には ‘last-nonmenu-event’ (*note Command Loop Info::を参照)が‘nil’かリス トならメッセージの表示にダイアログボックスかポップアップメニュー、 それ以外ならエコーエリアを使用する(これは‘y-or-n-p’が同様の決定を行 う際に使用する条件と同じ。*note Yes-or-No Queries::を参照)。 呼び出しの前後で‘last-nonmenu-event’を適切な値にバインドすることに よりエコーエリアでのマウスの使用を強制できる。 -- Function: message-box format-string &rest arguments この関数は‘message’と同様にメッセージを表示するが、利用可能なら常に ダイアログボックス(かポップアップメニュー)を使用する。端末がサポー トしないためにダイアログボックスやポップアップメニューが使用できな ければ、‘message-box’は‘message’と同様にエコーエリアを使用する。 -- Function: display-message-or-buffer message &optional buffer-name action frame この関数はメッセージMESSAGEを表示する。MESSAGEには文字列かバッファ ーを指定できる。これが‘max-mini-window-height’で定義されるエコーエ リアの最大高さより小さければ、‘message’を使用してエコーエリアに表示 される。それ以外ならメッセージを表示するために‘display-buffer’はポ ップアップバッファーを使用する。 エコーエリアに表示したメッセージ、またはポップアップバッファー使用 時はその表示に使用したウィンドウをリターンする。 MESSAGEが文字列ならオプション引数BUFFER-NAMEはポップアップバッファ ー使用時にメッセージ表示に使用するバッファー名(デフォルトは ‘*Message*’)。MESSAGEが文字列でエコーエリアに表示されていれば、いず れにせよコンテンツをバッファーに挿入するかどうかは指定されない。 オプション引数ACTIONとFRAMEは‘display-buffer’の場合と同様に、バッフ ァーが表示されている場合のみ使用される。 -- Function: current-message この関数はエコーエリア内にカレントで表示されているメッセージ、また はそれが存在しなければ‘nil’をリターンする。 37.4.2 処理の進捗レポート ------------------------- 処理の完了まで暫く時間を要するかもしれない際には、進行状況についてユーザ ーに通知するべきです。これによりユーザーが残り時間を予測するとともに、 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)) -- Function: make-progress-reporter message &optional min-value max-value current-value min-change min-time この関数は以下に挙げる他の関数の引数として使用されることになるプロ グレスリポーターオブジェクトを作成してリターンする。これはプログレ スリポーターを高速にするように、可能なかぎり多くのデータを事前に計 算するというアイデアが元となっている。 この後にプログレスリポーターを使用する際には、進行状況のパーセンテ ージを後に付加して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’を呼び出すので、最初のメッセー ジは即座にプリントされる。 -- Function: progress-reporter-update reporter &optional value この関数は操作の進行状況報告に関する主要な機能を担う。これは REPORTERのメッセージと、その後にVALUEにより決定された進行状況のパー センテージを表示する。パーセンテージが0、または引数MIN-CHANGEと MIN-TIMEに比べて十分0に近ければ出力は省略される。 REPORTERは‘make-progress-reporter’呼び出しがリターンした結果でなけ ればならない。VALUEは処理のカレント状況を指定して、 ‘make-progress-reporter’に渡されたMIN-VALUEとMAX-VALUEの間(両端を含 む)でなければならない。たとえばバッファーのスキャンにおいては、 VALUEは‘point’び呼び出し結果であるべきだろう。 この関数は‘make-progress-reporter’に渡されたMIN-CHANGEとMIN-TIMEに したがい、毎回の呼び出しで新たなメッセージを出力しない。したがって これは非常に高速であり、通常はこれを呼び出す回数を減らすことを試み るべきではない。結果として生じるオーバーヘッドは、あなたの努力をほ ぼ否定するだろう。 -- Function: progress-reporter-force-update reporter &optional value new-message この関数は‘progress-reporter-update’と同様だが、これは無条件にメッ セージをエコーエリアにプリントする点が異なる。 最初の2つの引数は‘progress-reporter-update’の場合と同じ意味をもつ。 オプションのNEW-MESSAGEでREPORTERのメッセージを変更できる。この関数 は常にエコーエリアを更新するので、そのような変更は即座にユーザーに 示されるだろう。 -- Function: progress-reporter-done reporter この関数は処理の完了時に呼び出されること。これはエコーエリア内に単 語‘done’を付加したREPORTERのメッセージを表示する。 ‘progress-reporter-update’に‘100%’とプリントさせようとせずに、常に この関数を呼び出すこと。まずこの関数は決してそれをプリントしないだ ろうし、これが発生しないために多くの正当な理由がある。次に‘done’は より自明である。 -- Macro: dotimes-with-progress-reporter (var count [result]) message body... これは‘dotimes’と同じ方法で機能するが、上述の関数を使用してループ進 行状況(loop progress)の報告も行う便利なマクロである。これによりタイ プ量を幾分節約できる。 以下の方法でこのマクロを使用することにより、このセクション冒頭の例 を書き換えることができる: (dotimes-with-progress-reporter (k 500) "Collecting some mana for Emacs..." (sit-for 0.01)) 37.4.3 ‘*Messages*’へのメッセージのロギング ------------------------------------------- エコーエリア内に表示されるほとんどすべてのメッセージは、ユーザーが後で参 照できるように‘*Messages*’バッファー内にも記録されます。これには ‘message’により出力されたメッセージも含まれます。デフォルトではこのバッ ファーは読み取り専用でメジャーモード‘messages-buffer-mode’を使用します。 ユーザーによる‘*Messages*’バッファーのkillを妨げるものは何もありませんが 、次回のメッセージ表示でバッファーは再作成されます。‘*Messages*’バッファ ーに直接アクセスする必要があり、それが確実に存在するようにしたいLispコー ドは、すべて関数‘messages-buffer’を使用するべきです。 -- Function: messages-buffer この関数は‘*Messages*’バッファーをリターンする。バッファーが存在し なければ作成してバッファーを‘messages-buffer-mode’に切り替える。 -- User Option: message-log-max この変数は‘*Messages*’バッファー内に保持するべき行数を指定する。値 ‘t’は保持すべき行数に制限がないことを意味して、値‘nil’はメッセージ のロギングを完全に無効にする。以下はメッセージを表示して、それがロ ギングされることを防ぐ例: (let (message-log-max) (message ...)) ‘*Messages*’にたいするユーザーの利便性を向上させるために、ロギング機 能は連続する同じメッセージを結合します。さらに2つのケースのために連続す る関連メッセージの結合も行います。2つのケースとは応答を後にともなう質問 (question followed by answer)、および一連のプログレスメッセージ(series of progress messages)です。 応答を後にともなう質問(question followed by an answer)とは、1つ目が ‘QUESTION’、2つ目が‘QUESTION...ANSWER’のように‘y-or-n-p’が生成するような 2つのメッセージをもつ応答です。1つ目のメッセージは2つ目のメッセージ以上 の追加情報を伝えないので、2つ目のメッセージをロギングして1つ目のメッセー ジは破棄します。 一連のプログレスメッセージ(series of progress messages)は、 ‘make-progress-reporter’が生成するような連続するメッセージをもちます。こ れらは‘BASE...HOW-FAR’のような形式であり、HOW-FARは毎回異なりますが BASEは常に同じです。このシリーズ内の各メッセージのロギングでは、そのメッ セージが前のメッセージと連続していれば前のメッセージを破棄します。 関数‘make-progress-reporter’と‘y-or-n-p’は、メッセージログ結合機能を アクティブにするために何ら特別なことを行う必要はありません。これは ‘...’で終わる共通のプレフィックスを共有する連続する2つのメッセージをログ する際には常にこの処理を行います。 37.4.4 エコーエリアのカスタマイズ --------------------------------- 以下の変数はエコーエリアが機能する方法の詳細を制御します。 -- Variable: cursor-in-echo-area この変数はエコーエリア内にメッセージ表示時にカーソルを表示する場所 を制御する。これが非‘nil’ならカーソルはメッセージの終端、それ以外な らカーソルはエコーエリア内ではなくポイント位置に表示される。 この値は通常は‘nil’。Lispプログラムは短時間の間、これを‘t’にバイン ドする。 -- Variable: echo-area-clear-hook このノーマルフックは‘(message nil)’、または別の何らかの理由によりエ コーエリアが作成されると常に実行される。 -- User Option: echo-keystrokes この変数はコマンド文字をエコーする前に、どれだけの時間を待機するか を決定する。この値は数字でなければならず、エコー前に待機する秒数を 指定する。ユーザーが(‘C-x’のような)プレフィックスキーをタイプしてか ら、継続してタイプを継続するのをこの秒数遅延した場合、エコーエリア 内にそのプレフィックスキーがエコーされる(あるキーシーケンスで一度エ コーが開始されると、同一のキーシーケンス内の後続するすべての文字は 即座にエコーされる)。 値が0ならコマンド入力はエコーされない。 -- Variable: message-truncate-lines 長いメッセージの表示により、そのメッセージ全体を表示するために、通 常はエコーエリアはリサイズされる。しかし変数 ‘message-truncate-lines’が非‘nil’なら、エコーエリアをリサイズせずエ コーエリアに収まるようメッセージは切り詰められる。 ミニバッファーウィンドウのリサイズの最大高さを指定する変数 ‘max-mini-window-height’はエコーエリアにも適用される(エコーエリアは真に ミニバッファーウィンドウの特殊な使い方である。*note Minibuffer Misc::を 参照)。 37.5 警告のレポート =================== “警告(warnings)”とはプログラムがユーザーにたいして問題の可能性を知らせる が、実行は継続するための機能です。 37.5.1 警告の基礎 ----------------- すべての警告は、ユーザーに問題を説明するためのテキストのメッセージと、 “重大レベル(severity level)”をもっています。重大レベルはシンボルです。以 下は可能性のある重大レベルとその意味を、重大度の降順でリストしたものです : ‘:emergency’ 直ちに対処しなければEmacs処理が間もなく深刻に害される問題。 ‘:error’ 本質的に悪いデータや状況のリポート。 ‘:warning’ 本質的に悪くはないが、可能性のある問題を励起する恐れのあるデータや 状況のリポート。 ‘:debug’ デバッグ中なら有用かもしれない情報のリポート。 あなたのプログラムが無効な入力データに遭遇した際には、‘error’呼び出し によるLispエラーのシグナルするか、または重大度‘:error’の警告をリポートす ることができます。Lispエラーのシグナルはもっとも簡単に行えることですが、 それはプログラムが処理を継続できないことを意味します。間違ったデータでも 処理を継続するための方法を実装するためにトラブルを受け取めたい場合には、 その問題をユーザーに知らせるために重大度‘:error’の警告をリポートするのが 正しい方法です。たとえばEmacs Lispバイトコンパイラーはこの方法によりエラ ーを報告して、他の関数のコンパイルを継続できます(プログラムがLispエラー をシグナルして‘condition-case’でhandleしたならユーザーがそのエラーを確認 することはないだろう。これは警告としてリポートすることによりユーザーにメ ッセージを示すことができる)。 クラス分けのために警告にはそれぞれ“警告タイプ(warning type)”がありま す。このタイプはシンボルのリストです。最初のシンボルはそのプログラムのユ ーザーオプションとして使用するカスタムグループであるべきです。たとえばバ イトコンパイラーの警告は警告タイプ‘(bytecomp)’を使用します。もし望むなら 、このリスト内で更にシンボルを使用することにより警告をサブカテゴリー化す ることもできます。 -- Function: display-warning type message &optional level buffer-name この関数はメッセージとしてMESSAGE、警告タイプとしてTYPEを使用して警 告をリポートする。LEVELは重大レベルであること。デフォルトは ‘:warning’。 BUFFER-NAMEが非‘nil’なら、それは警告をロギングするためのバッファー 名を指定する。デフォルトは‘*Warnings*’。 -- Function: lwarn type level message &rest args この関数は‘*Warnings*’バッファー内のメッセージとして ‘(format-message MESSAGE ARGS...)’の値を使用して警告をリポートする 。他の点ではこれは‘display-warning’と同じ。 -- Function: warn message &rest args この関数はメッセージとして‘(format-message MESSAGE ARGS...)’の値、 タイプとして‘(emacs)’、重大レベルとして‘:warning’を使用して警告をリ ポートする。これは互換性のためだけに存在する。固有な警告タイプを指 定するべきであり、この関数の使用は推奨しない。 37.5.2 警告のための変数 ----------------------- このセクション内で説明する変数をバインドすることにより、プログラムは警告 が表示される方法をカスタマイズできます。 -- Variable: warning-levels このリストは警告の重大レベルの意味と重大度の順序を定義する。それぞ れの要素は1つの重大レベルを定義して、それらを重大度の降順で配置した 。 各要素は‘(LEVEL STRING FUNCTION)’という形式をもち、LEVELはその要素 が定義する重大レベル。STRINGはそのレベルのテキストによる説明。 STRINGは警告タイプ情報の配置箇所の指定に‘%s’を使用するか、さもなく ばその情報を含まぬよう‘%s’を省略できる。 オプションのFUNCTIONが非‘nil’なら、これはユーザーの注目を得るために 引数なしで呼び出される関数であること。 通常はこの変数の値を変更しないこと。 -- Variable: warning-prefix-function 値が非‘nil’なら、それは警告用にプレフィックスを生成する関数であるこ と。プログラムはこの変数を適切な関数にバインドできる。 ‘display-warning’はwarningsバッファーがカレントの状態でこの関数を呼 び出して、関数はそのバッファーにテキストを挿入できる。そのテキスト が警告メッセージの先頭になる。 この関数は重大レベル、および‘warning-levels’内でのその重大レベルの エントリーという2つの引数で呼び出される。これはエントリーとして使用 するためのリストをリターンすること(この値は‘warning-levels’の実際の メンバーである必要はない)。この値を構築することにより関数はその警告 の重大レベルを変更したり、与えられた重大レベルにたいして異なる処理 を指定することができる。 この変数の値が‘nil’なら呼び出される関数は存在しない。 -- Variable: warning-series プログラムは次の警告がシリーズの開始であることを告げるために、この 変数を‘t’にバインドできる。複数の警告がシリーズを形成するということ は、それぞれの警告にたいしてポイントが維持されるように移動して、最 後の警告にポイントが表示されるのではなくシリーズの最初の警告にポイ ントを残すことを意味する。このシリーズは、そのローカルバインドが非 バインドされて‘warning-series’が再び‘nil’になったときに終了する。 この値は関数定義をもつシンボルでもよい。これは次の警告により warningsバッファーがカレントの状態で、引数なしでその関数が呼び出さ れることを除き‘t’と等価。この関数は警告シリーズのヘッダーの役目をも つであろうテキストを挿入できる。 あるシリーズが開始されると、その値はwarningsバッファー内でシリーズ 開始となるバッファー位置を指すマーカーとなる。 この変数の通常の値は‘nil’で、これはそれぞれの警告を個別に処理するこ とを意味する。 -- Variable: warning-fill-prefix この変数が非‘nil’なら、それは各警告テキストのフィルに使用するフィル プレフィックスを指定する。 -- Variable: warning-type-format この変数は警告メッセージ内の警告タイプを表示するためのフォーマット を指定する。この方法でフォーマットされたタイプは、 ‘warning-levels’内のエントリー内の文字列制御下にあるメッセージに含 まれることになる。デフォルト値は‘" (%s)"’。これを‘""’にバインドする と警告タイプはまったく表示されなくなる。 37.5.3 警告のためのオプション ----------------------------- 以下の変数は何が発生したときにLispプログラムが警告をリポートするかをユー ザーが制御するために使用されます。 -- User Option: warning-minimum-level このユーザーオプションはユーザーにたいして即座に表示されるべき最小 の重大レベルを指定する。デフォルトは‘:warning’であり、これは ‘:debug’警告を除くすべての警告が即座に表示されることを意味する。 -- User Option: warning-minimum-log-level このユーザーオプションはwarningsバッファー内にログされるべき最小の 重大レベルを指定する。デフォルトは‘:warning’であり、これは ‘:debug’警告を除くすべての警告がログされることを意味する。 -- User Option: warning-suppress-types このリストはユーザーにたいしてどの警告タイプを即座に表示するべきで はないかを指定する。このリスト内の各要素はシンボルのリストであるこ と。それの要素が警告タイプ内の最初の要素にマッチしたら警告は即座に 表示されない。 -- User Option: warning-suppress-log-types このリストはユーザーにたいしてどの警告タイプがwarningsバッファーに ログされるべきではないかを指定する。このリスト内の各要素はシンボル のリストであること。それの要素が警告タイプ内の最初の数要素にマッチ したら警告はログされない。 37.5.4 遅延された警告 --------------------- コマンド実行中には警告の表示を避けてコマンドの終わりでのみ警告を表示した いことがあるかもしれません。これは変数‘delayed-warnings-list’により行う ことができます。 -- Variable: delayed-warnings-list この変数の値はカレントのコマンド完了後に表示される警告のリスト。各 要素は以下のようなリストでなければならない: (TYPE MESSAGE [LEVEL [BUFFER-NAME]]) これらは‘display-warning’の引数リストと同じ形式、同じ意味である (*note Warning Basics::を参照)。‘post-command-hook’ (*note Command Overview::を参照)の実行直後に、Emacsのコマンドループはこの変数で指 定されたすべての警告を表示してから変数を‘nil’にリセットする。 遅延警告メカニズムをよりカスタマイズする必要があるプログラムは変数 ‘delayed-warnings-hook’を変更することができます: -- Variable: delayed-warnings-hook これは遅延警告を処理して表示するために、‘post-command-hook’の後に Emacsコマンドループが実行するノーマルフック。 デフォルト値は2つの関数からなるリスト: (collapse-delayed-warnings display-delayed-warnings) 関数‘collapse-delayed-warnings’は‘delayed-warnings-list’から重複す るエントリーを削除する。関数‘display-delayed-warnings’は ‘delayed-warnings-list’内の各要素にたいして順次‘display-warning’を 呼び出してから、‘delayed-warnings-list’を‘nil’にセットする。 37.6 不可視のテキスト ===================== ‘invisible’プロパティにより、スクリーン上に表示されないように文字を“不可 視(invisible)”にすることができます。これはテキストプロパティ(*note Text Properties::を参照)、またはオーバーレイプロパティ(*note Overlays::を参照 )のいずれかで行うことができます。カーソル移動もこれらの文字を部分的に無 視します。あるコマンドの後に不可視テキスト範囲内にポイントがあることをコ マンドループが検知した場合には、コマンドループはポイントをそのテキストの 別サイドへ再配置します。 もっともシンプルなケースでは、非‘nil’の‘invisible’プロパティにより文 字は不可視になります。これがデフォルトのケースであり、もし ‘buffer-invisibility-spec’のデフォルト値を変更したくない場合には、これが ‘invisible’プロパティを機能させる方法です。自身で ‘buffer-invisibility-spec’をセットする予定がなければ、‘invisible’プロパ ティの値として通常は‘t’を使用するべきです。 より一般的にはどの‘invisible’の値がテキストを不可視にするかを制御する ために変数‘buffer-invisibility-spec’を使用できます。テキストにたいして異 なる‘invisible’の値を与えることにより、事前に別のサブセットへテキストを クラス分けした後に‘buffer-invisibility-spec’の値を変更して、さまざまなサ ブセットを可視や不可視にすることができます。 特にデータベース内のエントリーのリストを表示するプログラム内では、 ‘buffer-invisibility-spec’による可視性の制御は有用です。これによりデータ ベース内の一部だけを閲覧するフィルターコマンドを簡便に実装することが可能 になります。この変数をセットするのは非常に高速であり、バッファー内のすべ てのテキストにたいしてプロパティが変更されたかスキャンするよりはるかに高 速です。 -- Variable: 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つの関数が 提供されています。 -- Function: add-to-invisibility-spec element この関数は、‘buffer-invisibility-spec’に要素ELEMENTを追加する。 ‘buffer-invisibility-spec’が‘t’なら、これはリスト‘(t)’に変更されて ‘invisible’プロパティが‘t’のテキストは不可視のまま留まる。 -- Function: remove-from-invisibility-spec element この関数は‘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) 以下の関数を使用することにより不可視性をチェックできます: -- Function: invisible-p pos-or-prop POS-OR-PROPがマーカーか数字の場合には、その位置のテキストが不可視な らこの関数は非‘nil’をリターンする。 POS-OR-PROPが別の類のLispオブジェクトなら、テキストプロパティかオー バーレイプロパティとして可能な値を意味すると解釈される。この場合に は‘buffer-invisibility-spec’のカレント値にもとづき、もしその値がテ キストを不可視とするようならこの関数は非‘nil’をリターンする。 テキストを操作したりポイントを移動する関数は、通常はそのテキストが不 可視かどうかに注意を払わずに、可視と不可視のテキストを同様に処理します。 ‘next-line’や‘previous-line’のようなユーザーレベルの行移動関数は ‘line-move-ignore-invisible’が非‘nil’ (デフォルト)なら不可視な改行を無視 します。これらの関数は不可視な改行がそのバッファーに存在しないかのように 振る舞いますが、それはそう振る舞うように明示的にプログラムされているから です。 あるコマンドが不可視テキストの境界内側のポイントで終了した場合には、 メイン編集ループはその不可視テキストの両端のうちのいずれかにポイントを再 配置します。そのコマンドの移動関数の全体的な方向と同じになるように Emacsが再配置の方向を決定します。これに疑問がある場合には、挿入された文 字が‘invisible’プロパティを継承しないような位置を優先してください。加え てそのテキストが省略記号で置換されずに、コマンドが不可視テキスト内への移 動のみを行う場合には、ポイントを1文字余計に移動して目に見えるようカーソ ルを移動することにより、そのコマンドの移動を反映するよう試みます。 したがってコマンドが(通常のstickinessをもつ)不可視範囲に後方へとポイ ントを移動すると、Emacsはポイントをその範囲の先頭に後方へと移動します。 コマンドが不可視範囲へ前方にポイントを移動した場合には、Emacsは不可視テ キストの前にある最初の可視文字に前方へとポイントを移動して、その後さらに 前方へ1文字余計に移動します。 これら不可視テキスト中間で終了するポイントにたいするこれらの“調整 (adjustments)”は、‘disable-point-adjustment’を非‘nil’にセットすることに より無効にできます。*note Adjusting Point::を参照してください。 インクリメンタル検索はマッチが不可視テキストを含む場合には、一時的お よび/または永続的に不可視オーバーレイを可視にすることができます。これを 有効にするためには、そのオーバーレイが非‘nil’の ‘isearch-open-invisible’プロパティをもつ必要があります。プロパティの値は 、そのオーバーレイを引数として呼び出される関数であるべきです。その関数は オーバーレイを永続的に可視にする必要があります。これは検索からのexit時に マッチがそのオーバーレイに重なるときに使用されます。 検索の間にそのようなオーバーレイのinvisible、およびintangibleプロパテ ィを一時的に変更することによりオーバーレイは一時的に可視にされます。特定 のオーバーレイにたいして異なる方法でこれを行いたいなら、それを ‘isearch-open-invisible-temporary’プロパティ(関数)に与えてください。その 関数は2つの引数により呼び出されます。1つ目はそのオーバーレイ、2つ目は ‘nil’ならオーバーレイを可視、‘t’なら再び不可視にします。 37.7 選択的な表示 ================= “選択的表示(selective display)”とはスクリーン上で特定の行を隠蔽する関連 する機能ペアーを指します。 1つ目の変種は明示的な選択的表示であり、これはLispプログラム内で使用す るようにデザインされています。これはテキスト変更により、どの行を隠すかを 制御します。この種の隠蔽は現在では時代遅れです。かわりに‘invisible’プロ パティで同じ効果を得ることができます(*note Invisible Text::を参照)。 2つ目の変種はインデントにもとづいて隠す行の選択を自動的に行います。こ の変種はユーザーレベルの機能としてデザインされています。 選択的表示を明示的に制御する方法では改行(control-j)を復帰 (control-m)に置換します。これにより以前は行末に改行があった行は隠蔽され ます。厳密に言うと改行だけが行を分離できるので、これはもはや一時的には行 ではなく前の行の一部です。 選択的表示は編集コマンドに直接影響を与えません。たとえば‘C-f’ (‘forward-char’)は隠蔽された行へと気軽にポイントを移動します。しかし復帰 文字による改行文字の置換は、いくつかの編集コマンドに影響を与えます。たと えば‘next-line’は改行だけを検索するために、隠蔽された行をスキップします 。選択的表示を使用するモードは改行を考慮するコマンドを定義したり、テキス トのどの部分を隠すか制御することもできます。 選択的表示されたバッファーをファイルに書き込む際には、control-mはすべ て改行として出力されます。これはファイル内のテキストを読み取る際には、す べて問題なく隠蔽されずに表示されることを意味します。選択的表示はEmacs内 でのみ顕在する効果です。 -- Variable: selective-display このバッファーローカル変数は選択的表示を有効にする。これは行、また は行の一部を隠すことができることを意味する。 • ‘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 ---------- -- User Option: selective-display-ellipses このバッファーローカル変数が非‘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 ---------- 省略記号(‘...’)にたいして他のテキストを代替えするためにディスプレイ テーブルを使用できる。*note Display Tables::を参照のこと。 37.8 一時的な表示 ================= 一時的表示(temporary display)は出力をバッファーに配置して編集用ではなく 閲覧用としてユーザーに示すためにLispプログラムにより使用されます。多くの ヘルプコマンドはこの機能を使用します。 -- Macro: with-output-to-temp-buffer buffer-name body... この関数はBUFFER-NAMEという名前のバッファー(必要なら最初に作成され る)にプリントされた任意の出力が挿入されるようアレンジ、さらにバッフ ァーをHelpモードにしてBODY内のフォームを実行する(類似する以下のフォ ーム‘with-temp-buffer-window’を参照)。最後にそのバッファーはいずれ かのウィンドウに表示されるが、そのウィンドウは選択されない。 BODY内のフォームが出力バッファーのメジャーモードを変更しないため、 実行の最後においても依然としてHelpモードにあるなら、 ‘with-output-to-temp-buffer’は最後にそのバッファーを読み取り専用す るとともに、クリック可能なクロスリファレンスとなるように関数名と変 数名のスキャンも行う。特にドキュメント文字列内のハイパーリンク上ア イテムに関する詳細は*note Tips for Documentation Strings: Docstring hyperlinks.を参照のこと。 文字列BUFFER-NAMEは一時的なバッファーを指定して、これはあらかじめ存 在する必要はない。引数はバッファーではなく文字列でなければならない 。そのバッファーは最初に消去されて(確認なし)、 ‘with-output-to-temp-buffer’のexit後は未変更(unmodified)とマークさ れる。 ‘with-output-to-temp-buffer’は‘standard-output’を一時的バッファーに バインドしてBODY内のフォームを評価する。BODY内のLisp出力関数を使用 した出力のデフォルト出力先は、そのバッファーになる(しかしスクリーン 表示やエコーエリア内のメッセージは一般的な世界の感覚では“出力”であ るものの影響は受けない)。*note Output Functions::を参照のこと。 この構構文の振る舞いをカスタマイズするために利用できるフックがいく つかあり、それらは以下にリストしてある。 リターン値はBODY内の最後のフォームの値。 ---------- Buffer: foo ---------- This is the contents of foo. ---------- Buffer: foo ---------- (with-output-to-temp-buffer "foo" (print 20) (print standard-output)) ⇒ # ---------- Buffer: foo ---------- 20 # ---------- Buffer: foo ---------- -- User Option: temp-buffer-show-function この変数が非‘nil’なら、‘with-output-to-temp-buffer’はヘルプバッファ ーを表示する処理を行うためにその関数を呼び出す。この関数は表示すべ きバッファーという1つの引数を受け取る。 ‘with-output-to-temp-buffer’が通常行うように、 ‘save-selected-window’内部や選択されたウィンドウ内でバッファーか選 択された状態で‘temp-buffer-show-hook’を実行するのは、この関数にとっ てよいアイデアである。 -- Variable: temp-buffer-setup-hook このノーマルフックはBODYを評価する前に ‘with-output-to-temp-buffer’により実行される。フック実行時には一時 的バッファーがカレントになる。このフックは通常はそのバッファーを Helpモードにするための関数にセットアップされる。 -- Variable: temp-buffer-show-hook このノーマルフックは一時的バッファー表示後に ‘with-output-to-temp-buffer’により実行される。フック実行時には一時 的バッファーがカレントになり、それが表示されているウィンドウが選択 される。 -- Macro: with-temp-buffer-window buffer-or-name action quit-function body... このマクロは‘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’ (*note Choosing Window::を参照)に渡す。 引数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’とほとんど同じですが、説明し ている点が異なります: -- Macro: with-current-buffer-window buffer-or-name action quit-function &rest body このマクロは‘with-temp-buffer-window’と同様だが、BODYの実行に際して BUFFER-OR-NAMEで指定したバッファーをカレントにする点が異なる。 -- Macro: with-displayed-buffer-window buffer-or-name action quit-function &rest body このマクロは‘with-temp-buffer-window’と同様だが、BODYの実行の_前_に BUFFER-OR-NAMEで指定したバッファーを表示する点が異なる。 一時的バッファーを表示するウィンドウは、以下のモードを使用してバッフ ァーのサイズをフィットさせることができます: -- User Option: temp-buffer-resize-mode このマイナーモードが有効なときは、一時的バッファーを表示しているウ ィンドウはバッファーのコンテンツにフィットするように自動的にリサイ ズされる。 そのバッファーにたいして特別に作成されたウィンドウの場合のみウィン ドウはリサイズされる。特に前に別のバッファーを表示していたウィンド ウはリサイズされない。デフォルトではこのモードはリサイズに ‘fit-window-to-buffer’を使用する(*note Resizing Windows::を参照)。 以下のオプション‘temp-buffer-max-height’と‘temp-buffer-max-width’を カスタマイズして他の関数を指定できる。 -- User Option: temp-buffer-max-height このオプションは‘temp-buffer-resize-mode’が有効な際に一時的バッファ ーを表示するウィンドウの最大高さ(行数)を指定する。その種のバッファ ーの高さ選択のために呼び出す関数でもよい。これはバッファーを唯一の 引数として受け取り、正の整数をリターンすること。関数の呼び出し時に はリサイズされるウィンドウが選択される。 -- User Option: temp-buffer-max-width このオプションは‘temp-buffer-resize-mode’が有効な際に一時的バッファ ーを表示するウィンドウの最大幅(列数)を指定する。その種のバッファー の高さ選択のために呼び出す関数でもよい。これはバッファーを唯一の引 数として受け取り、正の整数をリターンすること。関数の呼び出し時には リサイズされるウィンドウが選択される。 以下の関数は一時的な表示にカレントバッファーを使用します: -- Function: momentary-string-display string position &optional char message この関数はカレントバッファー内のPOSITIONにSTRINGを瞬間表示 (momentarily display)する。これはundoリストやバッファーの変更状態 (modification status)に影響を与えない。 瞬間表示は次の入力イベントまで留まる。次の入力イベントがCHARなら ‘momentary-string-display’はそれを無視してリターンする。それ以外な らそのイベントは後続の入力として使用するためにバッファリングされる 。つまりCHARとタイプすると表示からその文字列を単に削除して、(たとえ ば) CHARではない‘C-f’とタイプすると表示からその文字列を削除して、そ の後に(おそらく)ポイントを前方へ移動するだろう。引数CHARのデフォル トはスペース。 ‘momentary-string-display’のリターン値に意味はない。 文字列STRINGがコントロール文字を含まなければ、‘before-string’プロパ ティでオーバーレイを作成(その後に削除)することで、同じことをより汎 用的に行うことができる。*note Overlay Properties::を参照のこと。 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 ---------- 37.9 オーバーレイ ================= バッファーのテキストのスクリーン上の見栄えを変更するために、 プレゼンテ ーション機能として“オーバーレイ(overlay)”を使用できます。オーバーレイと は個々のバッファーに属するオブジェクトであり、指定された開始と終了をもっ ています。確認したりセットすることができるプロパティももっています。それ らはオーバーレイをもつテキストの表示に影響を与えます。 オーバーレイの視覚的効果は、対応するテキストプロパティと同様です (*note Text Properties::を参照)。しかし実装が異なるために、オーバーレイ は一般的にスケーラブルではありません(処理数に応じてバッファー内のオーバ ーレイ数に比例した時間を要する)。バッファー内の多数の部分の視覚的外観に 効果を及ぼす必要がある場合にはテキストプロパティの使用を推奨します。 オーバーレイはその開始と終了を記録するためにマーカーを使用します。し たがってバッファーのテキスト編集では、すべてのオーバーレイがそのテキスト に留まるように開始と終了が調整されます。オーバーレイ作成時にはオーバーレ イの先頭、または同様に終端にテキストが挿入された場合に、それがオーバーレ イの内側(または外側)になるべきなのかを指定できます。 37.9.1 オーバーレイの管理 ------------------------- このセクションではオーバーレイの作成、削除、移動、およびそれらのコンテン ツを調べる関数を説明します。オーバーレイはバッファーのコンテンツの一部で はないので、その変更はバッファーのundoリストに記録されません。 -- Function: overlayp object この関数はOBJECTがオーバーレイなら‘t’をリターンする。 -- Function: make-overlay start end &optional buffer front-advance rear-advance この関数はBUFFERに属する、STARTからENDの範囲のオーバーレイを作成し てリターンする。STARTとENDはいずれもバッファーの位置を指定しなけれ ばならず、整数かマーカーを指定できる。BUFFERが省略されると、そのオ ーバーレイはカレントバッファーに作成される。 STARTとENDが同一のバッファー位置を指定するオーバーレイは“空 (empty)”のオーバーレイとして知られる。STARTとENDの間のテキストが削 除されれば、非空のオーバーレイも空になり得る。これが発生したとき、 デフォルトではオーバーレイは削除されないが、‘evaporate’プロパティを 与えることにより削除されるようにできる(*note evaporate property: Overlay Properties.を参照)。 引数FRONT-ADVANCEとREAR-ADVANCEはそれぞれオーバーレイの開始と終了に たいするマーカーの挿入タイプを指定する。*note Marker Insertion Types::を参照のこと。どちらも‘nil’ (デフォルト)なら、そのオーバーレ イは先頭に挿入された任意のテキストを含むように拡張されるが、終端に 挿入されたテキストにたいしては拡張されない。FRONT-ADVANCEが非 ‘nil’なら、オーバーレイの先頭に挿入されたテキストはオーバーレイから 除外される。REAR-ADVANCEが非‘nil’なら、オーバーレイの終端に挿入され たテキストはオーバーレイに含まれる。 -- Function: overlay-start overlay この関数はOVERLAYが開始する位置を整数でリターンする。 -- Function: overlay-end overlay この関数はOVERLAYが終了する位置を整数でリターンする。 -- Function: overlay-buffer overlay この関数はOVERLAYが所属するバッファーをリターンする。OVERLAYが削除 されていたら‘nil’をリターンする。 -- Function: delete-overlay overlay この関数はOVERLAYを削除する。そのオーバーレイはLispオブジェクトとし て存在し続けて、そのプロパティリストは変更されないがバッファーへの 所属と表示にたいするすべての効果を失う。 削除済みオーバーレイが永続的に非接続という訳ではない。 ‘move-overlay’を呼び出すことによりバッファー内の位置を与えることが できる。 -- Function: move-overlay overlay start end &optional buffer この関数はOVERLAYをBUFFERに移動して、その境界をSTARTとENDに配置する 。STARTとENDの引数はいずれもバッファーの位置を指定しなければならず 、整数かマーカーを指定できる。 BUFFERが省略された場合、OVERLAYはすでに関連付けられている同じバッフ ァーに留まる。さらにOVERLAYが削除されていたら、それをカレントバッフ ァーに所属させる。 リターン値はOVERLAY。 これはオーバーレイの両端位置を変更する唯一の有効な方法である。手作 業でオーバーレイ内のマーカーの変更を試みてはならない。それにより他 の重要なデータ構造の更新が失敗して、いくつかのオーバーレイが失われ る可能性がある。 -- Function: remove-overlays &optional start end name value この関数はプロパティNAMEが値VALUEをもつような、STARTとENDの間のすべ てのオーバーレイを削除する。これによりオーバーレイの両端位置が変更 されたり分割される可能がある。 NAMEが省略か‘nil’なら、それは指定されたリージョン内のすべてのオーバ ーレイを削除することを意味する。STARTおよび/またはENDが省略か ‘nil’なら、それぞれバッファーの先頭と終端を意味する。したがって ‘(remove-overlays)’はカレントバッファー内のすべてのオーバーレイを削 除する。 -- Function: copy-overlay overlay この関数はOVERLAYのコピーをリターンする。このコピーはOVERLAYと同じ 両端位置とプロパティをもつ。しかしオーバーレイの開始と終了にたいす るマーカー挿入タイプはデフォルト値にセットされる(*note Marker Insertion Types::を参照)。 以下にいくつか例を示します: ;; オーバーレイの作成 (setq foo (make-overlay 1 10)) ⇒ # (overlay-start foo) ⇒ 1 (overlay-end foo) ⇒ 10 (overlay-buffer foo) ⇒ # ;; 後でチェックできるようプロパティ付与 (overlay-put foo 'happy t) ⇒ t ;; プロパティが付与されたか検証 (overlay-get foo 'happy) ⇒ t ;; オーバーレイを移動 (move-overlay foo 5 20) ⇒ # (overlay-start foo) ⇒ 5 (overlay-end foo) ⇒ 20 ;; オーバーレイを削除 (delete-overlay foo) ⇒ nil ;; 削除されたか検証 foo ⇒ # ;; 削除済みオーバーレイは位置をもたない (overlay-start foo) ⇒ nil (overlay-end foo) ⇒ nil (overlay-buffer foo) ⇒ nil ;; オーバーレイの削除取り消し (move-overlay foo 1 20) ⇒ # ;; 結果の検証 (overlay-start foo) ⇒ 1 (overlay-end foo) ⇒ 20 (overlay-buffer foo) ⇒ # ;; オーバーレイの移動と削除では、オーバーレイのプロパティは変更されない (overlay-get foo 'happy) ⇒ t Emacsはそれぞれのバッファーのオーバーレイを任意の中心位置(center position)で分割される2つのリストに格納します。一方のリストはバッファーの 中心位置から後方に拡張されて、もう一方は中心位置から前方へと拡張されます 。中心位置はバッファーの任意の位置をとることができます。 -- Function: overlay-recenter pos この関数はカレントバッファーのオーバーレイを位置POSの周辺に再センタ リングする。これにより位置POS近傍のオーバーレイの照合は高速になるが 、POSから離れた位置にたいしては低速になる。 バッファーを前方にスキャンしてオーバーレイを作成するループは、最初に ‘(overlay-recenter (point-max))’を行うことにより高速になる可能性がありま す。 37.9.2 オーバーレイのプロパティ ------------------------------- オーバーレイプロパティは文字が表示される方法をどちらのソースからも取得で きるという点においてテキストプロパティと似ています。しかしほとんどの観点 において両者は異なります。これらの比較は*note Text Properties::を参照し てください。 テキストプロパティはそのテキストの一部として考えることができます。オ ーバーレイとそのプロパティは特にテキストの一部とはみなされません。したが ってさまざまなバッファーや文字列の間でテキストをコピーすると、テキストプ ロパティは保持されますがオーバーレイを保持しようとは試みません。バッファ ーのテキストプロパティの変更はバッファーを変更済みとマークしますが、オー バーレイの移動やプロパティの変更は違います。テキストプロパティの変更とは 異なり、オーバーレイプロパティの変更はバッファーのundoリストに記録されま せん。 複数のオーバーレイが同じ文字にたいしてプロパティ値を指定できるので、 Emacsは各オーバーレイにたいして優先度の指定を許容します。2つのオーバーレ イが同じ値の優先度をもち、一方が他方にネストされている場合には、内側のオ ーバーレイが外側のオーバーレイより高い優先度をもちます。いずれのオーバー レイも他方をネストしない場合には、どちらのオーバーレイが優先されるかにつ いて予測するべきではありません。 以下の関数はオーバーレイのプロパティの読み取りとセットを行います: -- Function: overlay-get overlay prop この関数はOVERLAY内に記録されたプロパティPROPの値をリターンする。そ のプロパティにたいしてOVERLAYが何も値を記録していないが、シンボルで あるような‘category’プロパティをもつ場合には、そのシンボルのPROPプ ロパティが使用される。それ以外なら値は‘nil’。 -- Function: overlay-put overlay prop value この関数はOVERLAY内に記録されたプロパティPROPの値にVALUEをセットす る。リターン値はVALUE。 -- Function: overlay-properties overlay これはOVERLAYのプロパティリストのコピーをリターンする。 与えられた文字にたいしてテキストプロパティとオーバーレイプロパティの 両方をチェックする関数‘get-char-property’も参照してください。*note Examining Properties::を参照してください。 多くのオーバーレイプロパティには特別な意味があります。以下はそれらの テーブルです: ‘priority’ このプロパティの値はオーバーレイの優先度を決定する。優先度にたいし て値を指定したければ‘nil’ (か0)、または正の整数を使用すること。それ 以外のすべての値にたいする動作は未定義。 2つ以上のオーバーレイが同じ文字をカバーして、いずれもが同じプロパテ ィを指定する場合には優先度が重要になる。他より‘priority’の値が大き いほうが他をオーバーライドする。‘face’プロパティにたいしては、より 高い優先度のオーバーレイの値は他の値を完全にはオーバーライドしない 。かわりにより低い優先度の‘face’プロパティのface属性を高い優先度の face属性がオーバーライドする。 現在のところ、すべてのオーバーレイはテキストプロパティより優先され る。 Emacsは内部的なオーバーレイのいくつかにたいして非数値の優先度を使用 することがあるので、(自分が作成したオーバーレイでなければ)オーバー レイ優先度の算術演算を試みないように注意すること。オーバーレイを優 先度順に配置する必要があるなら、‘overlays-at’のSORTED引数を使用する こと。*note Finding Overlays::を参照のこと。 ‘window’ ‘window’プロパティが非‘nil’ならオーバーレイはそのウィンドウだけに適 用される。 ‘category’ オーバーレイが‘category’プロパティをもつなら、それをオーバーレイの “カテゴリー(category)”と呼ぶ。これはシンボルであること。そのシンボ ルのプロパティはオーバーレイのプロパティにたいしてデフォルトの役割 を果たす。 ‘face’ このプロパティはテキストの外観を制御する(*note Faces::を参照)。プロ パティの値は以下のいずれか: • フェイス名(シンボルか文字列)。 • anonymousフェイス: ‘(KEYWORD VALUE ...)’という形式のプロパティ リストでありKEYWORDはフェイス属性名、VALUEはその属性の値。 • フェイスのリスト。リストの要素はそれぞれフェイス名か anonymousフェイスのいずれかであること。これはリストされた各フ ェイスの属性を集約するフェイスを指定する。このリスト内で先に出 現するフェイスが、より高い優先度をもつ。 • ‘(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)したり、イメージに よる置き換えを行う。*note Display Property::を参照のこと。 ‘help-echo’ あるオーバーレイが‘help-echo’プロパティをもつなら、そのオーバーレイ 内のテキスト上にマウスを移動した際に、Emacsはエコーエリアかツールチ ップウィンドウにヘルプ文字列を表示する。詳細は*note Text help-echo::を参照のこと。 ‘field’ 同じ‘field’プロパティをもつ連続する文字は_フィールド(field)_を形成 する。‘forward-word’や‘beginning-of-line’を含むいくつかの移動関数は フィールド境界で移動を停止する。*note Fields::を参照のこと。 ‘modification-hooks’ このプロパティの値はオーバーレイ内の任意の文字の変更、またはオーバ ーレイの厳密に内側にテキストが挿入された場合に呼び出される関数のリ スト。 このフックの関数は各変更の前後両方で呼び出される。これらの関数が受 け取った情報を保存して呼び出し間で記録を比較すれば、バッファー内の テキストでどのような変更が行われたかを正確に判断できる。 変更前に呼び出された際にはオーバーレイ、‘nil’、変更されたテキスト範 囲の開始と終了という4つの引数を各関数は受け取る。 変更後に呼び出された際にはオーバーレイ、‘t’、変更されたテキスト範囲 の開始と終了、およびその範囲により置き換えられた変更前のテキスト長 という5つの引数を各関数は受け取る(変更前の長さは挿入では0、削除では 削除された文字数であり、変更後の先頭と終端が等しくなる)。 これらの関数がバッファーを変更する場合には、これらのフックを呼び出 す内部的メカニズムの混乱を避けるために、それを行う前後で ‘inhibit-modification-hooks’を‘t’にバインドすること。 テキストプロパティも‘modification-hooks’プロパティをサポートするが 詳細は幾分異なる(*note Special Properties::を参照)。 ‘insert-in-front-hooks’ このプロパティの値はオーバーレイ先頭へのテキスト挿入前後に呼び出さ れる関数のリスト。呼び出し方は‘modification-hooks’の関数と同様。 ‘insert-behind-hooks’ このプロパティの値はオーバーレイ終端へのテキスト挿入前後に呼び出さ れる関数のリスト。呼び出し方は‘modification-hooks’の関数と同様。 ‘invisible’ ‘invisible’プロパティによりオーバーレイ内のテキストを不可視にできる 。これはそのテキストがスクリーン上に表示されないことを意味する。詳 細は*note Invisible Text::を下さいのこと。 ‘intangible’ オーバーレイの‘intangible’プロパティは正に‘intangible’テキストプロ パティと同様に機能する。これは時代遅れである。詳細は*Note Special Properties::を参照のこと。 ‘isearch-open-invisible’ このプロパティはインクリメンタル検索にたいして最後のマッチがそのオ ーバーレイに重なる場合に、不可視なオーバーレイを永続的に可視にする 方法を告げる。*note Invisible Text::を参照のこと。 ‘isearch-open-invisible-temporary’ このプロパティはインクリメンタル検索にたいして、検索の間に不可視な オーバーレイを一時的に可視にする方法を告げる。*note Invisible Text::を参照のこと。 ‘before-string’ このプロパティの値はオーバーレイ先頭に表示するために追加する文字列 。この文字列はいかなる意味においてもバッファー内には出現せずにスク リーン上にのみ表れる。 ‘after-string’ このプロパティの値はオーバーレイ終端に表示するために追加する文字列 。この文字列はいかなる意味においてもバッファー内には出現せずにスク リーン上にのみ表れる。 ‘line-prefix’ このプロパティは表示時にそれぞれの非継続行の後に追加するディスプレ イ仕様(display spec)を指定する。*note Truncation::を参照のこと。 ‘wrap-prefix’ このプロパティは表示時にそれぞれの継続行の前に追加するディスプレイ 仕様(display spec)を指定する。*note Truncation::を参照のこと。 ‘evaporate’ このプロパティが非‘nil’の場合には、そのオーバーレイが空(長さが0)に なったら自動的に削除される。空のオーバーレイ(*note empty overlay: Managing Overlays.を参照)にたいして非‘nil’の‘evaporate’プロパティを 与えた場合には即座に削除される。オーバーレイがこのプロパティをもた なければ、バッファーからオーバーレイの開始位置と終了位置の間のテキ ストが削除された際に削除されないことに注意。 ‘keymap’ このプロパティが‘nil’なら、そのテキスト範囲にたいしてキーマップを指 定する。このキーマップはポイントの後の文字がそのオーバーレイ内にあ るときに使用されて、他のほとんどのキーマップより優先される。*note Active Keymaps::を参照のこと。 ‘local-map’ ‘local-map’プロパティは‘keymap’プロパティと同様だが、既存のキーマッ プに付け加えるのではなくバッファーのローカルマップを置き換える点が 異なる。これはそのキーマップがマイナーモードキーマップより低い優先 度をもつことも意味する。 ‘keymap’と‘local-map’プロパティは‘before-string’、‘after-string’、 ‘display’プロパティにより表示された文字列には影響しません。これはポイン トがその文字列上にない場合のマウスクリックや、その文字列に関する他のマウ スイベントにのみ関係があります。その文字列に特別なマウスイベントをバイン ドするには、そのイベントを‘keymap’か‘local-map’プロパティに割り当てます 。*note Special Properties::を参照してください。 37.9.3 オーバーレイにたいする検索 --------------------------------- -- Function: overlays-at pos &optional sorted この関数はカレントバッファー内の位置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)) -- Function: overlays-in beg end この関数はBEGからENDのリージョンと重複(overlap)するオーバーレイのリ ストをリターンする。オーバーレイがリージョン内の文字を少なくとも1つ 含めば、オーバーレイとリージョンは重複している。空のオーバーレイ (*note empty overlay: Managing Overlays.を参照)がBEGにある場合、厳 密にはBEGとBEGの間、またはENDがバッファー終端の位置を意味するときは ENDにある場合には重複している。 -- Function: next-overlay-change pos この関数はPOSの後にあるオーバーレイの開始か終了となるバッファー位置 をリターンする。それが存在しなければ‘(point-max)’をリターンする。 -- Function: previous-overlay-change pos この関数はPOSの前にあるオーバーレイの開始か終了となるバッファー位置 をリターンする。それが存在しなければ‘(point-min)’をリターンする。 以下に例としてプリミティブ関数‘next-single-char-property-change’ (*note Property Search::を参照)の単純化(かつ非効率的)したバージョンを示 します。これは位置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))) 37.10 表示されるテキストのサイズ ================================ すべての文字が同じ幅をもつ訳ではありませんが、以下の関数により文字の幅を チェックできます。関連する関数については*note Primitive Indent::と*note Screen Lines::を参照してください。 -- Function: char-width char この関数は文字CHARがカレントバッファーに表示された場合(つまりそのバ ッファーのディスプレイテーブルがあれば考慮に入れる。*note Display Tables::を参照)の幅を列数でリターンする。タブ文字の幅、通常は ‘tab-width’ (*note Usual Display::を参照)。 -- Function: string-width string この関数は文字列STRINGがカレントバッファーおよび選択されたウィンド ウに表示された場合の幅を列数でリターンする。 -- Function: truncate-string-to-width string width &optional start-column padding ellipsis この関数はSTRINGの一部を列数WIDTHにフィット新たな文字列としてリター ンする。 STRINGがWIDTHに満たなければ文字列終端が結果の終端となる。STRING内の 1つの複数列文字が列WIDTHを超えて跨がるようなら、その文字は結果に含 まれない。つまり結果はWIDTHより短くなるかもしれないが超えることはで きない。 オプション引数START-COLUMNは開始列を指定する。これが非‘nil’なら、そ の文字列の最初のSTART-COLUMN列は値から省かれる。STRING内の1つの複数 列文字が列START-COLUMNを超えて跨がるようなら、その文字は結果に含ま れない。 オプション引数PADDINGが非‘nil’なら、結果となる文字列の幅を正確に WIDTH列に拡張するためにパディング文字が追加される。結果文字列が WIDTHより短ければ結果文字列の終端にパディング文字が使用される。 STRING内の1つの複数列文字が列START-COLUMNを跨ぐ場合は先頭にもパディ ング文字が使用される。 ELLIPSISが非‘nil’なら、それはSTRINGの表示幅がELLIPSISの表示幅以下で なければWIDTHを超えてしまう場合に、STRINGの終端(任意のパディングを 含む)を置き換える文字列であること。ELLIPSISが非‘nil’かつ文字列以外 なら、それは変数‘truncate-string-ellipsis’の値を意味する。 (truncate-string-to-width "\tab\t" 12 4) ⇒ "ab" (truncate-string-to-width "\tab\t" 12 4 ?\s) ⇒ " ab " 以下の関数は与えられたウィンドウにあるテキストを表示したときのサイズ をピクセル単位でリターンします。この関数はテキストを含むためにウィンドウ を十分大きくするために‘fit-window-to-buffer’と‘fit-frame-to-buffer’ (*note Resizing Windows::を参照)により使用されます。 -- Function: window-text-pixel-size &optional window from to x-limit y-limit mode-and-header-line この関数はWINDOWのバッファーのテキストサイズをピクセル単位でリター ンする。WINDOWは生きたウィンドウでなければならずデフォルトは選択さ れたウィンドウ。リターン値は任意のテキスト行の最大ピクセル幅と、す べてのテキスト行の最大ピクセル高さのコンス。 オプション引数FROMが非‘nil’なら、それは考慮すべき最初のテキスト位置 を指定する。デフォルトはそのバッファーのアクセス可能な最小の位置。 FROMが‘t’なら改行文字ではないアクセス可能な最小位置を使用する。オプ ション引数TOが非‘nil’なら、それは考慮すべき最後のテキスト位置を指定 する。デフォルトはそのバッファーのアクセス可能な最大の位置。TOが ‘t’なら改行文字ではないアクセス可能な最大位置を使用する。 オプション引数X-LIMITが非‘nil’なら、それはリターンされ得る最大ピク セル幅を指定する。X-LIMITが‘nil’または省略された場合には、WINDOWの body(*note Window Sizes::を参照)のピクセル幅を使用する。これは呼び 出し側がWINDOWの幅の変更を意図しない場合に有用。それ以外なら呼び出 し側はここで想定されるWINDOWのbodyの最大幅を指定すること。X座標を超 えるテキストのX-LIMITは無視される。長い行の幅の計算には多くの時間を 要する可能性があるので、いずれにせよ切り詰められるであろう長い行を 含むバッファーの場合には、特に必要に応じてこの引数の値を小さくする ことはよいアイデアである。 オプション引数Y-LIMITが非‘nil’なら、それはリターンされ得る最大ピク セル高さを指定する。Y座標を超えるテキストのY-LIMITは無視される。大 きなバッファーのピクセル高さの計算には多くの時間を要する可能性があ るので、特に呼び出し側がバッファーのサイズを知らない場合におけるこ の変数の指定は合理的である。 オプション引数MODE-AND-HEADER-LINEが‘nil’または省略された場合には、 リターン値にWINDOWのモードラインとヘッダーラインの高さを含めないこ とを意味する。これがシンボル‘mode-line’か‘header-line’のいずれかな ら、それらが存在する場合にはリターン値にそのラインの高さだけを含め る。これが‘t’なら存在する場合は両方の高さをリターン値に含める。 37.11 行の高さ ============== 各ディスプレイ行のトータル高さは、その行のコンテンツ高さにディスプレイ上 部や下部にオプションで追加される垂直行スペーシングを加えて構成されます。 行のコンテンツ高さは、もしあれば最後の改行を含む、そのディスプレイ行 の文字またはイメージの最大高さです(継続されるディスプレイ行には最後の改 行が含まれない)。特にこれより大きい高さを指定しなければ、これがデフォル トの行高さになります(これは一般的には対応するフレームのデフォルトのフォ ント高さに等しい。*note Frame Font::を参照)。 より大きい行高さを明示的に指定するためにはディスプレイ行の絶対高さ、 または垂直スペースを指定する複数の方法が存在します。しかし何を指定したか に関わらず、実際の行高さがデフォルトの高さより小さくなることはありません 。 改行はその改行で終わるディスプレイ行のトータル高さを制御するテキスト プロパティとオーバーレイプロパティ‘line-height’をもつことができます。 プロパティの値が‘t’なら改行文字はその行の表示高さにたいして効果をもた ず、可視なコンテンツだけが高さを決定します。この場合には以下で説明する ‘line-spacing’プロパティも無視されます。これはイメージ間に追加のブランク 領域をもたない、小さなイメージ(やイメージスライス)にたいして有用です。 プロパティの値が‘(HEIGHT TOTAL)’という形式のリストなら、これはディス プレイ行の_下部_に余分なスペースを追加します。最初にEmacsは、その行の_上 部_の余分なスペースを制御するための高さspecとして、HEIGHTを使用します。 それから行のトータル高さをTOTALにするために、行の_下部_に必要なスペース を追加します。この場合には、改行にたいする‘line-spacing’プロパティのすべ ての値は無視されます。 他の種類のプロパティ値は高さspec(height spec)です。これは行の高さを指 定する数値に変換されます。高さspecを記述するためには複数の方法があります 。以下はそれらが数値に変換される方法です: ‘INTEGER’ 高さspecが正の整数なら高さの値はその整数。 ‘FLOAT’ 高さspecが浮動小数点数FLOATなら高さ数値はそのフレームのデフォルト行 高さのFLOAT倍。 ‘(FACE . RATIO)’ 高さspecがこのフォーマットのコンスなら、高さ数値はフェイスFACEの高 さのRATIO倍。RATIOには任意の型の数値を指定でき、‘nil’は1のratioを意 味する。FACEが‘t’ならカレントフェイスを参照する。 ‘(nil . RATIO)’ 高さspecがこのフォーマットのコンスなら高さ数値はその行のコンテンツ 高さのRATIO倍。 したがって任意の有効な種々の高さspecによりピクセル単位で高さが決定さ れます。行のコンテンツ高さがこれより小さければ、Emacsは指定されたトータ ル高さになるように余分な垂直スペースを行の上部に追加します。 ‘line-height’プロパティを指定しない場合には、その行の高さは行のコンテ ンツ高さとに行スペーシングを追加して構成されます。Emacsの異なるさまざま な部分のテキストにたいして、行スペーシングを指定する複数の方法が存在しま す。 グラフィカルなディスプレイではフレームパラメーター‘line-spacing’ (*note Layout Parameters::を参照)を使用することにより、フレーム内のすべ ての行にたいして行スペーシングを指定できます。しかし‘line-spacing’のデフ ォルト値が非‘nil’なら、それはそのフレームのフレームパラメーター ‘line-spacing’をオーバーライドします。整数は行の下部に配するピクセル数を 指定します。浮動小数点数はフレームのデフォルト行高さに相対的にスペーシン グを指定します。 バッファーローカル変数‘line-spacing’を通じて、バッファー内のすべての 行の行スペーシングを指定できます。整数は行の下部に配するピクセル数を指定 します。浮動小数点数はデフォルトフレーム行高さに相対的にスペーシングを指 定します。これはそのフレームにたいして指定された行スペーシングをオーバー ライドします。 最後に改行は改行で終わるディスプレイ行にたいしてデフォルトフレーム行 スペーシングを広くできるテキストプロパティとオーバーレイプロパティ ‘line-spacing’、および変数‘line-spacing’をもつことができます。その値がバ ッファーやフレームのデフォルトより大きければ、その改行で終端されるディス プレイ行にはかわりにその値が使用されます。 種々の方法によりこれらのメカニズムは各行のスペーシングにたいする Lisp値を指定します。値は高さspecで、これは上述したLisp値に変換されます。 しかしこの場合には高さ数値は行高さではなく行スペーシングを指定します。 テキスト端末では行スペーシングは変更できません。 37.12 フェイス ============== “フェイス(face)”とはフォント、フォアグラウンドカラー、バックグラウンドカ ラー、オプションのアンダーライン等のテキストを表示するためのグラフィカル な属性のコレクションのことです。フェイスはEmacsがバッファー内や、同様に モードラインのようなフレームの他の部分でテキストを表示する方法を制御しま す。 フェイスを表現する1つの方法として‘(:foreground "red" :weight bold)’の ような属性のプロパティリストがあります。このようなリストは“anonymousフェ イス(anonymous face)”と呼ばれます。たとえば‘face’テキストプロパティとし てanonymousフェイスを割り当てることができ、Emacsは指定された属性でテキス トを表示するでしょう。*note Special Properties::を参照してください。 より一般的にはフェイスは“フェイス名(face name)”を通じて参照されます。 これはフェイス属性のセットに関連付けられたLispシンボル(1)です。名前つき フェイスは‘defface’マクロを使用して定義できます(*note Defining Faces::を 参照)。Emacsにはいくつかの標準名前つきフェイスが同梱されています(*note Basic Faces::を参照)。 Emacsの多くの箇所で名前つきフェイスが要求されていて、anonymousフェイ スは受け入れられません。これらには*note Attribute Functions::に記述され る関数、および変数‘font-lock-keywords’ (*note Search-based Fontification::を参照)が含まれます。特に明記しないかぎり名前つきフェイス の参照に限定して用語“フェイス”を使用することにします。 -- Function: facep object この関数はOBJECTが名前つきフェイス(フェイス名の役目をもつLispシンボ ルか文字列)なら非‘nil’、それ以外なら‘nil’をリターンする。 ---------- Footnotes ---------- (1) 後方互換のため、フェイス名の指定に文字列も使用できます。これは同 名のLispシンボルと等価です。 37.12.1 フェイスの属性 ---------------------- “フェイス属性(Face attributes)”は、フェイスの視覚的外観を決定します。以 下はすべてのフェイス属性と、それらの可能な値と効果に関するテーブルです。 以下の値とは別に各フェイス属性は値‘unspecified’をもつことができます。 この特殊な値はフェイスがその属性を直接指定しないことを意味します。 ‘unspecified’属性はEmacsにかわりに親フェイス(以下の‘:inherit’属性の記述 を参照)を参照して、それに失敗したら基礎フェイス(*note Displaying Faces::を参照)を参照することを指示します。‘default’フェイスはすべての属 性を指定しなければなりません。 これらの属性のいくつかは特定の種類のディスプレイにおいてのみ意味があ ります。ディスプレイが特定の属性を処理できなければ、その属性は無視されま す。 ‘:family’ フォントファミリーかフォントセット(文字列)。フォントファミリーに関 する詳細は*Note (emacs)Fonts::を参照のこと。関数‘font-family-list’ (以下参照)は利用可能なファミリー名のリストをリターンする。フォント セットに関する情報は*note Fontsets::を参照のこと。 ‘:foundry’ ‘:family’属性により指定されるフォントファミリーにたいする“フォント foundry” (文字列)。*note (emacs)Fonts::を参照のこと。 ‘:width’ 相対的な文字幅。これはシンボル‘ultra-condensed’、 ‘extra-condensed’、‘condensed’、‘semi-condensed’、‘normal’、 ‘semi-expanded’、‘expanded’、‘extra-expanded’、‘ultra-expanded’のい ずれかであること。 ‘:height’ フォントの高さ。もっともシンプルなケースでは1/10ポイントを単位とす る整数。 値には“基礎フェイス(underlying face)”にたいして相対的に高さを指定す る浮動小数点数、または関数も指定できる(*note Displaying Faces::を参 照)。浮動小数点数は基礎フェイスの高さをスケーリングする量を指定する 。関数値は基礎フェイスの高さを単一の引数として呼び出されて、新たな フェイスの高さをリターンする。関数が整数を引数として渡された場合に は整数をリターンしなければならない。 デフォルトフェイスの高さは整数を使用して指定しなければならない。浮 動小数点数や関数は受け入れられない。 ‘: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進カラー仕様を指定できる。*note Color Names::を参照のこと。白黒 ディスプレイでは特定のグレー色調が点描パターンで実装されている。 ‘:distant-foreground’ 代替えのフォアグラウンドカラー(文字列)。これは‘:foreground’と似てい るが、使用されるであろうフォアグラウンドカラーがバックグラウンドカ ラーに近いときのみフォアグラウンドカラーとして使用される点が異なる 。これはたとえばテキストをマーク時(リージョンフェイス)に有用。その テキストがリージョンフェイスとして可視なフォアグラウンドをもつ場合 には、そのフォアグラウンドが使用される。フォアグラウンドがリージョ ンフェイスのバックグラウンドに近ければ、テキストを可読にするために ‘:distant-foreground’が使用される。 ‘:background’ バックグラウンドカラー(文字列)。値にはシステム定義済みカラー、また は16進カラー仕様を指定できる。*note Color Names::を参照のこと。 ‘:underline’ 文字にアンダーラインを引くべきか否か、およびその方法。 ‘:underline’属性として可能な値は以下のとおり: ‘nil’ アンダーラインを引かない。 ‘t’ そのフェイスのフォアグラウンドカラーでアンダーラインを引く。 COLOR 文字列COLORで指定されたカラーでアンダーラインを引く。 ‘(:color COLOR :style STYLE)’ COLORは文字列、またはそのフェイスのフォアグラウンドカラーを意 味するシンボル‘foreground-color’。属性‘:color’の省略はフェイス のフォアグラウンドカラーの使用を意味する。STYLEは直線を意味す る‘line’、または波線を意味する‘wave’いずれかのシンボルであるこ と。属性‘:style’の省略は直線を意味する。 ‘:overline’ 文字にオーバーラインを引くべきか否か、およびそのカラー。値が‘t’なら フェイスのフォアグラウンドカラーを使用してオーバーラインを引く。値 が文字列ならそのカラーを使用してオーバーラインを引く。値‘nil’はオー バーラインを引かないことを意味する。 ‘:strike-through’ 文字に取り消し線を引くべきか否か、およびそのカラー。値は ‘:overline’で使用される値と同じ。 ‘:box’ 文字周囲に枠(box)を描画するか否か、そのカラー、枠線の幅、および3D外 観。以下は‘:box’の可能な値と意味: ‘nil’ 枠を描画しない。 ‘t’ 幅1のフォアグラウンドカラーで枠線を描画する。 COLOR 幅1のカラーCOLORで枠線を描画する。 ‘(:line-width WIDTH :color COLOR :style STYLE)’ この方法では枠のすべての形相を明示的に指定できる。値WIDTHは描 画する線の幅を指定して、デフォルトは1。負の幅-Nは基礎テキスト のスペースを占有する線幅Nを意味して、文字の高さや幅の増加を避 けることができる。 値COLORは描画するカラーを指定する。シンプルな枠線ではフェイス のフォアグラウンドカラー、3D枠線ではフェイスのバックグラウンド カラーがデフォルト。 値STYLEは3D枠線を描画するか否かを指定する。‘released-button’な ら押下された3Dボタンのような外観、‘pressed-button’なら押下され ていない3Dボタンのような外観、‘nil’または省略された場合には 2D枠線が使用される。 ‘:inverse-video’ 文字が反転表示されて表示されるべきか否か。値は‘t’ (反転表示する)か ‘nil’ (反転表示しない)のいずれか。 ‘:stipple’ バックグラウンドの点描(ビットマップ)。 値には文字列を指定できる。外部形式Xビットマップデータを含むファイル の名前であること。ファイルは変数‘x-bitmap-file-path’にリストされる ディレクトリー内で検索される。 かわりに‘(WIDTH HEIGHT DATA)’という形式のリストによりビットマップで 直接値を指定できる。ここでWIDTHとHEIGHTはピクセル単位によるサイズ、 DATAは行単位でビットマップのrawビットを含む文字列。各行は文字列内で 連続する(WIDTH + 7) / 8バイトを占める(最善の結果を得るためにはユニ バイト文字列であること)。これは各行が常に少なくとも1バイト全体を占 めることを意味する。 値が‘nil’なら点描パターンを使用しないことを意味する。 これは特定のグレー色調を処理するために自動的に使用されるので、通常 はstipple属性のセットは必要ない。 ‘:font’ そのフェイスの表示に使用されるフォント。値はフォントオブジェクトで あること。フォントオブジェクト、フォントスペース、フォントエンティ ティーに関する情報は*note Low-Level Font::を参照のこと。 ‘set-face-attribute’ (*note Attribute Functions::を参照)を使用して この属性を指定する際にはフォントspec、フォントエンティティー、また は文字列を与えることもできる。Emacsはそのような値を適切なフォントオ ブジェクトに変換して、実際の属性値としてそのフォントオブジェクトを 格納する。文字列を指定する場合には、その文字列のコンテンツはフォン ト名であること(*note (emacs)Fonts::を参照)。フォント名がワイルドカ ードを含むXLFDなら、Emacsはそれらのワイルドカードに最初にマッチする フォントを選択する。この属性の指定により‘:family’、‘:foundry’、 ‘:width’、‘:height’、‘:weight’、‘:slant’の属性値も変更される。 ‘:inherit’ 属性を継承するフェイス名かフェイス名のリスト。継承フェイス由来の属 性は基礎フェイスより高い優先度で、基礎フェイスの場合と同じような方 法でマージされる(*note Displaying Faces::を参照)。フェイスのリスト が使用された場合には、リスト内で先頭側フェイスの属性が末尾側フェイ スの属性をオーバーライドする。 -- Function: font-family-list &optional frame この関数は利用可能なフォントファミリー名のリストをリターンする。オ プション引数FRAMEはそのテキストが表示されるフレームを指定する。これ が‘nil’なら選択されたフレームが使用される。 -- User Option: underline-minimum-offset この変数はアンダーラインが引かれたテキスト表示時に、ベースラインと アンダーライン間の最小距離をピクセル単位で指定する。 -- User Option: x-bitmap-file-path この変数は‘:stipple’属性のビットマップファイルを検索するディレクト リーのリストを指定する。 -- Function: bitmap-spec-p object これはOBJECT、‘:stipple’ (上記参照)での使用に適した有効なビットマッ プ仕様なら‘t’、それ以外なら‘nil’をリターンする。 37.12.2 フェイスの定義 ---------------------- フェイスを定義する通常の方法は‘defface’マクロを通じて定義する方法です。 このマクロはフェイス名(シンボル)をデフォルトの“フェイスspec(face spec)”と 関連付けます。フェイスspecとは任意の与えられた端末上でフェイスがどの属性 をもつべきかを指定する構文です。たとえばあるフェイスspecは高カラー端末で はあるフォアグラウンドカラーし、低カラー端末では異なるフォアグラウンドカ ラーを指定するかもしれません。 値がフェイス名であるような変数を作りたがる人がいます。ほとんどの場合 には、これは必要ありません。通常の手順は‘defface’でフェイスを定義して、 その名前を直接使用することです。 -- Macro: defface face spec doc [keyword value]... このマクロはSPECによりデフォルトフェイスspecが与えられるような名前 つきフェイスとしてFACEを宣言する。シンボルFACEはクォートせずに ‘-face’で終わらないこと(冗長かもしれない)。引数DOCはフェイスにたい するドキュメント文字列。追加のKEYWORD引数は‘defgroup’や ‘defcustom’の場合と同じ意味をもつ(*note Common Keywords::を参照)。 FACEがすでにデフォルトフェイスspecをもつ場合には、このマクロは何も 行わない。 デフォルトフェイスspecは何もカスタマイゼーション(*note Customization::を参照)の効果がないときのFACEの外観を決定する。 FACEが(Customテーマやinitファイルから読み込んだカスタマイズにより )すでにカスタマイズ済みなら、その外観はデフォルトフェイスspecの SPECをオーバーライドするカスタムフェイスspecにより決定される。しか しその後カスタマイゼーションが削除されたら、FACEの外観は再びそのデ フォルトフェイスspecにより決定されるだろう。 例外としてEmacs Lispモードで‘C-M-x’ (‘eval-defun’)から‘defface’を評 価した場合には、‘eval-defun’の特別な機能により‘defface’が何を指示す るかをフェイスが正確に反映するように、そのフェイス上の任意のカスタ ムフェイスをオーバーライドする。 SPEC引数は異なる種別の端末上でそのフェイスがどのような外観で表示さ れるべきかを示す“フェイスspec”。これは各要素が以下の形式であるよう なalistであること (DISPLAY . PLIST) DISPLAYは端末のクラス(以下参照)を指定する。PLISTはそのような端末上 でフェイスがどのような外観かを指定するフェイス属性とその値からなる プロパティリストであること。後方互換性のために‘(DISPLAY PLIST)’のよ うに要素を記述することもできる。 SPECの要素のDISPLAYの部分は、その要素がマッチする端末を決定する。与 えられた端末にたいして複数の要素がマッチした場合には、最初にマッチ した要素がその端末にたいして使用される。DISPLAYには以下の3つが可能: ‘default’ SPECのこの要素はどの端末にもマッチしない。かわりにすべての端末 に適用されるデフォルトを指定する。この要素が使用する場合には、 SPECの最初の要素でなければならない。この後の要素はこれらのデフ ォルトの一部、またはすべてをオーバーライドできる。 ‘t’ SPECのこの要素はすべての端末にマッチする。したがってSPECの後続 要素が使用されることはない。‘t’は通常はSPECの最後(か唯一)の要 素として使用される。 リスト DISPLAYがリストなら各要素は‘(CHARACTERISTIC VALUE...)’という形 式をもつこと。ここでCHARACTERISTICは端末をクラス分けする方法、 VALUEはDISPLAYに適用されるべき可能なクラス分類。 CHARACTERISTICに利用可能な値は: ‘type’ その端末が使用するウィンドウシステムの種類で‘graphic’ (任 意のグラフィック対応ディスプレイ)、‘x’、‘pc’ (MS-DOSコン ソール)、‘w32’ (MS Windows 9X/NT/2K/XP)、または‘tty’ (グ ラフィック非対応ディスプレイ)のいずれか。*note window-system: Window Systems.を参照のこと。 ‘class’ その端末がサポートするカラーの種類であり‘color’、 ‘grayscale’か‘mono’のいずれか。 ‘background’ バックグラウンドの種類であり‘light’か‘dark’のいずれか。 ‘min-colors’ その端末がサポートするべき最小カラー数を表す整数。端末の ‘display-color-cells’の値が少なくとも指定された整数ならそ の端末にマッチ。 ‘supports’ その端末がVALUE...で与えられたフェイス属性を表示可能か否 か(*note Face Attributes::を参照)。このテストがどのように 行われるかについてのより正確な情報は*note 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を格納します(*note Symbol Properties::を参照)。‘saved-face’プロパティはカスタマイゼーションバッフ ァーを使用してユーザーが保存した任意のフェイスspecを格納します。 ‘customized-face’プロパティはカレントセッションにたいしてカスタマイズさ れた保存されていないフェイスspecを格納します。そして‘theme-face’プロパテ ィはそのフェイスにたいするアクティブなカスタマイゼーションセッティングと 、フェイスspecをもつCustomテーマを関連付けるalistです。そのフェイスのド キュメント文字列は‘face-documentation’プロパティ内に格納されます。 フェイスは通常は‘defface’を使用して1回だけ宣言されて、その外観にたい するそれ以上の変更はCustomizeフレームワーク(Customizeユーザーインターフ ェースか‘custom-set-faces’関数を通じて。*note Applying Customizations::を 参照)、またはフェイスリマッピング(*note Face Remapping::を参照)により行 われます。Lispから直接フェイスspec変更を要する稀な状況では ‘face-spec-set’関数を使用できます。 -- Function: face-spec-set face spec &optional spec-type この関数は‘face’にたいするフェイスspecとしてSPECを適用する。SPECは 上述した‘defface’にたいするフェイスspecであること。 この関数はもしFACEが既存のものでなければ有効なフェイス名として FACEを定義して、既存フレームのその属性の(再)計算も行う。 引数SPEC-TYPEはどのspecをセットするべきかを決定する。これが‘nil’か ‘face-override-spec’なら、この関数は“オーバーライドspec(override spec)”をセットする。これはFACE上の他のすべてのフェイスspecをオーバ ーライドする。‘customized-face’や‘saved-face’なら、この関数はカスタ マイズされたspec、または保存されたカスタムspecをセットする。 ‘face-defface-spec’ならこの関数はデフォルトフェイスspec(‘defface’に よりセットされるものと同一)をセットする。‘reset’ならこの関数は FACEからすべてのカスタマイゼーションspecとオーバーライドspecをクリ アーする(この場合にはSPECの値は無視される)。SPEC-TYPEにたいする他の すべての値は内部的な使用のために予約済み。 37.12.3 フェイス属性のための関数 -------------------------------- このセクションでは名前つきフェイスの属性に直接アクセスしたり変更する関数 を説明します。 -- Function: face-attribute face attribute &optional frame inherit この関数はFRAME上のFACEにたいする属性ATTRIBUTEの値をリターンする。 FRAMEが‘nil’ならそれは選択されたフレームを意味する(*note Input Focus::を参照)。FRAMEが‘t’ならこの関数は新たに作成されるフレームに たいして指定された属性の値をリターンする(これは下記の ‘set-face-attribute’を使用して何らかの値を指定していなければ通常は ‘unspecified’)。 INHERITが‘nil’ならFACEにより定義される属性だけが考慮されるのでリタ ーンされる値は‘unspecified’、または相対的な値かもしれない。 INHERITが非‘nil’ならFACEのATTRIBUTEの定義が、‘:inherit’属性で指定さ れたフェイスとマージされる。しかしリターンされる値は依然として ‘unspecified’、または相対的な値かもしれない。INHERITがフェイスかフ ェイスのリストなら、指定された絶対的な値になるまで結果はそのフェイ ス(1つ以上)と更にマージされる。 リターン値が指定されていて、かつ絶対的であることを保証するためには INHERITにたいして‘default’の値を使用すること。(常に完全に指定される )‘default’フェイスとマージすることにより、すべての未指定や相対的な 値は解決されるだろう。 たとえば (face-attribute 'bold :weight) ⇒ bold -- Function: face-attribute-relative-p attribute value この関数はVALUEがフェイス属性ATTRIBUTEの値として使用された際に相対 的なら非‘nil’をリターンする。これはフェイスリスト内の後続のフェイス 、または継承した他のフェイスが由来となる任意の値で完全にオーバーラ イドするのではなく、それが変更されるであろうことを意味する。 すべての属性にたいして‘unspecified’は相対的な値。‘:height’にたいし ては浮動小数点数と関数値も相対的である。 たとえば: (face-attribute-relative-p :height 2.0) ⇒ t -- Function: face-all-attributes face &optional frame この関数はFACEの属性のalistをリターンする。結果の要素は ‘(ATTR-NAME . ATTR-VALUE)’という形式の名前/値ペアー。オプション引数 FRAMEはリターンするべきFACEの定義をもつフレームを指定する。省略か ‘nil’ならリターン値には新たに作成されるフレームにたいするFACEのデフ ォルト属性が記述される。 -- Function: merge-face-attribute attribute value1 value2 VALUE1がフェイス属性ATTRIBUTEにたいして相対的な値なら、基礎的な値 VALUE2とマージしてリターンする。それ以外の場合にはVALUE1がフェイス 属性ATTRIBUTEにたいして絶対的な値ならVALUE1を変更せずにリターンする 。 Emacsは通常は各フレームのフェイス属性を自動的に計算するために、各フェ イスのフェイスspecを使用します(*note Defining Faces::を参照)。関数 ‘set-face-attribute’は特定またはすべてのフレームのフェイスに直接属性を割 り当てることにより、この計算をオーバーライドできます。この関数は主として 内部的な使用を意図したものです。 -- Function: set-face-attribute face frame &rest arguments この関数はFRAMEにたいするFACEの1つ以上の属性をセットする。この方法 で指定された属性はFACEに属するフェイスspec(1つ以上)をオーバーライド する。 余分の引数ARGUMENTSはセットするべき属性と値を指定する。これらは (‘:family’や‘:underline’のような)属性名と値が交互になるように構成さ れていること。つまり、 (set-face-attribute 'foo nil :weight 'bold :slant 'italic) これは属性‘:weight’を‘bold’、.属性‘:slant’を‘italic’にセットする。 FRAMEが‘t’ならこの関数は新たに作成されるフレームにたいするデフォル ト属性をセットする。FRAMEが‘nil’ならこの関数はすべての既存フレーム 、同様に新たに作成されるフレームにたいしてその属性をセットする。 以下のコマンドと関数は主として古いバージョンのEmacsにたいする互換性の ために提供されます。これらは‘set-face-attribute’を呼び出すことにより機能 します。これらのFRAME引数にたいする値‘t’と‘nil’は、 ‘set-face-attribute’や‘face-attribute’の場合と同様に処理されます。コマン ドがインタラクティブに呼び出された場合にはミニバッファーを使用して引数を 読み取ります。 -- Command: set-face-foreground face color &optional frame -- Command: set-face-background face color &optional frame これらはそれぞれFACEの‘:foreground’属性、または‘:background’属性に COLORをセットする。 -- Command: set-face-stipple face pattern &optional frame これはFACEの‘:stipple’属性にPATTERNをセットする。 -- Command: set-face-font face font &optional frame これはFACEの‘:font’属性にFONTをセットする。 -- Function: set-face-bold face bold-p &optional frame これはFACEの‘:weight’属性にたいしてBOLD-Pが‘nil’ならNORMAL、それ以 外ならBOLDをセットする。 -- Function: set-face-italic face italic-p &optional frame これはFACEの‘:slant’属性にたいしてITALIC-Pが‘nil’ならNORMAL、それ以 外ならITALICをセットする。 -- Function: set-face-underline face underline &optional frame これはFACEの‘:underline’属性にUNDERLINEをセットする。 -- Function: set-face-inverse-video face inverse-video-p &optional frame これはFACEの‘:inverse-video’属性にINVERSE-VIDEO-Pをセットする。 -- Command: invert-face face &optional frame これはフェイスFACEのフォアグラウンドカラーとバックグラウンドカラー を交換する。 以下はフェイスの属性を調べる関数です。これらは主として古いバージョン のEmacsとの互換性のために提供されます。これらにたいしてFRAMEを指定しなけ れば選択されたフレーム、‘t’なら新たなフレームにたいするデフォルトデータ を参照します。フェイスがその属性にたいして何の値も定義していなければ ‘unspecified’がリターンされます。INHERITが‘nil’ならそのフェイスにより直 接定義された属性だけがリターンされます。INHERITが非‘nil’ならそのフェイス の‘:inherit’属性により指定される任意のフェイス、INHERITがフェイスまたは フェイスのリストなら指定された属性が見つかるまでそれらも考慮します。リタ ーンされる値が常に指定された値であることを保証するためにはINHERITに値 ‘default’を使用してください。 -- Function: face-font face &optional frame character この関数はフェイスFACEのフォント名をリターンする。 オプション引数FRAMEが指定されたら、そのフレームのFACEのフォント名を リターンする。FRAMEが省略か‘nil’なら選択されたフレームを使用する。 そしてこの場合には、オプションの3つ目の引数CHARACTERが与えられると 、CHARACTERにたいして使用されるフォント名をリターンする。 -- Function: face-foreground face &optional frame inherit -- Function: face-background face &optional frame inherit これらの関数はそれぞれフェイスFACEのフォアグラウンドカラーとバック グラウンドカラーを文字列としてリターンする。 -- Function: face-stipple face &optional frame inherit この関数はフェイスFACEのバックグラウンド点描パターンの名前、もしな ければ‘nil’をリターンする。 -- Function: face-bold-p face &optional frame inherit この関数はFACEの‘:weight’属性がnormalよりbold寄り(‘semi-bold’、 ‘bold’、‘extra-bold’、‘ultra-bold’のいずれか)なら非‘nil’、それ以外 なら‘nil’をリターンする。 -- Function: face-italic-p face &optional frame inherit この関数はFACEの‘:slant’属性が‘italic’か‘oblique’なら非‘nil’、それ 以外なら‘nil’をリターンする。 -- Function: face-underline-p face &optional frame inherit この関数はフェイスFACEが非‘nil’の‘:underline’属性を指定すれば非 ‘nil’をリターンする。 -- Function: face-inverse-video-p face &optional frame inherit この関数はフェイスFACEが非‘nil’の‘:inverse-video’属性を指定すれば非 ‘nil’をリターンする。 37.12.4 フェイスの表示 ---------------------- Emacsが与えられたテキスト断片を表示する際には、そのテキストの視覚的外観 は異なるソースから描画されるフェイスにより決定されるかもしれません。これ ら種々のソースが特定の文字にいたいして複数のフェイスを指定する場合には、 Emacsはそれらのさまざまなフェイスの属性をマージします。以下にEmacsがフェ イスをマージする順序を優先度順に記します: • そのテキストが特別なグリフで構成される場合には、そのグリフは特定の フェイスを指定できる。*note Glyphs::を参照のこと。 • アクティブなリージョンにテキストがある場合には、Emacsは‘region’フェ イスを使用してそれをハイライトする。*note (emacs)Standard Faces::を 参照のこと。 • 非‘nil’の‘face’属性をもつオーバーレイにテキストがある場合には、 Emacsはそのプロパティにより指定されるフェイス(1つ以上)を適用する。 そのオーバーレイが‘mouse-face’プロパティをもち、マウスがそのオーバ ーレイに十分に近ければEmacsはかわりに‘mouse-face’で指定されるフェイ スかフェイス属性を適用する。*note Overlay Properties::を参照のこと 。 1つの文字を複数のオーバーレイがカバーする場合には、高優先度のオーバ ーレイが低優先度のオーバーレイをオーバーライドする。*note Overlays::を参照のこと。 • そのテキストが‘face’や‘mouse-face’プロパティを含む場合には、Emacsは 指定されたフェイスやフェイス属性を適用する。*note Special Properties::を参照のこと(これはFont Lockモードのフェイス適用方法。 *note Font Lock Mode::を参照)。 • そのテキストが選択されたウィンドウのモードラインにある場合には、 Emacsは‘mode-line’フェイスを適用する。選択されていないウィンドウの モードラインではEmacsは‘mode-line-inactive’フェイスを使用する。ヘッ ダーラインにたいしてはEmacsは‘header-line’フェイスを適用する。 • 先行ステップの間に与えられた属性が指定されなければ、Emacsは ‘default’フェイスの属性を適用する。 各ステージにおいてフェイスが有効な‘:inherit’属性をもつ場合には、 Emacsは値‘unspecified’をもつすべての属性が、親フェイス(1つ以上)由来で描 画に使用される対応する値をもつものとして扱います。*note Face Attributes::を参照してください。親フェイスでも属性がunspecifiedのままか もしれないことに注意してください。その場合にはフェイスマージの次レベルで もその属性はunspecifiedのままです。 37.12.5 フェイスのリマップ -------------------------- 変数‘face-remapping-alist’はあるフェイスの外観のバッファーローカル、また はグローバルな変更にたいして使用されます。たとえばこれは ‘text-scale-adjust’コマンド(*note (emacs)Text Scale::を参照)の実装に使用 されています。 -- Variable: face-remapping-alist この変数の値は要素が‘(FACE . REMAPPING)’という形式をもつalist。これ によりEmacsはフェイスFACEをもつ任意のテキストを、通常のFACEの定義で はなくREMAPPINGで表示する。 REMAPPINGにはテキストプロパティ‘face’にたいして適切な任意のフェイス spec、すなわちフェイス(フェイス名か属性/値ペアーのプロパティリスト )、またはフェイスのリストのいずれかを指定できる。詳細は*note Special Properties::の‘face’テキストプロパティの記述を参照のこと。 REMAPPINGはリマップされるフェイスにたいる完全な仕様としての役目をも つ。これは通常のFACEを変更せずに置き換える。 ‘face-remapping-alist’がバッファーローカルなら、そのローカル値はそ のバッファーでのみ効果をもつ。 注意: フェイスのリマッピングは再帰的ではない。REMAPPINGが同じフェイ ス名FACEを参照する場合には、直接またはREMAPPING内の他の何らかのフェ イスの‘:inherit’属性を通じて、その参照はFACEの通常の定義を使用する 。たとえば‘mode-line’フェイスが‘face-remapping-alist’内の以下のエン トリーでリマップされるなら: (mode-line italic mode-line) ‘mode-line’フェイスの新たな定義は‘italic’フェイス、および(リマップ されていない)_通常_の‘mode-line’フェイスの定義から継承される。 以下の関数は‘face-remapping-alist’にたいする高レベルなインターフェー スを実装します。ほとんどのLispコードはリマッピングが他の場所に適用されて しまうのを避けるために、‘face-remapping-alist’を直接セットするのではなく これらの関数を使用するべきです。これらの関数はバッファーローカルなリマッ ピングを意図しており、すべてが副作用として‘face-remapping-alist’をバッフ ァーローカルにします。これらは以下の形式の‘face-remapping-alist’エントリ ーを管理します (FACE RELATIVE-SPEC-1 RELATIVE-SPEC-2 ... BASE-SPEC) 上述したようにRELATIVE-SPEC-NとBASE-SPECはそれぞれフェイス名か属性/値ペ アーのプロパティリストです。“相対的リマッピング(relative remapping)”エン トリーRELATIVE-SPEC-Nはそれぞれ関数‘face-remap-add-relative’と ‘face-remap-remove-relative’により管理されます。これらはテキストサイズ変 更のような単純な変更を意図しています。“ベースリマッピング(base remapping)”エントリーBASE-SPECは最低の優先度をもち、関数 ‘face-remap-set-base’と‘face-remap-reset-base’により管理されます。これは メジャーモードが制御下のバッファーでフェイスをリマップするために用いるこ とを意図しています。 -- Function: face-remap-add-relative face &rest specs この関数はカレントバッファー内のフェイスFACEにたいして、相対的リマ ッピングとしてSPECS内にフェイスspecを追加する。残りの引数SPECSはフ ェイス名のリスト、または属性/値ペアーのプロパティリストのいずれかの 形式であること。 リターン値はcookieとしての役目をもつLispオブジェクト。後でそのリマ ッピングの削除を要する場合には、引数として ‘face-remap-remove-relative’にこのオブジェクトを渡すことができる。 ;; 'escape-glyph'フェイスを'highlight'と'italic' ;; を組み合わせたフェイスにリマップする (face-remap-add-relative 'escape-glyph 'highlight 'italic) ;; 'default'フェイスのサイズを50%増加: (face-remap-add-relative 'default :height 1.5) -- Function: face-remap-remove-relative cookie この関数は以前‘face-remap-add-relative’で追加された相対的リマッピン グを削除する。COOKIEはリマッピングが追加されたときに ‘face-remap-add-relative’がリターンしたLispオブジェクトであること。 -- Function: face-remap-set-base face &rest specs この関数はカレントバッファー内のFACEのベースリマッピングをSPECSにセ ットする。SPECSが空なら‘face-remap-reset-base’(以下参照)を呼び出し たようにデフォルトベースリマッピングがリストアされる。これは単一の 値‘nil’を含むSPECSとは異なることに注意。これは逆の結果をもたらす (FACEのグローバル定義は無視される)。 これはグローバルなフェイス定義を継承したデフォルトのBASE-SPECを上書 きするので、必要ならそのような継承を追加するのは呼び出し側の責任で ある。 -- Function: face-remap-reset-base face この関数はFACEのベースリマッピングに、FACEのグローバル定義から継承 したデフォルト値にセットする。 37.12.6 フェイスを処理するための関数 ------------------------------------ 以下はフェイスの作成や処理を行う追加の関数です。 -- Function: face-list この関数はすべての定義済みフェイス名のリストをリターンする。 -- Function: face-id face この関数はフェイスFACEの“フェイス番号(face number)”をリターンする。 これはEmacs内の低レベルでフェイスを一意に識別する番号。フェイス番号 によるフェイス参照を要するのは稀である。 -- Function: face-documentation face この関数はフェイスFACEのドキュメント文字列、指定されていなければ ‘nil’をリターンする。 -- Function: face-equal face1 face2 &optional frame これはフェイスFACE1とフェイスFACE2が表示にたいして同じ属性をもつな ら‘t’をリターンする。 -- Function: face-differs-from-default-p face &optional frame これはフェイスFACEの表示がデフォルトフェイスと異なるなら非‘nil’をリ ターンする。 “フェイスエイリアス(face alias)”はあるフェイスにたいして等価な名前を 提供します。エイリアスシンボルの‘face-alias’プロパティに対象となるフェイ ス名を与えることによってフェイスエイリアスを定義できます。以下の例では ‘mode-line’フェイスにたいするエイリアスとして‘modeline’を作成します。 (put 'modeline 'face-alias 'mode-line) -- Macro: define-obsolete-face-alias obsolete-face current-face when このマクロはCURRENT-FACEのエイリアスとして‘obsolete-face’を定義する とともに、将来に削除されるかもしれないことを示すためにobsolete(時代 遅れ)とマークする。WHENは‘obsolete-face’がobsoleteになる時期を示す 文字列であること(通常はバージョン番号文字列)。 37.12.7 フェイスの自動割り当て ------------------------------ 以下のフックはバッファー内のテキストに自動的にフェイスを割り当てるために 使用されます。これはJit-Lockモードの実装の一部でありFont-Lockにより使用 されます。 -- Variable: fontification-functions この変数は再表示を行う直前にEmacsの再表示により呼び出される関数のリ ストを保持する。これらはFont Lockが有効でないときでも呼び出される。 Font Lockモードが有効なら、この変数は通常は単一の関数 ‘jit-lock-function’だけを保持する。 関数はバッファー位置POSを単一の引数としてリストされた順に呼び出され る。これらはカレントバッファー内のPOSで開始されるテキストにたいして 集合的にフェイスの割り当てを試みること。 関数は‘face’プロパティをセットすることにより割り当てるフェイスを記 録すること。またフェイスを割り当てたすべてのテキストに非‘nil’の ‘fontified’プロパティも追加すること。このプロパティは再表示にたいし て、そのテキストにたいしてそのフェイスがすでに割り当て済みであるこ とを告げる。 POSの後の文字がすでに非‘nil’の‘fontified’プロパティをもつがフォント 表示化を要さない場合には、何も行わない関数を追加するのがおそらくよ いアイデアである。ある関数が前の関数による割り当てをオーバーライド する場合には、実際に問題となるのは最後の関数終了後のプロパティであ る。 効率化のために通常は各呼び出しにおいて400から600前後の文字にフェイ スを割り当てるように、これらの関数を記述することを推奨する。 37.12.8 基本的なフェイス ------------------------ テキストにたいしてEmacs Lispプログラムが何らかのフェイス割り当てを要する 場合には、完全に新たなフェイスを定義するより特定の既存フェイス、またはそ れらを継承したフェイスを使用するほうがよいアイデアである場合がしばしばあ ります。Emacsに特定の外観を与えるために別のユーザーが基本フェイス(basic face)をカスタマイズしていても、この方法なら追加のカスタマイズなしでプロ グラムは適合することでしょう。 以下にEmacsが定義する基本フェイスのいくつかをリストしました。これらに 加えて、ハイライトがFont Lockモードによりまだ処理されていなかったり、い くつかのFont Lockフェイスが使用されていなければ、構文的ハイライトのため にFont Lockフェイスを使うようにしたいと思うかもしれません。*note Faces for Font Lock::を参照してください。 ‘default’ 属性がすべて指定されたデフォルトフェイス。他のすべてのフェイスは暗 にこのフェイスを継承する。未指定(unspecified)な任意の属性は、このフ ェイスの属性をデフォルトとする(*note Face Attributes::を参照)。 ‘bold’ ‘italic’ ‘bold-italic’ ‘underline’ ‘fixed-pitch’ ‘variable-pitch’ これらは名前に示されるような属性をもち(‘bold’はboldの‘:weight’属性 をもつ)、それ以外のすべての属性は未指定(そのために‘default’により与 えられる)。 ‘shadow’ テキストの淡色表示(dimmed out)用。たとえばこれはミニバッファー内で 無視されるファイル名部分に使用される(*note Minibuffers for File Names: (emacs)Minibuffer File.を参照)。 ‘link’ ‘link-visited’ ユーザーを別のバッファーや位置へと送るクリック可能テキストボタン用 。 ‘highlight’ 一時的に強調するべきテキスト範囲用。たとえば一般的にカーソルのハイ ライトには‘mouse-face’プロパティが割り当てられる(*note Special Properties::を参照)。 ‘match’ ‘isearch’ ‘lazy-highlight’ それぞれ定型検索(permanent search)のマッチ、インタラクティブ検索の マッチ、カレントのインタラクティブな検索のマッチ以外のlazyハイライ トにたいするテキスト用。 ‘error’ ‘warning’ ‘success’ エラー、警告、成功に関するテキスト用。たとえば‘*Compilation*’内のメ ッセージにたいして使用される。 37.12.9 フォントの選択 ---------------------- Emacsがグラフィカルなディスプレイ上で文字を描画可能になる前に、まずその 文字にたいする“フォント(font)”を選択しなければなりません(1)。*note (emacs)Fonts::を参照してください。Emacsは通常はその文字に割り当てられた フェイス、特にフェイス属性‘:family’、‘:weight’、‘:slant’、‘:width’(*note Face Attributes::を参照)にもとづいて自動的にフォントを選択します。フォン トの選択は表示される文字にも依存します。表示できるのは文字セットが限定さ れているフォントもいくつかあります。利用可能なフォントがこの要件を完全に 満たさなければEmacsは“もっとも近いフォント(closest matching font)”を探し ます。このセクション内の変数はEmacsがこの選択を行う方法を制御します。 -- User Option: face-font-family-alternatives あるfamilyが指定されたが存在しなければ、この変数は試みるべき代替え のフォントファミリーを指定する。各要素は以下の形式をもつ: (FAMILY ALTERNATE-FAMILIES...) FAMILYが指定されたが利用できなければ、EmacsはALTERNATE-FAMILIESで与 えられるファミリーで存在するものが見つかるまで1つずつファミリーを試 みる。 -- User Option: face-font-selection-order 希望するすべてのフェイス属性(‘:width’、‘:height’、‘:weight’、 ‘:slant’)に完全にマッチするフォントが存在しなければ、この変数はもっ とも近いフォントの選択時に考慮すべきこれらの属性の順序を指定する。 値はこれらの属性シンボルを重要度降順で含むリストであること。デフォ ルトは‘(:width :height :weight :slant)’。 フォント選択はまずこのリスト内の最初の属性にたいして利用可能な最適 マッチを探す。その後に、この方法で最適なフォントの中から2つ目の属性 にたいして最適なマッチを検索、...のように選択を行う。 属性‘:weight’と‘:width’は‘normal’を中心とする範囲のようなシンボリッ ク値をもつ。より極端(‘normal’から離れた)なマッチは、より極端ではな い(‘normal’に近い)マッチより幾分優先される。これは可能なかぎり非 normalなフェイスが、normalなフェイスとは対照的になることを保証する ようにデザインされている。 この変数が違いを生むケースの例はデフォルトフォントに等価なイタリッ クがない場合である。デフォルトの順では‘italic’フェイスはデフォルト のフォントに類似した非イタリックのフォントを使用するだろう。しかし ‘:height’の前に‘:slant’を配置すると、‘italic’フェイスはたとえ heightが同じでなくともイタリックフォントを使用するだろう。 -- User Option: face-font-registry-alternatives この変数はregistryが指定されたがそれが存在しない場合に試みるべき代 替えのフォントレジストリーを指定する。各要素は以下の形式をもつ: (REGISTRY ALTERNATE-REGISTRIES...) REGISTRYが指定されたが利用できなければ、Emacsは ALTERNATE-REGISTRIES内で存在するレジストリーが見つかるまで他のレジ ストリーを1つずつ試みる。 Emacsがスケーラブルフォントを使用するようにできますがデフォルトではそ れらを使用しないようになっています。 -- User Option: scalable-fonts-allowed この変数はどのスケーラブルフォントを使用するかを制御する。値‘nil’ (デフォルト)はスケーラブルフォントを使用しないことを意味する。‘t’は そのテキストにたいして適切と思われる任意のスケーラブルフォントを使 用することを意味する。 それ以外なら値は正規表現のリストであること。その場合には名前がこの リスト内の正規表現にマッチする任意のスケーラブルフォントの使用が有 効になる。たとえば、 (setq scalable-fonts-allowed '("iso10646-1$")) これはレジストリーが‘iso10646-1’のようなスケーラブルフォントの使用 を可能にする。 -- Variable: face-font-rescale-alist この変数は特定のフォントにたいするスケーリングを指定する。値は以下 の形式の要素をもつリストであること (FONTNAME-REGEXP . SCALE-FACTOR) 使用しようとするフォントの名前がFONTNAME-REGEXPにマッチする場合には 、これはファクターSCALE-FACTORに対応した同様な大きさのフォントの選 択を指示する。特定のフォントが提示する通常のheightやwidthが大きい、 または小さい場合にフォントサイズを正規化するためにこの機能を使用で きるだろう。 ---------- Footnotes ---------- (1) このコンテキストでは用語“font”はFont Lock(*note Font Lock Mode::を 参照)にたいして何も行いません。 37.12.10 フォントの照会 ----------------------- -- Function: x-list-fonts name &optional reference-face frame maximum width この関数はNAMEにマッチする利用可能なフォント名のリストをリターンす る。NAMEはFontconfig、GTK、またはXLFDのいずれかのフォーマットによる フォント名を含む文字列であること(*note (emacs)Fonts::を参照)。 XLFD文字列ではワイルドカード文字が使用できる。‘*’文字は任意の部分文 字列、‘?’は任意の単一文字にマッチする。フォント名のマッチングでは case(大文字小文字)の違いは無視される。 オプション引数REFERENCE-FACEとFRAMEが指定された場合には、リターンさ れるリストにはその時点でフレームFRAME上でのREFERENCE-FACE (フェイス 名)と同じサイズのフォントだけが含まれる。 オプション引数MAXIMUMはリターンされるフォント数の制限をセットする。 これが非‘nil’ならリターン値は最初にマッチしたMAXIMUM個のフォントの 後が切り捨てられる。MAXIMUMに小さい値を指定すれば、そのパターンに多 くのフォントがマッチするような場合に関数をより高速にできる。 オプション引数WIDTHは希望するフォントの幅を指定する。これが非 ‘nil’なら、この関数は文字の幅(平均)がREFERENCE-FACEのWIDTH倍の幅で あるようなフォントだけをリターンする。 -- Function: x-family-fonts &optional family frame この関数はFRAME上のファミリーFAMILYにたいして利用可能なフォントを記 述するリストをリターンする。FAMILYが省略か‘nil’ならこのリストはすべ てのファミリーに適用されて、それはすなわち利用可能なすべてのフォン トを含む。それ以外ならFAMILYは文字列であること。これにはワイルドカ ード‘?’と‘*’を含めることができる。 このリストはFRAMEのあるディスプレイを記述する。FRAMEが省略か‘nil’な ら、これは選択されたフレームのディスプレイに適用される(*note Input Focus::を参照)。 このリスト内の各要素は以下の形式のベクターであること: [FAMILY WIDTH POINT-SIZE WEIGHT SLANT FIXED-P FULL REGISTRY-AND-ENCODING] 最初の5つの要素はフェイス属性に対応する。あるフェイスにたいしてこれ らの属性を指定した場合には、そのフォントが使用されるだろう。 最後の3つの要素は、そのフォントに関する追加の情報を与える。そのフォ ントが固定ピッチ(fixed-pitch)でなければFIXED-Pは非‘nil’。FULLはその フォントのフルネーム、REGISTRY-AND-ENCODINGはそのフォントのレジスト リーとエンコーディングを与える。 37.12.11 フォントセット ----------------------- “フォントセット(fontset)”とは、それぞれが文字コードの範囲に割り当てられ るフォントのリストのことです。個々のフォントではEmacsがサポートする文字 の全範囲を表示できませんが、フォントセットであれば表示することができます 。フォントのようにフォントセットは名前をもつことができ、フレームやフェイ スにたいしてフォントを指定する際に、フォント名としてフォントセット名を使 用できます。以下はLispプログラム制御下でのフォントセット定義に関する情報 です。 -- Function: create-fontset-from-fontset-spec fontset-spec &optional style-variant-p noerror この関数は仕様文字列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フィールドにワイルドカード‘*’をもちます。 -- Function: set-fontset-font name character font-spec &optional frame add この関数は指定されたCHARACTERにたいして、FONT-SPECのフォントマッチ ングを使用するように既存のフォントセットNAMEを変更する。 NAMEが‘nil’ならこの関数はFRAMEのフォントセット、FRAMEが‘nil’なら選 択されたフレームのフォントセットを変更する。 NAMEが‘t’ならこの関数はshort名が‘fontset-default’であるようなデフォ ルトフォントセットを変更する。 CHARACTERには‘(FROM . TO)’のようなコンスを指定できる。ここでFROMと TOは文字コードポイント。この場合には範囲FROMからTO (両端を含む)まで のすべての文字にたいしてFONT-SPECを使用する。 CHARACTERには文字セットも指定できる。この場合にはその文字セット内の すべての文字にたいしてFONT-SPECを使用する。 CHARACTERにはスクリプト名も指定できる。この場合にはその文字セット内 のすべての文字にたいしてFONT-SPECを使用する。 FONT-SPECは関数‘font-spec’が作成したfont-specオブジェクトかもしれな い(*note Low-Level Font::を参照)。 FONT-SPECにはコンス‘(FAMILY . REGISTRY)’を指定できる。ここで FAMILYはフォントのファミリー名(先頭にfoundry名が含まれるかもしれな い)、REGISTRYはフォントのレジストリー名(末尾にエンコーディング名が 含まれるかもしれない)。 FONT-SPECにはフォント名文字列も指定できる。 FONT-SPECには、指定されたCHARACTERにたいするフォントが存在しないこ とを明示的に指定する‘nil’を指定できる。これはたとえばUnicodeの PUA(Private Use Area)由来のようなグリフをもたない文字のフォントにた いするシステムワイドの高価な検索を避けるために有用。 オプション引数ADDが非‘nil’なら以前セットされたフォントspecに FONT-SPECを追加する方法を指定する。‘prepend’ならFONT-SPECは先頭、 ‘append’ならFONT-SPECは末尾に追加される。デフォルトではFONT-SPECは 以前のセッティングをオーバーライドする。 たとえば以下は文字セット‘japanese-jisx0208’に属するすえての文字にた いして、ファミリー名が‘Kochi Gothic’であるようなフォントを使用する ようにデフォルトフォントセットを変更する。 (set-fontset-font t 'japanese-jisx0208 (font-spec :family "Kochi Gothic")) -- Function: char-displayable-p char この関数はEmacsがCHARを表示できるようなら‘t’をリターンする。より正 確には選択されたフレームのフォントセットが、CHARが属する文字セット を表示するためのフォントをもてば‘t’をリターンする。 フォントセットは文字単位でフォントを指定できる。フォントセットがこ れを行う場合には、この関数の値は正確ではないかもしれない。 37.12.12 低レベルのフォント表現 ------------------------------- 通常はフォントを直接扱う必要はありません。これを行う必要がある場合にはこ のセクションでその方法を説明します。 Emacs Lispではフォントは“フォントオブジェクト(font objects)”、“フォン トspec(font specs)”、“フォントエンティティー(font entities)”という3つの 異なるLispオブジェクトを使用して表現されます。 -- Function: fontp object &optional type OBJECTがフォントオブジェクト、フォントspec、フォントエンティティー なら‘t’、それ以外なら‘nil’をリターンする。 オプション引数TYPEが非‘nil’なら、チェックするLispオブジェクトの正確 なタイプを決定する。この場合にはTYPEは‘font-object’、‘font-spec’、 ‘font-entity’のいずれかであること。 フォントオブジェクトはEmacsが“オープンした”フォントを表します。Lispで フォントオブジェクトは変更できませんが調べることはできます。 -- Function: font-at position &optional window string ウィンドウWINDOW内の位置POSITIONにある文字を表示するために使用され ているフォントオブジェクトをリターンする。WINDOWが‘nil’の場合のデフ ォルトは選択されたウィンドウ。STRINGが‘nil’ならPOSITIONはカレントバ ッファー内の位置を指定する。それ以外ならSTRINGは文字列、POSITIONは その文字列内での位置を指定すること。 フォントspecはフォントを探すために使用できる仕様セットを含むLispオブ ジェクトです。フォントspec内の仕様にたいして1つ以上のフォントがマッチす ることができます。 -- Function: font-spec &rest arguments ARGUMENTS内の仕様を使用して新たなフォントspecをリターンする。これは ‘property’-‘value’のペアーであること。可能な仕様は以下のとおり: ‘:name’ XLFD、Fontconfig、GTKいずれかのフォーマットによるフォント名(文 字列)。*note (emacs)Fonts::を参照のこと。 ‘:family’ ‘:foundry’ ‘:weight’ ‘:slant’ ‘:width’ これらは同名のフェイス属性と同じ意味をもつ。*note Face Attributes::を参照のこと。 ‘:size’ フォントサイズ。非負の整数はピクセル単位、浮動小数点数ならポイ ントサイズを指定する。 ‘:adstyle’ ‘sans’のような、そのフォントにたいするタイポグラフィックスタイ ル(typographic style)の追加情報。値は文字列かシンボルであるこ と。 ‘:registry’ ‘iso8859-1’のようなフォントの文字セットレジストリーとエンコー ディング。値は文字列かシンボルであること。 ‘:script’ そのフォントがサポートしなければならないスクリプト(シンボル)。 ‘:lang’ そのフォントがサポートするべき言語。値は名前が2文字のISO-639言 語名であるようなシンボルであること。Xでは値は(もし空でなければ )フォントのXLFD名の“Additional Style”フィールドにたいしてマッ チされる。MS-Windowsではそのspecにマッチするフォントにはその言 語にたいして必要なコードページのサポートが要求される。現在のと ころこのプロパティでは‘ja’、‘ko’、‘zh’というCJK言語の小セット だけがサポートされる。 ‘:otf’ 複雑なテキストレイアウトを必要とするスクリプトをサポートする GNU/Linux上の‘libotf’のようなライブラリーとともにEmacsがコンパ イルされているような場合には、そのフォントはそれらのOpenType機 能をサポートするOpenTypeフォントでなければならない。値は以下の 形式のリストでなければならない (SCRIPT-TAG LANGSYS-TAG GSUB GPOS) ここでSCRIPT-TAGはOpenTypeスクリプトタグシンボル、 LANGSYS-TAGはOpenType言語システムタグシンボル(‘nil’ならデフォ ルト言語システムを使用)、‘gsub’はOpenType GSUB機能タグシンボル (何も要求されなければ‘nil’)、‘gpos’はOpenType GPOS機能タグシン ボルのリスト(何も要求されなければ‘nil’)。‘gsub’や‘gpos’がリス トなら、そのリスト内の‘nil’要素は、そのフォントが残りすべての タグシンボルにマッチしてはならないことを意味する。‘gpos’は省略 可。 -- Function: font-put font-spec property value フォントspec FONT-SPEC内のプロパティPROPERTYにVALUEをセットする。 フォントエンティティーはオープンする必要がないフォントへの参照です。 フォントオブジェクトとフォントspecの中間的な性質をもちフォントspecとは異 なり、フォントオブジェクトと同じように単一かつ特定のフォントを参照します 。フォントオブジェクトとは異なりフォントエンティティーの作成では、そのフ ォントのコンテンツはコンピューターへのメモリーにロードされません。 Emacsはスケーラブルフォントを参照するために単一のフォントエンティティー から複数の異なるサイズのフォントオブジェクトをオープンするかもしれません 。 -- Function: find-font font-spec &optional frame この関数はフレームFRAME上のフォントspec FONT-SPECにもっともマッチす るフォントエンティティーをリターンする。FRAMEが‘nil’の場合のデフォ ルトは選択されたフレーム。 -- Function: list-fonts font-spec &optional frame num prefer この関数はフォントspec FONT-SPECにマッチするすべてのフォントエンテ ィティーのリストをリターンする。 オプション引数FRAMEが非‘nil’なら、そのフォントが表示されるフレーム を指定する。オプション引数NUMが非‘nil’なら、それはリターンされるリ ストの最大長を指定する整数だること。オプション引数PREFERが非‘nil’な ら、それはリターンされるリスト順を制御するために使用する別のフォン トspecであること。リターンされるフォントspecはそのフォントspecにも っとも近い降順にソートされて格納される。 ‘:font’属性の値としてフォントspec、フォントエンティティー、フォント名 文字列を渡して‘set-face-attribute’を呼び出すと、Emacsは表示に利用可能な もっともマッチするフォントをオープンします。そしてそのフェイスにたいする ‘:font’属性の実際の値として、対応するフォントオブジェクトを格納します。 以下の関数はフォントに関する情報を取得するために使用できます。これら の関数のFONT引数にはフォントオブジェクト、フォントエンティティー、または フォントspecを指定できます。 -- Function: font-get font property この関数はFONTにたいするフォントプロパティPROPERTYの値をリターンす る。 FONTがフォントspecであり、そのフォントspecがPROPERTYを指定しなけれ ばリターン値は‘nil’。FONTがフォントオブジェクトかフォントエンティテ ィーなら、:SCRIPTプロパティにたいする値はそのフォントがサポートする スクリプトのリストかもしれない。 -- Function: font-face-attributes font &optional frame この関数はFONTに対応するフェイス属性のリストをリターンする。オプシ ョン引数FRAMEはフォントが表示されるフレームを指定する。これが ‘nil’なら選択されたフレームが使用される。リターン値は以下の形式 (:family FAMILY :height HEIGHT :weight WEIGHT :slant SLANT :width WIDTH) ここでFAMILY、HEIGHT、WEIGHT、SLANT、WIDTHの値はフェイス属性の値。 FONTにより指定されない場合には、いくつかのキー/属性ペアーはこのリス トから省略されるかもしれない。 -- Function: font-xlfd-name font &optional fold-wildcards この関数はFONTにマッチするXLFD((X Logical Font Descriptor))を文字列 としてリターンする。XLFDに関する情報は*note (emacs)Fonts::を参照の こと。その名前がXLFD(最大255文字を含むことが可能)にたいして長すぎれ ば、この関数は‘nil’をリターンする。 オプション引数FOLD-WILDCARDSが非‘nil’なら連続するワイルドカードは 1つにまとめられる。 以下の2つの関数はフォントに関して重要な情報をリターンします。 -- Function: font-info name &optional frame この関数は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]’という形式のベクター による値をリターンする。以下はこのベクターの各コンポーネントの意味: OPENED-NAME フォントのオープンに使用された名前(文字列)。 FULL-NAME フォントの完全名(文字列)。 SIZE フォントのピクセルサイズ。 HEIGHT フォント高さ(ピクセル単位)。 BASELINE-OFFSET ASCIIベースラインからのピクセル単位のオフセット(上方が正)。 RELATIVE-COMPOSE DEFAULT-ASCENT 文字の組み合わせ(compose)の方式を制御する数値。 ASCENT DESCENT このフォントのアセント(ascent)とディセント(descent)。これら2つ の数値の合計は上述のHEIGHTと等しくなること。 SPACE-WIDTH そのフォントのスペース文字の幅(ピクセル単位)。 AVERAGE-WIDTH そのフォントの文字の平均幅。これが0ならEmacsは表示のテキストレ イアウト計算時にかわりにSPACE-WIDTHの値を使用する。 FILENAME フォントのファイル名(文字列)。フォントのバックエンドがフォント のファイル名を見つける手段を提供しなければ‘nil’もあり得る。 CAPABILITY 最初の要素がフォントタイプを表す‘x’、‘opentype’、‘truetype’、 ‘type1’、‘pcf’、‘bdf’のいずれかのシンボルであるようなリスト。 OpenTypeフォントでは、フォントによりサポートされる機能GSUBと GPOSの2つの要素が含まれる。これらの要素はそれぞれ‘((SCRIPT (LANGSYS FEATURE ...) ...) ...)’という形式のリストであり、ここ でSCRIPTはOpenTypeのscriptタグを表すシンボル、LANGSYSは OpenTypeのlangsysタグを表すシンボル(またはデフォルトの langsysを表す‘nil’)、そよびFEATUREはそれぞれOpenTypeの featureタグを表す。 -- Function: query-font font-object この関数はFONT-OBJECTに関する情報をリターンする(これは引数としてフ ォント名を文字列で受け取る‘font-info’とは対照的)。 この関数は‘[NAME FILENAME PIXEL-SIZE MAX-WIDTH ASCENT DESCENT SPACE-WIDTH AVERAGE-WIDTH CAPABILITY]’という形式のベクターで値をリ ターンする。以下はこのベクターの各要素の意味: NAME フォント名(文字列)。 FILENAME フォントのファイル名(文字列)。フォントのバックエンドがフォント のファイル名を見つける手段を提供しなければ‘nil’もあり得る。 PIXEL-SIZE フォントをオープンするために使用されたフォントのピクセルサイズ 。 MAX-WIDTH フォントの最大のアドバンス幅。 ASCENT DESCENT このフォントのアセント(ascent)とディセント(descent)。これら2つ の数値の合計はフォントの高さを与える。 SPACE-WIDTH そのフォントのスペース文字の幅(ピクセル単位)。 AVERAGE-WIDTH そのフォントの文字の平均幅。これが0ならEmacsは表示のテキストレ イアウト計算時にかわりにSPACE-WIDTHの値を使用する。 CAPABILITY 最初の要素がフォントタイプを表す‘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プログラム内でのさまざまなレイアウトの検討を 可能にします。これらの関数は問い合わせられたフェイスがリマップされていた ら、リマップされたフェイスに関する情報をリターンすることによりフェイスの シマップを考慮します。*note Face Remapping::を参照してください。 -- Function: default-font-width この関数はカレントバッファーのデフォルトフェイスで使用されるフォン トの平均幅をピクセル単位でリターンする。 -- Function: default-font-height この関数はカレントバッファーのデフォルトフェイスで使用されるフォン トの高さをピクセル単位でリターンする。 -- Function: window-font-width &optional window face この関数はWINDOW内のFACEで使用されるフォントの平均幅をピクセル単位 でリターンする。WINDOWには生きたウィンドウを指定しなければならない 。‘nil’か省略ならWINDOWのデフォルトは選択されたウィンドウ、FACEのデ フォルトはWINDOW内のデフォルトフェイス。 -- Function: window-font-height &optional window face この関数はWINDOW内のFACEで使用されるフォントの高さをピクセル単位で リターンする。WINDOWには生きたウィンドウを指定しなければならない。 ‘nil’か省略ならWINDOWのデフォルトは選択されたウィンドウ、FACEのデフ ォルトはWINDOW内のデフォルトフェイス。 37.13 フリンジ ============== グラフィカルなディスプレイではEmacsは各ウィンドウに隣接して“フリンジ (fringes)”を描画します。これは切り詰め(truncation)、継続(continuation)、 水平スクロールを示すビットマップを表示できる側面の細い垂直ストリップです 。 37.13.1 フリンジのサイズと位置 ------------------------------ 以下のバッファーローカル変数はバッファーを表示するウィンドウのフリンジの 位置と幅を制御します。 -- Variable: fringes-outside-margins フリンジは通常はディスプレイマージンとウィンドウテキストの間に表示 される。この値が非‘nil’ならフリンジはディスプレイマージンの外側に表 示される。*note Display Margins::を参照のこと。 -- Variable: left-fringe-width この変数が非‘nil’なら、それは左フリンジの幅をピクセル単位で指定する 。値‘nil’はそのウィンドウのフレームの左フリンジ幅を使用することを意 味する。 -- Variable: right-fringe-width この変数が非‘nil’なら、それは右フリンジの幅をピクセル単位で指定する 。値‘nil’はそのウィンドウのフレームの右フリンジ幅を使用することを意 味する。 これらの変数にたいして値を指定しないすべてのバッファーは、フレームパ ラメーター‘left-fringe’および‘right-fringe’で指定された値を使用します (*note Layout Parameters::を参照)。 上記の変数はサブルーチンとして‘set-window-fringes’を呼び出す関数 ‘set-window-buffer’ (*note Buffers and Windows::を参照)を通じて実際に効 果をもちます。これらの変数のいずれかを変更しても影響を受ける各ウィンドウ で‘set-window-buffer’を呼び出さなければ、そのバッファーを表示する既存の ウィンドウのフリンジ表示は更新されません。個別のウィンドウでのフリンジ表 示を制御するために‘set-window-fringes’を使用することもできます。 -- Function: set-window-fringes window left &optional right outside-margins この関数はウィンドウWINDOWのフリンジ幅をセットする。WINDOWが‘nil’な ら選択されたウィンドウが使用される。 引数LEFTは左フリンジ、同様にRIGHTは右フリンジにたいしてピクセル単位 で幅を指定する。いずれかにたいする値‘nil’はデフォルトの幅を意味する 。OUTSIDE-MARGINSが非‘nil’ならフリンジをディスプレイマージンの外側 に表示することを指定する。 -- Function: window-fringes &optional window この関数はウィンドウWINDOWのフリンジに関する情報をリターンする。 WINDOWが省略か‘nil’なら選択されたウィンドウが使用される。値は ‘(LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS)’という形式。 37.13.2 フリンジのインジケーター -------------------------------- “フリンジインジケーター(Fringe indicators)”は行の切り詰めや継続、バッフ ァー境界などを示すウィンドウフリンジ内に表示される小さいアイコンのことで す。 -- User Option: indicate-empty-lines これが非‘nil’ならEmacsはグラフィカルなディスプレイ上で、バッファー 終端にある空行それぞれにたいしてフリンジ内に特別なグリフを表示する 。*note Fringes::を参照のこと。この変数はすべてのバッファーにおいて 自動的にバッファーローカルになる。 -- User Option: indicate-buffer-boundaries このバッファーローカル変数はウィンドウフリンジ内でバッファー境界と ウィンドウのスクロールを示す方法を制御する。 Emacsはバッファー境界(そのバッファーの最初の行と最後の行)がスクリー ン上に表示された際には、それを三角アイコン(angle icon)で示すことが できる。加えてスクリーンより上にテキストが存在すれば上矢印 (up-arrow)、スクリーンの下にテキストが存在すれば下矢印 (down-arrow)をフリンジ内に表示してそれを示すことができる。 基本的な値として3つの値がある: ‘nil’ これらのフリンジアイコンを何も表示しない。 ‘left’ 左フリンジに三角アイコンと矢印を表示する。 ‘right’ 右フリンジに三角アイコンと矢印を表示する。 その他の非alist 左フリンジに三角アイコンを表示して矢印を表示しない。 値がそれ以外ならどのフリンジインジケーターをどこに表示するかを指定 する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))’を使用す る。 -- Variable: fringe-indicator-alist このバッファーローカル変数は論理的ロジカルフリンジインジケーターか ら、ウィンドウフリンジ内に実際に表示されるビットマップへのマッピン グを指定する。値は‘(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’ オーバーレイ矢印に使用される(*note Overlay Arrow::を参照)。 各BITMAPSの値にはシンボルのリスト‘(LEFT RIGHT [LEFT1 RIGHT1])’を指 定できる。シンボルLEFTとRIGHTは特定のインジケーターにたいして左およ び/または右フリンジに表示するビットマップを指定する。LEFT1と RIGHT1はインジケーター‘bottom’と‘top-bottom’に固有であり、最後の改 行をもたない最後のテキスト行を示すために使用される。かわりに BITMAPSに左フリンジと右フリンジの両方で使用される単一のシンボルを指 定することもできる。 標準のビットマップシンボルのリストと自身で定義する方法については *note Fringe Bitmaps::を参照のこと。加えて‘nil’は空ビットマップ(表 示されないインジケーター)を表す。 ‘fringe-indicator-alist’がバッファーローカルな値をもち、論理的イン ジケーターにたいしてビットマップが定義されていないかビットマップが ‘t’ならば、‘fringe-indicator-alist’のデフォルト値から対応する値が使 用される。 37.13.3 フリンジのカーソルFringe Cursors ---------------------------------------- ある行がウィンドウと正確に同じ幅なとき、2行を使用するかわりにEmacsは右フ リンジ内にカーソルを表示します。フリンジ内のカーソルを表すために使用され るビットマップの違いはカレントバッファーのカーソルタイプに依存します。 -- User Option: overflow-newline-into-fringe これが非‘nil’なら、ウィンドウと正確に同じ幅の(最後の改行文字に継続 されない)行は継続されない。ポイントが行端に達した際には、カーソルは かわりに右フリンジに表示される。 -- Variable: fringe-cursor-alist この変数は論理的カーソルタイプから、右フリンジ内に実際に表示される フリンジビットマップへのマッピングを指定する。値は各要素が ‘(CURSOR-TYPE . BITMAP)’のような形式をもつようなalist。ここで BITMAPは使用するフリンジビットマップ、CURSOR-TYPEは表示するカーソル タイプ。 CURSOR-TYPEはそれぞれ‘box’、‘hollow’、‘bar’、‘hbar’、 ‘hollow-small’のいずれかであること。最初の4つはフレームパラメーター ‘cursor-type’の場合と同じ意味をもつ(*note Cursor Parameters::を参照 )。‘hollow-small’タイプは特定のディスプレイ行にたいして通常の ‘hollow-rectangle’が高すぎる際に‘hollow’のかわりに使用される。 BITMAPはそれぞれ、その論理的カーソルタイプにたいして表示されるフリ ンジビットマップを指定するシンボルであること。 詳細は*note Fringe Bitmaps::を参照のこと。 ‘fringe-cursor-alist’がバッファーローカルな値をもち、カーソルタイプ にたいして定義されたビットマップが存在しなければ、 ‘fringes-indicator-alist’のデフォルト値の対応する値が使用される。 37.13.4 フリンジのビットマップ ------------------------------ “フリンジビットマップ(fringe bitmaps)”は行の切り詰めや継続、バッファー境 界、オーバーレイ矢印等にたいする論理的フリンジインジケーターを表現する実 際のビットマップです。それぞれのビットマップはシンボルにより表されます。 これらのシンボルはフリンジインジケーターからビットマップへのマッピングを 行う変数‘fringe-indicator-alist’ (*note Fringe Indicators::を参照)、およ びフリンジカーソルからビットマップへのマッピングを行う変数 ‘fringe-cursor-alist’ (*note Fringe Cursors::を参照)から参照されます。 Lispプログラムも行内に出現する文字の1つに‘display’プロパティを使用す ることにより、左フリンジまたは右フリンジ内にビットマップを直接表示するこ とができます。そのような表示指定は以下の形式をもちます (FRINGE BITMAP [FACE]) FRINGEは、‘left-fringe’か‘right-fringe’いずれかのシンボルです。BITMAPは 表示するビットマップを識別するシンボルです。オプションのFACEは、そのフォ アグラウンドカラーをビットマップの表示に使用するフェイスの名前です。この フェイスは自動的に‘fringe’フェイスにマージされます。 以下はEmacsが定義する標準的なフリンジビットマップと、 (‘fringe-indicator-alist’と‘fringe-cursor-alist’を通じて)Emacs内で現在そ れらが使用される方法のリストです。 ‘left-arrow’、‘right-arrow’ 切り詰められた行を示すために使用される。 ‘left-curly-arrow’、‘right-curly-arrow’ 継続された行を示すために使用される。 ‘right-triangle’、‘left-triangle’ 前者はオーバーレイ矢印により使用され、後者は使用されない。 ‘up-arrow’、‘down-arrow’、‘top-left-angle’ ‘top-right-angle’ ‘bottom-left-angle’、‘bottom-right-angle’ ‘top-right-angle’、‘top-left-angle’ ‘left-bracket’、‘right-bracket’、‘top-right-angle’、‘top-left-angle’ バッファー境界を示すために使用される。 ‘filled-rectangle’、‘hollow-rectangle’ ‘filled-square’、‘hollow-square’ ‘vertical-bar’、‘horizontal-bar’ フリンジカーソルの異なるタイプにたいして使用される。 ‘empty-line’、‘exclamation-mark’、‘question-mark’、‘exclamation-mark’ Emacsの中核機能では使用されない。 次のサブセクションではフリンジビットマップを独自に定義する方法を説明しま す。 -- Function: fringe-bitmaps-at-pos &optional pos window この関数はウィンドウWINDOW内の位置POSを含むディスプレイ行のフリンジ ビットマップをリターンする。リターン値は‘(LEFT RIGHT OV)’という形式 をもつ。ここでLEFTは左フリンジ内のフリンジビットマップにたいするシ ンボル(ビットマップなしなら‘nil’)、RIGHTは同様に右フリンジにたいし て、OVが非‘nil’なら左フリンジにオーバーレイ矢印が存在することを意味 する。 WINDOW内でPOSが可視でなければ値は‘nil’。WINDOWが‘nil’なら選択された ウィンドウを意味する。POSが‘nil’ならWINDOW内のポイントの値を意味す る。 37.13.5 フリンジビットマップのカスタマイズ ------------------------------------------ -- Function: define-fringe-bitmap bitmap bits &optional height width align この関数はシンボルBITMAPを新たなフリンジビットマップとして定義、ま たはその名前の既存のビットマップを置き換える。 引数BITSは使用するイメージを指定する。これは各要素(整数)が対応する ビットマップの1行を指定する文字列か整数ベクターであること。整数の各 ビットはそのビットマップの1ピクセル、低位ビットはそのビットマップの 最右ピクセルに対応する。 高さは通常はBITSの長さ。しかし非‘nil’のHEIGHTにより異なる高さを指定 できる。幅は通常は8だが非‘nil’のWIDTHにより異なる幅を指定できる。 widthは1から16の整数でなければならない。 引数ALIGNはそのビットマップが使用される行範囲に相対的なビットマップ の位置を指定する。デフォルトはそのビットマップの中央。指定できる値 は‘top’、‘center’、‘bottom’。 ALIGN引数にはリスト‘(ALIGN PERIODIC)’も指定できて、ALIGNは上述のよ うに解釈される。PERIODICが非‘nil’なら、それは‘bits’内の行が指定され る高さに達するのに十分な回数繰り返されるべきであることを指定する。 -- Function: destroy-fringe-bitmap bitmap この関数はBITMAPにより識別されるフリンジビットマップを破棄する。 BITMAPが標準フリンジビットマップを識別する場合には、それを完全に消 去するかわりに実際にはそのビットマップの標準定義をリストアする。 -- Function: set-fringe-bitmap-face bitmap &optional face これはフリンジビットマップBITMAPにたいするフェイスにFACEをセットす る。FACEが‘nil’なら‘fringe’フェイスを選択する。ビットマップのフェイ スはそれを描画するカラーを制御する。 FACEは‘fringe’にマージされるためFACEは通常はフォアグラウンドカラー だけを指定すること。 37.13.6 オーバーレイ矢印 ------------------------ “オーバーレイ矢印(overlay arrow)”は、バッファー内の特定の行にたいしてユ ーザーに注意を促すために有用です。たとえばデバッガーでのインターフェース に使用されるモードでは、オーバーレイ矢印は実行されているコード行を示しま す。この機能は“オーバーレイ(overlays)”にたいして何も行いません(*note Overlays::を参照)。 -- Variable: overlay-arrow-string この変数は特定の行にたいして注意を喚起するために表示する文字列、ま たは矢印機能が使用されていなければ‘nil’を保持する。グラフィカルなデ ィスプレイではこの文字列のコンテンツは無視され、かわりにフリンジ領 域からディスプレイ領域左側にグリフが表示される。 -- Variable: overlay-arrow-position この変数はオーバーレイ矢印を表示する箇所を示すマーカーを保持する。 これは行の先頭となるポイントであること。非グラフィカルなディスプレ イではその行の先頭に矢印テキストが表示され、矢印テキストが表示され ないときに表示されるべきテキストがオーバーレイされる。その矢印は通 常は短く行は普通はインデントで開始されるので、上書きが問題となるこ とは通常はない。 オーバーレイ矢印の文字列は、そのバッファーの ‘overlay-arrow-position’の値がバッファー内を指せば与えられた任意の バッファーで表示される。したがって‘overlay-arrow-position’のバッフ ァーローカルなバインディングを作成することにより、複数のオーバーレ イ矢印の表示が可能である。しかしこれを達成するためには、 ‘overlay-arrow-variable-list’を使用するほうが通常はより明快。 ‘before-string’プロパティをもつオーバーレイを作成することにより同様の ことを行うことができます。*note Overlay Properties::を参照してください。 変数‘overlay-arrow-variable-list’を通じて複数のオーバーレイ矢印を定義 できます。 -- Variable: overlay-arrow-variable-list この変数の値は、それぞれがオーバーレイ矢印の位置を指定する変数のリ スト。変数‘overlay-arrow-position’はこのリスト上にあるために通常の 意味をもつ。 このリスト上の各変数は対応するオーバーレイ矢印位置に表示するためのオ ーバーレイ矢印文字列を指定する‘overlay-arrow-string’プロパティ(テキスト 端末用)、およびフリンジビットマップを指定する‘overlay-arrow-bitmap’プロ パティ(グラフィカル端末用)をもつことができます。これらのプロパティがセッ トされていなければデフォルトのフリンジインジケーター ‘overlay-arrow-string’と‘overlay-arrow’が使用されます。 37.14 スクロールバー ==================== フレームパラメーター‘vertical-scroll-bars’はそのフレーム内のウィンドウが 垂直スクロールバーをもつべきかと、それらが左か右のいずれかに配置されるべ きかを通常は制御します。フレームパラメーター‘scroll-bar-width’はそれらの 幅を指定します(‘nil’はデフォルトを意味する)。 フレームパラメーター‘horizontal-scroll-bars’はフレーム内のウィンドウ が水平スクロールバーをもつかどうかを制御します。フレームパラメーター ‘scroll-bar-height’はそれらの高さを指定します(‘nil’はデフォルトを意味す る)。*note Layout Parameters::を参照のしてください。 水平スクロールバーはすべてのプラットフォームで利用可能ではありません 。引数を受け取らない関数‘horizontal-scroll-bars-available-p’は、システム 上で水平スクロールバーが利用可能なら非‘nil’をリターンします。 以下の3つの関数は引数として生きたフレームを受け取り、デフォルトは選択 されたフレームです。 -- Function: frame-current-scroll-bars &optional frame この関数はフレームFRAMEのスクロールバーのタイプを報告する。値はコン スセル‘(VERTICAL-TYPE . HORIZONTAL-TYPE)’。ここでVERTICAL-TYPEは ‘left’、‘right’、または‘nil’ (スクロールバーなしを意味する)のいずれ か。HORIZONTAL-TYPEは‘bottom’か‘nil’ (水平スクロールバーなしを意味 する)のいずれか。 -- Function: frame-scroll-bar-width &optional Lisp_Object &optional frame この関数はウィンドウWINDOWにたいして垂直スクロールバーの幅をピクセ ル単位でリターンする。 -- Function: frame-scroll-bar-height &optional Lisp_Object &optional frame この関数はFRAMEの水平スクロールバーの高さをピクセル単位でリターンす る。 以下の関数を使用することにより、特定のウィンドウにたいするフレーム固 有のセッティングをオーバーライドできます: -- Function: set-window-scroll-bars window &optional width vertical-type height horizontal-type この関数はウィンドウWINDOWのスクロールバーの幅および/または高さ、タ イプをセットする。 WIDTHはピクセル単位で垂直スクロールバーの幅を指定する(‘nil’はそのフ レームにたいして指定された幅の使用を意味する)。VERTICAL-TYPEは垂直 スクロールバーをもつかどうか、もつ場合にはその位置を指定する。可能 な値は‘left’、‘right’、‘t’ (フレームのデフォルトの使用を意味する)、 垂直スクロールバーなしなら‘nil’のいずれか。 HEIGHTはピクセル単位で水平スクロールバーの高さを指定する(‘nil’はそ のフレームにたいして指定された高さの使用を意味する)。 HORIZONTAL-TYPEは水平スクロールバーをもつかどうかを指定する。可能な 値は‘bottom’、‘t’ (フレームのデフォルトの使用を意味する)、水平スク ロールバーなしなら‘nil’のいずれか。 WINDOWが‘nil’なら選択されたウィンドウが使用される。 以下の4つの関数は引数として生きたウィンドウを受け取り、デフォルトは選 択されたウィンドウです。 -- Function: window-scroll-bars &optional window この関数は‘(WIDTH COLUMNS VERTICAL-TYPE HEIGHT LINES HORIZONTAL-TYPE)’という形式のリストをリターンする。 値WIDTHは垂直スクロールバーの幅に指定された値(‘nil’もあり得る)。 COLUMNSは垂直スクロールバーが実際に占有する列数(丸められているかも しれない)。 値HEIGHTは水平スクロールバーの高さに指定された値(‘nil’もあり得る)。 LINESは水平スクロールバーが実際に占有する行数(丸められているかもし れない)。 -- Function: window-current-scroll-bars &optional window この関数はウィンドウWINDOWにたいするスクロールバータイプを報告する 。値はコンスセル‘(VERTICAL-TYPE . HORIZONTAL-TYPE)’。 ‘window-scroll-bars’とは異なりフレームのデフォルトと ‘scroll-bar-mode’を考慮して実際に使用されているスクロールバータイプ を報告する。 -- Function: window-scroll-bar-width &optional window この関数はWINDOWの垂直スクロールバーの幅をピクセル単位でリターンす る。 -- Function: window-scroll-bar-height &optional window この関数は、WINDOWの水平スクロールバーの高さをピクセル単位でリター ンする。 あるウィンドウにたいして‘set-window-scroll-bars’でこれらの値を指定し ない場合には、表示されようとするバッファーのバッファーローカル変数 ‘vertical-scroll-bar’、‘horizontal-scroll-bar’、‘scroll-bar-width’、 ‘scroll-bar-height’がウィンドウのスクロールバーを制御します。 ‘set-window-buffer’はこれらの変数を調べる関数です。あるウィンドウですで に可視なバッファーでこれらを変更した場合には、すでに表示されているのと同 じバッファーを指定して‘set-window-buffer’を呼び出すことにより、そのウィ ンドウに新たな値を記録させることができます。 以下の変数をセット(セットにより自動的にバッファーローカルになる)する ことにより、特定のバッファーのスクロールバーの外観を制御できます。 -- Variable: vertical-scroll-bar この変数は垂直スクロールバーの配置を指定する。可能な値は‘left’、 ‘right’、そのフレームのデフォルトの使用を意味する‘t’、スクロールバ ーなしの‘nil’のいずれか。 -- Variable: horizontal-scroll-bar この変数は水平スクロールバーの配置を指定する。可能な値は‘bottom’、 そのフレームのデフォルトの使用を意味する‘t’、スクロールバーなしの ‘nil’のいずれか。 -- Variable: scroll-bar-width この変数はそのバッファーの垂直スクロールバーをピクセル単位で量った 幅を指定する。値‘nil’はフレームにより指定された値の使用を意味する。 -- Variable: scroll-bar-height この変数はそのバッファーの水平スクロールバーをピクセル単位で量った 高さを指定する。値‘nil’はフレームにより指定された値の使用を意味する 。 最後に変数‘scroll-bar-mode’と‘horizontal-scroll-bar-mode’をカスタマイ ズすることにより、すべてのフレームでのスクロールバーの表示を切り替えるこ とができます。 -- User Option: scroll-bar-mode この変数はすべてのフレームに垂直スクロールバーを配置するべきかと、 その場所を制御する。可能な値は、スクロールバーなしの‘nil’、左にスク ロールバーを配置する‘left’、右にスクロールバーを配置する‘right’のい ずれか。 -- User Option: horizontal-scroll-bar-mode この変数はすべてのフレームに水平スクロールバーを表示するかどうかを 制御する。 37.15 ウィンドウディバイダー ============================ ウィンドウディバイダーとはフレームのウィンドウ間に描画されるバーのことで す。右(right)ディバイダーはあるウィンドウと、その右に隣接する任意のウィ ンドウの間に描画されます。その幅(厚さ)はフレームパラメーター ‘right-divider-width’で指定されます。下(bottom)ディバイダーはあるウィン ドウと、その下に隣接するウィンドウやエコーエリアとの間に描画されます。そ の幅はフレームパラメーター‘bottom-divider-width’で指定されます。いずれの 場合でも幅に0を指定すると、そのようなディバイダーを描画しないことを意味 します。*note Layout Parameters::を参照してください。 技術的には右ディバイダーはそれの左にあるウィンドウに所属して、その幅 がそのウィンドウのトータル幅に寄与することを意味します。下ディバイダーは 上にあるウィンドウに所属して、その幅がそのウィンドウのトータル高さに寄与 することを意味します。*note Window Sizes::を参照してください。あるウィン ドウが右ディバイダーと左ディバイダーの両方をもつ場合には下ディバイダーが 優勢になります。これは右ディバイダーが下ディバイダーの上で終端されるのに 比べて、下ディバイダーはそのウィンドウの完全なトータル幅で描画されること を意味しています。 ディバイダーはマウスでドラッグできるのでマウスで隣接するウィンドウの サイズを調整するために有用です。これらはスクロールバーやモードラインが表 示されていないときに隣接するウィンドウを視覚的に分離する役目もあります。 以下の3つのフェイスによりディバイダーの外観をカスタマイズできます: ‘window-divider’ ディバイダーの幅が3ピクセル未満のときは、このフェイスのフォアグラウ ンドカラーで塗りつぶしで描画される。これより広いディバイダーでは、 最初と最後のピクセルを除いた内部にたいしてのみこのフェイスが使用さ れる。 ‘window-divider-first-pixel’ これは少なくとも幅が3ピクセルあるディバイダーの最初のピクセルを描画 するために使用される。塗りつぶし(solid)の外観を得るためには ‘window-divider’フェイスに使用されるのと同じ値をセットすること。 ‘window-divider-last-pixel’ これは少なくとも幅が3ピクセルあるディバイダーの最後のピクセルを描画 するために使用される。塗りつぶし(solid)の外観を得るためには ‘window-divider’フェイスに使用されるのと同じ値をセットすること。 以下の2つの関数により特定のウィンドウのディバイダーのサイズを取得でき ます。 -- Function: window-right-divider-width &optional window WINDOWの右ディバイダーの幅(厚さ)をピクセル単位でリターンする。 WINDOWは生きたウィンドウでなければならずデフォルトは選択されたウィ ンドウ。最右ウィンドウにたいするリターン値は常に0。 -- Function: window-bottom-divider-width &optional window WINDOWの下ディバイダーの幅(厚さ)をピクセル単位でリターンする。 WINDOWは生きたウィンドウでなければならずデフォルトは選択されたウィ ンドウ。ミニバッファーウィンドウやミニバッファーがないフレームの最 下ウィンドウにたいするリターン値は常に0。 37.16 ‘display’プロパティ ========================= テキストプロパティ(またはオーバーレイプロパティ)の‘display’はテキストへ のイメージ挿入、およびテキスト表示のその他の事相を制御します。 ‘display’プロパティの値はディスプレイ仕様、または複数のディスプレイ仕様 を含むリストかベクターであるべきです。同じ‘display’プロパティ値内のディ スプレイ仕様は、一般的にはそれらがカバーするテキストにたいして並行して適 用されます。 複数のソース(オーバーレイおよび/またはテキストプロパティ)が ‘display’プロパティにたいして値を指定しますが1つの値だけが効果をもち、そ れは‘get-char-property’のルールにしたがいます。*note Examining Properties::を参照してください。 このセクションの残りの部分では、複数の種類のディスプレイ仕様とそれら の意味を説明します。 37.16.1 テキストを置換するディスプレー仕様 ------------------------------------------ ある種のディスプレイ仕様は、そのプロパティをもつテキストのかわりに表示す る何かを指定します。これらは“置換(replacing)”ディスプレイ仕様と呼ばれま す。Emacsはユーザーにたいして、この方法で置換されたバッファーテキストの 中間への対話的なポイント移動を許可しません。 ディスプレイ仕様のリストに1つ以上の置換ディスプレイ仕様が含まれる場合 には、最初の置換ディスプレイ仕様が残りをオーバーライドします。置換ディス プレイ仕様は他のほとんどのディスプレイ仕様は置換を許容しないので、それら とは無関係です。 置換ディスプレイ仕様では、“そのプロパティをもつテキスト”とは、 ‘display’プロパティとして同一のLispオブジェクトをもつ連続したすべての文 字を意味します。これらの文字は単一の単位として置換されます。‘display’プ ロパティに異なるLispオブジェクト(‘eq’ではないオブジェクト)をもつ2つの文 字は個別に処理されます。 以下はこの要点を示すための例です。文字列が置換ディスプレイ仕様として の役割をもち、指定された文字列のプロパティをもつテキストを置換します (*note Other Display Specs::を参照)。以下の関数を考えてみてください: (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で表示され ます。 37.16.2 スペースの指定 ---------------------- 指定された幅および/または高さのスペースを表示するためには‘(space . PROPS)’という形式のディスプレイ仕様を使用します。このプロパティを1つ以上 の連続する文字にputすることができます。これら_すべて_の文字のかわりに指 定された高さと幅のスペースが表示されます。以下はスペースのウェイトを指定 するためにPROPS内で使用できるプロパティです: ‘:width WIDTH’ WIDTHが数字なら、それはスペースの幅が通常の文字幅のWIDTH倍であるべ きかを指定する。WIDTHは“ピクセル幅(pixel width)”仕様でも可(*note Pixel Specification::を参照)。 ‘:relative-width FACTOR’ 幅の広さは同じ‘display’プロパティをもつ連続する文字のグループ内の最 初の文字から計算される必要があることを指定する。スペースの幅はその 文字のピクセル幅にFACTORを乗じた幅である(テキストモード端末では文字 の“ピクセル幅”は通常は1だがTAB文字や2倍の幅をもつCJK文字では1以上に なり得る)。 ‘:align-to HPOS’ スペースがHPOSに達するほど十分に広くあるべきことを指定する。HPOSが 数字なら通常の文字幅の単位で量られる。HPOSは“ピクセル幅(pixel width)”仕様でも可(*note Pixel Specification::を参照)。 上記プロパティのいずれか1つだけを使用するべきです。以下のプロパティで スペースの高さも指定できます: ‘:height HEIGHT’ スペースの高さを指定する。HEIGHTが数字ならスペースの高さが通常の文 字高さのHEIGHT倍であるべきことを指定する。HEIGHTは“ピクセル高さ仕様 (pixel height)”でも可(*note Pixel Specification::を参照)。 ‘:relative-height FACTOR’ このディスプレイ仕様をもつテキストの通常の高さにFACTORを乗じること によりスペースの高さを指定する。 ‘:ascent ASCENT’ ASCENTの値が非負の100以下の数字ならスペースの高さのASCENTパーセント をスペースのアセント(ascent: 上方)、すなわちベースラインより上の部 分とみなす。“ピクセルアセント(pixel ascent)”仕様によりアセントをピ クセル単位で指定することも可(*note Pixel Specification::を参照)。 ‘:height’と‘:relative-height’を両方同時に使用しないでください。 ‘:width’と‘:align-to’プロパティは非グラフィック端末でサポートされます が、このセクションのその他のスペースプロパティはサポートされません。 スペースプロパティは双方向テキスト表示の並べ替えのためのパラグラフ区 切りとして扱われます。詳細は*note Bidirectional Display::を参照してくだ さい。 37.16.3 スペースにたいするピクセル指定 -------------------------------------- プロパティ‘:width’、‘:align-to’、‘:height’、‘:ascent’の値は再表示の間に 評価される特別な種類の式です。その評価の結果はピクセルの絶対数として使用 されます。 以下の式がサポートされています: EXPR ::= NUM | (NUM) | UNIT | ELEM | POS | IMAGE | FORM NUM ::= INTEGER | FLOAT | SYMBOL UNIT ::= in | mm | cm | width | height ELEM ::= left-fringe | right-fringe | left-margin | right-margin | scroll-bar | text POS ::= left | center | right FORM ::= (NUM . EXPR) | (OP EXPR ...) OP ::= + | - フォームNUMはデフォルトフレームフォントの高さか幅、フォーム‘(NUM)’は 絶対ピクセル数を指定します。NUMがシンボルSYMBOLなら、それにたいするバッ ファーローカルな変数バインディングが使用されます。 単位‘in’、‘mm’、‘cm’はそれぞれインチ、ミリメートル、センチメートルご とのピクセル数を指定します。単位‘width’と‘height’はそれぞれカレントフェ イスのデフォルトの幅と高さに対応します。イメージ仕様‘image’はイメージの 幅や高さに対応します。 要素‘left-fringe’、‘right-fringe’、‘left-margin’、‘right-margin’、 ‘scroll-bar’、‘text’はそのウィンドウの対応する領域の幅を指定します。 位置‘left’、‘center’、‘right’はテキストエリアの左端、中央、右端から相 対的に位置を指定するために‘:align-to’とともに使用できます。 (‘text’を除いた)上記ウィンドウ要素は与えられたエリアの左端から相対的 に位置を指定するために‘:align-to’とともに使用することもできます。(最初に 出現するこれらシンボルのいずれかにより)相対的位置にたいするベースオフセ ットが一度セットがされると、残りのシンボルは指定されたエリアの幅として解 釈されます。たとえば左マージンの中央に位置揃えするには以下のようにします :align-to (+ left-margin (0.5 . left-margin)) 位置揃えにたいしてベースオフセットが何も指定されなければ、テキストエ リア左端にたいして常に相対的になります。たとえばヘッダーライン内の ‘:align-to 0’はテキストエリアの最初のテキスト行に位置揃えします。 ‘(NUM . EXPR)’という形式の値はNUMとEXPRにより生成される値を意味します 。たとえば‘(2 . in)’は2インチの幅、‘(0.5 . IMAGE)’は指定されたイメージの 幅(や高さ)の半分を指定します。 フォーム‘(+ EXPR ...)’は式の値を合計します。フォーム‘(- EXPR ...)’は 式の値を符号反転または減算します。 37.16.4 その他のディスプレー仕様 -------------------------------- 以下は‘display’テキストプロパティ内で使用できる他のディスプレイ仕様です 。 ‘STRING’ このプロパティをもつテキストのかわりにSTRINGを表示する。 再帰的なディスプレイ仕様はサポートされない。つまりSTRINGの ‘display’プロパティがあっても使用されない。 ‘(image . IMAGE-PROPS)’ この種のディスプレイ仕様はイメージディスクリプタである(*note Images::を参照)。ディスプレイ仕様として使用時には、そのディスプレイ 仕様をもつテキストのかわりに表示するイメージを意味する。 ‘(slice X Y WIDTH HEIGHT)’ この仕様は‘image’とともに、表示するイメージの“スライス(slice: イメ ージの特定の領域)”を指定する。要素YとXはイメージ内での左上隅、 WIDTHとHEIGHTはそのスライスの幅と高さを指定する。整数はピクセル数、 0.0から1.0までの浮動小数点数はイメージ全体の幅や高さの割合を意味す る。 ‘((margin nil) STRING)’ この形式のディスプレイ仕様は、このディスプレイ仕様をもつテキストの かわりにテキストと同じ位置に表示するSTRINGを意味する。これは単に STRINGを使用するのと同じだが、マージン表示(*note Display Margins::を 参照)の特殊なケースとして行われる点が異なる。 ‘(left-fringe BITMAP [FACE])’ ‘(right-fringe BITMAP [FACE])’ テキスト行の任意の文字がこのディスプレイ仕様をもつ場合には、その文 字のかわりにその行の左や右のフリンジに表示するBITMAPを指定する。オ プションのFACEはビットマップにたいして使用するカラーを指定する。詳 細は*note Fringe Bitmaps::を参照のこと。 ‘(space-width FACTOR)’ このディスプレイ仕様は、この仕様をもつテキスト内のすべてのスペース 文字に効果を及ぼす。これらすべてのスペースは通常の幅のFACTOR倍の幅 で表示される。要素FACTORは整数か浮動小数点数であること。スペース以 外の文字は影響を受けない。特にこれはタブ文字に影響を与えない。 ‘(height HEIGHT)’ このディスプレイ仕様はテキストを高く(taller)、または低く(shorter)す る。HEIGHTには以下を指定できる: ‘(+ N)’ これはNステップ大きいフォントの使用を意味する。“ステップ”は利 用可能なフォントのセットから定義される。利用可能なフォントとは 、具体的には、このような場合でなければ、heightを除いてそのテキ ストに指定されたすべての属性にマッチするフォント。適切なフォン トの各サイズは別のステップとして利用可能とみなされる。Nは整数 であること。 ‘(- N)’ これはNステップ小さいフォントの使用を意味する。 FACTOR (数値) 数値FACTORはデフォルトフォントのFACTOR倍高いフォントの使用を意 味する。 FUNCTION (シンボル) 高さを計算する関数。この関数はカレントの高さを引数として呼び出 されて、使用する新たな高さをリターンすること。 FORM (上記以外) HEIGHTの値が上記のいずれにもマッチしなければ、それはフォームで ある。Emacsは‘height’をカレントで指定されたフォントの高さにバ インドして新たな高さを取得するためにフォームを評価する。 ‘(raise FACTOR)’ この種のディスプレイ仕様は、その行のベースラインに相対的にテキスト を上(raise)か下(lower)に指定する。 FACTOR、影響を受けるテキストの高さにたいする乗数として解釈される数 値でなければならない。これが正なら文字を上に、負なら下に表示するこ とを意味する。 そのテキストが‘height’ディスプレイ仕様ももつ場合には、上や下に表示 する量には影響を与えない。上や下に表示する量はテキストにたいして使 用されるフェイスにもとづく。 任意のディスプレイ仕様にたいして条件を作成できます。これを行うには、 ‘(when CONDITION . SPEC)’という形式の別リスト内にパッケージします。この 場合には、仕様SPECはCONDITIONが非‘nil’値に評価されたときだけ適用されます 。この評価の間に‘object’は条件つき‘display’プロパティをもつ文字列、また はバッファーにバインドされます。‘position’と‘buffer-position’はそれぞれ ‘object’内の位置、および‘display’プロパティが見つかったバッファー位置に バインドされます。‘object’が文字列の際には両者の位置は異なるかもしれませ ん。 37.16.5 マージン内への表示 -------------------------- バッファーはその左側と右側に“ディスプレイマージン(display margins)”と呼 ばれるブランクエリアをもつことができます。それらのエリア内には通常はテキ ストが出現することはありませんが、‘display’プロパティを使用してディスプ レイマージン内に何かを配置することができます。現在のところマージン内のテ キストやイメージをマウスセンシティブにする方法はありません。 マージン内に何かを表示するにはテキストの‘display’プロパティのマージン 表示仕様(margin display specification)で指定します。これは配置したテキス トが表示されないことを意味する置換表示仕様です。マージン表示は表示されま すがそのテキストは表示されません。 マージン表示仕様とは‘((margin right-margin) SPEC)’や‘((margin left-margin) SPEC)’のようなものです。ここでSPECはマージン内に何を表示す るかを告げる別の表示仕様です。典型的にはこれは表示するテキスト文字列やイ メージディスクリプタです。 特定のバッファーテキストに_割り当てられた_マージンに何かを表示するた めには、そのテキストに‘before-string’プロパティを付してコンテンツとして マージン表示仕様をputします。 ディスプレイマージンが何かを表示可能になる前に、それらに非0の幅を与え なければなりません。これを行う通常の方法は以下の変数をセットする方法です : -- Variable: left-margin-width この変数は左マージンの幅を文字セル(別名は“列”)単位で指定する。これ 、すべてのバッファーでバッファーローカルである。値‘nil’は左マージン エリアなしを意味する。 -- Variable: right-margin-width この変数は右マージンの幅を文字セル単位で指定する。これはすべてのバ ッファーでバッファーローカルである。値‘nil’は右マージンエリアなしを 意味する。 これらの変数をセットしてもウィンドウには即座には反映されません。これ らの変数はウィンドウ内に新たなバッファーを表示する際にチェックされます。 したがって‘set-window-buffer’を呼び出すことにより変更を反映することがで きます。 マージン幅を即座にセットすることもできます。 -- Function: set-window-margins window left &optional right この関数はウィンドウWINDOWのマージン幅、文字セル単位で指定する。引 数LEFTは左マージン、RIGHTは右マージン(デフォルトは‘0’)を制御する。 -- Function: window-margins &optional window この関数はWINDOWの左マージンと右マージンの幅を‘(LEFT . RIGHT)’とい う形式のコンスセルでリターンする。2つのマージンエリアのいずれか一方 が存在しなければ幅は‘nil’でリターンされる。2つのマージンがどちらも 存在しなければ、この関数は‘(nil)’をリターンする。WINDOWが‘nil’なら 選択されたウィンドウが使用される。 37.17 イメージ ============== Emacsバッファー内にイメージを表示するためには最初にイメージディスクリプ タを作成して、それを表示されるテキストの‘display’プロパティ(*note Display Property::を参照)内のディスプレイ指定子として使用しなければなり ません。 Emacsはグラフィカルな端末で実行時には、通常はイメージの表示が可能です 。テキスト端末、イメージサポートを欠く特定のグラフィカル端末、またはイメ ージサポートなしでコンパイルされたEmacsではイメージを表示できません。原 則的にイメージが表示可能か判断するためには関数‘display-images-p’を使用で きます(*note Display Feature Testing::を参照)。 37.17.1 イメージのフォーマット ------------------------------ Emacsはいくつかの異なるフォーマットのイメージを表示できます。これらのイ メージフォーマットのいくつかは、特定のサポートライブラリーがインストール されている場合のみサポートされます。いくつかのプラットフォームでは Emacsはオンデマンドでサポートライブラリーをロードできます。そのような場 合には、それらの動的ライブラリーにたいする既知の名前セットを変更するため に変数‘dynamic-library-alist’を使用できます。*note Dynamic Libraries::を 参照してください。 サポートされるイメージフォーマット(と要求されるサポートライブラリー )にはPBMとXBM(サポートライブラリーに依存せず常に利用可能)、 XPM(‘libXpm’)、GIF (‘libgif’または‘libungif’)、PostScript(‘gs’)、 JPEG(‘libjpeg’)、TIFF(‘libtiff’)、PNG(‘libpng’)、SVG (‘librsvg’)が含まれ ます。 これらのイメージフォーマットはそれぞれ“イメージタイプシンボル(image type symbol)”に関連付けられます。上記のフォーマットにたいするシンボルは 順に‘pbm’、‘xbm’、‘xpm’、‘gif’、‘postscript’、‘jpeg’、‘tiff’、‘png’、 ‘svg’です。 さらにImageMagick(‘libMagickWand’)のサポートつきでEmacsをビルドした場 合には、EmacsはImageMagickが表示可能なイメージフォーマットを表示できます 。*note ImageMagick Images::を参照してください。ImageMagickを通じて表示 されるすべてのイメージはタイプシンボル‘imagemagick’をもちます。 -- Variable: image-types この変数はカレント構成で潜在的にサポートされるイメージフォーマット にたいするタイプシンボルのリストを含む。 “潜在的”とはEmacsがそのイメージタイプを知っていることを意味しており 、実際に使用可能である必要はない(たとえば動的ライブラリーが利用でき ないせいかもしれない)。どのイメージタイプが実際に利用できるか知るた めには‘image-type-available-p’を使用すること。 -- Function: image-type-available-p type この関数はタイプTYPEのイメージのロードと表示が可能なら非‘nil’をリタ ーンする。TYPEはイメージタイプシンボルであること。 サポートライブラリーが静的にリンクされたイメージタイプにたいして、 この関数は常に‘t’をリターンする。サポートライブラリーが動的にロード されるイメージタイプにたいしてはライブラリーがロード可能なら‘t’、そ れ以外なら‘nil’をリターンする。 37.17.2 イメージのディスクリプタ -------------------------------- “イメージディスクリプタ(image descriptor)”とは、イメージにたいする基礎的 なデータと表示する方法を指定するリストです。これは通常はオーバーレイプロ パティかテキストプロパティ‘display’(*note Other Display Specs::を参照)の 値を通じて使用されますが、バッファーにイメージを挿入する便利なヘルパー関 数については*note Showing Images::を参照してください。 イメージディスクリプタはそれぞれ‘(image . PROPS)’という形式をもちます 。ここでPROPSはキーワードシンボルと値のペアーからなるプロパティリストで あり、少なくともそのイメージタイプを指定するペアー‘:type TYPE’を含みます 。 以下はすべてのイメージタイプにたいして意味のあるプロパティのリストで す(以降のサブセクションで説明するように特定のイメージタイプにたいしての み意味があるプロパティも存在する): ‘:type TYPE’ イメージタイプ。 *note Image Formats::を参照のこと。 すべてのイメー ジディスクリプタは。このプロパティを含まなければならない。 ‘:file FILE’ これはファイルFILEからイメージをロードすることを意味する。FILEが絶 対ファイル名でなければ‘data-directory’内で展開される。 ‘:data DATA’ これはrawイメージデータを指定する。すべてのイメージディスクリプタは ‘:data’か‘:file’のいずれかをもたなければならないが両方もつことはで きない。 ほとんどのイメージタイプにたいして、‘:data’プロパティの値はイメージ データを含む文字列であること。いくつかのイメージタイプは‘:data’をサ ポートしない。それ以外のイメージタイプにたいしては‘:data’単独では不 十分であり、‘:data’とともに他のイメージプロパティを使用する必要があ る。詳細は以下のサブセクションを参照のこと。 ‘:margin MARGIN’ これはイメージ周囲に余分なマージンとして何ピクセル追加するかを指定 する。値MARGINは非負の数値か、そのような数値のペアー‘(X . Y)’でなけ ればならない。ペアーならXは水平方向に追加するピクセル数、Yは垂直方 向に追加するピクセル数を指定する。‘:margin’が指定されない場合のデフ ォルトは0。 ‘:ascent ASCENT’ これはイメージのアセント(ベースラインの上の部分)に使用するイメージ の高さの分量を指定する。値ASCENTは0から100の数値かシンボル ‘center’でなければならない。 ASCENTが数値ならアセントに使用するイメージの高さのパーセンテージで あること。 ASCENTが‘center’なら、イメージにたいしてテキストプロパティやオーバ ーレイプロパティにより指定される方法で、センターライン(そのイメージ 位置にテキストを描画する際の垂直方向のセンターライン)の垂直方向中心 にイメージが配置される。 このプロパティが省略された場合のデフォルトは50。 ‘:relief RELIEF’ これはイメージ周辺にシャドー矩形を追加する。値RELIEFはシャドーライ ン幅をピクセルで指定する。RELIEFが負ならボタンを押下した状態、それ 以外はボタンを押下していない状態のイメージでシャドーを描画する。 ‘:conversion ALGORITHM’ これはイメージを表示する前に適用するべき変換アルゴリズムを指定する 。値ALGORITHMは何のアルゴリズムかを指定する。 ‘laplace’ ‘emboss’ カラーの大きな差異を強調して小さな差異を不鮮明にするラプラスエ ッジ検出アルゴリズム(Laplace edge detection algorithm)を指定す る。無効なボタンのイメージ表示に、これが役立つと考える人もいま す。 ‘(edge-detection :matrix MATRIX :color-adjust ADJUST)’ 一般的なエッジ検出アルゴリズムを指定する。MATRIXは数値からなる 9要素のリストかベクターでなければならない。変換されたイメージ 内の位置x/yにあるピクセルは、その位置周辺にある元のピクセルか ら計算される。MATRIXはx/yに近接する各ピクセルにたいして、その ピクセルが変換先ピクセルに影響するファクター(factor: 要因)を指 定する。以下のように要素0はx-1/y-1にあるピクセルのファクター、 要素1はx/y-1にあるピクセルにたいするファクター、...を指定する 。 (x-1/y-1 x/y-1 x+1/y-1 x-1/y x/y x+1/y x-1/y+1 x/y+1 x+1/y+1) 結果となるピクセルは周辺ピクセルのRGB値を合計したカラーを指定 されたファクターで乗じて、その合計をファクター絶対値の合計で除 した色強度から計算される。 ラプラスエッジ検出は現在のところは以下のマトリクス (1 0 0 0 0 0 0 0 -1) エンボスエッジ検出(Emboss edge-detection)は以下のマトリクスを 使用する ( 2 -1 0 -1 0 1 0 1 -2) ‘disabled’ イメージが無効(disabled)に見えるよう変換することを指定する。 ‘:mask MASK’ MASKが‘heuristic’か‘(heuristic BG)’なら、フレームのバックグラウンド がイメージ背後に見えるようにイメージのクリッピングマスクを構築する 。BGが未指定か‘t’なら、イメージ4隅に最頻するカラーをそのイメージの バックグラウンドカラーとみなしてバックグラウンドカラーを決定する。 それ以外ならBGはイメージのバックグラウンドとみなすべきカラーを指定 するリスト‘(RED GREEN BLUE)’でなければならない。 MASKが‘nil’なら、イメージがマスクをもつ場合にはマスクを削除する。マ スクを含むフォーマットのイメージは‘:mask nil’を指定することにより削 除される可能性がある。 ‘:pointer SHAPE’ これはマウスポインターがそのイメージ上にある際のポインターシェイプ を指定する。利用可能なポインターシェイプについては*note 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’プロパティを含む場合はマウスカーソ ルがホットスポット上にあるときのマウスカーソルのシェイプを指定する 。利用可能なポインターシェイプについては*note Pointer Shape::を参照 のこと。 マウスポインターがホットスポット上にあるときにマウスをクリックした ときのイベントは、ホットスポットのIDとマウスイベントを組み合わせて 構成される。たとえばホットスポットのIDが‘area4’なら‘[area4 mouse-1]’。 -- Function: image-mask-p spec &optional frame この関数はイメージSPECがマスクビットマップをもつなら‘t’をリターンす る。FRAMEはそのイメージが表示されるフレーム。FRAMEが‘nil’か省略され た場合には選択されたフレームが使用される(*note Input Focus::を参照 )。 37.17.3 XBMイメージ ------------------- XBMフォーマットを使用するにはイメージタイプとして‘xbm’を指定します。この イメージフォーマットは外部ライブラリーを要求せず、このタイプのイメージは 常にサポートされます。 ‘xbm’イメージタイプにたいして追加のイメージプロパティがサポートされま す: ‘:foreground FOREGROUND’ 値FOREGROUNDはそのイメージのフォアグラウンドカラーを指定する文字列 、またはデフォルトカラーを指定する‘nil’であること。このカラーは XBM内の1の各ピクセルに使用される。デフォルトはフレームのフォアグラ ウンドカラー。 ‘:background BACKGROUND’ 値BACKGROUNDはそのイメージのバックグラウンドカラーを指定する文字列 、またはデフォルトカラーを指定する‘nil’であること。このカラーは XBM内の0の各ピクセルに使用される。デフォルトはフレームのバックグラ ウンドカラー。 外部ファイルのかわりにEmacs内のデータを指定してXBMイメージを指定する には以下の3つのプロパティを使用する: ‘:data DATA’ 値DATAはイメージのコンテンツを指定する。DATAとして使用できる3つのフ ォーマットが存在する: • それぞれがイメージの1ラインを指定するような文字列ベクターか boolベクター。‘:height’と‘:width’を指定する。 • 文字列ならXBMファイルが含むのと同じバイトシーケンスを含む。こ の場合は‘:height’と‘:width’を指定してはならない。これらを省略 することが、そのデータがXBMファイルのフォーマットをもつことを 示すからである。イメージの高さと幅はファイルのコンテンツにより 指定される。 • イメージのビットを含む文字列かboolベクター(終端の使用されない 余分なビットを含むかもしれない)。少なくともWIDTH * ‘height’ビ ットを含むこと。この場合にはその文字列がXBMファイル全体ではな く、単にビットだけを含むことを示すとともに、そのイメージのサイ ズを指定するために‘:height’と‘:width’を指定しなければならない 。 ‘:width WIDTH’ 値WIDTHはピクセル単位でイメージの幅を指定する。 ‘:height HEIGHT’ 値HEIGHTはピクセル単位でイメージの高さを指定する。 37.17.4 XPMイメージ ------------------- XPMフォーマットを使用するにはイメージタイプに‘xpm’を指定します。‘xpm’イ メージタイプでは追加のプロパティ‘:color-symbols’にも意味があります。 ‘:color-symbols SYMBOLS’ 値SYMBOLSは要素が‘(NAME . COLOR)’という形式をもつようなalistである こと。各要素においてNAMEはイメージファイル内に出現するカラー名、 COLORはそのカラー名の実際の表示に使用するカラーを指定する。 37.17.5 PostScriptイメージ -------------------------- あるイメージにたいしてPostScriptを使用するにはイメージタイプ ‘postscript’を指定します。これはGhostscriptがインストールされている場合 のみ機能します。常に以下の3つのプロパティを使用しなければなりません: ‘:pt-width WIDTH’ 値WIDTHはポイント(1/72インチ)単位で測ったイメージの幅を指定する。 WIDTHは整数でなければならない。 ‘:pt-height HEIGHT’ 値HEIGHTはポイント(1/72インチ)単位で測ったイメージの高さを指定する 。HEIGHTは整数でなければならない。 ‘:bounding-box BOX’ 値BOXは4つの整数からなるリストかベクターでなければならない。これら の整数は、PostScriptファイルの‘BoundingBox’に類似したPostScriptイメ ージのバウンディングボックスを指定する。 %%BoundingBox: 22 171 567 738 37.17.6 ImageMagickイメージ --------------------------- ImageMagickのサポートつきでEmacsをビルドした場合には、多くくのイメージフ ォーマットをロードするためにImageMagickライブラリーを使用できます(*note (emacs)File Conveniences::を参照)。ImageMagickを通じてロードしたイメージ のイメージタイプシンボルは、基礎となる実際のイメージフォーマットとは無関 係に‘imagemagick’になります。 -- Function: imagemagick-types この関数はカレントのImageMagickインストールによりサポートされるイメ ージファイル拡張子のリストをリターンする。リストの各要素は‘.bmp’イ メージは‘BMP’のような、イメージタイプにたいして内部的な ImageMagick名を表すシンボル。 -- User Option: imagemagick-enabled-types この変数の値はEmacsがImageMagickを使用してレンダリングを試みるかも しれないImageMagickイメージタイプのリスト。リストの各要素は ‘imagemagick-types’がリターンするリスト内のシンボルのいずれか、また は等価な文字列。もしくは値‘t’はImageMagickにたいして利用できるすべ てのイメージタイプを有効にする。この変数の値とは関係なく ‘imagemagick-types-inhibit’ (以下参照)が優先される。 -- User Option: imagemagick-types-inhibit この変数の値は‘imagemagick-enabled-types’の値とは無関係に、 ImageMagickを使用して決してレンダリングされることのない ImageMagickイメージタイプのリスト。値‘t’はImageMagickを完全に無効に する。 -- Variable: image-format-suffixes この変数はイメージタイプをファイル名拡張子にマッピングするalist。 EmacsはImageMagickライブラリーにイメージのタイプに関するヒントを与 えるために、この変数と‘:format’イメージプロパティ(以下参照)を組み合 わせて使用する。各要素は‘(TYPE EXTENSION)’という形式をもちTYPEはイ メージのcontent-typeを指定するシンボル、EXTENSIONは関連付けられるフ ァイル名拡張子を指定する文字列。 ImageMagickによりロードされたイメージは、追加で以下のイメージディスク リプタプロパティをサポートします: ‘:background BACKGROUND’ BACKGROUNDが非‘nil’なら、カラーを指定する文字列であること。これはイ メージが透明度をサポートする場合に、イメージのバックグラウンドカラ ーとして使用される。値が‘nil’の場合のデフォルトはフレームのバックグ ラウンドカラー。 ‘:width WIDTH, :height HEIGHT’ キーワード‘:width’と‘:height’はイメージのスケーリングに使用される。 いずれか一方のみが指定された場合には、アスペクト比を保つためにもう 一方が算出される。両方が指定された場合にはアスペクト比は保たれない かもしれない。 ‘:max-width MAX-WIDTH, :max-height MAX-HEIGHT’ キーワード‘:max-width’と‘:max-height’は、イメージのサイズがこれらの 値を超過した場合のスケーリングに使用される。‘:width’がセットされた 場合には‘max-width’より優先されて、‘:height’がセットされた場合には ‘max-height’より優先されるだろうが、それ以外ではこれらのキーワード を望むように混交できる。‘:max-width’と‘:max-height’は常にアスペクト 比を保つであろう。 ‘:format TYPE’ 値TYPEは‘image-format-suffixes’で見られるような、イメージのタイプを 指定するシンボルであること。これはイメージが関連付けられたファイル 名をもたない際に、イメージタイプを検出する助けとなるヒントを ImageMagickに提供する。 ‘:rotation ANGLE’ 回転角度を度数で指定する。 ‘:index FRAME’ *note Multi-Frame Images::を参照のこと。 37.17.7 その他のイメージタイプ ------------------------------ PBMイメージにはイメージタイプ‘pbm’を指定します。カラー、グレースケール、 およびモノクロのイメージがサポートされます。モノクロのPBMイメージにたい しては、2つの追加イメージプロパティがサポートされます。 ‘:foreground FOREGROUND’ 値FOREGROUNDはイメージのフォアグラウンドカラーを指定する文字列、ま たはデフォルトカラーなら‘nil’であること。このカラーはPBM内の1である ようなピクセルすべてに使用される。デフォルトはフレームのフォアグラ ウンドカラー。 ‘:background BACKGROUND’ 値BACKGROUNDはイメージのバックグラウンドカラーを指定する文字列、ま たはデフォルトカラーなら‘nil’であること。このカラーはPBM内の0である ようなピクセルすべてに使用される。デフォルトはフレームのバックグラ ウンドカラー。 Emacsがサポート可能な残りのイメージタイプは以下のとおり: GIF イメージタイプ‘gif’。‘:index’プロパティをサポートする。*note Multi-Frame Images::を参照のこと。 JPEG イメージタイプ‘jpeg’。 PNG イメージタイプ‘png’。 SVG イメージタイプ‘svg’。 TIFF イメージタイプ‘tiff’。‘:index’プロパティをサポートする。*note Multi-Frame Images::を参照のこと。 37.17.8 イメージの定義 ---------------------- 関数‘create-image’、‘defimage’、‘find-image’はイメージディスクリプタを作 成するための便利な手段を提供します。 -- Function: create-image file-or-data &optional type data-p &rest props この関数はFILE-OR-DATA内のデータを使用するイメージディスクリプタを 作成してリターンする。FILE-OR-DATAはファイル名、またはイメージデー タを含む文字列を指定できる。前者ならDATA-Pは‘nil’、後者なら非 ‘nil’であること。 オプション引数TYPEはイメージタイプを指定するシンボル。TYPEが省略か ‘nil’なら、‘create-image’はファイル先頭の数バイトかファイル名からイ メージタイプの判断を試みる。 残りの引数PROPSは追加のイメージプロパティを指定する。たとえば、 (create-image "foo.xpm" 'xpm nil :heuristic-mask t) この関数はそのタイプのイメージがサポートされていなければ‘nil’、それ 以外ならイメージディスクリプタをリターンする。 -- Macro: defimage symbol specs &optional doc このマクロはイメージマクロとして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’として定義される。 -- Function: find-image specs この関数はイメージ仕様SPECSのリストの1つを満足するイメージを探すた めの、便利な手段を提供する。 SPECS内の各仕様はイメージタイプに応じた内容のプロパティリストである 。すべての仕様は少なくとも‘:type TYPE’、および‘:file FILE’か ‘:data DATA’のいずれかのプロパティを含まなければならない。ここで TYPEは‘xbm’のようにイメージタイプを指定するシンボル、FILEはイメージ をロードするファイル、DATAは実際のイメージデータを含む文字列。この リスト内でTYPEがサポートされていて、かつFILEが存在する最初の仕様が 、リターンされるイメージ仕様の構築に使用される。満足する仕様がなけ れば‘nil’がリターンされる。 イメージは‘image-load-path’内で検索される。 -- User Option: 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"))) -- Function: image-load-path-for-library library image &optional path no-error この関数は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)) 37.17.9 イメージの表示 ---------------------- 自分で‘display’プロパティをセットアップしてイメージディスクリプタを使用 できますが、このセクションの関数を使用するほうがより簡単です。 -- Function: insert-image image &optional string area slice この関数はカレントバッファーのポイント位置に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’プロパティにそれを渡す。*note Display Property::を参照のこ と。 -- Function: insert-sliced-image image &optional string area rows cols この関数は‘insert-image’と同様にカレントバッファー内にIMAGEを挿入す るが、イメージをROWS✕COLSの同一サイズのスライスに分割する点が異なる 。 Emacsは各スライスを個別のイメージとして表示して、(巨大な)イメージを 表示するバッファーのページングの際にイメージ全体を上下にジャンプす るのではなく、より直感的な上下スクロールが可能になる。 -- Function: put-image image pos &optional string area この関数はカレントバッファー内のPOSの前にイメージIMAGEを配置する。 引数POSは整数かマーカーであること。これはイメージが表示されるべきバ ッファー位置を指定する。引数STRINGは代替として表示されるべきデフォ ルトのイメージを保持するテキストであること。 引数IMAGEはイメージディスクリプタでなければならず、それは ‘create-image’がリターンされたか、あるいは‘defimage’により格納され たイメージディスクリプタかもしれない。 引数AREAはマージン内にイメージを置くかどうかを指定する。これが ‘left-margin’なら左マージンにイメージが表示され、‘right-margin’なら 右マージンを指定する。AREAが‘nil’か省略なら、イメージはバッファーの テキスト内のポイント位置に表示される。 内部的には、この関数はオーバーレイを作成して、値がそのイメージであ るような‘display’プロパティをもつテキストを含む、‘before-string’プ ロパティをそのオーバーレイに与えている(なんと!)。 -- Function: remove-images start end &optional buffer この関数はBUFFERの位置STARTとENDの間のイメージを削除する。BUFFERが 省略か‘nil’ならカレントバッファーからイメージを削除する。 これは‘put-image’が行う方法でBUFFERに配置されたイメージだけを削除し て、‘insert-image’や他の方法で挿入されたイメージは削除しない。 -- Function: image-size spec &optional pixels frame この関数はペアー‘(WIDTH . HEIGHT)’としてイメージのサイズをリターン する。SPECはイメージ仕様。PIXELSが非‘nil’ならピクセル単位、それ以外 ならFRAMEのデフォルトの文字サイズの単位で量ったサイズをリターンする 。FRAMEはイメージが表示されるフレーム。FRAMEが‘nil’か省略された場合 はに選択されたフレームを使用する(*note Input Focus::を参照)。 -- Variable: max-image-size この変数はEmacsがロードするイメージの最大サイズを定義するために使用 される。Emacsはこの制限より大きいイメージのロード(と表示)を拒絶する だろう。 値が整数ならピクセル単位で量ったイメージの最大の高さと幅を直接指定 する。浮動小数点数ならフレームの高さと幅にたいする比率として、イメ ージの最大の高さと幅を指定する。値が数値でなければイメージサイズに たいする明示的な制限は存在しない。 この変数の目的は意図せずEmacsに不当に大きなイメージがロードされると を防ぐことである。これはイメージの初回ロード時だけ効果がある。イメ ージが一度イメージキャッシュに置かれると、その後に ‘max-image-size’の値が変更されても、そのイメージは常に表示可能であ る(*note Image Cache::を参照)。 37.17.10 マルチフレームのイメージ --------------------------------- 複数のイメージを含むことができるイメージファイルがいくつかあります。わた したちはこのような場合には、イメージ内に複数の“フレーム”があると表現して います。現在のところEmacsはGIF、TIFF、およびDJVMのような特定の ImageMagickフォーマットにたいする複数フレームをサポートします。 フレームは複数のページを表現するため(通常はたとえばマルチフレーム TIFFのケースが該当)、あるいはアニメーションを作成するため(通常はマルチフ レームGIFファイルのケースが該当)に使用できます。 マルチフレームイメージは、表示されるフレームを指定する整数値(0から数 える)が値であるようなプロパティ‘:index’をもっています。 -- Function: image-multi-frame-p image この関数はIMAGEが2つ以上のフレームを含めば非‘nil’をリターンする。実 際のリターン値はコンス‘(NIMAGES . DELAY)’でありNIMAGESはフレーム数 、DELAYはフレーム間の遅延秒数、イメージが遅延を指定しなければ ‘nil’。通常はアニメーションを意図されたイメージはフレームの遅延を指 定して、複数ページとして扱われることを意図したイメージは指定しない 。 -- Function: image-current-frame image この関数はIMAGEにたいして0から数えたカレントフレーム番号のインデッ クスをリターンする。 -- Function: image-show-frame image n &optional nocheck この関数はIMAGEをフレーム番号Nとスイッチする。NOCHECKが‘nil’なら有 効範囲外のフレーム番号を範囲終端に置き換える。IMAGEが指定された番号 のフレームを含まなければイメージは中抜きの四角(hollow box)で表示さ れる。 -- Function: image-animate image &optional index limit この関数はIMAGEをアニメーション表示する。オプションの整数INDEXは開 始するフレームを指定する(デフォルトは0)。オプション引数LIMITはアニ メーションの長さを制御する。これが省略か‘nil’ならアニメーション回数 は1回、‘t’なら永久にループ表示する。数値ならその秒数後にアニメーシ ョンは停止する。 アニメーションはタイマーにより処理されます。Emacsは最小のフレーム遅延を 0.01秒( ‘image-minimum-frame-delay’の値)とすることに注意してください。そ のイメージ自身が遅延を指定しなければEmacsは‘image-default-frame-delay’を 使用します。 -- Function: image-animate-timer image この関数はもし存在すればIMAGEのアニメーションに責任をもつタイマーを リターンする。 37.17.11 イメージキャッシュ --------------------------- Emacsはイメージをより効果的に再表示できるようにイメージをキャッシュしま す。Emacsがイメージを表示する際には、既存のイメージ仕様が望む仕様と ‘equal’なイメージキャッシュを検索します。マッチが見つかったらイメージは キャッシュから表示され、それ以外ではイメージは通常のようにロードされます 。 -- Function: image-flush spec &optional frame この関数はフレームFRAMEのイメージキャッシュから仕様SPECのイメージを 削除する。イメージ仕様の比較には‘equal’を使用する。FRAMEが‘nil’の場 合のデフォルトは選択されたフレーム。FRAMEが‘t’ならイメージはすべて の既存フレームでフラッシュされる。 Emacsの現実装では各グラフィカル端末はイメージキャッシュを処理して、 それはその端末上のすべてのフレームにより共有される(*note Multiple Terminals::を参照)。つまりあるフレームでイメージをリフレッシュする と、同一端末上の他のすべてのフレームでもリフレッシュされる。 ‘image-flush’の1つの用途はEmacsにイメージファイルの変更を伝えることで す。イメージ仕様が‘:file’プロパティを含む場合には、そのイメージの初回表 示時にファイルコンテンツにもとづいてイメージがキャッシュされます。たとえ その後にファイルが変更されても、Emacsはそのイメージの古いバージョンを表 示し続けます。‘image-flush’を呼び出すことによりそのイメージはキャッシュ からフラッシュされて、イメージの表示が次回必要になった際にEmacsにファイ ルの再読み込みを強制します。 ‘image-flush’の他の用途はメモリー節約です。Lispプログラムで ‘image-cache-eviction-delay’ (以下参照)より遥かに短い期間に多数の一時イ メージを作成する場合には、Emacsが自動的に行うことを待たずに自身で使用さ れていないイメージのフラッシュを選択できます。 -- Function: clear-image-cache &optional filter この関数はイメージキャッシュ内に格納されたすべてのイメージを削除し てイメージキャッシュをクリアーする。FILTERが省略か‘nil’なら選択され たフレームにたいしてキャッシュをクリアーする。FILTERがフレームなら 、そのフレームにたいしてキャッシュをクリアーする。FILTERが‘t’なら、 すべてのイメージキャッシュをクリアーする。それ以外ならFILTERはファ イル名として解釈されて、すべてのイメージキャッシュからそのファイル 名に関連付けられたすべてのイメージを削除する。 イメージキャッシュ内のイメージが指定された期間内に表示されなければ、 Emacsはそれをキャッシュから削除して割り当てられたメモリーを解放します。 -- Variable: image-cache-eviction-delay この変数は表示されることなくイメージがキャッシュ内に残留できる秒数 を指定する。あるイメージがこの秒数の間に表示されなければ、Emacsはそ れをイメージキャッシュから削除する。 ある状況下では、もしキャッシュ内のイメージ数が大きくなり過ぎた場合 には実際の立ち退き遅延(eviction delay)はこれより短くなり得る。 値が‘nil’なら明示的にキャッシュをクリアーした場合を除き、Emacsはキ ャッシュからイメージを削除しない。このモードはデバッグ時に有用かも しれない。 37.18 Embedded Native Widgets ============================= Emacsは必要なライブラリーのサポート付きでビルドされていて、かつグラフィ カル端末上で実行中なら、Emacsバッファー内にGTK WebKitウィジェットのよう なネイティブのウィジェットを表示できます。埋め込みウィジェットの表示を Emacsがサポートするかどうかをテストするためには、‘xwidget-internal’機能 が利用可能かどうかをチェックしてください(*note Named Features::を参照)。 Emacsバッファー内に埋め込みウィジェットを表示するためには、最初に xwidgetオブジェクトを作成して、テキストプロパティまたはオーバーレイプロ パティ‘display’内のディスプレイ仕様としてそのオブジェクトを使用します (*note Display Property::を参照)。 -- Function: make-xwidget type title width height arguments &optional buffer これはxwidgetオブジェクトを作成してリターンする。BUFFERが省略か ‘nil’の場合のデフォルトはカレントバッファー。BUFFERが存在しないバッ ファーの名前を指定する場合には作成する。TYPEはxwidgetコンポーネント を識別するもので以下のいずれかが可能: ‘webkit’ WebKitコンポーネント。 引数WIDTHとHEIGHTはウィジェットのサイズをピクセル単位で指定して、 TITLEはそのタイトルを指定する文字列。 -- Function: xwidgetp object この関数はOBJECTがxwidgetなら‘t’、それ以外は‘nil’をリターンする。 -- Function: xwidget-plist xwidget この関数はXWIDGETのプロパティリストをリターンする。 -- Function: set-xwidget-plist xwidget plist この関数はPLISTで与えられた新たなプロパティリストでXWIDGETのプロパ ティリストを置き換える。 -- Function: xwidget-buffer xwidget この関数はXWIDGETのバッファーをリターンする。 -- Function: get-buffer-xwidgets buffer この関数はBUFFERに関連付けられたxwidgetオブジェクトのリストをリター ンする。BUFFERはバッファーオブジェクトか既存のバッファー名(文字列 )を指定できる。BUFFERにxwidgetが含まれなければ値は‘nil’。 -- Function: xwidget-webkit-goto-uri xwidget uri この関数は与えられたXWIDGET内で指定したURIをブラウズ(browse: 閲覧 )する。URIはファイルかURLを指定する文字列。 -- Function: xwidget-webkit-execute-script xwidget script この関数はXWIDGETで指定されるブラウザウィジェットに、‘script’で指定 するJavaScriptを実行させる。 -- Function: xwidget-webkit-execute-script-rv xwidget script &optional default この関数は‘xwidget-webkit-execute-script’と同様に指定したSCRIPTを実 行するが、スクリプトのリターン値も文字列としてリターンする。この関 数はSCRIPTが値をリターンしなければDEFAULT、DEFAULTが省略されたら ‘nil’をリターンする。 -- Function: xwidget-webkit-get-title xwidget この関数はXWIDGETのタイトルを文字列としてリターンする。 -- Function: xwidget-resize xwidget width height この関数は指定したXWIDGETをWIDTHxHEIGHTのサイズ(ピクセル単位)にリサ イズする。 -- Function: xwidget-size-request xwidget この関数はXWIDGETのサイズを‘(WIDTH HEIGHT)’という形式のリストでリタ ーンする。単位はピクセル。 -- Function: xwidget-info xwidget この関数は‘[TYPE TITLE WIDTH HEIGHT]’という形式のベクターで XWIDGETの属性をリターンする。属性は通常はxwidgetの作成時に ‘make-xwidget’で決定される。 -- Function: set-xwidget-query-on-exit-flag xwidget flag この関数はEmacsがXWIDGETに関連付けられたバッファーのexitやkillの前 にユーザーに確認を求めるようにアレンジすることを可能にする。FLAGが 非‘nil’ならEmacsはユーザーに確認を求めて、それ以外なら確認を求めな い。 -- Function: xwidget-query-on-exit-flag xwidget この関数はXWIDGETのquery-on-exitフラグのカレントセッティングを‘t’か ‘nil’のいずれかでリターンする。 37.19 ボタン ============ Buttonパッケージはマウスやキーボードコマンドでアクティブ化することができ る、“ボタン(buttons)”の挿入と操作に関する関数を定義します。これらのボタ ンは典型的には種々のハイパーリンクに使用されます。 本質的にボタンとはバッファー内のテキスト範囲にアタッチされたテキスト プロパティやオーバーレイのプロパティのセットです。これらのプロパティは “ボタンプロパティ(button properties)”と呼ばれます。これらのプロパティの うちの1つは“アクションプロパティ(action property)”であり、これはユーザー がキーボードかマウスを使用してボタンを呼び出した際に呼び出される関数を指 定します。アクション関数はボタンを調べ、必要に応じて他のプロパティを使用 できます。 いくつかの機能面でButtonパッケージとWidgetパッケージは重複しています 。*note Introduction: (widget)Top.を参照してください。Buttonパッケージの 利点は、より高速で小さくプログラムにたいしてよりシンプルであることです。 ユーザーの観点からは、2つのパッケージが提供するインターフェイスは非常に 類似しています。 37.19.1 ボタンのプロパティ -------------------------- ボタンはその外観と振る舞いを定義するプロパティの連想リスト(associated list)をもち、アプリケーションの特別な目的のために他の任意のプロパティを 使用できます。以下のプロパティはButtonパッケージにたいして特別な意味をも ちます: ‘action’ ユーザーがボタンを呼び出した際に呼び出す関数であり、単一の引数 BUTTONを渡して呼び出される。デフォルトではこれは何も行わない ‘ignore’。 ‘mouse-action’ これは‘action’と似ているが与えられた際には、(押下のかわりに)マ ウスクリックによりボタンが呼び出された場合n‘action’のかわりに使用 される。与えられなければマウスクリックはかわりに‘action’を使用する 。 ‘face’ このタイプのボタンが表示される方法を制御するEmacsフェイス。デフォル トは‘button’フェイス。 ‘mouse-face’ ボタン上にマウスがある際の外観を制御する追加のフェイス(通常の buttonフェイスとマージされる)。デフォルトはEmacsの通常の ‘highlight’フェイス。 ‘keymap’ そのボタンリージョン(button region)でアクティブなバインディングを定 義するボタンのキーマップ。デフォルトは変数‘button-map’に格納された 通常のボタンリージョンキーマップであり、これはボタン呼び出しにたい してを定義している。 ‘type’ ボタンのタイプ。*note Button Types::を参照のこと。 ‘help-echo’ Emacsのツールチップヘルプシステムにより表示あれる文字列。デフォルト は‘"mouse-2, RET: Push this button"’。 ‘follow-link’ このボタンにたいしてクリックが振る舞う方法を定義する follow-linkプロパティ。*note Clickable Text::を参照のこと。 ‘button’ すべてのボタンは非‘nil’の‘button’プロパティをもち、これはボタンを含 むテキストリージョンを探すのに有用かもしれない(標準的なボタン関数は これを行う)。 ボタン内のテキストリージョンにたいして定義された他のプロパティも存在 しますが、それらは典型的な用途にたいしては一般的には無関係でしょう。 37.19.2 ボタンのタイプ ---------------------- すべてのボタンはボタンのプロパティにたいするデフォルト値を定義する“ボタ ンタイプ(button type)”をもっています。ボタンタイプは、より汎用的なタイプ から特化したタイプへと継承される階層構造で構成されており、特定のタスクに たいして特殊用途のボタンを簡単に定義できます。 -- Function: define-button-type name &rest properties NAME (シンボル)と呼ばれるボタンタイプを定義する。残りの引数は PROPERTY VALUEペアーのシーケンスを形成する。これはそのタイプのボタ ンにたいするデフォルトのプロパティ値を指定する(ボタンのタイプはキー ワード引数‘:type’を使用してボタン作成時にそれを‘type’プロパティに与 えることによりセット可能)。 加えてNAMEがデフォルトプロパティ値を継承するボタンタイプ指定するた めにキーワード引数‘:supertype’を使用できる。この継承はNAMEの定義時 のみ発生することに注意。その後にsupertypeに行われた変更はsubtypeに は反映されない。 ‘define-button-type’を使用してボタンのデフォルトプロパティを定義する のは必須ではありません — 特定のタイプをもたないボタンはビルトインのボタ ンタイプ‘button’を使用します — が推奨しません。これを行うことにより通常 はコードがより明快かつ効果的になるからです。 37.19.3 ボタンの作成 -------------------- ボタンはボタン固有の情報を保持するために、オーバーレイプロパティかテキス トプロパティを使用してテキストのリージョンに関連付けられます。これらはす べてボタンのタイプ(デフォルトはビルトインのボタンタイプ‘button’)から初期 化されます。すべてのEmacsテキストと同じようにボタンの外観は‘face’プロパ ティにより制御されます。(ボタンタイプ‘button’から継承された‘face’プロパ ティを通じることにより)デフォルトでは典型的なウェブページリンクのような シンプルなアンダーラインです。 簡便さのために2種類のボタン作成関数があります。1つはバッファーの既存 リージョンにボタンプロパティを追加する‘make-...button’と呼ばれる関数、も う1つはボタンテキストを挿入する‘insert-...button’と呼ばれる関数です。 すべてのボタン作成関数は‘&rest’引数のPROPERTIESを受け取ります。これは ボタンに追加するプロパティを指定するPROPERTY VALUEペアーのシーケンスであ る必要があります。*note Button Properties::を参照してください。これに加 えて他のプロパティの継承元となるボタンタイプの指定にキーワード引数 ‘:type’を使用できます。*note Button Types::を参照してください。作成の間 に明示的に指定されなかったプロパティは、(そのタイプがそのようなプロパテ ィを定義していれば)そのボタンのタイプから継承されます。 以下の関数はボタンプロパティを保持するためにオーバーレイを使用してボ タンを追加します(*note Overlays::を参照)。 -- Function: make-button beg end &rest properties これはカレントバッファー内のBEGからENDにボタンを作成してリターンす る。 -- Function: insert-button label &rest properties これはポイント位置にラベルLABELのボタンを挿入してリターンする。 以下の関数も同様ですが、ボタンプロパティを保持するためにテキストプロ パティを使用します(*note Text Properties::を参照)。この種のボタンはバッ ファーにマーカーを追加しないので、非常に多数のボタンが存在してもバッファ ーでの編集が低速になることはありません。しかしそのテキストに既存のfaceテ キストプロパティが存在する場合(たとえばFont Lockモードにより割り当てられ たフェイス)には、そのボタンのフェイスは可視にならないかもしれません。こ れらの関数はいずれも新たなボタンの開始位置をリターンします。 -- Function: make-text-button beg end &rest properties これはテキストプロパティを使用してカレントバッファー内のBEGから ENDにボタンを作成する。 -- Function: insert-text-button label &rest properties これはテキストプロパティを使用してポイント位置にラベルLABELのボタン を挿入する。 37.19.4 ボタンの操作 -------------------- ボタンのプロパティの取得やセットを行う関数が存在します。これらは何を行う かを判断するためにボタンが呼び出す関数からよく使用される関数です。 BUTTONパラメーターが指定された場合にはオーバーレイ(オーバーレイボタン の場合)、またはバッファー位置やマーカー(テキストプロパティボタンの場合 )いずれかという、特定のボタンを参照するオブジェクトを意味します。そのよ うなオブジェクトはボタンが関数を呼び出す際に1つ目の引数として渡されます 。 -- Function: button-start button BUTTONが開始される位置をリターンする。 -- Function: button-end button BUTTONが終了する位置をリターンする。 -- Function: button-get button prop ボタンBUTTONのPROPという名前のプロパティを取得する。 -- Function: button-put button prop val BUTTONのPROPプロパティにVALをセットする。 -- Function: button-activate button &optional use-mouse-action BUTTONの‘action’プロパティを呼び出す(単一の引数BUTTONを渡してプロパ ティの値である関数を呼び出す)。USE-MOUSE-ACTIONが非‘nil’なら、 ‘action’のかわりにそのボタンの‘mouse-action’プロパティの呼び出しを 試みる。ボタンが‘mouse-action’プロパティをもたなければ通常どおり ‘action’を使用する。 -- Function: button-label button BUTTONのテキストラベルをリターンする。 -- Function: button-type button BUTTONのボタンタイプをリターンする。 -- Function: button-has-type-p button type BUTTONがボタンタイプTYPE、またはTYPEのsubtypeのいずれかをもつなら ‘t’をリターンする。 -- Function: button-at pos カレントバッファー内の位置POSにあるボタン、または‘nil’をリターンす る。POSにあるボタンがテキストプロパティボタンならリターン値はPOSを 指すマーカー。 -- Function: button-type-put type prop val ボタンタイプTYPEのPROPプロパティにVALをセットする。 -- Function: button-type-get type prop ボタンタイプTYPEのPROPという名前のプロパティを取得する。 -- Function: button-type-subtype-p type supertype ボタンタイプTYPEがSUPERTYPEのsubtypeなら‘t’をリターンする。 37.19.5 ボタンのためのバッファーコマンド ---------------------------------------- Emacsバッファー内にボタンの配置や操作を行うコマンドや関数が存在します。 ‘push-button’はユーザーが実際にボタンを押下(push)するために使用するコ マンドであり、そのボタンのオーバーレイプロパティかテキストプロパティを使 用することにより、そのボタンのにデフォルトでバインドされ ます。ボタン自身の外部で有用な‘forward-button’や‘backward-button’のよう なコマンドは、‘button-buffer-map’に格納されたキーマップ内で追加で利用可 能です。ボタンを使用するモードはそのキーマップの親キーマップとして ‘button-buffer-map’の使用を望むかもしれません。 ボタンが非‘nil’の‘follow-link’プロパティをもち、かつ ‘mouse-1-click-follows-link’がセットされている場合には、素早い クリックにより‘push-button’コマンドもアクティブになるでしょう。 *note Clickable Text::を参照してください。 -- Command: push-button &optional pos use-mouse-action 位置POSにあるボタンが指定するアクションを行う。POSはバッファー位置 、またはマウスイベントのいずれか。USE-MOUSE-ACTIONが非‘nil’、または POSがマウスイベントなら‘action’のかわりにそのボタンの ‘mouse-action’プロパティの呼び出しを試みて、ボタンに ‘mouse-action’プロパティがなければ通常のように‘action’を使用する。 ‘push-button’がマウスイベントの結果としてインタラクティブに呼び出さ れたときはそのマウスイベントの位置、それ以外ではポイントの位置が POSのデフォルトになる。POSにボタンがなければ何もせずに‘nil’をリター ンして、それ以外なら‘t’をリターンする。 -- Command: forward-button n &optional wrap display-message 次のN番目、Nが負なら前のN番目のボタンに移動する。Nが0ならポイント位 置にある任意のボタンの開始に移動する。WRAPが非‘nil’ならバッファーの 先頭または終端を超えてもう一方の端へ移動を継続する。 DISPLAY-MESSAGEが非‘nil’ならボタンのhelp-echo文字列が表示される。非 ‘nil’の‘skip’プロパティをもつボタンはすべてスキップされる。見つかっ たボタンをリターンする。 -- Command: backward-button n &optional wrap display-message 前のN番目、Nが負なら次のN番目のボタンに移動する。Nが0ならポイント位 置にある任意のボタンの開始に移動する。WRAPが非‘nil’ならバッファーの 先頭または終端を超えて、もう一方の端へ移動を継続する。 DISPLAY-MESSAGEが非‘nil’ならボタンのhelp-echo文字列が表示される。非 ‘nil’の‘skip’プロパティをもつボタンはすべてスキップされる。見つかっ たボタンをリターンする。 -- Function: next-button pos &optional count-current -- Function: previous-button pos &optional count-current カレントバッファー内の位置POSの次(‘next-button’の場合)、または前 (‘previous-button’の場合)のボタンをリターンする。COUNT-CURRENTが非 ‘nil’なら、次のボタンから検索を開始するかわりにPOSにある任意のボタ ンを考慮する。 37.20 抽象的なディスプレー ========================== EwocパッケージはLispオブジェクトの構造を表すバッファーテキストを構成して 、その構造体の変更にしたがってテキストを更新します。これはデザインパラダ イム“model–view–controller”内の“view”コンポーネントと似ています。Ewocは “Emacs’s Widget for Object Collections(オブジェクトコレクション用Emacsウ ィジェット)”を意味します。 “ewoc”は特定のLispデータを表現するバッファーテキストの構築に要される 情報を組織化します。ewocのバッファーテキストは順番に、まず固定された “header”テキスト、次に一連のデータ要素のテキスト記述(あなたが指定する Lispオブジェクト)、最後に固定された“footer”テキストという3つのパートをも っています。具体的にはewocは以下の情報を含んでいます: • そのテキストが生成されたバッファー。 • バッファー内でのそのテキストの開始位置。 • ヘッダー文字列とフッター文字列。 • 2重リンクされた“ノード(nodes)”のチェーン。各ノードは以下を含む: • “データ要素(data element)”。単一のLispオブジェクト。 • そのチェーン内で先行と後続のノードへのリンク。 • カレントバッファー内にデータ要素値のテキスト表現を挿入する責務をも つ“pretty-printer”関数。 通常は‘ewoc-create’によりewocを定義して、その結果のewoc構造体内にノー ドを構築するためにEwocパッケージ内の別の関数に渡してバッファー内に表示し ます。バッファー内でこれが一度表示されれば、他の関数はバッファー位置とノ ードの対応を判断したり、あるノードのテキスト表現から別のノードのテキスト 表現への移動等を行います。*note Abstract Display Functions::を参照してく ださい。 ノードは変数が値を保持するのと同じ方法でデータ要素を“カプセル化 (encapsulate)”します。カプセル化は通常はewocへのノード追加の一部として発 生します。以下のようにデータ要素値を取得して、その場所に新たな値を配置す ることができます: (ewoc-data NODE) ⇒ value (ewoc-set-data NODE NEW-VALUE) ⇒ NEW-VALUE データ要素値として実際の値のコンテナーであるようなLispオブジェクト(リス トまたはベクター)、または他の構造体へのインデックスも使用できます。例 (*note Abstract Display Example::を参照)では後者のアプローチを使用してい ます。 データが変更された際にはバッファー内のテキストを更新したいでしょう。 ‘ewoc-refresh’呼び出しにより全ノード、‘ewoc-invalidate’を使用して特定の ノード、または‘ewoc-map’を使用して述語を満足するすべてのノードを更新でき ます。あるいは‘ewoc-delete’を使用して無効なノードを削除したり、その場所 に新たなノードを追加できます。ewocからのノード削除はバッファーからそれに 関連付けられたテキスト記述も同様に削除します。 37.20.1 抽象ディスプレーの関数 ------------------------------ このセクションでは、EWOCとNODEは上述(*note Abstract Display::を参照)の構 造体を、DATAはデータ要素として使用される任意のLispオブジェクトを意味しま す。 -- Function: ewoc-create pretty-printer &optional header footer nosep これはノード(とデータ要素)をもたない新たなewocを構築してリターンす る。PRETTY-PRINTERは1つの引数を受け取る関数であること。この引数は当 該ewoc内で使用を計画する類のデータ要素であり、‘insert’を使用してポ イント位置にそのテキスト記述を挿入する(Ewocパッケージの内部的メカニ ズムと干渉するために‘insert-before-markers’は決して使用しない)。 ヘッダー、フッター、およびすべてのノードのテキスト記述の後には、通 常は自動的に改行が挿入される。NOSEPが非‘nil’なら改行は何も挿入され ない。これはewoc全体を単一行に表示したり、これらのノードにたいして 何も行わないようにPRETTY-PRINTERをアレンジすることによりノードを不 可視にするために有用かもしれない。 ewocは作成時にカレントだったバッファー内のテキストを保守するので、 ‘ewoc-create’呼び出し前に意図するバッファーへ切り替えること。 -- Function: ewoc-buffer ewoc これは、EWOCがそのテキストを保守するバッファーをリターンする。 -- Function: ewoc-get-hf ewoc これはEWOCのヘッダーとフッターから作成されたコンスセル‘(HEADER . FOOTER)’をリターンする。 -- Function: ewoc-set-hf ewoc header footer これはEWOCのヘッダーとフッターに文字列HEADERとFOOTERをセットする。 -- Function: ewoc-enter-first ewoc data -- Function: ewoc-enter-last ewoc data これらはそれぞれDATAを新たなノードにカプセル化して、それをEWOCのチ ェーンノードの先頭または終端に配置する。 -- Function: ewoc-enter-before ewoc node data -- Function: ewoc-enter-after ewoc node data これらはそれぞれDATAを新たなノードにカプセル化して、それをEWOCの NODEの前または後に追加する。 -- Function: ewoc-prev ewoc node -- Function: ewoc-next ewoc node これらはそれぞれEWOC内のNODEの前または次のノードをリターンする。 -- Function: ewoc-nth ewoc n これはEWOC内で0基準のインデックスNで見つかったノードをリターンする 。負のNは終端から数えることを意味する。Nが範囲外なら‘ewoc-nth’は ‘nil’をリターンする。 -- Function: ewoc-data node これはNODEにカプセル化されたデータを抽出してリターンする。 -- Function: ewoc-set-data node data これはNODEにカプセル化されるデータとしてDATAをセットする。 -- Function: ewoc-locate ewoc &optional pos guess これはポイント(指定された場合はPOS)を含むEWOC内のノードを判断して、 そのノードをリターンする。EWOCがノードをもたなければ、‘nil’をリター ンする。POSが最初のノードの前なら最初のノード、最後のノードの後なら 最後のノードをリターンする。オプションの3つ目の引数GUESSは、POS近傍 にあると思われるノードであること。これは結果を変更しないが、関数の 実行を高速にする。 -- Function: ewoc-location node これはNODEの開始位置をリターンする。 -- Function: ewoc-goto-prev ewoc arg -- Function: ewoc-goto-next ewoc arg これらはそれぞれEWOC内の前または次のARG番目のノードにポイントを移動 する。すでに最初のノードにポイントがある場合、またはEWOCが空の場合 には‘ewoc-goto-prev’は移動しない。また‘ewoc-goto-next’が最後のノー ドを超えて移動すると結果は‘nil’。この特殊なケースを除き、これらの関 数は移動先のノードをリターンする。 -- Function: ewoc-goto-node ewoc node これはEWOC内のNODEの開始にポイントを移動する。 -- Function: ewoc-refresh ewoc この関数はEWOCのテキストを再生成する。これはヘッダーとフッターの間 のテキスト、すなわちすべてのデータ要素の表現を削除して、各ノードに たいして1つずつ順にpretty-printer関数を呼び出すことによりすることに より機能する。 -- Function: ewoc-invalidate ewoc &rest nodes これは‘ewoc-refresh’と似ているが、EWOC内のノードセット全体ではなく NODESだけを対象とする点が異なる。 -- Function: ewoc-delete ewoc &rest nodes これはEWOCからNODES内の各要素を削除する。 -- Function: ewoc-filter ewoc predicate &rest args これはEWOC内の各データ要素にたいしてPREDICATEを呼び出して、 PREDICATEが‘nil’をリターンしたノードを削除する。任意のARGSを PREDICATEに渡すことができる。 -- Function: ewoc-collect ewoc predicate &rest args これはEWOC内の各データ要素にたいしてPREDICATEを呼び出して、 PREDICATEが非‘nil’をリターンしたノードのリストをリターンする。リス ト内の要素はバッファー内での順序になる。任意のARGSをPREDICATEに渡す ことができる。 -- Function: ewoc-map map-function ewoc &rest args これはEWOC内の各データ要素にたいしてMAP-FUNCTIONを呼び出して、 MAP-FUNCTIONが非‘nil’をリターンしたノードを更新する。任意のARGSを MAP-FUNCTIONに渡すことができる。 37.20.2 抽象ディスプレーの例 ---------------------------- 以下は3つの整数からなるベクターを表すバッファー内の領域である“カラー構成 (color components)”表示をewocパッケージ内の関数を使用して、さまざまな方 法で実装するシンプルな例です。 (setq colorcomp-ewoc nil colorcomp-data nil colorcomp-mode-map nil colorcomp-labels ["Red" "Green" "Blue"]) (defun colorcomp-pp (data) (if data (let ((comp (aref colorcomp-data data))) (insert (aref colorcomp-labels data) "\t: #x" (format "%02X" comp) " " (make-string (ash comp -2) ?#) "\n")) (let ((cstr (format "#%02X%02X%02X" (aref colorcomp-data 0) (aref colorcomp-data 1) (aref colorcomp-data 2))) (samp " (sample text) ")) (insert "Color\t: " (propertize samp 'face `(foreground-color . ,cstr)) (propertize samp 'face `(background-color . ,cstr)) "\n")))) (defun colorcomp (color) "新たなバッファー内でCOLORの編集を許可する。 そのバッファーはColor Componentsモードになる。" (interactive "sColor (name or #RGB or #RRGGBB): ") (when (string= "" color) (setq color "green")) (unless (color-values color) (error "No such color: %S" color)) (switch-to-buffer (generate-new-buffer (format "originally: %s" color))) (kill-all-local-variables) (setq major-mode 'colorcomp-mode mode-name "Color Components") (use-local-map colorcomp-mode-map) (erase-buffer) (buffer-disable-undo) (let ((data (apply 'vector (mapcar (lambda (n) (ash n -8)) (color-values color)))) (ewoc (ewoc-create 'colorcomp-pp "\nColor Components\n\n" (substitute-command-keys "\n\\{colorcomp-mode-map}")))) (set (make-local-variable 'colorcomp-data) data) (set (make-local-variable 'colorcomp-ewoc) ewoc) (ewoc-enter-last ewoc 0) (ewoc-enter-last ewoc 1) (ewoc-enter-last ewoc 2) (ewoc-enter-last ewoc nil))) この例は‘colorcomp-data’の変更して選択プロセスを“完了”して、それらを 互いに簡便に結ぶキーマップを定義することにより(言い換えると “model/view/controller”デザインパラダイムのcontroller部分)、“color selection widget”への拡張が可能です。 (defun colorcomp-mod (index limit delta) (let ((cur (aref colorcomp-data index))) (unless (= limit cur) (aset colorcomp-data index (+ cur delta))) (ewoc-invalidate colorcomp-ewoc (ewoc-nth colorcomp-ewoc index) (ewoc-nth colorcomp-ewoc -1)))) (defun colorcomp-R-more () (interactive) (colorcomp-mod 0 255 1)) (defun colorcomp-G-more () (interactive) (colorcomp-mod 1 255 1)) (defun colorcomp-B-more () (interactive) (colorcomp-mod 2 255 1)) (defun colorcomp-R-less () (interactive) (colorcomp-mod 0 0 -1)) (defun colorcomp-G-less () (interactive) (colorcomp-mod 1 0 -1)) (defun colorcomp-B-less () (interactive) (colorcomp-mod 2 0 -1)) (defun colorcomp-copy-as-kill-and-exit () "color componentsをkillリングにコピーしてバッファーをkill。 文字列は#RRGGBB(6桁16進が付加されたハッシュ)にフォーマットされる。" (interactive) (kill-new (format "#%02X%02X%02X" (aref colorcomp-data 0) (aref colorcomp-data 1) (aref colorcomp-data 2))) (kill-buffer nil)) (setq colorcomp-mode-map (let ((m (make-sparse-keymap))) (suppress-keymap m) (define-key m "i" 'colorcomp-R-less) (define-key m "o" 'colorcomp-R-more) (define-key m "k" 'colorcomp-G-less) (define-key m "l" 'colorcomp-G-more) (define-key m "," 'colorcomp-B-less) (define-key m "." 'colorcomp-B-more) (define-key m " " 'colorcomp-copy-as-kill-and-exit) m)) わたしたちが決して各ノード内のデータを変更していないことに注意してく ださい。それらのデータはewoc作成時に‘nil’、または実際のカラーコンポーネ ントであるベクター‘colorcomp-data’にたいするインデックスに固定されていま す。 37.21 カッコの点滅 ================== このセクションではユーザーが閉カッコを挿入した際に、マッチする開カッコを Emacsが示すメカニズムを説明します。 -- Variable: blink-paren-function この変数の値は閉カッコ構文(close parenthesis syntax)の文字が挿入さ れた際に常に呼び出される関数(引数なし)であること。 ‘blink-paren-function’の値は‘nil’も可能であり、この場合は何も行わな い。 -- User Option: blink-matching-paren この変数が‘nil’なら‘blink-matching-open’は何も行わない。 -- User Option: blink-matching-paren-distance この変数はギブアップする前にマッチするカッコをスキャンする最大の距 離を指定する。 -- User Option: blink-matching-delay この変数はマッチするカッコを示し続ける秒数を指定する。分数の秒も良 好な結果をもたらすことがあるが、デフォルトはすべてのシステムで機能 する1である。 -- Command: blink-matching-open この関数は‘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))) 37.22 文字の表示 ================ このセクションでは文字がEmacsにより実際に表示される方法について説明しま す。文字は通常は“グリフ(glyph)”として表示されます。グリフとはスクリーン 上で1文字の位置を占めるグラフィカルなシンボルであり、その外観はその文字 自身に対応します。たとえば文字‘a’ (文字コード97)は‘a’と表示されます。し かしいくつかの文字は特別な方法で表示されます。たとえば改頁文字(文字コー ド12)は通常は2つのグリフのシーケンス‘^L’で表示されて、改行文字(文字コー ド10)は新たなスクリーン行を開始します。 “ディスプレイテーブル(display table)”を定義することにより、各文字が表 示される方法を変更できます。これはそれぞれの文字をグリフのシーケンスにマ ップするテーブルです。*note Display Tables::を参照してください。 37.22.1 通常の表示の慣習 ------------------------ 以下は各文字コードの表示にたいする慣習です(ディスプレイテーブルが存在し なければこれらの慣習をオーバーライドできる 。*note Display Tables::)を参 照)。 • コード32から126の“プリント可能ASCII文字(printable ASCII characters: 数字、英文字、および‘#’のようなシンボル)”は文字通りそのまま表示され る。 • タブ文字(文字コード9)は次のタブストップ列まで伸長された空白文字とし て表示される。*note (emacs)Text Display::を参照のこと。変数 ‘tab-width’はタブストップごとのスペース数を制御する(以下参照)。 • 改行文字(文字コード10)は特殊効果をもつ。これは先行する行を終端して 新たな行を開始する。 • 非プリント可能“ASCII制御文字(ASCII control characters)” — 文字コー ド0から31と文字(文字コード127) — は変数‘ctl-arrow’に応じて2つ の方法のいずれかで表示される。この変数が非‘nil’ (デフォルト)なら、 たとえばにたいしては‘^?’のように、これらの文字は1つ目のグリフ が‘^’ (‘^’のかわりに使用する文字をディスプレイテーブルで指定できる )のような2つのグリフのシーケンスとして表示される。 ‘ctl-arrow’が‘nil’なら、これらの文字は8進エスケープとして表示される (以下参照)。 このルールはバッファー内に復帰文字(CR: carriage return、文字コード 13)があればそれにも適用される。しかし復帰文字は通常はバッファーテキ スト内には存在しない。これらは行末変換(end-of-line conversion)の一 部として除去される(*note Coding System Basics::を参照)。 • “rawバイト(raw bytes)”とはコード128から255の非ASCII文字である。これ らの文字は“8進エスケープ(octal escapes)”として表示される。これは1つ 目が‘\’にたいするASCIIコードのグリフで、残りがその文字のコードを8進 で表した数字である(ディスプレイテーブルで‘\’のかわりに使用するグリ フを指定できる)。 • 255を超える非ASCII文字は、端末がサポートしていればそのまま表示され る。端末がサポートしない場合には、その文字は“グリフなし (glyphless)”と呼ばれて、通常はプレースホルダーグリフを使用して表示 される。たとえばある文字にたいしてグラフィカル端末がフォントをもた なければ、Emacsは通常は16進文字コードを含むボックスを表示する。 *note Glyphless Chars::を参照のこと。 上記の表示慣習はたとえディスプレイテーブルがあっても、アクティブディ スプレイテーブル内のエントリーが‘nil’であるようなすべての文字にたいして 適用されます。したがってディスプレイテーブルのセットアップ時に指定が必要 なのは特別な振る舞いを望む文字だけです。 以下の変数はスクリーン上で特定の文字が表示される方法に影響します。こ れらはその文字が占める列数を変更するのでインデント関数にも影響を与えます 。またモードラインが表示される方法にも影響があります。新たな値を使用して モードラインを強制的に再表示するには関数‘force-mode-line-update’を呼び出 してください(*note Mode Line Format::を参照)。 -- User Option: ctl-arrow このバッファーローカル変数はコントロール文字が表示される方法を制御 する。非‘nil’なら‘^A’のようにカレットとその文字、‘nil’なら‘\001’の ようにバックスラッシュと8進3桁のように8進エスケープとして表示される 。 -- User Option: tab-width このバッファーローカル変数の値はEmacsバッファー内でのタブ文字表示で 使用するタブストップ間のスペース数。値は列単位でデフォルトは8。この 機能はコマンド‘tab-to-tab-stop’で使用されるユーザー設定可能なタブス トップとは完全に無関係であることに注意。*note Indent Tabs::を参照の こと。 37.22.2 ディスプレーテーブル ---------------------------- ディスプレイテーブルとはサブタイプとして‘display-table’をもつ特殊用途の 文字テーブル(*note Char-Tables::を参照)であり、文字の通常の表示慣習をオ ーバーライドするために使用されます。このセクションではディスプレイテーブ ルオブジェクトの作成と調査、および要素を割り当てる方法について説明します 。 -- Function: make-display-table これはディスプレイテーブルを作成してリターンする。テーブルは初期状 態ではすべての要素に‘nil’をもつ。 ディスプレイテーブルの通常の要素は文字コードによりインデックス付けさ れます。インデックスCの要素はコードCの表示方法を示します。値は‘nil’ (こ れは通常の表示慣習に応じて文字Cを表示することを意味する。*note Usual Display::を参照)、またはグリフコードのベクター(これらのグリフとして文字 Cを表示することを意味する。*note Glyphs::を参照)のいずれかです。 *警告:* 改行文字の表示を変更するためにディスプレイテーブルを使用する と、バッファー全体が1つの長い行として表示されるでしょう。 ディスプレイテーブルは特殊用途向け6つの“エクストラスロット(extra slots)”をもつこともできます。以下はそれらの意味についてのテーブルです。 ‘nil’のスロットは以下で示すそのスロットにたいするデフォルトの使用を意味 します。 0 切り詰められたスクリーン行終端のグリフ(デフォルトでは‘$’)。*note Glyphs::を参照のこと。グラフィカルな端末ではEmacsは切り詰められたこ とをフリンジ内の矢印で示してディスプレイテーブルは使用しない。 1 継続行終端のグリフ(デフォルトは‘\’)。グラフィカルな端末ではEmacsは 継続をフリンジ内の曲矢印で示してディスプレイテーブルは使用しない。 2 8進文字コードとして表示される文字を示すグリフ(デフォルトは‘\’)。 3 コントロール文字を示す(デフォルトは‘^’)。 4 不可視行があることを示すグリフのベクター(デフォルトは‘...’)。*note Selective Display::を参照のこと。 5 横並びのウィンドウ間のボーダー描画に使用されるグリフ(デフォルトは ‘|’)。*note Splitting Windows::を参照のこと。これはスクロールバーが 存在するときだけ効果をもつ。スクロールバーがサポートされていて使用 中ならスクロールバーが2つのウィンドウを分割する。 たとえば以下は関数‘make-glyph-code’にたいして‘ctl-arrow’に非‘nil’をセ ットして得られる効果を模倣するディスプレイテーブル(*note Glyphs::を参照 のこと)を構築する例です: (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))))) -- Function: display-table-slot display-table slot この関数はDISPLAY-TABLEのエクストラスロットSLOTの値をリターンする。 引数SLOTには0から5の数字(両端を含む)、またはスロット名(シンボル)を 指定できる。有効なシンボルは‘truncation’、‘wrap’、‘escape’、 ‘control’、‘selective-display’、‘vertical-border’。 -- Function: set-display-table-slot display-table slot value この関数はDISPLAY-TABLEのエクストラスロットSLOTにVALUEを格納する。 引数SLOTには0から5の数字(両端を含む)、またはスロット名(シンボル)を 指定できる。有効なシンボルは‘truncation’、‘wrap’、‘escape’、 ‘control’、‘selective-display’、‘vertical-border’。 -- Function: describe-display-table display-table この関数はヘルプバッファーにディスプレイテーブルDISPLAY-TABLEの説明 を表示する。 -- Command: describe-current-display-table このコマンドはヘルプバッファーにカレントディスプレイテーブルの説明 を表示する。 37.22.3 アクティブなディスプレーテーブル ---------------------------------------- ウィンドウはそれぞれディスプレイテーブルを指定でき、各バッファーもディス プレイテーブルを指定できます。もしウィンドウにディスプレイテーブルがあれ ば、それはバッファーのディスプレイテーブルより優先されます。ウィンドウと バッファーがいずれもディスプレイテーブルをもたなければ、Emacsは標準的な ディスプレイテーブルの使用を試みます。標準ディスプレイテーブルが‘nil’な らEmacsは通常の文字表示慣習を使用します(*note Usual Display::を参照)。 ディスプレイテーブルはモードラインが表示される方法に影響を与えるので 、新たなディスプレイテーブルを使用してモードラインを強制的に再表示するに は‘force-mode-line-update’を使用することに注意してください(*note Mode Line Format::を参照)。 -- Function: window-display-table &optional window この関数はWINDOWのディスプレイテーブル、ディスプレイテーブルがなけ れば‘nil’をリターンする。WINDOWのデフォルトは選択されたウィンドウ。 -- Function: set-window-display-table window table この関数はWINDOWのディスプレイテーブルにTABLEをセットする。引数 TABLEはディスプレイテーブルか‘nil’のいずれかであること。 -- Variable: buffer-display-table この変数はすべてのバッファーにおいて自動的にバッファーローカルにな る。変数の値はバッファーのディスプレイテーブルを指定する。これが ‘nil’ならバッファーのディスプレイテーブルは存在しない。 -- Variable: standard-display-table この変数の値は、ウィンドウ内にバッファーを表示する際にウィンドウデ ィスプレイテーブルとバッファーディスプレイテーブルのいずれも定義さ れていないときや、Emacsがテキストを標準出力やエラーストリームに出力 中のときにEmacsが使用する標準ディスプレイテーブル(standard display table)。変数のデフォルトは通常は‘nil’だが、対話的なセッションで端末 がcurved quotesを表示できなければ、そのデフォルトはcurved quotesを ASCIIに近似的にマップする。*note Keys in Documentation::を参照のこ と。 ‘disp-table’ライブラリーでは、標準ディスプレイテーブルを変更するため に、いくつかの関数を定義されています。 37.22.4 グリフ -------------- “グリフ(glyph)”とはスクリーン上で1文字を占めるグラフィカルなシンボルです 。各グリフはLisp内で“グリフコード(glyph code)”として表現されます。これは 文字と、表示するフェイスをオプションで指定します(*note Faces::を参照)。 ディスプレイテーブル内でのエントリーとしての使用がグリフコードの主な用途 です(*note Display Tables::を参照)。以下の関数はグリフコードを操作するた めに使用されます: -- Function: make-glyph-code char &optional face この関数は文字CHARを表すグリフをフェイスFACEでリターンする。FACEが 省略か‘nil’ならグリフはデフォルトフェイスを使用して、その場合にはグ リフコードは整数。FACEが非‘nil’ならグリフコードが整数オブジェクトで ある必要はない。 -- Function: glyph-char glyph この関数はグリフコードGLYPHの文字をリターンする。 -- Function: glyph-face glyph この関数はグリフコードGLYPHのフェイス、またはGLYPHがデフォルトフェ イスを使用する場合には‘nil’をリターンする。 テキスト端末上で実際にどのようにグリフコードを表示するかを変更するた めに“glyph table”をセットアップできる。この機能は半ば時代遅れであり、か わりに‘glyphless-char-display’を使用すること(*note Glyphless Chars::を参 照)。 -- Variable: glyph-table この変数の値が非‘nil’なら、それはカレントグリフテーブルである。これ は文字端末上でのみ効果があり、グラフィカルディスプレイ上ではすべて のグリフはそのままliteralに表示される。グリフテーブルはG番目の要素 がグリフコードGの表示方法を指定するようなベクターであること。ここで Gはフェイス未指定なグリフにたいするグリフコード。要素はそれぞれ以下 のいずれかであること: ‘nil’ そのグリフをそのままliteralに表示する。 文字列 指定された文字列を端末に送信することによりグリフを表示する。 グリフコード 指定されたグリフコードをかわりに表示する。 グリフテーブルのテーブル長以上の整数グリフコードは、そのまま literalに表示される。 37.22.5 グリフ文字の表示 ------------------------ “グリフ無し文字(glyphless characters)”とはliteralに表示されるのではなく 特別な方法、すなわち16進コードを中に含むボックスとして表示される文字です 。これらの文字にはグリフが無いと明示的に定義された文字や、利用可能なフォ ントがない文字(グラフィカルなディスプレイ)、その端末のコーディングシステ ムではエンコードできない文字(テキスト端末)が同様に含まれます。 -- Variable: glyphless-char-display この変数の値はグリフ無し文字と表示方法を定義する文字テーブル。エン トリーはそれぞれ以下の表示メソッドのいずれかでなければならない: ‘nil’ 通常の方法でその文字を表示する。 ‘zero-width’ その文字を表示しない。 ‘thin-space’ グラフィカルな端末では幅が1ピクセル、テキスト端末では幅が1文字 の狭いスペース。 ‘empty-box’ 空のボックスを表示する。 ‘hex-code’ その文字のUnicodeコードポイントの16進表記を含むボックスを表示 する。 ASCII文字列 その文字列を含むボックスを表示する。文字列には最大で6文字が含 まれること。 コンスセル ‘(GRAPHICAL . TEXT)’ グラフィカルな端末ではGRAPHICAL、テキスト端末ではTEXTをで表示 する。GRAPHICALとTEXTはいずれも上述した表示メソッドのいずれか でなければならない。 ‘thin-space’、‘empty-box’、‘hex-code’、およびASCII文字列は ‘glyphless-char’フェイスで描画される。テキスト端末ではボックスは square brackets ‘[]’でエミュレートされる。 文字テーブルには利用可能なすべてのフォントでも表示できない、または その端末のコーディングシステムでエンコードできないすべての文字の表 示方法を定義する余分なスロットが1つある。その値は上述した表示メソッ ドのうち‘zero-width’とコンスセル以外のいずれかでなければならない。 アクティブなディスプレイテーブル内に非‘nil’なエントリーをもつ文字で は、そのディスプレイテーブルが効果をもつ。この場合にはEmacsは ‘glyphless-char-display’をまったく参照しない。 -- User Option: glyphless-char-display-control このユーザーオプションは似かよった文字のグループにたいして ‘glyphless-char-display’をセットする便利な手段を提供する。Lispコー ドからこの値を直接セットしてはならない。‘glyphless-char-display’更 新するカスタム関数‘:set’を通じた場合のみ値は効果をもつ。 この値は要素が‘(GROUP . METHOD)’であるようなalistであること。ここで GROUPは文字のグループを指定するシンボル、METHODはそれらを表示する方 法を指定するシンボル。 GROUPは以下のいずれかであること: ‘c0-control’ 改行文字とタブ文字を除く‘U+0000’から‘U+001F’までのASCIIコント ロール文字(通常は‘^A’のようなエスケープシーケンスとして表示さ れる。*note How Text Is Displayed: (emacs)Text Display.を参照 )。 ‘c1-control’ ‘U+0080’から‘U+009F’までの非ASCII、非プリント文字(通常は ‘\230’のような8進エスケープシーケンスとして表示される)。 ‘format-control’ ‘U+200E’のようなUnicode General Category [Cf]の文字だが、 ‘U+00AD’(Soft Hyphen)のようにグラフィックイメージをもつ文字を 除く。 ‘no-font’ 適切なフォントが存在しないか、その端末のコーディングシステムで はエンコードできない文字。 METHODシンボルは‘zero-width’、‘thin-space’、‘empty-box’、 ‘hex-code’のいずれかであること。これらは上述の ‘glyphless-char-display’での場合と同様の意味をもつ。 37.23 ビープ ============ このセクションではユーザーの注意を喚起するために、Emacsでベルを鳴らす方 法を説明します。これを行う頻度は控え目にしてください。頻繁なベルは刺激過 剰になる恐れがあります。同様にエラーのシグナル時に過度にビープ音を使用し ないよう注意してください。 -- Function: ding &optional do-not-terminate この関数はビープ音を鳴らす、またはスクリーンをフラッシュする(後述の ‘visible-bell’を参照)。DO-NOT-TERMINATEが‘nil’なら、この関数はカレ ントで実行中のキーボードマクロも終了する。 -- Function: beep &optional do-not-terminate これは‘ding’のシノニム。 -- User Option: visible-bell この変数はベルを表すためにスクリーンをフラッシュすべきかどうかを決 定する。非‘nil’ならフラッシュして、‘nil’ならフラッシュしない。これ はグラフィカルなディスプレイで効果的であり、テキスト端末ではその端 末のTermcapエントリーが可視ベル(visible bell) ‘vb’の能力を定義する 。 -- User Option: ring-bell-function これが非‘nil’ならEmacsがどのようにベルを鳴らすかを定義すること。値 は引数なしの関数であること。これが非‘nil’なら‘visible-bell’より優先 される。 37.24 ウィンドウシステム ======================== Emacsは複数のウィンドウシステムで機能しますが、特にXウィンドウシステムに おいてもっとも機能します。EmacsとXはどちらも“ウィンドウ”を使用しますが異 なる使い方をします。EmacsのフレームはXにおいては単一のウィンドウです。 Emacsの個々のウィンドウについては、Xはまったく関知しません。 -- Variable: window-system この端末ローカルな変数は、Emacsがフレームを表示するのに何のウィンド ウシステムを使用しているかを示す。可能な値は、 ‘x’ EmacsはXを使用してフレームを表示している。 ‘w32’ EmacsはネイティブMS-Windows GUIを使用してフレームを表示してい る。 ‘ns’ EmacsはNextstepインターフェイスを使用してフレームを表示してい る(GNUstepとMac OS Xで使用)。 ‘pc’ EmacsはMS-DOSのスクリーン直接書き込みを使用してフレームを表示 している。 ‘nil’ Emacsは文字ベース端末を使用してフレームを表示している。 -- Variable: initial-window-system この変数はスタートアップの間にEmacsが作成する最初のフレームにたいし て使用される‘window-system’の値を保持する(Emacsを‘--daemon’オプショ ンで呼び出し時には初期フレームを作成しないので、依然として‘w32’であ るMS-Windowsを除いて‘initial-window-system’は‘nil’。*note daemon: (emacs)Initial Options.を参照)。 -- Function: window-system &optional frame この関数はFRAMEを表示するために使用されているウィンドウシステムを示 す名前のシンボルをリターンする。この関数がリターンし得るシンボルの リストは変数‘window-system’の記述と同様。 テキスト端末とグラフィカルなディスプレイで異なる処理を行うコードを記 述したいときは、‘window-system’と‘initial-window-system’を述語やブーリー ンフラグ変数として_使用しないでください_。これは与えられたディスプレイタ イプでのEmacsの能力指標として‘window-system’が適していないからです。かわ りに‘display-graphic-p’、または*note Display Feature Testing::で説明して いるその他の述語‘display-*-p’を使用してください。 37.25 Tooltips ============== “ツールチップ(Tooltips)”はマウスポインターのカレント位置に関連するヘルプ 的なヒント(別名“tips”)の表示に使用される特別なフレームです(*note Frames::を参照)。Emacsはテキストのアクティブ範囲(*note Special Properties::を参照)、およびメニューアイテム(*note Extended Menu Items::を 参照)やツールバーのボタン(*note Tool Bar::を参照)のような種々のUI要素に 関するヘルプ文字列の表示にツールチップを使用します。 -- Function: tooltip-mode Tooltipモードはツールチップの表示を有効にするマイナーモード。このモ ードをオフにするとツールチップはエコーエリアに表示される。テキスト モード(別名“TTY”)のフレームでは、ツールチップは常にエコーエリアに表 示される。 GTK+サポート付きでEmacsがビルドされた際にはデフォルトでGTK+関数を使用 してツールチップを表示して、ツールチップの外観はGTK+のセッティングにより 制御されます。GTK+ツールチップは変数‘x-gtk-use-system-tooltips’の値を ‘nil’に変更して無効にできます。このセクションの残りではEmacs自身が提供す る非GTK+ツールチップを制御する方法を説明します。 ツールチップは特別なフレームなのでフレームパラメーターをもっています (*note Frame Parameters::を参照)。他のフレームと異なりツールチップのフレ ームパラメーターは特別な変数に格納されます。 -- Variable: tooltip-frame-parameters このカスタマイズ可能なオプションはツールチップ表示に使用するフレー ムパラメーターを保持する。すべてのフォントおよびカラーのパラメータ ーは無視して、かわりに対応する‘tooltip’フェイスの属性が使用される。 ‘left’や‘top’のパラメーターが含まれていれば、ツールチップが表示され るフレームに相対的な絶対座標として使用される(*note (emacs)Tooltips::で説明されている変数を使用してツールチップのマウス に相対的な位置をカスタマイズできる)。(‘left’と‘top’が与えられるとマ ウスに相対的なオフセットの値はオーバーライドされる)。 ‘tooltip’フェイスはツールチップ内に表示されるテキストの見栄えを決定し ます。デフォルトのフレームフォントより一般的にはサイズの小さい可変ピッチ フォントの使用が必要になります。 -- Variable: tooltip-functions これはEmacsがツールチップの表示を必要とする際に呼び出す関数のリスト であるようなアブノーマルフック。関数はそれぞれ最後のマウス移動イベ ントであるEVENTを単一の引数として呼び出される。このリスト上の関数が 実際にツールチップを表示するなら非‘nil’をリターンして、残りの関数は 呼び出されない。この変数のデフォルト値は‘tooltip-help-tips’という 1つの関数。 ‘tooltip-functions’のリストに配置する関数を独自に記述する場合には、ツ ールチップの表示をトリガーしたマウスイベントのバッファーを知る必要がある かもしれません。以下はこの情報を提供する関数です。 -- Function: tooltip-event-buffer event この関数はEVENTが発生したバッファーをリターンする。テキストがツール チップをトリガーしたバッファーを取得するために、これを ‘tooltip-functions’の関数の引数で呼び出す。イベントはバッファーでは ないところ(たとえばツールバー)で発生したかもしれず、そのような場合 にはこの関数は‘nil’をリターンする。 ツールチップ表示に関する他の側面は、いくつかのカスタマイズ可能なセッ ティングにより制御されます。*note (emacs)Tooltips::を参照してください。 37.26 双方向テキストの表示 ========================== 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)にしたがいます ()。EmacsはUnicode Standard v8.0の 要求に合致するUBAの“Full Bidirectionality”クラスの実装を提供します。 -- Variable: bidi-display-reordering このバッファーローカル変数の値が非‘nil’ (デフォルト)なら、Emacsは表 示で双方向の並べ替えを行う。この並べ替えはバッファーテキスト、同様 に文字列表示やバッファー内のテキストプロパティやオーバーレイプロパ ティ由来のオーバーレイ文字列に効果を及ぼす(*note Overlay Properties::および*note Display Property::を参照)。値が‘nil’なら Emacsはバッファー内での双方向の並べ替えを行わない。 ‘bidi-display-reordering’のデフォルト値は、モードライン内に表示され るテキスト(*note Mode Line Format::を参照)、およびヘッダー行(*note Header Lines::を参照)を含む、バッファーにより直接提供されない文字列 の並べ替えを制御する。 たとえバッファーの‘bidi-display-reordering’が非‘nil’でも、Emacsがユニ バイトバッファーのテキストの並べ替えを行うことはありません。これはユニバ イトバッファーに含まれるのが文字ではなくrawバイトであり、並べ替えに要す る方向的なプロパティを欠くからです。したがってあるバッファーのテキストが 並べ替えられるかどうかテストするには、‘bidi-display-reordering’のテスト 単独では不十分です。正しいテストは以下のようになります: (if (and enable-multibyte-characters bidi-display-reordering) ;; 表示時にバッファーは並べ替えられるだろう ) とはいえ親バッファーが並べ替えられた際には、ユニバイト表示やオーバー レイ文字列は_並べ替えられます_。これはEmacsによりプレーンASCII文字列がユ ニバイト文字列に格納されるからです。ユニバイト表示やオーバーレイ文字列が 非ASCII文字列を含むなら、それらの文字はL2Rの方向をもつとみなされます。 テキストプロパティ‘display’、値が文字列であるような‘display’プロパテ ィによるオーバーレイ、バッファーテキストを置換するその他任意のプロパティ にカバーされたテキストは表示時の並べ替えの際には単一の単位として扱われま す。つまりこれらのプロパティにカバーされたテキストのchunk全体が一緒に並 べ替えられます。さらにそのようなテキストchunk内の文字の双方向的なプロパ ティは無視されて、Emacsはあたかもそれらが“オブジェクト置換文字(Object Replacement Character)”として知られる単一文字で置換されたかのように並べ 替えます。これはテキスト範囲上にdisplayプロパティを配置することにより、 表示時に周辺テキストを並べ替える方法が変更され得ることを意味しています。 このような予期せぬ効果を防ぐには、常に周辺テキストと等しい方向のテキスト にたいしてそのようなプロパティを配置してください。 双方向テキストのパラグラフはそれぞれ、R2LかL2Rいずれかの“基本方向 (base direction)”をもちます。L2Rパラグラフはウィンドウの左マージンを先頭 に表示され、そのテキストが右マージンに達したら切り詰めや継続されます。 R2Lパラグラフはウィンドウの右マージンを先頭に表示され、そのテキストが左 マージンに達したら切り詰めや継続されます。 デフォルトではEmacsはテキスト先頭を調べることにより各パラグラフの基本 方向を判断します。基本方向の精細な決定手法はUBAにより指定されており、簡 潔に言うとその明示にな方向生をもつそのパラグラフ内の最初の文字がパラグラ フの基本方向を決定します。とはいえ、あるバッファーが自身のパラグラフにた いして特定の基本方向の強制を要する場合もあります。たとえばプログラムソー スコードを含むバッファーは、すべてのパラグラフがL2Rで表示されるよう強制 されるべきでしょう。これを行うために以下の変数を使用できます: -- Variable: bidi-paragraph-direction このバッファーローカル変数の値が‘right-to-left’か‘left-to-right’い ずれかのシンボルなら、そのバッファー内のすべてのパラグラフがその指 定された方向をもつとみなされる。その他すべての値は‘nil’ (デフォルト )と等価であり、それは各パラグラフの基本方向が内容により判断されるこ とを意味する。 プログラムソースコードにたいするモードは、これを‘left-to-right’にセ ットすること。Progモードはデフォルトでこれを行うので、Progモードか ら派生したモードは明示的にセットする必要はない(*note Basic Major Modes::を参照)。 -- Function: current-bidi-paragraph-direction &optional buffer この関数はBUFFERという名前のバッファーのポイント位置のパラグラフ方 向をリターンする。リターンされる値は‘left-to-right’か ‘right-to-left’いずれかのシンボルである。BUFFERが省略または‘nil’の 場合のデフォルトはカレントバッファー。変数 ‘bidi-paragraph-direction’のバッファーローカル値が非‘nil’なら、リタ ーンされる値はその値と等しくなるだろう。それ以外ならリターンされる 値はEmacsにより動的に決定されたパラグラフの方向を反映する。 ‘bidi-display-reordering’の値が‘nil’のバッファー、同様にユニバイト バッファーにたいしては、この関数は常に‘left-to-right’をリターンする 。 バッファーのカレントのスクリーン位置にたいして、ビジュアル順にL2Rか R2Lいずれかの方向に厳密なポイント移動を要す場合があります。Emacsはこれを 行うためのプリミティブを提供します。 -- Function: move-point-visually direction この関数は、カレントで選択されたウィンドウのバッファーにたいしてポ イントを、スクリーン上ですぐ右か左のポイントへ移動する。DIRECTIONが 正ならスクリーン位置は右、それ以外ならスクリーン位置は左へ移動する だろう。周囲の双方向コンテキストに依存して、これは潜在的に多くのバ ッファーのポイントを移動し得ることに注意。スクリーン行終端で呼び出 された場合には、この関数はDIRECTIONに応じて適宜、次行か前行の右端か 左端のスクリーン位置にポイントを移動する。 この関数は値として新たなバッファー位置をリターンする。 バッファー内で双方向の内容をもつ2つの文字列が並置されているときや、プ ログラムで1つのテキスト文字列に結合した場合には、双方向の並べ替えは以外 かつ不快な効果を与える可能性があります。典型的な問題ケースはBuffer Menuモ ードやRmail Summaryモードのようにバッファーがスペースや区切り文字分割さ れたテキストのフィールドのシーケンスで構成されているときです。それはセパ レーターとして使用されている区切り文字が“弱い方向性”をもち、周囲のテキス トの方向を採用するためです。結果として双方向の内容のフィールドが後続する 数値フィールドは、先行するフィールドヘ_左方向_に表示され、期待したレイア ウトを破壊してしまいます。この問題を回避するための方法がいくつかあります : − 双方向の内容をもち得る各フィールド終端にスペシャル文字LEFT-TO-RIGHT MARK(略してLRM)の‘U+200E’を付加する。後述の関数 ‘bidi-string-mark-left-to-right’はこの目的に手頃である(R2Lパラグラ フではかわりにRIGHT-TO-LEFT MARK、略してRLMの‘U+200F’を使用する)。 これはUBAにより推奨される解決策の1つ。 − フィールドセパレーターにタブ文字を含める。タブ文字は双方向の並べ替 えにおいて“セグメントセパレーター(segment separator)”の役割を演じて 、両側のテキストを個別に並べ替えさせる。 − ‘display’プロパティ、または‘(space . PROPS)’という形式の値をもつオ ーバーレイ(*note Specified Space::を参照)でフィールドを区切る。 Emacsはこのdisplay仕様を“パラグラフセパレーター(paragraph separator)”として扱い両側のテキストを個別に並べ替える。 -- Function: bidi-string-mark-left-to-right string この関数は結果を安全に他の文字列に結合できるよう、あるいはこの文字 列とスクリーン上で次行となる行に関連するレイアウトを乱すことなくバ ッファー内の他の文字列に並置できるよう、自身への引数STRINGを恐らく 変更してリターンする。この関数がリターンする文字列がR2Lパラグラフの 一部として表示される文字列なら、それは常に後続するテキストの左に出 現するだろう。この関数は自身の引数の文字を検証することにより機能し て、もしそれらの文字のいずれかがディスプレイ上の並べ替えを発生し得 るなら、この関数はその文字列にLRM文字を付加する。付加されたLRM文字 はテキストプロパティ‘invisible’に‘t’を与えることにより不可視にでき る(*note Invisible Text::を参照)。 並べ替えアルゴリズムは‘bidi-class’プロパティとして格納された文字の双 方向プロパティを使用します(*note Character Properties::を参照)。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、またはその逆にするようにオーバーライドされたテキストのインスタンス を検知するプリミティブを提供します。 -- Function: bidi-find-overridden-directionality from to &optional object この関数はOBJECTで指定されたテキストのFROM (含む)とTO (含まず)の間 のテキストを調べてR2Lの文字であるかのように表示が強制されている双方 向プロパティの強いL2R文字、L2Rの文字であるかのように表示が強制され ている強いR2L文字の最初の位置をリターンする。指定されたテキストリー ジョンでそのような文字が見つからなければ‘nil’をリターンする。 オプション引数OBJECTは検索するテキストを指定して、デフォルトはカレ ントバッファー。OBJECTが非‘nil’なら別のバッファーや文字列、またはウ ィンドウかもしれない。文字列ならこの関数はその文字列を検索する。ウ ィンドウならこの関数はそのウィンドウが表示するバッファーを検索する 。検査したいテキストをもつバッファーが何らかのウィンドウに表示され ていれば、この関数にバッファーを渡すのではなくそのウィンドウの指定 を推奨する。これはウィンドウ固有のオーバーレイにカバーされたバッフ ァーのテキストでは関数の結果が変化し得るが、関数にウィンドウ固有の オーバーレイを正しく考慮するように指示するからである。 テキストがR2L文字とL2R文字の混交を含み、かつ双方向制御が別の場所にコ ピーされる際には、その視覚的外見は変化するかもしれず、コピー先の周辺テキ ストの視覚的外見にも影響するかもしれません。これはUBAで指定される双方向 テキストの並び替えでは、コピーされるテキストとそれを取り囲む周辺テキスト の両方が非自明かつコンテキスト依存の効果をもつからです。 コピーされるテキストとコピー先周辺のテキストの視覚的外見をLispプロパ ティが保証することが必要なときがあるかもしれません。この効果を達成するた めにLispプログラムは以下の関数を使用できます。 -- Function: buffer-substring-with-bidi-context start end &optional no-properties この関数は‘buffer-substring’ (*note Buffer Contents::を参照)と同様 に機能するが、テキストが別の場所にコピーされる際に視覚的外見を保つ ために必要な双方向制御文字を前や後に付加する点が異なる。オプション 引数NO-PROPERTIESが非‘nil’なら、それはテキストのコピーからテキスト プロパティを削除することを意味する。 38 オペレーティングシステムのインターフェース ********************************************* これはEmacsの開始と終了、オペレーティングシステム内の値へのアクセス、端 末の入力と出力に関するチャプターです。 関連する情報は*note Building Emacs::を参照してください。端末とスクリ ーンに関連するオペレーティングシステムの状態に関する追加情報は*note Display::を参照してください。 38.1 Emacsのスタートアップ ========================== このセクションではEmacsが開始時に何を行うか、およびそれらのアクションの カスタマイズ方法を説明します。 38.1.1 要約: スタートアップ時のアクション順序 --------------------------------------------- Emacsは起動時に以下の処理を行います(‘startup.el’内の‘normal-top-level’を 参照): 1. この‘load-path’の各ディレクトリー内にある‘subdirs.el’という名前のフ ァイルを実行して‘load-path’にサブディレクトリーを追加する。このファ イルは通常はそのディレクトリー内にあるサブディレクトリーをこのリス ト変数に追加して、それらを順次スキャンする。ファイル‘subdirs.el’は 通常はEmacsインストール時に自動的に作成される。 2. ‘load-path’のディレクトリー内で見つかった‘leim-list.el’をすべてロー ドする。このファイルは入力メソッドの登録を意図している。この検索は ユーザーが作成するかもしれない個人的な‘leim-list.el’すべてにたいし てのみ行われる。標準的なEmacsライブラリーを含むディレクトリーはスキ ップされる(これらは単一の‘leim-list.el’だけに含まれるべきであり Emacs実行形式にコンパイル済)。 3. 変数‘before-init-time’に‘current-time’の値をセットする(*note Time of Day::を参照)。これは‘after-init-time’に‘nil’をセットすることによ りEmacs初期化時にLispプログラムへの合図も行う。 4. ‘LANG’のような環境変数がそれを要するなら言語環境と端末のコーディン グシステムをセットする。 5. コマンドライン引数にたいして基本的なパースをいくつか行う。 6. batchモードで実行されていなければ変数‘initial-window-system’が指定 するウィンドウシステムを初期化する(*note initial-window-system: Window Systems.を参照)。サポートされる各ウィンドウシステムにたいす る初期化関数は‘window-system-initialization-alist’により指定される 。‘initial-window-system’の値がWINDOWSYSTEMならファイル ‘term/WINDOWSYSTEM-win.el’内で適切な初期化関数が定義されている。こ のファイルはビルド時にEmacs実行可能形式にコンパイルされているべきで ある。 7. ノーマルフック‘before-init-hook’を実行する。 8. それが適切ならグラフィカルなフレームを作成する。これはオプション ‘--batch’か‘--daemon’が指定されていたら行われない。 9. 初期フレームのフェイスを初期化して必要ならメニューバーとツールバー をセットする。グフィカルなフレームがサポートされていたら、たとえカ レントフレームがグラフィカルでなくても、後でグラフィカルなフレーム が作成されるかもしれないのでツールバーをセットアップする。 10. リスト‘custom-delayed-init-variables’内のメンバーを再初期化するた めに‘custom-reevaluate-setting’を使用する。これらのメンバーは、デフ ォルト値がビルド時ではなく実行時のコンテキストに依存する、すべての 事前ロード済ユーザーオプションである。*note custom-initialize-delay: Building Emacs.を参照のこと。 11. 存在すればライブラリー‘site-start’をロードする。これはオプション ‘-Q’か‘--no-site-file’が指定された場合は行われない。 12. ユーザーのinitファイルをロードする(*note Init File::を参照)。これ はオプション‘-q’、‘-Q’、または‘--batch’が指定されていたら行われない 。‘-u’オプションが指定されたらEmacsはかわりにそのユーザーのホームデ ィレクトリー内でinitファイルを探す。 13. 存在すればライブラリー‘default’をロードする。これは ‘inhibit-default-init’が非‘nil’、あるいはオプション‘-q’、‘-Q’、また は‘--batch’指定された場合には行われない。 14. もしファイルが存在して読み込み可能なら、‘abbrev-file-name’で指定さ れるファイルからユーザーのabbrevをロードする(*note abbrev-file-name: Abbrev Files.を参照)。オプション‘--batch’が指定さ れていたら行われない。 15. インストール済みのオプションのEmacs Lispパッケージをすべてアクティ ブ化するために関数‘package-initialize’を呼び出す。*note Packaging Basics::を参照のこと。しかし‘package-enable-at-startup’が‘nil’、ま たは‘-q’、‘-Q’、‘--batch’のいずれかのオプションで開始時には、 Emacsはパッケージの初期化をしない。後者のケースでパッケージを初期化 するには、(たとえば‘--funcall’オプションを通じて)明示的に ‘package-initialize’を呼び出すこと。 16. 変数‘after-init-time’に‘current-time’の値をセットする。この変数は 事前に‘nil’にセットされている。これをカレント時刻にセットすることが 初期化フェーズが終わったことの合図となり、かつ‘before-init-time’と 共に用いることにより初期化に要した時間の計測手段を提供する。 17. ノーマルフック‘after-init-hook’を実行する。 18. バッファー‘*scratch*’が存在して、まだ(デフォルトであるべき )Fundamentalモードなら‘initial-major-mode’に応じたメジャーモードを セットする。 19. テキスト端末で開始された場合には、端末固有のLispライブラリー(*note Terminal-Specific::を参照)をロードしてフック‘tty-setup-hook’を実行 する。これは‘--batch’モード、または‘term-file-prefix’が‘nil’なら実 行されない。 20. ‘inhibit-startup-echo-area-message’で抑制していなければエコーエリ アに初期メッセージを表示する。 21. これ以前に処理されていないコマンドラインオプションをすべて処理する 。 22. オプション‘--batch’が指定されていたら、ここでexitする。 23. ‘*scratch*’が存在して空ならばバッファーに‘(substitute-command-keys initial-scratch-message)’を挿入する。 24. ‘initial-buffer-choice’が文字列ならその名前のファイル(かディレクト リー)をvisitする。関数なら引数なしでその関数を呼び出して、それがリ ターンしたバッファーを選択する。コマンドライン引数として単一のファ イルが与えられた場合にはファイルをvisitして、そのバッファーを ‘initial-buffer-choice’のそばに表示する。複数のファイルが与えられた 場合にはすべてのファイルをvisitして、‘initial-buffer-choice’のそば に‘*Buffer List*’バッファーを表示する。 25. ‘emacs-startup-hook’を実行する。 26. initファイルの指定が何であれ、それに応じて選択されたフレームのパラ メーターを変更する‘frame-notice-user-settings’を呼び出す。 27. ‘window-setup-hook’を実行する。このフックと‘emacs-startup-hook’の 違いは前述したフレームパラメーターの変更後にこれが実行される点のみ 。 28. copyleftとEmacsの基本的な使い方を含んだ特別なバッファー“スタートア ップスクリーン(startup screen)”を表示する。これは ‘inhibit-startup-screen’か‘initial-buffer-choice’が非‘nil’、あるい はコマンドラインオプション‘--no-splash’か‘-Q’が指定されていたら行わ れない。 29. オプション‘--daemon’が指定された場合、またはPosixシステムの場合に も‘server-start’を呼び出して制御端末からデタッチする。*note (emacs)Emacs Server::を参照のこと。 30. セッションマネージャーにより開始された場合には、以前のセッションの IDを引数として‘emacs-session-restore’を呼び出す。*note Session Management::を参照のこと。 以下のオプションはスタートアップシーケンスにおけるいくつかの側面に影響を 与えます。 -- User Option: inhibit-startup-screen この変数が非‘nil’ならスタートアップスクリーンを抑制する。この場合に はEmacsは通常は‘*scratch*’バッファーを表示する。しかし以下の ‘initial-buffer-choice’を参照されたい。 新しいユーザーがcopyleftやEmacsの基本的な使い方に関する情報を入手す るのを防げるので、新しいユーザーのinitファイル内や複数ユーザーに影 響するような方法でこの変数をセットしてはならない。 ‘inhibit-startup-message’と‘inhibit-splash-screen’はこの変数にたい するエイリアス。 -- User Option: initial-buffer-choice 非‘nil’ならこの変数はスタートアップ後にスタートアップスクリーンのか わりにEmacsが表示するファイルを指定する文字列であること。この変数が 関数ならEmacsはその関数を呼び出して、その関数はその後に表示するバッ ファーをリターンしなければならない。値が‘t’ならEmacsは‘*scratch*’バ ッファーを表示する。 -- User Option: inhibit-startup-echo-area-message この変数はエコーエリアのスタートアップメッセージの表示を制御する。 ユーザーのinitファイル内に以下の形式のテキストを追加することにより エコーエリアのスタートアップメッセージを抑制できる: (setq inhibit-startup-echo-area-message "YOUR-LOGIN-NAME") Emacsはユーザーのinitファイル内で上記のような式を明示的にチェックす る。ユーザーのロフイン名はLispの文字列定数としてこの式内に記述され ていなければならない。Customizeインターフェイスを使用することもでき る。他の方法で同じ値に‘inhibit-startup-echo-area-message’をセットし てもスタートアップメッセージは抑制されない。この方法により望むなら ユーザー自身で簡単にメッセージを抑制できるが、単に自分用のiniファイ ルを別のユーザーにコピーしてもメッセージは抑制されないだろう。 -- User Option: initial-scratch-message この変数が非‘nil’ならEmacsスタートアップ時に‘*scratch*’バッファーに 挿入するドキュメントとして扱われる文字列であること。‘nil’なら ‘*scratch*’バッファーは空になる。 以下のコマンドラインオプションはスタートアップシーケンスにおけるいくつか の側面に影響を与えます。*note (emacs)Initial Options::を参照してください 。 ‘--no-splash’ スプラッシュスクリーンを表示しない。 ‘--batch’ 対話的な端末なしで実行する。*note Batch Mode::を参照のこと。 ‘--daemon’ 表示の初期化を何も行わず単にバックグラウンドでサーバーを開始する。 ‘--no-init-file’ ‘-q’ initファイルと‘default’ライブラリーをいずれもロードしない。 ‘--no-site-file’ ‘site-start’ライブラリーをロードしない。 ‘--quick’ ‘-Q’ ‘-q --no-site-file --no-splash’と等価。 38.1.2 initファイル ------------------- Emacsの開始時は通常はユーザーの“initファイル(init file)”のロードを試みま す。これはユーザーのホームディレクトリー内にある‘.emacs’か‘.emacs.el’と いう名前のファイル、あるいはホームディレクトリーの‘.emacs.d’という名前の サブディレクトリー内にある‘init.el’という名前のファイルのいずれかのファ イルです。 コマンドラインスイッチ‘-q’、‘-Q’、‘-u’はinitファイルを探すべきか、お よびどこで探すべきかを制御します。‘-u USER’はそのユーザーではなくUSERの initファイルのロードを指示しますが、‘-q’ (‘-Q’のほうが強力)はinitファイ ルをロードしないことを指示します。*note (emacs)Entering Emacs::を参照し てください。いずれのオプションも指定されていなければユーザーのホームディ レクリーからinitファイルを探すために、Emacsは環境変数‘LOGNAME’、‘USER’ (ほとんどのシステム)、または‘USERNAME’ (MSシステム)を使用します。この方 法によりたとえsuしていたとしても、依然としてEmacsはそのユーザー自身の initファイルをロードできるのです。これらの環境変数が存在していなくても EmacsはユーザーIDからユーザーのホームディレクトリーを探します。 インストールしたEmacsによっては‘default.el’というLispライブラリーの “デフォルトinitファイル(default init file)”が存在するかもしれません。 Emacsはライブラリーの標準検索パスからこのファイルを探します(*note How Programs Do Loading::を参照)。このファイルは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’により、このファイルのロードを抑制できます。 -- User Option: site-run-file この変数はユーザーのinitファイルの前にロードするサイト用のカスタマ イズファイルを指定する。通常の値は‘"site-start"’。実際に効果がある ようにこれを変更するには、Emacsのdump前に変更するのが唯一の方法であ る。 一般的に必要とされる‘.emacs’ファイルのカスタマイズ方法については*note Init File Examples: (emacs)Init Examples.を参照のこと。 -- User Option: inhibit-default-init この変数が非‘nil’ならEmacsがデフォルトの初期化ライブラリーファイル をロードするのを防ぐ。デフォルト値は‘nil’。 -- Variable: before-init-hook このノーマルフックはすべてのinitファイル(‘site-start.el’、ユーザー のinitファイル、および‘default.el’)のロード直前に一度実行される(実 際に効果があるようにこれを変更するにはEmacsのdump前に変更するのが唯 一の方法)。 -- Variable: after-init-hook このノーマルフックはすべてのinitファイル(‘site-start.el’、ユーザー のinitファイル、および‘default.el’)のロード直後、端末固有ライブラリ ーのロードとコマンドラインアクション引数の処理の前に一度実行される 。 -- Variable: emacs-startup-hook このノーマルフックはコマンドライン引数の処理直後に一度実行される。 batchモードではEmacsはこのフックを実行しない。 -- Variable: window-setup-hook このノーマルフックは‘emacs-startup-hook’と非常に類似している。この フックは若干遅れてフレームパラメーターのセット後に実行されるのが唯 一の違い。*note window-setup-hook: Startup Summary.を参照のこと。 -- Variable: user-init-file この変数はユーザーのinitファイルの絶対ファイル名を保持する。実際に ロードされたinitファイルが‘.emacs.elc’のようにコンパイル済なら、値 はそれに対応するソースファイルを参照する。 -- Variable: user-emacs-directory この変数は‘.emacs.d’ディレクトリーの名前を保持する。これはMS-DOS以 外のプラットフォームでは‘~/.emacs.d’。 38.1.3 端末固有の初期化 ----------------------- 端末タイプはそれぞれ、その端末のタイプで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’への セットや追加も必要になるかもしれません。*note Terminal Input::を参照して ください。 端末タイプにハイフンとアンダースコアーが含まれて、その端末名に等しい 名前のライブラリーが見つからないときには、Emacsはその端末名から最後のハ イフンまたはアンダースコアー以降を取り除いて再試行します。このプロセスは Emacsがマッチするライブラリーを見つかるか、その名前にハイフンとアンダー スコアーが含まれなくなる(つまりその端末固有ファイルが存在しない)まで繰り 返されます。たとえば端末名が‘xterm-256color’で‘term/xterm-256color.el’と いうライブラリーが存在しなければEmacsは‘term/xterm.el’のロードを試みます 。必要なら端末タイプの完全な名称を見つかるために端末ライブラリーは ‘(getenv "TERM")’を評価できます。 initファイルで変数‘term-file-prefix’を‘nil’にセットすることにより端末 固有ライブラリーのロードを防ぐことができます。 ‘tty-setup-hook’を使用することにより、端末固有ライブラリーのいくつか のアクションのアレンジやオーバーライドもできます。これは新たなテキスト端 末の初期化後にEmacsが実行するノーマルフックです。自身のライブラリーをも たない端末にたいして初期化を定義するために、このフックを使用することので きるでしょう。*note Hooks::を参照してください。 -- User Option: term-file-prefix この変数の値が非‘nil’ならEmacsは以下のように端末固有初期化ファイル をロードする: (load (concat term-file-prefix (getenv "TERM"))) 端末初期化ファイルのロードを望まない場合には変数 ‘term-file-prefix’に‘nil’をセットできる。 MS-DOSではEmacsは環境変数‘TERM’に‘internal’をセットする。 -- User Option: term-file-aliases この変数は端末タイプとそのエイリアスをマップする連想リスト。たとえ ば‘("vt102" . "vt100")’という形式の要素はタイプ‘vt100’と同じように タイプ‘vt102’の端末を扱うことを意味する。 -- Variable: tty-setup-hook この変数は新たなテキスト端末の初期化後にEmacsが実行するノーマルフッ ク(これは非ウィンドウのモードでのEmacs開始時と‘emacsclient’のTTY接 続作成時に適用される)。(適用可能なら)このフックはユーザーのinitファ イルおよび端末固有Lispファイルのロード後に実行されるので、そのファ イルにより行われた定義を調整するためにフックを使用できる。 関連する機能については*note window-setup-hook: Init File.を参照のこ と。 38.1.4 コマンドライン引数 ------------------------- Emacs開始時に種々のアクションをリクエストするためにコマンドライン引数を 使用できます。Emacsを使う際にはログイン後に一度だけ起動して同一のEmacsセ ッション内ですべてを行うのが推奨される方法です(*note (emacs)Entering Emacs::を参照)。この理由によりコマンドライン引数を頻繁に使うことはないか もしれません。それでもセッションスクリプトからEmacsを呼び出すときや Emacsのデバッグ時にコマンドライン引数が有用になるかもしれません。このセ クションではEmacsがコマンドライン引数を処理する方法を説明します。 -- Function: command-line この関数はEmacsが呼び出された際のコマンドライン引数を解析、処理、そ して(とりわけ)ユーザーのinitファイルをロードしてスタートアップメッ セージを表示する。 -- Variable: command-line-processed この変数の値は一度コマンドラインが処理されると‘t’になる。 ‘dump-emacs’ (*note Building Emacs::を参照)を呼び出すことにより Emacsを再dumpする場合には、新たにdumpされたEmacsに新たなコマンドラ イン引数を処理させるために最初にこの変数に‘nil’をセットしたいと思う かもしれない。 -- Variable: command-switch-alist この変数はユーザー定義のコマンドライン引数とそれに関連付けられたハ ンドラー関数のalist。デフォルトでは空だが望むなら要素を追加できる。 “コマンドラインオプション(command-line option)”は以下の形式をもつコ マンドライン上の引数である: -OPTION ‘command-switch-alist’の要素は以下のようになる: (OPTION . HANDLER-FUNCTION) CARのOPTIONは文字列でコマンドラインオプションの名前(先頭のハイフン は含まない)。HANDLER-FUNCTIONはOPTIONを処理するために呼び出されて、 単一の引数としてオプション名を受け取る。 このオプションはコマンドライン内で引数を併う場合がある。この場合に は、HANDLER-FUNCTIONは残りのコマンドライン引数すべてを変数 ‘command-line-args-left’ (以下参照)で見つけることができる(コマンド ライン引数のリスト全体は‘command-line-args’)。 コマンドライン引数は‘startup.el’ファイル内の‘command-line-1’により 解析される。*note Command Line Arguments for Emacs Invocation: (emacs)Emacs Invocation.も参照のこと。 -- Variable: command-line-args この変数の値はEmacsに渡されたコマンドライン引数のリスト。 -- Variable: command-line-args-left この変数の値はまだ処理されていないコマンドライン引数のリスト。 -- Variable: command-line-functions この変数の値は認識されなかったコマンドライン引数を処理するための関 数のリスト。次の引数が処理されてそれに特別な意味がないときは、その 都度このリスト内の関数が非‘nil’をリターンするまでリスト内での出現順 に呼び出される。 これらの関数は引数なしで呼び出される。関数はその時点で一時的にバイ ンドされている変数‘argi’を通じて検討中のコマンドラインにアクセスで きる。残りの引数(カレントの引数含まず)は変数 ‘command-line-args-left’内にあり。 関数が‘argi’内のその引数を認識して処理したときは引数を処理したと告 げるために非‘nil’をリターンすること。後続の引数のいくつかを処理した ときは‘command-line-args-left’からそれらを削除してそれを示すことが できる。 これらの関数すべてが‘nil’をリターンした場合には引数はvisitすべきフ ァイル名として扱われる。 38.2 Emacsからの脱出 ==================== Emacsから抜け出すには2つの方法があります: 1つ目は永遠にexitするEmacsジョ ブのkill、2つ目はサスペンドする方法でこれは後からEmacsプロセスに再エンタ ーすることができます(もちろんグラフィカルな環境ではEmacsで特に何もせず単 に他のアプリケーションにスイッチして後で望むときにEmacsに戻れる)。 38.2.1 Emacsのkill ------------------ EmacsのkillとはEmacsプロセスの終了を意味します。端末からEmacsを開始した 場合には、通常は親プロセスの制御が再開されます。Emacsをkillする低レベル なプリミティブは‘kill-emacs’です。 -- Command: kill-emacs &optional exit-data このコマンドはフック‘kill-emacs-hook’を呼び出してからEmacsプロセス をexitしてkillする。 EXIT-DATAが整数ならEmacsプロセスのexitステータスとして使用される(こ れは主にbatch処理で有用。*note Batch Mode::を参照)。 EXIT-DATAが文字列なら内容は端末の入力バッファーに詰め込まれるので、 shell(や何であれ次の入力を読み込むプログラム)が読み込むことができる 。 関数‘kill-emacs’は通常はより高レベルなコマンド‘C-x C-c’ (‘save-buffers-kill-terminal’)を通じて呼び出される。*note (emacs)Exiting::を参照のこと。これはEmacsがオペレーティングシステムのシ グナル‘SIGTERM’や‘SIGHUP’を受け取った場合(たとえば制御端末が切断されたと き)や、batchモードで実行中に‘SIGINT’を受け取った場合(*note Batch Mode::を 参照)にも自動的にこれが呼び出される。 -- Variable: kill-emacs-hook このノーマルフックはEmacsのkillの前に‘kill-emacs’により実行される。 ‘kill-emacs’はユーザーとの対話が不可能な状況(たとえば端末が切断され たとき)で呼び出されるかもしれないので、このフックの関数はユーザーと の対話を試みるべきではない。Emacsシャットダウン時にユーザーと対話し たければ下記の‘kill-emacs-query-functions’を使用すること。 Emacsをkillしたときには保存されたファイルを除きEmacsプロセス内のすべ ての情報が失われます。うっかりEmacsをkillすることで大量の作業が失われる ので、‘save-buffers-kill-terminal’コマンドは保存を要するバッファーがあっ たり実行中のサブプロセスがある場合には確認の問い合わせを行います。これは アブノーマルフック‘kill-emacs-query-functions’も実行します。 -- Variable: kill-emacs-query-functions ‘save-buffers-kill-terminal’がEmacsをkillする際には標準の質問を尋ね た後、‘kill-emacs’を呼び出す前にこのフック内の関数を呼び出す。関数 は出現順に引数なしで呼び出される。関数はそれぞれ追加でユーザーから 確認を求めることができる。それらのいずれかが‘nil’をリターンすると ‘save-buffers-kill-emacs’はEmacsをkillせずに、このフック内の残りの 関数は実行されない。直接‘kill-emacs’を呼び出すとフックは実行されな い。 38.2.2 Emacsのサスペンド ------------------------ テキスト端末では“Emacsのサスペンド”ができます。これはEmacsを一時的にスト ップして上位のプロセスに制御を返します。これは通常はshellです。これによ り後で同じEmacsプロセス内の同じバッファー、同じkillリング、同じアンドゥ ヒストリー、...で編集を再開できます。Emacsを再開するには親shell内で適切 なコマンド — 恐らくは‘fg’ — を使用します。 そのEmacsセッションが開始された端末デバイス上でのみサスペンドは機能し ます。そのデバイスのことをセッションの“制御端末(controlling terminal)”と 呼びます。制御端末がグラフィカルな端末ならサスペンドは許されません。グラ フィカルな端末ではEmacsで特別なことをせずに単に別のアプリケーションにス イッチできるのでサスペンドは通常は関係ありません。 いくつかのオペレーティングシステム(‘SIGTSTP’のないシステムやMS-DOS)で はジョブの停止はサポートされません。これらのシステムでの停止はEmacsのサ ブプロセスとして新たなshellを一時的に作成します。Emacsに戻るためには shellをexitすればよいでしょう。 -- Command: suspend-emacs &optional string この関数はEmacsを停止して上位のプロセスに制御を返す。上位プロセスが Emacsを再開する際には、Lispでの‘suspend-emacs’の呼び出し元に‘nil’を リターンする。 この関数はそのEmacsセッションの制御端末上でのみ機能する。他のTTYデ バイスの制御を放棄するには‘suspend-tty’を使用する(下記参照)。その Emacsセッションが複数の端末を使用する場合にはEmacsのサスペンド前に 他のすべての端末からフレームを削除しなければならず、さもないとこの 関数はエラーをシグナルする。*note Multiple Terminals::を参照のこと 。 STRINGが非‘nil’なら、その各文字はEmacsの上位shellに端末入力として送 信される。STRING内の文字は上位shellによりエコーされずに結果だけが表 示される。 サスペンドする前に‘suspend-emacs’はノーマルフック‘suspend-hook’を実 行する。ユーザーがEmacs再開後に‘suspend-emacs’はノーマルフック ‘suspend-resume-hook’を実行する。*note Hooks::を参照のこと。 再開後の次回再表示では変数‘no-redraw-on-reenter’が‘nil’ならスクリー ン全体が再描画される。*note Refresh Screen::を参照のこと。 以下はこれらのフックの使用例: (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により読み取られて実行されている。 -- Variable: suspend-hook この変数はEmacsがサスペンド前に実行するノーマルフック。 -- Variable: suspend-resume-hook この変数はサスペンド後の再開時にEmacsが実行するノーマルフック。 -- Function: suspend-tty &optional tty TTYにEmacsが使用する端末デバイスを指定すると、この関数はそのデバイ スを放棄して以前の状態にリストアする。そのデバイスを使用していたフ レームは存在を続けるが更新はされず、Emacsはそれらのフレームから入力 を読み取らない。TTYには端末オブジェクト、フレーム(そのフレームの端 末の意)、‘nil’ (選択されたフレームの端末の意)を指定できる。*note Multiple Terminals::を参照のこと。 TTYがサスペンド済みなら何も行わない。 この関数は端末オブジェクトを各関数への引数としてフック ‘suspend-tty-functions’を実行する。 -- Function: resume-tty &optional tty この関数は以前にサスペンドされたデバイスTTYを再開する。ここでTTYは ‘suspend-tty’に指定できる値と同じである。 この関数は端末デバイスの再オープンと再初期化を行い、その端末の選択 されたフレームで端末を再描画する。それから端末ブジェクトを各関数へ の引数としてフック‘resume-tty-functions’を実行する。 同じデバイスが別のEmacs端末で使用済みなら、この関数はエラーをシグナ ルする。TTYがサスペンドされていなければ何もしない。 -- Function: controlling-tty-p &optional tty この関数はTTYがそのEmacsセッションの制御端末なら非‘nil’をリターンす る。TTYには端末オブジェクト、フレーム(そのフレームの端末の意)、 ‘nil’ (選択されたフレームの端末の意)を指定できる。 -- Command: suspend-frame このコマンドはフレームを“サスペンド”する。GUIフレームでは ‘iconify-frame’を呼び出す(*note Visibility of Frames::を参照)。テキ スト端末上のフレームでは、そのフレームが制御端末デバイス上で表示さ れていれば‘suspend-emacs’、されていなければ‘suspend-tty’のいずれか を呼び出す。 38.3 オペレーティングシステムの環境 =================================== Emacsはさまざまな変数を通じてオペレーティングシステム環境内の変数へのア クセスを提供します。これらの変数にはシステムの名前、ユーザーのUIDなどが 含まれます。 -- Variable: system-configuration この変数はユーザーのシステムのハードウェアとソフトウェアにたいする GNUの標準コンフィグレーション名(standard GNU configuration name)を 保持する。たとえば64ビットGNU/Linuxシステムにたいする典型的な値は ‘"x86_64-unknown-linux-gnu"’。 -- Variable: system-type この変数の値はEmacs実行中のオペレーティングシステムのタイプを示すシ ンボル。可能な値は: ‘aix’ IBMのAIX。 ‘berkeley-unix’ Berkeley BSDとその変種。 ‘cygwin’ MS-Windows上のPosixレイヤーであるCygwin。 ‘darwin’ Darwin (Mac OS X)。 ‘gnu’ (HURDとMachから構成される)GNUシステム。 ‘gnu/linux’ GNU/Linuxシステム — すなわちLinuxカーネルを使用するGNUシステム の変種(これらのシステムは人がしばしば“Linux”と呼ぶシステムだが 実際にはLinuxは単なるカーネルであってシステム全体ではない)。 ‘gnu/kfreebsd’ FreeBSDカーネルによる(glibcベースの)GNUシステム。 ‘hpux’ ヒューレット・パッカードのHPUXオペレーティングシステム。 ‘irix’ シリコングラフィックスのIrixシステム。 ‘nacl’ Google Native Client(NaCl)サンドボックスシステム。 ‘ms-dos’ MicrosoftのDOS。MS-DOSにたいするDJGPPでコンパイルされたEmacsは 、たとえMS-Windows上で実行されていても‘system-type’が ‘ms-dos’にバインドされる。 ‘usg-unix-v’ AT&TのUnix System V。 ‘windows-nt’ MicrosoftのWindows NT、9X以降。たとえばWindows 10でも ‘system-type’の値は常に‘windows-nt’。 わたしたちは絶対に必要になるまでは、より細分化するために新たなシン ボルを追加したくありません。実際のところ将来的にはこれらの候補のい くつかを取り除きたいと思っています。‘system-type’で許されているより 細分化する必要がある場合には、たとえば正規表現にたいして ‘system-configuration’をテストできます。 -- Function: system-name この関数は実行中のマシン名を文字列としてリターンする。 -- User Option: mail-host-address この変数が非‘nil’なら、この変数がemailアドレスを生成するために ‘system-name’のかわりに使用される。たとえばこれは ‘user-mail-address’のデフォルト値の構築時に使用される。*note User Identification::を参照のこと(これはEmacsスタートアップ時に行われる ので実際に使用されるのはEmacsのdump時に保存されたもの。*note Building Emacs::を参照)。 -- Command: getenv var &optional frame この関数は環境変数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 ... -- Command: setenv variable &optional value substitute このコマンドは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’をリターンする。 -- Variable: process-environment この変数はそれぞれが1つの環境変数を記す文字列リスト。関数‘getenv’と ‘setenv’はこの変数により機能する。 process-environment ⇒ ("PATH=/usr/local/bin:/usr/bin:/bin" "USER=lewis" "TERM=xterm" "SHELL=/bin/bash" "HOME=/home/lewis" ...) ‘process-environment’に同じ環境変数を指定す複数の要素が含まれる場合 には、それらの最初の要素が変数を指定して他は無視される。 -- Variable: initial-environment この変数はEmacs開始時にその親プロセスからEmacsが継承した環境変数の リストを保持する。 -- Variable: path-separator この変数は、(環境変数で見つけた)検索パス内でディレクトリーを区切る 文字を示す文字列を保持する。値はUnixとGNUシステムでは‘":"’、MSシス テムでは‘";"’。 -- Function: parse-colon-path path この関数は環境変数‘PATH’の値のような検索パス文字列を引数に受け取り 、それをセパレーターで分割してディレクトリー名のリストをリターンす る。このリスト内では、‘nil’はカレントディレクトリーを意味する。この 関数の名前からはセパレーターは“コロン”となるが、実際に使用するのは ‘path-separator’の値。 (parse-colon-path ":/foo:/bar") ⇒ (nil "/foo/" "/bar/") -- Variable: invocation-name この変数はEmacsが呼び出された時のプログラム名を保持する。値は文字列 でありディレクトリー名は含まれない。 -- Variable: invocation-directory この変数はEmacs実行可能形式が呼び出されたディレクトリー名、そのディ レクトリーが判断できなければ‘nil’をリターンする。 -- Variable: installation-directory 非‘nil’ならサブディレクトリー‘lib-src’と‘etc’を探すディレクトリーで ある。インストールされたEmacsなら通常は‘nil’。Emacsが標準のインスト ール位置にそれらのディレクトリーを見つけられないものの、Emacs実行可 能形式を含むディレクトリー(たとえば‘invocation-directory’)に何らか の関連があるディレクトリーで見つかることができたら非‘nil’。 -- Function: load-average &optional use-float この関数はカレント、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’はこれと類似する情報をリターンする。 -- Function: emacs-pid この関数はEmacsプロセスのプロセスIDを整数としてリターンする。 -- Variable: tty-erase-char この変数はEmacs開始前にそのシステムの端末ドライバーで選択されていた erase文字を保持する。 38.4 ユーザーの識別 =================== -- Variable: init-file-user この変数はEmacsによりどのユーザーのinitが使用されるべきか — なけれ ば‘nil’をリターンする。‘""’はログイン時のオリジナルのユーザーをリタ ーンする。この値は‘-q’や‘-u USER’のようなコマンドラインオプションを 反映する。 カスタマイズ関連のファイルや、他の類の短いユーザープロファイルをロ ードするLispパッケージは、それをどこで探すか判断するためにこの変数 にしたがうこと。これらのLispパッケージはこの変数内で見つかったユー ザー名のプロファイルをロードすること。‘init-file-user’が‘nil’なら ‘-q’、‘-Q’、または‘-batch’オプションが使用されたことを意味しており 、その場合にはLispパッケージはカスタマイズファイルやユーザープロフ ァイルを何もロードするべきではない。 -- User Option: user-mail-address これはEmacs実行中ユーザーの公称emailアドレス(nominal email address)を保持する。Emacsは通常はinit読み込み後に、ユーザーがこれを まだセットしていなれば変数にデフォルト値をセットする。デフォルト値 を使用したくなければinitファイル内でこの変数に他の何らかの値をセッ トすればよい。 -- Function: user-login-name &optional uid この関数はユーザーのログイン名をリターンする。これはいずれかがセッ トされていれば環境変数‘LOGNAME’か‘USER’を使用する。それ以外なら値は 実UIDではなく実効UIDにもとづく。 UID (数字)を指定するとUIDに対応するユーザー名、そのようなユーザーが 存在しなければ‘nil’が結果となる。 -- Function: user-real-login-name この関数はEmacsの実UIDに対応するユーザー名をリターンする。これは実 効UID、および環境変数‘LOGNAME’と‘USER’を無視する。 -- Function: user-full-name &optional uid この関数はログインユーザーの完全名、環境変数‘NAME’がセットされてい ればその値をリターンする。 EmacsプロセスのユーザーIDが既知のユーザーに不一致(かつ与えられた ‘NAME’が未セット)なら結果は‘"unknown"’。 UIDが非‘nil’なら数字(ユーザーID)か文字列(ログイン名)であること。そ の場合には‘user-full-name’はそのユーザー名かログイン名に対応する完 全名をリターンする。未定義のユーザー名かログイン名を指定すると ‘nil’をリターンする。 シンボル‘user-login-name’、‘user-real-login-name’、‘user-full-name’は 変数であると同時に関数でもあります。関数の場合には、その名前の変数と同じ 値をリターンします。これらの変数を使えば対応する関数が何をリターンするべ きかを告げることによりEmacsを騙すことができます。またフレームタイトルの 構築においても、これらの関数は有用です(*note Frame Titles::を参照)。 -- Function: user-real-uid この関数はユーザーの実UIDをリターンする。この値は、(非現実的だが)そ のUIDがLisp整数の範囲を超える程大きいような場合には浮動小数点数にな るかもしれない。 -- Function: user-uid この関数はユーザーの実効UIDをリターンする。値は浮動小数点数かもしれ ない。 -- Function: group-gid この関数はユーザーの実効GIDをリターンする。値は浮動小数点数かもしれ ない。 -- Function: group-real-gid この関数はユーザーの実GIDをリターンする。値は浮動小数点数かもしれな い。 -- Function: system-users この関数はシステム上のユーザー名をリストする文字列リストをリターン する。この情報をEmacsが取得できなければ‘user-real-login-name’の値だ けを含んだリストをリターンする。 -- Function: system-groups この関数はシステム上のグループ名をリストする文字列リストをリターン する。この情報をEmacsが取得できなければリターン値は‘nil’。 38.5 時刻 ========= このセクションではカレント時刻とタイムゾーンを決定する方法を説明します。 これらの関数のほとんどは時刻を4つの整数のリスト‘(SEC-HIGH SEC-LOW MICROSEC PICOSEC)’で表現します。これは式 HIGH * 2**16 + LOW + MICRO * 10**−6 + PICO * 10**−12を使用して“epoch” (January 1, 1970 at 00:00 UTC)か らの経過秒数を表します。 ‘current-time’のリターン値は、他の ‘file-attributes’のような関数(*note Definition of file-attributes::を参 照)のリターン値でのタイムスタンプのように、この形式を使用して表現されま す。あるケースにおいては、関数はMICROSECやPICOSECのコンポーネントを省略 した2要素や3要素(省略時のデフォルトは0)のリストをリターンすることがあり ます。 ‘current-time-string’にたいするTIME引数等の関数引数は、上述のような整 数のリスト、epochからの単一の経過秒数、カレント時刻を意味する‘nil’などの 、より一般的な“time値(time value)”を受け付けます。 ‘current-time-string’や‘format-time-string’を使用して可読性のある文字列 、‘decode-time’や‘float-time’を使用して他の形式にtime値を変換できます。 これらの関数は以降のセクションで説明します。 -- Function: current-time-string &optional time zone この関数はカレントの時刻と日付を可読形式の文字列でリターンする。こ の文字列の先頭部分には曜日、月、日付、時刻がこの順に含まれて、それ らが可変長となることはない。これらのフィールドにたいして使用される 文字数は常に同じなので、それらを切り出すために安心して‘substring’を 使用できる。年の部分は正確に4桁とは限らず、いつか追加情報が終端に付 加されるかもしれないので文字列終端からではなく先頭から文字を数える こと。 引数TIMEが与えられたら、それはカレント時刻のかわりにフォーマットす る時刻を指定する。オプション引数ZONEのデフォルトはカレントのタイム ゾーンルール。*note Time Zone Rules::を参照のこと。 (current-time-string) ⇒ "Wed Oct 14 22:21:05 1987" -- Function: current-time この関数は4つの整数のリスト‘(SEC-HIGH SEC-LOW MICROSEC PICOSEC)’で 表されたカレント時刻をリターンする。これらの整数うち後部は、低精度 の時刻をリターンするシステムでは0。現在のすべてのマシンでは PICOSECは1000の倍数だが、より高精度のクロックが利用可能になったら変 更されるかもしれない。 -- Function: float-time &optional time この関数はエポックからの経過秒数を浮動小数点数としてリターンする。 オプション引数TIME-VALUEが与えられた場合には、カレント時刻ではなく 変換する時刻を指定する。 _警告_: 結果は浮動小数点数なので正確ではないかもしれない。正確なタ イムスタンプが必要なら使用しないこと。 ‘time-to-seconds’はこの関数のエイリアス。 -- Function: seconds-to-time time この関数はtime値を整数リスト形式に変換する。たとえばTIMEが数値の場 合にはオーバーフローや丸めエラーが発生しなければ、これは ‘(time-to-seconds (seconds-to-time TIME))’と等価。 38.6 Time Zone Rules ==================== デフォルトのタイムゾーンは環境変数‘TZ’により判断されます。*note System Environment::を参照してください。たとえば‘(setenv \"TZ\" \"UTC0\")’とす れば万国標準時の使用をEmacsに指示できます。その環境に‘TZ’がなければ、 Emacsはプラットフォーム依存のデフォルト時刻であるシステムの実時間(system wall clock time)を使用します。 サポートされる‘TZ’のセットはシステム依存です。GNUと他の多くのシステム はtzdataデータベースをサポートします。これはたとえば ‘"America/New_York"’はニューヨーク市周辺のタイムゾーンを夏時間ヒストリー を指定します。GNUと他の多くのシステムはPOSIXスタイルの‘TZ’セッティングを サポートします。これはたとえば‘"EST+5EDT,M4.1.0/2,M10.5.0/2"’は1987から 2006にニューヨークで使用されたルールを指定します。すべてのシステムは万国 標準時(Universal Time)を意味する‘"UTC0"’文字列をサポートします。 地方時刻(local time)との間で変換を行う関数はタイムゾーンと夏時間ヒス トリーを指定する“タイムゾーンルール(time zone rule)”を受け付けます。この タイムゾーンルールが省略か‘nil’なら、変換にはEmacsのデフォルトのタイムゾ ーンが使用されます。‘t’なら変換には万国標準時を使用します。‘wall’ならシ ステムの実時間を変換に使用します。文字列なら変換にはその文字列と等しい ‘TZ’のタイムゾーンルールのセッティングが使用されます。 -- Function: current-time-zone &optional time zone この関数はユーザーが居るタイムゾーンを記すリストをリターンする。 値は‘(OFFSET ABBR)’という形式をもつ。ここでOFFSETは万国標準時刻より 進んでいる秒数(グリニッジより東)を与える整数。負の値はグリニッジよ り西を意味する。2つ目の要素ABBRはそのタイムゾーンのを与える省略名の 文字列。たとえば‘"CST"’は中国標準時か米国中部標準時のタイムゾーン。 夏時間の開始と終了時に、いずれの要素も変化し得る。ユーザーが季節時 間調整を用いていないタイムゾーンを指定した場合には、値は時期を通し て定数となる。 この値を計算するのに必要なすべての情報をオペレーティングシステムが 提供しなければ、このリストの未知の要素は‘nil’になる。 引数TIMEが与えられたら、それはカレント時刻のかわりに分析するべき time値を指定する。オプション引数ZONEのデフォルトはカレントのタイム ゾーンルール。 38.7 時刻の変換 =============== 以下の関数はtime値(*note Time of Day::を参照)を暦情報に変換したり逆の変 換を行います。 32ビットオペレーティングシステムの多くは、秒数コンポーネントに32ビッ ト情報を含んだシステム時刻に制限されます。これらのシステムは通常は万国標 準時の1901-12-13 20:45:52から2038-01-19 03:14:07までの時刻だけを処理しま す。しかし64ビット、およびいくつかの32ビットオペレーティングシステムは、 より大きな秒数コンポーネント値をもち、より遠い過去や未来の時刻を表現でき ます。 時刻変換関数は、たとえグレゴリオ暦導入前の日付にたいしても常にグレゴ リオ暦を使用します。年はB.C. 1年から年数を数えて伝統的なグレゴリオ年が行 うように0年をスキップしません。たとえば年数−37はグレゴリオ年のB.C. 38年 を表します。 -- Function: decode-time &optional time zone この関数はtime値を暦情報に変換する。TIMEを指定しなければカレント時 刻をデコードする。同様にZONEのデフォルトはカレントのタイムゾーンル ール。*note Time Zone Rules::を参照のこと。リターン値は以下のような 9要素のリスト: (SECONDS MINUTES HOUR DAY MONTH YEAR DOW DST UTCOFF) 以下は各要素の意味: SECONDS 0から59までの整数で表した分を過ぎた時分秒の秒。いくつかのオペ レーティングシステムでは閏秒にたいして60となる。 MINUTES 0から59までの整数で表した時を過ぎた時分秒の分。 HOUR 0から23までの整数で表した時分秒の時。 DAY 1から31までの整数で表した年月日の日。 MONTH 1から12までの整数で表した年月日の月。 YEAR 通常は1900より大きい整数で表した年月日の年。 DOW 0から6までの整数で表した曜日であり0は日曜日を意味する。 DST 夏時間が有効なら‘t’、それ以外は‘nil’。 UTCOFF 万国標準時からの秒数、すなわち東グリニッジの秒数を示す整数。 *Common Lispに関する注意:* Common LispではDOWとUTCOFFの意味が異なる 。 -- Function: encode-time seconds minutes hour day month year &optional zone この関数は‘decode-time’の逆バージョン。これは7アイテムの暦データを 整数リストのtime値に変換する。引数の意味は上述‘decode-time’のテーブ ルを参照のこと。 100未満の年が特別に扱われることはない。これに1900や2000を超える年を 意味させたい場合には、‘encode-time’を呼び出す前に自身でこれらを修正 しなければならない。 オプション引数ZONEのデフォルトは、カレントのタイムゾーンルール。 *note Time Zone Rules::を参照のこと。通常のタイムゾーンルール値に加 えて(‘decode-time’で得られるような)リスト、(‘decode-time’で得られる ような)整数も夏時間による更なる変更を受けずに適用される。 ‘encode-time’にたいして7個より多い引数を渡すと最初の6つはSECONDSか らYEAR、最後の引数がZONEとして使用されてその間の引数は無視される。 これにより以下のように‘decode-time’がリターンしたリストの要素を ‘encode-time’の引数として使用することが可能になる: (apply 'encode-time (decode-time ...)) SECONDS、MINUTES、HOUR、DAY、MONTHの引数に範囲外の値を使用すること により単純な日付計算ができる。たとえばDAYが0なら与えられたMONTHの前 月末日になる。 オペレーティングシステムは可能なtime値の範囲に制限を設ける。範囲外 の時刻のエンコードを試みると結果はエラーとなる。たとえばあるシステ ムでは1970年以前では機能せず、別のシステムではより以前の1901年以降 から機能する。 38.8 時刻のパースとフォーマット =============================== 以下の関数はtime値と文字列内のテキストの間で変換と逆変換を行います。 time値は2つから4つの整数からなるリストです(*note Time of Day::を参照)。 -- Function: date-to-time string この関数はtime文字列STRINGをパースして対応するtime値をリターンする 。 -- Function: format-time-string format-string &optional time zone この関数はTIME(省略時はカレント時刻)をFORMAT-STRINGに応じて文字列に 変換する。変換にはタイムゾーンルールZONE(デフォルトはカレントのタイ ムゾーンルール)を使用する。*note Time Zone Rules::を参照のこと。引 数FORMAT-STRINGには時刻を置換する‘%’シーケンスを含めることができる 。以下のテーブルは‘%’シーケンスの意味: ‘%a’ 曜日の短縮名を意味する。 ‘%A’ 曜日の完全名を意味する。 ‘%b’ 月の短縮名を意味する。 ‘%B’ 月の完全名を意味する。 ‘%c’ ‘%x %X’のシノニム。 ‘%C’ これはlocale固有の意味をもつ。デフォルトlocale(Cという名前の locale)では‘%A, %B %e, %Y’と等価。 ‘%d’ 0パディングされた年月日の日。 ‘%D’ ‘%m/%d/%y’のシノニム。 ‘%e’ ブランクでパディングされた年月日の日。 ‘%h’ ‘%b’のシノニム。 ‘%H’ 時分秒の時(00から23)を意味する。 ‘%I’ 時分秒の時(01から12)を意味する。 ‘%j’ 年内の経過日(001から366)を意味する。 ‘%k’ ブランクでパディングされた時分秒の時(0から23)を意味する。 ‘%l’ ブランクでパディングされた時分秒の時(1から12)を意味する。 ‘%m’ 年月日の月(01から12)を意味する。 ‘%M’ 時分秒の分(00から59)を意味する。 ‘%n’ 改行を意味する。 ‘%N’ ナノ秒(000000000–999999999)を意味する。より少ない桁数を求める 場合にはミリ秒は‘%3N’、マイクロ秒は‘%6N’を使用する。余分な桁は 丸めずに切り捨てられる。 ‘%p’ 必要に応じて‘AM’か‘PM’を意味する。 ‘%r’ ‘%I:%M:%S %p’のシノニム。 ‘%R’ ‘%H:%M’のシノニム。 ‘%S’ 時分秒の秒(00から59)を意味する。 ‘%t’ タブ文字を意味する。 ‘%T’ ‘%H:%M:%S’のシノニム。 ‘%U’ 週の開始を日曜日とみなした年内の週(01から52)。 ‘%w’ 数字で表した曜日(0から6)で日曜日が0。 ‘%W’ これは週の開始を月曜日とみなした年内の週(01から52)。 ‘%x’ これはlocale固有の意味をもつ。デフォルトlocale(Cという名前の locale)では‘%D’と等価。 ‘%X’ これはlocale固有の意味をもつ。デフォルトlocale(Cという名前の locale)では‘%T’と等価。 ‘%y’ 世紀を含まない年(00から99)を意味する。 ‘%Y’ 世紀を併なう年を意味する。 ‘%Z’ タイムゾーンの短縮形(たとえば‘EST’)を意味する。 ‘%z’ 数値的オフセットによるタイムゾーン(たとえば‘-0500’)を意味する 。 これら‘%’シーケンスのすべてにおいてフィールド幅とパディングのタイプ を指定できる。これは‘printf’での指定のように機能する。フィールド幅 は桁数として‘%’シーケンスの中間に記述する。このフィールド幅を‘0’で 開始すると0によるパディングを意味する。フィールド幅を‘_’で開始すれ ばスペースによるパディングを意味する。 たとえば‘%S’は分内で経過した秒数を指定するが‘%03S’は3箇所の0、 ‘%_3S’は3箇所にスペースをパディングすることを意味する。ただの ‘%3S’は0でパディングを行う。これは‘%S’が通常において2箇所にパディン グする方法のため。 文字‘E’と‘O’は、‘%’と上記テーブルのアルファベットのいずれかの間に使 用されたときには修飾子として作用する。‘E’は日付と時刻にカレント localeの代替バージョンの使用を指定する。たとえば日本のlocaleでは、 ‘%Ex’により日本の元号にもとづいた日付フォーマットを得られるだろう。 ‘E’は‘%Ec’、‘%EC’、‘%Ex’、‘%EX’、‘%Ey’、‘%EY’での使用が許されている 。 ‘O’は通常の10進数字(訳注: アラビア数字)ではなく、カレントlocaleの 数字の代替表現を使用する。これは数字を出力する、ほとんどすべてのア ルファベットで使用が許されている。 この関数は処理のほとんどを行うためにCライブラリー関数‘strftime’を使 用している(*note (libc)Formatting Calendar Time::を参照)。その関数 とやり取りするために‘locale-coding-system’ (*note Locales::を参照 )で指定されたコーディングシステムを使用して最初に引数のエンコーディ ングを行う。‘strftime’が結果文字列をリターンした後に同じコーディン グシステムを使用して‘format-time-string’はデコードを行う。 -- Function: format-seconds format-string seconds この関数は引数SECONDSをFORMAT-STRINGに応じた年、日、時、...の文字列 に変換する。引数FORMAT-STRINGには変換を制御する‘%’シーケンスを指定 することができる。以下のテーブルは‘%’の意味: ‘%y’ ‘%Y’ 年間365日での年の整数。 ‘%d’ ‘%D’ 年月日の日。 ‘%h’ ‘%H’ 時分秒の時の整数。 ‘%m’ ‘%M’ 時分秒の分の整数。 ‘%s’ ‘%S’ 時分秒の秒の整数。 ‘%z’ 非プリント制御フラグ。これを使用する際には他の指定はサイズ減少 順、すなわち年、日、時刻、分、...のように与えなければならない 。最初の非0変換に遭遇するまで‘%z’の左側の結果文字列は生成され ない。たとえば‘emacs-uptime’ (*note emacs-uptime: Processor Run Time.を参照)で使用されるデフォルトフォーマットでは、秒数は 常に生成されるが年、日、時、分はそれらが非0の場合のみ生成され るだろう。 ‘%%’ リテラルの‘%’を生成する。 大文字のフォーマットシーケンスは数字に加えて単位を生成するが、小文 字フォーマットは数字だけを生成する。 ‘%’に続けてフィールド幅を指定できる。指定したフ幅より短ければブラン クでパディングされる。この幅の前にオプションでピリオドを指定すれば 、かわりに0パディングを要求する。たとえば‘"%.3Y"’は‘"004 years"’を 生成するだろう。 _警告:_ この関数は‘most-positive-fixnum’を超えないSECONDSの値でのみ 機能する(*note most-positive-fixnum: Integer Basics.を参照)。 38.9 プロセッサーの実行時間 =========================== EmacsはEmacsプロセスにより使用された経過時間(elapsed time)とプロセッサー 時間(processor time)の両方にたいして、それらをリターンする関数とプリミテ ィブをいくつか提供します。 -- Command: emacs-uptime &optional format この関数はEmacsの“uptime” — このEmacsインスタンスが実行してから経過 した実世界における稼動時間を表す文字列をリターンする。この文字列は オプション引数FORMATに応じて‘format-seconds’によりフォーマットされ る。利用できるフォーマット記述子については*note format-seconds: Time Parsing.を参照のこと。FORMATが‘nil’か省略された場合のデフォル トは‘"%Y, %D, %H, %M, %z%S"’。 インタラクティブに呼び出されるとエコーエリアにuptimeをプリントする 。 -- Function: get-internal-run-time この関数はEmacsにより使用されたプロセッサーの実行時間を、 ‘current-time’の場合と同じフォーマット(*note Time of Day::を参照)の 4つの整数のリスト‘(SEC-HIGH SEC-LOW MICROSEC PICOSEC)’でリターンす る。 この関数がリターンする値にはEmacsがプロセッサーを使用していない時間 は含まれないこと、そしてEmacsプロセスが複数のスレッドをもつ場合には 、すべてのEmacsスレッドにより使用されたプロセッサー時間の合計値がリ ターンされることに注意。 システムがプロセッサー実行時間を判断する方法を提供しなければ ‘get-internal-run-time’は‘current-time’と同じ値をリターンする。 -- Command: emacs-init-time この関数はEmacsの初期化(*note Startup Summary::を参照)にかかった秒 数を文字列としてリターンする。インタラクティブに呼び出された場合に はエコーエリアにプリントする。 38.10 時間の計算 ================ 以下の関数はtime値(*note Time of Day::を参照)を使用して暦計算を行います 。 -- Function: time-less-p t1 t2 これはtime値T1がtime値T2より小なら‘t’をリターンする。 -- Function: time-subtract t1 t2 これは2つのtime値の間の差T1 − T2をtime値でリターンする。 -- Function: time-add t1 t2 これは2つのtime値の和をリターンする。引数のうち1つはある時点での時 刻ではなく時間差を表すこと。以下はtime値に秒数を加算する方法: (time-add TIME SECONDS) -- Function: time-to-days time-value この関数はA.C. 1年元日からTIME-VALUEまでの間の日数をリターンする。 -- Function: time-to-day-in-year time-value これはTIME-VALUEに対応する年内の日数をリターンする。 -- Function: date-leap-year-p year この関数はYEARが閏年なら‘t’をリターンする。 38.11 遅延実行のためのタイマー ============================== 将来の特定時刻や特定の長さのアイドル時間経過後に関数を呼び出すために“タ イマー(timer)”をセットアップできます。 EmacsはLispプログラム内では、任意の時点ではタイマーを実行できません。 サブプロセスからの出力が受け入れ可能なときだけEmacsはタイマーを実行でき ます。つまり待機中や待機することが_可能_な‘sit-for’や‘read-event’のよう な特定のプリミティブ関数内部でのみタイマーを実行できます。したがって Emacsがbusyならタイマーの実行は遅延するかもしれません。しかしEmacsが idleなら実行される時刻は非常に正確になります。 quitにより多くのタイマー関数が物事を不整合な状態に放置し得るので、タ ーマー関数呼び出し前にEmacsは‘inhibit-quit’に‘t’をバインドします。ほとん どのタイマー関数は多くの作業を行わないので、これは通常は問題にはなりませ ん。しかし実際には実行に長時間を要する関数を呼び出すタイマーが問題となる 恐れがあります。タイマー関数がquitを許容する必要があるなら ‘with-local-quit’を使用するべきです(*note Quitting::を参照)。たとえば外 部プロセスから出力を受け取るためにタイマー関数が ‘accept-process-output’を呼び出す場合には、外部プロセスのハング時の ‘C-g’を確実に機能させるために、その呼び出しを‘with-local-quit’内部にラッ プすべきです。 バッファー内容の変更のためにタイマー関数を呼び出すのは通常は悪いアイ デアです。これを行うときには単一のアンドゥエントリーが巨大になるのを防ぐ ために、通常はバッファーの変更前後で‘undo-boundary’を呼び出して、タイマ ーによる変更とユーザーのコマンドによる変更を分離するべきです。 タイマー関数は‘sit-for’のようなEmacsに待機を発生させるような関数 (*note Waiting::を参照)の呼び出しも避けるべきです。その待機中に別のタイ マー(同じタイマーとう可能性さえある)が実行され得るので、これは予測不可能 な効果を導く恐れがあります。特定時間の経過後に処理される必要があるタイマ ー関数は、新たなタイマーをスケジュールしてこれを行うことができます。 マッチデータを変更するかもしれない関数を呼び出すタイマー関数はマッチ データの保存とリストアをするべきです。*note Saving Match Data::を参照し てください。 -- Command: run-at-time time repeat function &rest args これは時刻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 min’ 現在時刻から1分後を表す。 ‘1 min 5 sec’ 現在時刻から65秒後を表す。 ‘1 min 2 sec 3 hour 4 day 5 week 6 fortnight 7 month 8 year’ 現在時刻から丁度103ヵ月123日10862秒後を表す。 相対time値にたいしてEmacsは月を正確に30日、年を正確に365.25とみなす 。 有用なフォーマットのすべてが文字列という訳ではない。TIMEが数字(整数 か浮動小数点数)なら秒で数えた相対時刻を指定する。‘encode-time’の結 果はTIMEにたいする絶対時刻の指定にも使用できる。 ほとんどの場合には、REPEATを_最初_に呼び出されている際には効果はな くTIME単独で時刻を指定する。例外が1つありTIMEが‘t’ならエポックから REPEATの倍数秒ごとに毎回そのタイマーが実行される。これは ‘display-time’のような関数にとって有用。 関数‘run-at-time’はスケジュール済みの将来の特定アクションを識別する time値をリターンする。‘cancel-timer’(以下参照)の呼び出しにこの値を 使用できる。 タイマーのリピートは名目上はREPEAT秒ごとに毎回実行されますが、すべて のタイマー呼び出しは遅延する可能性があることを忘れないでください。1つの 繰り返しの遅延が次の繰り返しに影響を与えることはありません。たとえば3回 分のスケジュール済みのタイマー繰り返しをカバーするほどの計算等により Emacsがbusyでも、それらは待機を開始して連続してそのタイマー関数が3回呼び 出されることになります(それらの間の別のタイマー呼び出しは想定していない )。最後の呼び出しからN秒より短くならずにタイマーを再実行したい場合には REPEAT引数を使用しないでください。タイマー関数は、かわりにそのタイマーを 明示的に再スケジュールするべきです。 -- User Option: timer-max-repeats この変数の値は以前スケジュールされていた呼び出しが止むを得ずに遅延 された際に、タイマー関数がリピートによりまとめて呼び出される最大の 回数を指定する -- Macro: with-timeout (seconds timeout-forms...) body... 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’はタイマーを使用するシンプルな方法を提供します。 *note Yes-or-No Queries::を参照してください。 -- Function: cancel-timer timer これはTIMERにたいして要求されたアクションをキャンセルする。ここで TIMERはタイマーであること。これは通常は以前に‘run-at-time’か ‘run-with-idle-timer’がリターンしたものである。この関数はこれらの関 数の1つの呼び出しの効果をキャンセルする。指定した時刻が到来しても特 に何も起きないだろう。 38.12 アイドルタイマー ====================== 以下はEmacsの特定の期間アイドル時に実行するタイマーをセットアップする方 法です。それらをセットアップする方法とは別にすればアイドルタイマーは通常 のタイマーと同様に機能します。 -- Command: run-with-idle-timer secs repeat function &rest args 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つの問題があります: • すべてのプロセスの出力をブロックする(Emacsは待機時のみプロセス出力 を受け入れるため)。 • その時刻の間に実行されるべきすべてのアイドルタイマーをブロックする 。 同様にSECS引数がカレントのアイドル期間以下となるような、別のアイドルタイ マー(同じアイドルタイマーも含む)をセットアップするアイドルタイマー関数を 記述しないでください。そのようなタイマーはほとんど即座に実行されて、 Emacsが次回アイドルになるのを待機するかわりに再現なく継続して実行される でしょう。以下で説明するようにカレントのアイドル期間を適切に増加させて再 スケジュールするのが正しいアプローチです。 -- Function: current-idle-time この関数はEmacsがアイドルならEmacsがアイドルとなった期間を ‘current-time’で使用するのと同じ4つの整数リストのフォーマット ‘(SEC-HIGH SEC-LOW MICROSEC PICOSEC)’でリターンする(*note Time of Day::を参照)。 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)))) 38.13 端末の入力 ================ このセクションでは端末入力の記録や操作のための関数と変数を説明します。関 連する関数については*note Display::を参照してください。 38.13.1 入力のモード -------------------- -- Function: set-input-mode interrupt flow meta &optional quit-char この関数はキーボード入力の読み取りにたいしてモードをセットする。 EmacsはINTERRUPTが非‘nil’なら入力割り込み、‘nil’ならCBREAKモードを 使用する。デフォルトのセッティングはシステムに依存する。いくつかの システムでは指定に関わらずに常にCBREAKモードを使用する。 EmacsがXと直接通信する際にはこの引数を無視して、それがEmacsの知る通 信手段であれば割り込みを使用する。 FLOWが非‘nil’なら、Emacsは端末への出力にたいしてXON/XOFFフロー制御 (‘C-q’と‘C-s’)を使用する。これはCBREAK以外では効果がない。 引数METAは127より上の文字コード入力にたいするサポートを制御する。 METAが‘t’ならEmacsは8番目のビットがセットされた文字をメタ文字に変換 する。METAが‘nil’ならEmacsは8番目のビットを無視する。これは端末がそ のビットをパリティビットとして使用する場合に必要となる。METAが‘t’と ‘nil’のいずれでもなければ、Emacsは入力の8ビットすべてを変更せずに使 用する。これは8ビット文字セットを使用する端末にたいして適している。 QUIT-CHARが非‘nil’ならquitに使用する文字を指定する。この文字は通常 は‘C-g’。*note Quitting::を参照のこと。 ‘current-input-mode’関数はEmacsがカレントで使用する入力モードのセッテ ィングをリターンします。 -- Function: current-input-mode この関数はキーボード入力読み取りにたいするカレントのモードをリター ンする。これは‘set-input-mode’の引数に対応した‘(INTERRUPT FLOW META QUIT)’という形式のリストをリターンする。 INTERRUPT Emacsが割り込み駆動の入力(interrupt-driven input)を使用時には 非‘nil’。‘nil’ならEmacsはCBREAKモードを使用している。 FLOW Emacsが端末出力にXON/XOFFフロー制御(‘C-q’と‘C-s’)を使用してい れば非‘nil’。この値はINTERRUPTが‘nil’のときのみ意味がある。 META Emacsが入力文字の8番目のビットをメタ文字として扱う場合には ‘t’。‘nil’はEmacsがすべての入力文字の8ビット目をクリアーするこ とを意味する。その他の値はEmacsが8ビットすべてを基本的な文字コ ードとして使用することを意味する。 QUIT カレントでEmacsがquitに使用する文字であり通常は‘C-g’。 38.13.2 入力の記録 ------------------ -- Function: recent-keys この関数はキーボードかマウスからの最後の入力イベント300個を含んだベ クターをリターンする。その入力イベントがキーシーケンスに含まれるか 否かに関わらずすべての入力イベントが含まれる。つまりキーボードマク ロにより生成されたイベントを含まない、最後の入力イベント300個を常に 入手することになる(キーボードマクロは、デバッグにとってより興味深い とはいえないので除外されている。そのマクロを呼び出したイベントを確 認するだけで充分であるはず)、 ‘clear-this-command-keys’ (*note Command Loop Info::を参照)を呼び出 すと、その直後はこの関数は空のベクターをリターンする。 -- Command: open-dribble-file filename この関数はFILENAMEという名前の“dribbleファイル(dribble file)”をオー プンする。dribbleファイルがオープンされたとき、キーボードとマウス (ただしキーボードマクロ由来は除く)からのそれぞれの入力イベントはそ のファイルに書き込まれる。非文字イベントは‘<...>’で囲まれたプリント 表現で表される。(パスワードのような)機密情報はdribbleファイルへの記 録を終了させることに注意。 引数‘nil’でこの関数を呼び出すことによりファイルはクローズされる。 *note Terminal Output::の‘open-termscript’も参照のこと。 38.14 端末の出力 ================ 端末出力関数は出力をテキスト端末に送信したり、端末に送信した出力を追跡し ます。変数‘baud-rate’はEmacsが端末の出力スピードをどのように考慮すべきか を指示します。 -- User Option: baud-rate この変数はEmacsの認識する端末の出力スピード。この変数をセットしても 実際のデータ転送スピードは変化しないが、この値はパディングのような 計算に使用される。 これはテキスト端末でスクリーンの一部をスクロールしたり再描画すべき かどうかについての判定にも影響する。グラフィカルな端末での対応する 機能については*note Forcing Redisplay::を参照のこと。 値の単位はボー(baud)。 ネットワークを介して実行中にネットワークの別の部分が違うボーレートで 機能している場合には、Emacsがリターンする値はユーザーのローカル端末で使 用される値と異なるかもしれません。いくつかのネットワークプロトコルはロー カル端末のスピードでリモートマシンと対話するので、Emacsや他のプログラム は正しい値を得ることができますが相手側はそうではありません。Emacsが誤っ た値をもつ場合には最適よりも劣る判定をもたらします。この問題を訂正するた めには‘baud-rate’をセットします。 -- Function: send-string-to-terminal string &optional terminal この関数はSTRINGを変更せずにTERMINALへ送信する。STRING内のコントロ ール文字は端末依存の効果をもつ(端末上に非ASCIIテキストを表示する必 要があるなら*note Explicit Encoding::に記述した関数のいずれかを使用 してエンコードすること)。この関数はテキスト端末だけを操作する。 TERMINALには端末オブジェクト、フレーム、または選択されたフレームの 端末を意味する‘nil’を指定できる。batchモードではTERMINALが‘nil’なら 、STRINGは‘stdout’に送信される。 この関数の1つの用途はダウンロード可能なファンクションキー定義をもつ 端末上でファンクションキーを定義することである。たとえば以下は(特定 の端末で)ファンクションキー4を前方へ4文字移動(そのコンピューターヘ 文字‘C-u C-f’を送信)するように定義する方法: (send-string-to-terminal "\eF4\^U\^F") ⇒ nil -- Command: open-termscript filename この関数はEmacsが端末へ送信したすべての文字を記録する“termscriptフ ァイル(termscript file)”をオープンする。リターン値は‘nil’。 termscriptファイルはEmacsのスクリーン文字化け問題、不正なTermcapエ ントリーや、実際のEmacsバグより頻繁に発生する望ましくない端末オプシ ョンのセッティングの調査に有用。どの文字が実際に出力されるか確信で きれば、それらの文字が使用中のTermcap仕様に対応するかどうか確実に判 断できる。 (open-termscript "../junk/termscript") ⇒ nil 引数‘nil’でこの関数を呼び出すことによりtermscriptファイルはクローズ される。 *note Recording Input::の‘open-dribble-file’も参照のこと。 38.15 サウンドの出力 ==================== Emacsを使用してサウンドを再生するためには関数‘play-sound’を使用します。 特定のシステムだけがサポートされています。実際に処理を行うことができない システムで‘play-sound’を呼び出すとエラーが発生します。 サウンドはRIFF-WAVEフォーマット(‘.wav’)かSun Audioフォーマット (‘.au’)で格納されていなければなりません。 -- Function: play-sound sound この関数は指定されたサウンドを再生する。引数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で呼び出される。 -- Command: play-sound-file file &optional volume device この関数はオプションでVOLUMEとDEVICEを指定してサウンドFILEを再生す る代替インターフェイス。 -- Variable: play-sound-functions リストの関数はサウンド再生前に呼び出される。関数はそれぞれサウンド を記述するプロパティリストを単一の引数として呼び出される。 38.16 X11キーシンボルの処理 =========================== システム固有のX11 keysym(key symbol: キーシンボル)を定義するには変数 ‘system-key-alist’をセットします。 -- Variable: 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が競合しないかぎり無害である。 この変数は常にカレント端末にたいしてローカルでありバッファーローカ ルにできない。*note Multiple Terminals::を参照のこと。 以下の変数をセットすればEmacsが修飾キーMeta、Alt、Hyper、Superにたい して何のkeysymを使用するべきかを指定できます。 -- Variable: x-alt-keysym -- Variable: x-meta-keysym -- Variable: x-hyper-keysym -- Variable: x-super-keysym keysymの名前はそれぞれ修飾子Alt、Meta、Hyper、Superを意味する名前で あること。たとえば以下はMeta修飾キーとAlt修飾キーを交換する方法: (setq x-alt-keysym 'meta) (setq x-meta-keysym 'alt) 38.17 batchモード ================= コマンドラインオプション‘-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’ならそれを使用してエンコードされます (*note Locales::を参照)。‘coding-system-for-write’を他のコーディングシス テムにバインドすればこれをオーバーライドできます(*note Explicit Encoding::を参照)。 -- Variable: noninteractive Emacsがbatchモードで実行中ならこの変数は非‘nil’。 38.18 セッションマネージャー ============================ Emacsはアプリケーションのサスペンドとリスタートに使用されるXセッション管 理プロトコル(XSMP: X Session Management Protocol)をサポートしています。 Xウィンドウシステムでは“セッションマネージャー(session manager)”と呼ばれ るプログラムが実行中アプリケーション追跡の責を負います。Xサーバーのシャ ットダウン時にセッションマネージャーはアプリケーションに状態を保存するか 尋ねて、それらが応答するまでシャットダウンを遅延します。アプリケーション がそのシャットダウンをキャンセルすることもできます。 セッションマネージャーがサスペンドされたセッションをリスタートする際 には、これらのアプリケーションにたいして保存された状態をリロードするよう に個別に指示します。これはリストアする保存済みセッションが何かを指定する 特別なコマンドラインオプションを指定することにより行われます。これは Emacsでは‘--smid SESSION’という引数です。 -- Variable: emacs-save-session-functions Emacsは‘emacs-save-session-functions’と呼ばれるフックを介した状態の 保存をサポートする。セッションマネージャーがウィンドウシステムのシ ャットダウンを告げた際にEmacsはこのフックを実行する。これらの関数は カレントバッファーを一時バッファーにセットして引数なしで呼び出され る。それぞれの関数はバッファーにLispコードを追加するために ‘insert’を使用できる。最後にEmacsは“セッションファイル(session file)”と呼ばれるファイル内にそのバッファーを保存する。 その後でセッションマネージャーがEmacsを再開する際に、Emacsはセッシ ョンファイルを自動的にロードする(*note Loading::を参照)。これはスタ ートアップ中に呼び出される‘emacs-session-restore’という名前の関数に より処理される。*note Startup Summary::を参照のこと。 ‘emacs-save-session-functions’内の関数が非‘nil’をリターンすると、 Emacsはセッションマネージャーにシャットダウンのキャンセルを要求しま す。 以下はセッションマネージャによりEmacsがリストアされる際に単に ‘*scratch*’にテキストを挿入する例です。 (add-hook 'emacs-save-session-functions 'save-yourself-test) (defun save-yourself-test () (insert "(save-current-buffer (switch-to-buffer \"*scratch*\") (insert \"I am restored\"))") nil) 38.19 デスクトップ通知 ====================== Emacsはfreedesktop.orgのDesktop Notifications Specificationをサポートす るシステムとMS-Windowsでは“通知(notifications)”を送ることができます。 Posixホストでこの機能を使用するには、EmacsがD-Busサポート付きでコンパイ ルされていて‘notifications’ライブラリーがロードされていなければなりませ ん。*note D-Bus: (dbus)Top.を参照してください。以下の関数はD-Bus利用可能 な際にサポートされます: -- Function: notifications-notify &rest params この関数は引数PARAMSで指定された構成したパラメーターによりD-Busを通 じてデスクトップに通知を送信する。これらの引数は交互になったキーワ ードと値のペアーで構成されていること。以下はサポートされているキー ワードと値: ‘:bus BUS’ D-Busのバス。この引数は‘:session’以外のバスを使用する場合のみ 必要。 ‘:title TITLE’ 通知のタイトル。 ‘:body TEXT’ 通知のbodyのテキスト。通知サーバーの実装に依存して‘"bold text"’のような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 (http://developer.gnome.org/notification-spec/#categories)を参 照のこと。 ‘: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 important." :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" -- Function: notifications-close-notification id &optional bus この関数は識別子IDの通知をクローズする。BUSはD-Bus接続を表す文字列 でありデフォルトは‘:session’。 -- Function: notifications-get-capabilities &optional bus 通知サーバーの能力をシンボルのリストでリターンする。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’で始まる。 -- Function: notifications-get-server-information &optional bus 通知サーバーの情報を文字列のリストでリターンする。BUSはD-Bus接続を 表す文字列でありデフォルトは‘:session’。リターンされるリストは ‘(NAME VENDOR VERSION SPEC-VERSION)’。 NAME サーバーのプロダクト名。 VENDOR ベンダー名。たとえば‘"KDE"’や‘"GNOME"’。 VERSION サーバーのバージョン番号。 SPEC-VERSION サーバーが準拠する仕様のバージョン。 SPEC_VERSIONが‘nil’ならサーバーは‘"1.0"’以前の仕様をサポートする。 EmacsがMS-WindowsでGUIセッションとして実行時には、ネイティブのプリミ ティブを通じてD-Bus通知の小サブセットをサポートします: -- Function: w32-notification-notify &rest params この関数は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’を呼び出してアクティブな通知を削 除しなければならない。 タスクバーから通知とアイコンを削除するには以下の関数を使用します: -- Function: w32-notification-close id この関数は与えられた一意なIDでトレー通知を削除する。 38.20 ファイル変更による通知 ============================ いくつかのオペレーティングシステムはファイル変更にたいするファイルシステ ムの監視をサポートします。正しく設定されていれば、Emacsは‘inotify’、 ‘kqueue’、‘gfilenotify’、‘w32notify’のようなライブラリーを静的にリンクし ます。これらのライブラリーによりローカルマシン上でのファイルシステムの監 視が有効になります。 リモートマシン上のファイルシステムの監視も可能です。*note Remote Files: (emacs)Remote Files.を参照してください。これはEmacsにリンク済みの ライブラリーのいずれかに依存する訳ではありません。 通知されたファイル変更によりこれらすべてのライブラリーは異なるイベン トを発行するので、Emacsは一意な参照を提供するライブラリー‘filenotify’を 提供しています。 -- Function: file-notify-add-watch file flags callback FILEに関するファイルシステムイベントの監視を追加する。これはFILEに 関するファイルシステムイベントがEmacsに報告されるように取り計らう。 リターン値は追加された監視ディスクリプター(descriptor)。タイプは背 景にあるライブラリーに依存しており、以下の例に示すとおり整数とみな すことはできない。比較には‘equal’を使用すること。 何らかの理由によりFILEが監視不可能なら、この関数はエラー ‘file-notify-error’をシグナルする。 マウントされたファイルシステムでファイル変更を監視できないことがあ る。これはこの関数により検出されないので、非‘nil’のリターン値が FILEの変更の通知を保証するものではない。 FLAGSは何を監視するかセットするためのコンディションのリスト。以下の シンボルを含めることができる: ‘change’ ファイル変更を監視。 ‘attribute-change’ パーミッションや変更時刻のようなファイル属性の変更を監視。 FILEがディレクトリーならディレクトリー内のすべてのファイルの変更が 通知される。これは再帰的に機能しない。 Emacsは何らかのイベント発生時には以下の形式のEVENTを単一の引数とし て関数CALLBACKを呼び出す: (DESCRIPTOR ACTION FILE [FILE1]) DESCRIPTORはこの関数がリターンするオブジェクトと同じ。ACTIONはイベ ントを示し、以下のシンボルのいずれか: ‘created’ FILEが作成された。 ‘deleted’ FILEが削除された。 ‘changed’ FILEの内容が変更された。‘w32notify’ライブラリーでは属性の変更 でも同様に報告される。 ‘renamed’ FILEがFILE1にリネームされた。 ‘attribute-changed’ FILEの属性が変更された。 ‘stopped’ 監視中のFILEが削除された。 ‘w32notify’ライブラリーは‘attribute-changed’イベントを報告しないこ とに注意。このライブラリーはパーミッションや変更時刻のようなファイ ル属性が何か変更された際には‘changed’イベントを報告する。同じように ‘kqueue’ライブラリーでは、ディレクトリー監視時にはファイル属性変更 の報告に信頼性がない。 ‘stopped’イベントはファイル監視の停止を報告する。これは ‘file-notify-rm-watch’の呼び出された(以下参照)、監視中のファイルが 削除された、または背後にあるライブラリーから別のエラーが報告された 可能性がある。 FILEとFILE1はイベントが報告されたファイルの名前。たとえば: (require 'filenotify) ⇒ filenotify (defun my-notify-callback (event) (message "Event %S" event)) ⇒ my-notify-callback (file-notify-add-watch "/tmp" '(change attribute-change) 'my-notify-callback) ⇒ 35025468 (write-region "foo" nil "/tmp/foo") ⇒ Event (35025468 created "/tmp/.#foo") Event (35025468 created "/tmp/foo") Event (35025468 changed "/tmp/foo") Event (35025468 deleted "/tmp/.#foo") (write-region "bla" nil "/tmp/foo") ⇒ Event (35025468 created "/tmp/.#foo") Event (35025468 changed "/tmp/foo") Event (35025468 deleted "/tmp/.#foo") (set-file-modes "/tmp/foo" (default-file-modes)) ⇒ Event (35025468 attribute-changed "/tmp/foo") アクション‘renamed’がリターンされるかどうかは使用する監視ライブラリ ーに依存する。それ以外では‘deleted’と‘created’のアクションがランダ ムな順にリターンされる。 (rename-file "/tmp/foo" "/tmp/bla") ⇒ Event (35025468 renamed "/tmp/foo" "/tmp/bla") (delete-file "/tmp/bla") ⇒ Event (35025468 deleted "/tmp/bla") -- Function: file-notify-rm-watch descriptor DESCRIPTORに指定された既存のファイル監視を削除する。DESCRIPTORは ‘file-notify-add-watch’がリターンしたオブジェクトであること。 -- Function: file-notify-valid-p descriptor 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 38.21 動的にロードされるライブラリー ==================================== “ダイナミックにロードされるライブラリー(dynamically loaded library)”とは 機能が最初に必要になったときにオンデマンドでロードされるライブラリーです 。Emacsは自身の機能をサポートするライブラリーのオンデマンドロードのよう に、それらをサポートします。 -- Variable: dynamic-library-alist ダイナミックライブラリーとそれらを実装する外部ライブラリーファイル の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に静的にリンクされていれば、この変数は無視 される。 38.22 Security Considerations ============================= すべてのアプリケーションと同じように、アクセス等のルールを励行するオペレ ーティングシステムでは、Emacsを安全な環境で実行できます。注意を払えば Emacsベースのアプリケーションがそのようなルールをチェックするセキュリテ ィ境界の一部になることもできます。Emacsのデフォルトのセッティングでは典 型的なソフトウェア開発環境としても良好に機能しますが、アタッカーを含んだ 信頼されないユーザーの存在する環境では調整を要します。以下はそのようなア プリケーションを開発する際に助けとなるセキュリティ問題の要覧です。これは 完全なものではありません。これはセキュリティチェックリストではなく、セキ ュリティに関する問題にたいするアイデアを与えることを意図したものです。 ファイルローカル変数 Emacsがvisitするファイルは、ファイルをvisitするバッファーに影響を与 える変数セッティングを含むことができる。*note File Local Variables::を参照のこと。同様にディレクトリーはディレクトリー内のす べてのファイルに共通なローカル変数値を指定できる。*note Directory Local Variables::を参照のこと。これらの変数の悪用から守るために Emacsはある程度の努力をしているにしても、過度に楽観してパッケージで ‘safe-local-variable’をセットすることにより単にセキュリティホールが 作られてしまうというのは、あまりにも有りがちな問題である。ファイル とディレクトリーの両方でこの機能を無効にするには、 ‘enable-local-variables’に‘nil’をセットする。 アクセスコントロール Emacsが通常は背後にあるオペレーティングシステムのアクセス権限にした がうとしても、アクセスを特別に扱うケースがある。たとえばファイル名 は独自のアクセスチェックによりファイルを特別に扱うハンドラーをもつ ことができる。*note Magic File Names::を参照のこと。また対応するフ ァイルが書き込み可でもバッファーを読み取り専用にできるが逆も可能で あり、その結果は‘File passwd is write-protected; try to save anyway? (yes or no)’のようなメッセージとなるかもしれない。*note Read Only Buffers::を参照のこと。 認証 Emacsには‘read-passwd’のようなパスワードを扱う関数がいくつかある。 *note Reading a Password::を参照のこと。これらの関数はパスワードを 公に喧伝しないにしても、Emacs内部にアクセスする猛者なアタッカーにた いする実装の証左はない。たとえばパスワード使用後にメモリーをクリア ーするためにelispコードが‘clear-string’を使用しても、パスワードの残 滓は依然としてガーベージコレクトされたフリーリスト内に存在する。 *note Modifying Strings::を参照のこと。 コードインジェクション Emacsは他の多くのアプリケーションにコマンドを送信でき、アプリケーシ ョンはコマンドの値として送信された文字列を命令と誤解しないように注 意を払う必要がある。たとえばファイルをAからBにリネームするためにシ ェルコマンドを使用する際には単に文字列‘mv A B’を使用するべきではな い。なぜならいずれかのファイル名が‘-’で始まったり、‘;’のようなシェ ルのメタ文字を含むかもしれない。この種の問題は ‘shell-quote-argument’のような関数の使用で回避できるものの、POSIXプ ラットフォームでは‘shell-quote-argument’はシェルのメタ文字はクォー トするが先頭の‘-’はクォートしない。*note Shell Arguments::を参照の こと。‘call-process’を使用するほうが通常はサブシェルより安全である 。*note Synchronous Processes::を参照のこと。同様に、たとえば‘mv’を 呼び出すかわりに‘(rename-file "A" "B" t)’を使用する等、Emacsのビル ドイン関数を使用するほうが安全である。*note Changing Files::を参照 のこと。 コーディングシステム Emacsはアクセスするファイルとネットワークのコーディングシステムを推 察する。*note Coding Systems::を参照のこと。Emacsの推察が誤っていた りネットワークの相手先がEmacsの推察に不同意なら、結果となるコーディ ングシステムは信頼できないかもしれない。更にその推察が正しいときで さえ、他のプログラムが使用できないバイトをEmacsが使用できる場合がよ くある。たとえばEmacsEmacsにとってはnullバイトは他と同じ単なる文字 だとしても、他の多くのアプリケーションはnull文字を文字列終端として 扱うので、nullバイトを含む文字列やファイルを誤って処理する。 Environment and configuration variables POSIXはEmacsの挙動に影響し得る環境変数をいくつか指定する。ASCII英大 文字、数字、アンダースコアだけから構成される名前をもつ任意の環境変 数がEmacsの内部の動作に影響を及ぼし得る。Emacsはその種の ‘EMACSLOADPATH’のような変数をいくつか使用する。*Note Library Search::を参照のこと。Emacsが呼び出すかもしれないユーティリティーす べてにたいして標準の挙動を得るためには、いくつかの環境変数(‘PATH’、 ‘POSIXLY_CORRECT’、‘SHELL’、‘TMPDIR’)が正しく設定されていることを要 するシステムがいくつかある。‘TZ’のような一見は無害な変数でさえセキ ュリティに影響し得る。*note System Environment::を参照のこと。 Emacsにはカスタマイズと同義な変数が他にある。たとえば変数 ‘shell-file-name’に非標準的な動作を行うシェルを指定すれば、Emacsベ ースのアプリケーションはご堂する可能性がある。 Installation Emacsのインストールの際にインストール先のディレクトリー階層が信頼で きないユーザーに変更可能なら、そのアプリケーションは信頼できない。 これはEmacsが使用するプログラムや読み書きするファイルのディレクトリ ー階層にも適用される。 Network access Emacsでは多くの場合にネットワークにアクセスするので、通常行うような ネットワークアクセスを回避したいと思うかもしれない。たとえば ‘tramp-mode’を‘nil’にセットしていなければ、特定の構文を使用するファ イル名はネットワークファイルとして解釈されて、ネットワーク越しに取 得される。*note The Tramp Manual: (tramp)Top.を参照のこと。 Race conditions Emacsアプリケーションには、他のアプリケーションが行う競合状態に関す るものと同種の問題がある。たとえば‘(file-readable-p "foo.txt")’が ‘t’をリターンしたときでさえ、‘file-readable-p’の呼び出しからその時 点の間に別のアプリケーションがファイルの権限を変更したために読み取 りできないかもしれない。*note Testing Accessibility::を参照のこと。 Resource limits Emacsがメモリーや他のオペレーティングシステムのリソースを使い切った ときには、通常は完了まで実行される計算が異常終了でトップレベルに戻 るかもしれないので挙動の信頼性が減少し得る。これにより通常は完了す る操作をEmacsが放棄するかもしれない。 39 配布用 Lispコードの準備 ************************** Emacs Lispコードをユーザーに配布するために、Emacsは標準的な方法を提供し ます。“パッケージ(package)”はユーザーが簡単にダウンロード、インストール 、アンインストール、および更新できるような方法でフォーマットと同梱された 1つ以上のファイルのコレクションです。 以降のセクションではパッケージを作成する方法、およびそれを他の人がダ ウンロードできるように“パッケージアーカイブ(package archive)”に配置する 方法を説明します。パッケージングシステムのユーザーレベル機能の説明は *note (emacs)Packages::を参照してください。 39.1 パッケージ化の基礎 ======================= パッケージは“シンプルパケージ(simple package)”か“複数ファイルパッケージ (multi-file package)”のいずれかです。シンプルパッケージは単一のEmacs Lispファイル内に格納される一方、複数ファイルパッケージはtarファイル(複数 のLispファイルとマニュアルのような非Lispファイルが含まれる可能性がある )に格納されます。 通常の使い方ではシンプルパッケージと複数ファイルパッケージとの違いは 比較的重要ではありません。Package Menuインターフェースでは、それらの間に 差異はありません。しかし以降のセクションで説明するように作成する手順は異 なります。 パッケージ(シンプルか複数ファイル)はそれぞれ特定の“属性 (attributes)”をもっています: Name 短い単語(たとえば‘auctex’)。これは通常はそのプログラム内でシンボル プレフィクスとしても使用される(*note Coding Conventions::を参照)。 Version 関数‘version-to-list’が理解できる形式のバージョン番号(たとえば ‘11.86’)。パッケージの各リリースではバージョン番号もアップすること 。 Brief description そのパッケージがPackage Menuにリストされる際にが表示される。理想的 には36文字以内の単一行であること。 Long description これは‘C-h P’ (‘describe-package’)により作成されたバッファーに表示 されて、その後にそのパッケージの簡単な説明(brief description)とイン ストール状態(installation status)が続く。これには通常はパッケージの 能力とインストール後に使用を開始する方法を複数行に渡って完全に記述 すること。 Dependencies そのパッケージが依存する他のパッケージ(最低のバージョン番号を含むか もしれない)。このリストは空でもよく、その場合にはパッケージは依存パ ッケージがないことを意味する。それ以外ならパッケージをインストール することにより依存パッケージも自動的にインストールされる。依存パッ ケージのいずれかが見つからなければパッケージをインストールすること はできない。 コマンド‘package-install-file’、またはPackage Menuのいずれかを介した パッケージのインストールでは、‘package-user-dir’に‘NAME-VERSION’という名 前のサブディレクトリーが作成されます。ここでNAMEはパッケージ名、 VERSIONはバージョン番号です(たとえば‘~/.emacs.d/elpa/auctex-11.86/’)。わ たしたちはこれをパッケージの“コンテンツディレクトリー(content directory)”と呼んでいます。これはEmacsがパッケージのコンテンツ(シンプル パッケージでは単一のLispファイル、または複数ファイルパッケージから抽出さ れたファイル)を配置する場所です。 その後にEmacsはautoloadマジックコメント(*note Autoload::を参照)にたい してコンテンツディレクトリー内のすべてのLispファイルを検索します。これら のautoload定義はコンテンツディレクトリーの‘NAME-autoloads.el’という名前 のファイルに保存されます。これらは通常はパッケージ内で定義された主要なユ ーザーコマンドのautoloadに使用されますが、‘auto-mode-alist’への要素の追 加(*note Auto Major Mode::を参照)等の別のタスクを行うこともできます。パ ッケージは通常はその中で定義された関数と変数のすべてをautoload_しない_こ とに注意してください — 通常はそのパッケージの使用を開始するために呼び出 される一握りのコマンドだけがautoloadされます。それからEmacsはそのパッケ ージ内のすべてのLispファイルをバイトコンパイルします。 インストール後はインストールされたパッケージは“ロード済み(loaded)”に なります。Emacsは‘load-path’にコンテンツディレクトリーを追加して ‘NAME-autoloads.el’内のautoload定義を評価します。 Emacsのスタートアップ時はインストール済みパッケージをロードするために 、常に自動的に関数‘package-initialize’が呼び出されます。これはinitファイ ルと、(もしあれば)abbrevファイルのロード後、かつ‘after-init-hook’の実行 前に行われます(*note Startup Summary::を参照)。ユーザーオプション ‘package-enable-at-startup’が‘nil’なら自動的なパッケージのロードは無効で す。 -- Command: package-initialize &optional no-activate この関数はインストール済みパッケージ、およびそれらがロード済みかど うかを記録するEmacsの内部レコードを初期化する。ユーザーオプション ‘package-load-list’は何のパッケージをロードするかを指定する。デフォ ルトではすべてのインストール済みパッケージがロードされる。スタート アップ中に呼び出されると、この関数は意図せずパッケージを2重にロード することを防ぐために‘package-enable-at-startup’に‘nil’をセットする 。*note (emacs)Package Installation::を参照のこと。 オプション引数NO-ACTIVATEが非‘nil’なら、インストール済みパッケージ を実際にロードせずにこのレコードを更新する。これは内部でのみ使用さ れる。 39.2 単純なパッケージ ===================== シンプルパッケージは単一のEmacs Lispソースファイルで構成されます。このフ ァイルはEmacs Lispライブラリーのヘッダー規約に準拠していなればなりません (*note Library Headers::を参照)。以下の例に示すようにパッケージの属性は 種々のヘッダーから取得されます: ;;; superfrobnicator.el --- Frobnicate and bifurcate flanges ;; Copyright (C) 2011 Free Software Foundation, Inc. ;; Author: J. R. Hacker ;; Version: 1.3 ;; Package-Requires: ((flange "1.0")) ;; Keywords: multimedia, frobnicate ;; URL: http://example.com/jrhacker/superfrobnicate ... ;;; Commentary: ;; This package provides a minor mode to frobnicate and/or ;; bifurcate any flanges you desire. To activate it, just type ... ;;;###autoload (define-minor-mode superfrobnicator-mode ... そのパッケージの名前は1行目のファイル名の拡張子を除いた部分と同じです 。ここでは‘superfrobnicator’です。 brief description(簡単な説明)も1行目から取得されます。ここでは ‘Frobnicate and bifurcate flanges’です(訳注: ‘flangeをフロブニケートして 二股化する’のフロブニケートとはある技術にたいする無目的で非生産的な具体 的行為を意味する)。 バージョン番号は、もしあれば‘Package-Version’ヘッダー、それ以外は ‘Version’ヘッダーから取得されます。これらのヘッダーのいずれかが_提供され ていなればなりません_。ここでのバージョン番号は1.3です。 そのファイルに‘;;; Commentary:’セクションがあれば、そのセクションは長 い説明(long description)として使用されます(その説明を表示する際には Emacsは‘;;; Commentary:’の行とコメント内のコメント文字列を省略する)。 そのファイルに‘Package-Requires’ヘッダーがあればパッケージの依存関係 (package dependencies)として使用されます。上の例ではパッケージはバージョ ン1.0以上の‘flange’パッケージに依存します。‘Package-Requires’ヘッダーの 説明は*note Library Headers::を参照してください。このヘッダーが省略され た場合にはパッケージに依存関係はありません。 ヘッダー‘Keywords’と‘URL’はオプションですが含めることを推奨します。コ マンド‘describe-package’は出力にリンクを追加するためにこれらを使用します 。‘Keywords’ヘッダーには‘finder-known-keywords’リストからの標準的キーワ ードを少なくとも1つ含めるべきです。 ファイルには*note Packaging Basics::で説明したように1つ以上の autoloadマジックコメントも含めるべきです。上の例ではマジックコメントによ り‘superfrobnicator-mode’が自動ロードされます。 パッケージアーカイブに単一ファイルのパッケージを追加する方法は*note Package Archives::を参照してください。 39.3 複数ファイルのパッケージ ============================= 複数ファイルパッケージは単一ファイルパッケージより作成の手軽さが少し劣り ますが、より多くの機能を提供します。複数ファイルパッケージには複数の Emacs Lispファイル、Infoマニュアル、および(イメージのような)他のファイル タイプを含めることができます。 インストールに先立ち複数パッケージはファイルとしてパッケージアーカイ ブに含まれます。このtarファイルは‘NAME-VERSION.tar’という名前でなければ なりません。ここでNAMEはパッケージ名、VERSIONはバージョン番号です。tarの コンテンツは一度解凍されたなら、“コンテンツディレクトリcontent directory)”である‘NAME-VERSION’という名前のディレクトリーにすべて解凍さ れなければなりません(*note Packaging Basics::を参照)。このコンテンツディ レクトリーのサブディレクトリーにもファイルが抽出されるかもしれません。 このコンテンツディレクトリー内のファイルのうち、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’になるでしょう。 -- Function: define-package name version &optional docstring requirements この関数はパッケージを定義する。NAMEはパッケージの名前(文字列)、 VERSIONは関数‘version-to-list’が理解できる形式のバージョン(文字列 )、DOCSTRINGは簡単な説明(brief description)。 REQUIREMENTSは必要となるパッケージとバージョン番号。このリスト内の 各要素は‘(DEP-NAME DEP-VERSION)’という形式であること。ここで DEP-NAMEはその依存するパッケージ名が名前であるようなシンボル、 DEP-VERSIONは依存するパッケージのバージョン番号(文字列)。 コンテンツディレクトリーに‘README’という名前のファイルがあれば長い説 明(long description)として使用されます。 コンテンツディレクトリーに‘dir’という名前のファイルがあれば、 ‘install-info’で作成されるInfoディレクトリーファイル名とみなされます。 *note Invoking install-info: (texinfo)Invoking install-info.を参照してく ださい。関係のあるInfoファイルもコンテンツディレクトリー内に解凍される必 要があります。この場合には、パッケージがアクティブ化されたときにEmacsが 自動的に‘Info-directory-list’にコンテンツディレクトリーを追加します。 パッケージ内に‘.elc’ファイルを含めないでください。これらはパッケージ のインストール時に作成されます。ファイルがバイトコンパイルされる順序を制 御する方法は存在しないことに注意してください。 ‘NAME-autoloads.el’という名前のファイルを含めてはなりません。このファ イルはパッケージのautoload定義のために予約済みです(*note Packaging Basics::を参照)。これはパッケージのインストール時にパッケージ内のすべて のLispファイルからautoloadマジックコメントを検索する際に自動的に作成され ます。 複数パッケージファイルが、(イメージのような)補助的なデータファイルを 含む場合には、パッケージ内のLispファイルは変数‘load-file-name’を通じてそ れらのファイルを参照できます(*note Loading::を参照)。以下は例です: (defconst superfrobnicator-base (file-name-directory load-file-name)) (defun superfrobnicator-fetch-image (file) (expand-file-name file superfrobnicator-base)) 39.4 パッケージアーカイブの作成と保守 ===================================== Package Menuを通じて“パッケージアーカイブ(package archives)”からユーザー はパッケージをダウンロードできます。そのようなアーカイブは変数 ‘package-archives’で指定されます。この変数のデフォルト値に でGNUプロジェクトがホストするアーカイブが単一のエン トリーとして含まれています。このセクションではパッケージアーカイブのセッ トアップと保守の方法について説明します。 -- User Option: package-archives この変数の値はEmacsパッケージマネージャーが認識するパッケージアーカ イブのリスト。 このalistの要素はそれぞれが1つのアーカイブに対応する‘(ID . LOCATION)’という形式であること。ここでIDはパッケージ名(文字列)、 LOCATIONは文字列であるような“ベースロケーション(base location)”。 ベースロケーションが‘http:’で始まればHTTPのURLとして扱われて、(デフ ォルトのGNUアーカイブのように)HTTPを介してこのアーカイブからパッケ ージがダウンロードされる。 それ以外ならベースロケーションはディレクトリー名であること。この場 合にはEmacsは通常のファイルアクセスを通じて、そのアーカイブからパッ ケージを取得する。localのようなアーカイブは主としてテストに有用。 パッケージアーカイブはパッケージ、および関連するファイルが格納された 単なるディレクトリーです。HTTPを介してそのアーカイブに到達できるようにし たければ、このディレクトリーがウェブサーバーにアクセスできなければなりま せん。これを達成する方法はマニュアルの範囲を超えます。 手軽なのは‘package-x’を通じてパッケージアーカイブのセットアップと更新 を行う方法です。これはEmacsに含まれていますがデフォルトではロードされま せん。ロードするには‘M-x load-library package-x ’、または ‘(require 'package-x)’をinitファイルに追加します。*note Lisp Libraries: (emacs)Lisp Libraries.を参照してください。一度ロードされれば以下を使用で きます: -- User Option: package-archive-upload-base この変数の値はディレクトリー名としてのパッケージアーカイブのベース ロケーション。‘package-x’ライブラリー内のコマンドはこのベースロケー ションを使用することになる。 このディレクトリー名は絶対ファイル名であること。パッケージアーカイ ブが別マシン上にある場合には、 ‘/ssh:foo@example.com:/var/www/packages/’のようなリモート名を指定で きる。*note Remote Files: (emacs)Remote Files.を参照のこと。 -- Command: package-upload-file filename このコマンドはファイル名FILENAMEの入力を求めて、そのファイルを ‘package-archive-upload-base’にアップロードする。このファイルはシン プルパッケージ(‘.el’ファイル)、または複数ファイルパッケージ (‘.tar’ファイル)のいずれかでなければならず、それ以外ならエラーが発 生する。そのパッケージの属性は自動的に解凍されて、アーカイブのコン テンツリストはこの情報でアップロードされる。 ‘package-archive-upload-base’が有効なディレクトリーを指定しない場合 には、この関数はインタラクティブにそれの入力を求める。そのディレク トリーが存在しなければ作成する。このディレクトリーが初期コンテンツ をもつ必要はない(最初に空のアーカイブを作成するためにこのコマンドを 使用できる)。 -- Command: package-upload-buffer このコマンドは‘package-upload-file’と似ているが、パッケージファイル の入力を求めずにカレントバッファーのコンテンツをアップロードする。 カレントバッファーはシンプルパッケージ(‘.el’ファイル)か複数ファイル パッケージ(‘.tar’ファイル)をvisitしていなればならず、それ以外ならエ ラーが発生する。 アーカイブ作成後に、それが‘package-archives’内になければPackage Menuイン ターフェースからアクセスできないことを忘れないでください。 公的なパッケージアーカイブの保守には責任が併ないます。アーカイブから Emacsユーザーがパッケージをインストールする際には、それらのパッケージは そのユーザーの権限において任意のコードを実行できるようになります(これは パッケージにたいしてだけでなく一般的なEmacsコードにたいしても真といえる )。そのためアーカイブの保守を保つとともにホスティングシステムが安全であ るよう維持するべきです。 暗号化されたキーを使用してパッケージに“サイン(sign)”するのがパッケー ジのセキュリティーを向上する1つの方法です。gpgのprivateキーとpublicキー を生成してあれば以下のようにそのパッケージにサインするためにgpgを使用で きます: gpg -ba -o FILE.sig FILE 単一ファイルパッケージにたいしては、FILEはそのパッケージのLispファイルで す。複数ファイルパッケージではそのパッケージのtarファイルです。同じ方法 によりアーカイブのコンテンツファイルにもサインできます。これを行うにはパ ッケージと同じディレクトリーで‘.sig’ファイルを利用可能できるようにしてく ださい。ダウンロードする人にたいしても、のようなキ ーサーバーにアップロードすることによりpublicキーを利用できるようにするべ きです。その人がアーカイブからパッケージをインストールする際には署名の検 証にpublicキーを使用できます。 これらの方法についての完全な説明はマニュアルの範囲を超えます。暗号化 キーとサインに関する詳細は*note GnuPG: (gnupg)Top.、Emacsに付属するGNU Privacy Guardへのインターフェースについては*note EasyPG: (epa)Top.を参照 してください。 Appendix A Emacs 24 Antinews **************************** 時代に逆らって生きるユーザーのために以下はEmacsバージョン24。5へのダウン グレードに関する情報です。Emacs 25.1機能の不在による結果としての偉大なる 単純さを、ぜひ堪能してください。 A.1 Old Lisp Features in Emacs 24 ================================= • 偶数個の引数で呼び出さなければならないという‘setq’と‘setf’の要件は 削除されました。これで奇数個の引数でこれらを呼び出すことが可能にな り、欠落分にはEmacsが‘nil’を提供するでしょう。単純明快なルールです! • サブプロセスがEmacsにより実行されたことを示すために、‘M-x shell’と ‘M-x compile’は必要に応じて環境変数‘EMACS’をセットします。このセッ ティングに対処する方法を何年もかけて習得したパッケージは、対処コー ドの使用を継続できます。 • ‘save-excursion’フォームは期待どおりにマークの保存とリストアを行い ます。新しい‘save-mark-and-excursion’は必要なくなったので削除しまし た。 • ユーザーに表示するメッセージやヘルプバッファーのクォート文字を変換 するための‘text-quoting-style’変数および関連する機能は削除されまし た。これでEmacsはコードに記述したのと完全に同一なクォート文字を表示 するようになりました! 同様に‘substitute-command-keys’はクォート文字 を加工しません。時代を遡るにつれてUnicodeのサポートと重要性は減少す るので、Unicode標準が考案したこれらのfancyな新クォートの表示は不必 要になります。 • regexpクラス内のUnicode文字プロパティのサポートを削除することにより 正規表現が簡略化されました。結果として‘[:alpha:]’と‘[:alnum:]’は単 語構文をもつ任意の文字、‘[:graph:]’と‘[:print:]’は任意のマルチバイ ト文字にマッチして、それらには代替コードポイントと未割り当てのコー ドポイントが含まれます。繰り返しますが、これは時代の逆行による Unicodeの重要性減少に沿っています。 • ‘(/ N)’の評価によりNを得るようになりました。Common Lispでの解釈は訂 正を要する酷い間違いだとわたしたちは気がついたのです。 • UPatternの‘quote’と‘app’を削除することにより‘pcase’は大幅に簡略化さ れました。Lispプログラムに新たにUPatternを定義させる必要がないこと も判明したにで、この機能をさらに簡略化するために‘pcase-defmacro’も 削除しました。 • テキストプロパティ‘cursor-intangible’と‘cursor-sensor-functions’を 、より単純な‘intangible’、‘point-entered’、‘point-left’プロパティに 置き換えることにより削除しました。後者はより低レベルで実装されるの で、ユーザーの期待により統合されるでしょう。同様の理由により ‘cursor-intangible-mode’と‘cursor-sensor-mode’は削除されました。フ ック変数‘inhibit-point-motion-hooks’の使用はもはや時代遅れではあり ません。 • ‘make-process’と接続タイプ‘pipe’の削除により、プロセスの作成と管理 を行う関数が大幅に改善、簡略化されました。サブプロセスの‘stderr’へ のリダイレクトはEmacsではなくシェルの機能により行われるべきなのです 。 • 有益なメッセージを妨げることはユーザーとの対話に有益ではないので、 それに使用され得る‘inhibit-message’変数の削除を決定しました。 • ジェネレーターとファイナライザーにたいするサポートは真に必要ではな いことが判明したので削除しました。 • 過度な複雑さとUnicodeサポートの減少の必要性のために、関数 ‘string-collate-lessp’と‘string-collate-equalp’は削除されました。こ れらのlocale非依存なカウンターパートである‘string-lessp’と ‘string-equal’はよりシンプルであり、locale依存の照合がEmacsにおいて 有用たりえる状況をわたしたちが確認できない予測可能な結果を得ること ができます。結果として‘ls-lisp.el’パッケージはlocale非依存な方法で ソートを行います。 • Emacsの過去のバージョンにおける双方向編集サポートの削除にたいする準 備として、2つの関数‘bidi-find-overridden-directionality’と ‘buffer-substring-with-bidi-context’の削除を開始しました。 • ‘current-time-string’のような時刻変換関数はオプション引数ZONEを受け 取らなくなりました。カレントタイムゾーンを変更する必要があるなら(何 で?)、‘set-time-zone-rule’で明示的に行ってください。 • 簡略化にたいする継続要求の一環として、他の多くの関数と変数が排除さ れました。 Appendix B GNU Free Documentation License ***************************************** Version 1.3, 3 November 2008 Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 0. PREAMBLE 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. 1. APPLICABILITY AND DEFINITIONS 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. 2. VERBATIM COPYING 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. 3. COPYING IN QUANTITY 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. 4. MODIFICATIONS 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: A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission. B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement. C. State on the Title page the name of the publisher of the Modified Version, as the publisher. D. Preserve all the copyright notices of the Document. E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices. F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below. G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’s license notice. H. Include an unaltered copy of this License. I. Preserve the section Entitled “History”, Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled “History” in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence. J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the “History” section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission. K. For any section Entitled “Acknowledgements” or “Dedications”, Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein. L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles. M. Delete any section Entitled “Endorsements”. Such a section may not be included in the Modified Version. N. Do not retitle any existing section to be Entitled “Endorsements” or to conflict in title with any Invariant Section. O. Preserve any Warranty Disclaimers. 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. 5. COMBINING DOCUMENTS 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.” 6. COLLECTIONS OF DOCUMENTS 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. 7. AGGREGATION WITH INDEPENDENT WORKS 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. 8. TRANSLATION 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. 9. TERMINATION 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. 10. FUTURE REVISIONS OF THIS LICENSE 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 . 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. 11. RELICENSING “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. ADDENDUM: How to use this License for your documents ==================================================== 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. Appendix C GNU General Public License ************************************* Version 3, 29 June 2007 Copyright © 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble ======== 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. TERMS AND CONDITIONS ==================== 0. Definitions. “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. 1. Source Code. 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. 2. Basic Permissions. 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. 3. Protecting Users’ Legal Rights From Anti-Circumvention Law. 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. 4. Conveying Verbatim Copies. 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. 5. Conveying Modified Source Versions. 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. The work must carry prominent notices stating that you modified it, and giving a relevant date. b. The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. c. You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d. If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. 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. 6. Conveying Non-Source Forms. 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. Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b. Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c. Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d. Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e. Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. 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. 7. Additional Terms. “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: a. Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b. Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c. Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d. Limiting the use for publicity purposes of names of licensors or authors of the material; or e. Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f. Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. 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. 8. Termination. 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. 9. Acceptance Not Required for Having Copies. 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. 10. Automatic Licensing of Downstream Recipients. 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. 11. Patents. 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. 12. No Surrender of Others’ Freedom. 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. 13. Use with the GNU Affero General Public License. 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. 14. Revised Versions of this License. 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. 15. Disclaimer of Warranty. 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. 16. Limitation of Liability. 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. 17. Interpretation of Sections 15 and 16. 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. END OF TERMS AND CONDITIONS =========================== How to Apply These Terms to Your New Programs ============================================= 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 . 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 . 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 . Appendix D ヒントと規約 *********************** このチャプターででは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コーディングの慣習 ================================ 以下は幅広いユーザーを意図したEmacs Lispコードを記述する際にしたがうべき 慣習です: • 単なるパッケージのロードがEmacsの編集の挙動を変更するべききではない 。コマンド、その機能を有効や無効にするコマンド、その呼び出しが含ま れる。 この慣習はカスタム定義を含むすべてのファイルに必須である。そのよう なファイルを慣習にしたがうために修正するのが非互換の変更を要するな ら、構うことはないから非互換の修正を行うこと。先送りにしてはならな い。 • 他のLispプログラムと区別するための短い単語を選択すること。あなたの プログラム内のグローバルなシンボルすべて、すなわち変数、定数、関数 の名前はその選択したプレフィクスで始まること。そのプレフィクスと名 前の残りの部分はハイフン‘-’で区切る。Emacs Lisp内のすべてのグローバ ル変数は同じネームスペース、関数はすべて別のネームスペースを共有す るので、これの実践は名前の競合を回避する(1)。他のパッケージから使用 されることを意図しない場合にはプレフィクス名前を2つのハイフンで区切 ること。 ユーザーの使用を意図したコマンド名では、何らかの単語がそのパッケー ジ名のプレフィクスの前にあると便利なことがある。関数や変数等を定義 する構文は‘defun’や‘defvar’で始まればより良く機能するので、名前内で それらの後に名前プレフィクスを置くこと。 この勧告は‘copy-list’のようなEmacs Lisp内のプリミティブではなく、伝 統的なLispプリミティブにさえ適用される。信じようと信じまいと ‘copy-list’を定義する尤もらしい方法は複数あるのだ。安全第一である。 かわりに‘foo-copy-list’や‘mylib-copy-list’のような名前を生成するた めに、あなたの名前プレフィクスを追加しよう。 ‘twiddle-files’のような特定の名前でEmacsに追加されるべきだと考えて いる関数を記述する場合には、プログラム内でそれを名前で呼び出さない こと。プログラム内ではそれを‘mylib-twiddle-files’で呼び出して、わた したちがそれをEmacsに追加するため提案メールを、 ‘bug-gnu-emacs@gnu.org’に送信すること。もし追加することになったとき に、わたしたちは十分容易にその名前を変更できるだろう。 1つのプレフィクスで十分でなければ、それらに意味があるかぎり、あなた のパッケージは2つか3つの一般的なプレフィクス候補を使用できる。 • 個々のLispファイルすべての終端に‘provide’呼出を配置すること。*note Named Features::を参照のこと。 • 事前に他の特定のLispプログラムのロードを要するファイルはファイル先 頭のコメントでそのように告げるべきである。また、それらが確実にロー ドされるように‘require’を使用すること。*note Named Features::を参照 のこと。 • ファイルFOOが別のファイルBAR内で定義されたマクロを使用するが、BAR内 の他の関数や変数を何も使用しない場合にはFOOに以下の式を含めること: (eval-when-compile (require 'BAR)) これはFOOのバイトコンパイル直前にBARをロードするようEmacsに告げるの で、そのマクロはコンパイル中は利用可能になる。‘eval-when-compile’の 使用によりコンパイル済みバージョンのFOOが_中古_ならBARのロードを避 けられる。これはファイル内の最初のマクロ呼び出しの前に呼び出すこと 。*note Compiling Macros::を参照のこと。 • 実行時に本当に必要でなければ、追加ライブラリーのロードを避けること 。あなたのファイルが単に他のいくつかのライブラリーなしでは機能しな いなら、トップレベルでそのライブラリーを単に‘require’してこれを行う こと。しかしあなたのファイルがいくつかの独立した機能を含み、それら の1つか2つだけが余分なライブラリーを要するなら、トップレベルではな く関連する関数内部への‘require’の配置を考慮すること。または必要時に 余分のライブラリーをロードするために‘autoload’ステートメントを使用 すること。この方法ではあなたのファイルの該当部分を使用しない人は、 余分なライブラリーをロードする必要がなくなる。 • Common Lisp拡張が必要なら古い‘cl’ライブラリーではなく、‘cl-lib’ライ ブラリーを使うこと。‘cl’ライブラリーはクリーンなネームスペースを使 用しない(定義が‘cl-’で始まらない)。パッケージが実行時に‘cl’をロード する場合には、そのパッケージを使用しないユーザーにたいして名前の衝 突を起こすかもしれない。 ‘(eval-when-compile (require 'cl))’で_コンパイル時_に‘cl’を使用する のは問題ない。コンパイラーはバイトコードを生成する前にマクロを展開 するので‘cl’内のマクロを使用するには十分である。ただしこの場合にお いても現代的な‘cl-lib’を使用するほうが良い。 • メジャーモードを定義する際にはメジャーモードの慣習にしたがってほし い。*note Major Mode Conventions::を参照のこと。 • マイナーモードを定義する際にはマイナーモードの慣習にしたがってほし い。*note Minor Mode Conventions::を参照のこと。 • ある関数の目的が特定の条件の真偽を告げることであるなら、(述語である “predicate”を意味する) ‘p’で終わる名前を与えること。その名前が1単語 なら単に‘p’、複数単語なら‘-p’を追加する。例は‘framep’や ‘frame-live-p’。 • ある変数の目的が単一の関数の格納にあるなら、‘-function’で終わる名前 を与えること。ある変数の目的が関数のリストの格納にあるなら(たとえば その変数がフックなら)、フックの命名規約にしたがってほしい。*note Hooks::を参照のこと。 • そのファイルをロードすることによりフックに関数が追加されるなら、 ‘FEATURE-unload-hook’という関数を定義すること。ここでFEATUREはパッ ケージが提供する機能の名前であり、そのような変更をアンドゥするため のフックにする。そのファイルのアンロードに‘unload-feature’を使用す ることにより、この関数が実行されるようになる。*note Unloading::を参 照のこと。 • Emacsのプリミティブにエイリアスを定義するのは悪いアイデアである。か わりに通常は標準の名前を使用すること。エイリアスが有用になるかもし れないケースは後方互換性や可搬性を向上させる場合である。 • パッケージで別のバージョンのEmacsにたいする互換性のためにエイリアス や新たな関数の定義が必要なら、別のバージョンにあるそのままの名前で はなくパッケージのプレフィクスを名前に付加すること。以下はそのよう な互換性問題を多く提供するGnusでの例。 (defalias 'gnus-point-at-bol (if (fboundp 'point-at-bol) 'point-at-bol 'line-beginning-position)) • Emacsのプリミティブの再定義やadviseは悪いアイデアである。これは特定 のプログラムには正しいことを行うが結果として他のプロラムが破壊され るかもしれない。 • 同様にあるLispパッケージで別のLispパッケージ内の関数にadviseするの も悪いアイデアである。 • ライブラリやパッケージでの‘eval-after-load’と ‘with-eval-after-load’の使用を避けること(*note Hooks for Loading::を 参照)。この機能は個人的なカスタマイズを意図している。Lispプログラム 内でこれを使用すると別のLisp内ではそれが見えず、その挙動を変更する ために不明瞭になる。これは別のパッケージ内の関数へのadviseと同様に デバッグの障害になる。 • Emacsの標準的な関数やライブラリープログラムの何かをファイルが置換す るなら、そのファイル冒頭の主要コメントでどの関数が置換されるか、置 換によりオリジナルと挙動がどのように異なるかを告げること。 • 関数や変数を定義するコンストラクターは関数ではなくマクロにして名前 は‘define-’で始まること。そのマクロは定義される名前を1つ目の引数で 受け取ること。これは自動的に定義を探す種々のツールの助けとなる。マ クロ自身の中でその名前を構築するのは、それらのツールを混乱させるの で避けること。 • 別のいくつかのシステムでは‘*’が先頭や終端にある変数名を選択する慣習 がある。Emacs Lispではその慣習を使用しないので、あなたのプログラム 内でそれを使用しないでほしい(Emacsでは特別な目的をもつバッファーだ けにそのような名前を使用する)。すべてのライブラリーが同じ慣習を使用 するなら人はEmacsがより整合性があることを見い出すだろう。 • Emacs Lispソースファイルのデフォルトのファイルコーディングシステム はUTFである(*note Text Representations::を参照)。あなたのプログラム がUTF-8_以外_の文字を含むような稀なケースでは、ソースファイル内の ‘-*-’行かローカル変数リスト内で適切なコーディングシステムを指定する こと。*note Local Variables in Files: (emacs)File Variables.を参照 のこと。 • デフォルトのインデントパラメーターでファイルをインデントすること。 • 自分で行に閉カッコを配置するのを習慣としてはならない。Lispプログラ マーはこれに当惑させられる。 • コピーを配布する場合は著作権表示と複製許可表示を配置してほしい。 *note Library Headers::を参照のこと。 ---------- Footnotes ---------- (1) Common Lispスタイルのパッケージシステムの恩恵はコストを上回るとは 考えられない。 D.2 キーバインディングの慣習 ============================ • Dired、Info、Compilation、Occurなどの多くのメジャーモードでは“ハイ パーリンク”を含む読み取り専用テキストを処理するようデザインされてい る。そのようなメジャーモードはリンクをフォローするように‘mouse-2’と を再定義すること。そのリンクが‘mouse-1-click-follows-link’にし たがうように‘follow-link’条件もセットアップすること。*note Clickable Text::を参照のこと。そのようなクリック可能リンクを実装す る簡便な手法については*note Buttons::を参照のこと。 • Lispプログラム内のキーとして‘C-c LETTER’を定義してはならない。 ‘C-c’とアルファベット(大文字小文字の両方)からなるシーケンスはユーザ ー用に予約済みである。これらはユーザー用として*唯一*予約されたシー ケンスなので阻害してはならない。 すべてのメジャーモードがこの慣習を尊重するよう変更するには多大な作 業を要する。この慣習を捨て去ればそのような作業は不要になりユーザー は不便になるだろう。この慣習を遵守してほしい。 • 修飾キーなしのからまでのファンクションキーもユーザー定義用 に予約済み。 • 後にコントロールキーか数字が続く‘C-c’シーケンスはメジャーモード用に 予約済みである。 • 後に‘{’、‘}’、‘<’、‘>’、 ‘:’、‘;’が続く‘C-c’シーケンスもメジャーモ ード用に予約済み。 • 後に他のASCII区切り文字やシンボル文字が続く‘C-c’シーケンスはマイナ ーモードに割り当てられている。メジャーモード内でのそれらの使用は絶 対禁止ではないが、もしそれを行えばそのメジャーモードがマイナーモー ドにより時々シャドーされるかもしれない。 • 後にプレフィクス文字(‘C-c’を含む)が続く‘C-h’をバインドしてはならな い。‘C-h’をバインドしなければ、そのプレフィクス文字をもつサブコマン ドをリストするためのヘルプ文字として自動的に利用可能になる。 • 別のが後に続く場合を除きで終わるキーシーケンスをバインド してはならない(つまり‘ ’で終わるキーシーケンスのバインド はOK)。 このルールの理由は任意のコンテキストにおける非プレフィクスであるよ うなのバインディングは、そのコンテキストにおいてファンクション キーとなるようなエスケープシーケンスの認識を阻害するからである。 • 同様には一般的にはキーシーケンスのキャンセルに使用されるので、 で終わるキーシーケンスをバインドしてはならない。 • 一時的なモードやユーザーが出入り可能な状態のような動作は、すべてエ スケープ手段として‘ ’か‘ ’を定義すること 。 通常のEmacsコマンドを受け入れる状態、より一般的には後にファンクショ ンキーか矢印キーが続く内のような状態は潜在的な意味をもつので ‘ ’を定義してはならない。なぜならそれはの後のエスケ ープシーケンスの認識を阻害するからである。これらの状態においては、 エスケープ手段として‘ ’を定義すること。それ以外なら かわりに‘ ’を定義すること。 D.3 Emacsプログラミングのヒント =============================== 以下の慣習にしたがうことによりあなたのプログラムが実行時によりEmacsに適 合するようになります。 • プログラム内で‘next-line’や‘previous-line’を使用してはならない。ほ とんど常に‘forward-line’のほうがより簡便であり、より予測可能かつ堅 牢である。*note Text Lines::を参照のこと。 • あなたのプログラム内でマークのセットが意図した機能でないなら、マー クをセットする関数を呼び出してはならない。マークはユーザーレベルの 機能なので、ユーザーの益となる値を提供する場合を除きマークの変更は 間違いである。*note The Mark::を参照のこと。 特に以下の関数は使用しないこと: • ‘beginning-of-buffer’、‘end-of-buffer’ • ‘replace-string’、‘replace-regexp’ • ‘insert-file’、‘insert-buffer’ インタラクティブなユーザーを意図した別の機能がないのにポイントの移 動、特定の文字列の置換、またはファイルやバッファーのコンテンツを挿 入したいだけなら単純な1、2行のLispコードでそれらの関数を置き換えら れる。 • ベクターを使用する特別な理由がある場合を除きベクターではなくリスト を使用すること。Lispではベクターよりリストを操作する機能のほうが多 く、リストを処理するほうが通常は簡便である。 要素の挿入や削除がなく(これはリストだけで可能)、ある程度のサイズが あって、(先頭か末尾から検索しない)ランダムアクセスがあるテーブルで はベクターが有利。 • エコーエリア内にメッセージを表示する推奨方法は‘princ’ではなく ‘message’関数。*note The Echo Area::を参照のこと。 • エラーコンディションに遭遇したときは関数‘error’ (または‘signal’)を 呼び出すこと。関数‘error’はリターンしない。*note Signaling Errors::を参照のこと。 エラーの報告に‘message’、‘throw’、‘sleep-for’、‘beep’を使用しないこ と。 • エラーメッセージは大文字で始まり、ピリオドで終わらないこと。 • ミニバッファー内で‘yes-or-no-p’か‘y-or-n-p’で答えを求める質問を行う 場合には大文字で始めて‘? ’で終わること。 • ミニバッファーのプロンプトでデフォルト値を示すときは、カッコ内に単 語‘default’を配置すること。これは以下のようになる: 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’指定を使用する際にはコマンドを繰り返すと きの引数値の再計算にたいして特別な段取りを行うので、このような注意 事項を採用する必要はない。 • 実行に長時間を要する多くのコマンドは開始時に‘Operating...’、完了時 に‘Operating...done’のような何らかのメッセージを表示すること。これ らのメッセージのスタイルは‘...’の周囲に_スペース_を置かず、‘done’の 後に_ピリオド_を置かないよう一定に保ってほしい。そのようなメッセー ジを生成する簡便な方法は*note Progress::を参照のこと。 • 再帰編集の使用を避けること。かわりにRmailの‘e’コマンドが行うように 、元のローカルキーマップに戻るよう定義したコマンドを含んだ新たなロ ーカルキーマップを使用するか、単に別のバッファーにスイッチしてユー ザーが自身で戻れるようにすること。*note Recursive Editing::を参照の こと。 D.4 コンパイル済みコードを高速化ためのヒント ============================================ 以下はバイトコンパイル済みLispプログラムの実行速度を改善する方法です。 • 時間がどこで消費されているか見つかるためにプログラムのプロファイル を行う。*note Profiling::を参照のこと。 • 可能なら常に再帰ではなく繰り返しを使用する。Emacs Lispではコンパイ ル済み関数が別のコンパイル済み関数を呼び出すときでさえ関数呼び出し は低速である。 • プリミティブのリスト検索関数‘memq’、‘member’、‘assq’、‘assoc’は明示 的な繰り返しより更に高速である。これらの検索プリミティブを使用でき るようにデータ構造を再配置することにも価値が有り得る。 • 特定のビルトイン関数は通常の関数呼び出しの必要を回避するようにバイ トコンパイル済みコードでは特別に扱われる。別の候補案のかわりにこれ らの関数を使用するのは良いアイデアである。コンパイラーにより特別に 扱われる関数かどうかを確認するには‘byte-compile’プロパティを調べれ ばよい。そのプロパティが非‘nil’ならその関数は特別に扱われる。 たとえば以下を入力すると‘aref’が特別にコンパイルされえることが示さ れる(*note Array Functions::を参照): (get 'aref 'byte-compile) ⇒ byte-compile-two-args この場合(および他の多くの場合)には、最初に‘byte-compile’プロパティ を定義する‘bytecomp’ライブラリーをロードしなければならない。 • プログラム内で実行時間のある程度を占める小さい関数を呼び出すなら関 数をinlineにする。これにより関数呼び出しのオーバーヘッドがなくなる 。関数のinline化はプログラム変更の自由度を減少させるのでユーザーが スピードを気にするに足るほど低速であり、inline化により顕著に速度が 改善されるのでなければ行ってはならない。*note Inline Functions::を 参照のこと。 D.5 コンパイラー警告を回避するためのヒント ========================================== • 以下のようにダミーの‘defvar’定義を追加して未定義のフリー変数に関す るコンパイラーの警告の回避を試みる: (defvar foo) このような定義はファイル内での変数‘foo’の使用にたいしてコンパイラー が警告しないようにする以外に影響はない。 • 同様に‘declare-function’ステートメントを使用して、_定義されるこが既 知_な未定義関数に関するコンパイラーの警告の回避を試みる(*note Declaring Functions::を参照)。 • 特定のファイルから多くの関数と変数を使用する場合には、それらに関す るコンパイラー警告を回避するためにパッケージに‘require’を追加できる 。たとえば、 (eval-when-compile (require 'foo)) • ある関数内で変数をバインドして別の関数内で使用やセットする場合には 、その変数が定義をもたなければ別関数に関してコンパイラーは警告を行 う。しかしその変数が短い名前をもつ場合には、Lispパッケージは短い変 数名を定義するべきではないので定義の追加により不明瞭になるかもしれ ない。行うべき正しい方法はパッケージ内の他の関数や変数に使用されて いる名前プレフィクスで始まるように変数をリネームすることである。 • 警告を回避する最後の手段は通常なら間違いであるが、その使用法では間 違いではないと解っている何かを行う際には‘with-no-warnings’の内側に 置くこと。*note Compiler Errors::を参照のこと。 D.6 ドキュメント文字列のヒント ============================== 以下はドキュメント文字列記述に関するいくつかのヒントと慣習です。コマンド ‘M-x checkdoc-minor-mode’を実行すれば慣習の多くをチェックできます。 • ユーザーが理解することを意図したすべての関数、コマン、変数はドキュ ント文字列をもつこと。 • Lispプログラムの内部的な変数とサブルーチンは同様にドキュメント文字 列をもつことができる。ドキュメント文字列は実行中のEmacs内で非常に僅 かなスペースしか占めない。 • 80列スクリーンのEmacsウィンドウに適合するようにドキュメント文字列を フォーマットすること。ほとんどの行を60文字以下に短くするのは良いア イデアである。最初の行は67文字以下にすること。さもないと‘apropos’の 出力で見栄えが悪くなる。 見栄えがよくなるならそのテキストをフィルできる。Emacs Lispモードは ‘emacs-lisp-docstring-fill-column’で指定された幅にドキュメント文字 列をフィルする。しかしドキュメント文字列の行ブレークを注意深く調整 すればドキュメント文字列の可読性をより向上できることがある。ドキュ メント文字列が長い場合にはセクション間に空行を使用すること。 • ドキュンメント文字列の最初の行は、それ自身が要約となるような1つか 2つの完全なセンテンスから成り立つこと。‘M-x apropos’は最初の行だけ を表示するので、その行のコンテンツが自身で完結していなければ結果の 見栄えは悪くなる。特に最初の行は大文字で始めてピリオドで終わること 。 関数では最初の行は“その関数は何を行うのか?”、変数にたいしては最初の 行は“その値は何を意味するのか?”という問いに簡略に答えること。 ドキュメント文字列を1行に制限しないこと。その関数や変数の使用法の詳 細を説明する必要に応じてその分の行数を使用すること。テキストの残り の部分にたいしても完全なセンテンスを使用してほしい。 • ユーザーが無効化されたコマンドの使用を試みる際には、Emacsはそれのド キュメント文字列の最初のパラグラフ(最初の空行までのすべて)だけを表 示する。もし望むなら、その表示をより有用になるように最初の空行の前 に何の情報を含めるか選択できる。 • 最初の行ではその関数のすべての重要な引数と、関数呼び出しで記述され る順にそれらに言及すること。その関数が多くの引数をもつなら最初の行 でそれらすべてに言及するのは不可能である。この場合にはもっとも重要 な引数を含む最初の引数数個について最初の行で言及すること。 • ある関数のドキュメント文字列がその関数の引数の値に言及する際には、 引数を大文字にした名前が引数の値であるかのように使用すること。つま り関数‘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 ... • ドキュメント文字列内でLispシンボルに言及する際にはcase(大文字小文字 )を絶対に変更しないこと。そのシンボルの名前が‘foo’なら“Foo”ではなく “foo”(“Foo”は違うシンボル)。 これは関数の引数の値の記述ポリシーと反するように見えるかもしれない が矛盾は実際には存在しない。引数の_value_はその関数が値の保持に使用 する_symbol_と同じではない。 これによりセンテンス先頭に小文字を置くことになり、それが煩しいなら センテンス開始がシンボルにならないようにセンテンスを書き換えること 。 • ドキュメント文字列の開始と終了に空白文字を使用しないこと。 • ソースコード内の後続行のテキスト、最初の行と揃うようにドキュメント 文字列の後続行を*インデントしてはならない*。これはソースコードでは 見栄えがよいがユーザーがドキュメトを閲覧する際は奇妙な見栄えになる 。開始のダブルクォーテーションの前のインデントは文字列の一部には含 まれないことを忘れないこと! • ドキュメント文字列がLispシンボルを参照する際には、たとえば ‘`lambda'’のように、それがプリントされるとき(通常は小文字を意味する )のようにcurved single quotes(‘と’)で括ること。例外が2つある。‘t’と ‘nil’は区切り文字で括らない。たとえば‘CODE can be ‘lambda’, nil, or t’。curved single quotesの入力方法は*note (emacs)Quotation Marks::を 参照のこと。 ドキュメント文字列には‘like-this’ではなく`like-this'のようにgrave accent `とapostrophe 'というクォートシンボルによる旧いシングルクォ ーテーションの慣習も使用できる。この旧い慣習はgrave accentと apostropheがミラーイメージであるような、現在では時代遅れとなったデ ィスプレイ用にデザインされている。 いずれかの慣習を使用するドキュメントは、ヘルプバッファーにコピーさ れる際にはユーザーの好みに応じてフォーマットされる。*note Keys in Documentation::を参照のこと。 Helpモードはシングルクォートされたシンボル名がドキュメント文字列で 使用されている際には、それが関数と変数のいずれかの定義をもっていれ ば自動的にハイパーリンクを作成する。これらの機能を使用するために何 か特別なことを行う必要はない。しかしあるシンボルが関数と変数の両方 の定義をもち一方だけを参照したい場合には、そのシンボル名の直前に ‘variable’、‘option’、‘function’、‘command’の単語のいずれかを記述し てそれを指定できる(これらの指示語の識別では大文字小文字に差はない )。たとえば以下を記述すると This function sets the variable `buffer-file-name'. これのハイパーリンクは‘buffer-file-name’の変数のドキュメントだけを 参照して関数のドキュメントは参照しない。 あるシンボルが関数および/または変数の定義をもつがドキュメントしてい るシンボルの使用とそれらが無関係なら、すべてのハイパーリンク作成を 防ぐためにシンボル名の前に単語‘symbol’か‘program’を記述できる。たと えば、 If the argument KIND-OF-RESULT is the symbol `list', this function returns a list of all the objects that satisfy the criterion. これは無関係な関数‘list’のドキュメントにハイパーリンクを作成しない 。 変数ドキュメントがない変数には、通常はハイパーリンクは作成されない 。そのような変数の前に単語‘variable’と‘option’のいずれかを記述すれ ばハイパーリンクの作成を強制できる。 フェイスにたいするハイパーリンクはフェイスの前か後に単語‘face’があ れば作成される。この場合にはたとえそのシンボルが変数や関数として定 義されていてもフェイスのドキュメントだけが表示される。 Infoドキュメントにハイパーリンクを作成するには、‘info node’、‘Info node’、‘info anchor’、‘Info anchor’のいずれかの後Infoのノード(かア ンカー)をシングルクォートして記述する。Infoファイル名のデフォルトは ‘emacs’。たとえば、 See Info node `Font Lock' and Info node `(elisp)Font Lock Basics'. 最後にURLのハイパーリンクを作成するには‘URL’の後にURLをシングルクォ ートして記述する。たとえば、 The home page for the GNU project has more information (see URL `http://www.gnu.org/'). • ドキュメント文字列内に直接キーシーケンスを記述しないこと。かわりに 、それらを表すために‘\\[...]’構文を使用すること。たとえば‘C-f’と記 述するかわりに‘\\[forward-char]’と記述する。Emacsがドキュメント文字 列を表示する際には何であれカレントで‘forward-char’にバインドされた キーに置き換える(これは通常は‘C-f’だがユーザーがキーバインディング を変更していれば何か他の文字かもしれない)。*note Keys in Documentation::を参照のこと。 • メジャーモードのドキュメント文字列ではグローバルマップではなく、そ のモードのローカルマップを参照したいだろう。したがってどのキーマッ プを使用するか指定するために、ドキュメント文字列内で一度‘\\<...>’構 文を使用する。最初に‘\\[...]’を使用する前にこれを行うこと。 ‘\\<...>’の内部のテキストはメジャーモードにたいするローカルキーマッ プを含む変数名であること。 ドキュメント文字列の表示が低速になるので非常に多数回の‘\\[...]’の使 用は実用的ではない。メジャーモードのもっとも重要なコマンドの記述に これを使用して、そのモードの残りのキーマップの表示には‘\\{...}’を使 用する。 • 一貫性を保つために関数のドキュメント文字列の最初のセンテンス内の動 詞は、命令形で表すこと。たとえば“Return the cons of A and B.”、好み によっては“Returns the cons of A and B.”を使用する。通常は最初のパ ラグラフの残りの部分にたいして同様に行っても見栄えがよい。各センテ ンスが叙実的で適切な主題をもつなら後続のパラグラフの見栄えはよくな る。 • yes-or-no述語であるような関数のドキュメント文字列は、何が真を構成す るか明示的に示すために、“Return t if”のような単語で始まること。単語 “return”は小文字の“t”で開始される幾分紛らわしい可能性のあるセンテン スを避ける。 • ドキュメント文字列内の開カッコで始まる行は以下のように開カッコの前 にバックスラッシュを記述する: The argument FOO can be either a number \(a buffer position) or a string (a file name). これはその開カッコがdefunの開始として扱われることを防ぐ(*note Defuns: (emacs)Defuns.を参照)。 • ドキュメント文字列は受動態ではなく能動態、未来形ではなく現在形で記 述すること。たとえば“A list containing A and B will be returned.”で はなく、“Return a list containing A and B.”と記述すること。 • 不必要な“cause”(や同等の単語)の使用を避けること。“Cause Emacs to display text in boldface”ではなく、単に“Display text in boldface”と 記述すること。 • 多くの人にとってなじみがなくtypoと間違えるであろうから、“iff”(“if and only if”を意味する数学用語)の使用を避けること。ほとんどの場合に は、その意味は単なる“if”で明快である。それ以外ではその意味を伝える 代替えフレーズを探すよう試みること。 • 特定のモードや状況でのみコマンドに意味がある際にはドキュメント文字 列内でそれに言及すること。たとえば‘dired-find-file’のドキュメントは : In Dired, visit the file or directory named on this line. • ユーザーがセットしたいと望むかもしれないオプションを表す変数を定義 する際には‘defcustom’を使用すること。*note Defining Variables::を参 照のこと。 • yes-or-noフラグであるような変数のドキュメント文字列は、すべての非 ‘nil’値が等価であることを明確にして、‘nil’と非‘nil’が何を意味するか を明示的に示すために“Non-nil means”のような単語で始めること。 D.7 コメント記述のヒント ======================== コメントにたいして以下の慣習を推奨します: ‘;’ 1つのセミコロン‘;’で始まるコメントはソースコードの右側の同じ列にす べて揃えられる。そのようなコメントは通常はその行のコードがどのよう に処理を行うかを説明する。たとえば: (setq base-version-list ; There was a base (assoc (substring fn 0 start-vn) ; version to which file-version-assoc-list)) ; this looks like ; a subversion. ‘;;’ 2つのセミコロン‘;;’で始まるコメントはコードと同じインデントレベルで 揃えられる。そのようなコメントは通常はその後の行の目的や、その箇所 でのプログラムの状態を説明する。たとえば: (prog1 (setq auto-fill-function ... ... ;; Update mode line. (force-mode-line-update))) わたしたちは通常は関数の外側のコメントにも2つのセミコロンを使用する 。 ;; This Lisp code is run in Emacs when it is to operate as ;; a server for other processes. 関数がドキュメント文字列をもたなければ、かわりにその関数の直前にそ の関数が何を行うかと、正しく呼び出す方法を説明する2つのセミコロンの コメントをもつこと。各引数の意味と引数で可能な値をその関数が解釈す る方法を正確に説明すること。しかしそのようなコメントはドキュメント 文字列に変換するほうがはるかに優れている。 ‘;;;’ 3つのセミコロン‘;;;’デ始まるコメントは左マージンから始まる。わたし たちはOutlineマイナーモードのheading(ヘッダー)とみなされるべきコメ ントにそれらを使用している。デフォルトでは少なくとも(後に1つの空白 文字と非空白文字が続く)3つのセミコロンはheadingとみなして、2つ以下 のセミコロンで始まるものはheadingとみなさない。歴史的に3つのセミコ ロンのコメントは関数内での行のコメントアウトに使用されてきたがこの 使用は推奨しない。 関数全体をコメントアウトするときは2つのセミコロンを使用する。 ‘;;;;’ 4つのセミコロン‘;;;;’で始まるコメントは左マージンに揃えられプログラ ムのメジャーセクションのheadingに使用される。たとえば: ;;;; The kill ring 一般的に言うとコマンド‘M-;’ (‘comment-dwim’)は適切なタイプのコメントを自 動的に開始するか、セミコロンの数に応じて既存のコメントを正しい位置にイン デントします。*note Manipulating Comments: (emacs)Comments.を参照してく ださい。 D.8 Emacsライブラリーのヘッダーの慣習 ===================================== Emacsにはセクションに分割してそれの記述者のような情報を与えるために、 Lispライブラリー内で特別なコメントを使用する慣習があります。それらのアイ テムにたいして標準的なフォーマットを使用すれば、ツール(や人)が関連する情 報を抽出するのが簡単になります。このセクションでは以下の例を出発点にこれ らの慣習を説明します。 ;;; foo.el --- Support for the Foo programming language ;; Copyright (C) 2010-2016 Your Name ;; Author: Your Name ;; Maintainer: Someone Else ;; Created: 14 Jul 2010 ;; Keywords: languages ;; Homepage: http://example.com/foo ;; This file is not part of GNU Emacs. ;; This file is free software... ... ;; along with this file. If not, see . 一番最初の行は以下のフォーマットをもつべきです: ;;; FILENAME --- DESCRIPTION この説明は1行に収まる必要があります。そのファイルに‘-*-’指定が必要なら DESCRIPTIONの後に配置してください。これにより最初の行が長くなりすぎるよ うなら、そのファイル終端でLocal Variablesセクションを使用してください。 著作権表示には、(あなたがそのファイルを記述したなら)通常はあなたの名 前をリストします。あなたの作業の著作権を主張する雇用者がいる場合には、か わりに彼らをリストする必要があるかもしれません。Emacsディストリビューシ ョンにあなたのファイルが受け入れられていなければ、著作権者がFree Software Foundation(またはそのファイルがGNU Emacsの一部)だと告げないでく ださい。著作権とライセンス通知の形式に関するより詳細な情報はthe guide on the GNU website (http://www.gnu.org/licenses/gpl-howto.html)を参照してく ださい。 著作権表示の後は、それぞれが‘;; HEADER-NAME:’で始まる複数の“ヘッダー コメント(header comment)”を記述します。以下は慣習的に利用できる HEADER-NAMEのテーブルです: ‘Author’ この行は少なくともそのライブラリーの主要な作者の名前とemailアドレス を示す。複数の作者がいる場合には前に‘;;’とタブか少なくとも2つのスペ ースがある継続行で彼らをリストする。わたしたちは‘<...>’という形式で 連絡用emailアドレスを含めることを推奨する。たとえば: ;; Author: Your Name ;; Someone Else ;; Another Person ‘Maintainer’ このヘッダーはAuthorヘッダーと同じフォーマット。これは現在そのファ イルを保守(バグレポートへの応答等)をする人(か人々)をリストする。 Maintainerの行がなければAuthorフィールドの人(人々)がMaintainerとみ なされる。Emacs内のいくつかのファイルはMaintainerに‘FSF’を使用して いる。これはファイルにたいしてオリジナル作者がもはや責任をもってお らずEmacsの一部として保守されていることを意味する。 ‘Created’ このオプションの行はファイルのオリジナルの作成日付を与えるもので歴 史的な興味のためだけに存在する。 ‘Version’ 個々のLispプログラムにたいしてバージョン番号を記録したいならこの行 に配置する。Emacsとともに配布されたLispファイルはEmacsのバージョン 番号自体が同じ役割を果たすので一般的には‘Version’ヘッダーをもたない 。複数ファイルのコレクションを配布する場合には、各ファイルではなく 主となるファイルにバージョンを記述することを推奨する。 ‘Keywords’ この行はヘルプコマンド‘finder-by-keyword’にたいするキーワードをリス トする。意味のあるキーワードのリストを確認するためにこのコマンドを 使用してほしい。コマンド‘M-x checkdoc-package-keywords RET’は ‘finder-known-keywords’にないすべてのキーワードを探して表示する。変 数‘checkdoc-package-keywords-flag’に非‘nil’をセットするとcheckdocコ マンドはチェックにキーワード検証を含める。 このフィールドはトピックでパッケージを探す人が、あなたのパッケージ を見つける手段となる。キーワードを分割するにはスペースとカンマの両 方を使用できる。 人はしばしばこのフィールドを単にFinder(訳注: ‘finder-by-keyword’が オープンするバッファー)に関連したキーワードではなくパッケージを説明 する任意のキーワードを記述する箇所だとみなすのは不運なことだ。 ‘Homepage’ この行はライブラリーのホームページを示す。 ‘Package-Version’ ‘Version’がパッケージマネージャーによる使用に適切でなければ、パッケ ージは‘Package-Version’を定義でき、かわりにこれが使用される。これは ‘Version’がRCSや‘version-to-list’でパース不能な何かであるようなら手 軽である。*note Packaging Basics::を参照のこと。 ‘Package-Requires’ これが存在する場合にはカレントパッケージが正しく動作するために依存 するパッケージを示す。*note Packaging Basics::を参照のこと。これは (パッケージの完全なセットがダウンロードされることを確実にするために )ダウンロード時と、(すべての依存パッケージがあるときだけパッケージ がアクティブになることを確実にするために)アクティブ化の両方でパッケ ージマネージャーにより使用される。 これのフォーマットはリストのリスト。サブリストそれぞれの‘car’はパッ ケージの名前(シンボル)、‘cadr’は許容できる最小のバージョン番号(文字 列)。たとえば: ;; Package-Requires: ((gnus "1.0") (bubbles "2.7.2")) パッケージのコードは自動的に、実行中のEmacsのカレントのバージョン番 号をもつ‘emacs’という名前のパッケージを定義する。これはパッケージが 要求するEmacsの最小のバージョンに使用できる。 ほぼすべてのLispライブラリーは‘Author’と‘Keywords’のヘッダーコメント 行をもつべきです。適切なら他のものを使用してください。ヘッダー行内で別の ヘッダー行の名前も使用できます。これらは標準的な意味をもたないので害にな ることを行うことはできません。 わたしたちはライブラリーファイルのコンテンツを分割するために追加の提 携コメントを使用します。これらは空行で他のものと分離されている必要があり ます。以下はそれらのテーブルです: ‘;;; Commentary:’ これはライブラリーが機能する方法を説明する、概論コメントを開始する 。これは複製許諾の直後にあり‘Change Log’、‘History’、‘Code’のコメン ト行で終端されていること。このテキストはFinderパッケージで使用され るのでそのコンテキスト内で有意であること。 ‘;;; Change Log:’ これは時間とともにそのファイルに加えられたオプションの変更ログを開 始する。このセクションに過剰な情報を配置してはならない。(Emacsが行 うように)バージョンコントロールシステムの詳細ログや個別の ‘ChangeLog’ファイルに留めるほうがよい。‘History’は‘Change Log’の代 替え。 ‘;;; Code:’ これはプログラムの実際のコードを開始する。 ‘;;; FILENAME ends here’ これは“フッター行(footer line)”。これはそのファイルの終端にある。こ れの目的はフッター行の欠落から、人がファイルの切り詰められたバージ ョンを検知することを可能にする。 Appendix E GNU Emacsの内部 ************************** このチャプターでは実行可能なEmacs実行可能形式を事前ロードされたLispライ ブラリーとともにダンプする方法、ストレージが割り当てられる方法、および Cプログラマーが興味をもつかもしれないGNU Emacsの内部的な側面のいくつかを 説明します。 E.1 Emacsのビルド ================= このセクションではEmacs実行可能形式のビルドに関するステップの説明をしま す。makefileがこれらすべてを自動的に行うので、Emacsをビルドやインストー ルをするためにこの題材を知る必要はありません。この情報はEmacs開発者に適 しています。 EmacsのビルドにはGNU Makeのバージョン3.81以降が必要です。 ‘src’ディレクトリー内のCソースファイルをコンパイルすることにより、 ‘temacs’と呼ばれる実行可能形式ファイルが生成されます。これは“bare impure Emacs(裸で不純なEmacs)”とも呼ばれます。これにはEmacs Lispインタープリタ ーとI/Oルーチンが含まれますが編集コマンドは含まれません。 コマンド‘temacs -l loadup’は‘temacs’を実行して‘loadup.el’をロードする ように計らいます。‘loadup’ライブラリーは通常のEmacs編集環境をセットアッ プする追加のLispライブラリーをロードします。このステップの後にはEmacs実 行可能形式は“bare(裸)”ではなくなります。 標準的なLispファイルのロードには若干の時間を要するので、ユーザーが直 接‘temacs’実行可能形式を実行することは通常はありません。そのかわり、 Emacsビルドの最終ステップとしてコマンド‘temacs -batch -l loadup dump’が 実行されます。特別な引数‘dump’により‘temacs’は‘emacs’と呼ばれる実行可能 形式のプログラムにダンプされます。これには標準的なLispファイルがすべて事 前ロードされています(引数‘-batch’は‘temacs’がその端末上でデータの初期化 を試みることを防げるので端末情報のテーブルはダンプされたEmacsでは空にな る)。 ダンプされた‘emacs’実行可能形式(“純粋”なEmacsとも呼ばれる)がインスト ールされるEmacsになります。変数‘preloaded-file-list’にはダンプ済み Emacsに事前ロードされるLispファイルのリストが格納されています。新たなオ ペレーティングシステムにEmacsをポートする際に、そのOSがダンプを実装して いなければEmacsは起動時に毎回‘loadup.el’をロードしなければなりません。 ‘site-load.el’という名前のライブラリーを記述することにより、事前ロー ドするファイルを追加指定できます。追加するファイルを保持するために純粋 (pure)なスペースNバイトを追加するように、以下の定義 #define SITELOAD_PURESIZE_EXTRA N でEmacsをリビルドする必要があるでしょう。‘src/puresize.h’を参考にしてく ださい(十分大きくなるまで20000ずつ増加させる)。しかし追加ファイルの事前 ロードの優位はマシンの高速化により減少します。現代的なマシンでは通常はお 勧めしません。 ‘loadup.el’が‘site-load.el’を読み込んだ後に‘Snarf-documentation’を呼 び出すことにより、それらが格納された場所のファイル‘etc/DOC’内にあるプリ ミティブと事前ロードされる関数(と変数)のドキュメント文字列を探します (*note Accessing Documentation: Definition of Snarf-documentation.を参照 )。 ‘site-init.el’という名前のライブラリー名に配置することにより、ダンプ 直前に実行する他のLisp式を指定できます。このファイルはドキュメント文字列 を見つけた後に実行されます。 関数や変数の定義を事前ロードしたい場合には、それを行うために3つの方法 があります。それらにより定義ロードしてその後のEmacs実行時にドキュメント 文字列をアクセス可能にします: • ‘etc/DOC’の生成時にそれらのファイルをスキャンするよう計らい ‘site-load.el’でロードする。 • ファイルを‘site-init.el’でロードしてEmacsインストール時にLispファイ ルのインストール先ディレクトリーにファイルをコピーする。 • それらの各ファイルでローカル変数として ‘byte-compile-dynamic-docstrings’に‘nil’値を指定して ‘site-load.el’か‘site-init.el’でロードする(この手法にはEmacsが毎回 そのドキュメント文字列用のスペースを確保するという欠点がある)。 通常の未変更のEmacsでユーザーが期待する何らかの機能を変更するような何 かを‘site-load.el’や‘site-init.el’内に配置することはお勧めしません。あな たのサイトで通常の機能をオーバーライドしなければならないと感じた場合には 、‘default.el’でそれを行えばユーザーが望む場合にあなたの変更をオーバーラ イドできます。*note Startup Summary::を参照してください。 ‘site-load.el’か‘site-init.el’のいずれかが‘load-path’を変更する場合には 変更はダンプ後に失われます。*note Library Search::を参照してください。 ‘load-path’を永続的に変更するには‘configure’の‘--enable-locallisppath’オ プションを指定してください。 事前ロード可能なパッケージでは、その後のEmacsスタートアップまで特定の 評価の遅延が必要(または便利)なことがあります。そのようなケースの大半はカ スタマイズ可能な変数の値に関するものです。たとえば‘tutorial-directory’は 事前ロードされる‘startup.el’内で定義される変数です。これのデフォルト値は ‘data-directory’にもとづいてセットされます。この変数はEmacsダンプ時では なくスタート時に‘data-directory’の値を必要とします。なぜならEmacs実行可 能形式はダンプされたものなので、恐らく異なる場所にインストールされるから です。 -- Function: custom-initialize-delay symbol value この関数は次回のEmacs開始までSYMBOLの初期化を遅延する。通常はカスタ マイズ可能変数の‘:initialize’プロパティとしてこの関数を指定すること により使用する(引数VALUEはフォームCustom由来の互換性のためだけに提 供されており使用しない)。 ‘custom-initialize-delay’が提供するより一般的な機能を要する稀なケース では‘before-init-hook’を使用できます(*note Startup Summary::を参照)。 -- Function: dump-emacs to-file from-file この関数はEmacsのカレント状態を実行可能ファイルTO-FILEにダンプする 。これはFROM-FILE (通常はファイル‘temacs’)からシンボルを取得する。 すでにダンプ済みのEmacs内でこの関数を使用する場合には‘-batch’で Emacsを実行しなければならない。 E.2 純粋ストレージ ================== Emacs Lispはユーザー作成Lispオブジェクトにたいして、“通常ストレージ (normal storage)”と“純粋ストレージ(pure storage)”という2種のストレージを もちます。通常ストレージはEmacsセッションが維持される間に新たにデータが 作成される場所です。純粋ストレージは事前ロードされた標準Lispファイル内の 特定のデータのために使用されます。このデータは実際のEmacs使用中に決して 変更されるべきではないデータです。 純粋ストレージは‘temacs’が標準的な事前ローLispライブラリーのロード中 にのみ割り当てられます。ファイル‘emacs’ではこのメモリースペースは読み取 り専用とマークされるのでマシン上で実行中のすべてのEmacsジョブで共有でき ます。純粋ストレージは拡張できません。Emacsのコンパイル時に固定された量 が割り当てられて、それが事前ロードされるライブラリーにたいして不足なら ‘temacs’はそれに収まらない部分を動的メモリーに割り当てます。結果イメージ は動作するでしょうがこの状況ではメモリーリークとなるのでガーベージコレク ション(*note Garbage Collection::を参照)は無効です。そのような通常なら発 生しないオーバーフローは、あなたが事前ロードライブラリの追加や標準的な事 前ロードライブラリに追加を試みないかぎり発生しません。Emacsはオーバーロ ードの開始時にオーバーロードに関する警告を表示するでしょう。これが発生し たらファイル‘src/puresize.h’内のコンパイルパラメーターを ‘SYSTEM_PURESIZE_EXTRA’を増やしてEmacsをリビルドする必要があります。 -- Function: purecopy object この関数は純粋ストレージにOBJECTのコピーを作成してリターンする。こ れは同じ文字で新たに文字列を作成することにより文字列をコピーするが 、純粋ストレージではテキストプロパティはない。これはベクターとコン スセルのコンテンツを再帰的にコピーする。シンボルのような他のオブジ ェクトのコピーは作成しないが未変更でリターンする。マーカーのコピー を試みるとエラーをシグナルする。 この関数はEmacsのビルド中とダンプ中を除き何もしない。通常は事前ロー ドされるLispファイル内でのみ呼び出される。 -- Variable: pure-bytes-used この変数の値は、これまでに割り当てられた純粋ストレージのバイト数。 ダンプされたEmacsでは通常は利用可能な純粋ストレージの総量とほとんど 同じであり、もしそうでないならわたしたちは事前割り当てをもっと少な くするだろう。 -- Variable: purify-flag この変数は‘defun’が純粋ストレージにその関数定義のコピーを作成するべ きか否かを判断する。これが非‘nil’ならその関数の定義は純粋ストレージ にコピーされる。 このフラグはEmacsのビルド用の基本的な関数の初回ロード中は‘t’となる 。実行可能形式としてEmacsをダンプすることにより、ダンプ前後の実際の 値とは無関係に常にこの変数に‘nil’が書き込まれる。 実行中のEmacsでこのフラグを変更しないこと。 E.3 ガーベージコレクション ========================== プログラムがリストを作成するときや、(ライブライのロード等により)ユーザー が新しい関数を定義する際には、そのデータは通常ストレージに配置されます。 通常ストレージが少なくなるとEmacsはもっとメモリーを割り当てるようにオペ レーティングシステムに要求します。シンボル、コンスセル、小さいベクター、 マーカー等のような別のタイプのLispオブジェクトはメモリー内の個別のブロッ クに隔離されます(大きいベクター、長い文字列、バッファー、および他の特定 の編集タイプは非常に巨大であり1つのオブジェクトにたいして個別のブロック が割り当てられて、小さな文字列は8kバイトのブロック、小さいベクターは4kバ イトのブロックにパックされる)。 基本的なベクターではないウィンドウ、バッファー、フレームがあたかもベ クターであるかのように管理されています。対応するCデータ構造体には‘struct vectorlike_header’フィールドが含まれていて、そのメンバー‘size’には‘enum pvec_type’で列挙されたサブタイプ、その構造体が含む‘Lisp_Object’フィール ドの数に関する情報、および残りのデータのサイズが含まれます。この情報はオ ブジェクトのメモリーフットプリントの計算に必要であり、ベクターブロックの 繰り返し処理の際のベクター割り当てコードにより使用されます。 しばらくの間いくつかのストレージを使用して、(たとえば)バッファーの killやあるオブジェクトを指す最後のポインターの削除によりそれを解放するの は非常に一般的です。この放棄されたストレージを再利用するためにEmacsは“ガ ーベージコレクター(garbage collector)”を提供します。ガーベージコレクター は、いまだLispプログラムからアクセス可能なすべてのLispオブジェクトを検索 、マークすることにより動作します。これを開始するにはすべてのシンボル、そ れらの値と関連付けられている関数定義、現在スタック上にあるすべてのデータ をアクセス可能であると仮定します。別のアクセス可能オブジェクトを介して間 接的に到達できるすべてのオブジェクトもアクセス可能とみなされます。 マーキングが終了してもマークされないオブジェクトはすべてガーベージ (garbage: ごみ)です。Lispプログラムかユーザーの行為かに関わらず、それら に到達する手段はもはや存在しないので参照することは不可能です。誰もそれを 失うことはないので、それらのスペースは再利用されることになります。ガーベ ージコレクターの2つ目ののフェーズ(sweep: スイープ、一掃)ではそれらの再利 用を計らいます。 スイープフェーズは将来の割り当て用に、シンボルやマーカーと同様に未使 用のコンスセルを“フリーリスト(free list)”上に配置します。これはアクセス 可能な文字列は少数の8kブロックを占有するように圧縮して、その後に他の8kブ ロックを解放します。ベクターブロックから到達不可能はベクターは可能なかぎ り最大のフリーエリアを作成するために統合して、フリーエリアが完全な4kブロ ックに跨がるようならブロックは解放されます。それ以外ならフリーエリアはフ リーリスト配列に記録されます。これは各エントリーが同サイズのエリアのフリ ーリストに対応します。巨大なベクター、バッファー、その他の巨大なオブジェ クトは個別に割り当てと解放が行われます。 Common Lispに関する注意: 他のLispと異なりGNU Emacs Lispはフリーリス トが空のときにガーベージコレクターを呼び出さない。かわりに単にオペ レーティングシステムに更なるストレージの割り当てを要求して、 ‘gc-cons-threshold’バイトを使い切るまで処理を継続する。 これは特定のLispプログラムの範囲の実行直前に明示的にガーベージコレ クターを呼び出せば、その範囲の実行中はガーベージコレクターが実行さ れないだろうと確信できることを意味する(そのプログラム範囲が2回目の ガーベージコレクションを強制するほど多くのスペースを使用しないとい う前提)。 -- Command: garbage-collect このコマンドはガーベージコレクションを実行して使用中のスペース量の 情報をリターンする(前回のガーベージコレクション以降に ‘gc-cons-threshold’バイトより多いLispデータを使用した場合には自然に ガーベージコレクションが発生することもあり得る)。 ‘garbage-collect’は使用中のスペース量の情報をリストでリターンする。 これの各エントリーは‘(NAME SIZE USED)’という形式をもつ。このエント リーでNAMEはそのエントリーが対応するオブジェクトの種類を記述するシ ンボル、SIZEはそれが使用するバイト数、USEDはヒープ内で生きているこ とが解ったオブジェクトの数、オプションのFREEは生きていないがEmacsが 将来の割り当て用に保持しているオブジェクトの数。全体的な結果は以下 のようになる: ((conses CONS-SIZE USED-CONSES FREE-CONSES) (symbols SYMBOL-SIZE USED-SYMBOLS FREE-SYMBOLS) (miscs MISC-SIZE USED-MISCS FREE-MISCS) (strings STRING-SIZE USED-STRINGS FREE-STRINGS) (string-bytes BYTE-SIZE USED-BYTES) (vectors VECTOR-SIZE USED-VECTORS) (vector-slots SLOT-SIZE USED-SLOTS FREE-SLOTS) (floats FLOAT-SIZE USED-FLOATS FREE-FLOATS) (intervals INTERVAL-SIZE USED-INTERVALS FREE-INTERVALS) (buffers BUFFER-SIZE USED-BUFFERS) (heap UNIT-SIZE TOTAL-SIZE FREE-SIZE)) 以下は例: (garbage-collect) ⇒ ((conses 16 49126 8058) (symbols 48 14607 0) (miscs 40 34 56) (strings 32 2942 2607) (string-bytes 1 78607) (vectors 16 7247) (vector-slots 8 341609 29474) (floats 8 71 102) (intervals 56 27 26) (buffers 944 8) (heap 1024 11715 2678)) 以下は各要素を説明するためのテーブル。最後の‘heap’エントリーはオプ ションであり、背景にある‘malloc’実装が‘mallinfo’関数を提供する場合 のみ与えられることに注意。 CONS-SIZE コンスセルの内部的サイズ(‘sizeof (struct Lisp_Cons)’)。 USED-CONSES 使用中のコンスセルの数。 FREE-CONSES オペレーティングシステムから取得したスペースにあるがカレントで 未使用のコンスセルの数。 SYMBOL-SIZE シンボルの内部的サイズ(‘sizeof (struct Lisp_Symbol)’)。 USED-SYMBOLS 使用中のシンボルの数。 FREE-SYMBOLS オペレーティングシステムから取得したスペースにあるがカレントで 未使用のシンボルの数。 MISC-SIZE 雑多なエンティティーの内部的なサイズ。‘sizeof (union Lisp_Misc)’は‘enum Lisp_Misc_Type’に列挙された最大タイプのサイ ズ。 USED-MISCS 使用中の雑多なエンティティーの数。これらのエンティティーにはマ ーカー、オーバーレイに加えて、ユーザーにとって不可視な特定のオ ブジェクトが含まれる。 FREE-MISCS オペレーティングシステムから取得したスペースにあるがカレントで 未使用の雑多なオブジェクトの数。 STRING-SIZE 文字列ヘッダーの内部的サイズ(‘sizeof (struct Lisp_String)’)。 USED-STRINGS 使用中の文字列ヘッダーの数。 FREE-STRINGS オペレーティングシステムから取得したスペースにあるがカレントで 未使用の文字列ヘッダーの数。 BYTE-SIZE これは利便性のために使用されるもので‘sizeof (char)’と同じ。 USED-BYTES すべての文字列データの総バイト数。 VECTOR-SIZE ベクターヘッダーの内部的サイズ(‘sizeof (struct Lisp_Vector)’)。 USED-VECTORS ベクターブロックから割り当てられたベクターブロック数。 SLOT-SIZE ベクタースロットの内部的なサイズで常に‘sizeof (Lisp_Object)’と 等しい。 USED-SLOTS 使用されているすべてのベクターのスロット数。 FREE-SLOTS すべてのベクターブロックのフリースロットの数。 FLOAT-SIZE 浮動小数点数オブジェクトの内部的なサイズ(‘sizeof (struct Lisp_Float)’)。(ネイティブプラットフォームの‘float’や ‘double’と混同しないこと。) USED-FLOATS 使用中の浮動小数点数の数。 FREE-FLOATS オペレーティングシステムから取得したスペースにあるがカレントで 未使用の浮動小数点数の数。 INTERVAL-SIZE インターバルオブジェクト(interval object)の内部的なサイズ (‘sizeof (struct interval)’)。 USED-INTERVALS 使用中のインターバルの数。 FREE-INTERVALS オペレーティングシステムから取得したスペースにあるがカレントで 未使用のインターバルの数。 BUFFER-SIZE バッファーの内部的なサイズ(‘sizeof (struct buffer)’)。 (‘buffer-size’関数がリターンする値と混同しないこと。) USED-BUFFERS 使用中のバッファーオブジェクトの数。これにはユーザーからは不可 視のkillされたバッファー、つまりリスト‘all_buffers’内のバッフ ァーすべてが含まれる。 UNIT-SIZE ヒープスペースを計る単位であり常に1024バイトと等しい。 TOTAL-SIZE UNIT-SIZE単位での総ヒープサイズ。 FREE-SIZE UNIT-SIZE単位でのカレントで未使用のヒープスペース。 純粋スペース(*note Pure Storage::を参照)内にオーバーフローがあれば 実際にガーベージコレクションを行うことは不可能なので ‘garbage-collect’は‘nil’をリターンする。 -- User Option: garbage-collection-messages この変数が非‘nil’ならEmacsはガーベージコレクションの最初と最後にメ ッセージを表示する。デフォルト値は‘nil’。 -- Variable: post-gc-hook これはガーベージコレクションの終わりに実行されるノーマルフック。ガ ーベージコレクションはこのフックの関数の実行中は抑制されるので慎重 に記述すること。 -- User Option: gc-cons-threshold この変数の値は別のガーベージコレクションをトリガーするために、ガー ベージコレクション後にLispオブジェクト用に割り当てなければならない ストレージのバイト数。特定のオブジェクトタイプに関する情報を取得す るために、‘garbage-collect’がリターンした結果を使用できる。バッファ ーのコンテンツに割り当てられたスペースは勘定に入らない。後続のガー ベージコレクションはこのthreshold(閾値)が消費されても即座には実行さ れず、次回にLispインタープリターが呼び出されたときにのみ実行される ことに注意。 thresholdの初期値は‘GC_DEFAULT_THRESHOLD’であり、これは‘alloc.c’内 で定義されている。これは‘word_size’単位で定義されているので、デフォ ルトの32ビット設定では400,000、64ビット設定では800,000になる。大き い値を指定するとガーベージコレクションの頻度が下る。これはガーベー ジコレクションにより費やされる時間を減少させるがメモリーの総使用量 は増大する。大量のLispデータを作成するプログラムの実行時にはこれを 行いたいと思うかもしれない。 ‘GC_DEFAULT_THRESHOLD’の1/10まで下げた小さな値を指定することにより 、より頻繁にガーベージコレクションを発生させることができる。この最 小値より小さい値は後続のガーベージコレクションで、 ‘garbage-collect’がthresholdを最小値に戻すときまでしか効果をもたな いだろう。 -- User Option: gc-cons-percentage この変数の値はガーベージコレクション発生するまでのコンス(訳注: これ は‘gc-cons-threshold’や‘gc-cons-percentage’の‘-cons-’のことで、これ らの変数が定義されている‘alloc.c’内ではLisp方言での‘cons’をより一般 化したメモリー割り当てプロセスのことを指す模様)の量をカレントヒープ サイズにたいする割り合いで指定する。この条件と‘gc-cons-threshold’を 並行して適用して、条件が両方満足されたときだけガーベージコレクショ ンが発生する。 ヒープサイズ増加にともないガーベージコレクションの処理時間は増大す る。したがってガーベージコレクションの頻度割合を減らすのが望ましい ことがある。 ‘garbage-collect’がリターンする値はデータ型に分類されたLispデータのメ モリー使用量を記述します。それとは対照的に関数‘memory-limit’はEmacsがカ レントで使用中の総メモリー量の情報を提供します。 -- Function: memory-limit この関数はEmacsが割り当てたメモリーの最後のバイトアドレスを1024で除 した値をリターンする。値を1024で除しているのはLisp整数に収まるよう にするため。 あなたのアクションがメモリー使用に与える影響について大まかなアイデ アを得るためにこれを使用することができる。 -- Variable: memory-full この変数はLispオブジェクト用のメモリーが不足に近い状態なら‘t’、それ 以外なら‘nil’。 -- Function: memory-use-counts これはそのEmacsセッションで作成されたオブジェクト数をカウントしたリ スト。これらのカウンターはそれぞれ特定の種類のオブジェクトを数える 。詳細はドキュメント文字列を参照のこと。 -- Function: memory-info この関数はシステムメモリーのトータル量とフリーな量をリターンする。 サポートされないシステムでは値は‘nil’かもしれない。 -- Variable: gcs-done この変数はそのEmacsセッションでそれまでに行われたガーベージコレクシ ョンの合計回数。 -- Variable: gc-elapsed この変数はそのEmacsセッションでガーベージコレクションの間に費やされ た経過時間を浮動小数点数で表した総秒数。 E.4 Stack-allocated Objects =========================== 上述のガーベージコレクターは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’を呼び出すと 未定義の挙動を引き起こします。 E.5 メモリー使用量 ================== 以下の関数と変数はEmacsが行なったメモリー割り当ての総量に関する情報をデ ータ型ごとに分類して提供します。これらの関数や変数と‘garbage-collect’が リターンする値との違いに注意してください。‘garbage-collect’はカレントで 存在するオブジェクトを計数しますが、以下の関数や変数はすでに解放されたオ ブジェクトを含めて割り当てのすべての数やサイズを計数します。 -- Variable: cons-cells-consed そのEmacsセッションでそれまでに割り当てられたコンスセルの総数。 -- Variable: floats-consed そのEmacsセッションでそれまでに割り当てられた浮動小数点数の総数。 -- Variable: vector-cells-consed そのEmacsセッションでそれまでに割り当てられたベクターセル -- Variable: symbols-consed そのEmacsセッションでそれまでに割り当てられたシンボルの総数。 -- Variable: string-chars-consed そのEmacsセッションでそれまでに割り当てられた文字列の文字の総数。 -- Variable: misc-objects-consed そのEmacsセッションでそれまでに割り当てられた雑多なオブジェクトの総 数。これにはマーカー、オーバーレイに加えてユーザーには不可視な特定 のオブジェクトが含まれる。 -- Variable: intervals-consed そのEmacsセッションでそれまでに割り当てられたインターバルの総数。 -- Variable: strings-consed そのEmacsセッションでそれまでに割り当てられた文字列の総数。 E.6 C方言 ========= EmacsのC部分はC99にたいして可搬性があります。‘’や ‘_Noreturn’のようなC11固有の機能は通常はconfigure時に行われるチェックな しでは使用しておらず、Emacsのビルド手順は必要なら代替えの実装を提供しま す。無名な構造体や共用体のようないくつかのC11機能はエミュレートが非常に 困難なので完全に無視しています。 そう遠くない将来のある時点で基本となるC方言は間違いなくC11に変更され るでしょう。 E.7 Emacsプリミティブの記述 =========================== LispプリミティブとはCで実装されたLisp関数です。Lispから呼び出せるように C関数インターフェースの詳細はCのマクロで処理されます。新たなCコードの記 述のしかたを真に理解するにはソースを読むのが唯一の方法ですが、ここではい くつかの事項について説明します。 スペシャルフォームの例として以下は‘eval.c’の‘or’です(通常の関数は同様 の一般的な外観をもつ)。 DEFUN ("or", For, Sor, 0, UNEVALLED, 0, doc: /* Eval args until one of them yields non-nil, then return that value. The remaining args are not evalled at all. If all args return nil, return nil. usage: (or CONDITIONS...) */) (Lisp_Object args) { Lisp_Object val = Qnil; while (CONSP (args)) { val = eval_sub (XCAR (args)); if (!NILP (val)) break; args = XCDR (args); QUIT; } return val; } では‘DEFUN’マクロの引数について詳細に説明しましょう。以下はそれらのテ ンプレートです: DEFUN (LNAME, FNAME, SNAME, MIN, MAX, INTERACTIVE, DOC) LNAME これは関数名として定義するLispシンボル名。上記例では‘or’。 FNAME これは関数のC関数名。これはCコードでその関数を呼び出すために使用さ れる名前。名前は慣習として‘F’の後にLisp名をつけて、Lisp名のすべての ダッシュ(‘-’)をアンダースコアに変更する。つまりCコードから呼び出す 場合には‘For’を呼び出す。 SNAME これはLispでその関数を表すsubrオブジェクト用にデータ保持のための構 造体に使用されるC変数名。この構造体はそのシンボルを作成してそれの定 義にsubrオブジェクトを格納する初期化ルーチンでLispシンボル名を伝達 する。慣習により常にFNAMEの‘F’を‘S’に置き換えた名前になる。 MIN これは関数が要求する引数の最小個数。関数‘or’は最小で0個の引数を受け 入れる。 MAX これは関数が受け入れる引数の最大個数が定数なら引数の最大個数。ある いは‘UNEVALLED’なら未評価の引数を受け取るスペシャルフォーム、 ‘MANY’なら評価される引数の個数に制限がないことを意味する(‘&rest’と 等価)。‘UNEVALLED’と‘MANY’はいずれもマクロ。MAXが数字ならMINより大 きく8より小さいこと。 INTERACTIVE これはLisp関数で‘interactive’の引数として使用されるようなインタラク ティブ仕様(文字列)。‘or’の場合は0(nullポインター)であり、それは ‘or’がインタラクティブに呼び出せないことを示す。値‘""’はインタラク ティブに呼び出す際に関数が引数を引き受けるべきではないことを示す。 値が‘"(’で始まる場合には、その文字列はLispフォームとして評価される 。たとえば: DEFUN ("foo", Ffoo, Sfoo, 0, UNEVALLED, "(list (read-char-by-name \"Insert character: \")\ (prefix-numeric-value current-prefix-arg)\ t))", doc: /* ... /*) DOC これはドキュメント文字列。複数行を含むために特別なことを要しないの で、これにはCの文字列構文ではなくCコメント構文を使用する。‘doc:’の 後のコメントはドキュメント文字列として認識される。コメントの開始と 終了の区切り文字‘/*’と‘*/’はドキュメント文字列の一部にはならない。 ドキュメント文字列の最後の行がキーワード‘usage:’で始まる場合には、 その行の残りの部分は引数リストをドキュメント化するためのものとして 扱われる。この方法によりCコード内で使用される引数名とは異なる引数名 をドキュメント文字列内で使用することができる。その関数の引数の個数 に制限がなければ‘usage:’は必須。 Lispコードでのドキュメント文字列にたいするすべての通常ルール(*note Documentation Tips::を参照)はCコードのドキュメント文字列にも適用さ れる。 ‘DEFUN’マクロ呼び出しの後には、そのC関数にたいする引数リストを引数の タイプを含めて記述しなければなりません。そのプリミティブがLispで固定され た最大個数をもつ引数を受け入れるならLisp引数それぞれにたいして1つのC引数 をもち、各引数のタイプは‘Lisp_Object’でなければなりません(ファイル ‘lisp.h’ではタイプ‘Lisp_Object’の値を作成する種々のマクロと関数が宣言さ れている)。そのプリミティブのLispの最大引数個数に上限がなければ正確に2つ のC引数をもたなければなりません。1つ目はLisp引数の個数で、2つ目はそれら の値を含むブロックのアドレスです。これらはそれぞれ‘int’、 ‘Lisp_Object *’のタイプをもちます。‘Lisp_Object’は任意のデータ型と任意の Lispオブジェクトを保持できるので実行時のみ実際のデータ型を判断できます。 特定のタイプの引数だけを受け入れるプリミティブを記述したければ適切な述語 を使用してタイプを明確にチェックしなければなりません(*note Type Predicates::を参照)。 関数‘For’自体ではローカル変数‘args’はEmacsのスタックマーキングによる ガーベージコレクションで制御されるオブジェクトを参照します。たとえガーベ ージコレクターがCの‘Lisp_Object’スタック変数から到達可能なオブジェクトは 再利用しないとしても、文字列の内容のようなオブジェクトの非オブジェクトコ ンポーネントは移動するかもしれないので、非オブジェクトコンポーネントにア クセスする関数はLisp評価を処理した後にはそれらのアドレスを再取得するよう 注意しなければなりません。Lisp評価は直接と間接を問わず‘eval_sub’か ‘Feval’の呼び出しを通じて発生する可能性があります。 ループ内部での‘QUIT’の呼び出しには注意してください。このマクロはユー ザーが‘C-g’を押下したかどうかをチェックして、もし押下していたら処理を abortします。潜在的に多数の繰り返しを要するすべてのループでこれを行う必 要があります。この場合には引数のリストは非常に長くなる可能性があります。 これはEmacsの応答性とユーザーエクスペリエンスを向上します。 Emacsが一度ダンプされた後に変数に何か書き込まれているときには、その静 的変数やグローバル変数にCの初期化を使用してはなりません。初期化されたこ れらの変数はEmacsのダンプの結果として、(特定のオペレーティングシステムで は)読み取り専用となるメモリーエリアに割り当てられます。*note Pure Storage::を参照してください。 C関数の定義だけではLispプリミティブを利用可能にするのに十分ではありま せん。そのプリミティブにたいしてLispシンボルを作成して関数セルに適切な subrオブジェクトを格納しなければなりません。このコードは以下のようになる でしょう: defsubr (&SNAME); ここでSNAMEは‘DEFUN’の3つ目の引数として使用する名前です。 すでにLispプリミティブが定義されたファイルにプリミティブを追加する場 合には、(そのファイル終端付近にある)‘syms_of_SOMETHING’という名前の関数 を探して‘defsubr’の呼び出しを追加してください。ファイルにこの関数がない 、または新たなファイルを作成する場合には‘syms_of_FILENAME’ (例: ‘syms_of_myfile’)を追加します。それから‘emacs.c’でそれらの関数が呼び出さ れるすべての箇所を探して‘syms_of_FILENAME’の呼び出しを追加してください。 関数‘syms_of_FILENAME’はLisp変数として可視となるすべてのC変数を定義す る場所でもあります。‘DEFVAR_LISP’はタイプ‘Lisp_Object’のC変数をLispから 可視にします。‘DEFVAR_INT’はタイプ‘int’のC変数を常に整数となる値をもつよ うにしてLispから可視にします。‘DEFVAR_BOOL’はタイプ‘int’のC変数を常に ‘t’か‘nil’のいずれかとなる値をもつようにしてLispから可視にします。 ‘DEFVAR_BOOL’で定義された変数はバイトコンパイラーに使用されるリスト ‘byte-boolean-vars’に自動的に追加されることに注意してください。 Cで定義されたLisp変数を‘defcustom’で宣言された変数のように振る舞わせ たければ‘cus-start.el’に適切なエントリーを追加してください。 タイプ‘Lisp_Object’のファイルをスコープとするC変数を定義する場合には 、以下のように‘syms_of_FILENAME’内で‘staticpro’を呼び出してガーベージコ レクションから保護しなければなりません: staticpro (&VARIABLE); 以下はより複雑な引数をもつ別の関数例です。これは‘window.c’からのコー ドであり、Lispオブジェクトを操作するためのマクロと関数の使用を示すもので す。 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p, Scoordinates_in_window_p, 2, 2, 0, doc: /* Return non-nil if COORDINATES are in WINDOW. ... or `right-margin' is returned. */) (register Lisp_Object coordinates, Lisp_Object window) { struct window *w; struct frame *f; int x, y; Lisp_Object lx, ly; CHECK_LIVE_WINDOW (window); w = XWINDOW (window); f = XFRAME (w->frame); CHECK_CONS (coordinates); lx = Fcar (coordinates); ly = Fcdr (coordinates); CHECK_NUMBER_OR_FLOAT (lx); CHECK_NUMBER_OR_FLOAT (ly); x = FRAME_PIXEL_X_FROM_CANON_X (f, lx) + FRAME_INTERNAL_BORDER_WIDTH(f); y = FRAME_PIXEL_Y_FROM_CANON_Y (f, ly) + FRAME_INTERNAL_BORDER_WIDTH(f); switch (coordinates_in_window (w, x, y)) { case ON_NOTHING: /* NOT in window at all. */ return Qnil; ... case ON_MODE_LINE: /* In mode line of window. */ return Qmode_line; ... case ON_SCROLL_BAR: /* On scroll-bar of window. */ /* Historically we are supposed to return nil in this case. */ return Qnil; default: abort (); } } CコードはCで記述されていなければ名前で呼び出すことはできないことに注 意してください。Lispで記述された関数を呼び出すには関数‘funcall’をCで具現 化した‘Ffuncall’を使用します。Lisp関数‘funcall’は個数制限なしの引数を受 け付けるので、Cでの引数はLispレベルでの引数個数とそれらの値を含む1次元配 列という2個の引数になります。Lispレベルでの1つ目の引数は呼び出す関数、残 りはそれに渡す引数です。 C関数‘call0’、‘call1’、‘call2’、...は個数が固定された引数でLisp関数を 手軽に呼び出す便利な方法を提供します。これらは‘Ffuncall’を呼び出すことに より機能します。 ‘eval.c’は例を探すのに適したファイルです。‘lisp.h’には重要なマクロと 関数の定義がいくつか含まれています。 副作用をもたない関数を定義する場合には、コンパイラーのオプティマイザ ーに知らせるために‘side-effect-free-fns’と ‘side-effect-and-error-free-fns’をバインドする‘byte-opt.el’内のコードを 更新してください。 E.8 オブジェクトの内部 ====================== Emacs Lispは豊富なデータタイプのセットを提供します。コンスセル、整数、文 字列のようにこれらのいくつかは、ほとんどすべてのLisp方言で一般的です。マ ーカやバッファーのようなそれ以外のものはLisp内でエディターコマンドを記述 するための基本的サポートを提供するために極めて特別かつ必要なものです。そ のような種々のオブジェクトタイプを実装してインタープリターのサブシステム との間でオブジェクトを渡す効果的な方法を提供するために、Cデータ構造体セ ットとそれらすべてにたいするポインターを表す“タグ付きポインター(tagged pointer)”と呼ばれる特別なタイプが存在します。 Cではタグ付きポインターはタイプ‘Lisp_Object’のオブジェクトです。その ようなタイプの初期化された変数は基本的なデータタイプである整数、シンボル 、文字列、コンスセル、浮動小数点数、ベクター類似オブジェクトや、その他の 雑多なオブジェクトのいずれかを値として常に保持します。これらのデータタイ プのそれぞれは対応するタグ値をもちます。すべてのタグは‘enum Lisp_Type’に より列挙されており、‘Lisp_Object’の3ビットのビットフィールドに配置されま す。残りのビットはそれ自身の値です。整数は即値(“値ビット”で直接表される )、他のすべてのオブジェクトはヒープに割り当てられた対応するオブジェクト へのCポインターで表されます。‘Lisp_Object’のサイズはプラットフォームと設 定に依存します。これは通常は背景プラットフォームのポインターと同一(32ビ ットマシンなら32ビット、64ビットマシンなら64ビット)ですが‘Lisp_Object’が 64ビットでも、すべてのポインターが32ビットのような特別な構成もあります。 後者は‘Lisp_Object’にたいして64ビットの‘long long’タイプを使用することに より、32ビットシステム上のLisp整数にたいする値範囲の制限を乗り越えるため にデザインされたトリックです。 以下のCデータ構造体は整数ではない基本的なデータタイプを表すために ‘lisp.h’で定義されています: ‘struct Lisp_Cons’ コンスセル。リストを構築するために使用されるオブジェクト。 ‘struct Lisp_String’ 文字列。文字シーケンスを表す基本的オブジェクト。 ‘struct Lisp_Vector’ 配列。インデックスによりアクセスできる固定サイズのLispオブジェクト のセット。 ‘struct Lisp_Symbol’ シンボル。一般的に識別子として使用される一意な名前のエンティティ。 ‘struct Lisp_Float’ Floating-point value. ‘union Lisp_Misc’ 上記のいずれにも適合しない雑多な種類のオブジェクト。 これらのタイプは内部的タイプシステムのファーストクラスの市民です。タ グスペースは限られているので他のすべてのタイプは‘Lisp_Vectorlike’か ‘Lisp_Misc’のサブクラスです。サブタイプのベクターは‘enum pvec_type’によ り列挙されておりウィンドウ、バッファー、フレーム、プロセスのようなほとん どすべての複雑なオブジェクトはこのカテゴリーに分類されます。マーカーとオ ーバーレイを含む残りのスペシャルタイプは‘enum Lisp_Misc_Type’により列挙 されており、‘Lisp_Misc’のサブタイプセットを形成します。 ‘Lisp_Vectorlike’のいくつかのサブタイプを説明します。バッファーオブジ ェクトは表示と編集を行うテキストを表します。ウィンドウはバッファーを表示 したり同一フレーム上で再帰的に他のウィンドウを配置するためのコンテナーに 使用される表示構造の一部です(Emacs LispのウィンドウオブジェクトとXのよう なユーザーインターフェースシステムに管理されるエンティティとしてのウィン ドウを混同しないこと。Emacsの用語では後者はフレームと呼ばれる)。最後にプ ロセスオブジェクトはサブプロセスの管理に使用されます。 E.8.1 バッファーの内部 ---------------------- Cでバッファーを表すために2つの構造体(‘buffer.h’を参照)が使用されます。 ‘buffer_text’構造体にはバッファーのテキストを記述するフィールドが含まれ ます。‘buffer’構造体は他のフィールドを保持します。インダイレクトバッファ ーの場合には、2つ以上の‘buffer’構造体が同じ‘buffer_text’構造体を参照しま す。 以下に‘struct buffer_text’内のフィールドをいくつか示します: ‘beg’ バッファーコンテンツのアドレス。 ‘gpt’ ‘gpt_byte’ バッファーのギャップの文字位置とバイト位置。*note Buffer Gap::を参 照のこと。 ‘z’ ‘z_byte’ バッファーテキストの終端の文字位置とバイト位置。 ‘gap_size’ バッファーのギャップのサイズ。*note Buffer Gap::を参照のこと。 ‘modiff’ ‘save_modiff’ ‘chars_modiff’ ‘overlay_modiff’ これらのフィールドはバッファーで行われたバッファー変更イベントの数 をカウントする。‘modiff’はバッファー変更イベントのたびに増分されて 、それ以外では決して変化しない。‘save_modiff’にはバッファーが最後に visitまたは保存されたときの‘modiff’の値が含まれる。‘chars_modiff’は バッファー内の文字にたいする変更だけをカウントして、その他すべての 種類の変更を無視する。‘overlay_modiff’はオーバーレイにたいする変更 だけをカウントする。 ‘beg_unchanged’ ‘end_unchanged’ 最後の再表示完了以降に未変更だと解っているテキスト、開始と終了の箇 所での文字数。 ‘unchanged_modified’ ‘overlay_unchanged_modified’ それぞれ最後に再表示が完了した後の‘modiff’と‘overlay_modiff’の値。 これらのカレント値が‘modiff’や‘overlay_modiff’とマッチしたら、それ は‘beg_unchanged’と‘end_unchanged’に有用な情報が含まれないことを意 味する。 ‘markers’ このバッファーを参照するマーカー。これは実際には単一のマーカーであ り、自身のマーカー“チェーン”内の一連の要素がバッファー内のテキスト を参照する他のマーカーになる。 ‘intervals’ そのバッファーのテキストプロパティを記録するインターバルツリー。 ‘struct buffer’のいくつかのフィールドを以下に示します: ‘header’ タイプ‘struct vectorlike_header’のヘッダーはベクター類似のすべての オブジェクトに共通。 ‘own_text’ 構造体‘struct buffer_text’は通常はバッファーのコンテンツを保持する 。このフィールドはインダイレクトバッファーでは使用されない。 ‘text’ そのバッファーの‘buffer_text’構造体へのポインター。通常のバッファー では上述の‘own_text’フィールド。インダイレクトバッファーではベース バッファーの‘own_text’フィールド。 ‘next’ killされたバッファーを含むすべてのバッファーのチェーン内において次 のバッファーへのポインター。このチェーンはkillされたバッファーを正 しく回収するために割り当てとガーベージコレクションのためだけに使用 される。 ‘pt’ ‘pt_byte’ バッファー内のポイントの文字位置とバイト位置。 ‘begv’ ‘begv_byte’ そのバッファー内のアクセス可能範囲の先頭位置の文字位置とバイト位置 。 ‘zv’ ‘zv_byte’ そのバッファー内のアクセス可能範囲の終端位置の文字位置とバイト位置 。 ‘base_buffer’ インダイレクトバッファーではベースバッファーのポイント。通常のバッ ファーではnull。 ‘local_flags’ このフィールドはバッファー内でローカルな変数にたいしてそれを示すフ ラグを含む。そのような変数はCコードでは‘DEFVAR_PER_BUFFER’を使用し て宣言され、それらのバッファーローカルなバインディングはバッファー 構造体自身内のフィールドに格納される(これらのフィールドのいくつかは このテーブル内で説明している)。 ‘modtime’ visitされているファイルの変更時刻。これはファイルの書き込みと読み込 み時にセットされる。そのバッファーをファイルに書き込む前にファイル がディスク上で変更されていないことを確認するために、このフィールド とそのファイルの変更時刻を比較する。*note Buffer Modification::を参 照のこと。 ‘auto_save_modified’ そのバッファーが最後に自動保存されたときの時刻。 ‘last_window_start’ そのバッファーが最後にウィンドウに表示されたときのバッファー内での ‘window-start’位置。 ‘clip_changed’ このフラグはバッファーでのナローイングが変更されているかを示す。 *note Narrowing::を参照のこと。 ‘prevent_redisplay_optimizations_p’ このフラグはバッファーの表示において再表示最適化が使用されるべきで はないことを示す。 ‘overlay_center’ このフィールドはカレントオーバーレイの中心位置を保持する。*note Managing Overlays::を参照のこと。 ‘overlays_before’ ‘overlays_after’ これらのフィールドはカレントオーバーレイ中心、またはその前で終わる オーバーレイのリスト、およびカレントオーバーレイの後で終わるオーバ ーレイのリスト。*note Managing Overlays::を参照のこと。 ‘overlays_before’は終端位置の記述順、‘overlays_after’は先頭位置増加 順で格納される。 ‘name’ そのバッファーを命名するLisp文字列。これは一意であることが保証され ている。*note Buffer Names::を参照のこと。 ‘save_length’ そのバッファーがvisitしているファイルを最後に読み込みか保存したとき の長さ。インダイレクトバッファーは決して保存されることはないので、 保存に関してはこのフィールドとその他のフィールドは‘buffer_text’構造 体で維持されない。 ‘directory’ 相対ファイル名を展開するディレクトリー。これはバッファーローカル変 数‘default-directory’の値(*note File Name Expansion::を参照)。 ‘filename’ そのバッファーがvisitしているファイルの名前。これはバッファーローカ ル変数‘buffer-file-name’の値(*note 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’ これらのフィールドは自動的にバッファーローカル(*note Buffer-Local Variables::を参照)になるLisp変数の値を格納する。これらに対応する変 数は名前に追加のプレフィクス‘buffer-’がつき、アンダースコアがダッシ ュで置換される。たとえば‘undo_list’は‘buffer-undo-list’の値を格納す る。 ‘mark’ そのバッファーにたいするマーク。マークはマーカーなのでリスト ‘markers’内にも含まれる。*note The Mark::を参照のこと。 ‘local_var_alist’ この連想リストはバッファーのバッファーローカル変数のバインディング を記述する。これにはバッファーオブジェクト内に特別なスロットをもつ 、ビルトインのバッファーローカルなバインディングは含まれない(このテ ーブルではそれらのスロットは省略している)。*note Buffer-Local Variables::を参照のこと。 ‘major_mode’ そのバッファーのメジャーモードを命名するシンボル(例: ‘lisp-mode’)。 ‘mode_name’ そのメジャーモードの愛称(例: ‘"Lisp"’)。 ‘keymap’ ‘abbrev_table’ ‘syntax_table’ ‘category_table’ ‘display_table’ これらのフィールドはバッファーのローカルキーマップ(*note Keymaps::を 参照)、abbrevテーブル(*note Abbrev Tables::を参照)、構文テーブル (*note Syntax Tables::を参照)、カテゴリーテーブル(*note Categories::を参照)、ディスプレーテーブル(*note Display Tables::を 参照)を格納する。 ‘downcase_table’ ‘upcase_table’ ‘case_canon_table’ これらのフィールドはテキストを小文字、大文字、およびcase-fold検索で のテキストの正規化の変換テーブルを格納する。*note Case Tables::を参 照のこと。 ‘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’ これらのフィールドは自動的にバッファーローカル(*note Buffer-Local Variables::を参照)になるLisp変数の値を格納する。これらに対応する変 数は名前のアンダースコアがダッシュで置換される。たとえば ‘mode_line_format’は‘mode-line-format’の値を格納する。 ‘last_selected_window’ これは最後に選択されていたときにそのバッファーを表示していたウィン ドウ、またはそのウィンドウがすでにそのバッファーを表示していなけれ ば‘nil’。 E.8.2 ウィンドウの内部 ---------------------- ウィンドウのフィールドには以下が含まれます(完全なリストは‘window.h’の ‘struct window’を参照): ‘frame’ そのウィンドウがあるフレーム。 ‘mini_p’ そのウィンドウがミニバッファーウィンドウなら非‘nil’。 ‘parent’ Emacsは内部的にウィンドウをツリーにアレンジする。ウィンドウの兄弟グ ループは、そのエリアがすべての兄弟を含むような親ウィンドウをもつ。 このフィールドはウィンドウの親を指す。 親ウィンドウはバッファーを表示せず子ウィンドウ形成を除いて表示では 少ししか役割を果たさない。Emacs Lispプログラムからは通常は親ウィン ドウへのアクセスがない。Emacs Lispプログラムでは実際にバッファーを 表示するツリーの子ノードのウィンドウにたいして操作を行う。 ‘hchild’ ‘vchild’ これらのフィールドはウィンドウの左端の子と上端の子を含む。子ウィン ドウによりウィンドウが分割される場合には‘hchild’、垂直に分割される 場合には‘vchild’が使用される。生きたウィンドウでは‘hchild’、 ‘vchild’、‘buffer’のいずれか1つだけが非‘nil’になる。 ‘next’ ‘prev’ そのウィンドウの次の兄弟と前の兄弟。自身のグループ内でそのウィンド ウが右端か下端なら‘next’は‘nil’。自身のグループ内でそのウィンドウが 左端か上端なら‘prev’は‘nil’。 ‘left_col’ そのウィンドウの左端をフレームの最左列(列0)から相対的に数えた列数。 ‘top_line’ そのウィンドウの上端をフレームの最上行(行0)から相対的に数えた行数。 ‘total_cols’ ‘total_lines’ 列数と行数で数えたウィンドウの幅と高さ。幅にはスクロールバーとフリ ンジおよび/または(もしあれば)ウィンドウ右側のセパレーターラインが含 まれる。 ‘buffer’ そのウィンドウが表示しているバッファー。 ‘start’ そのウィンドウ内に表示されるバッファーでウィンドウに最初に表示され る文字の位置を指すマーカー。 ‘pointm’ これはウィンドウが選択されているときのカレントバッファーのポイント 値。選択されていなければ前の値が保たれる。 ‘force_start’ このフラグが非‘nil’ならLispプログラムによりそのウィンドウが明示的に スクロールされたことを示す。これはポイントがスクリーン外にある場合 の次回再表示に影響を与える。影響とはポイント周辺のテキストを表示す るためにウィンドウをスクロールするかわりに、スクリーン上にある位置 にポイントを移動するというものである。 ‘frozen_window_start_p’ このフィールドは再表示にたいして、たとえポイントが不可視になったと してもウィンドウの‘start’を変更するべきではないことを示すために一時 的に1にセットされる。 ‘start_at_line_beg’ 非‘nil’は‘start’のカレント値がウィンドウ選択時に先頭行だったことを 意味する。 ‘use_time’ これはウィンドウが最後に選択された時刻。関数‘get-lru-window’はこの 値を使用する。 ‘sequence_number’ そのウィンドウ作成時に割り当てられた一意な番号。 ‘last_modified’ 前回のそのウィンドウの再表示完了時のウィンドウのバッファーの ‘modiff’フィールド。 ‘last_overlay_modified’ 前回のウィンドウの再表示完了時のウィンドウのバッファーの ‘overlay_modiff’フィールド。 ‘last_point’ 前回のウィンドウの再表示完了時のウィンドウのバッファーのポイント値 。 ‘last_had_star’ 非‘nil’値はウィンドウが最後に更新されたときウィンドウのバッファーが 変更されたことを意味する。 ‘vertical_scroll_bar’ そのウィンドウの垂直スクロールバー。 ‘left_margin_cols’ ‘right_margin_cols’ そのウィンドウの左マージンと右マージンの幅。値‘nil’はマージンがない ことを意味する。 ‘left_fringe_width’ ‘right_fringe_width’ そのウィンドウの左フリンジと右フリンジの幅。値‘nil’と‘t’はフレーム の値の使用を意味する。 ‘fringes_outside_margins’ 非‘nil’値はディスプレーマージン外側のフリンジ、それ以外ならフリンジ はマージンとテキストの間にあることを意味する。 ‘window_end_pos’ これは‘z’からウィンドウのカレントマトリクス内の最後のグリフのバッフ ァー位置を減じて算出される。この値は‘window_end_valid’が非‘nil’のと きだけ有効。 ‘window_end_bytepos’ ‘window_end_pos’に対応するバイト位置。 ‘window_end_vpos’ ‘window_end_pos’を含む行のウィンドウに相対的な垂直位置。 ‘window_end_valid’ このフィールドは‘window_end_pos’が真に有効なら非‘nil’値にセットされ る。これは重要な再表示が先に割り込んだ場合には、‘window_end_pos’を 算出した表示がスクリーン上に出現しなくなるので‘nil’となる。 ‘cursor’ そのウィンドウ内でカーソルがどこにあるかを記述する構造体。 ‘last_cursor’ 完了した最後の表示での‘cursor’の値。 ‘phys_cursor’ そのウィンドウのカーソルが物理的にどこにあるかを記述する構造体。 ‘phys_cursor_type’ ‘phys_cursor_height’ ‘phys_cursor_width’ そのウィンドウの最後の表示でのカーソルのタイプ、高さ、幅。 ‘phys_cursor_on_p’ このフィールドはカーソルが物理的にオンなら非0。 ‘cursor_off_p’ 非0はそのウィンドウのカーソルが論理的にオフであることを意味する。こ れはカーソルの点滅に使用される。 ‘last_cursor_off_p’ このフィールドは最後の再表示時の‘cursor_off_p’の値を含む。 ‘must_be_updated_p’ これはウィンドウを更新しなければならないとき、再表示の間は1にセット される。 ‘hscroll’ これはウィンドウ内の表示が左へ水平スクロールされている列数。これは 通常は0。 ‘vscroll’ ピクセル単位での垂直スクロール量。これは通常は0。 ‘dedicated’ そのウィンドウがそれのバッファー専用(dedicated)なら非‘nil’。 ‘display_table’ そのウィンドウのディスプレーテーブル、何も指定されていなければ ‘nil’。 ‘update_mode_line’ 非‘nil’はウィンドウのモードラインの更新が必要なことを意味する。 ‘base_line_number’ そのバッファーの特定の位置の行番号か‘nil’。これはモードラインでポイ ントの行番号を表示するために使用される。 ‘base_line_pos’ 行番号が既知であるバッファー位置、未知なら‘nil’。これがバッファーな らウィンドウがバッファーを表示するかぎり行番号は表示されない。 ‘column_number_displayed’ そのウィンドウのモードラインに表示されているカレント列番号、列番号 が表示されていなければ‘nil’。 ‘current_matrix’ ‘desired_matrix’ そのウィンドウのカレント、および望まれる表示を記述するグリフ。 E.8.3 プロセスの内部 -------------------- プロセスのフィールドには以下が含まれます(完全なリストは‘process.h’の ‘struct Lisp_Process’の定義を参照): ‘name’ プロセス名(文字列)。 ‘command’ そのプロセスの開始に使用されたコマンド引数を含むリスト。ネットワー クプロセスとシリアルプロセスではプロセスが実行中なら‘nil’、停止して いたら‘t’。 ‘filter’ そのプロセスから出力を受け取るために使用される関数。 ‘sentinel’ そのプロセスの状態が変化したら常に呼び出される関数。 ‘buffer’ そのプロセスに関連付けられたバッファー。 ‘pid’ オペレーティングシステムのプロセスID (整数)。ネットワークプロセスや シリアルプロセスのような疑似プロセスでは値0を使用する。 ‘childp’ フラグ。実際に子プロセスなら‘t’。ネットワークプロセスやシリアルプロ セスでは‘make-network-process’や‘make-serial-process’にもとづく plist。 ‘mark’ そのプロセスの出力からバッファーに挿入された終端位置を示すマーカー 。常にではないがこれはバッファー終端であることが多い。 ‘kill_without_query’ これが非0ならプロセス実行中にEmacsをkillしてもプロセスのkillにたい して確認を求めない。 ‘raw_status’ システムコール‘wait’がリターンするrawプロセス状態。 ‘status’ ‘process-status’がリターンするようなプロセス状態。 ‘tick’ ‘update_tick’ これら2つのフィールドが等しくないなら、センチネル実行かプロセスバッ ファーへのメッセージ挿入によりプロセスの状態変更が報告される必要が ある。 ‘pty_flag’ そのサブプロセスがptyを使用して対話する場合には非‘nil’、パイプを使 用する場合には‘nil’。 ‘infd’ そのプロセスからの入力にたいするファイルディクリプター。 ‘outfd’ そのプロセスへの出力にたいするファイルディクリプター。 ‘tty_name’ そのサブプロセスが使用する端末の名前、パイプを使用する場合には ‘nil’。 ‘decode_coding_system’ そのプロセスからの入力のデコーディングにたいするコーディングシステ ム。 ‘decoding_buf’ デコーディング用の作業バッファー。 ‘decoding_carryover’ デコーディングでのキャリーオーバーのサイズ。 ‘encode_coding_system’ そのプロセスからの出力のエンコーディングにたいするコーディングシス テム。 ‘encoding_buf’ エンコーディング用の作業バッファー。 ‘inherit_coding_system_flag’ プロセス出力のデコードに使用されるコーディングシステムからプロセス バッファーの‘coding-system’をセットするフラグ。 ‘type’ プロセスのタイプを示す‘real’、‘network’、‘serial’のいずれかのシンボ ル。 E.9 Cの整数型 ============= 以下はEmacsのCソースコード内で整数タイプを使用する際のガイドラインです。 これらのガイドラインはときに相反するアドバイスを与えることがありますが一 般的な常識に沿ったものがアドバイスです。 • 任意の制限の使用を避ける。たとえば‘s’の長さを‘int’の範囲に収めるこ とが要求されるのでなければ‘int len = strlen (s);’を使用しないこと。 • 符号付き整数の算術演算のオーバーフローのラップアラウンドを前提とし てはならない。Emacsのポート対象先によっては成立しない。実際には符号 付き整数のオーバーフローは未定義であり、コアダンプや早晩に非論理的 な振る舞いさえ起こし得る。符号なし整数のオーバーフローは2のべき乗の 剰余に確実にラップアラウンドされることが保証されている。 • 符号なしタイプと符号付きタイプを組み合わせるとコードが混乱するので 符号なしタイプより符号付きタイプを優先すること。他のガイドラインの 多くはタイプが符号付きだとみなしている。符号なしタイプを要する稀な ケースでは、符号付きの符号なし版(‘ptrdiff_t’のかわりに‘size_t’、 ‘intptr_t’のかわりに‘uintptr_t’)にたいして同様のアドバイスを適用で きる。 • 0から0x3FFFFFまでの範囲ではEmacs文字コードには‘int’を優先すること。 より一般的には、たとえばスクリーン列数のように‘int’範囲と既知である 整数には‘int’を優先すること。 • サイズ(たとえばすべての個別のCオブジェクトの最大サイズや、すべての C配列の最大要素数にバインドされる整数)にたいしては‘ptrdiff_t’を優先 すること。これは符号付きタイプにたいするEmacsの一般的な優先事項であ る。‘ptrdiff_t’の使用によりオブジェクトは‘PTRDIFF_MAX’に制限される が、より大きいオブジェクトはポインター減算を破壊するかもしれず結局 のところ問題を起こす可能性があるので、これは一方的に制限を課すもの ではない。 • ‘ssize_t’関連の制限をもつ低レベルAPIト対話する際を除いて‘ssize_t’を 避けること。これは典型的なプラトフォームでは‘ptrdiff_t’と等価だとし ても、‘ssize_t’は範囲が狭いときがあり使用によりサイズ関連の計算がオ ーバーフローするかもしれない。同じく‘ptrdiff_t’はより一般的で標準化 されており、標準的な‘printf’フォーマットをもち、Emacsの内部的なサイ ズオーバーフローのチェックの基礎である。‘ssize_t’を使用する際には POSIXガ−から‘SSIZE_MAX’の範囲の値にたいするサポートだけを要求するこ とに注意してほしい。 • ポインターの内部表現や与えられた任意のタイミングで存在可能なオブジ ェクト数や割り当て可能な総バイト数にのみバインドされる整数には ‘intptr_t’を優先すること。現在のことこEmacsは‘intptr_t’を使用したほ うがよいときに別のタイプを使用する場合がある。現在のEmacsのカレント 移植先にたいして未修正でコードが動作するので修正の優先度は低い。 • Emacs Lispのfixnumへの変換や逆変換を表す値ではfixnum演算が ‘EMACS_INT’にもとづくのでEmacsで定義されたタイプ‘EMACS_INT’を優先す ること。 • (ファイルサイズやエポック以降の経過秒数等の)システム値を表す際には 、(‘off_t’や‘time_t’等の)システムタイプを優先すること。安全だと解っ ていなければシステムタイプが符号付きだと仮定してはならない。たとえ ば‘off_t’は常に符号付きだが‘time_t’は符号付きである必要はない。 • ‘printf’族の関数を使用してプリントされ得る任意の符号付き整数かもし れない値を表す場合にはEmacsの定義タイプ‘printmax_t’を優先すること。 • 任意の符号付き整数かもしれない値を表す場合には‘intmax_t’を優先する こと。 • ブーリーンには‘bool’、‘false’、‘true’を使用すること。‘bool’の使用に よりプログラムの可読性が増して、‘int’を使用するより若干高速になる。 ‘int’、‘0’、‘1’を使用しても大丈夫だが旧スタイルは段階的に廃止される 。‘bool’を使用する際にはソースファイル‘lib/stdbool.in.h’に文書化さ れている‘bool’の代替実装の制限を尊重すること。特にブーリーンのビッ トフィールドは‘bool’ではなく‘bool_bf’タイプであること。そうすれば標 準のGCCでObjective Cをコンパイルするときでさえ正しく機能する。 • ビットフィールドでは‘int’は可搬性に劣るので、‘int’より‘unsigned int’か‘signed int’を優先すること。単一ビットのビットフィールドの値 は0か1なので‘unsigned int’か‘bool_bf’を使用すること。 Appendix F 標準的なエラー ************************* 以下は標準的なEmacsにおける、より重要なエラーシンボルを概念別にグループ 分けしたリストです。このリストには各シンボルのメッセージ、およびエラーを 発生し得る方法へのクロスリファレンスが含まれています。 これらのエラーシンボルはそれぞれ親となるエラー条件のセットをシンボル のリストとして保持します。このリストには通常はエラーシンボル自身とシンボ ル‘error’が含まれます。このリストは‘error’より狭義ですが単一のエラーシン ボルより広義であるような中間的なクラス分けのための追加シンボルを含む場合 があります。たとえばファイルアクセスでのすべてのエラーは条件 ‘file-error’をもちます。ここでわたしたちが特定のエラーシンボルにたいする 追加エラー条件に言及していなければ、それがないことを意味しています。 特別な例外としてエラーシンボル‘quit’は、quitはエラーとみなされないの でコンディション‘error’をもっていません。 これらのエラーシンボルのほとんどはC(主に‘data.c’)で定義されていますが 、いくつかはLispで定義されています。たとえばファイル‘userlock.el’では ‘file-locked’と‘file-supersession’のエラーが定義されています。Emacsとと もに配布される専門的なLispライブラリーのいくつかは、それら自身のエラーシ ンボルを定義しています。それらのすべてをここではリストしません。 エラーの発生とそれを処理する方法については*note Errors::を参照してく ださい。 ‘error’ メッセージは‘error’。*note Errors::を参照のこと。 ‘quit’ メッセージは‘Quit’。*note Quitting::を参照のこと。 ‘args-out-of-range’ メッセージは‘Args out of range’。これはシーケンス、バッファー、その 他コンテナー類似オブジェクトにたいして範囲を超えた要素にアクセスを 試みたときに発生する。*note Sequences Arrays Vectors::と*note Text::を参照のこと。 ‘arith-error’ メッセージは‘Arithmetic error’。これは0による整数除算を試みたときに 発生する。*note Numeric Conversions::と*note Arithmetic Operations::を参照のこと。 ‘beginning-of-buffer’ メッセージは‘Beginning of buffer’。*note Character Motion::を参照の こと。 ‘buffer-read-only’ メッセージは‘Buffer is read-only’。*note Read Only Buffers::を参照 のこと。 ‘circular-list’ メッセージは‘List contains a loop’。これは循環構造に遭遇時に発生す る。*note Circular Objects::を参照のこと。 ‘cl-assertion-failed’ メッセージは‘Assertion failed’。これは‘cl-assert’マクロのテスト失敗 時に発生する。*note (cl)Assertions::を参照のこと。 ‘coding-system-error’ メッセージは‘Invalid coding system’。*note Lisp and Coding Systems::を参照のこと。 ‘cyclic-function-indirection’ メッセージは‘Symbol's chain of function indirections contains a loop’。*Note Function Indirection::を参照のこと。 ‘cyclic-variable-indirection’ メッセージは‘Symbol's chain of variable indirections contains a loop’。*Note Variable Aliases::を参照のこと。 ‘dbus-error’ メッセージは‘D-Bus error’。これはEmacsがD-Busサポートつきでコンパイ ルされたときだけ定義される。*note (dbus)Errors and Events::を参照の こと。 ‘end-of-buffer’ メッセージは‘End of buffer’。*note Character Motion::を参照のこと。 ‘end-of-file’ メッセージは‘End of file during parsing’。これはファイルI/Oではなく Lispリーダーに属するので‘file-error’のサブカテゴリーではないことに 注意のこと。*note Input Functions::を参照のこと。 ‘file-already-exists’ これは‘file-error’のサブカテゴリー。*note Writing to Files::を参照 のこと。 ‘file-date-error’ これは‘file-error’のサブカテゴリー。これは‘copy-file’を試行して出力 ファイルの最終変更時刻のセットに失敗したときに発生する。*note Changing Files::を参照のこと。 ‘file-error’ このエラーメッセージは、通常はエラー条件‘file-error’が与えられたと きはデータアイテムだけから構築されるので、エラー文字列とサブカテゴ リーはここにリストしない。つまりエラー文字列は特に関連しない。しか しこれらのエラーシンボルは‘error-message’プロパティをもち、何もデー タが与えられなければ‘error-message’が_使用される_。*note Files::を 参照のこと。 ‘compression-error’ これは圧縮ファイルの処理の問題を起因とする‘file-error’のサブカテゴ リー。*note How Programs Do Loading::を参照のこと。 ‘file-locked’ これは‘file-error’のサブカテゴリー。*note File Locks::を参照のこと 。 ‘file-supersession’ これは‘file-error’のサブカテゴリー。*note Modification Time::を参照 のこと。 ‘file-notify-error’ これは‘file-error’のサブカテゴリー。*note File Notifications::を参 照のこと。 ‘ftp-error’ これはftpを使用したリモートファイルへのアクセスの問題を起因とする ‘file-error’のサブカテゴリー。*note (emacs)Remote Files::を参照のこ と。 ‘invalid-function’ メッセージは‘Invalid function’。*note Function Indirection::を参照 のこと。 ‘invalid-read-syntax’ メッセージは‘Invalid read syntax’。*note Printed Representation::を 参照のこと。 ‘invalid-regexp’ メッセージは‘Invalid regexp’。*note Regular Expressions::を参照のこ と。 ‘mark-inactive’ メッセージは‘The mark is not active now’。*note The Mark::を参照の こと。 ‘no-catch’ メッセージは‘No catch for tag’。*note Catch and Throw::を参照のこと 。 ‘scan-error’ メッセージは‘Scan error’。これは特定の構文解析関数が無効な構文やマ ッチしないカッコを見つけたときに発生する。慣習的に人間が可読なエラ ーメッセージ、移動を妨害する開始位置、妨害の終了位置という3つの引数 でraiseされる。*note List Motion::と*note Parsing Expressions::を参 照のこと。 ‘search-failed’ メッセージは‘Search failed’。*note Searching and Matching::を参照の こと。 ‘setting-constant’ メッセージは‘Attempt to set a constant symbol’。これは‘nil’、‘t’、 およびキーワードシンボルへの値の割り当て時に発生する。*note Constant Variables::を参照のこと。 ‘text-read-only’ メッセージは‘Text is read-only’。これは‘buffer-read-only’のサブカテ ゴリー。*note Special Properties::を参照のこと。 ‘undefined-color’ メッセージは‘Undefined color’。*note Color Names::を参照のこと。 ‘user-error’ メッセージは空文字列。*note Signaling Errors::を参照のこと。 ‘void-function’ メッセージは‘Symbol's function definition is void’。*note Function Cells::を参照のこと。 ‘void-variable’ メッセージは‘Symbol's value as variable is void’。*note Accessing Variables::を参照のこと。 ‘wrong-number-of-arguments’ メッセージは‘Wrong number of arguments’。*note Classifying Lists::を 参照のこと。 ‘wrong-type-argument’ メッセージは‘Wrong type argument’。*note Type Predicates::を参照の こと。 Appendix G 標準的なキーマップ ***************************** このセクションでは、より一般的なキーマップをリストします。これらの多くは Emacsの初回起動時に存在しますが、それらのいくつかは各機能へのアクセス時 にロードされます。 他にもより特化された多くのキーマップがあります。それらは特にメジャー モードやマイナーモードに関連付けられています。ミニバッファーはいくつかの キーマップを使用します(*note Completion Commands::を参照)。キーマップの 詳細については*note Keymaps::を参照してください。 ‘2C-mode-map’ プレフィクス‘C-x 6’のサブコマンドにたいするsparseキーマップ。 *note Two-Column Editing: (emacs)Two-Column.を参照のこと。 ‘abbrev-map’ プレフィクス‘C-x a’のサブコマンドにたいするsparseキーマップ。 *note (emacs)Defining Abbrevs::を参照のこと。 ‘button-buffer-map’ バッファーを含むバッファーに有用なsparseキーマップ。 これを親キーマップとして使用したいと思うかもしれない。*note Buttons::を参照のこと。 ‘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キーマップ。 *note (emacs)Registers::を参照のこと。 ‘esc-map’ ‘ESC’ (や‘Meta’)コマンドにたいする完全なキーマップ。 ‘facemenu-keymap’ プレフィクスキー‘M-o’にたいして使用されるsparseキーマップ。 ‘function-key-map’ すべての‘local-function-key-map’のインスタンスの親キーマップ (‘local-function-key-map’を参照)。 ‘global-map’ デフォルトのグローバルキーバインディングを含む完全なキーマップ。 モードでこのグローバルマップを変更しないこと。 ‘goto-map’ プレフィクスキー‘M-g’にたいして使用されるsparseキーマップ。 ‘help-map’ ヘルプ文字‘C-h’に後続するキーにたいするsparseキーマップ。 *note Help Functions::を参照のこと。 ‘Helper-help-map’ ヘルプユーティリティパッケージにより使用される完全なキーマップ。 これは値セルと関数セルに同じキーマップをもつ。 ‘input-decode-map’ キーパッドとファンクションキーの変換にたいするキーマップ。 存在しなければ空のsparseキーマップを含む。*note Translation Keymaps::を参照のこと。 ‘key-translation-map’ キー変換にたいするキーマップ。‘local-function-key-map’と異なり通常 のキーバインディングをオーバーライドする。*note Translation Keymaps::を参照のこと。 ‘kmacro-keymap’ プレフィクス検索‘C-x C-k’に後続するキーにたいするsparseキーマップ。 *note (emacs)Keyboard Macros::を参照のこと。 ‘local-function-key-map’ キーシーケンスを優先する代替えに変換するキーマップ。 存在しなければ空のsparseキーマップが含まれる。*note Translation Keymaps::を参照のこと。 ‘menu-bar-file-menu’ ‘menu-bar-edit-menu’ ‘menu-bar-options-menu’ ‘global-buffers-menu-map’ ‘menu-bar-tools-menu’ ‘menu-bar-help-menu’ これらのキーマップはメニューバー内のメインとなるトップレベルメニュ ーを表示する。 これらのいくつかはサブメニューを含む。たとえばEditメニューは ‘menu-bar-search-menu’を含む等。*note Menu Bar::を参照のこと。 ‘minibuffer-inactive-mode-map’ ミニバッファーが非アクティブ時に使用される完全なキーマップ。 *note Editing in the Minibuffer: (emacs)Minibuffer Edit.を参照のこ と。 ‘mode-line-coding-system-map’ ‘mode-line-input-method-map’ ‘mode-line-column-line-number-mode-map’ これらのキーマップはモードライン内の種々のエリアを制御する。 *note Mode Line Format::を参照のこと。 ‘mode-specific-map’ ‘C-c’に後続する文字にたいするキーマップ。これはグローバルキーマップ 内にあることに注意。これは実際にはモード固有のものではない。プフィ クスキー‘C-c’の使用方法を主に記述する‘C-h b’ (‘display-bindings’)内 で有益なのでこの名前が選ばれた。 ‘mouse-appearance-menu-map’ ‘S-mouse-1’キーにたいして使用されるsparseキーマップ。 ‘mule-keymap’ プレフィクスキー‘C-x ’にたいして使用されるグローバルキーマップ 。 ‘narrow-map’ プレフィクス‘C-x n’のサブコマンドにたいするsparseキーマップ。 ‘prog-mode-map’ Progモードにより使用されるキーマップ。 *note Basic Major Modes::を参照のこと。 ‘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’を拡張する。*note query-replace-map: Search and Replace.を参照のこと。 ‘search-map’ 検索関連コマンドにたいしてグローバルバインディングを提供する sparseキーマップ。 ‘special-mode-map’ Specialモードにより使用されるキーマップ。 *note Basic Major Modes::を参照のこと。 ‘tool-bar-map’ ツールバーのコンテンツを定義するキーマップ。 *note Tool Bar::を参照のこと。 ‘universal-argument-map’ ‘C-u’処理中に使用されるsparseキーマップ。 *note Prefix Command Arguments::を参照のこと。 ‘vc-prefix-map’ プレフィクスキー‘C-x v’にたいして使用されるグローバルキーマップ。 ‘x-alternatives-map’ グラフィカルなフレームでの特定キーのマップに使用されるsparseキーマ ップ。 関数‘x-setup-function-keys’はこれを使用する。 Appendix H 標準的なフック ************************* 以下はEmacsで適切なタイミングで呼び出す関数を提供するためのいくつかのフ ック関数のリストです。 これらの変数のほとんどは‘-hook’で終わる名前をもちます。これらは“ノー マルフック(normal hooks)”と呼ばれており‘run-hooks’により実行されます。そ のようなフックの値は関数のリストです。これらの関数は引数なしで呼び出され て値は完全に無視されます。そのようなフック上に新たに関数を配置するために は‘add-hook’を呼び出す方法を推奨します。フック使用についての詳細は*note Hooks::を参照してください。 ‘-functions’で終わる名前の変数は通常は“アブノーマルフック(abnormal hooks)”です(古いコードの中には非推奨の‘-hooks’サフィクスを使用するものも ある)。これらの値は関数のリストですが関数は特殊な方法で呼び出されます(引 数を渡されたりリターン値が使用される)。‘-function’で終わる名前の変数は値 として単一の関数をもちます。 以下のリストはすべてを網羅したリストではなく、より一般的なフックだけ をカバーしています。たとえばメジャーモードはそれぞれ ‘MODENAME-mode-hook’という名前のフックを定義します。メジャーモードは自身 が行う最後のこととして‘run-mode-hooks’でこのノーマルフックを実行します。 *note Mode Hooks::を参照してください。ほとんどのマイナーモードにもフック があります。 特別な機能によりファイルがロードされたときに評価する式を指定できます (*note Hooks for Loading::を参照)。この機能は正確にはフックではありませ んが同様のことを行います。 ‘activate-mark-hook’ ‘deactivate-mark-hook’ *note The Mark::を参照のこと。 ‘after-change-functions’ ‘before-change-functions’ ‘first-change-hook’ *note Change Hooks::を参照のこと。 ‘after-change-major-mode-hook’ ‘change-major-mode-after-body-hook’ *note Mode Hooks::を参照のこと。 ‘after-init-hook’ ‘before-init-hook’ ‘emacs-startup-hook’ ‘window-setup-hook’ *note Init File::を参照のこと。 ‘after-insert-file-functions’ ‘write-region-annotate-functions’ ‘write-region-post-annotation-function’ *note Format Conversion::を参照のこと。 ‘after-make-frame-functions’ ‘before-make-frame-hook’ *note Creating Frames::を参照のこと。 ‘after-save-hook’ ‘before-save-hook’ ‘write-contents-functions’ ‘write-file-functions’ *note Saving Buffers::を参照のこと。 ‘after-setting-font-hook’ フレームのフォント変更後に実行されるフック。 ‘auto-save-hook’ *Note Auto-Saving::を参照のこと。 ‘before-hack-local-variables-hook’ ‘hack-local-variables-hook’ *note File Local Variables::を参照のこと。 ‘buffer-access-fontify-functions’ *note Lazy Properties::を参照のこと。 ‘buffer-list-update-hook’ バッファーリスト変更時に実行されるフック(*note Buffer List::を参照 )。 ‘buffer-quit-function’ カレントバッファーをquitするために呼び出されるフック。 ‘change-major-mode-hook’ *note Creating Buffer-Local::を参照のこと。 ‘command-line-functions’ *note Command-Line Arguments::を参照のこと。 ‘delayed-warnings-hook’ コマンドループは‘post-command-hook’(以下参照)の直後にこれを実行する 。 ‘focus-in-hook’ ‘focus-out-hook’ *note Input Focus::を参照のこと。 ‘delete-frame-functions’ *note Deleting Frames::を参照のこと。 ‘delete-terminal-functions’ *note Multiple Terminals::を参照のこと。 ‘pop-up-frame-function’ ‘split-window-preferred-function’ *note Choosing Window Options::を参照のこと。 ‘echo-area-clear-hook’ *note Echo Area Customization::を参照のこと。 ‘find-file-hook’ ‘find-file-not-found-functions’ *note Visiting Functions::を参照のこと。 ‘font-lock-extend-after-change-region-function’ *note Region to Refontify::を参照のこと。 ‘font-lock-extend-region-functions’ *note Multiline 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’ *note Other Font Lock Variables::を参照のこと。 ‘fontification-functions’ *note Automatic Face Assignment: Auto Faces.を参照のこと。 ‘frame-auto-hide-function’ *note Quitting Windows::を参照のこと。 ‘kill-buffer-hook’ ‘kill-buffer-query-functions’ *note Killing Buffers::を参照のこと。 ‘kill-emacs-hook’ ‘kill-emacs-query-functions’ *note Killing Emacs::を参照のこと。 ‘menu-bar-update-hook’ *note Menu Bar::を参照のこと。 ‘minibuffer-setup-hook’ ‘minibuffer-exit-hook’ *note Minibuffer Misc::を参照のこと。 ‘mouse-leave-buffer-hook’ マウスコマンドでのウィンドウ切り替え時に実行されるフック。 ‘mouse-position-function’ *note Mouse Position::を参照のこと。 ‘prefix-command-echo-keystrokes-functions’ (‘C-u’のような)プレフィクスコマンドにより実行されるアブノーマルフッ クであり、カレントのプレフィクス状態を記述する文字列をリターンする こと。たとえば‘C-u’は‘C-u-’や‘C-u 1 2 3-’を生成する。フック関数はそ れぞれ引数なしで呼び出されてカレントのプレフィクス状態を記述する文 字列、プレフィクス状態がなければ‘nil’をリターンすること。*note Prefix Command Arguments::を参照のこと。 ‘prefix-command-preserve-state-hook’ プレフィクスコマンドが次のコマンドにカレントのプレフィクスコマンド を渡すことによりプレフィクスを確保する必要はある際にフックが実行さ れる。たとえば‘C-u’はユーザーが‘C-u -’や‘C-u’の後に数字をタイプした 際には、その状態を次のコマンドに渡す必要がある。 ‘pre-redisplay-functions’ フックはそれぞれのウィンドウで再表示の直前に実行される。*note Forcing Redisplay::を参照のこと。 ‘post-command-hook’ ‘pre-command-hook’ *note Command Overview::を参照のこと。 ‘post-gc-hook’ *note Garbage Collection::を参照のこと。 ‘post-self-insert-hook’ *note Keymaps and Minor Modes::を参照のこと。 ‘suspend-hook’ ‘suspend-resume-hook’ ‘suspend-tty-functions’ ‘resume-tty-functions’ *note Suspending Emacs::を参照のこと。 ‘syntax-begin-function’ ‘syntax-propertize-extend-region-functions’ ‘syntax-propertize-function’ ‘font-lock-syntactic-face-function’ *note Syntactic Font Lock::と*note Syntax Properties::を参照のこと 。 ‘temp-buffer-setup-hook’ ‘temp-buffer-show-function’ ‘temp-buffer-show-hook’ *note Temporary Displays::を参照のこと。 ‘tty-setup-hook’ *note Terminal-Specific::を参照のこと。 ‘window-configuration-change-hook’ ‘window-scroll-functions’ ‘window-size-change-functions’ *note Window Hooks::を参照のこと。 ‘window-text-change-functions’ ウィンドウのテキスト変更時の再表示で呼び出す関数。 Index ***** * Menu: * " in printing: Output Functions. (line 19084) * " in strings: Syntax for Strings. (line 2042) * ## read syntax: Symbol Type. (line 1746) * #$: Docs and Compilation. (line 16286) * #' syntax: Anonymous Functions. (line 12440) * #( read syntax: Text Props and Strings. (line 2140) * #@COUNT: Docs and Compilation. (line 16286) * #COLON read syntax: Symbol Type. (line 1746) * #N# read syntax: Circular Objects. (line 2613) * #N= read syntax: Circular Objects. (line 2613) * #^ read syntax: Char-Table Type. (line 2191) * $ in display: Truncation. (line 53692) * $ in regexp: Regexp Special. (line 48310) * %: Arithmetic Operations. (line 3431) * % in format: Formatting Strings. (line 4449) * & in replacement: Replacing Match. (line 48988) * &optional: Argument List. (line 11891) * &rest: Argument List. (line 11891) * ' for quoting: Quoting. (line 8431) * ( in regexp: Regexp Backslash. (line 48457) * (?: in regexp: Regexp Backslash. (line 48475) * (...) in lists: Cons Cell Type. (line 1808) * ) in regexp: Regexp Backslash. (line 48457) * *: Arithmetic Operations. (line 3388) * * in interactive: Using Interactive. (line 21402) * * in regexp: Regexp Special. (line 48184) * *scratch*: Auto Major Mode. (line 26973) * +: Arithmetic Operations. (line 3364) * + in regexp: Regexp Special. (line 48215) * , (with backquote): Backquote. (line 8471) * ,@ (with backquote): Backquote. (line 8484) * -: Arithmetic Operations. (line 3375) * --enable-locallisppath option to configure: Building Emacs. (line 64491) * –enable-profiling option of configure: Profiling. (line 18698) * . in lists: Dotted Pair Notation. (line 1917) * . in regexp: Regexp Special. (line 48179) * .emacs: Init File. (line 59800) * /: Arithmetic Operations. (line 3399) * /=: Comparison of Numbers. (line 3212) * /dev/tty: Serial Ports. (line 53074) * 1+: Arithmetic Operations. (line 3341) * 1-: Arithmetic Operations. (line 3361) * 1value: Test Coverage. (line 18648) * 2C-mode-map: Prefix Keys. (line 24473) * 2D box: Face Attributes. (line 55443) * 3D box: Face Attributes. (line 55443) * ; in comment: Comments. (line 1444) * <: Comparison of Numbers. (line 3216) * <=: Comparison of Numbers. (line 3220) * =: Comparison of Numbers. (line 3203) * >: Comparison of Numbers. (line 3224) * >=: Comparison of Numbers. (line 3228) * ? in character constant: Basic Char Syntax. (line 1530) * ? in minibuffer: Text from Minibuffer. (line 19629) * ? in regexp: Regexp Special. (line 48221) * @ in interactive: Using Interactive. (line 21405) * [ in regexp: Regexp Special. (line 48237) * [...] (Edebug): Specification List. (line 18293) * \ in character constant: General Escape Syntax. (line 1592) * \ in display: Truncation. (line 53692) * \ in printing: Output Functions. (line 19084) * \ in regexp: Regexp Special. (line 48321) * \ in replacement: Replacing Match. (line 48996) * \ in strings: Syntax for Strings. (line 2042) * \ in symbols: Symbol Type. (line 1712) * \' in regexp: Regexp Backslash. (line 48563) * \< in regexp: Regexp Backslash. (line 48583) * \= in regexp: Regexp Backslash. (line 48567) * \> in regexp: Regexp Backslash. (line 48587) * \a: Basic Char Syntax. (line 1550) * \b: Basic Char Syntax. (line 1550) * \b in regexp: Regexp Backslash. (line 48571) * \B in regexp: Regexp Backslash. (line 48579) * \e: Basic Char Syntax. (line 1550) * \f: Basic Char Syntax. (line 1550) * \n: Basic Char Syntax. (line 1550) * \n in print: Output Variables. (line 19221) * \N in replacement: Replacing Match. (line 48991) * \r: Basic Char Syntax. (line 1550) * \s: Basic Char Syntax. (line 1550) * \s in regexp: Regexp Backslash. (line 48533) * \S in regexp: Regexp Backslash. (line 48540) * \t: Basic Char Syntax. (line 1550) * \v: Basic Char Syntax. (line 1550) * \w in regexp: Regexp Backslash. (line 48525) * \W in regexp: Regexp Backslash. (line 48530) * \_< in regexp: Regexp Backslash. (line 48592) * \_> in regexp: Regexp Backslash. (line 48597) * \` in regexp: Regexp Backslash. (line 48559) * ] in regexp: Regexp Special. (line 48237) * ^ in interactive: Using Interactive. (line 21409) * ^ in regexp: Regexp Special. (line 48280) * `: Backquote. (line 8460) * ‘ (list substitution): Backquote. (line 8460) * | in regexp: Regexp Backslash. (line 48429) * abbrev: Abbrevs. (line 50374) * abbrev properties: Abbrev Properties. (line 50706) * abbrev table properties: Abbrev Table Properties. (line 50739) * abbrev tables: Abbrev Tables. (line 50411) * abbrev tables in modes: Major Mode Conventions. (line 26786) * abbrev-all-caps: Abbrev Expansion. (line 50608) * abbrev-expand-function: Abbrev Expansion. (line 50640) * abbrev-expansion: Abbrev Expansion. (line 50570) * abbrev-file-name: Abbrev Files. (line 50524) * abbrev-get: Abbrev Properties. (line 50713) * abbrev-insert: Abbrev Expansion. (line 50589) * abbrev-map: Standard Keymaps. (line 66058) * abbrev-minor-mode-table-alist: Standard Abbrev Tables. (line 50684) * abbrev-prefix-mark: Abbrev Expansion. (line 50597) * abbrev-put: Abbrev Properties. (line 50710) * abbrev-start-location: Abbrev Expansion. (line 50613) * abbrev-start-location-buffer: Abbrev Expansion. (line 50620) * abbrev-symbol: Abbrev Expansion. (line 50563) * abbrev-table-get: Abbrev Table Properties. (line 50746) * abbrev-table-name-list: Abbrev Tables. (line 50447) * abbrev-table-p: Abbrev Tables. (line 50419) * abbrev-table-put: Abbrev Table Properties. (line 50743) * abbreviate-file-name: Directory Names. (line 32175) * abbreviated file names: Directory Names. (line 32175) * abbrevs, looking up and expanding: Abbrev Expansion. (line 50559) * abbrevs-changed: Abbrev Files. (line 50544) * abnormal hook: Hooks. (line 26519) * abort-recursive-edit: Recursive Editing. (line 23918) * aborting: Recursive Editing. (line 23863) * abs: Comparison of Numbers. (line 3250) * absolute file name: Relative File Names. (line 32055) * absolute position: Frame Layout. (line 39012) * accept input from processes: Accepting Output. (line 52183) * accept-change-group: Atomic Changes. (line 46194) * accept-process-output: Accepting Output. (line 52188) * access control list: Extended Attributes. (line 31584) * access minibuffer contents: Minibuffer Contents. (line 21136) * access-file: Testing Accessibility. (line 31221) * accessibility of a file: Testing Accessibility. (line 31157) * accessible portion (of a buffer): Narrowing. (line 41811) * accessible-keymaps: Scanning Keymaps. (line 25515) * accessing documentation strings: Accessing Documentation. (line 29977) * accessing hash tables: Hash Access. (line 7398) * accessing plist properties: Plist Access. (line 6053) * ACL entries: Extended Attributes. (line 31584) * acos: Math Functions. (line 3723) * action (button property): Button Properties. (line 58329) * action alist, for display-buffer: Choosing Window. (line 36725) * action function, for display-buffer: Choosing Window. (line 36725) * action, customization keyword: Type Keywords. (line 14875) * activate-change-group: Atomic Changes. (line 46185) * activate-mark-hook: The Mark. (line 42335) * active display table: Active Display Table. (line 59047) * active keymap: Active Keymaps. (line 24544) * active keymap, controlling: Controlling Active Maps. (line 24684) * active-minibuffer-window: Minibuffer Windows. (line 21082) * adaptive-fill-first-line-regexp: Adaptive Fill. (line 43915) * adaptive-fill-function: Adaptive Fill. (line 43926) * adaptive-fill-mode: Adaptive Fill. (line 43872) * adaptive-fill-regexp: Adaptive Fill. (line 43907) * add-face-text-property: Changing Properties. (line 44734) * add-function: Core Advising Primitives. (line 12832) * add-hook: Setting Hooks. (line 26583) * add-name-to-file: Changing Files. (line 31702) * add-text-properties: Changing Properties. (line 44670) * add-to-history: Minibuffer History. (line 19753) * add-to-invisibility-spec: Invisible Text. (line 54316) * add-to-list: List Variables. (line 5279) * add-to-ordered-list: List Variables. (line 5313) * address field of register: Cons Cell Type. (line 1787) * adjust-window-trailing-edge: Resizing Windows. (line 35495) * adjusting point: Adjusting Point. (line 22047) * advertised binding: Keys in Documentation. (line 30205) * advice, add and remove: Core Advising Primitives. (line 12832) * advice-add: Advising Named Functions. (line 12972) * advice-eval-interactive-spec: Core Advising Primitives. (line 12912) * advice-function-mapc: Core Advising Primitives. (line 12907) * advice-function-member-p: Core Advising Primitives. (line 12902) * advice-mapc: Advising Named Functions. (line 12985) * advice-member-p: Advising Named Functions. (line 12981) * advice-remove: Advising Named Functions. (line 12977) * advising functions: Advising Functions. (line 12774) * advising named functions: Advising Named Functions. (line 12922) * after-change-functions: Change Hooks. (line 46246) * after-change-major-mode-hook: Mode Hooks. (line 27266) * after-find-file: Subroutines of Visiting. (line 30726) * after-init-hook: Init File. (line 59852) * after-init-time: Startup Summary. (line 59672) * after-insert-file-functions: Format Conversion Piecemeal. (line 33153) * after-load-functions: Hooks for Loading. (line 15989) * after-make-frame-functions: Creating Frames. (line 38640) * after-revert-hook: Reverting. (line 33782) * after-save-hook: Saving Buffers. (line 30887) * after-setting-font-hook: Standard Hooks. (line 66266) * after-string (overlay property): Overlay Properties. (line 55031) * alias, for coding systems: Coding System Basics. (line 47142) * alias, for faces: Face Functions. (line 56013) * alias, for functions: Defining Functions. (line 12088) * alias, for variables: Variable Aliases. (line 11425) * alist: Association Lists. (line 5765) * alist vs. plist: Plists and Alists. (line 6025) * alist-get: Association Lists. (line 5876) * all-completions: Basic Completion. (line 19960) * alpha, a frame parameter: Font and Color Parameters. (line 39896) * alt characters: Other Char Bits. (line 1685) * alternatives, defining: Generic Commands. (line 21721) * amalgamating commands, and undo: Undo. (line 43514) * and: Combining Conditions. (line 9029) * animation: Multi-Frame Images. (line 58110) * anonymous face: Faces. (line 55307) * anonymous function: Anonymous Functions. (line 12397) * apostrophe for quoting: Quoting. (line 8431) * append: Building Lists. (line 5106) * append-to-file: Writing to Files. (line 30990) * apply: Calling Functions. (line 12240) * apply, and debugging: Internals of Debugger. (line 17167) * apply-partially: Calling Functions. (line 12274) * applying customizations: Applying Customizations. (line 14991) * apropos: Help Functions. (line 30328) * aref: Array Functions. (line 6784) * args, customization keyword: Composite Types. (line 14779) * argument: What Is a Function. (line 11673) * argument binding: Argument List. (line 11880) * argument lists, features: Argument List. (line 11880) * arguments for shell commands: Shell Arguments. (line 50899) * arguments, interactive entry: Using Interactive. (line 21346) * arguments, reading: Minibuffers. (line 19328) * argv: Command-Line Arguments. (line 59993) * arith-error example: Handling Errors. (line 9725) * arith-error in division: Arithmetic Operations. (line 3427) * arithmetic operations: Arithmetic Operations. (line 3332) * arithmetic shift: Bitwise Operations. (line 3583) * array: Arrays. (line 6719) * array elements: Array Functions. (line 6785) * arrayp: Array Functions. (line 6773) * ASCII character codes: Character Type. (line 1510) * ASCII control characters: Usual Display. (line 58905) * ascii-case-table: Case Tables. (line 4772) * aset: Array Functions. (line 6797) * ash: Bitwise Operations. (line 3582) * asin: Math Functions. (line 3718) * ask-user-about-lock: File Locks. (line 31114) * ask-user-about-supersession-threat: Modification Time. (line 34325) * asking the user questions: Yes-or-No Queries. (line 20850) * assoc: Association Lists. (line 5813) * assoc-default: Association Lists. (line 5916) * assoc-string: Text Comparison. (line 4311) * association list: Association Lists. (line 5765) * assq: Association Lists. (line 5852) * assq-delete-all: Association Lists. (line 5971) * asynchronous subprocess: Asynchronous Processes. (line 51233) * atan: Math Functions. (line 3728) * atom: List-related Predicates. (line 4866) * atomic changes: Atomic Changes. (line 46151) * atoms: Cons Cell Type. (line 1805) * attributes of text: Text Properties. (line 44548) * Auto Fill mode: Auto Filling. (line 43937) * auto-coding-alist: Default Coding Systems. (line 47500) * auto-coding-functions: Default Coding Systems. (line 47544) * auto-coding-regexp-alist: Default Coding Systems. (line 47469) * auto-fill-chars: Auto Filling. (line 43959) * auto-fill-function: Auto Filling. (line 43945) * auto-hscroll-mode: Horizontal Scrolling. (line 37938) * auto-lower, a frame parameter: Management Parameters. (line 39742) * auto-mode-alist: Auto Major Mode. (line 26996) * auto-raise, a frame parameter: Management Parameters. (line 39738) * auto-raise-tool-bar-buttons: Tool Bar. (line 26293) * auto-resize-tool-bars: Tool Bar. (line 26281) * auto-save-default: Auto-Saving. (line 33626) * auto-save-file-name-p: Auto-Saving. (line 33534) * auto-save-hook: Auto-Saving. (line 33622) * auto-save-interval: Auto-Saving. (line 33605) * auto-save-list-file-name: Auto-Saving. (line 33679) * auto-save-list-file-prefix: Auto-Saving. (line 33696) * auto-save-mode: Auto-Saving. (line 33524) * auto-save-timeout: Auto-Saving. (line 33611) * auto-save-visited-file-name: Auto-Saving. (line 33585) * auto-window-vscroll: Vertical Scrolling. (line 37899) * autoload: Autoload. (line 15520) * autoload <1>: Autoload. (line 15502) * autoload cookie: Autoload. (line 15596) * autoload errors: Autoload. (line 15582) * autoload object: What Is a Function. (line 11750) * autoload-do-load: Autoload. (line 15688) * autoloadp: Autoload. (line 15575) * automatic face assignment: Auto Faces. (line 56029) * automatically buffer-local: Intro to Buffer-Local. (line 10842) * back-to-indentation: Motion by Indent. (line 44458) * background-color, a frame parameter: Font and Color Parameters. (line 39926) * background-mode, a frame parameter: Font and Color Parameters. (line 39862) * backing store: Display Feature Testing. (line 41064) * backquote (list substitution): Backquote. (line 8460) * backslash in character constants: General Escape Syntax. (line 1592) * backslash in regular expressions: Regexp Backslash. (line 48424) * backslash in strings: Syntax for Strings. (line 2042) * backslash in symbols: Symbol Type. (line 1712) * backspace: Basic Char Syntax. (line 1550) * backtrace: Internals of Debugger. (line 17127) * backtrace-debug: Internals of Debugger. (line 17173) * backtrace-frame: Internals of Debugger. (line 17190) * backtracking: Backtracking. (line 18357) * backtracking and POSIX regular expressions: POSIX Regexps. (line 48904) * backtracking and regular expressions: Regexp Special. (line 48193) * backup file: Backup Files. (line 33182) * backup files, rename or copy: Rename or Copy. (line 33302) * backup-buffer: Making Backups. (line 33205) * backup-by-copying: Rename or Copy. (line 33325) * backup-by-copying-when-linked: Rename or Copy. (line 33332) * backup-by-copying-when-mismatch: Rename or Copy. (line 33340) * backup-by-copying-when-privileged-mismatch: Rename or Copy. (line 33354) * backup-directory-alist: Making Backups. (line 33266) * backup-enable-predicate: Making Backups. (line 33242) * backup-file-name-p: Backup Names. (line 33426) * backup-inhibited: Making Backups. (line 33254) * backups and auto-saving: Backups and Auto-Saving. (line 33173) * backward-button: Button Buffer Commands. (line 58539) * backward-char: Character Motion. (line 41240) * backward-delete-char-untabify: Deletion. (line 42910) * backward-delete-char-untabify-method: Deletion. (line 42927) * backward-list: List Motion. (line 41619) * backward-prefix-chars: Motion and Syntax. (line 49933) * backward-sexp: List Motion. (line 41659) * backward-to-indentation: Motion by Indent. (line 44462) * backward-up-list: List Motion. (line 41633) * backward-word: Word Motion. (line 41277) * backward-word-strictly: Word Motion. (line 41310) * balance-windows: Resizing Windows. (line 35633) * balance-windows-area: Resizing Windows. (line 35641) * balanced parenthesis motion: List Motion. (line 41605) * balancing parentheses: Blinking. (line 58833) * balancing window sizes: Resizing Windows. (line 35633) * barf-if-buffer-read-only: Read Only Buffers. (line 34407) * base 64 encoding: Base 64. (line 45896) * base buffer: Indirect Buffers. (line 34718) * base coding system: Coding System Basics. (line 47099) * base direction of a paragraph: Bidirectional Display. (line 59420) * base for reading an integer: Integer Basics. (line 3004) * base location, package archive: Package Archives. (line 62216) * base remapping, faces: Face Remapping. (line 55931) * base64-decode-region: Base 64. (line 45922) * base64-decode-string: Base 64. (line 45929) * base64-encode-region: Base 64. (line 45901) * base64-encode-string: Base 64. (line 45912) * basic code (of input character): Keyboard Events. (line 22097) * basic faces: Basic Faces. (line 56061) * batch mode: Batch Mode. (line 61307) * batch-byte-compile: Compilation Functions. (line 16238) * baud, in serial connections: Serial Ports. (line 53181) * baud-rate: Terminal Output. (line 61168) * beep: Beeping. (line 59233) * before point, insertion: Insertion. (line 42689) * before-change-functions: Change Hooks. (line 46240) * before-hack-local-variables-hook: File Local Variables. (line 11235) * before-init-hook: Init File. (line 59846) * before-init-time: Startup Summary. (line 59613) * before-make-frame-hook: Creating Frames. (line 38636) * before-revert-hook: Reverting. (line 33777) * before-save-hook: Saving Buffers. (line 30880) * before-string (overlay property): Overlay Properties. (line 55026) * beginning of line: Text Lines. (line 41405) * beginning of line in regexp: Regexp Special. (line 48298) * beginning-of-buffer: Buffer End Motion. (line 41332) * beginning-of-defun: List Motion. (line 41663) * beginning-of-defun-function: List Motion. (line 41684) * beginning-of-line: Text Lines. (line 41365) * bell: Beeping. (line 59223) * bell character: Basic Char Syntax. (line 1550) * benchmark.el: Profiling. (line 18694) * benchmarking: Profiling. (line 18694) * bidi-display-reordering: Bidirectional Display. (line 59378) * bidi-find-overridden-directionality: Bidirectional Display. (line 59543) * bidi-paragraph-direction: Bidirectional Display. (line 59434) * bidi-string-mark-left-to-right: Bidirectional Display. (line 59499) * bidirectional class of characters: Character Properties. (line 46684) * bidirectional display: Bidirectional Display. (line 59358) * bidirectional reordering: Bidirectional Display. (line 59368) * big endian: Bindat Spec. (line 53253) * binary coding system: Coding System Basics. (line 47116) * binary I/O in batch mode: Input Functions. (line 18945) * bindat-get-field: Bindat Functions. (line 53405) * bindat-ip-to-string: Bindat Functions. (line 53436) * bindat-length: Bindat Functions. (line 53423) * bindat-pack: Bindat Functions. (line 53426) * bindat-unpack: Bindat Functions. (line 53396) * binding arguments: Argument List. (line 11880) * binding local variables: Local Variables. (line 10021) * binding of a key: Keymap Basics. (line 24132) * bitmap-spec-p: Face Attributes. (line 55529) * bitmaps, fringe: Fringe Bitmaps. (line 56858) * bitwise arithmetic: Bitwise Operations. (line 3510) * blink-cursor-alist: Cursor Parameters. (line 39834) * blink-matching-delay: Blinking. (line 58849) * blink-matching-open: Blinking. (line 58854) * blink-matching-paren: Blinking. (line 58842) * blink-matching-paren-distance: Blinking. (line 58845) * blink-paren-function: Blinking. (line 58836) * blinking parentheses: Blinking. (line 58833) * bobp: Near Point. (line 42499) * body height of a window: Window Sizes. (line 35297) * body of a window: Window Sizes. (line 35182) * body of function: Lambda Components. (line 11839) * body size of a window: Window Sizes. (line 35336) * body width of a window: Window Sizes. (line 35315) * bolp: Near Point. (line 42509) * bool-vector: Bool-Vectors. (line 7095) * bool-vector-count-consecutive: Bool-Vectors. (line 7136) * bool-vector-count-population: Bool-Vectors. (line 7140) * bool-vector-exclusive-or: Bool-Vectors. (line 7106) * bool-vector-intersection: Bool-Vectors. (line 7117) * bool-vector-not: Bool-Vectors. (line 7127) * bool-vector-p: Bool-Vectors. (line 7099) * bool-vector-set-difference: Bool-Vectors. (line 7122) * bool-vector-subsetp: Bool-Vectors. (line 7132) * bool-vector-union: Bool-Vectors. (line 7112) * Bool-vectors: Bool-Vectors. (line 7081) * boolean: nil and t. (line 1070) * booleanp: nil and t. (line 1098) * border-color, a frame parameter: Font and Color Parameters. (line 39938) * border-width, a frame parameter: Layout Parameters. (line 39632) * bottom dividers: Window Dividers. (line 57142) * bottom-divider-width, a frame parameter: Layout Parameters. (line 39673) * boundp: Void Variables. (line 10188) * box diagrams, for lists: Box Diagrams. (line 1837) * break: Debugger. (line 16701) * breakpoints (Edebug): Breakpoints. (line 17575) * bucket (in obarray): Creating Symbols. (line 7671) * buffer: Buffers. (line 33797) * buffer boundaries, indicating: Fringe Indicators. (line 56747) * buffer contents: Text. (line 42441) * buffer file name: Buffer File Name. (line 34073) * buffer gap: Buffer Gap. (line 34828) * buffer input stream: Input Streams. (line 18767) * buffer internals: Buffer Internals. (line 65239) * buffer list: Buffer List. (line 34419) * buffer modification: Buffer Modification. (line 34196) * buffer names: Buffer Names. (line 33988) * buffer output stream: Output Streams. (line 18968) * buffer portion as string: Buffer Contents. (line 42522) * buffer position: Positions. (line 41123) * buffer text notation: Buffer Text Notation. (line 1158) * buffer, read-only: Read Only Buffers. (line 34346) * buffer-access-fontified-property: Lazy Properties. (line 45385) * buffer-access-fontify-functions: Lazy Properties. (line 45372) * buffer-auto-save-file-format: Format Conversion Round-Trip. (line 33075) * buffer-auto-save-file-name: Auto-Saving. (line 33517) * buffer-backed-up: Making Backups. (line 33221) * buffer-base-buffer: Indirect Buffers. (line 34771) * buffer-chars-modified-tick: Buffer Modification. (line 34247) * buffer-disable-undo: Maintaining Undo. (line 43572) * buffer-display-count: Buffers and Windows. (line 36504) * buffer-display-table: Active Display Table. (line 59067) * buffer-display-time: Buffers and Windows. (line 36509) * buffer-enable-undo: Maintaining Undo. (line 43563) * buffer-end: Point. (line 41185) * buffer-file-coding-system: Encoding and I/O. (line 47162) * buffer-file-format: Format Conversion Round-Trip. (line 33032) * buffer-file-name: Buffer File Name. (line 34089) * buffer-file-name <1>: Buffer File Name. (line 34080) * buffer-file-number: Buffer File Name. (line 34110) * buffer-file-truename: Buffer File Name. (line 34103) * buffer-invisibility-spec: Invisible Text. (line 54287) * buffer-list: Buffer List. (line 34442) * buffer-list, a frame parameter: Buffer Parameters. (line 39718) * buffer-list-update-hook: Buffer List. (line 34551) * buffer-list-update-hook <1>: Standard Hooks. (line 66279) * buffer-live-p: Killing Buffers. (line 34711) * buffer-local variables: Buffer-Local Variables. (line 10795) * buffer-local variables in modes: Major Mode Conventions. (line 26816) * buffer-local-value: Creating Buffer-Local. (line 10985) * buffer-local-variables: Creating Buffer-Local. (line 10991) * buffer-modified-p: Buffer Modification. (line 34212) * buffer-modified-tick: Buffer Modification. (line 34241) * buffer-name: Buffer Names. (line 34000) * buffer-name-history: Minibuffer History. (line 19796) * buffer-narrowed-p: Narrowing. (line 41856) * buffer-offer-save: Killing Buffers. (line 34695) * buffer-predicate, a frame parameter: Buffer Parameters. (line 39711) * buffer-quit-function: Standard Hooks. (line 66283) * buffer-read-only: Read Only Buffers. (line 34369) * buffer-save-without-query: Killing Buffers. (line 34704) * buffer-saved-size: Auto-Saving. (line 33663) * buffer-size: Point. (line 41189) * buffer-stale-function: Reverting. (line 33787) * buffer-string: Buffer Contents. (line 42558) * buffer-substring: Buffer Contents. (line 42525) * buffer-substring-filters: Buffer Contents. (line 42614) * buffer-substring-no-properties: Buffer Contents. (line 42553) * buffer-substring-with-bidi-context: Bidirectional Display. (line 59571) * buffer-swap-text: Swapping Text. (line 34801) * buffer-undo-list: Undo. (line 43434) * bufferp: Buffer Basics. (line 33843) * bufferpos-to-filepos: Text Representations. (line 46387) * buffers to display on frame: Buffer Parameters. (line 39698) * buffers without undo information: Buffer Names. (line 33994) * buffers, controlled in windows: Buffers and Windows. (line 36470) * buffers, creating: Creating Buffers. (line 34561) * buffers, killing: Killing Buffers. (line 34617) * bugs: Caveats. (line 1013) * bugs in this manual: Caveats. (line 994) * building Emacs: Building Emacs. (line 64423) * building lists: Building Lists. (line 5053) * built-in function: What Is a Function. (line 11700) * bury-buffer: Buffer List. (line 34514) * butlast: List Elements. (line 5040) * button (button property): Button Properties. (line 58366) * button buffer commands: Button Buffer Commands. (line 58505) * button properties: Button Properties. (line 58323) * button types: Button Types. (line 58376) * button-activate: Manipulating Buttons. (line 58471) * button-at: Manipulating Buttons. (line 58488) * button-down event: Button-Down Events. (line 22423) * button-end: Manipulating Buttons. (line 58462) * button-face, customization keyword: Type Keywords. (line 14878) * button-get: Manipulating Buttons. (line 58465) * button-has-type-p: Manipulating Buttons. (line 58484) * button-label: Manipulating Buttons. (line 58478) * button-prefix, customization keyword: Type Keywords. (line 14883) * button-put: Manipulating Buttons. (line 58468) * button-start: Manipulating Buttons. (line 58459) * button-suffix, customization keyword: Type Keywords. (line 14883) * button-type: Manipulating Buttons. (line 58481) * button-type-get: Manipulating Buttons. (line 58496) * button-type-put: Manipulating Buttons. (line 58493) * button-type-subtype-p: Manipulating Buttons. (line 58499) * buttons in buffers: Buttons. (line 58302) * byte compilation: Byte Compilation. (line 16073) * byte compiler warnings, how to avoid: Warning Tips. (line 63961) * byte packing and unpacking: Byte Packing. (line 53232) * byte to string: Converting Representations. (line 46530) * byte-boolean-vars: Variables with Restricted Values. (line 11518) * byte-boolean-vars <1>: Writing Emacs Primitives. (line 65086) * byte-code: Byte Compilation. (line 16073) * byte-code function: Byte-Code Objects. (line 16484) * byte-code object: Byte-Code Objects. (line 16484) * byte-code-function-p: What Is a Function. (line 11774) * byte-compile: Compilation Functions. (line 16149) * byte-compile-dynamic: Dynamic Loading. (line 16334) * byte-compile-dynamic-docstrings: Docs and Compilation. (line 16271) * byte-compile-file: Compilation Functions. (line 16188) * byte-compiling macros: Compiling Macros. (line 13606) * byte-compiling require: Named Features. (line 15791) * byte-recompile-directory: Compilation Functions. (line 16218) * byte-to-position: Text Representations. (line 46375) * byte-to-string: Converting Representations. (line 46529) * bytes: Strings and Characters. (line 3802) * bytesize, in serial connections: Serial Ports. (line 53181) * C programming language: C Dialect. (line 64932) * C-c: Prefix Keys. (line 24454) * C-g: Quitting. (line 23622) * C-h: Prefix Keys. (line 24451) * C-M-x: Instrumenting. (line 17308) * C-x: Prefix Keys. (line 24460) * C-x 4: Prefix Keys. (line 24467) * C-x 5: Prefix Keys. (line 24470) * C-x 6: Prefix Keys. (line 24473) * C-x C-a C-m: Edebug Execution Modes. (line 17426) * C-x : Prefix Keys. (line 24464) * C-x v: Prefix Keys. (line 24476) * C-x X =: Coverage Testing. (line 17958) * caar: List Elements. (line 5028) * cadr: List Elements. (line 5031) * calendrical computations: Time Calculations. (line 60847) * calendrical information: Time Conversion. (line 60564) * call stack: Internals of Debugger. (line 17128) * call-interactively: Interactive Call. (line 21772) * call-process: Synchronous Processes. (line 50996) * call-process, command-line arguments from minibuffer: Shell Arguments. (line 50932) * call-process-region: Synchronous Processes. (line 51145) * call-process-shell-command: Synchronous Processes. (line 51193) * called-interactively-p: Distinguish Interactive. (line 21881) * calling a function: Calling Functions. (line 12192) * cancel-change-group: Atomic Changes. (line 46198) * cancel-debug-on-entry: Function Debugging. (line 16873) * cancel-timer: Timers. (line 60987) * canonical character height: Frame Font. (line 39098) * canonical character width: Frame Font. (line 39098) * capitalization: Case Conversion. (line 4649) * capitalize: Case Conversion. (line 4648) * capitalize-region: Case Changes. (line 44480) * capitalize-word: Case Changes. (line 44516) * car: List Elements. (line 4902) * car-safe: List Elements. (line 4928) * case conversion in buffers: Case Changes. (line 44475) * case conversion in Lisp: Case Conversion. (line 4609) * case in replacements: Replacing Match. (line 48960) * case-fold-search: Searching and Case. (line 48121) * case-replace: Searching and Case. (line 48126) * case-table-p: Case Tables. (line 4741) * catch: Catch and Throw. (line 9336) * categories of characters: Categories. (line 50237) * category (overlay property): Overlay Properties. (line 54924) * category (text property): Special Properties. (line 44927) * category set: Categories. (line 50252) * category table: Categories. (line 50243) * category, regexp search for: Regexp Backslash. (line 48542) * category-docstring: Categories. (line 50290) * category-set-mnemonics: Categories. (line 50349) * category-table: Categories. (line 50304) * category-table-p: Categories. (line 50307) * cdar: List Elements. (line 5034) * cddr: List Elements. (line 5037) * cdr: List Elements. (line 4915) * cdr-safe: List Elements. (line 4941) * ceiling: Numeric Conversions. (line 3302) * centering point: Textual Scrolling. (line 37804) * change hooks: Change Hooks. (line 46231) * change hooks for a character: Special Properties. (line 45171) * change load-path at configure time: Building Emacs. (line 64491) * change-major-mode-after-body-hook: Mode Hooks. (line 27262) * change-major-mode-hook: Creating Buffer-Local. (line 11061) * changing key bindings: Changing Key Bindings. (line 25063) * changing text properties: Changing Properties. (line 44652) * changing to another buffer: Current Buffer. (line 33850) * changing window size: Resizing Windows. (line 35433) * char-after: Near Point. (line 42456) * char-before: Near Point. (line 42467) * char-category-set: Categories. (line 50339) * char-charset: Character Sets. (line 46879) * char-code-property-description: Character Properties. (line 46804) * char-displayable-p: Fontsets. (line 56383) * char-equal: Text Comparison. (line 4109) * char-or-string-p: Predicates for Strings. (line 3878) * char-property-alias-alist: Examining Properties. (line 44623) * char-script-table: Character Properties. (line 46823) * char-syntax: Syntax Table Functions. (line 49804) * char-table length: Sequence Functions. (line 6145) * char-table-extra-slot: Char-Tables. (line 7003) * char-table-p: Char-Tables. (line 6986) * char-table-parent: Char-Tables. (line 6996) * char-table-range: Char-Tables. (line 7016) * char-table-subtype: Char-Tables. (line 6990) * char-tables: Char-Tables. (line 6936) * char-to-string: String Conversion. (line 4384) * char-width: Size of Displayed Text. (line 55132) * char-width-table: Character Properties. (line 46830) * character alternative (in regexp): Regexp Special. (line 48237) * character arrays: Strings and Characters. (line 3802) * character case: Case Conversion. (line 4609) * character categories: Categories. (line 50237) * character classes in regexp: Char Classes. (line 48366) * character code conversion: Coding System Basics. (line 47060) * character codepoint: Text Representations. (line 46319) * character codes: Character Codes. (line 46593) * character insertion: Commands for Insertion. (line 42795) * character printing: Describing Characters. (line 30268) * character properties: Character Properties. (line 46639) * character set, searching: Scanning Charsets. (line 46942) * character sets: Character Sets. (line 46848) * character to string: String Conversion. (line 4385) * character translation tables: Translation of Characters. (line 46971) * character width on display: Size of Displayed Text. (line 55128) * characterp: Character Codes. (line 46606) * characters: Strings and Characters. (line 3802) * characters for interactive codes: Interactive Codes. (line 21476) * characters, multi-byte: Non-ASCII Characters. (line 46309) * characters, representation in buffers and strings: Text Representations. (line 46329) * charset: Character Sets. (line 46848) * charset, coding systems to encode: Lisp and Coding Systems. (line 47301) * charset, text property: Explicit Encoding. (line 47795) * charset-after: Scanning Charsets. (line 46947) * charset-list: Character Sets. (line 46868) * charset-plist: Character Sets. (line 46889) * charset-priority-list: Character Sets. (line 46871) * charsetp: Character Sets. (line 46864) * charsets supported by a coding system: Lisp and Coding Systems. (line 47356) * check-coding-system: Lisp and Coding Systems. (line 47243) * check-coding-systems-region: Lisp and Coding Systems. (line 47305) * checkdoc: Tips. (line 63587) * checkdoc-current-buffer: Tips. (line 63587) * checkdoc-file: Tips. (line 63587) * checkdoc-minor-mode: Documentation Tips. (line 63994) * checkdoc-package-keywords: Library Headers. (line 64341) * checkdoc-package-keywords-flag: Library Headers. (line 64341) * child process: Processes. (line 50780) * child window: Windows and Frames. (line 34999) * choice, customization types: Splicing into Lists. (line 14807) * circular list: Cons Cells. (line 4837) * circular structure, read syntax: Circular Objects. (line 2613) * cl: Lisp History. (line 1040) * CL note—allocate more storage: Garbage Collection. (line 64626) * CL note—case of letters: Symbol Type. (line 1727) * CL note—default optional arg: Argument List. (line 11918) * CL note—integers vrs eq: Comparison of Numbers. (line 3197) * CL note—interning existing symbol: Creating Symbols. (line 7772) * CL note—lack union, intersection: Sets And Lists. (line 5594) * CL note—no continuable errors: Signaling Errors. (line 9539) * CL note—no setf functions: Adding Generalized Variables. (line 11657) * CL note—only throw in Emacs: Catch and Throw. (line 9330) * CL note—rplaca vs setcar: Modifying Lists. (line 5371) * CL note—special forms compared: Special Forms. (line 8402) * CL note—symbol in obarrays: Creating Symbols. (line 7727) * cl-call-next-method: Generic Functions. (line 12651) * cl-defgeneric: Generic Functions. (line 12511) * cl-defmethod: Generic Functions. (line 12532) * cl-next-method-p: Generic Functions. (line 12659) * classification of file types: Kinds of Files. (line 31277) * classifying events: Classifying Events. (line 22740) * cleanup forms: Cleanups. (line 9873) * clear-abbrev-table: Abbrev Tables. (line 50422) * clear-image-cache: Image Cache. (line 58189) * clear-string: Modifying Strings. (line 4102) * clear-this-command-keys: Command Loop Info. (line 22009) * clear-visited-file-modtime: Modification Time. (line 34287) * click event: Click Events. (line 22246) * clickable buttons in buffers: Buttons. (line 58302) * clickable text: Clickable Text. (line 45405) * clipboard: Window System Selections. (line 40667) * clipboard support (for MS-Windows): Window System Selections. (line 40715) * clone-indirect-buffer: Indirect Buffers. (line 34759) * CLOS: Generic Functions. (line 12483) * closure: Closures. (line 12751) * closures, example of using: Lexical Binding. (line 10690) * clrhash: Hash Access. (line 7418) * coded character set: Character Sets. (line 46848) * codepoint, largest value: Character Codes. (line 46616) * codes, interactive, description of: Interactive Codes. (line 21476) * codespace: Text Representations. (line 46319) * coding conventions in Emacs Lisp: Coding Conventions. (line 63598) * coding standards: Tips. (line 63583) * coding system: Coding Systems. (line 47051) * coding system for operation: Specifying Coding Systems. (line 47627) * coding system, automatically determined: Default Coding Systems. (line 47458) * coding system, validity check: Lisp and Coding Systems. (line 47243) * coding systems for encoding a string: Lisp and Coding Systems. (line 47294) * coding systems for encoding region: Lisp and Coding Systems. (line 47285) * coding systems, priority: Specifying Coding Systems. (line 47670) * coding-system-aliases: Coding System Basics. (line 47142) * coding-system-change-eol-conversion: Lisp and Coding Systems. (line 47270) * coding-system-change-text-conversion: Lisp and Coding Systems. (line 47278) * coding-system-charset-list: Lisp and Coding Systems. (line 47356) * coding-system-eol-type: Lisp and Coding Systems. (line 47250) * coding-system-for-read: Specifying Coding Systems. (line 47631) * coding-system-for-write: Specifying Coding Systems. (line 47655) * coding-system-get: Coding System Basics. (line 47125) * coding-system-list: Lisp and Coding Systems. (line 47233) * coding-system-p: Lisp and Coding Systems. (line 47239) * coding-system-priority-list: Specifying Coding Systems. (line 47677) * collapse-delayed-warnings: Delayed Warnings. (line 54251) * color names: Color Names. (line 40754) * color-defined-p: Color Names. (line 40772) * color-gray-p: Color Names. (line 40808) * color-supported-p: Color Names. (line 40796) * color-values: Color Names. (line 40814) * colors on text terminals: Text Terminal Colors. (line 40845) * column width: Frame Font. (line 39098) * columns: Columns. (line 44172) * COM1: Serial Ports. (line 53074) * combine-after-change-calls: Change Hooks. (line 46270) * combine-and-quote-strings: Shell Arguments. (line 50959) * combining conditions: Combining Conditions. (line 9019) * command: What Is a Function. (line 11726) * command descriptions: A Sample Function Description. (line 1188) * command history: Command History. (line 23985) * command in keymap: Key Lookup. (line 24888) * command loop: Command Loop. (line 21247) * command loop variables: Command Loop Info. (line 21927) * command loop, recursive: Recursive Editing. (line 23839) * command-debug-status: Internals of Debugger. (line 17181) * command-error-function: Processing of Errors. (line 9561) * command-execute: Interactive Call. (line 21814) * command-history: Command History. (line 23993) * command-line: Command-Line Arguments. (line 59950) * command-line arguments: Command-Line Arguments. (line 59942) * command-line options: Command-Line Arguments. (line 59964) * command-line-args: Command-Line Arguments. (line 59989) * command-line-args-left: Command-Line Arguments. (line 59992) * command-line-functions: Command-Line Arguments. (line 59995) * command-line-processed: Command-Line Arguments. (line 59955) * command-remapping: Remapping Commands. (line 25281) * command-switch-alist: Command-Line Arguments. (line 59963) * commandp: Interactive Call. (line 21754) * commandp example: High-Level Completion. (line 20365) * commands, defining: Defining Commands. (line 21316) * comment style: Syntax Flags. (line 49701) * comment syntax: Syntax Class Table. (line 49630) * comment-end-can-be-escaped: Control Parsing. (line 50161) * commentary, in a Lisp library: Library Headers. (line 64392) * comments: Comments. (line 1444) * comments, Lisp convention for: Comment Tips. (line 64207) * Common Lisp: Lisp History. (line 1024) * compare-buffer-substrings: Comparing Text. (line 42663) * compare-strings: Text Comparison. (line 4290) * compare-window-configurations: Window Configurations. (line 38263) * comparing buffer text: Comparing Text. (line 42660) * comparing file modification time: Modification Time. (line 34260) * comparing numbers: Comparison of Numbers. (line 3168) * comparing time values: Time Calculations. (line 60847) * compilation (Emacs Lisp): Byte Compilation. (line 16073) * compilation functions: Compilation Functions. (line 16124) * compile-defun: Compilation Functions. (line 16178) * compile-time constant: Eval During Compile. (line 16383) * compiled function: Byte-Code Objects. (line 16484) * compiler errors: Compiler Errors. (line 16419) * complete key: Keymap Basics. (line 24132) * completing-read: Minibuffer Completion. (line 20064) * completing-read-function: Minibuffer Completion. (line 20152) * completion: Completion. (line 19851) * completion styles: Completion Variables. (line 20587) * completion table: Basic Completion. (line 19885) * completion table, modifying: Basic Completion. (line 20046) * completion tables, combining: Basic Completion. (line 20046) * completion, file name: File Name Completion. (line 32387) * completion-at-point: Completion in Buffers. (line 20763) * completion-at-point-functions: Completion in Buffers. (line 20770) * completion-auto-help: Completion Commands. (line 20234) * completion-boundaries: Basic Completion. (line 19999) * completion-category-overrides: Completion Variables. (line 20624) * completion-extra-properties: Completion Variables. (line 20643) * completion-ignore-case: Basic Completion. (line 20019) * completion-ignored-extensions: File Name Completion. (line 32442) * completion-in-region: Completion in Buffers. (line 20834) * completion-regexp-list: Basic Completion. (line 20027) * completion-styles: Completion Variables. (line 20587) * completion-styles-alist: Completion Variables. (line 20594) * completion-table-case-fold: Basic Completion. (line 20046) * completion-table-dynamic: Programmed Completion. (line 20740) * completion-table-in-turn: Basic Completion. (line 20046) * completion-table-merge: Basic Completion. (line 20046) * completion-table-subvert: Basic Completion. (line 20046) * completion-table-with-cache: Programmed Completion. (line 20754) * completion-table-with-predicate: Basic Completion. (line 20046) * completion-table-with-quoting: Basic Completion. (line 20046) * completion-table-with-terminator: Basic Completion. (line 20046) * complex arguments: Minibuffers. (line 19328) * complex command: Command History. (line 23985) * composite types (customization): Composite Types. (line 14508) * composition (text property): Special Properties. (line 45237) * composition property, and point display: Adjusting Point. (line 22047) * compute-motion: Screen Lines. (line 41548) * concat: Creating Strings. (line 3971) * concatenating bidirectional strings: Bidirectional Display. (line 59473) * concatenating lists: Rearrangement. (line 5537) * concatenating strings: Creating Strings. (line 3972) * cond: Conditionals. (line 8792) * condition name: Error Symbols. (line 9792) * condition-case: Handling Errors. (line 9663) * condition-case-unless-debug: Handling Errors. (line 9637) * conditional evaluation: Conditionals. (line 8749) * conditional selection of windows: Cyclic Window Ordering. (line 36456) * cons: Building Lists. (line 5058) * cons cells: Building Lists. (line 5053) * cons-cells-consed: Memory Usage. (line 64903) * consing: Building Lists. (line 5072) * consp: List-related Predicates. (line 4862) * constant variables: Constant Variables. (line 9995) * constant variables <1>: Defining Variables. (line 10277) * constrain-to-field: Fields. (line 45628) * content directory, package: Packaging Basics. (line 62031) * continuation lines: Truncation. (line 53692) * continue-process: Signals to Processes. (line 51859) * control character key constants: Changing Key Bindings. (line 25078) * control character printing: Describing Characters. (line 30268) * control characters: Ctl-Char Syntax. (line 1621) * control characters in display: Usual Display. (line 58945) * control characters, reading: Quoted Character Input. (line 23424) * control structures: Control Structures. (line 8653) * Control-X-prefix: Prefix Keys. (line 24460) * controller part, model/view/controller: Abstract Display Example. (line 58782) * controlling terminal: Suspending Emacs. (line 60079) * controlling-tty-p: Suspending Emacs. (line 60167) * conventions for writing major modes: Major Mode Conventions. (line 26674) * conventions for writing minor modes: Minor Mode Conventions. (line 27572) * conversion of strings: String Conversion. (line 4328) * convert buffer position to file byte: Text Representations. (line 46384) * convert file byte to buffer position: Text Representations. (line 46384) * convert-standard-filename: Standard File Names. (line 32496) * converting file names from/to MS-Windows syntax: File Names. (line 31936) * converting numbers: Numeric Conversions. (line 3256) * coordinate, relative to frame: Coordinates and Windows. (line 38019) * coordinates-in-window-p: Coordinates and Windows. (line 38077) * copy-abbrev-table: Abbrev Tables. (line 50425) * copy-alist: Association Lists. (line 5932) * copy-category-table: Categories. (line 50314) * copy-directory: Create/Delete Dirs. (line 32634) * copy-file: Changing Files. (line 31755) * copy-hash-table: Other Hash. (line 7510) * copy-keymap: Creating Keymaps. (line 24340) * copy-marker: Creating Markers. (line 42053) * copy-overlay: Managing Overlays. (line 54781) * copy-region-as-kill: Kill Functions. (line 43144) * copy-sequence: Sequence Functions. (line 6192) * copy-syntax-table: Syntax Table Functions. (line 49758) * copy-tree: Building Lists. (line 5191) * copying alists: Association Lists. (line 5933) * copying bidirectional text, preserve visual order: Bidirectional Display. (line 59561) * copying files: Changing Files. (line 31682) * copying lists: Building Lists. (line 5107) * copying sequences: Sequence Functions. (line 6193) * copying strings: Creating Strings. (line 3972) * copying vectors: Vector Functions. (line 6900) * copysign: Float Basics. (line 3118) * cos: Math Functions. (line 3714) * count-lines: Text Lines. (line 41423) * count-loop: A Sample Function Description. (line 1244) * count-screen-lines: Screen Lines. (line 41499) * count-words: Text Lines. (line 41430) * counting columns: Columns. (line 44172) * coverage testing: Test Coverage. (line 18630) * coverage testing (Edebug): Coverage Testing. (line 17941) * create subprocess: Subprocess Creation. (line 50814) * create-file-buffer: Subroutines of Visiting. (line 30704) * create-fontset-from-fontset-spec: Fontsets. (line 56268) * create-image: Defining Images. (line 57921) * create-lockfiles: File Locks. (line 31111) * creating buffers: Creating Buffers. (line 34561) * creating hash tables: Creating Hash. (line 7281) * creating keymaps: Creating Keymaps. (line 24305) * creating markers: Creating Markers. (line 42010) * creating strings: Creating Strings. (line 3885) * creating, copying and deleting directories: Create/Delete Dirs. (line 32621) * cryptographic hash: Checksum/Hash. (line 45946) * ctl-arrow: Usual Display. (line 58944) * ctl-x-4-map: Prefix Keys. (line 24467) * ctl-x-5-map: Prefix Keys. (line 24470) * ctl-x-map: Prefix Keys. (line 24460) * ctl-x-r-map: Standard Keymaps. (line 66079) * curly quotes: Formatting Strings. (line 4437) * curly quotes <1>: Keys in Documentation. (line 30187) * curly quotes <2>: Documentation Tips. (line 64072) * current binding: Local Variables. (line 10044) * current buffer: Current Buffer. (line 33850) * current buffer mark: The Mark. (line 42216) * current buffer point and mark (Edebug): Edebug Display Update. (line 18042) * current buffer position: Point. (line 41169) * current command: Command Loop Info. (line 21954) * current stack frame: Using Debugger. (line 16932) * current-active-maps: Active Keymaps. (line 24599) * current-bidi-paragraph-direction: Bidirectional Display. (line 59446) * current-buffer: Current Buffer. (line 33862) * current-case-table: Case Tables. (line 4751) * current-column: Columns. (line 44185) * current-fill-column: Margins. (line 43825) * current-frame-configuration: Frame Configurations. (line 40375) * current-global-map: Controlling Active Maps. (line 24693) * current-idle-time: Idle Timers. (line 61050) * current-indentation: Primitive Indent. (line 44225) * current-input-method: Input Methods. (line 47865) * current-input-mode: Input Modes. (line 61116) * current-justification: Filling. (line 43733) * current-kill: Low-Level Kill Ring. (line 43298) * current-left-margin: Margins. (line 43820) * current-local-map: Controlling Active Maps. (line 24704) * current-message: Displaying Messages. (line 53869) * current-minor-mode-maps: Controlling Active Maps. (line 24724) * current-prefix-arg: Prefix Command Arguments. (line 23801) * current-time: Time of Day. (line 60497) * current-time-string: Time of Day. (line 60481) * current-time-zone: Time Zone Rules. (line 60543) * current-window-configuration: Window Configurations. (line 38211) * current-word: Buffer Contents. (line 42622) * currying: Calling Functions. (line 12266) * cursor: Window Point. (line 37421) * cursor (text property): Special Properties. (line 45099) * cursor position for display properties and overlays: Special Properties. (line 45118) * cursor, and frame parameters: Cursor Parameters. (line 39782) * cursor, fringe: Fringe Cursors. (line 56825) * cursor-color, a frame parameter: Font and Color Parameters. (line 39934) * cursor-in-echo-area: Echo Area Customization. (line 54031) * cursor-in-non-selected-windows: Cursor Parameters. (line 39815) * cursor-intangible (text property): Special Properties. (line 45089) * cursor-intangible-mode: Special Properties. (line 45089) * cursor-sensor-functions (text property): Special Properties. (line 45229) * cursor-sensor-mode: Special Properties. (line 45229) * cursor-type: Cursor Parameters. (line 39803) * cursor-type <1>: Cursor Parameters. (line 39807) * cursor-type, a frame parameter: Cursor Parameters. (line 39784) * curved quotes: Formatting Strings. (line 4437) * curved quotes <1>: Keys in Documentation. (line 30187) * curved quotes <2>: Documentation Tips. (line 64072) * cust-print: Printing in Edebug. (line 17862) * custom themes: Custom Themes. (line 15038) * custom-add-frequent-value: Variable Definitions. (line 14356) * custom-initialize-delay: Building Emacs. (line 64510) * custom-known-themes: Custom Themes. (line 15098) * custom-reevaluate-setting: Variable Definitions. (line 14369) * custom-set-faces: Applying Customizations. (line 15021) * custom-set-variables: Applying Customizations. (line 14998) * custom-theme-p: Custom Themes. (line 15093) * custom-theme-set-faces: Custom Themes. (line 15076) * custom-theme-set-variables: Custom Themes. (line 15067) * custom-unlispify-remove-prefixes: Group Definitions. (line 14172) * custom-variable-p: Variable Definitions. (line 14381) * customizable variables, how to define: Variable Definitions. (line 14184) * customization groups, defining: Group Definitions. (line 14126) * customization item: Customization. (line 13965) * customization keywords: Common Keywords. (line 13981) * customization types: Customization Types. (line 14390) * customization types, define new: Defining New Types. (line 14930) * customize-package-emacs-version-alist: Common Keywords. (line 14101) * cyclic ordering of windows: Cyclic Window Ordering. (line 36321) * cygwin-convert-file-name-from-windows: File Names. (line 31936) * cygwin-convert-file-name-to-windows: File Names. (line 31936) * data type: Lisp Data Types. (line 1366) * data-directory: Help Functions. (line 30434) * datagrams: Datagrams. (line 52754) * date-leap-year-p: Time Calculations. (line 60868) * date-to-time: Time Parsing. (line 60649) * deactivate-mark: The Mark. (line 42308) * deactivate-mark <1>: The Mark. (line 42323) * deactivate-mark-hook: The Mark. (line 42336) * debug: Invoking the Debugger. (line 17038) * debug-ignored-errors: Error Debugging. (line 16743) * debug-on-entry: Function Debugging. (line 16835) * debug-on-error: Error Debugging. (line 16721) * debug-on-error use: Processing of Errors. (line 9569) * debug-on-event: Error Debugging. (line 16783) * debug-on-message: Error Debugging. (line 16791) * debug-on-next-call: Internals of Debugger. (line 17166) * debug-on-quit: Infinite Loops. (line 16819) * debug-on-signal: Error Debugging. (line 16766) * debugger: Internals of Debugger. (line 17117) * debugger command list: Debugger Commands. (line 16952) * debugger for Emacs Lisp: Debugger. (line 16701) * debugger, explicit entry: Explicit Debug. (line 16884) * debugger-bury-or-kill: Using Debugger. (line 16910) * debugging errors: Error Debugging. (line 16711) * debugging invalid Lisp syntax: Syntax Errors. (line 18557) * debugging lisp programs: Debugging. (line 16669) * debugging specific functions: Function Debugging. (line 16829) * declare: Declare Form. (line 13254) * declare <1>: Declare Form. (line 13258) * declare-function: Declaring Functions. (line 13334) * declare-function <1>: Declaring Functions. (line 13366) * declaring functions: Declaring Functions. (line 13334) * decode process output: Decoding Output. (line 52150) * decode-char: Character Sets. (line 46909) * decode-coding-inserted-region: Explicit Encoding. (line 47802) * decode-coding-region: Explicit Encoding. (line 47760) * decode-coding-string: Explicit Encoding. (line 47780) * decode-time: Time Conversion. (line 60579) * decoding file formats: Format Conversion. (line 32906) * decoding in coding systems: Explicit Encoding. (line 47697) * decrement field of register: Cons Cell Type. (line 1787) * dedicated window: Dedicated Windows. (line 37243) * def-edebug-spec: Instrumenting Macro Calls. (line 18148) * defalias: Defining Functions. (line 12088) * defalias-fset-function property: Defining Functions. (line 12095) * default argument string: Interactive Codes. (line 21490) * default character height: Frame Font. (line 39092) * default character size: Frame Font. (line 39092) * default character width: Frame Font. (line 39092) * default coding system: Default Coding Systems. (line 47458) * default coding system, functions to determine: Default Coding Systems. (line 47544) * default filter function of a process: Filter Functions. (line 52044) * default font: Frame Font. (line 39092) * default height of character: Frame Font. (line 39092) * default init file: Init File. (line 59817) * default key binding: Format of Keymaps. (line 24212) * default sentinel function of a process: Sentinels. (line 52224) * default value: Default Value. (line 11084) * default value of char-table: Char-Tables. (line 6966) * default width of character: Frame Font. (line 39092) * default-boundp: Default Value. (line 11105) * default-directory: File Name Expansion. (line 32249) * default-file-modes: Changing Files. (line 31861) * default-font-height: Low-Level Font. (line 56662) * default-font-width: Low-Level Font. (line 56658) * default-frame-alist: Initial Parameters. (line 39427) * default-input-method: Input Methods. (line 47871) * default-justification: Filling. (line 43728) * default-minibuffer-frame: Minibuffers and Frames. (line 40153) * default-process-coding-system: Default Coding Systems. (line 47535) * default-text-properties: Examining Properties. (line 44635) * default-value: Default Value. (line 11099) * default.el: Startup Summary. (line 59657) * defconst: Defining Variables. (line 10277) * defcustom: Variable Definitions. (line 14192) * defface: Defining Faces. (line 55547) * defgroup: Group Definitions. (line 14143) * defimage: Defining Images. (line 57939) * define customization group: Group Definitions. (line 14126) * define customization options: Variable Definitions. (line 14184) * define hash comparisons: Defining Hash. (line 7434) * define image: Defining Images. (line 57918) * define new customization types: Defining New Types. (line 14930) * define-abbrev: Defining Abbrevs. (line 50475) * define-abbrev-table: Abbrev Tables. (line 50430) * define-advice: Advising Named Functions. (line 12966) * define-alternatives: Generic Commands. (line 21725) * define-button-type: Button Types. (line 58381) * define-category: Categories. (line 50261) * define-derived-mode: Derived Modes. (line 27069) * define-error: Error Symbols. (line 9792) * define-error <1>: Error Symbols. (line 9807) * define-fringe-bitmap: Customizing Bitmaps. (line 56922) * define-generic-mode: Generic Modes. (line 27394) * define-globalized-minor-mode: Defining Minor Modes. (line 27856) * define-hash-table-test: Defining Hash. (line 7448) * define-inline: Defining Functions. (line 12125) * define-key: Changing Key Bindings. (line 25100) * define-key-after: Modifying Menus. (line 26340) * define-minor-mode: Defining Minor Modes. (line 27711) * define-obsolete-face-alias: Face Functions. (line 56020) * define-obsolete-function-alias: Obsolete Functions. (line 13177) * define-obsolete-variable-alias: Variable Aliases. (line 11467) * define-package: Multi-file Packages. (line 62166) * define-prefix-command: Prefix Keys. (line 24526) * defined-colors: Color Names. (line 40788) * defining a function: Defining Functions. (line 12042) * defining abbrevs: Defining Abbrevs. (line 50465) * defining commands: Defining Commands. (line 21316) * defining customization variables in C: Writing Emacs Primitives. (line 65094) * defining faces: Defining Faces. (line 55536) * defining Lisp variables in C: Writing Emacs Primitives. (line 65086) * defining macros: Defining Macros. (line 13636) * defining menus: Defining Menus. (line 25661) * defining tokens, SMIE: SMIE Lexer. (line 29538) * defining-kbd-macro: Keyboard Macros. (line 24051) * definitions of symbols: Definitions. (line 7622) * defmacro: Defining Macros. (line 13645) * defsubr, Lisp symbol for a primitive: Writing Emacs Primitives. (line 65070) * defsubst: Inline Functions. (line 13214) * deftheme: Custom Themes. (line 15049) * defun: Defining Functions. (line 12045) * DEFUN, C macro to define Lisp primitives: Writing Emacs Primitives. (line 64974) * defun-prompt-regexp: List Motion. (line 41673) * defvar: Defining Variables. (line 10230) * defvar-local: Creating Buffer-Local. (line 10969) * defvaralias: Variable Aliases. (line 11432) * DEFVAR_INT, DEFVAR_LISP, DEFVAR_BOOL: Writing Emacs Primitives. (line 65086) * delay-mode-hooks: Mode Hooks. (line 27253) * delayed warnings: Delayed Warnings. (line 54225) * delayed-warnings-hook: Delayed Warnings. (line 54243) * delayed-warnings-hook <1>: Standard Hooks. (line 66292) * delayed-warnings-list: Delayed Warnings. (line 54229) * delete: Sets And Lists. (line 5702) * delete-and-extract-region: Deletion. (line 42879) * delete-auto-save-file-if-necessary: Auto-Saving. (line 33642) * delete-auto-save-files: Auto-Saving. (line 33650) * delete-backward-char: Deletion. (line 42898) * delete-blank-lines: User-Level Deletion. (line 43031) * delete-by-moving-to-trash: Changing Files. (line 31793) * delete-by-moving-to-trash <1>: Create/Delete Dirs. (line 32655) * delete-char: Deletion. (line 42887) * delete-directory: Create/Delete Dirs. (line 32655) * delete-dups: Sets And Lists. (line 5753) * delete-exited-processes: Deleting Processes. (line 51502) * delete-field: Fields. (line 45625) * delete-file: Changing Files. (line 31793) * delete-frame: Deleting Frames. (line 40063) * delete-frame event: Misc Events. (line 22591) * delete-frame-functions: Deleting Frames. (line 40064) * delete-horizontal-space: User-Level Deletion. (line 42941) * delete-indentation: User-Level Deletion. (line 42968) * delete-minibuffer-contents: Minibuffer Contents. (line 21162) * delete-old-versions: Numbered Backups. (line 33407) * delete-other-windows: Deleting Windows. (line 35908) * delete-overlay: Managing Overlays. (line 54745) * delete-process: Deleting Processes. (line 51508) * delete-region: Deletion. (line 42872) * delete-selection, symbol property: The Mark. (line 42371) * delete-selection-helper: The Mark. (line 42371) * delete-selection-pre-hook: The Mark. (line 42371) * delete-terminal: Multiple Terminals. (line 38694) * delete-terminal-functions: Multiple Terminals. (line 38709) * delete-to-left-margin: Margins. (line 43838) * delete-trailing-whitespace: User-Level Deletion. (line 43041) * delete-window: Deleting Windows. (line 35886) * delete-windows-on: Deleting Windows. (line 35922) * deleting files: Changing Files. (line 31682) * deleting frames: Deleting Frames. (line 40059) * deleting list elements: Sets And Lists. (line 5612) * deleting previous char: Deletion. (line 42899) * deleting processes: Deleting Processes. (line 51487) * deleting text vs killing: Deletion. (line 42851) * deleting whitespace: User-Level Deletion. (line 42942) * deleting windows: Deleting Windows. (line 35877) * delq: Sets And Lists. (line 5611) * dependencies: Packaging Basics. (line 61989) * derived mode: Derived Modes. (line 27062) * derived-mode-p: Derived Modes. (line 27160) * describe characters and events: Describing Characters. (line 30247) * describe-bindings: Scanning Keymaps. (line 25627) * describe-buffer-case-table: Case Tables. (line 4793) * describe-categories: Categories. (line 50366) * describe-current-display-table: Display Tables. (line 59040) * describe-display-table: Display Tables. (line 59036) * describe-mode: Mode Help. (line 27049) * describe-prefix-bindings: Help Functions. (line 30408) * describe-syntax: Syntax Table Functions. (line 49836) * description for interactive codes: Interactive Codes. (line 21476) * description format: Format of Descriptions. (line 1178) * deserializing: Byte Packing. (line 53239) * desktop notifications: Desktop Notifications. (line 61382) * desktop save mode: Desktop Save Mode. (line 29874) * desktop-buffer-mode-handlers: Desktop Save Mode. (line 29898) * desktop-save-buffer: Desktop Save Mode. (line 29884) * destroy-fringe-bitmap: Customizing Bitmaps. (line 56944) * destructive list operations: Modifying Lists. (line 5367) * detect-coding-region: Lisp and Coding Systems. (line 47318) * detect-coding-string: Lisp and Coding Systems. (line 47337) * diagrams, boxed, for lists: Box Diagrams. (line 1837) * dialog boxes: Dialog Boxes. (line 40577) * digit-argument: Prefix Command Arguments. (line 23824) * ding: Beeping. (line 59228) * dir-locals-class-alist: Directory Local Variables. (line 11400) * dir-locals-directory-cache: Directory Local Variables. (line 11405) * dir-locals-file: Directory Local Variables. (line 11333) * dir-locals-set-class-variables: Directory Local Variables. (line 11365) * dir-locals-set-directory-class: Directory Local Variables. (line 11385) * directional overrides: Bidirectional Display. (line 59524) * directory file name: Directory Names. (line 32101) * directory local variables: Directory Local Variables. (line 11322) * directory name: Directory Names. (line 32101) * directory part (of file name): File Name Components. (line 31952) * directory-file-name: Directory Names. (line 32135) * directory-files: Contents of Directories. (line 32520) * directory-files-and-attributes: Contents of Directories. (line 32562) * directory-files-recursively: Contents of Directories. (line 32548) * directory-name-p: Directory Names. (line 32129) * directory-oriented functions: Contents of Directories. (line 32512) * dired-kept-versions: Numbered Backups. (line 33413) * disable-command: Disabling Commands. (line 23965) * disable-point-adjustment: Adjusting Point. (line 22056) * disable-theme: Custom Themes. (line 15121) * disabled: Disabling Commands. (line 23940) * disabled command: Disabling Commands. (line 23935) * disabled-command-function: Disabling Commands. (line 23970) * disabling multibyte: Disabling Multibyte. (line 46438) * disabling undo: Maintaining Undo. (line 43573) * disassemble: Disassembly. (line 16567) * disassembled byte-code: Disassembly. (line 16553) * discard-input: Event Input Misc. (line 23530) * discarding input: Event Input Misc. (line 23531) * dispatch of methods for generic function: Generic Functions. (line 12629) * display (overlay property): Overlay Properties. (line 54957) * display (text property): Display Property. (line 57198) * display action: Choosing Window. (line 36725) * display area: Frame Layout. (line 38955) * display feature testing: Display Feature Testing. (line 40952) * display margins: Display Margins. (line 57452) * display message in echo area: Displaying Messages. (line 53773) * display name on X: Multiple Terminals. (line 38734) * display properties, and bidi reordering of text: Bidirectional Display. (line 59408) * display property, and point display: Adjusting Point. (line 22047) * display specification: Display Property. (line 57198) * display table: Display Tables. (line 58960) * display, a frame parameter: Basic Parameters. (line 39460) * display, abstract: Abstract Display. (line 58557) * display, arbitrary objects: Abstract Display. (line 58557) * display-backing-store: Display Feature Testing. (line 41064) * display-buffer: Choosing Window. (line 36743) * display-buffer-alist: Choosing Window. (line 36785) * display-buffer-at-bottom: Display Action Functions. (line 36942) * display-buffer-base-action: Choosing Window. (line 36795) * display-buffer-below-selected: Display Action Functions. (line 36922) * display-buffer-fallback-action: Choosing Window. (line 36800) * display-buffer-in-previous-window: Display Action Functions. (line 36929) * display-buffer-no-window: Display Action Functions. (line 36955) * display-buffer-overriding-action: Choosing Window. (line 36781) * display-buffer-pop-up-frame: Display Action Functions. (line 36850) * display-buffer-pop-up-window: Display Action Functions. (line 36875) * display-buffer-reuse-window: Display Action Functions. (line 36818) * display-buffer-same-window: Display Action Functions. (line 36812) * display-buffer-use-some-frame: Display Action Functions. (line 36858) * display-buffer-use-some-window: Display Action Functions. (line 36949) * display-color-cells: Display Feature Testing. (line 41093) * display-color-p: Display Feature Testing. (line 40983) * display-completion-list: Completion Commands. (line 20218) * display-delayed-warnings: Delayed Warnings. (line 54251) * display-graphic-p: Display Feature Testing. (line 40973) * display-grayscale-p: Display Feature Testing. (line 40988) * display-images-p: Display Feature Testing. (line 41017) * display-message-or-buffer: Displaying Messages. (line 53850) * display-mm-dimensions-alist: Display Feature Testing. (line 41059) * display-mm-height: Display Feature Testing. (line 41043) * display-mm-width: Display Feature Testing. (line 41051) * display-monitor-attributes-list: Multiple Terminals. (line 38798) * display-mouse-p: Display Feature Testing. (line 40979) * display-pixel-height: Display Feature Testing. (line 41027) * display-pixel-width: Display Feature Testing. (line 41035) * display-planes: Display Feature Testing. (line 41079) * display-popup-menus-p: Display Feature Testing. (line 40966) * display-save-under: Display Feature Testing. (line 41074) * display-screens: Display Feature Testing. (line 41023) * display-selections-p: Display Feature Testing. (line 41012) * display-start position: Window Start and End. (line 37450) * display-supports-face-attributes-p: Display Feature Testing. (line 40992) * display-table-slot: Display Tables. (line 59024) * display-type, a frame parameter: Basic Parameters. (line 39466) * display-visual-class: Display Feature Testing. (line 41085) * display-warning: Warning Basics. (line 54108) * displaying a buffer: Switching Buffers. (line 36572) * displaying faces: Displaying Faces. (line 55853) * displays, multiple: Multiple Terminals. (line 38655) * distinguish interactive calls: Distinguish Interactive. (line 21860) * dnd-protocol-alist: Drag and Drop. (line 40743) * do-auto-save: Auto-Saving. (line 33630) * DOC (documentation) file: Documentation Basics. (line 29952) * doc, customization keyword: Type Keywords. (line 14900) * doc-directory: Accessing Documentation. (line 30130) * Document Object Model: Document Object Model. (line 46049) * documentation: Accessing Documentation. (line 30004) * documentation conventions: Documentation Basics. (line 29937) * documentation for major mode: Mode Help. (line 27044) * documentation notation: Evaluation Notation. (line 1105) * documentation of function: Function Documentation. (line 11956) * documentation strings: Documentation. (line 29913) * documentation strings, conventions and tips: Documentation Tips. (line 63994) * documentation, keys in: Keys in Documentation. (line 30143) * documentation-property: Accessing Documentation. (line 29977) * dolist: Iteration. (line 9153) * DOM: Document Object Model. (line 46049) * dom-node: Document Object Model. (line 46061) * dotimes: Iteration. (line 9164) * dotimes-with-progress-reporter: Progress. (line 53964) * dotted list: Cons Cells. (line 4837) * dotted lists (Edebug): Specification List. (line 18309) * dotted pair notation: Dotted Pair Notation. (line 1917) * double-click events: Repeat Events. (line 22453) * double-click-fuzz: Repeat Events. (line 22520) * double-click-time: Repeat Events. (line 22528) * double-quote in strings: Syntax for Strings. (line 2042) * down-list: List Motion. (line 41637) * downcase: Case Conversion. (line 4620) * downcase-region: Case Changes. (line 44502) * downcase-word: Case Changes. (line 44529) * downcasing in lookup-key: Key Sequence Input. (line 23149) * drag and drop: Drag and Drop. (line 40729) * drag event: Drag Events. (line 22392) * drag-n-drop event: Misc Events. (line 22624) * dribble file: Recording Input. (line 61150) * dump-emacs: Building Emacs. (line 64519) * dumping Emacs: Building Emacs. (line 64440) * dynamic binding: Variable Scoping. (line 10522) * dynamic extent: Variable Scoping. (line 10522) * dynamic libraries: Dynamic Libraries. (line 61818) * dynamic loading of documentation: Docs and Compilation. (line 16254) * dynamic loading of functions: Dynamic Loading. (line 16296) * dynamic modules: Dynamic Modules. (line 16034) * dynamic scope: Variable Scoping. (line 10522) * dynamic-library-alist: Dynamic Libraries. (line 61823) * eager macro expansion: How Programs Do Loading. (line 15236) * easy-menu-define: Easy Menu. (line 26371) * easy-mmode-define-minor-mode: Defining Minor Modes. (line 27807) * echo area: The Echo Area. (line 53759) * echo area customization: Echo Area Customization. (line 54029) * echo-area-clear-hook: Echo Area Customization. (line 54039) * echo-keystrokes: Echo Area Customization. (line 54043) * edebug: Source Breakpoints. (line 17653) * Edebug debugging facility: Edebug. (line 17210) * Edebug execution modes: Edebug Execution Modes. (line 17363) * Edebug specification list: Specification List. (line 18184) * edebug-all-defs: Edebug Options. (line 18452) * edebug-all-forms: Edebug Options. (line 18461) * edebug-continue-kbd-macro: Edebug Options. (line 18515) * edebug-defun: Instrumenting. (line 17323) * edebug-display-freq-count: Coverage Testing. (line 17963) * edebug-eval-macro-args: Instrumenting Macro Calls. (line 18176) * edebug-eval-top-level-form: Instrumenting. (line 17323) * edebug-global-break-condition: Edebug Options. (line 18549) * edebug-initial-mode: Edebug Options. (line 18495) * edebug-on-error: Edebug Options. (line 18537) * edebug-on-quit: Edebug Options. (line 18541) * edebug-print-circle: Printing in Edebug. (line 17892) * edebug-print-length: Printing in Edebug. (line 17871) * edebug-print-level: Printing in Edebug. (line 17875) * edebug-print-trace-after: Trace Buffer. (line 17918) * edebug-print-trace-before: Trace Buffer. (line 17918) * edebug-save-displayed-buffer-points: Edebug Options. (line 18481) * edebug-save-windows: Edebug Options. (line 18470) * edebug-set-global-break-condition: Global Break Condition. (line 17640) * edebug-set-initial-mode: Edebug Execution Modes. (line 17425) * edebug-setup-hook: Edebug Options. (line 18445) * edebug-sit-for-seconds: Edebug Execution Modes. (line 17453) * edebug-temp-display-freq-count: Coverage Testing. (line 17958) * edebug-test-coverage: Edebug Options. (line 18511) * edebug-trace: Edebug Options. (line 18504) * edebug-trace <1>: Trace Buffer. (line 17928) * edebug-tracing: Trace Buffer. (line 17922) * edebug-unwrap-results: Edebug Options. (line 18520) * edge detection, images: Image Descriptors. (line 57639) * edit-and-eval-command: Object from Minibuffer. (line 19675) * editing types: Editing Types. (line 2376) * editor command loop: Command Loop. (line 21247) * eight-bit, a charset: Character Sets. (line 46858) * electric-future-map: A Sample Variable Description. (line 1284) * element (of list): Lists. (line 4800) * elements of sequences: Sequence Functions. (line 6171) * elp.el: Profiling. (line 18691) * elt: Sequence Functions. (line 6170) * Emacs event standard notation: Describing Characters. (line 30254) * Emacs process run time: Processor Run Time. (line 60810) * emacs, a charset: Character Sets. (line 46858) * emacs-build-time: Version Info. (line 1310) * emacs-init-time: Processor Run Time. (line 60839) * emacs-internal coding system: Coding System Basics. (line 47119) * emacs-lisp-docstring-fill-column: Documentation Tips. (line 64009) * emacs-major-version: Version Info. (line 1324) * emacs-minor-version: Version Info. (line 1327) * emacs-pid: System Environment. (line 60372) * emacs-save-session-functions: Session Management. (line 61350) * emacs-session-restore: Session Management. (line 61359) * emacs-startup-hook: Init File. (line 59858) * emacs-uptime: Processor Run Time. (line 60814) * emacs-version: Version Info. (line 1317) * emacs-version <1>: Version Info. (line 1297) * EMACSLOADPATH environment variable: Library Search. (line 15398) * emacs_module_init: Dynamic Modules. (line 16046) * embedded widgets: Xwidgets. (line 58216) * empty lines, indicating: Fringe Indicators. (line 56741) * empty list: Box Diagrams. (line 1869) * empty overlay: Managing Overlays. (line 54719) * empty region: The Region. (line 42415) * emulation-mode-map-alists: Controlling Active Maps. (line 24815) * enable-command: Disabling Commands. (line 23960) * enable-dir-local-variables: Directory Local Variables. (line 11411) * enable-local-eval: File Local Variables. (line 11298) * enable-local-variables: File Local Variables. (line 11183) * enable-multibyte-characters: Text Representations. (line 46361) * enable-multibyte-characters <1>: Disabling Multibyte. (line 46462) * enable-recursive-minibuffers: Recursive Mini. (line 21178) * enable-theme: Custom Themes. (line 15117) * encapsulation, ewoc: Abstract Display. (line 58591) * encode-char: Character Sets. (line 46917) * encode-coding-region: Explicit Encoding. (line 47728) * encode-coding-string: Explicit Encoding. (line 47752) * encode-time: Time Conversion. (line 60612) * encoding file formats: Format Conversion. (line 32906) * encoding in coding systems: Explicit Encoding. (line 47697) * encrypted network connections: Network. (line 52609) * end of line in regexp: Regexp Special. (line 48310) * end-of-buffer: Buffer End Motion. (line 41344) * end-of-defun: List Motion. (line 41668) * end-of-defun-function: List Motion. (line 41691) * end-of-file: Input Functions. (line 18899) * end-of-line: Text Lines. (line 41386) * end-of-line conversion: Coding System Basics. (line 47091) * endianness: Bindat Spec. (line 53253) * environment: Intro Eval. (line 8066) * environment variable access: System Environment. (line 60258) * environment variables, subprocesses: Subprocess Creation. (line 50871) * eobp: Near Point. (line 42504) * EOL conversion: Coding System Basics. (line 47091) * eol conversion of coding system: Lisp and Coding Systems. (line 47270) * eol type of coding system: Lisp and Coding Systems. (line 47250) * eolp: Near Point. (line 42514) * epoch: Time of Day. (line 60464) * eq: Equality Predicates. (line 2854) * eql: Comparison of Numbers. (line 3207) * equal: Equality Predicates. (line 2903) * equal-including-properties: Equality Predicates. (line 2962) * equality: Equality Predicates. (line 2849) * erase-buffer: Deletion. (line 42859) * error: Signaling Errors. (line 9463) * error cleanup: Cleanups. (line 9873) * error debugging: Error Debugging. (line 16711) * error description: Handling Errors. (line 9696) * error display: The Echo Area. (line 53759) * error handler: Handling Errors. (line 9577) * error in debug: Invoking the Debugger. (line 17087) * error message notation: Error Messages. (line 1148) * error name: Error Symbols. (line 9792) * error symbol: Error Symbols. (line 9792) * error-conditions: Error Symbols. (line 9792) * error-message-string: Handling Errors. (line 9719) * errors: Errors. (line 9418) * : Functions for Key Lookup. (line 25029) * esc-map: Prefix Keys. (line 24447) * ESC-prefix: Prefix Keys. (line 24447) * escape (ASCII character): Basic Char Syntax. (line 1550) * escape characters: Output Variables. (line 19221) * escape characters in printing: Output Functions. (line 19084) * escape sequence: Basic Char Syntax. (line 1569) * eval: Eval. (line 8526) * eval during compilation: Eval During Compile. (line 16347) * eval, and debugging: Internals of Debugger. (line 17167) * eval-and-compile: Eval During Compile. (line 16350) * eval-buffer: Eval. (line 8578) * eval-buffer (Edebug): Instrumenting. (line 17316) * eval-current-buffer: Eval. (line 8592) * eval-current-buffer (Edebug): Instrumenting. (line 17316) * eval-defun (Edebug): Instrumenting. (line 17308) * eval-expression (Edebug): Instrumenting. (line 17348) * eval-expression-debug-on-error: Error Debugging. (line 16758) * eval-expression-print-length: Output Variables. (line 19283) * eval-expression-print-level: Output Variables. (line 19284) * eval-minibuffer: Object from Minibuffer. (line 19664) * eval-region: Eval. (line 8558) * eval-region (Edebug): Instrumenting. (line 17316) * eval-when-compile: Eval During Compile. (line 16376) * evaluated expression argument: Interactive Codes. (line 21667) * evaluation: Evaluation. (line 8023) * evaluation error: Local Variables. (line 10119) * evaluation list group: Eval List. (line 17810) * evaluation notation: Evaluation Notation. (line 1105) * evaluation of buffer contents: Eval. (line 8578) * evaluation of special forms: Special Forms. (line 8310) * evaporate (overlay property): Overlay Properties. (line 55044) * even-window-sizes: Choosing Window Options. (line 37077) * event printing: Describing Characters. (line 30268) * event translation: Event Mod. (line 23315) * event type: Classifying Events. (line 22740) * event, reading only one: Reading One Event. (line 23197) * event-basic-type: Classifying Events. (line 22798) * event-click-count: Repeat Events. (line 22514) * event-convert-list: Classifying Events. (line 22823) * event-end: Accessing Mouse. (line 22853) * event-modifiers: Classifying Events. (line 22760) * event-start: Accessing Mouse. (line 22846) * eventp: Input Events. (line 22078) * events: Input Events. (line 22072) * ewoc: Abstract Display. (line 58557) * ewoc-buffer: Abstract Display Functions. (line 58637) * ewoc-collect: Abstract Display Functions. (line 58712) * ewoc-create: Abstract Display Functions. (line 58621) * ewoc-data: Abstract Display Functions. (line 58666) * ewoc-delete: Abstract Display Functions. (line 58704) * ewoc-enter-after: Abstract Display Functions. (line 58653) * ewoc-enter-before: Abstract Display Functions. (line 58652) * ewoc-enter-first: Abstract Display Functions. (line 58647) * ewoc-enter-last: Abstract Display Functions. (line 58648) * ewoc-filter: Abstract Display Functions. (line 58707) * ewoc-get-hf: Abstract Display Functions. (line 58640) * ewoc-goto-next: Abstract Display Functions. (line 58684) * ewoc-goto-node: Abstract Display Functions. (line 58691) * ewoc-goto-prev: Abstract Display Functions. (line 58683) * ewoc-invalidate: Abstract Display Functions. (line 58700) * ewoc-locate: Abstract Display Functions. (line 58672) * ewoc-location: Abstract Display Functions. (line 58680) * ewoc-map: Abstract Display Functions. (line 58718) * ewoc-next: Abstract Display Functions. (line 58658) * ewoc-nth: Abstract Display Functions. (line 58661) * ewoc-prev: Abstract Display Functions. (line 58657) * ewoc-refresh: Abstract Display Functions. (line 58694) * ewoc-set-data: Abstract Display Functions. (line 58669) * ewoc-set-hf: Abstract Display Functions. (line 58644) * examining text properties: Examining Properties. (line 44575) * examining the interactive form: Using Interactive. (line 21461) * examining windows: Buffers and Windows. (line 36470) * examples of using interactive: Interactive Examples. (line 21683) * excess close parentheses: Excess Close. (line 18609) * excess open parentheses: Excess Open. (line 18578) * excursion: Excursions. (line 41751) * exec-directory: Subprocess Creation. (line 50876) * exec-path: Subprocess Creation. (line 50882) * exec-suffixes: Subprocess Creation. (line 50840) * executable-find: Locating Files. (line 31671) * execute program: Subprocess Creation. (line 50827) * execute with prefix argument: Interactive Call. (line 21839) * execute-extended-command: Interactive Call. (line 21833) * execute-kbd-macro: Keyboard Macros. (line 24022) * executing-kbd-macro: Keyboard Macros. (line 24045) * execution speed: Compilation Tips. (line 63923) * exit: Recursive Editing. (line 23863) * exit recursive editing: Recursive Editing. (line 23863) * exit-minibuffer: Minibuffer Commands. (line 21043) * exit-recursive-edit: Recursive Editing. (line 23914) * exiting Emacs: Getting Out. (line 60017) * exp: Math Functions. (line 3733) * expand-abbrev: Abbrev Expansion. (line 50577) * expand-file-name: File Name Expansion. (line 32196) * expanding abbrevs: Abbrev Expansion. (line 50559) * expansion of file names: File Name Expansion. (line 32190) * expansion of macros: Expansion. (line 13526) * explicit selective display: Selective Display. (line 54401) * expression: Intro Eval. (line 8040) * expt: Math Functions. (line 3741) * extended file attributes: Extended Attributes. (line 31576) * extended menu item: Extended Menu Items. (line 25743) * extended-command-history: Minibuffer History. (line 19802) * extent: Variable Scoping. (line 10516) * external border: Frame Layout. (line 38918) * external menu bar: Frame Layout. (line 38938) * external tool bar: Frame Layout. (line 38947) * extra slots of char-table: Char-Tables. (line 6936) * extra-keyboard-modifiers: Event Mod. (line 23319) * face (button property): Button Properties. (line 58340) * face (overlay property): Overlay Properties. (line 54930) * face (text property): Special Properties. (line 44934) * face alias: Face Functions. (line 56013) * face attributes: Face Attributes. (line 55337) * face attributes, access and modification: Attribute Functions. (line 55688) * face codes of text: Special Properties. (line 44934) * face merging: Displaying Faces. (line 55853) * face name: Faces. (line 55313) * face remapping: Face Remapping. (line 55900) * face spec: Defining Faces. (line 55536) * face-all-attributes: Attribute Functions. (line 55732) * face-attribute: Attribute Functions. (line 55691) * face-attribute-relative-p: Attribute Functions. (line 55718) * face-background: Attribute Functions. (line 55825) * face-bold-p: Attribute Functions. (line 55833) * face-differs-from-default-p: Face Functions. (line 56009) * face-documentation: Accessing Documentation. (line 30025) * face-documentation <1>: Face Functions. (line 56001) * face-equal: Face Functions. (line 56005) * face-font: Attribute Functions. (line 55816) * face-font-family-alternatives: Font Selection. (line 56130) * face-font-registry-alternatives: Font Selection. (line 56163) * face-font-rescale-alist: Font Selection. (line 56191) * face-font-selection-order: Font Selection. (line 56140) * face-foreground: Attribute Functions. (line 55824) * face-id: Face Functions. (line 55996) * face-inverse-video-p: Attribute Functions. (line 55846) * face-italic-p: Attribute Functions. (line 55838) * face-list: Face Functions. (line 55993) * face-name-history: Minibuffer History. (line 19811) * face-remap-add-relative: Face Remapping. (line 55951) * face-remap-remove-relative: Face Remapping. (line 55968) * face-remap-reset-base: Face Remapping. (line 55984) * face-remap-set-base: Face Remapping. (line 55973) * face-remapping-alist: Face Remapping. (line 55905) * face-spec-set: Defining Faces. (line 55667) * face-stipple: Attribute Functions. (line 55829) * face-underline-p: Attribute Functions. (line 55842) * facemenu-keymap: Prefix Keys. (line 24485) * facep: Faces. (line 55325) * faces: Faces. (line 55301) * faces for font lock: Faces for Font Lock. (line 29079) * faces, automatic choice: Auto Faces. (line 56029) * false: nil and t. (line 1070) * fboundp: Function Cells. (line 12704) * fceiling: Rounding Operations. (line 3494) * FEATURE-unload-function: Unloading. (line 15962) * featurep: Named Features. (line 15867) * features: Named Features. (line 15874) * features <1>: Named Features. (line 15746) * fetch-bytecode: Dynamic Loading. (line 16338) * ffloor: Rounding Operations. (line 3490) * field (overlay property): Overlay Properties. (line 54969) * field (text property): Special Properties. (line 45094) * field width: Formatting Strings. (line 4538) * field-beginning: Fields. (line 45597) * field-end: Fields. (line 45607) * field-string: Fields. (line 45617) * field-string-no-properties: Fields. (line 45621) * fields: Fields. (line 45570) * fifo data structure: Rings. (line 7237) * file accessibility: Testing Accessibility. (line 31157) * file age: File Attributes. (line 31425) * file attributes: File Attributes. (line 31420) * file classification: Kinds of Files. (line 31277) * file contents, and default coding system: Default Coding Systems. (line 47469) * file format conversion: Format Conversion. (line 32906) * file handler: Magic File Names. (line 32684) * file hard link: Changing Files. (line 31704) * file local variables: File Local Variables. (line 11165) * file local variables <1>: Security Considerations. (line 61876) * file locks: File Locks. (line 31072) * file mode specification error: Auto Major Mode. (line 26923) * file modes: Testing Accessibility. (line 31240) * file modes and MS-DOS: Testing Accessibility. (line 31266) * file modes, setting: Changing Files. (line 31813) * file modification time: File Attributes. (line 31425) * file name abbreviations: Directory Names. (line 32175) * file name completion subroutines: File Name Completion. (line 32387) * file name of buffer: Buffer File Name. (line 34073) * file name of directory: Directory Names. (line 32101) * file name, and default coding system: Default Coding Systems. (line 47479) * file names: File Names. (line 31924) * file names in directory: Contents of Directories. (line 32512) * file names, trailing whitespace: Information about Files. (line 31150) * file notifications: File Notifications. (line 61654) * file open error: Subroutines of Visiting. (line 30733) * file permissions: Testing Accessibility. (line 31240) * file permissions, setting: Changing Files. (line 31813) * file symbolic links: Kinds of Files. (line 31281) * file with multiple names: Changing Files. (line 31704) * file, information about: Information about Files. (line 31143) * file-accessible-directory-p: Testing Accessibility. (line 31207) * file-acl: Extended Attributes. (line 31590) * file-already-exists: Changing Files. (line 31787) * file-attributes: File Attributes. (line 31446) * file-chase-links: Truenames. (line 31385) * file-coding-system-alist: Default Coding Systems. (line 47479) * file-directory-p: Kinds of Files. (line 31335) * file-equal-p: Truenames. (line 31406) * file-error: How Programs Do Loading. (line 15259) * file-executable-p: Testing Accessibility. (line 31186) * file-exists-p: Testing Accessibility. (line 31167) * file-expand-wildcards: Contents of Directories. (line 32572) * file-extended-attributes: Extended Attributes. (line 31617) * file-in-directory-p: Truenames. (line 31411) * file-local-copy: Magic File Names. (line 32826) * file-local-variables-alist: File Local Variables. (line 11227) * file-locked: File Locks. (line 31127) * file-locked-p: File Locks. (line 31089) * file-modes: Testing Accessibility. (line 31239) * file-modes-symbolic-to-number: Changing Files. (line 31882) * file-name encoding, MS-Windows: Encoding and I/O. (line 47221) * file-name-absolute-p: Relative File Names. (line 32066) * file-name-all-completions: File Name Completion. (line 32391) * file-name-as-directory: Directory Names. (line 32120) * file-name-base: File Name Components. (line 32043) * file-name-coding-system: Encoding and I/O. (line 47203) * file-name-completion: File Name Completion. (line 32414) * file-name-directory: File Name Components. (line 31968) * file-name-extension: File Name Components. (line 32007) * file-name-handler-alist: Magic File Names. (line 32684) * file-name-history: Minibuffer History. (line 19793) * file-name-nondirectory: File Name Components. (line 31981) * file-name-sans-extension: File Name Components. (line 32022) * file-name-sans-versions: File Name Components. (line 31991) * file-newer-than-file-p: File Attributes. (line 31424) * file-newest-backup: Backup Names. (line 33499) * file-nlinks: File Attributes. (line 31558) * file-notify-add-watch: File Notifications. (line 61668) * file-notify-rm-watch: File Notifications. (line 61764) * file-notify-valid-p: File Notifications. (line 61768) * file-ownership-preserved-p: Testing Accessibility. (line 31226) * file-precious-flag: Saving Buffers. (line 30893) * file-readable-p: Testing Accessibility. (line 31182) * file-regular-p: Kinds of Files. (line 31351) * file-relative-name: Relative File Names. (line 32081) * file-remote-p: Magic File Names. (line 32839) * file-selinux-context: Extended Attributes. (line 31605) * file-supersession: Modification Time. (line 34332) * file-symlink-p: Kinds of Files. (line 31280) * file-truename: Truenames. (line 31367) * file-writable-p: Testing Accessibility. (line 31193) * filepos-to-bufferpos: Text Representations. (line 46409) * fill-column: Margins. (line 43797) * fill-context-prefix: Adaptive Fill. (line 43875) * fill-forward-paragraph-function: Filling. (line 43769) * fill-individual-paragraphs: Filling. (line 43668) * fill-individual-varying-indent: Filling. (line 43690) * fill-nobreak-predicate: Margins. (line 43855) * fill-paragraph: Filling. (line 43644) * fill-paragraph-function: Filling. (line 43756) * fill-prefix: Margins. (line 43786) * fill-region: Filling. (line 43656) * fill-region-as-paragraph: Filling. (line 43694) * fillarray: Array Functions. (line 6819) * filling text: Filling. (line 43618) * filling, automatic: Auto Filling. (line 43937) * filter function: Filter Functions. (line 52044) * filter multibyte flag, of process: Decoding Output. (line 52174) * filter-buffer-substring: Buffer Contents. (line 42567) * filter-buffer-substring-function: Buffer Contents. (line 42588) * filter-buffer-substring-functions: Buffer Contents. (line 42598) * filtering killed text: Kill Functions. (line 43117) * filtering sequences: Sequence Functions. (line 6481) * find file in path: Locating Files. (line 31634) * find library: Library Search. (line 15353) * find-auto-coding: Default Coding Systems. (line 47560) * find-backup-file-name: Backup Names. (line 33479) * find-buffer-visiting: Buffer File Name. (line 34140) * find-charset-region: Scanning Charsets. (line 46952) * find-charset-string: Scanning Charsets. (line 46962) * find-coding-systems-for-charsets: Lisp and Coding Systems. (line 47301) * find-coding-systems-region: Lisp and Coding Systems. (line 47285) * find-coding-systems-string: Lisp and Coding Systems. (line 47294) * find-file: Visiting Functions. (line 30561) * find-file-hook: Visiting Functions. (line 30669) * find-file-literally: Visiting Functions. (line 30687) * find-file-literally <1>: Visiting Functions. (line 30580) * find-file-name-handler: Magic File Names. (line 32818) * find-file-noselect: Visiting Functions. (line 30599) * find-file-not-found-functions: Visiting Functions. (line 30677) * find-file-other-window: Visiting Functions. (line 30646) * find-file-read-only: Visiting Functions. (line 30654) * find-file-wildcards: Visiting Functions. (line 30662) * find-font: Low-Level Font. (line 56494) * find-image: Defining Images. (line 57961) * find-operation-coding-system: Default Coding Systems. (line 47587) * find-word-boundary-function-table: Word Motion. (line 41292) * finding files: Visiting Files. (line 30525) * finding windows: Cyclic Window Ordering. (line 36418) * first-change-hook: Change Hooks. (line 46290) * fit-frame-to-buffer: Resizing Windows. (line 35571) * fit-frame-to-buffer <1>: Resizing Windows. (line 35584) * fit-frame-to-buffer-margins: Resizing Windows. (line 35600) * fit-frame-to-buffer-sizes: Resizing Windows. (line 35611) * fit-window-to-buffer: Resizing Windows. (line 35529) * fit-window-to-buffer-horizontally: Resizing Windows. (line 35563) * fixed-size window: Window Sizes. (line 35382) * fixup-whitespace: User-Level Deletion. (line 42997) * flags in format specifications: Formatting Strings. (line 4562) * float: Numeric Conversions. (line 3258) * float-e: Math Functions. (line 3753) * float-output-format: Output Variables. (line 19316) * float-pi: Math Functions. (line 3756) * float-time: Time of Day. (line 60504) * floating-point functions: Math Functions. (line 3711) * floatp: Predicates on Numbers. (line 3140) * floats-consed: Memory Usage. (line 64906) * floor: Numeric Conversions. (line 3284) * flowcontrol, in serial connections: Serial Ports. (line 53181) * flushing input: Event Input Misc. (line 23531) * fmakunbound: Function Cells. (line 12709) * fn in function’s documentation string: Autoload. (line 15650) * focus event: Focus Events. (line 22557) * focus-follows-mouse: Input Focus. (line 40277) * focus-in-hook: Input Focus. (line 40269) * focus-in-hook <1>: Standard Hooks. (line 66296) * focus-out-hook: Input Focus. (line 40273) * focus-out-hook <1>: Standard Hooks. (line 66297) * follow links: Clickable Text. (line 45405) * follow-link (button property): Button Properties. (line 58362) * follow-link (text or overlay property): Clickable Text. (line 45485) * following-char: Near Point. (line 42473) * font and color, frame parameters: Font and Color Parameters. (line 39850) * font entity: Low-Level Font. (line 56485) * font information for layout: Low-Level Font. (line 56652) * font lock faces: Faces for Font Lock. (line 29079) * Font Lock mode: Font Lock Mode. (line 28576) * font lookup: Font Lookup. (line 56211) * font object: Low-Level Font. (line 56409) * font property: Low-Level Font. (line 56394) * font registry: Low-Level Font. (line 56448) * font selection: Font Selection. (line 56120) * font spec: Low-Level Font. (line 56419) * font, a frame parameter: Font and Color Parameters. (line 39916) * font-at: Low-Level Font. (line 56412) * font-backend, a frame parameter: Font and Color Parameters. (line 39852) * font-face-attributes: Low-Level Font. (line 56528) * font-family-list: Face Attributes. (line 55516) * font-get: Low-Level Font. (line 56519) * font-info: Low-Level Font. (line 56551) * font-lock-add-keywords: Customizing Keywords. (line 28899) * font-lock-builtin-face: Faces for Font Lock. (line 29122) * font-lock-comment-delimiter-face: Faces for Font Lock. (line 29112) * font-lock-comment-face: Faces for Font Lock. (line 29109) * font-lock-constant-face: Faces for Font Lock. (line 29119) * font-lock-defaults: Font Lock Basics. (line 28640) * font-lock-doc-face: Faces for Font Lock. (line 29132) * font-lock-ensure &optional beg end: Font Lock Basics. (line 28627) * font-lock-ensure-function: Other Font Lock Variables. (line 29008) * font-lock-extend-after-change-region-function: Region to Refontify. (line 29286) * font-lock-extra-managed-props: Other Font Lock Variables. (line 28974) * font-lock-face (text property): Special Properties. (line 44961) * font-lock-flush &optional beg end: Font Lock Basics. (line 28621) * font-lock-flush-function: Other Font Lock Variables. (line 29003) * font-lock-fontify-buffer: Font Lock Basics. (line 28603) * font-lock-fontify-buffer-function: Other Font Lock Variables. (line 28983) * font-lock-fontify-region beg end &optional loudly: Font Lock Basics. (line 28612) * font-lock-fontify-region-function: Other Font Lock Variables. (line 28991) * font-lock-function-name-face: Faces for Font Lock. (line 29099) * font-lock-keyword-face: Faces for Font Lock. (line 29105) * font-lock-keywords: Search-based Fontification. (line 28701) * font-lock-keywords-case-fold-search: Search-based Fontification. (line 28888) * font-lock-keywords-only: Syntactic Font Lock. (line 29156) * font-lock-mark-block-function: Other Font Lock Variables. (line 28963) * font-lock-multiline: Font Lock Multiline. (line 29248) * font-lock-negation-char-face: Faces for Font Lock. (line 29136) * font-lock-preprocessor-face: Faces for Font Lock. (line 29125) * font-lock-remove-keywords: Customizing Keywords. (line 28930) * font-lock-string-face: Faces for Font Lock. (line 29129) * font-lock-syntactic-face-function: Syntactic Font Lock. (line 29170) * font-lock-syntax-table: Syntactic Font Lock. (line 29162) * font-lock-type-face: Faces for Font Lock. (line 29116) * font-lock-unfontify-buffer: Font Lock Basics. (line 28608) * font-lock-unfontify-buffer-function: Other Font Lock Variables. (line 28987) * font-lock-unfontify-region beg end: Font Lock Basics. (line 28617) * font-lock-unfontify-region-function: Other Font Lock Variables. (line 28998) * font-lock-variable-name-face: Faces for Font Lock. (line 29102) * font-lock-warning-face: Faces for Font Lock. (line 29095) * font-put: Low-Level Font. (line 56482) * font-spec: Low-Level Font. (line 56423) * font-xlfd-name: Low-Level Font. (line 56540) * fontification-functions: Auto Faces. (line 56033) * fontified (text property): Special Properties. (line 44978) * fontp: Low-Level Font. (line 56401) * fontset: Fontsets. (line 56260) * foo: A Sample Function Description. (line 1204) * for: Argument Evaluation. (line 13716) * force coding system for operation: Specifying Coding Systems. (line 47627) * force entry to debugger: Explicit Debug. (line 16884) * force-mode-line-update: Mode Line Basics. (line 27921) * force-window-update: Forcing Redisplay. (line 53670) * forcing redisplay: Forcing Redisplay. (line 53651) * foreground-color, a frame parameter: Font and Color Parameters. (line 39922) * form: Intro Eval. (line 8040) * format: Formatting Strings. (line 4427) * format definition: Format Conversion Round-Trip. (line 32954) * format of keymaps: Format of Keymaps. (line 24182) * format specification: Formatting Strings. (line 4449) * format, customization keyword: Type Keywords. (line 14841) * format-alist: Format Conversion Round-Trip. (line 32948) * format-find-file: Format Conversion Round-Trip. (line 33053) * format-insert-file: Format Conversion Round-Trip. (line 33062) * format-message: Formatting Strings. (line 4436) * format-mode-line: Emulating Mode Line. (line 28379) * format-network-address: Misc Network. (line 53057) * format-seconds: Time Parsing. (line 60765) * format-time-string: Time Parsing. (line 60653) * format-write-file: Format Conversion Round-Trip. (line 33042) * formatting strings: Formatting Strings. (line 4417) * formatting time values: Time Parsing. (line 60646) * formfeed: Basic Char Syntax. (line 1550) * forward-button: Button Buffer Commands. (line 58531) * forward-char: Character Motion. (line 41229) * forward-comment: Motion via Parsing. (line 50003) * forward-line: Text Lines. (line 41404) * forward-list: List Motion. (line 41614) * forward-sexp: List Motion. (line 41642) * forward-to-indentation: Motion by Indent. (line 44467) * forward-word: Word Motion. (line 41250) * forward-word-strictly: Word Motion. (line 41303) * frame: Frames. (line 38536) * frame configuration: Frame Configurations. (line 40371) * frame creation: Creating Frames. (line 38600) * frame geometry: Frame Geometry. (line 38869) * frame layout: Frame Layout. (line 38879) * frame layout parameters: Layout Parameters. (line 39629) * frame parameters: Frame Parameters. (line 39314) * frame parameters for windowed displays: Window Frame Parameters. (line 39447) * frame position: Frame Geometry. (line 38869) * frame position <1>: Size and Position. (line 39135) * frame position <2>: Position Parameters. (line 39495) * frame size: Frame Geometry. (line 38869) * frame size <1>: Size and Position. (line 39135) * frame title: Frame Titles. (line 40026) * frame visibility: Visibility of Frames. (line 40286) * frame without a minibuffer: Minibuffers and Frames. (line 40136) * frame, which buffers to display: Buffer Parameters. (line 39698) * frame-alpha-lower-limit: Font and Color Parameters. (line 39897) * frame-auto-hide-function: Quitting Windows. (line 37377) * frame-char-height: Frame Font. (line 39104) * frame-char-width: Frame Font. (line 39105) * frame-current-scroll-bars: Scroll Bars. (line 57025) * frame-edges: Frame Layout. (line 39071) * frame-first-window: Windows and Frames. (line 35098) * frame-geometry: Frame Layout. (line 39023) * frame-height: Size and Position. (line 39180) * frame-inherited-parameters: Creating Frames. (line 38645) * frame-inhibit-implied-resize: Implied Frame Resizing. (line 39278) * frame-list: Finding All Frames. (line 40089) * frame-live-p: Deleting Frames. (line 40074) * frame-monitor-attributes: Multiple Terminals. (line 38862) * frame-parameter: Parameter Access. (line 39333) * frame-parameters: Parameter Access. (line 39339) * frame-pixel-height: Size and Position. (line 39159) * frame-pixel-width: Size and Position. (line 39160) * frame-pointer-visible-p: Mouse Position. (line 40490) * frame-position: Size and Position. (line 39142) * frame-relative coordinate: Coordinates and Windows. (line 38019) * frame-resize-pixelwise: Size and Position. (line 39191) * frame-root-window: Windows and Frames. (line 34992) * frame-scroll-bar-height: Scroll Bars. (line 57037) * frame-scroll-bar-width: Scroll Bars. (line 57032) * frame-selected-window: Selecting Windows. (line 36291) * frame-terminal: Frames. (line 38587) * frame-text-height: Size and Position. (line 39165) * frame-text-width: Size and Position. (line 39166) * frame-title-format: Frame Titles. (line 40035) * frame-visible-p: Visibility of Frames. (line 40297) * frame-width: Size and Position. (line 39181) * framep: Frames. (line 38570) * frames, scanning all: Finding All Frames. (line 40089) * free list: Garbage Collection. (line 64616) * free variable: Using Lexical Binding. (line 10779) * frequency counts: Coverage Testing. (line 17941) * frexp: Float Basics. (line 3106) * fringe bitmaps: Fringe Bitmaps. (line 56858) * fringe bitmaps, customizing: Customizing Bitmaps. (line 56922) * fringe cursors: Fringe Cursors. (line 56825) * fringe indicators: Fringe Indicators. (line 56736) * fringe-bitmaps-at-pos: Fringe Bitmaps. (line 56907) * fringe-cursor-alist: Fringe Cursors. (line 56834) * fringe-indicator-alist: Fringe Indicators. (line 56779) * fringes: Fringes. (line 56681) * fringes, and empty line indication: Fringe Indicators. (line 56741) * fringes-outside-margins: Fringe Size/Pos. (line 56692) * fround: Rounding Operations. (line 3502) * fset: Function Cells. (line 12723) * ftp-login: Cleanups. (line 9915) * ftruncate: Rounding Operations. (line 3498) * full keymap: Format of Keymaps. (line 24182) * full-height window: Window Sizes. (line 35282) * full-width window: Window Sizes. (line 35282) * fullboth frames: Size Parameters. (line 39587) * fullheight frames: Size Parameters. (line 39587) * fullscreen, a frame parameter: Size Parameters. (line 39587) * fullscreen-restore, a frame parameter: Size Parameters. (line 39612) * fullwidth frames: Size Parameters. (line 39587) * funcall: Calling Functions. (line 12207) * funcall, and debugging: Internals of Debugger. (line 17167) * funcall-interactively: Interactive Call. (line 21807) * function: Anonymous Functions. (line 12426) * function aliases: Defining Functions. (line 12088) * function call: Function Forms. (line 8258) * function call debugging: Function Debugging. (line 16829) * function cell: Symbol Components. (line 7562) * function cell in autoload: Autoload. (line 15557) * function declaration: Declaring Functions. (line 13334) * function definition: Function Names. (line 12005) * function descriptions: A Sample Function Description. (line 1188) * function form evaluation: Function Forms. (line 8258) * function input stream: Input Streams. (line 18779) * function invocation: Calling Functions. (line 12192) * function keys: Function Keys. (line 22153) * function name: Function Names. (line 12005) * function output stream: Output Streams. (line 18979) * function quoting: Anonymous Functions. (line 12427) * function safety: Function Safety. (line 13404) * function-documentation property: Documentation Basics. (line 29942) * function-get: Symbol Plists. (line 7901) * function-put: Symbol Plists. (line 7910) * functionals: Calling Functions. (line 12290) * functionp: What Is a Function. (line 11757) * functions in modes: Major Mode Conventions. (line 26717) * functions, making them interactive: Defining Commands. (line 21316) * fundamental-mode: Major Modes. (line 26639) * fundamental-mode-abbrev-table: Standard Abbrev Tables. (line 50690) * gamma correction: Font and Color Parameters. (line 39881) * gap-position: Buffer Gap. (line 34840) * gap-size: Buffer Gap. (line 34844) * garbage collection: Garbage Collection. (line 64599) * garbage collection protection: Writing Emacs Primitives. (line 65049) * garbage-collect: Garbage Collection. (line 64637) * garbage-collection-messages: Garbage Collection. (line 64788) * gc-cons-percentage: Garbage Collection. (line 64821) * gc-cons-threshold: Garbage Collection. (line 64797) * gc-elapsed: Garbage Collection. (line 64863) * gcs-done: Garbage Collection. (line 64859) * generalized variable: Generalized Variables. (line 11530) * generate-autoload-cookie: Autoload. (line 15672) * generate-new-buffer: Creating Buffers. (line 34593) * generate-new-buffer-name: Buffer Names. (line 34047) * generated-autoload-file: Autoload. (line 15678) * generators: Generators. (line 9176) * generic commands: Generic Commands. (line 21721) * generic functions: Generic Functions. (line 12472) * generic mode: Generic Modes. (line 27389) * geometry specification: Geometry. (line 39957) * get: Symbol Plists. (line 7852) * get, defcustom keyword: Variable Definitions. (line 14265) * get-buffer: Buffer Names. (line 34031) * get-buffer-create: Creating Buffers. (line 34572) * get-buffer-process: Process Buffers. (line 51976) * get-buffer-window: Buffers and Windows. (line 36516) * get-buffer-window-list: Buffers and Windows. (line 36542) * get-buffer-xwidgets: Xwidgets. (line 58253) * get-byte: Character Codes. (line 46625) * get-char-code-property: Character Properties. (line 46783) * get-char-property: Examining Properties. (line 44593) * get-char-property-and-overlay: Examining Properties. (line 44611) * get-charset-property: Character Sets. (line 46899) * get-device-terminal: Multiple Terminals. (line 38685) * get-file-buffer: Buffer File Name. (line 34124) * get-internal-run-time: Processor Run Time. (line 60825) * get-largest-window: Cyclic Window Ordering. (line 36439) * get-load-suffixes: Load Suffixes. (line 15332) * get-lru-window: Cyclic Window Ordering. (line 36421) * get-mru-window: Cyclic Window Ordering. (line 36434) * get-pos-property: Examining Properties. (line 44606) * get-process: Process Information. (line 51550) * get-register: Registers. (line 45809) * get-text-property: Examining Properties. (line 44584) * get-unused-category: Categories. (line 50299) * get-window-with-predicate: Cyclic Window Ordering. (line 36456) * getenv: System Environment. (line 60257) * gethash: Hash Access. (line 7402) * GID: User Identification. (line 60442) * global binding: Local Variables. (line 10021) * global break condition: Global Break Condition. (line 17633) * global keymap: Active Keymaps. (line 24578) * global variable: Global Variables. (line 9962) * global-abbrev-table: Standard Abbrev Tables. (line 50673) * global-buffers-menu-map: Standard Keymaps. (line 66132) * global-disable-point-adjustment: Adjusting Point. (line 22065) * global-key-binding: Functions for Key Lookup. (line 25004) * global-map: Controlling Active Maps. (line 24684) * global-mode-string: Mode Line Variables. (line 28180) * global-set-key: Key Binding Commands. (line 25466) * global-unset-key: Key Binding Commands. (line 25474) * glyph: Glyphs. (line 59088) * glyph code: Glyphs. (line 59088) * glyph-char: Glyphs. (line 59101) * glyph-face: Glyphs. (line 59104) * glyph-table: Glyphs. (line 59113) * glyphless characters: Glyphless Chars. (line 59136) * glyphless-char-display: Glyphless Chars. (line 59142) * glyphless-char-display-control: Glyphless Chars. (line 59185) * goto-char: Character Motion. (line 41214) * goto-map: Prefix Keys. (line 24479) * grammar, SMIE: SMIE Grammar. (line 29483) * graphical display: Frames. (line 38553) * graphical terminal: Frames. (line 38553) * group, customization keyword: Common Keywords. (line 13999) * group-gid: User Identification. (line 60442) * group-real-gid: User Identification. (line 60446) * gui-get-selection: Window System Selections. (line 40695) * gui-set-selection: Window System Selections. (line 40677) * gv-define-expander: Adding Generalized Variables. (line 11653) * gv-define-setter: Adding Generalized Variables. (line 11639) * gv-define-simple-setter: Adding Generalized Variables. (line 11616) * gv-letplace: Adding Generalized Variables. (line 11653) * hack-dir-local-variables: Directory Local Variables. (line 11346) * hack-dir-local-variables-non-file-buffer: Directory Local Variables. (line 11356) * hack-local-variables: File Local Variables. (line 11204) * hack-local-variables-hook: File Local Variables. (line 11239) * handle-shift-selection: The Mark. (line 42342) * handle-switch-frame: Input Focus. (line 40232) * handling errors: Handling Errors. (line 9577) * hardening: Security Considerations. (line 61865) * hash code: Defining Hash. (line 7434) * hash notation: Printed Representation. (line 1416) * hash table access: Hash Access. (line 7398) * hash tables: Hash Tables. (line 7251) * hash, cryptographic: Checksum/Hash. (line 45946) * hash-table-count: Other Hash. (line 7514) * hash-table-p: Other Hash. (line 7506) * hash-table-rehash-size: Other Hash. (line 7525) * hash-table-rehash-threshold: Other Hash. (line 7528) * hash-table-size: Other Hash. (line 7531) * hash-table-test: Other Hash. (line 7517) * hash-table-weakness: Other Hash. (line 7522) * hashing: Creating Symbols. (line 7671) * header comments: Library Headers. (line 64267) * header line (of a window): Header Lines. (line 28351) * header-line prefix key: Key Sequence Input. (line 23168) * header-line-format: Header Lines. (line 28356) * height of a line: Line Height. (line 55217) * height of a window: Window Sizes. (line 35205) * height spec: Line Height. (line 55246) * height, a frame parameter: Size Parameters. (line 39574) * help for major mode: Mode Help. (line 27044) * help functions: Help Functions. (line 30323) * help-buffer: Help Functions. (line 30438) * help-char: Help Functions. (line 30365) * help-command: Help Functions. (line 30358) * help-echo (overlay property): Overlay Properties. (line 54963) * help-echo (text property): Special Properties. (line 44992) * help-echo event: Misc Events. (line 22636) * help-echo, customization keyword: Type Keywords. (line 14909) * help-event-list: Help Functions. (line 30381) * help-form: Help Functions. (line 30386) * help-index (button property): Button Properties. (line 58358) * help-map: Help Functions. (line 30354) * help-setup-xref: Help Functions. (line 30452) * help-window-select: Help Functions. (line 30442) * Helper-describe-bindings: Help Functions. (line 30418) * Helper-help: Help Functions. (line 30424) * Helper-help-map: Help Functions. (line 30431) * hex numbers: Integer Basics. (line 3004) * hidden buffers: Buffer Names. (line 33994) * history list: Minibuffer History. (line 19702) * history of commands: Command History. (line 23985) * history-add-new-input: Minibuffer History. (line 19766) * history-delete-duplicates: Minibuffer History. (line 19779) * history-length: Minibuffer History. (line 19772) * HOME environment variable: Subprocess Creation. (line 50827) * hook variables, list of: Standard Hooks. (line 66204) * hooks: Hooks. (line 26491) * hooks for changing a character: Special Properties. (line 45171) * hooks for loading: Hooks for Loading. (line 15986) * hooks for motion of point: Special Properties. (line 45201) * hooks for text changes: Change Hooks. (line 46231) * hooks for window operations: Window Hooks. (line 38474) * horizontal combination: Windows and Frames. (line 35026) * horizontal position: Columns. (line 44172) * horizontal scrolling: Horizontal Scrolling. (line 37908) * horizontal-scroll-bar: Scroll Bars. (line 57111) * horizontal-scroll-bar prefix key: Key Sequence Input. (line 23168) * horizontal-scroll-bar-mode: Scroll Bars. (line 57135) * horizontal-scroll-bars, a frame parameter: Layout Parameters. (line 39644) * horizontal-scroll-bars-available-p: Scroll Bars. (line 57018) * how to visit files: Visiting Functions. (line 30549) * HTML DOM: Document Object Model. (line 46049) * hyper characters: Other Char Bits. (line 1685) * hyperlinks in documentation strings: Documentation Tips. (line 64089) * icon-left, a frame parameter: Position Parameters. (line 39537) * icon-name, a frame parameter: Management Parameters. (line 39753) * icon-title-format: Frame Titles. (line 40041) * icon-top, a frame parameter: Position Parameters. (line 39544) * icon-type, a frame parameter: Management Parameters. (line 39747) * iconified frame: Visibility of Frames. (line 40286) * iconify-frame: Visibility of Frames. (line 40305) * iconify-frame event: Misc Events. (line 22599) * identity: Calling Functions. (line 12299) * idle timers: Idle Timers. (line 60997) * idleness: Idle Timers. (line 61014) * IEEE floating point: Float Basics. (line 3071) * if: Conditionals. (line 8753) * ignore: Calling Functions. (line 12302) * ignore-errors: Handling Errors. (line 9768) * ignore-window-parameters: Window Parameters. (line 38380) * ignored-local-variables: File Local Variables. (line 11290) * image animation: Multi-Frame Images. (line 58110) * image cache: Image Cache. (line 58159) * image descriptor: Image Descriptors. (line 57566) * image formats: Image Formats. (line 57521) * image frames: Multi-Frame Images. (line 58110) * image maps: Image Descriptors. (line 57687) * image slice: Showing Images. (line 58049) * image types: Image Formats. (line 57521) * image-animate: Multi-Frame Images. (line 58140) * image-animate-timer: Multi-Frame Images. (line 58152) * image-cache-eviction-delay: Image Cache. (line 58201) * image-current-frame: Multi-Frame Images. (line 58130) * image-default-frame-delay: Multi-Frame Images. (line 58147) * image-flush: Image Cache. (line 58165) * image-format-suffixes: ImageMagick Images. (line 57834) * image-load-path: Defining Images. (line 57976) * image-load-path-for-library: Defining Images. (line 57993) * image-mask-p: Image Descriptors. (line 57715) * image-minimum-frame-delay: Multi-Frame Images. (line 58147) * image-multi-frame-p: Multi-Frame Images. (line 58122) * image-show-frame: Multi-Frame Images. (line 58134) * image-size: Showing Images. (line 58084) * image-type-available-p: Image Formats. (line 57554) * image-types: Image Formats. (line 57545) * ImageMagick images: ImageMagick Images. (line 57808) * imagemagick-enabled-types: ImageMagick Images. (line 57820) * imagemagick-types: ImageMagick Images. (line 57814) * imagemagick-types-inhibit: ImageMagick Images. (line 57828) * images in buffers: Images. (line 57507) * images, support for more formats: ImageMagick Images. (line 57808) * Imenu: Imenu. (line 28412) * imenu-add-to-menubar: Imenu. (line 28420) * imenu-case-fold-search: Imenu. (line 28474) * imenu-create-index-function: Imenu. (line 28534) * imenu-extract-index-name-function: Imenu. (line 28523) * imenu-generic-expression: Imenu. (line 28432) * imenu-prev-index-position-function: Imenu. (line 28513) * imenu-syntax-alist: Imenu. (line 28482) * implicit progn: Sequencing. (line 8693) * implied frame resizing: Implied Frame Resizing. (line 39265) * implied resizing of frame: Implied Frame Resizing. (line 39265) * inactive minibuffer: Intro to Minibuffers. (line 19395) * inc: Simple Macro. (line 13510) * indefinite extent: Variable Scoping. (line 10530) * indent-according-to-mode: Mode-Specific Indent. (line 44289) * indent-code-rigidly: Region Indent. (line 44367) * indent-for-tab-command: Mode-Specific Indent. (line 44253) * indent-line-function: Mode-Specific Indent. (line 44281) * indent-region: Region Indent. (line 44320) * indent-region-function: Region Indent. (line 44333) * indent-relative: Relative Indent. (line 44381) * indent-relative-maybe: Relative Indent. (line 44417) * indent-rigidly: Region Indent. (line 44353) * indent-tabs-mode: Primitive Indent. (line 44240) * indent-to: Primitive Indent. (line 44230) * indent-to-left-margin: Margins. (line 43844) * indentation: Indentation. (line 44213) * indentation rules, SMIE: SMIE Indentation. (line 29652) * indicate-buffer-boundaries: Fringe Indicators. (line 56746) * indicate-empty-lines: Fringe Indicators. (line 56740) * indicators, fringe: Fringe Indicators. (line 56736) * indirect buffers: Indirect Buffers. (line 34718) * indirect specifications: Specification List. (line 18277) * indirect-function: Function Indirection. (line 8236) * indirect-variable: Variable Aliases. (line 11475) * indirection for functions: Function Indirection. (line 8178) * infinite loops: Infinite Loops. (line 16804) * infinite recursion: Local Variables. (line 10119) * infinity: Float Basics. (line 3087) * inheritance, for faces: Face Attributes. (line 55509) * inheritance, keymap: Inheritance and Keymaps. (line 24363) * inheritance, syntax table: Syntax Basics. (line 49476) * inheritance, text property: Sticky Properties. (line 45288) * inhibit-default-init: Init File. (line 59842) * inhibit-eol-conversion: Specifying Coding Systems. (line 47664) * inhibit-field-text-motion: Word Motion. (line 41287) * inhibit-file-name-handlers: Magic File Names. (line 32811) * inhibit-file-name-operation: Magic File Names. (line 32815) * inhibit-iso-escape-detection: Lisp and Coding Systems. (line 47347) * inhibit-local-variables-regexps: File Local Variables. (line 11198) * inhibit-local-variables-regexps <1>: Auto Major Mode. (line 26940) * inhibit-message: Displaying Messages. (line 53822) * inhibit-modification-hooks: Change Hooks. (line 46294) * inhibit-null-byte-detection: Lisp and Coding Systems. (line 47341) * inhibit-point-motion-hooks: Special Properties. (line 45242) * inhibit-quit: Quitting. (line 23692) * inhibit-read-only: Read Only Buffers. (line 34375) * inhibit-read-only (text property): Special Properties. (line 45058) * inhibit-splash-screen: Startup Summary. (line 59742) * inhibit-startup-echo-area-message: Startup Summary. (line 59752) * inhibit-startup-message: Startup Summary. (line 59742) * inhibit-startup-screen: Startup Summary. (line 59733) * inhibit-x-resources: Resources. (line 40945) * init file: Init File. (line 59800) * init-file-user: User Identification. (line 60382) * init.el: Init File. (line 59800) * initial-buffer-choice: Startup Summary. (line 59745) * initial-environment: System Environment. (line 60313) * initial-frame-alist: Initial Parameters. (line 39390) * initial-major-mode: Auto Major Mode. (line 26972) * initial-scratch-message: Startup Summary. (line 59768) * initial-window-system: Window Systems. (line 59274) * initial-window-system, and startup: Startup Summary. (line 59622) * initialization of Emacs: Startup Summary. (line 59597) * initialize, defcustom keyword: Variable Definitions. (line 14277) * inline completion: Completion in Buffers. (line 20763) * inline functions: Inline Functions. (line 13209) * inline-const-p: Defining Functions. (line 12169) * inline-const-val: Defining Functions. (line 12172) * inline-error: Defining Functions. (line 12175) * inline-letevals: Defining Functions. (line 12160) * inline-quote: Defining Functions. (line 12155) * inner edges: Frame Layout. (line 38989) * inner frame: Frame Layout. (line 38989) * inner height: Frame Layout. (line 38989) * inner width: Frame Layout. (line 38989) * innermost containing parentheses: Parser State. (line 50073) * input events: Input Events. (line 22072) * input focus: Input Focus. (line 40162) * input methods: Input Methods. (line 47854) * input modes: Input Modes. (line 61091) * input stream: Input Streams. (line 18761) * input-decode-map: Translation Keymaps. (line 25321) * input-method-alist: Input Methods. (line 47891) * input-method-function: Invoking the Input Method. (line 23388) * input-pending-p: Event Input Misc. (line 23489) * insert: Insertion. (line 42717) * insert-abbrev-table-description: Abbrev Tables. (line 50452) * insert-and-inherit: Sticky Properties. (line 45350) * insert-before-markers: Insertion. (line 42723) * insert-before-markers-and-inherit: Sticky Properties. (line 45354) * insert-behind-hooks (overlay property): Overlay Properties. (line 55002) * insert-behind-hooks (text property): Special Properties. (line 45190) * insert-buffer: Commands for Insertion. (line 42789) * insert-buffer-substring: Insertion. (line 42752) * insert-buffer-substring-as-yank: Yanking. (line 43171) * insert-buffer-substring-no-properties: Insertion. (line 42774) * insert-button: Making Buttons. (line 58428) * insert-char: Insertion. (line 42735) * insert-default-directory: Reading File Names. (line 20521) * insert-directory: Contents of Directories. (line 32583) * insert-directory-program: Contents of Directories. (line 32613) * insert-file-contents: Reading from Files. (line 30930) * insert-file-contents-literally: Reading from Files. (line 30971) * insert-for-yank: Yanking. (line 43165) * insert-image: Showing Images. (line 58026) * insert-in-front-hooks (overlay property): Overlay Properties. (line 54998) * insert-in-front-hooks (text property): Special Properties. (line 45190) * insert-register: Registers. (line 45821) * insert-sliced-image: Showing Images. (line 58049) * insert-text-button: Making Buttons. (line 58443) * inserting killed text: Yank Commands. (line 43238) * insertion before point: Insertion. (line 42689) * insertion of text: Insertion. (line 42689) * insertion type of a marker: Marker Insertion Types. (line 42115) * inside comment: Parser State. (line 50080) * inside string: Parser State. (line 50077) * installation-directory: System Environment. (line 60340) * instrumenting for Edebug: Instrumenting. (line 17303) * int-to-string: String Conversion. (line 4352) * intangible (overlay property): Overlay Properties. (line 55011) * intangible (text property): Special Properties. (line 45066) * integer to decimal: String Conversion. (line 4342) * integer to hexadecimal: Formatting Strings. (line 4500) * integer to octal: Formatting Strings. (line 4493) * integer to string: String Conversion. (line 4342) * integer types (C programming language): C Integer Types. (line 65782) * integer-or-marker-p: Predicates on Markers. (line 41999) * integerp: Predicates on Numbers. (line 3144) * integers: Numbers. (line 2975) * integers in specific radix: Integer Basics. (line 3004) * interactive: Using Interactive. (line 21350) * interactive call: Interactive Call. (line 21743) * interactive code description: Interactive Codes. (line 21476) * interactive completion: Interactive Codes. (line 21480) * interactive function: Defining Commands. (line 21316) * interactive spec, using: Using Interactive. (line 21346) * interactive specification in primitives: Writing Emacs Primitives. (line 65005) * interactive, examples of using: Interactive Examples. (line 21683) * interactive-form: Using Interactive. (line 21461) * interactive-form property: Defining Commands. (line 21326) * interactive-form, symbol property: Using Interactive. (line 21361) * interactive-only property: Defining Commands. (line 21331) * intern: Creating Symbols. (line 7755) * intern-soft: Creating Symbols. (line 7776) * internal menu bar: Frame Layout. (line 38938) * internal representation of characters: Text Representations. (line 46329) * internal tool bar: Frame Layout. (line 38947) * internal windows: Basic Windows. (line 34892) * internal-border-width, a frame parameter: Layout Parameters. (line 39635) * internals, of buffer: Buffer Internals. (line 65239) * internals, of process: Process Internals. (line 65691) * internals, of window: Window Internals. (line 65500) * interning: Creating Symbols. (line 7683) * interpreter: Evaluation. (line 8023) * interpreter <1>: Evaluation. (line 8023) * interpreter-mode-alist: Auto Major Mode. (line 26977) * interprogram-cut-function: Low-Level Kill Ring. (line 43353) * interprogram-paste-function: Low-Level Kill Ring. (line 43332) * interrupt Lisp functions: Quitting. (line 23622) * interrupt-process: Signals to Processes. (line 51829) * intervals: Not Intervals. (line 45669) * intervals-consed: Memory Usage. (line 64923) * invalid prefix key error: Changing Key Bindings. (line 25113) * invalid-function: Function Indirection. (line 8189) * invalid-read-syntax: Printed Representation. (line 1426) * invalid-regexp: Regexp Backslash. (line 48601) * invert-face: Attribute Functions. (line 55801) * invisible (overlay property): Overlay Properties. (line 55006) * invisible (text property): Special Properties. (line 45062) * invisible frame: Visibility of Frames. (line 40286) * invisible text: Invisible Text. (line 54259) * invisible-p: Invisible Text. (line 54344) * invisible/intangible text, and point: Adjusting Point. (line 22047) * invocation-directory: System Environment. (line 60336) * invocation-name: System Environment. (line 60332) * invoking input method: Invoking the Input Method. (line 23383) * invoking lisp debugger: Invoking the Debugger. (line 17035) * is this call interactive: Distinguish Interactive. (line 21860) * isnan: Float Basics. (line 3103) * italic text: Face Attributes. (line 55388) * iter-close: Generators. (line 9235) * iter-defun: Generators. (line 9180) * iter-do: Generators. (line 9245) * iter-lambda: Generators. (line 9194) * iter-next: Generators. (line 9223) * iter-yield: Generators. (line 9198) * iter-yield-from: Generators. (line 9204) * iteration: Iteration. (line 9110) * jit-lock-register: Other Font Lock Variables. (line 29015) * jit-lock-unregister: Other Font Lock Variables. (line 29026) * joining lists: Rearrangement. (line 5537) * jumbled display of bidirectional text: Bidirectional Display. (line 59473) * just-one-space: User-Level Deletion. (line 43027) * justify-current-line: Filling. (line 43710) * kbd: Key Sequences. (line 24113) * kbd-macro-termination-hook: Keyboard Macros. (line 24068) * kept-new-versions: Numbered Backups. (line 33391) * kept-old-versions: Numbered Backups. (line 33396) * key: Key Sequences. (line 24086) * key binding: Keymap Basics. (line 24132) * key binding, conventions for: Key Binding Conventions. (line 63770) * key lookup: Key Lookup. (line 24851) * key sequence: Key Sequences. (line 24086) * key sequence error: Changing Key Bindings. (line 25113) * key sequence input: Key Sequence Input. (line 23084) * key substitution sequence: Keys in Documentation. (line 30143) * key translation function: Translation Keymaps. (line 25366) * key-binding: Active Keymaps. (line 24609) * key-description: Describing Characters. (line 30253) * key-translation-map: Translation Keymaps. (line 25346) * keyboard events: Keyboard Events. (line 22092) * keyboard events in strings: Strings of Events. (line 22998) * keyboard events, data in: Accessing Mouse. (line 22838) * keyboard input: Reading Input. (line 23071) * keyboard input decoding on X: Locales. (line 47922) * keyboard macro execution: Interactive Call. (line 21815) * keyboard macro termination: Beeping. (line 59229) * keyboard macro, terminating: Event Input Misc. (line 23531) * keyboard macros: Keyboard Macros. (line 24017) * keyboard macros (Edebug): Edebug Execution Modes. (line 17446) * keyboard-coding-system: Terminal I/O Encoding. (line 47822) * keyboard-quit: Quitting. (line 23716) * keyboard-translate: Event Mod. (line 23357) * keyboard-translate-table: Event Mod. (line 23338) * keymap: Keymaps. (line 24076) * keymap (button property): Button Properties. (line 58349) * keymap (overlay property): Overlay Properties. (line 55052) * keymap (text property): Special Properties. (line 45018) * keymap entry: Key Lookup. (line 24851) * keymap format: Format of Keymaps. (line 24182) * keymap in keymap: Key Lookup. (line 24898) * keymap inheritance: Inheritance and Keymaps. (line 24363) * keymap inheritance from multiple maps: Inheritance and Keymaps. (line 24410) * keymap of character: Special Properties. (line 45018) * keymap of character (and overlays): Overlay Properties. (line 55052) * keymap prompt string: Format of Keymaps. (line 24239) * keymap-parent: Inheritance and Keymaps. (line 24385) * keymap-prompt: Defining Menus. (line 25676) * keymapp: Format of Keymaps. (line 24289) * keymaps for translating events: Translation Keymaps. (line 25295) * keymaps in modes: Major Mode Conventions. (line 26728) * keymaps, scanning: Scanning Keymaps. (line 25512) * keymaps, standard: Standard Keymaps. (line 66044) * keys in documentation strings: Keys in Documentation. (line 30143) * keys, reserved: Key Binding Conventions. (line 63778) * keystroke: Key Sequences. (line 24086) * keyword symbol: Constant Variables. (line 9995) * keywordp: Constant Variables. (line 10008) * kill command repetition: Command Loop Info. (line 21961) * kill ring: The Kill Ring. (line 43055) * kill-all-local-variables: Creating Buffer-Local. (line 11037) * kill-append: Low-Level Kill Ring. (line 43325) * kill-buffer: Killing Buffers. (line 34644) * kill-buffer-hook: Killing Buffers. (line 34689) * kill-buffer-query-functions: Killing Buffers. (line 34681) * kill-emacs: Killing Emacs. (line 60029) * kill-emacs-hook: Killing Emacs. (line 60047) * kill-emacs-query-functions: Killing Emacs. (line 60061) * kill-local-variable: Creating Buffer-Local. (line 11019) * kill-new: Low-Level Kill Ring. (line 43317) * kill-process: Signals to Processes. (line 51837) * kill-read-only-ok: Kill Functions. (line 43139) * kill-region: Kill Functions. (line 43124) * kill-ring: Internals of Kill Ring. (line 43410) * kill-ring-max: Internals of Kill Ring. (line 43419) * kill-ring-yank-pointer: Internals of Kill Ring. (line 43414) * killing buffers: Killing Buffers. (line 34617) * killing Emacs: Killing Emacs. (line 60025) * kmacro-keymap: Standard Keymaps. (line 66118) * lambda: Anonymous Functions. (line 12409) * lambda expression: Lambda Expressions. (line 11789) * lambda in debug: Invoking the Debugger. (line 17059) * lambda in keymap: Key Lookup. (line 24908) * lambda list: Lambda Components. (line 11816) * lambda-list (Edebug): Specification List. (line 18339) * language-change event: Misc Events. (line 22670) * largest Lisp integer: Integer Basics. (line 3056) * largest window: Cyclic Window Ordering. (line 36439) * last: List Elements. (line 5009) * last-abbrev: Abbrev Expansion. (line 50625) * last-abbrev-location: Abbrev Expansion. (line 50630) * last-abbrev-text: Abbrev Expansion. (line 50634) * last-buffer: Buffer List. (line 34506) * last-coding-system-used: Encoding and I/O. (line 47189) * last-command: Command Loop Info. (line 21932) * last-command-event: Command Loop Info. (line 22024) * last-event-frame: Command Loop Info. (line 22035) * last-input-event: Event Input Misc. (line 23497) * last-kbd-macro: Keyboard Macros. (line 24061) * last-nonmenu-event: Command Loop Info. (line 22016) * last-prefix-arg: Prefix Command Arguments. (line 23812) * last-repeatable-command: Command Loop Info. (line 21948) * lax-plist-get: Plist Access. (line 6085) * lax-plist-put: Plist Access. (line 6089) * layout of frame: Frame Layout. (line 38879) * layout on display, and bidirectional text: Bidirectional Display. (line 59473) * layout parameters of frames: Layout Parameters. (line 39629) * lazy loading: Dynamic Loading. (line 16296) * lazy-completion-table: Basic Completion. (line 20033) * ldexp: Float Basics. (line 3114) * least recently used window: Cyclic Window Ordering. (line 36421) * left, a frame parameter: Position Parameters. (line 39498) * left-fringe, a frame parameter: Layout Parameters. (line 39657) * left-fringe-width: Fringe Size/Pos. (line 56697) * left-margin: Margins. (line 43850) * left-margin-width: Display Margins. (line 57476) * length: Sequence Functions. (line 6144) * let: Local Variables. (line 10065) * let*: Local Variables. (line 10089) * lexical binding: Variable Scoping. (line 10530) * lexical binding (Edebug): Edebug Eval. (line 17763) * lexical comparison of strings: Text Comparison. (line 4198) * lexical environment: Lexical Binding. (line 10675) * lexical scope: Variable Scoping. (line 10530) * lexical-binding: Using Lexical Binding. (line 10742) * library: Loading. (line 15128) * library compilation: Compilation Functions. (line 16219) * library header comments: Library Headers. (line 64267) * library search: Library Search. (line 15353) * libxml-parse-html-region: Parsing HTML/XML. (line 46005) * libxml-parse-xml-region: Parsing HTML/XML. (line 46041) * line end conversion: Coding System Basics. (line 47091) * line height: Frame Font. (line 39098) * line height <1>: Line Height. (line 55217) * line number: Text Lines. (line 41439) * line truncation: Truncation. (line 53692) * line wrapping: Truncation. (line 53692) * line-beginning-position: Text Lines. (line 41383) * line-end-position: Text Lines. (line 41401) * line-height (text property): Special Properties. (line 45140) * line-height (text property) <1>: Line Height. (line 55231) * line-move-ignore-invisible: Invisible Text. (line 54353) * line-number-at-pos: Text Lines. (line 41438) * line-prefix: Truncation. (line 53742) * line-spacing: Line Height. (line 55280) * line-spacing (text property): Special Properties. (line 45133) * line-spacing (text property) <1>: Line Height. (line 55286) * line-spacing, a frame parameter: Layout Parameters. (line 39691) * lines: Text Lines. (line 41359) * lines in region: Text Lines. (line 41424) * link, customization keyword: Common Keywords. (line 14012) * linked list: Cons Cell Type. (line 1800) * linking files: Changing Files. (line 31682) * Lisp debugger: Debugger. (line 16701) * Lisp expression motion: List Motion. (line 41605) * Lisp history: Lisp History. (line 1018) * Lisp library: Loading. (line 15128) * Lisp nesting error: Eval. (line 8608) * Lisp object: Lisp Data Types. (line 1366) * Lisp objects, stack-allocated: Stack-allocated Objects. (line 64870) * Lisp package: Packaging. (line 61976) * Lisp printer: Output Functions. (line 19114) * Lisp reader: Streams Intro. (line 18720) * lisp variables defined in C, restrictions: Variables with Restricted Values. (line 11502) * lisp-indent-function property: Indenting Macros. (line 13925) * lisp-mode-abbrev-table: Standard Abbrev Tables. (line 50698) * lisp-mode.el: Example Major Modes. (line 27466) * list: Building Lists. (line 5081) * list all coding systems: Lisp and Coding Systems. (line 47233) * list elements: List Elements. (line 4902) * list form evaluation: Classifying Lists. (line 8165) * list in keymap: Key Lookup. (line 24903) * list length: Sequence Functions. (line 6145) * list modification: List Variables. (line 5251) * list motion: List Motion. (line 41605) * list predicates: List-related Predicates. (line 4858) * list reverse: Sequence Functions. (line 6239) * list structure: Cons Cell Type. (line 1793) * list structure <1>: Cons Cells. (line 4851) * list, replace element: Setcar. (line 5379) * list-buffers-directory: Buffer File Name. (line 34187) * list-charset-chars: Character Sets. (line 46902) * list-fonts: Low-Level Font. (line 56499) * list-load-path-shadows: Library Search. (line 15456) * list-processes: Process Information. (line 51532) * list-system-processes: System Processes. (line 52364) * listify-key-sequence: Event Input Misc. (line 23485) * listing all buffers: Buffer List. (line 34419) * listp: List-related Predicates. (line 4873) * lists: Lists. (line 4800) * lists and cons cells: Cons Cells. (line 4808) * lists as sets: Sets And Lists. (line 5587) * literal evaluation: Self-Evaluating Forms. (line 8106) * little endian: Bindat Spec. (line 53253) * live buffer: Killing Buffers. (line 34639) * live windows: Basic Windows. (line 34885) * ln: Changing Files. (line 31787) * load: How Programs Do Loading. (line 15169) * load error with require: Named Features. (line 15758) * load errors: How Programs Do Loading. (line 15255) * load, customization keyword: Common Keywords. (line 14070) * load-average: System Environment. (line 60347) * load-file: How Programs Do Loading. (line 15270) * load-file-name: How Programs Do Loading. (line 15287) * load-file-rep-suffixes: Load Suffixes. (line 15318) * load-history: Where Defined. (line 15894) * load-in-progress: How Programs Do Loading. (line 15283) * load-library: How Programs Do Loading. (line 15278) * load-path: Library Search. (line 15356) * load-prefer-newer: Load Suffixes. (line 15345) * load-read-function: How Programs Do Loading. (line 15291) * load-suffixes: Load Suffixes. (line 15311) * load-theme: Custom Themes. (line 15108) * loading: Loading. (line 15128) * loading hooks: Hooks for Loading. (line 15986) * loading, and non-ASCII characters: Loading Non-ASCII. (line 15480) * loadup.el: Building Emacs. (line 64435) * local binding: Local Variables. (line 10021) * local keymap: Active Keymaps. (line 24564) * local variables: Local Variables. (line 10021) * local variables, killed by major mode: Creating Buffer-Local. (line 11037) * local-abbrev-table: Standard Abbrev Tables. (line 50679) * local-function-key-map: Translation Keymaps. (line 25332) * local-key-binding: Functions for Key Lookup. (line 24996) * local-map (overlay property): Overlay Properties. (line 55058) * local-map (text property): Special Properties. (line 45030) * local-set-key: Key Binding Commands. (line 25493) * local-unset-key: Key Binding Commands. (line 25501) * local-variable-if-set-p: Creating Buffer-Local. (line 10979) * local-variable-p: Creating Buffer-Local. (line 10975) * locale: Locales. (line 47917) * locale-coding-system: Locales. (line 47921) * locale-dependent string comparison: Text Comparison. (line 4244) * locale-dependent string equivalence: Text Comparison. (line 4156) * locale-info: Locales. (line 47940) * locate file in path: Locating Files. (line 31634) * locate-file: Locating Files. (line 31641) * locate-library: Library Search. (line 15440) * locate-user-emacs-file: Standard File Names. (line 32471) * lock file: File Locks. (line 31072) * lock-buffer: File Locks. (line 31097) * log: Math Functions. (line 3736) * logand: Bitwise Operations. (line 3630) * logb: Float Basics. (line 3122) * logging echo-area messages: Logging Messages. (line 53981) * logical arithmetic: Bitwise Operations. (line 3510) * logical order: Bidirectional Display. (line 59368) * logical shift: Bitwise Operations. (line 3518) * logior: Bitwise Operations. (line 3663) * lognot: Bitwise Operations. (line 3697) * logxor: Bitwise Operations. (line 3680) * looking up abbrevs: Abbrev Expansion. (line 50559) * looking up fonts: Font Lookup. (line 56211) * looking-at: Regexp Search. (line 48838) * looking-at-p: Regexp Search. (line 48887) * looking-back: Regexp Search. (line 48859) * lookup tables: Hash Tables. (line 7251) * lookup-key: Functions for Key Lookup. (line 24952) * loops, infinite: Infinite Loops. (line 16804) * lower case: Case Conversion. (line 4609) * lower-frame: Raising and Lowering. (line 40346) * lowering a frame: Raising and Lowering. (line 40333) * LRO: Bidirectional Display. (line 59524) * lsh: Bitwise Operations. (line 3517) * lwarn: Warning Basics. (line 54116) * M-g: Prefix Keys. (line 24479) * M-o: Prefix Keys. (line 24485) * M-s: Prefix Keys. (line 24482) * M-x: Interactive Call. (line 21844) * Maclisp: Lisp History. (line 1024) * macro: What Is a Function. (line 11720) * macro argument evaluation: Argument Evaluation. (line 13760) * macro call: Expansion. (line 13526) * macro call evaluation: Macro Forms. (line 8276) * macro caveats: Problems with Macros. (line 13681) * macro compilation: Compilation Functions. (line 16133) * macro descriptions: A Sample Function Description. (line 1188) * macro expansion: Expansion. (line 13557) * macro, how to define: Defining Macros. (line 13636) * macroexpand: Expansion. (line 13556) * macroexpand-1: Expansion. (line 13598) * macroexpand-all: Expansion. (line 13586) * macrop: Simple Macro. (line 13519) * macros: Macros. (line 13490) * macros, at compile time: Eval During Compile. (line 16390) * magic autoload comment: Autoload. (line 15596) * magic file names: Magic File Names. (line 32675) * magic-fallback-mode-alist: Auto Major Mode. (line 26992) * magic-mode-alist: Auto Major Mode. (line 26985) * mail-host-address: System Environment. (line 60249) * major mode: Major Modes. (line 26628) * major mode command: Major Modes. (line 26628) * major mode conventions: Major Mode Conventions. (line 26674) * major mode hook: Major Mode Conventions. (line 26830) * major mode keymap: Active Keymaps. (line 24571) * major mode, automatic selection: Auto Major Mode. (line 26895) * major-mode: Major Modes. (line 26658) * make-abbrev-table: Abbrev Tables. (line 50414) * make-auto-save-file-name: Auto-Saving. (line 33558) * make-backup-file-name: Backup Names. (line 33450) * make-backup-file-name-function: Making Backups. (line 33290) * make-backup-files: Making Backups. (line 33228) * make-bool-vector: Bool-Vectors. (line 7091) * make-button: Making Buttons. (line 58424) * make-byte-code: Byte-Code Objects. (line 16541) * make-category-set: Categories. (line 50329) * make-category-table: Categories. (line 50324) * make-char-table: Char-Tables. (line 6970) * make-composed-keymap: Inheritance and Keymaps. (line 24413) * make-directory: Create/Delete Dirs. (line 32626) * make-display-table: Display Tables. (line 58966) * make-finalizer: Finalizer Type. (line 2365) * make-frame: Creating Frames. (line 38602) * make-frame-invisible: Visibility of Frames. (line 40315) * make-frame-on-display: Multiple Terminals. (line 38752) * make-frame-visible: Visibility of Frames. (line 40309) * make-frame-visible event: Misc Events. (line 22606) * make-glyph-code: Glyphs. (line 59095) * make-hash-table: Creating Hash. (line 7283) * make-help-screen: Help Functions. (line 30466) * make-indirect-buffer: Indirect Buffers. (line 34743) * make-keymap: Creating Keymaps. (line 24325) * make-list: Building Lists. (line 5092) * make-local-variable: Creating Buffer-Local. (line 10891) * make-marker: Creating Markers. (line 42017) * make-network-process: Network Processes. (line 52790) * make-obsolete: Obsolete Functions. (line 13162) * make-obsolete-variable: Variable Aliases. (line 11452) * make-overlay: Managing Overlays. (line 54712) * make-pipe-process: Asynchronous Processes. (line 51330) * make-process: Asynchronous Processes. (line 51256) * make-progress-reporter: Progress. (line 53892) * make-ring: Rings. (line 7182) * make-serial-process: Serial Ports. (line 53110) * make-sparse-keymap: Creating Keymaps. (line 24307) * make-string: Creating Strings. (line 3888) * make-symbol: Creating Symbols. (line 7743) * make-symbolic-link: Changing Files. (line 31786) * make-syntax-table: Syntax Table Functions. (line 49750) * make-temp-file: Unique File Names. (line 32305) * make-temp-name: Unique File Names. (line 32371) * make-text-button: Making Buttons. (line 58439) * make-translation-table: Translation of Characters. (line 46982) * make-translation-table-from-alist: Translation of Characters. (line 47038) * make-translation-table-from-vector: Translation of Characters. (line 47025) * make-variable-buffer-local: Creating Buffer-Local. (line 10935) * make-vector: Vector Functions. (line 6892) * make-xwidget: Xwidgets. (line 58227) * making backup files: Making Backups. (line 33205) * making buttons: Making Buttons. (line 58401) * makunbound: Void Variables. (line 10155) * malicious use of directional overrides: Bidirectional Display. (line 59532) * managing overlays: Managing Overlays. (line 54705) * manipulating buttons: Manipulating Buttons. (line 58450) * map-char-table: Char-Tables. (line 7047) * map-charset-chars: Character Sets. (line 46926) * map-keymap: Scanning Keymaps. (line 25568) * map-y-or-n-p: Multiple Queries. (line 20946) * mapatoms: Creating Symbols. (line 7802) * mapc: Mapping Functions. (line 12366) * mapcar: Mapping Functions. (line 12334) * mapconcat: Mapping Functions. (line 12371) * maphash: Hash Access. (line 7426) * mapping functions: Mapping Functions. (line 12320) * margins, display: Display Margins. (line 57452) * margins, filling: Margins. (line 43786) * mark: The Mark. (line 42215) * mark excursion: Excursions. (line 41804) * mark ring: The Mark. (line 42204) * mark, the: The Mark. (line 42168) * mark-active: The Mark. (line 42328) * mark-even-if-inactive: The Mark. (line 42300) * mark-marker: The Mark. (line 42225) * mark-ring: The Mark. (line 42357) * mark-ring-max: The Mark. (line 42366) * marker argument: Interactive Codes. (line 21611) * marker creation: Creating Markers. (line 42010) * marker garbage collection: Overview of Markers. (line 41941) * marker information: Information from Markers. (line 42088) * marker input stream: Input Streams. (line 18771) * marker output stream: Output Streams. (line 18972) * marker relocation: Overview of Markers. (line 41934) * marker, how to move position: Moving Markers. (line 42138) * marker-buffer: Information from Markers. (line 42094) * marker-insertion-type: Marker Insertion Types. (line 42128) * marker-position: Information from Markers. (line 42091) * markerp: Predicates on Markers. (line 41994) * markers: Markers. (line 41910) * markers as numbers: Overview of Markers. (line 41948) * markers, predicates for: Predicates on Markers. (line 41990) * match data: Match Data. (line 48938) * match, customization keyword: Type Keywords. (line 14916) * match-alternatives, customization keyword: Composite Types. (line 14775) * match-beginning: Simple Match Data. (line 49068) * match-data: Entire Match Data. (line 49136) * match-end: Simple Match Data. (line 49079) * match-string: Simple Match Data. (line 49049) * match-string-no-properties: Simple Match Data. (line 49064) * match-substitute-replacement: Replacing Match. (line 49012) * mathematical functions: Math Functions. (line 3711) * max: Comparison of Numbers. (line 3232) * max-char: Character Codes. (line 46616) * max-image-size: Showing Images. (line 58091) * max-lisp-eval-depth: Eval. (line 8594) * max-mini-window-height: Minibuffer Windows. (line 21128) * max-mini-window-height <1>: Minibuffer Misc. (line 21226) * max-specpdl-size: Local Variables. (line 10118) * maximize-window: Resizing Windows. (line 35647) * maximized frames: Size Parameters. (line 39587) * maximizing windows: Resizing Windows. (line 35647) * maximum Lisp integer: Integer Basics. (line 3056) * maximum value of character codepoint: Character Codes. (line 46616) * md5: Checksum/Hash. (line 45985) * MD5 checksum: Checksum/Hash. (line 45946) * measuring resource usage: Profiling. (line 18663) * member: Sets And Lists. (line 5686) * member-ignore-case: Sets And Lists. (line 5748) * membership in a list: Sets And Lists. (line 5600) * memory allocation: Garbage Collection. (line 64581) * memory usage: Profiling. (line 18663) * memory usage <1>: Memory Usage. (line 64897) * memory-full: Garbage Collection. (line 64846) * memory-info: Garbage Collection. (line 64855) * memory-limit: Garbage Collection. (line 64838) * memory-use-counts: Garbage Collection. (line 64850) * memq: Sets And Lists. (line 5599) * memql: Sets And Lists. (line 5669) * menu bar: Menu Bar. (line 26072) * menu bar keymaps: Standard Keymaps. (line 66132) * menu definition example: Menu Example. (line 26015) * menu item: Defining Menus. (line 25661) * menu keymaps: Menu Keymaps. (line 25652) * menu modification: Modifying Menus. (line 26334) * menu prompt string: Defining Menus. (line 25661) * menu separators: Menu Separators. (line 25848) * menu-bar prefix key: Key Sequence Input. (line 23168) * menu-bar-file-menu: Standard Keymaps. (line 66132) * menu-bar-final-items: Menu Bar. (line 26120) * menu-bar-help-menu: Standard Keymaps. (line 66132) * menu-bar-lines frame parameter: Layout Parameters. (line 39678) * menu-bar-options-menu: Standard Keymaps. (line 66132) * menu-bar-tools-menu: Standard Keymaps. (line 66132) * menu-bar-update-hook: Menu Bar. (line 26129) * menu-item: Extended Menu Items. (line 25743) * menu-prompt-more-char: Keyboard Menus. (line 26008) * menus, popup: Pop-Up Menus. (line 40501) * merge-face-attribute: Attribute Functions. (line 55739) * message: Displaying Messages. (line 53776) * message digest: Checksum/Hash. (line 45951) * message, finding what causes a particular message: Error Debugging. (line 16791) * message-box: Displaying Messages. (line 53844) * message-log-max: Logging Messages. (line 53994) * message-or-box: Displaying Messages. (line 53832) * message-truncate-lines: Echo Area Customization. (line 54054) * messages-buffer: Logging Messages. (line 53990) * meta character key constants: Changing Key Bindings. (line 25078) * meta character printing: Describing Characters. (line 30268) * meta characters: Meta-Char Syntax. (line 1656) * meta characters lookup: Format of Keymaps. (line 24257) * meta-prefix-char: Functions for Key Lookup. (line 25028) * min: Comparison of Numbers. (line 3243) * minibuffer: Minibuffers. (line 19328) * minibuffer completion: Minibuffer Completion. (line 20061) * minibuffer contents, accessing: Minibuffer Contents. (line 21136) * minibuffer history: Minibuffer History. (line 19702) * minibuffer input: Recursive Editing. (line 23857) * minibuffer input, and command-line arguments: Shell Arguments. (line 50932) * minibuffer input, reading lisp objects: Object from Minibuffer. (line 19634) * minibuffer input, reading text strings: Text from Minibuffer. (line 19408) * minibuffer window, and next-window: Cyclic Window Ordering. (line 36333) * minibuffer windows: Minibuffer Windows. (line 21079) * minibuffer, a frame parameter: Buffer Parameters. (line 39702) * minibuffer-allow-text-properties: Text from Minibuffer. (line 19560) * minibuffer-auto-raise: Raising and Lowering. (line 40350) * minibuffer-complete: Completion Commands. (line 20200) * minibuffer-complete-and-exit: Completion Commands. (line 20203) * minibuffer-complete-word: Completion Commands. (line 20194) * minibuffer-completion-confirm: Completion Commands. (line 20176) * minibuffer-completion-help: Completion Commands. (line 20210) * minibuffer-completion-predicate: Completion Commands. (line 20171) * minibuffer-completion-table: Completion Commands. (line 20165) * minibuffer-confirm-exit-commands: Completion Commands. (line 20187) * minibuffer-contents: Minibuffer Contents. (line 21152) * minibuffer-contents-no-properties: Minibuffer Contents. (line 21157) * minibuffer-depth: Recursive Mini. (line 21173) * minibuffer-exit-hook: Minibuffer Misc. (line 21208) * minibuffer-frame-alist: Initial Parameters. (line 39421) * minibuffer-help-form: Minibuffer Misc. (line 21212) * minibuffer-history: Minibuffer History. (line 19785) * minibuffer-inactive-mode: Minibuffer Misc. (line 21239) * minibuffer-less frame: Frame Layout. (line 38995) * minibuffer-local-completion-map: Completion Commands. (line 20239) * minibuffer-local-filename-completion-map: Completion Commands. (line 20270) * minibuffer-local-map: Text from Minibuffer. (line 19568) * minibuffer-local-must-match-map: Completion Commands. (line 20256) * minibuffer-local-ns-map: Text from Minibuffer. (line 19616) * minibuffer-local-shell-command-map: Reading File Names. (line 20576) * minibuffer-message: Minibuffer Misc. (line 21231) * minibuffer-message-timeout: Minibuffer Misc. (line 21231) * minibuffer-only frame: Frame Layout. (line 38995) * minibuffer-only frame <1>: Initial Parameters. (line 39416) * minibuffer-prompt: Minibuffer Contents. (line 21138) * minibuffer-prompt-end: Minibuffer Contents. (line 21143) * minibuffer-prompt-width: Minibuffer Contents. (line 21148) * minibuffer-scroll-window: Minibuffer Misc. (line 21216) * minibuffer-selected-window: Minibuffer Misc. (line 21221) * minibuffer-setup-hook: Minibuffer Misc. (line 21204) * minibuffer-window: Minibuffer Windows. (line 21086) * minibuffer-window-active-p: Minibuffer Windows. (line 21108) * minibufferp: Minibuffer Misc. (line 21200) * minimize-window: Resizing Windows. (line 35653) * minimized frame: Visibility of Frames. (line 40286) * minimizing windows: Resizing Windows. (line 35653) * minimum Lisp integer: Integer Basics. (line 3060) * minor mode: Minor Modes. (line 27551) * minor mode conventions: Minor Mode Conventions. (line 27572) * minor-mode-alist: Mode Line Variables. (line 28163) * minor-mode-key-binding: Functions for Key Lookup. (line 25012) * minor-mode-list: Minor Modes. (line 27566) * minor-mode-map-alist: Controlling Active Maps. (line 24740) * minor-mode-overriding-map-alist: Controlling Active Maps. (line 24764) * mirroring of characters: Character Properties. (line 46725) * misc-objects-consed: Memory Usage. (line 64918) * mkdir: Create/Delete Dirs. (line 32626) * mod: Arithmetic Operations. (line 3451) * mode: Modes. (line 26476) * mode bits: Testing Accessibility. (line 31240) * mode help: Mode Help. (line 27044) * mode hook: Major Mode Conventions. (line 26830) * mode line: Mode Line Format. (line 27887) * mode line construct: Mode Line Data. (line 27937) * mode loading: Major Mode Conventions. (line 26886) * mode variable: Minor Mode Conventions. (line 27577) * mode-class (property): Major Mode Conventions. (line 26857) * mode-line prefix key: Key Sequence Input. (line 23168) * mode-line-buffer-identification: Mode Line Variables. (line 28103) * mode-line-client: Mode Line Variables. (line 28129) * mode-line-coding-system-map: Standard Keymaps. (line 66145) * mode-line-column-line-number-mode-map: Standard Keymaps. (line 66145) * mode-line-end-spaces: Mode Line Variables. (line 28156) * mode-line-format: Mode Line Top. (line 28019) * mode-line-frame-identification: Mode Line Variables. (line 28098) * mode-line-front-space: Mode Line Variables. (line 28151) * mode-line-input-method-map: Standard Keymaps. (line 66145) * mode-line-misc-info: Mode Line Variables. (line 28159) * mode-line-modes: Mode Line Variables. (line 28120) * mode-line-modified: Mode Line Variables. (line 28090) * mode-line-mule-info: Mode Line Variables. (line 28084) * mode-line-position: Mode Line Variables. (line 28108) * mode-line-process: Mode Line Variables. (line 28143) * mode-line-remote: Mode Line Variables. (line 28125) * mode-name: Mode Line Variables. (line 28134) * mode-specific-map: Prefix Keys. (line 24454) * model/view/controller: Abstract Display. (line 58557) * modification flag (of buffer): Buffer Modification. (line 34196) * modification of lists: Rearrangement. (line 5527) * modification time of buffer: Modification Time. (line 34260) * modification time of file: File Attributes. (line 31475) * modification-hooks (overlay property): Overlay Properties. (line 54974) * modification-hooks (text property): Special Properties. (line 45171) * modifier bits (of input character): Keyboard Events. (line 22097) * modifiers of events: Event Mod. (line 23315) * modify a list: List Variables. (line 5251) * modify-all-frames-parameters: Parameter Access. (line 39377) * modify-category-entry: Categories. (line 50356) * modify-frame-parameters: Parameter Access. (line 39344) * modify-syntax-entry: Syntax Table Functions. (line 49763) * modifying strings: Modifying Strings. (line 4082) * module-file-suffix: Dynamic Modules. (line 16042) * modulus: Arithmetic Operations. (line 3452) * momentary-string-display: Temporary Displays. (line 54635) * most recently selected windows: Selecting Windows. (line 36258) * most recently used window: Cyclic Window Ordering. (line 36434) * most-negative-fixnum: Integer Basics. (line 3060) * most-positive-fixnum: Integer Basics. (line 3056) * motion based on parsing: Motion via Parsing. (line 49969) * motion by chars, words, lines, lists: Motion. (line 41204) * motion event: Motion Events. (line 22538) * mouse click event: Click Events. (line 22246) * mouse drag event: Drag Events. (line 22392) * mouse events, data in: Accessing Mouse. (line 22838) * mouse events, in special parts of frame: Key Sequence Input. (line 23168) * mouse events, repeated: Repeat Events. (line 22453) * mouse motion events: Motion Events. (line 22538) * mouse pointer shape: Pointer Shape. (line 40627) * mouse position: Mouse Position. (line 40435) * mouse position list: Click Events. (line 22268) * mouse position list, accessing: Accessing Mouse. (line 22865) * mouse tracking: Mouse Tracking. (line 40390) * mouse, availability: Display Feature Testing. (line 40980) * mouse-1: Clickable Text. (line 45405) * mouse-1-click-follows-link: Clickable Text. (line 45478) * mouse-2: Key Binding Conventions. (line 63770) * mouse-absolute-pixel-position: Mouse Position. (line 40477) * mouse-action (button property): Button Properties. (line 58334) * mouse-appearance-menu-map: Standard Keymaps. (line 66155) * mouse-color, a frame parameter: Font and Color Parameters. (line 39930) * mouse-face (button property): Button Properties. (line 58344) * mouse-face (overlay property): Overlay Properties. (line 54950) * mouse-face (text property): Special Properties. (line 44968) * mouse-leave-buffer-hook: Standard Hooks. (line 66351) * mouse-movement-p: Classifying Events. (line 22819) * mouse-on-link-p: Clickable Text. (line 45562) * mouse-pixel-position: Mouse Position. (line 40463) * mouse-position: Mouse Position. (line 40438) * mouse-position-function: Mouse Position. (line 40444) * mouse-wheel-down-event: Misc Events. (line 22618) * mouse-wheel-up-event: Misc Events. (line 22618) * move to beginning or end of buffer: Buffer End Motion. (line 41320) * move-marker: Moving Markers. (line 42162) * move-overlay: Managing Overlays. (line 54754) * move-point-visually: Bidirectional Display. (line 59462) * move-to-column: Columns. (line 44190) * move-to-left-margin: Margins. (line 43830) * move-to-window-group-line: Screen Lines. (line 41539) * move-to-window-group-line-function: Screen Lines. (line 41539) * move-to-window-line: Screen Lines. (line 41519) * movemail: Subprocess Creation. (line 50877) * moving across syntax classes: Motion and Syntax. (line 49909) * moving markers: Moving Markers. (line 42138) * MS-DOS and file modes: Testing Accessibility. (line 31266) * MS-Windows file-name syntax: File Names. (line 31936) * mule-keymap: Prefix Keys. (line 24464) * multi-file package: Multi-file Packages. (line 62142) * multi-frame images: Multi-Frame Images. (line 58110) * multi-monitor: Multiple Terminals. (line 38793) * multi-query-replace-map: Search and Replace. (line 49363) * multi-tty: Multiple Terminals. (line 38655) * multibyte characters: Non-ASCII Characters. (line 46309) * multibyte text: Text Representations. (line 46329) * multibyte-char-to-unibyte: Converting Representations. (line 46533) * multibyte-string-p: Text Representations. (line 46416) * multibyte-syntax-as-symbol: Control Parsing. (line 50148) * multiline font lock: Multiline Font Lock. (line 29184) * multiple terminals: Multiple Terminals. (line 38655) * multiple windows: Basic Windows. (line 34861) * multiple X displays: Multiple Terminals. (line 38655) * multiple yes-or-no questions: Multiple Queries. (line 20940) * multiple-dispatch methods: Generic Functions. (line 12629) * multiple-frames: Frame Titles. (line 40046) * name, a frame parameter: Basic Parameters. (line 39479) * named function: Function Names. (line 12005) * naming backup files: Backup Names. (line 33422) * NaN: Float Basics. (line 3087) * narrow-map: Standard Keymaps. (line 66162) * narrow-to-page: Narrowing. (line 41839) * narrow-to-region: Narrowing. (line 41832) * narrowing: Narrowing. (line 41811) * native edges: Frame Layout. (line 38955) * native frame: Frame Layout. (line 38955) * native height: Frame Layout. (line 38955) * native position: Frame Layout. (line 38964) * native width: Frame Layout. (line 38955) * natnump: Predicates on Numbers. (line 3152) * natural numbers: Predicates on Numbers. (line 3153) * nbutlast: List Elements. (line 5046) * nconc: Rearrangement. (line 5536) * negative infinity: Float Basics. (line 3087) * negative-argument: Prefix Command Arguments. (line 23830) * network byte ordering: Bindat Spec. (line 53253) * network connection: Network. (line 52563) * network connection, encrypted: Network. (line 52609) * network servers: Network Servers. (line 52714) * network service name, and default coding system: Default Coding Systems. (line 47528) * network-coding-system-alist: Default Coding Systems. (line 47528) * network-interface-info: Misc Network. (line 53041) * network-interface-list: Misc Network. (line 53035) * new file message: Subroutines of Visiting. (line 30733) * newline: Basic Char Syntax. (line 1550) * newline <1>: Commands for Insertion. (line 42824) * newline and Auto Fill mode: Commands for Insertion. (line 42828) * newline in print: Output Functions. (line 19156) * newline in strings: Syntax for Strings. (line 2049) * newline-and-indent: Mode-Specific Indent. (line 44293) * next input: Event Input Misc. (line 23455) * next-button: Button Buffer Commands. (line 58547) * next-char-property-change: Property Search. (line 44867) * next-complete-history-element: Minibuffer Commands. (line 21072) * next-frame: Finding All Frames. (line 40102) * next-history-element: Minibuffer Commands. (line 21056) * next-matching-history-element: Minibuffer Commands. (line 21064) * next-overlay-change: Finding Overlays. (line 55101) * next-property-change: Property Search. (line 44816) * next-screen-context-lines: Textual Scrolling. (line 37789) * next-single-char-property-change: Property Search. (line 44881) * next-single-property-change: Property Search. (line 44845) * next-window: Cyclic Window Ordering. (line 36332) * nil: nil and t. (line 1070) * nil as a list: Box Diagrams. (line 1869) * nil in keymap: Key Lookup. (line 24882) * nil input stream: Input Streams. (line 18801) * nil output stream: Output Streams. (line 18987) * nlistp: List-related Predicates. (line 4882) * no-byte-compile: Byte Compilation. (line 16089) * no-catch: Catch and Throw. (line 9358) * no-conversion coding system: Coding System Basics. (line 47116) * no-redraw-on-reenter: Refresh Screen. (line 53643) * no-self-insert property: Defining Abbrevs. (line 50492) * node, ewoc: Abstract Display. (line 58575) * non-ASCII characters: Non-ASCII Characters. (line 46309) * non-ASCII characters in loaded files: Loading Non-ASCII. (line 15480) * non-ASCII text in keybindings: Key Binding Commands. (line 25448) * non-capturing group: Regexp Backslash. (line 48475) * non-greedy repetition characters in regexp: Regexp Special. (line 48226) * nondirectory part (of file name): File Name Components. (line 31952) * noninteractive: Batch Mode. (line 61330) * nonlocal exits: Nonlocal Exits. (line 9278) * nonlocal exits, cleaning up: Cleanups. (line 9867) * nonprinting characters, reading: Quoted Character Input. (line 23424) * noreturn: Test Coverage. (line 18652) * normal hook: Hooks. (line 26497) * normal-auto-fill-function: Auto Filling. (line 43954) * normal-backup-enable-predicate: Making Backups. (line 33250) * normal-mode: Auto Major Mode. (line 26899) * not: Combining Conditions. (line 9023) * not-modified: Buffer Modification. (line 34231) * notation: Evaluation Notation. (line 1105) * notifications, on desktop: Desktop Notifications. (line 61382) * notifications-close-notification: Desktop Notifications. (line 61530) * notifications-get-capabilities: Desktop Notifications. (line 61534) * notifications-get-server-information: Desktop Notifications. (line 61570) * notifications-notify: Desktop Notifications. (line 61389) * nreverse: Sequence Functions. (line 6262) * nth: List Elements. (line 4980) * nthcdr: List Elements. (line 4995) * null: List-related Predicates. (line 4888) * null bytes, and decoding text: Lisp and Coding Systems. (line 47341) * num-input-keys: Key Sequence Input. (line 23189) * num-nonmacro-input-events: Reading One Event. (line 23282) * number comparison: Comparison of Numbers. (line 3168) * number conversions: Numeric Conversions. (line 3256) * number-or-marker-p: Predicates on Markers. (line 42003) * number-sequence: Building Lists. (line 5200) * number-to-string: String Conversion. (line 4341) * numbered backups: Numbered Backups. (line 33368) * numberp: Predicates on Numbers. (line 3148) * numbers: Numbers. (line 2975) * numeric prefix argument: Prefix Command Arguments. (line 23726) * numeric prefix argument usage: Interactive Codes. (line 21629) * numerical RGB color specification: Color Names. (line 40754) * obarray: Creating Symbols. (line 7799) * obarray <1>: Creating Symbols. (line 7671) * obarray in completion: Basic Completion. (line 19901) * object: Lisp Data Types. (line 1366) * object internals: Object Internals. (line 65173) * object to string: Output Functions. (line 19166) * obsolete functions: Obsolete Functions. (line 13145) * octal character code: General Escape Syntax. (line 1610) * octal character input: Quoted Character Input. (line 23424) * octal escapes: Usual Display. (line 58920) * octal numbers: Integer Basics. (line 3004) * old advices, porting: Porting old advice. (line 13075) * one-window-p: Cyclic Window Ordering. (line 36408) * only-global-abbrevs: Defining Abbrevs. (line 50504) * opacity, frame: Font and Color Parameters. (line 39897) * open-dribble-file: Recording Input. (line 61149) * open-network-stream: Network. (line 52620) * open-paren-in-column-0-is-defun-start: List Motion. (line 41679) * open-termscript: Terminal Output. (line 61204) * OpenType font: Low-Level Font. (line 56465) * operating system environment: System Environment. (line 60182) * operating system signal: Killing Emacs. (line 60040) * operations (property): Magic File Names. (line 32797) * optimize regexp: Regexp Functions. (line 48678) * option descriptions: A Sample Variable Description. (line 1274) * optional arguments: Argument List. (line 11891) * options on command line: Command-Line Arguments. (line 59964) * options, defcustom keyword: Variable Definitions. (line 14244) * or: Combining Conditions. (line 9069) * ordering of windows, cyclic: Cyclic Window Ordering. (line 36321) * other-buffer: Buffer List. (line 34480) * other-window: Cyclic Window Ordering. (line 36379) * other-window-scroll-buffer: Textual Scrolling. (line 37730) * outer edges: Frame Layout. (line 38906) * outer frame: Frame Layout. (line 38906) * outer height: Frame Layout. (line 38906) * outer position: Frame Layout. (line 38911) * outer width: Frame Layout. (line 38906) * outer-window-id, a frame parameter: Management Parameters. (line 39763) * output from processes: Output from Processes. (line 51879) * output stream: Output Streams. (line 18963) * output-controlling variables: Output Variables. (line 19210) * overall prompt string: Format of Keymaps. (line 24239) * overflow: Integer Basics. (line 2989) * overflow-newline-into-fringe: Fringe Cursors. (line 56829) * overlay properties: Overlay Properties. (line 54855) * overlay, empty: Managing Overlays. (line 54719) * overlay-arrow-position: Overlay Arrow. (line 56972) * overlay-arrow-string: Overlay Arrow. (line 56966) * overlay-arrow-variable-list: Overlay Arrow. (line 56993) * overlay-buffer: Managing Overlays. (line 54741) * overlay-end: Managing Overlays. (line 54738) * overlay-get: Overlay Properties. (line 54878) * overlay-properties: Overlay Properties. (line 54888) * overlay-put: Overlay Properties. (line 54884) * overlay-recenter: Managing Overlays. (line 54843) * overlay-start: Managing Overlays. (line 54735) * overlayp: Managing Overlays. (line 54709) * overlays: Overlays. (line 54684) * overlays, managing: Managing Overlays. (line 54705) * overlays, scalability: Overlays. (line 54690) * overlays, searching for: Finding Overlays. (line 55073) * overlays-at: Finding Overlays. (line 55073) * overlays-in: Finding Overlays. (line 55093) * overlined text: Face Attributes. (line 55433) * override spec (for a face): Defining Faces. (line 55674) * overriding bidirectional properties: Bidirectional Display. (line 59524) * overriding-local-map: Controlling Active Maps. (line 24777) * overriding-local-map-menu-flag: Controlling Active Maps. (line 24794) * overriding-terminal-local-map: Controlling Active Maps. (line 24784) * overwrite-mode: Commands for Insertion. (line 42841) * package: Packaging. (line 61976) * package archive: Package Archives. (line 62209) * package archive security: Package Archives. (line 62278) * package attributes: Packaging Basics. (line 61989) * package autoloads: Packaging Basics. (line 62040) * package dependencies: Packaging Basics. (line 61989) * package name: Packaging Basics. (line 61989) * package signing: Package Archives. (line 62278) * package version: Packaging Basics. (line 61989) * package-archive-upload-base: Package Archives. (line 62244) * package-archives: Package Archives. (line 62216) * package-initialize: Packaging Basics. (line 62062) * package-upload-buffer: Package Archives. (line 62268) * package-upload-file: Package Archives. (line 62254) * package-version, customization keyword: Common Keywords. (line 14088) * packing: Byte Packing. (line 53239) * padding: Formatting Strings. (line 4538) * page-delimiter: Standard Regexps. (line 49395) * paragraph-separate: Standard Regexps. (line 49408) * paragraph-start: Standard Regexps. (line 49415) * parameters of initial frame: Initial Parameters. (line 39386) * parent of char-table: Char-Tables. (line 6960) * parent process: Processes. (line 50780) * parent window: Windows and Frames. (line 34999) * parent window <1>: Windows and Frames. (line 35009) * parenthesis: Cons Cell Type. (line 1808) * parenthesis depth: Low-Level Parsing. (line 50129) * parenthesis matching: Blinking. (line 58833) * parenthesis mismatch, debugging: Syntax Errors. (line 18570) * parity, in serial connections: Serial Ports. (line 53181) * parse state for a position: Position Parse. (line 50026) * parse-colon-path: System Environment. (line 60322) * parse-partial-sexp: Low-Level Parsing. (line 50121) * parse-sexp-ignore-comments: Control Parsing. (line 50154) * parse-sexp-lookup-properties: Syntax Properties. (line 49873) * parse-sexp-lookup-properties <1>: Control Parsing. (line 50158) * parser state: Parser State. (line 50062) * parsing buffer text: Syntax Tables. (line 49438) * parsing expressions: Parsing Expressions. (line 49941) * parsing html: Parsing HTML/XML. (line 46002) * parsing xml: Parsing HTML/XML. (line 46041) * parsing, control parameters: Control Parsing. (line 50148) * partial application of functions: Calling Functions. (line 12266) * partial-width windows: Truncation. (line 53714) * passwords, reading: Reading a Password. (line 21021) * PATH environment variable: Subprocess Creation. (line 50827) * path-separator: System Environment. (line 60317) * pattern matching: Pattern matching case statement. (line 8851) * PBM: Other Image Types. (line 57880) * pcase: Pattern matching case statement. (line 8859) * pcase <1>: Pattern matching case statement. (line 8851) * pcase-defmacro: Pattern matching case statement. (line 9009) * peculiar error: Error Symbols. (line 9814) * peeking at input: Event Input Misc. (line 23455) * percent symbol in mode line: Mode Line Data. (line 27951) * perform-replace: Search and Replace. (line 49251) * performance analysis: Coverage Testing. (line 17941) * permanent local variable: Creating Buffer-Local. (line 11073) * permissions, file: Testing Accessibility. (line 31240) * permissions, file <1>: Changing Files. (line 31813) * phishing using directional overrides: Bidirectional Display. (line 59532) * piece of advice: Advising Functions. (line 12774) * pipe: Asynchronous Processes. (line 51242) * pixel height of a window: Window Sizes. (line 35262) * pixel width of a window: Window Sizes. (line 35272) * pixelwise, resizing windows: Resizing Windows. (line 35512) * place form: Generalized Variables. (line 11530) * play-sound: Sound Output. (line 61231) * play-sound-file: Sound Output. (line 61263) * play-sound-functions: Sound Output. (line 61267) * plist: Property Lists. (line 6001) * plist access: Plist Access. (line 6053) * plist vs. alist: Plists and Alists. (line 6025) * plist-get: Plist Access. (line 6056) * plist-member: Plist Access. (line 6093) * plist-put: Plist Access. (line 6071) * plugin_is_GPL_compatible: Dynamic Modules. (line 16046) * point: Point. (line 41168) * point <1>: Point. (line 41144) * point excursion: Excursions. (line 41766) * point excursion <1>: Excursions. (line 41804) * point in window: Window Point. (line 37401) * point with narrowing: Point. (line 41154) * point-entered (text property): Special Properties. (line 45201) * point-left (text property): Special Properties. (line 45201) * point-marker: Creating Markers. (line 42023) * point-max: Point. (line 41179) * point-max-marker: Creating Markers. (line 42033) * point-min: Point. (line 41174) * point-min-marker: Creating Markers. (line 42028) * pointer (text property): Special Properties. (line 45128) * pointer shape: Pointer Shape. (line 40627) * pointers: Cons Cell Type. (line 1787) * polymorphism: Generic Functions. (line 12472) * pop: List Elements. (line 4954) * pop-mark: The Mark. (line 42274) * pop-to-buffer: Switching Buffers. (line 36693) * pop-up-frame-alist: Choosing Window Options. (line 37121) * pop-up-frame-function: Choosing Window Options. (line 37110) * pop-up-frames: Choosing Window Options. (line 37091) * pop-up-windows: Choosing Window Options. (line 37027) * port number, and default coding system: Default Coding Systems. (line 47528) * pos-visible-in-window-group-p: Window Start and End. (line 37612) * pos-visible-in-window-group-p-function: Window Start and End. (line 37612) * pos-visible-in-window-p: Window Start and End. (line 37580) * position (in buffer): Positions. (line 41123) * position argument: Interactive Codes. (line 21547) * position in window: Window Point. (line 37401) * position of frame: Frame Geometry. (line 38869) * position of frame <1>: Size and Position. (line 39135) * position of mouse: Mouse Position. (line 40435) * position-bytes: Text Representations. (line 46369) * positive infinity: Float Basics. (line 3087) * posix-looking-at: POSIX Regexps. (line 48927) * posix-search-backward: POSIX Regexps. (line 48923) * posix-search-forward: POSIX Regexps. (line 48919) * posix-string-match: POSIX Regexps. (line 48931) * posn-actual-col-row: Accessing Mouse. (line 22912) * posn-area: Accessing Mouse. (line 22873) * posn-at-point: Accessing Mouse. (line 22954) * posn-at-x-y: Accessing Mouse. (line 22961) * posn-col-row: Accessing Mouse. (line 22900) * posn-image: Accessing Mouse. (line 22927) * posn-object: Accessing Mouse. (line 22931) * posn-object-width-height: Accessing Mouse. (line 22941) * posn-object-x-y: Accessing Mouse. (line 22936) * posn-point: Accessing Mouse. (line 22878) * posn-string: Accessing Mouse. (line 22923) * posn-timestamp: Accessing Mouse. (line 22946) * posn-window: Accessing Mouse. (line 22868) * posn-x-y: Accessing Mouse. (line 22883) * posnp: Accessing Mouse. (line 22860) * post-command-hook: Command Overview. (line 21295) * post-gc-hook: Garbage Collection. (line 64792) * post-self-insert-hook: Commands for Insertion. (line 42816) * postscript images: PostScript Images. (line 57786) * pp: Output Functions. (line 19197) * pre-command-hook: Command Overview. (line 21289) * pre-redisplay-function: Forcing Redisplay. (line 53679) * pre-redisplay-functions: Forcing Redisplay. (line 53684) * preceding-char: Near Point. (line 42494) * precision in format specifications: Formatting Strings. (line 4596) * predicates for lists: List-related Predicates. (line 4858) * predicates for markers: Predicates on Markers. (line 41990) * predicates for numbers: Predicates on Numbers. (line 3134) * predicates for strings: Predicates for Strings. (line 3868) * prefix argument: Prefix Command Arguments. (line 23726) * prefix argument unreading: Event Input Misc. (line 23464) * prefix command: Prefix Keys. (line 24527) * prefix key: Prefix Keys. (line 24437) * prefix, defgroup keyword: Group Definitions. (line 14167) * prefix-arg: Prefix Command Arguments. (line 23806) * prefix-command-echo-keystrokes-functions: Standard Hooks. (line 66357) * prefix-command-preserve-state-hook: Standard Hooks. (line 66365) * prefix-help-command: Help Functions. (line 30401) * prefix-numeric-value: Prefix Command Arguments. (line 23794) * preloaded Lisp files: Building Emacs. (line 64449) * preloaded-file-list: Building Emacs. (line 64449) * preloading additional functions and variables: Building Emacs. (line 64472) * prepare-change-group: Atomic Changes. (line 46175) * preserving window sizes: Preserving Window Sizes. (line 35662) * preventing backtracking: Specification List. (line 18271) * preventing prefix key: Key Lookup. (line 24933) * preventing quitting: Quitting. (line 23660) * previous complete subexpression: Parser State. (line 50075) * previous-button: Button Buffer Commands. (line 58548) * previous-char-property-change: Property Search. (line 44876) * previous-complete-history-element: Minibuffer Commands. (line 21068) * previous-frame: Finding All Frames. (line 40122) * previous-history-element: Minibuffer Commands. (line 21052) * previous-matching-history-element: Minibuffer Commands. (line 21060) * previous-overlay-change: Finding Overlays. (line 55105) * previous-property-change: Property Search. (line 44840) * previous-single-char-property-change: Property Search. (line 44890) * previous-single-property-change: Property Search. (line 44861) * previous-window: Cyclic Window Ordering. (line 36374) * primary selection: Window System Selections. (line 40667) * primitive: What Is a Function. (line 11700) * primitive function: Primitive Function Type. (line 2290) * primitive function internals: Writing Emacs Primitives. (line 64944) * primitive type: Lisp Data Types. (line 1376) * primitive-undo: Undo. (line 43538) * prin1: Output Functions. (line 19130) * prin1-to-string: Output Functions. (line 19165) * princ: Output Functions. (line 19141) * print: Output Functions. (line 19113) * print example: Output Streams. (line 19004) * print name cell: Symbol Components. (line 7556) * print-circle: Output Variables. (line 19292) * print-continuous-numbering: Output Variables. (line 19303) * print-escape-multibyte: Output Variables. (line 19254) * print-escape-newlines: Output Variables. (line 19220) * print-escape-nonascii: Output Variables. (line 19244) * print-gensym: Output Variables. (line 19296) * print-length: Output Variables. (line 19264) * print-level: Output Variables. (line 19277) * print-number-table: Output Variables. (line 19310) * print-quoted: Output Variables. (line 19215) * printable ASCII characters: Usual Display. (line 58894) * printable-chars: Character Properties. (line 46834) * printed representation: Printed Representation. (line 1408) * printed representation for characters: Basic Char Syntax. (line 1530) * printing: Streams Intro. (line 18720) * printing (Edebug): Printing in Edebug. (line 17862) * printing circular structures: Printing in Edebug. (line 17862) * printing limits: Output Variables. (line 19265) * printing notation: Printing Notation. (line 1130) * priority (overlay property): Overlay Properties. (line 54899) * priority order of coding systems: Specifying Coding Systems. (line 47670) * process: Processes. (line 50780) * process creation: Subprocess Creation. (line 50814) * process filter: Filter Functions. (line 52044) * process filter multibyte flag: Decoding Output. (line 52174) * process information: Process Information. (line 51530) * process input: Input to Processes. (line 51718) * process internals: Process Internals. (line 65691) * process output: Output from Processes. (line 51879) * process sentinel: Sentinels. (line 52217) * process signals: Signals to Processes. (line 51783) * process-adaptive-read-buffering: Output from Processes. (line 51913) * process-attributes: System Processes. (line 52370) * process-buffer: Process Buffers. (line 51947) * process-coding-system: Process Information. (line 51688) * process-coding-system-alist: Default Coding Systems. (line 47506) * process-command: Process Information. (line 51558) * process-connection-type: Asynchronous Processes. (line 51463) * process-contact: Process Information. (line 51568) * process-datagram-address: Datagrams. (line 52769) * process-environment: System Environment. (line 60298) * process-exit-status: Process Information. (line 51672) * process-file: Synchronous Processes. (line 51093) * process-file-shell-command: Synchronous Processes. (line 51200) * process-file-side-effects: Synchronous Processes. (line 51132) * process-filter: Filter Functions. (line 52118) * process-get: Process Information. (line 51703) * process-id: Process Information. (line 51610) * process-kill-buffer-query-function: Process Buffers. (line 51940) * process-lines: Synchronous Processes. (line 51212) * process-list: Process Information. (line 51544) * process-live-p: Process Information. (line 51661) * process-mark: Process Buffers. (line 51954) * process-name: Process Information. (line 51618) * process-plist: Process Information. (line 51709) * process-put: Process Information. (line 51706) * process-query-on-exit-flag: Query Before Exit. (line 52338) * process-running-child-p: Input to Processes. (line 51771) * process-send-eof: Input to Processes. (line 51763) * process-send-region: Input to Processes. (line 51756) * process-send-string: Input to Processes. (line 51749) * process-sentinel: Sentinels. (line 52314) * process-status: Process Information. (line 51621) * process-tty-name: Process Information. (line 51679) * process-type: Process Information. (line 51666) * processing of errors: Processing of Errors. (line 9545) * processor run time: Processor Run Time. (line 60810) * processp: Processes. (line 50802) * profile: Profiling. (line 18663) * profiling: Profiling. (line 18663) * prog-mode: Basic Major Modes. (line 27187) * prog-mode, and bidi-paragraph-direction: Bidirectional Display. (line 59441) * prog-mode-hook: Basic Major Modes. (line 27173) * prog1: Sequencing. (line 8717) * prog2: Sequencing. (line 8734) * progn: Sequencing. (line 8702) * program arguments: Subprocess Creation. (line 50862) * program directories: Subprocess Creation. (line 50887) * program name, and default coding system: Default Coding Systems. (line 47506) * programmed completion: Programmed Completion. (line 20665) * programming conventions: Programming Tips. (line 63830) * programming types: Programming Types. (line 1462) * progress reporting: Progress. (line 53876) * progress-reporter-done: Progress. (line 53955) * progress-reporter-force-update: Progress. (line 53945) * progress-reporter-update: Progress. (line 53927) * prompt for file name: Reading File Names. (line 20403) * prompt string (of menu): Defining Menus. (line 25661) * prompt string of keymap: Format of Keymaps. (line 24239) * properties of text: Text Properties. (line 44548) * propertize: Changing Properties. (line 44763) * property category of text character: Special Properties. (line 44927) * property list: Property Lists. (line 6001) * property list cell: Symbol Components. (line 7566) * property lists vs association lists: Plists and Alists. (line 6025) * protect C variables from garbage collection: Writing Emacs Primitives. (line 65049) * protected forms: Cleanups. (line 9873) * provide: Named Features. (line 15812) * provide-theme: Custom Themes. (line 15060) * providing features: Named Features. (line 15746) * pty: Asynchronous Processes. (line 51242) * pure storage: Pure Storage. (line 64529) * pure-bytes-used: Pure Storage. (line 64561) * purecopy: Pure Storage. (line 64550) * purify-flag: Pure Storage. (line 64567) * push: List Variables. (line 5254) * push-button: Button Buffer Commands. (line 58520) * push-mark: The Mark. (line 42264) * put: Symbol Plists. (line 7863) * put-char-code-property: Character Properties. (line 46815) * put-charset-property: Character Sets. (line 46895) * put-image: Showing Images. (line 58058) * put-text-property: Changing Properties. (line 44665) * puthash: Hash Access. (line 7406) * query-font: Low-Level Font. (line 56607) * query-replace-history: Minibuffer History. (line 19789) * query-replace-map: Search and Replace. (line 49291) * querying the user: Yes-or-No Queries. (line 20850) * question mark in character constant: Basic Char Syntax. (line 1530) * quietly-read-abbrev-file: Abbrev Files. (line 50530) * QUIT, use in Lisp primitives: Writing Emacs Primitives. (line 65058) * quit-flag: Quitting. (line 23687) * quit-process: Signals to Processes. (line 51842) * quit-restore-window: Quitting Windows. (line 37315) * quit-window: Quitting Windows. (line 37308) * quitting: Quitting. (line 23622) * quitting from infinite loop: Infinite Loops. (line 16804) * quote: Quoting. (line 8428) * quote character: Parser State. (line 50084) * quote special characters in regexp: Regexp Functions. (line 48658) * quoted character input: Quoted Character Input. (line 23419) * quoted-insert suppression: Changing Key Bindings. (line 25218) * quoting and unquoting command-line arguments: Shell Arguments. (line 50932) * quoting characters in printing: Output Functions. (line 19084) * quoting using apostrophe: Quoting. (line 8431) * radio, customization types: Composite Types. (line 14669) * radix for reading an integer: Integer Basics. (line 3004) * raise-frame: Raising and Lowering. (line 40341) * raising a frame: Raising and Lowering. (line 40333) * random: Random Numbers. (line 3782) * random numbers: Random Numbers. (line 3762) * rassoc: Association Lists. (line 5843) * rassq: Association Lists. (line 5886) * rassq-delete-all: Association Lists. (line 5985) * raw prefix argument: Prefix Command Arguments. (line 23726) * raw prefix argument usage: Interactive Codes. (line 21632) * raw syntax descriptor: Syntax Table Internals. (line 50181) * raw-text coding system: Coding System Basics. (line 47107) * re-builder: Regular Expressions. (line 48143) * re-search-backward: Regexp Search. (line 48791) * re-search-forward: Regexp Search. (line 48743) * read: Input Functions. (line 18902) * read command name: Interactive Call. (line 21834) * read file names: Reading File Names. (line 20403) * read input: Reading Input. (line 23071) * read syntax: Printed Representation. (line 1408) * read syntax for characters: Basic Char Syntax. (line 1530) * read-buffer: High-Level Completion. (line 20288) * read-buffer-completion-ignore-case: High-Level Completion. (line 20330) * read-buffer-function: High-Level Completion. (line 20325) * read-char: Reading One Event. (line 23251) * read-char-choice: Reading One Event. (line 23303) * read-char-exclusive: Reading One Event. (line 23273) * read-circle: Input Functions. (line 18940) * read-coding-system: User-Chosen Coding Systems. (line 47442) * read-color: High-Level Completion. (line 20376) * read-command: High-Level Completion. (line 20334) * read-directory-name: Reading File Names. (line 20509) * read-event: Reading One Event. (line 23200) * read-expression-history: Minibuffer History. (line 19808) * read-file-modes: Changing Files. (line 31865) * read-file-name: Reading File Names. (line 20408) * read-file-name-completion-ignore-case: Reading File Names. (line 20505) * read-file-name-function: Reading File Names. (line 20500) * read-from-minibuffer: Text from Minibuffer. (line 19420) * read-from-string: Input Functions. (line 18906) * read-input-method-name: Input Methods. (line 47882) * read-kbd-macro: Describing Characters. (line 30311) * read-key: Reading One Event. (line 23291) * read-key-sequence: Key Sequence Input. (line 23088) * read-key-sequence-vector: Key Sequence Input. (line 23143) * read-minibuffer: Object from Minibuffer. (line 19637) * read-no-blanks-input: Text from Minibuffer. (line 19595) * read-non-nil-coding-system: User-Chosen Coding Systems. (line 47449) * read-only (text property): Special Properties. (line 45041) * read-only buffer: Read Only Buffers. (line 34346) * read-only buffers in interactive: Using Interactive. (line 21402) * read-only character: Special Properties. (line 45041) * read-only-mode: Read Only Buffers. (line 34387) * read-passwd: Reading a Password. (line 21024) * read-quoted-char: Quoted Character Input. (line 23423) * read-quoted-char quitting: Quitting. (line 23668) * read-regexp: Text from Minibuffer. (line 19504) * read-regexp-defaults-function: Text from Minibuffer. (line 19547) * read-shell-command: Reading File Names. (line 20560) * read-string: Text from Minibuffer. (line 19478) * read-variable: High-Level Completion. (line 20370) * reading: Streams Intro. (line 18720) * reading a single event: Reading One Event. (line 23197) * reading from files: Reading from Files. (line 30926) * reading from minibuffer with completion: Minibuffer Completion. (line 20061) * reading interactive arguments: Interactive Codes. (line 21509) * reading numbers in hex, octal, and binary: Integer Basics. (line 3004) * reading order: Bidirectional Display. (line 59368) * reading symbols: Creating Symbols. (line 7666) * real-last-command: Command Loop Info. (line 21944) * rearrangement of lists: Rearrangement. (line 5527) * rebinding: Changing Key Bindings. (line 25063) * recent-auto-save-p: Auto-Saving. (line 33596) * recent-keys: Recording Input. (line 61137) * recenter: Textual Scrolling. (line 37803) * recenter-positions: Textual Scrolling. (line 37846) * recenter-redisplay: Textual Scrolling. (line 37835) * recenter-top-bottom: Textual Scrolling. (line 37840) * recenter-window-group: Textual Scrolling. (line 37825) * recenter-window-group-function: Textual Scrolling. (line 37825) * recombining windows: Recombining Windows. (line 35950) * record command history: Interactive Call. (line 21796) * recording input: Recording Input. (line 61137) * recursion: Iteration. (line 9110) * recursion-depth: Recursive Editing. (line 23928) * recursive command loop: Recursive Editing. (line 23839) * recursive editing level: Recursive Editing. (line 23839) * recursive evaluation: Intro Eval. (line 8057) * recursive minibuffers: Recursive Mini. (line 21170) * recursive-edit: Recursive Editing. (line 23890) * redirect-frame-focus: Input Focus. (line 40238) * redisplay: Forcing Redisplay. (line 53655) * redo: Undo. (line 43426) * redraw-display: Refresh Screen. (line 53630) * redraw-frame: Refresh Screen. (line 53624) * reducing sequences: Sequence Functions. (line 6499) * references, following: Key Binding Conventions. (line 63770) * refresh the screen: Refresh Screen. (line 53620) * regexp: Regular Expressions. (line 48138) * regexp alternative: Regexp Backslash. (line 48429) * regexp grouping: Regexp Backslash. (line 48457) * regexp searching: Regexp Search. (line 48733) * regexp syntax: Syntax of Regexps. (line 48153) * regexp, special characters in: Regexp Special. (line 48176) * regexp-history: Minibuffer History. (line 19799) * regexp-opt: Regexp Functions. (line 48678) * regexp-opt-charset: Regexp Functions. (line 48717) * regexp-opt-depth: Regexp Functions. (line 48712) * regexp-quote: Regexp Functions. (line 48658) * regexps used standardly in editing: Standard Regexps. (line 49392) * region: The Region. (line 42387) * region argument: Interactive Codes. (line 21635) * region-beginning: The Region. (line 42395) * region-end: The Region. (line 42399) * register preview: Registers. (line 45843) * register-alist: Registers. (line 45768) * register-read-with-preview: Registers. (line 45842) * registers: Registers. (line 45761) * regular expression: Regular Expressions. (line 48138) * regular expression searching: Regexp Search. (line 48733) * regular expressions, developing: Regular Expressions. (line 48143) * reindent-then-newline-and-indent: Mode-Specific Indent. (line 44298) * relative file name: Relative File Names. (line 32055) * relative remapping, faces: Face Remapping. (line 55931) * remainder: Arithmetic Operations. (line 3432) * remapping commands: Remapping Commands. (line 25245) * remhash: Hash Access. (line 7410) * remote-file-name-inhibit-cache: Magic File Names. (line 32879) * remove: Sets And Lists. (line 5734) * remove-from-invisibility-spec: Invisible Text. (line 54321) * remove-function: Core Advising Primitives. (line 12892) * remove-hook: Setting Hooks. (line 26617) * remove-images: Showing Images. (line 58077) * remove-list-of-text-properties: Changing Properties. (line 44710) * remove-overlays: Managing Overlays. (line 54770) * remove-text-properties: Changing Properties. (line 44689) * removing from sequences: Sequence Functions. (line 6490) * remq: Sets And Lists. (line 5657) * rename-auto-save-file: Auto-Saving. (line 33656) * rename-buffer: Buffer Names. (line 34019) * rename-file: Changing Files. (line 31747) * rendering html: Parsing HTML/XML. (line 46036) * reordering, of bidirectional text: Bidirectional Display. (line 59368) * reordering, of elements in lists: Rearrangement. (line 5527) * repeat events: Repeat Events. (line 22453) * repeated loading: Repeated Loading. (line 15699) * replace bindings: Changing Key Bindings. (line 25171) * replace characters: Substitution. (line 45726) * replace characters in region: Substitution. (line 45721) * replace list element: Setcar. (line 5379) * replace matched text: Replacing Match. (line 48957) * replace part of list: Setcdr. (line 5456) * replace-buffer-in-windows: Buffers and Windows. (line 36555) * replace-match: Replacing Match. (line 48960) * replace-re-search-function: Search and Replace. (line 49383) * replace-regexp-in-string: Search and Replace. (line 49232) * replace-search-function: Search and Replace. (line 49377) * replacement after search: Search and Replace. (line 49219) * replacing display specs: Replacing Specs. (line 57216) * require: Named Features. (line 15846) * require, customization keyword: Common Keywords. (line 14075) * require-final-newline: Saving Buffers. (line 30908) * requiring features: Named Features. (line 15746) * reserved keys: Key Binding Conventions. (line 63778) * resize window: Resizing Windows. (line 35433) * resize-mini-windows: Minibuffer Windows. (line 21116) * rest arguments: Argument List. (line 11891) * restore-buffer-modified-p: Buffer Modification. (line 34227) * restricted-sexp, customization types: Composite Types. (line 14744) * restriction (in a buffer): Narrowing. (line 41811) * resume (cf. no-redraw-on-reenter): Refresh Screen. (line 53644) * resume-tty: Suspending Emacs. (line 60156) * resume-tty-functions: Suspending Emacs. (line 60160) * rethrow a signal: Handling Errors. (line 9709) * return (ASCII character): Basic Char Syntax. (line 1550) * return value: What Is a Function. (line 11673) * reverse: Sequence Functions. (line 6238) * reversing a list: Sequence Functions. (line 6263) * reversing a string: Sequence Functions. (line 6263) * reversing a vector: Sequence Functions. (line 6263) * revert-buffer: Reverting. (line 33711) * revert-buffer-function: Reverting. (line 33756) * revert-buffer-in-progress-p: Reverting. (line 33739) * revert-buffer-insert-file-contents-function: Reverting. (line 33766) * revert-without-query: Reverting. (line 33746) * reverting buffers: Reverting. (line 33706) * rgb value: Color Names. (line 40815) * right dividers: Window Dividers. (line 57142) * right-divider-width, a frame parameter: Layout Parameters. (line 39668) * right-fringe, a frame parameter: Layout Parameters. (line 39657) * right-fringe-width: Fringe Size/Pos. (line 56702) * right-margin-width: Display Margins. (line 57481) * right-to-left text: Bidirectional Display. (line 59358) * ring data structure: Rings. (line 7173) * ring-bell-function: Beeping. (line 59243) * ring-copy: Rings. (line 7200) * ring-elements: Rings. (line 7196) * ring-empty-p: Rings. (line 7204) * ring-insert: Rings. (line 7217) * ring-insert-at-beginning: Rings. (line 7230) * ring-length: Rings. (line 7192) * ring-p: Rings. (line 7186) * ring-ref: Rings. (line 7212) * ring-remove: Rings. (line 7224) * ring-size: Rings. (line 7189) * risky, defcustom keyword: Variable Definitions. (line 14319) * risky-local-variable-p: File Local Variables. (line 11286) * RLO: Bidirectional Display. (line 59524) * rm: Changing Files. (line 31794) * root window: Windows and Frames. (line 34977) * round: Numeric Conversions. (line 3315) * rounding in conversions: Numeric Conversions. (line 3256) * rounding without conversion: Rounding Operations. (line 3485) * rplaca: Modifying Lists. (line 5371) * rplacd: Modifying Lists. (line 5371) * run time stack: Internals of Debugger. (line 17128) * run-at-time: Timers. (line 60910) * run-hook-with-args: Running Hooks. (line 26557) * run-hook-with-args-until-failure: Running Hooks. (line 26561) * run-hook-with-args-until-success: Running Hooks. (line 26568) * run-hooks: Running Hooks. (line 26540) * run-mode-hooks: Mode Hooks. (line 27243) * run-with-idle-timer: Idle Timers. (line 61001) * S-expression: Intro Eval. (line 8040) * safe local variable: File Local Variables. (line 11243) * safe, defcustom keyword: Variable Definitions. (line 14323) * safe-length: List Elements. (line 5015) * safe-local-eval-forms: File Local Variables. (line 11305) * safe-local-variable-p: File Local Variables. (line 11266) * safe-local-variable-values: File Local Variables. (line 11255) * safe-magic (property): Magic File Names. (line 32789) * safely encode a string: Lisp and Coding Systems. (line 47294) * safely encode characters in a charset: Lisp and Coding Systems. (line 47301) * safely encode region: Lisp and Coding Systems. (line 47285) * safety of functions: Function Safety. (line 13404) * same-window-buffer-names: Choosing Window Options. (line 37126) * same-window-p: Choosing Window Options. (line 37138) * same-window-regexps: Choosing Window Options. (line 37132) * save abbrevs in files: Abbrev Files. (line 50514) * save-abbrevs: Abbrev Files. (line 50537) * save-buffer: Saving Buffers. (line 30767) * save-buffer-coding-system: Encoding and I/O. (line 47176) * save-current-buffer: Current Buffer. (line 33944) * save-excursion: Excursions. (line 41765) * save-mark-and-excursion: Excursions. (line 41803) * save-match-data: Saving Match Data. (line 49200) * save-restriction: Narrowing. (line 41860) * save-selected-window: Selecting Windows. (line 36263) * save-some-buffers: Saving Buffers. (line 30788) * save-window-excursion: Window Configurations. (line 38244) * SaveUnder feature: Display Feature Testing. (line 41074) * saving buffers: Saving Buffers. (line 30761) * saving text properties: Format Conversion. (line 32906) * saving window information: Window Configurations. (line 38197) * scalability of overlays: Overlays. (line 54690) * scalable fonts: Font Selection. (line 56173) * scalable-fonts-allowed: Font Selection. (line 56176) * scan-lists: Motion via Parsing. (line 49972) * scan-sexps: Motion via Parsing. (line 49991) * scanning expressions: Parsing Expressions. (line 49941) * scanning for character sets: Scanning Charsets. (line 46942) * scanning keymaps: Scanning Keymaps. (line 25512) * scope: Variable Scoping. (line 10516) * scoping rule: Variable Scoping. (line 10511) * screen layout: Frame Configuration Type. (line 2522) * screen lines, moving by: Screen Lines. (line 41450) * screen of terminal: Basic Windows. (line 34869) * screen refresh: Refresh Screen. (line 53620) * screen-gamma, a frame parameter: Font and Color Parameters. (line 39880) * script symbols: Character Properties. (line 46824) * scroll bar events, data in: Accessing Scroll. (line 22972) * scroll bars: Scroll Bars. (line 57008) * scroll-bar-background, a frame parameter: Font and Color Parameters. (line 39946) * scroll-bar-event-ratio: Accessing Scroll. (line 22974) * scroll-bar-foreground, a frame parameter: Font and Color Parameters. (line 39942) * scroll-bar-height: Scroll Bars. (line 57120) * scroll-bar-height, a frame parameter: Layout Parameters. (line 39653) * scroll-bar-mode: Scroll Bars. (line 57129) * scroll-bar-scale: Accessing Scroll. (line 22979) * scroll-bar-width: Scroll Bars. (line 57116) * scroll-bar-width, a frame parameter: Layout Parameters. (line 39649) * scroll-command property: Textual Scrolling. (line 37776) * scroll-conservatively: Textual Scrolling. (line 37741) * scroll-down: Textual Scrolling. (line 37688) * scroll-down-aggressively: Textual Scrolling. (line 37753) * scroll-down-command: Textual Scrolling. (line 37700) * scroll-error-top-bottom: Textual Scrolling. (line 37794) * scroll-left: Horizontal Scrolling. (line 37944) * scroll-margin: Textual Scrolling. (line 37734) * scroll-other-window: Textual Scrolling. (line 37706) * scroll-preserve-screen-position: Textual Scrolling. (line 37776) * scroll-right: Horizontal Scrolling. (line 37964) * scroll-step: Textual Scrolling. (line 37771) * scroll-up: Textual Scrolling. (line 37678) * scroll-up-aggressively: Textual Scrolling. (line 37765) * scroll-up-command: Textual Scrolling. (line 37694) * scrolling textually: Textual Scrolling. (line 37647) * search-backward: String Search. (line 48033) * search-failed: String Search. (line 48018) * search-forward: String Search. (line 47992) * search-map: Prefix Keys. (line 24482) * search-spaces-regexp: Regexp Search. (line 48891) * searching: Searching and Matching. (line 47968) * searching active keymaps for keys: Searching Keymaps. (line 24641) * searching and case: Searching and Case. (line 48103) * searching and replacing: Search and Replace. (line 49219) * searching for overlays: Finding Overlays. (line 55073) * searching for regexp: Regexp Search. (line 48733) * searching text properties: Property Search. (line 44798) * secondary selection: Window System Selections. (line 40667) * seconds-to-time: Time of Day. (line 60514) * secure-hash: Checksum/Hash. (line 45961) * security: Security Considerations. (line 61865) * seed, for random number generation: Random Numbers. (line 3768) * select safe coding system: User-Chosen Coding Systems. (line 47379) * select-frame: Input Focus. (line 40205) * select-frame-set-input-focus: Input Focus. (line 40198) * select-safe-coding-system: User-Chosen Coding Systems. (line 47379) * select-safe-coding-system-accept-default-p: User-Chosen Coding Systems. (line 47423) * select-window: Selecting Windows. (line 36233) * selected window: Basic Windows. (line 34916) * selected-frame: Input Focus. (line 40175) * selected-window: Basic Windows. (line 34927) * selected-window-group: Basic Windows. (line 34940) * selected-window-group-function: Basic Windows. (line 34941) * selecting a buffer: Current Buffer. (line 33850) * selecting a font: Font Selection. (line 56120) * selecting a window: Selecting Windows. (line 36233) * selection (for window systems): Window System Selections. (line 40667) * selection-coding-system: Window System Selections. (line 40709) * selective-display: Selective Display. (line 54426) * selective-display-ellipses: Selective Display. (line 54468) * self-evaluating form: Self-Evaluating Forms. (line 8106) * self-insert-and-exit: Minibuffer Commands. (line 21047) * self-insert-command: Commands for Insertion. (line 42794) * self-insert-command override: Changing Key Bindings. (line 25208) * self-insert-command, minor modes: Keymaps and Minor Modes. (line 27689) * self-insertion: Commands for Insertion. (line 42795) * SELinux context: Extended Attributes. (line 31584) * send-string-to-terminal: Terminal Output. (line 61187) * sending signals: Signals to Processes. (line 51783) * sentence-end: Standard Regexps. (line 49421) * sentence-end <1>: Standard Regexps. (line 49430) * sentence-end-double-space: Filling. (line 43742) * sentence-end-without-period: Filling. (line 43747) * sentence-end-without-space: Filling. (line 43752) * sentinel (of process): Sentinels. (line 52217) * seq library: Sequence Functions. (line 6374) * seq-concatenate: Sequence Functions. (line 6610) * seq-contains: Sequence Functions. (line 6567) * seq-count: Sequence Functions. (line 6555) * seq-difference: Sequence Functions. (line 6643) * seq-do: Sequence Functions. (line 6456) * seq-doseq: Sequence Functions. (line 6690) * seq-drop: Sequence Functions. (line 6420) * seq-drop-while: Sequence Functions. (line 6447) * seq-elt: Sequence Functions. (line 6388) * seq-empty-p: Sequence Functions. (line 6547) * seq-every-p: Sequence Functions. (line 6538) * seq-filter: Sequence Functions. (line 6480) * seq-find: Sequence Functions. (line 6525) * seq-group-by: Sequence Functions. (line 6652) * seq-intersection: Sequence Functions. (line 6635) * seq-into: Sequence Functions. (line 6661) * seq-length: Sequence Functions. (line 6405) * seq-let: Sequence Functions. (line 6695) * seq-map: Sequence Functions. (line 6460) * seq-mapcat: Sequence Functions. (line 6619) * seq-mapn: Sequence Functions. (line 6469) * seq-max: Sequence Functions. (line 6681) * seq-min: Sequence Functions. (line 6672) * seq-partition: Sequence Functions. (line 6627) * seq-position: Sequence Functions. (line 6577) * seq-reduce: Sequence Functions. (line 6498) * seq-remove: Sequence Functions. (line 6489) * seq-some: Sequence Functions. (line 6512) * seq-sort: Sequence Functions. (line 6562) * seq-subseq: Sequence Functions. (line 6598) * seq-take: Sequence Functions. (line 6429) * seq-take-while: Sequence Functions. (line 6438) * seq-uniq: Sequence Functions. (line 6588) * seqp: Sequence Functions. (line 6410) * sequence: Sequences Arrays Vectors. (line 6101) * sequence destructuring: Sequence Functions. (line 6696) * sequence functions in seq: Sequence Functions. (line 6374) * sequence iteration: Sequence Functions. (line 6691) * sequence length: Sequence Functions. (line 6145) * sequence reverse: Sequence Functions. (line 6239) * sequencep: Sequence Functions. (line 6140) * sequencing: Sequencing. (line 8680) * sequential execution: Sequencing. (line 8680) * serial connections: Serial Ports. (line 53074) * serial-process-configure: Serial Ports. (line 53180) * serial-term: Serial Ports. (line 53098) * serializing: Byte Packing. (line 53239) * session file: Session Management. (line 61351) * session manager: Session Management. (line 61336) * set: Setting Variables. (line 10474) * set, defcustom keyword: Variable Definitions. (line 14253) * set-advertised-calling-convention: Obsolete Functions. (line 13187) * set-after, defcustom keyword: Variable Definitions. (line 14327) * set-auto-coding: Default Coding Systems. (line 47581) * set-auto-mode: Auto Major Mode. (line 26928) * set-binary-mode: Input Functions. (line 18952) * set-buffer: Current Buffer. (line 33868) * set-buffer-auto-saved: Auto-Saving. (line 33600) * set-buffer-major-mode: Auto Major Mode. (line 26962) * set-buffer-modified-p: Buffer Modification. (line 34217) * set-buffer-multibyte: Selecting a Representation. (line 46548) * set-case-syntax: Case Tables. (line 4790) * set-case-syntax-delims: Case Tables. (line 4786) * set-case-syntax-pair: Case Tables. (line 4782) * set-case-table: Case Tables. (line 4754) * set-category-table: Categories. (line 50320) * set-char-table-extra-slot: Char-Tables. (line 7008) * set-char-table-parent: Char-Tables. (line 7000) * set-char-table-range: Char-Tables. (line 7030) * set-charset-priority: Character Sets. (line 46876) * set-coding-system-priority: Specifying Coding Systems. (line 47683) * set-default: Default Value. (line 11153) * set-default-file-modes: Changing Files. (line 31837) * set-display-table-slot: Display Tables. (line 59030) * set-face-attribute: Attribute Functions. (line 55751) * set-face-background: Attribute Functions. (line 55776) * set-face-bold: Attribute Functions. (line 55786) * set-face-font: Attribute Functions. (line 55783) * set-face-foreground: Attribute Functions. (line 55775) * set-face-inverse-video: Attribute Functions. (line 55797) * set-face-italic: Attribute Functions. (line 55790) * set-face-stipple: Attribute Functions. (line 55780) * set-face-underline: Attribute Functions. (line 55794) * set-file-acl: Changing Files. (line 31913) * set-file-extended-attributes: Changing Files. (line 31895) * set-file-modes: Changing Files. (line 31813) * set-file-selinux-context: Changing Files. (line 31902) * set-file-times: Changing Files. (line 31889) * set-fontset-font: Fontsets. (line 56335) * set-frame-configuration: Frame Configurations. (line 40379) * set-frame-font: Frame Font. (line 39113) * set-frame-height: Size and Position. (line 39224) * set-frame-parameter: Parameter Access. (line 39373) * set-frame-position: Size and Position. (line 39148) * set-frame-selected-window: Selecting Windows. (line 36296) * set-frame-size: Size and Position. (line 39214) * set-frame-width: Size and Position. (line 39244) * set-fringe-bitmap-face: Customizing Bitmaps. (line 56949) * set-input-method: Input Methods. (line 47876) * set-input-mode: Input Modes. (line 61091) * set-keyboard-coding-system: Terminal I/O Encoding. (line 47829) * set-keymap-parent: Inheritance and Keymaps. (line 24389) * set-left-margin: Margins. (line 43810) * set-mark: The Mark. (line 42243) * set-marker: Moving Markers. (line 42144) * set-marker-insertion-type: Marker Insertion Types. (line 42123) * set-match-data: Entire Match Data. (line 49171) * set-minibuffer-window: Minibuffer Windows. (line 21093) * set-mouse-absolute-pixel-position: Mouse Position. (line 40482) * set-mouse-pixel-position: Mouse Position. (line 40467) * set-mouse-position: Mouse Position. (line 40453) * set-network-process-option: Network Options. (line 52984) * set-process-buffer: Process Buffers. (line 51972) * set-process-coding-system: Process Information. (line 51694) * set-process-datagram-address: Datagrams. (line 52773) * set-process-filter: Filter Functions. (line 52113) * set-process-plist: Process Information. (line 51712) * set-process-query-on-exit-flag: Query Before Exit. (line 52341) * set-process-sentinel: Sentinels. (line 52295) * set-process-window-size: Process Buffers. (line 52001) * set-register: Registers. (line 45813) * set-right-margin: Margins. (line 43815) * set-standard-case-table: Case Tables. (line 4744) * set-syntax-table: Syntax Table Functions. (line 49828) * set-terminal-coding-system: Terminal I/O Encoding. (line 47844) * set-terminal-parameter: Terminal Parameters. (line 39997) * set-text-properties: Changing Properties. (line 44716) * set-transient-map: Controlling Active Maps. (line 24825) * set-visited-file-modtime: Modification Time. (line 34312) * set-visited-file-name: Buffer File Name. (line 34151) * set-window-buffer: Buffers and Windows. (line 36479) * set-window-combination-limit: Recombining Windows. (line 36128) * set-window-configuration: Window Configurations. (line 38218) * set-window-dedicated-p: Dedicated Windows. (line 37281) * set-window-display-table: Active Display Table. (line 59063) * set-window-fringes: Fringe Size/Pos. (line 56718) * set-window-group-start: Window Start and End. (line 37570) * set-window-group-start-function: Window Start and End. (line 37570) * set-window-hscroll: Horizontal Scrolling. (line 37985) * set-window-margins: Display Margins. (line 57493) * set-window-next-buffers: Window History. (line 37185) * set-window-parameter: Window Parameters. (line 38334) * set-window-point: Window Point. (line 37436) * set-window-prev-buffers: Window History. (line 37168) * set-window-scroll-bars: Scroll Bars. (line 57045) * set-window-start: Window Start and End. (line 37518) * set-window-vscroll: Vertical Scrolling. (line 37883) * set-xwidget-plist: Xwidgets. (line 58246) * set-xwidget-query-on-exit-flag: Xwidgets. (line 58289) * setcar: Setcar. (line 5382) * setcdr: Setcdr. (line 5458) * setenv: System Environment. (line 60278) * setf: Setting Generalized Variables. (line 11551) * setplist: Symbol Plists. (line 7880) * setq: Setting Variables. (line 10445) * setq-default: Default Value. (line 11113) * setq-local: Creating Buffer-Local. (line 10929) * sets: Sets And Lists. (line 5587) * setting modes of files: Changing Files. (line 31682) * setting-constant error: Constant Variables. (line 9995) * severity level: Warning Basics. (line 54074) * sexp: Intro Eval. (line 8040) * sexp motion: List Motion. (line 41605) * SHA hash: Checksum/Hash. (line 45946) * shadowed Lisp files: Library Search. (line 15456) * shadowing of variables: Local Variables. (line 10036) * shared structure, read syntax: Circular Objects. (line 2613) * shell command arguments: Shell Arguments. (line 50899) * shell-command-history: Minibuffer History. (line 19805) * shell-command-to-string: Synchronous Processes. (line 51208) * shell-quote-argument: Shell Arguments. (line 50906) * shift-selection, and interactive spec: Using Interactive. (line 21409) * shift-translation: Key Sequence Input. (line 23149) * show image: Showing Images. (line 58023) * show-help-function: Special Properties. (line 45249) * shr-insert-document: Parsing HTML/XML. (line 46036) * shrink-window-if-larger-than-buffer: Resizing Windows. (line 35618) * shy groups: Regexp Backslash. (line 48475) * sibling window: Windows and Frames. (line 34999) * side effect: Intro Eval. (line 8073) * SIGHUP: Killing Emacs. (line 60040) * SIGINT: Killing Emacs. (line 60040) * signal: Signaling Errors. (line 9494) * signal-process: Signals to Processes. (line 51867) * signaling errors: Signaling Errors. (line 9443) * signals: Signals to Processes. (line 51783) * SIGTERM: Killing Emacs. (line 60040) * SIGTSTP: Suspending Emacs. (line 60085) * sigusr1 event: Misc Events. (line 22647) * sigusr2 event: Misc Events. (line 22647) * simple package: Simple Packages. (line 62078) * sin: Math Functions. (line 3713) * single file package: Simple Packages. (line 62078) * single-function hook: Hooks. (line 26528) * single-key-description: Describing Characters. (line 30267) * sit-for: Waiting. (line 23576) * site-init.el: Building Emacs. (line 64472) * site-lisp directories: Library Search. (line 15381) * site-load.el: Building Emacs. (line 64455) * site-run-file: Init File. (line 59833) * site-start.el: Startup Summary. (line 59648) * size of frame: Frame Geometry. (line 38869) * size of image: Showing Images. (line 58085) * size of text on display: Size of Displayed Text. (line 55128) * size of window: Window Sizes. (line 35165) * skip-chars-backward: Skipping Characters. (line 41741) * skip-chars-forward: Skipping Characters. (line 41706) * skip-syntax-backward: Motion and Syntax. (line 49923) * skip-syntax-forward: Motion and Syntax. (line 49912) * skipping characters: Skipping Characters. (line 41698) * skipping characters of certain syntax: Motion and Syntax. (line 49909) * skipping comments: Control Parsing. (line 50155) * sleep-for: Waiting. (line 23602) * slice, image: Showing Images. (line 58049) * small-temporary-file-directory: Unique File Names. (line 32359) * smallest Lisp integer: Integer Basics. (line 3060) * SMIE: SMIE. (line 29360) * SMIE grammar: SMIE Grammar. (line 29483) * SMIE lexer: SMIE Lexer. (line 29538) * smie-bnf->prec2: Operator Precedence Grammars. (line 29449) * smie-close-block: SMIE setup. (line 29408) * smie-config: SMIE Customization. (line 29839) * smie-config-guess: SMIE Customization. (line 29846) * smie-config-local: SMIE Customization. (line 29863) * smie-config-save: SMIE Customization. (line 29851) * smie-config-set-indent: SMIE Customization. (line 29859) * smie-config-show-indent: SMIE Customization. (line 29855) * smie-down-list: SMIE setup. (line 29412) * smie-merge-prec2s: Operator Precedence Grammars. (line 29437) * smie-prec2->grammar: Operator Precedence Grammars. (line 29432) * smie-precs->prec2: Operator Precedence Grammars. (line 29441) * smie-rule-bolp: SMIE Indentation Helpers. (line 29717) * smie-rule-hanging-p: SMIE Indentation Helpers. (line 29720) * smie-rule-next-p: SMIE Indentation Helpers. (line 29726) * smie-rule-parent: SMIE Indentation Helpers. (line 29739) * smie-rule-parent-p: SMIE Indentation Helpers. (line 29732) * smie-rule-prev-p: SMIE Indentation Helpers. (line 29729) * smie-rule-separator: SMIE Indentation Helpers. (line 29744) * smie-rule-sibling-p: SMIE Indentation Helpers. (line 29735) * smie-setup: SMIE setup. (line 29386) * Snarf-documentation: Accessing Documentation. (line 30120) * sort: Sequence Functions. (line 6307) * sort-columns: Sorting. (line 44152) * sort-fields: Sorting. (line 44130) * sort-fold-case: Sorting. (line 44059) * sort-lines: Sorting. (line 44118) * sort-numeric-base: Sorting. (line 44148) * sort-numeric-fields: Sorting. (line 44138) * sort-pages: Sorting. (line 44126) * sort-paragraphs: Sorting. (line 44122) * sort-regexp-fields: Sorting. (line 44063) * sort-subr: Sorting. (line 43970) * sorting lists: Sequence Functions. (line 6308) * sorting sequences: Sequence Functions. (line 6562) * sorting text: Sorting. (line 43966) * sorting vectors: Sequence Functions. (line 6308) * sound: Sound Output. (line 61224) * source breakpoints: Source Breakpoints. (line 17653) * space (ASCII character): Basic Char Syntax. (line 1550) * space display spec, and bidirectional text: Bidirectional Display. (line 59494) * spaces, pixel specification: Pixel Specification. (line 57308) * spaces, specified height or width: Specified Space. (line 57255) * sparse keymap: Format of Keymaps. (line 24182) * in minibuffer: Text from Minibuffer. (line 19623) * special events: Special Events. (line 23545) * special form descriptions: A Sample Function Description. (line 1188) * special forms: Special Forms. (line 8310) * special forms for control structures: Control Structures. (line 8653) * special modes: Major Mode Conventions. (line 26857) * special variables: Using Lexical Binding. (line 10756) * special-event-map: Controlling Active Maps. (line 24808) * special-form-p: Special Forms. (line 8326) * special-mode: Basic Major Modes. (line 27196) * special-variable-p: Using Lexical Binding. (line 10762) * specify coding system: Specifying Coding Systems. (line 47627) * specify color: Color Names. (line 40754) * speedups: Compilation Tips. (line 63923) * splicing (with backquote): Backquote. (line 8484) * split-height-threshold: Choosing Window Options. (line 37065) * split-string: Creating Strings. (line 3999) * split-string-and-unquote: Shell Arguments. (line 50943) * split-string-default-separators: Creating Strings. (line 4075) * split-width-threshold: Choosing Window Options. (line 37071) * split-window: Splitting Windows. (line 35747) * split-window-below: Splitting Windows. (line 35859) * split-window-keep-point: Splitting Windows. (line 35864) * split-window-preferred-function: Choosing Window Options. (line 37039) * split-window-right: Splitting Windows. (line 35854) * split-window-sensibly: Choosing Window Options. (line 37050) * splitting windows: Splitting Windows. (line 35744) * sqrt: Math Functions. (line 3747) * stable sort: Sequence Functions. (line 6308) * stack allocated Lisp objects: Stack-allocated Objects. (line 64870) * standard abbrev tables: Standard Abbrev Tables. (line 50670) * standard colors for character terminals: Font and Color Parameters. (line 39867) * standard errors: Standard Errors. (line 65859) * standard hooks: Standard Hooks. (line 66204) * standard regexps used in editing: Standard Regexps. (line 49392) * standard syntax table: Syntax Basics. (line 49476) * standard-case-table: Case Tables. (line 4748) * standard-category-table: Categories. (line 50311) * standard-display-table: Active Display Table. (line 59072) * standard-input: Input Functions. (line 18935) * standard-output: Output Variables. (line 19210) * standard-syntax-table: Syntax Basics. (line 49484) * standard-translation-table-for-decode: Translation of Characters. (line 47007) * standard-translation-table-for-encode: Translation of Characters. (line 47013) * standards of coding style: Tips. (line 63583) * start-file-process: Asynchronous Processes. (line 51419) * start-file-process-shell-command: Asynchronous Processes. (line 51456) * start-process: Asynchronous Processes. (line 51377) * start-process, command-line arguments from minibuffer: Shell Arguments. (line 50932) * start-process-shell-command: Asynchronous Processes. (line 51442) * STARTTLS network connections: Network. (line 52609) * startup of Emacs: Startup Summary. (line 59597) * startup screen: Startup Summary. (line 59716) * startup.el: Startup Summary. (line 59597) * staticpro, protection from GC: Writing Emacs Primitives. (line 65097) * sticky text properties: Sticky Properties. (line 45288) * sticky, a frame parameter: Management Parameters. (line 39775) * stop points: Using Edebug. (line 17272) * stop-process: Signals to Processes. (line 51846) * stopbits, in serial connections: Serial Ports. (line 53181) * stopping an infinite loop: Infinite Loops. (line 16804) * stopping on events: Global Break Condition. (line 17633) * storage of vector-like Lisp objects: Garbage Collection. (line 64591) * store-match-data: Entire Match Data. (line 49182) * store-substring: Modifying Strings. (line 4090) * stream (for printing): Output Streams. (line 18963) * stream (for reading): Input Streams. (line 18761) * strike-through text: Face Attributes. (line 55439) * string: Creating Strings. (line 3900) * string creation: Creating Strings. (line 3885) * string equality: Text Comparison. (line 4109) * string in keymap: Key Lookup. (line 24893) * string input stream: Input Streams. (line 18776) * string length: Sequence Functions. (line 6145) * string modification: Modifying Strings. (line 4082) * string predicates: Predicates for Strings. (line 3868) * string reverse: Sequence Functions. (line 6239) * string search: String Search. (line 47981) * string to number: String Conversion. (line 4357) * string to object: Input Functions. (line 18907) * string, number of bytes: Text Representations. (line 46421) * string, writing a doc string: Documentation Basics. (line 29937) * string-as-multibyte: Selecting a Representation. (line 46581) * string-as-unibyte: Selecting a Representation. (line 46573) * string-bytes: Text Representations. (line 46420) * string-chars-consed: Memory Usage. (line 64915) * string-collate-equalp: Text Comparison. (line 4156) * string-collate-lessp: Text Comparison. (line 4244) * string-equal: Text Comparison. (line 4153) * string-greaterp: Text Comparison. (line 4240) * string-lessp: Text Comparison. (line 4237) * string-match: Regexp Search. (line 48808) * string-match-p: Regexp Search. (line 48834) * string-or-null-p: Predicates for Strings. (line 3874) * string-prefix-p: Text Comparison. (line 4188) * string-prefix-p <1>: Text Comparison. (line 4280) * string-suffix-p: Text Comparison. (line 4193) * string-suffix-p <1>: Text Comparison. (line 4285) * string-to-char: String Conversion. (line 4389) * string-to-int: String Conversion. (line 4382) * string-to-multibyte: Converting Representations. (line 46514) * string-to-number: String Conversion. (line 4356) * string-to-syntax: Syntax Table Internals. (line 50212) * string-to-unibyte: Converting Representations. (line 46522) * string-width: Size of Displayed Text. (line 55138) * string<: Text Comparison. (line 4198) * string=: Text Comparison. (line 4120) * stringp: Predicates for Strings. (line 3871) * strings: Strings and Characters. (line 3802) * strings with keyboard events: Strings of Events. (line 22998) * strings, formatting them: Formatting Strings. (line 4417) * strings-consed: Memory Usage. (line 64926) * submenu: Mouse Menus. (line 25968) * subprocess: Processes. (line 50780) * subr: What Is a Function. (line 11700) * subr-arity: What Is a Function. (line 11780) * subrp: What Is a Function. (line 11765) * subst-char-in-region: Substitution. (line 45724) * substitute characters: Substitution. (line 45721) * substitute-command-keys: Keys in Documentation. (line 30199) * substitute-in-file-name: File Name Expansion. (line 32263) * substitute-key-definition: Changing Key Bindings. (line 25169) * substituting keys in documentation: Keys in Documentation. (line 30143) * substring: Creating Strings. (line 3906) * substring-no-properties: Creating Strings. (line 3963) * subtype of char-table: Char-Tables. (line 6944) * suggestions: Caveats. (line 1013) * super characters: Other Char Bits. (line 1685) * suppress-keymap: Changing Key Bindings. (line 25207) * surrogate minibuffer frame: Minibuffers and Frames. (line 40136) * suspend (cf. no-redraw-on-reenter): Refresh Screen. (line 53644) * suspend evaluation: Recursive Editing. (line 23891) * suspend-emacs: Suspending Emacs. (line 60090) * suspend-frame: Suspending Emacs. (line 60172) * suspend-hook: Suspending Emacs. (line 60137) * suspend-resume-hook: Suspending Emacs. (line 60140) * suspend-tty: Suspending Emacs. (line 60143) * suspend-tty-functions: Suspending Emacs. (line 60153) * suspending Emacs: Suspending Emacs. (line 60073) * swap text between buffers: Swapping Text. (line 34780) * switch-to-buffer: Switching Buffers. (line 36586) * switch-to-buffer-in-dedicated-window: Switching Buffers. (line 36619) * switch-to-buffer-other-frame: Switching Buffers. (line 36674) * switch-to-buffer-other-window: Switching Buffers. (line 36661) * switch-to-buffer-preserve-window-point: Switching Buffers. (line 36645) * switch-to-next-buffer: Window History. (line 37218) * switch-to-prev-buffer: Window History. (line 37199) * switch-to-visible-buffer: Window History. (line 37232) * switches on command line: Command-Line Arguments. (line 59964) * switching to a buffer: Switching Buffers. (line 36572) * sxhash: Defining Hash. (line 7468) * symbol: Symbols. (line 7536) * symbol components: Symbol Components. (line 7552) * symbol equality: Creating Symbols. (line 7699) * symbol evaluation: Symbol Forms. (line 8139) * symbol function indirection: Function Indirection. (line 8178) * symbol in keymap: Key Lookup. (line 24915) * symbol name hashing: Creating Symbols. (line 7671) * symbol property: Symbol Properties. (line 7837) * symbol that evaluates to itself: Constant Variables. (line 9995) * symbol with constant value: Constant Variables. (line 9995) * symbol, where defined: Where Defined. (line 15883) * symbol-file: Where Defined. (line 15883) * symbol-function: Function Cells. (line 12674) * symbol-name: Creating Symbols. (line 7734) * symbol-plist: Symbol Plists. (line 7877) * symbol-value: Accessing Variables. (line 10406) * symbolp: Symbols. (line 7546) * symbols-consed: Memory Usage. (line 64912) * synchronous subprocess: Synchronous Processes. (line 50975) * syntactic font lock: Syntactic Font Lock. (line 29141) * syntax class: Syntax Descriptors. (line 49496) * syntax class table: Syntax Class Table. (line 49537) * syntax code: Syntax Table Internals. (line 50181) * syntax descriptor: Syntax Descriptors. (line 49510) * syntax entry, setting: Syntax Table Functions. (line 49764) * syntax error (Edebug): Backtracking. (line 18357) * syntax flags: Syntax Flags. (line 49664) * syntax for characters: Basic Char Syntax. (line 1530) * syntax of regular expressions: Syntax of Regexps. (line 48153) * syntax table: Syntax Tables. (line 49438) * syntax table example: Example Major Modes. (line 27473) * syntax table internals: Syntax Table Internals. (line 50173) * syntax tables in modes: Major Mode Conventions. (line 26777) * syntax-after: Syntax Table Internals. (line 50216) * syntax-class: Syntax Table Internals. (line 50222) * syntax-ppss: Position Parse. (line 50030) * syntax-ppss-flush-cache: Position Parse. (line 50053) * syntax-ppss-toplevel-pos: Parser State. (line 50108) * syntax-propertize-extend-region-functions: Syntax Properties. (line 49893) * syntax-propertize-function: Syntax Properties. (line 49878) * syntax-table: Syntax Table Functions. (line 49832) * syntax-table (text property): Syntax Properties. (line 49853) * syntax-table-p: Syntax Basics. (line 49459) * system abbrev: Abbrevs. (line 50392) * system processes: System Processes. (line 52354) * system type and name: System Environment. (line 60192) * system-configuration: System Environment. (line 60186) * system-groups: User Identification. (line 60455) * system-key-alist: X11 Keysyms. (line 61277) * system-messages-locale: Locales. (line 47928) * system-name: System Environment. (line 60246) * system-time-locale: Locales. (line 47934) * system-type: System Environment. (line 60192) * system-users: User Identification. (line 60450) * t: nil and t. (line 1088) * t input stream: Input Streams. (line 18791) * t output stream: Output Streams. (line 18984) * tab (ASCII character): Basic Char Syntax. (line 1550) * tab deletion: Deletion. (line 42911) * in minibuffer: Text from Minibuffer. (line 19626) * tab-always-indent: Mode-Specific Indent. (line 44304) * tab-stop-list: Indent Tabs. (line 44441) * tab-to-tab-stop: Indent Tabs. (line 44437) * tab-width: Usual Display. (line 58950) * tabs stops for indentation: Indent Tabs. (line 44428) * Tabulated List mode: Tabulated List Mode. (line 27274) * tabulated-list-entries: Tabulated List Mode. (line 27316) * tabulated-list-format: Tabulated List Mode. (line 27300) * tabulated-list-init-header: Tabulated List Mode. (line 27359) * tabulated-list-mode: Tabulated List Mode. (line 27286) * tabulated-list-print: Tabulated List Mode. (line 27368) * tabulated-list-printer: Tabulated List Mode. (line 27344) * tabulated-list-revert-hook: Tabulated List Mode. (line 27339) * tabulated-list-sort-key: Tabulated List Mode. (line 27352) * tag on run time stack: Catch and Throw. (line 9337) * tag, customization keyword: Common Keywords. (line 13993) * tan: Math Functions. (line 3715) * TCP: Network. (line 52563) * temacs: Building Emacs. (line 64423) * TEMP environment variable: Unique File Names. (line 32343) * temp-buffer-max-height: Temporary Displays. (line 54619) * temp-buffer-max-width: Temporary Displays. (line 54626) * temp-buffer-resize-mode: Temporary Displays. (line 54607) * temp-buffer-setup-hook: Temporary Displays. (line 54551) * temp-buffer-show-function: Temporary Displays. (line 54541) * temp-buffer-show-hook: Temporary Displays. (line 54557) * temp-buffer-window-setup-hook: Temporary Displays. (line 54587) * temp-buffer-window-show-hook: Temporary Displays. (line 54587) * temporary buffer display: Temporary Displays. (line 54488) * temporary display: Temporary Displays. (line 54488) * temporary files: Unique File Names. (line 32297) * temporary-file-directory: Unique File Names. (line 32342) * TERM environment variable: Terminal-Specific. (line 59914) * term-file-aliases: Terminal-Specific. (line 59924) * term-file-prefix: Terminal-Specific. (line 59913) * Termcap: Terminal-Specific. (line 59888) * terminal: Frames. (line 38548) * terminal input: Terminal Input. (line 61085) * terminal input modes: Input Modes. (line 61091) * terminal output: Terminal Output. (line 61164) * terminal parameters: Terminal Parameters. (line 39979) * terminal screen: Basic Windows. (line 34869) * terminal type: Terminal Type. (line 2499) * terminal-coding-system: Terminal I/O Encoding. (line 47837) * terminal-list: Multiple Terminals. (line 38682) * terminal-live-p: Frames. (line 38591) * terminal-local variables: Multiple Terminals. (line 38715) * terminal-name: Multiple Terminals. (line 38677) * terminal-parameter: Terminal Parameters. (line 39992) * terminal-parameters: Terminal Parameters. (line 39988) * terminal-specific initialization: Terminal-Specific. (line 59879) * termscript file: Terminal Output. (line 61205) * terpri: Output Functions. (line 19155) * test-completion: Basic Completion. (line 19981) * testcover-mark-all: Test Coverage. (line 18630) * testcover-next-mark: Test Coverage. (line 18630) * testcover-start: Test Coverage. (line 18630) * testing types: Type Predicates. (line 2672) * text: Text. (line 42424) * text area: Frame Layout. (line 39006) * text area of a window: Window Sizes. (line 35182) * text comparison: Text Comparison. (line 4109) * text conversion of coding system: Lisp and Coding Systems. (line 47278) * text deletion: Deletion. (line 42851) * text insertion: Insertion. (line 42689) * text near point: Near Point. (line 42449) * text parsing: Syntax Tables. (line 49438) * text properties: Text Properties. (line 44548) * text properties in files: Format Conversion. (line 32906) * text properties in the mode line: Properties in Mode. (line 28317) * text properties, changing: Changing Properties. (line 44652) * text properties, examining: Examining Properties. (line 44575) * text properties, read syntax: Text Props and Strings. (line 2140) * text properties, searching: Property Search. (line 44798) * text representation: Text Representations. (line 46315) * text terminal: Frames. (line 38553) * text-char-description: Describing Characters. (line 30291) * text-mode: Basic Major Modes. (line 27178) * text-mode-abbrev-table: Standard Abbrev Tables. (line 50695) * text-properties-at: Examining Properties. (line 44630) * text-property-any: Property Search. (line 44896) * text-property-default-nonsticky: Sticky Properties. (line 45333) * text-property-not-all: Property Search. (line 44905) * text-quoting-style: Keys in Documentation. (line 30186) * textual order: Control Structures. (line 8659) * textual scrolling: Textual Scrolling. (line 37647) * thing-at-point: Buffer Contents. (line 42634) * this-command: Command Loop Info. (line 21953) * this-command-keys: Command Loop Info. (line 21989) * this-command-keys-shift-translated: Key Sequence Input. (line 23154) * this-command-keys-vector: Command Loop Info. (line 22004) * this-original-command: Command Loop Info. (line 21983) * three-step-help: Help Functions. (line 30488) * throw: Catch and Throw. (line 9350) * throw example: Recursive Editing. (line 23863) * tiled windows: Basic Windows. (line 34875) * time calculations: Time Calculations. (line 60847) * time conversion: Time Conversion. (line 60564) * time formatting: Time Parsing. (line 60646) * time of day: Time of Day. (line 60462) * time parsing: Time Parsing. (line 60646) * time value: Time of Day. (line 60474) * time zone rule: Time Zone Rules. (line 60536) * time zone rules: Time Zone Rules. (line 60522) * time zone, current: Time Zone Rules. (line 60544) * time-add: Time Calculations. (line 60856) * time-less-p: Time Calculations. (line 60850) * time-subtract: Time Calculations. (line 60853) * time-to-day-in-year: Time Calculations. (line 60865) * time-to-days: Time Calculations. (line 60862) * timer: Timers. (line 60874) * timer-max-repeats: Timers. (line 60959) * timestamp of a mouse event: Accessing Mouse. (line 22946) * timing programs: Profiling. (line 18691) * tips for writing Lisp: Tips. (line 63583) * title bar: Frame Layout. (line 38930) * title, a frame parameter: Basic Parameters. (line 39470) * TLS network connections: Network. (line 52609) * TMP environment variable: Unique File Names. (line 32343) * TMPDIR environment variable: Unique File Names. (line 32343) * toggle-enable-multibyte-characters: Disabling Multibyte. (line 46472) * tool bar: Tool Bar. (line 26147) * tool-bar-add-item: Tool Bar. (line 26242) * tool-bar-add-item-from-menu: Tool Bar. (line 26261) * tool-bar-border: Tool Bar. (line 26305) * tool-bar-button-margin: Tool Bar. (line 26297) * tool-bar-button-relief: Tool Bar. (line 26301) * tool-bar-lines frame parameter: Layout Parameters. (line 39683) * tool-bar-local-item-from-menu: Tool Bar. (line 26274) * tool-bar-map: Tool Bar. (line 26225) * tool-bar-position frame parameter: Layout Parameters. (line 39687) * tooltip face: Tooltips. (line 59329) * tooltip for help strings: Special Properties. (line 44992) * tooltip-event-buffer: Tooltips. (line 59345) * tooltip-frame-parameters: Tooltips. (line 59319) * tooltip-functions: Tooltips. (line 59333) * tooltip-help-tips: Tooltips. (line 59333) * tooltip-mode: Tooltips. (line 59303) * tooltips: Tooltips. (line 59296) * top frame: Raising and Lowering. (line 40358) * top, a frame parameter: Position Parameters. (line 39532) * top-level: Recursive Editing. (line 23924) * top-level form: Loading. (line 15139) * total height of a window: Window Sizes. (line 35205) * total pixel height of a window: Window Sizes. (line 35262) * total pixel width of a window: Window Sizes. (line 35272) * total width of a window: Window Sizes. (line 35231) * tq-close: Transaction Queues. (line 52552) * tq-create: Transaction Queues. (line 52528) * tq-enqueue: Transaction Queues. (line 52534) * trace buffer: Trace Buffer. (line 17902) * track-mouse: Mouse Tracking. (line 40402) * trailing blanks in file names: Information about Files. (line 31150) * transaction queue: Transaction Queues. (line 52523) * transcendental functions: Math Functions. (line 3711) * transient keymap: Controlling Active Maps. (line 24825) * transient-mark-mode: The Mark. (line 42279) * translate-region: Substitution. (line 45746) * translating input events: Event Mod. (line 23315) * translation keymap: Translation Keymaps. (line 25295) * translation tables: Translation of Characters. (line 46971) * translation-table-for-input: Translation of Characters. (line 47018) * transparency, frame: Font and Color Parameters. (line 39897) * transpose-regions: Transposition. (line 45857) * trash: Changing Files. (line 31793) * trash <1>: Create/Delete Dirs. (line 32655) * tray notifications, MS-Windows: Desktop Notifications. (line 61589) * triple-click events: Repeat Events. (line 22453) * true: nil and t. (line 1088) * true list: Cons Cells. (line 4828) * truename (of file): Truenames. (line 31359) * truncate: Numeric Conversions. (line 3271) * truncate-lines: Truncation. (line 53707) * truncate-partial-width-windows: Truncation. (line 53713) * truncate-string-ellipsis: Size of Displayed Text. (line 55163) * truncate-string-to-width: Size of Displayed Text. (line 55142) * truth value: nil and t. (line 1070) * try-completion: Basic Completion. (line 19881) * tty-color-alist: Text Terminal Colors. (line 40877) * tty-color-approximate: Text Terminal Colors. (line 40886) * tty-color-clear: Text Terminal Colors. (line 40874) * tty-color-define: Text Terminal Colors. (line 40865) * tty-color-mode, a frame parameter: Font and Color Parameters. (line 39866) * tty-color-translate: Text Terminal Colors. (line 40891) * tty-erase-char: System Environment. (line 60375) * tty-setup-hook: Terminal-Specific. (line 59929) * tty-top-frame: Raising and Lowering. (line 40362) * turn multibyte support on or off: Disabling Multibyte. (line 46443) * two’s complement: Integer Basics. (line 3031) * type: Lisp Data Types. (line 1366) * type (button property): Button Properties. (line 58355) * type checking: Type Predicates. (line 2658) * type checking internals: Writing Emacs Primitives. (line 65047) * type predicates: Type Predicates. (line 2672) * type, defcustom keyword: Customization Types. (line 14395) * type-of: Type Predicates. (line 2829) * typographic conventions: Some Terms. (line 1063) * TZ, environment variable: Time Zone Rules. (line 60522) * UBA: Bidirectional Display. (line 59368) * UDP: Network. (line 52563) * UID: User Identification. (line 60433) * umask: Changing Files. (line 31838) * unassigned character codepoints: Character Properties. (line 46662) * unbalanced parentheses: Syntax Errors. (line 18570) * unbinding keys: Key Binding Commands. (line 25475) * unbury-buffer: Buffer List. (line 34545) * undecided coding-system, when encoding: Explicit Encoding. (line 47746) * undefined: Functions for Key Lookup. (line 24992) * undefined in keymap: Key Lookup. (line 24927) * undefined key: Keymap Basics. (line 24132) * underline-minimum-offset: Face Attributes. (line 55521) * underlined text: Face Attributes. (line 55413) * undo avoidance: Substitution. (line 45729) * undo-ask-before-discard: Maintaining Undo. (line 43605) * undo-auto-amalgamate: Undo. (line 43513) * undo-auto-current-boundary-timer: Undo. (line 43527) * undo-boundary: Undo. (line 43500) * undo-in-progress: Undo. (line 43533) * undo-limit: Maintaining Undo. (line 43590) * undo-outer-limit: Maintaining Undo. (line 43600) * undo-strong-limit: Maintaining Undo. (line 43594) * unexec: Building Emacs. (line 64520) * unhandled-file-name-directory: Magic File Names. (line 32867) * unibyte buffers, and bidi reordering: Bidirectional Display. (line 59391) * unibyte text: Text Representations. (line 46349) * unibyte-char-to-multibyte: Converting Representations. (line 46538) * unibyte-string: Text Representations. (line 46424) * Unicode: Text Representations. (line 46319) * unicode bidirectional algorithm: Bidirectional Display. (line 59368) * unicode character escape: General Escape Syntax. (line 1592) * unicode general category: Character Properties. (line 46675) * unicode, a charset: Character Sets. (line 46858) * unicode-category-table: Character Properties. (line 46818) * unintern: Creating Symbols. (line 7821) * uninterned symbol: Creating Symbols. (line 7699) * unique file names: Unique File Names. (line 32297) * universal-argument: Prefix Command Arguments. (line 23819) * universal-argument-map: Standard Keymaps. (line 66190) * unless: Conditionals. (line 8782) * unload-feature: Unloading. (line 15941) * unload-feature-special-hooks: Unloading. (line 15979) * unloading packages: Unloading. (line 15937) * unloading packages, preparing for: Coding Conventions. (line 63696) * unlock-buffer: File Locks. (line 31104) * unnumbered group: Regexp Backslash. (line 48475) * unpacking: Byte Packing. (line 53239) * unread-command-events: Event Input Misc. (line 23454) * unsafep: Function Safety. (line 13411) * unsplittable, a frame parameter: Buffer Parameters. (line 39722) * unused lexical variable: Using Lexical Binding. (line 10779) * unwind-protect: Cleanups. (line 9872) * unwinding: Cleanups. (line 9873) * up-list: List Motion. (line 41624) * upcase: Case Conversion. (line 4634) * upcase-initials: Case Conversion. (line 4670) * upcase-region: Case Changes. (line 44509) * upcase-word: Case Changes. (line 44537) * update-directory-autoloads: Autoload. (line 15596) * update-file-autoloads: Autoload. (line 15596) * upper case: Case Conversion. (line 4609) * upper case key sequence: Key Sequence Input. (line 23149) * uptime of Emacs: Processor Run Time. (line 60815) * use time of window: Selecting Windows. (line 36307) * use-empty-active-region: The Region. (line 42415) * use-global-map: Controlling Active Maps. (line 24728) * use-hard-newlines: Filling. (line 43777) * use-local-map: Controlling Active Maps. (line 24734) * use-region-p: The Region. (line 42409) * user errors, signaling: Signaling Errors. (line 9529) * user groups: User Identification. (line 60455) * user identification: User Identification. (line 60382) * user options, how to define: Variable Definitions. (line 14184) * user signals: Misc Events. (line 22647) * user-defined error: Error Symbols. (line 9792) * user-emacs-directory: Init File. (line 59872) * user-error: Signaling Errors. (line 9529) * user-full-name: User Identification. (line 60427) * user-full-name <1>: User Identification. (line 60415) * user-init-file: Init File. (line 59867) * user-login-name: User Identification. (line 60427) * user-login-name <1>: User Identification. (line 60403) * user-mail-address: User Identification. (line 60396) * user-position, a frame parameter: Position Parameters. (line 39549) * user-ptr object: Dynamic Modules. (line 16058) * user-ptrp: Dynamic Modules. (line 16065) * user-real-login-name: User Identification. (line 60427) * user-real-login-name <1>: User Identification. (line 60411) * user-real-uid: User Identification. (line 60433) * user-size, a frame parameter: Size Parameters. (line 39582) * user-uid: User Identification. (line 60438) * utf-8-emacs coding system: Coding System Basics. (line 47119) * valid windows: Basic Windows. (line 34899) * validity of coding system: Lisp and Coding Systems. (line 47243) * value cell: Symbol Components. (line 7559) * value of expression: Evaluation. (line 8023) * value of function: What Is a Function. (line 11673) * values: Eval. (line 8620) * variable: Variables. (line 9939) * variable aliases: Variable Aliases. (line 11425) * variable definition: Defining Variables. (line 10209) * variable descriptions: A Sample Variable Description. (line 1274) * variable limit error: Local Variables. (line 10119) * variable with constant value: Constant Variables. (line 9995) * variable, buffer-local: Buffer-Local Variables. (line 10795) * variable-documentation property: Documentation Basics. (line 29948) * variable-width spaces: Specified Space. (line 57255) * variant coding system: Coding System Basics. (line 47099) * vc-mode: Mode Line Variables. (line 28113) * vc-prefix-map: Prefix Keys. (line 24476) * vconcat: Vector Functions. (line 6899) * vector: Vector Functions. (line 6884) * vector (type): Vectors. (line 6844) * vector evaluation: Self-Evaluating Forms. (line 8106) * vector length: Sequence Functions. (line 6145) * vector reverse: Sequence Functions. (line 6239) * vector-cells-consed: Memory Usage. (line 64909) * vector-like objects, storage: Garbage Collection. (line 64591) * vectorp: Vector Functions. (line 6876) * verify-visited-file-modtime: Modification Time. (line 34268) * version number (in file name): File Name Components. (line 31952) * version, customization keyword: Common Keywords. (line 14083) * version-control: Numbered Backups. (line 33372) * vertical combination: Windows and Frames. (line 35026) * vertical fractional scrolling: Vertical Scrolling. (line 37855) * vertical scroll position: Vertical Scrolling. (line 37855) * vertical tab: Basic Char Syntax. (line 1550) * vertical-line prefix key: Key Sequence Input. (line 23168) * vertical-motion: Screen Lines. (line 41471) * vertical-scroll-bar: Scroll Bars. (line 57106) * vertical-scroll-bar prefix key: Key Sequence Input. (line 23168) * vertical-scroll-bars, a frame parameter: Layout Parameters. (line 39639) * view part, model/view/controller: Abstract Display. (line 58557) * view-register: Registers. (line 45818) * virtual buffers: Swapping Text. (line 34780) * visibility, a frame parameter: Management Parameters. (line 39733) * visible frame: Visibility of Frames. (line 40286) * visible-bell: Beeping. (line 59236) * visible-frame-list: Finding All Frames. (line 40096) * visited file: Buffer File Name. (line 34073) * visited file mode: Auto Major Mode. (line 26929) * visited-file-modtime: Modification Time. (line 34295) * visiting files: Visiting Files. (line 30525) * visiting files, functions for: Visiting Functions. (line 30549) * visual order: Bidirectional Display. (line 59368) * visual order, preserve when copying bidirectional text: Bidirectional Display. (line 59561) * visual-order cursor motion: Bidirectional Display. (line 59458) * void function: Function Indirection. (line 8178) * void function cell: Function Cells. (line 12689) * void variable: Void Variables. (line 10137) * void-function: Function Cells. (line 12675) * void-text-area-pointer: Pointer Shape. (line 40639) * void-variable error: Void Variables. (line 10137) * w32-collate-ignore-punctuation: Text Comparison. (line 4177) * w32-notification-close: Desktop Notifications. (line 61648) * w32-notification-notify: Desktop Notifications. (line 61592) * wait-for-wm, a frame parameter: Management Parameters. (line 39768) * waiting: Waiting. (line 23570) * waiting for command key input: Event Input Misc. (line 23490) * waiting-for-user-input-p: Sentinels. (line 52321) * walk-windows: Cyclic Window Ordering. (line 36393) * warn: Warning Basics. (line 54121) * warning options: Warning Options. (line 54197) * warning type: Warning Basics. (line 54101) * warning variables: Warning Variables. (line 54130) * warning-fill-prefix: Warning Variables. (line 54183) * warning-levels: Warning Variables. (line 54133) * warning-minimum-level: Warning Options. (line 54200) * warning-minimum-log-level: Warning Options. (line 54205) * warning-prefix-function: Warning Variables. (line 54148) * warning-series: Warning Variables. (line 54164) * warning-suppress-log-types: Warning Options. (line 54216) * warning-suppress-types: Warning Options. (line 54210) * warning-type-format: Warning Variables. (line 54187) * warnings: Warnings. (line 54068) * watch, for filesystem events: File Notifications. (line 61654) * webkit browser widget: Xwidgets. (line 58216) * wheel-down event: Misc Events. (line 22612) * wheel-up event: Misc Events. (line 22612) * when: Conditionals. (line 8772) * where was a symbol defined: Where Defined. (line 15883) * where-is-internal: Scanning Keymaps. (line 25579) * while: Iteration. (line 9115) * while-no-input: Event Input Misc. (line 23513) * whitespace: Basic Char Syntax. (line 1550) * wholenump: Predicates on Numbers. (line 3157) * widen: Narrowing. (line 41849) * widening: Narrowing. (line 41850) * width of a window: Window Sizes. (line 35231) * width, a frame parameter: Size Parameters. (line 39578) * window: Basic Windows. (line 34857) * window (overlay property): Overlay Properties. (line 54920) * window body: Window Sizes. (line 35182) * window body height: Window Sizes. (line 35297) * window body size: Window Sizes. (line 35336) * window body width: Window Sizes. (line 35315) * window combination: Windows and Frames. (line 35026) * window combination limit: Recombining Windows. (line 36128) * window configuration (Edebug): Edebug Display Update. (line 18045) * window configurations: Window Configurations. (line 38197) * window dividers: Window Dividers. (line 57142) * window end position: Window Start and End. (line 37487) * window excursions: Excursions. (line 41794) * window header line: Header Lines. (line 28351) * window height: Window Sizes. (line 35205) * window history: Window History. (line 37146) * window in direction: Windows and Frames. (line 35106) * window internals: Window Internals. (line 65500) * window layout in a frame: Window Configuration Type. (line 2511) * window layout, all frames: Frame Configuration Type. (line 2522) * window manager interaction, and frame parameters: Management Parameters. (line 39729) * window order by time of last use: Selecting Windows. (line 36307) * window ordering, cyclic: Cyclic Window Ordering. (line 36321) * window parameters: Window Parameters. (line 38321) * window pixel height: Window Sizes. (line 35262) * window pixel width: Window Sizes. (line 35272) * window point: Window Point. (line 37401) * window point internals: Window Internals. (line 65552) * window position: Window Point. (line 37401) * window position <1>: Coordinates and Windows. (line 38019) * window position on display: Position Parameters. (line 39495) * window positions and window managers: Position Parameters. (line 39556) * window resizing: Resizing Windows. (line 35433) * window selected within a frame: Basic Windows. (line 34916) * window size: Window Sizes. (line 35165) * window size on display: Size Parameters. (line 39570) * window size, changing: Resizing Windows. (line 35433) * window splitting: Splitting Windows. (line 35744) * window start position: Window Start and End. (line 37450) * window state: Window Configurations. (line 38287) * window that satisfies a predicate: Cyclic Window Ordering. (line 36456) * window top line: Window Start and End. (line 37465) * window tree: Windows and Frames. (line 34977) * window use time: Selecting Windows. (line 36307) * window width: Window Sizes. (line 35231) * window-absolute-body-pixel-edges: Coordinates and Windows. (line 38153) * window-absolute-pixel-edges: Coordinates and Windows. (line 38147) * window-absolute-pixel-position: Coordinates and Windows. (line 38177) * window-adjust-process-window-size-function: Process Buffers. (line 52018) * window-at: Coordinates and Windows. (line 38069) * window-body-edges: Coordinates and Windows. (line 38061) * window-body-height: Window Sizes. (line 35301) * window-body-pixel-edges: Coordinates and Windows. (line 38139) * window-body-size: Window Sizes. (line 35336) * window-body-width: Window Sizes. (line 35322) * window-bottom-divider-width: Window Dividers. (line 57189) * window-buffer: Buffers and Windows. (line 36474) * window-child: Windows and Frames. (line 35067) * window-combination-limit: Recombining Windows. (line 36066) * window-combination-limit <1>: Recombining Windows. (line 36136) * window-combination-resize: Recombining Windows. (line 36155) * window-combined-p: Windows and Frames. (line 35073) * window-configuration-change-hook: Window Hooks. (line 38518) * window-configuration-frame: Window Configurations. (line 38272) * window-configuration-p: Window Configurations. (line 38260) * window-current-scroll-bars: Scroll Bars. (line 57079) * window-dedicated-p: Dedicated Windows. (line 37274) * window-display-table: Active Display Table. (line 59059) * window-edges: Coordinates and Windows. (line 38031) * window-end: Window Start and End. (line 37487) * window-font-height: Low-Level Font. (line 56672) * window-font-width: Low-Level Font. (line 56666) * window-frame: Windows and Frames. (line 34958) * window-fringes: Fringe Size/Pos. (line 56728) * window-full-height-p: Window Sizes. (line 35285) * window-full-width-p: Window Sizes. (line 35291) * window-group-end: Window Start and End. (line 37509) * window-group-end-function: Window Start and End. (line 37509) * window-group-start: Window Start and End. (line 37479) * window-group-start-function: Window Start and End. (line 37480) * window-header-line-height: Header Lines. (line 28363) * window-header-line-height <1>: Window Sizes. (line 35357) * window-hscroll: Horizontal Scrolling. (line 37969) * window-id, a frame parameter: Management Parameters. (line 39758) * window-in-direction: Windows and Frames. (line 35106) * window-left-child: Windows and Frames. (line 35062) * window-line-height: Window Start and End. (line 37624) * window-list: Windows and Frames. (line 34962) * window-live-p: Basic Windows. (line 34888) * window-margins: Display Margins. (line 57497) * window-max-chars-per-line: Window Sizes. (line 35370) * window-min-height: Window Sizes. (line 35382) * window-min-height <1>: Window Sizes. (line 35389) * window-min-size: Window Sizes. (line 35404) * window-min-width: Window Sizes. (line 35382) * window-min-width <1>: Window Sizes. (line 35395) * window-minibuffer-p: Minibuffer Windows. (line 21100) * window-mode-line-height: Window Sizes. (line 35352) * window-next-buffers: Window History. (line 37180) * window-next-sibling: Windows and Frames. (line 35081) * window-parameter: Window Parameters. (line 38324) * window-parameters: Window Parameters. (line 38329) * window-parent: Windows and Frames. (line 35009) * window-persistent-parameters: Window Parameters. (line 38348) * window-pixel-edges: Coordinates and Windows. (line 38134) * window-pixel-height: Window Sizes. (line 35262) * window-pixel-width: Window Sizes. (line 35272) * window-point: Window Point. (line 37425) * window-point-insertion-type: Window Point. (line 37442) * window-preserve-size: Preserving Window Sizes. (line 35695) * window-preserved-size: Preserving Window Sizes. (line 35734) * window-prev-buffers: Window History. (line 37152) * window-prev-sibling: Windows and Frames. (line 35086) * window-resizable: Resizing Windows. (line 35444) * window-resize: Resizing Windows. (line 35472) * window-resize-pixelwise: Resizing Windows. (line 35512) * window-right-divider-width: Window Dividers. (line 57184) * window-scroll-bar-height: Scroll Bars. (line 57090) * window-scroll-bar-width: Scroll Bars. (line 57086) * window-scroll-bars: Scroll Bars. (line 57067) * window-scroll-functions: Window Hooks. (line 38481) * window-setup-hook: Init File. (line 59862) * window-size-change-functions: Window Hooks. (line 38497) * window-size-fixed: Preserving Window Sizes. (line 35673) * window-start: Window Start and End. (line 37464) * window-state-get: Window Configurations. (line 38287) * window-state-put: Window Configurations. (line 38306) * window-system: Window Systems. (line 59256) * window-system <1>: Window Systems. (line 59281) * window-system-initialization-alist: Startup Summary. (line 59622) * window-text-change-functions: Standard Hooks. (line 66411) * window-text-pixel-size: Size of Displayed Text. (line 55178) * window-top-child: Windows and Frames. (line 35057) * window-total-height: Window Sizes. (line 35209) * window-total-size: Window Sizes. (line 35252) * window-total-width: Window Sizes. (line 35234) * window-tree: Windows and Frames. (line 35144) * window-use-time: Selecting Windows. (line 36307) * window-valid-p: Basic Windows. (line 34911) * window-vscroll: Vertical Scrolling. (line 37875) * windowp: Basic Windows. (line 34881) * windows, controlling precisely: Buffers and Windows. (line 36470) * windows, recombining: Recombining Windows. (line 35950) * with-case-table: Case Tables. (line 4757) * with-coding-priority: Specifying Coding Systems. (line 47688) * with-current-buffer: Current Buffer. (line 33956) * with-current-buffer-window: Temporary Displays. (line 54594) * with-demoted-errors: Handling Errors. (line 9779) * with-displayed-buffer-window: Temporary Displays. (line 54599) * with-eval-after-load: Hooks for Loading. (line 15997) * with-file-modes: Changing Files. (line 31853) * with-help-window: Help Functions. (line 30442) * with-local-quit: Quitting. (line 23697) * with-no-warnings: Compiler Errors. (line 16469) * with-output-to-string: Output Functions. (line 19185) * with-output-to-temp-buffer: Temporary Displays. (line 54492) * with-selected-window: Selecting Windows. (line 36281) * with-silent-modifications: Changing Properties. (line 44791) * with-syntax-table: Syntax Table Functions. (line 49840) * with-temp-buffer: Current Buffer. (line 33966) * with-temp-buffer-window: Temporary Displays. (line 54563) * with-temp-file: Writing to Files. (line 31056) * with-temp-message: Displaying Messages. (line 53826) * with-timeout: Timers. (line 60964) * word-search-backward: String Search. (line 48089) * word-search-backward-lax: String Search. (line 48094) * word-search-forward: String Search. (line 48038) * word-search-forward-lax: String Search. (line 48082) * word-search-regexp: String Search. (line 48078) * words in region: Text Lines. (line 41431) * words-include-escapes: Word Motion. (line 41281) * wrap-prefix: Truncation. (line 53727) * write-abbrev-file: Abbrev Files. (line 50549) * write-char: Output Functions. (line 19162) * write-contents-functions: Saving Buffers. (line 30866) * write-file: Saving Buffers. (line 30810) * write-file-functions: Saving Buffers. (line 30830) * write-region: Writing to Files. (line 31002) * write-region-annotate-functions: Format Conversion Piecemeal. (line 33123) * write-region-post-annotation-function: Format Conversion Piecemeal. (line 33136) * writing a documentation string: Documentation Basics. (line 29937) * writing Emacs primitives: Writing Emacs Primitives. (line 64944) * writing to files: Writing to Files. (line 30984) * wrong-number-of-arguments: Argument List. (line 11880) * wrong-type-argument: Type Predicates. (line 2658) * X display names: Multiple Terminals. (line 38734) * X Window System: Window Systems. (line 59261) * x-alt-keysym: X11 Keysyms. (line 61295) * x-alternatives-map: Standard Keymaps. (line 66197) * x-bitmap-file-path: Face Attributes. (line 55525) * x-close-connection: Multiple Terminals. (line 38788) * x-color-defined-p: Color Names. (line 40785) * x-color-values: Color Names. (line 40839) * x-defined-colors: Color Names. (line 40793) * x-display-color-p: Display Feature Testing. (line 40984) * x-display-list: Multiple Terminals. (line 38763) * x-dnd-known-types: Drag and Drop. (line 40729) * x-dnd-test-function: Drag and Drop. (line 40729) * x-dnd-types-alist: Drag and Drop. (line 40738) * x-family-fonts: Font Lookup. (line 56233) * x-get-resource: Resources. (line 40904) * x-gtk-use-system-tooltips: Tooltips. (line 59309) * x-hyper-keysym: X11 Keysyms. (line 61297) * x-list-fonts: Font Lookup. (line 56211) * x-meta-keysym: X11 Keysyms. (line 61296) * x-open-connection: Multiple Terminals. (line 38768) * x-parse-geometry: Geometry. (line 39956) * x-pointer-shape: Pointer Shape. (line 40647) * x-popup-dialog: Dialog Boxes. (line 40585) * x-popup-menu: Pop-Up Menus. (line 40505) * x-resource-class: Resources. (line 40920) * x-resource-name: Resources. (line 40926) * x-sensitive-text-pointer-shape: Pointer Shape. (line 40651) * x-server-vendor: Display Feature Testing. (line 41110) * x-server-version: Display Feature Testing. (line 41100) * x-setup-function-keys: Standard Keymaps. (line 66197) * x-stretch-cursor: Cursor Parameters. (line 39823) * x-super-keysym: X11 Keysyms. (line 61298) * X11 keysyms: X11 Keysyms. (line 61274) * XBM: XBM Images. (line 57724) * XML DOM: Document Object Model. (line 46049) * XPM: XPM Images. (line 57775) * xwidget: Xwidgets. (line 58216) * xwidget-buffer: Xwidgets. (line 58250) * xwidget-info: Xwidgets. (line 58284) * xwidget-plist: Xwidgets. (line 58243) * xwidget-query-on-exit-flag: Xwidgets. (line 58295) * xwidget-resize: Xwidgets. (line 58276) * xwidget-size-request: Xwidgets. (line 58280) * xwidget-webkit-execute-script: Xwidgets. (line 58262) * xwidget-webkit-execute-script-rv: Xwidgets. (line 58266) * xwidget-webkit-get-title: Xwidgets. (line 58273) * xwidget-webkit-goto-uri: Xwidgets. (line 58258) * xwidgetp: Xwidgets. (line 58240) * y-or-n-p: Yes-or-No Queries. (line 20865) * y-or-n-p-with-timeout: Yes-or-No Queries. (line 20897) * yank: Yank Commands. (line 43237) * yank suppression: Changing Key Bindings. (line 25218) * yank-excluded-properties: Yanking. (line 43221) * yank-handled-properties: Yanking. (line 43209) * yank-pop: Yank Commands. (line 43259) * yank-undo-function: Yank Commands. (line 43281) * yanking and text properties: Yanking. (line 43209) * yes-or-no questions: Yes-or-No Queries. (line 20850) * yes-or-no-p: Yes-or-No Queries. (line 20902) * zerop: Predicates on Numbers. (line 3159) * zlib-available-p: Decompression. (line 45882) * zlib-decompress-region: Decompression. (line 45885)