[gnome-builder/wip/libide] libide: allow a mode to suggest the next default mode



commit 6b8a8f0d571bc90959d9be66271ec5f3fd4c4f7e
Author: Christian Hergert <christian hergert me>
Date:   Tue Mar 10 21:28:20 2015 -0700

    libide: allow a mode to suggest the next default mode
    
    This is handy so we don't have to suffix all the commands with
    "set-mode" ("vim-visual", permament) after every movement.

 data/keybindings/vim.css      |   11 ++++++
 libide/ide-source-view-mode.c |   73 +++++++++++++++++++++++++++++++++++------
 libide/ide-source-view-mode.h |    1 +
 libide/ide-source-view.c      |   14 +++++++-
 4 files changed, 87 insertions(+), 12 deletions(-)
---
diff --git a/data/keybindings/vim.css b/data/keybindings/vim.css
index 22f3057..6535b41 100644
--- a/data/keybindings/vim.css
+++ b/data/keybindings/vim.css
@@ -1062,6 +1062,17 @@ IdeSourceViewMode.vim-visual {
                     builder-vim-source-view-visual;
 }
 
+IdeSourceViewMode.vim-visual-with-count {
+  -IdeSourceViewMode-suppress-unbound: true;
+  -IdeSourceViewMode-coalesce-undo: true;
+  -IdeSourceViewMode-block-cursor: true;
+  -IdeSourceViewMode-default-mode: "vim-visual";
+
+  gtk-key-bindings: builder-vim-source-view,
+                    builder-vim-source-view-visual-with-count,
+                    builder-vim-source-view-visual;
+}
+
 IdeSourceViewMode.vim-visual-g {
   -IdeSourceViewMode-suppress-unbound: true;
   -IdeSourceViewMode-coalesce-undo: true;
diff --git a/libide/ide-source-view-mode.c b/libide/ide-source-view-mode.c
index 7ee11c9..0be2f49 100644
--- a/libide/ide-source-view-mode.c
+++ b/libide/ide-source-view-mode.c
@@ -29,6 +29,7 @@ typedef struct
 {
   GtkWidget             *view;
   char                  *name;
+  gchar                 *default_mode;
   IdeSourceViewModeType  type;
 } IdeSourceViewModePrivate;
 
@@ -73,26 +74,68 @@ get_boolean_param (IdeSourceViewMode *self,
   return ret;
 }
 
+gchar *
+get_string_param (IdeSourceViewMode *self,
+                   const gchar       *param)
+{
+  GValue value = { 0 };
+  gchar *ret;
+
+  g_value_init (&value, G_TYPE_STRING);
+  get_param (self, param, &value);
+  ret = g_value_dup_string (&value);
+  g_value_unset (&value);
+
+  return ret;
+}
+
+const gchar *
+ide_source_view_mode_get_default_mode (IdeSourceViewMode *self)
+{
+  IdeSourceViewModePrivate *priv = ide_source_view_mode_get_instance_private (self);
+
+  /*
+   * instead of switching back to "default" mode, use this mode instead
+   * if no other mode is specified.
+   */
+  return priv->default_mode;
+}
+
 gboolean
 ide_source_view_mode_get_coalesce_undo (IdeSourceViewMode *self)
 {
+  /*
+   * try to coalesce all the undo from the mode into a single
+   * undo. not perfect, but we try hard. useful for emulating vim.
+   */
   return get_boolean_param (self, "coalesce-undo");
 }
 
 gboolean
 ide_source_view_mode_get_suppress_unbound (IdeSourceViewMode *self)
 {
+  /*
+   * unknown keypresses are swallowed. you probably want to use this
+   * with a transient mode.
+   */
   return get_boolean_param (self, "suppress-unbound");
 }
 
 gboolean
 ide_source_view_mode_get_block_cursor (IdeSourceViewMode *self)
 {
+  /*
+   * fakes a block cursor by using overwrite mode in textview.
+   * you probably want to use this with "suppress-unbound".
+   */
   return get_boolean_param (self, "block-cursor");
 }
 gboolean
 ide_source_view_mode_get_keep_mark_on_char (IdeSourceViewMode *self)
 {
+  /* forces the source view to not let the cursor reach the end of the
+   * line (basically an iter over \n). this is useful for emulating vim
+   */
   return get_boolean_param (self, "keep-mark-on-char");
 }
 
@@ -104,6 +147,7 @@ ide_source_view_mode_finalize (GObject *object)
 
   g_clear_object (&priv->view);
   g_clear_pointer (&priv->name, g_free);
+  g_clear_pointer (&priv->default_mode, g_free);
   priv->type = 0;
 
   G_OBJECT_CLASS (ide_source_view_mode_parent_class)->finalize (object);
@@ -212,38 +256,46 @@ ide_source_view_mode_class_init (IdeSourceViewModeClass *klass)
 
   gtk_widget_class_install_style_property (GTK_WIDGET_CLASS (klass),
                                            g_param_spec_boolean ("coalesce-undo",
-                                                                 _("Coalesce Undo"),
-                                                                 _("Coalesce Undo Items"),
+                                                                 "Coalesce Undo",
+                                                                 "Coalesce Undo Items",
                                                                  FALSE,
                                                                  (G_PARAM_READABLE |
                                                                   G_PARAM_STATIC_STRINGS)));
 
   gtk_widget_class_install_style_property (GTK_WIDGET_CLASS (klass),
                                            g_param_spec_boolean ("suppress-unbound",
-                                                                 _("Supress Unbound"),
-                                                                 _("Suppress Unbound Keypresses"),
+                                                                 "Supress Unbound",
+                                                                 "Suppress Unbound Keypresses",
                                                                  FALSE,
                                                                  (G_PARAM_READABLE |
                                                                   G_PARAM_STATIC_STRINGS)));
 
   gtk_widget_class_install_style_property (GTK_WIDGET_CLASS (klass),
                                            g_param_spec_boolean ("block-cursor",
-                                                                 _("Block Cursor"),
-                                                                 _("Use fake block cursor by "
-                                                                   "using overwrite mode."),
+                                                                 "Block Cursor",
+                                                                 "Use fake block cursor by "
+                                                                  "using overwrite mode.",
                                                                  FALSE,
                                                                  (G_PARAM_READABLE |
                                                                   G_PARAM_STATIC_STRINGS)));
 
   gtk_widget_class_install_style_property (GTK_WIDGET_CLASS (klass),
                                            g_param_spec_boolean ("keep-mark-on-char",
-                                                                 _("Keep Mark on Char"),
-                                                                 _("Don't allow the cursor to "
-                                                                   "move to line end."),
+                                                                 "Keep Mark on Char",
+                                                                 "Don't allow the cursor to "
+                                                                  "move to line end.",
                                                                  FALSE,
                                                                  (G_PARAM_READABLE |
                                                                   G_PARAM_STATIC_STRINGS)));
 
+  gtk_widget_class_install_style_property (GTK_WIDGET_CLASS (klass),
+                                           g_param_spec_string ("default-mode",
+                                                                "Default Mode",
+                                                                "Suggest a followup default mode",
+                                                                NULL,
+                                                                (G_PARAM_READABLE |
+                                                                 G_PARAM_STATIC_STRINGS)));
+
   /* Proxy all action signals from source view */
   type = IDE_TYPE_SOURCE_VIEW;
   while (type != G_TYPE_INVALID && type != GTK_TYPE_WIDGET)
@@ -386,6 +438,7 @@ _ide_source_view_mode_new (GtkWidget             *view,
   priv->view = g_object_ref (view);
   priv->name = g_strdup (name);
   priv->type = type;
+  priv->default_mode = get_string_param (mode, "default-mode");
 
   IDE_TRACE_MSG ("coalesce_undo = %d", ide_source_view_mode_get_coalesce_undo (mode));
   IDE_TRACE_MSG ("supress_unbound = %d", ide_source_view_mode_get_suppress_unbound (mode));
diff --git a/libide/ide-source-view-mode.h b/libide/ide-source-view-mode.h
index 71db49f..3a29685 100644
--- a/libide/ide-source-view-mode.h
+++ b/libide/ide-source-view-mode.h
@@ -50,6 +50,7 @@ gboolean     ide_source_view_mode_get_block_cursor      (IdeSourceViewMode *self
 gboolean     ide_source_view_mode_get_suppress_unbound  (IdeSourceViewMode *self);
 gboolean     ide_source_view_mode_get_coalesce_undo     (IdeSourceViewMode *self);
 const gchar *ide_source_view_mode_get_name              (IdeSourceViewMode *self);
+const gchar *ide_source_view_mode_get_default_mode      (IdeSourceViewMode *self);
 gboolean     ide_source_view_mode_get_keep_mark_on_char (IdeSourceViewMode *self);
 
 G_END_DECLS
diff --git a/libide/ide-source-view.c b/libide/ide-source-view.c
index eb6cea4..84d7e5e 100644
--- a/libide/ide-source-view.c
+++ b/libide/ide-source-view.c
@@ -1552,6 +1552,7 @@ ide_source_view_do_mode (IdeSourceView *self,
                          GdkEventKey   *event)
 {
   IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
+  g_autofree gchar *suggested_default = NULL;
   gboolean ret = FALSE;
 
   g_assert (IDE_IS_SOURCE_VIEW (self));
@@ -1579,6 +1580,9 @@ ide_source_view_do_mode (IdeSourceView *self,
       /* hold a reference incase binding changes mode */
       mode = g_object_ref (priv->mode);
 
+      /* lookup what this mode thinks our next default should be */
+      suggested_default = g_strdup (ide_source_view_mode_get_default_mode (priv->mode));
+
       handled = _ide_source_view_mode_do_event (priv->mode, event, &remove);
 
       if (remove)
@@ -1599,7 +1603,7 @@ ide_source_view_do_mode (IdeSourceView *self,
     }
 
   if (!priv->mode)
-    ide_source_view_real_set_mode (self, NULL,  IDE_SOURCE_VIEW_MODE_TYPE_PERMANENT);
+    ide_source_view_real_set_mode (self, suggested_default, IDE_SOURCE_VIEW_MODE_TYPE_PERMANENT);
 
   if (ide_source_view_mode_get_keep_mark_on_char (priv->mode))
     {
@@ -2409,6 +2413,7 @@ ide_source_view_real_set_mode (IdeSourceView         *self,
                                IdeSourceViewModeType  type)
 {
   IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
+  g_autofree gchar *suggested_default = NULL;
   gboolean overwrite;
 
   IDE_ENTRY;
@@ -2428,6 +2433,11 @@ ide_source_view_real_set_mode (IdeSourceView         *self,
   if (priv->mode)
     {
       IdeSourceViewMode *old_mode = g_object_ref (priv->mode);
+      const gchar *str;
+
+      /* see if this mode suggested a default next mode */
+      str = ide_source_view_mode_get_default_mode (old_mode);
+      suggested_default = g_strdup (str);
 
       g_clear_object (&priv->mode);
       if (ide_source_view_mode_get_coalesce_undo (old_mode))
@@ -2437,7 +2447,7 @@ ide_source_view_real_set_mode (IdeSourceView         *self,
 
   if (mode == NULL)
     {
-      mode = "default";
+      mode = suggested_default ?: "default";
       type = IDE_SOURCE_VIEW_MODE_TYPE_PERMANENT;
     }
 


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