[gtksourceview/wip/search-revalidate-iters] SearchContext: add replace2() function that revalidates iters



commit cb8f41adeb71c569b464bfb9fcf0f1346b0a2123
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sat Jun 4 15:14:02 2016 +0200

    SearchContext: add replace2() function that revalidates iters
    
    And adapt the tests to use replace2().
    
    https://bugzilla.gnome.org/show_bug.cgi?id=754883

 docs/reference/gtksourceview-3.0-sections.txt |    1 +
 gtksourceview/gtksourcesearchcontext.c        |   84 +++++++++++++++++++++++++
 gtksourceview/gtksourcesearchcontext.h        |    8 +++
 tests/test-search.c                           |   12 ++--
 testsuite/test-search-context.c               |   33 +++++++---
 5 files changed, 122 insertions(+), 16 deletions(-)
---
diff --git a/docs/reference/gtksourceview-3.0-sections.txt b/docs/reference/gtksourceview-3.0-sections.txt
index dda07f2..6b8c4fa 100644
--- a/docs/reference/gtksourceview-3.0-sections.txt
+++ b/docs/reference/gtksourceview-3.0-sections.txt
@@ -667,6 +667,7 @@ gtk_source_search_context_backward
 gtk_source_search_context_backward_async
 gtk_source_search_context_backward_finish
 gtk_source_search_context_replace
+gtk_source_search_context_replace2
 gtk_source_search_context_replace_all
 gtk_source_search_context_get_regex_error
 <SUBSECTION Standard>
diff --git a/gtksourceview/gtksourcesearchcontext.c b/gtksourceview/gtksourcesearchcontext.c
index dd4dbee..2f9006a 100644
--- a/gtksourceview/gtksourcesearchcontext.c
+++ b/gtksourceview/gtksourcesearchcontext.c
@@ -3591,6 +3591,90 @@ gtk_source_search_context_replace (GtkSourceSearchContext  *search,
 }
 
 /**
+ * gtk_source_search_context_replace2:
+ * @search: a #GtkSourceSearchContext.
+ * @match_start: the start of the match to replace.
+ * @match_end: the end of the match to replace.
+ * @replace: the replacement text.
+ * @replace_length: the length of @replace in bytes, or -1.
+ * @error: location to a #GError, or %NULL to ignore errors.
+ *
+ * Replaces a search match by another text. If @match_start and @match_end
+ * doesn't correspond to a search match, %FALSE is returned.
+ *
+ * Unlike with gtk_source_search_context_replace(), the @match_start and
+ * @match_end iters are revalidated to point to the replacement text boundaries.
+ *
+ * For a regular expression replacement, you can check if @replace is valid by
+ * calling g_regex_check_replacement(). The @replace text can contain
+ * backreferences; read the g_regex_replace() documentation for more details.
+ *
+ * Returns: whether the match has been replaced.
+ * Since: 3.22
+ */
+gboolean
+gtk_source_search_context_replace2 (GtkSourceSearchContext  *search,
+                                   GtkTextIter             *match_start,
+                                   GtkTextIter             *match_end,
+                                   const gchar             *replace,
+                                   gint                     replace_length,
+                                   GError                 **error)
+{
+       GtkTextIter start;
+       GtkTextIter end;
+       GtkTextMark *start_mark;
+       gboolean replaced = FALSE;
+
+       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search), FALSE);
+       g_return_val_if_fail (match_start != NULL, FALSE);
+       g_return_val_if_fail (match_end != NULL, FALSE);
+       g_return_val_if_fail (replace != NULL, FALSE);
+       g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+       if (search->priv->buffer == NULL)
+       {
+               return FALSE;
+       }
+
+       if (!smart_forward_search (search, match_start, &start, &end))
+       {
+               return FALSE;
+       }
+
+       if (!gtk_text_iter_equal (match_start, &start) ||
+           !gtk_text_iter_equal (match_end, &end))
+       {
+               return FALSE;
+       }
+
+       start_mark = gtk_text_buffer_create_mark (search->priv->buffer, NULL, &start, TRUE);
+
+       if (gtk_source_search_settings_get_regex_enabled (search->priv->settings))
+       {
+               replaced = regex_replace (search, &start, &end, replace, error);
+       }
+       else
+       {
+               gtk_text_buffer_begin_user_action (search->priv->buffer);
+               gtk_text_buffer_delete (search->priv->buffer, &start, &end);
+               gtk_text_buffer_insert (search->priv->buffer, &end, replace, replace_length);
+               gtk_text_buffer_end_user_action (search->priv->buffer);
+
+               replaced = TRUE;
+       }
+
+       if (replaced)
+       {
+               gtk_text_buffer_get_iter_at_mark (search->priv->buffer, match_start, start_mark);
+               *match_end = end;
+       }
+
+       gtk_text_buffer_delete_mark (search->priv->buffer, start_mark);
+
+       return replaced;
+}
+
+/**
  * gtk_source_search_context_replace_all:
  * @search: a #GtkSourceSearchContext.
  * @replace: the replacement text.
diff --git a/gtksourceview/gtksourcesearchcontext.h b/gtksourceview/gtksourcesearchcontext.h
index 67e14b1..0269e2c 100644
--- a/gtksourceview/gtksourcesearchcontext.h
+++ b/gtksourceview/gtksourcesearchcontext.h
@@ -141,6 +141,14 @@ gboolean            gtk_source_search_context_replace                      
(GtkSourceSearchContext  *search,
                                                                                 gint                     
replace_length,
                                                                                 GError                 
**error);
 
+GTK_SOURCE_AVAILABLE_IN_3_22
+gboolean                gtk_source_search_context_replace2                     (GtkSourceSearchContext  
*search,
+                                                                                GtkTextIter             
*match_start,
+                                                                                GtkTextIter             
*match_end,
+                                                                                const gchar             
*replace,
+                                                                                gint                     
replace_length,
+                                                                                GError                 
**error);
+
 GTK_SOURCE_AVAILABLE_IN_3_10
 guint                   gtk_source_search_context_replace_all                  (GtkSourceSearchContext  
*search,
                                                                                 const gchar             
*replace,
diff --git a/tests/test-search.c b/tests/test-search.c
index c7062df..2de3cfc 100644
--- a/tests/test-search.c
+++ b/tests/test-search.c
@@ -266,12 +266,12 @@ button_replace_clicked_cb (TestSearch *search,
        entry_buffer = gtk_entry_get_buffer (search->priv->replace_entry);
        replace_length = gtk_entry_buffer_get_bytes (entry_buffer);
 
-       gtk_source_search_context_replace (search->priv->search_context,
-                                          &match_start,
-                                          &match_end,
-                                          gtk_entry_get_text (search->priv->replace_entry),
-                                          replace_length,
-                                          NULL);
+       gtk_source_search_context_replace2 (search->priv->search_context,
+                                           &match_start,
+                                           &match_end,
+                                           gtk_entry_get_text (search->priv->replace_entry),
+                                           replace_length,
+                                           NULL);
 
        gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (search->priv->source_buffer),
                                              NULL,
diff --git a/testsuite/test-search-context.c b/testsuite/test-search-context.c
index f8e39a4..f755518 100644
--- a/testsuite/test-search-context.c
+++ b/testsuite/test-search-context.c
@@ -868,6 +868,7 @@ test_replace (void)
        GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
        GtkTextIter start;
        GtkTextIter end;
+       gint offset;
        gboolean replaced;
        gchar *contents;
 
@@ -878,17 +879,21 @@ test_replace (void)
        gtk_text_buffer_get_iter_at_offset (text_buffer, &start, 1);
        gtk_text_buffer_get_iter_at_offset (text_buffer, &end, 3);
 
-       replaced = gtk_source_search_context_replace (context, &start, &end, "bb", 2, NULL);
+       replaced = gtk_source_search_context_replace2 (context, &start, &end, "bbb", -1, NULL);
        g_assert (!replaced);
 
        gtk_text_buffer_get_iter_at_offset (text_buffer, &start, 2);
        gtk_text_buffer_get_iter_at_offset (text_buffer, &end, 4);
 
-       replaced = gtk_source_search_context_replace (context, &start, &end, "bb", 2, NULL);
+       replaced = gtk_source_search_context_replace2 (context, &start, &end, "bbb", -1, NULL);
        g_assert (replaced);
+       offset = gtk_text_iter_get_offset (&start);
+       g_assert_cmpint (offset, ==, 2);
+       offset = gtk_text_iter_get_offset (&end);
+       g_assert_cmpint (offset, ==, 5);
 
        contents = get_buffer_contents (text_buffer);
-       g_assert_cmpstr (contents, ==, "aabb");
+       g_assert_cmpstr (contents, ==, "aabbb");
        g_free (contents);
 
        g_object_unref (source_buffer);
@@ -962,7 +967,9 @@ test_regex_basics (void)
 
        gtk_text_buffer_get_start_iter (text_buffer, &start);
        gtk_text_buffer_get_end_iter (text_buffer, &end);
-       gtk_source_search_context_replace (context, &start, &end, "\\2#\\1", -1, NULL);
+       gtk_source_search_context_replace2 (context, &start, &end, "\\2#\\1", -1, NULL);
+       g_assert (gtk_text_iter_is_start (&start));
+       g_assert (gtk_text_iter_is_end (&end));
 
        contents = get_buffer_contents (text_buffer);
        g_assert_cmpstr (contents, ==, "bb#aa");
@@ -1026,10 +1033,13 @@ test_regex_at_word_boundaries (void)
 
        gtk_text_buffer_get_iter_at_offset (text_buffer, &match_start, 1);
        gtk_text_buffer_get_end_iter (text_buffer, &match_end);
-       gtk_source_search_context_replace (context, &match_start, &match_end, "bb", -1, NULL);
+       gtk_source_search_context_replace2 (context, &match_start, &match_end, "bbb", -1, NULL);
+       offset = gtk_text_iter_get_offset (&match_start);
+       g_assert_cmpint (offset, ==, 1);
+       g_assert (gtk_text_iter_is_end (&match_end));
 
        content = get_buffer_contents (text_buffer);
-       g_assert_cmpstr (content, ==, "&bb");
+       g_assert_cmpstr (content, ==, "&bbb");
        g_free (content);
 
        /* Test replace multi-byte character */
@@ -1040,10 +1050,13 @@ test_regex_at_word_boundaries (void)
 
        gtk_text_buffer_get_iter_at_offset (text_buffer, &match_start, 1);
        gtk_text_buffer_get_end_iter (text_buffer, &match_end);
-       gtk_source_search_context_replace (context, &match_start, &match_end, "bb", -1, NULL);
+       gtk_source_search_context_replace2 (context, &match_start, &match_end, "bbb", -1, NULL);
+       offset = gtk_text_iter_get_offset (&match_start);
+       g_assert_cmpint (offset, ==, 1);
+       g_assert (gtk_text_iter_is_end (&match_end));
 
        content = get_buffer_contents (text_buffer);
-       g_assert_cmpstr (content, ==, "–bb");
+       g_assert_cmpstr (content, ==, "–bbb");
        g_free (content);
 
        g_object_unref (source_buffer);
@@ -1103,7 +1116,7 @@ test_regex_look_behind (void)
        g_assert_cmpint (pos, ==, 1);
 
        /* Replace */
-       gtk_source_search_context_replace (context, &match_start, &match_end, "R", -1, &error);
+       gtk_source_search_context_replace2 (context, &match_start, &match_end, "R", -1, &error);
        g_assert_no_error (error);
 
        contents = get_buffer_contents (text_buffer);
@@ -1178,7 +1191,7 @@ test_regex_look_ahead (void)
        g_assert_cmpint (pos, ==, 1);
 
        /* Replace */
-       gtk_source_search_context_replace (context, &match_start, &match_end, "R", -1, &error);
+       gtk_source_search_context_replace2 (context, &match_start, &match_end, "R", -1, &error);
        g_assert_no_error (error);
 
        contents = get_buffer_contents (text_buffer);


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