[gtksourceview/wip/chergert/vim] read and write the system clipboard (and emulated primary)
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/vim] read and write the system clipboard (and emulated primary)
- Date: Wed, 3 Nov 2021 20:46:36 +0000 (UTC)
commit 06d821fb131e59fc13bf33373dd6d2dcd6d6d480
Author: Christian Hergert <chergert redhat com>
Date: Wed Nov 3 13:46:31 2021 -0700
read and write the system clipboard (and emulated primary)
gtksourceview/vim/gtk-source-vim-registers.c | 132 ++++++++++++++++++++++++++-
1 file changed, 128 insertions(+), 4 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-registers.c b/gtksourceview/vim/gtk-source-vim-registers.c
index af55ec4e..536fd133 100644
--- a/gtksourceview/vim/gtk-source-vim-registers.c
+++ b/gtksourceview/vim/gtk-source-vim-registers.c
@@ -32,6 +32,9 @@ struct _GtkSourceVimRegisters
GHashTable *values;
+ char *clipboard;
+ char *primary_clipboard;
+
char *numbered[10];
int numbered_pos;
};
@@ -44,6 +47,8 @@ gtk_source_vim_registers_finalize (GObject *object)
GtkSourceVimRegisters *self = (GtkSourceVimRegisters *)object;
g_clear_pointer (&self->values, g_hash_table_unref);
+ g_clear_pointer (&self->clipboard, g_ref_string_release);
+ g_clear_pointer (&self->primary_clipboard, g_ref_string_release);
for (guint i = 0; i < G_N_ELEMENTS (self->numbered); i++)
{
@@ -70,6 +75,90 @@ gtk_source_vim_registers_init (GtkSourceVimRegisters *self)
(GDestroyNotify)g_ref_string_release);
}
+static void
+write_clipboard (GtkSourceVimRegisters *self,
+ GdkClipboard *clipboard,
+ char *refstr)
+{
+ g_assert (GTK_SOURCE_IS_VIM_REGISTERS (self));
+ g_assert (GDK_IS_CLIPBOARD (clipboard));
+ g_assert (refstr != NULL);
+
+ gdk_clipboard_set_text (clipboard, refstr);
+}
+
+static gboolean
+cancel_cb (gpointer data)
+{
+ g_cancellable_cancel (data);
+ return G_SOURCE_REMOVE;
+}
+
+typedef struct
+{
+ char *text;
+ GMainLoop *main_loop;
+ GCancellable *cancellable;
+} ReadClipboard;
+
+static void
+read_clipboard_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ ReadClipboard *clip = user_data;
+
+ g_assert (GDK_IS_CLIPBOARD (object));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (clip != NULL);
+ g_assert (clip->main_loop != NULL);
+ g_assert (G_IS_CANCELLABLE (clip->cancellable));
+
+ clip->text = gdk_clipboard_read_text_finish (GDK_CLIPBOARD (object), result, NULL);
+
+ g_main_loop_quit (clip->main_loop);
+}
+
+static void
+read_clipboard (GtkSourceVimRegisters *self,
+ GdkClipboard *clipboard,
+ char **text)
+{
+ ReadClipboard clip;
+ GSource *source;
+
+ g_assert (GTK_SOURCE_IS_VIM_REGISTERS (self));
+ g_assert (GDK_IS_CLIPBOARD (clipboard));
+
+ clip.text = NULL;
+ clip.main_loop = g_main_loop_new (NULL, FALSE);
+ clip.cancellable = g_cancellable_new ();
+
+ source = g_timeout_source_new (500);
+ g_source_set_name (source, "[gtksourceview cancel clipboard]");
+ g_source_set_callback (source, cancel_cb, clip.cancellable, NULL);
+ g_source_attach (source, NULL);
+
+ gdk_clipboard_read_text_async (clipboard,
+ clip.cancellable,
+ read_clipboard_cb,
+ &clip);
+
+ g_main_loop_run (clip.main_loop);
+
+ g_main_loop_unref (clip.main_loop);
+ g_object_unref (clip.cancellable);
+
+ g_source_destroy (source);
+
+ if (clip.text != NULL)
+ {
+ g_clear_pointer (text, g_ref_string_release);
+ *text = g_ref_string_new (clip.text);
+ g_free (clip.text);
+ }
+}
+
GtkSourceVimState *
gtk_source_vim_registers_new (void)
{
@@ -80,6 +169,8 @@ const char *
gtk_source_vim_registers_get (GtkSourceVimRegisters *self,
const char *name)
{
+ GtkSourceView *view;
+
g_return_val_if_fail (GTK_SOURCE_IS_VIM_REGISTERS (self), NULL);
if (name == NULL)
@@ -92,7 +183,24 @@ gtk_source_vim_registers_get (GtkSourceVimRegisters *self,
return gtk_source_vim_registers_get_numbered (self, *name - '0');
}
- return g_hash_table_lookup (self->values, name);
+ view = gtk_source_vim_state_get_view (GTK_SOURCE_VIM_STATE (self));
+
+ if (g_str_equal (name, "+"))
+ {
+ GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view));
+ read_clipboard (self, clipboard, &self->clipboard);
+ return self->clipboard;
+ }
+ else if (g_str_equal (name, "*"))
+ {
+ GdkClipboard *clipboard = gtk_widget_get_primary_clipboard (GTK_WIDGET (view));
+ read_clipboard (self, clipboard, &self->primary_clipboard);
+ return self->primary_clipboard;
+ }
+ else
+ {
+ return g_hash_table_lookup (self->values, name);
+ }
}
static inline char **
@@ -144,6 +252,7 @@ gtk_source_vim_registers_set (GtkSourceVimRegisters *self,
const char *name,
const char *value)
{
+ GtkSourceView *view;
char *str;
g_return_if_fail (GTK_SOURCE_IS_VIM_REGISTERS (self));
@@ -166,9 +275,24 @@ gtk_source_vim_registers_set (GtkSourceVimRegisters *self,
}
str = g_ref_string_new (value);
- g_hash_table_insert (self->values,
- (char *)g_intern_string (name),
- str);
+ view = gtk_source_vim_state_get_view (GTK_SOURCE_VIM_STATE (self));
+
+ if (g_str_equal (name, "+"))
+ {
+ GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view));
+ write_clipboard (self, clipboard, str);
+ }
+ else if (g_str_equal (name, "*"))
+ {
+ GdkClipboard *clipboard = gtk_widget_get_primary_clipboard (GTK_WIDGET (view));
+ write_clipboard (self, clipboard, str);
+ }
+ else
+ {
+ g_hash_table_insert (self->values,
+ (char *)g_intern_string (name),
+ str);
+ }
/* Push into the 0 numbered register and each 1..8 to
* the next numbered register position.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]