SF.net SVN: geany: [581] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Tue Jul 18 14:09:08 UTC 2006


Revision: 581
Author:   ntrel
Date:     2006-07-18 07:09:01 -0700 (Tue, 18 Jul 2006)
ViewCVS:  http://svn.sourceforge.net/geany/?rev=581&view=rev

Log Message:
-----------
Fix replacing the right length of text matched from a regex; Add support for back references when replacing with regex; Improve the speed of replace all/replace in selection; Don't lose the selection range after replacing in selection

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/document.c
    trunk/src/sciwrappers.c
    trunk/src/sciwrappers.h
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2006-07-18 12:28:04 UTC (rev 580)
+++ trunk/ChangeLog	2006-07-18 14:09:01 UTC (rev 581)
@@ -1,3 +1,12 @@
+2006-07-18  Nick Treleaven  <nick.treleaven at btinternet.com>
+
+ * src/sciwrappers.c, src/sciwrappers.h, src/document.c:
+   Fix replacing the right length of text matched from a regex.
+   Add support for back references when replacing with regex.
+   Improve the speed of replace all/replace in selection.
+   Don't lose the selection range after replacing in selection.
+
+
 2006-07-18  Enrico Tröger  <enrico.troeger at uvena.de>
 
  * src/dialogs.c, src/callbacks.c:

Modified: trunk/src/document.c
===================================================================
--- trunk/src/document.c	2006-07-18 12:28:04 UTC (rev 580)
+++ trunk/src/document.c	2006-07-18 14:09:01 UTC (rev 581)
@@ -58,7 +58,13 @@
 #include "notebook.h"
 
 
+/* Returns -1 if no text found or the new range endpoint after replacing.
+ * show_last is whether to select and scroll the last replacement in view. */
+static gint
+document_replace_range(gint idx, const gchar *find_text, const gchar *replace_text, gint flags,
+	gint start, gint end, gboolean show_last);
 
+
 /* returns the index of the notebook page which has the given filename
  * is_tm_filename is needed when passing TagManager filenames because they are
  * dereferenced, and would not match the link filename. */
@@ -765,9 +771,9 @@
 void document_replace_text(gint idx, const gchar *find_text, const gchar *replace_text, gint flags, gboolean search_backwards)
 {
 	gint selection_end, selection_start, search_pos;
-	gint find_text_len = strlen(find_text);
 
-	if (idx == -1 || ! find_text_len) return;
+	g_return_if_fail(find_text != NULL && replace_text != NULL);
+	if (idx == -1 || ! *find_text) return;
 
 	selection_start =  sci_get_selection_start(doc_list[idx].sci);
 	selection_end =  sci_get_selection_end(doc_list[idx].sci);
@@ -787,12 +793,14 @@
 
 	if (search_pos != -1)
 	{
-		sci_target_start(doc_list[idx].sci, search_pos);
-		sci_target_end(doc_list[idx].sci, search_pos + find_text_len);
-		sci_target_replace(doc_list[idx].sci, replace_text);
+		gint replace_len;
+		// search next/prev will select matching text, which we use to set the replace target
+		sci_target_from_selection(doc_list[idx].sci);
+		replace_len = sci_target_replace(doc_list[idx].sci, replace_text, flags & SCFIND_REGEXP);
+		// select the replacement and scroll in view
+		sci_set_selection_start(doc_list[idx].sci, search_pos);
+		sci_set_selection_end(doc_list[idx].sci, search_pos + replace_len);
 		sci_scroll_caret(doc_list[idx].sci);
-		sci_set_selection_start(doc_list[idx].sci, search_pos);
-		sci_set_selection_end(doc_list[idx].sci, search_pos + strlen(replace_text));
 	}
 	else
 	{
@@ -801,83 +809,106 @@
 }
 
 
-void document_replace_sel(gint idx, const gchar *find_text, const gchar *replace_text, gint flags)
+/* Returns -1 if no text found or the new range endpoint after replacing.
+ * show_last is whether to select and scroll the last replacement in view. */
+static gint
+document_replace_range(gint idx, const gchar *find_text, const gchar *replace_text, gint flags,
+	gint start, gint end, gboolean show_last)
 {
-	gint selection_end, selection_start, search_pos;
-	gint anchor_pos;
-	gint find_text_len = strlen(find_text);
-	gint replace_text_len = strlen(replace_text);
+	gint search_pos;
+	gint find_len = 0, replace_len = 0;
+	gboolean match_found = FALSE;
+	struct TextToFind ttf;
 
-	if (idx == -1 || ! find_text_len) return;
+	g_return_val_if_fail(find_text != NULL && replace_text != NULL, FALSE);
+	if (idx == -1 || ! *find_text) return FALSE;
 
-	selection_start = sci_get_selection_start(doc_list[idx].sci);
-	selection_end = sci_get_selection_end(doc_list[idx].sci);
-	if ((selection_end - selection_start) == 0)
-	{
-		utils_beep();
-		return;
-	}
+	sci_start_undo_action(doc_list[idx].sci);
+	ttf.chrg.cpMin = start;
+	ttf.chrg.cpMax = end;
+	ttf.lpstrText = (gchar*)find_text;
 
-	sci_start_undo_action(doc_list[idx].sci);
-	anchor_pos = selection_start;
 	while (TRUE)
 	{
-		sci_goto_pos(doc_list[idx].sci, anchor_pos, TRUE);
-		sci_set_search_anchor(doc_list[idx].sci);
-		search_pos = sci_search_next(doc_list[idx].sci, flags, find_text);
+		search_pos = sci_find_text(doc_list[idx].sci, flags, &ttf);
+		if (search_pos == -1) break;
+		find_len = ttf.chrgText.cpMax - ttf.chrgText.cpMin;
 
-		if (search_pos == -1 ||
-			search_pos < selection_start ||
-			search_pos + find_text_len > selection_end) break;
+		if (search_pos + find_len > end)
+			break; //found text is partly out of range
 		else
 		{
+			match_found = TRUE;
 			sci_target_start(doc_list[idx].sci, search_pos);
-			sci_target_end(doc_list[idx].sci, search_pos + find_text_len);
-			sci_target_replace(doc_list[idx].sci, replace_text);
-			anchor_pos = search_pos + replace_text_len; //avoid rematch
-			// update selection end point for each replacement
-			selection_end += replace_text_len - find_text_len;
+			sci_target_end(doc_list[idx].sci, search_pos + find_len);
+			replace_len = sci_target_replace(doc_list[idx].sci, replace_text,
+				flags & SCFIND_REGEXP);
+			ttf.chrg.cpMin = search_pos + replace_len; //next search starts after replacement
+			end += replace_len - find_len; //update end of range now text has changed
+			ttf.chrg.cpMax = end;
 		}
 	}
 	sci_end_undo_action(doc_list[idx].sci);
-	// set selection again, because it got lost and end may be moved
-	sci_set_selection_start(doc_list[idx].sci, selection_start);
-	sci_set_selection_end(doc_list[idx].sci, selection_end);
 
-	sci_scroll_caret(doc_list[idx].sci);
-	gtk_widget_hide(app->replace_dialog);
+	if (match_found && show_last)
+	{
+		// select the last replacement
+		gint sel_start = ttf.chrg.cpMin - replace_len;
+		sci_set_selection_start(doc_list[idx].sci, sel_start);
+		sci_set_selection_end(doc_list[idx].sci, sel_start + replace_len);
+		sci_scroll_caret(doc_list[idx].sci);
+	}
+	if (match_found)
+		return end;
+	else
+		return -1; //no text was found
 }
 
 
-void document_replace_all(gint idx, const gchar *find_text, const gchar *replace_text, gint flags)
+void document_replace_sel(gint idx, const gchar *find_text, const gchar *replace_text, gint flags)
 {
-	gint search_pos;
-	gint find_text_len = strlen(find_text);
-	gint replace_text_len = strlen(replace_text);
+	gint selection_end, selection_start;
 
-	if (idx == -1 || ! find_text_len) return;
+	g_return_if_fail(find_text != NULL && replace_text != NULL);
+	if (idx == -1 || ! *find_text) return;
 
-	sci_start_undo_action(doc_list[idx].sci);
-	sci_goto_pos(doc_list[idx].sci, 0, FALSE);
-	sci_set_search_anchor(doc_list[idx].sci);
+	selection_start = sci_get_selection_start(doc_list[idx].sci);
+	selection_end = sci_get_selection_end(doc_list[idx].sci);
+	if ((selection_end - selection_start) == 0)
+	{
+		utils_beep();
+		return;
+	}
 
-	search_pos = sci_search_next(doc_list[idx].sci, flags, find_text);
-	while (search_pos != -1)
+	selection_end = document_replace_range(idx, find_text, replace_text, flags,
+		selection_start, selection_end, FALSE);
+	if (selection_end == -1)
+		utils_beep();
+	else
 	{
-		sci_target_start(doc_list[idx].sci, search_pos);
-		sci_target_end(doc_list[idx].sci, search_pos + find_text_len);
-		sci_target_replace(doc_list[idx].sci, replace_text);
-		// next search starts after replaced text (avoids rematching):
-		sci_goto_pos(doc_list[idx].sci, search_pos + replace_text_len, TRUE);
-		sci_set_search_anchor(doc_list[idx].sci);
-		search_pos = sci_search_next(doc_list[idx].sci, flags, find_text);
+		//update the selection for the new endpoint
+		sci_set_selection_start(doc_list[idx].sci, selection_start);
+		sci_set_selection_end(doc_list[idx].sci, selection_end);
 	}
-	sci_end_undo_action(doc_list[idx].sci);
-	sci_scroll_caret(doc_list[idx].sci);
+
 	gtk_widget_hide(app->replace_dialog);
 }
 
 
+void document_replace_all(gint idx, const gchar *find_text, const gchar *replace_text, gint flags)
+{
+	gint len;
+	g_return_if_fail(find_text != NULL && replace_text != NULL);
+	if (idx == -1 || ! *find_text) return;
+
+	len = sci_get_length(doc_list[idx].sci);
+	if (document_replace_range(idx, find_text, replace_text, flags, 0, len, TRUE) == -1)
+		utils_beep();
+
+	gtk_widget_hide(app->replace_dialog);
+}
+
+
 void document_set_font(gint idx, const gchar *font_name, gint size)
 {
 	gint style;
@@ -1240,7 +1271,7 @@
 		{
 			sci_target_start(doc_list[idx].sci, i + 1);
 			sci_target_end(doc_list[idx].sci, line_end);
-			sci_target_replace(doc_list[idx].sci, "");
+			sci_target_replace(doc_list[idx].sci, "", FALSE);
 		}
 	}
 }

Modified: trunk/src/sciwrappers.c
===================================================================
--- trunk/src/sciwrappers.c	2006-07-18 12:28:04 UTC (rev 580)
+++ trunk/src/sciwrappers.c	2006-07-18 14:09:01 UTC (rev 581)
@@ -772,9 +772,9 @@
 }
 
 
-void sci_target_replace(ScintillaObject *sci, const gchar *text)
+gint sci_target_replace(ScintillaObject *sci, const gchar *text, gboolean regex)
 {
-	SSM(sci, SCI_REPLACETARGET, -1, (sptr_t) text);
+	return SSM(sci, (regex) ? SCI_REPLACETARGETRE : SCI_REPLACETARGET, -1, (sptr_t) text);
 }
 
 

Modified: trunk/src/sciwrappers.h
===================================================================
--- trunk/src/sciwrappers.h	2006-07-18 12:28:04 UTC (rev 580)
+++ trunk/src/sciwrappers.h	2006-07-18 14:09:01 UTC (rev 581)
@@ -138,7 +138,7 @@
 void				sci_target_from_selection	(ScintillaObject * sci);
 void				sci_target_start			(ScintillaObject * sci, gint start);
 void				sci_target_end				(ScintillaObject * sci, gint end);
-void				sci_target_replace			(ScintillaObject * sci, const gchar *text);
+gint				sci_target_replace			(ScintillaObject *sci, const gchar *text, gboolean regex);
 void				sci_set_keywords			(ScintillaObject * sci, gint k, gchar *text);
 void				sci_scroll_lines			(ScintillaObject * sci, gint lines);
 gint				sci_get_lexer				(ScintillaObject * sci);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Commits mailing list