[gtksourceview/wip/chergert/vim: 283/363] start on text objects




commit 1d70263a67b79ee731b09c39c9dcba736a3d9fe4
Author: Christian Hergert <chergert redhat com>
Date:   Thu Nov 4 14:47:34 2021 -0700

    start on text objects

 gtksourceview/vim/gtk-source-vim-text-object.c | 170 +++++++++++++++++++++++++
 gtksourceview/vim/gtk-source-vim-text-object.h |  58 +++++++++
 gtksourceview/vim/meson.build                  |   1 +
 3 files changed, 229 insertions(+)
---
diff --git a/gtksourceview/vim/gtk-source-vim-text-object.c b/gtksourceview/vim/gtk-source-vim-text-object.c
new file mode 100644
index 00000000..4c45c0ad
--- /dev/null
+++ b/gtksourceview/vim/gtk-source-vim-text-object.c
@@ -0,0 +1,170 @@
+/*
+ * 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-motion.h"
+#include "gtk-source-vim-text-object.h"
+
+typedef gboolean (*TextObjectMotion) (GtkTextIter *iter);
+
+enum {
+       TEXT_OBJECT_INNER = 0,
+       TEXT_OBJECT_A = 1,
+};
+
+enum {
+       TEXT_OBJECT_LINE_ENDS = 0,
+       TEXT_OBJECT_BUFFER_ENDS = 1,
+};
+
+struct _GtkSourceVimTextObject
+{
+       GtkSourceVimState parent_instance;
+       TextObjectMotion  forward_end;
+       TextObjectMotion  backward_start;
+       guint             inner_or_a : 1;
+       guint             captivity : 1;
+};
+
+G_DEFINE_TYPE (GtkSourceVimTextObject, gtk_source_vim_text_object, GTK_SOURCE_TYPE_VIM_STATE)
+
+static GtkSourceVimState *
+gtk_source_vim_text_object_new (TextObjectMotion forward_end,
+                                TextObjectMotion backward_start,
+                                guint            inner_or_a,
+                                guint            captivity)
+{
+       GtkSourceVimTextObject *self;
+
+       self = g_object_new (GTK_SOURCE_TYPE_VIM_TEXT_OBJECT, NULL);
+       self->forward_end = forward_end;
+       self->backward_start = backward_start;
+       self->inner_or_a = !!inner_or_a;
+       self->captivity = !!captivity;
+
+       return GTK_SOURCE_VIM_STATE (self);
+}
+
+#define TEXT_OBJECT_CTOR(name, forward, backward, inner_or_a, captivity)        \
+GtkSourceVimState *                                                             \
+gtk_source_vim_text_object_new_##name (void)                                    \
+{                                                                               \
+       return gtk_source_vim_text_object_new (gtk_source_vim_iter_##forward,   \
+                                              gtk_source_vim_iter_##backward,  \
+                                              TEXT_OBJECT_##inner_or_a,        \
+                                              TEXT_OBJECT_##captivity);        \
+}
+
+TEXT_OBJECT_CTOR (inner_word, forward_word_end, backward_word_start, INNER, LINE_ENDS)
+TEXT_OBJECT_CTOR (inner_WORD, forward_WORD_end, backward_WORD_start, INNER, LINE_ENDS)
+TEXT_OBJECT_CTOR (inner_sentence, forward_sentence_end, backward_word_start, INNER, BUFFER_ENDS)
+TEXT_OBJECT_CTOR (inner_paragraph, forward_paragraph_end, backward_paragraph_start, INNER, BUFFER_ENDS)
+TEXT_OBJECT_CTOR (inner_block_paren, forward_block_paren_end, backward_block_paren_start, INNER, BUFFER_ENDS)
+TEXT_OBJECT_CTOR (inner_block_brace, forward_block_brace_end, backward_block_brace_start, INNER, BUFFER_ENDS)
+TEXT_OBJECT_CTOR (inner_block_bracket, forward_block_bracket_end, backward_block_bracket_start, INNER, 
BUFFER_ENDS)
+TEXT_OBJECT_CTOR (inner_block_lt_gt, forward_block_lt_gt_end, backward_block_lt_gt_start, INNER, BUFFER_ENDS)
+TEXT_OBJECT_CTOR (inner_quote_double, forward_quote_double, backward_quote_double, INNER, LINE_ENDS)
+TEXT_OBJECT_CTOR (inner_quote_single, forward_quote_single, backward_quote_single, INNER, LINE_ENDS)
+TEXT_OBJECT_CTOR (inner_quote_grave, forward_quote_grave, backward_quote_grave, INNER, LINE_ENDS)
+
+TEXT_OBJECT_CTOR (a_word, forward_word_end, backward_word_start, A, LINE_ENDS)
+TEXT_OBJECT_CTOR (a_WORD, forward_WORD_end, backward_WORD_start, A, LINE_ENDS)
+TEXT_OBJECT_CTOR (a_sentence, forward_sentence_end, backward_word_start, A, BUFFER_ENDS)
+TEXT_OBJECT_CTOR (a_paragraph, forward_paragraph_end, backward_paragraph_start, A, BUFFER_ENDS)
+TEXT_OBJECT_CTOR (a_block_paren, forward_block_paren_end, backward_block_paren_start, A, BUFFER_ENDS)
+TEXT_OBJECT_CTOR (a_block_brace, forward_block_brace_end, backward_block_brace_start, A, BUFFER_ENDS)
+TEXT_OBJECT_CTOR (a_block_bracket, forward_block_bracket_end, backward_block_bracket_start, A, BUFFER_ENDS)
+TEXT_OBJECT_CTOR (a_block_lt_gt, forward_block_lt_gt_end, backward_block_lt_gt_start, A, BUFFER_ENDS)
+TEXT_OBJECT_CTOR (a_quote_double, forward_quote_double, backward_quote_double, A, LINE_ENDS)
+TEXT_OBJECT_CTOR (a_quote_single, forward_quote_single, backward_quote_single, A, LINE_ENDS)
+TEXT_OBJECT_CTOR (a_quote_grave, forward_quote_grave, backward_quote_grave, A, LINE_ENDS)
+
+#undef TEXT_OBJECT_CTOR
+
+static void
+gtk_source_vim_text_object_dispose (GObject *object)
+{
+       G_OBJECT_CLASS (gtk_source_vim_text_object_parent_class)->dispose (object);
+}
+
+static void
+gtk_source_vim_text_object_class_init (GtkSourceVimTextObjectClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->dispose = gtk_source_vim_text_object_dispose;
+}
+
+static void
+gtk_source_vim_text_object_init (GtkSourceVimTextObject *self)
+{
+}
+
+gboolean
+gtk_source_vim_text_object_select (GtkSourceVimTextObject *self,
+                                   GtkTextIter            *begin,
+                                   GtkTextIter            *end)
+{
+       GtkTextIter b, e;
+
+       g_return_val_if_fail (GTK_SOURCE_IS_VIM_TEXT_OBJECT (self), FALSE);
+       g_return_val_if_fail (begin != NULL, FALSE);
+       g_return_val_if_fail (end != NULL, FALSE);
+       g_return_val_if_fail (GTK_IS_TEXT_BUFFER (gtk_text_iter_get_buffer (begin)), FALSE);
+
+       if (self->forward_end == NULL || self->backward_start == NULL)
+               return FALSE;
+
+       b = e = *begin;
+
+       if (!self->forward_end (&e))
+               return FALSE;
+
+       b = e;
+
+       if (!self->backward_start (&b))
+               return FALSE;
+
+       if (self->captivity == TEXT_OBJECT_LINE_ENDS)
+       {
+               if (gtk_text_iter_get_line (&b) != gtk_text_iter_get_line (&e) ||
+                   gtk_text_iter_get_line (&b) != gtk_text_iter_get_line (begin) ||
+                   gtk_text_iter_get_line (&e) != gtk_text_iter_get_line (begin))
+               {
+                       return FALSE;
+               }
+       }
+
+       /* If we're INNER and find the new begin position being after
+        * where we started, then we want to select the space between
+        * the new beginning and the previous ending.
+        */
+       if (self->inner_or_a == TEXT_OBJECT_INNER &&
+           gtk_text_iter_compare (begin, &b) < 0)
+       {
+       }
+
+       *begin = b;
+       *end = e;
+
+       return TRUE;
+}
diff --git a/gtksourceview/vim/gtk-source-vim-text-object.h b/gtksourceview/vim/gtk-source-vim-text-object.h
new file mode 100644
index 00000000..ef4a74be
--- /dev/null
+++ b/gtksourceview/vim/gtk-source-vim-text-object.h
@@ -0,0 +1,58 @@
+/*
+ * 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_TEXT_OBJECT (gtk_source_vim_text_object_get_type())
+
+G_DECLARE_FINAL_TYPE (GtkSourceVimTextObject, gtk_source_vim_text_object, GTK_SOURCE, VIM_TEXT_OBJECT, 
GtkSourceVimState)
+
+GtkSourceVimState *gtk_source_vim_text_object_new_inner_word          (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_inner_WORD          (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_inner_sentence      (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_inner_paragraph     (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_inner_block_paren   (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_inner_block_brace   (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_inner_block_bracket (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_inner_block_lt_gt   (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_inner_quote_double  (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_inner_quote_single  (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_inner_quote_grave   (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_a_word              (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_a_WORD              (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_a_sentence          (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_a_paragraph         (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_a_block_paren       (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_a_block_brace       (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_a_block_bracket     (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_a_block_lt_gt       (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_a_quote_double      (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_a_quote_single      (void);
+GtkSourceVimState *gtk_source_vim_text_object_new_a_quote_grave       (void);
+gboolean           gtk_source_vim_text_object_select                  (GtkSourceVimTextObject *self,
+                                                                       GtkTextIter            *begin,
+                                                                       GtkTextIter            *end);
+
+G_END_DECLS
diff --git a/gtksourceview/vim/meson.build b/gtksourceview/vim/meson.build
index 690e219e..a2c55498 100644
--- a/gtksourceview/vim/meson.build
+++ b/gtksourceview/vim/meson.build
@@ -11,5 +11,6 @@ vim_sources = files([
   'gtk-source-vim-replace.c',
   'gtk-source-vim-state.c',
   'gtk-source-vim-text-history.c',
+  'gtk-source-vim-text-object.c',
   'gtk-source-vim-visual.c',
 ])


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