[gnome-builder/wip/mwleeds/replace: 30/30] 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: 30/30] command-bar: Implement the 'c' option for vim substitute commands
- Date: Thu, 7 Jul 2016 02:54:46 +0000 (UTC)
commit 50f6f7b5491cc9e1989662d001ae6e33b7efdafb
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 | 35 ++++++++++++++++++++++++++++++
libide/editor/ide-editor-frame-private.h | 1 +
libide/editor/ide-editor-frame.c | 27 +++++++++++++++++++++++
plugins/command-bar/gb-vim.c | 22 ++++++++++++++++++
4 files changed, 85 insertions(+), 0 deletions(-)
---
diff --git a/libide/editor/ide-editor-frame-actions.c b/libide/editor/ide-editor-frame-actions.c
index f99a3b5..2103ae8 100644
--- a/libide/editor/ide-editor-frame-actions.c
+++ b/libide/editor/ide-editor-frame-actions.c
@@ -357,10 +357,45 @@ ide_editor_frame_actions_replace_all (GSimpleAction *action,
g_free (unescaped_replace_text);
}
+static void
+ide_editor_frame_actions_replace_confirm (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ IdeEditorFrame *self = user_data;
+ g_autofree const gchar **strv = NULL;
+ gsize array_length;
+
+ g_assert (IDE_IS_EDITOR_FRAME (self));
+ g_assert (state != NULL);
+ g_assert (g_variant_is_of_type (state, G_VARIANT_TYPE_STRING_ARRAY));
+
+ strv = g_variant_get_strv (state, &array_length);
+ g_assert (array_length >= 2);
+
+ 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..134eb2f 100644
--- a/libide/editor/ide-editor-frame-private.h
+++ b/libide/editor/ide-editor-frame-private.h
@@ -55,6 +55,7 @@ struct _IdeEditorFrame
gulong cursor_moved_handler;
+ guint pending_replace_confirm;
guint auto_hide_map : 1;
guint show_ruler : 1;
};
diff --git a/libide/editor/ide-editor-frame.c b/libide/editor/ide-editor-frame.c
index 0fb2951..ae60f26 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 c2bcade..4a05bde 100644
--- a/plugins/command-bar/gb-vim.c
+++ b/plugins/command-bar/gb-vim.c
@@ -1021,6 +1021,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"));
@@ -1090,6 +1091,10 @@ gb_vim_command_search (GtkWidget *active_widget,
{
switch (*command)
{
+ case 'c':
+ confirm_replace = TRUE;
+ break;
+
case 'g':
break;
@@ -1103,6 +1108,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;
+
+ g_variant_builder_init (&builder, 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]