From a09558921bafcfae91b85af563ee10144c3b7ace Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Mon, 2 Jul 2012 23:08:07 +0300 Subject: [PATCH 1/4] InlineDiff: base implementation --- app/assets/stylesheets/sections/commits.scss | 11 ++++ app/helpers/commits_helper.rb | 55 +++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss index 078709e2..acab785a 100644 --- a/app/assets/stylesheets/sections/commits.scss +++ b/app/assets/stylesheets/sections/commits.scss @@ -82,6 +82,17 @@ color:#333; font-size: 12px; font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; + .old{ + span.idiff{ + background-color:#FAA; + } + } + .new{ + span.idiff{ + background-color:#AFA; + } + } + } .diff_file_content_image { background:#eee; diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 7ee85a5b..cbd2c969 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -35,8 +35,9 @@ module CommitsHelper line_old = 1 line_new = 1 type = nil - - lines_arr = diff_arr + + lines_arr = inline_diff diff_arr + #lines_arr = diff_arr lines_arr.each do |line| next if line.match(/^\-\-\- \/dev\/null/) next if line.match(/^\+\+\+ \/dev\/null/) @@ -45,6 +46,9 @@ module CommitsHelper full_line = html_escape(line.gsub(/\n/, '')) + full_line.gsub!("#!idiff-start!#", "") + full_line.gsub!("#!idiff-finish!#", "") + if line.match(/^@@ -/) type = "match" @@ -81,4 +85,51 @@ module CommitsHelper nil end end + + def inline_diff diff_arr + chain_of_first_symbols = "" + diff_arr.each_with_index do |line, i| + chain_of_first_symbols += line[0] + end + chain_of_first_symbols.gsub!(/[^\-\+]/, "#") + + offset = 0 + indexes = [] + while index = chain_of_first_symbols.index("#-+#", offset) + indexes << index + offset = index + 1 + end + + indexes.each do |index| + first_line = diff_arr[index+1] + second_line = diff_arr[index+2] + max_length = [first_line.size, second_line.size].max + + first_the_same_symbols = 0 + (0..max_length + 1).each do |i| + first_the_same_symbols = i - 1 + if first_line[i] != second_line[i] && i > 0 + break + end + end + first_token = first_line[0..first_the_same_symbols][1..-1] + + diff_arr[index+1].sub!(first_token, first_token + "#!idiff-start!#") + diff_arr[index+2].sub!(first_token, first_token + "#!idiff-start!#") + + last_the_same_symbols = 0 + (1..max_length + 1).each do |i| + last_the_same_symbols = -i + if first_line[-i] != second_line[-i] + break + end + end + last_the_same_symbols += 1 + last_token = first_line[last_the_same_symbols..-1] + + diff_arr[index+1].sub!(/#{last_token}$/, "#!idiff-finish!#" + last_token) + diff_arr[index+2].sub!(/#{last_token}$/, "#!idiff-finish!#" + last_token) + end + diff_arr + end end From cecdb0b384d2f6943fab704497e67a744eb553f7 Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Mon, 2 Jul 2012 23:34:25 +0300 Subject: [PATCH 2/4] InlineDiff: refactoring --- app/helpers/commits_helper.rb | 53 +-------------------------- lib/gitlab/inline_diff.rb | 69 +++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 51 deletions(-) create mode 100644 lib/gitlab/inline_diff.rb diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index cbd2c969..fa87632d 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -36,8 +36,7 @@ module CommitsHelper line_new = 1 type = nil - lines_arr = inline_diff diff_arr - #lines_arr = diff_arr + lines_arr = ::Gitlab::InlineDiff.processing diff_arr lines_arr.each do |line| next if line.match(/^\-\-\- \/dev\/null/) next if line.match(/^\+\+\+ \/dev\/null/) @@ -45,9 +44,7 @@ module CommitsHelper next if line.match(/^\+\+\+ b/) full_line = html_escape(line.gsub(/\n/, '')) - - full_line.gsub!("#!idiff-start!#", "") - full_line.gsub!("#!idiff-finish!#", "") + full_line = ::Gitlab::InlineDiff.replace_markers full_line if line.match(/^@@ -/) type = "match" @@ -86,50 +83,4 @@ module CommitsHelper end end - def inline_diff diff_arr - chain_of_first_symbols = "" - diff_arr.each_with_index do |line, i| - chain_of_first_symbols += line[0] - end - chain_of_first_symbols.gsub!(/[^\-\+]/, "#") - - offset = 0 - indexes = [] - while index = chain_of_first_symbols.index("#-+#", offset) - indexes << index - offset = index + 1 - end - - indexes.each do |index| - first_line = diff_arr[index+1] - second_line = diff_arr[index+2] - max_length = [first_line.size, second_line.size].max - - first_the_same_symbols = 0 - (0..max_length + 1).each do |i| - first_the_same_symbols = i - 1 - if first_line[i] != second_line[i] && i > 0 - break - end - end - first_token = first_line[0..first_the_same_symbols][1..-1] - - diff_arr[index+1].sub!(first_token, first_token + "#!idiff-start!#") - diff_arr[index+2].sub!(first_token, first_token + "#!idiff-start!#") - - last_the_same_symbols = 0 - (1..max_length + 1).each do |i| - last_the_same_symbols = -i - if first_line[-i] != second_line[-i] - break - end - end - last_the_same_symbols += 1 - last_token = first_line[last_the_same_symbols..-1] - - diff_arr[index+1].sub!(/#{last_token}$/, "#!idiff-finish!#" + last_token) - diff_arr[index+2].sub!(/#{last_token}$/, "#!idiff-finish!#" + last_token) - end - diff_arr - end end diff --git a/lib/gitlab/inline_diff.rb b/lib/gitlab/inline_diff.rb new file mode 100644 index 00000000..b70abc22 --- /dev/null +++ b/lib/gitlab/inline_diff.rb @@ -0,0 +1,69 @@ +module Gitlab + class InlineDiff + class << self + + START = "#!idiff-start!#" + FINISH = "#!idiff-finish!#" + + def processing diff_arr + indexes = _indexes_of_changed_lines diff_arr + + indexes.each do |index| + first_line = diff_arr[index+1] + second_line = diff_arr[index+2] + max_length = [first_line.size, second_line.size].max + + first_the_same_symbols = 0 + (0..max_length + 1).each do |i| + first_the_same_symbols = i - 1 + if first_line[i] != second_line[i] && i > 0 + break + end + end + first_token = first_line[0..first_the_same_symbols][1..-1] + + diff_arr[index+1].sub!(first_token, first_token + START) + diff_arr[index+2].sub!(first_token, first_token + START) + + last_the_same_symbols = 0 + (1..max_length + 1).each do |i| + last_the_same_symbols = -i + if first_line[-i] != second_line[-i] + break + end + end + last_the_same_symbols += 1 + last_token = first_line[last_the_same_symbols..-1] + + diff_arr[index+1].sub!(/#{last_token}$/, FINISH + last_token) + diff_arr[index+2].sub!(/#{last_token}$/, FINISH + last_token) + end + diff_arr + end + + def _indexes_of_changed_lines diff_arr + chain_of_first_symbols = "" + diff_arr.each_with_index do |line, i| + chain_of_first_symbols += line[0] + end + chain_of_first_symbols.gsub!(/[^\-\+]/, "#") + + offset = 0 + indexes = [] + while index = chain_of_first_symbols.index("#-+#", offset) + indexes << index + offset = index + 1 + end + indexes + end + + def replace_markers line + line.gsub!(START, "") + line.gsub!(FINISH, "") + line + end + + end + + end +end From 00bc0e2577123a87f680eba0372800da64077dcc Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Mon, 2 Jul 2012 23:39:38 +0300 Subject: [PATCH 3/4] InlineDiff: small cleaning --- lib/gitlab/inline_diff.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gitlab/inline_diff.rb b/lib/gitlab/inline_diff.rb index b70abc22..e488adb6 100644 --- a/lib/gitlab/inline_diff.rb +++ b/lib/gitlab/inline_diff.rb @@ -36,7 +36,7 @@ module Gitlab last_token = first_line[last_the_same_symbols..-1] diff_arr[index+1].sub!(/#{last_token}$/, FINISH + last_token) - diff_arr[index+2].sub!(/#{last_token}$/, FINISH + last_token) + diff_arr[index+2].sub!(/#{last_token}$/, FINISH + last_token) end diff_arr end From e3fed8aaf4b2b9c3a7a0b719acd52408b1d4f90a Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Thu, 5 Jul 2012 00:57:12 +0300 Subject: [PATCH 4/4] InlineDiff: fix bug "unmatched close parenthesis" --- lib/gitlab/inline_diff.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/gitlab/inline_diff.rb b/lib/gitlab/inline_diff.rb index e488adb6..0f289a61 100644 --- a/lib/gitlab/inline_diff.rb +++ b/lib/gitlab/inline_diff.rb @@ -34,9 +34,8 @@ module Gitlab end last_the_same_symbols += 1 last_token = first_line[last_the_same_symbols..-1] - - diff_arr[index+1].sub!(/#{last_token}$/, FINISH + last_token) - diff_arr[index+2].sub!(/#{last_token}$/, FINISH + last_token) + diff_arr[index+1].sub!(/#{Regexp.escape(last_token)}$/, FINISH + last_token) + diff_arr[index+2].sub!(/#{Regexp.escape(last_token)}$/, FINISH + last_token) end diff_arr end