From 4007fb49c95db0c85c62a5ef7b7e8f04af60e8dc Mon Sep 17 00:00:00 2001 From: jorgemanzo Date: Wed, 24 Jun 2020 20:41:38 -0700 Subject: [PATCH 01/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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/96] 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 b63ab4b065325aa58e01b2cf22e436cefd0a483d Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sat, 8 May 2021 10:18:21 +0100 Subject: [PATCH 27/96] Switch only if no uncommitted, force checkout --- src/FolderManager/ProjectFolderItem.vala | 5 ++++- src/Services/MonitoredRepository.vala | 13 +++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/FolderManager/ProjectFolderItem.vala b/src/FolderManager/ProjectFolderItem.vala index c48685615a..e83e4a9f68 100644 --- a/src/FolderManager/ProjectFolderItem.vala +++ b/src/FolderManager/ProjectFolderItem.vala @@ -125,7 +125,10 @@ namespace Scratch.FolderManager { menu.append (create_submenu_for_new ()); if (monitored_repo != null) { - menu.append (new ChangeBranchMenu (this)); + var branch_menu = new ChangeBranchMenu (this) { + sensitive = !monitored_repo.has_uncommitted + }; + menu.append (branch_menu); } menu.append (new Gtk.SeparatorMenuItem ()); diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index c4e1a469f8..f6da555054 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -63,6 +63,12 @@ namespace Scratch.Services { } } + public bool has_uncommitted { + get { + return file_status_map.size > 0; + } + } + construct { file_status_map = new Gee.HashMap (); status_options = new Ggit.StatusOptions (Ggit.StatusOption.INCLUDE_UNTRACKED | Ggit.StatusOption.RECURSE_UNTRACKED_DIRS, @@ -155,6 +161,13 @@ namespace Scratch.Services { public void change_branch (string new_branch_name) throws Error { var branch = git_repo.lookup_branch (new_branch_name, Ggit.BranchType.LOCAL); git_repo.set_head (((Ggit.Ref)branch).get_name ()); + var options = new Ggit.CheckoutOptions () { + //Ensure documents match checked out branch (deal with potential conflicts/losses beforehand) + strategy = Ggit.CheckoutStrategy.FORCE + }; + + git_repo.checkout_head (options); //Use default options for now + branch_name = new_branch_name; } From 5076dba416ea36966db082d99b2bc5fa397ed5f8 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sat, 8 May 2021 10:30:50 +0100 Subject: [PATCH 28/96] Remove outdated comment --- src/Services/MonitoredRepository.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index f6da555054..78b19ce0b2 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -166,7 +166,7 @@ namespace Scratch.Services { strategy = Ggit.CheckoutStrategy.FORCE }; - git_repo.checkout_head (options); //Use default options for now + git_repo.checkout_head (options); branch_name = new_branch_name; } From 91bc19484ced0438273695cccef58503f648d3a0 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Fri, 21 May 2021 18:18:10 +0100 Subject: [PATCH 29/96] Make background actually transparent as intended --- src/Services/MonitoredRepository.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Services/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index ea554ef593..ad968241ea 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -43,7 +43,7 @@ namespace Scratch.Services { color.parse ("#3689e6"); //Blueberry 500 break; default: - color.parse ("#000000"); //Transparent + color.parse ("#00000000"); //Transparent break; } From abe8b6bc81ef4473a906b9e032ca3e82c4a337d7 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sat, 22 May 2021 10:08:03 +0100 Subject: [PATCH 30/96] Show outline in document not sidebar --- plugins/outline/OutlinePlugin.vala | 112 ++++------------------------- src/Services/Document.vala | 42 +++++++++-- 2 files changed, 53 insertions(+), 101 deletions(-) diff --git a/plugins/outline/OutlinePlugin.vala b/plugins/outline/OutlinePlugin.vala index 4523219740..199918ca75 100644 --- a/plugins/outline/OutlinePlugin.vala +++ b/plugins/outline/OutlinePlugin.vala @@ -21,12 +21,6 @@ namespace Code.Plugins { public Object object { owned get; construct; } Scratch.Services.Interface scratch_interface; - SymbolOutline? current_view = null; - unowned Scratch.MainWindow window; - - OutlinePane? container = null; - - Gee.LinkedList views; private Gtk.Grid placeholder; @@ -41,7 +35,6 @@ namespace Code.Plugins { placeholder.attach (new Gtk.Image.from_icon_name ("plugin-outline-symbolic", Gtk.IconSize.DND), 0, 0); placeholder.attach (placeholder_label, 0, 1); - views = new Gee.LinkedList (); weak Gtk.IconTheme default_theme = Gtk.IconTheme.get_default (); default_theme.add_resource_path ("/io/elementary/code/plugin/outline"); } @@ -49,50 +42,19 @@ namespace Code.Plugins { public void activate () { scratch_interface = (Scratch.Services.Interface)object; scratch_interface.hook_document.connect (on_hook_document); - scratch_interface.hook_window.connect (on_hook_window); } public void deactivate () { - remove_container (); scratch_interface.hook_document.disconnect (on_hook_document); scratch_interface.hook_window.disconnect (on_hook_window); } public void update_state () { - - } - - void on_hook_window (Scratch.MainWindow window) { - if (container != null) { - return; - } - - this.window = window; - - container = new OutlinePane (); - container.add (placeholder); } void on_hook_document (Scratch.Services.Document doc) { - if (current_view != null && - current_view.doc == doc && - current_view.get_source_list ().get_parent () != null) { - - /* Ensure correct source list shown */ - container.set_visible_child (current_view.get_source_list ()); - - return; - } - - SymbolOutline view = null; - foreach (var v in views) { - if (v.doc == doc) { - view = v; - break; - } - } - - if (view == null && doc.file != null) { + if (doc.file != null && !doc.has_extra_widget ()) { + SymbolOutline view = null; var mime_type = doc.mime_type; switch (mime_type) { case "text/x-vala": @@ -107,66 +69,22 @@ namespace Code.Plugins { } if (view != null) { - view.closed.connect (() => {remove_view (view);}); - view.goto.connect (goto); - views.add (view); + view.closed.connect (() => { + doc.remove_extra_widget (view.get_source_list ()); + }); + view.goto.connect ((doc, line) => { + scratch_interface.open_file (doc.file); + + var text = doc.source_view; + Gtk.TextIter iter; + text.buffer.get_iter_at_line (out iter, line - 1); + text.buffer.place_cursor (iter); + text.scroll_to_iter (iter, 0.0, true, 0.5, 0.5); + }); view.parse_symbols (); + doc.add_extra_widget (view.get_source_list ()); } } - - if (view != null) { - var source_list = view.get_source_list (); - if (source_list.parent == null) { - container.add (source_list); - } - - container.set_visible_child (source_list); - container.show_all (); - current_view = view; - add_container (); - } else { - container.set_visible_child (placeholder); - } - } - - void add_container () { - if (container.get_parent () == null) { - window.sidebar.add_tab (container); - container.show_all (); - } - } - - void remove_container () { - var parent = container.get_parent (); - if (parent != null) { - window.sidebar.remove_tab (container); - } - - container.destroy (); - } - - void remove_view (SymbolOutline view) { - views.remove (view); - var source_list = view.get_source_list (); - if (source_list.parent == container) { - container.remove (source_list); - } - - if (views.is_empty) { - remove_container (); - } - - view.goto.disconnect (goto); - } - - void goto (Scratch.Services.Document doc, int line) { - scratch_interface.open_file (doc.file); - - var text = doc.source_view; - Gtk.TextIter iter; - text.buffer.get_iter_at_line (out iter, line - 1); - text.buffer.place_cursor (iter); - text.scroll_to_iter (iter, 0.0, true, 0.5, 0.5); } } } diff --git a/src/Services/Document.vala b/src/Services/Document.vala index 1cfdadebc5..f3d78ea63b 100644 --- a/src/Services/Document.vala +++ b/src/Services/Document.vala @@ -103,6 +103,7 @@ namespace Scratch.Services { private Gtk.ScrolledWindow scroll; private Gtk.InfoBar info_bar; private Gtk.SourceMap source_map; + private Gtk.Paned extra_widget_pane; private GLib.Cancellable save_cancellable; private GLib.Cancellable load_cancellable; @@ -139,11 +140,15 @@ namespace Scratch.Services { main_stack = new Gtk.Stack (); source_view = new Scratch.Widgets.SourceView (); - scroll = new Gtk.ScrolledWindow (null, null); + scroll = new Gtk.ScrolledWindow (null, null) { + expand = true + }; scroll.add (source_view); info_bar = new Gtk.InfoBar (); source_file = new Gtk.SourceFile (); source_map = new Gtk.SourceMap (); + extra_widget_pane = new Gtk.Paned (Gtk.Orientation.HORIZONTAL); + if (builder_blocks_font != null && builder_font_map != null) { source_map.set_font_map (builder_font_map); source_map.font_desc = builder_blocks_font; @@ -166,15 +171,18 @@ namespace Scratch.Services { return working; }); - var source_grid = new Gtk.Grid (); - source_grid.orientation = Gtk.Orientation.HORIZONTAL; + var source_grid = new Gtk.Grid () { + orientation = Gtk.Orientation.HORIZONTAL, + column_homogeneous = false + }; source_grid.add (scroll); source_grid.add (source_map); + extra_widget_pane.pack1 (source_grid, true, false); var doc_grid = new Gtk.Grid (); doc_grid.orientation = Gtk.Orientation.VERTICAL; doc_grid.add (info_bar); - doc_grid.add (source_grid); + doc_grid.add (extra_widget_pane); doc_grid.show_all (); main_stack.add_named (doc_grid, "content"); @@ -920,5 +928,31 @@ namespace Scratch.Services { warning ("Folder containing the file was unmounted"); mounted = false; } + + public bool add_extra_widget (Gtk.Widget extra) { + if (has_extra_widget ()) { + return false; + } else { + //TODO Style the extra widget to match the document. + extra_widget_pane.pack2 (extra, false, false); + var position = int.max (extra_widget_pane.get_allocated_width () * 4 / 5, 100); + extra_widget_pane.set_position (position); + // extra_widget_pane.show_all (); + return true; + } + } + + public bool remove_extra_widget (Gtk.Widget extra) { + if (!has_extra_widget ()) { + return false; + } else { + extra_widget_pane.get_child2 ().unparent (); + return true; + } + } + + public bool has_extra_widget () { + return extra_widget_pane.get_child2 () != null; + } } } From 2b9bd7b3c7be4cfa64e13f856403306b92edced2 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sat, 22 May 2021 11:00:15 +0100 Subject: [PATCH 31/96] Use paned; fix activate/deactivate --- plugins/outline/OutlinePlugin.vala | 19 +++++++++++++------ src/Services/Document.vala | 29 ++++++++++++++--------------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/plugins/outline/OutlinePlugin.vala b/plugins/outline/OutlinePlugin.vala index 199918ca75..cf07169e38 100644 --- a/plugins/outline/OutlinePlugin.vala +++ b/plugins/outline/OutlinePlugin.vala @@ -42,18 +42,28 @@ namespace Code.Plugins { public void activate () { scratch_interface = (Scratch.Services.Interface)object; scratch_interface.hook_document.connect (on_hook_document); + scratch_interface.hook_window.connect (on_hook_window); } public void deactivate () { scratch_interface.hook_document.disconnect (on_hook_document); scratch_interface.hook_window.disconnect (on_hook_window); + scratch_interface.manager.window.document_view.docs.foreach ((doc) => { + doc.remove_outline_widget (); + }); } public void update_state () { } - void on_hook_document (Scratch.Services.Document doc) { - if (doc.file != null && !doc.has_extra_widget ()) { + public void on_hook_window (Scratch.MainWindow window) { + if (window != null) { + on_hook_document (window.get_current_document ()); + } + } + + void on_hook_document (Scratch.Services.Document? doc) { + if (doc != null && doc.file != null && !doc.has_outline_widget ()) { SymbolOutline view = null; var mime_type = doc.mime_type; switch (mime_type) { @@ -69,9 +79,6 @@ namespace Code.Plugins { } if (view != null) { - view.closed.connect (() => { - doc.remove_extra_widget (view.get_source_list ()); - }); view.goto.connect ((doc, line) => { scratch_interface.open_file (doc.file); @@ -82,7 +89,7 @@ namespace Code.Plugins { text.scroll_to_iter (iter, 0.0, true, 0.5, 0.5); }); view.parse_symbols (); - doc.add_extra_widget (view.get_source_list ()); + doc.add_outline_widget (view.get_source_list ()); } } } diff --git a/src/Services/Document.vala b/src/Services/Document.vala index f3d78ea63b..78d394a3a1 100644 --- a/src/Services/Document.vala +++ b/src/Services/Document.vala @@ -103,7 +103,7 @@ namespace Scratch.Services { private Gtk.ScrolledWindow scroll; private Gtk.InfoBar info_bar; private Gtk.SourceMap source_map; - private Gtk.Paned extra_widget_pane; + private Gtk.Paned outline_widget_pane; private GLib.Cancellable save_cancellable; private GLib.Cancellable load_cancellable; @@ -147,7 +147,7 @@ namespace Scratch.Services { info_bar = new Gtk.InfoBar (); source_file = new Gtk.SourceFile (); source_map = new Gtk.SourceMap (); - extra_widget_pane = new Gtk.Paned (Gtk.Orientation.HORIZONTAL); + outline_widget_pane = new Gtk.Paned (Gtk.Orientation.HORIZONTAL); if (builder_blocks_font != null && builder_font_map != null) { source_map.set_font_map (builder_font_map); @@ -177,12 +177,12 @@ namespace Scratch.Services { }; source_grid.add (scroll); source_grid.add (source_map); - extra_widget_pane.pack1 (source_grid, true, false); + outline_widget_pane.pack1 (source_grid, true, false); var doc_grid = new Gtk.Grid (); doc_grid.orientation = Gtk.Orientation.VERTICAL; doc_grid.add (info_bar); - doc_grid.add (extra_widget_pane); + doc_grid.add (outline_widget_pane); doc_grid.show_all (); main_stack.add_named (doc_grid, "content"); @@ -929,30 +929,29 @@ namespace Scratch.Services { mounted = false; } - public bool add_extra_widget (Gtk.Widget extra) { - if (has_extra_widget ()) { + public bool add_outline_widget (Gtk.Widget extra) { + if (has_outline_widget ()) { return false; } else { //TODO Style the extra widget to match the document. - extra_widget_pane.pack2 (extra, false, false); - var position = int.max (extra_widget_pane.get_allocated_width () * 4 / 5, 100); - extra_widget_pane.set_position (position); - // extra_widget_pane.show_all (); + outline_widget_pane.pack2 (extra, false, false); + var position = int.max (outline_widget_pane.get_allocated_width () * 4 / 5, 100); + outline_widget_pane.set_position (position); return true; } } - public bool remove_extra_widget (Gtk.Widget extra) { - if (!has_extra_widget ()) { + public bool remove_outline_widget () { + if (!has_outline_widget ()) { return false; } else { - extra_widget_pane.get_child2 ().unparent (); + outline_widget_pane.get_child2 ().destroy (); return true; } } - public bool has_extra_widget () { - return extra_widget_pane.get_child2 () != null; + public bool has_outline_widget () { + return outline_widget_pane.get_child2 () != null; } } } From ad910d0872938bf1bbc7c4225d843d65ef1b4c14 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sat, 22 May 2021 15:12:38 +0100 Subject: [PATCH 32/96] Set outline object as doc data * Remove unused closed signal --- plugins/outline/C/CtagsSymbolOutline.vala | 9 ----- plugins/outline/OutlinePlugin.vala | 45 ++++++++++++--------- plugins/outline/SymbolOutline.vala | 1 - plugins/outline/Vala/ValaSymbolOutline.vala | 2 - 4 files changed, 26 insertions(+), 31 deletions(-) diff --git a/plugins/outline/C/CtagsSymbolOutline.vala b/plugins/outline/C/CtagsSymbolOutline.vala index 59205380e3..610225ed86 100644 --- a/plugins/outline/C/CtagsSymbolOutline.vala +++ b/plugins/outline/C/CtagsSymbolOutline.vala @@ -26,7 +26,6 @@ public class Code.Plugins.CtagsSymbolOutline : Object, Code.Plugins.SymbolOutlin public CtagsSymbolOutline (Scratch.Services.Document _doc) { doc = _doc; doc.doc_saved.connect (() => {parse_symbols ();}); - doc.doc_closed.connect (doc_closed); root = new Granite.Widgets.SourceList.ExpandableItem (_("Symbols")); @@ -42,14 +41,6 @@ public class Code.Plugins.CtagsSymbolOutline : Object, Code.Plugins.SymbolOutlin }); } - ~CtagsSymbolOutline () { - doc.doc_closed.disconnect (doc_closed); - } - - void doc_closed (Scratch.Services.Document doc) { - closed (); - } - public void parse_symbols () { if (current_subprocess != null) current_subprocess.force_exit (); diff --git a/plugins/outline/OutlinePlugin.vala b/plugins/outline/OutlinePlugin.vala index cf07169e38..041c10da5c 100644 --- a/plugins/outline/OutlinePlugin.vala +++ b/plugins/outline/OutlinePlugin.vala @@ -48,9 +48,7 @@ namespace Code.Plugins { public void deactivate () { scratch_interface.hook_document.disconnect (on_hook_document); scratch_interface.hook_window.disconnect (on_hook_window); - scratch_interface.manager.window.document_view.docs.foreach ((doc) => { - doc.remove_outline_widget (); - }); + scratch_interface.manager.window.document_view.docs.foreach (remove_outline_from_doc); } public void update_state () { @@ -64,35 +62,44 @@ namespace Code.Plugins { void on_hook_document (Scratch.Services.Document? doc) { if (doc != null && doc.file != null && !doc.has_outline_widget ()) { - SymbolOutline view = null; + SymbolOutline outline = null; var mime_type = doc.mime_type; switch (mime_type) { case "text/x-vala": - view = new ValaSymbolOutline (doc); + outline = new ValaSymbolOutline (doc); break; case "text/x-csrc": case "text/x-chdr": case "text/x-c++src": case "text/x-c++hdr": - view = new CtagsSymbolOutline (doc); + outline = new CtagsSymbolOutline (doc); break; } - - if (view != null) { - view.goto.connect ((doc, line) => { - scratch_interface.open_file (doc.file); - - var text = doc.source_view; - Gtk.TextIter iter; - text.buffer.get_iter_at_line (out iter, line - 1); - text.buffer.place_cursor (iter); - text.scroll_to_iter (iter, 0.0, true, 0.5, 0.5); - }); - view.parse_symbols (); - doc.add_outline_widget (view.get_source_list ()); + if (outline != null) { + add_outline_to_doc (doc, outline); } } } + + private void add_outline_to_doc (Scratch.Services.Document doc, SymbolOutline outline) { + outline.goto.connect ((doc, line) => { + scratch_interface.open_file (doc.file); + + var text = doc.source_view; + Gtk.TextIter iter; + text.buffer.get_iter_at_line (out iter, line - 1); + text.buffer.place_cursor (iter); + text.scroll_to_iter (iter, 0.0, true, 0.5, 0.5); + }); + outline.parse_symbols (); + doc.add_outline_widget (outline.get_source_list ()); + doc.set_data ("SymbolOutline", outline); + } + + private void remove_outline_from_doc (Scratch.Services.Document doc) { + doc.remove_outline_widget (); + doc.steal_data ("SymbolOutline"); + } } } diff --git a/plugins/outline/SymbolOutline.vala b/plugins/outline/SymbolOutline.vala index b024175453..ec3948561c 100644 --- a/plugins/outline/SymbolOutline.vala +++ b/plugins/outline/SymbolOutline.vala @@ -20,6 +20,5 @@ public interface Code.Plugins.SymbolOutline : Object { public abstract Scratch.Services.Document doc { get; protected set; } public abstract void parse_symbols (); public abstract Granite.Widgets.SourceList get_source_list (); - public signal void closed (); public signal void goto (Scratch.Services.Document doc, int line); } diff --git a/plugins/outline/Vala/ValaSymbolOutline.vala b/plugins/outline/Vala/ValaSymbolOutline.vala index 94c38401ed..d3954cd32f 100644 --- a/plugins/outline/Vala/ValaSymbolOutline.vala +++ b/plugins/outline/Vala/ValaSymbolOutline.vala @@ -51,8 +51,6 @@ public class Code.Plugins.ValaSymbolOutline : Object, Code.Plugins.SymbolOutline cancellable.cancel (); cancellable = null; } - - closed (); } public Granite.Widgets.SourceList get_source_list () { From 39fc0c580cf4832af0aafa78e06cb64277a479b9 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sun, 23 May 2021 09:48:57 +0100 Subject: [PATCH 33/96] Use selected or searchentry text for global search --- src/Dialogs/GlobalSearchDialog.vala | 11 ++++++++++- src/FolderManager/FileView.vala | 4 ++-- src/FolderManager/ProjectFolderItem.vala | 19 ++++++++++--------- src/MainWindow.vala | 13 ++++++++----- src/Widgets/SearchBar.vala | 4 ---- 5 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/Dialogs/GlobalSearchDialog.vala b/src/Dialogs/GlobalSearchDialog.vala index 7c048e6f6e..50d604d6f8 100644 --- a/src/Dialogs/GlobalSearchDialog.vala +++ b/src/Dialogs/GlobalSearchDialog.vala @@ -26,7 +26,16 @@ public class Scratch.Dialogs.GlobalSearchDialog : Granite.MessageDialog { private Gtk.Switch case_switch; private Gtk.Switch regex_switch; - public string search_term { get {return search_term_entry.text;} } + public string search_term { + get { + return search_term_entry.text; + } + + set { + search_term_entry.text = value; + } + } + public bool use_regex { get { return regex_switch.active; diff --git a/src/FolderManager/FileView.vala b/src/FolderManager/FileView.vala index e81011a212..020e26b0c2 100644 --- a/src/FolderManager/FileView.vala +++ b/src/FolderManager/FileView.vala @@ -145,12 +145,12 @@ namespace Scratch.FolderManager { } /* Do global search on project containing the file path supplied in parameter */ - public void search_global (string path) { + public void search_global (string path, string? term = null) { var item_for_path = (Item?)(expand_to_path (path)); if (item_for_path != null) { var search_root = item_for_path.get_root_folder (); if (search_root is ProjectFolderItem) { - search_root.global_search (search_root.file.file); + search_root.global_search (search_root.file.file, term); } } } diff --git a/src/FolderManager/ProjectFolderItem.vala b/src/FolderManager/ProjectFolderItem.vala index f287c43628..28f471dc27 100644 --- a/src/FolderManager/ProjectFolderItem.vala +++ b/src/FolderManager/ProjectFolderItem.vala @@ -241,10 +241,10 @@ namespace Scratch.FolderManager { return is_git_repo ? monitored_repo.is_valid_new_local_branch_name (new_name) : false; } - public void global_search (GLib.File start_folder = this.file.file) { + public void global_search (GLib.File start_folder = this.file.file, string? term = null) { /* For now set all options to the most inclusive (except case). * The ability to set these in the dialog (or by parameter) may be added later. */ - string? term = null; + string? search_term = null; bool use_regex = false; bool search_tracked_only = false; bool recurse_subfolders = true; @@ -258,13 +258,14 @@ namespace Scratch.FolderManager { null, start_folder.get_basename (), monitored_repo.git_repo != null ) { case_sensitive = case_sensitive, - use_regex = use_regex + use_regex = use_regex, + search_term = term }; dialog.response.connect ((response) => { switch (response) { case Gtk.ResponseType.ACCEPT: - term = dialog.search_term; + search_term = dialog.search_term; use_regex = dialog.use_regex; case_sensitive = dialog.case_sensitive; break; @@ -279,15 +280,15 @@ namespace Scratch.FolderManager { dialog.run (); - if (term != null) { + if (search_term != null) { /* Put search term in search bar to help user locate the position of the matches in each doc */ - var search_variant = new Variant.string (term); + var search_variant = new Variant.string (search_term); var app = (Gtk.Application)GLib.Application.get_default (); var win = (Scratch.MainWindow)(app.get_active_window ()); win.actions.lookup_action ("action_find").activate (search_variant); if (!use_regex) { - term = Regex.escape_string (term); + search_term = Regex.escape_string (search_term); } try { @@ -296,9 +297,9 @@ namespace Scratch.FolderManager { flags |= RegexCompileFlags.CASELESS; } - pattern = new Regex (term, flags); + pattern = new Regex (search_term, flags); } catch (Error e) { - critical ("Error creating regex from '%s': %s", term, e.message); + critical ("Error creating regex from '%s': %s", search_term, e.message); return; } } else { diff --git a/src/MainWindow.vala b/src/MainWindow.vala index a254adccda..6ef4a1f5c6 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -287,7 +287,7 @@ namespace Scratch { set_search_text (); }); search_bar.search_entry.unmap.connect_after (() => { /* signalled when reveal child */ - search_bar.set_search_string (""); + search_bar.search_entry.text = ""; search_bar.highlight_none (); }); search_bar.search_empty.connect (() => { @@ -881,19 +881,22 @@ namespace Scratch { path = param.get_string (); } + var current_doc = get_current_document (); + var selected_text = current_doc.get_selected_text (); + + string term = selected_text != "" ? selected_text : search_bar.search_entry.text; if (path == "") { - var current_doc = get_current_document (); if (current_doc != null) { path = current_doc.file.get_path (); } } - folder_manager_view.search_global (path); + folder_manager_view.search_global (path, term); } private void set_search_text () { if (current_search_term != "") { - search_bar.set_search_string (current_search_term); + search_bar.search_entry.text = current_search_term; search_bar.search_entry.grab_focus (); search_bar.search_next (); } else { @@ -903,7 +906,7 @@ namespace Scratch { var selected_text = current_doc.get_selected_text (); if (selected_text != "" && selected_text.length < MAX_SEARCH_TEXT_LENGTH) { current_search_term = selected_text; - search_bar.set_search_string (current_search_term); + search_bar.search_entry.text = current_search_term; } search_bar.search_entry.grab_focus (); /* causes loss of document selection */ diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index e06ef12e09..acadea6cfa 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -240,10 +240,6 @@ namespace Scratch.Widgets { this.window.get_current_document ().toggle_changed_handlers (true); } - public void set_search_string (string to_search) { - search_entry.text = to_search; - } - private void on_search_entry_text_changed () { var search_string = search_entry.text; search_context.settings.search_text = search_string; From fa81ddf425295f07a52ef99bebd42c8d6eeeb04f Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sun, 23 May 2021 10:11:39 +0100 Subject: [PATCH 34/96] Add global search button to search bar --- src/Widgets/SearchBar.vala | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index acadea6cfa..5bcccb4066 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -40,6 +40,8 @@ namespace Scratch.Widgets { private Gtk.Button replace_tool_button; private Gtk.Button replace_all_tool_button; + private Gtk.Button global_search_button; + private Scratch.Widgets.SourceView? text_view = null; private Gtk.TextBuffer? text_buffer = null; private Gtk.SourceSearchContext search_context = null; @@ -104,6 +106,12 @@ namespace Scratch.Widgets { ); case_sensitive_button.clicked.connect (on_search_entry_text_changed); + global_search_button = new Gtk.Button.from_icon_name ("gnome-globe") { + tooltip_markup = Granite.markup_accel_tooltip ({"F"}, "Global Search"), + action_name = "win.action_find_global", + action_target = new Variant.string ("") // Search in current active project + }; + var search_grid = new Gtk.Grid (); search_grid.margin = 3; search_grid.get_style_context ().add_class (Gtk.STYLE_CLASS_LINKED); @@ -112,6 +120,7 @@ namespace Scratch.Widgets { search_grid.add (tool_arrow_up); search_grid.add (tool_cycle_search); search_grid.add (case_sensitive_button); + search_grid.add (global_search_button); var search_flow_box_child = new Gtk.FlowBoxChild (); search_flow_box_child.can_focus = false; From e9ab5c25e901900d95f177020db894b9907757bd Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sun, 23 May 2021 10:27:07 +0100 Subject: [PATCH 35/96] Search term from focused widget --- src/MainWindow.vala | 5 ++++- src/Widgets/SearchBar.vala | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 6ef4a1f5c6..afb88c3a9d 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -884,7 +884,10 @@ namespace Scratch { var current_doc = get_current_document (); var selected_text = current_doc.get_selected_text (); - string term = selected_text != "" ? selected_text : search_bar.search_entry.text; + var term = search_bar.search_entry.has_focus ? + search_bar.search_entry.text : + selected_text; + if (path == "") { if (current_doc != null) { path = current_doc.file.get_path (); diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 5bcccb4066..2ee8ddf8ba 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -107,11 +107,17 @@ namespace Scratch.Widgets { case_sensitive_button.clicked.connect (on_search_entry_text_changed); global_search_button = new Gtk.Button.from_icon_name ("gnome-globe") { + can_focus = false, tooltip_markup = Granite.markup_accel_tooltip ({"F"}, "Global Search"), action_name = "win.action_find_global", action_target = new Variant.string ("") // Search in current active project }; + global_search_button.button_press_event.connect (() => { + search_entry.grab_focus (); + return false; + }); + var search_grid = new Gtk.Grid (); search_grid.margin = 3; search_grid.get_style_context ().add_class (Gtk.STYLE_CLASS_LINKED); From 03174727c163e5ec665869df6a9aac166ffdcf25 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sun, 23 May 2021 10:49:23 +0100 Subject: [PATCH 36/96] Fallback to searchentry when no focused selected text --- src/MainWindow.vala | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index afb88c3a9d..60b98ba6ba 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -884,10 +884,19 @@ namespace Scratch { var current_doc = get_current_document (); var selected_text = current_doc.get_selected_text (); + // If search entry focused use its text for search term, else use selected text var term = search_bar.search_entry.has_focus ? search_bar.search_entry.text : selected_text; + // If no focused selected text fallback to search entry text if visible + if (term == "" && + !search_bar.search_entry.has_focus && + search_revealer.reveal_child) { + + term = search_bar.search_entry.text; + } + if (path == "") { if (current_doc != null) { path = current_doc.file.get_path (); From 862af6511f5b4c9d36a1e549b4eaa65bc4eca1b5 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Wed, 26 May 2021 17:20:05 +0100 Subject: [PATCH 37/96] src/Widgets/SourceGutterRenderer.vala: Inline namespace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Foré --- src/Widgets/SourceGutterRenderer.vala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Widgets/SourceGutterRenderer.vala b/src/Widgets/SourceGutterRenderer.vala index f630291e7f..ad21dcfba4 100644 --- a/src/Widgets/SourceGutterRenderer.vala +++ b/src/Widgets/SourceGutterRenderer.vala @@ -1,5 +1,4 @@ -namespace Scratch.Widgets { - public class SourceGutterRenderer : Gtk.SourceGutterRenderer { + public class Scratch.Widgets.SourceGutterRenderer : Gtk.SourceGutterRenderer { public Gee.HashMap line_status_map; public FolderManager.ProjectFolderItem? project { get; set; default = null; } public string workdir_path { From c1d326fade271ea93c2e8d92cdc9556a62473138 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Wed, 26 May 2021 17:30:42 +0100 Subject: [PATCH 38/96] Minor cleanups --- src/MainWindow.vala | 2 +- src/Services/MonitoredRepository.vala | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index dfda425d8c..dc81661a90 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/MonitoredRepository.vala b/src/Services/MonitoredRepository.vala index ad968241ea..ce3d769941 100644 --- a/src/Services/MonitoredRepository.vala +++ b/src/Services/MonitoredRepository.vala @@ -273,7 +273,6 @@ 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 (); var status_map = line_status_map; int prev_deletions = 0; From 7b8460c80347ed0036cf39ecad9ff76b4d51d277 Mon Sep 17 00:00:00 2001 From: micahilbery Date: Wed, 30 Jun 2021 21:13:14 -0500 Subject: [PATCH 39/96] add custom elementary syntax styles --- data/io.elementary.code.gschema.xml | 2 +- data/meson.build | 5 ++ data/styles/elementary-dark.xml | 88 +++++++++++++++++++++++++++++ data/styles/elementary-light.xml | 88 +++++++++++++++++++++++++++++ src/Widgets/HeaderBar.vala | 4 +- 5 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 data/styles/elementary-dark.xml create mode 100644 data/styles/elementary-light.xml diff --git a/data/io.elementary.code.gschema.xml b/data/io.elementary.code.gschema.xml index 6ec10220c8..29a53f620a 100644 --- a/data/io.elementary.code.gschema.xml +++ b/data/io.elementary.code.gschema.xml @@ -121,7 +121,7 @@ Set the preferred font. - 'solarized-light' + 'elementary-light' Preferred Style Scheme Set the preferred style scheme. diff --git a/data/meson.build b/data/meson.build index c2ff0c2881..471d1eea6c 100644 --- a/data/meson.build +++ b/data/meson.build @@ -11,6 +11,11 @@ foreach i : icon_sizes ) endforeach +install_data([ + 'styles/elementary-dark.xml', + 'styles/elementary-light.xml', +], install_dir: join_paths(get_option('datadir'), 'gtksourceview-4', 'styles')) + install_data([ 'fonts/BuilderBlocks.ttf', ], install_dir: join_paths(get_option('datadir'), meson.project_name(), 'fonts')) diff --git a/data/styles/elementary-dark.xml b/data/styles/elementary-dark.xml new file mode 100644 index 0000000000..684169181b --- /dev/null +++ b/data/styles/elementary-dark.xml @@ -0,0 +1,88 @@ + + + + Micah Ilbery + <_description>Color scheme using the elementary color palette + + + + + + + + + + + + + + + + + + + + + + +