いつでもティータイム

ここはハートが目覚めて花咲いてリスペクトしあう場所

Emacs の環境構築

Emacs の環境構築

Emacs はいいぞ」と言われたので環境構築しました。

基本的な設定と必要になりそうなところだけ。

GNU Emacs のインストール

brew で入れます。

$ brew install emacs --with-cocoa

私は軟派なので --with-cocoaGUI 版も入れてます。

追記(2020 1/3) --with-cocoaオプションは#36070でなくなりました。 2020年1月現在、brewGUI版を入れる場合には以下のようにします。

$ brew cask install emacs

多分 GUI 版の方をメインで使うと思うので /Applications/シンボリックリンクを張って、Dock に追加しておきます。

ln -s /usr/local/Caskroom/emacs/26.3/Emacs.app /Applications/Emacs.app

コマンドラインから Emacs を使うときに GUI を起動されても困るので次のようにエイリアスしておく。

# in .zshrc
alias emacs="emacs -nw"

あと、このままだと Mac にデフォルトで入っている Emacs が優先されてしまう (/usr/bin/emacs) ため、 brew で入れた Emacs のパス(/usr/local/bin/emacs)が優先されるように変更しておく。

# in .zshenv
PATH=/usr/local/bin:$PATH
export PATH

これで導入はだいたい完了。

Emacs の設定

Emacs の設定は ~/.emacs.d/init.el に記述する。 .elEmacs Lisp の略のようで、Emacs の設定や拡張は LispEmacs 方言で記述するようだ。

PATH の設定

Emacs.el によって拡張可能なエディタである。 この .el を入れておくためのディレクトリを作成しておく。

mkdir ~/.emacs.d/elisp

以後、拡張するための Emacs Lisp~/.emacs.d/elisp に配置する。 ここに配置した Emacs Lisp を読み込むように、~/.emacs.d/init.el に設定を加える。

;; Load path
(defun add-to-load-path (&rest paths)
  (let (path)
    (dolist (path paths paths)
      (let ((default-directory (expand-file-name
                (concat user-emacs-directory path))))
        (add-to-list 'load-path default-directory)
        (if (fboundp 'normal-top-level-add-subdirs-to-load-path)
            (normal-top-level-add-subdirs-to-load-path))))))
(add-to-load-path "elisp")

ココを参考にしました。

パッケージ管理

Emacs はバージョン24以降、パッケージ管理機能が用意されている。 この機能を利用するための設定を記述する。

(この設定はできるだけ早く(設定ファイルの上の方で)記述したほうが良いらしい。)

(require 'package)
(add-to-list 'package-archives
         '("melpa" . "https://melpa.org/packages/"))
(add-to-list 'package-archives
         '("melpa-stable" . "https://stable.melpa.org/packages/"))
(setq package-user-dir "~/.emacs.d/elisp/package")
(package-initialize)

package-user-dir でパッケージのインストール先を指定している。 一応自作(するかわからないけど)の Emacs Lisp と区別するために ~/.emacs.d/elisp 以下にパッケージ管理用のディレクトリを指定。

PATH の共有

GUI 版の Emacs ではシェルの PATH 設定を引き継いでくれません(CUI の方は引き継いでくれてる)。

なのでシェルの PATH 設定を Emacs に共有させるための設定をします。

まず、M-x package-install から exec-path-from-shell をインストール。 インストールしたら設定ファイルに以下を記述。

;; PATH initialization
(when window-system
  (require 'exec-path-from-shell)
  (exec-path-from-shell-initialize))

M-x getenv から PATH と入力して Emacs環境変数を出力すればシェルの PATH が引き継がれていることを確認できる。

Command キーの設定

Emacs は独特のキー操作を要求される(Ctrl を押しながらや Meta を押しながらといったような)。 GUI 版の Emacs では Meta キーは Option キーに対応している。 しかし、これだと使いにくいので、Command キーに対応するように入れ替える。

;; Meta -> Command
(setq ns-command-modifier (quote meta))
(setq ns-alternate-modifier (quote super))

また、CUIEmacs でも Meta キーを利用するためにはターミナルの環境設定を弄る。 ターミナル環境設定からプロファイルを選択。 使用しているプロファイルを選択して、キーボードを選び、メタキーとして Option キーを使用にチェックを入れればOK。

シンプル表示

GUI 版の Emacs ではツールバーやスクロールバーなど、結構ゴテゴテしているのでそこらへんをまとめて非表示に。

;; Display
(when (fboundp 'menu-bar-mode) (menu-bar-mode -1))
(when (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(when (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
(line-number-mode 0)
(custom-set-variables '(blink-cursor-mode nil))

ついでに行番号とカーソル点滅も無効に。

バックアップファイルの無効

Emacs ではファイルを編集するとバックアップ用のファイル( ~ )が自動で作成される(例えば hoge.txt なら hoge.txt~)。 これは便利かもしれないけどディレクトリを汚すのが若干気になるので一応無効にしておく、けどもしかしたら戻すかもしれない。

;; Backup file
(setq backup-inhibited t)

Key-Bindings

よく使いそうな機能のショートカットを設定しておく。

;; Global-Key
(global-set-key "\C-z" nil)
(global-set-key "\C-ca" 'align)
(global-set-key "\C-cg" 'goto-line)
(global-set-key "\C-cl" 'what-line)
(global-set-key "\C-c;" 'comment-region)
(global-set-key "\C-c:" 'uncomment-region)
(global-set-key "\C-co" '(lambda () "" (interactive) (other-frame -1)))
(global-set-key "\C-ci" '(lambda () "" (interactive) (other-frame 1)))
(global-set-key "\C-c " 'text-adjust-space-region)

;; Minibuffer
(define-key minibuffer-local-completion-map "\C-w" 'backward-kill-word)

Emacs は様々なモードを切り替えてファイルの編集を行う。 ここではどのモードでも使いそうな操作についてグローバルなショートカットを設定。 また、minibuffer 中(主に\C-x\C-f)で単語消去するための設定も。

外観の設定

GUI 版の外観を設定する。 不要なものを非表示にとかやってたのに外観は弄るのかとかいうツッコミはなしで。

まずカラーテーマを設定。 暗めのテーマが好きなので良さげなのを入れる。 M-x package-install を実行して color-theme-sanityinc-tomorrow と入力。 インストールが終わったら設定ファイルに以下を追加。

;; Theme
(when window-system
  (load-theme 'sanityinc-tomorrow-night))

C-hv window-system で調べると自分の GUI 環境だと ns とでるので、このときだけカラーテーマをロードするようにする。 初回はテーマを読み込んでいいか質問されるので y と答える(設定ファイルに自動的に色々追加される)。

次にフォントを設定する。

;; Font
(when window-system
  (set-face-attribute 'default nil
                      :family "Monaco"
                      :height 130)
  (set-fontset-font "fontset-default"
                    'japanese-jisx0208
                    '("Hiragino Maru Gothic ProN"))
  (set-fontset-font "fontset-default"
                    'katakana-jisx0201
                    '("Hiragino Maru Gothic ProN")))

英字は Monaco, 日本語はヒラギノに設定。

これで大まかな設定は終了。 以降は Minor mode を設定していく。

Markdown-mode

;; Markdonw-mode
(add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode))
(add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode))

M-x package-install から markdown-mode をインストール。 .md および .markdown であったら自動的に markdown-mode で開くように設定。

C-mode

;; c-mode
(add-hook 'c-mode-hook
      #'(lambda ()
         (progn
           (setq c-default-style "k&r")
           (define-key c-mode-base-map "\C-m" 'newline-and-indent)
           (setq c-basic-offset 4 indent-tab-mode nil))))

もう C のコードを弄る機会は減ってきたけど、まだまだ触ることもあるので一応設定。

Python-mode

;; Python-mode
(require 'py-autopep8)
(add-hook 'python-mode-hook
      #'(lambda ()
         (define-key python-mode-map "\C-cF" 'py-autopep8)
         (define-key python-mode-map "\C-cf" 'py-autopep8-region)  
         (setq indent-tabs-mode nil)
         (setq indent-level 4)
         (setq python-indent 4)
         (setq tab-width 4)))

Python はコードのレイアウトが非常に重要な意味を持つ言語で、PEP8 という標準的なコーディング規約が存在する。 このコーディング規約に自動的に整形してくれる autopep8Emacs 上で実行するのが py-autopep8 であり、package-install でインストールした。 また、簡単に利用するためにキーバインディングを設定した。

autopep8 自体は pip でインストールした。 autopep8 はグローバルで使いたい機能であるので、pyenv で作成した Python 環境にベースとして入れている。

Java-mode

;; Java-mode
(add-hook 'java-mode-hook
      #'(lambda ()
        (setq c-basic-offset 4)
        (setq indent-tabs-mode t)
            (setq tab-width 4)))

おわりに

と、最低限の設定だけしてみた。

あとは構文チェック用のパッケージだとかその辺を必要に応じて入れてみる。