diff --git a/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h b/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h index d1e03a8a..124492e1 100644 --- a/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h +++ b/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h @@ -27,7 +27,7 @@ enum LangType {L_TXT, L_PHP , L_C, L_CPP, L_CS, L_OBJC, L_JAVA, L_RC,\ L_ASM, L_DIFF, L_PROPS, L_PS, L_RUBY, L_SMALLTALK, L_VHDL, L_KIX, L_AU3,\ L_CAML, L_ADA, L_VERILOG, L_MATLAB, L_HASKELL, L_INNO, L_SEARCHRESULT, L_CMAKE,\ // The end of enumated language type, so it should be always at the end - L_END}; + L_EXTERNAL}; enum winVer{WV_UNKNOWN, WV_WIN32S, WV_95, WV_98, WV_ME, WV_NT, WV_W2K, WV_XP, WV_S2003, WV_XPX64, WV_VISTA}; diff --git a/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp b/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp index 72f3dd7a..d086af71 100644 --- a/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp +++ b/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp @@ -93,16 +93,81 @@ bool PluginsManager::loadPlugins(const char *dir) getCustomizedShortcuts(pi->_moduleName, pi->_funcItems, pi->_nbFuncItem); - for (int i = 0 ; i < pi->_nbFuncItem ; i++) - if (!pi->_funcItems[i]._pFunc) + for (int c = 0 ; c < pi->_nbFuncItem ; c++) + if (!pi->_funcItems[c]._pFunc) throw string("\"FuncItems\" array is not set correctly"); pi->_pluginMenu = ::CreateMenu(); pi->_pFuncSetInfo(_nppData); + + GetLexerCountFn GetLexerCount = (GetLexerCountFn)::GetProcAddress(pi->_hLib, "GetLexerCount"); + // it's a lexer plugin + if (GetLexerCount) + { + GetLexerNameFn GetLexerName = (GetLexerNameFn)::GetProcAddress(pi->_hLib, "GetLexerName"); + if (!GetLexerName) + throw string("Loading GetLexerName function failed."); + + GetLexerStatusTextFn GetLexerStatusText = (GetLexerStatusTextFn)::GetProcAddress(pi->_hLib, "GetLexerStatusText"); + + if (!GetLexerStatusText) + throw string("Loading GetLexerStatusText function failed."); + + // Assign a buffer for the lexer name. + char lexName[MAX_EXTERNAL_LEXER_NAME_LEN]; + strcpy(lexName, ""); + char lexDesc[MAX_EXTERNAL_LEXER_DESC_LEN]; + strcpy(lexDesc, ""); + + int numLexers = GetLexerCount(); + + NppParameters * nppParams = NppParameters::getInstance(); + + ExternalLangContainer *containers[30]; + for (int x = 0; x < numLexers; x++) + { + GetLexerName(x, lexName, MAX_EXTERNAL_LEXER_NAME_LEN); + GetLexerStatusText(x, lexDesc, MAX_EXTERNAL_LEXER_DESC_LEN); + + if (!nppParams->isExistingExternalLangName(lexName) && nppParams->ExternalLangHasRoom()) + containers[x] = new ExternalLangContainer(lexName, lexDesc); + else + containers[x] = NULL; + } + + char xmlPath[MAX_PATH]; + strcpy(xmlPath, nppParams->getAppDataNppDir()); + PathAppend(xmlPath, "plugins\\Config"); + PathAppend(xmlPath, pi->_moduleName); + PathRemoveExtension(xmlPath); + PathAddExtension(xmlPath, ".xml"); + + if (!PathFileExists(xmlPath)) + { + throw string(string(xmlPath) + " is missing."); + } + + TiXmlDocument *_pXmlDoc = new TiXmlDocument(xmlPath); + + if (!_pXmlDoc->LoadFile()) + { + delete _pXmlDoc; + _pXmlDoc = NULL; + throw string(string(xmlPath) + " failed to load."); + } + + for (int x = 0; x < numLexers; x++) // postpone adding in case the xml is missing/corrupt + if (containers[x] != NULL) + nppParams->addExternalLangToEnd(containers[x]); + + nppParams->getExternalLexerFromXmlTree(_pXmlDoc); + nppParams->getExternalLexerDoc()->push_back(_pXmlDoc); + + ::SendMessage(_nppData._scintillaMainHandle, SCI_LOADLEXERLIBRARY, 0, (LPARAM)dllNames[i].c_str()); + } _pluginInfos.push_back(pi); - } catch(string s) { diff --git a/PowerEditor/src/MISC/PluginsManager/PluginsManager.h b/PowerEditor/src/MISC/PluginsManager/PluginsManager.h index 0c72e3aa..7c828007 100644 --- a/PowerEditor/src/MISC/PluginsManager/PluginsManager.h +++ b/PowerEditor/src/MISC/PluginsManager/PluginsManager.h @@ -157,4 +157,11 @@ private: bool hasPlugins(){return (_pluginInfos.size()!= 0);}; }; +#define EXT_LEXER_DECL __stdcall + +// External Lexer function definitions... +typedef int (EXT_LEXER_DECL *GetLexerCountFn)(); +typedef void (EXT_LEXER_DECL *GetLexerNameFn)(unsigned int Index, char *name, int buflength); +typedef void (EXT_LEXER_DECL *GetLexerStatusTextFn)(unsigned int Index, char *desc, int buflength); + #endif //PLUGINSMANAGER_H diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 625b51a6..0d7efff6 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -1332,6 +1332,16 @@ void Notepad_plus::checkLangsMenu(int id) const string Notepad_plus::getLangDesc(LangType langType, bool shortDesc) { + + if ((langType >= L_EXTERNAL) && (langType < NppParameters::getInstance()->L_END)) + { + ExternalLangContainer & elc = NppParameters::getInstance()->getELCFromIndex(langType - L_EXTERNAL); + if (shortDesc) + return string(elc._name); + else + return string(elc._desc); + } + static const int maxChar = 64; static char langDescArray[][maxChar] = { "Normal text", "Normal text file", @@ -1511,8 +1521,10 @@ void Notepad_plus::getApiFileName(LangType langType, string &fn) break; } default: - fn = "text"; - + if (langType >= L_EXTERNAL && langType < NppParameters::getInstance()->L_END) + fn = NppParameters::getInstance()->getELCFromIndex(langType - L_EXTERNAL)._name; + else + fn = "text"; } } @@ -3707,6 +3719,10 @@ void Notepad_plus::command(int id) setLangStatus(L_USER); checkLangsMenu(id); } + else if ((id >= IDM_LANG_EXTERNAL) && (id <= IDM_LANG_EXTERNAL_LIMIT)) + { + setLanguage(id, (LangType)(id - IDM_LANG_EXTERNAL + L_EXTERNAL)); + } else if ((id >= ID_MACRO) && (id < ID_MACRO_LIMIT)) { int i = id - ID_MACRO; @@ -5757,32 +5773,6 @@ LRESULT Notepad_plus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa _pTrayIco = new trayIconControler(_hSelf, IDI_M30ICON, IDC_MINIMIZED_TRAY, ::LoadIcon(_hInst, MAKEINTRESOURCE(IDI_M30ICON)), ""); checkSyncState(); - - - //Languages Menu - hMenu = ::GetSubMenu(::GetMenu(_hSelf), MENUINDEX_LANGUAGE); - if (nppGUI._excludedLangList.size() > 0) - { - for (size_t i = 0 ; i < nppGUI._excludedLangList.size() ; i++) - { - int cmdID = pNppParam->langTypeToCommandID(nppGUI._excludedLangList[i]._langType); - char itemName[256]; - ::GetMenuString(hMenu, cmdID, itemName, sizeof(itemName), MF_BYCOMMAND); - nppGUI._excludedLangList[i]._cmdID = cmdID; - nppGUI._excludedLangList[i]._langName = itemName; - ::DeleteMenu(hMenu, cmdID, MF_BYCOMMAND); - DrawMenuBar(_hSelf); - } - } - - // Add User Define Languages Entry - pos = ::GetMenuItemCount(hMenu) - 1; - - for (int i = 0 ; i < pNppParam->getNbUserLang() ; i++) - { - UserLangContainer & userLangContainer = pNppParam->getULCFromIndex(i); - ::InsertMenu(hMenu, pos + i , MF_BYPOSITION, IDM_LANG_USER + i + 1, userLangContainer.getName()); - } // Macro Menu std::vector & macros = pNppParam->getMacroList(); @@ -5847,6 +5837,51 @@ LRESULT Notepad_plus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa _isCmdScModified = true; pNppParam->setAccelerator(&_accelerator); + + + //Languages Menu + hMenu = ::GetSubMenu(::GetMenu(_hSelf), MENUINDEX_LANGUAGE); + + // Add external languages to menu + for (int i = 0 ; i < pNppParam->getNbExternalLang() ; i++) + { + ExternalLangContainer & externalLangContainer = pNppParam->getELCFromIndex(i); + + int numLangs = ::GetMenuItemCount(hMenu); + char buffer[100]; + + int x; + for(x = 0; (x == 0 || strcmp(externalLangContainer._name, buffer) > 0) && x < numLangs; x++) + { + ::GetMenuString(hMenu, x, buffer, sizeof(buffer), MF_BYPOSITION); + } + + ::InsertMenu(hMenu, x-1, MF_BYPOSITION, IDM_LANG_EXTERNAL + i, externalLangContainer._name); + } + + if (nppGUI._excludedLangList.size() > 0) + { + for (size_t i = 0 ; i < nppGUI._excludedLangList.size() ; i++) + { + int cmdID = pNppParam->langTypeToCommandID(nppGUI._excludedLangList[i]._langType); + char itemName[256]; + ::GetMenuString(hMenu, cmdID, itemName, sizeof(itemName), MF_BYCOMMAND); + nppGUI._excludedLangList[i]._cmdID = cmdID; + nppGUI._excludedLangList[i]._langName = itemName; + ::DeleteMenu(hMenu, cmdID, MF_BYCOMMAND); + DrawMenuBar(_hSelf); + } + } + + // Add User Define Languages Entry + pos = ::GetMenuItemCount(hMenu) - 1; + + for (int i = 0 ; i < pNppParam->getNbUserLang() ; i++) + { + UserLangContainer & userLangContainer = pNppParam->getULCFromIndex(i); + ::InsertMenu(hMenu, pos + i, MF_BYPOSITION, IDM_LANG_USER + i + 1, userLangContainer.getName()); + } + //-- Tool Bar Section --// toolBarStatusType tbStatus = nppGUI._toolBarStatus; diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 7eb861f9..76d0361d 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -28,7 +28,7 @@ NppParameters::NppParameters() : _pXmlDoc(NULL),_pXmlUserDoc(NULL), _pXmlUserSty _pXmlUserLangDoc(NULL), _pXmlNativeLangDoc(NULL),\ _nbLang(0), _nbFile(0), _nbMaxFile(10), _pXmlToolIconsDoc(NULL),\ _pXmlShortcutDoc(NULL), _pXmlContextMenuDoc(NULL), _pXmlSessionDoc(NULL),\ - _nbUserLang(0), _hUser32(NULL), _hUXTheme(NULL),\ + _nbUserLang(0), _nbExternalLang(0), _hUser32(NULL), _hUXTheme(NULL),\ _transparentFuncAddr(NULL), _enableThemeDialogTextureFuncAddr(NULL),\ _isTaskListRBUTTONUP_Active(false), _fileSaveDlgFilterIndex(-1) { @@ -71,6 +71,7 @@ void cutString(const char *str2cut, vector & patternVect) bool NppParameters::load(/*bool noUserPath*/) { + L_END = L_EXTERNAL; bool isAllLaoded = true; for (int i = 0 ; i < NB_LANG ; _langList[i] = NULL, i++); char nppPath[MAX_PATH]; @@ -359,6 +360,10 @@ bool NppParameters::load(/*bool noUserPath*/) getSessionFromXmlTree(); delete _pXmlSessionDoc; + for (size_t i = 0 ; i < _pXmlExternalLexerDoc.size() ; i++) + if (_pXmlExternalLexerDoc[i]) + delete _pXmlExternalLexerDoc[i]; + _pXmlSessionDoc = NULL; } return isAllLaoded; @@ -426,6 +431,22 @@ void NppParameters::getLangKeywordsFromXmlTree() if (!root) return; feedKeyWordsParameters(root); } + +void NppParameters::getExternalLexerFromXmlTree(TiXmlDocument *doc) +{ + TiXmlNode *root = doc->FirstChild("NotepadPlus"); + if (!root) return; + feedKeyWordsParameters(root); + feedStylerArray(root); +} + +int NppParameters::addExternalLangToEnd(ExternalLangContainer * externalLang) +{ + _externalLangArray[_nbExternalLang] = externalLang; + _nbExternalLang++; + L_END++; + return _nbExternalLang-1; +} bool NppParameters::getUserStylersFromXmlTree() { @@ -1371,9 +1392,16 @@ bool NppParameters::feedStylerArray(TiXmlNode *node) const char *lexerName = element->Attribute("name"); const char *lexerDesc = element->Attribute("desc"); const char *lexerUserExt = element->Attribute("ext"); + const char *lexerExcluded = element->Attribute("excluded"); if (lexerName) { _lexerStylerArray.addLexerStyler(lexerName, lexerDesc, lexerUserExt, childNode); + if (lexerExcluded != NULL && !strcmp(lexerExcluded, "yes")) + { + int index = getExternalLangIndexFromName(lexerName); + if (index != -1) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)(index + L_EXTERNAL))); + } } } @@ -1578,29 +1606,13 @@ LangType NppParameters::getLangIDFromStr(const char *langName) if (!strcmp("inno", langName)) return L_INNO; if (!strcmp("searchResult", langName)) return L_SEARCHRESULT; if (!strcmp("cmake", langName)) return L_CMAKE; + + int id = _pSelf->getExternalLangIndexFromName(langName); + if (id != -1) return (LangType)(id + L_EXTERNAL); + return L_TXT; } -int NppParameters::getIndexFromStr(const char *indexName) const -{ - string str(indexName); - - if (str == "instre1") - return LANG_INDEX_INSTR; - else if (str == "instre2") - return LANG_INDEX_INSTR2; - else if (str == "type1") - return LANG_INDEX_TYPE; - else if (str == "type2") - return LANG_INDEX_TYPE2; - else if (str == "type3") - return LANG_INDEX_TYPE3; - else if (str == "type4") - return LANG_INDEX_TYPE4; - else - return -1; -} - void NppParameters::feedKeyWordsParameters(TiXmlNode *node) { @@ -1633,9 +1645,9 @@ void NppParameters::feedKeyWordsParameters(TiXmlNode *node) if ((indexName) && (kwVal)) keyWords = kwVal->Value(); - int i = getIndexFromStr(indexName); + int i = getKwClassFromName(indexName); - if (i != -1) + if (i >= 0 && i <= KEYWORDSET_MAX) _langList[_nbLang]->setWords(keyWords, i); } _nbLang++; @@ -3034,8 +3046,13 @@ void NppParameters::writeExcludedLangList(TiXmlElement *element) for (size_t i = 0 ; i < _nppGUI._excludedLangList.size() ; i++) { - int nGrp = _nppGUI._excludedLangList[i]._langType / 8; - int nMask = 1 << _nppGUI._excludedLangList[i]._langType % 8; + LangType langType = _nppGUI._excludedLangList[i]._langType; + if (langType >= L_EXTERNAL && langType < L_END) + continue; + + int nGrp = langType / 8; + int nMask = 1 << langType % 8; + switch (nGrp) { @@ -3200,7 +3217,10 @@ int NppParameters::langTypeToCommandID(LangType lt) const case L_TXT : id = IDM_LANG_TEXT; break; default : - id = IDM_LANG_TEXT; + if(lt >= L_EXTERNAL && lt < L_END) + id = lt - L_EXTERNAL + IDM_LANG_EXTERNAL; + else + id = IDM_LANG_TEXT; } return id; } @@ -3218,13 +3238,10 @@ void NppParameters::writeStyles(LexerStylerArray & lexersStylers, StyleArray & g LexerStyler *pLs = _lexerStylerArray.getLexerStylerByName(nm); LexerStyler *pLs2 = lexersStylers.getLexerStylerByName(nm); - const char *extStr = pLs->getLexerUserExt(); - //pLs2->setLexerUserExt(extStr); - element->SetAttribute("ext", extStr); - - if (pLs) { + const char *extStr = pLs->getLexerUserExt(); + element->SetAttribute("ext", extStr); for (TiXmlNode *grChildNode = childNode->FirstChildElement("WordsStyle"); grChildNode ; grChildNode = grChildNode->NextSibling("WordsStyle")) @@ -3243,6 +3260,46 @@ void NppParameters::writeStyles(LexerStylerArray & lexersStylers, StyleArray & g } } } + + for(size_t x = 0; x < _pXmlExternalLexerDoc.size(); x++) + { + TiXmlNode *lexersRoot = ( _pXmlExternalLexerDoc[x]->FirstChild("NotepadPlus"))->FirstChildElement("LexerStyles"); + for (TiXmlNode *childNode = lexersRoot->FirstChildElement("LexerType"); + childNode ; + childNode = childNode->NextSibling("LexerType")) + { + TiXmlElement *element = childNode->ToElement(); + const char *nm = element->Attribute("name"); + + LexerStyler *pLs = _lexerStylerArray.getLexerStylerByName(nm); + LexerStyler *pLs2 = lexersStylers.getLexerStylerByName(nm); + + if (pLs) + { + const char *extStr = pLs->getLexerUserExt(); + //pLs2->setLexerUserExt(extStr); + element->SetAttribute("ext", extStr); + + for (TiXmlNode *grChildNode = childNode->FirstChildElement("WordsStyle"); + grChildNode ; + grChildNode = grChildNode->NextSibling("WordsStyle")) + { + TiXmlElement *grElement = grChildNode->ToElement(); + const char *styleName = grElement->Attribute("name"); + + int i = pLs->getStylerIndexByName(styleName); + if (i != -1) + { + Style & style = pLs->getStyler(i); + Style & style2Sync = pLs2->getStyler(i); + + writeStyle2Element(style, style2Sync, grElement); + } + } + } + } + _pXmlExternalLexerDoc[x]->SaveFile(); + } TiXmlNode *globalStylesRoot = (_pXmlUserStylerDoc->FirstChild("NotepadPlus"))->FirstChildElement("GlobalStyles"); diff --git a/PowerEditor/src/Parameters.h b/PowerEditor/src/Parameters.h index 13c67a58..caec60d7 100644 --- a/PowerEditor/src/Parameters.h +++ b/PowerEditor/src/Parameters.h @@ -220,6 +220,10 @@ static int getKwClassFromName(const char *str) { if (!strcmp("type3", str)) return LANG_INDEX_TYPE3; if (!strcmp("type4", str)) return LANG_INDEX_TYPE4; if (!strcmp("type5", str)) return LANG_INDEX_TYPE5; + + if ((str[1] == '\0') && (str[0] >= '0') && (str[0] <= '8')) // up to KEYWORDSET_MAX + return str[0] - '0'; + return -1; }; @@ -404,7 +408,7 @@ private : char _lexerUserExt[256]; }; -const int MAX_LEXER_STYLE = 50; +const int MAX_LEXER_STYLE = 80; struct LexerStylerArray { @@ -595,6 +599,7 @@ struct ScintillaViewParams const int NB_LIST = 20; const int NB_MAX_LRF_FILE = 30; const int NB_MAX_USER_LANG = 30; +const int NB_MAX_EXTERNAL_LANG = 30; const int LANG_NAME_LEN = 32; struct Lang @@ -724,7 +729,22 @@ private: bool _isPrefix[nbPrefixListAllowed]; }; -const int NB_LANG = 50; +#define MAX_EXTERNAL_LEXER_NAME_LEN 16 +#define MAX_EXTERNAL_LEXER_DESC_LEN 32 + +class ExternalLangContainer +{ +public: + char _name[MAX_EXTERNAL_LEXER_NAME_LEN]; + char _desc[MAX_EXTERNAL_LEXER_DESC_LEN]; + + ExternalLangContainer(const char *name, const char *desc) { + strncpy(_name, name, MAX_EXTERNAL_LEXER_NAME_LEN); + strncpy(_desc, desc, MAX_EXTERNAL_LEXER_DESC_LEN); + }; +}; + +const int NB_LANG = 80; const bool DUP = true; const bool FREE = false; @@ -738,6 +758,7 @@ public: void destroyInstance(); bool _isTaskListRBUTTONUP_Active; + int L_END; const NppGUI & getNppGUI() const { return _nppGUI; @@ -853,6 +874,22 @@ public: //qui doit etre jamais passer return *_userLangArray[0]; }; + + int getNbExternalLang() const {return _nbExternalLang;}; + int getExternalLangIndexFromName(const char *externalLangName) const { + for (int i = 0 ; i < _nbExternalLang ; i++) + { + if (!strcmp(externalLangName, _externalLangArray[i]->_name)) + return i; + } + return -1; + }; + ExternalLangContainer & getELCFromIndex(int i) {return *_externalLangArray[i];}; + + bool ExternalLangHasRoom() const {return _nbExternalLang < NB_MAX_EXTERNAL_LANG;}; + + void getExternalLexerFromXmlTree(TiXmlDocument *doc); + vector * getExternalLexerDoc() { return &_pXmlExternalLexerDoc;}; void writeUserDefinedLang(); void writeShortcuts(bool rewriteCmdSc, bool rewriteMacrosSc, bool rewriteUserCmdSc, bool rewriteScintillaKey, bool rewritePluginCmdSc); @@ -888,6 +925,21 @@ public: int addUserLangToEnd(const UserLangContainer & userLang, const char *newName); void removeUserLang(int index); + + bool isExistingExternalLangName(const char *newName) const { + if ((!newName) || (!newName[0])) + return true; + + for (int i = 0 ; i < _nbExternalLang ; i++) + { + if (!strcmp(_externalLangArray[i]->_name, newName)) + return true; + } + return false; + }; + + int addExternalLangToEnd(ExternalLangContainer * externalLang); + TiXmlDocument * getNativeLang() const {return _pXmlNativeLangDoc;}; TiXmlDocument * getToolIcons() const {return _pXmlToolIconsDoc;}; @@ -1006,6 +1058,8 @@ private: TiXmlDocument *_pXmlDoc, *_pXmlUserDoc, *_pXmlUserStylerDoc, *_pXmlUserLangDoc, *_pXmlNativeLangDoc,\ *_pXmlToolIconsDoc, *_pXmlShortcutDoc, *_pXmlContextMenuDoc, *_pXmlSessionDoc; + + vector _pXmlExternalLexerDoc; NppGUI _nppGUI; ScintillaViewParams _svp[2]; @@ -1019,6 +1073,8 @@ private: UserLangContainer *_userLangArray[NB_MAX_USER_LANG]; int _nbUserLang; char _userDefineLangPath[MAX_PATH]; + ExternalLangContainer *_externalLangArray[NB_MAX_EXTERNAL_LANG]; + int _nbExternalLang; CmdLineParams _cmdLineParams; @@ -1113,7 +1169,6 @@ private: bool getShortcuts(TiXmlNode *node, Shortcut & sc); bool getScintKey(TiXmlNode *node, ScintillaKeyMap & skm); - int getIndexFromStr(const char *indexName) const; void writeStyle2Element(Style & style2Wite, Style & style2Sync, TiXmlElement *element); void insertUserLang2Tree(TiXmlNode *node, UserLangContainer *userLang); void insertCmd(TiXmlNode *cmdRoot, const CommandShortcut & cmd); diff --git a/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp b/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp index db5f6c11..7a20d7b1 100644 --- a/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp +++ b/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp @@ -365,6 +365,33 @@ void ScintillaEditView::setUserLexer(const char *userLangName) } } +void ScintillaEditView::setExternalLexer(LangType typeDoc) +{ + int id = typeDoc - L_EXTERNAL; + char * name = NppParameters::getInstance()->getELCFromIndex(id)._name; + execute(SCI_SETLEXERLANGUAGE, 0, (LPARAM)name); + + LexerStyler *pStyler = (_pParameter->getLStylerArray()).getLexerStylerByName(name); + if (pStyler) + { + for (int i = 0 ; i < pStyler->getNbStyler() ; i++) + { + Style & style = pStyler->getStyler(i); + + setStyle(style._styleID, style._fgColor, style._bgColor, style._fontName, style._fontStyle, style._fontSize); + + if (style._keywordClass >= 0 && style._keywordClass <= KEYWORDSET_MAX) + { + string kwl(""); + if (style._keywords) + kwl = *(style._keywords); + + execute(SCI_SETKEYWORDS, style._keywordClass, (LPARAM)getCompleteKeywordList(kwl, typeDoc, style._keywordClass)); + } + } + } +} + void ScintillaEditView::setCppLexer(LangType langType) { const char *cppInstrs; @@ -745,7 +772,11 @@ void ScintillaEditView::defineDocType(LangType typeDoc) case L_TXT : default : - execute(SCI_SETLEXER, (_codepage == CP_CHINESE_TRADITIONAL)?SCLEX_MAKEFILE:SCLEX_NULL); break; + if(typeDoc >= L_EXTERNAL && typeDoc < NppParameters::getInstance()->L_END) + setExternalLexer(typeDoc); + else + execute(SCI_SETLEXER, (_codepage == CP_CHINESE_TRADITIONAL)?SCLEX_MAKEFILE:SCLEX_NULL); + break; } diff --git a/PowerEditor/src/ScitillaComponent/ScintillaEditView.h b/PowerEditor/src/ScitillaComponent/ScintillaEditView.h index 4272fc87..067f94ad 100644 --- a/PowerEditor/src/ScitillaComponent/ScintillaEditView.h +++ b/PowerEditor/src/ScitillaComponent/ScintillaEditView.h @@ -631,6 +631,7 @@ protected: void setXmlLexer(LangType type); void setUserLexer(); void setUserLexer(const char *userLangName); + void setExternalLexer(LangType typeDoc); void setEmbeddedJSLexer(); void setPhpEmbeddedLexer(); void setEmbeddedAspLexer(); diff --git a/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp b/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp index 03e77531..a01508fa 100644 --- a/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp +++ b/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp @@ -650,7 +650,7 @@ BOOL CALLBACK DefaultNewDocDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM ::SendDlgItemMessage(_hSelf, ID2Check, BM_SETCHECK, BST_CHECKED, 0); int index = 0; - for (int i = L_TXT ; i < L_END ; i++) + for (int i = L_TXT ; i < pNppParam->L_END ; i++) { string str; if ((LangType)i != L_USER) @@ -726,7 +726,7 @@ BOOL CALLBACK LangMenuDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lPara { case WM_INITDIALOG : { - for (int i = L_TXT ; i < L_END ; i++) + for (int i = L_TXT ; i < pNppParam->L_END ; i++) { string str; if ((LangType)i != L_USER) @@ -839,6 +839,29 @@ BOOL CALLBACK LangMenuDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lPara ::EnableWindow(::GetDlgItem(_hSelf, idButton2Enable), TRUE); ::EnableWindow(::GetDlgItem(_hSelf, idButton2Disable), FALSE); + if ((lmi._langType >= L_EXTERNAL) && (lmi._langType < pNppParam->L_END)) + { + bool found(false); + for(size_t x = 0; x < pNppParam->getExternalLexerDoc()->size() && !found; x++) + { + TiXmlNode *lexersRoot = pNppParam->getExternalLexerDoc()->at(x)->FirstChild("NotepadPlus")->FirstChildElement("LexerStyles"); + for (TiXmlNode *childNode = lexersRoot->FirstChildElement("LexerType"); + childNode ; + childNode = childNode->NextSibling("LexerType")) + { + TiXmlElement *element = childNode->ToElement(); + + if (string(element->Attribute("name")) == lmi._langName) + { + element->SetAttribute("excluded", (LOWORD(wParam)==IDC_BUTTON_REMOVE)?"yes":"no"); + pNppParam->getExternalLexerDoc()->at(x)->SaveFile(); + found = true; + break; + } + } + } + } + HWND grandParent; grandParent = ::GetParent(_hParent); diff --git a/PowerEditor/src/menuCmdID.h b/PowerEditor/src/menuCmdID.h index 9bcf3dcf..671be2c8 100644 --- a/PowerEditor/src/menuCmdID.h +++ b/PowerEditor/src/menuCmdID.h @@ -230,8 +230,11 @@ #define IDM_LANG_INNO (IDM_LANG + 47) #define IDM_LANG_CMAKE (IDM_LANG + 48) - #define IDM_LANG_USER (IDM_LANG + 50) //46050 - #define IDM_LANG_USER_LIMIT (IDM_LANG + 80) //46080 + #define IDM_LANG_EXTERNAL (IDM_LANG + 50) + #define IDM_LANG_EXTERNAL_LIMIT (IDM_LANG + 79) + + #define IDM_LANG_USER (IDM_LANG + 80) //46080 + #define IDM_LANG_USER_LIMIT (IDM_LANG + 110) //46110 #define IDM_ABOUT (IDM + 7000) diff --git a/scintilla/src/LexSearchResult.cxx b/scintilla/src/LexSearchResult.cxx index da4fe3dc..6acb295c 100644 --- a/scintilla/src/LexSearchResult.cxx +++ b/scintilla/src/LexSearchResult.cxx @@ -173,6 +173,7 @@ static void ColouriseSearchResultDoc(unsigned int startPos, int length, int, Wor ColouriseSearchResultLine(keywordlists, lineBuffer, linePos, startLine, i, styler); linePos = 0; startLine = i + 1; + while (!AtEOL(styler, i)) i++; } } if (linePos > 0) { // Last line does not have ending characters