[gtksourceview/wip/chergert/vim: 173/363] add API to clone a visual and get bounds (not the selection)




commit bd1be4b8799e7a946676cd864937125e553786b3
Author: Christian Hergert <chergert redhat com>
Date:   Sat Oct 30 15:47:00 2021 -0700

    add API to clone a visual and get bounds (not the selection)
    
    also wait to dispose marks until visual disposal so we can potentially
    replay these

 gtksourceview/vim/gtk-source-vim-visual.c | 95 +++++++++++++++++++++++++------
 gtksourceview/vim/gtk-source-vim-visual.h |  6 +-
 2 files changed, 83 insertions(+), 18 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-visual.c b/gtksourceview/vim/gtk-source-vim-visual.c
index 48803e1f..b7a49ca3 100644
--- a/gtksourceview/vim/gtk-source-vim-visual.c
+++ b/gtksourceview/vim/gtk-source-vim-visual.c
@@ -200,8 +200,20 @@ gtk_source_vim_visual_enter (GtkSourceVimState *state)
 
        buffer = gtk_source_vim_state_get_buffer (state, &iter, &selection);
 
-       self->started_at = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (buffer), NULL, &iter, TRUE);
-       self->cursor = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (buffer), NULL, &iter, FALSE);
+       if (self->started_at == NULL)
+       {
+               self->started_at = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (buffer), NULL, &iter, TRUE);
+               g_object_add_weak_pointer (G_OBJECT (self->started_at),
+                                          (gpointer *)&self->started_at);
+       }
+
+       if (self->cursor == NULL)
+       {
+               self->cursor = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (buffer), NULL, &iter, FALSE);
+               g_object_add_weak_pointer (G_OBJECT (self->cursor),
+                                          (gpointer *)&self->cursor);
+       }
+
        gtk_text_mark_set_visible (self->cursor, self->mode != GTK_SOURCE_VIM_VISUAL_CHAR);
 
        gtk_source_vim_visual_track_motion (self);
@@ -223,22 +235,12 @@ gtk_source_vim_visual_leave (GtkSourceVimState *state)
 
        gtk_text_view_set_overwrite (GTK_TEXT_VIEW (view), TRUE);
 
-       if (self->cursor)
-       {
-               gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (buffer), &iter, self->cursor);
-               gtk_text_buffer_delete_mark (GTK_TEXT_BUFFER (buffer), self->cursor);
-               self->cursor = NULL;
-       }
-
-       if (self->started_at)
-       {
-               gtk_text_buffer_delete_mark (GTK_TEXT_BUFFER (buffer), self->started_at);
-               self->started_at = NULL;
-       }
-
+       gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (buffer), &iter, self->cursor);
        if (gtk_text_iter_ends_line (&iter) && !gtk_text_iter_starts_line (&iter))
                gtk_text_iter_backward_char (&iter);
 
+       gtk_text_mark_set_visible (self->cursor, FALSE);
+
        gtk_source_vim_state_select (state, &iter, &iter);
 }
 
@@ -288,8 +290,25 @@ gtk_source_vim_visual_handle_keypress (GtkSourceVimState *state,
 static void
 gtk_source_vim_visual_dispose (GObject *object)
 {
-       g_assert (GTK_SOURCE_VIM_VISUAL (object)->started_at == NULL);
-       g_assert (GTK_SOURCE_VIM_VISUAL (object)->cursor == NULL);
+       GtkSourceVimVisual *self = (GtkSourceVimVisual *)object;
+
+       if (self->cursor)
+       {
+               GtkTextMark *mark = self->cursor;
+               GtkTextBuffer *buffer = gtk_text_mark_get_buffer (mark);
+
+               g_clear_weak_pointer (&self->cursor);
+               gtk_text_buffer_delete_mark (GTK_TEXT_BUFFER (buffer), mark);
+       }
+
+       if (self->started_at)
+       {
+               GtkTextMark *mark = self->cursor;
+               GtkTextBuffer *buffer = gtk_text_mark_get_buffer (mark);
+
+               g_clear_weak_pointer (&self->started_at);
+               gtk_text_buffer_delete_mark (GTK_TEXT_BUFFER (buffer), mark);
+       }
 
        G_OBJECT_CLASS (gtk_source_vim_visual_parent_class)->dispose (object);
 }
@@ -324,3 +343,45 @@ gtk_source_vim_visual_new (GtkSourceVimVisualMode mode)
 
        return GTK_SOURCE_VIM_STATE (self);
 }
+
+gboolean
+gtk_source_vim_visual_get_bounds (GtkSourceVimVisual *self,
+                                  GtkTextIter        *cursor,
+                                  GtkTextIter        *started_at)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_VIM_VISUAL (self), FALSE);
+
+       if (cursor != NULL)
+       {
+               if (self->cursor == NULL)
+                       return FALSE;
+
+               gtk_text_buffer_get_iter_at_mark (gtk_text_mark_get_buffer (self->cursor),
+                                                 cursor, self->cursor);
+       }
+
+       if (started_at != NULL)
+       {
+               if (self->started_at == NULL)
+                       return FALSE;
+
+               gtk_text_buffer_get_iter_at_mark (gtk_text_mark_get_buffer (self->started_at),
+                                                 started_at, self->started_at);
+       }
+
+       return TRUE;
+}
+
+GtkSourceVimState *
+gtk_source_vim_visual_clone (GtkSourceVimVisual *self)
+{
+       GtkSourceVimState *ret;
+
+       g_return_val_if_fail (GTK_SOURCE_IS_VIM_VISUAL (self), NULL);
+
+       ret = gtk_source_vim_visual_new (self->mode);
+       g_set_weak_pointer (&GTK_SOURCE_VIM_VISUAL (ret)->cursor, self->cursor);
+       g_set_weak_pointer (&GTK_SOURCE_VIM_VISUAL (ret)->started_at, self->started_at);
+
+       return ret;
+}
diff --git a/gtksourceview/vim/gtk-source-vim-visual.h b/gtksourceview/vim/gtk-source-vim-visual.h
index 38eaf473..3bae41c8 100644
--- a/gtksourceview/vim/gtk-source-vim-visual.h
+++ b/gtksourceview/vim/gtk-source-vim-visual.h
@@ -36,6 +36,10 @@ typedef enum
 
 G_DECLARE_FINAL_TYPE (GtkSourceVimVisual, gtk_source_vim_visual, GTK_SOURCE, VIM_VISUAL, GtkSourceVimState)
 
-GtkSourceVimState *gtk_source_vim_visual_new (GtkSourceVimVisualMode mode);
+GtkSourceVimState *gtk_source_vim_visual_new        (GtkSourceVimVisualMode  mode);
+GtkSourceVimState *gtk_source_vim_visual_clone      (GtkSourceVimVisual     *self);
+gboolean           gtk_source_vim_visual_get_bounds (GtkSourceVimVisual     *self,
+                                                     GtkTextIter            *cursor,
+                                                     GtkTextIter            *started_at);
 
 G_END_DECLS


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