在Emacs的文本模式下设置四个空格缩进

181

当在主模式text-mode的缓冲区中按下TAB键时,我无法成功使Emacs从8空格制表符切换到4空格制表符。我已经将以下内容添加到我的.emacs文件中:

(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)

;;; And I have tried
(setq indent-tabs-mode nil)
(setq tab-width 4)

无论我如何更改我的.emacs文件(或者我的缓冲区的本地变量),TAB按钮总是做同样的事情。

  1. 如果上面没有文本,则缩进8个空格
  2. 如果前一行有文本,则缩进到第二个单词的开头

尽管我很喜欢Emacs,但这很烦人。是否有一种方法可以让Emacs在上一行没有文本时至少缩进4个空格?


针对C++或csharp-mode模式,我在(defun csharp-mode ()...)的结尾处添加了(setq tab-width 4)和(setq c-basic-offset 4),这使得(1)制表符显示为4个字符而不是8个字符,(2)当我按tab键时在新行上会出现4个空格。 - Jared Updike
非常晚了,但我刚意识到使用(setq tab-width 4)不起作用,但如果你使用(setq-default tab-width 4),你就不需要做任何其他事情。 - Sambatyon
如果您想使用空格,但是要转到制表位,请查看我的答案。 - forkandwait
注意:对于那些发现这个问题的人,请注意:(setq-default tab-width 4) 不等同于 (setq tab-width 4),一定不要漏掉 "-default"! - zachaysan
16
我不敢相信这么做很难。 - jds
21个回答

4

将以下内容添加到您的 .emacs 文件中:

这将设置制表符的显示宽度为 2 个字符(将数字 2 更改为任何您想要的数字)

(setq default-tab-width 2)

为了确保emacs实际上使用制表符而不是空格:
(global-set-key (kbd "TAB") 'self-insert-command)

顺便说一下,当在emacs中退格键后退到制表符时,默认的操作是将其转换为空格再删除一个空格。这可能很烦人。如果您希望它只删除制表符,可以按照以下步骤操作:

(setq c-backspace-function 'backward-delete-char)

尽情享受!


不符合问题中要求的至少4个空格。 - kmarsh

4

对我来说,只需使用c-set-style更改样式就足够了。


4

自定义设置可以覆盖(setq tab width 4),因此要么使用setq-default,要么告诉Customize您正在进行的操作。我遇到了类似于OP的问题,并且仅使用这个方法就解决了它,不需要调整tab-stop-list或任何insert函数:

(custom-set-variables
 '(tab-width 4 't)
 )

在这之后立即添加以下内容会很有用(来自emacsWiki的提示):

(defvaralias 'c-basic-offset 'tab-width)
(defvaralias 'cperl-indent-level 'tab-width)

这只是让我将已经缩进的内容切换回左对齐。第二次按Tab键会将其带回起始缩进位置。在左对齐文本上按Tab键不会有任何反应。 - questionto42
在这个答案中提到并使用4个空格的 M+i,在这里却变成了8个空格。 - questionto42
这个(最后两行)能否在模型行中完成,以文件为单位。对于它来说,定义一个变量与另一个变量相同的值可能足够了,但我不知道如何在模型行中实现。 - alfC

3

这是唯一的解决方案,可以防止我插入制表符,而无需进行任何制表符转换或空格转换。这两种方法都很可行,但是会浪费空间:

(setq-default
    indent-tabs-mode nil
    tab-width 4
    tab-stop-list (quote (4 8))
)

请注意,quote需要两个数字才能工作(但不要超过两个!)。
此外,在大多数主要模式(例如Python),Emacs会自动缩进。如果您需要在自动缩进之外进行缩进,请使用: M-i

建议使用数字序列:(setq-default indent-tabs-mode nil tab-width 4 tab-stop-list (number-sequence 4 200 4) ) - questionto42
1
@questionto42,正如我所建议的那样,这是一个限制。为什么要使用它,当我的解决方案可以自动扩展到无限大呢? - ryanpcmcquen
我对此一无所知,另一个得到高赞的回答只是说:“每当看到这样的代码(setq tab-stop-list 4 8 12 …………),我总是感到有些痛心,因为 number-sequence 函数正等着被使用。” 而你在这里的函数看起来就像是那种受到批评的代码。 - questionto42
1
@questionto42 那条评论批评的是没有使用序列的代码,但我的代码使用的序列比那里提供的更高效。 - ryanpcmcquen
请注意,(我)所提到的建议使用number-sequence的答案是在tab-stop-list隐式扩展到无限之前提出的--当我写下这个答案时,你只会得到你列出的制表位。然而(根据我稍后对同一答案的编辑),这些相同的更改意味着tab-stop-listnil(现在默认情况下应该是)将导致Emacs将tab-width的倍数视为隐式制表位;因此(setq-default tab-width 4)应该与您的(setq-default tab-width 4 tab-stop-list (quote (4 8)))行为相同。 - phils
显示剩余5条评论

2

在我将下面的内容写入.emacs文件之前,其他的最佳答案都无法解决我的问题:

(global-set-key (kbd "TAB") 'self-insert-command)

是的,这使得制表符成为真正的制表符,无论它是否有意义。普通的制表符会查看制表符是否适合代码。当在代码中左对齐时,制表符不会缩进,这个制表符就没有意义了。这是为了帮助自动对齐,但大多数情况下,您更愿意使用代码编辑器而不是emacs进行代码格式化。然后在emacs中,您通常只想要制表符。这里的代码每次按制表符键时都会产生8个空格。结合这个答案,可以在M+i上产生4个空格。 - questionto42

1

修改了 此答案,没有使用任何钩子:

(setq-default
  indent-tabs-mode t
  tab-stop-list (number-sequence 4 200 4)
  tab-width 4
  indent-line-function 'insert-tab)

很奇怪,当我将这个添加到~/.emacs时,Tab键就完全无法使用了,一按下它,行就会被左对齐,仅此而已。可能是我的错误,还不熟悉Emacs。在左对齐的文本上按Tab键根本没有任何反应。 - questionto42
当使用M+i时,进一步缩进4个空格是有效的,如此答案所述。也许我的制表符测试被Emacs自动对齐Python文件所支配,这也在那个答案中解释了。 - questionto42

0

为了在文本模式下按下Tab键时,可以通过固定值进行缩进和制表(而不是根据前一行的单词)

另请参阅:indent-relative-first-indent-point、tab-width indent-tabs-mode

(add-hook 'text-mode-hook
 (lambda()
   (progn
     (setq tab-always-indent nil) 
     ;(setq electric-indent-mode nil)
     (setq indent-line-function 
           (lambda()
             (indent-relative 't)   
             )
           ) 
     (setq tab-always-indent nil)
     )))

当我在一个缩进的行上按tab键时,它会左对齐,第二次则跳回到开始缩进。在左对齐文本上按tab键根本没有任何反应。 - questionto42
M+i这个答案中以4个空格工作,这里则使用8个空格。 - questionto42

0
(setq-default tab-width 4)
(setq-default indent-tabs-mode nil)

0

从我的初始化文件中,不同之处在于我想要空格而不是制表符:

(add-hook 'sql-mode-hook
          (lambda ()
             (progn
               (setq-default tab-width 4)
               (setq indent-tabs-mode nil)
               (setq indent-line-function 'tab-to-tab-stop) 
               (modify-syntax-entry ?_ "w")       ; 现在'_'不再被视为单词分隔符
               (modify-syntax-entry ?- "w")       ; 现在'-'不再被视为单词分隔符 
               )))

0

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