From 4007fb49c95db0c85c62a5ef7b7e8f04af60e8dc Mon Sep 17 00:00:00 2001 From: jorgemanzo Date: Wed, 24 Jun 2020 20:41:38 -0700 Subject: [PATCH 01/27] experimenting with diff line numbers --- src/Widgets/GitDiffGutter.vala | 48 ++++++++++++++++++++++++++++++++++ src/Widgets/SourceView.vala | 4 +++ src/meson.build | 1 + 3 files changed, 53 insertions(+) create mode 100644 src/Widgets/GitDiffGutter.vala diff --git a/src/Widgets/GitDiffGutter.vala b/src/Widgets/GitDiffGutter.vala new file mode 100644 index 0000000000..1ff7db18c4 --- /dev/null +++ b/src/Widgets/GitDiffGutter.vala @@ -0,0 +1,48 @@ +namespace Scratch.Widgets { + public class GitDiffGutter : Gtk.SourceGutter { + + private GLib.File repo_path; + private Ggit.Repository? git_repo = null; + private Ggit.Diff workdir_diff_List; + + public GitDiffGutter () { + stdout.printf("MAKING NEW DIFF GUTTER\n"); + try { + repo_path = GLib.File.new_for_path ("/home/puffin/code/code"); + git_repo = Ggit.Repository.open (repo_path); + workdir_diff_List = new Ggit.Diff.index_to_workdir (git_repo, null, null); + } catch (GLib.Error e) { + stdout.printf("Error trying to open repo: %s\n", e.message); + } + } + + private int diff_file_callback (Ggit.DiffDelta delta, float progress) { + return 0; + } + + private int diff_binary_callback (Ggit.DiffDelta delta, Ggit.DiffBinary binary) { + return 0; + } + + private int diff_hunk_callback (Ggit.DiffDelta delta, Ggit.DiffHunk hunk) { + return 0; + } + + private int diff_line_callback (Ggit.DiffDelta delta, Ggit.DiffHunk? hunk, Ggit.DiffLine line) { + Ggit.DiffFile? file_diff = delta.get_old_file (); + Ggit.DiffLineType type_of_change = line.get_origin(); + string path = file_diff.get_path (); + stdout.printf("In file: %s\n", path); + if (type_of_change == Ggit.DiffLineType.ADDITION) { + stdout.printf("Line -> %d added\n", line.get_new_lineno ()); + } + return 0; + } + + public void make_diff () { + stdout.printf("MAKE_DIFF()\n"); + workdir_diff_List.foreach (diff_file_callback, diff_binary_callback, diff_hunk_callback, diff_line_callback); + } + + } +} \ No newline at end of file diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index 9d6544db4e..e6f96fa167 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -32,6 +32,7 @@ namespace Scratch.Widgets { private uint size_allocate_timer = 0; private Gtk.TextIter last_select_start_iter; private Gtk.TextIter last_select_end_iter; + private GitDiffGutter git_diff_gutter; private const uint THROTTLE_MS = 400; @@ -158,6 +159,9 @@ namespace Scratch.Widgets { }); } }); + + git_diff_gutter = new GitDiffGutter(); + git_diff_gutter.make_diff(); } private bool get_current_line (out Gtk.TextIter start, out Gtk.TextIter end) { diff --git a/src/meson.build b/src/meson.build index cefe9dd084..a21b9f0ed2 100644 --- a/src/meson.build +++ b/src/meson.build @@ -33,6 +33,7 @@ code_files = files( 'Services/ZeitgeistLogger.vala', 'Widgets/DocumentView.vala', 'Widgets/FormatBar.vala', + 'Widgets/GitDiffGutter.vala', 'Widgets/HeaderBar.vala', 'Widgets/Pane.vala', 'Widgets/PaneSwitcher.vala', From a6e68a903e1563ce3cb9db91aba6a0bc8415f3c6 Mon Sep 17 00:00:00 2001 From: jorgemanzo Date: Fri, 26 Jun 2020 09:38:14 -0700 Subject: [PATCH 02/27] Saving progress sgr --- src/Widgets/GitDiffGutter.vala | 68 +++++++++++++++++++++++++++++----- src/Widgets/SourceView.vala | 9 ++++- 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/Widgets/GitDiffGutter.vala b/src/Widgets/GitDiffGutter.vala index 1ff7db18c4..e397e49af4 100644 --- a/src/Widgets/GitDiffGutter.vala +++ b/src/Widgets/GitDiffGutter.vala @@ -1,10 +1,13 @@ namespace Scratch.Widgets { - public class GitDiffGutter : Gtk.SourceGutter { - + public class GitDiffGutter : Gtk.SourceGutterRenderer { private GLib.File repo_path; private Ggit.Repository? git_repo = null; private Ggit.Diff workdir_diff_List; - + private Gee.HashSet lines_with_additions; + private Gee.HashSet lines_with_deletions; + private Gdk.RGBA gutter_color; + private string open_file_path = "src/Widgets/GitDiffGutter.vala"; + public GitDiffGutter () { stdout.printf("MAKING NEW DIFF GUTTER\n"); try { @@ -14,6 +17,27 @@ namespace Scratch.Widgets { } catch (GLib.Error e) { stdout.printf("Error trying to open repo: %s\n", e.message); } + lines_with_additions = new Gee.HashSet (); + lines_with_deletions = new Gee.HashSet (); + gutter_color = Gdk.RGBA (); + this.set_size(10); + this.set_visible (true); + } + + public override void draw (Cairo.Context cr, Gdk.Rectangle bg, Gdk.Rectangle area, Gtk.TextIter start, Gtk.TextIter end, Gtk.SourceGutterRendererState state) { + base.draw (cr, bg, area, start, end, state); + int gutter_line_no = start.get_line () + 2; + if (lines_with_additions.contains (gutter_line_no)) { + gutter_color.parse ("rgba(0,256,0,1)"); + this.set_background (gutter_color); + } + else if (lines_with_deletions.contains (gutter_line_no)) { + gutter_color.parse ("rgba(256,0,0,1)"); + this.set_background (gutter_color); + } else { + gutter_color.parse ("rgba(0,0,0,0)"); + this.set_background (gutter_color); + } } private int diff_file_callback (Ggit.DiffDelta delta, float progress) { @@ -30,19 +54,45 @@ namespace Scratch.Widgets { private int diff_line_callback (Ggit.DiffDelta delta, Ggit.DiffHunk? hunk, Ggit.DiffLine line) { Ggit.DiffFile? file_diff = delta.get_old_file (); - Ggit.DiffLineType type_of_change = line.get_origin(); - string path = file_diff.get_path (); - stdout.printf("In file: %s\n", path); - if (type_of_change == Ggit.DiffLineType.ADDITION) { - stdout.printf("Line -> %d added\n", line.get_new_lineno ()); + Ggit.DiffLineType type_of_change = delta.get_status (); + string diff_file_path = file_diff.get_path (); + int new_diff_line_no = line.get_new_lineno (); + int old_diff_line_no = line.get_old_lineno (); + stdout.printf ("path: %s\n", diff_file_path); + + if(type_of_change == Ggit.DiffLineType.ADDITION) { + stdout.printf("ADDED: %d or %d\n", new_diff_line_no, old_diff_line_no); + } else if(type_of_change == Ggit.DeltaType.DELETION) { + stdout.printf("DELETED: %d or %d\n", new_diff_line_no, old_diff_line_no); + } else if(type_of_change == Ggit.DeltaType.MODIFIED) { + stdout.printf("MODIFIED: %d or %d\n", new_diff_line_no, old_diff_line_no); + } + + if (diff_file_path == open_file_path && type_of_change == Ggit.DeltaType.ADDED) { + lines_with_additions.add (new_diff_line_no); + } else if (diff_file_path == open_file_path && type_of_change == Ggit.DeltaType.DELETED) { + lines_with_deletions.add (old_diff_line_no); } return 0; } + public void print_lines_with_additions () { + foreach (int line_no in lines_with_additions) { + stdout.printf ("%d\n", line_no); + } + } + + public void print_lines_with_deletions () { + foreach (int line_no in lines_with_deletions) { + stdout.printf ("%d\n", line_no); + } + } + + public void make_diff () { stdout.printf("MAKE_DIFF()\n"); workdir_diff_List.foreach (diff_file_callback, diff_binary_callback, diff_hunk_callback, diff_line_callback); } } -} \ No newline at end of file +} diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index e6f96fa167..078d1a8d9b 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -33,6 +33,9 @@ namespace Scratch.Widgets { private Gtk.TextIter last_select_start_iter; private Gtk.TextIter last_select_end_iter; private GitDiffGutter git_diff_gutter; + // Hello hello + // Hi + // hi private const uint THROTTLE_MS = 400; @@ -157,11 +160,15 @@ namespace Scratch.Widgets { bottom_margin = calculate_bottom_margin (allocation.height); return GLib.Source.REMOVE; }); + } }); - git_diff_gutter = new GitDiffGutter(); + git_diff_gutter = new GitDiffGutter();// git_diff_gutter.make_diff(); + // git_diff_gutter.print_lines_with_deletions(); + // Gtk.SourceGutter source_gutter = this.get_gutter(Gtk.TextWindowType.LEFT); + // source_gutter.insert(git_diff_gutter, 1); } private bool get_current_line (out Gtk.TextIter start, out Gtk.TextIter end) { From d873d296fc5786aa53186a2a1e1d0106c7dfdf7b Mon Sep 17 00:00:00 2001 From: jorgemanzo Date: Fri, 26 Jun 2020 19:23:06 -0700 Subject: [PATCH 03/27] Gutter is colored more or less well enough --- src/Widgets/GitDiffGutter.vala | 221 ++++++++++++++++++++++++++++----- src/Widgets/SourceView.vala | 6 +- 2 files changed, 190 insertions(+), 37 deletions(-) diff --git a/src/Widgets/GitDiffGutter.vala b/src/Widgets/GitDiffGutter.vala index e397e49af4..59c352a318 100644 --- a/src/Widgets/GitDiffGutter.vala +++ b/src/Widgets/GitDiffGutter.vala @@ -3,43 +3,48 @@ namespace Scratch.Widgets { private GLib.File repo_path; private Ggit.Repository? git_repo = null; private Ggit.Diff workdir_diff_List; - private Gee.HashSet lines_with_additions; - private Gee.HashSet lines_with_deletions; + private Ggit.DiffLine previous_line_diff = null; + private Gee.HashMap lines_to_status; private Gdk.RGBA gutter_color; private string open_file_path = "src/Widgets/GitDiffGutter.vala"; + private const string ADDED = "GREEN"; + private const string MODIFIED = "BLUE"; + private const string DELETED = "RED"; public GitDiffGutter () { stdout.printf("MAKING NEW DIFF GUTTER\n"); try { repo_path = GLib.File.new_for_path ("/home/puffin/code/code"); - git_repo = Ggit.Repository.open (repo_path); + git_repo = Ggit.Repository.open (repo_path);// workdir_diff_List = new Ggit.Diff.index_to_workdir (git_repo, null, null); } catch (GLib.Error e) { stdout.printf("Error trying to open repo: %s\n", e.message); } - lines_with_additions = new Gee.HashSet (); - lines_with_deletions = new Gee.HashSet (); + lines_to_status = new Gee.HashMap (); gutter_color = Gdk.RGBA (); this.set_size(10); this.set_visible (true); } + public override void draw (Cairo.Context cr, Gdk.Rectangle bg, Gdk.Rectangle area, Gtk.TextIter start, Gtk.TextIter end, Gtk.SourceGutterRendererState state) { base.draw (cr, bg, area, start, end, state); int gutter_line_no = start.get_line () + 2; - if (lines_with_additions.contains (gutter_line_no)) { - gutter_color.parse ("rgba(0,256,0,1)"); - this.set_background (gutter_color); - } - else if (lines_with_deletions.contains (gutter_line_no)) { - gutter_color.parse ("rgba(256,0,0,1)"); + if (lines_to_status.contains (gutter_line_no)) { + string change = lines_to_status.get (gutter_line_no); + if (change == ADDED) { + gutter_color.parse ("rgba(0,0,256,1)"); + } else if (change == MODIFIED) { + gutter_color.parse ("rgba(0,256,0,1)"); + } else if (change == DELETED) { + gutter_color.parse ("rgba(256,0,0,1)"); + } this.set_background (gutter_color); } else { gutter_color.parse ("rgba(0,0,0,0)"); this.set_background (gutter_color); } } - private int diff_file_callback (Ggit.DiffDelta delta, float progress) { return 0; } @@ -52,39 +57,187 @@ namespace Scratch.Widgets { return 0; } + private bool is_modified (Ggit.DiffLine line) { + bool is_modified_diff = false; + if (previous_line_diff != null) { + // current diff + Ggit.DiffLineType type_of_change = line.get_origin (); + bool is_added_line = type_of_change == Ggit.DiffLineType.ADDITION ? true : false; + bool is_deleted_line = type_of_change == Ggit.DiffLineType.DELETION ? true : false; + + // Compare to previous diff + Ggit.DiffLineType prev_type_of_change = previous_line_diff.get_origin (); + bool prev_is_added_line = prev_type_of_change == Ggit.DiffLineType.ADDITION ? true : false; + bool prev_is_deleted_line = prev_type_of_change == Ggit.DiffLineType.DELETION ? true : false; + + // In order to be a modified line they need to be "opposites" of each other + bool added_line_opposite = is_added_line != prev_is_added_line; + bool deleted_line_opposite = is_deleted_line != prev_is_deleted_line; + + is_modified_diff = added_line_opposite && deleted_line_opposite ? true : false; + } + return is_modified_diff; + } + + private bool is_added (Ggit.DiffLine line) { + Ggit.DiffLineType type_of_change = line.get_origin (); + return type_of_change == Ggit.DiffLineType.ADDITION ? true : false; + } + + private bool is_deleted (Ggit.DiffLine line) { + bool is_deleted = false; + if (previous_line_diff != null) { + // current diff + Ggit.DiffLineType type_of_change = line.get_origin (); + bool is_added_line = type_of_change == Ggit.DiffLineType.ADDITION ? true : false; + bool is_deleted_line = type_of_change == Ggit.DiffLineType.DELETION ? true : false; + + // Compare to previous diff + Ggit.DiffLineType prev_type_of_change = previous_line_diff.get_origin (); + bool prev_is_added_line = prev_type_of_change == Ggit.DiffLineType.ADDITION ? true : false; + bool prev_is_deleted_line = prev_type_of_change == Ggit.DiffLineType.DELETION ? true : false; + + // We will color the current line red if the previous line looked like a deleted diff-line. + bool added_line_equal = is_added_line == prev_is_added_line; + bool deleted_line_opposite = is_deleted_line != prev_is_deleted_line; + + is_deleted = added_line_equal && deleted_line_opposite; + } + return is_deleted; + } + private int diff_line_callback (Ggit.DiffDelta delta, Ggit.DiffHunk? hunk, Ggit.DiffLine line) { Ggit.DiffFile? file_diff = delta.get_old_file (); - Ggit.DiffLineType type_of_change = delta.get_status (); + Ggit.DiffLineType type_of_change = line.get_origin (); + string diff_file_path = file_diff.get_path (); int new_diff_line_no = line.get_new_lineno (); int old_diff_line_no = line.get_old_lineno (); - stdout.printf ("path: %s\n", diff_file_path); - - if(type_of_change == Ggit.DiffLineType.ADDITION) { - stdout.printf("ADDED: %d or %d\n", new_diff_line_no, old_diff_line_no); - } else if(type_of_change == Ggit.DeltaType.DELETION) { - stdout.printf("DELETED: %d or %d\n", new_diff_line_no, old_diff_line_no); - } else if(type_of_change == Ggit.DeltaType.MODIFIED) { - stdout.printf("MODIFIED: %d or %d\n", new_diff_line_no, old_diff_line_no); - } + bool is_added_line = type_of_change == Ggit.DiffLineType.ADDITION ? true : false; + bool is_deleted_line = type_of_change == Ggit.DiffLineType.DELETION ? true : false; + string str_is_added_line = type_of_change == Ggit.DiffLineType.ADDITION ? "Yes" : "No"; + string str_is_deleted_line = type_of_change == Ggit.DiffLineType.DELETION ? "Yes" : "No"; - if (diff_file_path == open_file_path && type_of_change == Ggit.DeltaType.ADDED) { - lines_with_additions.add (new_diff_line_no); - } else if (diff_file_path == open_file_path && type_of_change == Ggit.DeltaType.DELETED) { - lines_with_deletions.add (old_diff_line_no); + + if (is_modified (line)) { + lines_to_status.set (line.get_new_lineno (), MODIFIED); + } else if (is_added (line)) { + lines_to_status.set (line.get_new_lineno (), ADDED); + } else if (is_deleted (line)) { + lines_to_status.set (line.get_new_lineno (), DELETED); } + previous_line_diff = line; return 0; - } + /* Modified an existing line + is_added_line: No + is_deleted_line: No + new_diff_line_no: 18 + old_diff_line_no: 14 - public void print_lines_with_additions () { - foreach (int line_no in lines_with_additions) { - stdout.printf ("%d\n", line_no); - } + // Modification begins + is_added_line: No + is_deleted_line: Yes + new_diff_line_no: -1 + old_diff_line_no: 15 + + is_added_line: Yes + is_deleted_line: No + new_diff_line_no: 19 + old_diff_line_no: -1 + // Ends + + is_added_line: No + is_deleted_line: No + new_diff_line_no: 20 + old_diff_line_no: 16 + */ + + /* Added a completely new line + // All of these are seperate additions + is_added_line: Yes + is_deleted_line: No + new_diff_line_no: 11 + old_diff_line_no: -1 + + is_added_line: Yes + is_deleted_line: No + new_diff_line_no: 12 + old_diff_line_no: -1 + + is_added_line: Yes + is_deleted_line: No + new_diff_line_no: 13 + old_diff_line_no: -1 + */ + + /* Deleted a line + is_added_line: No + is_deleted_line: No + new_diff_line_no: 47 + old_diff_line_no: 40 + + is_added_line: No + is_deleted_line: No + new_diff_line_no: 48 + old_diff_line_no: 41 + + // Deleted line + is_added_line: No + is_deleted_line: Yes + new_diff_line_no: -1 + old_diff_line_no: 42 + + is_added_line: No + is_deleted_line: No + new_diff_line_no: 49 + old_diff_line_no: 43 + */ + + /* Untouched lines + is_added_line: No + is_deleted_line: No + new_diff_line_no: 5 + old_diff_line_no: 5 + + or + + + is_added_line: No + is_deleted_line: No + new_diff_line_no: 15 + old_diff_line_no: 11 + */ + + // if (lines_to_status.has_key (line_no)) { + // // Seen line before? Line must be modified instead + // lines_to_status.set (line_no, MODIFIED); + // } else { + // // First time seeing a line, record its status + // if (is_added_line) { + // lines_to_status.set (line_no, ADDED); + // } else if (is_deleted_line) { + // lines_to_status.set (line_no, DELETED); + // } + // } + + // if (diff_file_path == open_file_path) { + // stdout.printf("is_added_line: %s\n", str_is_added_line); + // stdout.printf("is_deleted_line: %s\n", str_is_deleted_line); + // stdout.printf("new_diff_line_no: %d\n", new_diff_line_no); + // stdout.printf("old_diff_line_no: %d\n\n", old_diff_line_no); + // } + + // if (diff_file_path == open_file_path && type_of_change == Ggit.DiffLineType.ADDITION) { + // lines_with_additions.add (new_diff_line_no); + // } else if (diff_file_path == open_file_path && type_of_change == Ggit.DiffLineType.DELETION) { + // lines_with_deletions.add (old_diff_line_no); + // } + // return 0; } - public void print_lines_with_deletions () { - foreach (int line_no in lines_with_deletions) { - stdout.printf ("%d\n", line_no); + public void print_lines_status () { + foreach (var line in lines_to_status.entries) { + stdout.printf ("%d => %s\n", line.key, line.value); } } diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index 078d1a8d9b..ddef116f17 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -166,9 +166,9 @@ namespace Scratch.Widgets { git_diff_gutter = new GitDiffGutter();// git_diff_gutter.make_diff(); - // git_diff_gutter.print_lines_with_deletions(); - // Gtk.SourceGutter source_gutter = this.get_gutter(Gtk.TextWindowType.LEFT); - // source_gutter.insert(git_diff_gutter, 1); + git_diff_gutter.print_lines_status(); + Gtk.SourceGutter source_gutter = this.get_gutter(Gtk.TextWindowType.LEFT); + source_gutter.insert(git_diff_gutter, 1); } private bool get_current_line (out Gtk.TextIter start, out Gtk.TextIter end) { From 59e6c8dda526d1a47eb0eab766b4f42a937b2de1 Mon Sep 17 00:00:00 2001 From: jorgemanzo Date: Fri, 26 Jun 2020 19:32:46 -0700 Subject: [PATCH 04/27] Fixed bug in colors --- src/Widgets/GitDiffGutter.vala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Widgets/GitDiffGutter.vala b/src/Widgets/GitDiffGutter.vala index 59c352a318..7730b44cbe 100644 --- a/src/Widgets/GitDiffGutter.vala +++ b/src/Widgets/GitDiffGutter.vala @@ -9,7 +9,7 @@ namespace Scratch.Widgets { private string open_file_path = "src/Widgets/GitDiffGutter.vala"; private const string ADDED = "GREEN"; private const string MODIFIED = "BLUE"; - private const string DELETED = "RED"; + private const string DELETED = "RED";// public GitDiffGutter () { stdout.printf("MAKING NEW DIFF GUTTER\n"); @@ -22,20 +22,21 @@ namespace Scratch.Widgets { } lines_to_status = new Gee.HashMap (); gutter_color = Gdk.RGBA (); - this.set_size(10); + this.set_size(3); this.set_visible (true); } + public override void draw (Cairo.Context cr, Gdk.Rectangle bg, Gdk.Rectangle area, Gtk.TextIter start, Gtk.TextIter end, Gtk.SourceGutterRendererState state) { base.draw (cr, bg, area, start, end, state); int gutter_line_no = start.get_line () + 2; if (lines_to_status.contains (gutter_line_no)) { string change = lines_to_status.get (gutter_line_no); if (change == ADDED) { - gutter_color.parse ("rgba(0,0,256,1)"); - } else if (change == MODIFIED) { gutter_color.parse ("rgba(0,256,0,1)"); + } else if (change == MODIFIED) { + gutter_color.parse ("rgba(0,0,256,1)"); } else if (change == DELETED) { gutter_color.parse ("rgba(256,0,0,1)"); } @@ -48,7 +49,6 @@ namespace Scratch.Widgets { private int diff_file_callback (Ggit.DiffDelta delta, float progress) { return 0; } - private int diff_binary_callback (Ggit.DiffDelta delta, Ggit.DiffBinary binary) { return 0; } From 1ad3695a989ce1684d8abc79538aba063fe47892 Mon Sep 17 00:00:00 2001 From: jorgemanzo Date: Fri, 26 Jun 2020 21:06:54 -0700 Subject: [PATCH 05/27] Reload when switching between different files --- src/Services/Document.vala | 6 ++++++ src/Widgets/DocumentView.vala | 1 + src/Widgets/GitDiffGutter.vala | 23 +++++++++++++++-------- src/Widgets/SourceView.vala | 16 ++++++++-------- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/Services/Document.vala b/src/Services/Document.vala index 26c1ef18e7..951c8eb5f0 100644 --- a/src/Services/Document.vala +++ b/src/Services/Document.vala @@ -576,8 +576,14 @@ namespace Scratch.Services { } } + // When switching between tabs, refresh the source view gutter + public void refresh_sourceview_gutter () { + this.source_view.refresh_gutter (this.file.get_path ()); + } + // Focus the SourceView public new void focus () { + this.source_view.refresh_gutter (this.file.get_path ()); this.source_view.grab_focus (); } diff --git a/src/Widgets/DocumentView.vala b/src/Widgets/DocumentView.vala index 4a4324aa6d..0a96d2bce8 100644 --- a/src/Widgets/DocumentView.vala +++ b/src/Widgets/DocumentView.vala @@ -181,6 +181,7 @@ public class Scratch.Widgets.DocumentView : Granite.Widgets.DynamicNotebook { if (nth_doc.file != null && nth_doc.file.get_uri () == doc.file.get_uri ()) { current_document = nth_doc; + current_document.refresh_sourceview_gutter(); warning ("This Document was already opened! Not opening a duplicate!"); return; } diff --git a/src/Widgets/GitDiffGutter.vala b/src/Widgets/GitDiffGutter.vala index 7730b44cbe..7124beae4d 100644 --- a/src/Widgets/GitDiffGutter.vala +++ b/src/Widgets/GitDiffGutter.vala @@ -6,15 +6,17 @@ namespace Scratch.Widgets { private Ggit.DiffLine previous_line_diff = null; private Gee.HashMap lines_to_status; private Gdk.RGBA gutter_color; - private string open_file_path = "src/Widgets/GitDiffGutter.vala"; + private string open_file_path = null; + private string repo_path_location = null; private const string ADDED = "GREEN"; private const string MODIFIED = "BLUE"; private const string DELETED = "RED";// - public GitDiffGutter () { + public GitDiffGutter (string repo_path_location) { stdout.printf("MAKING NEW DIFF GUTTER\n"); + this.repo_path_location = repo_path_location; try { - repo_path = GLib.File.new_for_path ("/home/puffin/code/code"); + repo_path = GLib.File.new_for_path (repo_path_location); git_repo = Ggit.Repository.open (repo_path);// workdir_diff_List = new Ggit.Diff.index_to_workdir (git_repo, null, null); } catch (GLib.Error e) { @@ -108,9 +110,15 @@ namespace Scratch.Widgets { private int diff_line_callback (Ggit.DiffDelta delta, Ggit.DiffHunk? hunk, Ggit.DiffLine line) { Ggit.DiffFile? file_diff = delta.get_old_file (); + string diff_file_path = file_diff.get_path (); + + // Only process the diff if its for the file in focus. + if (!(diff_file_path in open_file_path)) { + return 0; + } + Ggit.DiffLineType type_of_change = line.get_origin (); - string diff_file_path = file_diff.get_path (); int new_diff_line_no = line.get_new_lineno (); int old_diff_line_no = line.get_old_lineno (); bool is_added_line = type_of_change == Ggit.DiffLineType.ADDITION ? true : false; @@ -241,11 +249,10 @@ namespace Scratch.Widgets { } } - - public void make_diff () { - stdout.printf("MAKE_DIFF()\n"); + public void reload (string basename) { + stdout.printf("Reloading with: %s\n", basename); + open_file_path = basename; workdir_diff_List.foreach (diff_file_callback, diff_binary_callback, diff_hunk_callback, diff_line_callback); } - } } diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index ddef116f17..c3a05265cf 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -13,10 +13,10 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * -* You should have received a copy of the GNU General Public +* You should have received a copy of the GNU General Public// * License along with this program; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -* Boston, MA 02110-1301 USA +* Boston, MA 02110-1301 USA /// */ namespace Scratch.Widgets { @@ -33,9 +33,6 @@ namespace Scratch.Widgets { private Gtk.TextIter last_select_start_iter; private Gtk.TextIter last_select_end_iter; private GitDiffGutter git_diff_gutter; - // Hello hello - // Hi - // hi private const uint THROTTLE_MS = 400; @@ -164,9 +161,8 @@ namespace Scratch.Widgets { } }); - git_diff_gutter = new GitDiffGutter();// - git_diff_gutter.make_diff(); - git_diff_gutter.print_lines_status(); + // Make the gutter renderer and insert into the left side of the source view. + git_diff_gutter = new GitDiffGutter("home/puffin/code/code"); Gtk.SourceGutter source_gutter = this.get_gutter(Gtk.TextWindowType.LEFT); source_gutter.insert(git_diff_gutter, 1); } @@ -492,5 +488,9 @@ namespace Scratch.Widgets { selection_changed_timer = 0; return false; } + + public void refresh_gutter (string basename) { + git_diff_gutter.reload (basename); + } } } From 17fd5581c50dc2679f855b20c3a2c8a5f77ba32f Mon Sep 17 00:00:00 2001 From: jorgemanzo Date: Fri, 26 Jun 2020 21:23:09 -0700 Subject: [PATCH 06/27] Some cleanup of class properties --- src/Widgets/GitDiffGutter.vala | 68 ++++++++++++++-------------------- src/Widgets/SourceView.vala | 6 +-- 2 files changed, 31 insertions(+), 43 deletions(-) diff --git a/src/Widgets/GitDiffGutter.vala b/src/Widgets/GitDiffGutter.vala index 7124beae4d..ee1e560084 100644 --- a/src/Widgets/GitDiffGutter.vala +++ b/src/Widgets/GitDiffGutter.vala @@ -1,38 +1,47 @@ namespace Scratch.Widgets { public class GitDiffGutter : Gtk.SourceGutterRenderer { - private GLib.File repo_path; - private Ggit.Repository? git_repo = null; - private Ggit.Diff workdir_diff_List; + private Ggit.Diff repo_diff_list; + // Use the previously seen diff to compare with the current diff to determine the "type" of diff private Ggit.DiffLine previous_line_diff = null; + + // This keeps track of what lines had which kind of modification + // (either new additions, modifying an existing line, or deleting lines) private Gee.HashMap lines_to_status; + + // Use this to represent the color of a cell in the gutter before it is drawn private Gdk.RGBA gutter_color; + private string open_file_path = null; - private string repo_path_location = null; + private string repo_path = null; + + // Use these to note what lines were modified, which lines are newly added, which lines were removed. private const string ADDED = "GREEN"; private const string MODIFIED = "BLUE"; private const string DELETED = "RED";// - public GitDiffGutter (string repo_path_location) { + public GitDiffGutter (string repo_path) { stdout.printf("MAKING NEW DIFF GUTTER\n"); - this.repo_path_location = repo_path_location; + this.repo_path = repo_path; try { - repo_path = GLib.File.new_for_path (repo_path_location); - git_repo = Ggit.Repository.open (repo_path);// - workdir_diff_List = new Ggit.Diff.index_to_workdir (git_repo, null, null); + GLib.File repo_file_location = GLib.File.new_for_path (repo_path); + Ggit.Repository? git_repo = Ggit.Repository.open (repo_file_location);// + repo_diff_list = new Ggit.Diff.index_to_workdir (git_repo, null, null); } catch (GLib.Error e) { stdout.printf("Error trying to open repo: %s\n", e.message); } lines_to_status = new Gee.HashMap (); gutter_color = Gdk.RGBA (); - this.set_size(3); + this.set_size (3); this.set_visible (true); } - + // Here we take advantage of the method that draws each cell in the gutter + // to determine if said line has been modified in some way. If it has, + // we set the cell's color appropriately. public override void draw (Cairo.Context cr, Gdk.Rectangle bg, Gdk.Rectangle area, Gtk.TextIter start, Gtk.TextIter end, Gtk.SourceGutterRendererState state) { base.draw (cr, bg, area, start, end, state); - int gutter_line_no = start.get_line () + 2; + int gutter_line_no = start.get_line () + 2; // For some reason, all the diffs are off by two lines...? if (lines_to_status.contains (gutter_line_no)) { string change = lines_to_status.get (gutter_line_no); if (change == ADDED) { @@ -108,6 +117,10 @@ namespace Scratch.Widgets { return is_deleted; } + // We look through every diff line of the repo (unfortunately...) and determine if + // the diff is for the file that is in focus. Then we determine the kind of modification, + // and save it with the line number. That way we have line numbers mapped to modifications + // when it comes time to draw the gutter's cells. private int diff_line_callback (Ggit.DiffDelta delta, Ggit.DiffHunk? hunk, Ggit.DiffLine line) { Ggit.DiffFile? file_diff = delta.get_old_file (); string diff_file_path = file_diff.get_path (); @@ -136,7 +149,8 @@ namespace Scratch.Widgets { } previous_line_diff = line; return 0; - /* Modified an existing line + /* Notes for myself on how the DiffLine objects work. + Modified an existing line is_added_line: No is_deleted_line: No new_diff_line_no: 18 @@ -215,32 +229,6 @@ namespace Scratch.Widgets { new_diff_line_no: 15 old_diff_line_no: 11 */ - - // if (lines_to_status.has_key (line_no)) { - // // Seen line before? Line must be modified instead - // lines_to_status.set (line_no, MODIFIED); - // } else { - // // First time seeing a line, record its status - // if (is_added_line) { - // lines_to_status.set (line_no, ADDED); - // } else if (is_deleted_line) { - // lines_to_status.set (line_no, DELETED); - // } - // } - - // if (diff_file_path == open_file_path) { - // stdout.printf("is_added_line: %s\n", str_is_added_line); - // stdout.printf("is_deleted_line: %s\n", str_is_deleted_line); - // stdout.printf("new_diff_line_no: %d\n", new_diff_line_no); - // stdout.printf("old_diff_line_no: %d\n\n", old_diff_line_no); - // } - - // if (diff_file_path == open_file_path && type_of_change == Ggit.DiffLineType.ADDITION) { - // lines_with_additions.add (new_diff_line_no); - // } else if (diff_file_path == open_file_path && type_of_change == Ggit.DiffLineType.DELETION) { - // lines_with_deletions.add (old_diff_line_no); - // } - // return 0; } public void print_lines_status () { @@ -252,7 +240,7 @@ namespace Scratch.Widgets { public void reload (string basename) { stdout.printf("Reloading with: %s\n", basename); open_file_path = basename; - workdir_diff_List.foreach (diff_file_callback, diff_binary_callback, diff_hunk_callback, diff_line_callback); + repo_diff_list.foreach (diff_file_callback, diff_binary_callback, diff_hunk_callback, diff_line_callback); } } } diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index c3a05265cf..2e0478749b 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -13,10 +13,10 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * -* You should have received a copy of the GNU General Public// +* You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -* Boston, MA 02110-1301 USA /// +* Boston, MA 02110-1301 USA */ namespace Scratch.Widgets { @@ -157,7 +157,7 @@ namespace Scratch.Widgets { bottom_margin = calculate_bottom_margin (allocation.height); return GLib.Source.REMOVE; }); - + } }); From 6f6e535f011d9ae7731f32c01f1428e750d07207 Mon Sep 17 00:00:00 2001 From: jorgemanzo Date: Sat, 27 Jun 2020 00:00:27 -0700 Subject: [PATCH 07/27] Cleanup + color improvements --- src/Widgets/GitDiffGutter.vala | 12 +++++------- src/Widgets/SourceView.vala | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Widgets/GitDiffGutter.vala b/src/Widgets/GitDiffGutter.vala index ee1e560084..4eb6956660 100644 --- a/src/Widgets/GitDiffGutter.vala +++ b/src/Widgets/GitDiffGutter.vala @@ -12,18 +12,16 @@ namespace Scratch.Widgets { private Gdk.RGBA gutter_color; private string open_file_path = null; - private string repo_path = null; // Use these to note what lines were modified, which lines are newly added, which lines were removed. private const string ADDED = "GREEN"; private const string MODIFIED = "BLUE"; private const string DELETED = "RED";// - public GitDiffGutter (string repo_path) { + public GitDiffGutter (string path_to_git_folder) { stdout.printf("MAKING NEW DIFF GUTTER\n"); - this.repo_path = repo_path; try { - GLib.File repo_file_location = GLib.File.new_for_path (repo_path); + GLib.File repo_file_location = GLib.File.new_for_path (path_to_git_folder); Ggit.Repository? git_repo = Ggit.Repository.open (repo_file_location);// repo_diff_list = new Ggit.Diff.index_to_workdir (git_repo, null, null); } catch (GLib.Error e) { @@ -45,11 +43,11 @@ namespace Scratch.Widgets { if (lines_to_status.contains (gutter_line_no)) { string change = lines_to_status.get (gutter_line_no); if (change == ADDED) { - gutter_color.parse ("rgba(0,256,0,1)"); + gutter_color.parse ("#68b723"); } else if (change == MODIFIED) { - gutter_color.parse ("rgba(0,0,256,1)"); + gutter_color.parse ("#f37329"); } else if (change == DELETED) { - gutter_color.parse ("rgba(256,0,0,1)"); + gutter_color.parse ("#c6262e"); } this.set_background (gutter_color); } else { diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index 2e0478749b..1be62033af 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -162,7 +162,7 @@ namespace Scratch.Widgets { }); // Make the gutter renderer and insert into the left side of the source view. - git_diff_gutter = new GitDiffGutter("home/puffin/code/code"); + git_diff_gutter = new GitDiffGutter("/home/puffin/code/code/.git/"); Gtk.SourceGutter source_gutter = this.get_gutter(Gtk.TextWindowType.LEFT); source_gutter.insert(git_diff_gutter, 1); } From 41ecf9be53b397b529f3bee2b469c3980ad5db62 Mon Sep 17 00:00:00 2001 From: jorgemanzo Date: Sat, 27 Jun 2020 00:11:22 -0700 Subject: [PATCH 08/27] Renamed the class --- .../{GitDiffGutter.vala => SourceGutterRenderer.vala} | 4 ++-- src/Widgets/SourceView.vala | 8 ++++---- src/meson.build | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) rename src/Widgets/{GitDiffGutter.vala => SourceGutterRenderer.vala} (98%) diff --git a/src/Widgets/GitDiffGutter.vala b/src/Widgets/SourceGutterRenderer.vala similarity index 98% rename from src/Widgets/GitDiffGutter.vala rename to src/Widgets/SourceGutterRenderer.vala index 4eb6956660..45f5a62b55 100644 --- a/src/Widgets/GitDiffGutter.vala +++ b/src/Widgets/SourceGutterRenderer.vala @@ -1,5 +1,5 @@ namespace Scratch.Widgets { - public class GitDiffGutter : Gtk.SourceGutterRenderer { + public class SourceGutterRenderer : Gtk.SourceGutterRenderer { private Ggit.Diff repo_diff_list; // Use the previously seen diff to compare with the current diff to determine the "type" of diff private Ggit.DiffLine previous_line_diff = null; @@ -18,7 +18,7 @@ namespace Scratch.Widgets { private const string MODIFIED = "BLUE"; private const string DELETED = "RED";// - public GitDiffGutter (string path_to_git_folder) { + public SourceGutterRenderer (string path_to_git_folder) { stdout.printf("MAKING NEW DIFF GUTTER\n"); try { GLib.File repo_file_location = GLib.File.new_for_path (path_to_git_folder); diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index 1be62033af..23ffba666c 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -32,7 +32,7 @@ namespace Scratch.Widgets { private uint size_allocate_timer = 0; private Gtk.TextIter last_select_start_iter; private Gtk.TextIter last_select_end_iter; - private GitDiffGutter git_diff_gutter; + private SourceGutterRenderer git_diff_gutter_renderer; private const uint THROTTLE_MS = 400; @@ -162,9 +162,9 @@ namespace Scratch.Widgets { }); // Make the gutter renderer and insert into the left side of the source view. - git_diff_gutter = new GitDiffGutter("/home/puffin/code/code/.git/"); + git_diff_gutter_renderer = new SourceGutterRenderer("/home/puffin/code/code/.git/"); Gtk.SourceGutter source_gutter = this.get_gutter(Gtk.TextWindowType.LEFT); - source_gutter.insert(git_diff_gutter, 1); + source_gutter.insert(git_diff_gutter_renderer, 1); } private bool get_current_line (out Gtk.TextIter start, out Gtk.TextIter end) { @@ -490,7 +490,7 @@ namespace Scratch.Widgets { } public void refresh_gutter (string basename) { - git_diff_gutter.reload (basename); + git_diff_gutter_renderer.reload (basename); } } } diff --git a/src/meson.build b/src/meson.build index a21b9f0ed2..97371d06ec 100644 --- a/src/meson.build +++ b/src/meson.build @@ -33,7 +33,7 @@ code_files = files( 'Services/ZeitgeistLogger.vala', 'Widgets/DocumentView.vala', 'Widgets/FormatBar.vala', - 'Widgets/GitDiffGutter.vala', + 'Widgets/SourceGutterRenderer.vala', 'Widgets/HeaderBar.vala', 'Widgets/Pane.vala', 'Widgets/PaneSwitcher.vala', From e825f6cfc88e1195512de6a2475d2862ee0cebda Mon Sep 17 00:00:00 2001 From: jorgemanzo Date: Sat, 27 Jun 2020 23:36:07 -0700 Subject: [PATCH 09/27] Cleaning up the renderer --- src/Widgets/SourceGutterRenderer.vala | 96 --------------------------- 1 file changed, 96 deletions(-) diff --git a/src/Widgets/SourceGutterRenderer.vala b/src/Widgets/SourceGutterRenderer.vala index 45f5a62b55..ea6025f479 100644 --- a/src/Widgets/SourceGutterRenderer.vala +++ b/src/Widgets/SourceGutterRenderer.vala @@ -128,16 +128,6 @@ namespace Scratch.Widgets { return 0; } - Ggit.DiffLineType type_of_change = line.get_origin (); - - int new_diff_line_no = line.get_new_lineno (); - int old_diff_line_no = line.get_old_lineno (); - bool is_added_line = type_of_change == Ggit.DiffLineType.ADDITION ? true : false; - bool is_deleted_line = type_of_change == Ggit.DiffLineType.DELETION ? true : false; - string str_is_added_line = type_of_change == Ggit.DiffLineType.ADDITION ? "Yes" : "No"; - string str_is_deleted_line = type_of_change == Ggit.DiffLineType.DELETION ? "Yes" : "No"; - - if (is_modified (line)) { lines_to_status.set (line.get_new_lineno (), MODIFIED); } else if (is_added (line)) { @@ -147,92 +137,6 @@ namespace Scratch.Widgets { } previous_line_diff = line; return 0; - /* Notes for myself on how the DiffLine objects work. - Modified an existing line - is_added_line: No - is_deleted_line: No - new_diff_line_no: 18 - old_diff_line_no: 14 - - // Modification begins - is_added_line: No - is_deleted_line: Yes - new_diff_line_no: -1 - old_diff_line_no: 15 - - is_added_line: Yes - is_deleted_line: No - new_diff_line_no: 19 - old_diff_line_no: -1 - // Ends - - is_added_line: No - is_deleted_line: No - new_diff_line_no: 20 - old_diff_line_no: 16 - */ - - /* Added a completely new line - // All of these are seperate additions - is_added_line: Yes - is_deleted_line: No - new_diff_line_no: 11 - old_diff_line_no: -1 - - is_added_line: Yes - is_deleted_line: No - new_diff_line_no: 12 - old_diff_line_no: -1 - - is_added_line: Yes - is_deleted_line: No - new_diff_line_no: 13 - old_diff_line_no: -1 - */ - - /* Deleted a line - is_added_line: No - is_deleted_line: No - new_diff_line_no: 47 - old_diff_line_no: 40 - - is_added_line: No - is_deleted_line: No - new_diff_line_no: 48 - old_diff_line_no: 41 - - // Deleted line - is_added_line: No - is_deleted_line: Yes - new_diff_line_no: -1 - old_diff_line_no: 42 - - is_added_line: No - is_deleted_line: No - new_diff_line_no: 49 - old_diff_line_no: 43 - */ - - /* Untouched lines - is_added_line: No - is_deleted_line: No - new_diff_line_no: 5 - old_diff_line_no: 5 - - or - - - is_added_line: No - is_deleted_line: No - new_diff_line_no: 15 - old_diff_line_no: 11 - */ - } - - public void print_lines_status () { - foreach (var line in lines_to_status.entries) { - stdout.printf ("%d => %s\n", line.key, line.value); - } } public void reload (string basename) { From f240b5666ebbdb4409c172627306f897e491f2d7 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 10 Dec 2020 19:28:31 +0000 Subject: [PATCH 10/27] Get repo from sidebar for each document --- src/FolderManager/FileView.vala | 18 +++ src/FolderManager/ProjectFolderItem.vala | 6 +- src/MainWindow.vala | 5 + src/Services/Document.vala | 14 +- src/Widgets/DocumentView.vala | 2 +- src/Widgets/SourceGutterRenderer.vala | 164 +++++++++++++---------- src/Widgets/SourceView.vala | 23 +++- 7 files changed, 150 insertions(+), 82 deletions(-) diff --git a/src/FolderManager/FileView.vala b/src/FolderManager/FileView.vala index 2263056e5a..e2175d3d44 100644 --- a/src/FolderManager/FileView.vala +++ b/src/FolderManager/FileView.vala @@ -130,6 +130,24 @@ namespace Scratch.FolderManager { return null; } + public Ggit.Repository? get_git_repo_for_file (GLib.File file) { + var folders = root.children; + foreach (var item in root.children) { + if (!(item is ProjectFolderItem)) { + continue; + } else { + var folder = (ProjectFolderItem)item; + if (folder.git_repo != null && + folder.contains_file (file)) { + + return folder.git_repo; + } + } + } + + return null; + } + private void add_folder (File folder, bool expand) { if (is_open (folder)) { warning ("Folder '%s' is already open.", folder.path); diff --git a/src/FolderManager/ProjectFolderItem.vala b/src/FolderManager/ProjectFolderItem.vala index 3386fd4e92..b797a332ac 100644 --- a/src/FolderManager/ProjectFolderItem.vala +++ b/src/FolderManager/ProjectFolderItem.vala @@ -28,7 +28,7 @@ namespace Scratch.FolderManager { // Static source IDs for each instance of a top level folder, ensures we don't check for git updates too much private static Gee.HashMap git_update_timer_ids; private string top_level_path; - private Ggit.Repository? git_repo = null; + public Ggit.Repository? git_repo { get; construct; } private GLib.FileMonitor git_monitor; private GLib.FileMonitor gitignore_monitor; @@ -155,6 +155,10 @@ namespace Scratch.FolderManager { }); } + public bool contains_file (GLib.File descendant) { + return file.file.get_relative_path (descendant) != null; + } + private void do_git_update () { if (git_repo == null) { return; diff --git a/src/MainWindow.vala b/src/MainWindow.vala index c6f228d3a8..497d275667 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -554,6 +554,11 @@ namespace Scratch { } public void open_document (Scratch.Services.Document doc, bool focus = true) { + if (doc.source_view.git_repo_not_set ()) { + Ggit.Repository? repo = folder_manager_view.get_git_repo_for_file (doc.file); + doc.source_view.set_git_repo (repo); + } + document_view.open_document (doc, focus); } diff --git a/src/Services/Document.vala b/src/Services/Document.vala index 0cc26f90b2..98d73ad641 100644 --- a/src/Services/Document.vala +++ b/src/Services/Document.vala @@ -51,12 +51,14 @@ namespace Scratch.Services { } private Gtk.SourceFile source_file; - public File file { + public GLib.File file { get { return source_file.location; } - set { + + set construct { source_file.set_location (value); + source_view.location = value; file_changed (); label = get_basename (); } @@ -85,7 +87,7 @@ namespace Scratch.Services { } public Gtk.Stack main_stack; - public Scratch.Widgets.SourceView source_view; + public Scratch.Widgets.SourceView source_view { get; construct; } public string original_content; private string last_save_content; @@ -572,13 +574,13 @@ namespace Scratch.Services { // When switching between tabs, refresh the source view gutter public void refresh_sourceview_gutter () { - this.source_view.refresh_gutter (this.file.get_path ()); + source_view.refresh_gutter (); } // Focus the SourceView public new void focus () { - this.source_view.refresh_gutter (this.file.get_path ()); - this.source_view.grab_focus (); + source_view.refresh_gutter (); + source_view.grab_focus (); } // Get file uri diff --git a/src/Widgets/DocumentView.vala b/src/Widgets/DocumentView.vala index d81bec0128..4d0ab0bdaa 100644 --- a/src/Widgets/DocumentView.vala +++ b/src/Widgets/DocumentView.vala @@ -193,7 +193,7 @@ public class Scratch.Widgets.DocumentView : Granite.Widgets.DynamicNotebook { current_document = nth_doc; } - current_document.refresh_sourceview_gutter(); + current_document.refresh_sourceview_gutter (); debug ("This Document was already opened! Not opening a duplicate!"); return; } diff --git a/src/Widgets/SourceGutterRenderer.vala b/src/Widgets/SourceGutterRenderer.vala index ea6025f479..5587470c79 100644 --- a/src/Widgets/SourceGutterRenderer.vala +++ b/src/Widgets/SourceGutterRenderer.vala @@ -1,6 +1,6 @@ namespace Scratch.Widgets { public class SourceGutterRenderer : Gtk.SourceGutterRenderer { - private Ggit.Diff repo_diff_list; + private Ggit.Diff? repo_diff_list = null; // Use the previously seen diff to compare with the current diff to determine the "type" of diff private Ggit.DiffLine previous_line_diff = null; @@ -11,53 +11,75 @@ namespace Scratch.Widgets { // Use this to represent the color of a cell in the gutter before it is drawn private Gdk.RGBA gutter_color; - private string open_file_path = null; + private string workdir_path = null; + private string doc_path = null; // Use these to note what lines were modified, which lines are newly added, which lines were removed. private const string ADDED = "GREEN"; private const string MODIFIED = "BLUE"; private const string DELETED = "RED";// - public SourceGutterRenderer (string path_to_git_folder) { - stdout.printf("MAKING NEW DIFF GUTTER\n"); - try { - GLib.File repo_file_location = GLib.File.new_for_path (path_to_git_folder); - Ggit.Repository? git_repo = Ggit.Repository.open (repo_file_location);// - repo_diff_list = new Ggit.Diff.index_to_workdir (git_repo, null, null); - } catch (GLib.Error e) { - stdout.printf("Error trying to open repo: %s\n", e.message); - } + public bool git_repo_set { get {return workdir_path != null;}} + + public SourceGutterRenderer () { + debug ("MAKING NEW DIFF GUTTER\n"); + lines_to_status = new Gee.HashMap (); gutter_color = Gdk.RGBA (); - this.set_size (3); - this.set_visible (true); + set_size (3); + set_visible (true); } + public void set_git_repo (Ggit.Repository? repo) { + workdir_path = ""; + if (repo != null) { + workdir_path = repo.workdir.get_path (); + try { + repo_diff_list = new Ggit.Diff.index_to_workdir (repo, null, null); + } catch (Error e) { + critical ("Error getting diff list %s", e.message); + workdir_path = ""; + } + } + } // Here we take advantage of the method that draws each cell in the gutter // to determine if said line has been modified in some way. If it has, // we set the cell's color appropriately. - public override void draw (Cairo.Context cr, Gdk.Rectangle bg, Gdk.Rectangle area, Gtk.TextIter start, Gtk.TextIter end, Gtk.SourceGutterRendererState state) { + public override void draw (Cairo.Context cr, + Gdk.Rectangle bg, + Gdk.Rectangle area, + Gtk.TextIter start, + Gtk.TextIter end, + Gtk.SourceGutterRendererState state) { + base.draw (cr, bg, area, start, end, state); - int gutter_line_no = start.get_line () + 2; // For some reason, all the diffs are off by two lines...? - if (lines_to_status.contains (gutter_line_no)) { - string change = lines_to_status.get (gutter_line_no); - if (change == ADDED) { - gutter_color.parse ("#68b723"); - } else if (change == MODIFIED) { - gutter_color.parse ("#f37329"); - } else if (change == DELETED) { - gutter_color.parse ("#c6262e"); + var gutter_line_no = start.get_line () + 2; // For some reason, all the diffs are off by two lines...? + gutter_color.parse ("rgba(0,0,0,0)"); + + if (lines_to_status.has_key (gutter_line_no)) { + switch (lines_to_status.get (gutter_line_no)) { + case ADDED: + gutter_color.parse ("#68b723"); + break; + case MODIFIED: + gutter_color.parse ("#f37329"); + break; + case DELETED: + gutter_color.parse ("#c6262e"); + break; + default: + break; } - this.set_background (gutter_color); - } else { - gutter_color.parse ("rgba(0,0,0,0)"); - this.set_background (gutter_color); } + + set_background (gutter_color); } + private int diff_file_callback (Ggit.DiffDelta delta, float progress) { return 0; } + private int diff_binary_callback (Ggit.DiffDelta delta, Ggit.DiffBinary binary) { return 0; } @@ -67,52 +89,31 @@ namespace Scratch.Widgets { } private bool is_modified (Ggit.DiffLine line) { - bool is_modified_diff = false; if (previous_line_diff != null) { - // current diff - Ggit.DiffLineType type_of_change = line.get_origin (); - bool is_added_line = type_of_change == Ggit.DiffLineType.ADDITION ? true : false; - bool is_deleted_line = type_of_change == Ggit.DiffLineType.DELETION ? true : false; - - // Compare to previous diff - Ggit.DiffLineType prev_type_of_change = previous_line_diff.get_origin (); - bool prev_is_added_line = prev_type_of_change == Ggit.DiffLineType.ADDITION ? true : false; - bool prev_is_deleted_line = prev_type_of_change == Ggit.DiffLineType.DELETION ? true : false; - // In order to be a modified line they need to be "opposites" of each other - bool added_line_opposite = is_added_line != prev_is_added_line; - bool deleted_line_opposite = is_deleted_line != prev_is_deleted_line; - - is_modified_diff = added_line_opposite && deleted_line_opposite ? true : false; + return (is_addition (line) != is_addition (previous_line_diff)) && + (is_deletion (line) != is_deletion (previous_line_diff)); } - return is_modified_diff; + + return false; } - private bool is_added (Ggit.DiffLine line) { - Ggit.DiffLineType type_of_change = line.get_origin (); - return type_of_change == Ggit.DiffLineType.ADDITION ? true : false; + private bool is_addition (Ggit.DiffLine line) { + return line.get_origin () == Ggit.DiffLineType.ADDITION; + } + + private bool is_deletion (Ggit.DiffLine line) { + return line.get_origin () == Ggit.DiffLineType.ADDITION; } private bool is_deleted (Ggit.DiffLine line) { - bool is_deleted = false; if (previous_line_diff != null) { - // current diff - Ggit.DiffLineType type_of_change = line.get_origin (); - bool is_added_line = type_of_change == Ggit.DiffLineType.ADDITION ? true : false; - bool is_deleted_line = type_of_change == Ggit.DiffLineType.DELETION ? true : false; - - // Compare to previous diff - Ggit.DiffLineType prev_type_of_change = previous_line_diff.get_origin (); - bool prev_is_added_line = prev_type_of_change == Ggit.DiffLineType.ADDITION ? true : false; - bool prev_is_deleted_line = prev_type_of_change == Ggit.DiffLineType.DELETION ? true : false; - // We will color the current line red if the previous line looked like a deleted diff-line. - bool added_line_equal = is_added_line == prev_is_added_line; - bool deleted_line_opposite = is_deleted_line != prev_is_deleted_line; - - is_deleted = added_line_equal && deleted_line_opposite; + return (is_addition (line) == is_addition (previous_line_diff)) && + (is_deletion (line) != is_deletion (previous_line_diff)); } - return is_deleted; + + return false; } // We look through every diff line of the repo (unfortunately...) and determine if @@ -121,28 +122,53 @@ namespace Scratch.Widgets { // when it comes time to draw the gutter's cells. private int diff_line_callback (Ggit.DiffDelta delta, Ggit.DiffHunk? hunk, Ggit.DiffLine line) { Ggit.DiffFile? file_diff = delta.get_old_file (); - string diff_file_path = file_diff.get_path (); + string? diff_file_path = null; + if (file_diff != null) { + diff_file_path = file_diff.get_path (); + } // Only process the diff if its for the file in focus. - if (!(diff_file_path in open_file_path)) { + if (diff_file_path == null || + !(doc_path.has_suffix (diff_file_path))) { return 0; } if (is_modified (line)) { lines_to_status.set (line.get_new_lineno (), MODIFIED); - } else if (is_added (line)) { + } else if (is_addition (line)) { + lines_to_status.set (line.get_new_lineno (), ADDED); } else if (is_deleted (line)) { + lines_to_status.set (line.get_new_lineno (), DELETED); } + previous_line_diff = line; return 0; } - public void reload (string basename) { - stdout.printf("Reloading with: %s\n", basename); - open_file_path = basename; - repo_diff_list.foreach (diff_file_callback, diff_binary_callback, diff_hunk_callback, diff_line_callback); + private bool loading = false; + public void reload (string doc_path) { + if (loading) { + return; + } else { + loading = true; + } + lines_to_status.clear (); + if (repo_diff_list == null) { + return; + } + debug ("Reloading with: %s\n", doc_path); + this.doc_path = doc_path; + try { + repo_diff_list.foreach ( + diff_file_callback, diff_binary_callback, diff_hunk_callback, diff_line_callback + ); + } catch (Error e) { + warning ("Error getting repo diff %s", e.message); + } finally { + loading = false; + } } } } diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index e4e12b1e90..a6a427eea3 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -28,6 +28,8 @@ namespace Scratch.Widgets { public Gtk.TextTag warning_tag; public Gtk.TextTag error_tag; + public GLib.File location { get; set; } + private string font; private uint selection_changed_timer = 0; private uint size_allocate_timer = 0; @@ -166,9 +168,9 @@ namespace Scratch.Widgets { }); // Make the gutter renderer and insert into the left side of the source view. - git_diff_gutter_renderer = new SourceGutterRenderer("/home/puffin/code/code/.git/"); - Gtk.SourceGutter source_gutter = this.get_gutter(Gtk.TextWindowType.LEFT); - source_gutter.insert(git_diff_gutter_renderer, 1); + git_diff_gutter_renderer = new SourceGutterRenderer (); + var source_gutter = get_gutter (Gtk.TextWindowType.LEFT); + source_gutter.insert (git_diff_gutter_renderer, 1); } private bool get_current_line (out Gtk.TextIter start, out Gtk.TextIter end) { @@ -508,8 +510,19 @@ namespace Scratch.Widgets { return false; } - public void refresh_gutter (string basename) { - git_diff_gutter_renderer.reload (basename); + public void refresh_gutter () { + if (git_diff_gutter_renderer.git_repo_set) { + git_diff_gutter_renderer.reload (location.get_path ()); + } + } + + public void set_git_repo (Ggit.Repository? repo) { + git_diff_gutter_renderer.set_git_repo (repo); + refresh_gutter (); + } + + public bool git_repo_not_set () { + return !git_diff_gutter_renderer.git_repo_set; } } } From 101adb2bb4fb60a704e121b115fac0eb328215d9 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 10 Dec 2020 19:38:48 +0000 Subject: [PATCH 11/27] Fix construct Document --- src/Services/Document.vala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Services/Document.vala b/src/Services/Document.vala index 98d73ad641..e45d4fd115 100644 --- a/src/Services/Document.vala +++ b/src/Services/Document.vala @@ -56,7 +56,7 @@ namespace Scratch.Services { return source_file.location; } - set construct { + private set { source_file.set_location (value); source_view.location = value; file_changed (); @@ -112,7 +112,8 @@ namespace Scratch.Services { private ZeitgeistLogger zg_log = new ZeitgeistLogger (); #endif public Document (SimpleActionGroup actions, File? file = null) { - this.actions = actions; + Object (actions: actions); + this.file = file; page = main_stack; } From 97bedfe731698e9e43d0cd338da2c9b7dcafacfe Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Fri, 11 Dec 2020 12:16:14 +0000 Subject: [PATCH 12/27] Code-style improvement --- src/FolderManager/FileView.vala | 9 ++------- src/FolderManager/ProjectFolderItem.vala | 2 +- src/Widgets/SourceGutterRenderer.vala | 2 ++ src/Widgets/SourceView.vala | 4 +--- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/FolderManager/FileView.vala b/src/FolderManager/FileView.vala index e2175d3d44..8362ce2b84 100644 --- a/src/FolderManager/FileView.vala +++ b/src/FolderManager/FileView.vala @@ -131,15 +131,10 @@ namespace Scratch.FolderManager { } public Ggit.Repository? get_git_repo_for_file (GLib.File file) { - var folders = root.children; foreach (var item in root.children) { - if (!(item is ProjectFolderItem)) { - continue; - } else { + if (item is ProjectFolderItem) { var folder = (ProjectFolderItem)item; - if (folder.git_repo != null && - folder.contains_file (file)) { - + if (folder.git_repo != null && folder.contains_file (file)) { return folder.git_repo; } } diff --git a/src/FolderManager/ProjectFolderItem.vala b/src/FolderManager/ProjectFolderItem.vala index b797a332ac..2742f46b2e 100644 --- a/src/FolderManager/ProjectFolderItem.vala +++ b/src/FolderManager/ProjectFolderItem.vala @@ -28,7 +28,7 @@ namespace Scratch.FolderManager { // Static source IDs for each instance of a top level folder, ensures we don't check for git updates too much private static Gee.HashMap git_update_timer_ids; private string top_level_path; - public Ggit.Repository? git_repo { get; construct; } + public Ggit.Repository? git_repo { get; construct; } //Assumes will not be made a repo while in use. private GLib.FileMonitor git_monitor; private GLib.FileMonitor gitignore_monitor; diff --git a/src/Widgets/SourceGutterRenderer.vala b/src/Widgets/SourceGutterRenderer.vala index 5587470c79..09fef9c5e8 100644 --- a/src/Widgets/SourceGutterRenderer.vala +++ b/src/Widgets/SourceGutterRenderer.vala @@ -154,10 +154,12 @@ namespace Scratch.Widgets { } else { loading = true; } + lines_to_status.clear (); if (repo_diff_list == null) { return; } + debug ("Reloading with: %s\n", doc_path); this.doc_path = doc_path; try { diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index a6a427eea3..92bf48c129 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -163,14 +163,12 @@ namespace Scratch.Widgets { bottom_margin = calculate_bottom_margin (allocation.height); return GLib.Source.REMOVE; }); - } }); // Make the gutter renderer and insert into the left side of the source view. git_diff_gutter_renderer = new SourceGutterRenderer (); - var source_gutter = get_gutter (Gtk.TextWindowType.LEFT); - source_gutter.insert (git_diff_gutter_renderer, 1); + get_gutter (Gtk.TextWindowType.LEFT).insert (git_diff_gutter_renderer, 1); } private bool get_current_line (out Gtk.TextIter start, out Gtk.TextIter end) { From b024a6ea1f03c9f4de44e6a357e5437c352a40cc Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Mon, 3 May 2021 11:28:09 +0100 Subject: [PATCH 13/27] Move git stuff to MonitoredRepository --- src/FolderManager/ProjectFolderItem.vala | 4 + src/MainWindow.vala | 2 +- src/Services/Document.vala | 4 + src/Services/MonitoredRepository.vala | 106 ++++++++++++++ src/Widgets/SourceGutterRenderer.vala | 178 ++++------------------- src/Widgets/SourceView.vala | 7 +- 6 files changed, 147 insertions(+), 154 deletions(-) diff --git a/src/FolderManager/ProjectFolderItem.vala b/src/FolderManager/ProjectFolderItem.vala index e514054e3a..4a32a39212 100644 --- a/src/FolderManager/ProjectFolderItem.vala +++ b/src/FolderManager/ProjectFolderItem.vala @@ -443,6 +443,10 @@ namespace Scratch.FolderManager { return; } + public bool refresh_diff (ref Gee.HashMap line_status_map, string doc_path) { + return monitored_repo.refresh_diff (doc_path, ref line_status_map); + } + private class ChangeBranchMenu : Gtk.MenuItem { public Scratch.Services.MonitoredRepository monitored_repo { get { diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 78c3b0ce52..e49800ec8c 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -212,7 +212,7 @@ namespace Scratch { } }); - foreach (var action in action_accelerators.get_keys ()) { + foreach (var action in action_accelerators.get_keys ()) { var accels_array = action_accelerators[action].to_array (); accels_array += null; diff --git a/src/Services/Document.vala b/src/Services/Document.vala index 340e3099f7..6b5312ee93 100644 --- a/src/Services/Document.vala +++ b/src/Services/Document.vala @@ -25,6 +25,8 @@ namespace Scratch.Services { READONLY } + + public class Document : Granite.Widgets.Tab { private const uint LOAD_TIMEOUT_MSEC = 5000; @@ -204,6 +206,8 @@ namespace Scratch.Services { } else { set_saved_status (true); } + + source_view.refresh_gutter (); }); /* Create as loaded - could be new document */ diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index c4e1a469f8..00f72def06 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -19,6 +19,33 @@ */ namespace Scratch.Services { + public enum VCStatus { + NONE, + ADDED, + MODIFIED, + DELETED; + + public Gdk.RGBA to_rgba () { + var color = Gdk.RGBA (); + switch (this) { + case ADDED: + color.parse ("#68b723"); + break; + case MODIFIED: + color.parse ("#f37329"); + break; + case DELETED: + color.parse ("#c6262e"); + break; + default: + color.parse ("#000000"); + break; + } + + return color; + } + } + public class MonitoredRepository : Object { public Ggit.Repository git_repo { get; set construct; } public string branch_name { @@ -210,5 +237,84 @@ namespace Scratch.Services { public bool path_is_ignored (string path) throws Error { return git_repo.path_is_ignored (path); } + + private bool refreshing = false; + public bool refresh_diff (string file_path, + ref Gee.HashMap line_status_map) { + + // Need to have our own map since the callback closures cannot capture + // a reference to the ref parameter. Vala bug?? + // var status_map = new Gee.HashMap (); + var status_map = line_status_map; + + if (refreshing) { + return false; + } + + bool result = false; + refreshing = true; + bool? prev_addition = null; + bool? prev_deletion = null; + try { + var repo_diff_list = new Ggit.Diff.index_to_workdir (git_repo, null, null); + repo_diff_list.foreach (null, null, null, + (delta, hunk, line) => { + unowned var file_diff = delta.get_old_file (); + string? diff_file_path = null; + if (file_diff != null) { + diff_file_path = file_diff.get_path (); + } + + // Only process the diff if its for the file in focus. + if (diff_file_path == null || + !(file_path.has_suffix (diff_file_path))) { + return 0; + } + + process_diff_line (line.get_origin (), line.get_new_lineno (), + ref status_map, + ref prev_addition, + ref prev_deletion + ); + + return 0; + + } + ); + + result = true; + } catch (Error e) { + critical ("Error getting diff list %s", e.message); + } finally { + refreshing = false; + } + + line_status_map = status_map; + return result; + } + + private void process_diff_line (Ggit.DiffLineType line_type, int line_no, + ref Gee.HashMap line_status_map, + ref bool? prev_addition, + ref bool? prev_deletion) { + + bool is_addition = line_type == Ggit.DiffLineType.ADDITION; + bool is_deletion = line_type == Ggit.DiffLineType.DELETION; + bool addition_match = is_addition == prev_addition; + bool deletion_match = is_deletion == prev_deletion; + bool is_modified = prev_addition != null ? !(addition_match || deletion_match) : false; + bool is_deleted = prev_addition != null ? addition_match && !deletion_match : false; + + if (is_modified) { + line_status_map.set (line_no, VCStatus.MODIFIED); + } else if (is_addition) { + line_status_map.set (line_no, VCStatus.ADDED); + } else if (is_deleted) { + line_status_map.set (line_no, VCStatus.DELETED); + } + + prev_addition = is_addition; + prev_deletion = is_deletion; + } } } diff --git a/src/Widgets/SourceGutterRenderer.vala b/src/Widgets/SourceGutterRenderer.vala index 62fd0671c5..f0437387ec 100644 --- a/src/Widgets/SourceGutterRenderer.vala +++ b/src/Widgets/SourceGutterRenderer.vala @@ -1,52 +1,37 @@ namespace Scratch.Widgets { public class SourceGutterRenderer : Gtk.SourceGutterRenderer { - private Ggit.Diff? repo_diff_list = null; - // Use the previously seen diff to compare with the current diff to determine the "type" of diff - private Ggit.DiffLine previous_line_diff = null; - - // This keeps track of what lines had which kind of modification - // (either new additions, modifying an existing line, or deleting lines) - private Gee.HashMap lines_to_status; - - // Use this to represent the color of a cell in the gutter before it is drawn - private Gdk.RGBA gutter_color; + private Gee.HashMap line_status_map; + public FolderManager.ProjectFolderItem? project { get; set; default = null; } + public string workdir_path { + get { + return project != null ? project.top_level_path : ""; + } + } - private string workdir_path = ""; - private string doc_path = ""; + private string _doc_path = ""; + public string doc_path { + get { + return _doc_path; + } - // Use these to note what lines were modified, which lines are newly added, which lines were removed. - private const string ADDED = "GREEN"; - private const string MODIFIED = "BLUE"; - private const string DELETED = "RED";// + set { + _doc_path = value; + refresh (); + } + } - public bool project_set { get {return workdir_path != "";}} + public bool project_set { + get { + return project != null; + } + } public SourceGutterRenderer () { - debug ("MAKING NEW DIFF GUTTER\n"); - - lines_to_status = new Gee.HashMap (); - gutter_color = Gdk.RGBA (); + line_status_map = new Gee.HashMap (); set_size (3); set_visible (true); } - public void set_project (FolderManager.ProjectFolderItem? project) { - workdir_path = ""; - if (project != null) { - assert (project.is_git_repo); - workdir_path = project.top_level_path; - try { - repo_diff_list = new Ggit.Diff.index_to_workdir (project.git_repo, null, null); - } catch (Error e) { - critical ("Error getting diff list %s", e.message); - workdir_path = ""; - } - } - } - - // Here we take advantage of the method that draws each cell in the gutter - // to determine if said line has been modified in some way. If it has, - // we set the cell's color appropriately. public override void draw (Cairo.Context cr, Gdk.Rectangle bg, Gdk.Rectangle area, @@ -56,122 +41,13 @@ namespace Scratch.Widgets { base.draw (cr, bg, area, start, end, state); var gutter_line_no = start.get_line () + 2; // For some reason, all the diffs are off by two lines...? - gutter_color.parse ("rgba(0,0,0,0)"); - - if (lines_to_status.has_key (gutter_line_no)) { - switch (lines_to_status.get (gutter_line_no)) { - case ADDED: - gutter_color.parse ("#68b723"); - break; - case MODIFIED: - gutter_color.parse ("#f37329"); - break; - case DELETED: - gutter_color.parse ("#c6262e"); - break; - default: - break; - } - } - - set_background (gutter_color); - } - - private int diff_file_callback (Ggit.DiffDelta delta, float progress) { - return 0; - } - - private int diff_binary_callback (Ggit.DiffDelta delta, Ggit.DiffBinary binary) { - return 0; - } - - private int diff_hunk_callback (Ggit.DiffDelta delta, Ggit.DiffHunk hunk) { - return 0; - } - - private bool is_modified (Ggit.DiffLine line) { - if (previous_line_diff != null) { - // In order to be a modified line they need to be "opposites" of each other - return (is_addition (line) != is_addition (previous_line_diff)) && - (is_deletion (line) != is_deletion (previous_line_diff)); + if (line_status_map.has_key (gutter_line_no)) { + set_background (line_status_map.get (gutter_line_no).to_rgba ()); } - - return false; - } - - private bool is_addition (Ggit.DiffLine line) { - return line.get_origin () == Ggit.DiffLineType.ADDITION; - } - - private bool is_deletion (Ggit.DiffLine line) { - return line.get_origin () == Ggit.DiffLineType.ADDITION; - } - - private bool is_deleted (Ggit.DiffLine line) { - if (previous_line_diff != null) { - // We will color the current line red if the previous line looked like a deleted diff-line. - return (is_addition (line) == is_addition (previous_line_diff)) && - (is_deletion (line) != is_deletion (previous_line_diff)); - } - - return false; - } - - // We look through every diff line of the repo (unfortunately...) and determine if - // the diff is for the file that is in focus. Then we determine the kind of modification, - // and save it with the line number. That way we have line numbers mapped to modifications - // when it comes time to draw the gutter's cells. - private int diff_line_callback (Ggit.DiffDelta delta, Ggit.DiffHunk? hunk, Ggit.DiffLine line) { - Ggit.DiffFile? file_diff = delta.get_old_file (); - string? diff_file_path = null; - if (file_diff != null) { - diff_file_path = file_diff.get_path (); - } - - // Only process the diff if its for the file in focus. - if (diff_file_path == null || - !(doc_path.has_suffix (diff_file_path))) { - return 0; - } - - if (is_modified (line)) { - lines_to_status.set (line.get_new_lineno (), MODIFIED); - } else if (is_addition (line)) { - - lines_to_status.set (line.get_new_lineno (), ADDED); - } else if (is_deleted (line)) { - - lines_to_status.set (line.get_new_lineno (), DELETED); - } - - previous_line_diff = line; - return 0; } - private bool loading = false; - public void reload (string doc_path) { - if (loading) { - return; - } else { - loading = true; - } - - lines_to_status.clear (); - if (repo_diff_list == null) { - return; - } - - debug ("Reloading with: %s\n", doc_path); - this.doc_path = doc_path; - try { - repo_diff_list.foreach ( - diff_file_callback, diff_binary_callback, diff_hunk_callback, diff_line_callback - ); - } catch (Error e) { - warning ("Error getting repo diff %s", e.message); - } finally { - loading = false; - } + public void refresh () { + project.refresh_diff (ref line_status_map, _doc_path); } } } diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index 0bbb4c6e44..3e84f5f65e 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -184,6 +184,9 @@ namespace Scratch.Widgets { // Make the gutter renderer and insert into the left side of the source view. git_diff_gutter_renderer = new SourceGutterRenderer (); get_gutter (Gtk.TextWindowType.LEFT).insert (git_diff_gutter_renderer, 1); + notify["location"].connect (() => { + git_diff_gutter_renderer.doc_path = location.get_path (); + }); } private bool get_current_line (out Gtk.TextIter start, out Gtk.TextIter end) { @@ -582,12 +585,12 @@ namespace Scratch.Widgets { public void refresh_gutter () { if (git_diff_gutter_renderer.project_set) { - git_diff_gutter_renderer.reload (location.get_path ()); + git_diff_gutter_renderer.refresh (); } } public void set_project (FolderManager.ProjectFolderItem? project) { - git_diff_gutter_renderer.set_project (project); + git_diff_gutter_renderer.project = project; refresh_gutter (); } From 88a323bc2118d00881526f609fec48861081cac9 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Mon, 3 May 2021 12:58:34 +0100 Subject: [PATCH 14/27] Improve diff parsing; add OTHER VCStatus --- src/Services/MonitoredRepository.vala | 69 +++++++++++++++------------ src/Widgets/SourceGutterRenderer.vala | 2 + 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index 00f72def06..a0bb84eeb7 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -23,22 +23,26 @@ namespace Scratch.Services { NONE, ADDED, MODIFIED, - DELETED; + DELETED, + OTHER; public Gdk.RGBA to_rgba () { var color = Gdk.RGBA (); switch (this) { case ADDED: - color.parse ("#68b723"); + color.parse ("#68b723"); //Lime 500 break; case MODIFIED: - color.parse ("#f37329"); + color.parse ("#f37329"); //Orange 500 break; case DELETED: - color.parse ("#c6262e"); + color.parse ("#c6262e"); //Strawberry 500 + break; + case OTHER: + color.parse ("#3689e6"); //Blueberry 500 break; default: - color.parse ("#000000"); + color.parse ("#000000"); //Transparent break; } @@ -245,6 +249,7 @@ namespace Scratch.Services { // Need to have our own map since the callback closures cannot capture // a reference to the ref parameter. Vala bug?? // var status_map = new Gee.HashMap (); + line_status_map.clear (); var status_map = line_status_map; if (refreshing) { @@ -253,27 +258,28 @@ namespace Scratch.Services { bool result = false; refreshing = true; - bool? prev_addition = null; - bool? prev_deletion = null; + int prev_deletion = -1; try { var repo_diff_list = new Ggit.Diff.index_to_workdir (git_repo, null, null); repo_diff_list.foreach (null, null, null, (delta, hunk, line) => { unowned var file_diff = delta.get_old_file (); - string? diff_file_path = null; - if (file_diff != null) { - diff_file_path = file_diff.get_path (); + if (file_diff == null) { + return 0; } + unowned var diff_file_path = file_diff.get_path (); // Only process the diff if its for the file in focus. if (diff_file_path == null || !(file_path.has_suffix (diff_file_path))) { + return 0; } - process_diff_line (line.get_origin (), line.get_new_lineno (), + process_diff_line (line.get_origin (), + line.get_new_lineno (), + line.get_old_lineno (), ref status_map, - ref prev_addition, ref prev_deletion ); @@ -293,28 +299,29 @@ namespace Scratch.Services { return result; } - private void process_diff_line (Ggit.DiffLineType line_type, int line_no, + private void process_diff_line (Ggit.DiffLineType line_type, int new_line_no, int old_line_no, ref Gee.HashMap line_status_map, - ref bool? prev_addition, - ref bool? prev_deletion) { - - bool is_addition = line_type == Ggit.DiffLineType.ADDITION; - bool is_deletion = line_type == Ggit.DiffLineType.DELETION; - bool addition_match = is_addition == prev_addition; - bool deletion_match = is_deletion == prev_deletion; - bool is_modified = prev_addition != null ? !(addition_match || deletion_match) : false; - bool is_deleted = prev_addition != null ? addition_match && !deletion_match : false; - - if (is_modified) { - line_status_map.set (line_no, VCStatus.MODIFIED); - } else if (is_addition) { - line_status_map.set (line_no, VCStatus.ADDED); - } else if (is_deleted) { - line_status_map.set (line_no, VCStatus.DELETED); + ref int prev_deletion) { + + + if (line_type == Ggit.DiffLineType.CONTEXT) { + return; + } else if (new_line_no < 0) { + prev_deletion = old_line_no; //TODO deal with showing deleted lines (no longer present in SourceView) + return; + } else { + if (old_line_no < 0) { //Line added + line_status_map.set ( + new_line_no, new_line_no == prev_deletion ? VCStatus.MODIFIED :VCStatus.ADDED + ); + } else { + line_status_map.set (new_line_no, VCStatus.OTHER); + } + } - prev_addition = is_addition; - prev_deletion = is_deletion; + prev_deletion = -1; } } } + diff --git a/src/Widgets/SourceGutterRenderer.vala b/src/Widgets/SourceGutterRenderer.vala index f0437387ec..dddfa250d3 100644 --- a/src/Widgets/SourceGutterRenderer.vala +++ b/src/Widgets/SourceGutterRenderer.vala @@ -43,6 +43,8 @@ namespace Scratch.Widgets { var gutter_line_no = start.get_line () + 2; // For some reason, all the diffs are off by two lines...? if (line_status_map.has_key (gutter_line_no)) { set_background (line_status_map.get (gutter_line_no).to_rgba ()); + } else { + set_background (Services.VCStatus.NONE.to_rgba ()); } } From 1be91eaefc661a524040ed3a2b3046956abc2522 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Mon, 3 May 2021 13:00:53 +0100 Subject: [PATCH 15/27] Fix lint --- src/Services/MonitoredRepository.vala | 1 - src/Widgets/SourceGutterRenderer.vala | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index a0bb84eeb7..8ef029277d 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -324,4 +324,3 @@ namespace Scratch.Services { } } } - diff --git a/src/Widgets/SourceGutterRenderer.vala b/src/Widgets/SourceGutterRenderer.vala index dddfa250d3..4b6329e0fb 100644 --- a/src/Widgets/SourceGutterRenderer.vala +++ b/src/Widgets/SourceGutterRenderer.vala @@ -49,7 +49,7 @@ namespace Scratch.Widgets { } public void refresh () { - project.refresh_diff (ref line_status_map, _doc_path); + project.refresh_diff (ref line_status_map, _doc_path); } } } From c4d71fbcd7b8101f9a78004f18a4ebb3d36acdb2 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Mon, 3 May 2021 15:52:33 +0100 Subject: [PATCH 16/27] Fix process_diff_line; only refresh when file content changes --- src/FolderManager/FolderItem.vala | 10 ------ src/FolderManager/ProjectFolderItem.vala | 8 +---- src/MainWindow.vala | 6 ++-- src/Services/Document.vala | 8 ----- src/Services/MonitoredRepository.vala | 40 ++++++++++++++++-------- src/Widgets/DocumentView.vala | 1 - src/Widgets/SourceGutterRenderer.vala | 23 +++++++------- src/Widgets/SourceView.vala | 11 ------- 8 files changed, 41 insertions(+), 66 deletions(-) diff --git a/src/FolderManager/FolderItem.vala b/src/FolderManager/FolderItem.vala index 7604315d8c..d35c65d66e 100644 --- a/src/FolderManager/FolderItem.vala +++ b/src/FolderManager/FolderItem.vala @@ -322,16 +322,6 @@ namespace Scratch.FolderManager { break; } } - - // Reduce spamming of root (still results in multiple signals per change in file being edited - //TODO Throttle this signal? - if (event == FileMonitorEvent.CHANGES_DONE_HINT) { - //TODO Get root folder once as it will not change for the life of this folder - var root = get_root_folder (this); - if (root != null) { - root.child_folder_changed (this); - } - } } private void on_add_new (bool is_folder) { diff --git a/src/FolderManager/ProjectFolderItem.vala b/src/FolderManager/ProjectFolderItem.vala index 4a32a39212..7d7d6b6f17 100644 --- a/src/FolderManager/ProjectFolderItem.vala +++ b/src/FolderManager/ProjectFolderItem.vala @@ -62,17 +62,10 @@ namespace Scratch.FolderManager { monitored_repo.branch_changed.connect ((update_branch_name)); monitored_repo.ignored_changed.connect ((deprioritize_git_ignored)); monitored_repo.file_status_change.connect (() => update_item_status (null)); - monitored_repo.update (); update_branch_name (monitored_repo.get_current_branch ()); } } - public void child_folder_changed (FolderItem folder) { - if (monitored_repo != null) { - monitored_repo.update (); - } - } - public void child_folder_loaded (FolderItem folder) { foreach (var child in folder.children) { if (child is Item) { @@ -86,6 +79,7 @@ namespace Scratch.FolderManager { } if (monitored_repo != null) { + monitored_repo.update_status_map (); update_item_status (folder); deprioritize_git_ignored (); } diff --git a/src/MainWindow.vala b/src/MainWindow.vala index e49800ec8c..09cd8e7593 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -554,10 +554,8 @@ namespace Scratch { } public void open_document (Scratch.Services.Document doc, bool focus = true, int cursor_position = 0) { - if (doc.source_view.project_not_set ()) { - FolderManager.ProjectFolderItem? project = folder_manager_view.get_project_for_file (doc.file); - doc.source_view.set_project (project); - } + FolderManager.ProjectFolderItem? project = folder_manager_view.get_project_for_file (doc.file); + doc.source_view.set_project (project); document_view.open_document (doc, focus, cursor_position); } diff --git a/src/Services/Document.vala b/src/Services/Document.vala index 6b5312ee93..e039844823 100644 --- a/src/Services/Document.vala +++ b/src/Services/Document.vala @@ -206,8 +206,6 @@ namespace Scratch.Services { } else { set_saved_status (true); } - - source_view.refresh_gutter (); }); /* Create as loaded - could be new document */ @@ -567,14 +565,8 @@ namespace Scratch.Services { } } - // When switching between tabs, refresh the source view gutter - public void refresh_sourceview_gutter () { - source_view.refresh_gutter (); - } - // Focus the SourceView public new void focus () { - source_view.refresh_gutter (); source_view.grab_focus (); } diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index 8ef029277d..1f20aa403e 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -78,6 +78,7 @@ namespace Scratch.Services { public signal void branch_changed (string new_branch_name); public signal void ignored_changed (); public signal void file_status_change (); + public signal void file_content_changed (); private FileMonitor? git_monitor = null; private FileMonitor? gitignore_monitor = null; @@ -107,7 +108,10 @@ namespace Scratch.Services { try { git_monitor = git_folder.monitor_directory (GLib.FileMonitorFlags.NONE); - git_monitor.changed.connect (update); + git_monitor.changed.connect (() => { + update_status_map (); + file_content_changed (); //If displayed in SourceView signal update of gutter + }); } catch (IOError e) { warning ("An error occured setting up a file monitor on the git folder: %s", e.message); } @@ -196,7 +200,7 @@ namespace Scratch.Services { } private bool do_update = false; - public void update () { + public void update_status_map () { if (update_timer_id == 0) { update_timer_id = Timeout.add (150, () => { if (do_update) { @@ -246,19 +250,21 @@ namespace Scratch.Services { public bool refresh_diff (string file_path, ref Gee.HashMap line_status_map) { + + + if (refreshing) { + return false; + } // Need to have our own map since the callback closures cannot capture // a reference to the ref parameter. Vala bug?? // var status_map = new Gee.HashMap (); line_status_map.clear (); var status_map = line_status_map; - if (refreshing) { - return false; - } - bool result = false; refreshing = true; int prev_deletion = -1; + int prev_delta = 0; try { var repo_diff_list = new Ggit.Diff.index_to_workdir (git_repo, null, null); repo_diff_list.foreach (null, null, null, @@ -280,7 +286,8 @@ namespace Scratch.Services { line.get_new_lineno (), line.get_old_lineno (), ref status_map, - ref prev_deletion + ref prev_deletion, + ref prev_delta ); return 0; @@ -301,19 +308,26 @@ namespace Scratch.Services { private void process_diff_line (Ggit.DiffLineType line_type, int new_line_no, int old_line_no, ref Gee.HashMap line_status_map, - ref int prev_deletion) { - + ref int prev_deletion, + ref int prev_delta) { if (line_type == Ggit.DiffLineType.CONTEXT) { return; - } else if (new_line_no < 0) { + } + + if (new_line_no < 0) { prev_deletion = old_line_no; //TODO deal with showing deleted lines (no longer present in SourceView) + prev_delta--; return; } else { if (old_line_no < 0) { //Line added - line_status_map.set ( - new_line_no, new_line_no == prev_deletion ? VCStatus.MODIFIED :VCStatus.ADDED - ); + prev_delta++; + if (new_line_no != prev_deletion + prev_delta) { + line_status_map.set (new_line_no, VCStatus.ADDED); + } else { + line_status_map.set (new_line_no, VCStatus.MODIFIED); + } + } else { line_status_map.set (new_line_no, VCStatus.OTHER); } diff --git a/src/Widgets/DocumentView.vala b/src/Widgets/DocumentView.vala index cd0d186ba5..80c97e6ed9 100644 --- a/src/Widgets/DocumentView.vala +++ b/src/Widgets/DocumentView.vala @@ -195,7 +195,6 @@ public class Scratch.Widgets.DocumentView : Granite.Widgets.DynamicNotebook { current_document = nth_doc; } - current_document.refresh_sourceview_gutter (); debug ("This Document was already opened! Not opening a duplicate!"); return; } diff --git a/src/Widgets/SourceGutterRenderer.vala b/src/Widgets/SourceGutterRenderer.vala index 4b6329e0fb..3b65b1ec81 100644 --- a/src/Widgets/SourceGutterRenderer.vala +++ b/src/Widgets/SourceGutterRenderer.vala @@ -16,20 +16,22 @@ namespace Scratch.Widgets { set { _doc_path = value; - refresh (); } } - public bool project_set { - get { - return project != null; - } - } - - public SourceGutterRenderer () { + construct { line_status_map = new Gee.HashMap (); set_size (3); set_visible (true); + notify["project"].connect (() => { + //Assuming project will not change again + if (project.is_git_repo) { + project.refresh_diff (ref line_status_map, _doc_path); + project.monitored_repo.file_content_changed.connect (() => { + project.refresh_diff (ref line_status_map, _doc_path); + }); + } + }); } public override void draw (Cairo.Context cr, @@ -39,17 +41,14 @@ namespace Scratch.Widgets { Gtk.TextIter end, Gtk.SourceGutterRendererState state) { - base.draw (cr, bg, area, start, end, state); var gutter_line_no = start.get_line () + 2; // For some reason, all the diffs are off by two lines...? if (line_status_map.has_key (gutter_line_no)) { set_background (line_status_map.get (gutter_line_no).to_rgba ()); } else { set_background (Services.VCStatus.NONE.to_rgba ()); } - } - public void refresh () { - project.refresh_diff (ref line_status_map, _doc_path); + base.draw (cr, bg, area, start, end, state); } } } diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index 3e84f5f65e..618d0252eb 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -583,19 +583,8 @@ namespace Scratch.Widgets { return false; } - public void refresh_gutter () { - if (git_diff_gutter_renderer.project_set) { - git_diff_gutter_renderer.refresh (); - } - } - public void set_project (FolderManager.ProjectFolderItem? project) { git_diff_gutter_renderer.project = project; - refresh_gutter (); - } - - public bool project_not_set () { - return !git_diff_gutter_renderer.project_set; } } } From 4aa6767ae773af46e5251af6c3e910a33d3a5b6b Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Mon, 3 May 2021 17:17:52 +0100 Subject: [PATCH 17/27] Reinstate some needed code and other improvements * Throttle refresh diff and control from SourceView * Match gutter/diff line to source position * Minor code style improvements --- src/FolderManager/FolderItem.vala | 10 +++++++++ src/FolderManager/ProjectFolderItem.vala | 10 +++++++-- src/MainWindow.vala | 2 +- src/Services/MonitoredRepository.vala | 21 +++++++----------- src/Widgets/SourceGutterRenderer.vala | 26 ++++------------------- src/Widgets/SourceView.vala | 27 ++++++++++++++++++++---- 6 files changed, 54 insertions(+), 42 deletions(-) diff --git a/src/FolderManager/FolderItem.vala b/src/FolderManager/FolderItem.vala index d35c65d66e..7604315d8c 100644 --- a/src/FolderManager/FolderItem.vala +++ b/src/FolderManager/FolderItem.vala @@ -322,6 +322,16 @@ namespace Scratch.FolderManager { break; } } + + // Reduce spamming of root (still results in multiple signals per change in file being edited + //TODO Throttle this signal? + if (event == FileMonitorEvent.CHANGES_DONE_HINT) { + //TODO Get root folder once as it will not change for the life of this folder + var root = get_root_folder (this); + if (root != null) { + root.child_folder_changed (this); + } + } } private void on_add_new (bool is_folder) { diff --git a/src/FolderManager/ProjectFolderItem.vala b/src/FolderManager/ProjectFolderItem.vala index 7d7d6b6f17..862dca572d 100644 --- a/src/FolderManager/ProjectFolderItem.vala +++ b/src/FolderManager/ProjectFolderItem.vala @@ -66,6 +66,12 @@ namespace Scratch.FolderManager { } } + public void child_folder_changed (FolderItem folder) { + if (monitored_repo != null) { + monitored_repo.update_status_map (); + } + } + public void child_folder_loaded (FolderItem folder) { foreach (var child in folder.children) { if (child is Item) { @@ -437,8 +443,8 @@ namespace Scratch.FolderManager { return; } - public bool refresh_diff (ref Gee.HashMap line_status_map, string doc_path) { - return monitored_repo.refresh_diff (doc_path, ref line_status_map); + public void refresh_diff (ref Gee.HashMap line_status_map, string doc_path) { + monitored_repo.refresh_diff (doc_path, ref line_status_map); } private class ChangeBranchMenu : Gtk.MenuItem { diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 09cd8e7593..15134c1182 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -555,7 +555,7 @@ namespace Scratch { public void open_document (Scratch.Services.Document doc, bool focus = true, int cursor_position = 0) { FolderManager.ProjectFolderItem? project = folder_manager_view.get_project_for_file (doc.file); - doc.source_view.set_project (project); + doc.source_view.project = project; document_view.open_document (doc, focus, cursor_position); } diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index 1f20aa403e..5023fc49bf 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -110,7 +110,6 @@ namespace Scratch.Services { git_monitor = git_folder.monitor_directory (GLib.FileMonitorFlags.NONE); git_monitor.changed.connect (() => { update_status_map (); - file_content_changed (); //If displayed in SourceView signal update of gutter }); } catch (IOError e) { warning ("An error occured setting up a file monitor on the git folder: %s", e.message); @@ -237,6 +236,8 @@ namespace Scratch.Services { return Source.CONTINUE; } }); + + file_content_changed (); //If displayed in SourceView signal update of gutter } else { do_update = false; } @@ -247,23 +248,21 @@ namespace Scratch.Services { } private bool refreshing = false; - public bool refresh_diff (string file_path, + public void refresh_diff (string file_path, ref Gee.HashMap line_status_map) { - - if (refreshing) { - return false; + return; + } else { + refreshing = true; } + // Need to have our own map since the callback closures cannot capture // a reference to the ref parameter. Vala bug?? // var status_map = new Gee.HashMap (); - line_status_map.clear (); var status_map = line_status_map; - bool result = false; - refreshing = true; - int prev_deletion = -1; + int prev_deletion = -2; int prev_delta = 0; try { var repo_diff_list = new Ggit.Diff.index_to_workdir (git_repo, null, null); @@ -291,11 +290,8 @@ namespace Scratch.Services { ); return 0; - } ); - - result = true; } catch (Error e) { critical ("Error getting diff list %s", e.message); } finally { @@ -303,7 +299,6 @@ namespace Scratch.Services { } line_status_map = status_map; - return result; } private void process_diff_line (Ggit.DiffLineType line_type, int new_line_no, int old_line_no, diff --git a/src/Widgets/SourceGutterRenderer.vala b/src/Widgets/SourceGutterRenderer.vala index 3b65b1ec81..038e5f0b60 100644 --- a/src/Widgets/SourceGutterRenderer.vala +++ b/src/Widgets/SourceGutterRenderer.vala @@ -1,6 +1,6 @@ namespace Scratch.Widgets { public class SourceGutterRenderer : Gtk.SourceGutterRenderer { - private Gee.HashMap line_status_map; + public Gee.HashMap line_status_map; public FolderManager.ProjectFolderItem? project { get; set; default = null; } public string workdir_path { get { @@ -8,30 +8,11 @@ namespace Scratch.Widgets { } } - private string _doc_path = ""; - public string doc_path { - get { - return _doc_path; - } - - set { - _doc_path = value; - } - } - construct { line_status_map = new Gee.HashMap (); set_size (3); set_visible (true); - notify["project"].connect (() => { - //Assuming project will not change again - if (project.is_git_repo) { - project.refresh_diff (ref line_status_map, _doc_path); - project.monitored_repo.file_content_changed.connect (() => { - project.refresh_diff (ref line_status_map, _doc_path); - }); - } - }); + } public override void draw (Cairo.Context cr, @@ -41,7 +22,8 @@ namespace Scratch.Widgets { Gtk.TextIter end, Gtk.SourceGutterRendererState state) { - var gutter_line_no = start.get_line () + 2; // For some reason, all the diffs are off by two lines...? + //Gutter and diff lines numbers start at one, source lines start at 0 + var gutter_line_no = start.get_line () + 1; if (line_status_map.has_key (gutter_line_no)) { set_background (line_status_map.get (gutter_line_no).to_rgba ()); } else { diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index 618d0252eb..fee2883954 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -28,6 +28,7 @@ namespace Scratch.Widgets { public Gtk.TextTag error_tag; public GLib.File location { get; set; } + public FolderManager.ProjectFolderItem project { get; set; default = null; } private string font; private uint selection_changed_timer = 0; @@ -184,8 +185,15 @@ namespace Scratch.Widgets { // Make the gutter renderer and insert into the left side of the source view. git_diff_gutter_renderer = new SourceGutterRenderer (); get_gutter (Gtk.TextWindowType.LEFT).insert (git_diff_gutter_renderer, 1); - notify["location"].connect (() => { - git_diff_gutter_renderer.doc_path = location.get_path (); + + notify["project"].connect (() => { + //Assuming project will not change again + if (project.is_git_repo) { + schedule_refresh_diff (); + project.monitored_repo.file_content_changed.connect (() => { + schedule_refresh_diff (); + }); + } }); } @@ -583,8 +591,19 @@ namespace Scratch.Widgets { return false; } - public void set_project (FolderManager.ProjectFolderItem? project) { - git_diff_gutter_renderer.project = project; + uint refresh_diff_timeout_id = 0; + private void schedule_refresh_diff () { + if (refresh_diff_timeout_id > 0) { + Source.remove (refresh_diff_timeout_id); + } + + refresh_diff_timeout_id = Timeout.add (250, () => { + refresh_diff_timeout_id = 0; + git_diff_gutter_renderer.line_status_map.clear (); + project.refresh_diff (ref git_diff_gutter_renderer.line_status_map, location.get_path ()); + queue_draw (); + return Source.REMOVE; + }); } } } From 376d54a8f668185d12c9dfffce62eba9920530f2 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Mon, 3 May 2021 18:24:03 +0100 Subject: [PATCH 18/27] Minor code cleanup --- src/FolderManager/FileView.vala | 4 ++-- src/FolderManager/ProjectFolderItem.vala | 3 +-- src/Services/Document.vala | 2 -- src/Services/MonitoredRepository.vala | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/FolderManager/FileView.vala b/src/FolderManager/FileView.vala index cda97d4b0e..f29ae68655 100644 --- a/src/FolderManager/FileView.vala +++ b/src/FolderManager/FileView.vala @@ -192,7 +192,8 @@ namespace Scratch.FolderManager { } } - public unowned ProjectFolderItem? get_active_project (GLib.File? active_file, out List project_list) { + public unowned ProjectFolderItem? get_active_project (GLib.File? active_file, + out List project_list) { unowned ProjectFolderItem? project = null; project_list = null; foreach (var child in root.children) { @@ -204,7 +205,6 @@ namespace Scratch.FolderManager { if (active_file != null) if (project.file.file.equal (active_file) || - // project.file.file.get_relative_path (active_file) != null) { project.contains_file (active_file)) { return project; diff --git a/src/FolderManager/ProjectFolderItem.vala b/src/FolderManager/ProjectFolderItem.vala index 862dca572d..6bba8383c0 100644 --- a/src/FolderManager/ProjectFolderItem.vala +++ b/src/FolderManager/ProjectFolderItem.vala @@ -40,8 +40,7 @@ namespace Scratch.FolderManager { } } - // Temporarily expose for SourceGutterRenderer. - public Ggit.Repository? git_repo { + private Ggit.Repository? git_repo { get { return (is_git_repo ? monitored_repo.git_repo : null); } diff --git a/src/Services/Document.vala b/src/Services/Document.vala index e039844823..908b719d24 100644 --- a/src/Services/Document.vala +++ b/src/Services/Document.vala @@ -25,8 +25,6 @@ namespace Scratch.Services { READONLY } - - public class Document : Granite.Widgets.Tab { private const uint LOAD_TIMEOUT_MSEC = 5000; diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index 5023fc49bf..e06f90067d 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -248,8 +248,7 @@ namespace Scratch.Services { } private bool refreshing = false; - public void refresh_diff (string file_path, - ref Gee.HashMap line_status_map) { + public void refresh_diff (string file_path, ref Gee.HashMap line_status_map) { if (refreshing) { return; From a74aa958cdca369c905e063d07adfd351e08cb24 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Mon, 3 May 2021 18:51:33 +0100 Subject: [PATCH 19/27] Fix showing modified block --- src/Services/MonitoredRepository.vala | 29 ++++++++++++++------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index e06f90067d..ab4fbe1279 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -261,8 +261,8 @@ namespace Scratch.Services { // var status_map = new Gee.HashMap (); var status_map = line_status_map; - int prev_deletion = -2; - int prev_delta = 0; + int prev_deletions = 0; + int prev_additions = 0; try { var repo_diff_list = new Ggit.Diff.index_to_workdir (git_repo, null, null); repo_diff_list.foreach (null, null, null, @@ -284,8 +284,8 @@ namespace Scratch.Services { line.get_new_lineno (), line.get_old_lineno (), ref status_map, - ref prev_deletion, - ref prev_delta + ref prev_deletions, + ref prev_additions ); return 0; @@ -302,24 +302,27 @@ namespace Scratch.Services { private void process_diff_line (Ggit.DiffLineType line_type, int new_line_no, int old_line_no, ref Gee.HashMap line_status_map, - ref int prev_deletion, - ref int prev_delta) { + ref int prev_deletions, + ref int prev_additions) { if (line_type == Ggit.DiffLineType.CONTEXT) { + prev_deletions = 0; + prev_additions = 0; return; } if (new_line_no < 0) { - prev_deletion = old_line_no; //TODO deal with showing deleted lines (no longer present in SourceView) - prev_delta--; + prev_deletions++; + prev_additions = 0; return; } else { if (old_line_no < 0) { //Line added - prev_delta++; - if (new_line_no != prev_deletion + prev_delta) { - line_status_map.set (new_line_no, VCStatus.ADDED); - } else { + prev_additions++; + if (prev_deletions >= prev_additions) { line_status_map.set (new_line_no, VCStatus.MODIFIED); + } else { + line_status_map.set (new_line_no, VCStatus.ADDED); + prev_deletions = 0; } } else { @@ -327,8 +330,6 @@ namespace Scratch.Services { } } - - prev_deletion = -1; } } } From 92f337173ce2b7ec7922aadcb80799f32a5888aa Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 4 May 2021 09:42:12 +0100 Subject: [PATCH 20/27] No need to recreate Ggit.Diff object each time --- src/Services/MonitoredRepository.vala | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index ab4fbe1279..69375c6c9c 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -52,6 +52,7 @@ namespace Scratch.Services { public class MonitoredRepository : Object { public Ggit.Repository git_repo { get; set construct; } + private Ggit.Diff repo_diff_list; public string branch_name { get { return _branch_name; @@ -100,10 +101,19 @@ namespace Scratch.Services { status_options = new Ggit.StatusOptions (Ggit.StatusOption.INCLUDE_UNTRACKED | Ggit.StatusOption.RECURSE_UNTRACKED_DIRS, Ggit.StatusShow.INDEX_AND_WORKDIR, null); + + try { + repo_diff_list = new Ggit.Diff.index_to_workdir (git_repo, null, null); + } catch (Error e) { + critical ("Error creating diff"); + } } public MonitoredRepository (Ggit.Repository _git_repo) { - git_repo = _git_repo; + Object ( + git_repo: _git_repo + ); + var git_folder = git_repo.get_location (); try { @@ -264,7 +274,6 @@ namespace Scratch.Services { int prev_deletions = 0; int prev_additions = 0; try { - var repo_diff_list = new Ggit.Diff.index_to_workdir (git_repo, null, null); repo_diff_list.foreach (null, null, null, (delta, hunk, line) => { unowned var file_diff = delta.get_old_file (); From 9bd426cf26984aa23aa503dcfb256a86ceb59041 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 4 May 2021 09:59:26 +0100 Subject: [PATCH 21/27] Fix long line --- src/Services/MonitoredRepository.vala | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index 69375c6c9c..dea7892673 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -98,9 +98,11 @@ namespace Scratch.Services { construct { file_status_map = new Gee.HashMap (); - status_options = new Ggit.StatusOptions (Ggit.StatusOption.INCLUDE_UNTRACKED | Ggit.StatusOption.RECURSE_UNTRACKED_DIRS, - Ggit.StatusShow.INDEX_AND_WORKDIR, - null); + status_options = new Ggit.StatusOptions ( + Ggit.StatusOption.INCLUDE_UNTRACKED | Ggit.StatusOption.RECURSE_UNTRACKED_DIRS, + Ggit.StatusShow.INDEX_AND_WORKDIR, + null + ); try { repo_diff_list = new Ggit.Diff.index_to_workdir (git_repo, null, null); From 3122248dfba7eaf9b423f4e6284681821e88b4ad Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 4 May 2021 11:41:39 +0100 Subject: [PATCH 22/27] Show unmodified lines that replace a deleted line with blue --- src/Services/MonitoredRepository.vala | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index dea7892673..a7bea695fd 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -23,7 +23,8 @@ namespace Scratch.Services { NONE, ADDED, MODIFIED, - DELETED, + DELETED, //Cannot show in normal SourceView but for future use in Diff view? + REPLACES_DELETED, //For unmodified lines that replace deleted lines OTHER; public Gdk.RGBA to_rgba () { @@ -38,7 +39,7 @@ namespace Scratch.Services { case DELETED: color.parse ("#c6262e"); //Strawberry 500 break; - case OTHER: + case REPLACES_DELETED: color.parse ("#3689e6"); //Blueberry 500 break; default: @@ -317,6 +318,9 @@ namespace Scratch.Services { ref int prev_additions) { if (line_type == Ggit.DiffLineType.CONTEXT) { + if (prev_deletions > 0) { + line_status_map.set (new_line_no, VCStatus.REPLACES_DELETED); + } prev_deletions = 0; prev_additions = 0; return; @@ -327,10 +331,11 @@ namespace Scratch.Services { prev_additions = 0; return; } else { - if (old_line_no < 0) { //Line added + if (line_type == Ggit.DiffLineType.ADDITION) { //Line added prev_additions++; if (prev_deletions >= prev_additions) { line_status_map.set (new_line_no, VCStatus.MODIFIED); + prev_deletions--; } else { line_status_map.set (new_line_no, VCStatus.ADDED); prev_deletions = 0; From 3d0b154f7d7b931772438816745a59809086fd50 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 4 May 2021 11:48:05 +0100 Subject: [PATCH 23/27] Looks like we do need to recreate Diff object --- src/Services/MonitoredRepository.vala | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index a7bea695fd..a1eaa5c0d8 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -53,7 +53,6 @@ namespace Scratch.Services { public class MonitoredRepository : Object { public Ggit.Repository git_repo { get; set construct; } - private Ggit.Diff repo_diff_list; public string branch_name { get { return _branch_name; @@ -104,12 +103,6 @@ namespace Scratch.Services { Ggit.StatusShow.INDEX_AND_WORKDIR, null ); - - try { - repo_diff_list = new Ggit.Diff.index_to_workdir (git_repo, null, null); - } catch (Error e) { - critical ("Error creating diff"); - } } public MonitoredRepository (Ggit.Repository _git_repo) { @@ -277,6 +270,7 @@ namespace Scratch.Services { int prev_deletions = 0; int prev_additions = 0; try { + var repo_diff_list = new Ggit.Diff.index_to_workdir (git_repo, null, null); repo_diff_list.foreach (null, null, null, (delta, hunk, line) => { unowned var file_diff = delta.get_old_file (); From 70844b0c6651090a42f34b85376a5298fd9d1969 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 4 May 2021 12:19:34 +0100 Subject: [PATCH 24/27] Fix whitespace. Only redraw gutter when diff refreshes --- src/Services/MonitoredRepository.vala | 8 +++----- src/Widgets/SourceGutterRenderer.vala | 1 - src/Widgets/SourceView.vala | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index a1eaa5c0d8..3fef0900ed 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -23,8 +23,8 @@ namespace Scratch.Services { NONE, ADDED, MODIFIED, - DELETED, //Cannot show in normal SourceView but for future use in Diff view? - REPLACES_DELETED, //For unmodified lines that replace deleted lines + DELETED, // Cannot show in normal SourceView but for future use in Diff view? + REPLACES_DELETED, // For unmodified lines that replace deleted lines OTHER; public Gdk.RGBA to_rgba () { @@ -255,7 +255,6 @@ namespace Scratch.Services { private bool refreshing = false; public void refresh_diff (string file_path, ref Gee.HashMap line_status_map) { - if (refreshing) { return; } else { @@ -315,6 +314,7 @@ namespace Scratch.Services { if (prev_deletions > 0) { line_status_map.set (new_line_no, VCStatus.REPLACES_DELETED); } + prev_deletions = 0; prev_additions = 0; return; @@ -334,11 +334,9 @@ namespace Scratch.Services { line_status_map.set (new_line_no, VCStatus.ADDED); prev_deletions = 0; } - } else { line_status_map.set (new_line_no, VCStatus.OTHER); } - } } } diff --git a/src/Widgets/SourceGutterRenderer.vala b/src/Widgets/SourceGutterRenderer.vala index 038e5f0b60..f630291e7f 100644 --- a/src/Widgets/SourceGutterRenderer.vala +++ b/src/Widgets/SourceGutterRenderer.vala @@ -12,7 +12,6 @@ namespace Scratch.Widgets { line_status_map = new Gee.HashMap (); set_size (3); set_visible (true); - } public override void draw (Cairo.Context cr, diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index fee2883954..893fd4854d 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -601,7 +601,7 @@ namespace Scratch.Widgets { refresh_diff_timeout_id = 0; git_diff_gutter_renderer.line_status_map.clear (); project.refresh_diff (ref git_diff_gutter_renderer.line_status_map, location.get_path ()); - queue_draw (); + git_diff_gutter_renderer.queue_draw (); return Source.REMOVE; }); } From 53a443202d016768446947880d295235cc8d322f Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Wed, 5 May 2021 09:31:39 +0100 Subject: [PATCH 25/27] Revert making source_view a property --- src/Services/Document.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Services/Document.vala b/src/Services/Document.vala index 908b719d24..de0ecc77dc 100644 --- a/src/Services/Document.vala +++ b/src/Services/Document.vala @@ -96,7 +96,7 @@ namespace Scratch.Services { } public Gtk.Stack main_stack; - public Scratch.Widgets.SourceView source_view { get; construct; } + public Scratch.Widgets.SourceView source_view; public string original_content; private string last_save_content; From 9222d058d33242b196f6b19d75cdf2c1dbf22dcc Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Fri, 7 May 2021 19:12:38 +0100 Subject: [PATCH 26/27] Initial implementation of project-diff action. * Put project diff in temp doc and display --- src/FolderManager/FileView.vala | 11 +++++++ src/FolderManager/ProjectFolderItem.vala | 15 +++++++++ src/MainWindow.vala | 39 +++++++++++++++++++++++- src/Services/MonitoredRepository.vala | 34 +++++++++++++++++++++ src/Widgets/DocumentView.vala | 7 +++-- 5 files changed, 103 insertions(+), 3 deletions(-) diff --git a/src/FolderManager/FileView.vala b/src/FolderManager/FileView.vala index f29ae68655..35613ecf54 100644 --- a/src/FolderManager/FileView.vala +++ b/src/FolderManager/FileView.vala @@ -192,6 +192,17 @@ namespace Scratch.FolderManager { } } + // Returns diff of entire project associated with param file + public string? get_project_diff (GLib.File? current_doc_file) throws GLib.Error { + GLib.List project_list; + unowned var active_project = get_active_project (current_doc_file, out project_list); + if (active_project != null) { + return active_project.get_project_diff (); + } + + throw new GLib.IOError.FAILED ("Could not determine the active Git project"); + } + public unowned ProjectFolderItem? get_active_project (GLib.File? active_file, out List project_list) { unowned ProjectFolderItem? project = null; diff --git a/src/FolderManager/ProjectFolderItem.vala b/src/FolderManager/ProjectFolderItem.vala index 6bba8383c0..d7bdacd2e8 100644 --- a/src/FolderManager/ProjectFolderItem.vala +++ b/src/FolderManager/ProjectFolderItem.vala @@ -132,6 +132,17 @@ namespace Scratch.FolderManager { if (monitored_repo != null) { menu.append (new ChangeBranchMenu (this)); + var diff_accellabel = new Granite.AccelLabel.from_action_name ( + _("Show Diff"), + MainWindow.ACTION_PREFIX + MainWindow.ACTION_SHOW_DIFF + "::" + ); + + var diff_item = new Gtk.MenuItem () { + action_name = "win.action_show_diff", + action_target = new Variant.string (file.file.get_path ()) + }; + diff_item.add (diff_accellabel); + menu.append (diff_item); } menu.append (new Gtk.SeparatorMenuItem ()); @@ -446,6 +457,10 @@ namespace Scratch.FolderManager { monitored_repo.refresh_diff (doc_path, ref line_status_map); } + public string? get_project_diff () throws GLib.Error { + return monitored_repo.get_project_diff (); + } + private class ChangeBranchMenu : Gtk.MenuItem { public Scratch.Services.MonitoredRepository monitored_repo { get { diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 15134c1182..b4032b20dd 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -90,6 +90,7 @@ namespace Scratch { public const string ACTION_PREVIOUS_TAB = "action_previous_tab"; public const string ACTION_CLEAR_LINES = "action_clear_lines"; public const string ACTION_NEW_BRANCH = "action_new_branch"; + public const string ACTION_SHOW_DIFF = "action_show_diff"; public static Gee.MultiMap action_accelerators = new Gee.HashMultiMap (); @@ -129,7 +130,8 @@ namespace Scratch { { ACTION_NEXT_TAB, action_next_tab }, { ACTION_PREVIOUS_TAB, action_previous_tab }, { ACTION_CLEAR_LINES, action_clear_lines }, - { ACTION_NEW_BRANCH, action_new_branch, "s" } + { ACTION_NEW_BRANCH, action_new_branch, "s" }, + { ACTION_SHOW_DIFF, action_show_diff, "s" } }; public MainWindow (Scratch.Application scratch_app) { @@ -176,6 +178,7 @@ namespace Scratch { action_accelerators.set (ACTION_PREVIOUS_TAB, "Tab"); action_accelerators.set (ACTION_CLEAR_LINES, "K"); //Geany action_accelerators.set (ACTION_NEW_BRANCH + "::", "B"); + action_accelerators.set (ACTION_SHOW_DIFF + "::", "D"); var provider = new Gtk.CssProvider (); provider.load_from_resource ("io/elementary/code/Application.css"); @@ -1025,5 +1028,39 @@ namespace Scratch { folder_manager_view.new_branch (file); } + + private void action_show_diff (SimpleAction action, Variant? param) { + string path = ""; + File? file = null; + if (param != null) { + path = param.get_string (); + } + + if (path == "") { + var current_doc = get_current_document (); + if (current_doc != null) { + file = current_doc.file; + } + } else { + file = File.new_for_path (path); + } + + try { + string diff_text = folder_manager_view.get_project_diff (file); + FileIOStream iostream; + File diff_file = File.new_tmp ("git-diff-XXXXXX.diff", out iostream); + warning ("tmp file name: %s\n", diff_file.get_path ()); + + var ostream = iostream.output_stream; + var dostream = new DataOutputStream (ostream); + dostream.put_string (diff_text); + iostream.close (); + + var doc = new Services.Document (actions, diff_file); + document_view.open_document (doc); + } catch (Error e) { + warning ("Unable to get project diff: %s", e.message); + } + } } } diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index 3fef0900ed..1438aecbac 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -339,5 +339,39 @@ namespace Scratch.Services { } } } + + public string get_project_diff () throws GLib.Error { + var sb = new StringBuilder (""); + var repo_diff_list = new Ggit.Diff.index_to_workdir (git_repo, null, null); + repo_diff_list.print (Ggit.DiffFormatType.PATCH, (delta, hunk, line) => { + unowned var file_diff = delta.get_old_file (); + if (file_diff == null) { + return 0; + } + + if (line != null) { + var delta_type = line.get_origin (); + string prefix = "?"; + switch (delta_type) { + case Ggit.DiffLineType.ADDITION: + prefix = "+"; + break; + case Ggit.DiffLineType.DELETION: + prefix = "-"; + break; + case Ggit.DiffLineType.CONTEXT: + prefix = " "; + break; + default: + break; + } + //TODO Add color according to linetype + sb.append (prefix + line.get_text ()); + } + return 0; + }); + + return sb.str; + } } } diff --git a/src/Widgets/DocumentView.vala b/src/Widgets/DocumentView.vala index 80c97e6ed9..0d88f86f7f 100644 --- a/src/Widgets/DocumentView.vala +++ b/src/Widgets/DocumentView.vala @@ -146,12 +146,13 @@ public class Scratch.Widgets.DocumentView : Granite.Widgets.DynamicNotebook { return unsaved_file_path_builder (extension); } - public void new_document () { + public Services.Document? new_document () { + Services.Document? doc = null; var file = File.new_for_path (unsaved_file_path_builder ()); try { file.create (FileCreateFlags.PRIVATE); - var doc = new Services.Document (window.actions, file); + doc = new Services.Document (window.actions, file); insert_tab (doc, -1); current_document = doc; @@ -161,6 +162,8 @@ public class Scratch.Widgets.DocumentView : Granite.Widgets.DynamicNotebook { } catch (Error e) { critical (e.message); } + + return doc; } public void new_document_from_clipboard (string clipboard) { From 39424097aed90f74f866f3bb66d7716bb40940a9 Mon Sep 17 00:00:00 2001 From: Jeremy Paul Wootten Date: Tue, 26 Oct 2021 19:43:20 +0100 Subject: [PATCH 27/27] Add release appdata --- data/io.elementary.code.appdata.xml.in | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/data/io.elementary.code.appdata.xml.in b/data/io.elementary.code.appdata.xml.in index 0e8e190cb7..493d062893 100644 --- a/data/io.elementary.code.appdata.xml.in +++ b/data/io.elementary.code.appdata.xml.in @@ -26,6 +26,18 @@ + + +

Improvements:

+
    +
  • Add action to show the git diff of the current project in a temporary document
  • +
+

Minor updates:

+
    +
  • Updated translations
  • +
+
+

Fixes: