OSDN Git Service

InlineDiff: base implementation
authorValeriy Sizov <vsv2711@gmail.com>
Mon, 2 Jul 2012 20:08:07 +0000 (23:08 +0300)
committerValeriy Sizov <vsv2711@gmail.com>
Mon, 2 Jul 2012 20:08:07 +0000 (23:08 +0300)
app/assets/stylesheets/sections/commits.scss
app/helpers/commits_helper.rb

index 078709e..acab785 100644 (file)
     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;
index 7ee85a5..cbd2c96 100644 (file)
@@ -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!#", "<span class='idiff'>")
+      full_line.gsub!("#!idiff-finish!#", "</span>")
+
       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