Finish Calltip.

Make AutoComplete class.
AutoComplete uses XML data.
Add exception handling (dumping filedata).
Sync Project file with added files.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository@205 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
harrybharry 2008-05-22 23:42:00 +00:00
parent 7085e69724
commit e6cfeedc0d
14 changed files with 925 additions and 729 deletions

View File

@ -0,0 +1,44 @@
//This code was retrieved from
//http://www.thunderguy.com/semicolon/2002/08/15/visual-c-exception-handling/3/
//(Visual C++ exception handling)
//By Bennett
//Formatting Slightly modified for N++
#include "Win32Exception.h"
#include "eh.h" //eehh... =]
Win32Exception::Win32Exception(const EXCEPTION_RECORD * info) {
_location = info->ExceptionAddress;
_code = info->ExceptionCode;
switch (info->ExceptionCode) {
case EXCEPTION_ACCESS_VIOLATION:
_event = "Access violation";
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
case EXCEPTION_INT_DIVIDE_BY_ZERO:
_event = "Division by zero";
break;
default:
_event = "Unlisted exception";
}
}
void Win32Exception::installHandler() {
_set_se_translator(Win32Exception::translate);
}
void Win32Exception::translate(unsigned code, EXCEPTION_POINTERS * info) {
// Windows guarantees that *(info->ExceptionRecord) is valid
switch (code) {
case EXCEPTION_ACCESS_VIOLATION:
throw Win32AccessViolation(info->ExceptionRecord);
break;
default:
throw Win32Exception(info->ExceptionRecord);
}
}
Win32AccessViolation::Win32AccessViolation(const EXCEPTION_RECORD * info) : Win32Exception(info) {
_isWrite = info->ExceptionInformation[0] == 1;
_badAddress = reinterpret_cast<ExceptionAddress>(info->ExceptionInformation[1]);
}

View File

@ -0,0 +1,42 @@
//This code was retrieved from
//http://www.thunderguy.com/semicolon/2002/08/15/visual-c-exception-handling/3/
//(Visual C++ exception handling)
//By Bennett
//Formatting Slightly modified for N++
#include "windows.h"
#include <exception>
typedef const void* ExceptionAddress; // OK on Win32 platform
class Win32Exception : public std::exception
{
public:
static void installHandler();
virtual const char* what() const { return _event; };
ExceptionAddress where() const { return _location; };
unsigned code() const { return _code; };
protected:
Win32Exception(const EXCEPTION_RECORD * info); //Constructor only accessible by exception handler
static void translate(unsigned code, EXCEPTION_POINTERS * info);
private:
const char * _event;
ExceptionAddress _location;
unsigned int _code;
};
class Win32AccessViolation: public Win32Exception
{
public:
bool isWrite() const { return _isWrite; };
ExceptionAddress badAddress() const { return _badAddress; };
private:
Win32AccessViolation(const EXCEPTION_RECORD * info);
bool _isWrite;
ExceptionAddress _badAddress;
friend void Win32Exception::translate(unsigned code, EXCEPTION_POINTERS* info);
};

View File

@ -61,8 +61,10 @@ struct SortTaskListPred
Notepad_plus::Notepad_plus(): Window(), _mainWindowStatus(0), _pDocTab(NULL), _pEditView(NULL),
_pMainSplitter(NULL), _isfullScreen(false),
_recordingMacro(false), _pTrayIco(NULL), _isUDDocked(false), _isRTL(false),
_linkTriggered(true), _isDocModifing(false), _isHotspotDblClicked(false), _isSaving(false), _sysMenuEntering(false)
_linkTriggered(true), _isDocModifing(false), _isHotspotDblClicked(false), _isSaving(false), _sysMenuEntering(false),
_autoCompleteMain(&_mainEditView), _autoCompleteSub(&_subEditView)
{
ZeroMemory(&_prevSelectedRange, sizeof(_prevSelectedRange));
_winVersion = (NppParameters::getInstance())->getWinVersion();
@ -1611,65 +1613,7 @@ string Notepad_plus::getLangDesc(LangType langType, bool shortDesc)
return string(elc._desc);
}
static const int maxChar = 64;
static char langDescArray[][maxChar] = {
"Normal text", "Normal text file",
"PHP", "PHP Hypertext Preprocessor file",
"C", "C source file",
"C++", "C++ source file",
"C#", "C# source file",
"Objective-C", "Objective-C source file",
"Java", "Java source file",
"RC", "Windows Resource file",
"HTML", "Hyper Text Markup Language file",
"XML", "eXtensible Markup Language file",
"Makefile", "Makefile",
"Pascal", "Pascal source file",
"Batch", "Batch file",
"ini", "MS ini file",
"NFO", "MSDOS Style/ASCII Art",
"udf", "User Define File",
"ASP", "Active Server Pages script file",
"SQL", "Structured Query Language file",
"VB", "Visual Basic file",
"JavaScript", "JavaScript file",
"CSS", "Cascade Style Sheets File",
"Perl", "Perl source file",
"Python", "Python file",
"Lua", "Lua source File",
"TeX", "TeX file",
"Fortran", "Fortran source file",
"Shell", "Unix script file",
"Flash Action", "Flash Action script file",
"NSIS", "Nullsoft Scriptable Install System script file",
"TCL", "Tool Command Language file",
"Lisp", "List Processing language file",
"Scheme", "Scheme file",
"Assembly", "Assembly language source file",
"Diff", "Diff file",
"Properties file", "Properties file",
"Postscript", "Postscript file",
"Ruby", "Ruby file",
"Smalltalk", "Smalltalk file",
"VHDL", "VHSIC Hardware Description Language file",
"KiXtart", "KiXtart file",
"AutoIt", "AutoIt",
"CAML", "Categorical Abstract Machine Language",
"Ada", "Ada file",
"Verilog", "Verilog file",
"MATLAB", "MATrix LABoratory",
"Haskell", "Haskell",
"Inno", "Inno Setup script",
"Internal Search", "Internal Search",
"CMAKEFILE", "CMAKEFILE",
"YAML", "YAML Ain't Markup Language"
};
int index = (int(langType)) * 2 + (shortDesc?0:1);
if (index >= sizeof(langDescArray)/maxChar)
index = 0;
string str2Show = langDescArray[index];
string str2Show = ScintillaEditView::langNames[langType].longName;
if (langType == L_USER)
{
@ -1683,125 +1627,6 @@ string Notepad_plus::getLangDesc(LangType langType, bool shortDesc)
return str2Show;
}
void Notepad_plus::getApiFileName(LangType langType, string &fn)
{
switch (langType)
{
case L_C: fn = "c"; break;
case L_CPP: fn = "cpp"; break;
case L_OBJC: fn = "objC"; break;
case L_JAVA: fn = "java"; break;
case L_CS : fn = "cs"; break;
case L_XML: fn = "xml"; break;
case L_JS: fn = "javascript"; break;
case L_PHP: fn = "php"; break;
case L_VB:
case L_ASP: fn = "vb"; break;
case L_CSS: fn = "css"; break;
case L_LUA: fn = "lua"; break;
case L_PERL: fn = "perl"; break;
case L_PASCAL: fn = "pascal"; break;
case L_PYTHON: fn = "python"; break;
case L_TEX : fn = "tex"; break;
case L_FORTRAN : fn = "fortran"; break;
case L_BASH : fn = "bash"; break;
case L_FLASH : fn = "flash"; break;
case L_NSIS : fn = "nsis"; break;
case L_TCL : fn = "tcl"; break;
case L_LISP : fn = "lisp"; break;
case L_SCHEME : fn = "scheme"; break;
case L_ASM :
fn = "asm"; break;
case L_DIFF :
fn = "diff"; break;
/*
case L_PROPS :
fn = "Properties file"; break;
*/
case L_PS :
fn = "postscript"; break;
case L_RUBY :
fn = "ruby"; break;
case L_SMALLTALK :
fn = "smalltalk"; break;
case L_VHDL :
fn = "vhdl"; break;
case L_KIX :
fn = "kix"; break;
case L_AU3 :
fn = "autoit"; break;
case L_CAML :
fn = "caml"; break;
case L_ADA :
fn = "ada"; break;
case L_VERILOG :
fn = "verilog"; break;
case L_MATLAB :
fn = "matlab"; break;
case L_HASKELL :
fn = "haskell"; break;
case L_INNO :
fn = "inno"; break;
case L_CMAKE :
fn = "cmake"; break;
case L_YAML :
fn = "yaml"; break;
case L_USER :
{
Buffer & currentBuf = _pEditView->getCurrentBuffer();
if (currentBuf.isUserDefineLangExt())
{
fn = currentBuf.getUserDefineLangName();
}
break;
}
default:
if (langType >= L_EXTERNAL && langType < NppParameters::getInstance()->L_END)
fn = NppParameters::getInstance()->getELCFromIndex(langType - L_EXTERNAL)._name;
else
fn = "text";
}
}
BOOL Notepad_plus::notify(SCNotification *notification)
{
//Important, keep track of which element generated the message
@ -2160,22 +1985,11 @@ BOOL Notepad_plus::notify(SCNotification *notification)
case SCN_CHARADDED:
{
charAdded(static_cast<char>(notification->ch));
static const NppGUI & nppGUI = NppParameters::getInstance()->getNppGUI();
char s[64];
notifyView->getWordToCurrentPos(s, sizeof(s));
AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub;
autoC->update(notification->ch);
if (strlen(s) >= nppGUI._autocFromLen)
{
if (nppGUI._autocStatus == nppGUI.autoc_word)
autoCompFromCurrentFile(false);
else if (nppGUI._autocStatus == nppGUI.autoc_func)
showAutoComp();
}
if (nppGUI._funcParams || _funcCalltip.isVisible()) {
_funcCalltip.updateCalltip(notification->ch);
}
break;
}
@ -2196,12 +2010,14 @@ BOOL Notepad_plus::notify(SCNotification *notification)
break;
case SCN_UPDATEUI:
{
braceMatch();
markSelectedText();
updateStatusBar();
if (_funcCalltip.isVisible())
_funcCalltip.updateCalltip(0);
AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub;
autoC->update(0);
break;
}
case TTN_GETDISPINFO:
{
@ -2303,12 +2119,8 @@ BOOL Notepad_plus::notify(SCNotification *notification)
case SCN_CALLTIPCLICK:
{
int dir = notification->position;
if (dir == 1) {
_funcCalltip.showPrevOverload();
} else if (dir == 2) {
_funcCalltip.showNextOverload();
}
AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub;
autoC->callTipClick(notification->position);
break;
}
@ -5036,167 +4848,24 @@ void Notepad_plus::checkUnicodeMenuItems(UniMode um) const
::CheckMenuRadioItem(_mainMenuHandle, IDM_FORMAT_ANSI, IDM_FORMAT_AS_UTF_8, id, MF_BYCOMMAND);
}
static bool isInList(string word, const vector<string> & wordArray)
{
for (size_t i = 0 ; i < wordArray.size() ; i++)
if (wordArray[i] == word)
return true;
return false;
};
void Notepad_plus::autoCompFromCurrentFile(bool autoInsert)
{
int curPos = int(_pEditView->execute(SCI_GETCURRENTPOS));
int startPos = int(_pEditView->execute(SCI_WORDSTARTPOSITION, curPos, true));
if (curPos == startPos)
return;
const size_t bufSize = 256;
size_t len = (curPos > startPos)?(curPos - startPos):(startPos - curPos);
if (len >= bufSize)
return;
char beginChars[bufSize];
_pEditView->getText(beginChars, startPos, curPos);
string expr("\\<");
expr += beginChars;
expr += "[^ \\t.,;:\"()=<>'+!\\[\\]]*";
//::MessageBox(NULL, expr.c_str(), "", MB_OK);
int docLength = int(_pEditView->execute(SCI_GETLENGTH));
int flags = SCFIND_WORDSTART | SCFIND_MATCHCASE | SCFIND_REGEXP | SCFIND_POSIX;
_pEditView->execute(SCI_SETTARGETSTART, 0);
_pEditView->execute(SCI_SETTARGETEND, docLength);
_pEditView->execute(SCI_SETSEARCHFLAGS, flags);
vector<string> wordArray;
int posFind = int(_pEditView->execute(SCI_SEARCHINTARGET, expr.length(), (LPARAM)expr.c_str()));
while (posFind != -1)
{
int wordStart = int(_pEditView->execute(SCI_GETTARGETSTART));
int wordEnd = int(_pEditView->execute(SCI_GETTARGETEND));
size_t foundTextLen = wordEnd - wordStart;
if (foundTextLen < bufSize)
{
char w[bufSize];
_pEditView->getText(w, wordStart, wordEnd);
if (strcmp(w, beginChars))
if (!isInList(w, wordArray))
wordArray.push_back(w);
}
_pEditView->execute(SCI_SETTARGETSTART, wordEnd/*posFind + foundTextLen*/);
_pEditView->execute(SCI_SETTARGETEND, docLength);
posFind = int(_pEditView->execute(SCI_SEARCHINTARGET, expr.length(), (LPARAM)expr.c_str()));
}
if (wordArray.size() == 0) return;
if (wordArray.size() == 1 && autoInsert)
{
_pEditView->execute(SCI_SETTARGETSTART, startPos);
_pEditView->execute(SCI_SETTARGETEND, curPos);
_pEditView->execute(SCI_REPLACETARGETRE, wordArray[0].length(), (LPARAM)wordArray[0].c_str());
_pEditView->execute(SCI_GOTOPOS, startPos + wordArray[0].length());
return;
}
sort(wordArray.begin(), wordArray.end());
string words("");
for (size_t i = 0 ; i < wordArray.size() ; i++)
{
words += wordArray[i];
if (i != wordArray.size()-1)
words += " ";
}
_pEditView->execute(SCI_AUTOCSETSEPARATOR, WPARAM(' '));
_pEditView->execute(SCI_AUTOCSETIGNORECASE, 3);
_pEditView->execute(SCI_AUTOCSHOW, curPos - startPos, WPARAM(words.c_str()));
void Notepad_plus::showAutoComp() {
bool isFromPrimary = _pEditView == &_mainEditView;
AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub;
autoC->showAutoComplete();
}
void Notepad_plus::showAutoComp()
{
int curPos = int(_pEditView->execute(SCI_GETCURRENTPOS));
int line = _pEditView->getCurrentLineNumber();
int debutLinePos = int(_pEditView->execute(SCI_POSITIONFROMLINE, line ));
int debutMotPos = curPos;
char c = char(_pEditView->execute(SCI_GETCHARAT, debutMotPos-1));
while ((debutMotPos>0)&&(debutMotPos>=debutLinePos)&&((isalnum(c))||(c=='_')))
{
debutMotPos--;
c = char(_pEditView->execute(SCI_GETCHARAT, debutMotPos-1));
}
LangType langType = _pEditView->getCurrentDocType();
if ((langType == L_RC) || (langType == L_HTML) || (langType == L_SQL))
{
int typeIndex = LANG_INDEX_INSTR;
const char *pKeywords = (NppParameters::getInstance())->getWordList(langType, typeIndex);
if (pKeywords)
{
_pEditView->execute(SCI_AUTOCSETSEPARATOR, WPARAM(' '));
_pEditView->execute(SCI_AUTOCSETIGNORECASE, 3);
_pEditView->execute(SCI_AUTOCSHOW, curPos-debutMotPos, WPARAM(pKeywords));
}
}
else
{
char nppPath[MAX_PATH];
strcpy(nppPath, _nppPath);
PathRemoveFileSpec(nppPath);
string fullFileName = nppPath;
string fileName;
getApiFileName(langType, fileName);
fileName += ".api";
fullFileName += "\\plugins\\APIs\\";
fullFileName += fileName;
FILE* f = fopen( fullFileName.c_str(), "r" );
if (f)
{
fseek( f, 0, SEEK_END );
size_t sz = ftell( f );
fseek( f, 0, SEEK_SET );
char* pData = new char[sz+1];
size_t nbChar = fread(pData, 1, sz, f);
pData[nbChar] = '\0';
fclose( f );
_pEditView->execute(SCI_AUTOCSETSEPARATOR, WPARAM('\n'));
_pEditView->execute(SCI_AUTOCSETIGNORECASE, 3);
_pEditView->execute(SCI_AUTOCSHOW, curPos-debutMotPos, WPARAM(pData));
delete[] pData;
}
}
void Notepad_plus::autoCompFromCurrentFile(bool autoInsert) {
bool isFromPrimary = _pEditView == &_mainEditView;
AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub;
autoC->showWordComplete(autoInsert);
}
void Notepad_plus::showFunctionComp() {
//string langName;
//LangType langType = _pEditView->getCurrentDocType();
//getApiFileName(langType, langName);
//_funcCalltip.initCalltip(_pEditView, langName.c_str());
_funcCalltip.updateCalltip(0, true);
bool isFromPrimary = _pEditView == &_mainEditView;
AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub;
autoC->showFunctionComplete();
}
void Notepad_plus::changeMenuLang(string & pluginsTrans, string & windowTrans)
{
if (!_nativeLang) return;
@ -8379,4 +8048,83 @@ void Notepad_plus::markSelectedText()
_findReplaceDlg.markAll2(text2Find);
}
//ONLY CALL IN CASE OF EMERGENCY: EXCEPTION
//This function is destructive
bool Notepad_plus::emergency() {
const char * outdir = "C:\\N++RECOV";
bool status = false;
do {
if (::CreateDirectory(outdir, NULL) == FALSE && ::GetLastError() != ERROR_ALREADY_EXISTS) {
break;
}
ScintillaEditView * viewToRecover = &_mainEditView;
status |= dumpFiles(viewToRecover, outdir, "Main");
viewToRecover = &_subEditView;
status |= dumpFiles(viewToRecover, outdir, "Sub");
} while (false);
return status;
}
bool Notepad_plus::dumpFiles(ScintillaEditView * viewToRecover, const char * outdir, const char * fileprefix) {
//start dumping unsaved files to recovery directory
bool somethingsaved = false;
bool somedirty = false;
size_t nrdocs = viewToRecover->getNbDoc();
bool skipfirst = viewToRecover->getCurrentDocIndex() == 0; //if cur doc is first, dont do setdocpointer or itll be deleted
char savePath[MAX_PATH] = {0};
int bufferSize = 2048;
char dataBuffer[2048+1] = {0}; //not too bug of a buffer, we dont know how much we've got here
FILE * dumpFile;
TextRange textRange;
textRange.lpstrText = dataBuffer;
//rescue primary
for(size_t i = 0; i < nrdocs; i++) {
Buffer & docbuf = viewToRecover->getBufferAt(i);
if (!docbuf.isDirty()) //skip saved documents
continue;
else
somedirty = true;
if (i != 0 || !skipfirst)
viewToRecover->execute(SCI_SETDOCPOINTER, 0, docbuf._doc);
const char * unitext = "";
if (docbuf.getUnicodeMode() != uni8Bit)
unitext = "_uni";
sprintf(savePath, "%s\\%s%03d%s.dump", outdir, fileprefix, i, unitext);
dumpFile = fopen(savePath, "wb");
if (!dumpFile) { //cannot create file, this is bad
::MessageBox(NULL, savePath, "Cannot dump file", MB_OK | MB_ICONWARNING);
continue;
}
//now it gets tricky, we have to have some allocated memory, we can only hope we have some
int size = viewToRecover->execute(SCI_GETLENGTH);
int saved = 0;
while(0 < size) {
if (size < bufferSize) {
bufferSize = size; //last piece of data smaller than buffer
}
textRange.chrg.cpMin = saved;
textRange.chrg.cpMax = saved + bufferSize;
viewToRecover->execute(SCI_GETTEXTRANGE, 0, (LPARAM)&textRange);
size_t res = fwrite(dataBuffer, bufferSize, 1, dumpFile);
if (!res) //FAILURE!
break;
saved += bufferSize;
size -= bufferSize;
}
somethingsaved |= size==0;
fclose(dumpFile);
}
return somethingsaved || !somedirty;
}

View File

@ -46,7 +46,7 @@
#include "RunMacroDlg.h"
#include "DockingManager.h"
#include "Process.h"
#include "FunctionCallTip.h"
#include "AutoCompletion.h"
#define NOTEPAD_PP_CLASS_NAME "Notepad++"
@ -78,9 +78,6 @@ struct iconLocator {
class FileDialog;
//Class assumes Scintilla makes sure calltip never gets displayed twice
class Notepad_plus : public Window {
enum comment_mode {cm_comment, cm_uncomment, cm_toggle};
public:
@ -171,13 +168,15 @@ public:
bool loadSession(Session & session);
winVer getWinVersion() const {return _winVersion;};
bool emergency();
private:
static const char _className[32];
char _nppPath[MAX_PATH];
Window *_pMainWindow;
DockingManager _dockingManager;
FunctionCallTip _funcCalltip;
AutoCompletion _autoCompleteMain;
AutoCompletion _autoCompleteSub; //each Scintilla has its own autoComplete
TiXmlNode *_nativeLang, *_toolIcons;
@ -413,10 +412,10 @@ private:
void setLangStatus(LangType langType){
_statusBar.setText(getLangDesc(langType).c_str(), STATUSBAR_DOC_TYPE);
string langName;
getApiFileName(langType, langName);
_funcCalltip.initCalltip(_pEditView, langName.c_str());
if (_pEditView == &_mainEditView)
_autoCompleteMain.setLanguage(langType);
else
_autoCompleteSub.setLanguage(langType);
};
void setDisplayFormat(formatType f) {
@ -603,7 +602,6 @@ private:
void showAutoComp();
void autoCompFromCurrentFile(bool autoInsert = true);
void getApiFileName(LangType langType, std::string &fn);
void showFunctionComp();
void changeStyleCtrlsLang(HWND hDlg, int *idArray, const char **translatedText);
@ -753,6 +751,8 @@ private:
}
return true;
};
bool dumpFiles(ScintillaEditView * viewToRecover, const char * outdir, const char * fileprefix = ""); //helper func
};
#endif //NOTEPAD_PLUS_H

View File

@ -2013,59 +2013,21 @@ TiXmlNode * NppParameters::getChildElementByAttribut(TiXmlNode *pere, const char
// 2 restes : L_H, L_USER
LangType NppParameters::getLangIDFromStr(const char *langName)
{
if (!strcmp("c", langName)) return L_C;
if (!strcmp("cpp", langName)) return L_CPP;
if (!strcmp("java", langName)) return L_JAVA;
if (!strcmp("cs", langName)) return L_CS;
if (!strcmp("objc", langName)) return L_OBJC;
if (!strcmp("rc", langName)) return L_RC;
if (!strcmp("html", langName)) return L_HTML;
if (!strcmp("javascript", langName)) return L_JS;
if (!strcmp("php", langName)) return L_PHP;
if (!strcmp("vb", langName)) return L_VB;
if (!strcmp("sql", langName)) return L_SQL;
if (!strcmp("xml", langName)) return L_XML;
if (!strcmp("asp", langName)) return L_ASP;
if (!strcmp("perl", langName)) return L_PERL;
if (!strcmp("pascal", langName)) return L_PASCAL;
if (!strcmp("python", langName)) return L_PYTHON;
if (!strcmp("css", langName)) return L_CSS;
if (!strcmp("lua", langName)) return L_LUA;
if (!strcmp("batch", langName)) return L_BATCH;
if (!strcmp("ini", langName)) return L_INI;
if (!strcmp("nfo", langName)) return L_NFO;
if (!strcmp("makefile", langName)) return L_MAKEFILE;
if (!strcmp("tex", langName)) return L_TEX;
if (!strcmp("fortran", langName)) return L_FORTRAN;
if (!strcmp("bash", langName)) return L_BASH;
if (!strcmp("actionscript", langName)) return L_FLASH;
if (!strcmp("nsis", langName)) return L_NSIS;
if (!strcmp("tcl", langName)) return L_TCL;
int lang = (int)L_TXT;
for(; lang < L_EXTERNAL; lang++) {
const char * name = ScintillaEditView::langNames[lang].lexerName;
if (!strcmp(name, langName)) { //found lang?
return (LangType)lang;
}
}
if (!strcmp("lisp", langName)) return L_LISP;
if (!strcmp("scheme", langName)) return L_SCHEME;
if (!strcmp("asm", langName)) return L_ASM;
if (!strcmp("diff", langName)) return L_DIFF;
if (!strcmp("props", langName)) return L_PROPS;
if (!strcmp("postscript", langName)) return L_PS;
if (!strcmp("ruby", langName)) return L_RUBY;
if (!strcmp("smalltalk", langName)) return L_SMALLTALK;
if (!strcmp("vhdl", langName)) return L_VHDL;
//Cannot find language, check if its an external one
if (!strcmp("caml", langName)) return L_CAML;
if (!strcmp("verilog", langName)) return L_VERILOG;
if (!strcmp("kix", langName)) return L_KIX;
if (!strcmp("autoit", langName)) return L_AU3;
if (!strcmp("ada", langName)) return L_ADA;
if (!strcmp("matlab", langName)) return L_MATLAB;
if (!strcmp("haskell", langName)) return L_HASKELL;
if (!strcmp("inno", langName)) return L_INNO;
if (!strcmp("searchResult", langName)) return L_SEARCHRESULT;
if (!strcmp("cmake", langName)) return L_CMAKE;
if (!strcmp("yaml", langName)) return L_YAML;
int id = _pSelf->getExternalLangIndexFromName(langName);
if (id != -1) return (LangType)(id + L_EXTERNAL);
LangType l = (LangType)lang;
if (l == L_EXTERNAL) { //try find external lexer
int id = _pSelf->getExternalLangIndexFromName(langName);
if (id != -1) return (LangType)(id + L_EXTERNAL);
}
return L_TXT;
}

View File

@ -357,8 +357,11 @@ public:
void addStyler(int styleID, TiXmlNode *styleNode);
void addStyler(int styleID, char *styleName) {
ZeroMemory(&_styleArray[_nbStyler], sizeof(Style));;
_styleArray[_nbStyler]._styleID = styleID;
_styleArray[_nbStyler]._styleDesc = styleName;
_styleArray[_nbStyler]._fgColor = black;
_styleArray[_nbStyler]._bgColor = white;
_nbStyler++;
};

View File

@ -0,0 +1,311 @@
//this file is part of Notepad++
//Copyright (C)2008 Harry Bruin <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 "AutoCompletion.h"
#include "Notepad_plus_msgs.h"
static bool isInList(string word, const vector<string> & wordArray)
{
for (size_t i = 0 ; i < wordArray.size() ; i++)
if (wordArray[i] == word)
return true;
return false;
};
AutoCompletion::AutoCompletion(ScintillaEditView * pEditView) : _active(false), _pEditView(pEditView), _funcCalltip(pEditView),
_curLang(L_TXT), _XmlFile(NULL), _activeCompletion(CompletionNone),
_pXmlKeyword(NULL), _ignoreCase(true), _keyWords("")
{
//Do not load any language yet
}
bool AutoCompletion::showAutoComplete() {
if (!_active)
return false;
int curPos = int(_pEditView->execute(SCI_GETCURRENTPOS));
int line = _pEditView->getCurrentLineNumber();
int startLinePos = int(_pEditView->execute(SCI_POSITIONFROMLINE, line ));
int startWordPos = startLinePos;
int len = curPos-startLinePos;
char * lineBuffer = new char[len+1];
_pEditView->getText(lineBuffer, startLinePos, curPos);
//_pEditView->execute(SCI_GETTEXT, (WPARAM)len, (LPARAM)lineBuffer);
int offset = len-1;
int nrChars = 0;
char c;
while (offset>=0)
{
c = lineBuffer[offset];
if (isalnum(c) || c == '_') {
nrChars++;
} else {
break;
}
offset--;
}
startWordPos = curPos-nrChars;
_pEditView->execute(SCI_AUTOCSETSEPARATOR, WPARAM('\n'));
_pEditView->execute(SCI_AUTOCSETIGNORECASE, _ignoreCase);
_pEditView->execute(SCI_AUTOCSHOW, curPos-startWordPos, WPARAM(_keyWords.c_str()));
_activeCompletion = CompletionAuto;
return true;
}
bool AutoCompletion::showWordComplete(bool autoInsert) {
if (!_active)
return false;
int curPos = int(_pEditView->execute(SCI_GETCURRENTPOS));
int startPos = int(_pEditView->execute(SCI_WORDSTARTPOSITION, curPos, true));
if (curPos == startPos)
return false;
const size_t bufSize = 256;
size_t len = (curPos > startPos)?(curPos - startPos):(startPos - curPos);
if (len >= bufSize)
return false;
char beginChars[bufSize];
_pEditView->getText(beginChars, startPos, curPos);
string expr("\\<");
expr += beginChars;
expr += "[^ \\t.,;:\"()=<>'+!\\[\\]]*";
int docLength = int(_pEditView->execute(SCI_GETLENGTH));
int flags = SCFIND_WORDSTART | SCFIND_MATCHCASE | SCFIND_REGEXP | SCFIND_POSIX;
_pEditView->execute(SCI_SETTARGETSTART, 0);
_pEditView->execute(SCI_SETTARGETEND, docLength);
_pEditView->execute(SCI_SETSEARCHFLAGS, flags);
vector<string> wordArray;
int posFind = int(_pEditView->execute(SCI_SEARCHINTARGET, expr.length(), (LPARAM)expr.c_str()));
while (posFind != -1)
{
int wordStart = int(_pEditView->execute(SCI_GETTARGETSTART));
int wordEnd = int(_pEditView->execute(SCI_GETTARGETEND));
size_t foundTextLen = wordEnd - wordStart;
if (foundTextLen < bufSize)
{
char w[bufSize];
_pEditView->getText(w, wordStart, wordEnd);
if (strcmp(w, beginChars))
if (!isInList(w, wordArray))
wordArray.push_back(w);
}
_pEditView->execute(SCI_SETTARGETSTART, wordEnd/*posFind + foundTextLen*/);
_pEditView->execute(SCI_SETTARGETEND, docLength);
posFind = int(_pEditView->execute(SCI_SEARCHINTARGET, expr.length(), (LPARAM)expr.c_str()));
}
if (wordArray.size() == 0) return false;
if (wordArray.size() == 1 && autoInsert)
{
_pEditView->execute(SCI_SETTARGETSTART, startPos);
_pEditView->execute(SCI_SETTARGETEND, curPos);
_pEditView->execute(SCI_REPLACETARGETRE, wordArray[0].length(), (LPARAM)wordArray[0].c_str());
_pEditView->execute(SCI_GOTOPOS, startPos + wordArray[0].length());
return true;
}
string words("");
for (size_t i = 0 ; i < wordArray.size() ; i++)
{
words += wordArray[i];
if (i != wordArray.size()-1)
words += " ";
}
_pEditView->execute(SCI_AUTOCSETSEPARATOR, WPARAM(' '));
_pEditView->execute(SCI_AUTOCSETIGNORECASE, _ignoreCase);
_pEditView->execute(SCI_AUTOCSHOW, curPos - startPos, WPARAM(words.c_str()));
_activeCompletion = CompletionWord;
return true;
}
bool AutoCompletion::showFunctionComplete() {
if (!_active)
return false;
if (_funcCalltip.updateCalltip(0, true)) {
_activeCompletion = CompletionFunc;
return true;
}
return false;
}
void AutoCompletion::update(int character) {
if (!_active)
return;
const NppGUI & nppGUI = NppParameters::getInstance()->getNppGUI();
if (nppGUI._funcParams || _funcCalltip.isVisible()) {
if (_funcCalltip.updateCalltip(character)) { //calltip visible because triggered by autocomplete, set mode
_activeCompletion = CompletionFunc;
return; //only return in case of success, else autocomplete
}
}
if (!character)
return;
//If autocomplete already active, let Scintilla handle it
if (_pEditView->execute(SCI_AUTOCACTIVE) != 0)
return;
char s[64];
_pEditView->getWordToCurrentPos(s, sizeof(s));
if (strlen(s) >= nppGUI._autocFromLen)
{
if (nppGUI._autocStatus == nppGUI.autoc_word)
showWordComplete(false);
else if (nppGUI._autocStatus == nppGUI.autoc_func)
showAutoComplete();
}
}
void AutoCompletion::callTipClick(int direction) {
if (!_active)
return;
if (direction == 1) {
_funcCalltip.showPrevOverload();
} else if (direction == 2) {
_funcCalltip.showNextOverload();
}
}
bool AutoCompletion::setLanguage(LangType language) {
if (_curLang == language)
return true;
_curLang = language;
char path[MAX_PATH];
::GetModuleFileName(NULL, path, MAX_PATH);
PathRemoveFileSpec(path);
strcat(path, "\\plugins\\APIs\\");
strcat(path, getApiFileName());
strcat(path, ".xml");
_XmlFile = TiXmlDocument(path);
_active = _XmlFile.LoadFile();
TiXmlNode * pAutoNode = NULL;
if (_active) {
_active = false; //safety
TiXmlNode * pNode = _XmlFile.FirstChild("NotepadPlus");
if (!pNode)
return false;
pAutoNode = pNode = pNode->FirstChildElement("AutoComplete");
if (!pNode)
return false;
pNode = pNode->FirstChildElement("KeyWord");
if (!pNode)
return false;
_pXmlKeyword = reinterpret_cast<TiXmlElement *>(pNode);
if (!_pXmlKeyword)
return false;
_active = true;
}
if(_active) { //try setting up environment
//setup defaults
_ignoreCase = true;
_funcCalltip._start = '(';
_funcCalltip._stop = ')';
_funcCalltip._param = ',';
_funcCalltip._terminal = ';';
TiXmlElement * pElem = pAutoNode->FirstChildElement("Environment");
if (pElem) {
const char * val = 0;
val = pElem->Attribute("ignoreCase");
if (val && !strcmp(val, "no"))
_ignoreCase = false;
val = pElem->Attribute("startFunc");
if (val && val[0])
_funcCalltip._start = val[0];
val = pElem->Attribute("stopFunc");
if (val && val[0])
_funcCalltip._stop = val[0];
val = pElem->Attribute("paramSeparator");
if (val && val[0])
_funcCalltip._param = val[0];
val = pElem->Attribute("terminal");
if (val && val[0])
_funcCalltip._terminal = val[0];
}
}
if (_active) {
_funcCalltip.setLanguageXML(_pXmlKeyword);
} else {
_funcCalltip.setLanguageXML(NULL);
}
_keyWords = "";
if (_active) { //Cache the keywords
//Iterate through all keywords
TiXmlElement *funcNode = _pXmlKeyword;
const char * name = NULL;
for (; funcNode; funcNode = funcNode->NextSiblingElement("KeyWord") ) {
name = funcNode->Attribute("name");
if (!name) //malformed node
continue;
_keyWords.append(name);
_keyWords.append("\n");
}
}
return _active;
}
const char * AutoCompletion::getApiFileName() {
if (_curLang == L_USER)
{
Buffer & currentBuf = _pEditView->getCurrentBuffer();
if (currentBuf.isUserDefineLangExt())
{
return currentBuf.getUserDefineLangName();
}
}
if (_curLang >= L_EXTERNAL && _curLang < NppParameters::getInstance()->L_END)
return NppParameters::getInstance()->getELCFromIndex(_curLang - L_EXTERNAL)._name;
return ScintillaEditView::langNames[_curLang].lexerName;
}

View File

@ -0,0 +1,57 @@
//this file is part of Notepad++
//Copyright (C)2008 Harry Bruin <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 AUTOCOMPLETION_H
#define AUTOCOMPLETION_H
#include "ScintillaEditView.h"
#include "FunctionCallTip.h"
#include "tinyxml.h"
class AutoCompletion {
public:
enum ActiveCompletion {CompletionNone = 0, CompletionAuto, CompletionWord, CompletionFunc};
AutoCompletion(ScintillaEditView * pEditView);
bool setLanguage(LangType language);
//AutoComplete from the list
bool showAutoComplete();
//WordCompletion from the current file
bool showWordComplete(bool autoInsert); //autoInsert true if completion should fill in the word on a single match
//Parameter display from the list
bool showFunctionComplete();
void update(int character);
void callTipClick(int direction);
private:
bool _active;
ScintillaEditView * _pEditView;
LangType _curLang;
TiXmlDocument _XmlFile;
TiXmlElement * _pXmlKeyword;
ActiveCompletion _activeCompletion;
bool _ignoreCase;
std::string _keyWords;
FunctionCallTip _funcCalltip;
const char * getApiFileName();
};
#endif //AUTOCOMPLETION_H

View File

@ -1,3 +1,7 @@
//this file is part of Notepad++
//Copyright (C)2008 Harry Bruin <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.
@ -39,59 +43,28 @@ bool stringEqualN(const char * first, const char * second, int n) {
return true;
};
void FunctionCallTip::initCalltip(ScintillaEditView * editView, const char * language) {
_pEditView = editView;
if (_langName)
delete [] _langName;
_langName = new char[strlen(language)+1];
strcpy(_langName, language);
_initialized = true;
void FunctionCallTip::setLanguageXML(TiXmlElement * pXmlKeyword) {
if (isVisible())
close();
_pXmlKeyword = pXmlKeyword;
}
void FunctionCallTip::updateCalltip(int ch, bool needShown) {
if (!_initialized)
return;
bool FunctionCallTip::updateCalltip(int ch, bool needShown) {
if (!needShown && ch != _start && !isVisible()) //must be already visible
return;
return false;
_curPos = _pEditView->execute(SCI_GETCURRENTPOS);
//recalculate everything
if (!getCursorFunction()) { //cannot display calltip (anymore)
close();
return;
return false;
}
showCalltip();
return;
/*
switch (ch) {
case '(':
case 0: { //recalculate everything
if (!getCursorFunction()) { //cannot display calltip (anymore)
close();
return;
}
showCalltip();
return; }
case ')': { //close calltip
close();
return; }
case ',': { //show next param
_currentParam++;
showCalltip();
return; }
default: { //any other character: nothing to do
break; }
}
*/
return true;
}
void FunctionCallTip::showNextOverload() {
if (!_initialized)
return;
if (!isVisible())
return;
_currentOverload = (_currentOverload+1) % _currentNrOverloads;
@ -99,8 +72,6 @@ void FunctionCallTip::showNextOverload() {
}
void FunctionCallTip::showPrevOverload() {
if (!_initialized)
return;
if (!isVisible())
return;
_currentOverload = _currentOverload > 0?(_currentOverload-1) : _currentNrOverloads-1;
@ -108,8 +79,6 @@ void FunctionCallTip::showPrevOverload() {
}
void FunctionCallTip::close() {
if (!_initialized)
return;
if (!isVisible()) {
return;
}
@ -126,10 +95,6 @@ bool FunctionCallTip::getCursorFunction() {
int offset = _curPos - startpos; //offset is cursor location, only stuff before cursor has influence
if (offset < 2) {
reset();
if (_funcName) {
delete [] _funcName;
_funcName = 0;
}
return false; //cannot be a func, need name and separator
}
char * lineData = new char[len];
@ -222,11 +187,7 @@ bool FunctionCallTip::getCursorFunction() {
_currentParam = curValue.param;
if (!_funcName || !stringEqualN(_funcName, funcToken.token, strlen(_funcName))) { //check if we need to reload data
if (_funcName)
delete [] _funcName;
_funcName = new char[strlen(funcToken.token) + 1]; //add the return type aswell
strcpy(_funcName, funcToken.token);
res = loadData();
res = loadFunction(funcToken.token);
} else {
res = true;
}
@ -243,91 +204,75 @@ bool FunctionCallTip::getCursorFunction() {
}
/*
CTF (CalltipFormat) file structure (ignore spaces).
There MUST be a return type, however, may be empty string (or empty line even)
_no_ CR. ESC = 027 = 0x1B
(
NULL FunctionName LF
return value (ESC possibleparam)* LF
)*
NULL
Find function in XML structure and parse it
*/
bool FunctionCallTip::loadData() {
char filePath[MAX_PATH];
::GetModuleFileName(NULL, filePath, MAX_PATH);
PathRemoveFileSpec(filePath);
strcat(filePath, "\\plugins\\APIs\\");
strcat(filePath, _langName);
strcat(filePath, ".ctf");
FILE * ctfFile = fopen(filePath, "rb"); //CalltipFormat File
if (!ctfFile)
return false;
//Copy all data, close with \n to be sure
fseek(ctfFile, 0, SEEK_END );
size_t fileSize = ftell(ctfFile);
fseek(ctfFile, 0, SEEK_SET );
char * fileData = new char[fileSize+1];
size_t nbChar = fread(fileData, 1, fileSize, ctfFile);
fileData[nbChar] = 0;
fclose(ctfFile);
bool FunctionCallTip::loadFunction(const char * nameToFind) {
//The functions should be ordered, but linear search because we cant access like array
size_t i = 0, location = 0;
bool found = false;
int funcLen = strlen(_funcName);
fileSize -= funcLen; //if not enough is left, no need to keep searching
while(i < fileSize) {
if (fileData[i] == 0) { //reached new function
//case sensitive search
if (stringEqualN(_funcName, fileData+i+1, funcLen)) { //found it
found = true;
location = i + 2 + funcLen; //skip zero + LF + name of func (all known at this point)
break;
}
}
i++;
}
if (!found) {
delete [] fileData;
return false;
}
int argStart = location;
std::vector< pair<int, int> > overloadLocations; //start, length
while(fileData[location] != 0) { //keep reading each line of overloads untill next function is found
argStart = location;
while(fileData[location] != '\n') {
location++;
}
overloadLocations.push_back(pair<int, int>(argStart, location-argStart));
location++; //skip newline
}
_currentNrOverloads = overloadLocations.size();
_currentOverloads = new char*[_currentNrOverloads];
_params = new vector<int>[_currentNrOverloads];
int j = 0;
for(int i = 0; i < _currentNrOverloads; i++) {
pair<int, int> & cur = overloadLocations.at(i);
_currentOverloads[i] = new char[cur.second+1];
memcpy(_currentOverloads[i], fileData+cur.first, cur.second);
_currentOverloads[i][cur.second] = 0;
j = 0;
while(_currentOverloads[i][j] != 0) {
if (_currentOverloads[i][j] == 0x1B) {
_currentOverloads[i][j] = 0;
_params[i].push_back(j+1);
_curFunction = NULL;
//Iterate through all keywords and find the correct function keyword
TiXmlElement *funcNode = _pXmlKeyword;
const char * name = NULL;
for (; funcNode; funcNode = funcNode->NextSiblingElement("KeyWord") ) {
name = funcNode->Attribute("name");
if (!name) //malformed node
continue;
int compVal = strcmp(name, nameToFind);
if (!compVal) { //found it?
const char * val = funcNode->Attribute("func");
if (val)
{
if (!strcmp(val, "yes")) {
//what we've been looking for
_curFunction = funcNode;
break;
} else {
//name matches, but not a function, abort the entire procedure
return false;
}
j++;
}
} else if (compVal > 0) { //too far, abort
return false;
}
}
//Nothing found
if (!_curFunction)
return false;
_funcName = name;
if (!_funcName) //this should not happen
return false;
_retVals.clear();
_overloads.clear();
stringVec paramVec;
TiXmlElement *overloadNode = _curFunction->FirstChildElement("Overload");
TiXmlElement *paramNode = NULL;
for (; overloadNode ; overloadNode = overloadNode->NextSiblingElement("Overload") ) {
const char * retVal = overloadNode->Attribute("retVal");
if (!retVal)
continue; //malformed node
_retVals.push_back(retVal);
paramNode = overloadNode->FirstChildElement("Param");
for (; paramNode ; paramNode = paramNode->NextSiblingElement("Param") ) {
const char * param = paramNode->Attribute("name");
if (!param)
continue; //malformed node
paramVec.push_back(param);
}
_overloads.push_back(paramVec);
paramVec.clear();
_currentNrOverloads++;
}
_currentNrOverloads = (int)_overloads.size();
if (_currentNrOverloads == 0) //malformed node
return false;
delete [] fileData;
return true;
}
@ -336,26 +281,40 @@ void FunctionCallTip::showCalltip() {
//ASSERT
return;
}
char * curOverloadText = _currentOverloads[_currentOverload];
int bytesNeeded = strlen(curOverloadText) + strlen(_funcName) + 5;//'retval funcName (params)\0'
size_t nrParams = _params[_currentOverload].size();
if (nrParams) {
for(size_t i = 0; i < nrParams; i++) {
bytesNeeded += strlen(curOverloadText+_params[_currentOverload][i]) + 2; //'param, '
//Check if the current overload still holds. If the current param exceeds amounti n overload, see if another one fits better (enough params)
stringVec & params = _overloads.at(_currentOverload);
size_t psize = params.size()+1, osize;
if ((size_t)_currentParam >= psize) {
osize = _overloads.size();
for(size_t i = 0; i < osize; i++) {
psize = _overloads.at(i).size()+1;
if ((size_t)_currentParam < psize) {
_currentOverload = i;
break;
}
}
}
const char * curRetValText = _retVals.at(_currentOverload);
int bytesNeeded = strlen(curRetValText) + strlen(_funcName) + 5;//'retval funcName (params)\0'
size_t nrParams = params.size();
for(size_t i = 0; i < nrParams; i++) {
bytesNeeded += strlen(params.at(i)) + 2; //'param, '
}
if (_currentNrOverloads > 1) {
bytesNeeded += 24; // /\00001 of 00003\/
}
char * textBuffer = new char[bytesNeeded];
//char langDepChar[4] = " "; //Language dependant characters, like '(', ')', ',' and ';'
textBuffer[0] = 0;
if (_currentNrOverloads > 1) {
sprintf(textBuffer, "\001%u of %u\002", _currentOverload+1, _currentNrOverloads);
}
strcat(textBuffer, curOverloadText);
strcat(textBuffer, curRetValText);
strcat(textBuffer, " ");
strcat(textBuffer, _funcName);
strcat(textBuffer, " (");
@ -365,9 +324,9 @@ void FunctionCallTip::showCalltip() {
for(size_t i = 0; i < nrParams; i++) {
if (i == _currentParam) {
highlightstart = strlen(textBuffer);
highlightend = highlightstart + strlen(curOverloadText+_params[_currentOverload][i]);
highlightend = highlightstart + strlen(params.at(i));
}
strcat(textBuffer, curOverloadText+_params[_currentOverload][i]);
strcat(textBuffer, params.at(i));
if (i < nrParams-1)
strcat(textBuffer, ", ");
}
@ -389,36 +348,16 @@ void FunctionCallTip::showCalltip() {
void FunctionCallTip::reset() {
_currentOverload = 0;
//_currentNrOverloads = 0;
_currentParam = 0;
_curPos = 0;
_startPos = 0;
}
void FunctionCallTip::cleanup() {
if (_currentOverloads) {
for(int i = 0; i < _currentNrOverloads; i++)
delete [] _currentOverloads[i];
_currentNrOverloads = 0;
delete [] _currentOverloads;
_currentOverloads = 0;
}
if(_funcName) {
delete [] _funcName;
_funcName = 0;
}
if (_params) {
delete [] _params;
_params = 0;
}
if (_langName) {
delete [] _langName;
_langName = 0;
}
reset();
_overloads.clear();
_currentNrOverloads = 0;
_retVals.clear();
_funcName = 0;
_pEditView = NULL;
_currentOverload = 0;
_currentParam = 0;
_initialized = false;
}

View File

@ -1,4 +1,4 @@
//this file is part of notepad++
//this file is part of Notepad++
//Copyright (C)2008 Harry Bruin <harrybharry@users.sourceforge.net>
//
//This program is free software; you can redistribute it and/or
@ -20,30 +20,36 @@
#include "ScintillaEditView.h"
typedef std::vector<const char *> stringVec;
class FunctionCallTip {
friend class AutoCompletion;
public:
FunctionCallTip() : _pEditView(NULL), _langName(NULL), _currentOverloads(NULL), _funcName(NULL), _params(NULL), _initialized(false),
_start('('), _stop(')'), _param(','), _terminal(';') {};
FunctionCallTip(ScintillaEditView * pEditView) : _pEditView(pEditView), _pXmlKeyword(NULL), _curPos(0), _startPos(0),
_curFunction(NULL), _currentNrOverloads(0), _currentOverload(0),
_currentParam(0), _funcName(NULL),
_start('('), _stop(')'), _param(','), _terminal(';')
{};
~FunctionCallTip() {/* cleanup(); */};
void initCalltip(ScintillaEditView * editView, const char * language); //show the calltip
void updateCalltip(int ch, bool needShown = false); //Ch is character typed, or 0 if another event occured. NeedShown is true if calltip should be attempted to displayed
void showNextOverload();
void showPrevOverload();
bool isVisible() { return _pEditView?_pEditView->execute(SCI_CALLTIPACTIVE) == TRUE:false; };
void setLanguageXML(TiXmlElement * pXmlKeyword); //set calltip keyword node
bool updateCalltip(int ch, bool needShown = false); //Ch is character typed, or 0 if another event occured. NeedShown is true if calltip should be attempted to displayed. Return true if calltip was made visible
void showNextOverload(); //show next overlaoded parameters
void showPrevOverload(); //show prev overlaoded parameters
bool isVisible() { return _pEditView?_pEditView->execute(SCI_CALLTIPACTIVE) == TRUE:false; }; //true if calltip visible
void close(); //Close calltip if visible
private:
char * _langName; //current language
ScintillaEditView * _pEditView; //Scintilla to display calltip in
bool _initialized;
TiXmlElement * _pXmlKeyword; //current keyword node (first one)
int _curPos; //cursor position
int _startPos; //display start position
char * _funcName; //current name of function
char ** _currentOverloads; //pointer to list of strings each containing possible overload
vector<int> * _params; //array of vectors with offsets found for params
TiXmlElement * _curFunction; //current function element
//cache some XML values n stuff
const char * _funcName; //name of function
stringVec _retVals; //vector of overload return values/types
vector<stringVec> _overloads; //vector of overload params (=vector)
int _currentNrOverloads; //current amount of overloads
int _currentOverload; //current chosen overload
int _currentParam; //current highlighted param
@ -54,9 +60,10 @@ private:
char _terminal;
bool getCursorFunction(); //retrieve data about function at cursor. Returns true if a function was found. Calls loaddata if needed
bool loadData(); //returns true if the function can be found
bool loadFunction(const char * nameToFind); //returns true if the function can be found
void showCalltip(); //display calltip based on current variables
void reset(); //reset all vars in case function is invalidated
void cleanup(); //delete any leftovers
};
#endif// FUNCTIONCALLTIP_H

View File

@ -54,6 +54,61 @@ const int ScintillaEditView::_markersArray[][NB_FOLDER_STATE] = {
{SC_MARK_BOXMINUS, SC_MARK_BOXPLUS, SC_MARK_VLINE, SC_MARK_LCORNER, SC_MARK_BOXPLUSCONNECTED, SC_MARK_BOXMINUSCONNECTED, SC_MARK_TCORNER}
};
//Array with all the names of all languages
LanguageName ScintillaEditView::langNames[L_EXTERNAL+1] = {
{"normal", "Normal text", "Normal text file", L_TXT},
{"php", "PHP", "PHP Hypertext Preprocessor file", L_PHP},
{"c", "C", "C source file", L_C},
{"cpp", "C++", "C++ source file", L_CPP},
{"cs", "C#", "C# source file", L_CS},
{"objc", "Objective-C", "Objective-C source file", L_OBJC},
{"java", "Java", "Java source file", L_JAVA},
{"rc", "RC", "Windows Resource file", L_RC},
{"html", "HTML", "Hyper Text Markup Language file", L_HTML},
{"xml", "XML", "eXtensible Markup Language file", L_XML},
{"makefile", "Makefile", "Makefile", L_MAKEFILE},
{"pascal", "Pascal", "Pascal source file", L_PASCAL},
{"batch", "Batch", "Batch file", L_BATCH},
{"ini", "ini", "MS ini file", L_INI},
{"nfo", "NFO", "MSDOS Style/ASCII Art", L_NFO},
{"udf", "udf", "User Define File", L_USER},
{"asp", "ASP", "Active Server Pages script file", L_ASP},
{"sql", "SQL", "Structured Query Language file", L_SQL},
{"vb", "VB", "Visual Basic file", L_VB},
{"javascript", "JavaScript", "JavaScript file", L_JS},
{"css", "CSS", "Cascade Style Sheets File", L_CSS},
{"perl", "Perl", "Perl source file", L_PERL},
{"python", "Python", "Python file", L_PYTHON},
{"lua", "Lua", "Lua source File", L_LUA},
{"tex", "TeX", "TeX file", L_TEX},
{"fortran", "Fortran", "Fortran source file", L_FORTRAN},
{"bash", "Shell", "Unix script file", L_BASH},
{"actionscript","Flash Action", "Flash Action script file", L_FLASH}, //WARNING, was "flash"
{"nsis", "NSIS", "Nullsoft Scriptable Install System script file", L_NSIS},
{"tcl", "TCL", "Tool Command Language file", L_TCL},
{"lisp", "Lisp", "List Processing language file", L_LISP},
{"scheme", "Scheme", "Scheme file", L_SCHEME},
{"asm", "Assembly", "Assembly language source file", L_ASM},
{"diff", "Diff", "Diff file", L_DIFF},
{"props", "Properties file", "Properties file", L_PROPS},
{"postscript", "Postscript", "Postscript file", L_PS},
{"ruby", "Ruby", "Ruby file", L_RUBY},
{"smalltalk", "Smalltalk", "Smalltalk file", L_SMALLTALK},
{"vhdl", "VHDL", "VHSIC Hardware Description Language file", L_VHDL},
{"kix", "KiXtart", "KiXtart file", L_KIX},
{"autoit", "AutoIt", "AutoIt", L_AU3},
{"caml", "CAML", "Categorical Abstract Machine Language", L_CAML},
{"ada", "Ada", "Ada file", L_ADA},
{"verilog", "Verilog", "Verilog file", L_VERILOG},
{"matlab", "MATLAB", "MATrix LABoratory", L_MATLAB},
{"haskell", "Haskell", "Haskell", L_HASKELL},
{"inno", "Inno", "Inno Setup script", L_INNO},
{"searchResult","Internal Search", "Internal Search", L_SEARCHRESULT},
{"cmake", "CMAKEFILE", "CMAKEFILE", L_CMAKE},
{"yaml", "YAML", "YAML Ain't Markup Language", L_YAML},
{"ext", "External", "External", L_EXTERNAL}
};
//const int MASK_RED = 0xFF0000;
//const int MASK_GREEN = 0x00FF00;
//const int MASK_BLUE = 0x0000FF;
@ -297,7 +352,7 @@ void ScintillaEditView::setXmlLexer(LangType type)
for (int i = 0 ; i < 4 ; i++)
execute(SCI_SETKEYWORDS, i, reinterpret_cast<LPARAM>(""));
makeStyle("xml");
makeStyle(type);
}
else if ((type == L_HTML) || (type == L_PHP) || (type == L_ASP))
{
@ -307,7 +362,7 @@ void ScintillaEditView::setXmlLexer(LangType type)
const char *htmlKeyWords =_pParameter->getWordList(L_HTML, LANG_INDEX_INSTR);
execute(SCI_SETKEYWORDS, 0, reinterpret_cast<LPARAM>(htmlKeyWords?htmlKeyWords:""));
makeStyle("html");
makeStyle(type);
setEmbeddedJSLexer();
setPhpEmbeddedLexer();
@ -318,7 +373,7 @@ void ScintillaEditView::setXmlLexer(LangType type)
void ScintillaEditView::setEmbeddedJSLexer()
{
const char *pKwArray[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
makeStyle("javascript", pKwArray);
makeStyle(L_JS, pKwArray);
std::string keywordList("");
if (pKwArray[LANG_INDEX_INSTR])
@ -334,7 +389,7 @@ void ScintillaEditView::setEmbeddedJSLexer()
void ScintillaEditView::setPhpEmbeddedLexer()
{
const char *pKwArray[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
makeStyle("php", pKwArray);
makeStyle(L_PHP, pKwArray);
std::string keywordList("");
if (pKwArray[LANG_INDEX_INSTR])
@ -349,7 +404,7 @@ void ScintillaEditView::setPhpEmbeddedLexer()
void ScintillaEditView::setEmbeddedAspLexer()
{
const char *pKwArray[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
makeStyle("asp", pKwArray);
makeStyle(L_ASP, pKwArray);
std::string keywordList("");
if (pKwArray[LANG_INDEX_INSTR])
@ -360,36 +415,11 @@ void ScintillaEditView::setEmbeddedAspLexer()
execute(SCI_STYLESETEOLFILLED, SCE_HBA_DEFAULT, true);
}
void ScintillaEditView::setUserLexer()
{
execute(SCI_SETLEXER, SCLEX_USER);
UserLangContainer & userLangContainer = *(_userDefineDlg._pCurrentUserLang);
execute(SCI_SETPROPERTY, (WPARAM)"userDefine.ignoreCase", (LPARAM)(userLangContainer._isCaseIgnored?"1":"0"));
execute(SCI_SETPROPERTY, (WPARAM)"userDefine.commentLineSymbol", (LPARAM)(userLangContainer._isCommentLineSymbol?"1":"0"));
execute(SCI_SETPROPERTY, (WPARAM)"userDefine.commentSymbol", (LPARAM)(userLangContainer._isCommentSymbol?"1":"0"));
const char strArray[4][20] = {"userDefine.g1Prefix", "userDefine.g2Prefix", "userDefine.g3Prefix", "userDefine.g4Prefix"};
for (int i = 0 ; i < 4 ; i++)
execute(SCI_SETPROPERTY, (WPARAM)strArray[i], (LPARAM)(userLangContainer._isPrefix[i]?"1":"0"));
for (int i = 0 ; i < userLangContainer.getNbKeywordList() ; i++)
{
execute(SCI_SETKEYWORDS, i, reinterpret_cast<LPARAM>(userLangContainer._keywordLists[i]));
}
for (int i = 0 ; i < userLangContainer._styleArray.getNbStyler() ; i++)
{
Style & style = userLangContainer._styleArray.getStyler(i);
setStyle(style);
}
}
void ScintillaEditView::setUserLexer(const char *userLangName)
{
execute(SCI_SETLEXER, SCLEX_USER);
UserLangContainer & userLangContainer = NppParameters::getInstance()->getULCFromName(userLangName);
UserLangContainer & userLangContainer = userLangName?NppParameters::getInstance()->getULCFromName(userLangName):*(_userDefineDlg._pCurrentUserLang);
execute(SCI_SETPROPERTY, (WPARAM)"userDefine.ignoreCase", (LPARAM)(userLangContainer._isCaseIgnored?"1":"0"));
execute(SCI_SETPROPERTY, (WPARAM)"userDefine.commentLineSymbol", (LPARAM)(userLangContainer._isCommentLineSymbol?"1":"0"));
execute(SCI_SETPROPERTY, (WPARAM)"userDefine.commentSymbol", (LPARAM)(userLangContainer._isCommentSymbol?"1":"0"));
@ -443,7 +473,8 @@ void ScintillaEditView::setCppLexer(LangType langType)
const char *cppTypes;
const char *doxygenKeyWords = _pParameter->getWordList(L_CPP, LANG_INDEX_TYPE2);
char *lexerName;
const char *lexerName = ScintillaEditView::langNames[langType].lexerName;
/*char *lexerName;
switch (langType)
{
case L_C:
@ -469,7 +500,7 @@ void ScintillaEditView::setCppLexer(LangType langType)
default:
return;
}
}*/
execute(SCI_SETLEXER, SCLEX_CPP);
if (isCJK())
@ -487,7 +518,7 @@ void ScintillaEditView::setCppLexer(LangType langType)
if (langType == L_JS)
{
LexerStyler *pStyler = (_pParameter->getLStylerArray()).getLexerStylerByName("javascript");
LexerStyler *pStyler = (_pParameter->getLStylerArray()).getLexerStylerByName(lexerName);
if (pStyler)
{
for (int i = 0 ; i < pStyler->getNbStyler() ; i++)
@ -519,7 +550,7 @@ void ScintillaEditView::setCppLexer(LangType langType)
}
const char *pKwArray[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
makeStyle(lexerName, pKwArray);
makeStyle(langType, pKwArray);
std::string instr1("");
if (pKwArray[LANG_INDEX_INSTR])
@ -544,11 +575,11 @@ void ScintillaEditView::setObjCLexer(LangType langType)
const char *pKwArray[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
const char *lexerName = "objc";
if (langType == L_FLASH)
lexerName = "actionscript";
//const char *lexerName = "objc";
//if (langType == L_FLASH)
// lexerName = "actionscript";
makeStyle(lexerName, pKwArray);
makeStyle(langType, pKwArray);
std::string objcInstr1Kwl("");
if (pKwArray[LANG_INDEX_INSTR])
@ -584,13 +615,13 @@ void ScintillaEditView::setKeywords(LangType langType, const char *keywords, int
execute(SCI_SETKEYWORDS, index, (LPARAM)getCompleteKeywordList(wordList, langType, index));
}
void ScintillaEditView::setLexer(int lexerID, LangType langType, const char *lexerName, int whichList)
void ScintillaEditView::setLexer(int lexerID, LangType langType, int whichList)
{
execute(SCI_SETLEXER, lexerID);
const char *pKwArray[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
makeStyle(lexerName, pKwArray);
makeStyle(langType, pKwArray);
if (whichList & LIST_0)
{
@ -628,6 +659,25 @@ void ScintillaEditView::setLexer(int lexerID, LangType langType, const char *lex
}
}
void ScintillaEditView::makeStyle(LangType language, const char **keywordArray)
{
const char * lexerName = ScintillaEditView::langNames[language].lexerName;
LexerStyler *pStyler = (_pParameter->getLStylerArray()).getLexerStylerByName(lexerName);
if (pStyler)
{
for (int i = 0 ; i < pStyler->getNbStyler() ; i++)
{
Style & style = pStyler->getStyler(i);
setStyle(style);
if (keywordArray)
{
if ((style._keywordClass != -1) && (style._keywords))
keywordArray[style._keywordClass] = style._keywords->c_str();
}
}
}
}
void ScintillaEditView::defineDocType(LangType typeDoc)
{
//setStyle(STYLE_DEFAULT, black, white, "Verdana", 0, 9);
@ -1305,24 +1355,6 @@ void ScintillaEditView::expand(int &line, bool doExpand, bool force, int visLeve
//recalcHorizontalScrollbar(); //Update scrollbar after folding
}
void ScintillaEditView::makeStyle(const char *lexerName, const char **keywordArray)
{
LexerStyler *pStyler = (_pParameter->getLStylerArray()).getLexerStylerByName(lexerName);
if (pStyler)
{
for (int i = 0 ; i < pStyler->getNbStyler() ; i++)
{
Style & style = pStyler->getStyler(i);
setStyle(style);
if (keywordArray)
{
if ((style._keywordClass != -1) && (style._keywords))
keywordArray[style._keywordClass] = style._keywords->c_str();
}
}
}
}
void ScintillaEditView::performGlobalStyles()
{
StyleArray & stylers = _pParameter->getMiscStylerArray();

View File

@ -125,6 +125,13 @@ char * int2str(char *str, int strLen, int number, int base, int nbChiffre, bool
typedef LRESULT (WINAPI *CallWindowProcFunc) (WNDPROC,HWND,UINT,WPARAM,LPARAM);
struct LanguageName {
const char * lexerName;
const char * shortName;
const char * longName;
LangType LangID;
};
class ScintillaEditView : public Window
{
friend class Notepad_plus;
@ -493,8 +500,6 @@ public:
return (execute(SCI_GETCARETLINEVISIBLE) != 0);
};
inline void makeStyle(const char *lexerName, const char **keywordArray = NULL);
void performGlobalStyles();
void expand(int &line, bool doExpand, bool force = false, int visLevels = 0, int level = -1);
@ -618,6 +623,7 @@ public:
execute(SCI_INDICATORCLEARRANGE, docStart, docEnd-docStart);
};
static LanguageName ScintillaEditView::langNames[L_EXTERNAL+1];
protected:
static HINSTANCE _hLib;
static int _refCount;
@ -673,168 +679,168 @@ protected:
bool _wrapRestoreNeeded;
//Lexers and Styling
const char * getCompleteKeywordList(std::string & kwl, LangType langType, int keywordIndex);
void setKeywords(LangType langType, const char *keywords, int index);
void setLexer(int lexerID, LangType langType, int whichList);
inline void makeStyle(LangType langType, const char **keywordArray = NULL);
void setStyle(Style styleToSet); //NOT by reference (style edited)
void setSpecialStyle(Style & styleToSet); //by reference
void setSpecialIndicator(Style & styleToSet);
void setCppLexer(LangType type);
//Complex lexers (same lexer, different language)
void setXmlLexer(LangType type);
void setUserLexer();
void setUserLexer(const char *userLangName);
void setCppLexer(LangType type);
void setObjCLexer(LangType type);
void setUserLexer(const char *userLangName = NULL);
void setExternalLexer(LangType typeDoc);
void setEmbeddedJSLexer();
void setPhpEmbeddedLexer();
void setEmbeddedAspLexer();
//Simple lexers
void setCssLexer() {
setLexer(SCLEX_CSS, L_CSS, "css", LIST_0 | LIST_1);
setLexer(SCLEX_CSS, L_CSS, LIST_0 | LIST_1);
};
void setLuaLexer() {
setLexer(SCLEX_LUA, L_LUA, "lua", LIST_0 | LIST_1 | LIST_2 | LIST_3);
setLexer(SCLEX_LUA, L_LUA, LIST_0 | LIST_1 | LIST_2 | LIST_3);
};
void setMakefileLexer() {
execute(SCI_SETLEXER, SCLEX_MAKEFILE);
makeStyle("makefile");
makeStyle(L_MAKEFILE);
};
void setIniLexer() {
execute(SCI_SETLEXER, SCLEX_PROPERTIES);
execute(SCI_STYLESETEOLFILLED, SCE_PROPS_SECTION, true);
makeStyle("ini");
makeStyle(L_INI);
};
void setObjCLexer(LangType type);
void setSqlLexer() {
setLexer(SCLEX_SQL, L_SQL, "sql", LIST_0);
setLexer(SCLEX_SQL, L_SQL, LIST_0);
};
void setBashLexer() {
setLexer(SCLEX_BASH, L_BASH, "bash", LIST_0);
setLexer(SCLEX_BASH, L_BASH, LIST_0);
};
void setVBLexer() {
setLexer(SCLEX_VB, L_VB, "vb", LIST_0);
setLexer(SCLEX_VB, L_VB, LIST_0);
};
void setPascalLexer() {
setLexer(SCLEX_PASCAL, L_PASCAL, "pascal", LIST_0);
setLexer(SCLEX_PASCAL, L_PASCAL, LIST_0);
};
void setPerlLexer() {
setLexer(SCLEX_PERL, L_PERL, "perl", LIST_0);
setLexer(SCLEX_PERL, L_PERL, LIST_0);
};
void setPythonLexer() {
setLexer(SCLEX_PYTHON, L_PYTHON, "python", LIST_0);
setLexer(SCLEX_PYTHON, L_PYTHON, LIST_0);
};
void setBatchLexer() {
setLexer(SCLEX_BATCH, L_BATCH, "batch", LIST_0);
setLexer(SCLEX_BATCH, L_BATCH, LIST_0);
};
void setTeXLexer() {
for (int i = 0 ; i < 4 ; i++)
execute(SCI_SETKEYWORDS, i, reinterpret_cast<LPARAM>(""));
setLexer(SCLEX_TEX, L_TEX, "tex", 0);
setLexer(SCLEX_TEX, L_TEX, 0);
};
void setNsisLexer() {
setLexer(SCLEX_NSIS, L_NSIS, "nsis", LIST_0 | LIST_1 | LIST_2 | LIST_3);
setLexer(SCLEX_NSIS, L_NSIS, LIST_0 | LIST_1 | LIST_2 | LIST_3);
};
void setFortranLexer() {
setLexer(SCLEX_F77, L_FORTRAN, "fortran", LIST_0 | LIST_1 | LIST_2);
setLexer(SCLEX_F77, L_FORTRAN, LIST_0 | LIST_1 | LIST_2);
};
void setLispLexer(){
setLexer(SCLEX_LISP, L_LISP, "lisp", LIST_0);
setLexer(SCLEX_LISP, L_LISP, LIST_0);
};
void setSchemeLexer(){
setLexer(SCLEX_LISP, L_SCHEME, "lisp", LIST_0);
setLexer(SCLEX_LISP, L_SCHEME, LIST_0);
};
void setAsmLexer(){
setLexer(SCLEX_ASM, L_ASM, "asm", LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5);
setLexer(SCLEX_ASM, L_ASM, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5);
};
void setDiffLexer(){
setLexer(SCLEX_DIFF, L_DIFF, "diff", LIST_NONE);
setLexer(SCLEX_DIFF, L_DIFF, LIST_NONE);
};
void setPropsLexer(){
setLexer(SCLEX_PROPERTIES, L_PROPS, "props", LIST_NONE);
setLexer(SCLEX_PROPERTIES, L_PROPS, LIST_NONE);
};
void setPostscriptLexer(){
setLexer(SCLEX_PS, L_PS, "postscript", LIST_0 | LIST_1 | LIST_2 | LIST_3);
setLexer(SCLEX_PS, L_PS, LIST_0 | LIST_1 | LIST_2 | LIST_3);
};
void setRubyLexer(){
setLexer(SCLEX_RUBY, L_RUBY, "ruby", LIST_0);
setLexer(SCLEX_RUBY, L_RUBY, LIST_0);
execute(SCI_STYLESETEOLFILLED, SCE_RB_POD, true);
};
void setSmalltalkLexer(){
setLexer(SCLEX_SMALLTALK, L_SMALLTALK, "smalltalk", LIST_0);
setLexer(SCLEX_SMALLTALK, L_SMALLTALK, LIST_0);
};
void setVhdlLexer(){
setLexer(SCLEX_VHDL, L_VHDL, "vhdl", LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5 | LIST_6);
setLexer(SCLEX_VHDL, L_VHDL, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5 | LIST_6);
};
void setKixLexer(){
setLexer(SCLEX_KIX, L_KIX, "kix", LIST_0 | LIST_1 | LIST_2);
setLexer(SCLEX_KIX, L_KIX, LIST_0 | LIST_1 | LIST_2);
};
void setAutoItLexer(){
setLexer(SCLEX_AU3, L_AU3, "autoit", LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5 | LIST_6);
setLexer(SCLEX_AU3, L_AU3, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5 | LIST_6);
};
void setCamlLexer(){
setLexer(SCLEX_CAML, L_CAML, "caml", LIST_0 | LIST_1 | LIST_2);
setLexer(SCLEX_CAML, L_CAML, LIST_0 | LIST_1 | LIST_2);
};
void setAdaLexer(){
setLexer(SCLEX_ADA, L_ADA, "ada", LIST_0);
setLexer(SCLEX_ADA, L_ADA, LIST_0);
};
void setVerilogLexer(){
setLexer(SCLEX_VERILOG, L_VERILOG, "verilog", LIST_0 | LIST_1);
setLexer(SCLEX_VERILOG, L_VERILOG, LIST_0 | LIST_1);
};
void setMatlabLexer(){
setLexer(SCLEX_MATLAB, L_MATLAB, "matlab", LIST_0);
setLexer(SCLEX_MATLAB, L_MATLAB, LIST_0);
};
void setHaskellLexer(){
setLexer(SCLEX_HASKELL, L_HASKELL, "haskell", LIST_0);
setLexer(SCLEX_HASKELL, L_HASKELL, LIST_0);
};
void setInnoLexer() {
setLexer(SCLEX_INNOSETUP, L_INNO, "inno", LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5);
setLexer(SCLEX_INNOSETUP, L_INNO, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5);
};
void setCmakeLexer() {
setLexer(SCLEX_CMAKE, L_CMAKE, "cmake", LIST_0 | LIST_1 | LIST_2);
setLexer(SCLEX_CMAKE, L_CMAKE, LIST_0 | LIST_1 | LIST_2);
};
void setYamlLexer() {
setLexer(SCLEX_YAML, L_YAML, "yaml", LIST_0);
setLexer(SCLEX_YAML, L_YAML, LIST_0);
};
void setSearchResultLexer() {
execute(SCI_STYLESETEOLFILLED, SCE_SEARCHRESULT_HEARDER, true);
setLexer(SCLEX_SEARCHRESULT, L_SEARCHRESULT, "searchResult", LIST_1 | LIST_2 | LIST_3);
setLexer(SCLEX_SEARCHRESULT, L_SEARCHRESULT, LIST_1 | LIST_2 | LIST_3);
};
void defineMarker(int marker, int markerType, COLORREF fore, COLORREF back) {
execute(SCI_MARKERDEFINE, marker, markerType);
execute(SCI_MARKERSETFORE, marker, fore);
execute(SCI_MARKERSETBACK, marker, back);
};
bool isNeededFolderMarge(LangType typeDoc) const {
switch (typeDoc)
{
@ -855,6 +861,14 @@ protected:
return true;
}
};
//END: Lexers and Styling
void defineMarker(int marker, int markerType, COLORREF fore, COLORREF back) {
execute(SCI_MARKERDEFINE, marker, markerType);
execute(SCI_MARKERSETFORE, marker, fore);
execute(SCI_MARKERSETBACK, marker, back);
};
bool isCJK() const {
return ((_codepage == CP_CHINESE_TRADITIONAL) || (_codepage == CP_CHINESE_SIMPLIFIED) ||
(_codepage == CP_JAPANESE) || (_codepage == CP_KOREAN) || (_codepage == CP_GREEK));
@ -871,10 +885,6 @@ protected:
default : return 0;
}
};
const char * getCompleteKeywordList(std::string & kwl, LangType langType, int keywordIndex);
void setKeywords(LangType langType, const char *keywords, int index);
void setLexer(int lexerID, LangType langType, const char *lexerName, int whichList);
bool expandWordSelection();
void arrangeBuffers(UINT nItems, UINT *items);

View File

@ -19,9 +19,8 @@
#include "SysMsg.h"
#include "Process.h"
#include <exception>
//const char localConfFile[] = "doLocalConf.xml";
#include <exception> //default C++ esception
#include "Win32Exception.h" //Win32 exception
typedef std::vector<const char*> ParamVector;
void parseCommandLine(char * commandLine, ParamVector & paramVector) {
@ -101,6 +100,8 @@ const char FLAG_READONLY[] = "-ro";
const char FLAG_NOSESSION[] = "-nosession";
const char FLAG_NOTABBAR[] = "-notabbar";
void doException(Notepad_plus & notepad_plus_plus);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpszCmdLine, int nCmdShow)
{
bool TheFirstOne = true;
@ -225,6 +226,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpszCmdLine, int nCmdSh
MSG msg;
msg.wParam = 0;
Win32Exception::installHandler();
try {
notepad_plus_plus.init(hInstance, NULL, quotFileName.c_str(), &cmdLineParams);
@ -240,31 +242,48 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpszCmdLine, int nCmdSh
{
if (::TranslateAccelerator(notepad_plus_plus.getHSelf(), notepad_plus_plus.getAccTable(), &msg) == 0)
{
try {
::TranslateMessage(&msg);
if (unicodeSupported)
::DispatchMessageW(&msg);
else
::DispatchMessage(&msg);
} catch(std::exception ex) {
::MessageBox(NULL, ex.what(), "Exception", MB_OK);
} catch(...) {
systemMessage("System Error");
}
::TranslateMessage(&msg);
if (unicodeSupported)
::DispatchMessageW(&msg);
else
::DispatchMessage(&msg);
}
}
}
}
} catch(int i) {
if (i == 106901)
::MessageBox(NULL, "Scintilla.init is failed!", "106901", MB_OK);
::MessageBox(NULL, "Scintilla.init is failed!", "Notepad++ Exception: 106901", MB_OK);
else {
char str[50] = "God Damned Exception : ";
char code[10];
itoa(i, code, 10);
::MessageBox(NULL, strcat(str, code), "int exception", MB_OK);
::MessageBox(NULL, strcat(str, code), "Notepad++ Exception", MB_OK);
}
doException(notepad_plus_plus);
} catch(std::exception ex) {
::MessageBox(NULL, ex.what(), "C++ Exception", MB_OK);
doException(notepad_plus_plus);
} catch (const Win32Exception & ex) {
char message[1024]; //TODO: sane number
sprintf(message, "An exception occured. Notepad++ cannot recover and must be shut down.\r\nThe exception details are as follows:\r\n"
"Code:\t0x%08X\r\nType:\t%s\r\nException address: 0x%08X"
"\r\n\r\nNotepad++ will attempt to save any unsaved data. However, dataloss is very likely.",
ex.code(), ex.what(), ex.where());
::MessageBox(NULL, message, "Win32Exception", MB_OK | MB_ICONERROR);
doException(notepad_plus_plus);
} catch(...) { //this shouldnt ever have to happen
doException(notepad_plus_plus);
}
return (UINT)msg.wParam;
}
void doException(Notepad_plus & notepad_plus_plus) {
::MessageBox(NULL, "Notepad++ will attempt to save any unsaved data. However, dataloss is very likely.", "Recovery initiating", MB_OK | MB_ICONINFORMATION);
bool res = notepad_plus_plus.emergency();
if (res) {
::MessageBox(NULL, "Notepad++ was able to successfully recover some unsaved documents, or nothing to be saved could be found.\r\nYou can find the results at C:\\N++RECOV", "Recovery success", MB_OK | MB_ICONINFORMATION);
} else {
::MessageBox(NULL, "Unfortunatly, Notepad++ was not able to save your work. We are sorry for any lost data.", "Recovery failure", MB_OK | MB_ICONERROR);
}
}

View File

@ -19,10 +19,12 @@
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/EHa"
Optimization="0"
AdditionalIncludeDirectories="..\src\WinControls\AboutDlg;..\..\scintilla\include;..\include;..\src\WinControls;..\src\WinControls\ImageListSet;..\src\WinControls\OpenSaveFileDialog;..\src\WinControls\SplitterContainer;..\src\WinControls\StaticDialog;..\src\WinControls\TabBar;..\src\WinControls\ToolBar;..\src\MISC\Process;..\src\ScitillaComponent;..\src\MISC;..\src\MISC\SysMsg;..\src\WinControls\StatusBar;..\src;..\src\WinControls\StaticDialog\RunDlg;..\src\tinyxml;..\src\WinControls\ColourPicker;..\src\MISC\RegExt;..\src\WinControls\TrayIcon;..\src\WinControls\shortcut;..\src\WinControls\Grid;..\src\WinControls\ContextMenu;..\src\MISC\PluginsManager;..\src\WinControls\Preference;..\src\WinControls\WindowsDlg;..\src\WinControls\TaskList;..\src\WinControls\DockingWnd;..\src\WinControls\ToolTip"
AdditionalIncludeDirectories="..\src\WinControls\AboutDlg;..\..\scintilla\include;..\include;..\src\WinControls;..\src\WinControls\ImageListSet;..\src\WinControls\OpenSaveFileDialog;..\src\WinControls\SplitterContainer;..\src\WinControls\StaticDialog;..\src\WinControls\TabBar;..\src\WinControls\ToolBar;..\src\MISC\Process;..\src\ScitillaComponent;..\src\MISC;..\src\MISC\SysMsg;..\src\WinControls\StatusBar;..\src;..\src\WinControls\StaticDialog\RunDlg;..\src\tinyxml;..\src\WinControls\ColourPicker;..\src\MISC\RegExt;..\src\WinControls\TrayIcon;..\src\WinControls\shortcut;..\src\WinControls\Grid;..\src\WinControls\ContextMenu;..\src\MISC\PluginsManager;..\src\WinControls\Preference;..\src\WinControls\WindowsDlg;..\src\WinControls\TaskList;..\src\WinControls\DockingWnd;..\src\WinControls\ToolTip;..\src\MISC\Exception"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="TRUE"
ExceptionHandling="FALSE"
BasicRuntimeChecks="0"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
@ -188,10 +190,16 @@ IF NOT EXIST ..\bin\userDefineLang.xml COPY ..\src\userDefineLang.xml ..\bin\use
<File
RelativePath="..\src\MISC\SysMsg\SysMsg.cpp">
</File>
<File
RelativePath="..\src\Misc\Exception\Win32Exception.cpp">
</File>
</Filter>
<Filter
Name="ScintillaComponent"
Filter="">
<File
RelativePath="..\src\ScitillaComponent\AutoCompletion.cpp">
</File>
<File
RelativePath="..\src\ScitillaComponent\Buffer.cpp">
</File>
@ -204,6 +212,9 @@ IF NOT EXIST ..\bin\userDefineLang.xml COPY ..\src\userDefineLang.xml ..\bin\use
<File
RelativePath="..\src\ScitillaComponent\FindReplaceDlg.cpp">
</File>
<File
RelativePath="..\src\ScitillaComponent\FunctionCallTip.cpp">
</File>
<File
RelativePath="..\src\ScitillaComponent\GoToLineDlg.cpp">
</File>
@ -397,10 +408,16 @@ IF NOT EXIST ..\bin\userDefineLang.xml COPY ..\src\userDefineLang.xml ..\bin\use
<File
RelativePath="..\src\MISC\SysMsg\SysMsg.h">
</File>
<File
RelativePath="..\src\Misc\Exception\Win32Exception.h">
</File>
</Filter>
<Filter
Name="ScintillaComponent"
Filter="">
<File
RelativePath="..\src\ScitillaComponent\AutoCompletion.h">
</File>
<File
RelativePath="..\src\ScitillaComponent\Buffer.h">
</File>
@ -416,6 +433,9 @@ IF NOT EXIST ..\bin\userDefineLang.xml COPY ..\src\userDefineLang.xml ..\bin\use
<File
RelativePath="..\src\ScitillaComponent\FindReplaceDlg.h">
</File>
<File
RelativePath="..\src\ScitillaComponent\FunctionCallTip.h">
</File>
<File
RelativePath="..\src\ScitillaComponent\GoToLineDlg.h">
</File>
@ -871,4 +891,6 @@ IF NOT EXIST ..\bin\userDefineLang.xml COPY ..\src\userDefineLang.xml ..\bin\use
</Filter>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>