lib/textbringer/modes/ruby_mode.rb in textbringer-0.2.8 vs lib/textbringer/modes/ruby_mode.rb in textbringer-0.2.9

- old
+ new

@@ -149,11 +149,11 @@ @buffer[:ruby_compile_command] || if File.exist?("Rakefile") prefix = File.exist?("Gemfile") ? "bundle exec " : "" prefix + "rake" elsif @buffer.file_name - "ruby " + @buffer.file_name + ruby_install_name + " " + @buffer.file_name else nil end end @@ -198,19 +198,42 @@ end end private + INDENT_BEG_RE = /^([ \t]*)((class|module|def|if|unless|case|while|until|for|begin|end)\b|\})/ + + def space_width(s) + s.gsub(/\t/, " " * @buffer[:tab_width]).size + end + + def beginning_of_indentation + loop do + @buffer.re_search_backward(INDENT_BEG_RE) + space = @buffer.match_string(1) + s = @buffer.substring(@buffer.point_min, @buffer.point) + if PartialLiteralAnalyzer.in_literal?(s) + next + end + return space_width(space) + end + rescue SearchError + @buffer.beginning_of_buffer + 0 + end + def calculate_indentation if @buffer.current_line == 1 return 0 end @buffer.save_excursion do @buffer.beginning_of_line bol_pos = @buffer.point - tokens = Ripper.lex(@buffer.substring(@buffer.point_min, - @buffer.point)) + base_indentation = beginning_of_indentation + start_pos = @buffer.point + start_line = @buffer.current_line + tokens = Ripper.lex(@buffer.substring(start_pos, bol_pos)) _, event, text = tokens.last if event == :on_tstring_beg || event == :on_heredoc_beg || event == :on_regexp_beg || (event == :on_regexp_end && text.size > 1) || @@ -220,11 +243,11 @@ line, column, event, = find_nearest_beginning_token(tokens) if event == :on_lparen return column + 1 end if line - @buffer.goto_line(line) + @buffer.goto_line(start_line - 1 + line) while !@buffer.beginning_of_buffer? if @buffer.save_excursion { @buffer.backward_char @buffer.skip_re_backward(/\s/) @buffer.char_before == ?, @@ -233,22 +256,21 @@ else break end end @buffer.looking_at?(/[ \t]*/) - base_indentation = @buffer.match_string(0). - gsub(/\t/, " " * @buffer[:tab_width]).size - else - base_indentation = 0 + base_indentation = space_width(@buffer.match_string(0)) end @buffer.goto_char(bol_pos) - if line.nil? || - @buffer.looking_at?(/[ \t]*([}\])]|(end|else|elsif|when|rescue|ensure)\b)/) + if line.nil? indentation = base_indentation else indentation = base_indentation + @buffer[:indent_level] end + if @buffer.looking_at?(/[ \t]*([}\])]|(end|else|elsif|when|rescue|ensure)\b)/) + indentation -= @buffer[:indent_level] + end _, last_event, last_text = tokens.reverse_each.find { |_, e, _| e != :on_sp && e != :on_nl && e != :on_ignored_nl } if (last_event == :on_op && last_text != "|") || last_event == :on_period || @@ -303,8 +325,35 @@ end stack.pop end end return nil + end + + class PartialLiteralAnalyzer < Ripper + def self.in_literal?(src) + new(src).in_literal? + end + + def in_literal? + @literal_level = 0 + parse + @literal_level > 0 + end + + private + + %w(embdoc heredoc tstring regexp + symbols qsymbols words qwords).each do |name| + define_method("on_#{name}_beg") do |token| + @literal_level += 1 + end + end + + %w(embdoc heredoc tstring regexp).each do |name| + define_method("on_#{name}_end") do |token| + @literal_level -= 1 + end + end end end end