[gtksourceview/wip/chergert/vim: 205/293] synchronize text history to "." register
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/vim: 205/293] synchronize text history to "." register
- Date: Fri, 5 Nov 2021 04:23:05 +0000 (UTC)
commit 17ad6aeeec791118ea674bbd077a9ada8499b745
Author: Christian Hergert <chergert redhat com>
Date: Tue Nov 2 12:09:59 2021 -0700
synchronize text history to "." register
gtksourceview/vim/gtk-source-vim-text-history.c | 76 +++++++++++++++++++++++++
1 file changed, 76 insertions(+)
---
diff --git a/gtksourceview/vim/gtk-source-vim-text-history.c b/gtksourceview/vim/gtk-source-vim-text-history.c
index ece86630..9f99276c 100644
--- a/gtksourceview/vim/gtk-source-vim-text-history.c
+++ b/gtksourceview/vim/gtk-source-vim-text-history.c
@@ -23,6 +23,7 @@
#include "gtksourcebuffer.h"
+#include "gtk-source-vim-registers.h"
#include "gtk-source-vim-text-history.h"
typedef enum
@@ -200,10 +201,54 @@ gtk_source_vim_text_history_begin (GtkSourceVimTextHistory *self)
G_CONNECT_SWAPPED);
}
+/*
+ * string_truncate_n_chars:
+ * @str: the GString
+ * @n_chars: the number of chars to remove
+ *
+ * Removes @n_chars from the tail of @str, possibly taking into
+ * account UTF-8 characters that are multi-width.
+ */
+static void
+string_truncate_n_chars (GString *str,
+ gsize n_chars)
+{
+ if (str == NULL)
+ {
+ return;
+ }
+
+ if (n_chars >= str->len)
+ {
+ g_string_truncate (str, 0);
+ return;
+ }
+
+ g_assert (str->len > 0);
+
+ while (n_chars > 0 && str->len > 0)
+ {
+ guchar ch = str->str[--str->len];
+
+ /* If high bit is zero we have a one-byte char. If we have
+ * reached the byte with 0xC0 mask set then we are at the
+ * first character of a multi-byte char.
+ */
+ if ((ch & 0x80) == 0 || (ch & 0xC0) == 0xC0)
+ {
+ n_chars--;
+ }
+ }
+
+ str->str[str->len] = 0;
+}
+
void
gtk_source_vim_text_history_end (GtkSourceVimTextHistory *self)
{
+ GtkSourceVimState *registers;
GtkSourceBuffer *buffer;
+ GString *inserted;
g_return_if_fail (GTK_SOURCE_IS_VIM_TEXT_HISTORY (self));
@@ -215,6 +260,37 @@ gtk_source_vim_text_history_end (GtkSourceVimTextHistory *self)
g_signal_handlers_disconnect_by_func (buffer,
G_CALLBACK (gtk_source_vim_text_history_delete_range_cb),
self);
+
+ /* Collect the inserted text into a single string and then set that
+ * in the "." register which is a read-only register to the user
+ * containing the last inserted text.
+ */
+ inserted = g_string_new (NULL);
+ for (guint i = 0; i < self->ops->len; i++)
+ {
+ const Op *op = &g_array_index (self->ops, Op, i);
+ const char *str = self->bytes->str + op->offset;
+
+ switch (op->kind)
+ {
+ case OP_INSERT:
+ g_string_append_len (inserted, str, g_utf8_offset_to_pointer (str,
op->length) - str);
+ break;
+
+ case OP_BACKSPACE:
+ string_truncate_n_chars (inserted, op->length);
+ break;
+
+ default:
+ case OP_DELETE:
+ break;
+ }
+ }
+
+ registers = gtk_source_vim_state_get_registers (GTK_SOURCE_VIM_STATE (self));
+ gtk_source_vim_registers_take (GTK_SOURCE_VIM_REGISTERS (registers),
+ ".",
+ g_string_free (inserted, FALSE));
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]