[gnome-builder] libide/sourceview: add select-line/delete-line actions
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] libide/sourceview: add select-line/delete-line actions
- Date: Mon, 5 Sep 2022 22:11:05 +0000 (UTC)
commit 8b6ce34dbeba5c140d1ae1d8f6168ccae6297f45
Author: Christian Hergert <chergert redhat com>
Date: Mon Sep 5 15:10:57 2022 -0700
libide/sourceview: add select-line/delete-line actions
Related #1760
src/libide/sourceview/gtk/menus.ui | 10 ++++
src/libide/sourceview/ide-source-view.c | 82 +++++++++++++++++++++++++++++++++
2 files changed, 92 insertions(+)
---
diff --git a/src/libide/sourceview/gtk/menus.ui b/src/libide/sourceview/gtk/menus.ui
index 728a80613..0a07b7ac0 100644
--- a/src/libide/sourceview/gtk/menus.ui
+++ b/src/libide/sourceview/gtk/menus.ui
@@ -108,6 +108,16 @@
<section id="ide-source-view-popup-menu-line-section">
<attribute name="page" translatable="yes">Text Editor</attribute>
<attribute name="group" translatable="yes">Selection</attribute>
+ <item>
+ <attribute name="label" translatable="yes">Select _Line</attribute>
+ <attribute name="action">buffer.select-line</attribute>
+ <attribute name="accel"><control>l</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">_Delete Line</attribute>
+ <attribute name="action">buffer.delete-line</attribute>
+ <attribute name="accel"><control>d</attribute>
+ </item>
<item>
<attribute name="label" translatable="yes">_Join Lines</attribute>
<attribute name="action">selection.join</attribute>
diff --git a/src/libide/sourceview/ide-source-view.c b/src/libide/sourceview/ide-source-view.c
index 683380fc5..b034cd6c9 100644
--- a/src/libide/sourceview/ide-source-view.c
+++ b/src/libide/sourceview/ide-source-view.c
@@ -708,6 +708,84 @@ ide_source_view_push_snippet (GtkSourceView *source_view,
GTK_SOURCE_VIEW_CLASS (ide_source_view_parent_class)->push_snippet (source_view, snippet, location);
}
+static void
+ide_source_view_action_select_line (GtkWidget *widget,
+ const char *action_name,
+ GVariant *param)
+{
+ IdeSourceView *self = (IdeSourceView *)widget;
+ GtkTextBuffer *buffer;
+ GtkTextIter begin, end;
+
+ g_assert (IDE_IS_SOURCE_VIEW (self));
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self));
+ gtk_text_buffer_get_selection_bounds (buffer, &begin, &end);
+ gtk_text_iter_order (&begin, &end);
+
+ /* Move beginning of selection/cursor to position 0 of first */
+ if (!gtk_text_iter_starts_line (&begin))
+ gtk_text_iter_set_line_offset (&begin, 0);
+
+ /* Move end of selection/cursor to end of line */
+ if (!gtk_text_iter_ends_line (&end))
+ gtk_text_iter_forward_to_line_end (&end);
+
+ /* Swallow the \n with the selection */
+ if (!gtk_text_iter_is_end (&end))
+ gtk_text_iter_forward_char (&end);
+
+ gtk_text_buffer_select_range (buffer, &begin, &end);
+
+ /* NOTE: This shouldn't be needed, but due to some invalidation issues in
+ * the line display cache, seems to improve chances we get proper
+ * invalidation lines within cache.
+ */
+ gtk_widget_queue_draw (widget);
+}
+
+static void
+ide_source_view_action_delete_line (GtkWidget *widget,
+ const char *action_name,
+ GVariant *param)
+{
+ IdeSourceView *self = (IdeSourceView *)widget;
+ GtkTextBuffer *buffer;
+ GtkTextIter begin, end;
+ g_autofree char *text = NULL;
+
+ g_assert (IDE_IS_SOURCE_VIEW (self));
+
+ ide_source_view_action_select_line (widget, NULL, NULL);
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self));
+
+ /* If we're at the end of the buffer, then we need to remove the
+ * leading \n instead of the trailing \n to make it appear to the
+ * user that a line was removed.
+ */
+ gtk_text_buffer_begin_user_action (buffer);
+ gtk_text_buffer_get_selection_bounds (buffer, &begin, &end);
+ gtk_text_iter_order (&begin, &end);
+ if (gtk_text_iter_is_end (&end) &&
+ gtk_text_iter_get_line (&begin) == gtk_text_iter_get_line (&end))
+ gtk_text_iter_backward_char (&begin);
+ text = gtk_text_iter_get_slice (&begin, &end);
+ gtk_text_buffer_delete (buffer, &begin, &end);
+ gtk_text_buffer_end_user_action (buffer);
+
+ /* now move the cursor to the beginning of the new line */
+ gtk_text_iter_set_line_offset (&begin, 0);
+ while (!gtk_text_iter_ends_line (&begin) &&
+ g_unichar_isspace (gtk_text_iter_get_char (&begin)))
+ gtk_text_iter_forward_char (&begin);
+ gtk_text_buffer_select_range (buffer, &begin, &begin);
+
+ /* it's nice to place the text into the primary selection so that
+ * the user can paste it in other places.
+ */
+ gdk_clipboard_set_text (gtk_widget_get_primary_clipboard (widget), text);
+}
+
static void
ide_source_view_dispose (GObject *object)
{
@@ -875,10 +953,14 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
gtk_widget_class_install_action (widget_class, "zoom.one", NULL, ide_source_view_zoom_one_action);
gtk_widget_class_install_action (widget_class, "selection.sort", "(bb)", ide_source_view_selection_sort);
gtk_widget_class_install_action (widget_class, "selection.join", NULL, ide_source_view_selection_join);
+ gtk_widget_class_install_action (widget_class, "buffer.select-line", NULL,
ide_source_view_action_select_line);
+ gtk_widget_class_install_action (widget_class, "buffer.delete-line", NULL,
ide_source_view_action_delete_line);
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_plus, GDK_CONTROL_MASK, "zoom.in", NULL);
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_minus, GDK_CONTROL_MASK, "zoom.out", NULL);
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_0, GDK_CONTROL_MASK, "zoom.one", NULL);
+ gtk_widget_class_add_binding_action (widget_class, GDK_KEY_l, GDK_CONTROL_MASK, "buffer.select-line",
NULL);
+ gtk_widget_class_add_binding_action (widget_class, GDK_KEY_d, GDK_CONTROL_MASK, "buffer.delete-line",
NULL);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]