条件分岐 - 環境設定のための Emacs Lisp 入門
Emacs Lisp 入門の第 8 回です。
設定に絞った Emacs Lisp の入門なので、制御構造は必要ないかと思い、前回で終了していました。
しかし、 OS など環境の違う場合に同じ設定ファイルを使おうとすると、条件分岐は必要になってきます。
そこで、今回、 elisp での条件分岐について追加しました。
条件分岐の式
条件分岐の式の基本は if です。(if 条件式 真の式 偽の式1 偽の式2 :)条件式は真ならば式の 2 番目の引数として渡した式が評価され、 偽ならば 3 番目以降が順に評価されます。
ただし、 if は偽の時は複数書けるのですが、真で評価する式には 1 つしか書けません。 こういった場合、 progn で複数書けます。
(if 条件式 (progn 式1 式2 :))ただ、ちょっと書くのが面倒なので、真の時だけ渡した式を順に評価する when も用意されています。
(when 条件式 式1 式2 :)また、逆に偽の時に実行する unless もあります。
条件式
条件分岐に使う条件式では nil の場合に偽、 t など nil 以外の場合に真として判定されます。nil 以外ですので、 数値の 0、 空文字などでも 真となります。
(if nil "true" "false") ;; "false" (if t "true" "false") ;; "true" (if 0 "true" "false") ;; "true" (if "" "true" "false") ;; "true"空リスト
'()
が真か偽かは Lisp の処理系によって違うのですが、 elisp では空リストは nil です。例えば、 変数に 空リスト
'()
を格納したとしても、その変数には nil が格納されることになります。
(if '() "true" "false") ;; "false" (setq foo '()) foo ;; nil
一致判定
一致判定には eq を使います。設定には基本的に eq を覚えておけば十分ですが、 似たような関数として、 equal というのもあり、こちらの方がゆるい一致判定といえます。
関数 | 機能 |
---|---|
eq | シンボル、整数値が一致。 |
equal | 2 つの値が一致 |
(eq 'foo 'foo) ;; t (eq 1 1) ;; t (eq "foo" "foo") ;; nil (equal "foo" "foo") ;; t
論理式
elisp にも論理式があります。 設定に関して言えば、 not ぐらいを覚えておくぐらいでいいかと思います。関数 | 意味 | 説明 |
---|---|---|
not | 否定 | 真、偽の反転 |
and | 論理積 | すべて真の時、真 |
or | 論理和 | どれか一つ真の時、真 |
(not t) ;; nil (not nil) ;; t (and nil t) ;; nil (or nil t) ;; t
設定でよく使う条件式
実際に設定でよく使う条件式を紹介します。式 | 機能 | 切り替え |
---|---|---|
system-type | OS の判定 | OS |
window-system | Window システムの判定 | ターミナルかどうか |
file-exists-p | ファイルの存在チェック | ファイル、ライブラリーの有無 |
require, load | ロードの成功、失敗 | |
fboundp | 関数が定義済みかどうかのチェック | バージョン |
OS
設定ファイルの共通化の基本としては OS で処理を変えることだと思います。OS を表すシンボルが system-type の変数に格納されており、 これで OS を判断します。
格納されている主なシンボルを以下の表にあげます。 詳しくは C-h v system-type で変数の内容を確認するようにしてください。
シンボル | タイプ |
---|---|
gnu/linux | GNU/Linux |
gnu/kfreebsd | Free BSD |
darwin | Mac OS X |
windows-nt | Windows |
cygwin | Windows(Cygwin 版) |
なお、 Windows 7 などでも Cygwin でビルドした Emacs でなければ、 windows-nt になります。
また、 シンボル名の '/' の文字はただの文字として扱われています。 elisp は前置法なので、 +, - などわりといろんな記号が変数(シンボル)名に使用できます。
;; Windows の場合、 IME の変換でエラーがでないようにする (when (eq system-type 'windows-nt) (global-set-key [M-kanji] 'ignore) (global-set-key [kanji] 'ignore) )
ターミナル
window-system の変数には実行時の Window システムが 'x', 'w32' などのシンボルで格納されています。 Window システムというのは、 Unix における X Window System など GUI を実現しているシステムです。 これで、 OS の判定ができなくもないですが、 system-type を使う方が普通です。では、 window-system を何に使うかというと、ターミナルかどうか判定に使います。 ターミナルではキーコードなどの問題で切り替えが必要なことがあります。
Window システムが使われていないということで、ターミナルでは window-system が nil となっています。
;; ターミナルの場合(window-system が nil)、 ;; <backspace> が C-h になるため、 C-h で一文字削除に設定 (unless window-system (global-set-key "\C-h" 'delete-backward-char) ;; 全般 (define-key isearch-mode-map "\C-h" 'isearch-delete-char) ;; インクリメンタルサーチ用 (add-hook 'c-mode-common-hook '(lambda () (local-set-key "\C-h" 'c-electric-delete))) ;; C 言語系モード )
ファイル、ライブラリーの有無
設定ファイルのロード中にエラーが発生すると途中で止まってしまいます。file-exists-p の関数を使うと、ファイルの有無がチェックできるので、 ファイルがあるときだけロードするということができます。
(setq custom-file "~/.emacs.d/custom_setttings.el") (if (file-exists-p custom-file) (load custom-file))ただ、以前ファイルのロードのところで説明した load は 第 2 引数に t を指定すると、 「ロード対象のファイルが存在しない」という問題に関しては、エラーを発生しなくなります。
そのため、前述のコードは次のように書けます。
(setq custom-file "~/.emacs.d/custom_setttings.el") (load custom-file t)load と同様に require も 第 3 引数に t を指定 すると エラーが発生しなくなります。
これらはエラーは発生しなくても、ロードに成功すれば t 、 失敗すれば nil を返します。 これを利用して、 ロードし、成功した場合だけ実行する処理 が書けます。
(when (require 'auto-complete-config nil t) (ac-config-default))
バージョン
共通して設定ファイルを使用する場合、すべての Emacs が同じバージョンとは限りません。 その対策として、バージョンの番号によって処理を切り替えてもよいのですが、 使いたい関数が定義されているかチェックしてから実行した方が確実です。fboundp を使うと、関数が定義されているか をチェックすることができます。
(if (fboundp 'normal-top-level-add-subdirs-to-load-path) (normal-top-level-add-subdirs-to-load-path))以前、変数の解説で、一つのシンボルには 関数と変数が格納(結合)できる と説明しました。
fboundp は関数用ですが、 変数が定義されているかどうかをチェックする boundp という 関数もあります。 ただ、変数の場合は未定義の変数に値を設定したとしても、エラーではないので、 あまり設定では使用しません。
- 関連記事
Facebook コメント
コメント