BLOG

続Emacsのインデント設定

kuroda

前回の記事では、 tab-widthcustom-set-variables 関数を使って設定する方法をご紹介しました。
実はこの方法には1つ問題があり、すべてのファイル種類で tab-width の値が等しくなってしまうのです。

具体的には、以下のように設定したとします。

(setting-html-tab 4) ; htmlファイルのtab-widthを4に設定
(setting-js-tab 3)   ; jsファイルのtab-widthを3に設定

この状態で適当なhtmlファイルを開くと、tab幅を4に設定して表示されます。
次に適当なjsファイルを開くと、こちらは設定したとおりtab幅3で表示されます。
ところが、ここでさっき開いたhtmlファイルのバッファを表示させると、こっちもtab幅が3に変わってしまっています。
この状態で M-x html-mode として html-mode に切り替え直すと、tab幅は4に戻りますが、今度はjsファイルのバッファに切り替えたときにそっちがtab幅3になってしまっています。

setq をモードのフックの中で使って変数を設定すると、モード毎に値を分けることができるのですが、 custom-set-variablesを使うと全モードで共通の値になってしまうようで、これが原因で上記のような挙動になってしまいます。

そういうわけで、custom-set-variablessetqを適当に使い分けるようにしたのが以下のelispになります。

こちらがhtml用で

(defun setting-html-tab (&optional tab-width)
  (interactive)

  (let* ((tab-width (if tab-width tab-width 3))
         (hook `(lambda ()
                  (setq tab-width ,tab-width)
                  (setq indent-tabs-mode t))))

    (custom-set-variables
     `(sgml-basic-offset ,tab-width))

    (remove-hook 'html-mode-hook hook)
    (add-hook 'html-mode-hook hook t)))
(setting-html-tab)

(defun setting-html-space (width &optional tab-width)
  (interactive "nWidth:")

  (let* ((tab-width (if tab-width tab-width 8))
         (hook `(lambda ()
                  (setq tab-width ,tab-width)
                  (setq indent-tabs-mode nil))))

    (custom-set-variables
     `(sgml-basic-offset ,width))

    (remove-hook 'html-mode-hook hook)
    (add-hook 'html-mode-hook hook t)))

こっちがjavascript用です

(defun setting-js-tab (&optional tab-width)
  (interactive)

  (let* ((tab-width (if tab-width tab-width 3))
         (hook `(lambda ()
                  (setq tab-width ,tab-width)
                  (setq indent-tabs-mode t))))

    (custom-set-variables
     `(js-indent-level ,tab-width))

    (remove-hook 'js-mode-hook hook)
    (add-hook 'js-mode-hook hook t)))
(setting-js-tab)

(defun setting-js-space (width &optional tab-width)
  (interactive "nWidth:")

  (let* ((tab-width (if tab-width tab-width 8))
         (hook `(lambda ()
                  (setq indent-tabs-mode nil)
                  (setq tab-width ,tab-width))))

    (custom-set-variables
     `(js-indent-level ,width))

    (remove-hook 'js-mode-hook hook)
    (add-hook 'js-mode-hook hook t)))