From fb94eb5ec5a65087c9b87de6f266fac7cbf6f805 Mon Sep 17 00:00:00 2001 From: harrybharry Date: Thu, 17 Jul 2008 13:18:24 +0000 Subject: [PATCH] Adjusted Smart Highlighter to only highlight the visible lines. Highlighting code is now in a new class SmartHighlighter. git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository@292 f5eea248-9336-0410-98b8-ebc06183d4e3 --- PowerEditor/src/Notepad_plus.cpp | 85 ++------- PowerEditor/src/Notepad_plus.h | 62 +------ .../src/ScitillaComponent/FindReplaceDlg.cpp | 170 +++++++++--------- .../src/ScitillaComponent/FindReplaceDlg.h | 1 + .../ScitillaComponent/SmartHighlighter.cpp | 157 ++++++++++++++++ .../src/ScitillaComponent/SmartHighlighter.h | 35 ++++ .../visual.net/notepadPlus.vc.7.0.vcproj | 6 + scintilla/include/Scintilla.h | 2 + scintilla/src/Editor.cxx | 9 + scintilla/src/Editor.h | 1 + 10 files changed, 318 insertions(+), 210 deletions(-) create mode 100644 PowerEditor/src/ScitillaComponent/SmartHighlighter.cpp create mode 100644 PowerEditor/src/ScitillaComponent/SmartHighlighter.h diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 1421004dd..f4ba0eee6 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -44,8 +44,6 @@ const char Notepad_plus::_className[32] = NOTEPAD_PP_CLASS_NAME; const char *urlHttpRegExpr = "http://[a-z0-9_\\-\\+.:?&@=/%#]*"; -const int smartHighlightFileSizeLimit = 1024 * 1024 * 3; // 3 MB - int docTabIconIDs[] = {IDI_SAVED_ICON, IDI_UNSAVED_ICON, IDI_READONLY_ICON}; enum tb_stat {tb_saved, tb_unsaved, tb_ro}; @@ -75,7 +73,7 @@ Notepad_plus::Notepad_plus(): Window(), _mainWindowStatus(0), _pDocTab(NULL), _p _pMainSplitter(NULL), _isfullScreen(false), _recordingMacro(false), _pTrayIco(NULL), _isUDDocked(false), _isRTL(false), _linkTriggered(true), _isDocModifing(false), _isHotspotDblClicked(false), _sysMenuEntering(false), - _autoCompleteMain(&_mainEditView), _autoCompleteSub(&_subEditView) + _autoCompleteMain(&_mainEditView), _autoCompleteSub(&_subEditView), _smartHighlighter(&_findReplaceDlg) { ZeroMemory(&_prevSelectedRange, sizeof(_prevSelectedRange)); @@ -2204,10 +2202,6 @@ BOOL Notepad_plus::notify(SCNotification *notification) notifyView->execute(SCI_SETANCHOR, pos); _isHotspotDblClicked = false; } - else - { - markSelectedText(); - } } break; @@ -2221,14 +2215,19 @@ BOOL Notepad_plus::notify(SCNotification *notification) XmlMatchedTagsHighlighter xmlTagMatchHiliter(_pEditView); xmlTagMatchHiliter.tagMatch(nppGUI._enableTagAttrsHilite); } - - markSelectedText(); + _smartHighlighter.highlightView(notifyView); updateStatusBar(); AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub; autoC->update(0); break; } + case SCN_SCROLLED: + { + _smartHighlighter.highlightView(notifyView); + break; + } + case TTN_GETDISPINFO: { LPTOOLTIPTEXT lpttt; @@ -5762,12 +5761,6 @@ LRESULT Notepad_plus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa } case WM_CREATE: { - _fileEditView.init(_hInst, hwnd); - MainFileManager->init(this, &_fileEditView); //get it up and running asap. - - pNppParam->setFontList(hwnd); - NppGUI & nppGUI = (NppGUI &)pNppParam->getNppGUI(); - // Menu _mainMenuHandle = ::GetMenu(_hSelf); @@ -5777,15 +5770,21 @@ LRESULT Notepad_plus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa _pNonDocTab = &_subDocTab; _pNonEditView = &_subEditView; + _mainEditView.init(_hInst, hwnd); + _subEditView.init(_hInst, hwnd); + + _fileEditView.init(_hInst, hwnd); + MainFileManager->init(this, &_fileEditView); //get it up and running asap. + + pNppParam->setFontList(hwnd); + NppGUI & nppGUI = (NppGUI &)pNppParam->getNppGUI(); + _mainWindowStatus = WindowMainActive; _activeView = MAIN_VIEW; const ScintillaViewParams & svp1 = pNppParam->getSVP(SCIV_PRIMARY); const ScintillaViewParams & svp2 = pNppParam->getSVP(SCIV_SECOND); - _mainEditView.init(_hInst, hwnd); - _subEditView.init(_hInst, hwnd); - int tabBarStatus = nppGUI._tabStatus; _toReduceTabBar = ((tabBarStatus & TAB_REDUCE) != 0); _docTabIconList.create(_toReduceTabBar?13:20, _hInst, docTabIconIDs, sizeof(docTabIconIDs)/sizeof(int)); @@ -7989,56 +7988,6 @@ bool Notepad_plus::str2Cliboard(const char *str2cpy) return true; } - -void Notepad_plus::markSelectedText() -{ - const NppGUI & nppGUI = (NppParameters::getInstance())->getNppGUI(); - if (!nppGUI._enableSmartHilite) - return; - - if (_pEditView->isSelecting()) - //printStr("catch u!!!"); - return; - - // - if (_pEditView->getCurrentDocLen() > smartHighlightFileSizeLimit) - return; - - //Get selection - CharacterRange range = _pEditView->getSelection(); - //Dont mark if the selection has not changed. - if (range.cpMin == _prevSelectedRange.cpMin && range.cpMax == _prevSelectedRange.cpMax) - { - return; - } - _prevSelectedRange = range; - - //Clear marks - _pEditView->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE_2); - - //If nothing selected, dont mark anything - if (range.cpMin == range.cpMax) - { - return; - } - - char text2Find[MAX_PATH]; - _pEditView->getSelectedText(text2Find, sizeof(text2Find), false); //do not expand selection (false) - - if (!isQualifiedWord(text2Find)) - return; - else - { - unsigned char c = (unsigned char)_pEditView->execute(SCI_GETCHARAT, range.cpMax); - if (c) - { - if (isWordChar(char(c))) - return; - } - } - _findReplaceDlg.markAll2(text2Find); -} - //ONLY CALL IN CASE OF EMERGENCY: EXCEPTION //This function is destructive bool Notepad_plus::emergency() { diff --git a/PowerEditor/src/Notepad_plus.h b/PowerEditor/src/Notepad_plus.h index 22c1bf940..63adf06bd 100644 --- a/PowerEditor/src/Notepad_plus.h +++ b/PowerEditor/src/Notepad_plus.h @@ -48,6 +48,7 @@ #include "Process.h" #include "AutoCompletion.h" #include "Buffer.h" +#include "SmartHighlighter.h" #define NOTEPAD_PP_CLASS_NAME "Notepad++" @@ -189,7 +190,6 @@ public: void notifyBufferChanged(Buffer * buffer, int mask); private: - void loadCommandlineParams(const char * commandLine, CmdLineParams * pCmdParams); static const char _className[32]; char _nppPath[MAX_PATH]; Window *_pMainWindow; @@ -198,6 +198,8 @@ private: AutoCompletion _autoCompleteMain; AutoCompletion _autoCompleteSub; //each Scintilla has its own autoComplete + SmartHighlighter _smartHighlighter; + TiXmlNode *_nativeLang, *_toolIcons; DocTabView _mainDocTab; @@ -752,7 +754,6 @@ private: }; void setFileOpenSaveDlgFilters(FileDialog & fDlg); - void markSelectedText(); void markSelectedTextInc(bool enable); Style * getStyleFromName(const char *styleName) { @@ -768,63 +769,10 @@ private: return st; }; - bool isQualifiedWord(const char *str) - { - for (size_t i = 0 ; i < strlen(str) ; i++) - { - if (!isWordChar(str[i])) - return false; - } - return true; - }; - - bool isWordChar(char ch) const { - if ((unsigned char)ch < 0x20) - return false; - - switch(ch) - { - case ' ': - case ' ': - case '\n': - case '\r': - case '.': - case ',': - case '?': - case ';': - case ':': - case '!': - case '(': - case ')': - case '[': - case ']': - case '+': - case '-': - case '*': - case '/': - case '#': - case '@': - case '^': - case '%': - case '$': - case '"': - case '\'': - case '~': - case '&': - case '{': - case '}': - case '|': - case '=': - case '<': - case '>': - case '\\': - return false; - } - return true; - }; - bool dumpFiles(const char * outdir, const char * fileprefix = ""); //helper func void drawTabbarColoursFromStylerArray(); + + void loadCommandlineParams(const char * commandLine, CmdLineParams * pCmdParams); }; #endif //NOTEPAD_PLUS_H diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp index 4b2de66a5..65deafaeb 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp @@ -990,13 +990,61 @@ int FindReplaceDlg::markAllInc(const char *txt2find, FindOption *opt) int FindReplaceDlg::processAll(ProcessOperation op, const char *txt2find, const char *txt2replace, bool isEntire, const char *fileName, FindOption *opt) { - int nbReplaced = 0; + FindOption *pOptions = opt?opt:&_options; + + CharacterRange cr = (*_ppEditView)->getSelection(); + int docLength = int((*_ppEditView)->execute(SCI_GETLENGTH)); + + // Default : + // direction : down + // begin at : 0 + // end at : end of doc + int startPosition = 0; + int endPosition = docLength; + + bool direction = pOptions->_whichDirection; + + //first try limiting scope by direction + if (direction == DIR_UP) + { + startPosition = 0; + endPosition = cr.cpMax; + } + else + { + startPosition = cr.cpMin; + endPosition = docLength; + } + + //then adjust scope if the full document needs to be changed + if (pOptions->_isWrapAround || isEntire || (op == ProcessCountAll)) //entire document needs to be scanned + { + startPosition = 0; + endPosition = docLength; + } + + //then readjust scope if the selection override is active and allowed + if ((_isInSelection) && ((op == ProcessMarkAll) || ((op == ProcessReplaceAll) && (!isEntire)))) //if selection limiter and either mark all or replace all w/o entire document override + { + startPosition = cr.cpMin; + endPosition = cr.cpMax; + } + + return processRange(op, txt2find, txt2replace, startPosition, endPosition, fileName, opt); +} + +int FindReplaceDlg::processRange(ProcessOperation op, const char *txt2find, const char *txt2replace, int startRange, int endRange, const char *fileName, FindOption *opt) +{ + int nbProcessed = 0; if (!isCreated() && !txt2find) - return nbReplaced; + return nbProcessed; if ((op == ProcessReplaceAll) && (*_ppEditView)->getCurrentBuffer()->isReadOnly()) - return nbReplaced; + return nbProcessed; + + if (startRange == endRange) + return nbProcessed; if (!fileName) fileName = ""; @@ -1022,7 +1070,7 @@ int FindReplaceDlg::processAll(ProcessOperation op, const char *txt2find, const if (!pTextFind[0]) { delete [] pTextFind; - return nbReplaced; + return nbProcessed; } char *pTextReplace = NULL; @@ -1049,47 +1097,9 @@ int FindReplaceDlg::processAll(ProcessOperation op, const char *txt2find, const bool isRegExp = pOptions->_searchType == FindRegex; int flags = Searching::buildSearchFlags(pOptions); - CharacterRange cr = (*_ppEditView)->getSelection(); - int docLength = int((*_ppEditView)->execute(SCI_GETLENGTH)); - - // Default : - // direction : down - // begin at : 0 - // end at : end of doc - int startPosition = 0; - int endPosition = docLength; - - bool direction = pOptions->_whichDirection; - - //first try limiting scope by direction - if (direction == DIR_UP) - { - startPosition = cr.cpMax; - endPosition = 0; - } - else - { - startPosition = cr.cpMin; - endPosition = docLength; - } - - //then adjust scope if the full document needs to be changed - if (pOptions->_isWrapAround || isEntire || (op == ProcessCountAll)) //entire document needs to be scanned - { - startPosition = 0; - endPosition = docLength; - direction = DIR_DOWN; - } - - //then readjust scope if the selection override is active and allowed - if ((_isInSelection) && ((op == ProcessMarkAll) || ((op == ProcessReplaceAll) && (!isEntire)))) //if selection limiter and either mark all or replace all w/o entire document override - { - startPosition = cr.cpMin; - endPosition = cr.cpMax; - } - - (*_ppEditView)->execute(SCI_SETTARGETSTART, startPosition); - (*_ppEditView)->execute(SCI_SETTARGETEND, endPosition); + //Initial range for searching + (*_ppEditView)->execute(SCI_SETTARGETSTART, startRange); + (*_ppEditView)->execute(SCI_SETTARGETEND, endRange); (*_ppEditView)->execute(SCI_SETSEARCHFLAGS, flags); if (op == ProcessMarkAll) //if marking, check if purging is needed @@ -1103,9 +1113,12 @@ int FindReplaceDlg::processAll(ProcessOperation op, const char *txt2find, const } } - int posFind = int((*_ppEditView)->execute(SCI_SEARCHINTARGET, (WPARAM)stringSizeFind, (LPARAM)pTextFind)); + int targetStart = 0; + int targetEnd = 0; + + targetStart = int((*_ppEditView)->execute(SCI_SEARCHINTARGET, (WPARAM)stringSizeFind, (LPARAM)pTextFind)); - if ((posFind != -1) && (op == ProcessFindAll)) //add new filetitle if this file results in hits + if ((targetStart != -1) && (op == ProcessFindAll)) //add new filetitle if this file results in hits { const int fileNameLen = strlen(fileName); @@ -1119,14 +1132,18 @@ int FindReplaceDlg::processAll(ProcessOperation op, const char *txt2find, const ascii_to_utf8(fileName, fileNameLen, _uniFileName); _pFinder->addFileNameTitle(_uniFileName); } - while (posFind != -1) + while (targetStart != -1) { //int posFindBefore = posFind; - int start = int((*_ppEditView)->execute(SCI_GETTARGETSTART)); - int end = int((*_ppEditView)->execute(SCI_GETTARGETEND)); - int foundTextLen = (end >= start)?end - start:start - end; + targetStart = int((*_ppEditView)->execute(SCI_GETTARGETSTART)); + targetEnd = int((*_ppEditView)->execute(SCI_GETTARGETEND)); + if (targetEnd > endRange) { //we found a result but outside our range, therefore do not process it + break; + } + int foundTextLen = targetEnd - targetStart; + int replaceDelta = 0; - // Search resulted in empty token, problematic (can this happen?)!!! + // Search resulted in empty token, possible with RE if (!foundTextLen) { delete [] pTextFind; delete [] pTextReplace; @@ -1135,7 +1152,7 @@ int FindReplaceDlg::processAll(ProcessOperation op, const char *txt2find, const switch (op) { case ProcessFindAll: { - int lineNumber = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, posFind); + int lineNumber = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, targetStart); int lend = (*_ppEditView)->execute(SCI_GETLINEENDPOSITION, lineNumber); int lstart = (*_ppEditView)->execute(SCI_POSITIONFROMLINE, lineNumber); int nbChar = lend - lstart; @@ -1171,83 +1188,66 @@ int FindReplaceDlg::processAll(ProcessOperation op, const char *txt2find, const pLine = _line; } //printStr(isUnicode?"unicode":"no unicode"); - _pFinder->add(FoundInfo(start, end, pLine, fileName, _pFinder->_lineCounter), lineNumber + 1); - - startPosition = posFind + foundTextLen; + _pFinder->add(FoundInfo(targetStart, targetEnd, pLine, fileName, _pFinder->_lineCounter), lineNumber + 1); break; } case ProcessReplaceAll: { - (*_ppEditView)->execute(SCI_SETTARGETSTART, start); - (*_ppEditView)->execute(SCI_SETTARGETEND, end); int replacedLength = (*_ppEditView)->execute(isRegExp?SCI_REPLACETARGETRE:SCI_REPLACETARGET, (WPARAM)stringSizeReplace, (LPARAM)pTextReplace); - - startPosition = (direction == DIR_UP)?posFind - replacedLength:posFind + replacedLength; - if ((_isInSelection) && (!isEntire)) - { - endPosition = endPosition - foundTextLen + replacedLength; - } - else - { - if (direction == DIR_DOWN) - endPosition = docLength = docLength - foundTextLen + replacedLength; - } + replaceDelta = replacedLength - foundTextLen; break; } case ProcessMarkAll: { if (_doStyleFoundToken) { (*_ppEditView)->execute(SCI_SETINDICATORCURRENT, SCE_UNIVERSAL_FOUND_STYLE); - (*_ppEditView)->execute(SCI_INDICATORFILLRANGE, start, end - start); + (*_ppEditView)->execute(SCI_INDICATORFILLRANGE, targetStart, foundTextLen); } if (_doMarkLine) { - int lineNumber = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, posFind); + int lineNumber = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, targetStart); int state = (*_ppEditView)->execute(SCI_MARKERGET, lineNumber); if (!(state & (1 << MARK_BOOKMARK))) (*_ppEditView)->execute(SCI_MARKERADD, lineNumber, MARK_BOOKMARK); } - startPosition = (direction == DIR_UP)?posFind - foundTextLen:posFind + foundTextLen; break; } case ProcessMarkAll_2: { (*_ppEditView)->execute(SCI_SETINDICATORCURRENT, SCE_UNIVERSAL_FOUND_STYLE_2); - (*_ppEditView)->execute(SCI_INDICATORFILLRANGE, start, end - start); - - startPosition = (direction == DIR_UP)?posFind - foundTextLen:posFind + foundTextLen; + (*_ppEditView)->execute(SCI_INDICATORFILLRANGE, targetStart, foundTextLen); break; } case ProcessMarkAll_IncSearch: { (*_ppEditView)->execute(SCI_SETINDICATORCURRENT, SCE_UNIVERSAL_FOUND_STYLE_INC); - (*_ppEditView)->execute(SCI_INDICATORFILLRANGE, start, end - start); - - startPosition = (direction == DIR_UP)?posFind - foundTextLen:posFind + foundTextLen; + (*_ppEditView)->execute(SCI_INDICATORFILLRANGE, targetStart, foundTextLen); break; } case ProcessCountAll: { - startPosition = posFind + foundTextLen; + //Nothing to do break; } default: { delete [] pTextFind; delete [] pTextReplace; - return nbReplaced; + return nbProcessed; } } - (*_ppEditView)->execute(SCI_SETTARGETSTART, startPosition); - (*_ppEditView)->execute(SCI_SETTARGETEND, endPosition); + startRange = targetStart + foundTextLen + replaceDelta; //search from result onwards + endRange += replaceDelta; //adjust end of range in case of replace + (*_ppEditView)->execute(SCI_SETTARGETSTART, startRange); + (*_ppEditView)->execute(SCI_SETTARGETEND, endRange); - posFind = int((*_ppEditView)->execute(SCI_SEARCHINTARGET, (WPARAM)stringSizeFind, (LPARAM)pTextFind)); - nbReplaced++; + nbProcessed++; + targetStart = (int)((*_ppEditView)->execute(SCI_SEARCHINTARGET, (WPARAM)stringSizeFind, (LPARAM)pTextFind)); } delete [] pTextFind; delete [] pTextReplace; - return nbReplaced; + return nbProcessed; } void FindReplaceDlg::replaceAllInOpenedDocs() diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h index 38acde1c4..f93bf5d54 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h @@ -252,6 +252,7 @@ public : int markAllInc(const char *str2find, FindOption *opt); int processAll(ProcessOperation op, const char *txt2find, const char *txt2replace, bool isEntire = false, const char *fileName = NULL, FindOption *opt = NULL); + int processRange(ProcessOperation op, const char *txt2find, const char *txt2replace, int startRange, int endRange, const char *fileName = NULL, FindOption *opt = NULL); void replaceAllInOpenedDocs(); void findAllIn(InWhat op); void setSearchText(const char * txt2find, bool isUTF8 = false) { diff --git a/PowerEditor/src/ScitillaComponent/SmartHighlighter.cpp b/PowerEditor/src/ScitillaComponent/SmartHighlighter.cpp new file mode 100644 index 000000000..7bfcd5d9d --- /dev/null +++ b/PowerEditor/src/ScitillaComponent/SmartHighlighter.cpp @@ -0,0 +1,157 @@ +//this file is part of notepad++ +//Copyright (C)2003 Harry +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include "SmartHighlighter.h" +#include "Parameters.h" + +#define MAXLINEHIGHLIGHT 400 //prevent highlighter from doing too much work when a lot is visible + +SmartHighlighter::SmartHighlighter(FindReplaceDlg * pFRDlg) +: _pFRDlg(pFRDlg) +{ + //Nothing to do +} + +void SmartHighlighter::highlightView(ScintillaEditView * pHighlightView) +{ + const NppGUI & nppGUI = (NppParameters::getInstance())->getNppGUI(); + if (!nppGUI._enableSmartHilite) + return; + + //Get selection + CharacterRange range = pHighlightView->getSelection(); + + //if (pHighlightView->isSelecting()) + // return; + + //Clear marks + pHighlightView->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE_2); + + //If nothing selected, dont mark anything + if (range.cpMin == range.cpMax) + { + return; + } + + int textlen = range.cpMax - range.cpMin + 1; + + char * text2Find = new char[textlen]; + pHighlightView->getSelectedText(text2Find, textlen, false); //do not expand selection (false) + + bool valid = true; + //The word has to consist if wordChars only, and the characters before and after something else + if (!isQualifiedWord(text2Find)) + valid = false; + else + { + unsigned char c = (unsigned char)pHighlightView->execute(SCI_GETCHARAT, range.cpMax); + if (c) + { + if (isWordChar(char(c))) + valid = false; + } + c = (unsigned char)pHighlightView->execute(SCI_GETCHARAT, range.cpMin-1); + if (c) + { + if (isWordChar(char(c))) + valid = false; + } + } + if (!valid) { + delete [] text2Find; + return; + } + + // save target locations for other search functions + int originalStartPos = (int)pHighlightView->execute(SCI_GETTARGETSTART); + int originalEndPos = (int)pHighlightView->execute(SCI_GETTARGETEND); + + // Get the range of text visible and highlight everything in it + int firstLine = (int)pHighlightView->execute(SCI_GETFIRSTVISIBLELINE); + int nrLines = min((int)pHighlightView->execute(SCI_LINESONSCREEN), MAXLINEHIGHLIGHT ) + 1; + int lastLine = (int)pHighlightView->execute(SCI_DOCLINEFROMVISIBLE, firstLine + nrLines); + int startPos = (int)pHighlightView->execute(SCI_POSITIONFROMLINE, firstLine); + int endPos = (int)pHighlightView->execute(SCI_POSITIONFROMLINE, lastLine); + if (endPos == -1) { //past EOF + endPos = (int)pHighlightView->getCurrentDocLen() - 1; + } + + FindOption fo; + fo._isMatchCase = true; + fo._isWholeWord = true; + _pFRDlg->processRange(ProcessMarkAll_2, text2Find, NULL, startPos, endPos, NULL, &fo); + + // restore the original targets to avoid conflicts with the search/replace functions + pHighlightView->execute(SCI_SETTARGETSTART, originalStartPos); + pHighlightView->execute(SCI_SETTARGETEND, originalEndPos); +} + +bool SmartHighlighter::isQualifiedWord(const char *str) const +{ + for (size_t i = 0 ; i < strlen(str) ; i++) + { + if (!isWordChar(str[i])) + return false; + } + return true; +}; + +bool SmartHighlighter::isWordChar(char ch) const +{ + if ((unsigned char)ch < 0x20) + return false; + + switch(ch) + { + case ' ': + case ' ': + case '\n': + case '\r': + case '.': + case ',': + case '?': + case ';': + case ':': + case '!': + case '(': + case ')': + case '[': + case ']': + case '+': + case '-': + case '*': + case '/': + case '#': + case '@': + case '^': + case '%': + case '$': + case '"': + case '\'': + case '~': + case '&': + case '{': + case '}': + case '|': + case '=': + case '<': + case '>': + case '\\': + return false; + } + return true; +}; diff --git a/PowerEditor/src/ScitillaComponent/SmartHighlighter.h b/PowerEditor/src/ScitillaComponent/SmartHighlighter.h new file mode 100644 index 000000000..fe72055d2 --- /dev/null +++ b/PowerEditor/src/ScitillaComponent/SmartHighlighter.h @@ -0,0 +1,35 @@ +//this file is part of notepad++ +//Copyright (C)2003 Harry +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef SMARTHIGHLIGHTER_H +#define SMARTHIGHLIGHTER_H + +#include "ScintillaEditView.h" +#include "FindReplaceDlg.h" + +class SmartHighlighter { +public: + SmartHighlighter(FindReplaceDlg * pFRDlg); + void highlightView(ScintillaEditView * pHighlightView); +private: + FindReplaceDlg * _pFRDlg; + + bool isQualifiedWord(const char *str) const; + bool isWordChar(char ch) const; +}; + +#endif //SMARTHIGHLIGHTER_H \ No newline at end of file diff --git a/PowerEditor/visual.net/notepadPlus.vc.7.0.vcproj b/PowerEditor/visual.net/notepadPlus.vc.7.0.vcproj index b2cb2ebd9..5d1bb5b90 100644 --- a/PowerEditor/visual.net/notepadPlus.vc.7.0.vcproj +++ b/PowerEditor/visual.net/notepadPlus.vc.7.0.vcproj @@ -229,6 +229,9 @@ IF NOT EXIST ..\bin\userDefineLang.xml COPY ..\src\userDefineLang.xml ..\bin\use + + @@ -453,6 +456,9 @@ IF NOT EXIST ..\bin\userDefineLang.xml COPY ..\src\userDefineLang.xml ..\bin\use + + diff --git a/scintilla/include/Scintilla.h b/scintilla/include/Scintilla.h index 3c5aab5e7..e0786cdd3 100644 --- a/scintilla/include/Scintilla.h +++ b/scintilla/include/Scintilla.h @@ -754,6 +754,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCN_AUTOCSELECTION 2022 #define SCN_INDICATORCLICK 2023 #define SCN_INDICATORRELEASE 2024 + +#define SCN_SCROLLED 2080 //--Autogenerated -- end of section automatically generated from Scintilla.iface // These structures are defined to be exactly the same shape as the Win32 diff --git a/scintilla/src/Editor.cxx b/scintilla/src/Editor.cxx index 9afaaa5d1..a54d1632e 100644 --- a/scintilla/src/Editor.cxx +++ b/scintilla/src/Editor.cxx @@ -898,6 +898,7 @@ void Editor::ScrollTo(int line, bool moveThumb) { if (moveThumb) { SetVerticalScrollPos(); } + NotifyScrolled(); } } @@ -915,6 +916,8 @@ void Editor::HorizontalScrollTo(int xPos) { SetHorizontalScrollPos(); RedrawRect(GetClientRectangle()); } + + NotifyScrolled(); } void Editor::MoveCaretInsideView(bool ensureVisible) { @@ -3714,6 +3717,12 @@ void Editor::NotifyPainted() { NotifyParent(scn); } +void Editor::NotifyScrolled() { + SCNotification scn = {0}; + scn.nmhdr.code = SCN_SCROLLED; + NotifyParent(scn); +} + void Editor::NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt) { int mask = pdoc->decorations.AllOnFor(position); if ((click && mask) || pdoc->decorations.clickNotified) { diff --git a/scintilla/src/Editor.h b/scintilla/src/Editor.h index a6ceec009..03ae10715 100644 --- a/scintilla/src/Editor.h +++ b/scintilla/src/Editor.h @@ -370,6 +370,7 @@ protected: // ScintillaBase subclass needs access to much of Editor void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt); void NotifyUpdateUI(); void NotifyPainted(); + void NotifyScrolled(); void NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt); bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt); void NotifyNeedShown(int pos, int len);