[gnome-builder/wip/vim] vim: plumb some command line entry work.



commit fdc5112011c06b17bc9d0da23c0d178f63ef0c9b
Author: Christian Hergert <christian hergert me>
Date:   Tue Sep 30 18:23:18 2014 -0700

    vim: plumb some command line entry work.

 src/editor/gb-editor-vim.c |  141 +++++++++++++++++++++++++++++++++++---------
 1 files changed, 112 insertions(+), 29 deletions(-)
---
diff --git a/src/editor/gb-editor-vim.c b/src/editor/gb-editor-vim.c
index 0d20b5c..617eb2b 100644
--- a/src/editor/gb-editor-vim.c
+++ b/src/editor/gb-editor-vim.c
@@ -28,11 +28,12 @@
 struct _GbEditorVimPrivate
 {
   GtkTextView     *text_view;
-  GString         *command_line;
+  GtkEntry        *command_entry;
   GbEditorVimMode  mode;
   gulong           key_press_event_handler;
   gulong           mark_set_handler;
   gulong           delete_range_handler;
+  gulong           command_entry_activate_handler;
   guint            target_line_offset;
   guint            enabled : 1;
   guint            connected : 1;
@@ -41,6 +42,7 @@ struct _GbEditorVimPrivate
 enum
 {
   PROP_0,
+  PROP_COMMAND_ENTRY,
   PROP_ENABLED,
   PROP_MODE,
   PROP_TEXT_VIEW,
@@ -89,6 +91,15 @@ gb_editor_vim_set_mode (GbEditorVim     *vim,
 {
   g_return_if_fail (GB_IS_EDITOR_VIM (vim));
 
+  /*
+   * Don't allow changing to command mode if we don't have an editable widget.
+   */
+  if ((mode == GB_EDITOR_VIM_COMMAND) && !vim->priv->command_entry)
+    {
+      g_warning ("Cannot change to command mode, no command entry widget set.");
+      mode = GB_EDITOR_VIM_NORMAL;
+    }
+
   vim->priv->mode = mode;
 
   /*
@@ -115,8 +126,8 @@ gb_editor_vim_set_mode (GbEditorVim     *vim,
   /*
    * Clear the command line text.
    */
-  if (vim->priv->command_line->len)
-    g_string_truncate (vim->priv->command_line, 0);
+  if (GTK_IS_ENTRY (vim->priv->command_entry))
+    gtk_entry_set_text (GTK_ENTRY (vim->priv->command_entry), "");
 
   /*
    * If we are are going to normal mode and are at the end of the line,
@@ -1321,6 +1332,19 @@ gb_editor_vim_get_has_selection (GbEditorVim *vim)
   return gtk_text_buffer_get_has_selection (buffer);
 }
 
+static void
+gb_editor_vim_command_entry_activate_cb (GtkEntry    *entry,
+                                         GbEditorVim *vim)
+{
+  const gchar *text;
+
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+  g_return_if_fail (GB_IS_EDITOR_VIM (vim));
+
+  text = gtk_entry_get_text (entry);
+  g_print ("Execute Command Line: \"%s\"\n", text);
+}
+
 static gboolean
 gb_editor_vim_handle_normal (GbEditorVim *vim,
                              GdkEventKey *event)
@@ -1665,6 +1689,11 @@ static gboolean
 gb_editor_vim_handle_command (GbEditorVim *vim,
                               GdkEventKey *event)
 {
+  /*
+   * We typically shouldn't be hitting here, we should be focused in the
+   * command_entry widget.
+   */
+
   switch (event->keyval)
     {
     case GDK_KEY_Escape:
@@ -1674,37 +1703,22 @@ gb_editor_vim_handle_command (GbEditorVim *vim,
       gb_editor_vim_set_mode (vim, GB_EDITOR_VIM_NORMAL);
       return TRUE;
 
+    /*
+     * Execute the command line if we can.
+     */
     case GDK_KEY_KP_Enter:
     case GDK_KEY_Return:
-      /*
-       * Execute the command line and then go back to normal mode.
-       */
-      g_printerr ("Execute Command Line: %s\n", vim->priv->command_line->str);
-      gb_editor_vim_set_mode (vim, GB_EDITOR_VIM_NORMAL);
+      if (vim->priv->command_entry)
+        gb_editor_vim_command_entry_activate_cb (vim->priv->command_entry, vim);
+      else
+        gb_editor_vim_set_mode (vim, GB_EDITOR_VIM_NORMAL);
       return TRUE;
 
-    case GDK_KEY_u:
-      /*
-       * Delete everything before the cursor upon <Control>U.
-       */
-      if ((event->state & GDK_CONTROL_MASK) != 0)
-        {
-          g_string_truncate (vim->priv->command_line, 0);
-          return TRUE;
-        }
-
-      break;
-
     default:
       break;
     }
 
-  /*
-   * TODO: This is not sufficient, since we can't handle control text.
-   *       We really need to display an entry that we own somewhere.
-   *       Possibly on our behalf by the editor container.
-   */
-  g_string_append (vim->priv->command_line, event->string);
+  gtk_bindings_activate_event (G_OBJECT (vim->priv->text_view), event);
 
   return TRUE;
 }
@@ -1944,6 +1958,53 @@ gb_editor_vim_set_text_view (GbEditorVim *vim,
   g_object_notify_by_pspec (G_OBJECT (vim), gParamSpecs [PROP_TEXT_VIEW]);
 }
 
+GtkEntry *
+gb_editor_vim_get_command_entry (GbEditorVim *vim)
+{
+  g_return_val_if_fail (GB_IS_EDITOR_VIM (vim), NULL);
+
+  return vim->priv->command_entry;
+}
+
+void
+gb_editor_vim_set_command_entry (GbEditorVim *vim,
+                                 GtkEntry    *command_entry)
+{
+  GbEditorVimPrivate *priv;
+
+  g_return_if_fail (GB_IS_EDITOR_VIM (vim));
+  g_return_if_fail (!command_entry || GTK_IS_ENTRY (command_entry));
+
+  priv = vim->priv;
+
+  if (priv->command_entry == command_entry)
+    return;
+
+  if (priv->command_entry)
+    {
+      g_signal_handler_disconnect (priv->command_entry,
+                                   priv->command_entry_activate_handler);
+      priv->command_entry_activate_handler = 0;
+      g_object_remove_weak_pointer (G_OBJECT (priv->command_entry),
+                                    (gpointer *)&priv->command_entry);
+      priv->command_entry = NULL;
+    }
+
+  if (command_entry)
+    {
+      priv->command_entry = command_entry;
+      g_object_add_weak_pointer (G_OBJECT (priv->command_entry),
+                                 (gpointer *)&priv->command_entry);
+      priv->command_entry_activate_handler =
+        g_signal_connect (priv->command_entry,
+                          "activate",
+                          G_CALLBACK (gb_editor_vim_command_entry_activate_cb),
+                          vim);
+    }
+
+  g_object_notify_by_pspec (G_OBJECT (vim), gParamSpecs [PROP_COMMAND_ENTRY]);
+}
+
 static void
 gb_editor_vim_finalize (GObject *object)
 {
@@ -1957,8 +2018,12 @@ gb_editor_vim_finalize (GObject *object)
       priv->text_view = NULL;
     }
 
-  g_string_free (priv->command_line, TRUE);
-  priv->command_line = NULL;
+  if (priv->command_entry_activate_handler && priv->command_entry)
+    {
+      g_signal_handler_disconnect (priv->command_entry,
+                                   priv->command_entry_activate_handler);
+      priv->command_entry_activate_handler = 0;
+    }
 
   G_OBJECT_CLASS (gb_editor_vim_parent_class)->finalize (object);
 }
@@ -1973,6 +2038,10 @@ gb_editor_vim_get_property (GObject    *object,
 
   switch (prop_id)
     {
+    case PROP_COMMAND_ENTRY:
+      g_value_set_object (value, gb_editor_vim_get_command_entry (vim));
+      break;
+
     case PROP_ENABLED:
       g_value_set_boolean (value, gb_editor_vim_get_enabled (vim));
       break;
@@ -2000,6 +2069,10 @@ gb_editor_vim_set_property (GObject      *object,
 
   switch (prop_id)
     {
+    case PROP_COMMAND_ENTRY:
+      gb_editor_vim_set_command_entry (vim, g_value_get_object (value));
+      break;
+
     case PROP_ENABLED:
       gb_editor_vim_set_enabled (vim, g_value_get_boolean (value));
       break;
@@ -2023,6 +2096,17 @@ gb_editor_vim_class_init (GbEditorVimClass *klass)
   object_class->get_property = gb_editor_vim_get_property;
   object_class->set_property = gb_editor_vim_set_property;
 
+  gParamSpecs [PROP_COMMAND_ENTRY] =
+    g_param_spec_object ("command-entry",
+                         _("Command Entry"),
+                         _("The command entry widget for command mode."),
+                         GTK_TYPE_ENTRY,
+                         (G_PARAM_READWRITE |
+                          G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_COMMAND_ENTRY,
+                                   gParamSpecs [PROP_COMMAND_ENTRY]);
+
   gParamSpecs [PROP_ENABLED] =
     g_param_spec_boolean ("enabled",
                           _("Enabled"),
@@ -2062,7 +2146,6 @@ gb_editor_vim_init (GbEditorVim *vim)
   vim->priv = gb_editor_vim_get_instance_private (vim);
   vim->priv->enabled = FALSE;
   vim->priv->mode = GB_EDITOR_VIM_NORMAL;
-  vim->priv->command_line = g_string_new (NULL);
 }
 
 GType


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