【发布时间】:2010-02-12 05:59:35
【问题描述】:
如何让 Emacs 以 ShiftTab 将所选文本向左移动 4 个空格?
【问题讨论】:
标签: emacs
如何让 Emacs 以 ShiftTab 将所选文本向左移动 4 个空格?
【问题讨论】:
标签: emacs
为此,我使用命令indent-rigidly,绑定到C-x TAB。给它参数 -4 将所选区域向左移动四个空格:C-u -4 C-x TAB。
http://www.gnu.org/s/emacs/manual/html_node/elisp/Region-Indent.html
【讨论】:
indent-code-rigidly,因为它只保留了 cmets 和多行字符串
这会从当前行的前面删除 4 个空格(前提是空格存在)。
(global-set-key (kbd "<S-tab>") 'un-indent-by-removing-4-spaces)
(defun un-indent-by-removing-4-spaces ()
"remove 4 spaces from beginning of of line"
(interactive)
(save-excursion
(save-match-data
(beginning-of-line)
;; get rid of tabs at beginning of line
(when (looking-at "^\\s-+")
(untabify (match-beginning 0) (match-end 0)))
(when (looking-at "^ ")
(replace-match "")))))
如果您的变量 tab-width 恰好是 4(这就是您想要“撤消”的内容),那么您可以将 (looking-at "^ ") 替换为更通用的名称,例如 (concat "^" (make-string tab-width ?\ ))。
此外,代码将使用untabify 将行前的制表符转换为空格。
【讨论】:
(kbd "<backtab>") 而不是 (kbd "<S-tab>") 对我有用。
我制作了一些函数,根据您使用的是 tab 还是 shift+tab,将一个区域向左或向右移动四个空格:
(defun indent-region-custom(numSpaces)
(progn
; default to start and end of current line
(setq regionStart (line-beginning-position))
(setq regionEnd (line-end-position))
; if there's a selection, use that instead of the current line
(when (use-region-p)
(setq regionStart (region-beginning))
(setq regionEnd (region-end))
)
(save-excursion ; restore the position afterwards
(goto-char regionStart) ; go to the start of region
(setq start (line-beginning-position)) ; save the start of the line
(goto-char regionEnd) ; go to the end of region
(setq end (line-end-position)) ; save the end of the line
(indent-rigidly start end numSpaces) ; indent between start and end
(setq deactivate-mark nil) ; restore the selected region
)
)
)
(defun untab-region (N)
(interactive "p")
(indent-region-custom -4)
)
(defun tab-region (N)
(interactive "p")
(if (active-minibuffer-window)
(minibuffer-complete) ; tab is pressed in minibuffer window -> do completion
; else
(if (string= (buffer-name) "*shell*")
(comint-dynamic-complete) ; in a shell, use tab completion
; else
(if (use-region-p) ; tab is pressed is any other buffer -> execute with space insertion
(indent-region-custom 4) ; region was selected, call indent-region-custom
(insert " ") ; else insert four spaces as expected
)))
)
(global-set-key (kbd "<backtab>") 'untab-region)
(global-set-key (kbd "<tab>") 'tab-region)
编辑:添加了 Maven 的代码来检查是否在 minibuffer 中,以及在特定缓冲区(例如 shell)中的 tab 补全。
【讨论】:
我改进了 Stanley Bak 的回答。 对我来说,这个全局键绑定破坏了 minibuffer 的完成。
所以我也包含了一个小型缓冲区的案例。
编辑:重命名indent-region -> indent-region-custom。
indent-region 与现有命令冲突,并在保存时缩进(保存前挂钩)和其他一些组合键出现错误。
(defun indent-region-custom(numSpaces)
(progn
;; default to start and end of current line
(setq regionStart (line-beginning-position))
(setq regionEnd (line-end-position))
;; if there's a selection, use that instead of the current line
(when (use-region-p)
(setq regionStart (region-beginning))
(setq regionEnd (region-end))
)
(save-excursion ; restore the position afterwards
(goto-char regionStart) ; go to the start of region
(setq start (line-beginning-position)) ; save the start of the line
(goto-char regionEnd) ; go to the end of region
(setq end (line-end-position)) ; save the end of the line
(indent-rigidly start end numSpaces) ; indent between start and end
(setq deactivate-mark nil) ; restore the selected region
)
)
)
(defun untab-region (N)
(interactive "p")
(indent-region-custom -4)
)
(defun tab-region (N)
(interactive "p")
(if (active-minibuffer-window)
(minibuffer-complete) ; tab is pressed in minibuffer window -> do completion
(if (use-region-p) ; tab is pressed is any other buffer -> execute with space insertion
(indent-region-custom 4) ; region was selected, call indent-region-custom
(insert " ") ; else insert four spaces as expected
)
)
)
(global-set-key (kbd "<backtab>") 'untab-region)
(global-set-key (kbd "<tab>") 'tab-region)
【讨论】: