Patch #1701 2006-12-07 19:58

dmoore

Support for Advanced Style REGEX find/replace
Download
1701-Support_for_Ad.patch (11.3 KB)
Category
Application::Refinement
Status
Accepted
Close date
2007-04-12 10:00
Assigned to
 
Index: src/sdk/editorconfigurationdlg.cpp
===================================================================
--- src/sdk/editorconfigurationdlg.cpp    (revision 3315)
+++ src/sdk/editorconfigurationdlg.cpp    (working copy)
@@ -123,6 +123,7 @@
        XRCCTRL(*this, "chkBackspaceUnindents", wxCheckBox)->SetValue(cfg->ReadBool(_T("/backspace_unindents"), true));
        XRCCTRL(*this, "chkWordWrap", wxCheckBox)->SetValue(cfg->ReadBool(_T("/word_wrap"), false));
        XRCCTRL(*this, "chkPosixRegex", wxCheckBox)->SetValue(cfg->ReadBool(_T("/use_posix_style_regexes"), false));
+       XRCCTRL(*this, "chkAdvancedRegex", wxCheckBox)->SetValue(cfg->ReadBool(_T("/use_advanced_regexes"), false));
        XRCCTRL(*this, "chkShowLineNumbers", wxCheckBox)->SetValue(cfg->ReadBool(_T("/show_line_numbers"), true));
        XRCCTRL(*this, "chkHighlightCaretLine", wxCheckBox)->SetValue(cfg->ReadBool(_T("/highlight_caret_line"), false));
        XRCCTRL(*this, "spnTabSize", wxSpinCtrl)->SetValue(cfg->ReadInt(_T("/tab_size"), 4));
@@ -837,6 +838,7 @@
         cfg->Write(_T("/backspace_unindents"),     XRCCTRL(*this, "chkBackspaceUnindents", wxCheckBox)->GetValue());
         cfg->Write(_T("/word_wrap"),             XRCCTRL(*this, "chkWordWrap", wxCheckBox)->GetValue());
         cfg->Write(_T("/use_posix_style_regexes"),XRCCTRL(*this, "chkPosixRegex", wxCheckBox)->GetValue());
+        cfg->Write(_T("/use_advanced_regexes"), XRCCTRL(*this, "chkAdvancedRegex", wxCheckBox)->GetValue());

         cfg->Write(_T("/show_line_numbers"),     XRCCTRL(*this, "chkShowLineNumbers", wxCheckBox)->GetValue());
         cfg->Write(_T("/highlight_caret_line"), XRCCTRL(*this, "chkHighlightCaretLine", wxCheckBox)->GetValue());
Index: src/sdk/editormanager.cpp
===================================================================
--- src/sdk/editormanager.cpp    (revision 3315)
+++ src/sdk/editormanager.cpp    (working copy)
@@ -1415,6 +1415,7 @@
     if (!control || !data)
         return -1;

+    bool AdvRegex=false;
     int flags = 0;
     CalculateFindReplaceStartEnd(control, data);

@@ -1429,8 +1430,18 @@
         flags |= wxSCI_FIND_REGEXP;
         if (Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/use_posix_style_regexes"), false))
             flags |= wxSCI_FIND_POSIX;
+        AdvRegex=Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/use_advanced_regexes"), false);
     }

+    wxRegEx re;
+    if(AdvRegex)
+    {
+        if(data->matchCase)
+            re.Compile(data->findText,wxRE_ADVANCED|wxRE_NEWLINE);
+        else
+            re.Compile(data->findText,wxRE_ADVANCED|wxRE_NEWLINE|wxRE_ICASE);
+    }
+
     control->BeginUndoAction();
     int pos = -1;
     bool replace = false;
@@ -1444,7 +1455,32 @@
     while (!stop)
     {
         int lengthFound = 0;
-        pos = control->FindText(data->start, data->end, data->findText, flags, &lengthFound);
+        if(!AdvRegex)
+            pos = control->FindText(data->start, data->end, data->findText, flags, &lengthFound);
+        else
+        {
+            wxString text=control->GetTextRange(data->start, data->end);
+            if(re.Matches(text))
+            {
+                size_t start,len;
+                re.GetMatch(&start,&len,0);
+                pos=start+data->start;
+                lengthFound=len;
+                if(start==0&&len==0) //For searches for "^" or "$" (and null returning variants on this) need to make sure we have forward progress and not simply matching on a previous BOL/EOL find
+                {
+                    text=text.Mid(1);
+                    if(re.Matches(text))
+                    {
+                        size_t start,len;
+                        re.GetMatch(&start,&len,0);
+                        pos=start+data->start+1;
+                        lengthFound=len;
+                    } else
+                        pos=-1;
+                }
+            } else
+                pos=-1;
+        }
         if (pos != -1)
         {
             control->GotoPos(pos);
@@ -1534,8 +1570,17 @@
                     // set target same as selection
                     control->SetTargetStart(control->GetSelectionStart());
                     control->SetTargetEnd(control->GetSelectionEnd());
-                    // replace with regEx support
-                    lengthReplace = control->ReplaceTargetRE(data->replaceText);
+                    if(AdvRegex)
+                    {
+                        wxString text=control->GetSelectedText();
+                        re.Replace(&text,data->replaceText,1);
+                        lengthReplace=text.Len();
+                        control->ReplaceSelection(text);
+                    } else
+                    {
+                        // replace with regEx support
+                        lengthReplace = control->ReplaceTargetRE(data->replaceText);
+                    }
                     // reset target
                     control->SetTarget
download for full patch...
dmoore 2006-12-07 20:04

This patch allows the user to select the wxRegex Advanced style for Find/Replace and Find/Replace in files. The option to use it is in the Settings -> Editor dialog.

I've done some simple testing on this, but someone should play around with it to make sure it doesn't have any bugs. The patch is not as efficient as could be, mostly because i didn't want to have to rewrite the find/replace code in its entirety (but pulling the entire Scintilla buffer for each search action is probably more than a little costly...).

Note that I set wxRE_ADVANCED and wxRE_NEWLINE flags (the latter allows support for ^ and $ as start / end of line markers). The regex testbed plugin should offer this and the "posix" style regexes as options.

mandrav 2007-04-12 10:00

Patch applied, thank you.