summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorV.Barkov <[email protected]>2016-11-20 09:36:10 +0300
committerV.Barkov <[email protected]>2016-11-20 09:36:10 +0300
commit206d27c66761cedebec8bedcaa91bf9f08846095 (patch)
tree33d97b7ecc39bb50a26bcb5a745e462dd5624d63
parent49be92055f3f3319b9149b991d5b55a5ba99d453 (diff)
downloadpluma-206d27c66761cedebec8bedcaa91bf9f08846095.tar.bz2
pluma-206d27c66761cedebec8bedcaa91bf9f08846095.tar.xz
Implemented regexp finding
-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.c3
-rw-r--r--pluma/pluma-document.c165
-rw-r--r--pluma/pluma-document.h8
-rw-r--r--pluma/pluma-utils.c95
-rw-r--r--pluma/pluma-utils.h9
8 files changed, 255 insertions, 76 deletions
diff --git a/pluma/dialogs/pluma-search-dialog.c b/pluma/dialogs/pluma-search-dialog.c
index 329e1721..6263b937 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..03b8048a 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);
diff --git a/pluma/pluma-document.c b/pluma/pluma-document.c
index 85890566..43abf989 100644
--- a/pluma/pluma-document.c
+++ b/pluma/pluma-document.c
@@ -1919,12 +1919,23 @@ pluma_document_search_forward (PlumaDocument *doc,
while (!found)
{
- found = gtk_text_iter_forward_search (&iter,
- doc->priv->search_text,
- search_flags,
- &m_start,
- &m_end,
- end);
+ 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);
+ }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))
{
@@ -1957,71 +1968,83 @@ 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)
-{
- 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) ||
- (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");
- return FALSE;
- }
- 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
- iter = *end;
-
- search_flags = GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY;
-
- if (!PLUMA_SEARCH_IS_CASE_SENSITIVE (doc->priv->search_flags))
- {
- search_flags = search_flags | GTK_TEXT_SEARCH_CASE_INSENSITIVE;
- }
-
- while (!found)
- {
- found = gtk_text_iter_backward_search (&iter,
- doc->priv->search_text,
- search_flags,
- &m_start,
- &m_end,
- start);
-
- 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);
-
- 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;
+ 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) ||
+ (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");
+ return FALSE;
+ }
+ 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
+ iter = *end;
+
+ search_flags = GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY;
+
+ if (!PLUMA_SEARCH_IS_CASE_SENSITIVE (doc->priv->search_flags))
+ {
+ search_flags = search_flags | GTK_TEXT_SEARCH_CASE_INSENSITIVE;
+ }
+
+ while (!found)
+ {
+ 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);
+
+ 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;
}
/* FIXME this is an issue for introspection regardning @find */
diff --git a/pluma/pluma-document.h b/pluma/pluma-document.h
index 6d90323e..ee8d6f88 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 887e9ff5..a5f67a2c 100644
--- a/pluma/pluma-utils.c
+++ b/pluma/pluma-utils.c
@@ -1571,3 +1571,98 @@ 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;
+
+ 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);
+ if(forward_search)
+ {
+ match_string=all_matches[0];
+ gtk_text_iter_forward_search(begin_iter
+ ,match_string
+ ,flags
+ ,match_start
+ ,match_end
+ ,limit);
+ }
+ else
+ {
+ match_string=all_matches[g_strv_length(all_matches)-1];
+ gtk_text_iter_backward_search(begin_iter
+ ,match_string
+ ,flags
+ ,match_start
+ ,match_end
+ ,limit);
+ }
+ }
+
+ 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 066bb438..fb62ec48 100644
--- a/pluma/pluma-utils.h
+++ b/pluma/pluma-utils.h
@@ -151,6 +151,15 @@ 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__ */