diff options
author | nyamatongwe <unknown> | 2001-04-05 01:58:04 +0000 |
---|---|---|
committer | nyamatongwe <unknown> | 2001-04-05 01:58:04 +0000 |
commit | 508b1b5ca03dffc1ec2d5a98a378da4cdd30ef84 (patch) | |
tree | 7141531f889b0ffe3a3b262faa9ef8924fa17018 /src | |
parent | 9b04df8e99b54645a92580712a6551b39ac511f5 (diff) | |
download | scintilla-mirror-508b1b5ca03dffc1ec2d5a98a378da4cdd30ef84.tar.gz |
Replace target functionality to make find and replace operations faster
by diminishing screen updates and allow for \d patterns in the replacement
text.
Diffstat (limited to 'src')
-rw-r--r-- | src/AutoComplete.cxx | 4 | ||||
-rw-r--r-- | src/Document.cxx | 66 | ||||
-rw-r--r-- | src/Document.h | 8 | ||||
-rw-r--r-- | src/Editor.cxx | 34 | ||||
-rw-r--r-- | src/Editor.h | 1 | ||||
-rw-r--r-- | src/RESearch.cxx | 53 | ||||
-rw-r--r-- | src/RESearch.h | 7 |
7 files changed, 140 insertions, 33 deletions
diff --git a/src/AutoComplete.cxx b/src/AutoComplete.cxx index 6abae23d6..81eb12d99 100644 --- a/src/AutoComplete.cxx +++ b/src/AutoComplete.cxx @@ -117,7 +117,9 @@ void AutoComplete::Move(int delta) { void AutoComplete::Select(const char *word) { int pos = lb.Find(word); //Platform::DebugPrintf("Autocompleting at <%s> %d\n", wordCurrent, pos); - if (pos != -1) + if (pos == -1) + Cancel(); + else lb.Select(pos); } diff --git a/src/Document.cxx b/src/Document.cxx index ba7fa4911..8adf2daf2 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -18,9 +18,6 @@ #include "Document.h" #include "RESearch.h" -void re_fail(char *,char) { -} - // This is ASCII specific but is safe with chars >= 0x80 inline bool isspacechar(unsigned char ch) { return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); @@ -49,6 +46,10 @@ Document::Document() { useTabs = true; watchers = 0; lenWatchers = 0; + + matchesValid = false; + pre = 0; + substituted = 0; } Document::~Document() { @@ -58,6 +59,10 @@ Document::~Document() { delete []watchers; watchers = 0; lenWatchers = 0; + delete pre; + pre = 0; + delete []substituted; + substituted = 0; } // Increase reference count and return its previous value. @@ -786,6 +791,10 @@ long Document::FindText(int minPos, int maxPos, const char *s, bool caseSensitive, bool word, bool wordStart, bool regExp, int *length) { if (regExp) { + if (!pre) + pre = new RESearch(); + if (!pre) + return -1; char *pat = new char[strlen(s) + 1]; if (!pat) return -1; @@ -807,20 +816,22 @@ long Document::FindText(int minPos, int maxPos, const char *s, endPos = MovePositionOutsideChar(endPos, 1, false); DocumentIndexer di(this, endPos); - RESearch re; strcat(pat, s); - const char *errmsg = re.Compile(pat); + const char *errmsg = pre->Compile(pat); if (errmsg) { delete []pat; return -1; } - // Find a variable in a property file: \$([A-Za-z0-9_.]+) - int success = re.Execute(di, startPos); + // Find a variable in a property file: \$(\([A-Za-z0-9_.]+\)) + // Replace first '.' with '-' in each property file variable reference: + // Search: \$(\([A-Za-z0-9_-]+\)\.\([A-Za-z0-9_.]+\)) + // Replace: $(\1-\2) + int success = pre->Execute(di, startPos); int pos = -1; int lenRet = 0; if (success) { - pos = re.bopat[0]; - lenRet = re.eopat[0] - re.bopat[0]; + pos = pre->bopat[0]; + lenRet = pre->eopat[0] - pre->bopat[0]; } delete []pat; *length = lenRet; @@ -890,6 +901,43 @@ long Document::FindText(int minPos, int maxPos, const char *s, return -1; } +const char *Document::SubstituteByPosition(const char *text) { + if (!pre) + return 0; + delete []substituted; + substituted = 0; + DocumentIndexer di(this, Length()); + if (!pre->GrabMatches(di)) + return 0; + unsigned int lenResult = 0; + for (const char *t=text; *t; t++) { + if ((*t == '\\') && (*(t+1) >= '1' && *(t+1) <= '9')) { + unsigned int patNum = *(t+1) - '0'; + lenResult += pre->eopat[patNum] - pre->bopat[patNum]; + t++; + } else { + lenResult++; + } + } + substituted = new char[lenResult + 1]; + if (!substituted) + return 0; + char *o = substituted; + for (const char *s=text; *s; s++) { + if ((*s == '\\') && (*(s+1) >= '1' && *(s+1) <= '9')) { + unsigned int patNum = *(s+1) - '0'; + unsigned int len = pre->eopat[patNum] - pre->bopat[patNum]; + strcpy(o, pre->pat[patNum]); + o += len; + s++; + } else { + *o++ = *s; + } + } + *o = '\0'; + return substituted; +} + int Document::LinesTotal() { return cb.Lines(); } diff --git a/src/Document.h b/src/Document.h index b52036513..bfc1a6e57 100644 --- a/src/Document.h +++ b/src/Document.h @@ -60,6 +60,7 @@ public: class DocWatcher; class DocModification; +class RESearch; /** */ @@ -89,7 +90,11 @@ private: WatcherWithUserData *watchers; int lenWatchers; - + + bool matchesValid; + RESearch *pre; + char *substituted; + public: int stylingBits; int stylingBitsMask; @@ -175,6 +180,7 @@ public: long FindText(int minPos, int maxPos, const char *s, bool caseSensitive, bool word, bool wordStart, bool regExp, int *length); long FindText(int iMessage, unsigned long wParam, long lParam); + const char *SubstituteByPosition(const char *text); int LinesTotal(); void ChangeCase(Range r, bool makeUpperCase); diff --git a/src/Editor.cxx b/src/Editor.cxx index 9f65203d2..8590c362f 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -3246,6 +3246,23 @@ void Editor::EnsureLineVisible(int lineDoc) { } } +int Editor::ReplaceTarget(bool replacePatterns, const char *text) { + pdoc->BeginUndoAction(); + if (replacePatterns) { + text = pdoc->SubstituteByPosition(text); + if (!text) + return 0; + } + if (targetStart != targetEnd) + pdoc->DeleteChars(targetStart, targetEnd - targetStart); + targetEnd = targetStart; + unsigned int len = strlen(text); + pdoc->InsertString(targetStart, text); + targetEnd = targetStart + len; + pdoc->EndUndoAction(); + return len; +} + static bool ValidMargin(unsigned long wParam) { return wParam < ViewStyle::margins; } @@ -3566,20 +3583,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { targetEnd = wParam; break; - case SCI_REPLACETARGET: { - if (lParam == 0) - return 0; - pdoc->BeginUndoAction(); - unsigned int chars = targetEnd - targetStart; - if (targetStart != targetEnd) - pdoc->DeleteChars(targetStart, chars); - targetEnd = targetStart; - char *replacement = reinterpret_cast<char *>(lParam); - pdoc->InsertString(targetStart, replacement); - targetEnd = targetStart + strlen(replacement); - pdoc->EndUndoAction(); - } - break; + case SCI_REPLACETARGET: + PLATFORM_ASSERT(lParam); + return ReplaceTarget(wParam, reinterpret_cast<char *>(lParam)); case EM_LINESCROLL: case SCI_LINESCROLL: diff --git a/src/Editor.h b/src/Editor.h index e82496663..c7c7b114e 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -320,6 +320,7 @@ protected: // ScintillaBase subclass needs access to much of Editor void Expand(int &line, bool doExpand); void ToggleContraction(int line); void EnsureLineVisible(int lineDoc); + int ReplaceTarget(bool replacePatterns, const char *text); virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0; diff --git a/src/RESearch.cxx b/src/RESearch.cxx index a9b0d264f..fbc116363 100644 --- a/src/RESearch.cxx +++ b/src/RESearch.cxx @@ -29,6 +29,11 @@ * Modification history: * * $Log$ + * Revision 1.2 2001/04/05 01:58:04 nyamatongwe + * Replace target functionality to make find and replace operations faster + * by diminishing screen updates and allow for \d patterns in the replacement + * text. + * * Revision 1.1 2001/04/04 12:52:44 nyamatongwe * Moved to public domain regular expresion implementation. * @@ -231,10 +236,47 @@ const char bitarr[] = {1,2,4,8,16,32,64,'\200'}; #define badpat(x) (*nfa = END, x) RESearch::RESearch() { + Init(); +} + +RESearch::~RESearch() { + Clear(); +} + +void RESearch::Init() { sta = NOP; /* status of lastpat */ bol = 0; - for (int i=0; i<BITBLK; i++) - bittab[i] = 0; + for (int i=0; i<MAXTAG; i++) + pat[i] = 0; + for (int j=0; j<BITBLK; j++) + bittab[j] = 0; +} + +void RESearch::Clear() { + for (int i=0; i<MAXTAG; i++) { + delete []pat[i]; + pat[i] = 0; + bopat[i] = NOTFOUND; + eopat[i] = NOTFOUND; + } +} + +bool RESearch::GrabMatches(CharacterIndexer &ci) { + bool success = true; + for (unsigned int i=0; i<MAXTAG; i++) { + if ((bopat[i] != NOTFOUND) && (eopat[i] != NOTFOUND)) { + unsigned int len = eopat[i] - bopat[i]; + pat[i] = new char[len + 1]; + if (pat[i]) { + for (unsigned int j=0; j<len; j++) + pat[i][j] = ci.CharAt(bopat[i] + j); + pat[i][len] = '\0'; + } else { + success = false; + } + } + } + return success; } void RESearch::ChSet(char c) { @@ -487,11 +529,8 @@ int RESearch::Execute(CharacterIndexer &ci, int lp) { bol = lp; failure = 0; - - for (int i=0;i<MAXTAG;i++) { - bopat[i] = NOTFOUND; - eopat[i] = NOTFOUND; - } + + Clear(); switch(*ap) { diff --git a/src/RESearch.h b/src/RESearch.h index f9cf7fdc5..62a78f48e 100644 --- a/src/RESearch.h +++ b/src/RESearch.h @@ -26,6 +26,10 @@ class RESearch { public: RESearch(); + ~RESearch(); + void Init(); + void Clear(); + bool GrabMatches(CharacterIndexer &ci); void ChSet(char c); const char *Compile(char *pat); int Execute(CharacterIndexer &ci, int lp); @@ -33,11 +37,12 @@ public: int Substitute(CharacterIndexer &ci, char *src, char *dst); enum {MAXTAG=10}; - enum {MAXNFA=1024}; + enum {MAXNFA=2048}; enum {NOTFOUND=-1}; int bopat[MAXTAG]; int eopat[MAXTAG]; + char *pat[MAXTAG]; private: int PMatch(CharacterIndexer &ci, int lp, char *ap); |