読者です 読者をやめる 読者になる 読者になる

第三回 init.el読書会に参加しました

emacs

第三回は gongoさん(@)さんでした.

~/.emacs.dより user-emacs-directoryを使った方がよい

https://github.com/gongo/elfactory/blob/master/init.el


前にも書いたけど, 他人が使うことを容易にするためには
'~/.emacs.d'とベタ書きするよりは, user-emacs-directory変数を
使った方がよいです.


例えば init.elを以下のように書き換えた(リファクタリング含む)とします.

;;---------------------------------------
;; load-path for elisp files
;;---------------------------------------
;; emacs -l init.el等で直接ロードしたときに, user-emacs-directoryが書き換わる
(when load-file-name
  (setq user-emacs-directory (file-name-directory load-file-name)))

(dolist (dir '("site-lisp" "vendor"))
  (add-to-list 'load-path (concat user-emacs-directory dir)))

(let ((secret (concat user-emacs-directory ".secrets.el")))
  (when (file-exists-p secret)
    (load-file secret)))

(require 'cask "~/.cask/cask.el")
(cask-initialize)

;;---------------------------------------
;; load-path for config files
;;---------------------------------------
(require 'init-loader)
(init-loader-load (concat user-emacs-directory "config"))

こうしておくと, 誰かが gongoさんの emacs設定ファイル群を cloneして,
以下のコマンドを実行すると, ~/.emacs.dでなく, cloneしたディレクトリを
起点として Emacsを起動することができます.

 % git clone https://github.com/gongo/elfactory.git
 % cd elfactory
 # gongoさんは Caskを利用しているので caskをインストールしておく必要あり
 % emacs -Q -l init.el

公開できないファイルがないと完全に同じ環境にならない等ありますが,
他人に使ってもらうということを考えるのであればこのように設定しておくと
よいと思います.

append-to-list(自作マクロ)は add-to-listでよい

https://github.com/gongo/elfactory/blob/master/config/00_defmacros.el#L33


おしりから要素を突っ込むということですが, add-to-listの第三引数が
append引数なのでそれを使えばよいと思います. add-to-listは追加する
要素が既に存在する場合(equalで比較)は何もしないので, 重複する
内容を追加するということを避けることができます.

lazyloadは eval-after-loadでよい

https://github.com/gongo/elfactory/blob/master/config/00_defmacros.el#L40


eval-after-loadはライブラリがインストールされていなければ
そもそも何もしないので, インストールされているかのチェックは特に行う必要はないです.
あとパッケージマネージャを使っている場合, 設定ファイルに autoloadの設定を書く必要は
基本的にありません. 自分が特殊なことをしているのであれば別ですが, もし必要で
あればそれはパッケージ自体に問題がありますので, 作者に報告をした方がよいと思います.

init-loaderを使っている場合, 環境による場合分けは基本不要

https://github.com/gongo/elfactory/blob/master/config/00_defvars.el


init-loaderは設定ファイルの名前により, Windowsしかロードしない,
MacOSXしかロードしないということができるので, そちらの枠組みを
使った方が綺麗に設定ファイルが書けるのではないかと思います.


詳しくは下記を参照してください.
https://github.com/emacs-jp/init-loader#files-to-be-loaded

faceの複数属性を設定するなら set-face-attributeもあり

https://github.com/gongo/elfactory/blob/master/config/01_basic.el#L60


個人的な好みですが, 複数属性を設定するときは set-face-attributeを
使っています. 例えば以下は

(set-face-foreground  'whitespace-tab "#700000")
(set-face-background  'whitespace-tab 'nil)
(set-face-underline   'whitespace-tab t)

以下と等価になります.

(set-face-attribute 'whitespace-tab nil
                    :foreground "#700000" :background nil
                    :underline t)

direxのロード不要

https://github.com/gongo/elfactory/blob/master/config/15_direx.el


遅延ロードできます.

20_cucumber-mode.elは不要

https://github.com/gongo/elfactory/blob/master/config/20_cucumber-mode.el


遅延ロードできますし, auto-mode-alistの設定は cask-initializeで
できているのでファイル全体が必要ありません.


特殊な拡張子の設定を追加する場合は別ですが, 基本的な拡張子に対する
auto-mode-alistの設定は不要です(coffee-modeにおける .coffeeとか markdown-modeに
おける .mdとか). 標準的なものがデフォルトで設定されないようなら
パッケージ作者に報告した方がよいでしょう.

go-autocompleteのロードは, go-modeのロードまで遅延させることができる.

https://github.com/gongo/elfactory/blob/master/config/20_go-mode.el


以下のような感じでしょうか.

(eval-after-load 'go-mode
  '(require 'go-autocomplete))


なお Emacs 24.4から with-eval-after-loadというマクロが追加されており,
eval-after-load内のクォートが不要になります.

(with-eval-after-load 'go-mode
  (require 'go-autocomplete))

.md, .markdownの auto-mode-alistの設定は不要

https://github.com/gongo/elfactory/blob/master/config/20_markdown-mode.el


.mkdnはデフォルトでは設定されないので必要です.

emmet-modeのロードは不要

https://github.com/gongo/elfactory/blob/master/config/20_markup.el#L4


キーマップの設定が 1つだけ toplevelなのでそれを eval-after-loadの中に
いれれば, requireは取り除けます. ちゃんとロードしてから設定をしたいという
場合は下記のようになるでしょうか.

(add-hook 'sgml-mode-hook 'emmet-mode)
(add-hook 'css-mode-hook  'emmet-mode)

(eval-after-load 'emmet-mode
  '(progn
     (defun-add-hook 'emmet-mode-hook
       (setq emmet-indentation 2))
     (define-key emmet-mode-keymap (kbd "C-j") nil)
     (define-key emmet-mode-keymap (kbd "C-<tab>") 'emmet-expand-line)))

web-modeのロードは不要

https://github.com/gongo/elfactory/blob/master/config/20_markup.el#L19


こちらは requireを取り除くだけでよいです.
ただ厳密にやるなら以下のような感じでしょうか.

(add-to-list 'auto-mode-alist '("\\.tpl\\'"   . web-mode))
(add-to-list 'auto-mode-alist '("\\.ihtml\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))

(eval-after-load 'web-mode
  '(defun-add-hook 'web-mode-hook
     (setq web-mode-html-offset   4)
     (setq web-mode-css-offset    4)
     (setq web-mode-script-offset 4)
     (setq web-mode-php-offset    4)
     (setq indent-tabs-mode nil)
     (setq tab-width 4)))

cl.elより cl-lib.elの方がよい

https://github.com/gongo/elfactory/blob/master/config/30_org-mode.el


'cl-' prefixをつけるのが面倒かもしれないですが, 今後も Emacs
使うのであれば cl-libの方がよいです. eval-when-compileも不要に
なりますし.

ace-jump-modeのロード不要

https://github.com/gongo/elfactory/blob/master/config/50_ace-jump.el


遅延ロードできます.

flycheckのロード不要

https://github.com/gongo/elfactory/blob/master/config/50_flycheck.el


あと少しそれますが, マイナーモードの有効は t, nilでなく +1, -1を
使う方がいいそうです.

おわり

次回は 9月27日(土) 22時からの予定です.