emacs のテキストモードで Shift+Tab を実現する - Assemblrを参考にして次のように設定した。リージョンが存在しているときには、そのリージョン内の行をインデントしたり逆インデントする。リージョンが存在していないときには、現在のカーソル位置をもとにインデントしたり逆インデントする。インデントは C-i か Tab キーで、逆インデントは Shift-Tab で行う。
(add-hook 'text-mode-hook (lambda () (define-key text-mode-map (kbd "C-i") 'tab-to-tab-stop-dwim) (define-key text-mode-map (kbd "S-<tab>") 'backtab-dwim) (set (make-local-variable 'tab-width) 4) (set (make-local-variable 'tab-stop-list) (loop for i from 4 to 140 by 4 collect i)))) (defun tab-to-tab-stop-dwim () (interactive) (tab-to-tab-stop-or-backtab 'tab-to-tab-stop)) (defun backtab-dwim () (interactive) (tab-to-tab-stop-or-backtab 'backtab)) (defun tab-to-tab-stop-or-backtab (func) (if mark-active (save-excursion (let ((lines (count-lines (region-beginning) (region-end)))) (goto-char (region-beginning)) (loop repeat lines do (progn (funcall func) (forward-line)))) (setq deactivate-mark nil))) (funcall func)) (defun backtab () "delete indentation" (interactive) (save-excursion (when (string= "\t" (char-to-string (following-char))) (delete-char 1)) (when (string= "\t" (char-to-string (preceding-char))) (delete-backward-char 1))))