Kaydet (Commit) b9f6cf69 authored tarafından Nick Treleaven's avatar Nick Treleaven

Use more POSIX-like syntax for regular expression bracket matching; Prevent…

Use more POSIX-like syntax for regular expression bracket matching; Prevent searching backwards with a regex (unsupported); Scroll in view after the last replacement for replace all/selection. Also move hiding the replace dialog out of document.c

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@582 ea778897-0a13-0410-b9d1-a72fbfd435f5
üst 5f05ba68
......@@ -5,6 +5,12 @@
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.
* src/callbacks.c, src/callbacks.h, src/document.c, src/dialogs.c,
doc/geany.docbook:
Use more POSIX-like syntax for regular expression bracket matching.
Prevent searching backwards with a regex (unsupported).
Scroll in view after the last replacement for replace all/selection.
2006-07-18 Enrico Tröger <enrico.troeger@uvena.de>
......
......@@ -414,12 +414,15 @@
</para>
</section>
-->
<section>
<section id="searchreplace">
<title>Search and Replace</title>
<para>
You can use regular expressions in the search dialog, just by activating the check box (see
the image below). Detailed information about special characters can be found in the
<xref linkend="regexp"/>.
You can use regular expressions in the search and replace dialogs, just by
activating the check box (see the image below).
The syntax is POSIX-like, as described in <xref linkend="regexp"/>.
<note><para>
Searching backwards with regular expressions is not supported.
</para></note>
<figure>
<title>Search dialog</title>
<graphic fileref="images/find_dialog.jpg"></graphic>
......@@ -448,17 +451,17 @@
<entry>Matches any character.</entry>
</row>
<row>
<entry>\(</entry>
<entry>(</entry>
<entry>This marks the start of a region for tagging a match.</entry>
</row>
<row>
<entry>\)</entry>
<entry>)</entry>
<entry>This marks the end of a tagged region.</entry>
</row>
<row>
<entry>\n</entry>
<entry>Where n is 1 through 9 refers to the first through ninth tagged region
when replacing. For example, if the search string was Fred\([1-9]\)XXX
when replacing. For example, if the search string was Fred([1-9])XXX
and the replace string was Sam\1YYY, when applied to Fred2XXX this would
generate Sam2YYY.
</entry>
......@@ -475,7 +478,7 @@
<entry>\x</entry>
<entry>This allows you to use a character x that would otherwise have a special
meaning. For example, \[ would be interpreted as [ and not as the start
of a character set.
of a character set. Use \\ for a literal backslash.
</entry>
</row>
<row>
......@@ -491,6 +494,10 @@
any character except an alphabetic character.
</entry>
</row>
<row>
<entry>^</entry>
<entry>This matches the start of a line (unless used inside a set, see above).</entry>
</row>
<row>
<entry>$</entry>
<entry>This matches the end of a line.</entry>
......
......@@ -1809,6 +1809,37 @@ on_find_next1_activate (GtkMenuItem *menuitem,
}
void
on_find_previous1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
gint idx = document_get_cur_idx();
if (app->search_text == NULL) return;
if (search_flags & SCFIND_REGEXP)
utils_beep(); //Can't reverse search order for a regex (find next ignores search backwards)
else
{
document_find_text(idx, app->search_text, search_flags,
!search_backwards);
}
}
void on_find_checkbutton_toggled (GtkToggleButton *togglebutton,
gpointer user_data)
{
GtkToggleButton *chk_regexp = GTK_TOGGLE_BUTTON(
lookup_widget(GTK_WIDGET(app->find_dialog), "check_regexp"));
GtkWidget *chk_back =
lookup_widget(GTK_WIDGET(app->find_dialog), "check_back");
if (togglebutton == chk_regexp)
gtk_widget_set_sensitive(chk_back, ! gtk_toggle_button_get_active(chk_regexp));
}
void
on_find_dialog_response (GtkDialog *dialog,
gint response,
......@@ -1850,7 +1881,7 @@ on_find_dialog_response (GtkDialog *dialog,
gtk_combo_box_prepend_text(GTK_COMBO_BOX(user_data), app->search_text);
search_flags = (fl1 ? SCFIND_MATCHCASE : 0) |
(fl2 ? SCFIND_WHOLEWORD : 0) |
(fl3 ? SCFIND_REGEXP : 0) |
(fl3 ? SCFIND_REGEXP | SCFIND_POSIX: 0) |
(fl4 ? SCFIND_WORDSTART : 0);
document_find_text(idx, app->search_text, search_flags, search_backwards);
}
......@@ -1867,6 +1898,19 @@ on_find_entry_activate (GtkEntry *entry,
}
void on_replace_checkbutton_toggled (GtkToggleButton *togglebutton,
gpointer user_data)
{
GtkToggleButton *chk_regexp = GTK_TOGGLE_BUTTON(
lookup_widget(GTK_WIDGET(app->replace_dialog), "check_regexp"));
GtkWidget *chk_back =
lookup_widget(GTK_WIDGET(app->replace_dialog), "check_back");
if (togglebutton == chk_regexp)
gtk_widget_set_sensitive(chk_back, ! gtk_toggle_button_get_active(chk_regexp));
}
void
on_replace_dialog_response (GtkDialog *dialog,
gint response,
......@@ -1924,7 +1968,7 @@ on_replace_dialog_response (GtkDialog *dialog,
search_flags_re = (fl1 ? SCFIND_MATCHCASE : 0) |
(fl2 ? SCFIND_WHOLEWORD : 0) |
(fl3 ? SCFIND_REGEXP : 0) |
(fl3 ? SCFIND_REGEXP | SCFIND_POSIX : 0) |
(fl4 ? SCFIND_WORDSTART : 0);
if (search_in_all_buffers_re && response == GEANY_RESPONSE_REPLACE_ALL)
......@@ -1936,6 +1980,7 @@ on_replace_dialog_response (GtkDialog *dialog,
document_replace_all(i, find, replace, search_flags_re);
}
gtk_widget_hide(app->replace_dialog);
}
else
{
......@@ -1943,17 +1988,20 @@ on_replace_dialog_response (GtkDialog *dialog,
{
case GEANY_RESPONSE_REPLACE:
{
document_replace_text(idx, find, replace, search_flags_re, search_backwards_re);
document_replace_text(idx, find, replace, search_flags_re,
search_backwards_re);
break;
}
case GEANY_RESPONSE_REPLACE_ALL:
{
document_replace_all(idx, find, replace, search_flags_re);
gtk_widget_hide(app->replace_dialog);
break;
}
case GEANY_RESPONSE_REPLACE_SEL:
{
document_replace_sel(idx, find, replace, search_flags_re);
gtk_widget_hide(app->replace_dialog);
break;
}
}
......@@ -2496,20 +2544,6 @@ on_run_button_clicked (GtkToolButton *toolbutton,
}
void
on_find_previous1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
gint idx = document_get_cur_idx();
if (app->search_text)
{
document_find_text(idx, app->search_text, search_flags,
!search_backwards);
}
}
void
on_go_to_line1_activate (GtkMenuItem *menuitem,
gpointer user_data)
......
......@@ -375,6 +375,13 @@ void
on_find_next1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_find_previous1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void on_find_checkbutton_toggled (GtkToggleButton *togglebutton,
gpointer user_data);
void
on_find_dialog_response (GtkDialog *dialog,
gint response,
......@@ -384,6 +391,9 @@ void
on_find_entry_activate (GtkEntry *entry,
gpointer user_data);
void on_replace_checkbutton_toggled (GtkToggleButton *togglebutton,
gpointer user_data);
void
on_replace_dialog_response (GtkDialog *dialog,
gint response,
......@@ -569,10 +579,6 @@ void
on_run_button_clicked (GtkToolButton *toolbutton,
gpointer user_data);
void
on_find_previous1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_go_to_line1_activate (GtkMenuItem *menuitem,
gpointer user_data);
......
......@@ -855,8 +855,10 @@ void dialogs_show_find(void)
g_object_set_data_full(G_OBJECT(app->find_dialog), "check_regexp",
gtk_widget_ref(checkbox3), (GDestroyNotify)gtk_widget_unref);
gtk_button_set_focus_on_click(GTK_BUTTON(checkbox3), FALSE);
gtk_tooltips_set_tip(tooltips, checkbox3,
_("For detailed information about using regular expressions, please read the documentation."), NULL);
gtk_tooltips_set_tip(tooltips, checkbox3, _("Use POSIX-like regular expressions. "
"For detailed information about using regular expressions, please read the documentation."), NULL);
g_signal_connect(G_OBJECT(checkbox3), "toggled",
G_CALLBACK(on_find_checkbutton_toggled), NULL);
checkbox6 = gtk_check_button_new_with_mnemonic(_("_Replace control characters"));
g_object_set_data_full(G_OBJECT(app->find_dialog), "check_escape",
......@@ -984,8 +986,10 @@ void dialogs_show_replace(void)
g_object_set_data_full(G_OBJECT(app->replace_dialog), "check_regexp",
gtk_widget_ref(checkbox3), (GDestroyNotify)gtk_widget_unref);
gtk_button_set_focus_on_click(GTK_BUTTON(checkbox3), FALSE);
gtk_tooltips_set_tip(tooltips, checkbox3,
_("For detailed information about using regular expressions, please read the documentation."), NULL);
gtk_tooltips_set_tip(tooltips, checkbox3, _("Use POSIX-like regular expressions. "
"For detailed information about using regular expressions, please read the documentation."), NULL);
g_signal_connect(G_OBJECT(checkbox3), "toggled",
G_CALLBACK(on_replace_checkbutton_toggled), NULL);
checkbox7 = gtk_check_button_new_with_mnemonic(_("_Replace control characters"));
g_object_set_data_full(G_OBJECT(app->replace_dialog), "check_escape",
......
......@@ -58,11 +58,10 @@
#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. */
/* Returns -1 if no text found or the new range endpoint after replacing. */
static gint
document_replace_range(gint idx, const gchar *find_text, const gchar *replace_text, gint flags,
gint start, gint end, gboolean show_last);
document_replace_range(gint idx, const gchar *find_text, const gchar *replace_text,
gint flags, gint start, gint end);
/* returns the index of the notebook page which has the given filename
......@@ -697,7 +696,8 @@ void document_find_next(gint idx, const gchar *text, gint flags, gboolean find_b
{
gint selection_end, search_pos;
if (idx == -1 || ! strlen(text)) return;
g_return_if_fail(text != NULL);
if (idx == -1 || ! *text) return;
selection_end = sci_get_selection_end(doc_list[idx].sci);
if (!inc && sci_can_copy(doc_list[idx].sci))
......@@ -735,7 +735,10 @@ void document_find_text(gint idx, const gchar *text, gint flags, gboolean search
{
gint selection_end, selection_start, search_pos;
if (idx == -1 || ! strlen(text)) return;
g_return_if_fail(text != NULL);
if (idx == -1 || ! *text) return;
// Sci doesn't support searching backwards with a regex
if (flags & SCFIND_REGEXP) search_backwards = FALSE;
selection_start = sci_get_selection_start(doc_list[idx].sci);
selection_end = sci_get_selection_end(doc_list[idx].sci);
......@@ -768,12 +771,15 @@ void document_find_text(gint idx, const gchar *text, gint flags, gboolean search
}
void document_replace_text(gint idx, const gchar *find_text, const gchar *replace_text, gint flags, gboolean search_backwards)
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;
g_return_if_fail(find_text != NULL && replace_text != NULL);
if (idx == -1 || ! *find_text) return;
// Sci doesn't support searching backwards with a regex
if (flags & SCFIND_REGEXP) search_backwards = FALSE;
selection_start = sci_get_selection_start(doc_list[idx].sci);
selection_end = sci_get_selection_end(doc_list[idx].sci);
......@@ -809,11 +815,10 @@ void document_replace_text(gint idx, const gchar *find_text, const gchar *replac
}
/* 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. */
/* Returns -1 if no text found or the new range endpoint after replacing. */
static gint
document_replace_range(gint idx, const gchar *find_text, const gchar *replace_text, gint flags,
gint start, gint end, gboolean show_last)
document_replace_range(gint idx, const gchar *find_text, const gchar *replace_text,
gint flags, gint start, gint end)
{
gint search_pos;
gint find_len = 0, replace_len = 0;
......@@ -850,16 +855,12 @@ document_replace_range(gint idx, const gchar *find_text, const gchar *replace_te
}
sci_end_undo_action(doc_list[idx].sci);
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)
{
// scroll last match in view.
sci_goto_pos(doc_list[idx].sci, ttf.chrg.cpMin, TRUE);
return end;
}
else
return -1; //no text was found
}
......@@ -881,7 +882,7 @@ void document_replace_sel(gint idx, const gchar *find_text, const gchar *replace
}
selection_end = document_replace_range(idx, find_text, replace_text, flags,
selection_start, selection_end, FALSE);
selection_start, selection_end);
if (selection_end == -1)
utils_beep();
else
......@@ -890,22 +891,19 @@ void document_replace_sel(gint idx, const gchar *find_text, const gchar *replace
sci_set_selection_start(doc_list[idx].sci, selection_start);
sci_set_selection_end(doc_list[idx].sci, selection_end);
}
gtk_widget_hide(app->replace_dialog);
}
void document_replace_all(gint idx, const gchar *find_text, const gchar *replace_text, gint flags)
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)
if (document_replace_range(idx, find_text, replace_text, flags, 0, len) == -1)
utils_beep();
gtk_widget_hide(app->replace_dialog);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment