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
This commit is contained in:
harrybharry 2008-07-17 13:18:24 +00:00
parent ea80233f65
commit fb94eb5ec5
10 changed files with 318 additions and 210 deletions

View File

@ -44,8 +44,6 @@
const char Notepad_plus::_className[32] = NOTEPAD_PP_CLASS_NAME; const char Notepad_plus::_className[32] = NOTEPAD_PP_CLASS_NAME;
const char *urlHttpRegExpr = "http://[a-z0-9_\\-\\+.:?&@=/%#]*"; 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}; int docTabIconIDs[] = {IDI_SAVED_ICON, IDI_UNSAVED_ICON, IDI_READONLY_ICON};
enum tb_stat {tb_saved, tb_unsaved, tb_ro}; 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), _pMainSplitter(NULL), _isfullScreen(false),
_recordingMacro(false), _pTrayIco(NULL), _isUDDocked(false), _isRTL(false), _recordingMacro(false), _pTrayIco(NULL), _isUDDocked(false), _isRTL(false),
_linkTriggered(true), _isDocModifing(false), _isHotspotDblClicked(false), _sysMenuEntering(false), _linkTriggered(true), _isDocModifing(false), _isHotspotDblClicked(false), _sysMenuEntering(false),
_autoCompleteMain(&_mainEditView), _autoCompleteSub(&_subEditView) _autoCompleteMain(&_mainEditView), _autoCompleteSub(&_subEditView), _smartHighlighter(&_findReplaceDlg)
{ {
ZeroMemory(&_prevSelectedRange, sizeof(_prevSelectedRange)); ZeroMemory(&_prevSelectedRange, sizeof(_prevSelectedRange));
@ -2204,10 +2202,6 @@ BOOL Notepad_plus::notify(SCNotification *notification)
notifyView->execute(SCI_SETANCHOR, pos); notifyView->execute(SCI_SETANCHOR, pos);
_isHotspotDblClicked = false; _isHotspotDblClicked = false;
} }
else
{
markSelectedText();
}
} }
break; break;
@ -2221,14 +2215,19 @@ BOOL Notepad_plus::notify(SCNotification *notification)
XmlMatchedTagsHighlighter xmlTagMatchHiliter(_pEditView); XmlMatchedTagsHighlighter xmlTagMatchHiliter(_pEditView);
xmlTagMatchHiliter.tagMatch(nppGUI._enableTagAttrsHilite); xmlTagMatchHiliter.tagMatch(nppGUI._enableTagAttrsHilite);
} }
_smartHighlighter.highlightView(notifyView);
markSelectedText();
updateStatusBar(); updateStatusBar();
AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub; AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub;
autoC->update(0); autoC->update(0);
break; break;
} }
case SCN_SCROLLED:
{
_smartHighlighter.highlightView(notifyView);
break;
}
case TTN_GETDISPINFO: case TTN_GETDISPINFO:
{ {
LPTOOLTIPTEXT lpttt; LPTOOLTIPTEXT lpttt;
@ -5762,12 +5761,6 @@ LRESULT Notepad_plus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa
} }
case WM_CREATE: 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 // Menu
_mainMenuHandle = ::GetMenu(_hSelf); _mainMenuHandle = ::GetMenu(_hSelf);
@ -5777,15 +5770,21 @@ LRESULT Notepad_plus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa
_pNonDocTab = &_subDocTab; _pNonDocTab = &_subDocTab;
_pNonEditView = &_subEditView; _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; _mainWindowStatus = WindowMainActive;
_activeView = MAIN_VIEW; _activeView = MAIN_VIEW;
const ScintillaViewParams & svp1 = pNppParam->getSVP(SCIV_PRIMARY); const ScintillaViewParams & svp1 = pNppParam->getSVP(SCIV_PRIMARY);
const ScintillaViewParams & svp2 = pNppParam->getSVP(SCIV_SECOND); const ScintillaViewParams & svp2 = pNppParam->getSVP(SCIV_SECOND);
_mainEditView.init(_hInst, hwnd);
_subEditView.init(_hInst, hwnd);
int tabBarStatus = nppGUI._tabStatus; int tabBarStatus = nppGUI._tabStatus;
_toReduceTabBar = ((tabBarStatus & TAB_REDUCE) != 0); _toReduceTabBar = ((tabBarStatus & TAB_REDUCE) != 0);
_docTabIconList.create(_toReduceTabBar?13:20, _hInst, docTabIconIDs, sizeof(docTabIconIDs)/sizeof(int)); _docTabIconList.create(_toReduceTabBar?13:20, _hInst, docTabIconIDs, sizeof(docTabIconIDs)/sizeof(int));
@ -7989,56 +7988,6 @@ bool Notepad_plus::str2Cliboard(const char *str2cpy)
return true; 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 //ONLY CALL IN CASE OF EMERGENCY: EXCEPTION
//This function is destructive //This function is destructive
bool Notepad_plus::emergency() { bool Notepad_plus::emergency() {

View File

@ -48,6 +48,7 @@
#include "Process.h" #include "Process.h"
#include "AutoCompletion.h" #include "AutoCompletion.h"
#include "Buffer.h" #include "Buffer.h"
#include "SmartHighlighter.h"
#define NOTEPAD_PP_CLASS_NAME "Notepad++" #define NOTEPAD_PP_CLASS_NAME "Notepad++"
@ -189,7 +190,6 @@ public:
void notifyBufferChanged(Buffer * buffer, int mask); void notifyBufferChanged(Buffer * buffer, int mask);
private: private:
void loadCommandlineParams(const char * commandLine, CmdLineParams * pCmdParams);
static const char _className[32]; static const char _className[32];
char _nppPath[MAX_PATH]; char _nppPath[MAX_PATH];
Window *_pMainWindow; Window *_pMainWindow;
@ -198,6 +198,8 @@ private:
AutoCompletion _autoCompleteMain; AutoCompletion _autoCompleteMain;
AutoCompletion _autoCompleteSub; //each Scintilla has its own autoComplete AutoCompletion _autoCompleteSub; //each Scintilla has its own autoComplete
SmartHighlighter _smartHighlighter;
TiXmlNode *_nativeLang, *_toolIcons; TiXmlNode *_nativeLang, *_toolIcons;
DocTabView _mainDocTab; DocTabView _mainDocTab;
@ -752,7 +754,6 @@ private:
}; };
void setFileOpenSaveDlgFilters(FileDialog & fDlg); void setFileOpenSaveDlgFilters(FileDialog & fDlg);
void markSelectedText();
void markSelectedTextInc(bool enable); void markSelectedTextInc(bool enable);
Style * getStyleFromName(const char *styleName) { Style * getStyleFromName(const char *styleName) {
@ -768,63 +769,10 @@ private:
return st; 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 bool dumpFiles(const char * outdir, const char * fileprefix = ""); //helper func
void drawTabbarColoursFromStylerArray(); void drawTabbarColoursFromStylerArray();
void loadCommandlineParams(const char * commandLine, CmdLineParams * pCmdParams);
}; };
#endif //NOTEPAD_PLUS_H #endif //NOTEPAD_PLUS_H

View File

@ -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 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) if (!isCreated() && !txt2find)
return nbReplaced; return nbProcessed;
if ((op == ProcessReplaceAll) && (*_ppEditView)->getCurrentBuffer()->isReadOnly()) if ((op == ProcessReplaceAll) && (*_ppEditView)->getCurrentBuffer()->isReadOnly())
return nbReplaced; return nbProcessed;
if (startRange == endRange)
return nbProcessed;
if (!fileName) if (!fileName)
fileName = ""; fileName = "";
@ -1022,7 +1070,7 @@ int FindReplaceDlg::processAll(ProcessOperation op, const char *txt2find, const
if (!pTextFind[0]) { if (!pTextFind[0]) {
delete [] pTextFind; delete [] pTextFind;
return nbReplaced; return nbProcessed;
} }
char *pTextReplace = NULL; char *pTextReplace = NULL;
@ -1049,47 +1097,9 @@ int FindReplaceDlg::processAll(ProcessOperation op, const char *txt2find, const
bool isRegExp = pOptions->_searchType == FindRegex; bool isRegExp = pOptions->_searchType == FindRegex;
int flags = Searching::buildSearchFlags(pOptions); int flags = Searching::buildSearchFlags(pOptions);
CharacterRange cr = (*_ppEditView)->getSelection(); //Initial range for searching
int docLength = int((*_ppEditView)->execute(SCI_GETLENGTH)); (*_ppEditView)->execute(SCI_SETTARGETSTART, startRange);
(*_ppEditView)->execute(SCI_SETTARGETEND, endRange);
// 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);
(*_ppEditView)->execute(SCI_SETSEARCHFLAGS, flags); (*_ppEditView)->execute(SCI_SETSEARCHFLAGS, flags);
if (op == ProcessMarkAll) //if marking, check if purging is needed 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); const int fileNameLen = strlen(fileName);
@ -1119,14 +1132,18 @@ int FindReplaceDlg::processAll(ProcessOperation op, const char *txt2find, const
ascii_to_utf8(fileName, fileNameLen, _uniFileName); ascii_to_utf8(fileName, fileNameLen, _uniFileName);
_pFinder->addFileNameTitle(_uniFileName); _pFinder->addFileNameTitle(_uniFileName);
} }
while (posFind != -1) while (targetStart != -1)
{ {
//int posFindBefore = posFind; //int posFindBefore = posFind;
int start = int((*_ppEditView)->execute(SCI_GETTARGETSTART)); targetStart = int((*_ppEditView)->execute(SCI_GETTARGETSTART));
int end = int((*_ppEditView)->execute(SCI_GETTARGETEND)); targetEnd = int((*_ppEditView)->execute(SCI_GETTARGETEND));
int foundTextLen = (end >= start)?end - start:start - end; 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) { if (!foundTextLen) {
delete [] pTextFind; delete [] pTextFind;
delete [] pTextReplace; delete [] pTextReplace;
@ -1135,7 +1152,7 @@ int FindReplaceDlg::processAll(ProcessOperation op, const char *txt2find, const
switch (op) { switch (op) {
case ProcessFindAll: { case ProcessFindAll: {
int lineNumber = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, posFind); int lineNumber = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, targetStart);
int lend = (*_ppEditView)->execute(SCI_GETLINEENDPOSITION, lineNumber); int lend = (*_ppEditView)->execute(SCI_GETLINEENDPOSITION, lineNumber);
int lstart = (*_ppEditView)->execute(SCI_POSITIONFROMLINE, lineNumber); int lstart = (*_ppEditView)->execute(SCI_POSITIONFROMLINE, lineNumber);
int nbChar = lend - lstart; int nbChar = lend - lstart;
@ -1171,83 +1188,66 @@ int FindReplaceDlg::processAll(ProcessOperation op, const char *txt2find, const
pLine = _line; pLine = _line;
} }
//printStr(isUnicode?"unicode":"no unicode"); //printStr(isUnicode?"unicode":"no unicode");
_pFinder->add(FoundInfo(start, end, pLine, fileName, _pFinder->_lineCounter), lineNumber + 1); _pFinder->add(FoundInfo(targetStart, targetEnd, pLine, fileName, _pFinder->_lineCounter), lineNumber + 1);
startPosition = posFind + foundTextLen;
break; } break; }
case ProcessReplaceAll: { 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); int replacedLength = (*_ppEditView)->execute(isRegExp?SCI_REPLACETARGETRE:SCI_REPLACETARGET, (WPARAM)stringSizeReplace, (LPARAM)pTextReplace);
replaceDelta = replacedLength - foundTextLen;
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;
}
break; } break; }
case ProcessMarkAll: { case ProcessMarkAll: {
if (_doStyleFoundToken) if (_doStyleFoundToken)
{ {
(*_ppEditView)->execute(SCI_SETINDICATORCURRENT, SCE_UNIVERSAL_FOUND_STYLE); (*_ppEditView)->execute(SCI_SETINDICATORCURRENT, SCE_UNIVERSAL_FOUND_STYLE);
(*_ppEditView)->execute(SCI_INDICATORFILLRANGE, start, end - start); (*_ppEditView)->execute(SCI_INDICATORFILLRANGE, targetStart, foundTextLen);
} }
if (_doMarkLine) if (_doMarkLine)
{ {
int lineNumber = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, posFind); int lineNumber = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, targetStart);
int state = (*_ppEditView)->execute(SCI_MARKERGET, lineNumber); int state = (*_ppEditView)->execute(SCI_MARKERGET, lineNumber);
if (!(state & (1 << MARK_BOOKMARK))) if (!(state & (1 << MARK_BOOKMARK)))
(*_ppEditView)->execute(SCI_MARKERADD, lineNumber, MARK_BOOKMARK); (*_ppEditView)->execute(SCI_MARKERADD, lineNumber, MARK_BOOKMARK);
} }
startPosition = (direction == DIR_UP)?posFind - foundTextLen:posFind + foundTextLen;
break; } break; }
case ProcessMarkAll_2: { case ProcessMarkAll_2: {
(*_ppEditView)->execute(SCI_SETINDICATORCURRENT, SCE_UNIVERSAL_FOUND_STYLE_2); (*_ppEditView)->execute(SCI_SETINDICATORCURRENT, SCE_UNIVERSAL_FOUND_STYLE_2);
(*_ppEditView)->execute(SCI_INDICATORFILLRANGE, start, end - start); (*_ppEditView)->execute(SCI_INDICATORFILLRANGE, targetStart, foundTextLen);
startPosition = (direction == DIR_UP)?posFind - foundTextLen:posFind + foundTextLen;
break; } break; }
case ProcessMarkAll_IncSearch: { case ProcessMarkAll_IncSearch: {
(*_ppEditView)->execute(SCI_SETINDICATORCURRENT, SCE_UNIVERSAL_FOUND_STYLE_INC); (*_ppEditView)->execute(SCI_SETINDICATORCURRENT, SCE_UNIVERSAL_FOUND_STYLE_INC);
(*_ppEditView)->execute(SCI_INDICATORFILLRANGE, start, end - start); (*_ppEditView)->execute(SCI_INDICATORFILLRANGE, targetStart, foundTextLen);
startPosition = (direction == DIR_UP)?posFind - foundTextLen:posFind + foundTextLen;
break; } break; }
case ProcessCountAll: { case ProcessCountAll: {
startPosition = posFind + foundTextLen; //Nothing to do
break; } break; }
default: { default: {
delete [] pTextFind; delete [] pTextFind;
delete [] pTextReplace; delete [] pTextReplace;
return nbReplaced; return nbProcessed;
} }
} }
(*_ppEditView)->execute(SCI_SETTARGETSTART, startPosition); startRange = targetStart + foundTextLen + replaceDelta; //search from result onwards
(*_ppEditView)->execute(SCI_SETTARGETEND, endPosition); 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)); nbProcessed++;
nbReplaced++; targetStart = (int)((*_ppEditView)->execute(SCI_SEARCHINTARGET, (WPARAM)stringSizeFind, (LPARAM)pTextFind));
} }
delete [] pTextFind; delete [] pTextFind;
delete [] pTextReplace; delete [] pTextReplace;
return nbReplaced; return nbProcessed;
} }
void FindReplaceDlg::replaceAllInOpenedDocs() void FindReplaceDlg::replaceAllInOpenedDocs()

View File

@ -252,6 +252,7 @@ public :
int markAllInc(const char *str2find, FindOption *opt); 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 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 replaceAllInOpenedDocs();
void findAllIn(InWhat op); void findAllIn(InWhat op);
void setSearchText(const char * txt2find, bool isUTF8 = false) { void setSearchText(const char * txt2find, bool isUTF8 = false) {

View File

@ -0,0 +1,157 @@
//this file is part of notepad++
//Copyright (C)2003 Harry <harrybharry@users.sourceforge.net>
//
//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;
};

View File

@ -0,0 +1,35 @@
//this file is part of notepad++
//Copyright (C)2003 Harry <harrybharry@users.sourceforge.net>
//
//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

View File

@ -229,6 +229,9 @@ IF NOT EXIST ..\bin\userDefineLang.xml COPY ..\src\userDefineLang.xml ..\bin\use
<File <File
RelativePath="..\src\ScitillaComponent\ScintillaEditView.cpp"> RelativePath="..\src\ScitillaComponent\ScintillaEditView.cpp">
</File> </File>
<File
RelativePath="..\src\ScitillaComponent\SmartHighlighter.cpp">
</File>
<File <File
RelativePath="..\src\ScitillaComponent\UserDefineDialog.cpp"> RelativePath="..\src\ScitillaComponent\UserDefineDialog.cpp">
</File> </File>
@ -453,6 +456,9 @@ IF NOT EXIST ..\bin\userDefineLang.xml COPY ..\src\userDefineLang.xml ..\bin\use
<File <File
RelativePath="..\src\ScitillaComponent\ScintillaEditView.h"> RelativePath="..\src\ScitillaComponent\ScintillaEditView.h">
</File> </File>
<File
RelativePath="..\src\ScitillaComponent\SmartHighlighter.h">
</File>
<File <File
RelativePath="..\src\ScitillaComponent\UserDefineDialog.h"> RelativePath="..\src\ScitillaComponent\UserDefineDialog.h">
</File> </File>

View File

@ -754,6 +754,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCN_AUTOCSELECTION 2022 #define SCN_AUTOCSELECTION 2022
#define SCN_INDICATORCLICK 2023 #define SCN_INDICATORCLICK 2023
#define SCN_INDICATORRELEASE 2024 #define SCN_INDICATORRELEASE 2024
#define SCN_SCROLLED 2080
//--Autogenerated -- end of section automatically generated from Scintilla.iface //--Autogenerated -- end of section automatically generated from Scintilla.iface
// These structures are defined to be exactly the same shape as the Win32 // These structures are defined to be exactly the same shape as the Win32

View File

@ -898,6 +898,7 @@ void Editor::ScrollTo(int line, bool moveThumb) {
if (moveThumb) { if (moveThumb) {
SetVerticalScrollPos(); SetVerticalScrollPos();
} }
NotifyScrolled();
} }
} }
@ -915,6 +916,8 @@ void Editor::HorizontalScrollTo(int xPos) {
SetHorizontalScrollPos(); SetHorizontalScrollPos();
RedrawRect(GetClientRectangle()); RedrawRect(GetClientRectangle());
} }
NotifyScrolled();
} }
void Editor::MoveCaretInsideView(bool ensureVisible) { void Editor::MoveCaretInsideView(bool ensureVisible) {
@ -3714,6 +3717,12 @@ void Editor::NotifyPainted() {
NotifyParent(scn); 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) { void Editor::NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt) {
int mask = pdoc->decorations.AllOnFor(position); int mask = pdoc->decorations.AllOnFor(position);
if ((click && mask) || pdoc->decorations.clickNotified) { if ((click && mask) || pdoc->decorations.clickNotified) {

View File

@ -370,6 +370,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt); void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt);
void NotifyUpdateUI(); void NotifyUpdateUI();
void NotifyPainted(); void NotifyPainted();
void NotifyScrolled();
void NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt); void NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt);
bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt); bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt);
void NotifyNeedShown(int pos, int len); void NotifyNeedShown(int pos, int len);