smarttabs icon indicating copy to clipboard operation
smarttabs copied to clipboard

Ruby: indentation is inserting tabs inappropriately.

Open rye opened this issue 9 years ago • 10 comments

It appears that the Ruby indentation configuration is broken. C indentation is conforming to the Smart Tabs concept, but the following (example) Ruby code gets indented incorrectly. I have tried removing all tab characters and reindenting the buffer, but the same problem persists. I have replaced tab characters with -> |.

require "banana"

class Test
-> |class Banana
-> |-> |def initialize
-> |-> |-> |if (ENV["banana"] ||
-> |-> |-> |-> |ENV["chicken"] ||
-> |-> |-> |-> |ENV["cow"])
-> |-> |-> |-> |puts "happy"
-> |-> |-> |end
-> |-> |end
-> |end
end

I would expect it to instead do the following:

require "banana"

class Test
-> |class Banana
-> |-> |def initialize
-> |-> |-> |if (ENV["banana"] ||
-> |-> |-> |....ENV["chicken"] ||
-> |-> |-> |....ENV["cow"])
-> |-> |-> |-> |puts "happy"
-> |-> |-> |end
-> |-> |end
-> |end
end

In examining behavior in much larger and more complex reindentation situations, this problem is the same in many situations: it appears that ruby-indent-line or ruby-indent-region is interpreting what should be four spaces as a tab character and is converting to tab characters when it should not.

Is there something that I am missing? I am currently using a very recent version of the Git mirror of the Emacs BZR repository (the development version).

rye avatar Oct 04 '14 20:10 rye

Either the smart-tabs-mode set-up for Ruby is using the wrong variables, or the Ruby mode’s indentation logic is different to other languages’. In the first case, a patch should be relatively straightforward for someone familiar with Emacs’s Ruby mode; in the second, this mode cannot easily be made compatible with Ruby.

Patches are very welcome; analyses showing incompatibility less so, but still welcome.

jcsalomon avatar Oct 20 '14 21:10 jcsalomon

I recently tested some possible fixes for this. One of them was to simply call the ruby-indent-line function to reindent lines. This works perfectly fine, indenting the aforementioned lines correctly. However, ruby-indent-line is not the default indent-line-function; smie-indent-line is. To fix this, I just always (setq indent-line-function 'ruby-indent-line) during ruby-mode-hook.

rye avatar Nov 09 '14 22:11 rye

Will switching ruby-indent-line for smie-indent-line present surprises to the user, and can this switch be included in the smart-tabs-create-language-advice ruby lines? Or should smart-tabs-mode be cleverer and use the correct indentation function? (I ask out of ignorance of Ruby-mode behavior; whichever you decide on and submit as a patch will be added.)

jcsalomon avatar Nov 12 '14 19:11 jcsalomon

Well, I know that ruby-indent-line works correctly, and smie-indent-line does not.

rye avatar Jan 11 '15 02:01 rye

It appears that the variable ruby-use-smie in ruby-mode.el determines if Ruby will use SMIE or not. If indent-line-function is buffer-locally set to ruby-indent-line, ruby-indent-line is therefore (duh) used, and it works perfectly. I tried defining a hook to do this (pegged to ruby-mode-hook), but it didn't work.

rye avatar Jan 11 '15 02:01 rye

Unfortunately, I do not have much experience with EmacsLISP packaging, and so I'm somewhat at a loss as to what to do.

EDIT: Fixed words.

rye avatar Jan 11 '15 03:01 rye

It appears that smart-tabs-advice's modifications to the value of indent-line-function are simply getting obliterated by SMIE, and so any modifications don't carry through to the end of all of the hooks that are called.

rye avatar Jan 11 '15 03:01 rye

I fixed it in my personal configuration this morning, by adding (setq ruby-use-smie nil) to my configuration. Perhaps this should be documented for others?

rye avatar Jan 11 '15 19:01 rye

I would prefer a patch that included this within the Ruby set-up; either on its own or within the Ruby mode hook.

jcsalomon avatar Jan 11 '15 19:01 jcsalomon

Thanks @rye for the fix. This should be indeed documented.

scast avatar Nov 07 '16 19:11 scast