aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/Scintilla.iface7
-rw-r--r--src/AutoComplete.cxx4
-rw-r--r--src/Document.cxx66
-rw-r--r--src/Document.h8
-rw-r--r--src/Editor.cxx34
-rw-r--r--src/Editor.h1
-rw-r--r--src/RESearch.cxx53
-rw-r--r--src/RESearch.h7
-rw-r--r--win32/PlatWin.cxx5
9 files changed, 150 insertions, 35 deletions
diff --git a/include/Scintilla.iface b/include/Scintilla.iface
index 8fdbdedcc..dd4a167f1 100644
--- a/include/Scintilla.iface
+++ b/include/Scintilla.iface
@@ -717,7 +717,12 @@ set void SetTargetStart=2190(position pos,)
set void SetTargetEnd=2191(position pos,)
# Replace the target text with the argument text.
-fun void ReplaceTarget=2192(, string text)
+# If replacePatterns then looks for \d where d is between 1 and 9
+# and replaces these with the strings matched in the last search
+# operation which were surrounded by \( and \).
+# Returns the length of the replacement text including any change
+# caused by processing the \d patterns.
+fun int ReplaceTarget=2192(bool replacePatterns, string text)
# Show a call tip containing a definition near position pos.
fun void CallTipShow=2200(position pos, string definition)
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);
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx
index c2967d2a5..90540baf6 100644
--- a/win32/PlatWin.cxx
+++ b/win32/PlatWin.cxx
@@ -696,7 +696,10 @@ void Window::SetTitle(const char *s) {
}
LRESULT Window::SendMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
- return ::SendMessage(id, msg, wParam, lParam);
+ if (id)
+ return ::SendMessage(id, msg, wParam, lParam);
+ else
+ return 0;
}
int Window::GetDlgCtrlID() {