[gtksourceview/wip/chergert/vim] more work on layered state in vim/
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/vim] more work on layered state in vim/
- Date: Thu, 21 Oct 2021 22:26:14 +0000 (UTC)
commit f964314ea3ed6f8c11f9500969a68da08cdd8200
Author: Christian Hergert <chergert redhat com>
Date: Thu Oct 21 15:26:09 2021 -0700
more work on layered state in vim/
gtksourceview/gtksourcetypes-private.h | 2 -
gtksourceview/gtksourcetypes.h | 1 +
gtksourceview/gtksourcevim-private.h | 71 ----
gtksourceview/gtksourcevim.c | 435 ------------------------
gtksourceview/gtksourcevimimcontext.c | 230 +++----------
gtksourceview/gtksourcevimimcontext.h | 12 +-
gtksourceview/gtksourcevimstate.c | 438 -------------------------
gtksourceview/gtksourcevimstate.h | 75 -----
gtksourceview/meson.build | 5 +-
gtksourceview/vim/gtk-source-vim-command-bar.c | 56 ++++
gtksourceview/vim/gtk-source-vim-command-bar.h | 34 ++
gtksourceview/vim/gtk-source-vim-insert.h | 8 +-
gtksourceview/vim/gtk-source-vim-normal.c | 22 +-
gtksourceview/vim/gtk-source-vim-normal.h | 7 +-
gtksourceview/vim/gtk-source-vim-replace.h | 6 +-
gtksourceview/vim/gtk-source-vim-state.c | 46 ++-
gtksourceview/vim/gtk-source-vim-state.h | 7 +-
gtksourceview/vim/gtk-source-vim-visual.h | 7 +-
gtksourceview/vim/gtk-source-vim.c | 243 ++++++++++++++
gtksourceview/vim/gtk-source-vim.h | 20 +-
gtksourceview/vim/meson.build | 6 +
21 files changed, 479 insertions(+), 1252 deletions(-)
---
diff --git a/gtksourceview/gtksourcetypes-private.h b/gtksourceview/gtksourcetypes-private.h
index 669bbc0a..cde07715 100644
--- a/gtksourceview/gtksourcetypes-private.h
+++ b/gtksourceview/gtksourcetypes-private.h
@@ -39,8 +39,6 @@ typedef struct _GtkSourceMarksSequence GtkSourceMarksSequence;
typedef struct _GtkSourcePixbufHelper GtkSourcePixbufHelper;
typedef struct _GtkSourceRegex GtkSourceRegex;
typedef struct _GtkSourceSnippetBundle GtkSourceSnippetBundle;
-typedef struct _GtkSourceVim GtkSourceVim;
-typedef struct _GtkSourceVimCallbacks GtkSourceVimCallbacks;
#ifdef _MSC_VER
/* For Visual Studio, we need to export the symbols used by the unit tests */
diff --git a/gtksourceview/gtksourcetypes.h b/gtksourceview/gtksourcetypes.h
index a6a8da02..61859e31 100644
--- a/gtksourceview/gtksourcetypes.h
+++ b/gtksourceview/gtksourcetypes.h
@@ -54,6 +54,7 @@ typedef struct _GtkSourceHover GtkSourceHover;
typedef struct _GtkSourceHoverContext GtkSourceHoverContext;
typedef struct _GtkSourceHoverDisplay GtkSourceHoverDisplay;
typedef struct _GtkSourceHoverProvider GtkSourceHoverProvider;
+typedef struct _GtkSourceVimIMContext GtkSourceVimIMContext;
typedef struct _GtkSourceIndenter GtkSourceIndenter;
typedef struct _GtkSourceLanguage GtkSourceLanguage;
typedef struct _GtkSourceLanguageManager GtkSourceLanguageManager;
diff --git a/gtksourceview/gtksourcevimimcontext.c b/gtksourceview/gtksourcevimimcontext.c
index 0e7a6c6a..c61aec94 100644
--- a/gtksourceview/gtksourcevimimcontext.c
+++ b/gtksourceview/gtksourcevimimcontext.c
@@ -23,18 +23,14 @@
#include "gtksourceview.h"
#include "gtksourcevimimcontext.h"
-#include "gtksourcevim-private.h"
-
#include "gtksource-enumtypes.h"
+#include "vim/gtk-source-vim.h"
+
struct _GtkSourceVimIMContext
{
- GtkIMContext parent_instance;
- GtkSourceView *view;
- GtkSourceVim *vim;
- char *command_bar_text;
- char *command_text;
- GtkSourceVimMode mode;
+ GtkIMContext parent_instance;
+ GtkSourceVim *vim;
};
G_DEFINE_TYPE (GtkSourceVimIMContext, gtk_source_vim_im_context, GTK_TYPE_IM_CONTEXT)
@@ -43,12 +39,10 @@ enum {
PROP_0,
PROP_COMMAND_BAR_TEXT,
PROP_COMMAND_TEXT,
- PROP_MODE,
- PROP_VIEW,
N_PROPS
};
-static GParamSpec *properties [N_PROPS];
+static GParamSpec *properties[N_PROPS];
GtkIMContext *
gtk_source_vim_im_context_new (void)
@@ -64,10 +58,19 @@ gtk_source_vim_im_context_set_client_widget (GtkIMContext *context,
g_return_if_fail (GTK_SOURCE_IS_VIM_IM_CONTEXT (self));
- if (g_set_weak_pointer (&self->view, GTK_SOURCE_VIEW (widget)))
+ if (!GTK_SOURCE_IS_VIEW (widget))
+ return;
+
+ if (self->vim != NULL)
{
- gtk_source_vim_set_view (self->vim, self->view);
+ g_object_run_dispose (G_OBJECT (self->vim));
+ g_clear_object (&self->vim);
}
+
+ self->vim = gtk_source_vim_new (GTK_SOURCE_VIEW (widget));
+
+ 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]);
}
static void
@@ -84,92 +87,44 @@ static void
gtk_source_vim_im_context_focus_in (GtkIMContext *context)
{
GtkSourceVimIMContext *self = (GtkSourceVimIMContext *)context;
+ GtkSourceView *view;
g_return_if_fail (GTK_SOURCE_IS_VIM_IM_CONTEXT (self));
- gtk_text_view_set_overwrite (GTK_TEXT_VIEW (self->view), TRUE);
- gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (self->view), TRUE);
-
- g_print ("Focus in %p\n", self->view);
-}
-
-static void
-gtk_source_vim_im_context_focus_out (GtkIMContext *context)
-{
- GtkSourceVimIMContext *self = (GtkSourceVimIMContext *)context;
-
- g_return_if_fail (GTK_SOURCE_IS_VIM_IM_CONTEXT (self));
-
- gtk_text_view_set_overwrite (GTK_TEXT_VIEW (self->view), FALSE);
- gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (self->view), FALSE);
+ if (self->vim == NULL)
+ return;
- g_print ("Focus out\n");
-}
-
-static void
-gtk_source_vim_im_context_beep (gpointer user_data)
-{
- GtkSourceVimIMContext *self = user_data;
- GdkDisplay *display;
-
- g_assert (GTK_SOURCE_IS_VIM_IM_CONTEXT (self));
+ view = gtk_source_vim_state_get_view (GTK_SOURCE_VIM_STATE (self->vim));
- if (self->view != NULL &&
- (display = gtk_widget_get_display (GTK_WIDGET (self->view))))
+ if (view != NULL)
{
- gdk_display_beep (display);
+ gtk_text_view_set_overwrite (GTK_TEXT_VIEW (view), TRUE);
+ gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), TRUE);
}
-}
-
-static void
-gtk_source_vim_im_context_set_mode (GtkSourceVimMode mode,
- gpointer user_data)
-{
- GtkSourceVimIMContext *self = user_data;
-
- g_assert (GTK_SOURCE_IS_VIM_IM_CONTEXT (self));
- self->mode = mode;
- g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_MODE]);
+ g_print ("Focus in %p\n", view);
}
static void
-gtk_source_vim_im_context_set_label (GtkSourceVimLabel label,
- const char *text,
- gpointer user_data)
+gtk_source_vim_im_context_focus_out (GtkIMContext *context)
{
- GtkSourceVimIMContext *self = user_data;
+ GtkSourceVimIMContext *self = (GtkSourceVimIMContext *)context;
+ GtkSourceView *view;
- g_assert (GTK_SOURCE_IS_VIM_IM_CONTEXT (self));
+ g_return_if_fail (GTK_SOURCE_IS_VIM_IM_CONTEXT (self));
- if (label == GTK_SOURCE_VIM_LABEL_COMMAND_BAR)
- {
- g_free (self->command_bar_text);
- self->command_bar_text = g_strdup (text);
- g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_COMMAND_BAR_TEXT]);
- }
- else if (label == GTK_SOURCE_VIM_LABEL_COMMAND)
- {
- g_free (self->command_text);
- self->command_text = g_strdup (text);
- g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_COMMAND_TEXT]);
- }
-}
+ g_print ("Focus out\n");
-static gboolean
-gtk_source_vim_im_context_propagate_keypress (GdkEvent *event,
- gpointer user_data)
-{
- GtkSourceVimIMContext *self = user_data;
+ if (self->vim == NULL)
+ return;
- g_assert (GTK_SOURCE_IS_VIM_IM_CONTEXT (self));
+ view = gtk_source_vim_state_get_view (GTK_SOURCE_VIM_STATE (self->vim));
- if (self->view == NULL)
+ if (view != NULL)
{
- return FALSE;
+ gtk_text_view_set_overwrite (GTK_TEXT_VIEW (view), FALSE);
+ gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
}
-
- return gtk_text_view_im_context_filter_keypress (GTK_TEXT_VIEW (self->view), event);
}
static gboolean
@@ -177,28 +132,27 @@ gtk_source_vim_im_context_filter_keypress (GtkIMContext *context,
GdkEvent *event)
{
GtkSourceVimIMContext *self = (GtkSourceVimIMContext *)context;
- GdkModifierType state;
- gboolean ret = FALSE;
- guint keyval;
g_assert (GTK_SOURCE_IS_VIM_IM_CONTEXT (self));
g_assert (gdk_event_get_event_type (event) == GDK_KEY_PRESS ||
gdk_event_get_event_type (event) == GDK_KEY_RELEASE);
- return gtk_source_vim_deliver (self->vim, event);
+ if (self->vim == NULL)
+ {
+ return FALSE;
+ }
+
+ return gtk_source_vim_state_handle_event (GTK_SOURCE_VIM_STATE (self->vim), event);
}
static void
-gtk_source_vim_im_context_finalize (GObject *object)
+gtk_source_vim_im_context_dispose (GObject *object)
{
GtkSourceVimIMContext *self = (GtkSourceVimIMContext *)object;
- g_clear_weak_pointer (&self->view);
- g_clear_pointer (&self->vim, gtk_source_vim_free);
- g_clear_pointer (&self->command_text, g_free);
- g_clear_pointer (&self->command_bar_text, g_free);
+ g_clear_object (&self->vim);
- G_OBJECT_CLASS (gtk_source_vim_im_context_parent_class)->finalize (object);
+ G_OBJECT_CLASS (gtk_source_vim_im_context_parent_class)->dispose (object);
}
static void
@@ -219,27 +173,6 @@ gtk_source_vim_im_context_get_property (GObject *object,
g_value_set_string (value, gtk_source_vim_im_context_get_command_bar_text (self));
break;
- case PROP_VIEW:
- g_value_set_object (value, gtk_source_vim_im_context_get_view (self));
- break;
-
- case PROP_MODE:
- g_value_set_static_string (value, gtk_source_vim_im_context_get_mode (self));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-gtk_source_vim_im_context_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- switch (prop_id)
- {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -251,9 +184,8 @@ gtk_source_vim_im_context_class_init (GtkSourceVimIMContextClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkIMContextClass *im_context_class = GTK_IM_CONTEXT_CLASS (klass);
- object_class->finalize = gtk_source_vim_im_context_finalize;
+ object_class->dispose = gtk_source_vim_im_context_dispose;
object_class->get_property = gtk_source_vim_im_context_get_property;
- object_class->set_property = gtk_source_vim_im_context_set_property;
im_context_class->set_client_widget = gtk_source_vim_im_context_set_client_widget;
im_context_class->reset = gtk_source_vim_im_context_reset;
@@ -261,13 +193,6 @@ gtk_source_vim_im_context_class_init (GtkSourceVimIMContextClass *klass)
im_context_class->focus_out = gtk_source_vim_im_context_focus_out;
im_context_class->filter_keypress = gtk_source_vim_im_context_filter_keypress;
- properties [PROP_VIEW] =
- g_param_spec_object ("view",
- "View",
- "The view the IM context is attached to",
- GTK_SOURCE_TYPE_VIEW,
- (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
properties [PROP_COMMAND_TEXT] =
g_param_spec_string ("command-text",
"Command Text",
@@ -282,45 +207,12 @@ gtk_source_vim_im_context_class_init (GtkSourceVimIMContextClass *klass)
NULL,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- properties [PROP_MODE] =
- g_param_spec_string ("mode",
- "Mode",
- "The VIM mode for the context",
- "NORMAL",
- (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
gtk_source_vim_im_context_init (GtkSourceVimIMContext *self)
{
- static const GtkSourceVimCallbacks callbacks = {
- .beep = gtk_source_vim_im_context_beep,
- .set_mode = gtk_source_vim_im_context_set_mode,
- .set_label = gtk_source_vim_im_context_set_label,
- .filter_keypress = gtk_source_vim_im_context_propagate_keypress,
- };
-
- self->vim = gtk_source_vim_new (&callbacks, self);
-}
-
-/**
- * gtk_source_vim_im_context_get_view:
- * @self: a #GtkSourceVimIMContext
- *
- * Gets the #GtkSourceView that @self is attached to.
- *
- * Returns: (transfer none) (nullable): a #GtkSourceView or %NULL
- *
- * Since: 5.4
- */
-GtkSourceView *
-gtk_source_vim_im_context_get_view (GtkSourceVimIMContext *self)
-{
- g_return_val_if_fail (GTK_SOURCE_IS_VIM_IM_CONTEXT (self), NULL);
-
- return self->view;
}
/**
@@ -338,7 +230,10 @@ gtk_source_vim_im_context_get_command_text (GtkSourceVimIMContext *self)
{
g_return_val_if_fail (GTK_SOURCE_IS_VIM_IM_CONTEXT (self), NULL);
- return self->command_text;
+ if (self->vim == NULL)
+ return NULL;
+
+ return gtk_source_vim_get_command_text (self->vim);
}
/**
@@ -356,29 +251,8 @@ gtk_source_vim_im_context_get_command_bar_text (GtkSourceVimIMContext *self)
{
g_return_val_if_fail (GTK_SOURCE_IS_VIM_IM_CONTEXT (self), NULL);
- return self->command_bar_text;
-}
-
-const char *
-gtk_source_vim_im_context_get_mode (GtkSourceVimIMContext *self)
-{
- g_return_val_if_fail (GTK_SOURCE_IS_VIM_IM_CONTEXT (self), 0);
-
- switch ((int)self->mode)
- {
- case GTK_SOURCE_VIM_INSERT:
- return "INSERT";
- case GTK_SOURCE_VIM_REPLACE:
- return "REPLACE";
- case GTK_SOURCE_VIM_VIRTUAL_REPLACE:
- return "VREPLACE";
- case GTK_SOURCE_VIM_VISUAL:
- return "VISUAL";
- case GTK_SOURCE_VIM_VISUAL_LINE:
- return "VISUAL LINE";
- case GTK_SOURCE_VIM_VISUAL_BLOCK:
- return "VISUAL BLOCK";
- default:
+ if (self->vim == NULL)
return NULL;
- }
+
+ return gtk_source_vim_get_command_bar_text (self->vim);
}
diff --git a/gtksourceview/gtksourcevimimcontext.h b/gtksourceview/gtksourcevimimcontext.h
index e3e10470..6c08f540 100644
--- a/gtksourceview/gtksourcevimimcontext.h
+++ b/gtksourceview/gtksourcevimimcontext.h
@@ -33,18 +33,14 @@ G_BEGIN_DECLS
#define GTK_SOURCE_TYPE_VIM_IM_CONTEXT (gtk_source_vim_im_context_get_type())
-GTK_SOURCE_AVAILABLE_IN_5_4
+GTK_SOURCE_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GtkSourceVimIMContext, gtk_source_vim_im_context, GTK_SOURCE, VIM_IM_CONTEXT,
GtkIMContext)
-GTK_SOURCE_AVAILABLE_IN_5_4
+GTK_SOURCE_AVAILABLE_IN_ALL
GtkIMContext *gtk_source_vim_im_context_new (void);
-GTK_SOURCE_AVAILABLE_IN_5_4
-GtkSourceView *gtk_source_vim_im_context_get_view (GtkSourceVimIMContext *self);
-GTK_SOURCE_AVAILABLE_IN_5_4
+GTK_SOURCE_AVAILABLE_IN_ALL
const char *gtk_source_vim_im_context_get_command_text (GtkSourceVimIMContext *self);
-GTK_SOURCE_AVAILABLE_IN_5_4
+GTK_SOURCE_AVAILABLE_IN_ALL
const char *gtk_source_vim_im_context_get_command_bar_text (GtkSourceVimIMContext *self);
-GTK_SOURCE_AVAILABLE_IN_5_4
-const char *gtk_source_vim_im_context_get_mode (GtkSourceVimIMContext *self);
G_END_DECLS
diff --git a/gtksourceview/meson.build b/gtksourceview/meson.build
index d059af8c..278a0168 100644
--- a/gtksourceview/meson.build
+++ b/gtksourceview/meson.build
@@ -5,6 +5,8 @@ core_marshallers = gnome.genmarshal('gtksource-marshal',
valist_marshallers: true,
)
+subdir('vim')
+
core_public_h = files([
'gtksource.h',
'gtksourcebuffer.h',
@@ -135,8 +137,6 @@ core_private_c = files([
'gtksourcesnippetbundle.c',
'gtksourcesnippetbundle-parser.c',
'gtksourceview-snippets.c',
- 'gtksourcevim.c',
- 'gtksourcevimstate.c',
'implregex.c',
])
@@ -225,6 +225,7 @@ core_sources = [
gtksourceversion_h,
core_marshallers,
gtksource_res,
+ vim_sources,
]
install_headers(
diff --git a/gtksourceview/vim/gtk-source-vim-command-bar.c b/gtksourceview/vim/gtk-source-vim-command-bar.c
new file mode 100644
index 00000000..cbb2385f
--- /dev/null
+++ b/gtksourceview/vim/gtk-source-vim-command-bar.c
@@ -0,0 +1,56 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#include "gtk-source-vim-command-bar.h"
+
+struct _GtkSourceVimCommandBar
+{
+ GtkSourceVimState parent_instance;
+};
+
+G_DEFINE_TYPE (GtkSourceVimCommandBar, gtk_source_vim_command_bar, GTK_SOURCE_TYPE_VIM_STATE)
+
+GtkSourceVimCommandBar *
+gtk_source_vim_command_bar_new (void)
+{
+ return g_object_new (GTK_SOURCE_TYPE_VIM_COMMAND_BAR, NULL);
+}
+
+static void
+gtk_source_vim_command_bar_dispose (GObject *object)
+{
+ G_OBJECT_CLASS (gtk_source_vim_command_bar_parent_class)->dispose (object);
+}
+
+static void
+gtk_source_vim_command_bar_class_init (GtkSourceVimCommandBarClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = gtk_source_vim_command_bar_dispose;
+}
+
+static void
+gtk_source_vim_command_bar_init (GtkSourceVimCommandBar *self)
+{
+}
diff --git a/gtksourceview/vim/gtk-source-vim-command-bar.h b/gtksourceview/vim/gtk-source-vim-command-bar.h
new file mode 100644
index 00000000..bf212128
--- /dev/null
+++ b/gtksourceview/vim/gtk-source-vim-command-bar.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+
+#include "gtk-source-vim-state.h"
+
+G_BEGIN_DECLS
+
+#define GTK_SOURCE_TYPE_VIM_COMMAND_BAR (gtk_source_vim_command_bar_get_type())
+
+G_DECLARE_FINAL_TYPE (GtkSourceVimCommandBar, gtk_source_vim_command_bar, GTK_SOURCE, VIM_COMMAND_BAR,
GtkSourceVimState)
+
+GtkSourceVimCommandBar *gtk_source_vim_command_bar_new (void);
+
+G_END_DECLS
diff --git a/gtksourceview/vim/gtk-source-vim-insert.h b/gtksourceview/vim/gtk-source-vim-insert.h
index 0d1b3d10..49ed3459 100644
--- a/gtksourceview/vim/gtk-source-vim-insert.h
+++ b/gtksourceview/vim/gtk-source-vim-insert.h
@@ -21,14 +21,14 @@
#pragma once
-#include "gtksourcevimstate.h"
+#include "gtk-source-vim-state.h"
G_BEGIN_DECLS
-#define GTK_TYPE_SOURCE_VIM_INSERT (gtk_source_vim_insert_get_type())
+#define GTK_SOURCE_TYPE_VIM_INSERT (gtk_source_vim_insert_get_type())
-G_DECLARE_FINAL_TYPE (GtkSourceVimInsert, gtk_source_vim_insert, GTK_SOURCE, VIM_INSERT, GObject)
+G_DECLARE_FINAL_TYPE (GtkSourceVimInsert, gtk_source_vim_insert, GTK_SOURCE, VIM_INSERT, GtkSourceVimState)
-GtkSourceVimInsert *gtk_source_vim_insert_new (GtkSourceVimState *parent);
+GtkSourceVimInsert *gtk_source_vim_insert_new (void);
G_END_DECLS
diff --git a/gtksourceview/vim/gtk-source-vim-normal.c b/gtksourceview/vim/gtk-source-vim-normal.c
index b2e495aa..7f149042 100644
--- a/gtksourceview/vim/gtk-source-vim-normal.c
+++ b/gtksourceview/vim/gtk-source-vim-normal.c
@@ -21,7 +21,7 @@
#include "config.h"
-#include "gtksourcevimnormal.h"
+#include "gtk-source-vim-normal.h"
typedef enum
{
@@ -62,7 +62,7 @@ is_escape (guint keyval,
GdkModifierType mods)
{
return keyval == GDK_KEY_Escape ||
- (keyval == GDK_KEY_bracketleft && (state & GDK_CONTROL_MASK) != 0);
+ (keyval == GDK_KEY_bracketleft && (mods & GDK_CONTROL_MASK) != 0);
}
static void
@@ -91,6 +91,7 @@ gtk_source_vim_normal_handle_keypress (GtkSourceVimState *state,
return TRUE;
}
+#if 0
if (keyval >= GDK_KEY_0 && keyval <= GDK_KEY_9)
{
}
@@ -138,6 +139,7 @@ gtk_source_vim_normal_handle_keypress (GtkSourceVimState *state,
case GDK_KEY_9:
break;
}
+#endif
return FALSE;
}
@@ -176,11 +178,17 @@ gtk_source_vim_normal_init (GtkSourceVimNormal *self)
}
GtkSourceVimNormal *
-gtk_source_vim_normal_new (GtkSourceVimState *parent)
+gtk_source_vim_normal_new (void)
{
- g_return_val_if_fail (GTK_SOURCE_IS_VIM_STATE (parent), NULL);
+ return g_object_new (GTK_SOURCE_TYPE_VIM_STATE, NULL);
+}
+
+void
+gtk_source_vim_normal_clear (GtkSourceVimNormal *self)
+{
+ g_return_if_fail (GTK_SOURCE_IS_VIM_NORMAL (self));
- return g_object_new (GTK_SOURCE_TYPE_VIM_STATE,
- "parent", parent,
- NULL);
+ /* TODO: clear any state other than repeat, registers, marks, etc
+ * so that input from the user feels fresh.
+ */
}
diff --git a/gtksourceview/vim/gtk-source-vim-normal.h b/gtksourceview/vim/gtk-source-vim-normal.h
index a09a5d40..7ff91c18 100644
--- a/gtksourceview/vim/gtk-source-vim-normal.h
+++ b/gtksourceview/vim/gtk-source-vim-normal.h
@@ -21,14 +21,15 @@
#pragma once
-#include "gtksourcevimstate.h"
+#include "gtk-source-vim-state.h"
G_BEGIN_DECLS
-#define GTK_TYPE_SOURCE_VIM_NORMAL (gtk_source_vim_normal_get_type())
+#define GTK_SOURCE_TYPE_VIM_NORMAL (gtk_source_vim_normal_get_type())
G_DECLARE_FINAL_TYPE (GtkSourceVimNormal, gtk_source_vim_normal, GTK_SOURCE, VIM_NORMAL, GtkSourceVimState)
-GtkSourceVimNormal *gtk_source_vim_normal_new (GtkSourceVimState *parent);
+GtkSourceVimNormal *gtk_source_vim_normal_new (void);
+void gtk_source_vim_normal_clear (GtkSourceVimNormal *self);
G_END_DECLS
diff --git a/gtksourceview/vim/gtk-source-vim-replace.h b/gtksourceview/vim/gtk-source-vim-replace.h
index 2b297a5a..35282995 100644
--- a/gtksourceview/vim/gtk-source-vim-replace.h
+++ b/gtksourceview/vim/gtk-source-vim-replace.h
@@ -21,14 +21,14 @@
#pragma once
-#include "gtksourcevimstate.h"
+#include "gtk-source-vim-state.h"
G_BEGIN_DECLS
-#define GTK_TYPE_SOURCE_VIM_REPLACE (gtk_source_vim_replace_get_type())
+#define GTK_SOURCE_TYPE_VIM_REPLACE (gtk_source_vim_replace_get_type())
G_DECLARE_FINAL_TYPE (GtkSourceVimReplace, gtk_source_vim_replace, GTK_SOURCE, VIM_REPLACE,
GtkSourceVimState)
-GtkSourceVimReplace *gtk_source_vim_replace_new (GtkSourceVimState *parent);
+GtkSourceVimReplace *gtk_source_vim_replace_new (void);
G_END_DECLS
diff --git a/gtksourceview/vim/gtk-source-vim-state.c b/gtksourceview/vim/gtk-source-vim-state.c
index 31fb2843..378988cc 100644
--- a/gtksourceview/vim/gtk-source-vim-state.c
+++ b/gtksourceview/vim/gtk-source-vim-state.c
@@ -21,6 +21,9 @@
#include "config.h"
+#include "gtksourcebuffer.h"
+#include "gtksourceview.h"
+
#include "gtk-source-vim-state.h"
typedef struct
@@ -42,9 +45,9 @@ enum {
static GParamSpec *properties [N_PROPS];
static inline void
-get_key_string (guint keyval,
- GdkModifierType mods,
- char str[16])
+keyval_to_string (guint keyval,
+ GdkModifierType mods,
+ char str[16])
{
int pos = 0;
@@ -286,6 +289,29 @@ gtk_source_vim_state_beep (GtkSourceVimState *self)
}
}
+GtkSourceVimState *
+gtk_source_vim_state_get_child (GtkSourceVimState *self)
+{
+ GtkSourceVimStatePrivate *priv = gtk_source_vim_state_get_instance_private (self);
+
+ g_return_val_if_fail (GTK_SOURCE_IS_VIM_STATE (self), NULL);
+
+ return priv->child;
+}
+
+GtkSourceVimState *
+gtk_source_vim_state_get_current (GtkSourceVimState *self)
+{
+ GtkSourceVimStatePrivate *priv = gtk_source_vim_state_get_instance_private (self);
+
+ g_return_val_if_fail (GTK_SOURCE_IS_VIM_STATE (self), NULL);
+
+ if (priv->child == NULL)
+ return self;
+
+ return gtk_source_vim_state_get_current (priv->child);
+}
+
GtkSourceVimState *
gtk_source_vim_state_get_parent (GtkSourceVimState *self)
{
@@ -315,20 +341,20 @@ gtk_source_vim_state_repeat (GtkSourceVimState *self,
{
g_return_if_fail (GTK_SOURCE_IS_VIM_STATE (self));
- if (GTK_SOURCE_VIM_GET_CLASS (self)->repeat)
+ if (GTK_SOURCE_VIM_STATE_GET_CLASS (self)->repeat)
{
- GTK_SOURCE_VIM_GET_CLASS (self)->repeat (self, repeat);
+ GTK_SOURCE_VIM_STATE_GET_CLASS (self)->repeat (self, repeat);
}
}
gboolean
-gtk_source_vim_get_can_repeat (GtkSourceVimState *self)
+gtk_source_vim_state_get_can_repeat (GtkSourceVimState *self)
{
g_return_val_if_fail (GTK_SOURCE_IS_VIM_STATE (self), FALSE);
- if (GTK_SOURCE_VIM_GET_CLASS (self)->get_can_repeat)
+ if (GTK_SOURCE_VIM_STATE_GET_CLASS (self)->get_can_repeat)
{
- return GTK_SOURCE_VIM_GET_CLASS (self)->get_can_repeat (self);
+ return GTK_SOURCE_VIM_STATE_GET_CLASS (self)->get_can_repeat (self);
}
return FALSE;
@@ -341,9 +367,9 @@ gtk_source_vim_state_handle_event (GtkSourceVimState *self,
g_return_val_if_fail (GTK_SOURCE_IS_VIM_STATE (self), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
- if (GTK_SOURCE_VIM_GET_CLASS (self)->handle_event)
+ if (GTK_SOURCE_VIM_STATE_GET_CLASS (self)->handle_event)
{
- return GTK_SOURCE_VIM_GET_CLASS (self)->handle_event (self, event);
+ return GTK_SOURCE_VIM_STATE_GET_CLASS (self)->handle_event (self, event);
}
return FALSE;
diff --git a/gtksourceview/vim/gtk-source-vim-state.h b/gtksourceview/vim/gtk-source-vim-state.h
index 89a61c7f..84f8efeb 100644
--- a/gtksourceview/vim/gtk-source-vim-state.h
+++ b/gtksourceview/vim/gtk-source-vim-state.h
@@ -24,11 +24,10 @@
#include <gtk/gtk.h>
#include "gtksourcetypes.h"
-#include "gtksourcetypes-private.h"
G_BEGIN_DECLS
-#define GTK_TYPE_SOURCE_VIM_STATE (gtk_source_vim_state_get_type())
+#define GTK_SOURCE_TYPE_VIM_STATE (gtk_source_vim_state_get_type())
G_DECLARE_DERIVABLE_TYPE (GtkSourceVimState, gtk_source_vim_state, GTK_SOURCE, VIM_STATE, GObject)
@@ -58,6 +57,8 @@ void gtk_source_vim_state_push (GtkSourceVimState *self,
GtkSourceVimState *new_state);
void gtk_source_vim_state_pop (GtkSourceVimState *self);
void gtk_source_vim_state_beep (GtkSourceVimState *self);
+GtkSourceVimState *gtk_source_vim_state_get_child (GtkSourceVimState *self);
+GtkSourceVimState *gtk_source_vim_state_get_current (GtkSourceVimState *self);
GtkSourceView *gtk_source_vim_state_get_view (GtkSourceVimState *self);
GtkSourceBuffer *gtk_source_vim_state_get_buffer (GtkSourceVimState *self,
GtkTextIter *insert,
@@ -66,7 +67,7 @@ GtkSourceVimState *gtk_source_vim_state_get_root (GtkSourceVimState *self)
GtkSourceVimState *gtk_source_vim_state_get_parent (GtkSourceVimState *self);
gboolean gtk_source_vim_state_handle_event (GtkSourceVimState *self,
GdkEvent *event);
-gboolean gtk_source_vim_state_get_can_repeat (GtkSourceVimState *self,
+gboolean gtk_source_vim_state_get_can_repeat (GtkSourceVimState *self);
void gtk_source_vim_state_repeat (GtkSourceVimState *self,
int repeat);
diff --git a/gtksourceview/vim/gtk-source-vim-visual.h b/gtksourceview/vim/gtk-source-vim-visual.h
index 411444fa..9ebed71a 100644
--- a/gtksourceview/vim/gtk-source-vim-visual.h
+++ b/gtksourceview/vim/gtk-source-vim-visual.h
@@ -21,7 +21,7 @@
#pragma once
-#include "gtksourcevimstate.h"
+#include "gtk-source-vim-state.h"
G_BEGIN_DECLS
@@ -32,11 +32,10 @@ typedef enum
GTK_SOURCE_VIM_VISUAL_BLOCK,
} GtkSourceVimVisualMode;
-#define GTK_TYPE_SOURCE_VIM_VISUAL (gtk_source_vim_visual_get_type())
+#define GTK_SOURCE_TYPE_VIM_VISUAL (gtk_source_vim_visual_get_type())
G_DECLARE_FINAL_TYPE (GtkSourceVimVisual, gtk_source_vim_visual, GTK_SOURCE, VIM_VISUAL, GObject)
-GtkSourceVimVisual *gtk_source_vim_visual_new (GtkSourceVimState *parent,
- GtkSourceVimVisualMode mode);
+GtkSourceVimVisual *gtk_source_vim_visual_new (GtkSourceVimVisualMode mode);
G_END_DECLS
diff --git a/gtksourceview/vim/gtk-source-vim.c b/gtksourceview/vim/gtk-source-vim.c
new file mode 100644
index 00000000..fff5d177
--- /dev/null
+++ b/gtksourceview/vim/gtk-source-vim.c
@@ -0,0 +1,243 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#include "gtk-source-vim.h"
+#include "gtk-source-vim-command-bar.h"
+#include "gtk-source-vim-normal.h"
+
+struct _GtkSourceVim
+{
+ GtkSourceVimState parent_instance;
+};
+
+G_DEFINE_TYPE (GtkSourceVim, gtk_source_vim, GTK_SOURCE_TYPE_VIM_STATE)
+
+enum {
+ PROP_0,
+ PROP_COMMAND_TEXT,
+ PROP_COMMAND_BAR_TEXT,
+ N_PROPS
+};
+
+enum {
+ SPLIT,
+ N_SIGNALS
+};
+
+static GParamSpec *properties[N_PROPS];
+static guint signals[N_SIGNALS];
+
+GtkSourceVim *
+gtk_source_vim_new (GtkSourceView *view)
+{
+ return g_object_new (GTK_SOURCE_TYPE_VIM,
+ "view", view,
+ NULL);
+}
+
+static gboolean
+gtk_source_vim_handle_event (GtkSourceVimState *state,
+ GdkEvent *event)
+{
+ GtkSourceVimState *current;
+
+ g_assert (GTK_SOURCE_IS_VIM (state));
+ g_assert (event != NULL);
+
+ current = gtk_source_vim_state_get_current (state);
+
+ if (current == state)
+ {
+ return FALSE;
+ }
+
+ return gtk_source_vim_state_handle_event (current, event);
+}
+
+static void
+gtk_source_vim_constructed (GObject *object)
+{
+ GtkSourceVim *self = (GtkSourceVim *)object;
+ g_autoptr(GtkSourceVimNormal) normal = NULL;
+
+ G_OBJECT_CLASS (gtk_source_vim_parent_class)->constructed (object);
+
+ normal = gtk_source_vim_normal_new ();
+ gtk_source_vim_state_push (GTK_SOURCE_VIM_STATE (self),
+ GTK_SOURCE_VIM_STATE (normal));
+}
+
+static void
+gtk_source_vim_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkSourceVim *self = GTK_SOURCE_VIM (object);
+
+ switch (prop_id)
+ {
+ case PROP_COMMAND_TEXT:
+ g_value_set_string (value, gtk_source_vim_get_command_text (self));
+ break;
+
+ case PROP_COMMAND_BAR_TEXT:
+ g_value_set_string (value, gtk_source_vim_get_command_bar_text (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gtk_source_vim_class_init (GtkSourceVimClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkSourceVimStateClass *state_class = GTK_SOURCE_VIM_STATE_CLASS (klass);
+
+ object_class->constructed = gtk_source_vim_constructed;
+ object_class->get_property = gtk_source_vim_get_property;
+
+ state_class->handle_event = gtk_source_vim_handle_event;
+
+ properties [PROP_COMMAND_TEXT] =
+ g_param_spec_string ("command-text",
+ "Command Text",
+ "Command Text",
+ NULL,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_COMMAND_BAR_TEXT] =
+ g_param_spec_string ("command-bar-text",
+ "Command Bar Text",
+ "Command Bar Text",
+ NULL,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+
+ /**
+ * GtkSourceVim::split:
+ * @self: a #GtkSourceVim
+ * @orientation: a #GtkOrientation for vertical or horizontal
+ * @new_document: %TRUE if a new document should be created
+ * @focus_split: %TRUE if the new document should be focused
+ * @numeric: a numeric value provided with the command such as
+ * the number of columns for the split
+ */
+ signals[SPLIT] =
+ g_signal_new ("split",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE,
+ 3,
+ GTK_TYPE_ORIENTATION,
+ G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN,
+ G_TYPE_INT);
+}
+
+static void
+gtk_source_vim_init (GtkSourceVim *self)
+{
+}
+
+const char *
+gtk_source_vim_get_command_text (GtkSourceVim *self)
+{
+ GtkSourceVimState *current;
+
+ g_return_val_if_fail (GTK_SOURCE_IS_VIM (self), NULL);
+
+ current = gtk_source_vim_state_get_current (GTK_SOURCE_VIM_STATE (self));
+
+ if (GTK_SOURCE_IS_VIM_NORMAL (current))
+ {
+ /* TODO */
+ }
+
+ return NULL;
+}
+
+const char *
+gtk_source_vim_get_command_bar_text (GtkSourceVim *self)
+{
+ GtkSourceVimState *child;
+
+ g_return_val_if_fail (GTK_SOURCE_IS_VIM (self), NULL);
+
+ child = gtk_source_vim_state_get_child (GTK_SOURCE_VIM_STATE (self));
+
+ if (GTK_SOURCE_IS_VIM_COMMAND_BAR (child))
+ {
+ /* TODO */
+ }
+
+ return NULL;
+}
+
+void
+gtk_source_vim_emit_split (GtkSourceVim *self,
+ GtkOrientation orientation,
+ gboolean new_document,
+ gboolean focus_split,
+ int numeric)
+{
+ g_return_if_fail (GTK_SOURCE_IS_VIM (self));
+
+ g_signal_emit (self, signals[SPLIT], 0,
+ orientation, new_document, focus_split, numeric);
+}
+
+void
+gtk_source_vim_reset (GtkSourceVim *self)
+{
+ GtkSourceVimState *current;
+
+ g_return_if_fail (GTK_SOURCE_IS_VIM (self));
+
+ /* Clear everything up to the top-most Normal mode */
+ while ((current = gtk_source_vim_state_get_current (GTK_SOURCE_VIM_STATE (self))))
+ {
+ GtkSourceVimState *parent = gtk_source_vim_state_get_parent (current);
+
+ if (parent == NULL || parent == GTK_SOURCE_VIM_STATE (self))
+ break;
+
+ gtk_source_vim_state_pop (current);
+ }
+
+ current = gtk_source_vim_state_get_current (GTK_SOURCE_VIM_STATE (self));
+
+ /* If we found the normal mode (should always happen), then
+ * also tell it to clear anything in progress.
+ */
+ if (GTK_SOURCE_IS_VIM_NORMAL (current))
+ {
+ gtk_source_vim_normal_clear (GTK_SOURCE_VIM_NORMAL (current));
+ }
+}
diff --git a/gtksourceview/vim/gtk-source-vim.h b/gtksourceview/vim/gtk-source-vim.h
index 9a7e6f87..b867b6cf 100644
--- a/gtksourceview/vim/gtk-source-vim.h
+++ b/gtksourceview/vim/gtk-source-vim.h
@@ -21,20 +21,22 @@
#pragma once
-#include "gtksourcevim.h"
+#include "gtk-source-vim-state.h"
G_BEGIN_DECLS
-#define GTK_TYPE_SOURCE_VIM (gtk_source_vim_get_type())
+#define GTK_SOURCE_TYPE_VIM (gtk_source_vim_get_type())
G_DECLARE_FINAL_TYPE (GtkSourceVim, gtk_source_vim, GTK_SOURCE, VIM, GtkSourceVimState)
-GtkSourceVim *gtk_source_vim_new (GtkSourceView *view);
-const char *gtk_source_vim_get_command (GtkSourceVim *self);
-const char *gtk_source_vim_get_command_bar (GtkSourceVim *self);
-void gtk_source_vim_emit_split (GtkSourceVim *self,
- GtkOrientation orientation,
- gboolean new_document,
- gboolean focus_split);
+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);
+void gtk_source_vim_emit_split (GtkSourceVim *self,
+ GtkOrientation orientation,
+ gboolean new_document,
+ gboolean focus_split,
+ int numeric);
G_END_DECLS
diff --git a/gtksourceview/vim/meson.build b/gtksourceview/vim/meson.build
new file mode 100644
index 00000000..a0eb2858
--- /dev/null
+++ b/gtksourceview/vim/meson.build
@@ -0,0 +1,6 @@
+vim_sources = files([
+ 'gtk-source-vim.c',
+ 'gtk-source-vim-command-bar.c',
+ 'gtk-source-vim-normal.c',
+ 'gtk-source-vim-state.c',
+])
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]