前回の記事では、 tab-width
を custom-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-variables
とsetq
を適当に使い分けるようにしたのが以下の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)))