Help us understand the problem. What is going on with this article?

init.elの設定をコンピューターごとに分岐させる

More than 3 years have passed since last update.

Emacsの大きな特徴の一つは、Mac OS X、Linux、Windowsなどといった異なったOSでも、同じUI、ほぼ同じ設定で使えることだと思っています。

とはいえ、OSなどの環境ごとに設定を切り替える必要がある部分や、切り替えた方が便利な部分があることも事実。ここでは、init.el(.emacs)の設定をOSなどの環境に合わせて切り替える方法を考えます。

切り替えに使う変数

system-type変数

system-type変数を使うと、OSごとに設定を切り替えられます。主なOSの種類は次のとおり。

  • gnu/linux
  • darwin
  • windows-nt

詳細は、C-h vdescribe-variable)でsystem-typeを調べてください。

たとえば、次のようなMac OS Xだけで有効な設定を~/.emacs.d/init-darwin.elファイルに記述したとします。

;; Mac OS X用の文字コード指定
(setq file-name-coding-system 'utf-8-hfs)
(setq locale-coding-system 'utf-8-hfs)

この設定は、init.elに次の記述をすることでMac OS Xの場合だけ、呼び出すことができます。LinuxやWindowsなど、Mac OS X以外のOSの場合は呼び出しません。

(when (equal system-type 'darwin)
  (load-file "~/.emacs.d/init-darwin.el"))

window-system変数

window-system変数は、ウインドウシステムごとに設定を切り替えられます。主なウィンドウシステムの主な種類は次のとおり。

  • nil
  • x
  • w32
  • mac
  • ns

詳細は、C-h vwindow-systemを調べてください。

Mac OS Xの場合はmacの場合が多いと思うのですが、nsの場合もあるかもしれません。自分のEmacsで調べるにはESC-:eval-expression)でwindow-systemを評価してください。

たとえば、次のようなMac OS XのEmacsアプリ(非ターミナル)だけで有効にしたい設定を~/.emacs.d/init-mac-gui.elファイルに記述したとします。
ここでは、環境変数およびexce-path、フレーム、フォントなどを設定しています。

;; Mac OS Xのpath_helperでPATHを取得し、あらためてPATHとして設定
(let ((shell-file-name "/bin/bash"))
    (setenv "PATH"
            (shell-command-to-string
             "eval $(/usr/libexec/path_helper -s) && printf $PATH")))

;; Emacs変数exec-pathに、環境変数PATHの内容を設定
(setq exec-path nil)

(dolist
    (dir (split-string (getenv "PATH") "[:\n]"))
  (when (file-directory-p dir)
    (add-to-list 'exec-path dir t)))

;; 標準のフォントサイズとフォントファミリーの設定
(set-face-attribute 'default nil
                    :height 120
                    :family "Menlo")

;; キャラクターセットごとにフォントファミリーを設定
(dolist
    (list
     '(
       (jisx0201 "Osaka")
       (japanese-jisx0213.2004-1 "Hiragino Kaku Gothic ProN")
       (japanese-jisx0213-2 "Hiragino Kaku Gothic ProN")
       ))
  (let ((charset (car list))
        (fontfamily (nth 1 list)))
    (cond
     ((not (member charset charset-list))
        (message "Character set %s is not found." charset))
     ((not (member fontfamily (font-family-list)))
        (message "Font family %s is not found." fontfamily))
     ((set-fontset-font t charset (font-spec :family fontfamily))))))

;; フレームの設定
(dolist
    (val
     '(
       (foreground-color . "black")
       (background-color . "gray99")
       (cursor-color . "DarkOliveGreen")
       (cursor-type . box)
       ))
  (add-to-list 'default-frame-alist val))

;; commandキーをEmacsのMetaキーに
(setq mac-command-modifier 'meta)

;; ミニバッファにカーソルを移動する際、自動的にキーボードをASCIIモードにする
(mac-auto-ascii-mode 1)

;; Mac OS Xのキー設定
(dolist
    (map
     '(
       ("<M-f1>" other-frame)    ; Mac OS Xの他アプリと同様に、command + F1でアプリケーションの次のウィンドウを操作対象にする
       ))
  (let ((key (car map)) (func (nth 1 map)))
    (if (not (functionp func)) (message "%s is not defined." func)
      (global-set-key (kbd key) func))))

(cd "~")

この設定は、init.elに次の記述をすることで呼び出すことができます。

(when (equal system-type 'darwin)
  (load-file "~/.emacs.d/init-mac-gui.el"))

system-typewindow-systemの違いは、コンソール(端末)上でEmacsを使う場合にあらわれます。

たとえばMac OS Xでsystem-typeは、コンソール上のEmacsでもEmacsアプリでもdarwinです。一方window-systemは、コンソール上のEmacsではnil、Emacsアプリではmac(またはns)です。

環境変数およびexce-path、フレーム、フォントなどの設定はコンソール上のEmacsでは不要なため、上記のinit-mac-gui.elではwindow-systemを使って設定を分岐させています。

コンソール上でEmacsを使わない人は、window-systemsystem-typeのどちらか一方を使えば十分かもしれません。

system-name変数

system-name変数を使うと、コンピューターのホスト名を取得できるため、コンピューターごとに設定を切り替えられます。
ただし、素のsystem-nameでは、DNSドメイン名の付いたFQDNしか取得できません。
そこで、ドメイン名を除いたシンプルなホスト名を格納する変数system-name-simpleを定義しました。

(defvar system-name-simple
  (replace-regexp-in-string "\\..*\\'" "" (system-name))
  "The simple host name of the machine Emacs is running on, which is without domain information.")

たとえば、ホスト名がtigerのコンピューターだけで有効にしたい設定を次の~/.emacs.d/init-tiger.elファイルに記述したとします。

;; フレームの設定
(when (equal window-system 'mac)
  (dolist
      (val
       '(
         (width . 180)
         (height . 55)
         (top . 22)
         (left . 0)
         ))
    (add-to-list 'default-frame-alist val)))

ここでは、Emacsアプリの場合にフレームの大きさを設定するようにしています。画面の大きさが異なるMacコンピューターを複数台つかっている場合は、コンピューターごとにフレームの大きさを設定したくなると思います。

この設定は、system-name-simpleを定義してから次の記述をすることで呼び出すことができます。

(when (equal system-name-simple "tiger")
  (load-file "~/.emacs.d/init-tiger.el"))

さいごに

system-typewindow-systemsystem-nameなどの変数を使いこなせば、環境ごとにEmacsの設定を分岐させられます。init.elに記述する設定を、共通部分と特定のシステムやコンピューター向けの部分と分けられるので、保守性や利便性が上がります。

init.elの記述を分けるという点では、Advent Calender2日目のinit.elから設定を追い出してパッケージ化しようで記載された「私のinit.el長すぎ!!」問題対策と相通ずる部分もあるかとおもいます。

なお、環境ごとに設定を変えるためのEmacsパッケージとして、init-loaderがあるようです。私自身は、syste-typeなどを使う方がシンプルでわかりやすいと思うので、使っていません。

それでは、素敵な年末とEmacsライフを。

j8takagi
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away