Emacs カスタマイズ

最近また開発環境について考える機会があったので、少しメモ。 コーディングのためのガイドラインとしてよくあるインデントの扱いについて設定するための elisp を作成したので、インデントがらみの設定とともに掲載しておきます。

タブストップ位置の自動作成

Emacs のタブストップ位置は tab-stop-list 変数で設定可能で通常は以下のように設定します。

(setq tab-stop-list '(8 16 24 32 40 48 56 64 72 80 88 96 104 112 120))

上記はデフォルト値なんですが、タブ幅4にする場合は

(setq tab-stop-list '(4 8 12 16 20 24 28 32 36 40 44 48 52 56 60))

のように設定します。
見ての通り、少々面倒です。
なので、次のものを用意しました。

;; tab-stop-list を指定幅で作成する
(defun make-tab-stop-list (stride)
  "Make tab-stop-list"
  (interactive "nTabStride: ")      ; 'n' で数値として読み込む
  (setq tab-stop-list ())
  (let ((num stride))
    (while (< num 256)
    (setq tab-stop-list `(,@tab-stop-list ,num))
    (setq num (+ num stride)))))

使用方法は以下。

(make-tab-stop-list 8)  ; タブ幅8設定
(make-tab-stop-list 4)  ; タブ幅4設定

バックタブ

逆インデントのためのバックタブです。タブストップに合わせて逆インデントします。

;; backtab
(defun backtab-to-tab-stop ()
  "Do back to previous tab-stop"
  (interactive)
  (let ((tabs tab-stop-list)
    (col (current-column))
    (tab-last 0))
    (back-to-indentation)           ; 現在行の白文字でない最初の文字へポイントを移動
    (if (= col (current-column))        ; 当初のカーソル位置が白文字でない最初の文字位置と一致しているかどうかで期待する位置を調整
    (while (and tabs (> col (car tabs)))
      (setq tab-last (car tabs))
      (setq tabs (cdr tabs)))
      (while (and tabs (>= col (car tabs)))
      (setq tab-last (car tabs))
      (setq tabs (cdr tabs))))
    ; 期待するタブ位置にくるまで1文字ずつ削除
    (while (> (current-column) tab-last)
      (delete-backward-char 1))))

下記のような設定で「SHIFT + Tab」にキーバインドしておくと良いかと思います。

(global-set-key [S-tab] 'backtab-to-tab-stop)

その他

タブコードの幅は tab-width で設定可能です。

(set tab-width 8)

タブコードを使わず空白を使用するには以下で設定可能です。

(setq indent-tabs-mode nil)