ChatGPT解决这个技术问题 Extra ChatGPT

在 Emacs 中以文本模式设置 4 空格缩进

在主模式 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 按钮总是做同样的事情。

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

尽管我很喜欢 Emacs,但它变得越来越烦人。当上一行没有文本时,有没有办法让 Emacs 至少缩进 4 个空格?

对于模式行 C++ 或 csharp-mode,我将 (setq tab-width 4) (setq c-basic-offset 4) 添加到 (defun csharp-mode () ... ) 的末尾,它确实做到了 ( 1) 制表符显示为 4 个而不是 8 个字符,(2) 当我按制表符时,我在新行上得到 4 个空格。
很晚了,但我才意识到使用 (setq tab-width 4) 不起作用,但如果你使用 (setq-default tab-width 4) 你不需要做任何其他事情。
如果您想使用空格但转到制表位,请参阅我的回答。
发现此问题的其他人请注意:(setq-default tab-width 4)(setq tab-width 4) 不同,请确保您没有错过“-default”!
我不敢相信这很难做到。

a
alcortes

简短的回答:

关键是告诉emacs在缩进时插入你想要的任何东西,这是通过改变indent-line-function来完成的。将其更改为插入一个制表符,然后将制表符更改为 4 个空格比将其更改为插入 4 个空格更容易。以下配置将解决您的问题:

(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)
(setq indent-line-function 'insert-tab)

解释:

Indentation Controlled by Major Mode @ emacs manual

每个主要模式的一个重要功能是为正在编辑的语言自定义键以正确缩进。 [...] indent-line-function 变量是用于缩进当前行的函数(以及各种命令,例如调用 indent-region 时)。命令 indent-according-to-mode 只是调用这个函数。 [...] 对于许多模式,默认值是相对缩进的。

来自 indent-relative @emacs 手册:

Indent-relative Space out 到下一个非空行中的下一个缩进点。 [...]如果前一个非空白行在列点开始处没有缩进点,则改为执行“tab-to-tab-stop”。

只需将 indent-line-function 的值更改为 insert-tab 函数,并将制表符插入配置为 4 个空格。


我和OP有同样的问题,你的解决方案对我不起作用。
你的配置为我插入了 8 个空格。
我使用的是 emacs 23.3.1 版,简短的回答不会将其更改为空格。这个答案具有误导性。
@BruceBarnett 我处于文本模式,这些说明仍然不起作用。
对于那些不知道的人...将上面显示的代码块中的行添加到 ~/.emacs。如果您没有该文件,您可以创建它。
p
phils

更新:从 Emacs 24.4 开始:

tab-stop-list 现在隐式扩展到无穷大。它的默认值更改为 nil,这意味着每个制表符宽度列都有一个制表位。

这意味着不再需要按如下所示的方式设置 tab-stop-list,因为您可以将其设置为 nil

原始答案如下...

number-sequence 函数坐在那里等待使用时,看到像 (setq tab-stop-list 4 8 12 ................) 这样的东西总是让我有点痛苦。

(setq tab-stop-list (number-sequence 4 200 4))

或者

(defun my-generate-tab-stops (&optional width max)
  "Return a sequence suitable for `tab-stop-list'."
  (let* ((max-column (or max 200))
         (tab-width (or width tab-width))
         (count (/ max-column tab-width)))
    (number-sequence tab-width (* tab-width count) tab-width)))

(setq tab-width 4)
(setq tab-stop-list (my-generate-tab-stops))

这是我可以在我的系统上工作的唯一答案。
emacs 缩进自定义页面说选项卡列表“通过重复最后一步隐式扩展到无穷大” - 这意味着列表(4 8)应该足够好,没有明确的数字序列
@JamesWaldby-jwpat7 确实,这发生在 24.4(2014 年)。 NEWS 说:“tab-stop-list 现在隐式扩展到无穷大。它的默认值更改为 nil,这意味着每 tab-width 列有一个制表位。” -- 所以实际上你可以使用默认值 nil
缩进似乎 4 in 但 emacs 在 \begin{tikzpicture} 和 \end{tikzpicture} 之间应用了 2 个空格
@alper:缩进功能因模式而异——不同的语言可能有非常不同的规则和要求。您必须阅读有关 Emacs 如何专门进行 LaTeX(我认为)缩进的阅读。
s
skrueger

不要将变量 tab-width 与变量 tab-stop-list 混淆。前者用于显示文字 TAB 字符。后者控制在某些模式下按 TAB 字符时插入的字符。

-- GNU Emacs Manual

(customize-variable (quote tab-stop-list))

或将制表符列表条目添加到 .emacs 文件中的自定义设置变量:

(custom-set-variables
  ;; custom-set-variables was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 '(tab-stop-list (quote (4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120))))

编辑标签行为的另一种方法是使用 M-x edit-tab-stops

有关 edit-tab-stops 的详细信息,请参阅 GNU Emacs Manual on Tab Stops


tab-width 和 tab-stop-list 都是需要的。 tab-width 在显示选项卡时使用,而在添加选项卡时需要 tab-stop-list 来确定制表位。
真的没有比 '(tab-stop-list (quote (4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120))) 更短的吗?好吧,只要它有效,我猜......:P
根据文档,您不需要所有这些职位。只需执行 4 8 12,它将扩展到所有其他人(继续添加 4)。显然,如果您只使用 1 个或 2 个元素而不是 3 个,它只会使用制表符宽度作为最后一步。所以理论上,如果我想用四个空格来制表符,并且我的制表符宽度设置为 4。我可以写 '(tab-stop-list (quote (4)))
@NicholasPeterson 感谢您注意到这一点!但是,实际上 quote 似乎需要两个数字来无限地继续序列。请参阅:stackoverflow.com/a/42148697/2662028
D
Dave Webb

您可能会发现按以下方式设置选项卡更容易:

M-x customize-group

Customize group: 提示符处输入 indent

您将看到一个屏幕,您可以在其中设置所有缩进选项并为当前会话设置它们或为所有未来会话保存它们。

如果您这样做,您会想要 set up a customisations file


我需要记住 Mx customize-group - 非常方便的快捷方式!
缩进似乎是 4,但它仍然在 \begin{tikzpicture}\end{tikzpicture} 之间应用 2
佚名
(setq tab-width 4)
(setq tab-stop-list '(4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80))
(setq indent-tabs-mode nil)

a
alecxe
(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)
(setq indent-line-function 'insert-tab)
(setq c-default-style "linux") 
(setq c-basic-offset 4) 
(c-set-offset 'comment-intro 0)

这也适用于 C++ 代码和里面的注释


派对迟到了,但谢谢你。我无法理解为什么 emacs 需要特定的指令才能将其缩进规则也应用于 C/C++ 代码。我将来会关注vim...
我想自己问这个问题,这样我才能接受这个答案。如果可以的话,我会给它一个赏金。我非常非常沮丧,因为一个改变让 emacs 不愿意在 4 点按标签,正在浏览这个页面上的所有解决方案,你为我节省了大量的工作!
l
lawlist
(defun my-custom-settings-fn ()
  (setq indent-tabs-mode t)
  (setq tab-stop-list (number-sequence 2 200 2))
  (setq tab-width 2)
  (setq indent-line-function 'insert-tab))

(add-hook 'text-mode-hook 'my-custom-settings-fn)

当此页面上的其他人没有时,这对我有用。
在 emacs 中工作 26.3
佚名

此问题不是由缺少制表位引起的;是 emacs 有一个(新的?)选项卡方法,称为 indent-relative,它似乎旨在排列表格数据。 TAB 键映射到方法 indent-for-tab-command,它调用变量 indent-line-function 设置的任何方法,这是文本模式的缩进相关方法。我还没有想出一个好方法来覆盖 indent-line-function 变量(文本模式钩子不起作用,所以它可能在模式钩子运行后被重置?)但是一个简单的方法来摆脱这个行为是通过将 TAB 设置为更简单的 tab-to-tab-stop 方法来放弃 intent-for-tab-command 方法:

(define-key text-mode-map (kbd "TAB") 'tab-to-tab-stop)


g
gigilibala

您可以将这些代码行添加到您的 .emacs 文件中。它为文本模式添加了一个钩子,以使用 insert-tab 而不是 indent-relative。

(custom-set-variables
 '(indent-line-function 'insert-tab)
 '(indent-tabs-mode t)
 '(tab-width 4))
(add-hook 'text-mode-hook
      (lambda() (setq indent-line-function 'insert-tab)))

我希望它有所帮助。


c
cjm

尝试这个:

(add-hook 'text-mode-hook
  (function
   (lambda ()
     (setq tab-width 4)
     (define-key text-mode-map "\C-i" 'self-insert-command)
     )))

这将使 TAB 始终插入一个文字 TAB 字符,每 4 个字符带有制表位(但仅在文本模式下)。如果这不是您所要求的,请描述您希望看到的行为。


我认为 OP 想要空格而不是制表符(因此点击制表符会插入 4 个空格)。
结合 Aquamacs 2.4,这个特定的答案给了我另一种语言的字符而不是标签:렔。如果 tab 键被按下超过一次,结果是:렔렔(没有任何分隔)。对于每个连续的制表符按下也是如此。
d
dividebyzero

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


q
qwerty9967

将此添加到您的 .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 个空格。
Y
Yary

自定义可能会影响 (setq tab width 4),因此请使用 setq-default 或让自定义知道您在做什么。我也遇到了与 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)

这只是让我将已经缩进的东西切换回左对齐。第二次制表符将其带回开始缩进。在左对齐文本上按制表符根本没有任何作用。
并且提到的 M+i 和在 this answer 中使用 4 个空格时,这里有 8 个空格。
这(最后两行)可以在单个文件级别使用模式行完成吗?为此,将一个变量定义为另一个变量的值可能就足够了,但我不知道如何在模式行中做到这一点。
r
ryanpcmcquen

这是唯一可以防止标签被插入的解决方案,无需将标签序列或转换为空格。这两个似乎都足够了,但很浪费:

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

请注意,quote 需要两个数字才能工作(但不能更多!)。

此外,在大多数主要模式(例如 Python)中,缩进在 Emacs 中是自动的。如果您需要在自动缩进之外缩进,请使用:


M+i 技巧适用于 4 个空格。该选项卡只是让我将已经缩进的东西切换回左对齐。第二次制表符将其带回开始缩进。任何左对齐的东西都不会改变。我在一个 Python 文件中,这可能是这里所说的自动对齐。但是这个答案使用 tab-stop-list 这不是一个好方法,它应该是 number-sequence 而不是,参见 this highly upvoted answer
建议使用数字序列代替:bash (setq-default indent-tabs-mode nil tab-width 4 tab-stop-list (number-sequence 4 200 4) )
@ questionto42,为什么?这不会在 200+ 时停止缩进一致性吗?
@questionto42 这是我建议的限制。当我的解决方案自动扩展到无穷大时,为什么要使用它?
@questionto42 该评论批评不使用序列的代码,但我的代码使用的序列比那里提供的序列更有效。
j
josliber

直到我在 .emacs 文件中写了这个,最好的答案才起作用:

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

是的,这使标签成为真正的标签,无论它是否有意义。普通选项卡查看选项卡是否适合代码。在代码中,左对齐的东西不会被标签缩进,这个标签没有意义。这是为了帮助自动对齐,但大多数时候您宁愿使用代码编辑器而不是 emacs 进行代码格式化。然后在 emacs 中,无论如何,您通常都只想要选项卡。 代码在您按 Tab 时会产生 8 个空格。将此与 this answer 结合起来,在 M+i 上留出 4 个空格。
佚名

你有没有尝试过

(setq  tab-width  4)

他们的问题中有这个,所以是的,可以肯定地假设他们尝试过。
D
Dason
(setq-default tab-width 4)
(setq-default indent-tabs-mode nil)

f
flyrain

顺便说一句,对于 C 模式,我将 (setq-default c-basic-offset 4) 添加到 .emacs。有关详细信息,请参阅 http://www.emacswiki.org/emacs/IndentingC


S
Stefan

从我的初始化文件中,不同,因为我想要空格而不是制表符:

(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")       ; now '_' is not considered a word-delimiter
               (modify-syntax-entry ?- "w")       ; now '-' is not considered a word-delimiter 
               )))

S
Saurabh

修改后的 this answer 没有任何钩子:

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

奇怪,当我将它添加到 ~/.emacs 时,选项卡根本不起作用,只要我按下它,行就会左对齐,仅此而已。可能是我的错误,emacs 新手。在左对齐文本上按制表符根本没有任何作用。
使用 this answer 中提到的 M+i 时,要进一步缩进 4 个空格。可能我的选项卡测试主要由我的 Python 文件的 emacs 自动对齐控制,在那个答案中也有解释。
a
alex_1948511

要在文本模式下按 Tab 进行缩进,然后按固定值制表符/间距(不按前一行字)

另见:缩进相对第一个缩进点,制表符宽度缩进制表符模式

(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)
     )))

当我在缩进的行上按下制表符时,我得到一个左对齐,第二次它跳回开始缩进。在左对齐文本上按制表符根本没有任何作用。
并且提到的 M+i 和在 this answer 中使用 4 个空格时,这里有 8 个空格。