diff options
| author | nyamatongwe <devnull@localhost> | 2001-04-05 01:58:04 +0000 | 
|---|---|---|
| committer | nyamatongwe <devnull@localhost> | 2001-04-05 01:58:04 +0000 | 
| commit | 529ea750b146c23bd1f8c0ec0b3bbeb64689a736 (patch) | |
| tree | 7141531f889b0ffe3a3b262faa9ef8924fa17018 /src | |
| parent | a9318190f7318a86b272f23132126a45c8111dce (diff) | |
| download | scintilla-mirror-529ea750b146c23bd1f8c0ec0b3bbeb64689a736.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); | 
