[gnome-builder/wip/mwleeds/replace: 185/185] command-bar: Implement the 'c' option for vim substitute commands
- From: Matthew Leeds <mwleeds src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/mwleeds/replace: 185/185] command-bar: Implement the 'c' option for vim substitute commands
- Date: Fri, 1 Jul 2016 17:33:40 +0000 (UTC)
commit fd8001defe913ede8cf3ec8da4b43de700adac25
Author: Matthew Leeds <mleeds redhat com>
Date: Fri Jul 1 12:01:29 2016 -0400
command-bar: Implement the 'c' option for vim substitute commands
In vim, if the 'c' option is specified at the end of a substitute
command (like :%s/this/that/gc), the user is prompted to confirm or deny
replacement on each occurrence of the search term. This commit makes
Builder recognize that option and respond by opening the replace UI with
the search entry and replace entry fields filled in.
Because the search_revealer animation doesn't happen immediately (it
waits for the frame clock to increment), we can't directly trigger the
"next-search-result" action in ide_editor_frame_actions_replace_confirm.
The selection would be cleared once the search_entry widget is mapped.
So instead we setup a callback on the buffer's has-selection property,
and use that to trigger next-search-result if there's a pending
replace-confirm action.
https://bugzilla.gnome.org/show_bug.cgi?id=765635
libide/editor/ide-editor-frame-actions.c | 31 ++++++++++++++++++++++++++++++
libide/editor/ide-editor-frame-private.h | 1 +
libide/editor/ide-editor-frame.c | 27 ++++++++++++++++++++++++++
plugins/command-bar/gb-vim.c | 21 ++++++++++++++++++++
4 files changed, 80 insertions(+), 0 deletions(-)
---
diff --git a/libide/editor/ide-editor-frame-actions.c b/libide/editor/ide-editor-frame-actions.c
index 42935ea..bd5b9df 100644
--- a/libide/editor/ide-editor-frame-actions.c
+++ b/libide/editor/ide-editor-frame-actions.c
@@ -358,10 +358,41 @@ ide_editor_frame_actions_replace_all (GSimpleAction *action,
}
}
+static void
+ide_editor_frame_actions_replace_confirm (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ IdeEditorFrame *self = user_data;
+ g_autofree const gchar **strv;
+
+ g_assert (IDE_IS_EDITOR_FRAME (self));
+
+ strv = g_variant_get_strv (state, NULL);
+
+ gtk_entry_set_text (GTK_ENTRY (self->search_entry), strv[0]);
+ gtk_entry_set_text (GTK_ENTRY (self->replace_entry), strv[1]);
+
+ gtk_widget_show (GTK_WIDGET (self->replace_entry));
+ gtk_widget_show (GTK_WIDGET (self->replace_button));
+ gtk_widget_show (GTK_WIDGET (self->replace_all_button));
+
+ /* increment pending_replace_confirm so that search_revealer_on_child_revealed_changed
+ * will know to go to the next search result (the occurrence only stays selected after
+ * search_entry has been mapped).
+ */
+ self->pending_replace_confirm++;
+
+ gtk_revealer_set_reveal_child (self->search_revealer, TRUE);
+
+ gtk_widget_grab_focus (GTK_WIDGET (self->search_entry));
+}
+
static const GActionEntry IdeEditorFrameActions[] = {
{ "find", ide_editor_frame_actions_find, "i" },
{ "next-search-result", ide_editor_frame_actions_next_search_result },
{ "previous-search-result", ide_editor_frame_actions_previous_search_result },
+ { "replace-confirm", ide_editor_frame_actions_replace_confirm, "as" },
};
static const GActionEntry IdeEditorFrameSearchActions[] = {
diff --git a/libide/editor/ide-editor-frame-private.h b/libide/editor/ide-editor-frame-private.h
index c266cd7..e5725af 100644
--- a/libide/editor/ide-editor-frame-private.h
+++ b/libide/editor/ide-editor-frame-private.h
@@ -57,6 +57,7 @@ struct _IdeEditorFrame
guint auto_hide_map : 1;
guint show_ruler : 1;
+ guint pending_replace_confirm;
};
G_END_DECLS
diff --git a/libide/editor/ide-editor-frame.c b/libide/editor/ide-editor-frame.c
index 84e89b7..f604273 100644
--- a/libide/editor/ide-editor-frame.c
+++ b/libide/editor/ide-editor-frame.c
@@ -448,6 +448,25 @@ on_search_text_changed (IdeEditorFrame *self,
ide_str_empty0 (search_text) ? FALSE : TRUE);
}
+static void
+search_revealer_on_child_revealed_changed (IdeEditorFrame *self,
+ GParamSpec *pspec,
+ GtkRevealer *search_revealer)
+{
+ g_assert (IDE_IS_EDITOR_FRAME (self));
+ g_assert (GTK_IS_REVEALER (search_revealer));
+
+ if (self->pending_replace_confirm == 0 ||
+ !gtk_revealer_get_child_revealed (search_revealer))
+ return;
+
+ ide_widget_action (GTK_WIDGET (self), "frame", "next-search-result", NULL);
+
+ self->pending_replace_confirm--;
+
+ gtk_widget_grab_focus (GTK_WIDGET (self->replace_button));
+}
+
void
ide_editor_frame_set_document (IdeEditorFrame *self,
IdeBuffer *buffer)
@@ -510,6 +529,14 @@ ide_editor_frame_set_document (IdeEditorFrame *self,
G_CALLBACK (on_search_text_changed),
self,
G_CONNECT_SWAPPED);
+
+ /* Setup a callback so the replace-confirm action can work properly. */
+ self->pending_replace_confirm = 0;
+ g_signal_connect_object (self->search_revealer,
+ "notify::child-revealed",
+ G_CALLBACK (search_revealer_on_child_revealed_changed),
+ self,
+ G_CONNECT_SWAPPED);
}
static gboolean
diff --git a/plugins/command-bar/gb-vim.c b/plugins/command-bar/gb-vim.c
index 48701f1..69fccd4 100644
--- a/plugins/command-bar/gb-vim.c
+++ b/plugins/command-bar/gb-vim.c
@@ -1001,6 +1001,7 @@ gb_vim_command_search (GtkWidget *active_widget,
gchar *search_text = NULL;
gchar *replace_text = NULL;
gunichar separator;
+ gboolean confirm_replace = FALSE;
g_assert (GTK_IS_WIDGET (active_widget));
g_assert (g_str_has_prefix (command, "%s") || g_str_has_prefix (command, "s"));
@@ -1070,6 +1071,9 @@ gb_vim_command_search (GtkWidget *active_widget,
{
switch (*command)
{
+ case 'c':
+ confirm_replace = TRUE;
+ break;
case 'g':
break;
@@ -1083,6 +1087,23 @@ gb_vim_command_search (GtkWidget *active_widget,
search_text = g_strndup (search_begin, search_end - search_begin);
replace_text = g_strndup (replace_begin, replace_end - replace_begin);
+ if (confirm_replace)
+ {
+ GVariant *variant;
+ GVariantBuilder *builder;
+
+ builder = g_variant_builder_new (G_VARIANT_TYPE_STRING_ARRAY);
+ g_variant_builder_add (builder, "s", search_text);
+ g_variant_builder_add (builder, "s", replace_text);
+ variant = g_variant_builder_end (builder);
+
+ ide_widget_action (GTK_WIDGET (IDE_EDITOR_VIEW (active_widget)->frame1),
+ "frame",
+ "replace-confirm",
+ variant);
+ return TRUE;
+ }
+
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (source_view));
if (gtk_text_buffer_get_has_selection (buffer))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]