[gtksourceview/wip/regex-search: 1/10] New search and replace API, with SearchContext and SearchSettings



commit da848c994ce3b27eda9924f9f8c030f24be3c881
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sat Jul 27 21:30:24 2013 +0200

    New search and replace API, with SearchContext and SearchSettings
    
    The API is more flexible. Before, only one search was possible at a
    time: there was a 1:1 relationship between the buffer and the private
    Search object. Now it is a 1:N relationship between the buffer and the
    SearchContext: it is possible to run several searches at the same time.
    And also a 1:N relationship between the SearchContext and the
    SearchSettings: it is possible to share search settings between several
    buffers.
    
    In summary, it is an indirect many-to-many relationship between the
    buffer and the search settings.
    
           0-N       1-1               1-1       0-N
    Buffer ------------- SearchContext ------------- SearchSettings

 docs/reference/gtksourceview-3.0-sections.txt |   24 -
 gtksourceview/Makefile.am                     |    2 +
 gtksourceview/gtksource.h                     |    1 +
 gtksourceview/gtksourcebuffer.c               |  829 +-----------------------
 gtksourceview/gtksourcebuffer.h               |   82 ---
 gtksourceview/gtksourcesearchcontext.c        |  896 +++++++++++++++++--------
 gtksourceview/gtksourcesearchcontext.h        |  129 ++--
 gtksourceview/gtksourcesearchsettings.c       |  472 +++++++++++++
 gtksourceview/gtksourcesearchsettings.h       |   85 +++
 gtksourceview/gtksourcetypes.h                |    1 +
 po/POTFILES.in                                |    1 +
 tests/test-search-context.c                   |  390 +++++++-----
 tests/test-search-performances.c              |   33 +-
 tests/test-search.c                           |  249 ++++----
 tests/test-search.ui                          |   22 +-
 15 files changed, 1631 insertions(+), 1585 deletions(-)
---
diff --git a/docs/reference/gtksourceview-3.0-sections.txt b/docs/reference/gtksourceview-3.0-sections.txt
index f30fb49..8c159c8 100644
--- a/docs/reference/gtksourceview-3.0-sections.txt
+++ b/docs/reference/gtksourceview-3.0-sections.txt
@@ -37,30 +37,6 @@ gtk_source_buffer_begin_not_undoable_action
 gtk_source_buffer_end_not_undoable_action
 gtk_source_buffer_get_undo_manager
 gtk_source_buffer_set_undo_manager
-<SUBSECTION>
-gtk_source_buffer_set_search_text
-gtk_source_buffer_get_search_text
-gtk_source_buffer_set_case_sensitive_search
-gtk_source_buffer_get_case_sensitive_search
-gtk_source_buffer_set_search_at_word_boundaries
-gtk_source_buffer_get_search_at_word_boundaries
-gtk_source_buffer_set_search_wrap_around
-gtk_source_buffer_get_search_wrap_around
-gtk_source_buffer_set_regex_search
-gtk_source_buffer_get_regex_search
-gtk_source_buffer_get_regex_search_error
-gtk_source_buffer_set_highlight_search
-gtk_source_buffer_get_highlight_search
-gtk_source_buffer_get_search_occurrences_count
-gtk_source_buffer_get_search_occurrence_position
-gtk_source_buffer_forward_search
-gtk_source_buffer_forward_search_async
-gtk_source_buffer_forward_search_finish
-gtk_source_buffer_backward_search
-gtk_source_buffer_backward_search_async
-gtk_source_buffer_backward_search_finish
-gtk_source_buffer_search_replace
-gtk_source_buffer_search_replace_all
 <SUBSECTION Standard>
 GtkSourceBufferClass
 GTK_SOURCE_IS_BUFFER
diff --git a/gtksourceview/Makefile.am b/gtksourceview/Makefile.am
index 9479ede..c05795c 100644
--- a/gtksourceview/Makefile.am
+++ b/gtksourceview/Makefile.am
@@ -40,6 +40,7 @@ libgtksourceview_headers =                    \
        gtksourcemarkattributes.h               \
        gtksourceprintcompositor.h              \
        gtksourcesearchcontext.h                \
+       gtksourcesearchsettings.h               \
        gtksourcestyle.h                        \
        gtksourcestylescheme.h                  \
        gtksourcestyleschememanager.h           \
@@ -103,6 +104,7 @@ libgtksourceview_c_files = \
        gtksourcemarkattributes.c       \
        gtksourceprintcompositor.c      \
        gtksourcesearchcontext.c        \
+       gtksourcesearchsettings.c       \
        gtksourcestyle.c                \
        gtksourcestylescheme.c          \
        gtksourcestyleschememanager.c   \
diff --git a/gtksourceview/gtksource.h b/gtksourceview/gtksource.h
index 1b258ba..1c7bd79 100644
--- a/gtksourceview/gtksource.h
+++ b/gtksourceview/gtksource.h
@@ -38,6 +38,7 @@
 #include <gtksourceview/gtksourcemarkattributes.h>
 #include <gtksourceview/gtksourceprintcompositor.h>
 #include <gtksourceview/gtksourcesearchcontext.h>
+#include <gtksourceview/gtksourcesearchsettings.h>
 #include <gtksourceview/gtksourcestyle.h>
 #include <gtksourceview/gtksourcestylescheme.h>
 #include <gtksourceview/gtksourcestyleschememanager.h>
diff --git a/gtksourceview/gtksourcebuffer.c b/gtksourceview/gtksourcebuffer.c
index 7bbf348..e6cd89e 100644
--- a/gtksourceview/gtksourcebuffer.c
+++ b/gtksourceview/gtksourcebuffer.c
@@ -148,6 +148,7 @@
 #define PROFILE(x)
 #endif
 
+/* For bracket matching */
 #define MAX_CHARS_BEFORE_FINDING_A_MATCH    10000
 
 #define TAG_CONTEXT_CLASS_NAME "GtkSourceViewTagContextClassName"
@@ -169,18 +170,10 @@ enum {
        PROP_CAN_REDO,
        PROP_HIGHLIGHT_SYNTAX,
        PROP_HIGHLIGHT_MATCHING_BRACKETS,
-       PROP_HIGHLIGHT_SEARCH,
        PROP_MAX_UNDO_LEVELS,
        PROP_LANGUAGE,
        PROP_STYLE_SCHEME,
-       PROP_UNDO_MANAGER,
-       PROP_SEARCH_TEXT,
-       PROP_SEARCH_OCCURRENCES_COUNT,
-       PROP_CASE_SENSITIVE_SEARCH,
-       PROP_SEARCH_AT_WORD_BOUNDARIES,
-       PROP_SEARCH_WRAP_AROUND,
-       PROP_REGEX_SEARCH,
-       PROP_REGEX_SEARCH_ERROR
+       PROP_UNDO_MANAGER
 };
 
 struct _GtkSourceBufferPrivate
@@ -200,8 +193,6 @@ struct _GtkSourceBufferPrivate
        GtkSourceUndoManager  *undo_manager;
        gint                   max_undo_levels;
 
-       GtkSourceSearchContext *search;
-
        guint                  highlight_syntax : 1;
        guint                  highlight_brackets : 1;
        guint                  constructed : 1;
@@ -331,19 +322,6 @@ gtk_source_buffer_class_init (GtkSourceBufferClass *klass)
                                                               G_PARAM_READWRITE));
 
        /**
-        * GtkSourceBuffer:highlight-search:
-        *
-        * Whether to highlight search occurrences in the buffer.
-        */
-       g_object_class_install_property (object_class,
-                                        PROP_HIGHLIGHT_SEARCH,
-                                        g_param_spec_boolean ("highlight-search",
-                                                              _("Highlight Search"),
-                                                              _("Whether to highlight search occurrences"),
-                                                              TRUE,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
-       /**
         * GtkSourceBuffer:max-undo-levels:
         *
         * Number of undo levels for the buffer. -1 means no limit. This property
@@ -410,124 +388,6 @@ gtk_source_buffer_class_init (GtkSourceBufferClass *klass)
                                                              GTK_SOURCE_TYPE_UNDO_MANAGER,
                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
-       /**
-        * GtkSourceBuffer:search-text:
-        *
-        * A search string, or %NULL if the search is disabled. If the regular
-        * expression search is enabled, #GtkSourceBuffer:search-text is the
-        * pattern.
-        *
-        * Since: 3.10
-        */
-       g_object_class_install_property (object_class,
-                                        PROP_SEARCH_TEXT,
-                                        g_param_spec_string ("search-text",
-                                                             _("Search text"),
-                                                             _("The text to search"),
-                                                             NULL,
-                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
-       /**
-        * GtkSourceBuffer:search-occurrences-count:
-        *
-        * The total number of search occurrences. If the search is disabled,
-        * the value is 0. If the buffer is not already fully scanned, the value
-        * is -1.
-        *
-        * Since: 3.10
-        */
-       g_object_class_install_property (object_class,
-                                        PROP_SEARCH_OCCURRENCES_COUNT,
-                                        g_param_spec_int ("search-occurrences-count",
-                                                          _("Search occurrences count"),
-                                                          _("Total number of search occurrences"),
-                                                          -1,
-                                                          G_MAXINT,
-                                                          0,
-                                                          G_PARAM_READABLE));
-
-       /**
-        * GtkSourceBuffer:case-sensitive-search:
-        *
-        * Whether the search is case sensitive.
-        *
-        * Since: 3.10
-        */
-       g_object_class_install_property (object_class,
-                                        PROP_CASE_SENSITIVE_SEARCH,
-                                        g_param_spec_boolean ("case-sensitive-search",
-                                                              _("Case sensitive search"),
-                                                              _("Case sensitive search"),
-                                                              FALSE,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
-       /**
-        * GtkSourceBuffer:search-at-word-boundaries:
-        *
-        * If %TRUE, a search match must start and end a word. The match can
-        * span multiple words.
-        *
-        * Since: 3.10
-        */
-       g_object_class_install_property (object_class,
-                                        PROP_SEARCH_AT_WORD_BOUNDARIES,
-                                        g_param_spec_boolean ("search-at-word-boundaries",
-                                                              _("Search at word boundaries"),
-                                                              _("Search at word boundaries"),
-                                                              FALSE,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
-       /**
-        * GtkSourceBuffer:search-wrap-around:
-        *
-        * For a forward search, continue at the beginning of the buffer if no
-        * search occurrence is found. For a backward search, continue at the
-        * end of the buffer.
-        *
-        * Since: 3.10
-        */
-       g_object_class_install_property (object_class,
-                                        PROP_SEARCH_WRAP_AROUND,
-                                        g_param_spec_boolean ("search-wrap-around",
-                                                              _("Search: wrap around"),
-                                                              _("Search: wrap around"),
-                                                              TRUE,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
-       /**
-        * GtkSourceBuffer:regex-search:
-        *
-        * Search by regular expressions with #GtkSourceBuffer:search-text as
-        * the pattern.
-        *
-        * Since: 3.10
-        */
-       g_object_class_install_property (object_class,
-                                        PROP_REGEX_SEARCH,
-                                        g_param_spec_boolean ("regex-search",
-                                                              _("Regex search"),
-                                                              _("Search by regular expression"),
-                                                              FALSE,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
-       /**
-        * GtkSourceBuffer:regex-search-error:
-        *
-        * If the regex search pattern doesn't follow all the rules,
-        * #GtkSourceBuffer:regex-search-error will be set. If the pattern
-        * is valid, #GtkSourceBuffer:regex-search-error is %NULL.
-        *
-        * Free with g_error_free().
-        *
-        * Since: 3.10
-        */
-       g_object_class_install_property (object_class,
-                                        PROP_REGEX_SEARCH_ERROR,
-                                        g_param_spec_pointer ("regex-search-error",
-                                                              _("Regex search error"),
-                                                              _("Regular expression search error"),
-                                                              G_PARAM_READABLE));
-
        param_types[0] = GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE;
        param_types[1] = GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE;
 
@@ -663,9 +523,9 @@ gtk_source_buffer_init (GtkSourceBuffer *buffer)
        priv->style_scheme = _gtk_source_style_scheme_get_default ();
 
        if (priv->style_scheme != NULL)
+       {
                g_object_ref (priv->style_scheme);
-
-       priv->search = gtk_source_search_context_new (buffer);
+       }
 }
 
 static void
@@ -708,7 +568,6 @@ gtk_source_buffer_dispose (GObject *object)
        g_clear_object (&buffer->priv->highlight_engine);
        g_clear_object (&buffer->priv->language);
        g_clear_object (&buffer->priv->style_scheme);
-       g_clear_object (&buffer->priv->search);
 
        G_OBJECT_CLASS (gtk_source_buffer_parent_class)->dispose (object);
 }
@@ -737,11 +596,6 @@ gtk_source_buffer_set_property (GObject      *object,
                                                                           g_value_get_boolean (value));
                        break;
 
-               case PROP_HIGHLIGHT_SEARCH:
-                       gtk_source_search_context_set_highlight (source_buffer->priv->search,
-                                                                g_value_get_boolean (value));
-                       break;
-
                case PROP_MAX_UNDO_LEVELS:
                        gtk_source_buffer_set_max_undo_levels (source_buffer,
                                                               g_value_get_int (value));
@@ -762,31 +616,6 @@ gtk_source_buffer_set_property (GObject      *object,
                                                            g_value_get_object (value));
                        break;
 
-               case PROP_SEARCH_TEXT:
-                       gtk_source_search_context_set_text (source_buffer->priv->search,
-                                                           g_value_get_string (value));
-                       break;
-
-               case PROP_CASE_SENSITIVE_SEARCH:
-                       gtk_source_search_context_set_case_sensitive (source_buffer->priv->search,
-                                                                     g_value_get_boolean (value));
-                       break;
-
-               case PROP_SEARCH_AT_WORD_BOUNDARIES:
-                       gtk_source_search_context_set_at_word_boundaries (source_buffer->priv->search,
-                                                                         g_value_get_boolean (value));
-                       break;
-
-               case PROP_SEARCH_WRAP_AROUND:
-                       gtk_source_search_context_set_wrap_around (source_buffer->priv->search,
-                                                                  g_value_get_boolean (value));
-                       break;
-
-               case PROP_REGEX_SEARCH:
-                       gtk_source_search_context_set_regex_enabled (source_buffer->priv->search,
-                                                                    g_value_get_boolean (value));
-                       break;
-
                default:
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                        break;
@@ -817,10 +646,6 @@ gtk_source_buffer_get_property (GObject    *object,
                                             source_buffer->priv->highlight_brackets);
                        break;
 
-               case PROP_HIGHLIGHT_SEARCH:
-                       g_value_set_boolean (value, gtk_source_search_context_get_highlight 
(source_buffer->priv->search));
-                       break;
-
                case PROP_MAX_UNDO_LEVELS:
                        g_value_set_int (value,
                                         source_buffer->priv->max_undo_levels);
@@ -846,34 +671,6 @@ gtk_source_buffer_get_property (GObject    *object,
                        g_value_set_object (value, source_buffer->priv->undo_manager);
                        break;
 
-               case PROP_SEARCH_TEXT:
-                       g_value_set_string (value, gtk_source_search_context_get_text 
(source_buffer->priv->search));
-                       break;
-
-               case PROP_SEARCH_OCCURRENCES_COUNT:
-                       g_value_set_int (value, gtk_source_search_context_get_occurrences_count 
(source_buffer->priv->search));
-                       break;
-
-               case PROP_CASE_SENSITIVE_SEARCH:
-                       g_value_set_boolean (value, gtk_source_search_context_get_case_sensitive 
(source_buffer->priv->search));
-                       break;
-
-               case PROP_SEARCH_AT_WORD_BOUNDARIES:
-                       g_value_set_boolean (value, gtk_source_search_context_get_at_word_boundaries 
(source_buffer->priv->search));
-                       break;
-
-               case PROP_SEARCH_WRAP_AROUND:
-                       g_value_set_boolean (value, gtk_source_search_context_get_wrap_around 
(source_buffer->priv->search));
-                       break;
-
-               case PROP_REGEX_SEARCH:
-                       g_value_set_boolean (value, gtk_source_search_context_get_regex_enabled 
(source_buffer->priv->search));
-                       break;
-
-               case PROP_REGEX_SEARCH_ERROR:
-                       g_value_set_pointer (value, gtk_source_search_context_get_regex_error 
(source_buffer->priv->search));
-                       break;
-
                default:
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                        break;
@@ -1792,10 +1589,8 @@ _gtk_source_buffer_update_highlight (GtkSourceBuffer   *buffer,
                                                     synchronous);
        }
 
-       gtk_source_search_context_update_highlight (buffer->priv->search,
-                                                   start,
-                                                   end,
-                                                   synchronous);
+       /* TODO: update highlighting for the currently highlighted search
+        * context. */
 }
 
 /**
@@ -2736,615 +2531,3 @@ gtk_source_buffer_get_undo_manager (GtkSourceBuffer *buffer)
 
        return buffer->priv->undo_manager;
 }
-
-/**
- * gtk_source_buffer_set_search_text:
- * @buffer: a #GtkSourceBuffer.
- * @text: (allow-none): the nul-terminated text to search, or %NULL to disable the search.
- *
- * Sets the text to search. If @text is %NULL or is empty, the search will be
- * disabled. A copy of @text will be made, so you can safely free @text after
- * a call to this function.
- *
- * You may be interested to call gtk_source_utils_unescape_search_text() before
- * this function.
- *
- * Since: 3.10
- */
-void
-gtk_source_buffer_set_search_text (GtkSourceBuffer *buffer,
-                                  const gchar     *text)
-{
-       const gchar *cur_text;
-
-       g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
-
-       cur_text = gtk_source_search_context_get_text (buffer->priv->search);
-
-       if (cur_text == NULL && (text == NULL || *text == '\0'))
-       {
-               return;
-       }
-
-       if (g_strcmp0 (cur_text, text) != 0)
-       {
-               gtk_source_search_context_set_text (buffer->priv->search, text);
-               g_object_notify (G_OBJECT (buffer), "search-text");
-       }
-}
-
-/**
- * gtk_source_buffer_get_search_text:
- * @buffer: a #GtkSourceBuffer.
- *
- * Gets the text to search. The return value must not be freed.
- *
- * You may be interested to call gtk_source_utils_escape_search_text() after
- * this function.
- *
- * Returns: the text to search, or %NULL if the search is disabled.
- * Since: 3.10
- */
-const gchar *
-gtk_source_buffer_get_search_text (GtkSourceBuffer *buffer)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), NULL);
-
-       return gtk_source_search_context_get_text (buffer->priv->search);
-}
-
-/**
- * gtk_source_buffer_set_case_sensitive_search:
- * @buffer: a #GtkSourceBuffer.
- * @case_sensitive: the setting.
- *
- * Enables or disables the case sensitivity for the search.
- *
- * Since: 3.10
- */
-void
-gtk_source_buffer_set_case_sensitive_search (GtkSourceBuffer *buffer,
-                                            gboolean         case_sensitive)
-{
-       gboolean cur_val;
-
-       g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
-
-       case_sensitive = case_sensitive != FALSE;
-
-       cur_val = gtk_source_search_context_get_case_sensitive (buffer->priv->search);
-
-       if (cur_val != case_sensitive)
-       {
-               gtk_source_search_context_set_case_sensitive (buffer->priv->search,
-                                                             case_sensitive);
-
-               g_object_notify (G_OBJECT (buffer), "case-sensitive-search");
-       }
-}
-
-/**
- * gtk_source_buffer_get_case_sensitive_search:
- * @buffer: a #GtkSourceBuffer.
- *
- * Returns: whether the search is case sensitive.
- * Since: 3.10
- */
-gboolean
-gtk_source_buffer_get_case_sensitive_search (GtkSourceBuffer *buffer)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), FALSE);
-
-       return gtk_source_search_context_get_case_sensitive (buffer->priv->search);
-}
-
-/**
- * gtk_source_buffer_set_search_at_word_boundaries:
- * @buffer: a #GtkSourceBuffer.
- * @at_word_boundaries: the setting.
- *
- * Change whether the search is done at word boundaries. If @at_word_boundaries
- * is %TRUE, a search match must start and end a word. The match can span
- * multiple words. See also gtk_text_iter_starts_word() and
- * gtk_text_iter_ends_word().
- *
- * Since: 3.10
- */
-void
-gtk_source_buffer_set_search_at_word_boundaries (GtkSourceBuffer *buffer,
-                                                gboolean         at_word_boundaries)
-{
-       gboolean cur_val;
-
-       g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
-
-       at_word_boundaries = at_word_boundaries != FALSE;
-
-       cur_val = gtk_source_search_context_get_at_word_boundaries (buffer->priv->search);
-
-       if (cur_val != at_word_boundaries)
-       {
-               gtk_source_search_context_set_at_word_boundaries (buffer->priv->search,
-                                                                 at_word_boundaries);
-
-               g_object_notify (G_OBJECT (buffer), "search-at-word-boundaries");
-       }
-}
-
-/**
- * gtk_source_buffer_get_search_at_word_boundaries:
- * @buffer: a #GtkSourceBuffer.
- *
- * Returns: whether to search at word boundaries.
- * Since: 3.10
- */
-gboolean
-gtk_source_buffer_get_search_at_word_boundaries (GtkSourceBuffer *buffer)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), FALSE);
-
-       return gtk_source_search_context_get_at_word_boundaries (buffer->priv->search);
-}
-
-/**
- * gtk_source_buffer_set_search_wrap_around:
- * @buffer: a #GtkSourceBuffer.
- * @wrap_around: the setting.
- *
- * Enables or disables the wrap around search. If @wrap_around is %TRUE, the
- * forward search continues at the beginning of the buffer if no search
- * occurrences are found. Similarly, the backward search continues to search at
- * the end of the buffer.
- *
- * Since: 3.10
- */
-void
-gtk_source_buffer_set_search_wrap_around (GtkSourceBuffer *buffer,
-                                         gboolean         wrap_around)
-{
-       gboolean cur_val;
-
-       g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
-
-       wrap_around = wrap_around != FALSE;
-
-       cur_val = gtk_source_search_context_get_wrap_around (buffer->priv->search);
-
-       if (cur_val != wrap_around)
-       {
-               gtk_source_search_context_set_wrap_around (buffer->priv->search,
-                                                          wrap_around);
-
-               g_object_notify (G_OBJECT (buffer), "search-wrap-around");
-       }
-}
-
-/**
- * gtk_source_buffer_get_search_wrap_around:
- * @buffer: a #GtkSourceBuffer.
- *
- * Returns: whether to wrap around the search.
- * Since: 3.10
- */
-gboolean
-gtk_source_buffer_get_search_wrap_around (GtkSourceBuffer *buffer)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), FALSE);
-
-       return gtk_source_search_context_get_wrap_around (buffer->priv->search);
-}
-
-/**
- * gtk_source_buffer_set_regex_search:
- * @buffer: a #GtkSourceBuffer.
- * @regex: the setting.
- *
- * Enables or disables whether to search by regular expressions.
- * If enabled, the #GtkSourceBuffer:search-text property contains the pattern of
- * the regular expression.
- *
- * See also gtk_source_buffer_get_regex_search_error().
- *
- * Since: 3.10
- */
-void
-gtk_source_buffer_set_regex_search (GtkSourceBuffer *buffer,
-                                   gboolean         regex)
-{
-       gboolean cur_val;
-
-       g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
-
-       regex = regex != FALSE;
-
-       cur_val = gtk_source_search_context_get_regex_enabled (buffer->priv->search);
-
-       if (cur_val != regex)
-       {
-               gtk_source_search_context_set_regex_enabled (buffer->priv->search, regex);
-
-               g_object_notify (G_OBJECT (buffer), "regex-search");
-       }
-}
-
-/**
- * gtk_source_buffer_get_regex_search:
- * @buffer: a #GtkSourceBuffer.
- *
- * Returns: whether to search by regular expressions.
- * Since: 3.10
- */
-gboolean
-gtk_source_buffer_get_regex_search (GtkSourceBuffer *buffer)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), FALSE);
-
-       return gtk_source_search_context_get_regex_enabled (buffer->priv->search);
-}
-
-/**
- * gtk_source_buffer_get_regex_search_error:
- * @buffer: a #GtkSourceBuffer.
- *
- * Regular expression patterns must follow certain rules. If
- * #GtkSourceBuffer:search-text breaks a rule, the error can be retrieved with
- * this function. The error domain is #G_REGEX_ERROR.
- *
- * Free the return value with g_error_free().
- *
- * Returns: the #GError, or %NULL if the pattern is valid.
- * Since: 3.10
- */
-GError *
-gtk_source_buffer_get_regex_search_error (GtkSourceBuffer *buffer)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), NULL);
-
-       return gtk_source_search_context_get_regex_error (buffer->priv->search);
-}
-
-/**
- * gtk_source_buffer_set_highlight_search:
- * @buffer: a #GtkSourceBuffer.
- * @highlight: the setting.
- *
- * Enables or disables search highlighting. If you disable the search
- * highlighting, you can still use the other search and replace functions.
- *
- * Since: 3.10
- */
-void
-gtk_source_buffer_set_highlight_search (GtkSourceBuffer *buffer,
-                                       gboolean         highlight)
-{
-       gboolean cur_val;
-
-       g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
-
-       highlight = highlight != FALSE;
-
-       cur_val = gtk_source_search_context_get_highlight (buffer->priv->search);
-
-       if (cur_val != highlight)
-       {
-               gtk_source_search_context_set_highlight (buffer->priv->search, highlight);
-
-               g_object_notify (G_OBJECT (buffer), "highlight-search");
-       }
-}
-
-/**
- * gtk_source_buffer_get_highlight_search:
- * @buffer: a #GtkSourceBuffer.
- *
- * Returns: whether to highlight search occurrences.
- * Since: 3.10
- */
-gboolean
-gtk_source_buffer_get_highlight_search (GtkSourceBuffer *buffer)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), FALSE);
-
-       return gtk_source_search_context_get_highlight (buffer->priv->search);
-}
-
-/**
- * gtk_source_buffer_get_search_occurrences_count:
- * @buffer: a #GtkSourceBuffer.
- *
- * Gets the total number of search occurrences. If the buffer is not already
- * fully scanned, the total number of occurrences is unknown, and -1 is
- * returned.
- *
- * Returns: the total number of search occurrences, or -1 if unknown.
- * Since: 3.10
- */
-gint
-gtk_source_buffer_get_search_occurrences_count (GtkSourceBuffer *buffer)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), 0);
-
-       return gtk_source_search_context_get_occurrences_count (buffer->priv->search);
-}
-
-/**
- * gtk_source_buffer_get_search_occurrence_position:
- * @buffer: a #GtkSourceBuffer.
- * @match_start: the start of the occurrence.
- * @match_end: the end of the occurrence.
- *
- * Gets the position of a search occurrence. If the buffer is not already fully
- * scanned, the position may be unknown, and -1 is returned. Therefore you
- * should call this function when you know that the buffer is fully scanned.
- *
- * Returns: the position of the search occurrence. The first occurrence has the
- * position 1 (not 0). Returns 0 if @match_start and @match_end doesn't delimit
- * an occurrence. Returns -1 if the position is not yet known.
- *
- * Since: 3.10
- */
-gint
-gtk_source_buffer_get_search_occurrence_position (GtkSourceBuffer   *buffer,
-                                                 const GtkTextIter *match_start,
-                                                 const GtkTextIter *match_end)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), -1);
-       g_return_val_if_fail (match_start != NULL, -1);
-       g_return_val_if_fail (match_end != NULL, -1);
-
-       return gtk_source_search_context_get_occurrence_position (buffer->priv->search,
-                                                                 match_start,
-                                                                 match_end);
-}
-
-/**
- * gtk_source_buffer_forward_search:
- * @buffer: a #GtkSourceBuffer.
- * @iter: start of search.
- * @match_start: (out) (allow-none): return location for start of match, or %NULL.
- * @match_end: (out) (allow-none): return location for end of match, or %NULL.
- *
- * Synchronous forward search. It is recommended to use the asynchronous
- * functions instead, to not block the user interface. However, if you are sure
- * that the @buffer is small, this function is more convenient to use.
- *
- * Returns: whether a match was found.
- * Since: 3.10
- */
-gboolean
-gtk_source_buffer_forward_search (GtkSourceBuffer   *buffer,
-                                 const GtkTextIter *iter,
-                                 GtkTextIter       *match_start,
-                                 GtkTextIter       *match_end)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), FALSE);
-       g_return_val_if_fail (iter != NULL, FALSE);
-
-       return gtk_source_search_context_forward (buffer->priv->search,
-                                                 iter,
-                                                 match_start,
-                                                 match_end);
-}
-
-/**
- * gtk_source_buffer_forward_search_async:
- * @buffer: a #GtkSourceBuffer.
- * @iter: start of search.
- * @cancellable: (allow-none): a #GCancellable, or %NULL.
- * @callback: a #GAsyncReadyCallback to call when the operation is finished.
- * @user_data: the data to pass to the @callback function.
- *
- * Asynchronous forward search. See the #GAsyncResult documentation to know
- * how to use this function.
- *
- * If the operation is cancelled, the @callback will only be called if
- * @cancellable was not %NULL. gtk_source_buffer_forward_search_async() takes
- * ownership of @cancellable, so you can unref it after calling this function.
- *
- * Since: 3.10
- */
-void
-gtk_source_buffer_forward_search_async (GtkSourceBuffer     *buffer,
-                                       const GtkTextIter   *iter,
-                                       GCancellable        *cancellable,
-                                       GAsyncReadyCallback  callback,
-                                       gpointer             user_data)
-{
-       g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
-       g_return_if_fail (iter != NULL);
-
-       gtk_source_search_context_forward_async (buffer->priv->search,
-                                                iter,
-                                                cancellable,
-                                                callback,
-                                                user_data);
-}
-
-/**
- * gtk_source_buffer_forward_search_finish:
- * @buffer: a #GtkSourceBuffer.
- * @result: a #GAsyncResult.
- * @match_start: (out) (allow-none): return location for start of match, or %NULL.
- * @match_end: (out) (allow-none): return location for end of match, or %NULL.
- * @error: a #GError, or %NULL.
- *
- * Finishes a forward search started with
- * gtk_source_buffer_forward_search_async().
- *
- * Returns: whether a match was found.
- * Since: 3.10
- */
-gboolean
-gtk_source_buffer_forward_search_finish (GtkSourceBuffer  *buffer,
-                                        GAsyncResult     *result,
-                                        GtkTextIter      *match_start,
-                                        GtkTextIter      *match_end,
-                                        GError          **error)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), FALSE);
-
-       return gtk_source_search_context_forward_finish (buffer->priv->search,
-                                                        result,
-                                                        match_start,
-                                                        match_end,
-                                                        error);
-}
-
-/**
- * gtk_source_buffer_backward_search:
- * @buffer: a #GtkSourceBuffer.
- * @iter: start of search.
- * @match_start: (out) (allow-none): return location for start of match, or %NULL.
- * @match_end: (out) (allow-none): return location for end of match, or %NULL.
- *
- * Synchronous backward search. It is recommended to use the asynchronous
- * functions instead, to not block the user interface. However, if you are sure
- * that the @buffer is small, this function is more convenient to use.
- *
- * Returns: whether a match was found.
- * Since: 3.10
- */
-gboolean
-gtk_source_buffer_backward_search (GtkSourceBuffer   *buffer,
-                                  const GtkTextIter *iter,
-                                  GtkTextIter       *match_start,
-                                  GtkTextIter       *match_end)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), FALSE);
-       g_return_val_if_fail (iter != NULL, FALSE);
-
-       return gtk_source_search_context_backward (buffer->priv->search,
-                                                  iter,
-                                                  match_start,
-                                                  match_end);
-}
-
-/**
- * gtk_source_buffer_backward_search_async:
- * @buffer: a #GtkSourceBuffer.
- * @iter: start of search.
- * @cancellable: (allow-none): a #GCancellable, or %NULL.
- * @callback: a #GAsyncReadyCallback to call when the operation is finished.
- * @user_data: the data to pass to the @callback function.
- *
- * Asynchronous backward search. See the #GAsyncResult documentation to know
- * how to use this function.
- *
- * If the operation is cancelled, the @callback will only be called if
- * @cancellable was not %NULL. gtk_source_buffer_backward_search_async() takes
- * ownership of @cancellable, so you can unref it after calling this function.
- *
- * Since: 3.10
- */
-void
-gtk_source_buffer_backward_search_async (GtkSourceBuffer     *buffer,
-                                        const GtkTextIter   *iter,
-                                        GCancellable        *cancellable,
-                                        GAsyncReadyCallback  callback,
-                                        gpointer             user_data)
-{
-       g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
-       g_return_if_fail (iter != NULL);
-
-       gtk_source_search_context_backward_async (buffer->priv->search,
-                                                 iter,
-                                                 cancellable,
-                                                 callback,
-                                                 user_data);
-}
-
-/**
- * gtk_source_buffer_backward_search_finish:
- * @buffer: a #GtkSourceBuffer.
- * @result: a #GAsyncResult.
- * @match_start: (out) (allow-none): return location for start of match, or %NULL.
- * @match_end: (out) (allow-none): return location for end of match, or %NULL.
- * @error: a #GError, or %NULL.
- *
- * Finishes a backward search started with
- * gtk_source_buffer_backward_search_async().
- *
- * Returns: whether a match was found.
- * Since: 3.10
- */
-gboolean
-gtk_source_buffer_backward_search_finish (GtkSourceBuffer  *buffer,
-                                         GAsyncResult     *result,
-                                         GtkTextIter      *match_start,
-                                         GtkTextIter      *match_end,
-                                         GError          **error)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), FALSE);
-
-       return gtk_source_search_context_backward_finish (buffer->priv->search,
-                                                         result,
-                                                         match_start,
-                                                         match_end,
-                                                         error);
-}
-
-/**
- * gtk_source_buffer_search_replace:
- * @buffer: a #GtkSourceBuffer.
- * @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.
- *
- * Replaces a search match by another text. If @match_start and @match_end
- * doesn't correspond to a search match, %FALSE is returned.
- *
- * 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.10
- */
-gboolean
-gtk_source_buffer_search_replace (GtkSourceBuffer   *buffer,
-                                 const GtkTextIter *match_start,
-                                 const GtkTextIter *match_end,
-                                 const gchar       *replace,
-                                 gint               replace_length)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), 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);
-
-       return gtk_source_search_context_replace (buffer->priv->search,
-                                                 match_start,
-                                                 match_end,
-                                                 replace,
-                                                 replace_length);
-}
-
-/**
- * gtk_source_buffer_search_replace_all:
- * @buffer: a #GtkSourceBuffer.
- * @replace: the replacement text.
- * @replace_length: the length of @replace in bytes, or -1.
- *
- * Replaces all search matches by another text. It is a synchronous function, so
- * it can block the user interface.
- *
- * 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: the number of replaced matches.
- * Since: 3.10
- */
-guint
-gtk_source_buffer_search_replace_all (GtkSourceBuffer *buffer,
-                                     const gchar     *replace,
-                                     gint             replace_length)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), 0);
-       g_return_val_if_fail (replace != NULL, 0);
-
-       return gtk_source_search_context_replace_all (buffer->priv->search,
-                                                     replace,
-                                                     replace_length);
-}
diff --git a/gtksourceview/gtksourcebuffer.h b/gtksourceview/gtksourcebuffer.h
index e6cf6ec..8fa90d7 100644
--- a/gtksourceview/gtksourcebuffer.h
+++ b/gtksourceview/gtksourcebuffer.h
@@ -180,88 +180,6 @@ GtkSourceUndoManager       *gtk_source_buffer_get_undo_manager                     
(GtkSourceBuffer        *buf
 void                    gtk_source_buffer_set_undo_manager                     (GtkSourceBuffer        
*buffer,
                                                                                 GtkSourceUndoManager   
*manager);
 
-void                    gtk_source_buffer_set_search_text                      (GtkSourceBuffer        
*buffer,
-                                                                                const gchar            
*text);
-
-const gchar            *gtk_source_buffer_get_search_text                      (GtkSourceBuffer        
*buffer);
-
-void                    gtk_source_buffer_set_case_sensitive_search            (GtkSourceBuffer        
*buffer,
-                                                                                gboolean                
case_sensitive);
-
-gboolean                gtk_source_buffer_get_case_sensitive_search            (GtkSourceBuffer        
*buffer);
-
-void                    gtk_source_buffer_set_search_at_word_boundaries        (GtkSourceBuffer        
*buffer,
-                                                                                gboolean                
at_word_boundaries);
-
-gboolean                gtk_source_buffer_get_search_at_word_boundaries        (GtkSourceBuffer        
*buffer);
-
-void                    gtk_source_buffer_set_search_wrap_around               (GtkSourceBuffer        
*buffer,
-                                                                                gboolean                
wrap_around);
-
-gboolean                gtk_source_buffer_get_search_wrap_around               (GtkSourceBuffer        
*buffer);
-
-void                    gtk_source_buffer_set_regex_search                     (GtkSourceBuffer        
*buffer,
-                                                                                gboolean                
regex);
-
-gboolean                gtk_source_buffer_get_regex_search                     (GtkSourceBuffer        
*buffer);
-
-GError                 *gtk_source_buffer_get_regex_search_error               (GtkSourceBuffer        
*buffer);
-
-void                    gtk_source_buffer_set_highlight_search                 (GtkSourceBuffer        
*buffer,
-                                                                                gboolean                
highlight);
-
-gboolean                gtk_source_buffer_get_highlight_search                 (GtkSourceBuffer        
*buffer);
-
-gint                    gtk_source_buffer_get_search_occurrences_count         (GtkSourceBuffer        
*buffer);
-
-gint                    gtk_source_buffer_get_search_occurrence_position       (GtkSourceBuffer        
*buffer,
-                                                                                const GtkTextIter      
*match_start,
-                                                                                const GtkTextIter      
*match_end);
-
-gboolean                gtk_source_buffer_forward_search                       (GtkSourceBuffer        
*buffer,
-                                                                                const GtkTextIter      *iter,
-                                                                                GtkTextIter            
*match_start,
-                                                                                GtkTextIter            
*match_end);
-
-void                    gtk_source_buffer_forward_search_async                 (GtkSourceBuffer        
*buffer,
-                                                                                const GtkTextIter      *iter,
-                                                                                GCancellable           
*cancellable,
-                                                                                GAsyncReadyCallback     
callback,
-                                                                                gpointer                
user_data);
-
-gboolean                gtk_source_buffer_forward_search_finish                (GtkSourceBuffer        
*buffer,
-                                                                                GAsyncResult           
*result,
-                                                                                GtkTextIter            
*match_start,
-                                                                                GtkTextIter            
*match_end,
-                                                                                GError                
**error);
-
-gboolean                gtk_source_buffer_backward_search                      (GtkSourceBuffer        
*buffer,
-                                                                                const GtkTextIter      *iter,
-                                                                                GtkTextIter            
*match_start,
-                                                                                GtkTextIter            
*match_end);
-
-void                    gtk_source_buffer_backward_search_async                (GtkSourceBuffer        
*buffer,
-                                                                                const GtkTextIter      *iter,
-                                                                                GCancellable           
*cancellable,
-                                                                                GAsyncReadyCallback     
callback,
-                                                                                gpointer                
user_data);
-
-gboolean                gtk_source_buffer_backward_search_finish               (GtkSourceBuffer        
*buffer,
-                                                                                GAsyncResult           
*result,
-                                                                                GtkTextIter            
*match_start,
-                                                                                GtkTextIter            
*match_end,
-                                                                                GError                
**error);
-
-gboolean                gtk_source_buffer_search_replace                       (GtkSourceBuffer        
*buffer,
-                                                                                const GtkTextIter      
*match_start,
-                                                                                const GtkTextIter      
*match_end,
-                                                                                const gchar            
*replace,
-                                                                                gint                    
replace_length);
-
-guint                   gtk_source_buffer_search_replace_all                   (GtkSourceBuffer        
*buffer,
-                                                                                const gchar            
*replace,
-                                                                                gint                    
replace_length);
-
 /* private */
 
 G_GNUC_INTERNAL
diff --git a/gtksourceview/gtksourcesearchcontext.c b/gtksourceview/gtksourcesearchcontext.c
index 2544399..8e05cbf 100644
--- a/gtksourceview/gtksourcesearchcontext.c
+++ b/gtksourceview/gtksourcesearchcontext.c
@@ -20,11 +20,13 @@
  */
 
 #include "gtksourcesearchcontext.h"
+#include "gtksourcesearchsettings.h"
 #include "gtksourcebuffer.h"
 #include "gtksourcestylescheme.h"
 #include "gtksourcestyle-private.h"
 #include "gtksourceutils.h"
 #include "gtktextregion.h"
+#include "gtksourceview-i18n.h"
 
 #include <string.h>
 
@@ -183,9 +185,24 @@
  */
 #define SCAN_BATCH_SIZE 100
 
+enum
+{
+       PROP_0,
+       PROP_BUFFER,
+       PROP_SETTINGS,
+       PROP_OCCURRENCES_COUNT,
+       PROP_REGEX_ERROR
+};
+
 struct _GtkSourceSearchContextPrivate
 {
        GtkTextBuffer *buffer;
+       GtkSourceSearchSettings *settings;
+
+       /* The tag to apply to search occurrences. Even if the highlighting is
+        * disabled, the tag is applied.
+        */
+       GtkTextTag *found_tag;
 
        /* The region to scan and highlight. If NULL, the scan is finished. */
        GtkTextRegion *scan_region;
@@ -201,22 +218,16 @@ struct _GtkSourceSearchContextPrivate
        GTask *task;
        GtkTextRegion *task_region;
 
-       gulong idle_scan_id;
-
-       gint occurrences_count;
-
-       GtkTextTag *found_tag;
-
-       /* State of the search. If text is NULL, the search is disabled. */
-       gchar *text;
+       /* If the regex search is disabled, text_nb_lines is the number of lines
+        * of the search text. It is useful to adjust the region to scan.
+        */
        gint text_nb_lines;
+
        GRegex *regex;
        GError *regex_error;
-       GtkTextSearchFlags flags;
-       guint at_word_boundaries : 1;
-       guint wrap_around : 1;
-       guint regex_enabled : 1;
-       guint highlight : 1;
+
+       gint occurrences_count;
+       gulong idle_scan_id;
 };
 
 /* Data for the asynchronous forward and backward search tasks. */
@@ -242,6 +253,17 @@ dispose_has_run (GtkSourceSearchContext *search)
        return search->priv->buffer == NULL;
 }
 
+static GtkSourceSearchSettings *
+get_settings (GtkSourceSearchContext *search)
+{
+       if (search->priv->settings == NULL)
+       {
+               search->priv->settings = gtk_source_search_settings_new ();
+       }
+
+       return search->priv->settings;
+}
+
 static void
 sync_found_tag (GtkSourceSearchContext *search)
 {
@@ -253,11 +275,13 @@ sync_found_tag (GtkSourceSearchContext *search)
                return;
        }
 
+       /*
        if (!search->priv->highlight)
        {
                _gtk_source_style_apply (NULL, search->priv->found_tag);
                return;
        }
+       */
 
        style_scheme = gtk_source_buffer_get_style_scheme (GTK_SOURCE_BUFFER (search->priv->buffer));
 
@@ -462,6 +486,20 @@ clear_search (GtkSourceSearchContext *search)
        search->priv->occurrences_count = 0;
 }
 
+static GtkTextSearchFlags
+get_text_search_flags (GtkSourceSearchContext *search)
+{
+       GtkSourceSearchSettings *settings = get_settings (search);
+       GtkTextSearchFlags flags = GTK_TEXT_SEARCH_TEXT_ONLY | GTK_TEXT_SEARCH_VISIBLE_ONLY;
+
+       if (!gtk_source_search_settings_get_case_sensitive (settings))
+       {
+               flags |= GTK_TEXT_SEARCH_CASE_INSENSITIVE;
+       }
+
+       return flags;
+}
+
 static void
 regex_search_get_real_start (GtkSourceSearchContext *search,
                             const GtkTextIter      *start,
@@ -638,13 +676,16 @@ basic_forward_search (GtkSourceSearchContext *search,
                      const GtkTextIter      *limit)
 {
        GtkTextIter begin_search = *iter;
+       GtkSourceSearchSettings *settings = get_settings (search);
+       const gchar *search_text = gtk_source_search_settings_get_search_text (settings);
+       GtkTextSearchFlags flags;
 
-       if (search->priv->text == NULL)
+       if (search_text == NULL)
        {
                return FALSE;
        }
 
-       if (search->priv->regex_enabled)
+       if (gtk_source_search_settings_get_regex_enabled (settings))
        {
                return basic_forward_regex_search (search,
                                                   iter,
@@ -653,16 +694,18 @@ basic_forward_search (GtkSourceSearchContext *search,
                                                   limit);
        }
 
+       flags = get_text_search_flags (search);
+
        while (TRUE)
        {
                gboolean found = gtk_text_iter_forward_search (&begin_search,
-                                                              search->priv->text,
-                                                              search->priv->flags,
+                                                              search_text,
+                                                              flags,
                                                               match_start,
                                                               match_end,
                                                               limit);
 
-               if (!found || !search->priv->at_word_boundaries)
+               if (!found || !gtk_source_search_settings_get_at_word_boundaries (settings))
                {
                        return found;
                }
@@ -773,13 +816,16 @@ basic_backward_search (GtkSourceSearchContext *search,
                       const GtkTextIter      *limit)
 {
        GtkTextIter begin_search = *iter;
+       GtkSourceSearchSettings *settings = get_settings (search);
+       const gchar *search_text = gtk_source_search_settings_get_search_text (settings);
+       GtkTextSearchFlags flags;
 
-       if (search->priv->text == NULL)
+       if (search_text == NULL)
        {
                return FALSE;
        }
 
-       if (search->priv->regex_enabled)
+       if (gtk_source_search_settings_get_regex_enabled (settings))
        {
                return basic_backward_regex_search (search,
                                                    iter,
@@ -788,16 +834,18 @@ basic_backward_search (GtkSourceSearchContext *search,
                                                    limit);
        }
 
+       flags = get_text_search_flags (search);
+
        while (TRUE)
        {
                gboolean found = gtk_text_iter_backward_search (&begin_search,
-                                                               search->priv->text,
-                                                               search->priv->flags,
+                                                               search_text,
+                                                               flags,
                                                                match_start,
                                                                match_end,
                                                                limit);
 
-               if (!found || !search->priv->at_word_boundaries)
+               if (!found || !gtk_source_search_settings_get_at_word_boundaries (settings))
                {
                        return found;
                }
@@ -835,12 +883,14 @@ smart_forward_search_async_step (GtkSourceSearchContext *search,
        GtkTextIter region_start = *start_at;
        GtkTextRegion *region = NULL;
        ForwardBackwardData *task_data;
+       GtkSourceSearchSettings *settings = get_settings (search);
+       const gchar *search_text = gtk_source_search_settings_get_search_text (settings);
 
        if (gtk_text_iter_is_end (start_at))
        {
-               if (search->priv->text != NULL &&
+               if (search_text != NULL &&
                    !*wrapped_around &&
-                   search->priv->wrap_around)
+                   gtk_source_search_settings_get_wrap_around (settings))
                {
                        gtk_text_buffer_get_start_iter (search->priv->buffer, start_at);
                        *wrapped_around = TRUE;
@@ -973,12 +1023,14 @@ smart_backward_search_async_step (GtkSourceSearchContext *search,
        GtkTextIter region_end = *start_at;
        GtkTextRegion *region = NULL;
        ForwardBackwardData *task_data;
+       GtkSourceSearchSettings *settings = get_settings (search);
+       const gchar *search_text = gtk_source_search_settings_get_search_text (settings);
 
        if (gtk_text_iter_is_start (start_at))
        {
-               if (search->priv->text != NULL &&
+               if (search_text != NULL &&
                    !*wrapped_around &&
-                   search->priv->wrap_around)
+                   gtk_source_search_settings_get_wrap_around (settings))
                {
                        gtk_text_buffer_get_end_iter (search->priv->buffer, start_at);
                        *wrapped_around = TRUE;
@@ -1254,6 +1306,8 @@ smart_forward_search_without_scanning (GtkSourceSearchContext *search,
                                       const GtkTextIter      *stop_at)
 {
        GtkTextIter iter;
+       GtkSourceSearchSettings *settings = get_settings (search);
+       const gchar *search_text = gtk_source_search_settings_get_search_text (settings);
 
        g_assert (start_at != NULL);
        g_assert (match_start != NULL);
@@ -1262,7 +1316,7 @@ smart_forward_search_without_scanning (GtkSourceSearchContext *search,
 
        iter = *start_at;
 
-       if (search->priv->text == NULL)
+       if (search_text == NULL)
        {
                return FALSE;
        }
@@ -1382,6 +1436,8 @@ scan_subregion (GtkSourceSearchContext *search,
        GtkTextIter iter;
        GtkTextIter *limit;
        gboolean found = TRUE;
+       GtkSourceSearchSettings *settings = get_settings (search);
+       const gchar *search_text = gtk_source_search_settings_get_search_text (settings);
 
        if (search->priv->found_tag == NULL)
        {
@@ -1416,7 +1472,7 @@ scan_subregion (GtkSourceSearchContext *search,
                gtk_text_region_subtract (search->priv->task_region, start, end);
        }
 
-       if (search->priv->text == NULL)
+       if (search_text == NULL)
        {
                /* We have removed the found_tag, we are done. */
                return;
@@ -1626,7 +1682,7 @@ idle_scan_normal_search (GtkSourceSearchContext *search)
        {
                search->priv->idle_scan_id = 0;
 
-               g_object_notify (G_OBJECT (search->priv->buffer), "search-occurrences-count");
+               g_object_notify (G_OBJECT (search), "occurrences-count");
 
                if (search->priv->scan_region != NULL)
                {
@@ -1926,7 +1982,7 @@ idle_scan_regex_search (GtkSourceSearchContext *search)
        {
                search->priv->idle_scan_id = 0;
 
-               g_object_notify (G_OBJECT (search->priv->buffer), "search-occurrences-count");
+               g_object_notify (G_OBJECT (search), "occurrences-count");
 
                if (search->priv->scan_region != NULL)
                {
@@ -1943,7 +1999,9 @@ idle_scan_regex_search (GtkSourceSearchContext *search)
 static gboolean
 idle_scan_cb (GtkSourceSearchContext *search)
 {
-       return search->priv->regex_enabled ?
+       GtkSourceSearchSettings *settings = get_settings (search);
+
+       return gtk_source_search_settings_get_regex_enabled (settings) ?
               idle_scan_regex_search (search) :
               idle_scan_normal_search (search);
 }
@@ -2021,8 +2079,13 @@ smart_forward_search (GtkSourceSearchContext *search,
                      GtkTextIter            *match_end)
 {
        GtkTextIter iter = *start_at;
+       GtkSourceSearchSettings *settings = get_settings (search);
+       const gchar *search_text = gtk_source_search_settings_get_search_text (settings);
+
+       g_return_val_if_fail (match_start != NULL, FALSE);
+       g_return_val_if_fail (match_end != NULL, FALSE);
 
-       if (search->priv->text == NULL)
+       if (search_text == NULL)
        {
                return FALSE;
        }
@@ -2109,8 +2172,13 @@ smart_backward_search (GtkSourceSearchContext *search,
                       GtkTextIter            *match_end)
 {
        GtkTextIter iter = *start_at;
+       GtkSourceSearchSettings *settings = get_settings (search);
+       const gchar *search_text = gtk_source_search_settings_get_search_text (settings);
 
-       if (search->priv->text == NULL)
+       g_return_val_if_fail (match_start != NULL, FALSE);
+       g_return_val_if_fail (match_end != NULL, FALSE);
+
+       if (search_text == NULL)
        {
                return FALSE;
        }
@@ -2171,6 +2239,8 @@ static void
 update_regex (GtkSourceSearchContext *search)
 {
        gboolean regex_error_changed = FALSE;
+       GtkSourceSearchSettings *settings = get_settings (search);
+       const gchar *search_text = gtk_source_search_settings_get_search_text (settings);
 
        if (search->priv->regex != NULL)
        {
@@ -2185,21 +2255,22 @@ update_regex (GtkSourceSearchContext *search)
                regex_error_changed = TRUE;
        }
 
-       if (search->priv->regex_enabled && search->priv->text != NULL)
+       if (search_text != NULL &&
+           gtk_source_search_settings_get_regex_enabled (settings))
        {
                GRegexCompileFlags compile_flags = G_REGEX_OPTIMIZE | G_REGEX_MULTILINE;
-               gchar *pattern = search->priv->text;
+               gchar *pattern = (gchar *)search_text;
 
                search->priv->text_nb_lines = 0;
 
-               if (search->priv->flags & GTK_TEXT_SEARCH_CASE_INSENSITIVE)
+               if (!gtk_source_search_settings_get_case_sensitive (settings))
                {
                        compile_flags |= G_REGEX_CASELESS;
                }
 
-               if (search->priv->at_word_boundaries)
+               if (gtk_source_search_settings_get_at_word_boundaries (settings))
                {
-                       pattern = g_strdup_printf ("\\b%s\\b", search->priv->text);
+                       pattern = g_strdup_printf ("\\b%s\\b", search_text);
                }
 
                search->priv->regex = g_regex_new (pattern,
@@ -2212,7 +2283,7 @@ update_regex (GtkSourceSearchContext *search)
                        regex_error_changed = TRUE;
                }
 
-               if (search->priv->at_word_boundaries)
+               if (gtk_source_search_settings_get_at_word_boundaries (settings))
                {
                        g_free (pattern);
                }
@@ -2220,7 +2291,7 @@ update_regex (GtkSourceSearchContext *search)
 
        if (regex_error_changed)
        {
-               g_object_notify (G_OBJECT (search->priv->buffer), "regex-search-error");
+               g_object_notify (G_OBJECT (search), "regex-error");
        }
 }
 
@@ -2249,10 +2320,13 @@ insert_text_before_cb (GtkSourceSearchContext *search,
                       gchar                  *text,
                       gint                    length)
 {
+       GtkSourceSearchSettings *settings = get_settings (search);
+       const gchar *search_text = gtk_source_search_settings_get_search_text (settings);
+
        clear_task (search);
 
-       if (!search->priv->regex_enabled &&
-           search->priv->text != NULL)
+       if (search_text != NULL &&
+           !gtk_source_search_settings_get_regex_enabled (settings))
        {
                GtkTextIter start = *location;
                GtkTextIter end = *location;
@@ -2268,7 +2342,9 @@ insert_text_after_cb (GtkSourceSearchContext *search,
                      gchar                  *text,
                      gint                    length)
 {
-       if (search->priv->regex_enabled)
+       GtkSourceSearchSettings *settings = get_settings (search);
+
+       if (gtk_source_search_settings_get_regex_enabled (settings))
        {
                update (search);
        }
@@ -2293,10 +2369,12 @@ delete_range_before_cb (GtkSourceSearchContext *search,
 {
        GtkTextIter start_buffer;
        GtkTextIter end_buffer;
+       GtkSourceSearchSettings *settings = get_settings (search);
+       const gchar *search_text = gtk_source_search_settings_get_search_text (settings);
 
        clear_task (search);
 
-       if (search->priv->regex_enabled)
+       if (gtk_source_search_settings_get_regex_enabled (settings))
        {
                return;
        }
@@ -2311,7 +2389,7 @@ delete_range_before_cb (GtkSourceSearchContext *search,
                return;
        }
 
-       if (search->priv->text != NULL)
+       if (search_text != NULL)
        {
                GtkTextIter start = *delete_start;
                GtkTextIter end = *delete_end;
@@ -2329,7 +2407,9 @@ delete_range_after_cb (GtkSourceSearchContext *search,
                       GtkTextIter            *start,
                       GtkTextIter            *end)
 {
-       if (search->priv->regex_enabled)
+       GtkSourceSearchSettings *settings = get_settings (search);
+
+       if (gtk_source_search_settings_get_regex_enabled (settings))
        {
                update (search);
        }
@@ -2346,6 +2426,7 @@ set_buffer (GtkSourceSearchContext *search,
        g_assert (search->priv->buffer == NULL);
 
        search->priv->buffer = GTK_TEXT_BUFFER (buffer);
+       g_object_ref (search->priv->buffer);
 
        g_signal_connect_object (buffer,
                                 "insert-text",
@@ -2372,66 +2453,6 @@ set_buffer (GtkSourceSearchContext *search,
                                 G_CONNECT_AFTER | G_CONNECT_SWAPPED);
 }
 
-static void
-gtk_source_search_context_dispose (GObject *object)
-{
-       GtkSourceSearchContext *search = GTK_SOURCE_SEARCH_CONTEXT (object);
-
-       clear_search (search);
-
-       search->priv->buffer = NULL;
-
-       G_OBJECT_CLASS (gtk_source_search_context_parent_class)->dispose (object);
-}
-
-static void
-gtk_source_search_context_finalize (GObject *object)
-{
-       GtkSourceSearchContext *search = GTK_SOURCE_SEARCH_CONTEXT (object);
-
-       g_free (search->priv->text);
-
-       if (search->priv->regex != NULL)
-       {
-               g_regex_unref (search->priv->regex);
-       }
-
-       if (search->priv->regex_error != NULL)
-       {
-               g_error_free (search->priv->regex_error);
-       }
-
-       G_OBJECT_CLASS (gtk_source_search_context_parent_class)->finalize (object);
-}
-
-static void
-gtk_source_search_context_class_init (GtkSourceSearchContextClass *klass)
-{
-       GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-       object_class->dispose = gtk_source_search_context_dispose;
-       object_class->finalize = gtk_source_search_context_finalize;
-}
-
-static void
-gtk_source_search_context_init (GtkSourceSearchContext *search)
-{
-       search->priv = gtk_source_search_context_get_instance_private (search);
-}
-
-GtkSourceSearchContext *
-gtk_source_search_context_new (GtkSourceBuffer *buffer)
-{
-       GtkSourceSearchContext *search;
-
-       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), NULL);
-
-       search = g_object_new (GTK_SOURCE_TYPE_SEARCH_CONTEXT, NULL);
-       set_buffer (search, buffer);
-
-       return search;
-}
-
 static gint
 compute_number_of_lines (const gchar *text)
 {
@@ -2468,130 +2489,295 @@ compute_number_of_lines (const gchar *text)
        return nb_of_lines;
 }
 
-void
-gtk_source_search_context_set_text (GtkSourceSearchContext *search,
-                                   const gchar            *text)
+static void
+search_text_updated (GtkSourceSearchContext *search)
 {
-       g_return_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search));
-       g_return_if_fail (text == NULL || g_utf8_validate (text, -1, NULL));
-
-       g_free (search->priv->text);
+       GtkSourceSearchSettings *settings = get_settings (search);
 
-       if (text == NULL || *text == '\0')
+       if (gtk_source_search_settings_get_regex_enabled (settings))
        {
-               search->priv->text = NULL;
+               search->priv->text_nb_lines = 0;
        }
        else
        {
-               search->priv->text = g_strdup (text);
+               const gchar *text = gtk_source_search_settings_get_search_text (settings);
+               search->priv->text_nb_lines = compute_number_of_lines (text);
        }
+}
 
-       if (search->priv->regex_enabled)
+static void
+settings_notify_cb (GtkSourceSearchContext  *search,
+                   GParamSpec              *pspec,
+                   GtkSourceSearchSettings *settings)
+{
+       const gchar *property = g_param_spec_get_name (pspec);
+
+       if (g_str_equal (property, "wrap-around"))
        {
-               search->priv->text_nb_lines = 0;
+               update (search);
+               return;
        }
-       else
+
+       if (g_str_equal (property, "search-text"))
        {
-               search->priv->text_nb_lines = compute_number_of_lines (search->priv->text);
+               search_text_updated (search);
        }
 
        update_regex (search);
        update (search);
 }
 
-const gchar *
-gtk_source_search_context_get_text (GtkSourceSearchContext *search)
+static void
+gtk_source_search_context_dispose (GObject *object)
 {
-       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search), NULL);
+       GtkSourceSearchContext *search = GTK_SOURCE_SEARCH_CONTEXT (object);
+
+       clear_search (search);
+
+       g_clear_object (&search->priv->buffer);
+       g_clear_object (&search->priv->settings);
 
-       return search->priv->text;
+       G_OBJECT_CLASS (gtk_source_search_context_parent_class)->dispose (object);
 }
 
-void
-gtk_source_search_context_set_case_sensitive (GtkSourceSearchContext *search,
-                                             gboolean                case_sensitive)
+static void
+gtk_source_search_context_finalize (GObject *object)
 {
-       g_return_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search));
+       GtkSourceSearchContext *search = GTK_SOURCE_SEARCH_CONTEXT (object);
 
-       if (case_sensitive)
+       if (search->priv->regex != NULL)
        {
-               search->priv->flags &= ~GTK_TEXT_SEARCH_CASE_INSENSITIVE;
+               g_regex_unref (search->priv->regex);
        }
-       else
+
+       if (search->priv->regex_error != NULL)
        {
-               search->priv->flags |= GTK_TEXT_SEARCH_CASE_INSENSITIVE;
+               g_error_free (search->priv->regex_error);
        }
 
-       update_regex (search);
-       update (search);
+       G_OBJECT_CLASS (gtk_source_search_context_parent_class)->finalize (object);
 }
 
-gboolean
-gtk_source_search_context_get_case_sensitive (GtkSourceSearchContext *search)
+static void
+gtk_source_search_context_get_property (GObject    *object,
+                                       guint       prop_id,
+                                       GValue     *value,
+                                       GParamSpec *pspec)
 {
-       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search), FALSE);
+       GtkSourceSearchContext *search;
 
-       return (search->priv->flags & GTK_TEXT_SEARCH_CASE_INSENSITIVE) == 0;
+       g_return_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (object));
+
+       search = GTK_SOURCE_SEARCH_CONTEXT (object);
+
+       switch (prop_id)
+       {
+               case PROP_BUFFER:
+                       g_value_set_object (value, search->priv->buffer);
+                       break;
+
+               case PROP_SETTINGS:
+                       g_value_set_object (value, get_settings (search));
+                       break;
+
+               case PROP_OCCURRENCES_COUNT:
+                       g_value_set_int (value, gtk_source_search_context_get_occurrences_count (search));
+                       break;
+
+               case PROP_REGEX_ERROR:
+                       g_value_set_pointer (value, gtk_source_search_context_get_regex_error (search));
+                       break;
+
+               default:
+                       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                       break;
+       }
 }
 
-void
-gtk_source_search_context_set_at_word_boundaries (GtkSourceSearchContext *search,
-                                                 gboolean                at_word_boundaries)
+static void
+gtk_source_search_context_set_property (GObject      *object,
+                                       guint         prop_id,
+                                       const GValue *value,
+                                       GParamSpec   *pspec)
 {
-       g_return_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search));
+       GtkSourceSearchContext *search;
 
-       search->priv->at_word_boundaries = at_word_boundaries;
+       g_return_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (object));
 
-       update_regex (search);
-       update (search);
+       search = GTK_SOURCE_SEARCH_CONTEXT (object);
+
+       switch (prop_id)
+       {
+               case PROP_BUFFER:
+                       set_buffer (search, g_value_get_object (value));
+                       break;
+
+               case PROP_SETTINGS:
+                       gtk_source_search_context_set_settings (search, g_value_get_object (value));
+                       break;
+
+               default:
+                       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                       break;
+       }
 }
 
-gboolean
-gtk_source_search_context_get_at_word_boundaries (GtkSourceSearchContext *search)
+static void
+gtk_source_search_context_class_init (GtkSourceSearchContextClass *klass)
 {
-       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search), FALSE);
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-       return search->priv->at_word_boundaries;
+       object_class->dispose = gtk_source_search_context_dispose;
+       object_class->finalize = gtk_source_search_context_finalize;
+       object_class->get_property = gtk_source_search_context_get_property;
+       object_class->set_property = gtk_source_search_context_set_property;
+
+       /**
+        * GtkSourceSearchContext:buffer:
+        *
+        * The #GtkSourceBuffer associated to the search context.
+        *
+        * Since: 3.10
+        */
+       g_object_class_install_property (object_class,
+                                        PROP_BUFFER,
+                                        g_param_spec_object ("buffer",
+                                                             _("Buffer"),
+                                                             _("The associated GtkSourceBuffer"),
+                                                             GTK_SOURCE_TYPE_BUFFER,
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+       /**
+        * GtkSourceSearchContext:settings:
+        *
+        * The #GtkSourceSearchSettings associated to the search context.
+        *
+        * Since: 3.10
+        */
+       g_object_class_install_property (object_class,
+                                        PROP_SETTINGS,
+                                        g_param_spec_object ("settings",
+                                                             _("Settings"),
+                                                             _("The associated GtkSourceSearchSettings"),
+                                                             GTK_SOURCE_TYPE_SEARCH_SETTINGS,
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+       /**
+        * GtkSourceSearchContext:occurrences-count:
+        *
+        * The total number of search occurrences. If the search is disabled,
+        * the value is 0. If the buffer is not already fully scanned, the value
+        * is -1.
+        *
+        * Since: 3.10
+        */
+       g_object_class_install_property (object_class,
+                                        PROP_OCCURRENCES_COUNT,
+                                        g_param_spec_int ("occurrences-count",
+                                                          _("Occurrences count"),
+                                                          _("Total number of search occurrences"),
+                                                          -1,
+                                                          G_MAXINT,
+                                                          0,
+                                                          G_PARAM_READABLE));
+
+       /**
+        * GtkSourceSearchContext:regex-error:
+        *
+        * If the regex search pattern doesn't follow all the rules, this
+        * property will be set. If the pattern is valid, the value is %NULL.
+        *
+        * Free with g_error_free().
+        *
+        * Since: 3.10
+        */
+       g_object_class_install_property (object_class,
+                                        PROP_REGEX_ERROR,
+                                        g_param_spec_pointer ("regex-error",
+                                                              _("Regex error"),
+                                                              _("Regular expression error"),
+                                                              G_PARAM_READABLE));
 }
 
-void
-gtk_source_search_context_set_wrap_around (GtkSourceSearchContext *search,
-                                          gboolean                wrap_around)
+static void
+gtk_source_search_context_init (GtkSourceSearchContext *search)
 {
-       g_return_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search));
+       search->priv = gtk_source_search_context_get_instance_private (search);
+}
 
-       search->priv->wrap_around = wrap_around;
-       update (search);
+GtkSourceSearchContext *
+gtk_source_search_context_new (GtkSourceBuffer         *buffer,
+                              GtkSourceSearchSettings *settings)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), NULL);
+       g_return_val_if_fail (settings == NULL || GTK_SOURCE_IS_SEARCH_SETTINGS (settings), NULL);
+
+       return g_object_new (GTK_SOURCE_TYPE_SEARCH_CONTEXT,
+                            "buffer", buffer,
+                            "settings", settings,
+                            NULL);
 }
 
-gboolean
-gtk_source_search_context_get_wrap_around (GtkSourceSearchContext *search)
+GtkSourceBuffer *
+gtk_source_search_context_get_buffer (GtkSourceSearchContext *search)
 {
-       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search), FALSE);
+       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search), NULL);
 
-       return search->priv->wrap_around;
+       return GTK_SOURCE_BUFFER (search->priv->buffer);
+}
+
+GtkSourceSearchSettings *
+gtk_source_search_context_get_settings (GtkSourceSearchContext *search)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search), NULL);
+
+       return get_settings (search);
 }
 
 void
-gtk_source_search_context_set_regex_enabled (GtkSourceSearchContext *search,
-                                            gboolean                regex_enabled)
+gtk_source_search_context_set_settings (GtkSourceSearchContext  *search,
+                                       GtkSourceSearchSettings *settings)
 {
        g_return_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search));
+       g_return_if_fail (GTK_SOURCE_IS_SEARCH_SETTINGS (settings));
+
+       if (search->priv->settings != NULL)
+       {
+               g_signal_handlers_disconnect_by_func (search->priv->settings,
+                                                     settings_notify_cb,
+                                                     search);
+
+               g_object_unref (search->priv->settings);
+       }
+
+       search->priv->settings = g_object_ref (settings);
 
-       search->priv->regex_enabled = regex_enabled;
+       g_signal_connect_object (settings,
+                                "notify",
+                                G_CALLBACK (settings_notify_cb),
+                                search,
+                                G_CONNECT_SWAPPED);
 
+       search_text_updated (search);
        update_regex (search);
        update (search);
-}
 
-gboolean
-gtk_source_search_context_get_regex_enabled (GtkSourceSearchContext *search)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search), FALSE);
-
-       return search->priv->regex_enabled;
+       g_object_notify (G_OBJECT (search), "settings");
 }
 
+/**
+ * gtk_source_search_context_get_regex_error:
+ * @search: a #GtkSourceSearchContext.
+ *
+ * Regular expression patterns must follow certain rules. If
+ * #GtkSourceSearchContext:search-text breaks a rule, the error can be retrieved
+ * with this function. The error domain is #G_REGEX_ERROR.
+ *
+ * Free the return value with g_error_free().
+ *
+ * Returns: the #GError, or %NULL if the pattern is valid.
+ * Since: 3.10
+ */
 GError *
 gtk_source_search_context_get_regex_error (GtkSourceSearchContext *search)
 {
@@ -2605,36 +2791,41 @@ gtk_source_search_context_get_regex_error (GtkSourceSearchContext *search)
        return g_error_copy (search->priv->regex_error);
 }
 
-void
-gtk_source_search_context_set_highlight (GtkSourceSearchContext *search,
-                                        gboolean                highlight)
-{
-       g_return_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search));
-
-       search->priv->highlight = highlight;
-
-       if (search->priv->found_tag != NULL)
-       {
-               sync_found_tag (search);
-       }
-}
-
-gboolean
-gtk_source_search_context_get_highlight (GtkSourceSearchContext *search)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search), FALSE);
-
-       return search->priv->highlight;
-}
-
+/**
+ * gtk_source_search_context_get_occurrences_count:
+ * @search: a #GtkSourceSearchContext.
+ *
+ * Gets the total number of search occurrences. If the buffer is not already
+ * fully scanned, the total number of occurrences is unknown, and -1 is
+ * returned.
+ *
+ * Returns: the total number of search occurrences, or -1 if unknown.
+ * Since: 3.10
+ */
 gint
 gtk_source_search_context_get_occurrences_count (GtkSourceSearchContext *search)
 {
-       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search), 0);
+       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search), -1);
 
        return is_text_region_empty (search->priv->scan_region) ? search->priv->occurrences_count : -1;
 }
 
+/**
+ * gtk_source_search_context_get_occurrence_position:
+ * @search: a #GtkSourceSearchContext.
+ * @match_start: the start of the occurrence.
+ * @match_end: the end of the occurrence.
+ *
+ * Gets the position of a search occurrence. If the buffer is not already fully
+ * scanned, the position may be unknown, and -1 is returned. Therefore you
+ * should call this function when you know that the buffer is fully scanned.
+ *
+ * Returns: the position of the search occurrence. The first occurrence has the
+ * position 1 (not 0). Returns 0 if @match_start and @match_end doesn't delimit
+ * an occurrence. Returns -1 if the position is not yet known.
+ *
+ * Since: 3.10
+ */
 gint
 gtk_source_search_context_get_occurrence_position (GtkSourceSearchContext *search,
                                                   const GtkTextIter      *match_start,
@@ -2706,80 +2897,30 @@ gtk_source_search_context_get_occurrence_position (GtkSourceSearchContext *searc
        return position + 1;
 }
 
-void
-gtk_source_search_context_update_highlight (GtkSourceSearchContext *search,
-                                           const GtkTextIter      *start,
-                                           const GtkTextIter      *end,
-                                           gboolean                synchronous)
-{
-       GtkTextRegion *region_to_highlight;
-
-       g_return_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search));
-       g_return_if_fail (start != NULL);
-       g_return_if_fail (end != NULL);
-
-       if (dispose_has_run (search) ||
-           is_text_region_empty (search->priv->scan_region))
-       {
-               return;
-       }
-
-       region_to_highlight = gtk_text_region_intersect (search->priv->scan_region,
-                                                        start,
-                                                        end);
-
-       if (is_text_region_empty (region_to_highlight))
-       {
-               if (region_to_highlight != NULL)
-               {
-                       gtk_text_region_destroy (region_to_highlight, TRUE);
-               }
-
-               return;
-       }
-
-       if (!synchronous)
-       {
-               if (search->priv->high_priority_region != NULL)
-               {
-                       /* The high priority region is used to highlight the
-                        * region visible on screen. So if we are here, that
-                        * means that the visible region has changed. So we can
-                        * destroy the old high_priority_region.
-                        */
-                       gtk_text_region_destroy (search->priv->high_priority_region, TRUE);
-               }
-
-               search->priv->high_priority_region = region_to_highlight;
-               install_idle_scan (search);
-               return;
-       }
-
-       if (search->priv->regex_enabled)
-       {
-               GtkTextIter start;
-
-               gtk_text_region_nth_subregion (search->priv->scan_region,
-                                              0,
-                                              &start,
-                                              NULL);
-
-               regex_search_scan_chunk (search, &start, end);
-       }
-       else
-       {
-               scan_all_region (search, region_to_highlight);
-               gtk_text_region_destroy (region_to_highlight, TRUE);
-       }
-}
-
+/**
+ * gtk_source_search_context_forward:
+ * @search: a #GtkSourceSearchContext.
+ * @iter: start of search.
+ * @match_start: (out) (allow-none): return location for start of match, or %NULL.
+ * @match_end: (out) (allow-none): return location for end of match, or %NULL.
+ *
+ * Synchronous forward search. It is recommended to use the asynchronous
+ * functions instead, to not block the user interface. However, if you are sure
+ * that the @buffer is small, this function is more convenient to use.
+ *
+ * Returns: whether a match was found.
+ * Since: 3.10
+ */
 gboolean
 gtk_source_search_context_forward (GtkSourceSearchContext *search,
                                   const GtkTextIter      *iter,
                                   GtkTextIter            *match_start,
                                   GtkTextIter            *match_end)
 {
+       GtkTextIter m_start;
+       GtkTextIter m_end;
        gboolean found;
+       GtkSourceSearchSettings *settings;
 
        g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search), FALSE);
        g_return_val_if_fail (iter != NULL, FALSE);
@@ -2789,19 +2930,48 @@ gtk_source_search_context_forward (GtkSourceSearchContext *search,
                return FALSE;
        }
 
-       found = smart_forward_search (search, iter, match_start, match_end);
+       settings = get_settings (search);
+
+       found = smart_forward_search (search, iter, &m_start, &m_end);
 
-       if (!found && search->priv->wrap_around)
+       if (!found && gtk_source_search_settings_get_wrap_around (settings))
        {
                GtkTextIter start_iter;
                gtk_text_buffer_get_start_iter (search->priv->buffer, &start_iter);
 
-               found = smart_forward_search (search, &start_iter, match_start, match_end);
+               found = smart_forward_search (search, &start_iter, &m_start, &m_end);
+       }
+
+       if (found && match_start != NULL)
+       {
+               *match_start = m_start;
+       }
+
+       if (found && match_end != NULL)
+       {
+               *match_end = m_end;
        }
 
        return found;
 }
 
+/**
+ * gtk_source_search_context_forward_async:
+ * @search: a #GtkSourceSearchContext.
+ * @iter: start of search.
+ * @cancellable: (allow-none): a #GCancellable, or %NULL.
+ * @callback: a #GAsyncReadyCallback to call when the operation is finished.
+ * @user_data: the data to pass to the @callback function.
+ *
+ * Asynchronous forward search. See the #GAsyncResult documentation to know
+ * how to use this function.
+ *
+ * If the operation is cancelled, the @callback will only be called if
+ * @cancellable was not %NULL. gtk_source_search_context_forward_async() takes
+ * ownership of @cancellable, so you can unref it after calling this function.
+ *
+ * Since: 3.10
+ */
 void
 gtk_source_search_context_forward_async (GtkSourceSearchContext *search,
                                         const GtkTextIter      *iter,
@@ -2818,11 +2988,25 @@ gtk_source_search_context_forward_async (GtkSourceSearchContext *search,
        }
 
        clear_task (search);
-       search->priv->task = g_task_new (search->priv->buffer, cancellable, callback, user_data);
+       search->priv->task = g_task_new (search, cancellable, callback, user_data);
 
        smart_forward_search_async (search, iter, FALSE);
 }
 
+/**
+ * gtk_source_search_context_forward_finish:
+ * @search: a #GtkSourceSearchContext.
+ * @result: a #GAsyncResult.
+ * @match_start: (out) (allow-none): return location for start of match, or %NULL.
+ * @match_end: (out) (allow-none): return location for end of match, or %NULL.
+ * @error: a #GError, or %NULL.
+ *
+ * Finishes a forward search started with
+ * gtk_source_search_context_forward_async().
+ *
+ * Returns: whether a match was found.
+ * Since: 3.10
+ */
 gboolean
 gtk_source_search_context_forward_finish (GtkSourceSearchContext  *search,
                                          GAsyncResult            *result,
@@ -2840,7 +3024,7 @@ gtk_source_search_context_forward_finish (GtkSourceSearchContext  *search,
                return FALSE;
        }
 
-       g_return_val_if_fail (g_task_is_valid (result, search->priv->buffer), FALSE);
+       g_return_val_if_fail (g_task_is_valid (result, search), FALSE);
 
        data = g_task_propagate_pointer (G_TASK (result), error);
 
@@ -2868,13 +3052,30 @@ gtk_source_search_context_forward_finish (GtkSourceSearchContext  *search,
        return found;
 }
 
+/**
+ * gtk_source_search_context_backward:
+ * @search: a #GtkSourceSearchContext.
+ * @iter: start of search.
+ * @match_start: (out) (allow-none): return location for start of match, or %NULL.
+ * @match_end: (out) (allow-none): return location for end of match, or %NULL.
+ *
+ * Synchronous backward search. It is recommended to use the asynchronous
+ * functions instead, to not block the user interface. However, if you are sure
+ * that the @buffer is small, this function is more convenient to use.
+ *
+ * Returns: whether a match was found.
+ * Since: 3.10
+ */
 gboolean
 gtk_source_search_context_backward (GtkSourceSearchContext *search,
                                    const GtkTextIter      *iter,
                                    GtkTextIter            *match_start,
                                    GtkTextIter            *match_end)
 {
+       GtkTextIter m_start;
+       GtkTextIter m_end;
        gboolean found;
+       GtkSourceSearchSettings *settings;
 
        g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search), FALSE);
        g_return_val_if_fail (iter != NULL, FALSE);
@@ -2884,20 +3085,49 @@ gtk_source_search_context_backward (GtkSourceSearchContext *search,
                return FALSE;
        }
 
-       found = smart_backward_search (search, iter, match_start, match_end);
+       settings = get_settings (search);
 
-       if (!found && search->priv->wrap_around)
+       found = smart_backward_search (search, iter, &m_start, &m_end);
+
+       if (!found && gtk_source_search_settings_get_wrap_around (settings))
        {
                GtkTextIter end_iter;
 
                gtk_text_buffer_get_end_iter (search->priv->buffer, &end_iter);
 
-               found = smart_backward_search (search, &end_iter, match_start, match_end);
+               found = smart_backward_search (search, &end_iter, &m_start, &m_end);
+       }
+
+       if (found && match_start != NULL)
+       {
+               *match_start = m_start;
+       }
+
+       if (found && match_end != NULL)
+       {
+               *match_end = m_end;
        }
 
        return found;
 }
 
+/**
+ * gtk_source_search_context_backward_async:
+ * @search: a #GtkSourceSearchContext.
+ * @iter: start of search.
+ * @cancellable: (allow-none): a #GCancellable, or %NULL.
+ * @callback: a #GAsyncReadyCallback to call when the operation is finished.
+ * @user_data: the data to pass to the @callback function.
+ *
+ * Asynchronous backward search. See the #GAsyncResult documentation to know
+ * how to use this function.
+ *
+ * If the operation is cancelled, the @callback will only be called if
+ * @cancellable was not %NULL. gtk_source_search_context_backward_async() takes
+ * ownership of @cancellable, so you can unref it after calling this function.
+ *
+ * Since: 3.10
+ */
 void
 gtk_source_search_context_backward_async (GtkSourceSearchContext *search,
                                          const GtkTextIter      *iter,
@@ -2914,11 +3144,25 @@ gtk_source_search_context_backward_async (GtkSourceSearchContext *search,
        }
 
        clear_task (search);
-       search->priv->task = g_task_new (search->priv->buffer, cancellable, callback, user_data);
+       search->priv->task = g_task_new (search, cancellable, callback, user_data);
 
        smart_backward_search_async (search, iter, FALSE);
 }
 
+/**
+ * gtk_source_search_context_backward_finish:
+ * @search: a #GtkSourceSearchContext.
+ * @result: a #GAsyncResult.
+ * @match_start: (out) (allow-none): return location for start of match, or %NULL.
+ * @match_end: (out) (allow-none): return location for end of match, or %NULL.
+ * @error: a #GError, or %NULL.
+ *
+ * Finishes a backward search started with
+ * gtk_source_search_context_backward_async().
+ *
+ * Returns: whether a match was found.
+ * Since: 3.10
+ */
 gboolean
 gtk_source_search_context_backward_finish (GtkSourceSearchContext  *search,
                                           GAsyncResult            *result,
@@ -2982,6 +3226,24 @@ regex_replace (GtkSourceSearchContext *search,
        return TRUE;
 }
 
+/**
+ * gtk_source_search_context_replace:
+ * @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.
+ *
+ * Replaces a search match by another text. If @match_start and @match_end
+ * doesn't correspond to a search match, %FALSE is returned.
+ *
+ * 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.10
+ */
 gboolean
 gtk_source_search_context_replace (GtkSourceSearchContext *search,
                                   const GtkTextIter      *match_start,
@@ -2991,6 +3253,7 @@ gtk_source_search_context_replace (GtkSourceSearchContext *search,
 {
        GtkTextIter start;
        GtkTextIter end;
+       GtkSourceSearchSettings *settings;
 
        g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search), FALSE);
        g_return_val_if_fail (match_start != NULL, FALSE);
@@ -3002,6 +3265,8 @@ gtk_source_search_context_replace (GtkSourceSearchContext *search,
                return FALSE;
        }
 
+       settings = get_settings (search);
+
        if (!smart_forward_search (search, match_start, &start, &end))
        {
                return FALSE;
@@ -3013,7 +3278,7 @@ gtk_source_search_context_replace (GtkSourceSearchContext *search,
                return FALSE;
        }
 
-       if (search->priv->regex_enabled)
+       if (gtk_source_search_settings_get_regex_enabled (settings))
        {
                return regex_replace (search, &start, &end, replace);
        }
@@ -3026,6 +3291,22 @@ gtk_source_search_context_replace (GtkSourceSearchContext *search,
        return TRUE;
 }
 
+/**
+ * gtk_source_search_context_replace_all:
+ * @search: a #GtkSourceSearchContext.
+ * @replace: the replacement text.
+ * @replace_length: the length of @replace in bytes, or -1.
+ *
+ * Replaces all search matches by another text. It is a synchronous function, so
+ * it can block the user interface.
+ *
+ * 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: the number of replaced matches.
+ * Since: 3.10
+ */
 guint
 gtk_source_search_context_replace_all (GtkSourceSearchContext *search,
                                       const gchar            *replace,
@@ -3037,6 +3318,7 @@ gtk_source_search_context_replace_all (GtkSourceSearchContext *search,
        guint nb_matches_replaced = 0;
        gboolean highlight_matching_brackets;
        gboolean has_regex_references = FALSE;
+       GtkSourceSearchSettings *settings;
 
        g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search), 0);
        g_return_val_if_fail (replace != NULL, 0);
@@ -3046,7 +3328,9 @@ gtk_source_search_context_replace_all (GtkSourceSearchContext *search,
                return 0;
        }
 
-       if (search->priv->regex_enabled &&
+       settings = get_settings (search);
+
+       if (gtk_source_search_settings_get_regex_enabled (settings) &&
            !g_regex_check_replacement (replace, &has_regex_references, NULL))
        {
                return 0;
@@ -3105,3 +3389,73 @@ gtk_source_search_context_replace_all (GtkSourceSearchContext *search,
 
        return nb_matches_replaced;
 }
+
+void
+_gtk_source_search_context_update_highlight (GtkSourceSearchContext *search,
+                                            const GtkTextIter      *start,
+                                            const GtkTextIter      *end,
+                                            gboolean                synchronous)
+{
+       GtkTextRegion *region_to_highlight;
+       GtkSourceSearchSettings *settings;
+
+       g_return_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search));
+       g_return_if_fail (start != NULL);
+       g_return_if_fail (end != NULL);
+
+       if (dispose_has_run (search) ||
+           is_text_region_empty (search->priv->scan_region))
+       {
+               return;
+       }
+
+       settings = get_settings (search);
+
+       region_to_highlight = gtk_text_region_intersect (search->priv->scan_region,
+                                                        start,
+                                                        end);
+
+       if (is_text_region_empty (region_to_highlight))
+       {
+               if (region_to_highlight != NULL)
+               {
+                       gtk_text_region_destroy (region_to_highlight, TRUE);
+               }
+
+               return;
+       }
+
+       if (!synchronous)
+       {
+               if (search->priv->high_priority_region != NULL)
+               {
+                       /* The high priority region is used to highlight the
+                        * region visible on screen. So if we are here, that
+                        * means that the visible region has changed. So we can
+                        * destroy the old high_priority_region.
+                        */
+                       gtk_text_region_destroy (search->priv->high_priority_region, TRUE);
+               }
+
+               search->priv->high_priority_region = region_to_highlight;
+               install_idle_scan (search);
+               return;
+       }
+
+       if (gtk_source_search_settings_get_regex_enabled (settings))
+       {
+               GtkTextIter start;
+
+               gtk_text_region_nth_subregion (search->priv->scan_region,
+                                              0,
+                                              &start,
+                                              NULL);
+
+               regex_search_scan_chunk (search, &start, end);
+       }
+       else
+       {
+               scan_all_region (search, region_to_highlight);
+               gtk_text_region_destroy (region_to_highlight, TRUE);
+       }
+}
diff --git a/gtksourceview/gtksourcesearchcontext.h b/gtksourceview/gtksourcesearchcontext.h
index 0c2c7cf..58ffb6b 100644
--- a/gtksourceview/gtksourcesearchcontext.h
+++ b/gtksourceview/gtksourcesearchcontext.h
@@ -47,98 +47,79 @@ struct _GtkSourceSearchContext
 struct _GtkSourceSearchContextClass
 {
        GObjectClass parent_class;
-};
-
-GType                  gtk_source_search_context_get_type                      (void) G_GNUC_CONST;
-
-GtkSourceSearchContext *gtk_source_search_context_new                          (GtkSourceBuffer        
*buffer);
-
-void                   gtk_source_search_context_set_text                      (GtkSourceSearchContext 
*search,
-                                                                                const gchar            
*text);
-
-const gchar *          gtk_source_search_context_get_text                      (GtkSourceSearchContext 
*search);
 
-void                   gtk_source_search_context_set_case_sensitive            (GtkSourceSearchContext 
*search,
-                                                                                gboolean                
case_sensitive);
-
-gboolean               gtk_source_search_context_get_case_sensitive            (GtkSourceSearchContext 
*search);
-
-void                   gtk_source_search_context_set_at_word_boundaries        (GtkSourceSearchContext 
*search,
-                                                                                gboolean                
at_word_boundaries);
-
-gboolean               gtk_source_search_context_get_at_word_boundaries        (GtkSourceSearchContext 
*search);
-
-void                   gtk_source_search_context_set_wrap_around               (GtkSourceSearchContext 
*search,
-                                                                                gboolean                
wrap_around);
+       gpointer padding[10];
+};
 
-gboolean               gtk_source_search_context_get_wrap_around               (GtkSourceSearchContext 
*search);
+GType                   gtk_source_search_context_get_type                     (void) G_GNUC_CONST;
 
-void                   gtk_source_search_context_set_regex_enabled             (GtkSourceSearchContext 
*search,
-                                                                                gboolean                
regex_enabled);
+GtkSourceSearchContext *gtk_source_search_context_new                          (GtkSourceBuffer         
*buffer,
+                                                                                GtkSourceSearchSettings 
*settings);
 
-gboolean               gtk_source_search_context_get_regex_enabled             (GtkSourceSearchContext 
*search);
+GtkSourceBuffer                *gtk_source_search_context_get_buffer                   
(GtkSourceSearchContext  *search);
 
-GError *               gtk_source_search_context_get_regex_error               (GtkSourceSearchContext 
*search);
+GtkSourceSearchSettings        *gtk_source_search_context_get_settings                 
(GtkSourceSearchContext  *search);
 
-void                   gtk_source_search_context_set_highlight                 (GtkSourceSearchContext 
*search,
-                                                                                gboolean                
highlight);
+void                    gtk_source_search_context_set_settings                 (GtkSourceSearchContext  
*search,
+                                                                                GtkSourceSearchSettings 
*settings);
 
-gboolean               gtk_source_search_context_get_highlight                 (GtkSourceSearchContext 
*search);
+GError                 *gtk_source_search_context_get_regex_error              (GtkSourceSearchContext  
*search);
 
-gint                   gtk_source_search_context_get_occurrences_count         (GtkSourceSearchContext 
*search);
+gint                    gtk_source_search_context_get_occurrences_count        (GtkSourceSearchContext  
*search);
 
-gint                   gtk_source_search_context_get_occurrence_position       (GtkSourceSearchContext 
*search,
-                                                                                const GtkTextIter      
*match_start,
-                                                                                const GtkTextIter      
*match_end);
+gint                    gtk_source_search_context_get_occurrence_position      (GtkSourceSearchContext  
*search,
+                                                                                const GtkTextIter       
*match_start,
+                                                                                const GtkTextIter       
*match_end);
 
-void                   gtk_source_search_context_update_highlight              (GtkSourceSearchContext 
*search,
-                                                                                const GtkTextIter      
*start,
-                                                                                const GtkTextIter      *end,
-                                                                                gboolean                
synchronous);
+gboolean                gtk_source_search_context_forward                      (GtkSourceSearchContext  
*search,
+                                                                                const GtkTextIter       
*iter,
+                                                                                GtkTextIter             
*match_start,
+                                                                                GtkTextIter             
*match_end);
 
-gboolean               gtk_source_search_context_forward                       (GtkSourceSearchContext 
*search,
-                                                                                const GtkTextIter      *iter,
-                                                                                GtkTextIter            
*match_start,
-                                                                                GtkTextIter            
*match_end);
+void                    gtk_source_search_context_forward_async                (GtkSourceSearchContext  
*search,
+                                                                                const GtkTextIter       
*iter,
+                                                                                GCancellable            
*cancellable,
+                                                                                GAsyncReadyCallback      
callback,
+                                                                                gpointer                 
user_data);
 
-void                   gtk_source_search_context_forward_async                 (GtkSourceSearchContext 
*search,
-                                                                                const GtkTextIter      *iter,
-                                                                                GCancellable           
*cancellable,
-                                                                                GAsyncReadyCallback     
callback,
-                                                                                gpointer                
user_data);
+gboolean                gtk_source_search_context_forward_finish               (GtkSourceSearchContext  
*search,
+                                                                                GAsyncResult            
*result,
+                                                                                GtkTextIter             
*match_start,
+                                                                                GtkTextIter             
*match_end,
+                                                                                GError                 
**error);
 
-gboolean               gtk_source_search_context_forward_finish                (GtkSourceSearchContext 
*search,
-                                                                                GAsyncResult           
*result,
-                                                                                GtkTextIter            
*match_start,
-                                                                                GtkTextIter            
*match_end,
-                                                                                GError                
**error);
+gboolean                gtk_source_search_context_backward                     (GtkSourceSearchContext  
*search,
+                                                                                const GtkTextIter       
*iter,
+                                                                                GtkTextIter             
*match_start,
+                                                                                GtkTextIter             
*match_end);
 
-gboolean               gtk_source_search_context_backward                      (GtkSourceSearchContext 
*search,
-                                                                                const GtkTextIter      *iter,
-                                                                                GtkTextIter            
*match_start,
-                                                                                GtkTextIter            
*match_end);
+void                    gtk_source_search_context_backward_async               (GtkSourceSearchContext  
*search,
+                                                                                const GtkTextIter       
*iter,
+                                                                                GCancellable            
*cancellable,
+                                                                                GAsyncReadyCallback      
callback,
+                                                                                gpointer                 
user_data);
 
-void                   gtk_source_search_context_backward_async                (GtkSourceSearchContext 
*search,
-                                                                                const GtkTextIter      *iter,
-                                                                                GCancellable           
*cancellable,
-                                                                                GAsyncReadyCallback     
callback,
-                                                                                gpointer                
user_data);
+gboolean                gtk_source_search_context_backward_finish              (GtkSourceSearchContext  
*search,
+                                                                                GAsyncResult            
*result,
+                                                                                GtkTextIter             
*match_start,
+                                                                                GtkTextIter             
*match_end,
+                                                                                GError                 
**error);
 
-gboolean               gtk_source_search_context_backward_finish               (GtkSourceSearchContext 
*search,
-                                                                                GAsyncResult           
*result,
-                                                                                GtkTextIter            
*match_start,
-                                                                                GtkTextIter            
*match_end,
-                                                                                GError                
**error);
+gboolean                gtk_source_search_context_replace                      (GtkSourceSearchContext  
*search,
+                                                                                const GtkTextIter       
*match_start,
+                                                                                const GtkTextIter       
*match_end,
+                                                                                const gchar             
*replace,
+                                                                                gint                     
replace_length);
 
-gboolean               gtk_source_search_context_replace                       (GtkSourceSearchContext 
*search,
-                                                                                const GtkTextIter      
*match_start,
-                                                                                const GtkTextIter      
*match_end,
-                                                                                const gchar            
*replace,
-                                                                                gint                    
replace_length);
+guint                   gtk_source_search_context_replace_all                  (GtkSourceSearchContext  
*search,
+                                                                                const gchar             
*replace,
+                                                                                gint                     
replace_length);
 
-guint                  gtk_source_search_context_replace_all                   (GtkSourceSearchContext 
*search,
-                                                                                const gchar            
*replace,
-                                                                                gint                    
replace_length);
+G_GNUC_INTERNAL
+void                    _gtk_source_search_context_update_highlight            (GtkSourceSearchContext  
*search,
+                                                                                const GtkTextIter       
*start,
+                                                                                const GtkTextIter       *end,
+                                                                                gboolean                 
synchronous);
 
 G_END_DECLS
 
diff --git a/gtksourceview/gtksourcesearchsettings.c b/gtksourceview/gtksourcesearchsettings.c
new file mode 100644
index 0000000..9a66a90
--- /dev/null
+++ b/gtksourceview/gtksourcesearchsettings.c
@@ -0,0 +1,472 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */
+/* gtksourcesearchsettings.c
+ * This file is part of GtkSourceView
+ *
+ * Copyright (C) 2013 - Sébastien Wilmet <swilmet gnome org>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "gtksourcesearchsettings.h"
+#include "gtksourceview-i18n.h"
+
+enum
+{
+       PROP_0,
+       PROP_SEARCH_TEXT,
+       PROP_CASE_SENSITIVE,
+       PROP_AT_WORD_BOUNDARIES,
+       PROP_WRAP_AROUND,
+       PROP_REGEX_ENABLED
+};
+
+struct _GtkSourceSearchSettingsPrivate
+{
+       gchar *search_text;
+       guint case_sensitive : 1;
+       guint at_word_boundaries : 1;
+       guint wrap_around : 1;
+       guint regex_enabled : 1;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkSourceSearchSettings, gtk_source_search_settings, G_TYPE_OBJECT)
+
+static void
+gtk_source_search_settings_finalize (GObject *object)
+{
+       GtkSourceSearchSettings *settings = GTK_SOURCE_SEARCH_SETTINGS (object);
+
+       g_free (settings->priv->search_text);
+
+       G_OBJECT_CLASS (gtk_source_search_settings_parent_class)->finalize (object);
+}
+
+static void
+gtk_source_search_settings_get_property (GObject    *object,
+                                        guint       prop_id,
+                                        GValue     *value,
+                                        GParamSpec *pspec)
+{
+       GtkSourceSearchSettings *settings;
+
+       g_return_if_fail (GTK_SOURCE_IS_SEARCH_SETTINGS (object));
+
+       settings = GTK_SOURCE_SEARCH_SETTINGS (object);
+
+       switch (prop_id)
+       {
+               case PROP_SEARCH_TEXT:
+                       g_value_set_string (value, settings->priv->search_text);
+                       break;
+
+               case PROP_CASE_SENSITIVE:
+                       g_value_set_boolean (value, settings->priv->case_sensitive);
+                       break;
+
+               case PROP_AT_WORD_BOUNDARIES:
+                       g_value_set_boolean (value, settings->priv->at_word_boundaries);
+                       break;
+
+               case PROP_WRAP_AROUND:
+                       g_value_set_boolean (value, settings->priv->wrap_around);
+                       break;
+
+               case PROP_REGEX_ENABLED:
+                       g_value_set_boolean (value, settings->priv->regex_enabled);
+                       break;
+
+               default:
+                       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                       break;
+       }
+}
+
+static void
+gtk_source_search_settings_set_property (GObject      *object,
+                                        guint         prop_id,
+                                        const GValue *value,
+                                        GParamSpec   *pspec)
+{
+       GtkSourceSearchSettings *settings;
+
+       g_return_if_fail (GTK_SOURCE_IS_SEARCH_SETTINGS (object));
+
+       settings = GTK_SOURCE_SEARCH_SETTINGS (object);
+
+       switch (prop_id)
+       {
+               case PROP_SEARCH_TEXT:
+                       g_free (settings->priv->search_text);
+                       settings->priv->search_text = g_value_dup_string (value);
+                       break;
+
+               case PROP_CASE_SENSITIVE:
+                       settings->priv->case_sensitive = g_value_get_boolean (value);
+                       break;
+
+               case PROP_AT_WORD_BOUNDARIES:
+                       settings->priv->at_word_boundaries = g_value_get_boolean (value);
+                       break;
+
+               case PROP_WRAP_AROUND:
+                       settings->priv->wrap_around = g_value_get_boolean (value);
+                       break;
+
+               case PROP_REGEX_ENABLED:
+                       settings->priv->regex_enabled = g_value_get_boolean (value);
+                       break;
+
+               default:
+                       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                       break;
+       }
+}
+
+static void
+gtk_source_search_settings_class_init (GtkSourceSearchSettingsClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->finalize = gtk_source_search_settings_finalize;
+       object_class->get_property = gtk_source_search_settings_get_property;
+       object_class->set_property = gtk_source_search_settings_set_property;
+
+       /**
+        * GtkSourceSearchSettings:search-text:
+        *
+        * A search string, or %NULL if the search is disabled. If the regular
+        * expression search is enabled, #GtkSourceSearchSettings:search-text is
+        * the pattern.
+        *
+        * Since: 3.10
+        */
+       g_object_class_install_property (object_class,
+                                        PROP_SEARCH_TEXT,
+                                        g_param_spec_string ("search-text",
+                                                             _("Search text"),
+                                                             _("The text to search"),
+                                                             NULL,
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+       /**
+        * GtkSourceSearchSettings:case-sensitive:
+        *
+        * Whether the search is case sensitive.
+        *
+        * Since: 3.10
+        */
+       g_object_class_install_property (object_class,
+                                        PROP_CASE_SENSITIVE,
+                                        g_param_spec_boolean ("case-sensitive",
+                                                              _("Case sensitive"),
+                                                              _("Case sensitive"),
+                                                              FALSE,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+       /**
+        * GtkSourceSearchSettings:at-word-boundaries:
+        *
+        * If %TRUE, a search match must start and end a word. The match can
+        * span multiple words.
+        *
+        * Since: 3.10
+        */
+       g_object_class_install_property (object_class,
+                                        PROP_AT_WORD_BOUNDARIES,
+                                        g_param_spec_boolean ("at-word-boundaries",
+                                                              _("At word boundaries"),
+                                                              _("Search at word boundaries"),
+                                                              FALSE,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+       /**
+        * GtkSourceSearchSettings:wrap-around:
+        *
+        * For a forward search, continue at the beginning of the buffer if no
+        * search occurrence is found. For a backward search, continue at the
+        * end of the buffer.
+        *
+        * Since: 3.10
+        */
+       g_object_class_install_property (object_class,
+                                        PROP_WRAP_AROUND,
+                                        g_param_spec_boolean ("wrap-around",
+                                                              _("Wrap around"),
+                                                              _("Wrap around"),
+                                                              TRUE,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+       /**
+        * GtkSourceSearchSettings:regex-enabled:
+        *
+        * Search by regular expressions with
+        * #GtkSourceSearchSettings:search-text as the pattern.
+        *
+        * Since: 3.10
+        */
+       g_object_class_install_property (object_class,
+                                        PROP_REGEX_ENABLED,
+                                        g_param_spec_boolean ("regex-enabled",
+                                                              _("Regex enabled"),
+                                                              _("Whether to search by regular expression"),
+                                                              FALSE,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+gtk_source_search_settings_init (GtkSourceSearchSettings *self)
+{
+       self->priv = gtk_source_search_settings_get_instance_private (self);
+}
+
+/**
+ * gtk_source_search_settings_new:
+ *
+ * Creates a new search settings object.
+ *
+ * Returns: a new search settings object.
+ * Since: 3.10
+ */
+GtkSourceSearchSettings *
+gtk_source_search_settings_new (void)
+{
+       return g_object_new (GTK_SOURCE_TYPE_SEARCH_SETTINGS, NULL);
+}
+
+/**
+ * gtk_source_search_settings_set_search_text:
+ * @settings: a #GtkSourceSearchSettings.
+ * @search_text: (allow-none): the nul-terminated text to search, or %NULL to disable the search.
+ *
+ * Sets the text to search. If @text is %NULL or is empty, the search will be
+ * disabled. A copy of @text will be made, so you can safely free @text after
+ * a call to this function.
+ *
+ * You may be interested to call gtk_source_utils_unescape_search_text() before
+ * this function.
+ *
+ * Since: 3.10
+ */
+void
+gtk_source_search_settings_set_search_text (GtkSourceSearchSettings *settings,
+                                           const gchar             *search_text)
+{
+       g_return_if_fail (GTK_SOURCE_IS_SEARCH_SETTINGS (settings));
+       g_return_if_fail (search_text == NULL || g_utf8_validate (search_text, -1, NULL));
+
+       if ((settings->priv->search_text == NULL &&
+            (search_text == NULL || search_text[0] == '\0')) ||
+           g_strcmp0 (settings->priv->search_text, search_text) == 0)
+       {
+               return;
+       }
+
+       g_free (settings->priv->search_text);
+
+       if (search_text == NULL || search_text[0] == '\0')
+       {
+               settings->priv->search_text = NULL;
+       }
+       else
+       {
+               settings->priv->search_text = g_strdup (search_text);
+       }
+
+       g_object_notify (G_OBJECT (settings), "search-text");
+}
+
+/**
+ * gtk_source_search_settings_get_search_text:
+ * @settings: a #GtkSourceSearchSettings.
+ *
+ * Gets the text to search. The return value must not be freed.
+ *
+ * You may be interested to call gtk_source_utils_escape_search_text() after
+ * this function.
+ *
+ * Returns: the text to search, or %NULL if the search is disabled.
+ * Since: 3.10
+ */
+const gchar *
+gtk_source_search_settings_get_search_text (GtkSourceSearchSettings *settings)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_SETTINGS (settings), NULL);
+
+       return settings->priv->search_text;
+}
+
+/**
+ * gtk_source_search_settings_set_case_sensitive:
+ * @settings: a #GtkSourceSearchSettings.
+ * @case_sensitive: the setting.
+ *
+ * Enables or disables the case sensitivity for the search.
+ *
+ * Since: 3.10
+ */
+void
+gtk_source_search_settings_set_case_sensitive (GtkSourceSearchSettings *settings,
+                                              gboolean                 case_sensitive)
+{
+       g_return_if_fail (GTK_SOURCE_IS_SEARCH_SETTINGS (settings));
+
+       case_sensitive = case_sensitive != FALSE;
+
+       if (settings->priv->case_sensitive != case_sensitive)
+       {
+               settings->priv->case_sensitive = case_sensitive;
+               g_object_notify (G_OBJECT (settings), "case-sensitive");
+       }
+}
+
+/**
+ * gtk_source_search_settings_get_case_sensitive:
+ * @settings: a #GtkSourceSearchSettings.
+ *
+ * Returns: whether the search is case sensitive.
+ * Since: 3.10
+ */
+gboolean
+gtk_source_search_settings_get_case_sensitive (GtkSourceSearchSettings *settings)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_SETTINGS (settings), FALSE);
+
+       return settings->priv->case_sensitive;
+}
+
+/**
+ * gtk_source_search_settings_set_at_word_boundaries:
+ * @settings: a #GtkSourceSearchSettings.
+ * @at_word_boundaries: the setting.
+ *
+ * Change whether the search is done at word boundaries. If @at_word_boundaries
+ * is %TRUE, a search match must start and end a word. The match can span
+ * multiple words. See also gtk_text_iter_starts_word() and
+ * gtk_text_iter_ends_word().
+ *
+ * Since: 3.10
+ */
+void
+gtk_source_search_settings_set_at_word_boundaries (GtkSourceSearchSettings *settings,
+                                                  gboolean                 at_word_boundaries)
+{
+       g_return_if_fail (GTK_SOURCE_IS_SEARCH_SETTINGS (settings));
+
+       at_word_boundaries = at_word_boundaries != FALSE;
+
+       if (settings->priv->at_word_boundaries != at_word_boundaries)
+       {
+               settings->priv->at_word_boundaries = at_word_boundaries;
+               g_object_notify (G_OBJECT (settings), "at-word-boundaries");
+       }
+}
+
+/**
+ * gtk_source_search_settings_get_at_word_boundaries:
+ * @settings: a #GtkSourceSearchSettings.
+ *
+ * Returns: whether to search at word boundaries.
+ * Since: 3.10
+ */
+gboolean
+gtk_source_search_settings_get_at_word_boundaries (GtkSourceSearchSettings *settings)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_SETTINGS (settings), FALSE);
+
+       return settings->priv->at_word_boundaries;
+}
+
+/**
+ * gtk_source_search_settings_set_wrap_around:
+ * @settings: a #GtkSourceSearchSettings.
+ * @wrap_around: the setting.
+ *
+ * Enables or disables the wrap around search. If @wrap_around is %TRUE, the
+ * forward search continues at the beginning of the buffer if no search
+ * occurrences are found. Similarly, the backward search continues to search at
+ * the end of the buffer.
+ *
+ * Since: 3.10
+ */
+void
+gtk_source_search_settings_set_wrap_around (GtkSourceSearchSettings *settings,
+                                           gboolean                 wrap_around)
+{
+       g_return_if_fail (GTK_SOURCE_IS_SEARCH_SETTINGS (settings));
+
+       wrap_around = wrap_around != FALSE;
+
+       if (settings->priv->wrap_around != wrap_around)
+       {
+               settings->priv->wrap_around = wrap_around;
+               g_object_notify (G_OBJECT (settings), "wrap-around");
+       }
+}
+
+/**
+ * gtk_source_search_settings_get_wrap_around:
+ * @settings: a #GtkSourceSearchSettings.
+ *
+ * Returns: whether to wrap around the search.
+ * Since: 3.10
+ */
+gboolean
+gtk_source_search_settings_get_wrap_around (GtkSourceSearchSettings *settings)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_SETTINGS (settings), FALSE);
+
+       return settings->priv->wrap_around;
+}
+
+/**
+ * gtk_source_search_settings_set_regex_enabled:
+ * @settings: a #GtkSourceSearchSettings.
+ * @regex_enabled: the setting.
+ *
+ * Enables or disables whether to search by regular expressions.
+ * If enabled, the #GtkSourceSearchSettings:search-text property contains the
+ * pattern of the regular expression.
+ *
+ * Since: 3.10
+ */
+void
+gtk_source_search_settings_set_regex_enabled (GtkSourceSearchSettings *settings,
+                                             gboolean                 regex_enabled)
+{
+       g_return_if_fail (GTK_SOURCE_IS_SEARCH_SETTINGS (settings));
+
+       regex_enabled = regex_enabled != FALSE;
+
+       if (settings->priv->regex_enabled != regex_enabled)
+       {
+               settings->priv->regex_enabled = regex_enabled;
+               g_object_notify (G_OBJECT (settings), "regex-enabled");
+       }
+}
+
+/**
+ * gtk_source_search_settings_get_regex_enabled:
+ * @settings: a #GtkSourceSearchSettings.
+ *
+ * Returns: whether to search by regular expressions.
+ * Since: 3.10
+ */
+gboolean
+gtk_source_search_settings_get_regex_enabled (GtkSourceSearchSettings *settings)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_SETTINGS (settings), FALSE);
+
+       return settings->priv->regex_enabled;
+}
diff --git a/gtksourceview/gtksourcesearchsettings.h b/gtksourceview/gtksourcesearchsettings.h
new file mode 100644
index 0000000..56f727d
--- /dev/null
+++ b/gtksourceview/gtksourcesearchsettings.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */
+/* gtksourcesearchsettings.h
+ * This file is part of GtkSourceView
+ *
+ * Copyright (C) 2013 - Sébastien Wilmet <swilmet gnome org>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __GTK_SOURCE_SEARCH_SETTINGS_H__
+#define __GTK_SOURCE_SEARCH_SETTINGS_H__
+
+#include <glib-object.h>
+#include <gtksourceview/gtksourcetypes.h>
+
+G_BEGIN_DECLS
+
+#define GTK_SOURCE_TYPE_SEARCH_SETTINGS             (gtk_source_search_settings_get_type ())
+#define GTK_SOURCE_SEARCH_SETTINGS(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GTK_SOURCE_TYPE_SEARCH_SETTINGS, GtkSourceSearchSettings))
+#define GTK_SOURCE_SEARCH_SETTINGS_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), 
GTK_SOURCE_TYPE_SEARCH_SETTINGS, GtkSourceSearchSettingsClass))
+#define GTK_SOURCE_IS_SEARCH_SETTINGS(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
GTK_SOURCE_TYPE_SEARCH_SETTINGS))
+#define GTK_SOURCE_IS_SEARCH_SETTINGS_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), 
GTK_SOURCE_TYPE_SEARCH_SETTINGS))
+#define GTK_SOURCE_SEARCH_SETTINGS_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), 
GTK_SOURCE_TYPE_SEARCH_SETTINGS, GtkSourceSearchSettingsClass))
+
+typedef struct _GtkSourceSearchSettingsClass    GtkSourceSearchSettingsClass;
+typedef struct _GtkSourceSearchSettingsPrivate  GtkSourceSearchSettingsPrivate;
+
+struct _GtkSourceSearchSettings
+{
+       GObject parent;
+
+       GtkSourceSearchSettingsPrivate *priv;
+};
+
+struct _GtkSourceSearchSettingsClass
+{
+       GObjectClass parent_class;
+
+       gpointer padding[10];
+};
+
+GType                   gtk_source_search_settings_get_type                    (void) G_GNUC_CONST;
+
+GtkSourceSearchSettings *gtk_source_search_settings_new                                (void);
+
+void                    gtk_source_search_settings_set_search_text             (GtkSourceSearchSettings 
*settings,
+                                                                                const gchar             
*search_text);
+
+const gchar            *gtk_source_search_settings_get_search_text             (GtkSourceSearchSettings 
*settings);
+
+void                    gtk_source_search_settings_set_case_sensitive          (GtkSourceSearchSettings 
*settings,
+                                                                                gboolean                 
case_sensitive);
+
+gboolean                gtk_source_search_settings_get_case_sensitive          (GtkSourceSearchSettings 
*settings);
+
+void                    gtk_source_search_settings_set_at_word_boundaries      (GtkSourceSearchSettings 
*settings,
+                                                                                gboolean                 
at_word_boundaries);
+
+gboolean                gtk_source_search_settings_get_at_word_boundaries      (GtkSourceSearchSettings 
*settings);
+
+void                    gtk_source_search_settings_set_wrap_around             (GtkSourceSearchSettings 
*settings,
+                                                                                gboolean                 
wrap_around);
+
+gboolean                gtk_source_search_settings_get_wrap_around             (GtkSourceSearchSettings 
*settings);
+
+void                    gtk_source_search_settings_set_regex_enabled           (GtkSourceSearchSettings 
*settings,
+                                                                                gboolean                 
regex_enabled);
+
+gboolean                gtk_source_search_settings_get_regex_enabled           (GtkSourceSearchSettings 
*settings);
+
+G_END_DECLS
+
+#endif /* __GTK_SOURCE_SEARCH_SETTINGS_H__ */
diff --git a/gtksourceview/gtksourcetypes.h b/gtksourceview/gtksourcetypes.h
index ddbe654..6442ddd 100644
--- a/gtksourceview/gtksourcetypes.h
+++ b/gtksourceview/gtksourcetypes.h
@@ -43,6 +43,7 @@ typedef struct _GtkSourceMarkAttributes               GtkSourceMarkAttributes;
 typedef struct _GtkSourceMark                  GtkSourceMark;
 typedef struct _GtkSourcePrintCompositor       GtkSourcePrintCompositor;
 typedef struct _GtkSourceSearchContext         GtkSourceSearchContext;
+typedef struct _GtkSourceSearchSettings                GtkSourceSearchSettings;
 typedef struct _GtkSourceStyle                 GtkSourceStyle;
 typedef struct _GtkSourceStyleScheme           GtkSourceStyleScheme;
 typedef struct _GtkSourceStyleSchemeManager    GtkSourceStyleSchemeManager;
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 08105a7..ec203dc 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -132,6 +132,7 @@ gtksourceview/gtksourcemark.c
 gtksourceview/gtksourceprintcompositor.c
 gtksourceview/gtksourceregex.c
 gtksourceview/gtksourcesearchcontext.c
+gtksourceview/gtksourcesearchsettings.c
 gtksourceview/gtksourcestyle.c
 gtksourceview/gtksourcestylescheme.c
 gtksourceview/gtksourcestyleschememanager.c
diff --git a/tests/test-search-context.c b/tests/test-search-context.c
index d313fc7..aafc63d 100644
--- a/tests/test-search-context.c
+++ b/tests/test-search-context.c
@@ -36,10 +36,10 @@ typedef struct
        guint forward : 1;
 } AsyncData;
 
-static void check_async_search_results (GtkSourceBuffer *source_buffer,
-                                       SearchResult    *results,
-                                       gboolean         forward,
-                                       gboolean         start_check);
+static void check_async_search_results (GtkSourceSearchContext *context,
+                                       SearchResult           *results,
+                                       gboolean                forward,
+                                       gboolean                start_check);
 
 static void
 flush_queue (void)
@@ -54,37 +54,42 @@ flush_queue (void)
 static void
 test_occurrences_count_simple (void)
 {
-       GtkSourceBuffer *buffer = gtk_source_buffer_new (NULL);
+       GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
+       GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
        GtkTextIter iter;
        gint occurrences_count;
 
-       gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
-       gtk_text_buffer_insert (GTK_TEXT_BUFFER (buffer), &iter, "Some foo\nSome bar\n", -1);
+       gtk_text_buffer_get_start_iter (text_buffer, &iter);
+       gtk_text_buffer_insert (text_buffer, &iter, "Some foo\nSome bar\n", -1);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 0);
 
-       gtk_source_buffer_set_search_text (buffer, "world");
+       gtk_source_search_settings_set_search_text (settings, "world");
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 0);
 
-       gtk_source_buffer_set_search_text (buffer, "Some");
+       gtk_source_search_settings_set_search_text (settings, "Some");
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 2);
 
-       gtk_source_buffer_set_search_text (buffer, "foo");
+       gtk_source_search_settings_set_search_text (settings, "foo");
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 1);
 
-       gtk_source_buffer_set_search_text (buffer, "world");
+       gtk_source_search_settings_set_search_text (settings, "world");
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 0);
 
-       g_object_unref (buffer);
+       g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 static void
@@ -92,6 +97,8 @@ test_occurrences_count_with_insert (void)
 {
        GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
        GtkTextIter iter;
        gint occurrences_count;
 
@@ -99,61 +106,63 @@ test_occurrences_count_with_insert (void)
        gtk_text_buffer_get_start_iter (text_buffer, &iter);
        gtk_text_buffer_insert (text_buffer, &iter, "foobar", -1);
 
-       gtk_source_buffer_set_search_text (source_buffer, "foo");
+       gtk_source_search_settings_set_search_text (settings, "foo");
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 1);
 
        /* Contents: "foobar " */
        gtk_text_buffer_get_end_iter (text_buffer, &iter);
        gtk_text_buffer_insert (text_buffer, &iter, " ", -1);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 1);
 
        /* Contents: "foobar foobeer" */
        gtk_text_buffer_get_end_iter (text_buffer, &iter);
        gtk_text_buffer_insert (text_buffer, &iter, "foobeer", -1);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 2);
 
        /* Contents: "foo bar foobeer" */
        gtk_text_buffer_get_iter_at_offset (text_buffer, &iter, 3);
        gtk_text_buffer_insert (text_buffer, &iter, " ", -1);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 2);
 
        /* Contents: "foto bar foobeer" */
        gtk_text_buffer_get_iter_at_offset (text_buffer, &iter, 2);
        gtk_text_buffer_insert (text_buffer, &iter, "t", -1);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 1);
 
        /* Contents: "footo bar foobeer" */
        gtk_text_buffer_get_iter_at_offset (text_buffer, &iter, 2);
        gtk_text_buffer_insert (text_buffer, &iter, "o", -1);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 2);
 
        /* Contents: "foofooto bar foobeer" */
        gtk_text_buffer_get_start_iter (text_buffer, &iter);
        gtk_text_buffer_insert (text_buffer, &iter, "foo", -1);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 3);
 
        /* Contents: "fooTfooto bar foobeer" */
        gtk_text_buffer_get_iter_at_offset (text_buffer, &iter, 3);
        gtk_text_buffer_insert (text_buffer, &iter, "T", -1);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 3);
 
        g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 static void
@@ -161,61 +170,63 @@ test_occurrences_count_with_delete (void)
 {
        GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
        GtkTextIter start;
        GtkTextIter end;
        gint occurrences_count;
 
-       gtk_source_buffer_set_search_text (source_buffer, "foo");
+       gtk_source_search_settings_set_search_text (settings, "foo");
 
        /* Contents: "foo" -> "" */
        gtk_text_buffer_set_text (text_buffer, "foo", -1);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 1);
 
        gtk_text_buffer_get_bounds (text_buffer, &start, &end);
        gtk_text_buffer_delete (text_buffer, &start, &end);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 0);
 
        /* Contents: "foo" -> "oo" */
        gtk_text_buffer_set_text (text_buffer, "foo", -1);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 1);
 
        gtk_text_buffer_get_start_iter (text_buffer, &start);
        gtk_text_buffer_get_iter_at_offset (text_buffer, &end, 1);
        gtk_text_buffer_delete (text_buffer, &start, &end);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 0);
 
        /* Contents: "foobar foobeer" -> "foobar" */
        gtk_text_buffer_set_text (text_buffer, "foobar foobeer", -1);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 2);
 
        gtk_text_buffer_get_iter_at_offset (text_buffer, &start, 6);
        gtk_text_buffer_get_end_iter (text_buffer, &end);
        gtk_text_buffer_delete (text_buffer, &start, &end);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 1);
 
        /* Contents: "foo[foo]foo" -> "foofoo" */
        gtk_text_buffer_set_text (text_buffer, "foofoofoo", -1);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 3);
 
        gtk_text_buffer_get_iter_at_offset (text_buffer, &start, 3);
        gtk_text_buffer_get_iter_at_offset (text_buffer, &end, 6);
        gtk_text_buffer_delete (text_buffer, &start, &end);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 2);
 
        /* Contents: "fo[of]oo" -> "fooo" */
@@ -223,23 +234,25 @@ test_occurrences_count_with_delete (void)
        gtk_text_buffer_get_iter_at_offset (text_buffer, &end, 4);
        gtk_text_buffer_delete (text_buffer, &start, &end);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 1);
 
        /* Contents: "foto" -> "foo" */
        gtk_text_buffer_set_text (text_buffer, "foto", -1);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 0);
 
        gtk_text_buffer_get_iter_at_offset (text_buffer, &start, 2);
        gtk_text_buffer_get_iter_at_offset (text_buffer, &end, 3);
        gtk_text_buffer_delete (text_buffer, &start, &end);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 1);
 
        g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 static void
@@ -247,26 +260,30 @@ test_occurrences_count_multiple_lines (void)
 {
        GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
        gint occurrences_count;
 
-       gtk_source_buffer_set_search_text (source_buffer, "world\nhello");
+       gtk_source_search_settings_set_search_text (settings, "world\nhello");
 
        gtk_text_buffer_set_text (text_buffer, "hello world\nhello world\nhello world\n", -1);
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 2);
 
-       gtk_source_buffer_set_search_text (source_buffer, "world\n");
+       gtk_source_search_settings_set_search_text (settings, "world\n");
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 3);
 
-       gtk_source_buffer_set_search_text (source_buffer, "\nhello world\n");
+       gtk_source_search_settings_set_search_text (settings, "\nhello world\n");
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 1);
 
        g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 static void
@@ -274,29 +291,33 @@ test_case_sensitivity (void)
 {
        GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
        gboolean case_sensitive;
        gint occurrences_count;
 
        gtk_text_buffer_set_text (text_buffer, "Case", -1);
-       gtk_source_buffer_set_search_text (source_buffer, "case");
+       gtk_source_search_settings_set_search_text (settings, "case");
 
-       gtk_source_buffer_set_case_sensitive_search (source_buffer, TRUE);
-       case_sensitive = gtk_source_buffer_get_case_sensitive_search (source_buffer);
+       gtk_source_search_settings_set_case_sensitive (settings, TRUE);
+       case_sensitive = gtk_source_search_settings_get_case_sensitive (settings);
        g_assert (case_sensitive);
 
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 0);
 
-       gtk_source_buffer_set_case_sensitive_search (source_buffer, FALSE);
-       case_sensitive = gtk_source_buffer_get_case_sensitive_search (source_buffer);
+       gtk_source_search_settings_set_case_sensitive (settings, FALSE);
+       case_sensitive = gtk_source_search_settings_get_case_sensitive (settings);
        g_assert (!case_sensitive);
 
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 1);
 
        g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 static void
@@ -304,35 +325,40 @@ test_search_at_word_boundaries (void)
 {
        GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
        gboolean at_word_boundaries;
        gint occurrences_count;
 
        gtk_text_buffer_set_text (text_buffer, "AtWordBoundaries AtWord", -1);
-       gtk_source_buffer_set_search_text (source_buffer, "AtWord");
+       gtk_source_search_settings_set_search_text (settings, "AtWord");
 
-       gtk_source_buffer_set_search_at_word_boundaries (source_buffer, TRUE);
-       at_word_boundaries = gtk_source_buffer_get_search_at_word_boundaries (source_buffer);
+       gtk_source_search_settings_set_at_word_boundaries (settings, TRUE);
+       at_word_boundaries = gtk_source_search_settings_get_at_word_boundaries (settings);
        g_assert (at_word_boundaries);
 
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 1);
 
-       gtk_source_buffer_set_search_at_word_boundaries (source_buffer, FALSE);
-       at_word_boundaries = gtk_source_buffer_get_search_at_word_boundaries (source_buffer);
+       gtk_source_search_settings_set_at_word_boundaries (settings, FALSE);
+       at_word_boundaries = gtk_source_search_settings_get_at_word_boundaries (settings);
        g_assert (!at_word_boundaries);
 
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 2);
 
        g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 static void
-check_search_results (GtkSourceBuffer *source_buffer,
-                     SearchResult    *results,
-                     gboolean         forward)
+check_search_results (GtkSourceBuffer        *source_buffer,
+                     GtkSourceSearchContext *context,
+                     SearchResult           *results,
+                     gboolean                forward)
 {
        GtkTextIter iter;
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
@@ -350,18 +376,18 @@ check_search_results (GtkSourceBuffer *source_buffer,
 
                if (forward)
                {
-                       found = gtk_source_buffer_forward_search (source_buffer,
-                                                                 &iter,
-                                                                 &match_start,
-                                                                 &match_end);
-               }
-               else
-               {
-                       found = gtk_source_buffer_backward_search (source_buffer,
+                       found = gtk_source_search_context_forward (context,
                                                                   &iter,
                                                                   &match_start,
                                                                   &match_end);
                }
+               else
+               {
+                       found = gtk_source_search_context_backward (context,
+                                                                   &iter,
+                                                                   &match_start,
+                                                                   &match_end);
+               }
 
                g_assert (found == results[i].found);
 
@@ -378,9 +404,9 @@ check_search_results (GtkSourceBuffer *source_buffer,
 }
 
 static void
-finish_check_result (GtkSourceBuffer *source_buffer,
-                    GAsyncResult    *result,
-                    AsyncData       *data)
+finish_check_result (GtkSourceSearchContext *context,
+                    GAsyncResult           *result,
+                    AsyncData              *data)
 {
        GtkTextIter match_start;
        GtkTextIter match_end;
@@ -389,20 +415,20 @@ finish_check_result (GtkSourceBuffer *source_buffer,
 
        if (data->forward)
        {
-               found = gtk_source_buffer_forward_search_finish (source_buffer,
-                                                                result,
-                                                                &match_start,
-                                                                &match_end,
-                                                                NULL);
-       }
-       else
-       {
-               found = gtk_source_buffer_backward_search_finish (source_buffer,
+               found = gtk_source_search_context_forward_finish (context,
                                                                  result,
                                                                  &match_start,
                                                                  &match_end,
                                                                  NULL);
        }
+       else
+       {
+               found = gtk_source_search_context_backward_finish (context,
+                                                                  result,
+                                                                  &match_start,
+                                                                  &match_end,
+                                                                  NULL);
+       }
 
        g_assert (found == search_result.found);
 
@@ -415,7 +441,7 @@ finish_check_result (GtkSourceBuffer *source_buffer,
                g_assert_cmpint (match_end_offset, ==, search_result.match_end_offset);
        }
 
-       check_async_search_results (source_buffer,
+       check_async_search_results (context,
                                    data->results,
                                    data->forward,
                                    FALSE);
@@ -424,13 +450,14 @@ finish_check_result (GtkSourceBuffer *source_buffer,
 }
 
 static void
-check_async_search_results (GtkSourceBuffer *source_buffer,
-                           SearchResult    *results,
-                           gboolean         forward,
-                           gboolean         start_check)
+check_async_search_results (GtkSourceSearchContext *context,
+                           SearchResult           *results,
+                           gboolean                forward,
+                           gboolean                start_check)
 {
-       static GtkTextIter iter;
+       GtkSourceBuffer *source_buffer = gtk_source_search_context_get_buffer (context);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       static GtkTextIter iter;
        AsyncData *data;
 
        if (start_check)
@@ -450,20 +477,20 @@ check_async_search_results (GtkSourceBuffer *source_buffer,
 
        if (forward)
        {
-               gtk_source_buffer_forward_search_async (source_buffer,
-                                                       &iter,
-                                                       NULL,
-                                                       (GAsyncReadyCallback)finish_check_result,
-                                                       data);
-       }
-       else
-       {
-               gtk_source_buffer_backward_search_async (source_buffer,
+               gtk_source_search_context_forward_async (context,
                                                         &iter,
                                                         NULL,
                                                         (GAsyncReadyCallback)finish_check_result,
                                                         data);
        }
+       else
+       {
+               gtk_source_search_context_backward_async (context,
+                                                         &iter,
+                                                         NULL,
+                                                         (GAsyncReadyCallback)finish_check_result,
+                                                         data);
+       }
 }
 
 static void
@@ -471,6 +498,8 @@ test_forward_search (void)
 {
        GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
        gboolean wrap_around;
 
        static SearchResult results1[] =
@@ -492,31 +521,39 @@ test_forward_search (void)
        };
 
        gtk_text_buffer_set_text (text_buffer, "aaaa", -1);
-       gtk_source_buffer_set_search_text (source_buffer, "aa");
+       gtk_source_search_settings_set_search_text (settings, "aa");
 
        /* Wrap around: TRUE */
 
-       gtk_source_buffer_set_search_wrap_around (source_buffer, TRUE);
-       wrap_around = gtk_source_buffer_get_search_wrap_around (source_buffer);
+       gtk_source_search_settings_set_wrap_around (settings, TRUE);
+       wrap_around = gtk_source_search_settings_get_wrap_around (settings);
        g_assert (wrap_around);
 
-       check_search_results (source_buffer, results1, TRUE);
+       check_search_results (source_buffer, context, results1, TRUE);
+
+       g_test_trap_subprocess ("/Search/forward/subprocess/async-wrap-around",
+                               0,
+                               G_TEST_SUBPROCESS_INHERIT_STDERR);
 
-       g_test_trap_subprocess ("/Search/forward/subprocess/async-wrap-around", 0, 0);
        g_test_trap_assert_passed ();
 
        /* Wrap around: FALSE */
 
-       gtk_source_buffer_set_search_wrap_around (source_buffer, FALSE);
-       wrap_around = gtk_source_buffer_get_search_wrap_around (source_buffer);
+       gtk_source_search_settings_set_wrap_around (settings, FALSE);
+       wrap_around = gtk_source_search_settings_get_wrap_around (settings);
        g_assert (!wrap_around);
 
-       check_search_results (source_buffer, results2, TRUE);
+       check_search_results (source_buffer, context, results2, TRUE);
+
+       g_test_trap_subprocess ("/Search/forward/subprocess/async-normal",
+                               0,
+                               G_TEST_SUBPROCESS_INHERIT_STDERR);
 
-       g_test_trap_subprocess ("/Search/forward/subprocess/async-normal", 0, 0);
        g_test_trap_assert_passed ();
 
        g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 static void
@@ -524,6 +561,8 @@ test_async_forward_search_normal (void)
 {
        GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
 
        static SearchResult results[] =
        {
@@ -535,13 +574,15 @@ test_async_forward_search_normal (void)
        };
 
        gtk_text_buffer_set_text (text_buffer, "aaaa", -1);
-       gtk_source_buffer_set_search_text (source_buffer, "aa");
-       gtk_source_buffer_set_search_wrap_around (source_buffer, FALSE);
+       gtk_source_search_settings_set_search_text (settings, "aa");
+       gtk_source_search_settings_set_wrap_around (settings, FALSE);
 
-       check_async_search_results (source_buffer, results, TRUE, TRUE);
+       check_async_search_results (context, results, TRUE, TRUE);
 
        gtk_main ();
        g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 static void
@@ -549,6 +590,8 @@ test_async_forward_search_wrap_around (void)
 {
        GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
 
        static SearchResult results[] =
        {
@@ -560,13 +603,15 @@ test_async_forward_search_wrap_around (void)
        };
 
        gtk_text_buffer_set_text (text_buffer, "aaaa", -1);
-       gtk_source_buffer_set_search_text (source_buffer, "aa");
-       gtk_source_buffer_set_search_wrap_around (source_buffer, TRUE);
+       gtk_source_search_settings_set_search_text (settings, "aa");
+       gtk_source_search_settings_set_wrap_around (settings, TRUE);
 
-       check_async_search_results (source_buffer, results, TRUE, TRUE);
+       check_async_search_results (context, results, TRUE, TRUE);
 
        gtk_main ();
        g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 static void
@@ -574,6 +619,8 @@ test_backward_search (void)
 {
        GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
 
        static SearchResult results1[] =
        {
@@ -594,25 +641,33 @@ test_backward_search (void)
        };
 
        gtk_text_buffer_set_text (text_buffer, "aaaa", -1);
-       gtk_source_buffer_set_search_text (source_buffer, "aa");
+       gtk_source_search_settings_set_search_text (settings, "aa");
 
        /* Wrap around: TRUE */
 
-       gtk_source_buffer_set_search_wrap_around (source_buffer, TRUE);
-       check_search_results (source_buffer, results1, FALSE);
+       gtk_source_search_settings_set_wrap_around (settings, TRUE);
+       check_search_results (source_buffer, context, results1, FALSE);
+
+       g_test_trap_subprocess ("/Search/backward/subprocess/async-wrap-around",
+                               0,
+                               G_TEST_SUBPROCESS_INHERIT_STDERR);
 
-       g_test_trap_subprocess ("/Search/backward/subprocess/async-wrap-around", 0, 0);
        g_test_trap_assert_passed ();
 
        /* Wrap around: FALSE */
 
-       gtk_source_buffer_set_search_wrap_around (source_buffer, FALSE);
-       check_search_results (source_buffer, results2, FALSE);
+       gtk_source_search_settings_set_wrap_around (settings, FALSE);
+       check_search_results (source_buffer, context, results2, FALSE);
+
+       g_test_trap_subprocess ("/Search/backward/subprocess/async-normal",
+                               0,
+                               G_TEST_SUBPROCESS_INHERIT_STDERR);
 
-       g_test_trap_subprocess ("/Search/backward/subprocess/async-normal", 0, 0);
        g_test_trap_assert_passed ();
 
        g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 static void
@@ -620,6 +675,8 @@ test_async_backward_search_normal (void)
 {
        GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
 
        static SearchResult results[] =
        {
@@ -631,13 +688,15 @@ test_async_backward_search_normal (void)
        };
 
        gtk_text_buffer_set_text (text_buffer, "aaaa", -1);
-       gtk_source_buffer_set_search_text (source_buffer, "aa");
-       gtk_source_buffer_set_search_wrap_around (source_buffer, FALSE);
+       gtk_source_search_settings_set_search_text (settings, "aa");
+       gtk_source_search_settings_set_wrap_around (settings, FALSE);
 
-       check_async_search_results (source_buffer, results, FALSE, TRUE);
+       check_async_search_results (context, results, FALSE, TRUE);
 
        gtk_main ();
        g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 static void
@@ -645,6 +704,8 @@ test_async_backward_search_wrap_around (void)
 {
        GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
 
        static SearchResult results[] =
        {
@@ -656,50 +717,41 @@ test_async_backward_search_wrap_around (void)
        };
 
        gtk_text_buffer_set_text (text_buffer, "aaaa", -1);
-       gtk_source_buffer_set_search_text (source_buffer, "aa");
-       gtk_source_buffer_set_search_wrap_around (source_buffer, TRUE);
+       gtk_source_search_settings_set_search_text (settings, "aa");
+       gtk_source_search_settings_set_wrap_around (settings, TRUE);
 
-       check_async_search_results (source_buffer, results, FALSE, TRUE);
+       check_async_search_results (context, results, FALSE, TRUE);
 
        gtk_main ();
        g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 static void
 test_highlight (void)
 {
-       GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
-       gboolean highlight;
-
-       gtk_source_buffer_set_highlight_search (source_buffer, TRUE);
-       highlight = gtk_source_buffer_get_highlight_search (source_buffer);
-       g_assert (highlight);
-
-       gtk_source_buffer_set_highlight_search (source_buffer, FALSE);
-       highlight = gtk_source_buffer_get_highlight_search (source_buffer);
-       g_assert (!highlight);
-
-       g_object_unref (source_buffer);
+       /* TODO */
 }
 
 static void
 test_get_search_text (void)
 {
-       GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
        const gchar *search_text;
 
-       search_text = gtk_source_buffer_get_search_text (source_buffer);
+       search_text = gtk_source_search_settings_get_search_text (settings);
        g_assert (search_text == NULL);
 
-       gtk_source_buffer_set_search_text (source_buffer, "");
-       search_text = gtk_source_buffer_get_search_text (source_buffer);
+       gtk_source_search_settings_set_search_text (settings, "");
+       search_text = gtk_source_search_settings_get_search_text (settings);
        g_assert (search_text == NULL);
 
-       gtk_source_buffer_set_search_text (source_buffer, "search-text");
-       search_text = gtk_source_buffer_get_search_text (source_buffer);
+       gtk_source_search_settings_set_search_text (settings, "search-text");
+       search_text = gtk_source_search_settings_get_search_text (settings);
        g_assert_cmpstr (search_text, ==, "search-text");
 
-       g_object_unref (source_buffer);
+       g_object_unref (settings);
 }
 
 static void
@@ -707,32 +759,36 @@ test_occurrence_position (void)
 {
        GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
        GtkTextIter start;
        GtkTextIter end;
        gint pos;
 
        gtk_text_buffer_set_text (text_buffer, "aaaa", -1);
-       gtk_source_buffer_set_search_text (source_buffer, "aa");
+       gtk_source_search_settings_set_search_text (settings, "aa");
        flush_queue ();
 
        gtk_text_buffer_get_start_iter (text_buffer, &start);
        end = start;
        gtk_text_iter_forward_chars (&end, 2);
 
-       pos = gtk_source_buffer_get_search_occurrence_position (source_buffer, &start, &end);
+       pos = gtk_source_search_context_get_occurrence_position (context, &start, &end);
        g_assert_cmpint (pos, ==, 1);
 
        gtk_text_iter_forward_char (&start);
        gtk_text_iter_forward_char (&end);
-       pos = gtk_source_buffer_get_search_occurrence_position (source_buffer, &start, &end);
+       pos = gtk_source_search_context_get_occurrence_position (context, &start, &end);
        g_assert_cmpint (pos, ==, 0);
 
        gtk_text_iter_forward_char (&start);
        gtk_text_iter_forward_char (&end);
-       pos = gtk_source_buffer_get_search_occurrence_position (source_buffer, &start, &end);
+       pos = gtk_source_search_context_get_occurrence_position (context, &start, &end);
        g_assert_cmpint (pos, ==, 2);
 
        g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 static void
@@ -740,25 +796,27 @@ test_replace (void)
 {
        GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
        GtkTextIter start;
        GtkTextIter end;
        gboolean replaced;
        gchar *contents;
 
        gtk_text_buffer_set_text (text_buffer, "aaaa", -1);
-       gtk_source_buffer_set_search_text (source_buffer, "aa");
+       gtk_source_search_settings_set_search_text (settings, "aa");
        flush_queue ();
 
        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_buffer_search_replace (source_buffer, &start, &end, "bb", 2);
+       replaced = gtk_source_search_context_replace (context, &start, &end, "bb", 2);
        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_buffer_search_replace (source_buffer, &start, &end, "bb", 2);
+       replaced = gtk_source_search_context_replace (context, &start, &end, "bb", 2);
        g_assert (replaced);
 
        gtk_text_buffer_get_start_iter (text_buffer, &start);
@@ -769,6 +827,8 @@ test_replace (void)
 
        g_free (contents);
        g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 static void
@@ -776,16 +836,18 @@ test_replace_all (void)
 {
        GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
        gint nb_replacements;
        GtkTextIter start;
        GtkTextIter end;
        gchar *contents;
 
        gtk_text_buffer_set_text (text_buffer, "aaaa", -1);
-       gtk_source_buffer_set_search_text (source_buffer, "aa");
+       gtk_source_search_settings_set_search_text (settings, "aa");
        flush_queue ();
 
-       nb_replacements = gtk_source_buffer_search_replace_all (source_buffer, "bb", 2);
+       nb_replacements = gtk_source_search_context_replace_all (context, "bb", 2);
        g_assert_cmpint (nb_replacements, ==, 2);
 
        gtk_text_buffer_get_start_iter (text_buffer, &start);
@@ -796,6 +858,8 @@ test_replace_all (void)
 
        g_free (contents);
        g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 static void
@@ -803,6 +867,8 @@ test_regex (void)
 {
        GtkSourceBuffer *source_buffer = gtk_source_buffer_new (NULL);
        GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
+       GtkSourceSearchSettings *settings = gtk_source_search_settings_new ();
+       GtkSourceSearchContext *context = gtk_source_search_context_new (source_buffer, settings);
        gboolean regex_enabled;
        gint occurrences_count;
        GtkTextIter start;
@@ -810,33 +876,33 @@ test_regex (void)
        gchar *contents;
 
        gtk_text_buffer_set_text (text_buffer, "hello\nworld\n", -1);
-       gtk_source_buffer_set_regex_search (source_buffer, TRUE);
-       regex_enabled = gtk_source_buffer_get_regex_search (source_buffer);
+       gtk_source_search_settings_set_regex_enabled (settings, TRUE);
+       regex_enabled = gtk_source_search_settings_get_regex_enabled (settings);
        g_assert (regex_enabled);
 
        /* Simple regex */
 
-       gtk_source_buffer_set_search_text (source_buffer, "\\w+");
+       gtk_source_search_settings_set_search_text (settings, "\\w+");
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 2);
 
        /* Test partial matching */
 
-       gtk_source_buffer_set_search_text (source_buffer, "(.*\n)*");
+       gtk_source_search_settings_set_search_text (settings, "(.*\n)*");
        flush_queue ();
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (context);
        g_assert_cmpint (occurrences_count, ==, 1);
 
        /* Test replace */
 
        gtk_text_buffer_set_text (text_buffer, "aa#bb", -1);
-       gtk_source_buffer_set_search_text (source_buffer, "(\\w+)#(\\w+)");
+       gtk_source_search_settings_set_search_text (settings, "(\\w+)#(\\w+)");
        flush_queue ();
 
        gtk_text_buffer_get_start_iter (text_buffer, &start);
        gtk_text_buffer_get_end_iter (text_buffer, &end);
-       gtk_source_buffer_search_replace (source_buffer, &start, &end, "\\2#\\1", -1);
+       gtk_source_search_context_replace (context, &start, &end, "\\2#\\1", -1);
 
        gtk_text_buffer_get_start_iter (text_buffer, &start);
        gtk_text_buffer_get_end_iter (text_buffer, &end);
@@ -847,7 +913,7 @@ test_regex (void)
        /* Test replace all */
 
        gtk_text_buffer_set_text (text_buffer, "aa#bb cc#dd", -1);
-       gtk_source_buffer_search_replace_all (source_buffer, "\\2#\\1", -1);
+       gtk_source_search_context_replace_all (context, "\\2#\\1", -1);
 
        gtk_text_buffer_get_start_iter (text_buffer, &start);
        gtk_text_buffer_get_end_iter (text_buffer, &end);
@@ -856,6 +922,8 @@ test_regex (void)
        g_free (contents);
 
        g_object_unref (source_buffer);
+       g_object_unref (settings);
+       g_object_unref (context);
 }
 
 int
diff --git a/tests/test-search-performances.c b/tests/test-search-performances.c
index cbd7c6b..a65e8c9 100644
--- a/tests/test-search-performances.c
+++ b/tests/test-search-performances.c
@@ -33,9 +33,9 @@
  */
 
 static void
-on_notify_search_occurrences_count_cb (GtkSourceBuffer *buffer,
-                                      GParamSpec      *spec,
-                                      GTimer          *timer)
+on_notify_search_occurrences_count_cb (GtkSourceSearchContext *search_context,
+                                      GParamSpec             *spec,
+                                      GTimer                 *timer)
 {
        g_print ("smart asynchronous search, case sensitive: %lf seconds.\n",
                 g_timer_elapsed (timer, NULL));
@@ -47,6 +47,8 @@ int
 main (int argc, char *argv[])
 {
        GtkSourceBuffer *buffer;
+       GtkSourceSearchContext *search_context;
+       GtkSourceSearchSettings *search_settings;
        GtkTextIter iter;
        GtkTextIter match_end;
        GTimer *timer;
@@ -124,14 +126,17 @@ main (int argc, char *argv[])
 
        /* Smart forward search, with default flags in gsv */
 
+       search_settings = gtk_source_search_settings_new ();
+       search_context = gtk_source_search_context_new (buffer, search_settings);
+
        g_timer_start (timer);
 
-       gtk_source_buffer_set_search_wrap_around (buffer, FALSE);
-       gtk_source_buffer_set_search_text (buffer, "foo");
+       gtk_source_search_settings_set_wrap_around (search_settings, FALSE);
+       gtk_source_search_settings_set_search_text (search_settings, "foo");
 
        gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
 
-       while (gtk_source_buffer_forward_search (buffer, &iter, NULL, &match_end))
+       while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end))
        {
                iter = match_end;
        }
@@ -144,13 +149,13 @@ main (int argc, char *argv[])
 
        g_timer_start (timer);
 
-       gtk_source_buffer_set_search_text (buffer, NULL);
-       gtk_source_buffer_set_case_sensitive_search (buffer, TRUE);
-       gtk_source_buffer_set_search_text (buffer, "foo");
+       gtk_source_search_settings_set_search_text (search_settings, NULL);
+       gtk_source_search_settings_set_case_sensitive (search_settings, TRUE);
+       gtk_source_search_settings_set_search_text (search_settings, "foo");
 
        gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
 
-       while (gtk_source_buffer_forward_search (buffer, &iter, NULL, &match_end))
+       while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end))
        {
                iter = match_end;
        }
@@ -168,15 +173,15 @@ main (int argc, char *argv[])
         * difference in the overhead.
         */
 
-       g_signal_connect (buffer,
-                         "notify::search-occurrences-count",
+       g_signal_connect (search_context,
+                         "notify::occurrences-count",
                          G_CALLBACK (on_notify_search_occurrences_count_cb),
                          timer);
 
        g_timer_start (timer);
 
-       gtk_source_buffer_set_search_text (buffer, NULL);
-       gtk_source_buffer_set_search_text (buffer, "foo");
+       gtk_source_search_settings_set_search_text (search_settings, NULL);
+       gtk_source_search_settings_set_search_text (search_settings, "foo");
 
        gtk_main ();
        return 0;
diff --git a/tests/test-search.c b/tests/test-search.c
index 22df00a..67c2e73 100644
--- a/tests/test-search.c
+++ b/tests/test-search.c
@@ -22,32 +22,34 @@
 #include <gtk/gtk.h>
 #include <gtksourceview/gtksource.h>
 
-#define TEST_TYPE_SEARCH_UI             (test_search_ui_get_type ())
-#define TEST_SEARCH_UI(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_SEARCH_UI, 
TestSearchUI))
-#define TEST_SEARCH_UI_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_SEARCH_UI, 
TestSearchUIClass))
-#define TEST_IS_SEARCH_UI(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_SEARCH_UI))
-#define TEST_IS_SEARCH_UI_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_SEARCH_UI))
-#define TEST_SEARCH_UI_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_SEARCH_UI, 
TestSearchUIClass))
-
-typedef struct _TestSearchUI        TestSearchUI;
-typedef struct _TestSearchUIClass   TestSearchUIClass;
-typedef struct _TestSearchUIPrivate TestSearchUIPrivate;
-
-struct _TestSearchUI
+#define TEST_TYPE_SEARCH             (test_search_get_type ())
+#define TEST_SEARCH(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_SEARCH, TestSearch))
+#define TEST_SEARCH_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_SEARCH, TestSearchClass))
+#define TEST_IS_SEARCH(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_SEARCH))
+#define TEST_IS_SEARCH_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_SEARCH))
+#define TEST_SEARCH_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_SEARCH, TestSearchClass))
+
+typedef struct _TestSearch        TestSearch;
+typedef struct _TestSearchClass   TestSearchClass;
+typedef struct _TestSearchPrivate TestSearchPrivate;
+
+struct _TestSearch
 {
        GtkGrid parent;
-       TestSearchUIPrivate *priv;
+       TestSearchPrivate *priv;
 };
 
-struct _TestSearchUIClass
+struct _TestSearchClass
 {
        GtkGridClass parent_class;
 };
 
-struct _TestSearchUIPrivate
+struct _TestSearchPrivate
 {
        GtkSourceView *source_view;
        GtkSourceBuffer *source_buffer;
+       GtkSourceSearchContext *search_context;
+       GtkSourceSearchSettings *search_settings;
        GtkEntry *replace_entry;
        GtkLabel *label_occurrences;
        GtkLabel *label_regex_error;
@@ -55,13 +57,13 @@ struct _TestSearchUIPrivate
        guint idle_update_label_id;
 };
 
-GType test_search_ui_get_type (void);
+GType test_search_get_type (void);
 
-G_DEFINE_TYPE_WITH_PRIVATE (TestSearchUI, test_search_ui, GTK_TYPE_GRID)
+G_DEFINE_TYPE_WITH_PRIVATE (TestSearch, test_search, GTK_TYPE_GRID)
 
 static void
-open_file (TestSearchUI *search,
-          const gchar  *filename)
+open_file (TestSearch  *search,
+          const gchar *filename)
 {
        gchar *contents;
        GError *error = NULL;
@@ -93,7 +95,7 @@ open_file (TestSearchUI *search,
 }
 
 static void
-update_label_occurrences (TestSearchUI *search)
+update_label_occurrences (TestSearch *search)
 {
        gint occurrences_count;
        GtkTextIter select_start;
@@ -101,15 +103,15 @@ update_label_occurrences (TestSearchUI *search)
        gint occurrence_pos;
        gchar *text;
 
-       occurrences_count = gtk_source_buffer_get_search_occurrences_count (search->priv->source_buffer);
+       occurrences_count = gtk_source_search_context_get_occurrences_count (search->priv->search_context);
 
        gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (search->priv->source_buffer),
                                              &select_start,
                                              &select_end);
 
-       occurrence_pos = gtk_source_buffer_get_search_occurrence_position (search->priv->source_buffer,
-                                                                          &select_start,
-                                                                          &select_end);
+       occurrence_pos = gtk_source_search_context_get_occurrence_position (search->priv->search_context,
+                                                                           &select_start,
+                                                                           &select_end);
 
        if (occurrences_count == -1)
        {
@@ -129,11 +131,11 @@ update_label_occurrences (TestSearchUI *search)
 }
 
 static void
-update_label_regex_error (TestSearchUI *search)
+update_label_regex_error (TestSearch *search)
 {
        GError *error;
 
-       error = gtk_source_buffer_get_regex_search_error (search->priv->source_buffer);
+       error = gtk_source_search_context_get_regex_error (search->priv->search_context);
 
        if (error == NULL)
        {
@@ -148,28 +150,19 @@ update_label_regex_error (TestSearchUI *search)
        }
 }
 
-/* The search entry is a GtkSearchEntry. The "changed" signal is delayed on a
- * GtkSearchEntry (but not with a simple GtkEntry). That's why the
- * "notify::text" signal is used instead.
- * With the "changed" signal, the search highlighting takes some time to be
- * updated, while with the notify signal, it is immediate.
- *
- * See https://bugzilla.gnome.org/show_bug.cgi?id=700229
- */
 static void
-search_entry_text_notify_cb (TestSearchUI *search,
-                            GParamSpec   *spec,
-                            GtkEntry     *entry)
+search_entry_changed_cb (TestSearch *search,
+                        GtkEntry   *entry)
 {
        const gchar *text = gtk_entry_get_text (entry);
        gchar *unescaped_text = gtk_source_utils_unescape_search_text (text);
 
-       gtk_source_buffer_set_search_text (search->priv->source_buffer, unescaped_text);
+       gtk_source_search_settings_set_search_text (search->priv->search_settings, unescaped_text);
        g_free (unescaped_text);
 }
 
 static void
-select_search_occurrence (TestSearchUI      *search,
+select_search_occurrence (TestSearch        *search,
                          const GtkTextIter *match_start,
                          const GtkTextIter *match_end)
 {
@@ -186,26 +179,26 @@ select_search_occurrence (TestSearchUI      *search,
 }
 
 static void
-backward_search_finished (GtkSourceBuffer *buffer,
-                         GAsyncResult    *result,
-                         TestSearchUI    *search)
+backward_search_finished (GtkSourceSearchContext *search_context,
+                         GAsyncResult           *result,
+                         TestSearch             *search)
 {
        GtkTextIter match_start;
        GtkTextIter match_end;
 
-       if (gtk_source_buffer_backward_search_finish (buffer,
-                                                     result,
-                                                     &match_start,
-                                                     &match_end,
-                                                     NULL))
+       if (gtk_source_search_context_backward_finish (search_context,
+                                                      result,
+                                                      &match_start,
+                                                      &match_end,
+                                                      NULL))
        {
                select_search_occurrence (search, &match_start, &match_end);
        }
 }
 
 static void
-button_previous_clicked_cb (TestSearchUI *search,
-                           GtkButton    *button)
+button_previous_clicked_cb (TestSearch *search,
+                           GtkButton  *button)
 {
        GtkTextIter start_at;
 
@@ -213,34 +206,34 @@ button_previous_clicked_cb (TestSearchUI *search,
                                              &start_at,
                                              NULL);
 
-       gtk_source_buffer_backward_search_async (search->priv->source_buffer,
-                                                &start_at,
-                                                NULL,
-                                                (GAsyncReadyCallback)backward_search_finished,
-                                                search);
+       gtk_source_search_context_backward_async (search->priv->search_context,
+                                                 &start_at,
+                                                 NULL,
+                                                 (GAsyncReadyCallback)backward_search_finished,
+                                                 search);
 }
 
 static void
-forward_search_finished (GtkSourceBuffer *buffer,
-                        GAsyncResult    *result,
-                        TestSearchUI    *search)
+forward_search_finished (GtkSourceSearchContext *search_context,
+                        GAsyncResult           *result,
+                        TestSearch             *search)
 {
        GtkTextIter match_start;
        GtkTextIter match_end;
 
-       if (gtk_source_buffer_forward_search_finish (buffer,
-                                                    result,
-                                                    &match_start,
-                                                    &match_end,
-                                                    NULL))
+       if (gtk_source_search_context_forward_finish (search_context,
+                                                     result,
+                                                     &match_start,
+                                                     &match_end,
+                                                     NULL))
        {
                select_search_occurrence (search, &match_start, &match_end);
        }
 }
 
 static void
-button_next_clicked_cb (TestSearchUI *search,
-                       GtkButton    *button)
+button_next_clicked_cb (TestSearch *search,
+                       GtkButton  *button)
 {
        GtkTextIter start_at;
 
@@ -248,16 +241,16 @@ button_next_clicked_cb (TestSearchUI *search,
                                              NULL,
                                              &start_at);
 
-       gtk_source_buffer_forward_search_async (search->priv->source_buffer,
-                                               &start_at,
-                                               NULL,
-                                               (GAsyncReadyCallback)forward_search_finished,
-                                               search);
+       gtk_source_search_context_forward_async (search->priv->search_context,
+                                                &start_at,
+                                                NULL,
+                                                (GAsyncReadyCallback)forward_search_finished,
+                                                search);
 }
 
 static void
-button_replace_clicked_cb (TestSearchUI *search,
-                          GtkButton    *button)
+button_replace_clicked_cb (TestSearch *search,
+                          GtkButton  *button)
 {
        GtkTextIter match_start;
        GtkTextIter match_end;
@@ -272,37 +265,37 @@ button_replace_clicked_cb (TestSearchUI *search,
        entry_buffer = gtk_entry_get_buffer (search->priv->replace_entry);
        replace_length = gtk_entry_buffer_get_bytes (entry_buffer);
 
-       gtk_source_buffer_search_replace (search->priv->source_buffer,
-                                         &match_start,
-                                         &match_end,
-                                         gtk_entry_get_text (search->priv->replace_entry),
-                                         replace_length);
+       gtk_source_search_context_replace (search->priv->search_context,
+                                          &match_start,
+                                          &match_end,
+                                          gtk_entry_get_text (search->priv->replace_entry),
+                                          replace_length);
 
        gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (search->priv->source_buffer),
                                              NULL,
                                              &iter);
 
-       gtk_source_buffer_forward_search_async (search->priv->source_buffer,
-                                               &iter,
-                                               NULL,
-                                               (GAsyncReadyCallback)forward_search_finished,
-                                               search);
+       gtk_source_search_context_forward_async (search->priv->search_context,
+                                                &iter,
+                                                NULL,
+                                                (GAsyncReadyCallback)forward_search_finished,
+                                                search);
 }
 
 static void
-button_replace_all_clicked_cb (TestSearchUI *search,
-                              GtkButton    *button)
+button_replace_all_clicked_cb (TestSearch *search,
+                              GtkButton  *button)
 {
        GtkEntryBuffer *entry_buffer = gtk_entry_get_buffer (search->priv->replace_entry);
        gint replace_length = gtk_entry_buffer_get_bytes (entry_buffer);
 
-       gtk_source_buffer_search_replace_all (search->priv->source_buffer,
-                                             gtk_entry_get_text (search->priv->replace_entry),
-                                             replace_length);
+       gtk_source_search_context_replace_all (search->priv->search_context,
+                                              gtk_entry_get_text (search->priv->replace_entry),
+                                              replace_length);
 }
 
 static gboolean
-update_label_idle_cb (TestSearchUI *search)
+update_label_idle_cb (TestSearch *search)
 {
        search->priv->idle_update_label_id = 0;
 
@@ -315,7 +308,7 @@ static void
 mark_set_cb (GtkTextBuffer *buffer,
             GtkTextIter   *location,
             GtkTextMark   *mark,
-            TestSearchUI  *search)
+            TestSearch    *search)
 {
        GtkTextMark *insert;
        GtkTextMark *selection_bound;
@@ -332,72 +325,73 @@ mark_set_cb (GtkTextBuffer *buffer,
 }
 
 static void
-highlight_toggled_cb (TestSearchUI    *search,
+highlight_toggled_cb (TestSearch      *search,
                      GtkToggleButton *button)
 {
-       gtk_source_buffer_set_highlight_search (search->priv->source_buffer,
-                                               gtk_toggle_button_get_active (button));
+       /* TODO */
 }
 
 static void
-match_case_toggled_cb (TestSearchUI    *search,
+match_case_toggled_cb (TestSearch      *search,
                       GtkToggleButton *button)
 {
-       gtk_source_buffer_set_case_sensitive_search (search->priv->source_buffer,
-                                                    gtk_toggle_button_get_active (button));
+       gtk_source_search_settings_set_case_sensitive (search->priv->search_settings,
+                                                      gtk_toggle_button_get_active (button));
 }
 
 static void
-at_word_boundaries_toggled_cb (TestSearchUI    *search,
+at_word_boundaries_toggled_cb (TestSearch      *search,
                               GtkToggleButton *button)
 {
-       gtk_source_buffer_set_search_at_word_boundaries (search->priv->source_buffer,
-                                                        gtk_toggle_button_get_active (button));
+       gtk_source_search_settings_set_at_word_boundaries (search->priv->search_settings,
+                                                          gtk_toggle_button_get_active (button));
 }
 
 static void
-wrap_around_toggled_cb (TestSearchUI    *search,
-                       GtkToggleButton *button)
+wrap_around_toggled_cb (TestSearch      *search,
+                       GtkToggleButton *button)
 {
-       gtk_source_buffer_set_search_wrap_around (search->priv->source_buffer,
-                                                 gtk_toggle_button_get_active (button));
+       gtk_source_search_settings_set_wrap_around (search->priv->search_settings,
+                                                   gtk_toggle_button_get_active (button));
 }
 
 static void
-regex_toggled_cb (TestSearchUI    *search,
+regex_toggled_cb (TestSearch      *search,
                  GtkToggleButton *button)
 {
-       gtk_source_buffer_set_regex_search (search->priv->source_buffer,
-                                           gtk_toggle_button_get_active (button));
+       gtk_source_search_settings_set_regex_enabled (search->priv->search_settings,
+                                                     gtk_toggle_button_get_active (button));
 }
 
 static void
-test_search_ui_dispose (GObject *object)
+test_search_dispose (GObject *object)
 {
-       TestSearchUI *search = TEST_SEARCH_UI (object);
+       TestSearch *search = TEST_SEARCH (object);
 
        g_clear_object (&search->priv->source_buffer);
+       g_clear_object (&search->priv->search_context);
+       g_clear_object (&search->priv->search_settings);
 
-       G_OBJECT_CLASS (test_search_ui_parent_class)->dispose (object);
+       G_OBJECT_CLASS (test_search_parent_class)->dispose (object);
 }
 
 static void
-test_search_ui_class_init (TestSearchUIClass *klass)
+test_search_class_init (TestSearchClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
-       object_class->dispose = test_search_ui_dispose;
+       object_class->dispose = test_search_dispose;
 
        gtk_widget_class_set_template_from_resource (widget_class,
                                                     "/org/gnome/gtksourceview/tests/ui/test-search.ui");
 
-       gtk_widget_class_bind_template_child_private (widget_class, TestSearchUI, source_view);
-       gtk_widget_class_bind_template_child_private (widget_class, TestSearchUI, replace_entry);
-       gtk_widget_class_bind_template_child_private (widget_class, TestSearchUI, label_occurrences);
-       gtk_widget_class_bind_template_child_private (widget_class, TestSearchUI, label_regex_error);
+       gtk_widget_class_bind_template_child_private (widget_class, TestSearch, source_view);
+       gtk_widget_class_bind_template_child_private (widget_class, TestSearch, replace_entry);
+       gtk_widget_class_bind_template_child_private (widget_class, TestSearch, label_occurrences);
+       gtk_widget_class_bind_template_child_private (widget_class, TestSearch, label_regex_error);
 
-       gtk_widget_class_bind_template_callback (widget_class, search_entry_text_notify_cb);
+       gtk_widget_class_bind_template_callback (widget_class, search_entry_changed_cb);
        gtk_widget_class_bind_template_callback (widget_class, button_previous_clicked_cb);
        gtk_widget_class_bind_template_callback (widget_class, button_next_clicked_cb);
        gtk_widget_class_bind_template_callback (widget_class, button_replace_clicked_cb);
@@ -415,11 +409,11 @@ test_search_ui_class_init (TestSearchUIClass *klass)
 }
 
 static void
-test_search_ui_init (TestSearchUI *search)
+test_search_init (TestSearch *search)
 {
        PangoFontDescription *font;
 
-       search->priv = test_search_ui_get_instance_private (search);
+       search->priv = test_search_get_instance_private (search);
 
        gtk_widget_init_template (GTK_WIDGET (search));
 
@@ -437,8 +431,13 @@ test_search_ui_init (TestSearchUI *search)
 
        open_file (search, TOP_SRCDIR "/gtksourceview/gtksourcesearchcontext.c");
 
-       g_signal_connect_swapped (search->priv->source_buffer,
-                                 "notify::search-occurrences-count",
+       search->priv->search_settings = gtk_source_search_settings_new ();
+
+       search->priv->search_context = gtk_source_search_context_new (search->priv->source_buffer,
+                                                                     search->priv->search_settings);
+
+       g_signal_connect_swapped (search->priv->search_context,
+                                 "notify::occurrences-count",
                                  G_CALLBACK (update_label_occurrences),
                                  search);
 
@@ -447,25 +446,25 @@ test_search_ui_init (TestSearchUI *search)
                          G_CALLBACK (mark_set_cb),
                          search);
 
-       g_signal_connect_swapped (search->priv->source_buffer,
-                                 "notify::regex-search-error",
+       g_signal_connect_swapped (search->priv->search_context,
+                                 "notify::regex-error",
                                  G_CALLBACK (update_label_regex_error),
                                  search);
 
        update_label_regex_error (search);
 }
 
-static TestSearchUI *
-test_search_ui_new (void)
+static TestSearch *
+test_search_new (void)
 {
-       return g_object_new (test_search_ui_get_type (), NULL);
+       return g_object_new (test_search_get_type (), NULL);
 }
 
 gint
 main (gint argc, gchar *argv[])
 {
        GtkWidget *window;
-       TestSearchUI *search;
+       TestSearch *search;
 
        gtk_init (&argc, &argv);
 
@@ -478,7 +477,7 @@ main (gint argc, gchar *argv[])
                          G_CALLBACK (gtk_main_quit),
                          NULL);
 
-       search = test_search_ui_new ();
+       search = test_search_new ();
        gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (search));
 
        gtk_widget_show (window);
diff --git a/tests/test-search.ui b/tests/test-search.ui
index 9fbab66..c4d3e3b 100644
--- a/tests/test-search.ui
+++ b/tests/test-search.ui
@@ -26,7 +26,7 @@
     <property name="stock">gtk-find-and-replace</property>
     <property name="icon_size">1</property>
   </object>
-  <template class="TestSearchUI" parent="GtkGrid">
+  <template class="TestSearch" parent="GtkGrid">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
     <property name="border_width">6</property>
@@ -88,7 +88,7 @@
             <property name="primary_icon_name">edit-find-symbolic</property>
             <property name="primary_icon_activatable">False</property>
             <property name="primary_icon_sensitive">False</property>
-            <signal name="notify::text" handler="search_entry_text_notify_cb" object="TestSearchUI" 
swapped="yes"/>
+            <signal name="changed" handler="search_entry_changed_cb" object="TestSearch" swapped="yes"/>
           </object>
           <packing>
             <property name="left_attach">1</property>
@@ -118,7 +118,7 @@
             <property name="receives_default">True</property>
             <property name="halign">start</property>
             <property name="image">image1</property>
-            <signal name="clicked" handler="button_previous_clicked_cb" object="TestSearchUI" swapped="yes"/>
+            <signal name="clicked" handler="button_previous_clicked_cb" object="TestSearch" swapped="yes"/>
           </object>
           <packing>
             <property name="left_attach">2</property>
@@ -134,7 +134,7 @@
             <property name="receives_default">True</property>
             <property name="halign">start</property>
             <property name="image">image2</property>
-            <signal name="clicked" handler="button_next_clicked_cb" object="TestSearchUI" swapped="yes"/>
+            <signal name="clicked" handler="button_next_clicked_cb" object="TestSearch" swapped="yes"/>
           </object>
           <packing>
             <property name="left_attach">3</property>
@@ -186,7 +186,7 @@
             <property name="receives_default">False</property>
             <property name="xalign">0</property>
             <property name="draw_indicator">True</property>
-            <signal name="toggled" handler="match_case_toggled_cb" object="TestSearchUI" swapped="yes"/>
+            <signal name="toggled" handler="match_case_toggled_cb" object="TestSearch" swapped="yes"/>
           </object>
           <packing>
             <property name="left_attach">0</property>
@@ -203,7 +203,7 @@
             <property name="receives_default">False</property>
             <property name="xalign">0</property>
             <property name="draw_indicator">True</property>
-            <signal name="toggled" handler="at_word_boundaries_toggled_cb" object="TestSearchUI" 
swapped="yes"/>
+            <signal name="toggled" handler="at_word_boundaries_toggled_cb" object="TestSearch" 
swapped="yes"/>
           </object>
           <packing>
             <property name="left_attach">0</property>
@@ -221,7 +221,7 @@
             <property name="xalign">0</property>
             <property name="active">True</property>
             <property name="draw_indicator">True</property>
-            <signal name="toggled" handler="wrap_around_toggled_cb" object="TestSearchUI" swapped="yes"/>
+            <signal name="toggled" handler="wrap_around_toggled_cb" object="TestSearch" swapped="yes"/>
           </object>
           <packing>
             <property name="left_attach">0</property>
@@ -239,7 +239,7 @@
             <property name="xalign">0</property>
             <property name="active">True</property>
             <property name="draw_indicator">True</property>
-            <signal name="toggled" handler="highlight_toggled_cb" object="TestSearchUI" swapped="yes"/>
+            <signal name="toggled" handler="highlight_toggled_cb" object="TestSearch" swapped="yes"/>
           </object>
           <packing>
             <property name="left_attach">0</property>
@@ -256,7 +256,7 @@
             <property name="receives_default">False</property>
             <property name="xalign">0</property>
             <property name="draw_indicator">True</property>
-            <signal name="toggled" handler="regex_toggled_cb" object="TestSearchUI" swapped="yes"/>
+            <signal name="toggled" handler="regex_toggled_cb" object="TestSearch" swapped="yes"/>
           </object>
           <packing>
             <property name="left_attach">0</property>
@@ -314,7 +314,7 @@
             <property name="can_focus">True</property>
             <property name="receives_default">True</property>
             <property name="image">image3</property>
-            <signal name="clicked" handler="button_replace_clicked_cb" object="TestSearchUI" swapped="yes"/>
+            <signal name="clicked" handler="button_replace_clicked_cb" object="TestSearch" swapped="yes"/>
           </object>
           <packing>
             <property name="left_attach">2</property>
@@ -331,7 +331,7 @@
             <property name="receives_default">True</property>
             <property name="image">image4</property>
             <property name="always_show_image">True</property>
-            <signal name="clicked" handler="button_replace_all_clicked_cb" object="TestSearchUI" 
swapped="yes"/>
+            <signal name="clicked" handler="button_replace_all_clicked_cb" object="TestSearch" 
swapped="yes"/>
           </object>
           <packing>
             <property name="left_attach">3</property>


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