如何在Emacs中将按键绑定到缩进/取消缩进区域?

15

我希望定义两个按键绑定,用于将选定的区域缩进/取消缩进四个空格。


Before:

hello
world
foo
bar
  • 可视化地选择worldfoo
  • 键入>

之后:

hello
    world
    foo
bar
我也想将 < 绑定到取消缩进区域。
我不熟悉 emacs,请帮忙。

请指出您实际工作的模式/语言。可能已经具备此功能。 - aartist
我在这个答案中编写了制表/取消制表区域的函数:https://dev59.com/RXE95IYBdhLWcg3wlu0g#35183657 - Stanley Bak
4个回答

26

已经有相应的键盘快捷方式了:

缩进:C-u 4 C-x TAB

取消缩进:C-u - 4 C-x TAB

如果你觉得输入起来太麻烦,你可以在你的 .emacs 文件中加入以下内容:

(defun my-indent-region (N)
  (interactive "p")
  (if (use-region-p)
      (progn (indent-rigidly (region-beginning) (region-end) (* N 4))
             (setq deactivate-mark nil))
    (self-insert-command N)))

(defun my-unindent-region (N)
  (interactive "p")
  (if (use-region-p)
      (progn (indent-rigidly (region-beginning) (region-end) (* N -4))
             (setq deactivate-mark nil))
    (self-insert-command N)))

(global-set-key ">" 'my-indent-region)
(global-set-key "<" 'my-unindent-region)

使用此代码,大于 (>) 和 小于 (<) 键将使所选区域每次缩进/取消缩进四个空格。


1
我刚刚编辑了代码以保持区域活动状态。但是通常可以通过键入“C-x C-x”重新选择。然后,您还可以使用前缀参数:“例如,C-u 2 >”将缩进8个空格。 - Thomas
请注意,要使您区域的第一行缩进和取消缩进,您需要在标记区域的开头选择额外的一行。但这非常棒! - Mauricio A. Cinelli
请参考@seth2810的答案,以获取区域的开头和结尾(使用region-beginningregion-end而不是取pointmark的最小值和最大值)的Emacs方法。它还有一点“DWIM”:如果区域未激活,则它将在当前行上操作。 - Davor Cubranic
@DavorCubranic 谢谢,我已经相应地更新了我的回答。 - Thomas
我该如何编写 ctrl + >ctrl + < 的键盘组合?仅仅写 "C->""C-<" 是不起作用的 (global-set-key: Key sequence C - > starts with non-prefix key C)。算了,我已经想到了解决方法,我会写一个答案。 - Zelphir Kaltstahl
显示剩余3条评论

2
(defun keyboard-indent (&optional arg)
  (interactive)
  (let ((deactivate-mark nil)
        (beg (or (and mark-active (region-beginning))
                 (line-beginning-position)))
        (end (or (and mark-active (region-end)) (line-end-position))))
    (indent-rigidly beg end (* (or arg 1) tab-width))))

(defun keyboard-unindent (&optional arg)
  (interactive)
  (keyboard-indent (* -1 (or arg 1))))

1
除了@Thomas已经写的内容,您可能不想使用键<>进行缩进或取消缩进。想象一下,如果您需要编写一些HTML并且不能再输入这些字符,这就是为什么我在我的init文件中插入以下键设置的原因:
(global-set-key (kbd "C-<") 'my-indent-region)
(global-set-key (kbd "C->") 'my-unindent-region)

注意:没有 (kbd ...) 将无法正常工作。您会收到一个错误信息:
global-set-key: Key sequence C - > starts with non-prefix key C

在我上面的回答中,不能再使用 <> 键是不正确的;相反,代码会检查缓冲区的某些部分是否被选中,只有在按下相应键时才进行(取消)缩进。如果您想要简单地插入 <>,则可以在没有选择任何内容时这样做。 - Thomas

1
您可以使用将 4 替换为 tab-width,如下所示:
(defun indent-region-shift-right-n (N)
  (interactive "p")
  (if (use-region-p)
      (progn (indent-rigidly (region-beginning) (region-end) (* N tab-width))
             (setq deactivate-mark nil))
    (self-insert-command N)))
(defun unindent-region-shift-left-n (N)
  (interactive "p")
  (if (use-region-p)
      (progn (indent-rigidly (region-beginning) (region-end) (* N (- tab-width)))
             (setq deactivate-mark nil))
    (self-insert-command N)))
(global-set-key ">" 'indent-region-shift-right-n)
(global-set-key "<" 'unindent-region-shift-left-n)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接