[gtksourceview/wip/chergert/vim: 228/363] add char pending




commit 1e82a96437afd2383670b47e69739b42d6be86c5
Author: Christian Hergert <chergert redhat com>
Date:   Tue Nov 2 17:29:18 2021 -0700

    add char pending

 gtksourceview/vim/gtk-source-vim-char-pending.c | 115 ++++++++++++++++++++++++
 gtksourceview/vim/gtk-source-vim-char-pending.h |  36 ++++++++
 gtksourceview/vim/gtk-source-vim-state.c        |  52 ++++++++++-
 gtksourceview/vim/gtk-source-vim-state.h        |   3 +
 gtksourceview/vim/meson.build                   |   1 +
 5 files changed, 205 insertions(+), 2 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-char-pending.c b/gtksourceview/vim/gtk-source-vim-char-pending.c
new file mode 100644
index 00000000..e5462f98
--- /dev/null
+++ b/gtksourceview/vim/gtk-source-vim-char-pending.c
@@ -0,0 +1,115 @@
+/*
+ * 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 <glib/gi18n.h>
+
+#include "gtk-source-vim-char-pending.h"
+#include "gtk-source-vim-insert-literal.h"
+
+struct _GtkSourceVimCharPending
+{
+       GtkSourceVimState parent_class;
+       gunichar character;
+       char string[16];
+       guint is_literal : 1;
+};
+
+G_DEFINE_TYPE (GtkSourceVimCharPending, gtk_source_vim_char_pending, GTK_SOURCE_TYPE_VIM_STATE)
+
+static gboolean
+gtk_source_vim_char_pending_handle_keypress (GtkSourceVimState *state,
+                                             guint              keyval,
+                                             guint              keycode,
+                                             GdkModifierType    mods,
+                                             const char        *string)
+{
+       GtkSourceVimCharPending *self = (GtkSourceVimCharPending *)state;
+
+       g_assert (GTK_SOURCE_IS_VIM_CHAR_PENDING (self));
+
+       /* If we haven't entered literal mode then escape should just
+        * exit from char-pending.
+        */
+       if (gtk_source_vim_state_is_escape (keyval, mods))
+       {
+               if (self->is_literal)
+                       self->character = '\e';
+               goto completed;
+       }
+
+       if (keyval == GDK_KEY_v && (mods & GDK_CONTROL_MASK) != 0)
+       {
+               self->is_literal = TRUE;
+               return TRUE;
+       }
+
+       gtk_source_vim_state_keyval_unescaped (keyval, mods, self->string);
+
+       if (self->string[0] != 0)
+       {
+               if ((self->string[0] & 0x80) == 0x80)
+                       self->character = g_utf8_get_char (self->string);
+               else
+                       self->character = self->string[0];
+       }
+
+completed:
+       gtk_source_vim_state_pop (state);
+
+       return TRUE;
+}
+
+static void
+gtk_source_vim_char_pending_class_init (GtkSourceVimCharPendingClass *klass)
+{
+       GtkSourceVimStateClass *state_class = GTK_SOURCE_VIM_STATE_CLASS (klass);
+
+       state_class->handle_keypress = gtk_source_vim_char_pending_handle_keypress;
+}
+
+static void
+gtk_source_vim_char_pending_init (GtkSourceVimCharPending *self)
+{
+}
+
+GtkSourceVimState *
+gtk_source_vim_char_pending_new (void)
+{
+       return g_object_new (GTK_SOURCE_TYPE_VIM_CHAR_PENDING, NULL);
+}
+
+gunichar
+gtk_source_vim_char_pending_get_character (GtkSourceVimCharPending *self)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_VIM_CHAR_PENDING (self), 0);
+
+       return self->character;
+}
+
+const char *
+gtk_source_vim_char_pending_get_string (GtkSourceVimCharPending *self)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_VIM_CHAR_PENDING (self), NULL);
+
+       return self->string;
+}
diff --git a/gtksourceview/vim/gtk-source-vim-char-pending.h b/gtksourceview/vim/gtk-source-vim-char-pending.h
new file mode 100644
index 00000000..f5179158
--- /dev/null
+++ b/gtksourceview/vim/gtk-source-vim-char-pending.h
@@ -0,0 +1,36 @@
+/*
+ * 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_CHAR_PENDING (gtk_source_vim_char_pending_get_type())
+
+G_DECLARE_FINAL_TYPE (GtkSourceVimCharPending, gtk_source_vim_char_pending, GTK_SOURCE, VIM_CHAR_PENDING, 
GtkSourceVimState)
+
+GtkSourceVimState *gtk_source_vim_char_pending_new           (void);
+gunichar           gtk_source_vim_char_pending_get_character (GtkSourceVimCharPending *self);
+const char        *gtk_source_vim_char_pending_get_string    (GtkSourceVimCharPending *self);
+
+G_END_DECLS
diff --git a/gtksourceview/vim/gtk-source-vim-state.c b/gtksourceview/vim/gtk-source-vim-state.c
index 37970a47..c34a989c 100644
--- a/gtksourceview/vim/gtk-source-vim-state.c
+++ b/gtksourceview/vim/gtk-source-vim-state.c
@@ -21,6 +21,8 @@
 
 #include "config.h"
 
+#include <string.h>
+
 #include "gtksourcebuffer.h"
 #include "gtksourceutils-private.h"
 #include "gtksourceview.h"
@@ -54,8 +56,54 @@ enum {
 static GParamSpec *properties [N_PROPS];
 
 void
-gtk_source_vim_state_keyval_to_string (guint                 keyval,
-                                       GdkModifierType       mods,
+gtk_source_vim_state_keyval_unescaped (guint           keyval,
+                                       GdkModifierType mods,
+                                       char            str[16])
+{
+#define return_str(v) \
+       G_STMT_START { g_strlcpy (str, v, 16); return; } G_STMT_END
+
+       str[0] = 0;
+
+       if (keyval == GDK_KEY_Escape)
+               return_str ("\e");
+
+       if ((mods & GDK_CONTROL_MASK) != 0)
+       {
+               switch (keyval)
+               {
+                       case GDK_KEY_l:
+                               return_str ("\f");
+
+                       case GDK_KEY_a:
+                               return_str ("\a");
+
+                       default:
+                               break;
+               }
+       }
+
+       switch (keyval)
+       {
+               case GDK_KEY_BackSpace:
+                       return_str ("\b");
+
+               case GDK_KEY_Return:
+               case GDK_KEY_KP_Enter:
+                       return_str ("\r");
+
+               default:
+                       break;
+       }
+
+       return gtk_source_vim_state_keyval_to_string (keyval, mods, str);
+
+#undef return_str
+}
+
+void
+gtk_source_vim_state_keyval_to_string (guint           keyval,
+                                       GdkModifierType mods,
                                        char            str[16])
 {
        int pos = 0;
diff --git a/gtksourceview/vim/gtk-source-vim-state.h b/gtksourceview/vim/gtk-source-vim-state.h
index 654f91db..d46d6499 100644
--- a/gtksourceview/vim/gtk-source-vim-state.h
+++ b/gtksourceview/vim/gtk-source-vim-state.h
@@ -117,6 +117,9 @@ void               gtk_source_vim_state_place_cursor_onscreen      (GtkSourceVim
 void               gtk_source_vim_state_keyval_to_string           (guint              keyval,
                                                                     GdkModifierType    mods,
                                                                     char               str[16]);
+void               gtk_source_vim_state_keyval_unescaped           (guint              keyval,
+                                                                    GdkModifierType    mods,
+                                                                    char               str[16]);
 
 static inline gboolean
 gtk_source_vim_state_is_escape (guint           keyval,
diff --git a/gtksourceview/vim/meson.build b/gtksourceview/vim/meson.build
index 35572f33..bce7e2c5 100644
--- a/gtksourceview/vim/meson.build
+++ b/gtksourceview/vim/meson.build
@@ -1,5 +1,6 @@
 vim_sources = files([
   'gtk-source-vim.c',
+  'gtk-source-vim-char-pending.c',
   'gtk-source-vim-command.c',
   'gtk-source-vim-command-bar.c',
   'gtk-source-vim-delete.c',


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