summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xpluma/dialogs/pluma-search-dialog.c20
-rwxr-xr-xpluma/dialogs/pluma-search-dialog.h4
-rw-r--r--pluma/dialogs/pluma-search-dialog.ui27
-rw-r--r--pluma/pluma-commands-search.c41
-rw-r--r--pluma/pluma-document.c109
-rw-r--r--pluma/pluma-document.h8
-rw-r--r--pluma/pluma-utils.c127
-rw-r--r--pluma/pluma-utils.h10
8 files changed, 296 insertions, 50 deletions
diff --git a/pluma/dialogs/pluma-search-dialog.c b/pluma/dialogs/pluma-search-dialog.c
index 329e1721..a77701c0 100755
--- a/pluma/dialogs/pluma-search-dialog.c
+++ b/pluma/dialogs/pluma-search-dialog.c
@@ -68,6 +68,7 @@ struct _PlumaSearchDialogPrivate
GtkWidget *replace_entry;
GtkWidget *replace_text_entry;
GtkWidget *match_case_checkbutton;
+ GtkWidget *match_regex_checkbutton;
GtkWidget *entire_word_checkbutton;
GtkWidget *backwards_checkbutton;
GtkWidget *wrap_around_checkbutton;
@@ -352,6 +353,7 @@ pluma_search_dialog_init (PlumaSearchDialog *dlg)
"search_label", &dlg->priv->search_label,
"replace_with_label", &dlg->priv->replace_label,
"match_case_checkbutton", &dlg->priv->match_case_checkbutton,
+ "match_regex_checkbutton",&dlg->priv->match_regex_checkbutton,
"entire_word_checkbutton", &dlg->priv->entire_word_checkbutton,
"search_backwards_checkbutton", &dlg->priv->backwards_checkbutton,
"wrap_around_checkbutton", &dlg->priv->wrap_around_checkbutton,
@@ -583,6 +585,24 @@ pluma_search_dialog_get_match_case (PlumaSearchDialog *dialog)
}
void
+pluma_search_dialog_set_match_regex (PlumaSearchDialog *dialog,
+ gboolean match_case)
+{
+ g_return_if_fail (PLUMA_IS_SEARCH_DIALOG (dialog));
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->match_regex_checkbutton),
+ match_case);
+}
+
+gboolean
+pluma_search_dialog_get_match_regex (PlumaSearchDialog *dialog)
+{
+ g_return_val_if_fail (PLUMA_IS_SEARCH_DIALOG (dialog), FALSE);
+
+ return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->match_regex_checkbutton));
+}
+
+void
pluma_search_dialog_set_entire_word (PlumaSearchDialog *dialog,
gboolean entire_word)
{
diff --git a/pluma/dialogs/pluma-search-dialog.h b/pluma/dialogs/pluma-search-dialog.h
index fb92efba..e6ebe8dc 100755
--- a/pluma/dialogs/pluma-search-dialog.h
+++ b/pluma/dialogs/pluma-search-dialog.h
@@ -111,6 +111,10 @@ void pluma_search_dialog_set_match_case (PlumaSearchDialog *dialog,
gboolean match_case);
gboolean pluma_search_dialog_get_match_case (PlumaSearchDialog *dialog);
+void pluma_search_dialog_set_match_regex (PlumaSearchDialog *dialog,
+ gboolean match_case);
+gboolean pluma_search_dialog_get_match_regex (PlumaSearchDialog *dialog);
+
void pluma_search_dialog_set_entire_word (PlumaSearchDialog *dialog,
gboolean entire_word);
gboolean pluma_search_dialog_get_entire_word (PlumaSearchDialog *dialog);
diff --git a/pluma/dialogs/pluma-search-dialog.ui b/pluma/dialogs/pluma-search-dialog.ui
index a1a37b5d..b7b70aca 100644
--- a/pluma/dialogs/pluma-search-dialog.ui
+++ b/pluma/dialogs/pluma-search-dialog.ui
@@ -181,6 +181,22 @@ Author: Wolfgang Ulbrich
</packing>
</child>
<child>
+ <object class="GtkCheckButton" id="match_regex_checkbutton">
+ <property name="label" translatable="yes">Match _regular expression</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkCheckButton" id="entire_word_checkbutton">
<property name="label" translatable="yes">Match _entire word only</property>
<property name="visible">True</property>
@@ -193,7 +209,7 @@ Author: Wolfgang Ulbrich
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
<child>
@@ -209,7 +225,7 @@ Author: Wolfgang Ulbrich
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
- <property name="position">2</property>
+ <property name="position">3</property>
</packing>
</child>
<child>
@@ -226,7 +242,7 @@ Author: Wolfgang Ulbrich
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
- <property name="position">3</property>
+ <property name="position">4</property>
</packing>
</child>
<child>
@@ -243,7 +259,7 @@ Author: Wolfgang Ulbrich
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
- <property name="position">4</property>
+ <property name="position">5</property>
</packing>
</child>
</object>
@@ -268,5 +284,8 @@ Author: Wolfgang Ulbrich
<action-widget response="0">replace_button</action-widget>
<action-widget response="0">find_next_button</action-widget>
</action-widgets>
+ <child>
+ <placeholder/>
+ </child>
</object>
</interface>
diff --git a/pluma/pluma-commands-search.c b/pluma/pluma-commands-search.c
index 1a75dbca..f4db2479 100644
--- a/pluma/pluma-commands-search.c
+++ b/pluma/pluma-commands-search.c
@@ -227,6 +227,7 @@ do_find (PlumaSearchDialog *dialog,
gchar *search_text;
const gchar *entry_text;
gboolean match_case;
+ gboolean match_regex;
gboolean entire_word;
gboolean wrap_around;
gboolean search_backwards;
@@ -244,6 +245,7 @@ do_find (PlumaSearchDialog *dialog,
doc = PLUMA_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view)));
match_case = pluma_search_dialog_get_match_case (dialog);
+ match_regex = pluma_search_dialog_get_match_regex(dialog);
entire_word = pluma_search_dialog_get_entire_word (dialog);
search_backwards = pluma_search_dialog_get_backwards (dialog);
wrap_around = pluma_search_dialog_get_wrap_around (dialog);
@@ -257,6 +259,7 @@ do_find (PlumaSearchDialog *dialog,
PLUMA_SEARCH_SET_CASE_SENSITIVE (flags, match_case);
PLUMA_SEARCH_SET_ENTIRE_WORD (flags, entire_word);
+ PLUMA_SEARCH_SET_MATCH_REGEX (flags, match_regex);
search_text = pluma_document_get_search_text (doc, &old_flags);
@@ -342,7 +345,9 @@ do_replace (PlumaSearchDialog *dialog,
gchar *unescaped_replace_text;
gchar *selected_text = NULL;
gboolean match_case;
+ gboolean match_regex;
gboolean parse_escapes;
+ gboolean need_refind;
doc = pluma_window_get_active_document (window);
if (doc == NULL)
@@ -372,17 +377,36 @@ do_replace (PlumaSearchDialog *dialog,
NULL);
match_case = pluma_search_dialog_get_match_case (dialog);
+ match_regex = pluma_search_dialog_get_match_regex(dialog);
+
+ if (selected_text != NULL)
+ {
+ if(!match_regex)
+ {
+ need_refind = (match_case && (strcmp (selected_text,unescaped_search_text) != 0))
+ || (!match_case && !g_utf8_caselessnmatch (selected_text,
+ unescaped_search_text,
+ strlen (selected_text),
+ strlen (unescaped_search_text)) != 0);
+ }
+ else
+ {
+ need_refind = !g_regex_match_simple(unescaped_search_text,
+ selected_text,
+ match_case ? 0 : GTK_TEXT_SEARCH_CASE_INSENSITIVE ,
+ 0);
+ }
+ }
+ else
+ {
+ need_refind = TRUE;
+ }
- if ((selected_text == NULL) ||
- (match_case && (strcmp (selected_text, unescaped_search_text) != 0)) ||
- (!match_case && !g_utf8_caselessnmatch (selected_text,
- unescaped_search_text,
- strlen (selected_text),
- strlen (unescaped_search_text)) != 0))
+ if (need_refind)
{
do_find (dialog, window);
g_free (unescaped_search_text);
- g_free (selected_text);
+ g_free (selected_text);
return;
}
@@ -406,6 +430,7 @@ do_replace_all (PlumaSearchDialog *dialog,
const gchar *search_entry_text;
const gchar *replace_entry_text;
gboolean match_case;
+ gboolean match_regex;
gboolean entire_word;
gboolean parse_escapes;
guint flags = 0;
@@ -435,9 +460,11 @@ do_replace_all (PlumaSearchDialog *dialog,
g_return_if_fail ((replace_entry_text) != NULL);
match_case = pluma_search_dialog_get_match_case (dialog);
+ match_regex = pluma_search_dialog_get_match_regex(dialog);
entire_word = pluma_search_dialog_get_entire_word (dialog);
PLUMA_SEARCH_SET_CASE_SENSITIVE (flags, match_case);
+ PLUMA_SEARCH_SET_MATCH_REGEX (flags, match_regex);
PLUMA_SEARCH_SET_ENTIRE_WORD (flags, entire_word);
count = pluma_document_replace_all (doc,
diff --git a/pluma/pluma-document.c b/pluma/pluma-document.c
index ed8ca1fa..8634636f 100644
--- a/pluma/pluma-document.c
+++ b/pluma/pluma-document.c
@@ -1922,13 +1922,24 @@ pluma_document_search_forward (PlumaDocument *doc,
while (!found)
{
+ if(!PLUMA_SEARCH_IS_MATCH_REGEX(doc->priv->search_flags))
+ {
found = gtk_text_iter_forward_search (&iter,
- doc->priv->search_text,
- search_flags,
- &m_start,
- &m_end,
- end);
-
+ doc->priv->search_text,
+ search_flags,
+ &m_start,
+ &m_end,
+ end);
+ }else{
+ found = pluma_gtk_text_iter_regex_search (&iter,
+ doc->priv->search_text,
+ search_flags,
+ &m_start,
+ &m_end,
+ end,
+ TRUE);
+ }
+
if (found && PLUMA_SEARCH_IS_ENTIRE_WORD (doc->priv->search_flags))
{
found = gtk_text_iter_starts_word (&m_start) &&
@@ -1960,23 +1971,23 @@ pluma_document_search_forward (PlumaDocument *doc,
**/
gboolean
pluma_document_search_backward (PlumaDocument *doc,
- const GtkTextIter *start,
- const GtkTextIter *end,
- GtkTextIter *match_start,
- GtkTextIter *match_end)
+ const GtkTextIter *start,
+ const GtkTextIter *end,
+ GtkTextIter *match_start,
+ GtkTextIter *match_end)
{
GtkTextIter iter;
GtkTextSearchFlags search_flags;
gboolean found = FALSE;
GtkTextIter m_start;
GtkTextIter m_end;
-
+
g_return_val_if_fail (PLUMA_IS_DOCUMENT (doc), FALSE);
- g_return_val_if_fail ((start == NULL) ||
- (gtk_text_iter_get_buffer (start) == GTK_TEXT_BUFFER (doc)), FALSE);
- g_return_val_if_fail ((end == NULL) ||
+ g_return_val_if_fail ((start == NULL) ||
+( gtk_text_iter_get_buffer (start) == GTK_TEXT_BUFFER (doc)), FALSE);
+ g_return_val_if_fail ((end == NULL) ||
(gtk_text_iter_get_buffer (end) == GTK_TEXT_BUFFER (doc)), FALSE);
-
+
if (doc->priv->search_text == NULL)
{
pluma_debug_message (DEBUG_DOCUMENT, "doc->priv->search_text == NULL\n");
@@ -1984,7 +1995,7 @@ pluma_document_search_backward (PlumaDocument *doc,
}
else
pluma_debug_message (DEBUG_DOCUMENT, "doc->priv->search_text == \"%s\"\n", doc->priv->search_text);
-
+
if (end == NULL)
gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &iter);
else
@@ -1999,32 +2010,45 @@ pluma_document_search_backward (PlumaDocument *doc,
while (!found)
{
- found = gtk_text_iter_backward_search (&iter,
- doc->priv->search_text,
- search_flags,
- &m_start,
- &m_end,
- start);
-
+ if(!PLUMA_SEARCH_IS_MATCH_REGEX(doc->priv->search_flags))
+ {
+ found = gtk_text_iter_backward_search (&iter,
+ doc->priv->search_text,
+ search_flags,
+ &m_start,
+ &m_end,
+ start);
+ }
+ else
+ {
+ found = pluma_gtk_text_iter_regex_search (&iter,
+ doc->priv->search_text,
+ search_flags,
+ &m_start,
+ &m_end,
+ end,
+ FALSE);
+ }
+
if (found && PLUMA_SEARCH_IS_ENTIRE_WORD (doc->priv->search_flags))
{
- found = gtk_text_iter_starts_word (&m_start) &&
- gtk_text_iter_ends_word (&m_end);
+ found = gtk_text_iter_starts_word (&m_start) &&
+ gtk_text_iter_ends_word (&m_end);
- if (!found)
+ if (!found)
iter = m_start;
}
else
break;
}
-
+
if (found && (match_start != NULL))
*match_start = m_start;
-
+
if (found && (match_end != NULL))
*match_end = m_end;
-
- return found;
+
+ return found;
}
/* FIXME this is an issue for introspection regardning @find */
@@ -2089,12 +2113,23 @@ pluma_document_replace_all (PlumaDocument *doc,
do
{
- found = gtk_text_iter_forward_search (&iter,
- search_text,
- search_flags,
- &m_start,
- &m_end,
- NULL);
+ if(!PLUMA_SEARCH_IS_MATCH_REGEX(flags))
+ {
+ found = gtk_text_iter_forward_search (&iter,
+ search_text,
+ search_flags,
+ &m_start,
+ &m_end,
+ NULL);
+ }else{
+ found = pluma_gtk_text_iter_regex_search (&iter,
+ search_text,
+ search_flags,
+ &m_start,
+ &m_end,
+ NULL,
+ TRUE);
+ }
if (found && PLUMA_SEARCH_IS_ENTIRE_WORD (flags))
{
@@ -2123,7 +2158,7 @@ pluma_document_replace_all (PlumaDocument *doc,
replace_text_len);
iter = m_start;
- }
+ }
} while (found);
diff --git a/pluma/pluma-document.h b/pluma/pluma-document.h
index 6d90323e..a8d64895 100644
--- a/pluma/pluma-document.h
+++ b/pluma/pluma-document.h
@@ -69,7 +69,8 @@ typedef enum
PLUMA_SEARCH_DONT_SET_FLAGS = 1 << 0,
PLUMA_SEARCH_ENTIRE_WORD = 1 << 1,
PLUMA_SEARCH_CASE_SENSITIVE = 1 << 2,
- PLUMA_SEARCH_PARSE_ESCAPES = 1 << 3
+ PLUMA_SEARCH_PARSE_ESCAPES = 1 << 3,
+ PLUMA_SEARCH_MATCH_REGEX = 1 << 4,
} PlumaSearchFlags;
@@ -317,6 +318,11 @@ void _pluma_document_search_region (PlumaDocument *doc,
#define PLUMA_SEARCH_SET_PARSE_ESCAPES(sflags,state) ((state == TRUE) ? \
(sflags |= PLUMA_SEARCH_PARSE_ESCAPES) : (sflags &= ~PLUMA_SEARCH_PARSE_ESCAPES))
+#define PLUMA_SEARCH_IS_MATCH_REGEX(sflags) ((sflags & PLUMA_SEARCH_MATCH_REGEX) != 0)
+#define PLUMA_SEARCH_SET_MATCH_REGEX(sflags,state) ((state == TRUE) ? \
+(sflags |= PLUMA_SEARCH_MATCH_REGEX) : (sflags &= ~PLUMA_SEARCH_MATCH_REGEX))
+
+
typedef GMountOperation *(*PlumaMountOperationFactory)(PlumaDocument *doc,
gpointer userdata);
diff --git a/pluma/pluma-utils.c b/pluma/pluma-utils.c
index a739401a..b8f081c0 100644
--- a/pluma/pluma-utils.c
+++ b/pluma/pluma-utils.c
@@ -1578,3 +1578,130 @@ pluma_utils_decode_uri (const gchar *uri,
return TRUE;
}
+
+gboolean
+pluma_gtk_text_iter_regex_search (const GtkTextIter *iter,
+ const gchar *str,
+ GtkTextSearchFlags flags,
+ GtkTextIter *match_start,
+ GtkTextIter *match_end,
+ const GtkTextIter *limit,
+ gboolean forward_search)
+{
+ GRegex *regex;
+ GRegexCompileFlags compile_flags;
+ GMatchInfo *match_info;
+ gchar *text;
+ GtkTextIter *begin_iter;
+ GtkTextIter *end_iter;
+ gchar **all_matches;
+ gchar *match_string;
+ gboolean found;
+ gint non_null_result_number;
+ gboolean non_null_result_found;
+ guint result_size;
+
+ compile_flags = 0;
+ if ((flags & GTK_TEXT_SEARCH_CASE_INSENSITIVE) != 0)
+ compile_flags |= G_REGEX_CASELESS;
+
+ regex = g_regex_new (str,compile_flags,0,NULL);
+ if (regex == NULL)
+ return FALSE;
+
+ begin_iter = gtk_text_iter_copy (iter);
+ if (limit == NULL)
+ {
+ end_iter = gtk_text_iter_copy (begin_iter);
+ if (forward_search)
+ {
+ gtk_text_buffer_get_end_iter (gtk_text_iter_get_buffer(begin_iter),
+ end_iter);
+ }
+ else
+ {
+ gtk_text_buffer_get_start_iter (gtk_text_iter_get_buffer (begin_iter),
+ end_iter);
+ }
+ }
+ else
+ {
+ end_iter = gtk_text_iter_copy (limit);
+ }
+
+ if ((flags & GTK_TEXT_SEARCH_TEXT_ONLY) != 0)
+ {
+ if ((flags & GTK_TEXT_SEARCH_VISIBLE_ONLY) != 0)
+ text = gtk_text_iter_get_visible_text (begin_iter, end_iter);
+ else
+ text = gtk_text_iter_get_text (begin_iter, end_iter);
+ }
+ else
+ {
+ if ((flags & GTK_TEXT_SEARCH_VISIBLE_ONLY) != 0)
+ text = gtk_text_iter_get_visible_slice (begin_iter, end_iter);
+ else
+ text = gtk_text_iter_get_slice (begin_iter, end_iter);
+ }
+
+ found = g_regex_match_all (regex,text,0,&match_info);
+ if (found)
+ {
+ all_matches = g_match_info_fetch_all (match_info);
+ result_size = (gint) g_strv_length (all_matches);
+
+ if(forward_search){
+ non_null_result_number = 0;
+ } else {
+ non_null_result_number = result_size - 1 ;
+ }
+ non_null_result_found = FALSE;
+ while((non_null_result_number >= 0)
+ && (non_null_result_number < result_size) ) {
+
+ if(g_utf8_strlen (all_matches [non_null_result_number], G_MAXSSIZE) != 0) {
+ non_null_result_found = TRUE;
+ break;
+ } else {
+ if(forward_search) {
+ non_null_result_number++;
+ } else {
+ non_null_result_number--;
+ }
+ }
+
+ }
+
+ if(!non_null_result_found) {
+ found = FALSE;
+ goto free_resources;
+ }
+
+ match_string = all_matches [non_null_result_number];
+ if (forward_search)
+ {
+ gtk_text_iter_forward_search (begin_iter,
+ match_string,
+ flags,
+ match_start,
+ match_end,
+ limit);
+ }
+ else
+ {
+ gtk_text_iter_backward_search (begin_iter,
+ match_string,
+ flags,
+ match_start,
+ match_end,
+ limit);
+ }
+ }
+
+free_resources:
+ gtk_text_iter_free (begin_iter);
+ gtk_text_iter_free (end_iter);
+ g_match_info_free (match_info);
+ g_regex_unref (regex);
+ return found;
+}
diff --git a/pluma/pluma-utils.h b/pluma/pluma-utils.h
index a73926d2..e9dd0a5b 100644
--- a/pluma/pluma-utils.h
+++ b/pluma/pluma-utils.h
@@ -149,8 +149,16 @@ gboolean pluma_utils_decode_uri (const gchar *uri,
/* Turns data from a drop into a list of well formatted uris */
gchar **pluma_utils_drop_get_uris (GtkSelectionData *selection_data);
+/* Provides regexp forward search */
+gboolean
+pluma_gtk_text_iter_regex_search (const GtkTextIter *iter,
+ const gchar *str,
+ GtkTextSearchFlags flags,
+ GtkTextIter *match_start,
+ GtkTextIter *match_end,
+ const GtkTextIter *limit, gboolean forward_search);
+
G_END_DECLS
#endif /* __PLUMA_UTILS_H__ */
-