[gitg/wip/albfan/keyboard-stage] Add keyboard for diff selection
- From: Alberto Fanjul <albfan src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gitg/wip/albfan/keyboard-stage] Add keyboard for diff selection
- Date: Fri, 30 Sep 2022 07:19:36 +0000 (UTC)
commit 43a59cbc3151fe66dc6992cbe2f3a609b01c6e6e
Author: Alberto Fanjul <albertofanjul gmail com>
Date: Sat Sep 3 11:48:02 2022 +0200
Add keyboard for diff selection
gitg/commit/gitg-commit.vala | 31 +++++-
.../gitg-diff-view-file-renderer-text-split.vala | 29 +++---
libgitg/gitg-diff-view-file-renderer-text.vala | 19 +++-
libgitg/gitg-diff-view-file-selectable.vala | 110 ++++++++++++++++++---
libgitg/gitg-diff-view.vala | 89 +++++++++++++++++
libgitg/gitg-sidebar.vala | 16 ++-
6 files changed, 261 insertions(+), 33 deletions(-)
---
diff --git a/gitg/commit/gitg-commit.vala b/gitg/commit/gitg-commit.vala
index cb561a09..eb0d435e 100644
--- a/gitg/commit/gitg-commit.vala
+++ b/gitg/commit/gitg-commit.vala
@@ -143,14 +143,43 @@ namespace GitgCommit
public bool on_key_pressed (Gdk.EventKey event) {
var mmask = Gtk.accelerator_get_default_mod_mask();
+ var modifiers = event.state;
+ bool control = Gdk.ModifierType.CONTROL_MASK in modifiers;
+ bool shift = Gdk.ModifierType.SHIFT_MASK in modifiers;
- if ((mmask & event.state) == Gdk.ModifierType.CONTROL_MASK)
+ if (control && shift)
+ {
+ if (event.keyval == Gdk.Key.Up)
+ {
+ d_main.diff_view.move_highlight_mark_up ();
+ return true;
+ } else if (event.keyval == Gdk.Key.Down)
+ {
+ d_main.diff_view.move_highlight_mark_down ();
+ return true;
+ } else if (event.keyval == Gdk.Key.Right)
+ {
+ d_main.diff_view.move_highlight_mark_right ();
+ return true;
+ } else if (event.keyval == Gdk.Key.Left)
+ {
+ d_main.diff_view.move_highlight_mark_left ();
+ return true;
+ }
+ }
+
+ if (control)
{
if ((event.keyval == Gdk.Key.Return || event.keyval == Gdk.Key.KP_Enter))
{
on_commit_clicked ();
return true;
}
+ else if ((event.keyval == Gdk.Key.space || event.keyval == Gdk.Key.KP_Space))
+ {
+ d_main.diff_view.selection_update (shift);
+ return true;
+ }
}
return false;
}
diff --git a/libgitg/gitg-diff-view-file-renderer-text-split.vala
b/libgitg/gitg-diff-view-file-renderer-text-split.vala
index 4d1bafcc..97edb1ae 100644
--- a/libgitg/gitg-diff-view-file-renderer-text-split.vala
+++ b/libgitg/gitg-diff-view-file-renderer-text-split.vala
@@ -25,8 +25,8 @@ class Gitg.DiffViewFileRendererTextSplit : Gtk.Box, DiffSelectable, DiffViewFile
[GtkChild( name = "scroll_right" )]
private unowned Gtk.ScrolledWindow d_scroll_right;
- private Gitg.DiffViewFileRendererText d_renderer_left;
- private Gitg.DiffViewFileRendererText d_renderer_right;
+ public Gitg.DiffViewFileRendererText d_renderer_left;
+ public Gitg.DiffViewFileRendererText d_renderer_right;
public DiffViewFileInfo info { get; construct set; }
@@ -107,12 +107,6 @@ class Gitg.DiffViewFileRendererTextSplit : Gtk.Box, DiffSelectable, DiffViewFile
d_scroll_right.add(d_renderer_right);
}
- construct
- {
- //can_select = d_renderer_left.can_select() || d_renderer_right.can_select();
- can_select = false;
- }
-
public void add_hunk(Ggit.DiffHunk hunk, Gee.ArrayList<Ggit.DiffLine> lines)
{
d_renderer_left.add_hunk(hunk, lines);
@@ -123,8 +117,7 @@ class Gitg.DiffViewFileRendererTextSplit : Gtk.Box, DiffSelectable, DiffViewFile
{
get
{
- //return d_renderer_left.has_selection() || d_renderer_right.has_selection();
- return false;
+ return d_renderer_left.has_selection || d_renderer_right.has_selection;
}
}
@@ -132,17 +125,21 @@ class Gitg.DiffViewFileRendererTextSplit : Gtk.Box, DiffSelectable, DiffViewFile
{
}
- public bool can_select { get; construct set; }
+ public bool can_select {
+ get {
+ return d_renderer_left.can_select || d_renderer_right.can_select;
+ }
+ construct set {}
+ }
public PatchSet selection
{
owned get
{
- /*if (d_renderer_left.has_selection())
- return d_renderer_left.get_selection();
- if (d_renderer_right.has_selection())
- return d_renderer_right.get_selection();
- */
+ if (d_renderer_left.has_selection)
+ return d_renderer_left.selection;
+ if (d_renderer_right.has_selection)
+ return d_renderer_right.selection;
return new PatchSet();
}
}
diff --git a/libgitg/gitg-diff-view-file-renderer-text.vala b/libgitg/gitg-diff-view-file-renderer-text.vala
index fe6c15d7..e9009c56 100644
--- a/libgitg/gitg-diff-view-file-renderer-text.vala
+++ b/libgitg/gitg-diff-view-file-renderer-text.vala
@@ -185,7 +185,7 @@ class Gitg.DiffViewFileRendererText : Gtk.SourceView, DiffSelectable, DiffViewFi
public DiffViewFileRendererText(DiffViewFileInfo info, bool can_select, Style style)
{
- Object(info: info, can_select: can_select, d_style: style);
+ Object(info: info, can_select: can_select, d_style: style, show_line_marks: true);
}
construct
@@ -260,6 +260,21 @@ class Gitg.DiffViewFileRendererText : Gtk.SourceView, DiffSelectable, DiffViewFi
highlight = true;
}
+ public void move_highlight_mark_down ()
+ {
+ d_selectable.move_highlight_mark_down ();
+ }
+
+ public void move_highlight_mark_up ()
+ {
+ d_selectable.move_highlight_mark_up ();
+ }
+
+ public void selection_update (bool shiftPressed)
+ {
+ d_selectable.selection_update (shiftPressed);
+ }
+
protected override void dispose()
{
base.dispose();
@@ -652,6 +667,7 @@ class Gitg.DiffViewFileRendererText : Gtk.SourceView, DiffSelectable, DiffViewFi
var header_attributes = new Gtk.SourceMarkAttributes();
var added_attributes = new Gtk.SourceMarkAttributes();
var removed_attributes = new Gtk.SourceMarkAttributes();
+ var empty_attributes = new Gtk.SourceMarkAttributes();
var dark = new Theme().is_theme_dark();
@@ -671,6 +687,7 @@ class Gitg.DiffViewFileRendererText : Gtk.SourceView, DiffSelectable, DiffViewFi
this.set_mark_attributes("header", header_attributes, 0);
this.set_mark_attributes("added", added_attributes, 0);
this.set_mark_attributes("removed", removed_attributes, 0);
+ this.set_mark_attributes("empty", empty_attributes, 0);
}
protected override void constructed()
diff --git a/libgitg/gitg-diff-view-file-selectable.vala b/libgitg/gitg-diff-view-file-selectable.vala
index c80fe9a5..bcf11eb0 100644
--- a/libgitg/gitg-diff-view-file-selectable.vala
+++ b/libgitg/gitg-diff-view-file-selectable.vala
@@ -26,6 +26,7 @@ enum Gitg.DiffSelectionMode {
class Gitg.DiffViewFileSelectable : Object
{
private string d_selection_category = "selection";
+ private string d_highlight_category = "highlight";
private Gtk.TextTag d_selection_tag;
private DiffSelectionMode d_selection_mode;
private Gtk.TextMark d_start_selection_mark;
@@ -138,6 +139,8 @@ class Gitg.DiffViewFileSelectable : Object
private void update_theme()
{
var selection_attributes = new Gtk.SourceMarkAttributes();
+ var highlight_attributes = new Gtk.SourceMarkAttributes();
+ highlight_attributes.icon_name = "pan-end-symbolic";
var context = source_view.get_style_context();
Gdk.RGBA theme_selected_bg_color, theme_selected_fg_color;
@@ -146,13 +149,14 @@ class Gitg.DiffViewFileSelectable : Object
{
selection_attributes.background = theme_selected_bg_color;
}
-
+
if (context.lookup_color("theme_selected_fg_color", out theme_selected_fg_color))
{
d_selection_tag.foreground_rgba = theme_selected_fg_color;
}
- source_view.set_mark_attributes(d_selection_category, selection_attributes, 0);
+ source_view.set_mark_attributes(d_highlight_category, highlight_attributes, 0);
+ source_view.set_mark_attributes(d_selection_category, selection_attributes, 1);
}
private bool get_line_selected(Gtk.TextIter iter)
@@ -273,6 +277,11 @@ class Gitg.DiffViewFileSelectable : Object
}
buffer.apply_tag(d_selection_tag, current, line_end);
+ Gtk.TextIter start_iter, end_iter;
+ buffer.get_start_iter (out start_iter);
+ buffer.get_end_iter (out end_iter);
+ buffer.remove_source_marks (start_iter, end_iter,
d_highlight_category);
+ buffer.create_source_mark(null, d_highlight_category, current);
}
}
@@ -359,6 +368,80 @@ class Gitg.DiffViewFileSelectable : Object
update_selection_range(iter, end, select);
}
+ public void move_highlight_mark_up() {
+ Gtk.TextIter start_iter, end_iter;
+ var buffer = source_view.buffer as Gtk.SourceBuffer;
+ buffer.get_start_iter (out start_iter);
+ buffer.get_end_iter (out end_iter);
+
+ Gtk.TextIter iter;
+ buffer.get_start_iter (out iter);
+ if (buffer.forward_iter_to_source_mark (ref iter, d_highlight_category))
+ {
+ iter.backward_line ();
+ }
+ while (iter.get_line () >= start_iter.get_line ())
+ {
+ if (get_line_is_diff(iter))
+ {
+ buffer.remove_source_marks (start_iter, end_iter, d_highlight_category);
+ buffer.create_source_mark(null, d_highlight_category, iter);
+ break;
+ }
+ if (!iter.backward_line ())
+ {
+ break;
+ }
+ }
+ }
+
+ public void move_highlight_mark_down() {
+ Gtk.TextIter start_iter, end_iter;
+ var buffer = source_view.buffer as Gtk.SourceBuffer;
+ buffer.get_start_iter (out start_iter);
+ buffer.get_end_iter (out end_iter);
+
+ Gtk.TextIter iter;
+ buffer.get_start_iter(out iter);
+ if (buffer.forward_iter_to_source_mark (ref iter, d_highlight_category))
+ {
+ iter.forward_line ();
+ }
+ while (iter.get_line () <= end_iter.get_line ())
+ {
+ if (get_line_is_diff(iter))
+ {
+ buffer.remove_source_marks (start_iter, end_iter, d_highlight_category);
+ buffer.create_source_mark(null, d_highlight_category, iter);
+ break;
+ }
+ if (!iter.forward_line ())
+ {
+ break;
+ }
+ }
+ }
+
+ public void selection_update(bool shiftPressed)
+ {
+ var buffer = source_view.buffer as Gtk.SourceBuffer;
+ Gtk.TextIter iter;
+ buffer.get_start_iter (out iter);
+ if (buffer.forward_iter_to_source_mark (ref iter, d_highlight_category))
+ {
+ if (shiftPressed)
+ {
+ update_selection(iter);
+ }
+ else
+ {
+ toggle_selection(iter);
+ }
+ update_has_selection();
+ //TODO: Allow to highlight hunks to select them with shortcuts
+ }
+ }
+
private bool button_press_event_on_view(Gdk.EventButton event)
{
if (event.button != 1)
@@ -375,7 +458,9 @@ class Gitg.DiffViewFileSelectable : Object
var buffer = source_view.buffer;
- if ((event.state & Gdk.ModifierType.SHIFT_MASK) != 0)
+ var mmask = Gtk.accelerator_get_default_mod_mask();
+
+ if ((mmask & event.state) == Gdk.ModifierType.SHIFT_MASK)
{
update_selection(iter);
return true;
@@ -388,17 +473,16 @@ class Gitg.DiffViewFileSelectable : Object
}
d_is_rubber_band = true;
+ toggle_selection(iter);
+ return true;
+ }
- var select = !get_line_selected(iter);
+ private void toggle_selection(Gtk.TextIter iter)
+ {
+ var buffer = source_view.buffer;
+ var select = get_line_selected(iter);
- if (select)
- {
- d_selection_mode = DiffSelectionMode.SELECTING;
- }
- else
- {
- d_selection_mode = DiffSelectionMode.DESELECTING;
- }
+ d_selection_mode = select ? DiffSelectionMode.DESELECTING : DiffSelectionMode.SELECTING;
d_originally_selected.clear();
@@ -406,8 +490,6 @@ class Gitg.DiffViewFileSelectable : Object
buffer.move_mark(d_end_selection_mark, iter);
update_selection(iter);
-
- return true;
}
private void update_selection(Gtk.TextIter cursor)
diff --git a/libgitg/gitg-diff-view.vala b/libgitg/gitg-diff-view.vala
index 0894bd26..3568c4db 100644
--- a/libgitg/gitg-diff-view.vala
+++ b/libgitg/gitg-diff-view.vala
@@ -1070,6 +1070,95 @@ public class Gitg.DiffView : Gtk.Grid
}
}
+ public void move_highlight_mark_down ()
+ {
+ //TODO: select only the current one
+ //TODO: There's a selection for any of them
+ //TODO: Remove all this pile of function call
+ //Make sure highlight file is shown (scroll)
+ foreach (var file in d_grid_files.get_children())
+ {
+ var renderer_list = (file as Gitg.DiffViewFile).renderer_list;
+ foreach (DiffViewFileRenderer renderer in renderer_list)
+ {
+ Gitg.DiffViewFileRendererText renderer_text = null;
+ if (renderer is DiffViewFileRendererText)
+ renderer_text = renderer as DiffViewFileRendererText;
+ else if (renderer is DiffViewFileRendererTextSplit) {
+ if (left)
+ renderer_text = (renderer as
DiffViewFileRendererTextSplit).d_renderer_left;
+ else
+ renderer_text = (renderer as
DiffViewFileRendererTextSplit).d_renderer_right;
+ }
+ if(renderer_text == null) {
+ continue;
+ }
+ renderer_text.move_highlight_mark_down ();
+ }
+ }
+ }
+
+ public void move_highlight_mark_up ()
+ {
+ //TODO: select only the current one
+ foreach (var file in d_grid_files.get_children())
+ {
+ var renderer_list = (file as Gitg.DiffViewFile).renderer_list;
+ foreach (DiffViewFileRenderer renderer in renderer_list)
+ {
+ Gitg.DiffViewFileRendererText renderer_text = null;
+ if (renderer is DiffViewFileRendererText)
+ renderer_text = renderer as DiffViewFileRendererText;
+ else if (renderer is DiffViewFileRendererTextSplit) {
+ if (left)
+ renderer_text = (renderer as
DiffViewFileRendererTextSplit).d_renderer_left;
+ else
+ renderer_text = (renderer as
DiffViewFileRendererTextSplit).d_renderer_right;
+ }
+ if(renderer_text == null) {
+ continue;
+ }
+ renderer_text.move_highlight_mark_up ();
+ }
+ }
+ }
+
+ bool left = true;
+
+ public void move_highlight_mark_right ()
+ {
+ left = false;
+ }
+
+ public void move_highlight_mark_left ()
+ {
+ left = true;
+ }
+
+ public void selection_update (bool shiftPressed)
+ {
+ //TODO: select only the current one
+ foreach (var file in d_grid_files.get_children())
+ {
+ var renderer_list = (file as Gitg.DiffViewFile).renderer_list;
+ foreach (DiffViewFileRenderer renderer in renderer_list)
+ {
+ Gitg.DiffViewFileRendererText renderer_text = null;
+ if (renderer is DiffViewFileRendererText)
+ renderer_text = renderer as DiffViewFileRendererText;
+ else if (renderer is DiffViewFileRendererTextSplit) {
+ if (left)
+ renderer_text = (renderer as
DiffViewFileRendererTextSplit).d_renderer_left;
+ else
+ renderer_text = (renderer as
DiffViewFileRendererTextSplit).d_renderer_right;
+ }
+ if(renderer_text == null) {
+ continue;
+ }
+ renderer_text.selection_update (shiftPressed);
+ }
+ }
+ }
private void update_hide_show_options(Gdk.Window window, int ex, int ey)
{
void *data;
diff --git a/libgitg/gitg-sidebar.vala b/libgitg/gitg-sidebar.vala
index deebbeae..f20c14ef 100644
--- a/libgitg/gitg-sidebar.vala
+++ b/libgitg/gitg-sidebar.vala
@@ -423,7 +423,21 @@ public class Sidebar : Gtk.TreeView
protected override bool key_press_event(Gdk.EventKey event)
{
- if ((event.state & Gtk.accelerator_get_default_mod_mask()) != 0)
+ var mmask = Gtk.accelerator_get_default_mod_mask();
+ var modifiers = event.state;
+
+ if (Gdk.ModifierType.CONTROL_MASK in modifiers && Gdk.ModifierType.SHIFT_MASK in modifiers
+ && (event.keyval == Gdk.Key.Up || event.keyval == Gdk.Key.Down))
+ {
+ return false;
+ }
+
+ if (Gdk.ModifierType.CONTROL_MASK in modifiers && (event.keyval == Gdk.Key.space ||
event.keyval == Gdk.Key.KP_Space))
+ {
+ return false;
+ }
+
+ if ((event.state & mmask) != 0)
{
return base.key_press_event(event);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]