[gtksourceview/wip/regex-search] Regex search: replace with g_regex_replace()



commit 9b936bd4a9ec7d08aaeef1f8b82082473543f210
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sun Jul 21 15:01:58 2013 +0200

    Regex search: replace with g_regex_replace()
    
    It is now possible to use backreferences in the replacement text: \0,
    \1, \g<name>, etc.

 gtksourceview/gtksourcesearch.c |  126 ++++++++++++++++++++++++++++-----------
 1 files changed, 92 insertions(+), 34 deletions(-)
---
diff --git a/gtksourceview/gtksourcesearch.c b/gtksourceview/gtksourcesearch.c
index bcd4e04..325a888 100644
--- a/gtksourceview/gtksourcesearch.c
+++ b/gtksourceview/gtksourcesearch.c
@@ -467,6 +467,25 @@ regex_search_get_real_start (GtkSourceSearch   *search,
        }
 }
 
+static GRegexMatchFlags
+regex_search_get_match_options (const GtkTextIter *real_start,
+                               const GtkTextIter *end)
+{
+       GRegexMatchFlags match_options = 0;
+
+       if (!gtk_text_iter_starts_line (real_start))
+       {
+               match_options |= G_REGEX_MATCH_NOTBOL;
+       }
+
+       if (!gtk_text_iter_ends_line (end))
+       {
+               match_options |= G_REGEX_MATCH_NOTEOL;
+       }
+
+       return match_options;
+}
+
 /* Get the @match_start and @match_end iters of the @match_info.
  * g_match_info_fetch_pos() returns byte positions. To get the iters, we need to
  * know the number of UTF-8 characters. A GMatchInfo can contain several matches
@@ -537,7 +556,7 @@ basic_forward_regex_search (GtkSourceSearch   *search,
        gint start_pos;
        gchar *subject;
        gssize subject_length;
-       GRegexMatchFlags match_options = 0;
+       GRegexMatchFlags match_options;
        GMatchInfo *match_info;
        GError *error = NULL;
        GtkTextIter iter;
@@ -560,15 +579,7 @@ basic_forward_regex_search (GtkSourceSearch   *search,
                end = *limit;
        }
 
-       if (!gtk_text_iter_starts_line (&real_start))
-       {
-               match_options |= G_REGEX_MATCH_NOTBOL;
-       }
-
-       if (!gtk_text_iter_ends_line (&end))
-       {
-               match_options |= G_REGEX_MATCH_NOTEOL;
-       }
+       match_options = regex_search_get_match_options (&real_start, &end);
 
        subject = gtk_text_iter_get_visible_text (&real_start, &end);
        subject_length = strlen (subject);
@@ -668,7 +679,7 @@ basic_backward_regex_search (GtkSourceSearch   *search,
        gint start_pos;
        gchar *subject;
        gssize subject_length;
-       GRegexMatchFlags match_options = 0;
+       GRegexMatchFlags match_options;
        GMatchInfo *match_info;
        GError *error = NULL;
        GtkTextIter iter;
@@ -695,15 +706,7 @@ basic_backward_regex_search (GtkSourceSearch   *search,
 
        end = *start_at;
 
-       if (!gtk_text_iter_starts_line (&real_start))
-       {
-               match_options |= G_REGEX_MATCH_NOTBOL;
-       }
-
-       if (!gtk_text_iter_ends_line (&end))
-       {
-               match_options |= G_REGEX_MATCH_NOTEOL;
-       }
+       match_options = regex_search_get_match_options (&real_start, &end);
 
        subject = gtk_text_iter_get_visible_text (&real_start, &end);
        subject_length = strlen (subject);
@@ -1661,7 +1664,7 @@ regex_search_scan_segment (GtkSourceSearch   *search,
        gint start_pos;
        gchar *subject;
        gssize subject_length;
-       GRegexMatchFlags match_options = 0;
+       GRegexMatchFlags match_options;
        GMatchInfo *match_info;
        GError *error = NULL;
        GtkTextIter iter;
@@ -1693,19 +1696,17 @@ regex_search_scan_segment (GtkSourceSearch   *search,
               g_print ("start position in the subject: %d\n", start_pos);
        });
 
-       if (!gtk_text_iter_starts_line (&real_start))
-       {
-               match_options |= G_REGEX_MATCH_NOTBOL;
+       match_options = regex_search_get_match_options (&real_start, segment_end);
 
+       if (match_options & G_REGEX_MATCH_NOTBOL)
+       {
                DEBUG ({
                       g_print ("match notbol\n");
                });
        }
 
-       if (!gtk_text_iter_ends_line (segment_end))
+       if (match_options & G_REGEX_MATCH_NOTEOL)
        {
-               match_options |= G_REGEX_MATCH_NOTEOL;
-
                DEBUG ({
                       g_print ("match noteol\n");
                });
@@ -2869,6 +2870,55 @@ _gtk_source_search_backward_finish (GtkSourceSearch  *search,
                                                  error);
 }
 
+static void
+regex_replace (GtkSourceSearch   *search,
+              const GtkTextIter *match_start,
+              const GtkTextIter *match_end,
+              const gchar       *replace)
+{
+       GtkTextIter real_start;
+       GtkTextIter m_start = *match_start;
+       GtkTextIter m_end = *match_end;
+       gint start_pos;
+       gchar *subject;
+       gchar *subject_replaced;
+       GRegexMatchFlags match_options;
+       GError *error = NULL;
+
+       g_assert (search->priv->regex != NULL);
+
+       regex_search_get_real_start (search, match_start, &real_start, &start_pos);
+
+       subject = gtk_text_iter_get_visible_text (&real_start, match_end);
+
+       match_options = regex_search_get_match_options (&real_start, match_end);
+
+       subject_replaced = g_regex_replace (search->priv->regex,
+                                           subject,
+                                           -1,
+                                           start_pos,
+                                           replace,
+                                           match_options,
+                                           &error);
+
+       g_free (subject);
+
+       if (error != NULL)
+       {
+               g_warning ("Regex replace error: %s", error->message);
+               g_error_free (error);
+               g_free (subject_replaced);
+               return;
+       }
+
+       gtk_text_buffer_begin_user_action (search->priv->buffer);
+       gtk_text_buffer_delete (search->priv->buffer, &m_start, &m_end);
+       gtk_text_buffer_insert (search->priv->buffer, &m_start, subject_replaced, -1);
+       gtk_text_buffer_end_user_action (search->priv->buffer);
+
+       g_free (subject_replaced);
+}
+
 gboolean
 _gtk_source_search_replace (GtkSourceSearch   *search,
                            const GtkTextIter *match_start,
@@ -2889,7 +2939,10 @@ _gtk_source_search_replace (GtkSourceSearch   *search,
                return FALSE;
        }
 
-       basic_forward_search (search, match_start, &start, &end, match_end);
+       if (!basic_forward_search (search, match_start, &start, &end, match_end))
+       {
+               return FALSE;
+       }
 
        if (!gtk_text_iter_equal (match_start, &start) ||
            !gtk_text_iter_equal (match_end, &end))
@@ -2897,12 +2950,17 @@ _gtk_source_search_replace (GtkSourceSearch   *search,
                return FALSE;
        }
 
-       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, &start, replace, replace_length);
-
-       gtk_text_buffer_end_user_action (search->priv->buffer);
+       if (search->priv->regex_enabled)
+       {
+               regex_replace (search, &start, &end, replace);
+       }
+       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, &start, replace, replace_length);
+               gtk_text_buffer_end_user_action (search->priv->buffer);
+       }
 
        return TRUE;
 }


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