[gtksourceview/wip/chergert/vim: 11/73] some slight work on transitions
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/vim: 11/73] some slight work on transitions
- Date: Tue, 26 Oct 2021 23:20:36 +0000 (UTC)
commit dfe60eb65fca91e294860e7ace536585bbbfd8e5
Author: Christian Hergert <chergert redhat com>
Date: Tue Oct 19 12:28:32 2021 -0700
some slight work on transitions
I think we'll want a way to enter/exit a state so that we can more easily
handle transitions.
gtksourceview/gtksourcevim-private.h | 15 +++--
gtksourceview/gtksourcevim.c | 114 +++++++++++++++++++++++++++++++---
gtksourceview/gtksourcevimimcontext.c | 5 +-
3 files changed, 119 insertions(+), 15 deletions(-)
---
diff --git a/gtksourceview/gtksourcevim-private.h b/gtksourceview/gtksourcevim-private.h
index 8c0d186c..28964cb1 100644
--- a/gtksourceview/gtksourcevim-private.h
+++ b/gtksourceview/gtksourcevim-private.h
@@ -23,6 +23,7 @@
#include <gdk/gdk.h>
+#include "gtksourcetypes.h"
#include "gtksourcetypes-private.h"
G_BEGIN_DECLS
@@ -58,11 +59,13 @@ struct _GtkSourceVimCallbacks
gpointer user_data);
};
-GtkSourceVim *gtk_source_vim_new (const GtkSourceVimCallbacks *callbacks,
- gpointer user_data);
-gboolean gtk_source_vim_deliver (GtkSourceVim *self,
- GdkEvent *event);
-void gtk_source_vim_reset (GtkSourceVim *self);
-void gtk_source_vim_free (GtkSourceVim *self);
+GtkSourceVim *gtk_source_vim_new (const GtkSourceVimCallbacks *callbacks,
+ gpointer user_data);
+void gtk_source_vim_set_view (GtkSourceVim *self,
+ GtkSourceView *view);
+gboolean gtk_source_vim_deliver (GtkSourceVim *self,
+ GdkEvent *event);
+void gtk_source_vim_reset (GtkSourceVim *self);
+void gtk_source_vim_free (GtkSourceVim *self);
G_END_DECLS
diff --git a/gtksourceview/gtksourcevim.c b/gtksourceview/gtksourcevim.c
index ce52b06b..1f470cbc 100644
--- a/gtksourceview/gtksourcevim.c
+++ b/gtksourceview/gtksourcevim.c
@@ -21,6 +21,9 @@
#include "config.h"
+#include <gtk/gtk.h>
+
+#include "gtksourceview.h"
#include "gtksourcevim-private.h"
typedef struct
@@ -30,13 +33,20 @@ typedef struct
GString *command_label;
GString *command_bar_label;
int count;
+
+ union {
+ struct {
+ char begin;
+ } insert;
+ };
} GtkSourceVimState;
struct _GtkSourceVim
{
- GtkSourceVimCallbacks callbacks;
- gpointer callback_data;
- GQueue state;
+ GtkSourceView *view;
+ GtkSourceVimCallbacks callbacks;
+ gpointer callback_data;
+ GQueue state;
};
static inline gboolean
@@ -48,6 +58,33 @@ key_is_escape (guint keyval,
(keyval == GDK_KEY_bracketleft && (state & GDK_CONTROL_MASK) != 0);
}
+static gboolean
+get_iter_at_insert (GtkSourceVim *self,
+ GtkTextIter *iter)
+{
+ GtkTextBuffer *buffer;
+
+ g_assert (self != NULL);
+
+ if (self->view == NULL ||
+ !(buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->view))))
+ return FALSE;
+
+ gtk_text_buffer_get_iter_at_mark (buffer, iter, gtk_text_buffer_get_insert (buffer));
+
+ return TRUE;
+}
+
+static void
+move_insert (GtkSourceVim *self,
+ GtkTextIter *iter)
+{
+ g_assert (self != NULL);
+ g_assert (iter != NULL);
+
+ gtk_text_buffer_select_range (gtk_text_iter_get_buffer (iter), iter, iter);
+}
+
static inline gboolean
gtk_source_vim_filter_keypress (GtkSourceVim *self,
GdkEvent *event)
@@ -172,6 +209,21 @@ gtk_source_vim_pop (GtkSourceVim *self)
}
gtk_source_vim_notify_labels (self);
+
+ if (state->mode == GTK_SOURCE_VIM_NORMAL &&
+ (popped->mode == GTK_SOURCE_VIM_INSERT ||
+ popped->mode == GTK_SOURCE_VIM_REPLACE))
+ {
+ GtkTextIter iter;
+
+ if (get_iter_at_insert (self, &iter) &&
+ gtk_text_iter_ends_line (&iter) &&
+ gtk_text_iter_backward_char (&iter))
+ {
+ move_insert (self, &iter);
+ }
+ }
+
}
gtk_source_vim_state_free (popped);
@@ -204,6 +256,7 @@ gtk_source_vim_free (GtkSourceVim *self)
gtk_source_vim_pop (self);
}
+ g_clear_weak_pointer (&self->view);
g_free (self);
}
}
@@ -229,6 +282,8 @@ gtk_source_vim_handle_normal (GtkSourceVim *self,
guint keyval,
GdkModifierType mods)
{
+ GtkSourceVimState *new_state;
+
g_assert (self != NULL);
g_assert (state != NULL);
g_assert (state->mode == GTK_SOURCE_VIM_NORMAL);
@@ -249,7 +304,39 @@ gtk_source_vim_handle_normal (GtkSourceVim *self,
return TRUE;
case GDK_KEY_i:
- gtk_source_vim_push (self, GTK_SOURCE_VIM_INSERT);
+ new_state = gtk_source_vim_push (self, GTK_SOURCE_VIM_INSERT);
+ new_state->insert.begin = 'i';
+ return TRUE;
+ case GDK_KEY_I:
+ new_state = gtk_source_vim_push (self, GTK_SOURCE_VIM_INSERT);
+ new_state->insert.begin = 'I';
+ return TRUE;
+
+ case GDK_KEY_a:
+ new_state = gtk_source_vim_push (self, GTK_SOURCE_VIM_INSERT);
+ new_state->insert.begin = 'a';
+ return TRUE;
+ case GDK_KEY_A:
+ new_state = gtk_source_vim_push (self, GTK_SOURCE_VIM_INSERT);
+ new_state->insert.begin = 'A';
+ return TRUE;
+
+ case GDK_KEY_o:
+ new_state = gtk_source_vim_push (self, GTK_SOURCE_VIM_INSERT);
+ new_state->insert.begin = 'o';
+ return TRUE;
+ case GDK_KEY_O:
+ new_state = gtk_source_vim_push (self, GTK_SOURCE_VIM_INSERT);
+ new_state->insert.begin = 'O';
+ return TRUE;
+
+ case GDK_KEY_s:
+ new_state = gtk_source_vim_push (self, GTK_SOURCE_VIM_INSERT);
+ new_state->insert.begin = 's';
+ return TRUE;
+ case GDK_KEY_S: /* synonym cc */
+ new_state = gtk_source_vim_push (self, GTK_SOURCE_VIM_INSERT);
+ new_state->insert.begin = 'S';
return TRUE;
default:
@@ -259,8 +346,8 @@ gtk_source_vim_handle_normal (GtkSourceVim *self,
}
gboolean
-gtk_source_vim_deliver (GtkSourceVim *self,
- GdkEvent *event)
+gtk_source_vim_deliver (GtkSourceVim *self,
+ GdkEvent *event)
{
GtkSourceVimState *state;
GdkEventType event_type;
@@ -269,6 +356,8 @@ gtk_source_vim_deliver (GtkSourceVim *self,
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (self->state.length > 0, FALSE);
+ g_return_val_if_fail (GTK_SOURCE_IS_VIEW (self->view), FALSE);
+ g_return_val_if_fail (event != NULL, FALSE);
state = g_queue_peek_tail (&self->state);
@@ -294,8 +383,7 @@ gtk_source_vim_deliver (GtkSourceVim *self,
return FALSE;
}
- switch (state->mode)
- {
+ switch (state->mode) {
case GTK_SOURCE_VIM_INSERT:
if (key_is_escape (keyval, keycode, mods))
@@ -335,3 +423,13 @@ gtk_source_vim_deliver (GtkSourceVim *self,
return FALSE;
}
+
+void
+gtk_source_vim_set_view (GtkSourceVim *self,
+ GtkSourceView *view)
+{
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (!view || GTK_SOURCE_IS_VIEW (view));
+
+ g_set_weak_pointer (&self->view, view);
+}
diff --git a/gtksourceview/gtksourcevimimcontext.c b/gtksourceview/gtksourcevimimcontext.c
index 1bbbff5b..0e7a6c6a 100644
--- a/gtksourceview/gtksourcevimimcontext.c
+++ b/gtksourceview/gtksourcevimimcontext.c
@@ -64,7 +64,10 @@ gtk_source_vim_im_context_set_client_widget (GtkIMContext *context,
g_return_if_fail (GTK_SOURCE_IS_VIM_IM_CONTEXT (self));
- g_set_weak_pointer (&self->view, GTK_SOURCE_VIEW (widget));
+ if (g_set_weak_pointer (&self->view, GTK_SOURCE_VIEW (widget)))
+ {
+ gtk_source_vim_set_view (self->vim, self->view);
+ }
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]