[gnome-builder/wip/libide] libide: add IdeSourceView:smart-backspace gproperty
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/libide] libide: add IdeSourceView:smart-backspace gproperty
- Date: Sun, 15 Mar 2015 04:01:46 +0000 (UTC)
commit 074ad36e63dab752c2fbc1211d00fee72d87c49d
Author: Christian Hergert <christian hergert me>
Date: Sat Mar 14 21:01:04 2015 -0700
libide: add IdeSourceView:smart-backspace gproperty
Smart backspace will attempt to backspace extra characters when you are
at the indent boundary. It will mind the tab_indent and indent_width
properties to generally do the right thing.
If you are a tab, and the indent_width is less than the tab width, spaces
will be added until you reach the target indent width (after removing the
tab).
libide/ide-source-view.c | 121 +++++++++++++++++++++++++++++++++++++++++++++-
libide/ide-source-view.h | 3 +
2 files changed, 122 insertions(+), 2 deletions(-)
---
diff --git a/libide/ide-source-view.c b/libide/ide-source-view.c
index 8e3e4f9..a521c78 100644
--- a/libide/ide-source-view.c
+++ b/libide/ide-source-view.c
@@ -143,6 +143,7 @@ typedef struct
guint show_line_changes : 1;
guint show_search_bubbles : 1;
guint show_search_shadow : 1;
+ guint smart_backspace : 1;
guint snippet_completion : 1;
guint waiting_for_capture : 1;
} IdeSourceViewPrivate;
@@ -174,6 +175,7 @@ enum {
PROP_SHOW_LINE_CHANGES,
PROP_SHOW_SEARCH_BUBBLES,
PROP_SHOW_SEARCH_SHADOW,
+ PROP_SMART_BACKSPACE,
PROP_SNIPPET_COMPLETION,
LAST_PROP
};
@@ -1881,6 +1883,73 @@ is_modifier_key (GdkEventKey *event)
}
static gboolean
+ide_source_view_do_smart_backspace (IdeSourceView *self,
+ GdkEventKey *event)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter insert;
+ GtkTextIter end;
+ guint visual_column;
+ gint indent_width;
+ gint tab_width;
+
+ g_assert (IDE_IS_SOURCE_VIEW (self));
+ g_assert (event);
+ g_assert (event->type == GDK_KEY_PRESS);
+
+#define GET_VISUAL_COLUMN(iter) gtk_source_view_get_visual_column(GTK_SOURCE_VIEW(self),iter)
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self));
+
+ gtk_text_buffer_get_selection_bounds (buffer, &insert, &end);
+
+ if (!gtk_text_iter_equal (&insert, &end))
+ return FALSE;
+
+ visual_column = GET_VISUAL_COLUMN (&insert);
+ indent_width = gtk_source_view_get_indent_width (GTK_SOURCE_VIEW (self));
+ tab_width = gtk_source_view_get_tab_width (GTK_SOURCE_VIEW (self));
+ if (indent_width <= 0)
+ indent_width = tab_width;
+
+ if (visual_column < indent_width)
+ return FALSE;
+
+ if ((visual_column % indent_width) == 0)
+ {
+ gint target_column = visual_column - indent_width;
+ gunichar ch;
+
+ g_assert_cmpint (target_column, >=, 0);
+
+ while (GET_VISUAL_COLUMN (&insert) > target_column)
+ {
+ gtk_text_iter_backward_char (&insert);
+ ch = gtk_text_iter_get_char (&insert);
+
+ if (!g_unichar_isspace (ch))
+ return FALSE;
+ }
+
+ ch = gtk_text_iter_get_char (&insert);
+ if (!g_unichar_isspace (ch))
+ return FALSE;
+
+ gtk_text_buffer_begin_user_action (buffer);
+ gtk_text_buffer_delete (buffer, &insert, &end);
+ while (GET_VISUAL_COLUMN (&insert) < target_column)
+ gtk_text_buffer_insert (buffer, &insert, " ", 1);
+ gtk_text_buffer_end_user_action (buffer);
+
+ return TRUE;
+ }
+
+#undef GET_VISUAL_COLUMN
+
+ return FALSE;
+}
+
+static gboolean
ide_source_view_key_press_event (GtkWidget *widget,
GdkEventKey *event)
{
@@ -1981,8 +2050,12 @@ ide_source_view_key_press_event (GtkWidget *widget,
* then we might want to delete it too.
*/
if ((event->keyval == GDK_KEY_BackSpace) && !gtk_text_buffer_get_has_selection (buffer))
- if (ide_source_view_maybe_delete_match (self, event))
- return TRUE;
+ {
+ if (ide_source_view_maybe_delete_match (self, event))
+ return TRUE;
+ else if (priv->smart_backspace && ide_source_view_do_smart_backspace (self, event))
+ return TRUE;
+ }
/*
* If we have an auto-indenter and the event is for a trigger key, then we
@@ -4149,6 +4222,10 @@ ide_source_view_get_property (GObject *object,
g_value_set_boolean (value, ide_source_view_get_show_search_shadow (self));
break;
+ case PROP_SMART_BACKSPACE:
+ g_value_set_boolean (value, ide_source_view_get_smart_backspace (self));
+ break;
+
case PROP_SNIPPET_COMPLETION:
g_value_set_boolean (value, ide_source_view_get_snippet_completion (self));
break;
@@ -4218,6 +4295,10 @@ ide_source_view_set_property (GObject *object,
ide_source_view_set_show_search_shadow (self, g_value_get_boolean (value));
break;
+ case PROP_SMART_BACKSPACE:
+ ide_source_view_set_smart_backspace (self, g_value_get_boolean (value));
+ break;
+
case PROP_SNIPPET_COMPLETION:
ide_source_view_set_snippet_completion (self, g_value_get_boolean (value));
break;
@@ -4397,6 +4478,15 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
g_object_class_install_property (object_class, PROP_SHOW_SEARCH_SHADOW,
gParamSpecs [PROP_SHOW_SEARCH_SHADOW]);
+ gParamSpecs [PROP_SMART_BACKSPACE] =
+ g_param_spec_boolean ("smart-backspace",
+ _("Smart Backspace"),
+ _("If smart backspace should be used."),
+ FALSE,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_SMART_BACKSPACE,
+ gParamSpecs [PROP_SMART_BACKSPACE]);
+
gParamSpecs [PROP_SNIPPET_COMPLETION] =
g_param_spec_boolean ("snippet-completion",
_("Snippet Completion"),
@@ -5673,3 +5763,30 @@ ide_source_view_set_show_search_shadow (IdeSourceView *self,
ide_source_view_invalidate_window (self);
}
}
+
+gboolean
+ide_source_view_get_smart_backspace (IdeSourceView *self)
+{
+ IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
+
+ g_return_val_if_fail (IDE_IS_SOURCE_VIEW (self), NULL);
+
+ return priv->smart_backspace;
+}
+
+void
+ide_source_view_set_smart_backspace (IdeSourceView *self,
+ gboolean smart_backspace)
+{
+ IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_SOURCE_VIEW (self));
+
+ smart_backspace = !!smart_backspace;
+
+ if (smart_backspace != priv->smart_backspace)
+ {
+ priv->smart_backspace = smart_backspace;
+ g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_SMART_BACKSPACE]);
+ }
+}
diff --git a/libide/ide-source-view.h b/libide/ide-source-view.h
index 561c471..549e880 100644
--- a/libide/ide-source-view.h
+++ b/libide/ide-source-view.h
@@ -284,6 +284,7 @@ gboolean ide_source_view_get_show_grid_lines (IdeSource
gboolean ide_source_view_get_show_line_changes (IdeSourceView *self);
gboolean ide_source_view_get_show_search_bubbles (IdeSourceView *self);
gboolean ide_source_view_get_show_search_shadow (IdeSourceView *self);
+gboolean ide_source_view_get_smart_backspace (IdeSourceView *self);
gboolean ide_source_view_get_snippet_completion (IdeSourceView *self);
GType ide_source_view_get_type (void);
void ide_source_view_get_visible_rect (IdeSourceView *self,
@@ -313,6 +314,8 @@ void ide_source_view_set_show_search_bubbles (IdeSource
gboolean
show_search_bubbles);
void ide_source_view_set_show_search_shadow (IdeSourceView *self,
gboolean
show_search_bubbles);
+void ide_source_view_set_smart_backspace (IdeSourceView *self,
+ gboolean
smart_backspace);
void ide_source_view_set_snippet_completion (IdeSourceView *self,
gboolean
snippet_completion);
void ide_source_view_set_back_forward_list (IdeSourceView *self,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]