2

I really have problem reading code with spaces, so I use the visual studio code editor to indent codes from spaces to tabs before I read them.

But the problem is rails has a lot of files, I have to do the same operation repetitively. So, I want to use Dir.glob to iterate over all of them and covert spaces to tabs and overwrite those files. It is a terrible idea, but still...

Currently my String#spaces_to_tabs() method looks like this:

Code

# A method that works for now...
String.define_method(:spaces_to_tabs) do
    each_line.map do |x|
        match = x.match(/^([^\S\t\n\r]*)/)[0]
        m_len = match.length
        (m_len > 0 && m_len % 2 == 0) ? ?\t * (m_len / 2) + x[m_len .. -1] : x
    end.join
end

Which kind of works

Here's a test:

# Put some content that will get converted to space
content = <<~EOF << '# Hello!'
  def x
    'Hello World'
  end

  p x

  module X
    refine Array do
      define_method(:tally2) do
        uniq.reduce({}) { |h, x| h.merge!( x => count(x) ) }
      end
    end
  end

  using X
  [1, 2, 3, 4, 4, 4,?a, ?b, ?a].tally2
  p [1, 2, 3, 4, 4, 4,?a, ?b, ?a].tally2
  \r\r\t\t # Some invalid content
EOF

puts content.spaces_to_tabs

Output:

def x
    'Hello World'
end

p x

module X
    refine Array do
        define_method(:tally2) do
            uniq.reduce({}) { |h, x| h.merge!( x => count(x) ) }
        end
    end
end

using X
[1, 2, 3, 4, 4, 4,?a, ?b, ?a].tally2
p [1, 2, 3, 4, 4, 4,?a, ?b, ?a].tally2
         # Some invalid content
# Hello!

Currently it does not:

  1. Affect white-spaces (\t, \r, \n) other than spaces.
  2. Affect the output of code, only converts spaces to tabs.

I can't use my editor because:

  1. With Dir.glob (not included in this example), I can iterate over only .rb, .js, .erb, .html, .css, and .scss files.

Also, this is slow, but I can have at most 1000 files (above extensions) with 1000 lines of code for each file, but that's max, and not too practical, I generally have < 100 files with a couple of hundred lines of code. The code can take 10 seconds, which is not a problem here, since I need to run the code once for a project...

Is there a better way to do it?


Edit

Here's the full code with globbing for converting all major files in rails:

#!/usr/bin/ruby -w
String.define_method(:bold) { "\e[1m#{self}" }

String.define_method(:spaces_to_tabs) do
    each_line.map do |x|
        match = x.match(/^([^\S\t\n\r]*)/)[0]
        m_len = match.length
        (m_len > 0 && m_len % 2 == 0) ? ?\t * (m_len / 2) + x[m_len .. -1] : x
    end.join
end

GREEN = "\e[38;2;85;160;10m".freeze
BLUE = "\e[38;2;0;125;255m".freeze
TURQUOISE = "\e[38;2;60;230;180m".freeze
RESET = "\e[0m".freeze
BLINK = "\e[5m".freeze

dry_test = ARGV.any? { |x| x[/^\-(\-dry\-test|d)$/] }
puts "#{TURQUOISE.bold}:: Info:#{RESET}#{TURQUOISE} Running in Dry Test mode. Files will not be changed.#{RESET}\n\n" if dry_test

Dir.glob("{app,config,db,lib,public}/**/**.{rb,erb,js,css,scss,html}").map do |y|
    if File.file?(y) && File.readable?(y)
        read = IO.read(y)
        converted = read.spaces_to_tabs

        unless read == converted
            puts "#{BLINK}#{BLUE.bold}:: Converting#{RESET}#{GREEN} indentation to tabs of #{y}#{RESET}"
            IO.write(y, converted) unless dry_test
        end
    end
end
15 Volts
  • 1,946
  • 15
  • 37
  • It may help: https://stackoverflow.com/questions/20675237/converting-spaces-to-tabs-in-multiple-files-sublime-text-2 – iGian Aug 02 '20 at 08:14
  • Would you mind elaborating on why you have a _problem reading code with spaces_? I never notice a difference in my editor between both. – spickermann Aug 02 '20 at 09:04
  • 1
    This is [a really bad idea](http://tarantsov.com/hackers-coding-style-guide/why-tabs-should-be-avoided.html). Configure your editor to display the code the way you want instead of manhandling the code. I don't use VSCode but this is configurable in pretty much every code editor in existance. – max Aug 02 '20 at 09:04
  • I think 1 space is shown as one space, but I can configure tabs to show as 4 or 8 spaces. Currently I use 4 space tabs, but Rails uses 2 space indentation, I think I can't render 2 spaces as 4 spaces with VSCode... – 15 Volts Aug 02 '20 at 09:07

1 Answers1

1

If this is just an intellectual exercise about tab indentation algorithms, then fine. If you really have trouble viewing the files, use Rubocop. It has configuration options that allow you to beautify the code, and the type of spaces it generates and the degree of indentation it applies. I use it with Atom and atom-beautify but I'm sure it has a plugin for VS code too. https://docs.rubocop.org/rubocop/0.86/cops_layout.html#layoutindentationconsistency

nullTerminator
  • 396
  • 1
  • 6