[gtksourceview/wip/chergert/vim] wire up command execution



commit d99dfbf6924b2c23a235033d9189c0fbbef88333
Author: Christian Hergert <chergert redhat com>
Date:   Tue Oct 26 16:56:17 2021 -0700

    wire up command execution
    
    just for :q in the test

 gtksourceview/gtksourcevimimcontext.c          | 60 ++++++++++++++++++++++++--
 gtksourceview/vim/gtk-source-vim-command-bar.c |  8 +++-
 gtksourceview/vim/gtk-source-vim.c             | 51 +++++++++++++++++++++-
 gtksourceview/vim/gtk-source-vim.h             |  2 +
 tests/test-vim.c                               | 22 ++++++++--
 5 files changed, 131 insertions(+), 12 deletions(-)
---
diff --git a/gtksourceview/gtksourcevimimcontext.c b/gtksourceview/gtksourcevimimcontext.c
index 1cd48103..7be52fcf 100644
--- a/gtksourceview/gtksourcevimimcontext.c
+++ b/gtksourceview/gtksourcevimimcontext.c
@@ -42,7 +42,13 @@ enum {
        N_PROPS
 };
 
+enum {
+       EXECUTE_COMMAND,
+       N_SIGNALS
+};
+
 static GParamSpec *properties[N_PROPS];
+static guint signals[N_SIGNALS];
 
 GtkIMContext *
 gtk_source_vim_im_context_new (void)
@@ -69,6 +75,20 @@ on_vim_notify_cb (GtkSourceVimIMContext *self,
                g_object_notify_by_pspec (G_OBJECT (self), pspec);
 }
 
+static gboolean
+on_vim_execute_command_cb (GtkSourceVimIMContext *self,
+                           const char            *command,
+                           GtkSourceVim          *vim)
+{
+       gboolean ret = FALSE;
+
+       g_assert (GTK_SOURCE_IS_VIM_IM_CONTEXT (self));
+       g_assert (GTK_SOURCE_IS_VIM (vim));
+
+       g_signal_emit (self, signals[EXECUTE_COMMAND], 0, command, &ret);
+       return ret;
+}
+
 static void
 gtk_source_vim_im_context_set_client_widget (GtkIMContext *context,
                                              GtkWidget    *widget)
@@ -86,10 +106,16 @@ gtk_source_vim_im_context_set_client_widget (GtkIMContext *context,
        self->vim = gtk_source_vim_new (GTK_SOURCE_VIEW (widget));
 
        g_signal_connect_object (self->vim,
-                                "notify",
-                                G_CALLBACK (on_vim_notify_cb),
-                                self,
-                                G_CONNECT_SWAPPED);
+                                "notify",
+                                G_CALLBACK (on_vim_notify_cb),
+                                self,
+                                G_CONNECT_SWAPPED);
+
+       g_signal_connect_object (self->vim,
+                                "execute-command",
+                                G_CALLBACK (on_vim_execute_command_cb),
+                                self,
+                                G_CONNECT_SWAPPED);
 
        g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COMMAND_TEXT]);
        g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COMMAND_BAR_TEXT]);
@@ -199,6 +225,32 @@ gtk_source_vim_im_context_class_init (GtkSourceVimIMContextClass *klass)
                                     (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
        g_object_class_install_properties (object_class, N_PROPS, properties);
+
+       /**
+        * GtkSourceVimIMContext::execute-command:
+        * @self: a #GtkSourceVimIMContext
+        * @command: the command to execute
+        *
+        * The "execute-command" signal is emitted when a command should be
+        * executed. This might be something like ":wq" or ":e <path>".
+        *
+        * If the application chooses to implement this, it should return
+        * %TRUE from this signal to indicate the command has been handled.
+        *
+        * Returns: %TRUE if handled; otherwise %FALSE.
+        *
+        * Since: 5.4
+        */
+       signals[EXECUTE_COMMAND] =
+               g_signal_new ("execute-command",
+                             G_TYPE_FROM_CLASS (klass),
+                             G_SIGNAL_RUN_LAST,
+                             0,
+                             g_signal_accumulator_true_handled, NULL,
+                             NULL,
+                             G_TYPE_BOOLEAN,
+                             1,
+                             G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
 }
 
 static void
diff --git a/gtksourceview/vim/gtk-source-vim-command-bar.c b/gtksourceview/vim/gtk-source-vim-command-bar.c
index 3040fe65..762a78e7 100644
--- a/gtksourceview/vim/gtk-source-vim-command-bar.c
+++ b/gtksourceview/vim/gtk-source-vim-command-bar.c
@@ -69,12 +69,16 @@ do_notify (GtkSourceVimCommandBar *self)
 
 static void
 do_execute (GtkSourceVimCommandBar *self,
-           const char             *command)
+            const char             *command)
 {
+       GtkSourceVimState *root;
+
        g_assert (GTK_SOURCE_IS_VIM_COMMAND_BAR (self));
        g_assert (command != NULL);
 
-       g_print ("Exec command: %s\n", command);
+       root = gtk_source_vim_state_get_root (GTK_SOURCE_VIM_STATE (self));
+       if (GTK_SOURCE_IS_VIM (root))
+               gtk_source_vim_emit_execute_command (GTK_SOURCE_VIM (root), command);
 }
 
 static gboolean
diff --git a/gtksourceview/vim/gtk-source-vim.c b/gtksourceview/vim/gtk-source-vim.c
index d080fa47..c024ec0d 100644
--- a/gtksourceview/vim/gtk-source-vim.c
+++ b/gtksourceview/vim/gtk-source-vim.c
@@ -42,6 +42,7 @@ enum {
 };
 
 enum {
+       EXECUTE_COMMAND,
        SPLIT,
        N_SIGNALS
 };
@@ -55,8 +56,15 @@ gtk_source_vim_new (GtkSourceView *view)
        g_return_val_if_fail (GTK_SOURCE_IS_VIEW (view), NULL);
 
        return g_object_new (GTK_SOURCE_TYPE_VIM,
-                            "view", view,
-                            NULL);
+                            "view", view,
+                            NULL);
+}
+
+static gboolean
+gtk_source_vim_real_execute_command (GtkSourceVim *self,
+                                     const char   *command)
+{
+       return FALSE;
 }
 
 static gboolean
@@ -137,6 +145,32 @@ gtk_source_vim_class_init (GtkSourceVimClass *klass)
 
        g_object_class_install_properties (object_class, N_PROPS, properties);
 
+       /**
+        * GtkSourceVim::execute-command:
+        * @self: a #GtkSourceVim
+        * @command: the command to execute
+        *
+        * The "execute-command" signal is emitted when the user has requested
+        * a command to be executed from the command bar (or possibly other
+        * VIM commands internally).
+        *
+        * If the command is something GtkSourceVim can handle internally,
+        * it will do so. Otherwise the application is responsible for
+        * handling it.
+        *
+        * Returns: %TRUE if handled, otherwise %FALSE.
+        */
+       signals[EXECUTE_COMMAND] =
+               g_signal_new_class_handler ("execute-command",
+                                           G_TYPE_FROM_CLASS (klass),
+                                           G_SIGNAL_RUN_LAST,
+                                           G_CALLBACK (gtk_source_vim_real_execute_command),
+                                           g_signal_accumulator_true_handled, NULL,
+                                           NULL,
+                                           G_TYPE_BOOLEAN,
+                                           1,
+                                           G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
+
        /**
         * GtkSourceVim::split:
         * @self: a #GtkSourceVim
@@ -241,3 +275,16 @@ gtk_source_vim_reset (GtkSourceVim *self)
                gtk_source_vim_normal_clear (GTK_SOURCE_VIM_NORMAL (current));
        }
 }
+
+gboolean
+gtk_source_vim_emit_execute_command (GtkSourceVim *self,
+                                     const char   *command)
+{
+       gboolean ret = FALSE;
+
+       g_return_val_if_fail (GTK_SOURCE_IS_VIM (self), FALSE);
+
+       g_signal_emit (self, signals[EXECUTE_COMMAND], 0, command, &ret);
+
+       return ret;
+}
diff --git a/gtksourceview/vim/gtk-source-vim.h b/gtksourceview/vim/gtk-source-vim.h
index b867b6cf..3e8efad5 100644
--- a/gtksourceview/vim/gtk-source-vim.h
+++ b/gtksourceview/vim/gtk-source-vim.h
@@ -33,6 +33,8 @@ GtkSourceVim *gtk_source_vim_new                  (GtkSourceView  *view);
 void          gtk_source_vim_reset                (GtkSourceVim   *self);
 const char   *gtk_source_vim_get_command_text     (GtkSourceVim   *self);
 const char   *gtk_source_vim_get_command_bar_text (GtkSourceVim   *self);
+gboolean      gtk_source_vim_emit_execute_command (GtkSourceVim   *self,
+                                                   const char     *command);
 void          gtk_source_vim_emit_split           (GtkSourceVim   *self,
                                                    GtkOrientation  orientation,
                                                    gboolean        new_document,
diff --git a/tests/test-vim.c b/tests/test-vim.c
index 3077fad6..c81242ba 100644
--- a/tests/test-vim.c
+++ b/tests/test-vim.c
@@ -23,6 +23,21 @@
 
 #include <gtksourceview/gtksource.h>
 
+static GMainLoop *main_loop;
+
+static gboolean
+execute_command (GtkSourceVimIMContext *context,
+                 const char            *command)
+{
+       if (g_str_equal (command, ":q"))
+       {
+               g_main_loop_quit (main_loop);
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
 static void
 load_cb (GObject      *object,
          GAsyncResult *result,
@@ -55,8 +70,7 @@ open_file (GtkSourceBuffer *buffer,
 }
 
 static gboolean
-on_close_request (GtkWindow *window,
-                  GMainLoop *main_loop)
+on_close_request (GtkWindow *window)
 {
        g_main_loop_quit (main_loop);
        return FALSE;
@@ -66,7 +80,6 @@ int
 main (int argc,
       char *argv[])
 {
-       GMainLoop *main_loop;
        GtkWindow *window;
        GtkSourceStyleSchemeManager *schemes;
        GtkSourceLanguageManager *languages;
@@ -112,6 +125,7 @@ main (int argc,
 
        im_context = gtk_source_vim_im_context_new ();
        g_object_bind_property (im_context, "command-bar-text", command_bar, "label", G_BINDING_SYNC_CREATE);
+       g_signal_connect (im_context, "execute-command", G_CALLBACK (execute_command), NULL);
        gtk_im_context_set_client_widget (im_context, GTK_WIDGET (view));
 
        key = gtk_event_controller_key_new ();
@@ -119,7 +133,7 @@ main (int argc,
        gtk_event_controller_set_propagation_phase (key, GTK_PHASE_CAPTURE);
        gtk_widget_add_controller (GTK_WIDGET (view), key);
 
-       g_signal_connect (window, "close-request", G_CALLBACK (on_close_request), main_loop);
+       g_signal_connect (window, "close-request", G_CALLBACK (on_close_request), NULL);
        gtk_window_present (window);
 
        file = g_file_new_for_path (TOP_SRCDIR "/gtksourceview/gtksourcebuffer.c");


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]