diff options
author | Rubén Dávila <rdavila84@gmail.com> | 2016-01-07 22:37:01 -0500 |
---|---|---|
committer | Rubén Dávila <rdavila84@gmail.com> | 2016-01-07 22:37:01 -0500 |
commit | 21b602c60ad787b63039d804a5e15b43d0d3c32c (patch) | |
tree | 91a068f9360b295c14599dd6547972c416a3614d /lib/gitlab/diff/highlight.rb | |
parent | f1f4fdf778245cab74ff9cda2a421315c21a99aa (diff) | |
download | gitlab-ce-21b602c60ad787b63039d804a5e15b43d0d3c32c.tar.gz |
Change strategy to highlight diffs. #3945
Now we apply syntax highlighting to the whole old and new files.
This basically help us to highlight adequately multiline content.
Diffstat (limited to 'lib/gitlab/diff/highlight.rb')
-rw-r--r-- | lib/gitlab/diff/highlight.rb | 70 |
1 files changed, 53 insertions, 17 deletions
diff --git a/lib/gitlab/diff/highlight.rb b/lib/gitlab/diff/highlight.rb index 7f340de65cc..0d0a3268107 100644 --- a/lib/gitlab/diff/highlight.rb +++ b/lib/gitlab/diff/highlight.rb @@ -1,22 +1,43 @@ module Gitlab module Diff class Highlight + attr_reader :diff_file + + delegate :repository, :old_path, :new_path, :old_ref, :new_ref, + to: :diff_file, prefix: :diff + # Apply syntax highlight to provided source code # - # file_name - The file name related to the code. - # lines - It can be an Array of Gitlab::Diff::Line objects or simple Strings. - # When passing Strings you need to provide the required 'end of lines' - # chars ("\n") for each String given that we don't append them automatically. + # diff_file - an instance of Gitlab::Diff::File # # Returns an Array with the processed items. - def self.process_diff_lines(file_name, lines) - processor = new(file_name, lines) + def self.process_diff_lines(diff_file) + processor = new(diff_file) processor.highlight end - def initialize(file_name, lines) - @file_name = file_name - @lines = lines + def self.process_file(repository, ref, file_name) + blob = repository.blob_at(ref, file_name) + return [] unless blob + + content = blob.data + lexer = Rouge::Lexer.guess(filename: file_name, source: content).new rescue Rouge::Lexers::PlainText.new + formatter.format(lexer.lex(content)).lines + end + + def self.formatter + @formatter ||= Rouge::Formatters::HTMLGitlab.new( + nowrap: true, + cssclass: 'code highlight', + lineanchors: true, + lineanchorsid: 'LC' + ) + end + + def initialize(diff_file) + @diff_file = diff_file + @file_name = diff_file.new_path + @lines = diff_file.diff_lines end def highlight @@ -47,7 +68,7 @@ module Gitlab def extract_line_prefixes @diff_line_prefixes ||= begin if is_diff_line? - text_lines.map { |line| line.sub!(/\A((\+|\-)\s*)/, '');$1 } + text_lines.map { |line| line.sub!(/\A((\+|\-))/, '');$1 } else [] end @@ -57,11 +78,17 @@ module Gitlab def update_diff_lines @highlighted_code.lines.each_with_index do |line, i| diff_line = @lines[i] + line_prefix = @diff_line_prefixes[i] || ' ' # ignore highlighting for "match" lines next if diff_line.type == 'match' - diff_line.text = "#{@diff_line_prefixes[i]}#{line}" + case diff_line.type + when 'new', nil + diff_line.text = new_lines[diff_line.new_pos - 1].try(:gsub!, /\A\s/, line_prefix) + when 'old' + diff_line.text = old_lines[diff_line.old_pos - 1].try(:gsub!, /\A\s/, line_prefix) + end end @lines @@ -79,12 +106,21 @@ module Gitlab end def formatter - Rouge::Formatters::HTMLGitlab.new( - nowrap: true, - cssclass: 'code highlight', - lineanchors: true, - lineanchorsid: 'LC' - ) + self.class.formatter + end + + def old_lines + @old_lines ||= begin + lines = self.class.process_file(diff_repository, diff_old_ref, diff_old_path) + lines.map! { |line| " #{line}" } + end + end + + def new_lines + @new_lines ||= begin + lines = self.class.process_file(diff_repository, diff_new_ref, diff_new_path) + lines.map! { |line| " #{line}" } + end end end end |