diff options
| -rwxr-xr-x | pluma/dialogs/pluma-search-dialog.c | 20 | ||||
| -rwxr-xr-x | pluma/dialogs/pluma-search-dialog.h | 4 | ||||
| -rw-r--r-- | pluma/dialogs/pluma-search-dialog.ui | 27 | ||||
| -rw-r--r-- | pluma/pluma-commands-search.c | 41 | ||||
| -rw-r--r-- | pluma/pluma-document.c | 109 | ||||
| -rw-r--r-- | pluma/pluma-document.h | 8 | ||||
| -rw-r--r-- | pluma/pluma-utils.c | 95 | ||||
| -rw-r--r-- | pluma/pluma-utils.h | 10 | 
8 files changed, 264 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..e397b258 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..ff872e09 100644 --- a/pluma/pluma-utils.c +++ b/pluma/pluma-utils.c @@ -1578,3 +1578,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 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__ */ -  | 
