在Emacs的ruby-mode中,使用制表符而不是空格进行缩进

3

我一直在尝试配置Emacs,使其在缩进Ruby代码时插入“制表符”而不是一系列“空格”。

到目前为止,我已经尝试设置变量ruby-indent-tabs-modet,根据文档,如果这个变量非空,则会“在ruby模式中插入制表符”。但是到目前为止还没有成功。

我还尝试通过Easy customisation进行自定义,它将以下内容插入到我的init.el中:

(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.
 '(ruby-indent-tabs-mode t))
(custom-set-faces
 ;; custom-set-faces 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.
 )

通过 C-h v 检查变量后,它报告变量设置为t,但按下 TAB 仍然插入空格。

我甚至尝试编辑 ruby-mode 的 .el 文件并重新编译,但没有效果。

希望得到帮助。

----- 编辑 -----

这是通过 C-h m 报告的活动次要模式:

启用的次要模式:Abbrev Auto-Complete Auto-Composition
Auto-Compression Auto-Encryption File-Name-Shadow Font-Lock
Global-Auto-Complete Global-Font-Lock Inf-Ruby Line-Number Menu-Bar
Show-Smartparens Show-Smartparens-Global Smartparens
Smartparens-Global Transient-Mark

init.el 文件当前有:

(require 'cask "/Users/snowingheart/.cask/cask.el")
(cask-initialize)
(require 'pallet)

(add-to-list 'load-path "~/elisp")
(load "php-mode")
(add-to-list 'auto-mode-alist
             '("\\.php[34]?\\'\\|\\.phtml\\'" . php-mode))

(global-set-key (kbd "C-x <up>") 'windmove-up)
(global-set-key (kbd "C-x <down>") 'windmove-down)
(global-set-key (kbd "C-x <right>") 'windmove-right)
(global-set-key (kbd "C-x <left>") 'windmove-left)

(require 'package)
(add-to-list 'package-archives
    '("marmalade" .
      "http://marmalade-repo.org/packages/"))
(package-initialize)

(global-set-key (kbd "C-x >") 'mc/mark-next-like-this)
(global-set-key (kbd "C-x <") 'mc/mark-previous-like-this)
(global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this)
(global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)

(require 'smartparens-config)
(require 'smartparens-ruby)
(require 'smartparens-erb)
(smartparens-global-mode)
(show-smartparens-global-mode t)

(sp-with-modes '(rhtml-mode)
               (sp-local-pair "<%=" "%>")
               (sp-local-pair "<%-" "%>"))
(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories
             "~/.emacs.d/.cask/24.3.50.1/elpa/auto-complete-20130724.1750/dict")
(ac-config-default)
(setq ac-ignore-case nil)
(add-to-list 'ac-modes 'enh-ruby-mode)
(add-to-list 'ac-modes 'web-mode)

(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.
 '(indent-tabs-mode t)
 '(ruby-indent-tabs-mode t))
(custom-set-faces
 ;; custom-set-faces 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.
 )

(setq-default indent-tabs-mode t)
(setq enh-ruby-indent-tabs-mode t)

(smart-tabs-insinuate 'ruby)
(smart-tabs-advice ruby-indent-line ruby-indent-level)
(setq ruby-indent-tabs-mode t)

4
请重新考虑使用制表符还是空格。制表符在各种编辑器中的显示方式不同,尤其是在由其他人配置时,可能会导致代码对齐出现严重问题。有些人希望制表符显示为两个空格,有些人希望它们显示为四个,还有一些人希望它们显示为八个。因此,在Ruby中,我们使用两个空格进行缩进,而不是制表符,以保持所编写代码的一致性。缩进不仅仅是为了你的舒适,也是为了那些维护或继承你代码的人着想。 - the Tin Man
我非常同意你的观点。问题在于这不是为了我的利益,而是为了我的一个同事。他的编辑器(sublime)使用制表符缩进代码,当我们在同一文件上工作时,当我交出我的两个空格的文件时,事情往往会出现问题。 - snowingheart
2
@snowingheart:在这方面,Sublime Text是完全可配置的。它甚至会检查文件并尝试猜测缩进间隔。我不明白为什么这是你的问题而不是你同事的问题? - Borodin
@Borodin 哈哈,我猜他可能还没有完全探索它?而且我以为我能够轻松配置emacs...话虽如此,我会告诉他去研究一下,也许问题可以通过这种方式解决。 - snowingheart
我同时使用Sublime和vim,完全没有问题。将Sublime默认设置为两个空格而不使用制表符非常容易。vim也是如此。Emacs肯定和其他两个一样灵活。 - the Tin Man
显示剩余3条评论
2个回答

2
尝试将以下内容添加到您的init.el文件中(在您已经有的自定义设置下方):
(setq-default indent-tabs-mode t)

indent-tabs-mode的文档中可以看到:

如果这个参数为非nil,缩进会使用制表符。

我不使用ruby-mode,所以我不知道indent-tabs-moderuby-indent-tabs-mode之间可能存在的交互作用。只设置indent-tabs-modet(并删除你对ruby-indent-tabs-mode所做的自定义)可能就足够了。但是,当你将上面的片段添加到你的配置中时,Emacs的默认行为将是插入制表符进行缩进。

编辑

可以看到这里enh-ruby-mode定义了一个名为enh-ruby-indent-tabs-mode的可自定义变量,默认值为nil之后,此变量的值用于覆盖indent-tabs-mode的值,这就是为什么将indent-tabs-mode设置为t对于启用了enh-ruby-mode的缓冲区没有影响的原因。

因此,除非您启用了除ruby-modeenh-ruby-mode之外可能修改indent-tabs-mode变量的任何其他模式,否则添加

(setq enh-ruby-indent-tabs-mode t)

将代码添加到您的 init.el 应该可以解决您的问题。

另一种修改(可行解决方案)

(致谢:这个答案让我找到了正确的方向。)

使用:

  • Emacs 24.3.1

  • ruby-mode 版本 1.2(内置)

  • enh-ruby-mode 版本 20140406.252(通过 M-x package-install 安装)

我成功地将以下内容添加到完全空白init.el 文件中,使其正常工作:

(package-initialize)

(setq-default tab-width 2)
(setq enh-ruby-indent-tabs-mode t)
(defvaralias 'enh-ruby-indent-level 'tab-width)
(defvaralias 'enh-ruby-hanging-indent-level 'tab-width)

这个解决方案适用于 Emacs 的图形用户界面和控制台版本。它可能会很好地集成到您的其他自定义中,但是您需要从您上面发布的 init.el 版本中删除 custom-set-variables 部分及其以下所有内容。
另请注意,如果您遇到 Emacs 插入空格而不是制表符的情况,您可以通过 引用它 并使用 C-q TAB 强制插入制表符。

总结

事实证明,在enh-ruby-mode中存在一个错误,当enh-ruby-indent-tabs-mode设置为t时,导致从第二层开始的块缩进失败。enh-ruby-mode的作者/维护者没有修复它的计划,但该错误报告包括一个据说可以修复此问题的补丁。


我试图通过 M-x set-variable 设置变量,现在它被设置为 t,但仍然使用空格进行缩进... - snowingheart
1
@snowingheart 不用谢,没错。我不知道为什么...但既然我们基本上解决了你最初的问题(而且这个评论区变得非常长;)),你可能想考虑发布一个单独的问题来解决这个特定的问题。或者,如果您有GitHub帐户,直接在他们的问题跟踪器上提交问题,向enh-ruby-mode的开发人员提问也是有意义的。 编辑:实际上,已经有这样一个问题了。 - itsjeyd
1
我会在那里尝试一下代码,然后 :D 读到作者对这个问题的看法有点令人沮丧,因为正如lyro所说,如果没有计划支持制表符,那么应该明确说明。 - snowingheart
1
哦,你能在你的回答中链接到那个问题吗?只是为了完整性:P - snowingheart
1
@snowingheart 好的,我会做的 :) 尽管这是一条崎岖的道路,但我认为我们在这里为遇到相同问题的人们创建了一个很好的资源。可能不会有太多人,但无论如何... :) - itsjeyd
显示剩余16条评论

0

更新的答案 au goût du jour(Emacs 28.2):

indent-tabs-moderuby-indent-tabs-mode设置为t

在您的~/.emacs.el全局设置中:

(setq indent-tabs-mode t)
(setq ruby-indent-tabs-mode t)
(setq tab-width 2)
(setq ruby-indent-level 2)

或者更好的方法是,将其限制在特定项目中,在~/src/your-project/.dir-locals.el(例如)文件中:
((ruby-mode . ((indent-tabs-mode . t)
               (ruby-indent-tabs-mode . t)
               (tab-width . 2)
               (ruby-indent-level . 2))))

由于某些原因,这似乎并不在所有地方都起作用。看起来是ruby-mode中的一个错误。 - Apteryx

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