[NEW_FEATURE] Enhance "Find in all opened files" and "Find in files" features.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository@410 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
donho 2009-02-04 01:06:38 +00:00
parent 7d2eb78375
commit 7705e0b571
15 changed files with 503 additions and 344 deletions

View File

@ -268,6 +268,38 @@ const wchar_t * WcharMbcsConvertor::char2wchar(const char * mbcs2Convert, UINT c
return _wideCharStr;
}
// "mstart" and "mend" are pointers to indexes in mbcs2Convert,
// which are converted to the corresponding indexes in the returned wchar_t string.
const wchar_t * WcharMbcsConvertor::char2wchar(const char * mbcs2Convert, UINT codepage, int *mstart, int *mend)
{
if (!_wideCharStr)
{
_wideCharStr = new wchar_t[initSize];
_wideCharAllocLen = initSize;
}
int len = MultiByteToWideChar(codepage, 0, mbcs2Convert, -1, _wideCharStr, 0);
if (len > 0)
{
if (len > int(_wideCharAllocLen))
{
delete [] _wideCharStr;
_wideCharAllocLen = len;
_wideCharStr = new wchar_t[_wideCharAllocLen];
}
MultiByteToWideChar(codepage, 0, mbcs2Convert, -1, _wideCharStr, len);
*mstart = MultiByteToWideChar(codepage, 0, mbcs2Convert, *mstart, _wideCharStr, 0);
*mend = MultiByteToWideChar(codepage, 0, mbcs2Convert, *mend, _wideCharStr, 0);
}
else
{
_wideCharStr[0] = 0;
*mstart = 0;
*mend = 0;
}
return _wideCharStr;
}
const char * WcharMbcsConvertor::wchar2char(const wchar_t * wcharStr2Convert, UINT codepage)
{
if (!_multiByteStr)

View File

@ -107,6 +107,7 @@ public:
static void destroyInstance() {delete _pSelf;};
const wchar_t * char2wchar(const char* mbStr, UINT codepage);
const wchar_t * char2wchar(const char * mbcs2Convert, UINT codepage, int *mstart, int *mend);
const char * wchar2char(const wchar_t* wcStr, UINT codepage);
protected:

View File

@ -1426,9 +1426,9 @@ bool Notepad_plus::replaceAllFiles() {
if (nbTotal < 0)
lstrcpy(result, TEXT("The regular expression to search is formed badly"));
else
wsprintf(result, TEXT("%d occurrences were replaced."), nbTotal);
wsprintf(result, TEXT("%d occurrences replaced."), nbTotal);
::MessageBox(_hSelf, result, TEXT(""), MB_OK);
::printStr(result);
return true;
}
@ -1570,6 +1570,12 @@ DWORD WINAPI AsyncCancelFindInFiles(LPVOID NppHWND)
bool Notepad_plus::replaceInFiles()
{
const TCHAR *dir2Search = _findReplaceDlg.getDir2Search();
if (!dir2Search[0] || !::PathFileExists(dir2Search))
{
return false;
}
bool isRecursive = _findReplaceDlg.isRecursive();
bool isInHiddenDir = _findReplaceDlg.isInHiddenDir();
int nbTotal = 0;
@ -1577,15 +1583,9 @@ bool Notepad_plus::replaceInFiles()
ScintillaEditView *pOldView = _pEditView;
_pEditView = &_invisibleEditView;
Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER);
const TCHAR *dir2Search = _findReplaceDlg.getDir2Search();
if (!dir2Search[0] || !::PathFileExists(dir2Search))
{
return false;
}
HANDLE CancelThreadHandle = ::CreateThread(NULL, 0, AsyncCancelFindInFiles, _hSelf, 0, NULL);
Buffer * oldBuf = _invisibleEditView.getCurrentBuffer(); //for manually setting the buffer, so notifications can be handled properly
Buffer * pBuf = NULL;
HANDLE CancelThreadHandle = NULL;
vector<generic_string> patterns2Match;
if (_findReplaceDlg.getFilters() == TEXT(""))
@ -1595,6 +1595,9 @@ bool Notepad_plus::replaceInFiles()
getMatchedFileNames(dir2Search, patterns2Match, fileNames, isRecursive, isInHiddenDir);
if (fileNames.size() > 1)
CancelThreadHandle = ::CreateThread(NULL, 0, AsyncCancelFindInFiles, _hSelf, 0, NULL);
bool dontClose = false;
for (size_t i = 0 ; i < fileNames.size() ; i++)
{
@ -1617,6 +1620,7 @@ bool Notepad_plus::replaceInFiles()
Buffer * pBuf = MainFileManager->getBufferByID(id);
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument());
_invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? 0 : SC_CP_UTF8);
_invisibleEditView._currentBuffer = pBuf;
int nbReplaced = _findReplaceDlg.processAll(ProcessReplaceAll, NULL, NULL, true, fileNames.at(i).c_str());
nbTotal += nbReplaced;
@ -1630,9 +1634,11 @@ bool Notepad_plus::replaceInFiles()
}
}
TerminateThread(CancelThreadHandle, 0);
if (CancelThreadHandle)
TerminateThread(CancelThreadHandle, 0);
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc);
_invisibleEditView._currentBuffer = oldBuf;
_pEditView = pOldView;
TCHAR msg[128];
@ -1644,17 +1650,6 @@ bool Notepad_plus::replaceInFiles()
bool Notepad_plus::findInFiles()
{
bool isRecursive = _findReplaceDlg.isRecursive();
bool isInHiddenDir = _findReplaceDlg.isInHiddenDir();
int nbTotal = 0;
ScintillaEditView *pOldView = _pEditView;
_pEditView = &_invisibleEditView;
Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER);
if (!_findReplaceDlg.isFinderEmpty())
_findReplaceDlg.clearFinder();
const TCHAR *dir2Search = _findReplaceDlg.getDir2Search();
if (!dir2Search[0] || !::PathFileExists(dir2Search))
@ -1662,7 +1657,13 @@ bool Notepad_plus::findInFiles()
return false;
}
HANDLE CancelThreadHandle = ::CreateThread(NULL, 0, AsyncCancelFindInFiles, _hSelf, 0, NULL);
bool isRecursive = _findReplaceDlg.isRecursive();
bool isInHiddenDir = _findReplaceDlg.isInHiddenDir();
int nbTotal = 0;
ScintillaEditView *pOldView = _pEditView;
_pEditView = &_invisibleEditView;
Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER);
HANDLE CancelThreadHandle = NULL;
vector<generic_string> patterns2Match;
if (_findReplaceDlg.getFilters() == TEXT(""))
@ -1670,15 +1671,12 @@ bool Notepad_plus::findInFiles()
_findReplaceDlg.getPatterns(patterns2Match);
vector<generic_string> fileNames;
_findReplaceDlg.putFindResultStr(TEXT("Scanning files to search..."));
_findReplaceDlg.refresh();
getMatchedFileNames(dir2Search, patterns2Match, fileNames, isRecursive, isInHiddenDir);
TCHAR msg[128];
wsprintf(msg, TEXT("Found %d matching files"), fileNames.size());
_findReplaceDlg.putFindResultStr((const TCHAR*)msg);
_findReplaceDlg.refresh();
if (fileNames.size() > 1)
CancelThreadHandle = ::CreateThread(NULL, 0, AsyncCancelFindInFiles, _hSelf, 0, NULL);
_findReplaceDlg.beginNewFilesSearch();
bool dontClose = false;
for (size_t i = 0 ; i < fileNames.size() ; i++)
@ -1703,25 +1701,22 @@ bool Notepad_plus::findInFiles()
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument());
_invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? 0 : SC_CP_UTF8);
generic_string str = TEXT("File: ");
str += fileNames.at(i);
_findReplaceDlg.putFindResultStr(str.c_str());
nbTotal += _findReplaceDlg.processAll(ProcessFindAll, NULL, NULL, true, fileNames.at(i).c_str());
if (!dontClose)
MainFileManager->closeBuffer(id, _pEditView);
}
}
TerminateThread(CancelThreadHandle, 0);
if (CancelThreadHandle)
TerminateThread(CancelThreadHandle, 0);
_findReplaceDlg.finishFilesSearch(nbTotal);
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc);
_pEditView = pOldView;
wsprintf(msg, TEXT("%d hits"), nbTotal);
_findReplaceDlg.putFindResultStr((const TCHAR *)&msg);
_findReplaceDlg.refresh();
_findReplaceDlg.putFindResult(nbTotal);
if (nbTotal) _findReplaceDlg.display(false);
return true;
}
@ -1737,10 +1732,7 @@ bool Notepad_plus::findInOpenedFiles()
const bool isEntireDoc = true;
if (!_findReplaceDlg.isFinderEmpty())
_findReplaceDlg.clearFinder();
_findReplaceDlg.setSearchWord2Finder();
_findReplaceDlg.beginNewFilesSearch();
if (_mainWindowStatus & WindowMainActive)
{
@ -1764,10 +1756,13 @@ bool Notepad_plus::findInOpenedFiles()
}
}
_findReplaceDlg.finishFilesSearch(nbTotal);
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc);
_pEditView = pOldView;
_findReplaceDlg.putFindResult(nbTotal);
if (nbTotal) _findReplaceDlg.display(false);
return true;
}
@ -7079,8 +7074,7 @@ LRESULT Notepad_plus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa
case WM_FINDINFILES :
{
findInFiles();
return TRUE;
return findInFiles();
}
case WM_REPLACEINFILES :

View File

@ -318,7 +318,7 @@ BEGIN
MENUITEM SEPARATOR
MENUITEM "Go to another view", IDM_VIEW_GOTO_ANOTHER_VIEW
MENUITEM "Clone to another view", IDM_VIEW_CLONE_TO_ANOTHER_VIEW
MENUITEM "Focus on other view", IDM_VIEW_SWITCHTO_OTHER_VIEW // working, but no need in menu
MENUITEM "Focus on other view", IDM_VIEW_SWITCHTO_OTHER_VIEW
MENUITEM "Go to new instance", IDM_VIEW_GOTO_NEW_INSTANCE
MENUITEM "Open in new instance", IDM_VIEW_LOAD_IN_NEW_INSTANCE
MENUITEM SEPARATOR

View File

@ -147,6 +147,8 @@ void Searching::displaySectionCentered(int posStart, int posEnd, ScintillaEditVi
pEditView->execute(SCI_SETANCHOR, posStart);
}
LONG FindReplaceDlg::originalFinderProc = NULL;
void FindReplaceDlg::addText2Combo(const TCHAR * txt2add, HWND hCombo, bool isUTF8)
{
if (!hCombo) return;
@ -378,87 +380,154 @@ void FindReplaceDlg::updateCombos()
updateCombo(IDFINDWHAT);
}
FoundInfo Finder::EmptyFoundInfo(0, 0, TEXT(""));
SearchResultMarking Finder::EmptySearchResultMarking;
bool Finder::notify(SCNotification *notification)
{
switch (notification->nmhdr.code)
{
case SCN_MARGINCLICK:
{
if (notification->margin == ScintillaEditView::_SC_MARGE_FOLDER)
{
_scintView.marginClick(notification->position, notification->modifiers);
}
break;
}
case SCN_DOUBLECLICK :
{
try {
int currentPos = _scintView.execute(SCI_GETCURRENTPOS);
if (currentPos)
{
TCHAR prevChar = (TCHAR)_scintView.execute(SCI_GETCHARAT, currentPos - 1);
if (prevChar == 0x0A)
currentPos -= 2;
}
case SCN_DOUBLECLICK:
// remove selection from the finder
int pos = notification->position;
if (pos == INVALID_POSITION)
pos = _scintView.execute(SCI_GETLINEENDPOSITION, notification->line);
_scintView.execute(SCI_SETSEL, pos, pos);
GotoFoundLine();
break;
}
return false;
}
void Finder::GotoFoundLine()
{
int currentPos = _scintView.execute(SCI_GETCURRENTPOS);
int lno = _scintView.execute(SCI_LINEFROMPOSITION, currentPos);
int start = _scintView.execute(SCI_POSITIONFROMLINE, lno);
int end = _scintView.execute(SCI_GETLINEENDPOSITION, lno);
if (start + 2 >= end) return; // avoid empty lines
if (_scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELHEADERFLAG)
{
_scintView.execute(SCI_TOGGLEFOLD, lno);
_scintView.execute(SCI_SETCURRENTPOS, start);
_scintView.execute(SCI_SETANCHOR, start);
return false;
return;
}
// in getInfo() method the previous line is renew as current for next call
const FoundInfo &fInfo = getInfo(lno);
const FoundInfo fInfo = *(_pMainFoundInfos->begin() + lno);
int markedLine = getCurrentMarkedLine();
// now we clean the previous mark
if (markedLine != -1)
(*_ppEditView)->execute(SCI_MARKERDELETE, markedLine, MARK_BOOKMARK);
// After cleaning the previous mark, we can swich to another document
int cmd = getMode()==FILES_IN_DIR?WM_DOOPEN:NPPM_SWITCHTOFILE;
::SendMessage(::GetParent(_hParent), cmd, 0, (LPARAM)fInfo._fullPath.c_str());
// Switch to another document
::SendMessage(::GetParent(_hParent), WM_DOOPEN, 0, (LPARAM)fInfo._fullPath.c_str());
Searching::displaySectionCentered(fInfo._start, fInfo._end, *_ppEditView);
// we set the current mark here
int nb = (*_ppEditView)->getCurrentLineNumber();
setCurrentMarkedLine(nb);
(*_ppEditView)->execute(SCI_MARKERADD, nb, MARK_BOOKMARK);
// Then we colourise the double clicked line
setFinderStyle();
_scintView.showMargin(ScintillaEditView::_SC_MARGE_FOLDER, true);
_scintView.execute(SCI_SETLEXER, SCLEX_NULL);
_scintView.execute(SCI_STYLESETEOLFILLED, SCE_SEARCHRESULT_KWORD3, true);
//
_scintView.execute(SCI_SETLEXER, SCLEX_NULL); // yuval - this line causes a bug!!! (last line suddenly belongs to file level header instead of having level=0x400)
// later it affects DeleteResult and gotoNextFoundResult (assertions)!!
_scintView.execute(SCI_STYLESETEOLFILLED, SCE_SEARCHRESULT_HIGHLIGHT_LINE, true);
_scintView.execute(SCI_STARTSTYLING, start, STYLING_MASK);
_scintView.execute(SCI_SETSTYLING, end - start + 2, SCE_SEARCHRESULT_KWORD3);
_scintView.execute(SCI_SETSTYLING, end - start + 2, SCE_SEARCHRESULT_HIGHLIGHT_LINE);
_scintView.execute(SCI_COLOURISE, start, end + 1);
_scintView.execute(SCI_SETCURRENTPOS, start);
_scintView.execute(SCI_SETANCHOR, start);
return true;
}
} catch(...){
printStr(TEXT("SCN_DOUBLECLICK problem"));
}
break;
}
void Finder::DeleteResult()
{
int currentPos = _scintView.execute(SCI_GETCURRENTPOS); // yniq - add handling deletion of multiple lines?
default :
break;
int lno = _scintView.execute(SCI_LINEFROMPOSITION, currentPos);
int start = _scintView.execute(SCI_POSITIONFROMLINE, lno);
int end = _scintView.execute(SCI_GETLINEENDPOSITION, lno);
if (start + 2 >= end) return; // avoid empty lines
if (_scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELHEADERFLAG) // delete a folder
{
int endline = _scintView.execute(SCI_GETLASTCHILD, lno, -1) + 1;
assert((size_t) endline <= _pMainFoundInfos->size());
_pMainFoundInfos->erase(_pMainFoundInfos->begin() + lno, _pMainFoundInfos->begin() + endline); // remove found info
_pMainMarkings->erase(_pMainMarkings->begin() + lno, _pMainMarkings->begin() + endline);
int end = _scintView.execute(SCI_POSITIONFROMLINE, endline);
_scintView.execute(SCI_SETSEL, start, end);
setFinderReadOnly(false);
_scintView.execute(SCI_CLEAR);
setFinderReadOnly(true);
}
else // delete one line
{
assert((size_t) lno < _pMainFoundInfos->size());
_pMainFoundInfos->erase(_pMainFoundInfos->begin() + lno); // remove found info
_pMainMarkings->erase(_pMainMarkings->begin() + lno);
setFinderReadOnly(false);
_scintView.execute(SCI_LINEDELETE);
setFinderReadOnly(true);
}
_MarkingsStruct._length = _pMainMarkings->size();
assert(_pMainFoundInfos->size() == _pMainMarkings->size());
assert(_scintView.execute(SCI_GETLINECOUNT) == _pMainFoundInfos->size() + 1);
}
void Finder::gotoNextFoundResult(int direction)
{
int increment = direction < 0 ? -1 : 1;
int currentPos = _scintView.execute(SCI_GETCURRENTPOS);
int lno = _scintView.execute(SCI_LINEFROMPOSITION, currentPos);
int total_lines = _scintView.execute(SCI_GETLINECOUNT);
if (total_lines <= 1) return;
if (lno == total_lines - 1) lno--; // last line doesn't belong to any search, use last search
int init_lno = lno;
int max_lno = _scintView.execute(SCI_GETLASTCHILD, lno, searchHeaderLevel);
assert(max_lno <= total_lines - 2);
// get the line number of the current search (searchHeaderLevel)
int level = _scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELNUMBERMASK;
int min_lno = lno;
while (level-- >= fileHeaderLevel)
{
min_lno = _scintView.execute(SCI_GETFOLDPARENT, min_lno);
assert(min_lno >= 0);
}
if (min_lno < 0) min_lno = lno; // when lno is a search header line // yuval - remove this?
assert(min_lno <= max_lno);
lno += increment;
if (lno > max_lno) lno = min_lno;
else if (lno < min_lno) lno = max_lno;
while (_scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELHEADERFLAG)
{
lno += increment;
if (lno > max_lno) lno = min_lno;
else if (lno < min_lno) lno = max_lno;
if (lno == init_lno) break;
}
if ((_scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELHEADERFLAG) == 0)
{
int start = _scintView.execute(SCI_POSITIONFROMLINE, lno);
_scintView.execute(SCI_SETSEL, start, start);
_scintView.execute(SCI_ENSUREVISIBLE, lno);
_scintView.execute(SCI_SCROLLCARET);
GotoFoundLine();
}
return false;
}
@ -861,6 +930,7 @@ BOOL CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP
default :
break;
}
break;
}
}
return FALSE;
@ -1219,7 +1289,10 @@ int FindReplaceDlg::processRange(ProcessOperation op, const TCHAR *txt2find, con
if (nbChar > 1024 - 3)
lend = lstart + 1020;
(*_ppEditView)->getGenericText(lineBuf, lstart, lend);
int start_mark = targetStart - lstart;
int end_mark = targetEnd - lstart;
(*_ppEditView)->getGenericText(lineBuf, lstart, lend, &start_mark, &end_mark);
generic_string line;
#ifdef UNICODE
line = lineBuf;
@ -1236,7 +1309,10 @@ int FindReplaceDlg::processRange(ProcessOperation op, const TCHAR *txt2find, con
line = lineBuf;
#endif
line += TEXT("\r\n");
_pFinder->add(FoundInfo(targetStart, targetEnd, line.c_str(), fileName, _pFinder->_lineCounter), lineNumber + 1);
SearchResultMarking srm;
srm._start = start_mark;
srm._end = end_mark;
_pFinder->add(FoundInfo(targetStart, targetEnd, fileName), srm, line.c_str(), lineNumber + 1);
break;
}
@ -1312,6 +1388,9 @@ int FindReplaceDlg::processRange(ProcessOperation op, const TCHAR *txt2find, con
delete [] pTextFind;
delete [] pTextReplace;
if (nbProcessed > 0 && op == ProcessFindAll)
_pFinder->addFileHitCount(nbProcessed);
return nbProcessed;
}
@ -1329,7 +1408,8 @@ void FindReplaceDlg::findAllIn(InWhat op)
_pFinder->init(_hInst, _hSelf, _ppEditView);
tTbData data = {0};
_pFinder->create(&data);
_pFinder->create(&data, false);
::SendMessage(_hParent, NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, (WPARAM)_pFinder->getHSelf());
// define the default docking behaviour
data.uMask = DWS_DF_CONT_BOTTOM | DWS_ICONTAB | DWS_ADDINFO;
data.hIconTab = (HICON)::LoadImage(_hInst, MAKEINTRESOURCE(IDI_FIND_RESULT_ICON), IMAGE_ICON, 0, 0, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT);
@ -1343,16 +1423,24 @@ void FindReplaceDlg::findAllIn(InWhat op)
::SendMessage(_hParent, NPPM_DMMREGASDCKDLG, 0, (LPARAM)&data);
_pFinder->_scintView.init(_hInst, _pFinder->getHSelf());
// Subclass the ScintillaEditView for the Finder (Scintilla doesn't notify all key presses)
originalFinderProc = SetWindowLong( _pFinder->_scintView.getHSelf(), GWL_WNDPROC, (LONG) finderProc);
_pFinder->_scintView.performGlobalStyles();
_pFinder->setFinderReadOnly(true);
_pFinder->_scintView.execute(SCI_SETCODEPAGE, SC_CP_UTF8);
_pFinder->_scintView.execute(SCI_SETCODEPAGE, SC_CP_DBCS);
_pFinder->_scintView.execute(SCI_USEPOPUP, FALSE);
_pFinder->_scintView.execute(SCI_SETUNDOCOLLECTION, false); //dont store any undo information
_pFinder->_scintView.execute(SCI_SETCARETLINEVISIBLE, 1);
_pFinder->_scintView.showMargin(ScintillaEditView::_SC_MARGE_FOLDER, true);
//_statusBar.init(_hInst, _hSelf, 0);
RECT findRect;
//const int scintEditInitHeight = 130;
char ptrword[sizeof(void*)*2+1];
sprintf(ptrword, "%p", &_pFinder->_MarkingsStruct);
_pFinder->_scintView.execute(SCI_SETKEYWORDS, 0, (LPARAM) ptrword);
// get the width of FindDlg
RECT findRect;
::GetWindowRect(_pFinder->getHSelf(), &findRect);
// overwrite some default settings
@ -1363,25 +1451,21 @@ void FindReplaceDlg::findAllIn(InWhat op)
_pFinder->display();
}
_pFinder->setFinderStyle();
_pFinder->setMode(op);
::SendMessage(_pFinder->getHSelf(), WM_SIZE, 0, 0);
if (op == ALL_OPEN_DOCS)
::SendMessage(_hParent, WM_FINDALL_INOPENEDDOC, 0, 0);
else if (op == FILES_IN_DIR)
::SendMessage(_hParent, WM_FINDINFILES, 0, 0);
refresh();
}
void FindReplaceDlg::putFindResultStr(const TCHAR *text)
{
wsprintf(_findAllResultStr, TEXT("%s"), text);
}
void FindReplaceDlg::refresh()
{
::SendMessage(_hParent, NPPM_DMMSHOW, 0, (LPARAM)_pFinder->getHSelf());
if (::SendMessage(_hParent, (op==ALL_OPEN_DOCS)?WM_FINDALL_INOPENEDDOC:WM_FINDINFILES, 0, 0))
{
wsprintf(_findAllResultStr, TEXT("%d hits"), _findAllResult);
if (_findAllResult)
{
focusOnFinder();
}
else
getFocus(); // no hits
}
else // error - search folder doesn't exist
::SendMessage(_hSelf, WM_NEXTDLGCTL, (WPARAM)::GetDlgItem(_hSelf, IDD_FINDINFILES_DIR_COMBO), TRUE);
}
void FindReplaceDlg::enableReplaceFunc(bool isEnable)
@ -1480,12 +1564,11 @@ void Finder::setFinderStyle()
styleDefault._colorStyle = COLORSTYLE_ALL; //All colors set
_scintView.setStyle(styleDefault);
}
_scintView.execute(SCI_STYLECLEARALL);
_scintView.execute(SCI_SETSTYLEBITS, 5);
_scintView.setSearchResultLexer();
_scintView.execute(SCI_COLOURISE, 0, -1);
_scintView.execute(SCI_SETEOLMODE, SC_EOL_LF);
_scintView.execute(SCI_SETEOLMODE, SC_EOL_CRLF);
}
BOOL CALLBACK Finder::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
@ -1520,9 +1603,15 @@ BOOL CALLBACK Finder::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
return TRUE;
}
case NPPM_INTERNAL_SCINTILLAFINFERCLEARALL:
{
removeAll();
return TRUE;
}
default :
{
break;
return FALSE;
}
}
}
@ -1540,6 +1629,7 @@ BOOL CALLBACK Finder::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
tmp.push_back(MenuItemUnit(0, TEXT("Separator")));
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERCOPY, TEXT("Copy")));
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERSELECTALL, TEXT("Select All")));
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERCLEARALL, TEXT("Clear All")));
scintillaContextmenu.create(_hSelf, tmp);

View File

@ -39,13 +39,11 @@ enum DIALOG_TYPE {FIND_DLG, REPLACE_DLG, FINDINFILES_DLG};
enum InWhat{ALL_OPEN_DOCS, FILES_IN_DIR};
struct FoundInfo {
FoundInfo(int start, int end, const TCHAR *foundLine, const TCHAR *fullPath, size_t lineNum)
: _start(start), _end(end), _foundLine(foundLine), _fullPath(fullPath), _scintLineNumber(lineNum){};
FoundInfo(int start, int end, const TCHAR *fullPath)
: _start(start), _end(end), _fullPath(fullPath) {};
int _start;
int _end;
std::generic_string _foundLine;
std::generic_string _fullPath;
size_t _scintLineNumber;
};
struct TargetRange {
@ -88,7 +86,10 @@ private:
class Finder : public DockingDlgInterface {
friend class FindReplaceDlg;
public:
Finder() : DockingDlgInterface(IDD_FINDRESULT), _markedLine(-1), _lineCounter(0) {};
Finder() : DockingDlgInterface(IDD_FINDRESULT), _pMainFoundInfos(&_foundInfos1), _pMainMarkings(&_markings1) {
_MarkingsStruct._length = 0;
_MarkingsStruct._markings = NULL;
};
~Finder() {
_scintView.destroy();
@ -98,100 +99,152 @@ public:
_ppEditView = ppEditView;
};
void addFileNameTitle(const TCHAR * fileName) {
generic_string str = TEXT("[");
str += fileName;
str += TEXT("]\n");
void addSearchLine(const TCHAR *searchName) {
generic_string str = TEXT("Search \"");
str += searchName;
str += TEXT("\"\r\n");
setFinderReadOnly(false);
_scintView.appandGenericText(str.c_str());
_scintView.addGenericText(str.c_str());
setFinderReadOnly(true);
_lineCounter++;
_lastSearchHeaderPos = _scintView.execute(SCI_GETCURRENTPOS) - 2;
_pMainFoundInfos->push_back(EmptyFoundInfo);
_pMainMarkings->push_back(EmptySearchResultMarking);
};
void add(FoundInfo fi, int lineNb) {
_foundInfos.push_back(fi);
std::generic_string str = TEXT("Line ");
void addFileNameTitle(const TCHAR * fileName) {
generic_string str = TEXT(" ");
str += fileName;
str += TEXT("\r\n");
setFinderReadOnly(false);
_scintView.addGenericText(str.c_str());
setFinderReadOnly(true);
_lastFileHeaderPos = _scintView.execute(SCI_GETCURRENTPOS) - 2;
_pMainFoundInfos->push_back(EmptyFoundInfo);
_pMainMarkings->push_back(EmptySearchResultMarking);
};
void addFileHitCount(int count) {
TCHAR text[20];
wsprintf(text, TEXT(" (%i hits)"), count);
setFinderReadOnly(false);
_scintView.insertGenericTextFrom(_lastFileHeaderPos, text);
setFinderReadOnly(true);
nFoundFiles++;
};
void addSearchHitCount(int count) {
TCHAR text[50];
wsprintf(text, TEXT(" (%i hits in %i files)"), count, nFoundFiles);
setFinderReadOnly(false);
_scintView.insertGenericTextFrom(_lastSearchHeaderPos, text);
setFinderReadOnly(true);
};
void add(FoundInfo fi, SearchResultMarking mi, const TCHAR* foundline, int lineNb) {
_pMainFoundInfos->push_back(fi);
_pMainMarkings->push_back(mi);
std::generic_string str = TEXT("\tLine ");
TCHAR lnb[16];
wsprintf(lnb, TEXT("%d"), lineNb);
str += lnb;
str += TEXT(" : ");
str += fi._foundLine;
str += TEXT(": ");
str += foundline;
size_t len = str.length();
if (len >= SC_SEARCHRESULT_LINEBUFFERMAXLENGTH)
if (str.length() >= SC_SEARCHRESULT_LINEBUFFERMAXLENGTH)
{
const TCHAR * endOfLongLine = TEXT("...\r\n");
str = str.substr(0, SC_SEARCHRESULT_LINEBUFFERMAXLENGTH - lstrlen(endOfLongLine) - 1);
str += endOfLongLine;
}
else
{
// Make sure we have EOL. We might not have one for example when searching in non-text files.
// This can happen because Scintilla line endings (\n) are not the same as
// string line endings (\0). In this case we will see only a part of the line
// in the find result window.
if (str[len-1] != '\n')
str += TEXT("\n");
}
setFinderReadOnly(false);
_scintView.appandGenericText(str.c_str());
_scintView.addGenericText(str.c_str());
setFinderReadOnly(true);
_lineCounter++;
};
void setFinderStyle();
void removeAll() {
_markedLine = -1;
_foundInfos.clear();
_pMainFoundInfos->clear();
_pMainMarkings->clear();
setFinderReadOnly(false);
_scintView.execute(SCI_CLEARALL);
setFinderReadOnly(true);
_lineCounter = 0;
};
FoundInfo & getInfo(int curLineNum) {
int nbInfo = _foundInfos.size();
void beginNewFilesSearch() {
_scintView.execute(SCI_SETLEXER, SCLEX_NULL);
for (size_t i = (nbInfo <= curLineNum)?nbInfo -1:curLineNum ; i > 0 ; i--)
{
if (_foundInfos[i]._scintLineNumber == curLineNum)
return _foundInfos[i];
}
return _foundInfos[0]; // should never be reached
_scintView.execute(SCI_SETCURRENTPOS, 0);
_pMainFoundInfos = _pMainFoundInfos == &_foundInfos1 ? &_foundInfos2 : &_foundInfos1;
_pMainMarkings = _pMainMarkings == &_markings1 ? &_markings2 : &_markings1;
nFoundFiles = 0;
// fold all old searches (1st level only)
_scintView.collapse(searchHeaderLevel - SC_FOLDLEVELBASE, fold_collapse);
};
bool isEmpty() const {
return _foundInfos.empty();
void finishFilesSearch(int count) {
std::vector<FoundInfo>* _pOldFoundInfos;
std::vector<SearchResultMarking>* _pOldMarkings;
_pOldFoundInfos = _pMainFoundInfos == &_foundInfos1 ? &_foundInfos2 : &_foundInfos1;
_pOldMarkings = _pMainMarkings == &_markings1 ? &_markings2 : &_markings1;
_pOldFoundInfos->insert(_pOldFoundInfos->begin(), _pMainFoundInfos->begin(), _pMainFoundInfos->end());
_pOldMarkings->insert(_pOldMarkings->begin(), _pMainMarkings->begin(), _pMainMarkings->end());
_pMainFoundInfos->clear();
_pMainMarkings->clear();
_pMainFoundInfos = _pOldFoundInfos;
_pMainMarkings = _pOldMarkings;
_MarkingsStruct._length = _pMainMarkings->size();
_MarkingsStruct._markings = &((*_pMainMarkings)[0]);
addSearchHitCount(count);
_scintView.execute(SCI_SETSEL, 0, 0);
_scintView.execute(SCI_SETLEXER, SCLEX_SEARCHRESULT);
};
int getCurrentMarkedLine() const {return _markedLine;};
void setCurrentMarkedLine(int line) {_markedLine = line;};
InWhat getMode() const {return _mode;};
void setMode(InWhat mode) {_mode = mode;};
void setSearchWord(const TCHAR *word2search) {
_scintView.setHiLiteResultWords(word2search);
};
void gotoNextFoundResult(int direction);
void GotoFoundLine();
void DeleteResult();
protected :
virtual BOOL CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);
bool notify(SCNotification *notification);
private:
enum { searchHeaderLevel = SC_FOLDLEVELBASE + 1, fileHeaderLevel, resultLevel };
ScintillaEditView **_ppEditView;
std::vector<FoundInfo> _foundInfos;
std::vector<FoundInfo> _foundInfos1;
std::vector<FoundInfo> _foundInfos2;
std::vector<FoundInfo>* _pMainFoundInfos;
std::vector<SearchResultMarking> _markings1;
std::vector<SearchResultMarking> _markings2;
std::vector<SearchResultMarking>* _pMainMarkings;
SearchResultMarkings _MarkingsStruct;
ScintillaEditView _scintView;
int _markedLine;
InWhat _mode;
size_t _lineCounter;
unsigned int nFoundFiles;
int _lastFileHeaderPos;
int _lastSearchHeaderPos;
void setFinderReadOnly(bool isReadOnly) {
_scintView.execute(SCI_SETREADONLY, isReadOnly);
};
static FoundInfo EmptyFoundInfo;
static SearchResultMarking EmptySearchResultMarking;
};
//FindReplaceDialog: standard find/replace window
@ -275,27 +328,11 @@ public :
}
::SendMessage(hCombo, CB_SETEDITSEL, 0, MAKELPARAM(0, -1)); // select all text - fast edit
}
bool isFinderEmpty() const {
return _pFinder->isEmpty();
};
void clearFinder() {
_pFinder->removeAll();
};
void gotoNextFoundResult(int direction = 0) {if (_pFinder) _pFinder->gotoNextFoundResult(direction);};
void putFindResult(int result) {
_findAllResult = result;
};
void putFindResultStr(const TCHAR *text);
void refresh();
void setSearchWord2Finder(){
generic_string str2Search = getText2search();
_pFinder->setSearchWord(str2Search.c_str());
};
const TCHAR * getDir2Search() const {return _directory.c_str();};
void getPatterns(vector<generic_string> & patternVect);
@ -333,11 +370,49 @@ public :
tie.pszText = (TCHAR *)name2change;
TabCtrl_SetItem(_tab.getHSelf(), index, &tie);
}
void beginNewFilesSearch()
{
_pFinder->beginNewFilesSearch();
bool isUnicode = (*_ppEditView)->getCurrentBuffer()->getUnicodeMode() != uni8Bit;
_pFinder->addSearchLine(getText2search().c_str());
}
void finishFilesSearch(int count)
{
_pFinder->finishFilesSearch(count);
}
void focusOnFinder() {
// Show finder and set focus
if (_pFinder) {
::SendMessage(_hParent, NPPM_DMMSHOW, 0, (LPARAM)_pFinder->getHSelf());
_pFinder->_scintView.getFocus();
}
};
protected :
virtual BOOL CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);
void addText2Combo(const TCHAR * txt2add, HWND comboID, bool isUTF8 = false);
generic_string getTextFromCombo(HWND hCombo, bool isUnicode = false) const;
static LONG originalFinderProc;
// Window procedure for the finder
static LRESULT FAR PASCAL finderProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_KEYDOWN && (wParam == VK_DELETE || wParam == VK_RETURN))
{
ScintillaEditView *pScint = (ScintillaEditView *)(::GetWindowLongPtr(hwnd, GWL_USERDATA));
Finder *pFinder = (Finder *)(::GetWindowLongPtr(pScint->getHParent(), GWL_USERDATA));
if (wParam == VK_RETURN)
pFinder->GotoFoundLine();
else // VK_DELETE
pFinder->DeleteResult();
return 0;
}
else
// Call default (original) window procedure
return CallWindowProc((WNDPROC) originalFinderProc, hwnd, message, wParam, lParam);
}
private :
DIALOG_TYPE _currentStatus;
@ -390,7 +465,7 @@ private :
void setDefaultButton(int nID)
{
#if 0
// Where is a problem when you:
// There is a problem when you:
// 1. open the find dialog
// 2. press the "close" buttom
// 3. open it again

View File

@ -1451,6 +1451,23 @@ void ScintillaEditView::getGenericText(TCHAR *dest, int start, int end) const
#endif
}
// "mstart" and "mend" are pointers to indexes in the read string,
// which are converted to the corresponding indexes in the returned TCHAR string.
void ScintillaEditView::getGenericText(TCHAR *dest, int start, int end, int *mstart, int *mend) const
{
#ifdef UNICODE
WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance();
char *destA = new char[end - start + 1];
getText(destA, start, end);
unsigned int cp = execute(SCI_GETCODEPAGE);
const TCHAR *destW = wmc->char2wchar(destA, cp, mstart, mend);
lstrcpy(dest, destW);
delete [] destA;
#else
getText(dest, start, end);
#endif
}
void ScintillaEditView::insertGenericTextFrom(int position, const TCHAR *text2insert) const
{
#ifdef UNICODE
@ -1530,6 +1547,18 @@ void ScintillaEditView::appandGenericText(const TCHAR * text2Append) const
#endif
}
void ScintillaEditView::addGenericText(const TCHAR * text2Append) const
{
#ifdef UNICODE
WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance();
unsigned int cp = execute(SCI_GETCODEPAGE);
const char *text2AppendA =wmc->wchar2char(text2Append, cp);
execute(SCI_ADDTEXT, strlen(text2AppendA), (LPARAM)text2AppendA);
#else
execute(SCI_ADDTEXT, strlen(text2AppendA), (LPARAM)text2AppendA);
#endif
}
int ScintillaEditView::replaceTarget(const TCHAR * str2replace, int fromTargetPos, int toTargetPos) const
{
if (fromTargetPos != -1 || toTargetPos != -1)

View File

@ -167,6 +167,7 @@ public:
void getText(char *dest, int start, int end) const;
void getGenericText(TCHAR *dest, int start, int end) const;
void getGenericText(TCHAR *dest, int start, int end, int *mstart, int *mend) const;
void insertGenericTextFrom(int position, const TCHAR *text2insert) const;
void replaceSelWith(const char * replaceText);
@ -179,6 +180,7 @@ public:
TCHAR * getGenericSelectedText(TCHAR * txt, int size, bool expand = true);
int searchInTarget(const TCHAR * Text2Find, int fromPos, int toPos) const;
void appandGenericText(const TCHAR * text2Append) const;
void addGenericText(const TCHAR * text2Append) const;
int replaceTarget(const TCHAR * str2replace, int fromTargetPos = -1, int toTargetPos = -1) const;
int replaceTargetRegExMode(const TCHAR * re, int fromTargetPos = -1, int toTargetPos = -1) const;
void showAutoComletion(int lenEntered, const TCHAR * list);
@ -701,8 +703,9 @@ protected:
};
void setSearchResultLexer() {
execute(SCI_STYLESETEOLFILLED, SCE_SEARCHRESULT_HEARDER, true);
setLexer(SCLEX_SEARCHRESULT, L_SEARCHRESULT, LIST_1 | LIST_2 | LIST_3);
execute(SCI_STYLESETEOLFILLED, SCE_SEARCHRESULT_FILE_HEADER, true);
execute(SCI_STYLESETEOLFILLED, SCE_SEARCHRESULT_SEARCH_HEADER, true);
setLexer(SCLEX_SEARCHRESULT, L_SEARCHRESULT, 0);
};
bool isNeededFolderMarge(LangType typeDoc) const {

View File

@ -302,6 +302,8 @@
#define NPPM_INTERNAL_CANCEL_FIND_IN_FILES (NOTEPADPLUS_USER_INTERNAL + 24)
#define NPPM_INTERNAL_RELOADNATIVELANG (NOTEPADPLUS_USER_INTERNAL + 25)
#define NPPM_INTERNAL_PLUGINSHORTCUTMOTIFIED (NOTEPADPLUS_USER_INTERNAL + 26)
#define NPPM_INTERNAL_SCINTILLAFINFERCLEARALL (NOTEPADPLUS_USER_INTERNAL + 27)
// See Notepad_plus_msgs.h
//#define NOTEPADPLUS_USER (WM_USER + 1000)

View File

@ -14,5 +14,7 @@
<Command name="Wikipedia Search" Ctrl="no" Alt="yes" Shift="no" Key="114">http://en.wikipedia.org/wiki/Special:Search?search=$(CURRENT_WORD)</Command>
<Command name="open file" Ctrl="no" Alt="yes" Shift="no" Key="116">$(NPP_DIRECTORY)\notepad++.exe $(CURRENT_WORD)</Command>
<Command name="open in another instance" Ctrl="no" Alt="yes" Shift="no" Key="117">$(NPP_DIRECTORY)\notepad++.exe $(CURRENT_WORD) -nosession -multiInst</Command>
<Command name="Open containing folder" Ctrl="no" Alt="no" Shift="no" Key="0">explorer $(CURRENT_DIRECTORY)</Command>
<Command name="Open current dir cmd" Ctrl="no" Alt="no" Shift="no" Key="0">cmd /K cd $(CURRENT_DIRECTORY)</Command>
</UserDefinedCommands>
</NotepadPlus>

View File

@ -689,12 +689,11 @@
</LexerType>
<LexerType name="searchResult" desc="Search result" ext="">
<WordsStyle name="DEFAULT" styleID="0" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" fontSize="" />
<WordsStyle name="SELECTED LINE" styleID="6" fgColor="FFFF80" bgColor="0000FF" fontName="" fontStyle="1" fontSize="" />
<WordsStyle name="HEARDER" styleID="1" fgColor="008000" bgColor="D5FFD5" fontName="" fontStyle="1" fontSize="" />
<WordsStyle name="NUMBER" styleID="2" fgColor="FF0000" bgColor="FFFFFF" fontName="" fontStyle="0" fontSize="" />
<WordsStyle name="HIT WORD" styleID="3" fgColor="FF0000" bgColor="FFFF80" fontName="" fontStyle="4" fontSize="" />
<WordsStyle name="KEYWORD1" styleID="4" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="1" fontSize="" keywordClass="instre2">if else for while</WordsStyle>
<WordsStyle name="KEYWORD2" styleID="5" fgColor="0080FF" bgColor="FFFFFF" fontName="" fontStyle="0" fontSize="" keywordClass="type1">bool long int char</WordsStyle>
<WordsStyle name="SEARCH HEADER" styleID="1" fgColor="000080" bgColor="BBBBFF" fontName="" fontStyle="1" fontSize="" />
<WordsStyle name="FILE HEADER" styleID="2" fgColor="008000" bgColor="D5FFD5" fontName="" fontStyle="1" fontSize="" />
<WordsStyle name="LINE NUMBER" styleID="3" fgColor="FF0000" bgColor="FFFFFF" fontName="" fontStyle="0" fontSize="" />
<WordsStyle name="HIT WORD" styleID="4" fgColor="FF0000" bgColor="FFFFBF" fontName="" fontStyle="0" fontSize="" />
<WordsStyle name="SELECTED LINE" styleID="5" fgColor="FFFF80" bgColor="000080" fontName="" fontStyle="0" fontSize="" />
</LexerType>
</LexerStyles>
<GlobalStyles>

View File

@ -290,6 +290,10 @@
RelativePath="..\src\lastRecentFileList.cpp"
>
</File>
<File
RelativePath="..\src\MISC\Exception\MiniDumper.cpp"
>
</File>
<File
RelativePath="..\src\Notepad_plus.cpp"
>
@ -583,6 +587,10 @@
RelativePath="..\src\menuCmdID.h"
>
</File>
<File
RelativePath="..\src\MISC\Exception\MiniDumper.h"
>
</File>
<File
RelativePath="..\src\Notepad_plus.h"
>

View File

@ -170,12 +170,11 @@
#define SCE_D_COMMENTDOCKEYWORDERROR 17
#define SCE_SEARCHRESULT_DEFAULT 0
#define SCE_SEARCHRESULT_HEARDER 1
#define SCE_SEARCHRESULT_NUMBER 2
#define SCE_SEARCHRESULT_WORD2SEARCH 3
#define SCE_SEARCHRESULT_KWORD1 4
#define SCE_SEARCHRESULT_KWORD2 5
#define SCE_SEARCHRESULT_KWORD3 6
#define SCE_SEARCHRESULT_SEARCH_HEADER 1
#define SCE_SEARCHRESULT_FILE_HEADER 2
#define SCE_SEARCHRESULT_LINE_NUMBER 3
#define SCE_SEARCHRESULT_WORD2SEARCH 4
#define SCE_SEARCHRESULT_HIGHLIGHT_LINE 5
#define SCE_OBJC_DIRECTIVE 20
#define SCE_OBJC_QUALIFIER 21

View File

@ -828,6 +828,16 @@ struct SCNotification {
int y; // SCN_DWELLSTART, SCN_DWELLEND
};
struct SearchResultMarking {
long _start;
long _end;
};
struct SearchResultMarkings {
long _length;
SearchResultMarking *_markings;
};
#ifdef SCI_NAMESPACE
}
#endif

View File

@ -24,6 +24,7 @@
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <vector>
#include "Platform.h"
@ -33,6 +34,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
// The following definitions are a copy of the ones in FindReplaceDlg.h
static enum { searchHeaderLevel = SC_FOLDLEVELBASE + 1, fileHeaderLevel, resultLevel };
static inline bool AtEOL(Accessor &styler, unsigned int i) {
return (styler[i] == '\n') ||
((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
@ -42,143 +47,78 @@ static const char * const emptyWordListDesc[] = {
0
};
inline bool isSpaceChar(char ch) {
return ((ch == ' ') || (ch == ' '));
};
// return value : false if the end of line is reached, otherwise true
inline bool eatWhiteSpaces(const char *line, unsigned int & pos) {
if (pos >= strlen(line)) return false;
//int i = pos;
for ( ; line[pos] && isSpaceChar(line[pos]) ; pos++);
return (pos < strlen(line));
};
static void ColouriseSearchResultLine(WordList *keywordlists[], char *lineBuffer, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, Accessor &styler)
static void ColouriseSearchResultLine(SearchResultMarkings* pMarkings, char *lineBuffer, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, Accessor &styler, int linenum)
{
// startLine and endPos are the absolute positions.
WordList &word2Search = *keywordlists[0];
WordList &keywords1 = *keywordlists[1];
WordList &keywords2 = *keywordlists[2];
WordList &keywords3 = *keywordlists[3];
if (lineBuffer[0] == '[')
if (lineBuffer[0] == ' ') // file header
{
styler.ColourTo(endPos, SCE_SEARCHRESULT_HEARDER);
}
else
styler.ColourTo(endPos, SCE_SEARCHRESULT_FILE_HEADER);
}
else if (lineBuffer[0] == 'S') // search header
{
styler.ColourTo(endPos, SCE_SEARCHRESULT_SEARCH_HEADER);
}
else // line info
{
const unsigned int firstTokenLen = 4;
unsigned int currentPos;
PLATFORM_ASSERT(lengthLine >= firstTokenLen + 2);
styler.ColourTo(startLine + firstTokenLen, SCE_SEARCHRESULT_DEFAULT);
unsigned int currentPos = firstTokenLen;
for ( ; lineBuffer[currentPos] != ':' ; currentPos++);
styler.ColourTo(startLine + currentPos - 1, SCE_SEARCHRESULT_NUMBER);
for (currentPos = firstTokenLen; lineBuffer[currentPos] != ':' ; currentPos++) PLATFORM_ASSERT(currentPos < lengthLine);
styler.ColourTo(startLine + currentPos - 1, SCE_SEARCHRESULT_LINE_NUMBER);
//StyleContext sc(startPos, length, initStyle, styler);
int currentStat = SCE_SEARCHRESULT_DEFAULT;
PLATFORM_ASSERT(linenum < pMarkings->_length);
SearchResultMarking mi = pMarkings->_markings[linenum];
const int maxWordSize = 4096;
char word[maxWordSize];
bool isEndReached = eatWhiteSpaces(lineBuffer, currentPos);
currentPos += 2; // skip ": "
unsigned int match_start = startLine + currentPos + mi._start - 1;
unsigned int match_end = startLine + currentPos + mi._end - 1;
styler.ColourTo(startLine + currentPos - 1, SCE_SEARCHRESULT_DEFAULT);
while (currentPos < lengthLine)
{
for (int j = 0 ; j < maxWordSize ; currentPos++, j++)
{
if (currentPos >= lengthLine)
{
isEndReached = true;
break;
}
char ch = lineBuffer[currentPos];
if ((ch == ' ') || (ch == 0x0A) || (ch == 0x0D))
{
if (j == 0)
goto end;
word[j] = '\0';
if ((word2Search) && (word2Search.InList(word)))
{
currentStat = SCE_SEARCHRESULT_WORD2SEARCH;
}
else if ((keywords1) && (keywords1.InList(word)))
{
currentStat = SCE_SEARCHRESULT_KWORD1;
}
else if ((keywords2) && (keywords2.InList(word)))
{
currentStat = SCE_SEARCHRESULT_KWORD2;
}
else if ((keywords3) && (keywords3.InList(word)))
{
currentStat = SCE_SEARCHRESULT_KWORD3;
}
else
{
currentStat = SCE_SEARCHRESULT_DEFAULT;
}
styler.ColourTo(startLine + currentPos - 1, currentStat);
currentStat = SCE_SEARCHRESULT_DEFAULT;
isEndReached = !eatWhiteSpaces(lineBuffer, currentPos);
break;
}
else
word[j] = ch;
}
if (isEndReached)
{
styler.ColourTo(endPos, SCE_SEARCHRESULT_DEFAULT);
}
else
{
styler.ColourTo(startLine + currentPos - 1, currentStat);
}
if (match_start <= endPos) {
styler.ColourTo(match_start, SCE_SEARCHRESULT_DEFAULT);
if (match_end <= endPos)
styler.ColourTo(match_end, SCE_SEARCHRESULT_WORD2SEARCH);
else
currentStat = SCE_SEARCHRESULT_WORD2SEARCH;
}
end :
styler.ColourTo(endPos, SCE_SEARCHRESULT_DEFAULT);
styler.ColourTo(endPos, currentStat);
}
}
static void ColouriseSearchResultDoc(unsigned int startPos, int length, int, WordList *keywordlists[], Accessor &styler) {
char lineBuffer[SC_SEARCHRESULT_LINEBUFFERMAXLENGTH];
styler.StartAt(startPos);
styler.StartSegment(startPos);
unsigned int linePos = 0;
unsigned int startLine = startPos;
SearchResultMarkings* pMarkings = NULL;
sscanf(keywordlists[0]->words[0], "%p", &pMarkings);
PLATFORM_ASSERT(pMarkings);
for (unsigned int i = startPos; i < startPos + length; i++) {
lineBuffer[linePos++] = styler[i];
if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
// End of line (or of line buffer) met, colourise it
lineBuffer[linePos] = '\0';
ColouriseSearchResultLine(keywordlists, lineBuffer, linePos, startLine, i, styler);
ColouriseSearchResultLine(pMarkings, lineBuffer, linePos, startLine, i, styler, styler.GetLine(startLine));
linePos = 0;
startLine = i + 1;
while (!AtEOL(styler, i)) i++;
}
}
if (linePos > 0) { // Last line does not have ending characters
ColouriseSearchResultLine(keywordlists, lineBuffer, linePos, startLine, startPos + length - 1, styler);
ColouriseSearchResultLine(pMarkings, lineBuffer, linePos, startLine, startPos + length - 1, styler, styler.GetLine(startLine));
}
}
// adaption by ksc, using the "} else {" trick of 1.53
// 030721
static void FoldSearchResultDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
@ -188,7 +128,7 @@ static void FoldSearchResultDoc(unsigned int startPos, int length, int, WordList
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
bool headerPoint = false;
int headerPoint = 0;
int lev;
for (unsigned int i = startPos; i < endPos; i++) {
@ -199,57 +139,32 @@ static void FoldSearchResultDoc(unsigned int startPos, int length, int, WordList
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\n') || (ch == '\r' && chNext != '\n');
if (style == SCE_SEARCHRESULT_HEARDER)
if (style == SCE_SEARCHRESULT_FILE_HEADER)
{
headerPoint = true;
headerPoint = fileHeaderLevel;
}
else if (style == SCE_SEARCHRESULT_SEARCH_HEADER)
{
headerPoint = searchHeaderLevel;
}
if (atEOL) {
lev = SC_FOLDLEVELBASE;
lev = headerPoint ? SC_FOLDLEVELHEADERFLAG + headerPoint : resultLevel;
headerPoint = 0;
if (lineCurrent > 0) {
int levelPrevious = styler.LevelAt(lineCurrent - 1);
if (levelPrevious & SC_FOLDLEVELHEADERFLAG) {
lev = SC_FOLDLEVELBASE + 1;
} else {
lev = levelPrevious & SC_FOLDLEVELNUMBERMASK;
}
}
if (headerPoint) {
lev = SC_FOLDLEVELBASE;
}
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (headerPoint) {
lev |= SC_FOLDLEVELHEADERFLAG;
}
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
visibleChars = 0;
headerPoint = false;
}
if (!isspacechar(ch))
visibleChars++;
}
if (lineCurrent > 0) {
int levelPrevious = styler.LevelAt(lineCurrent - 1);
if (levelPrevious & SC_FOLDLEVELHEADERFLAG) {
lev = SC_FOLDLEVELBASE + 1;
} else {
lev = levelPrevious & SC_FOLDLEVELNUMBERMASK;
}
} else {
lev = SC_FOLDLEVELBASE;
}
int flagsNext = styler.LevelAt(lineCurrent);
styler.SetLevel(lineCurrent, lev | flagsNext & ~SC_FOLDLEVELNUMBERMASK);
styler.SetLevel(lineCurrent, SC_FOLDLEVELBASE);
}
LexerModule lmSearchResult(SCLEX_SEARCHRESULT, ColouriseSearchResultDoc, "searchResult", FoldSearchResultDoc, emptyWordListDesc);