From 252468c29b35046dc7bce4761f9f2a9507830f97 Mon Sep 17 00:00:00 2001 From: Don Ho Date: Fri, 1 Apr 2022 19:17:18 +0200 Subject: [PATCH] Revert "Remove the external lexer support" This reverts commit 41a5bf0245b53e74186e49a21adec2c518587b5c. --- .gitignore | 2 - PowerEditor/src/MISC/FileNameStringSplitter.h | 1 + .../MISC/PluginsManager/Notepad_plus_msgs.h | 8 +- .../MISC/PluginsManager/PluginsManager.cpp | 95 ++++++++++--- .../src/MISC/PluginsManager/PluginsManager.h | 7 +- PowerEditor/src/Notepad_plus.cpp | 53 +++++++- PowerEditor/src/NppBigSwitch.cpp | 20 ++- PowerEditor/src/NppCommands.cpp | 8 ++ PowerEditor/src/NppIO.cpp | 4 + PowerEditor/src/Parameters.cpp | 126 +++++++++++++++++- PowerEditor/src/Parameters.h | 41 +++++- .../src/ScintillaComponent/AutoCompletion.cpp | 7 +- PowerEditor/src/ScintillaComponent/Buffer.cpp | 22 ++- .../src/ScintillaComponent/FindReplaceDlg.cpp | 9 +- .../ScintillaComponent/ScintillaEditView.cpp | 45 ++++++- .../ScintillaComponent/ScintillaEditView.h | 5 +- .../FunctionList/functionParser.cpp | 10 +- .../WinControls/FunctionList/functionParser.h | 4 +- .../WinControls/Preference/preferenceDlg.cpp | 27 +++- PowerEditor/src/menuCmdID.h | 4 +- PowerEditor/src/winmain.cpp | 2 +- 21 files changed, 420 insertions(+), 80 deletions(-) diff --git a/.gitignore b/.gitignore index 03bae3a26..581cf6d26 100644 --- a/.gitignore +++ b/.gitignore @@ -55,8 +55,6 @@ UpgradeLog*.htm *.bak PowerEditor/bin/notepad++.exe -PowerEditor/bin/Notepad++.exp -PowerEditor/bin/Notepad++.lib PowerEditor/bin/SciLexer.dll PowerEditor/bin/config.xml PowerEditor/bin/stylers.xml diff --git a/PowerEditor/src/MISC/FileNameStringSplitter.h b/PowerEditor/src/MISC/FileNameStringSplitter.h index 4cd82370a..f3718251f 100644 --- a/PowerEditor/src/MISC/FileNameStringSplitter.h +++ b/PowerEditor/src/MISC/FileNameStringSplitter.h @@ -23,6 +23,7 @@ class FileNameStringSplitter public: FileNameStringSplitter(const TCHAR *fileNameStr) { + //if (!fileNameStr) return; TCHAR *pStr = NULL; bool isInsideQuotes = false; const int filePathLength = MAX_PATH; diff --git a/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h b/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h index be34bb1de..d2688ec32 100644 --- a/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h +++ b/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h @@ -35,7 +35,7 @@ enum LangType {L_TEXT, L_PHP , L_C, L_CPP, L_CS, L_OBJC, L_JAVA, L_RC,\ L_REGISTRY, L_RUST, L_SPICE, L_TXT2TAGS, L_VISUALPROLOG, L_TYPESCRIPT,\ // Don't use L_JS, use L_JAVASCRIPT instead // The end of enumated language type, so it should be always at the end - L_END}; + L_EXTERNAL}; enum class ExternalLexerAutoIndentMode { Standard, C_Like, Custom }; enum class MacroStatus { Idle, RecordInProgress, RecordingStopped, PlayingBack }; @@ -456,10 +456,6 @@ enum Platform { PF_UNKNOWN, PF_X86, PF_X64, PF_IA64, PF_ARM64 }; HICON hToolbarIconDarkMode; }; - // Due to Scintilla 5 doesn't support external lexer, the following 2 messages are deprecated - they do nothing and return always FALSE - #define NPPM_GETEXTERNALLEXERAUTOINDENTMODE_DEPRECATED (NPPMSG + 103) - #define NPPM_SETEXTERNALLEXERAUTOINDENTMODE_DEPRECATED (NPPMSG + 104) - /* #define NPPM_GETEXTERNALLEXERAUTOINDENTMODE (NPPMSG + 103) // BOOL NPPM_GETEXTERNALLEXERAUTOINDENTMODE(const TCHAR *languageName, ExternalLexerAutoIndentMode &autoIndentMode) // Get ExternalLexerAutoIndentMode for an installed external programming language. @@ -475,7 +471,7 @@ enum Platform { PF_UNKNOWN, PF_X86, PF_X64, PF_IA64, PF_ARM64 }; // - C_Like means Notepad++ will perform a C-Language style indentation for the selected external language; // - Custom means a Plugin will be controlling auto-indentation for the current language. // returned value: TRUE if function call was successful, otherwise FALSE. - */ + #define NPPM_ISAUTOINDENTON (NPPMSG + 105) // BOOL NPPM_ISAUTOINDENTON(0, 0) // Returns the current Use Auto-Indentation setting in Notepad++ Preferences. diff --git a/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp b/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp index 63099cb36..b8849e2c9 100644 --- a/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp +++ b/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp @@ -173,17 +173,82 @@ int PluginsManager::loadPlugin(const TCHAR *pluginFilePath) // it's a lexer plugin if (GetLexerCount) { - // Lexer library (.dll) is not supported in Scintilla 5 + GetLexerNameFn GetLexerName = (GetLexerNameFn)::GetProcAddress(pi->_hLib, "GetLexerName"); + if (!GetLexerName) + throw generic_string(TEXT("Loading GetLexerName function failed.")); + + GetLexerStatusTextFn GetLexerStatusText = (GetLexerStatusTextFn)::GetProcAddress(pi->_hLib, "GetLexerStatusText"); + + if (!GetLexerStatusText) + throw generic_string(TEXT("Loading GetLexerStatusText function failed.")); + + // Assign a buffer for the lexer name. + char lexName[MAX_EXTERNAL_LEXER_NAME_LEN]; + lexName[0] = '\0'; + TCHAR lexDesc[MAX_EXTERNAL_LEXER_DESC_LEN]; + lexDesc[0] = '\0'; + + int numLexers = GetLexerCount(); + + ExternalLangContainer *containers[30]; + + WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance(); + for (int x = 0; x < numLexers; ++x) + { + GetLexerName(x, lexName, MAX_EXTERNAL_LEXER_NAME_LEN); + GetLexerStatusText(x, lexDesc, MAX_EXTERNAL_LEXER_DESC_LEN); + const TCHAR *pLexerName = wmc.char2wchar(lexName, CP_ACP); + if (!nppParams.isExistingExternalLangName(pLexerName) && nppParams.ExternalLangHasRoom()) + containers[x] = new ExternalLangContainer(pLexerName, lexDesc); + else + containers[x] = NULL; + } + + TCHAR xmlPath[MAX_PATH]; + wcscpy_s(xmlPath, nppParams.getNppPath().c_str()); + PathAppend(xmlPath, TEXT("plugins\\Config")); + PathAppend(xmlPath, pi->_moduleName.c_str()); + PathRemoveExtension(xmlPath); + PathAddExtension(xmlPath, TEXT(".xml")); + + if (!PathFileExists(xmlPath)) + { + lstrcpyn(xmlPath, TEXT("\0"), MAX_PATH ); + wcscpy_s(xmlPath, nppParams.getAppDataNppDir() ); + PathAppend(xmlPath, TEXT("plugins\\Config")); + PathAppend(xmlPath, pi->_moduleName.c_str()); + PathRemoveExtension( xmlPath ); + PathAddExtension( xmlPath, TEXT(".xml") ); + + if (! PathFileExists( xmlPath ) ) + { + throw generic_string(generic_string(xmlPath) + TEXT(" is missing.")); + } + } + + TiXmlDocument *pXmlDoc = new TiXmlDocument(xmlPath); + + if (!pXmlDoc->LoadFile()) + { + delete pXmlDoc; + pXmlDoc = NULL; + throw generic_string(generic_string(xmlPath) + TEXT(" 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); + //const char *pDllName = wmc.wchar2char(pluginFilePath, CP_ACP); + //::SendMessage(_nppData._scintillaMainHandle, SCI_LOADLEXERLIBRARY, 0, reinterpret_cast(pDllName)); - generic_string s = pluginFileName; - s += TEXT(" is a Lexer library.\n"); - s += TEXT("Lexer library is not supported in Scintilla 5.\nIt'll be loaded as only a normal plugin, the external language part won't work with this version of Notepad++."); - ::MessageBox(_nppData._nppHandle, s.c_str(), pluginFilePath, MB_OK); } - addInLoadedDlls(pluginFilePath, pluginFileName); _pluginInfos.push_back(pi); - return static_cast(_pluginInfos.size() - 1); } catch (std::exception& e) @@ -193,19 +258,17 @@ int PluginsManager::loadPlugin(const TCHAR *pluginFilePath) } catch (generic_string& s) { - if (pi && pi->_hLib) - { - ::FreeLibrary(pi->_hLib); - } - s += TEXT("\n\n"); s += pluginFileName; s += USERMSG; - if (::MessageBox(_nppData._nppHandle, s.c_str(), pluginFilePath, MB_YESNO) == IDYES) + if (::MessageBox(NULL, s.c_str(), pluginFilePath, MB_YESNO) == IDYES) { + if (pi && pi->_hLib) + { + ::FreeLibrary(pi->_hLib); + } ::DeleteFile(pluginFilePath); } - delete pi; return -1; } @@ -215,7 +278,7 @@ int PluginsManager::loadPlugin(const TCHAR *pluginFilePath) msg += TEXT("\n\n"); msg += pluginFileName; msg += USERMSG; - if (::MessageBox(_nppData._nppHandle, msg.c_str(), pluginFilePath, MB_YESNO) == IDYES) + if (::MessageBox(NULL, msg.c_str(), pluginFilePath, MB_YESNO) == IDYES) { if (pi && pi->_hLib) { @@ -228,7 +291,7 @@ int PluginsManager::loadPlugin(const TCHAR *pluginFilePath) } } -bool PluginsManager::loadPluginsFromItsOwnFolder(const TCHAR* dir, const PluginViewList* pluginUpdateInfoList) +bool PluginsManager::loadPluginsV2(const TCHAR* dir, const PluginViewList* pluginUpdateInfoList) { if (_isDisabled) return false; diff --git a/PowerEditor/src/MISC/PluginsManager/PluginsManager.h b/PowerEditor/src/MISC/PluginsManager/PluginsManager.h index e1cdfdd77..14a120d0b 100644 --- a/PowerEditor/src/MISC/PluginsManager/PluginsManager.h +++ b/PowerEditor/src/MISC/PluginsManager/PluginsManager.h @@ -86,7 +86,8 @@ public: _nppData = nppData; } - bool loadPluginsFromItsOwnFolder(const TCHAR *dir = NULL, const PluginViewList* pluginUpdateInfoList = nullptr); + int loadPlugin(const TCHAR *pluginFilePath); + bool loadPluginsV2(const TCHAR *dir = NULL, const PluginViewList* pluginUpdateInfoList = nullptr); bool unloadPlugin(int index, HWND nppHandle); @@ -126,8 +127,6 @@ private: IDAllocator _markerAlloc; bool _noMoreNotification = false; - int loadPlugin(const TCHAR* pluginFilePath); - void pluginCrashAlert(const TCHAR *pluginName, const TCHAR *funcSignature) { generic_string msg = pluginName; @@ -163,3 +162,5 @@ private: // 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, TCHAR *desc, int buflength); diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index efccb6b20..e2ae1580d 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -407,8 +407,9 @@ LRESULT Notepad_plus::init(HWND hwnd) _scintillaCtrls4Plugins.init(_pPublicInterface->getHinst(), hwnd); _pluginsManager.init(nppData); + bool enablePluginAdmin = _pluginsAdminDlg.initFromJson(); - _pluginsManager.loadPluginsFromItsOwnFolder(nppParam.getPluginRootDir(), enablePluginAdmin ? &_pluginsAdminDlg.getAvailablePluginUpdateInfoList() : nullptr); + _pluginsManager.loadPluginsV2(nppParam.getPluginRootDir(), enablePluginAdmin ? &_pluginsAdminDlg.getAvailablePluginUpdateInfoList() : nullptr); _restoreButton.init(_pPublicInterface->getHinst(), hwnd); // ------------ // @@ -466,6 +467,24 @@ LRESULT Notepad_plus::init(HWND hwnd) //Languages Menu HMENU hLangMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_LANGUAGE); + // Add external languages to menu + for (int i = 0; i < nppParam.getNbExternalLang(); ++i) + { + ExternalLangContainer & externalLangContainer = nppParam.getELCFromIndex(i); + + int numLangs = ::GetMenuItemCount(hLangMenu); + const int bufferSize = 100; + TCHAR buffer[bufferSize]; + + int x; + for (x = 0; (x == 0 || lstrcmp(externalLangContainer._name, buffer) > 0) && x < numLangs; ++x) + { + ::GetMenuString(hLangMenu, x, buffer, bufferSize, MF_BYPOSITION); + } + + ::InsertMenu(hLangMenu, x - 1, MF_BYPOSITION, IDM_LANG_EXTERNAL + i, externalLangContainer._name); + } + if (nppGUI._excludedLangList.size() > 0) { for (size_t i = 0, len = nppGUI._excludedLangList.size(); i < len; ++i) @@ -2339,14 +2358,25 @@ void Notepad_plus::checkLangsMenu(int id) const generic_string Notepad_plus::getLangDesc(LangType langType, bool getName) { - if (langType >= L_END) + NppParameters& nppParams = NppParameters::getInstance(); + + if ((langType >= L_EXTERNAL) && (langType < nppParams.L_END)) + { + ExternalLangContainer & elc = nppParams.getELCFromIndex(langType - L_EXTERNAL); + if (getName) + return generic_string(elc._name); + else + return generic_string(elc._desc); + } + + if (langType > L_EXTERNAL) langType = L_TEXT; generic_string str2Show; if (getName) - str2Show = ScintillaEditView::_langNames[langType].shortName; + str2Show = ScintillaEditView::langNames[langType].shortName; else - str2Show = ScintillaEditView::_langNames[langType].longName; + str2Show = ScintillaEditView::langNames[langType].longName; if (langType == L_USER) { @@ -3075,6 +3105,15 @@ void Notepad_plus::maintainIndentation(TCHAR ch) LangType type = _pEditView->getCurrentBuffer()->getLangType(); ExternalLexerAutoIndentMode autoIndentMode = ExternalLexerAutoIndentMode::Standard; + // For external languages, query for custom auto-indentation funcionality + if (type >= L_EXTERNAL) + { + NppParameters& nppParam = NppParameters::getInstance(); + autoIndentMode = nppParam.getELCFromIndex(type - L_EXTERNAL)._autoIndentMode; + if (autoIndentMode == ExternalLexerAutoIndentMode::Custom) + return; + } + // Do not alter indentation if we were at the beginning of the line and we pressed Enter if ((((eolMode == SC_EOL_CRLF || eolMode == SC_EOL_LF) && ch == '\n') || (eolMode == SC_EOL_CR && ch == '\r')) && prevLine >= 0 && _pEditView->getLineLength(prevLine) == 0) @@ -3465,7 +3504,7 @@ LangType Notepad_plus::menuID2LangType(int cmdID) break; } } - return L_TEXT; + return L_EXTERNAL; } @@ -4247,7 +4286,7 @@ void Notepad_plus::docOpenInNewInstance(FileTransferMode mode, int x, int y) if (lt != L_USER) { command += TEXT(" -l"); - command += ScintillaEditView::_langNames[lt].lexerName; + command += ScintillaEditView::langNames[lt].lexerName; } command += TEXT(" -n"); command += to_wstring(_pEditView->getCurrentLineNumber() + 1); @@ -6121,7 +6160,7 @@ std::vector Notepad_plus::loadCommandlineParams(const TCHAR * co { pBuf->setLangType(L_USER, udl.c_str()); } - else + else if (lt != L_EXTERNAL && lt < nppParams.L_END) { pBuf->setLangType(lt); } diff --git a/PowerEditor/src/NppBigSwitch.cpp b/PowerEditor/src/NppBigSwitch.cpp index cc316899c..75ea065f4 100644 --- a/PowerEditor/src/NppBigSwitch.cpp +++ b/PowerEditor/src/NppBigSwitch.cpp @@ -415,7 +415,7 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa { if (!wParam) return FALSE; - if (lParam < L_TEXT || lParam >= L_END || lParam == L_USER) + if (lParam < L_TEXT || lParam >= L_EXTERNAL || lParam == L_USER) return FALSE; BufferID id = (BufferID)wParam; @@ -2555,14 +2555,24 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa return langDesc.length(); } - case NPPM_GETEXTERNALLEXERAUTOINDENTMODE_DEPRECATED: + case NPPM_GETEXTERNALLEXERAUTOINDENTMODE: { - return FALSE; + int index = nppParam.getExternalLangIndexFromName(reinterpret_cast(wParam)); + if (index < 0) + return FALSE; + + *(reinterpret_cast(lParam)) = nppParam.getELCFromIndex(index)._autoIndentMode; + return TRUE; } - case NPPM_SETEXTERNALLEXERAUTOINDENTMODE_DEPRECATED: + case NPPM_SETEXTERNALLEXERAUTOINDENTMODE: { - return FALSE; + int index = nppParam.getExternalLangIndexFromName(reinterpret_cast(wParam)); + if (index < 0) + return FALSE; + + nppParam.getELCFromIndex(index)._autoIndentMode = static_cast(lParam); + return TRUE; } case NPPM_ISAUTOINDENTON: diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index c8ce131d6..ef977efbb 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -3777,6 +3777,14 @@ void Notepad_plus::command(int id) _pDocMap->setSyntaxHiliting(); } } + else if ((id >= IDM_LANG_EXTERNAL) && (id <= IDM_LANG_EXTERNAL_LIMIT)) + { + setLanguage((LangType)(id - IDM_LANG_EXTERNAL + L_EXTERNAL)); + if (_pDocMap) + { + _pDocMap->setSyntaxHiliting(); + } + } else if ((id >= ID_MACRO) && (id < ID_MACRO_LIMIT)) { int i = id - ID_MACRO; diff --git a/PowerEditor/src/NppIO.cpp b/PowerEditor/src/NppIO.cpp index ade0d6b1d..867461456 100644 --- a/PowerEditor/src/NppIO.cpp +++ b/PowerEditor/src/NppIO.cpp @@ -2047,6 +2047,8 @@ bool Notepad_plus::loadSession(Session & session, bool isSnapshotMode, bool shou LangType typeToSet = L_TEXT; if (id != 0 && id != IDM_LANG_USER) typeToSet = menuID2LangType(id); + if (typeToSet == L_EXTERNAL ) + typeToSet = (LangType)(id - IDM_LANG_EXTERNAL + L_EXTERNAL); Buffer *buf = MainFileManager.getBufferByID(lastOpened); @@ -2156,6 +2158,8 @@ bool Notepad_plus::loadSession(Session & session, bool isSnapshotMode, bool shou if (id != 0) typeToSet = menuID2LangType(id); + if (typeToSet == L_EXTERNAL ) + typeToSet = (LangType)(id - IDM_LANG_EXTERNAL + L_EXTERNAL); Buffer * buf = MainFileManager.getBufferByID(lastOpened); diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index dd31fea1b..89fa31655 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -934,6 +934,11 @@ NppParameters::~NppParameters() delete _userLangArray[i]; if (_hUXTheme) FreeLibrary(_hUXTheme); + + for (std::vector::iterator it = _pXmlExternalLexerDoc.begin(), end = _pXmlExternalLexerDoc.end(); it != end; ++it ) + delete (*it); + + _pXmlExternalLexerDoc.clear(); } @@ -970,6 +975,11 @@ bool NppParameters::reloadStylers(const TCHAR* stylePath) getUserStylersFromXmlTree(); + // Reload plugin styles. + for ( size_t i = 0; i < getExternalLexerDoc()->size(); ++i) + { + getExternalLexerFromXmlTree( getExternalLexerDoc()->at(i) ); + } return true; } @@ -1032,6 +1042,7 @@ generic_string NppParameters::getSettingsFolder() bool NppParameters::load() { + L_END = L_EXTERNAL; bool isAllLaoded = true; _isx64 = sizeof(void *) == 8; @@ -1470,6 +1481,10 @@ bool NppParameters::load() getSessionFromXmlTree(pXmlSessionDoc, _session); delete pXmlSessionDoc; + + for (size_t i = 0, len = _pXmlExternalLexerDoc.size() ; i < len ; ++i) + if (_pXmlExternalLexerDoc[i]) + delete _pXmlExternalLexerDoc[i]; } //-------------------------------------------------------------// @@ -1575,6 +1590,21 @@ void NppParameters::SetTransparent(HWND hwnd, int percent) } } + +bool NppParameters::isExistingExternalLangName(const TCHAR *newName) const +{ + if ((!newName) || (!newName[0])) + return true; + + for (int i = 0 ; i < _nbExternalLang ; ++i) + { + if (!lstrcmp(_externalLangArray[i]->_name, newName)) + return true; + } + return false; +} + + const TCHAR* NppParameters::getUserDefinedLangNameFromExt(TCHAR *ext, TCHAR *fullName) const { if ((!ext) || (!ext[0])) @@ -1612,6 +1642,18 @@ const TCHAR* NppParameters::getUserDefinedLangNameFromExt(TCHAR *ext, TCHAR *ful return nullptr; } + +int NppParameters::getExternalLangIndexFromName(const TCHAR* externalLangName) const +{ + for (int i = 0 ; i < _nbExternalLang ; ++i) + { + if (!lstrcmp(externalLangName, _externalLangArray[i]->_name)) + return i; + } + return -1; +} + + UserLangContainer* NppParameters::getULCFromName(const TCHAR *userLangName) { for (int i = 0 ; i < _nbUserLang ; ++i) @@ -1714,6 +1756,25 @@ void NppParameters::getLangKeywordsFromXmlTree() feedKeyWordsParameters(root); } + +void NppParameters::getExternalLexerFromXmlTree(TiXmlDocument *doc) +{ + TiXmlNode *root = doc->FirstChild(TEXT("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() { TiXmlNode *root = _pXmlUserStylerDoc->FirstChild(TEXT("NotepadPlus")); @@ -2813,7 +2874,7 @@ std::pair NppParameters::feedUserLang(TiXmlNode *n } } - catch (const std::exception&) + catch (const std::exception& /*e*/) { delete _userLangArray[--_nbUserLang]; } @@ -3603,9 +3664,16 @@ bool NppParameters::feedStylerArray(TiXmlNode *node) const TCHAR *lexerName = element->Attribute(TEXT("name")); const TCHAR *lexerDesc = element->Attribute(TEXT("desc")); const TCHAR *lexerUserExt = element->Attribute(TEXT("ext")); + const TCHAR *lexerExcluded = element->Attribute(TEXT("excluded")); if (lexerName) { _lexerStylerVect.addLexerStyler(lexerName, lexerDesc, lexerUserExt, childNode); + if (lexerExcluded != NULL && (lstrcmp(lexerExcluded, TEXT("yes")) == 0)) + { + int index = getExternalLangIndexFromName(lexerName); + if (index != -1) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)(index + L_EXTERNAL))); + } } } @@ -3888,15 +3956,24 @@ TiXmlNode * NppParameters::getChildElementByAttribut(TiXmlNode *pere, const TCHA LangType NppParameters::getLangIDFromStr(const TCHAR *langName) { int lang = static_cast(L_TEXT); - for (; lang < L_END; ++lang) + for (; lang < L_EXTERNAL; ++lang) { - const TCHAR * name = ScintillaEditView::_langNames[lang].lexerName; + const TCHAR * name = ScintillaEditView::langNames[lang].lexerName; if (!lstrcmp(name, langName)) //found lang? { return (LangType)lang; } } + //Cannot find language, check if its an external one + + LangType l = (LangType)lang; + if (l == L_EXTERNAL) //try find external lexer + { + int id = NppParameters::getInstance().getExternalLangIndexFromName(langName); + if (id != -1) return (LangType)(id + L_EXTERNAL); + } + return L_TEXT; } @@ -6747,7 +6824,7 @@ void NppParameters::writeExcludedLangList(TiXmlElement *element) for (size_t i = 0, len = _nppGUI._excludedLangList.size(); i < len ; ++i) { LangType langType = _nppGUI._excludedLangList[i]._langType; - if (langType >= L_END) + if (langType >= L_EXTERNAL && langType < L_END) continue; int nGrp = langType / groupNbMember; @@ -7047,7 +7124,10 @@ int NppParameters::langTypeToCommandID(LangType lt) const 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; } @@ -7124,6 +7204,42 @@ generic_string NppParameters::writeStyles(LexerStylerArray & lexersStylers, Styl } } + for (size_t x = 0; x < _pXmlExternalLexerDoc.size(); ++x) + { + TiXmlNode* lexersRoot2 = ( _pXmlExternalLexerDoc[x]->FirstChild(TEXT("NotepadPlus")))->FirstChildElement(TEXT("LexerStyles")); + for (TiXmlNode* childNode = lexersRoot2->FirstChildElement(TEXT("LexerType")); + childNode ; + childNode = childNode->NextSibling(TEXT("LexerType"))) + { + TiXmlElement *element = childNode->ToElement(); + const TCHAR *nm = element->Attribute(TEXT("name")); + + LexerStyler *pLs = _lexerStylerVect.getLexerStylerByName(nm); + LexerStyler *pLs2 = lexersStylers.getLexerStylerByName(nm); + + if (pLs) + { + const TCHAR *extStr = pLs->getLexerUserExt(); + element->SetAttribute(TEXT("ext"), extStr); + + for (TiXmlNode *grChildNode = childNode->FirstChildElement(TEXT("WordsStyle")); + grChildNode ; + grChildNode = grChildNode->NextSibling(TEXT("WordsStyle"))) + { + TiXmlElement *grElement = grChildNode->ToElement(); + const TCHAR *styleName = grElement->Attribute(TEXT("name")); + const Style * pStyle = pLs->findByName(styleName); + Style * pStyle2Sync = pLs2 ? pLs2->findByName(styleName) : nullptr; + if (pStyle && pStyle2Sync) + { + writeStyle2Element(*pStyle, *pStyle2Sync, grElement); + } + } + } + } + _pXmlExternalLexerDoc[x]->SaveFile(); + } + TiXmlNode *globalStylesRoot = (_pXmlUserStylerDoc->FirstChild(TEXT("NotepadPlus")))->FirstChildElement(TEXT("GlobalStyles")); for (TiXmlNode *childNode = globalStylesRoot->FirstChildElement(TEXT("WidgetStyle")); diff --git a/PowerEditor/src/Parameters.h b/PowerEditor/src/Parameters.h index 95e848f20..0f0d3a93e 100644 --- a/PowerEditor/src/Parameters.h +++ b/PowerEditor/src/Parameters.h @@ -241,7 +241,7 @@ struct CmdLineParams bool _isRecursive = false; bool _openFoldersAsWorkspace = false; - LangType _langType = L_END; + LangType _langType = L_EXTERNAL; generic_string _localizationPath; generic_string _udlName; @@ -274,7 +274,7 @@ struct CmdLineParamsDTO intptr_t _column2go = 0; intptr_t _pos2go = 0; - LangType _langType = L_END; + LangType _langType = L_EXTERNAL; generic_string _udlName; static CmdLineParamsDTO FromCmdLineParams(const CmdLineParams& params) @@ -1072,6 +1072,25 @@ private: friend class StylerDlg; }; +#define MAX_EXTERNAL_LEXER_NAME_LEN 16 +#define MAX_EXTERNAL_LEXER_DESC_LEN 32 + + + +class ExternalLangContainer final +{ +public: + TCHAR _name[MAX_EXTERNAL_LEXER_NAME_LEN]; + TCHAR _desc[MAX_EXTERNAL_LEXER_DESC_LEN]; + ExternalLexerAutoIndentMode _autoIndentMode = ExternalLexerAutoIndentMode::Standard; + + ExternalLangContainer(const TCHAR* name, const TCHAR* desc) + { + generic_strncpy(_name, name, MAX_EXTERNAL_LEXER_NAME_LEN); + generic_strncpy(_desc, desc, MAX_EXTERNAL_LEXER_DESC_LEN); + } +}; + struct FindHistory final { @@ -1268,6 +1287,7 @@ public: generic_string getSettingsFolder(); bool _isTaskListRBUTTONUP_Active = false; + int L_END; NppGUI & getNppGUI() { return _nppGUI; @@ -1382,6 +1402,16 @@ public: UserLangContainer & getULCFromIndex(size_t i) {return *_userLangArray[i];}; UserLangContainer * getULCFromName(const TCHAR *userLangName); + int getNbExternalLang() const {return _nbExternalLang;}; + int getExternalLangIndexFromName(const TCHAR *externalLangName) const; + + ExternalLangContainer & getELCFromIndex(int i) {return *_externalLangArray[i];}; + + bool ExternalLangHasRoom() const {return _nbExternalLang < NB_MAX_EXTERNAL_LANG;}; + + void getExternalLexerFromXmlTree(TiXmlDocument *doc); + std::vector * getExternalLexerDoc() { return &_pXmlExternalLexerDoc; }; + void writeDefaultUDL(); void writeNonDefaultUDL(); void writeNeed2SaveUDL(); @@ -1407,6 +1437,10 @@ public: int addUserLangToEnd(const UserLangContainer & userLang, const TCHAR *newName); void removeUserLang(size_t index); + bool isExistingExternalLangName(const TCHAR *newName) const; + + int addExternalLangToEnd(ExternalLangContainer * externalLang); + TiXmlDocumentA * getNativeLangA() const {return _pXmlNativeLangDocA;}; TiXmlDocument * getToolIcons() const {return _pXmlToolIconsDoc;}; @@ -1648,6 +1682,8 @@ private: TiXmlDocumentA *_pXmlNativeLangDocA = nullptr; TiXmlDocumentA *_pXmlContextMenuDocA = nullptr; + std::vector _pXmlExternalLexerDoc; + NppGUI _nppGUI; ScintillaViewParams _svp; Lang* _langList[NB_LANG] = { nullptr }; @@ -1668,6 +1704,7 @@ private: unsigned char _nbUserLang = 0; // won't be exceeded to 255; generic_string _userDefineLangsFolderPath; generic_string _userDefineLangPath; + ExternalLangContainer* _externalLangArray[NB_MAX_EXTERNAL_LANG] = { nullptr }; int _nbExternalLang = 0; CmdLineParamsDTO _cmdLineParams; diff --git a/PowerEditor/src/ScintillaComponent/AutoCompletion.cpp b/PowerEditor/src/ScintillaComponent/AutoCompletion.cpp index 8448f880a..dd1830eed 100644 --- a/PowerEditor/src/ScintillaComponent/AutoCompletion.cpp +++ b/PowerEditor/src/ScintillaComponent/AutoCompletion.cpp @@ -1065,12 +1065,15 @@ const TCHAR * AutoCompletion::getApiFileName() } } - if (_curLang > L_END) + if (_curLang >= L_EXTERNAL && _curLang < NppParameters::getInstance().L_END) + return NppParameters::getInstance().getELCFromIndex(_curLang - L_EXTERNAL)._name; + + if (_curLang > L_EXTERNAL) _curLang = L_TEXT; if (_curLang == L_JAVASCRIPT) _curLang = L_JS; - return ScintillaEditView::_langNames[_curLang].lexerName; + return ScintillaEditView::langNames[_curLang].lexerName; } diff --git a/PowerEditor/src/ScintillaComponent/Buffer.cpp b/PowerEditor/src/ScintillaComponent/Buffer.cpp index afa826694..1f300565b 100644 --- a/PowerEditor/src/ScintillaComponent/Buffer.cpp +++ b/PowerEditor/src/ScintillaComponent/Buffer.cpp @@ -1444,13 +1444,23 @@ bool FileManager::loadFileData(Document doc, int64_t fileSize, const TCHAR * fil } _pscratchTilla->execute(SCI_CLEARALL); - int lexerID = SCLEX_NULL; - if (fileFormat._language < L_END) - { - lexerID = ScintillaEditView::_langNames[fileFormat._language].lexerID; - } - _pscratchTilla->setLexerFromID(lexerID); + if (fileFormat._language < L_EXTERNAL) + { +#pragma warning( push ) +#pragma warning( disable : 4996) + const char* pName = LexerNameFromID(ScintillaEditView::langNames[fileFormat._language].lexerID); //deprecated, therefore disabled warning +#pragma warning( pop ) + _pscratchTilla->execute(SCI_SETILEXER, 0, reinterpret_cast(CreateLexer(pName))); + } + else + { + int id = fileFormat._language - L_EXTERNAL; + TCHAR * name = nppParam.getELCFromIndex(id)._name; + WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance(); + const char *pName = wmc.wchar2char(name, CP_ACP); + _pscratchTilla->execute(SCI_SETILEXER, 0, reinterpret_cast(CreateLexer(pName))); + } if (fileFormat._encoding != -1) _pscratchTilla->execute(SCI_SETCODEPAGE, SC_CP_UTF8); diff --git a/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp b/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp index 81b593796..9496634fd 100644 --- a/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp +++ b/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp @@ -18,8 +18,8 @@ #include #include "FindReplaceDlg.h" #include "ScintillaEditView.h" -#include "ILexer.h" -#include "Lexilla.h" +#include +#include #include "Notepad_plus_msgs.h" #include "localization.h" #include "Utf8.h" @@ -2314,9 +2314,6 @@ int FindReplaceDlg::processRange(ProcessOperation op, FindReplaceInfo & findRepl if (!isCreated() && !findReplaceInfo._txt2find) return nbProcessed; - if (!_ppEditView) - return nbProcessed; - ScintillaEditView *pEditView = *_ppEditView; if (view2Process) pEditView = view2Process; @@ -4314,7 +4311,7 @@ void Finder::setFinderStyle() NppDarkMode::setBorder(_scintView.getHSelf()); // Set current line background color for the finder - const TCHAR * lexerName = ScintillaEditView::_langNames[L_SEARCHRESULT].lexerName; + const TCHAR * lexerName = ScintillaEditView::langNames[L_SEARCHRESULT].lexerName; LexerStyler *pStyler = (NppParameters::getInstance().getLStylerArray()).getLexerStylerByName(lexerName); if (pStyler) { diff --git a/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp b/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp index d36b7e8d6..31b0be165 100644 --- a/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp +++ b/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp @@ -61,7 +61,7 @@ const int ScintillaEditView::_markersArray[][NB_FOLDER_STATE] = { // Array with all the names of all languages // The order of lang type (enum LangType) must be respected -LanguageName ScintillaEditView::_langNames[L_END + 1] = { +LanguageName ScintillaEditView::langNames[L_EXTERNAL + 1] = { {TEXT("normal"), TEXT("Normal text"), TEXT("Normal text file"), L_TEXT, SCLEX_NULL}, {TEXT("php"), TEXT("PHP"), TEXT("PHP Hypertext Preprocessor file"), L_PHP, SCLEX_HTML}, {TEXT("c"), TEXT("C"), TEXT("C source file"), L_C, SCLEX_CPP}, @@ -148,7 +148,7 @@ LanguageName ScintillaEditView::_langNames[L_END + 1] = { {TEXT("txt2tags"), TEXT("txt2tags"), TEXT("txt2tags file"), L_TXT2TAGS, SCLEX_TXT2TAGS}, {TEXT("visualprolog"), TEXT("Visual Prolog"), TEXT("Visual Prolog file"), L_VISUALPROLOG, SCLEX_VISUALPROLOG}, {TEXT("typescript"), TEXT("TypeScript"), TEXT("TypeScript file"), L_TYPESCRIPT, SCLEX_CPP}, -{TEXT("endOfLang"), TEXT("EndOfLang"), TEXT("End of Language"), L_END, SCLEX_NULL} +{TEXT("ext"), TEXT("External"), TEXT("External"), L_EXTERNAL, SCLEX_NULL} }; //const int MASK_RED = 0xFF0000; @@ -877,6 +877,36 @@ void ScintillaEditView::setUserLexer(const TCHAR *userLangName) } } +void ScintillaEditView::setExternalLexer(LangType typeDoc) +{ + int id = typeDoc - L_EXTERNAL; + TCHAR * name = NppParameters::getInstance().getELCFromIndex(id)._name; + + WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance(); + const char *pName = wmc.wchar2char(name, CP_ACP); + + execute(SCI_SETILEXER, 0, reinterpret_cast(CreateLexer(pName))); + + LexerStyler *pStyler = (NppParameters::getInstance().getLStylerArray()).getLexerStylerByName(name); + if (pStyler) + { + for (const Style & style : *pStyler) + { + setStyle(style); + + if (style._keywordClass >= 0 && style._keywordClass <= KEYWORDSET_MAX) + { + basic_string keywordList(""); + if (!style._keywords.empty()) + { + keywordList = wstring2string(style._keywords, CP_ACP); + } + execute(SCI_SETKEYWORDS, style._keywordClass, reinterpret_cast(getCompleteKeywordList(keywordList, typeDoc, style._keywordClass))); + } + } + } +} + void ScintillaEditView::setCppLexer(LangType langType) { const char *cppInstrs; @@ -944,7 +974,7 @@ void ScintillaEditView::setJsLexer() execute(SCI_SETKEYWORDS, 2, reinterpret_cast(doxygenKeyWords_char)); } - const TCHAR *newLexerName = ScintillaEditView::_langNames[L_JAVASCRIPT].lexerName; + const TCHAR *newLexerName = ScintillaEditView::langNames[L_JAVASCRIPT].lexerName; LexerStyler *pNewStyler = (NppParameters::getInstance().getLStylerArray()).getLexerStylerByName(newLexerName); if (pNewStyler) // New js styler is available, so we can use it do more modern styling { @@ -984,7 +1014,7 @@ void ScintillaEditView::setJsLexer() } else // New js styler is not available, we use the old styling for the sake of retro-compatibility { - const TCHAR *lexerName = ScintillaEditView::_langNames[L_JS].lexerName; + const TCHAR *lexerName = ScintillaEditView::langNames[L_JS].lexerName; LexerStyler *pOldStyler = (NppParameters::getInstance().getLStylerArray()).getLexerStylerByName(lexerName); if (pOldStyler) @@ -1256,7 +1286,7 @@ void ScintillaEditView::setLexer(int lexerID, LangType langType, int whichList) void ScintillaEditView::makeStyle(LangType language, const TCHAR **keywordArray) { - const TCHAR * lexerName = ScintillaEditView::_langNames[language].lexerName; + const TCHAR * lexerName = ScintillaEditView::langNames[language].lexerName; LexerStyler *pStyler = (NppParameters::getInstance().getLStylerArray()).getLexerStylerByName(lexerName); if (pStyler) { @@ -1675,7 +1705,10 @@ void ScintillaEditView::defineDocType(LangType typeDoc) case L_TEXT : default : - setLexerFromID(SCLEX_NULL); + if (typeDoc >= L_EXTERNAL && typeDoc < NppParameters::getInstance().L_END) + setExternalLexer(typeDoc); + else + setLexerFromID((_codepage == CP_CHINESE_TRADITIONAL) ? SCLEX_MAKEFILE : SCLEX_NULL); break; } diff --git a/PowerEditor/src/ScintillaComponent/ScintillaEditView.h b/PowerEditor/src/ScintillaComponent/ScintillaEditView.h index 733d03320..3e8d0b7f2 100644 --- a/PowerEditor/src/ScintillaComponent/ScintillaEditView.h +++ b/PowerEditor/src/ScintillaComponent/ScintillaEditView.h @@ -541,7 +541,7 @@ public: bool getIndicatorRange(size_t indicatorNumber, size_t* from = NULL, size_t* to = NULL, size_t* cur = NULL); - static LanguageName _langNames[L_END + 1]; + static LanguageName langNames[L_EXTERNAL+1]; void bufferUpdated(Buffer * buffer, int mask); BufferID getCurrentBufferID() { return _currentBufferID; }; @@ -609,7 +609,6 @@ public: void setPositionRestoreNeeded(bool val) { _positionRestoreNeeded = val; }; void markedTextToClipboard(int indiStyle, bool doAll = false); void removeAnyDuplicateLines(); - bool setLexerFromID(int lexerID); protected: static bool _SciInit; @@ -651,6 +650,7 @@ protected: const char * getCompleteKeywordList(std::basic_string & kwl, LangType langType, int keywordIndex); void setKeywords(LangType langType, const char *keywords, int index); void setLexer(int lexerID, LangType langType, int whichList); + bool setLexerFromID(int lexerID); void makeStyle(LangType langType, const TCHAR **keywordArray = NULL); void setStyle(Style styleToSet); //NOT by reference (style edited) void setSpecialStyle(const Style & styleToSet); //by reference @@ -665,6 +665,7 @@ protected: void setTclLexer(); void setObjCLexer(LangType type); void setUserLexer(const TCHAR *userLangName = NULL); + void setExternalLexer(LangType typeDoc); void setEmbeddedJSLexer(); void setEmbeddedPhpLexer(); void setEmbeddedAspLexer(); diff --git a/PowerEditor/src/WinControls/FunctionList/functionParser.cpp b/PowerEditor/src/WinControls/FunctionList/functionParser.cpp index 5439aba24..1f44f67e3 100644 --- a/PowerEditor/src/WinControls/FunctionList/functionParser.cpp +++ b/PowerEditor/src/WinControls/FunctionList/functionParser.cpp @@ -23,7 +23,7 @@ using namespace std; FunctionParsersManager::~FunctionParsersManager() { - for (size_t i = 0, len = L_END + nbMaxUserDefined; i < len; ++i) + for (size_t i = 0, len = L_EXTERNAL + nbMaxUserDefined; i < len; ++i) { if (_parsers[i] != nullptr) delete _parsers[i]; @@ -160,7 +160,7 @@ bool FunctionParsersManager::loadFuncListFromXmlTree(generic_string & xmlDirPath index = lType; if (overrideId.empty()) { - generic_string lexerName = ScintillaEditView::_langNames[lType].lexerName; + generic_string lexerName = ScintillaEditView::langNames[lType].lexerName; funcListRulePath += lexerName; funcListRulePath += TEXT(".xml"); } @@ -281,7 +281,7 @@ bool FunctionParsersManager::getOverrideMapFromXmlTree(generic_string & xmlDirPa } else if (userDefinedLangName && userDefinedLangName[0]) { - if (_currentUDIndex < L_END + nbMaxUserDefined) + if (_currentUDIndex < L_EXTERNAL + nbMaxUserDefined) { ++_currentUDIndex; _parsers[_currentUDIndex] = new ParserInfo(id, userDefinedLangName); @@ -343,10 +343,10 @@ FunctionParser * FunctionParsersManager::getParser(const AssociationInfo & assoI case checkUserDefined: { - if (_currentUDIndex == L_END) // no User Defined Language parser + if (_currentUDIndex == L_EXTERNAL) // no User Defined Language parser return nullptr; - for (int i = L_END + 1; i <= _currentUDIndex; ++i) + for (int i = L_EXTERNAL + 1; i <= _currentUDIndex; ++i) { if (_parsers[i]->_userDefinedLangName == assoInfo._userDefinedLangName) { diff --git a/PowerEditor/src/WinControls/FunctionList/functionParser.h b/PowerEditor/src/WinControls/FunctionList/functionParser.h index cf1956e24..5344ec6ae 100644 --- a/PowerEditor/src/WinControls/FunctionList/functionParser.h +++ b/PowerEditor/src/WinControls/FunctionList/functionParser.h @@ -156,8 +156,8 @@ private: generic_string _xmlDirPath; // The 1st place to load function list files. Usually it's "%APPDATA%\Notepad++\functionList\" generic_string _xmlDirInstalledPath; // Where Notepad++ is installed. The 2nd place to load function list files. Usually it's "%PROGRAMFILES%\Notepad++\functionList\" - ParserInfo* _parsers[L_END + nbMaxUserDefined] = {nullptr}; - int _currentUDIndex = L_END; + ParserInfo* _parsers[L_EXTERNAL + nbMaxUserDefined] = {nullptr}; + int _currentUDIndex = L_EXTERNAL; bool getOverrideMapFromXmlTree(generic_string & xmlDirPath); bool loadFuncListFromXmlTree(generic_string & xmlDirPath, LangType lType, const generic_string& overrideId, int udlIndex = -1); diff --git a/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp b/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp index 1cfd882ed..b907ba58e 100644 --- a/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp +++ b/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp @@ -1933,7 +1933,7 @@ intptr_t CALLBACK NewDocumentSubDlg::run_dlgProc(UINT message, WPARAM wParam, LP ::SendDlgItemMessage(_hSelf, IDC_CHECK_OPENANSIASUTF8, BM_SETCHECK, (ID2Check == IDC_RADIO_UTF8SANSBOM && ndds._openAnsiAsUtf8)?BST_CHECKED:BST_UNCHECKED, 0); ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_OPENANSIASUTF8), ID2Check == IDC_RADIO_UTF8SANSBOM); - for (int i = L_TEXT + 1 ; i < L_END ; ++i) // Skip L_TEXT + for (int i = L_TEXT + 1 ; i < nppParam.L_END ; ++i) // Skip L_TEXT { LangType lt = static_cast(i); str.clear(); @@ -2372,7 +2372,7 @@ intptr_t CALLBACK LanguageSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPARA // // Lang Menu // - for (int i = L_TEXT ; i < L_END ; ++i) + for (int i = L_TEXT ; i < nppParam.L_END ; ++i) { generic_string str; if (static_cast(i) != L_USER) @@ -2626,6 +2626,29 @@ intptr_t CALLBACK LanguageSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPARA ::EnableWindow(::GetDlgItem(_hSelf, idButton2Enable), TRUE); ::EnableWindow(::GetDlgItem(_hSelf, idButton2Disable), FALSE); + if ((lmi._langType >= L_EXTERNAL) && (lmi._langType < nppParam.L_END)) + { + bool found(false); + for (size_t x = 0; x < nppParam.getExternalLexerDoc()->size() && !found; ++x) + { + TiXmlNode *lexersRoot = nppParam.getExternalLexerDoc()->at(x)->FirstChild(TEXT("NotepadPlus"))->FirstChildElement(TEXT("LexerStyles")); + for (TiXmlNode *childNode = lexersRoot->FirstChildElement(TEXT("LexerType")); + childNode ; + childNode = childNode->NextSibling(TEXT("LexerType"))) + { + TiXmlElement *element = childNode->ToElement(); + + if (generic_string(element->Attribute(TEXT("name"))) == lmi._langName) + { + element->SetAttribute(TEXT("excluded"), (LOWORD(wParam)==IDC_BUTTON_REMOVE)?TEXT("yes"):TEXT("no")); + nppParam.getExternalLexerDoc()->at(x)->SaveFile(); + found = true; + break; + } + } + } + } + HWND grandParent = ::GetParent(_hParent); if (LOWORD(wParam)==IDC_BUTTON_REMOVE) diff --git a/PowerEditor/src/menuCmdID.h b/PowerEditor/src/menuCmdID.h index 01cb9b355..b5618f140 100644 --- a/PowerEditor/src/menuCmdID.h +++ b/PowerEditor/src/menuCmdID.h @@ -526,8 +526,8 @@ #define IDM_LANG_VISUALPROLOG (IDM_LANG + 83) #define IDM_LANG_TYPESCRIPT (IDM_LANG + 84) - //#define IDM_LANG_EXTERNAL (IDM_LANG + 165) - //#define IDM_LANG_EXTERNAL_LIMIT (IDM_LANG + 179) + #define IDM_LANG_EXTERNAL (IDM_LANG + 165) + #define IDM_LANG_EXTERNAL_LIMIT (IDM_LANG + 179) #define IDM_LANG_USER (IDM_LANG + 180) //46180: Used for translation #define IDM_LANG_USER_LIMIT (IDM_LANG + 210) //46210: Ajust with IDM_LANG_USER diff --git a/PowerEditor/src/winmain.cpp b/PowerEditor/src/winmain.cpp index c9ade407c..74a476794 100644 --- a/PowerEditor/src/winmain.cpp +++ b/PowerEditor/src/winmain.cpp @@ -226,7 +226,7 @@ LangType getLangTypeFromParam(ParamVector & params) { generic_string langStr; if (!getParamVal('l', params, langStr)) - return L_TEXT; + return L_EXTERNAL; return NppParameters::getLangIDFromStr(langStr.c_str()); }