[gtksourceview/wip/chergert/vim] start on command abstraction
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/vim] start on command abstraction
- Date: Fri, 29 Oct 2021 05:00:03 +0000 (UTC)
commit 1f2948c604b7e31e0f06031f62c954e4e55103e9
Author: Christian Hergert <chergert redhat com>
Date: Thu Oct 28 21:59:15 2021 -0700
start on command abstraction
gtksourceview/vim/gtk-source-vim-command.c | 277 +++++++++++++++++++++++++++++
gtksourceview/vim/gtk-source-vim-command.h | 39 ++++
gtksourceview/vim/meson.build | 1 +
3 files changed, 317 insertions(+)
---
diff --git a/gtksourceview/vim/gtk-source-vim-command.c b/gtksourceview/vim/gtk-source-vim-command.c
new file mode 100644
index 00000000..c1e7e988
--- /dev/null
+++ b/gtksourceview/vim/gtk-source-vim-command.c
@@ -0,0 +1,277 @@
+/*
+ * 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 "gtksourcebuffer.h"
+
+#include "gtk-source-vim-command.h"
+
+struct _GtkSourceVimCommand
+{
+ GtkSourceVimState parent_instance;
+ GtkSourceVimMotion *motion;
+ GtkSourceVimMotion *selection_motion;
+ char *command;
+};
+
+G_DEFINE_TYPE (GtkSourceVimCommand, gtk_source_vim_command, GTK_SOURCE_TYPE_VIM_STATE)
+
+enum {
+ PROP_0,
+ PROP_COMMAND,
+ PROP_MOTION,
+ PROP_SELECTION_MOTION,
+ N_PROPS
+};
+
+static GParamSpec *properties[N_PROPS];
+
+static void
+gtk_source_vim_command_join (GtkSourceVimCommand *self)
+{
+ GtkSourceBuffer *buffer;
+ GtkTextIter iter;
+ GtkTextIter selection;
+ GtkTextIter end;
+ guint offset;
+
+ buffer = gtk_source_vim_state_get_buffer (GTK_SOURCE_VIM_STATE (self), &iter, &selection);
+
+ gtk_text_iter_order (&iter, &selection);
+ offset = gtk_text_iter_get_offset (&iter);
+
+ end = iter;
+ if (!gtk_text_iter_ends_line (&end))
+ gtk_text_iter_forward_to_line_end (&end);
+ offset = gtk_text_iter_get_offset (&end);
+
+ gtk_source_buffer_join_lines (buffer, &iter, &selection);
+ gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (buffer), &iter, offset);
+ gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer), &iter, &iter);
+}
+
+static void
+gtk_source_vim_command_append_command (GtkSourceVimState *state,
+ GString *string)
+{
+ /* command should be empty during command */
+ g_string_truncate (string, 0);
+}
+
+static void
+gtk_source_vim_command_repeat (GtkSourceVimState *state)
+{
+ GtkSourceVimCommand *self = (GtkSourceVimCommand *)state;
+ GtkSourceBuffer *buffer;
+ GtkTextIter iter;
+ GtkTextIter selection;
+
+ g_assert (GTK_SOURCE_IS_VIM_COMMAND (self));
+
+ buffer = gtk_source_vim_state_get_buffer (state, &iter, &selection);
+
+ if (self->motion)
+ {
+ gtk_source_vim_motion_apply (self->motion, &iter, TRUE);
+ }
+
+ if (self->selection_motion)
+ {
+ gtk_source_vim_motion_apply (self->selection_motion, &selection, TRUE);
+ }
+
+ gtk_source_vim_state_select (state, &iter, &selection);
+
+ gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (buffer));
+
+ /* XXX: obviously need to add an abstraction here for
+ * registered commands (and possible options on them).
+ */
+
+ if (g_strcmp0 (self->command, ":join") == 0)
+ {
+ gtk_source_vim_command_join (self);
+ }
+
+ gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer));
+}
+
+static void
+gtk_source_vim_command_leave (GtkSourceVimState *state)
+{
+ gtk_source_vim_command_repeat (state);
+}
+
+static void
+gtk_source_vim_command_dispose (GObject *object)
+{
+ GtkSourceVimCommand *self = (GtkSourceVimCommand *)object;
+
+ g_clear_object (&self->motion);
+ g_clear_object (&self->selection_motion);
+ g_clear_pointer (&self->command, g_free);
+
+ G_OBJECT_CLASS (gtk_source_vim_command_parent_class)->dispose (object);
+}
+
+static void
+gtk_source_vim_command_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkSourceVimCommand *self = GTK_SOURCE_VIM_COMMAND (object);
+
+ switch (prop_id)
+ {
+ case PROP_COMMAND:
+ g_value_set_string (value, self->command);
+ break;
+
+ case PROP_MOTION:
+ g_value_set_object (value, self->motion);
+ break;
+
+ case PROP_SELECTION_MOTION:
+ g_value_set_object (value, self->selection_motion);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gtk_source_vim_command_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkSourceVimCommand *self = GTK_SOURCE_VIM_COMMAND (object);
+
+ switch (prop_id)
+ {
+ case PROP_COMMAND:
+ self->command = g_value_dup_string (value);
+ break;
+
+ case PROP_MOTION:
+ gtk_source_vim_command_set_motion (self, g_value_get_object (value));
+ break;
+
+ case PROP_SELECTION_MOTION:
+ gtk_source_vim_command_set_selection_motion (self, g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gtk_source_vim_command_class_init (GtkSourceVimCommandClass *klass)
+{
+ GtkSourceVimStateClass *state_class = GTK_SOURCE_VIM_STATE_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = gtk_source_vim_command_dispose;
+ object_class->get_property = gtk_source_vim_command_get_property;
+ object_class->set_property = gtk_source_vim_command_set_property;
+
+ state_class->append_command = gtk_source_vim_command_append_command;
+ state_class->leave = gtk_source_vim_command_leave;
+ state_class->repeat = gtk_source_vim_command_repeat;
+
+ properties [PROP_COMMAND] =
+ g_param_spec_string ("command",
+ "Command",
+ "The command to run",
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_MOTION] =
+ g_param_spec_object ("motion",
+ "Motion",
+ "The motion for the insertion cursor",
+ GTK_SOURCE_TYPE_VIM_MOTION,
+ (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_SELECTION_MOTION] =
+ g_param_spec_object ("selection-motion",
+ "Seleciton Motion",
+ "The motion for the selection bound",
+ GTK_SOURCE_TYPE_VIM_MOTION,
+ (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+gtk_source_vim_command_init (GtkSourceVimCommand *self)
+{
+}
+
+void
+gtk_source_vim_command_set_motion (GtkSourceVimCommand *self,
+ GtkSourceVimMotion *motion)
+{
+ g_return_if_fail (GTK_SOURCE_IS_VIM_COMMAND (self));
+ g_return_if_fail (!motion || GTK_SOURCE_IS_VIM_MOTION (motion));
+
+ if (g_set_object (&self->motion, motion))
+ {
+ if (motion)
+ {
+ gtk_source_vim_state_set_parent (GTK_SOURCE_VIM_STATE (motion),
+ GTK_SOURCE_VIM_STATE (self));
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MOTION]);
+ }
+}
+
+void
+gtk_source_vim_command_set_selection_motion (GtkSourceVimCommand *self,
+ GtkSourceVimMotion *selection_motion)
+{
+ g_return_if_fail (GTK_SOURCE_IS_VIM_COMMAND (self));
+ g_return_if_fail (!selection_motion || GTK_SOURCE_IS_VIM_MOTION (selection_motion));
+
+ if (g_set_object (&self->selection_motion, selection_motion))
+ {
+ if (selection_motion)
+ {
+ gtk_source_vim_state_set_parent (GTK_SOURCE_VIM_STATE (selection_motion),
+ GTK_SOURCE_VIM_STATE (self));
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTION_MOTION]);
+ }
+}
+
+const char *
+gtk_source_vim_command_get_command (GtkSourceVimCommand *self)
+{
+ g_return_val_if_fail (GTK_SOURCE_IS_VIM_COMMAND (self), NULL);
+
+ return self->command;
+}
diff --git a/gtksourceview/vim/gtk-source-vim-command.h b/gtksourceview/vim/gtk-source-vim-command.h
new file mode 100644
index 00000000..7a6dcbc5
--- /dev/null
+++ b/gtksourceview/vim/gtk-source-vim-command.h
@@ -0,0 +1,39 @@
+/*
+ * 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-motion.h"
+#include "gtk-source-vim-state.h"
+
+G_BEGIN_DECLS
+
+#define GTK_SOURCE_TYPE_VIM_COMMAND (gtk_source_vim_command_get_type())
+
+G_DECLARE_FINAL_TYPE (GtkSourceVimCommand, gtk_source_vim_command, GTK_SOURCE, VIM_COMMAND,
GtkSourceVimState)
+
+const char *gtk_source_vim_command_get_command (GtkSourceVimCommand *self);
+void gtk_source_vim_command_set_motion (GtkSourceVimCommand *self,
+ GtkSourceVimMotion *motion);
+void gtk_source_vim_command_set_selection_motion (GtkSourceVimCommand *self,
+ GtkSourceVimMotion *selection_motion);
+
+G_END_DECLS
diff --git a/gtksourceview/vim/meson.build b/gtksourceview/vim/meson.build
index b164ce2a..0c2e3118 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-command.c',
'gtk-source-vim-command-bar.c',
'gtk-source-vim-delete.c',
'gtk-source-vim-motion.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]