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