mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-10 05:06:46 +10:00
Apply syntax highlighting when expanding diff plus some refactor. #3945
This commit is contained in:
@@ -66,7 +66,7 @@ class Projects::BlobController < Projects::ApplicationController
|
||||
|
||||
def diff
|
||||
@form = UnfoldForm.new(params)
|
||||
@lines = @blob.data.lines[@form.since - 1..@form.to - 1]
|
||||
@lines = Gitlab::Diff::Highlight.process_diff_lines(@blob.name, @blob.data.lines[@form.since - 1..@form.to - 1])
|
||||
|
||||
if @form.bottom?
|
||||
@match_line = ''
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
%td.old_line.diff-line-num{data: {linenumber: line_old}}
|
||||
= link_to raw(line_old), "#"
|
||||
%td.new_line= link_to raw(line_new) , "#"
|
||||
%td.line_content.noteable_line= ' ' * @form.indent + line
|
||||
%td.line_content.noteable_line= raw("#{' ' * @form.indent}#{line}")
|
||||
|
||||
- if @form.unfold? && @form.bottom? && @form.to < @blob.loc
|
||||
%tr.line_holder{ id: @form.to }
|
||||
|
||||
@@ -1,31 +1,62 @@
|
||||
module Gitlab
|
||||
module Diff
|
||||
class Highlight
|
||||
def self.process_diff_lines(file_name, diff_lines)
|
||||
processor = new(file_name, diff_lines)
|
||||
# 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.
|
||||
#
|
||||
# Returns an Array with the processed items.
|
||||
def self.process_diff_lines(file_name, lines)
|
||||
processor = new(file_name, lines)
|
||||
processor.highlight
|
||||
end
|
||||
|
||||
def initialize(file_name, diff_lines)
|
||||
text_lines = diff_lines.map(&:text)
|
||||
@file_name = file_name
|
||||
@diff_lines = diff_lines
|
||||
@diff_line_prefixes = text_lines.map { |line| line.sub!(/\A((\+|\-)\s*)/, '');$1 }
|
||||
@raw_lines = text_lines.join("\n")
|
||||
def initialize(file_name, lines)
|
||||
@file_name = file_name
|
||||
@lines = lines
|
||||
end
|
||||
|
||||
def highlight
|
||||
@code = unescape_html(@raw_lines)
|
||||
return [] if @lines.empty?
|
||||
|
||||
extract_line_prefixes
|
||||
|
||||
@code = unescape_html(raw_content)
|
||||
@highlighted_code = formatter.format(lexer.lex(@code))
|
||||
|
||||
update_diff_lines
|
||||
is_diff_line? ? update_diff_lines : @highlighted_code.lines
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def is_diff_line?
|
||||
@lines.first.is_a?(Gitlab::Diff::Line)
|
||||
end
|
||||
|
||||
def text_lines
|
||||
@text_lines ||= (is_diff_line? ? @lines.map(&:text) : @lines)
|
||||
end
|
||||
|
||||
def raw_content
|
||||
@raw_content ||= text_lines.join(is_diff_line? ? "\n" : nil)
|
||||
end
|
||||
|
||||
def extract_line_prefixes
|
||||
@diff_line_prefixes ||= begin
|
||||
if is_diff_line?
|
||||
text_lines.map { |line| line.sub!(/\A((\+|\-)\s*)/, '');$1 }
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update_diff_lines
|
||||
@highlighted_code.lines.each_with_index do |line, i|
|
||||
diff_line = @diff_lines[i]
|
||||
diff_line = @lines[i]
|
||||
|
||||
# ignore highlighting for "match" lines
|
||||
next if diff_line.type == 'match'
|
||||
@@ -33,7 +64,7 @@ module Gitlab
|
||||
diff_line.text = "#{@diff_line_prefixes[i]}#{line}"
|
||||
end
|
||||
|
||||
@diff_lines
|
||||
@lines
|
||||
end
|
||||
|
||||
def lexer
|
||||
|
||||
@@ -9,25 +9,41 @@ describe Gitlab::Diff::Highlight, lib: true do
|
||||
let(:diff_file) { Gitlab::Diff::File.new(diff) }
|
||||
|
||||
describe '.process_diff_lines' do
|
||||
let(:diff_lines) { Gitlab::Diff::Highlight.process_diff_lines(diff_file.new_path, diff_file.diff_lines) }
|
||||
context 'when processing Gitlab::Diff::Line objects' do
|
||||
let(:diff_lines) { Gitlab::Diff::Highlight.process_diff_lines(diff_file.new_path, diff_file.diff_lines) }
|
||||
|
||||
it 'should return Gitlab::Diff::Line elements' do
|
||||
expect(diff_lines.first).to be_an_instance_of(Gitlab::Diff::Line)
|
||||
it 'should return Gitlab::Diff::Line elements' do
|
||||
expect(diff_lines.first).to be_an_instance_of(Gitlab::Diff::Line)
|
||||
end
|
||||
|
||||
it 'should highlight the code' do
|
||||
code = %Q{<span id="LC3" class="line"> <span class="k">def</span> <span class="nf">popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kp">nil</span><span class="p">)</span></span>\n}
|
||||
|
||||
expect(diff_lines[2].text).to eq(code)
|
||||
end
|
||||
|
||||
it 'should keep the inline diff markup' do
|
||||
expect(diff_lines[5].text).to match(Regexp.new(Regexp.escape('<span class="idiff">RuntimeError, </span>')))
|
||||
end
|
||||
|
||||
it 'should not modify "match" lines' do
|
||||
expect(diff_lines[0].text).to eq('@@ -6,12 +6,18 @@ module Popen')
|
||||
expect(diff_lines[22].text).to eq('@@ -19,6 +25,7 @@ module Popen')
|
||||
end
|
||||
end
|
||||
|
||||
it 'should highlight the code' do
|
||||
code = %Q{<span id="LC3" class="line"> <span class="k">def</span> <span class="nf">popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kp">nil</span><span class="p">)</span></span>\n}
|
||||
context 'when processing raw lines' do
|
||||
let(:lines) { ["puts 'Hello'\n", "# A comment"] }
|
||||
let(:highlighted_lines) { Gitlab::Diff::Highlight.process_diff_lines('demo.rb', lines) }
|
||||
|
||||
expect(diff_lines[2].text).to eq(code)
|
||||
it 'should highlight the code' do
|
||||
line_1 = %Q{<span id="LC1" class="line"><span class="nb">puts</span> <span class="s1">'Hello'</span></span>\n}
|
||||
line_2 = %Q{<span id="LC2" class="line"><span class="c1"># A comment</span></span>}
|
||||
|
||||
expect(highlighted_lines[0]).to eq(line_1)
|
||||
expect(highlighted_lines[1]).to eq(line_2)
|
||||
end
|
||||
end
|
||||
|
||||
it 'should keep the inline diff markup' do
|
||||
expect(diff_lines[5].text).to match(Regexp.new(Regexp.escape('<span class="idiff">RuntimeError, </span>')))
|
||||
end
|
||||
|
||||
it 'should not modify "match" lines' do
|
||||
expect(diff_lines[0].text).to eq('@@ -6,12 +6,18 @@ module Popen')
|
||||
expect(diff_lines[22].text).to eq('@@ -19,6 +25,7 @@ module Popen')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user