Class: DiffLog
Overview
Will store a diff each time a file is saved.
Constant Summary collapse
- @@log =
File.("~/.emacs.d/difflog.notes")
- @@temp_path =
"/tmp/saved.txt"
Class Method Summary collapse
- .compare_with_saved ⇒ Object
- .diffs(path = nil) ⇒ Object
- .do_compare_with ⇒ Object
- .enter_from_difflog ⇒ Object
-
.enter_new ⇒ Object
Insert new text added during last save.
- .enter_old ⇒ Object
- .enter_old_or_new(old_or_new) ⇒ Object
- .format(raw) ⇒ Object
- .is_one_line_change?(txt) ⇒ Boolean
-
.last_diff ⇒ Object
Insert old text deleted during last save.
-
.last_intraline_diff(txt = nil) ⇒ Object
Grabs last diff from difflog, and calculates exactly what changed.
- .menu ⇒ Object
-
.open ⇒ Object
Open file having difflog.
- .parse_tree_diffs(txt) ⇒ Object
-
.save ⇒ Object
Appends diff to difflog, then saves.
-
.save_diffs(options = {}) ⇒ Object
Util function used by public functions.
Class Method Details
.compare_with_saved ⇒ Object
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/xiki/diff_log.rb', line 156 def self.compare_with_saved if Keys.prefix_u buffer_unsaved = View.buffer path = View.file View.to_buffer "untitled" $el.rename_uniquely View << File.read(path) return $el.ediff_buffers View.buffer, buffer_unsaved end diff = self.save_diffs :dont_log=>1 diff = "" if diff.nil? View.to_buffer("*diff with saved*") View.clear Notes.mode View.insert diff.count("\n") > 2 ? diff : "> Note\n- No Differences!\n" end |
.diffs(path = nil) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/xiki/diff_log.rb', line 42 def self.diffs path=nil txt = File.open(@@log, 'rb') {|f| f.read} txt = txt.sub(/\A- /, '').split(/^- /).reverse.uniq path ||= Tree.dir # Pull from tree if there path = Bookmarks[path] if path if ! path regex = /^\// elsif File.file? path # File regex = /^#{Regexp.escape File.dirname path}\/\n - #{Regexp.escape File.basename path}/ else # Dir regex = /^#{Regexp.escape path}/ path = "#{path}/" if path !~ /\/$/ end txt = txt.select{|o| o =~ regex} "- @#{txt.join("- @")}" end |
.do_compare_with ⇒ Object
246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/xiki/diff_log.rb', line 246 def self.do_compare_with prefix = Keys.prefix :clear=>1 # up+ means compare buffers in first two views return $el.ediff_buffers( $el.window_buffer($el.nth(0, $el.window_list)), $el.window_buffer($el.nth(1, $el.window_list))) if prefix == :u # Save place and grab file at spot source_path = Tree.dir_at_spot dest_path = Tree.dir :file=>1 $el.ediff_files source_path, dest_path end |
.enter_from_difflog ⇒ Object
184 185 186 187 188 189 |
# File 'lib/xiki/diff_log.rb', line 184 def self.enter_from_difflog Location.as_spot View. if View. DiffLog.open $el.isearch_backward end |
.enter_new ⇒ Object
Insert new text added during last save
81 82 83 |
# File 'lib/xiki/diff_log.rb', line 81 def self.enter_new self.enter_old_or_new :new end |
.enter_old ⇒ Object
85 86 87 |
# File 'lib/xiki/diff_log.rb', line 85 def self.enter_old self.enter_old_or_new :old end |
.enter_old_or_new(old_or_new) ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/xiki/diff_log.rb', line 89 def self.enter_old_or_new old_or_new diff = DiffLog.last_diff one_line_change = DiffLog.is_one_line_change? diff # Show intraline change if changed just one line and not up+ if ! Keys.up? && one_line_change View.<< DiffLog.last_intraline_diff[old_or_new == :old ? 0 : 1] rescue View.beep $! return end # Show lines diff.gsub! /^ *[+:-].*\n/, "" # Only leave red and green lines if old_or_new == :old diff.gsub! /^ +\|\+.*\n/, "" diff.gsub! /^ +\|\-/, "" else diff.gsub! /^ +\|\-.*\n/, "" diff.gsub! /^ +\|\+/, "" end View << diff end |
.format(raw) ⇒ Object
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/xiki/diff_log.rb', line 133 def self.format raw path, file = raw.match(/--- (.+\/)(.+?)\t/)[1..2] # Delete paths at top raw.sub!(/.+\n.+\n/, '') # Make @@... lines into lines having numbers raw.gsub!(/^@@ -(\d+).* \+(\d+).+@@$/) { a, b = $1.to_i, $2.to_i highest = a > b ? a : b " :#{highest}" } # Make - and + lines into -| and +| lines raw.gsub!(/^\+(.*)/, " |+\\1") raw.gsub!(/^-(.*)/, " |-\\1") # Return with path "- #{path}\n" + " - #{file}\n" + raw end |
.is_one_line_change?(txt) ⇒ Boolean
74 75 76 77 78 |
# File 'lib/xiki/diff_log.rb', line 74 def self.is_one_line_change? txt txt.scan(/^ +\|\-/).length == 1 && txt.scan(/^ +\|\+/).length == 1 && txt.scan(/^ +:/).length end |
.last_diff ⇒ Object
Insert old text deleted during last save
66 67 68 69 70 71 72 |
# File 'lib/xiki/diff_log.rb', line 66 def self.last_diff $el.with(:save_window_excursion) do DiffLog.open Search.backward "^-" txt = View.txt View.cursor, View.bottom end end |
.last_intraline_diff(txt = nil) ⇒ Object
Grabs last diff from difflog, and calculates exactly what changed. Whithin the line. So, it performs a single-line diff
It presumes a single-line change, and a change at only one point on the line.
DiffLog.last_intraline_diff
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/xiki/diff_log.rb', line 269 def self.last_intraline_diff txt=nil txt ||= DiffLog.last_diff linea = txt[/ +\|\-(.+)/, 1] lineb = txt[/ +\|\+(.+)/, 1] raise "The last diff in the difflog didn't have a red and a green." if linea.nil? || lineb.nil? linea_length, lineb_length = linea.length, lineb.length from_start = 0 while from_start < linea_length break if linea[from_start] != lineb[from_start] from_start += 1 end from_end = 1 while from_end < linea_length break if from_end > linea_length || from_end > lineb_length || linea[linea_length-from_end] != lineb[lineb_length-from_end] from_end += 1 end deltaa = from_end > linea_length ? "" : linea[from_start..(linea_length-from_end)] delteab = from_end > lineb_length ? "" : lineb[from_start..(lineb_length-from_end)] [deltaa, delteab] end |
.menu ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/xiki/diff_log.rb', line 9 def self. " .open/ .diffs/ .diffs/$p/ docs/ > Summary | The difflog tracks diffs of all the changes you make to file | (assuming you save using as+file). | > Keys | open+diffs - open the difflog | search+diffs - search the difflog from the bottom " end |
.open ⇒ Object
Open file having difflog
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/xiki/diff_log.rb', line 26 def self.open View. if View. # If open, just switch to it and revert if View.buffer_open?("difflog.notes") View.to_buffer("difflog.notes") $el.revert_buffer true, true, true else # Otherwise, open it View.open(@@log) end View.to_bottom Line.previous Line.to_words $el.recenter -4 end |
.parse_tree_diffs(txt) ⇒ Object
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/xiki/diff_log.rb', line 210 def self.parse_tree_diffs txt result = [[], []] txt = txt.split("\n") i, length = 0, txt.length while i < length line = txt[i] # a_or_d = line[/^[ad]/] match = line.match(/^(.)(\d+) (\d+)/) raise "Line #{line} unexpected by DiffLog.parse_tree_diffs" if ! match a_or_d, line_number, many = match[1..3] line_number, many = line_number.to_i, many.to_i if a_or_d == "d" i += 1 many.times do |n| result[1] << line_number + n end next end if a_or_d == "a" i += 1 many.times do |n| result[0] << line_number + n end next end raise "DiffLog.parse_tree_diffs doesn't know what to do with #{line}" end result end |
.save ⇒ Object
Appends diff to difflog, then saves. Mapped to as_file.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/xiki/diff_log.rb', line 116 def self.save return if View.file_name == "difflog.notes" prefix = Keys.prefix :clear=>1 self.save_diffs $el.save_buffer if prefix == :u sleep(0.3) Firefox.reload elsif prefix == 9 Launcher.do_last_launch end end |
.save_diffs(options = {}) ⇒ Object
Util function used by public functions
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/xiki/diff_log.rb', line 192 def self.save_diffs ={} if [:patha] && [:textb] patha = [:patha] File.open(@@temp_path, "w") { |f| f << [:textb] } else patha = View.file $el.write_region nil, nil, @@temp_path end diff = Console.sync "diff -U 0 \"#{patha}\" \"#{@@temp_path}\"" return if diff.empty? || diff =~ /: No such file or directory\n/ # Fail quietly if file didn't exist diff = self.format(diff) rescue nil return diff if diff.nil? || [:dont_log] File.open(@@log, "a") { |f| f << diff } unless diff.count("\n") <= 2 end |