notepad-plus-plus/PowerEditor/src/ScitillaComponent/SmartHighlighter.cpp

180 lines
5.0 KiB
C++
Raw Normal View History

//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 "precompiledHeaders.h"
#include "SmartHighlighter.h"
#include "ScintillaEditView.h"
#include "FindReplaceDlg.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)
{
//Get selection
CharacterRange range = pHighlightView->getSelection();
//Clear marks
pHighlightView->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE_SMART);
//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
{
UCHAR c = (UCHAR)pHighlightView->execute(SCI_GETCHARAT, range.cpMax);
if (c)
{
if (isWordChar(char(c)))
valid = false;
}
c = (UCHAR)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 = firstLine+nrLines;
int startPos = 0;//(int)pHighlightView->execute(SCI_POSITIONFROMLINE, firstLine);
int endPos = 0;//(int)pHighlightView->execute(SCI_POSITIONFROMLINE, lastLine);
//if (endPos == -1) { //past EOF
// endPos = (int)pHighlightView->getCurrentDocLen() - 1;
//}
int currentLine = firstLine;
int prevDocLineChecked = -1; //invalid start
FindOption fo;
fo._isMatchCase = false;
fo._isWholeWord = true;
const TCHAR * searchText = NULL;
#ifdef UNICODE
WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance();
unsigned int cp = pHighlightView->execute(SCI_GETCODEPAGE);
const TCHAR * text2FindW = wmc->char2wchar(text2Find, cp);
searchText = text2FindW;
#else
searchText = text2Find;
#endif
for(; currentLine < lastLine; currentLine++) {
int docLine = (int)pHighlightView->execute(SCI_DOCLINEFROMVISIBLE, currentLine);
if (docLine == prevDocLineChecked)
continue; //still on same line (wordwrap)
prevDocLineChecked = docLine;
startPos = (int)pHighlightView->execute(SCI_POSITIONFROMLINE, docLine);
endPos = (int)pHighlightView->execute(SCI_POSITIONFROMLINE, docLine+1);
if (endPos == -1) { //past EOF
endPos = (int)pHighlightView->getCurrentDocLen() - 1;
_pFRDlg->processRange(ProcessMarkAll_2, searchText, NULL, startPos, endPos, NULL, &fo);
break;
} else {
_pFRDlg->processRange(ProcessMarkAll_2, searchText, 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 ((UCHAR)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;
};