Question

I've been trying to configure Emacs so that it insert a 'tab' instead of a series of 'spaces' when indenting Ruby code.

So far, I've tried setting the var ruby-indent-tabs-mode to t so that, as per the documentation, it would "insert tabs in ruby mode if this is non-nil.". But so far, no dice.

I've also tried customising it via Easy customisation, which inserted the following into my 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.
 )

And after inspecting the variable via C-h v, it reports the variable is set to t, but pressing TAB keeps on inserting spaces.

I even tried editing the .el file for ruby-mode and re-compiling it to no effect.

Help would be appreciated.

----- EDIT -----

Here's the minor modes reported active via C-h m:

Enabled minor modes: 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

The init.el file currently has:

(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)
Was it helpful?

Solution

Try adding the following to your init.el (below the customizations you already have):

(setq-default indent-tabs-mode t)

From the documentation for indent-tabs-mode:

Indentation can insert tabs if this is non-nil.

I don't use ruby-mode so I don't know about possible interactions between indent-tabs-mode and ruby-indent-tabs-mode. It might just be enough to set indent-tabs-mode to t (and erase the customizations you made to ruby-indent-tabs-mode). But when you add the snippet above to your configuration, the default behavior for Emacs will be to insert tabs for indentation.


EDIT

As can be seen here, enh-ruby-mode defines a customizable variable called enh-ruby-indent-tabs-mode with a default value of nil. Later on the value of this variable is used to override the value of indent-tabs-mode, which is why setting indent-tabs-mode to t has no effect on buffers with enh-ruby-mode enabled.

So unless you enable any other modes besides ruby-mode and enh-ruby-mode that might be modifying the indent-tabs-mode variable, adding

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

to your init.el should fix your problem.


Another EDIT (working solution)

(Credits: This answer put me on the right track.)

Using

  • Emacs 24.3.1

  • ruby-mode version 1.2 (built-in)

  • enh-ruby-mode version 20140406.252 (installed via M-x package-install ...)

I was able to make it work by adding the following to an otherwise completely empty init.el file:

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

This solution works for both the GUI and the console version of Emacs. It will probably integrate fine with your other customizations but you will need to remove the custom-set-variables section and everything below it from the version of your init.el you posted above.

Note also that if you do come across a situation in which Emacs inserts a space instead of a tab you can always delete it and force insertion of a tab by quoting it via C-q TAB.


Wrapping up

Turns out there is a bug in enh-ruby-mode which causes indentation to fail for blocks starting from the second level when enh-ruby-indent-tabs-mode is set to t. The author/maintainer of enh-ruby-mode has no plans of fixing it, but the bug report includes a patch that supposedly fixes the issue.

OTHER TIPS

Updated answer au goût du jour (Emacs 28.2):

Set the indent-tabs-mode and ruby-indent-tabs-mode to t.

Globally, in your ~/.emacs.el:

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

Or better, limited to a particular project, in a ~/src/your-project/.dir-locals.el (for example) file:

((ruby-mode . ((indent-tabs-mode . t)
               (ruby-indent-tabs-mode . t)
               (tab-width . 2)
               (ruby-indent-level . 2))))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top