mirror of
https://github.com/notepad-plus-plus/notepad-plus-plus.git
synced 2025-07-21 12:54:42 +02:00
Make external language library work again after upgrading to Scintilla5
Make external lexer library work again after upgrading to Scintilla5. Old external lexer libraries needs to add CreateLexer export function which returns ILexer5 instance (Lexilla protocol interface of Scintilla5). Tested with papyrus lexer plugin, this external lexer plugin is compatible with Notepad++ next release: https://github.com/blu3mania/npp-papyrus Close #11468
This commit is contained in:
parent
252468c29b
commit
121a396bf0
@ -22,6 +22,8 @@
|
|||||||
#include "PluginsManager.h"
|
#include "PluginsManager.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "pluginsAdmin.h"
|
#include "pluginsAdmin.h"
|
||||||
|
#include "ILexer.h"
|
||||||
|
#include "Lexilla.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -169,40 +171,58 @@ int PluginsManager::loadPlugin(const TCHAR *pluginFilePath)
|
|||||||
|
|
||||||
pi->_pluginMenu = ::CreateMenu();
|
pi->_pluginMenu = ::CreateMenu();
|
||||||
|
|
||||||
GetLexerCountFn GetLexerCount = (GetLexerCountFn)::GetProcAddress(pi->_hLib, "GetLexerCount");
|
Lexilla::GetLexerCountFn GetLexerCount = (Lexilla::GetLexerCountFn)::GetProcAddress(pi->_hLib, LEXILLA_GETLEXERCOUNT);
|
||||||
// it's a lexer plugin
|
// it's a lexer plugin
|
||||||
if (GetLexerCount)
|
if (GetLexerCount)
|
||||||
{
|
{
|
||||||
GetLexerNameFn GetLexerName = (GetLexerNameFn)::GetProcAddress(pi->_hLib, "GetLexerName");
|
Lexilla::GetLexerNameFn GetLexerName = (Lexilla::GetLexerNameFn)::GetProcAddress(pi->_hLib, LEXILLA_GETLEXERNAME);
|
||||||
if (!GetLexerName)
|
if (!GetLexerName)
|
||||||
throw generic_string(TEXT("Loading GetLexerName function failed."));
|
throw generic_string(TEXT("Loading GetLexerName function failed."));
|
||||||
|
|
||||||
GetLexerStatusTextFn GetLexerStatusText = (GetLexerStatusTextFn)::GetProcAddress(pi->_hLib, "GetLexerStatusText");
|
//Lexilla::GetLexerFactoryFn GetLexerFactory = (Lexilla::GetLexerFactoryFn)::GetProcAddress(pi->_hLib, LEXILLA_GETLEXERFACTORY);
|
||||||
|
//if (!GetLexerFactory)
|
||||||
|
//throw generic_string(TEXT("Loading GetLexerFactory function failed."));
|
||||||
|
|
||||||
if (!GetLexerStatusText)
|
Lexilla::CreateLexerFn CreateLexer = (Lexilla::CreateLexerFn)::GetProcAddress(pi->_hLib, LEXILLA_CREATELEXER);
|
||||||
throw generic_string(TEXT("Loading GetLexerStatusText function failed."));
|
if (!CreateLexer)
|
||||||
|
throw generic_string(TEXT("Loading CreateLexer function failed."));
|
||||||
|
|
||||||
|
//Lexilla::GetLibraryPropertyNamesFn GetLibraryPropertyNames = (Lexilla::GetLibraryPropertyNamesFn)::GetProcAddress(pi->_hLib, LEXILLA_GETLIBRARYPROPERTYNAMES);
|
||||||
|
//if (!GetLibraryPropertyNames)
|
||||||
|
//throw generic_string(TEXT("Loading GetLibraryPropertyNames function failed."));
|
||||||
|
|
||||||
|
//Lexilla::SetLibraryPropertyFn SetLibraryProperty = (Lexilla::SetLibraryPropertyFn)::GetProcAddress(pi->_hLib, LEXILLA_SETLIBRARYPROPERTY);
|
||||||
|
//if (!SetLibraryProperty)
|
||||||
|
//throw generic_string(TEXT("Loading SetLibraryProperty function failed."));
|
||||||
|
|
||||||
|
//Lexilla::GetNameSpaceFn GetNameSpace = (Lexilla::GetNameSpaceFn)::GetProcAddress(pi->_hLib, LEXILLA_GETNAMESPACE);
|
||||||
|
//if (!GetNameSpace)
|
||||||
|
//throw generic_string(TEXT("Loading GetNameSpace function failed."));
|
||||||
|
|
||||||
// Assign a buffer for the lexer name.
|
// Assign a buffer for the lexer name.
|
||||||
char lexName[MAX_EXTERNAL_LEXER_NAME_LEN];
|
char lexName[MAX_EXTERNAL_LEXER_NAME_LEN];
|
||||||
lexName[0] = '\0';
|
lexName[0] = '\0';
|
||||||
TCHAR lexDesc[MAX_EXTERNAL_LEXER_DESC_LEN];
|
|
||||||
lexDesc[0] = '\0';
|
|
||||||
|
|
||||||
int numLexers = GetLexerCount();
|
int numLexers = GetLexerCount();
|
||||||
|
|
||||||
ExternalLangContainer* containers[30];
|
ExternalLangContainer* containers[30];
|
||||||
|
|
||||||
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
|
|
||||||
for (int x = 0; x < numLexers; ++x)
|
for (int x = 0; x < numLexers; ++x)
|
||||||
{
|
{
|
||||||
GetLexerName(x, lexName, MAX_EXTERNAL_LEXER_NAME_LEN);
|
GetLexerName(x, lexName, MAX_EXTERNAL_LEXER_NAME_LEN);
|
||||||
GetLexerStatusText(x, lexDesc, MAX_EXTERNAL_LEXER_DESC_LEN);
|
if (!nppParams.isExistingExternalLangName(lexName) && nppParams.ExternalLangHasRoom())
|
||||||
const TCHAR *pLexerName = wmc.char2wchar(lexName, CP_ACP);
|
{
|
||||||
if (!nppParams.isExistingExternalLangName(pLexerName) && nppParams.ExternalLangHasRoom())
|
containers[x] = new ExternalLangContainer;
|
||||||
containers[x] = new ExternalLangContainer(pLexerName, lexDesc);
|
containers[x]->_name = lexName;
|
||||||
|
containers[x]->fnCL = CreateLexer;
|
||||||
|
//containers[x]->fnGLPN = GetLibraryPropertyNames;
|
||||||
|
//containers[x]->fnSLP = SetLibraryProperty;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
containers[x] = NULL;
|
containers[x] = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TCHAR xmlPath[MAX_PATH];
|
TCHAR xmlPath[MAX_PATH];
|
||||||
wcscpy_s(xmlPath, nppParams.getNppPath().c_str());
|
wcscpy_s(xmlPath, nppParams.getNppPath().c_str());
|
||||||
@ -243,9 +263,12 @@ int PluginsManager::loadPlugin(const TCHAR *pluginFilePath)
|
|||||||
|
|
||||||
nppParams.getExternalLexerFromXmlTree(pXmlDoc);
|
nppParams.getExternalLexerFromXmlTree(pXmlDoc);
|
||||||
nppParams.getExternalLexerDoc()->push_back(pXmlDoc);
|
nppParams.getExternalLexerDoc()->push_back(pXmlDoc);
|
||||||
|
|
||||||
|
|
||||||
//const char *pDllName = wmc.wchar2char(pluginFilePath, CP_ACP);
|
//const char *pDllName = wmc.wchar2char(pluginFilePath, CP_ACP);
|
||||||
//::SendMessage(_nppData._scintillaMainHandle, SCI_LOADLEXERLIBRARY, 0, reinterpret_cast<LPARAM>(pDllName));
|
//::SendMessage(_nppData._scintillaMainHandle, SCI_LOADLEXERLIBRARY, 0, reinterpret_cast<LPARAM>(pDllName));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
addInLoadedDlls(pluginFilePath, pluginFileName);
|
addInLoadedDlls(pluginFilePath, pluginFileName);
|
||||||
_pluginInfos.push_back(pi);
|
_pluginInfos.push_back(pi);
|
||||||
|
@ -157,10 +157,3 @@ private:
|
|||||||
_loadedDlls.push_back(LoadedDllInfo(fullPath, fn));
|
_loadedDlls.push_back(LoadedDllInfo(fullPath, fn));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#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, TCHAR *desc, int buflength);
|
|
||||||
|
@ -467,6 +467,7 @@ LRESULT Notepad_plus::init(HWND hwnd)
|
|||||||
//Languages Menu
|
//Languages Menu
|
||||||
HMENU hLangMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_LANGUAGE);
|
HMENU hLangMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_LANGUAGE);
|
||||||
|
|
||||||
|
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
|
||||||
// Add external languages to menu
|
// Add external languages to menu
|
||||||
for (int i = 0; i < nppParam.getNbExternalLang(); ++i)
|
for (int i = 0; i < nppParam.getNbExternalLang(); ++i)
|
||||||
{
|
{
|
||||||
@ -475,14 +476,15 @@ LRESULT Notepad_plus::init(HWND hwnd)
|
|||||||
int numLangs = ::GetMenuItemCount(hLangMenu);
|
int numLangs = ::GetMenuItemCount(hLangMenu);
|
||||||
const int bufferSize = 100;
|
const int bufferSize = 100;
|
||||||
TCHAR buffer[bufferSize];
|
TCHAR buffer[bufferSize];
|
||||||
|
const TCHAR* lexerNameW = wmc.char2wchar(externalLangContainer._name.c_str(), CP_ACP);
|
||||||
|
|
||||||
int x;
|
int x = 0;
|
||||||
for (x = 0; (x == 0 || lstrcmp(externalLangContainer._name, buffer) > 0) && x < numLangs; ++x)
|
for (; (x == 0 || lstrcmp(lexerNameW, buffer) > 0) && x < numLangs; ++x)
|
||||||
{
|
{
|
||||||
::GetMenuString(hLangMenu, x, buffer, bufferSize, MF_BYPOSITION);
|
::GetMenuString(hLangMenu, x, buffer, bufferSize, MF_BYPOSITION);
|
||||||
}
|
}
|
||||||
|
|
||||||
::InsertMenu(hLangMenu, x - 1, MF_BYPOSITION, IDM_LANG_EXTERNAL + i, externalLangContainer._name);
|
::InsertMenu(hLangMenu, x - 1, MF_BYPOSITION, IDM_LANG_EXTERNAL + i, lexerNameW);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nppGUI._excludedLangList.size() > 0)
|
if (nppGUI._excludedLangList.size() > 0)
|
||||||
@ -2363,10 +2365,9 @@ generic_string Notepad_plus::getLangDesc(LangType langType, bool getName)
|
|||||||
if ((langType >= L_EXTERNAL) && (langType < nppParams.L_END))
|
if ((langType >= L_EXTERNAL) && (langType < nppParams.L_END))
|
||||||
{
|
{
|
||||||
ExternalLangContainer & elc = nppParams.getELCFromIndex(langType - L_EXTERNAL);
|
ExternalLangContainer & elc = nppParams.getELCFromIndex(langType - L_EXTERNAL);
|
||||||
if (getName)
|
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
|
||||||
return generic_string(elc._name);
|
const TCHAR* lexerNameW = wmc.char2wchar(elc._name.c_str(), CP_ACP);
|
||||||
else
|
return generic_string(lexerNameW);
|
||||||
return generic_string(elc._desc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (langType > L_EXTERNAL)
|
if (langType > L_EXTERNAL)
|
||||||
|
@ -1591,14 +1591,14 @@ void NppParameters::SetTransparent(HWND hwnd, int percent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool NppParameters::isExistingExternalLangName(const TCHAR *newName) const
|
bool NppParameters::isExistingExternalLangName(const char* newName) const
|
||||||
{
|
{
|
||||||
if ((!newName) || (!newName[0]))
|
if ((!newName) || (!newName[0]))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (int i = 0 ; i < _nbExternalLang ; ++i)
|
for (int i = 0 ; i < _nbExternalLang ; ++i)
|
||||||
{
|
{
|
||||||
if (!lstrcmp(_externalLangArray[i]->_name, newName))
|
if (_externalLangArray[i]->_name == newName)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -1645,9 +1645,10 @@ const TCHAR* NppParameters::getUserDefinedLangNameFromExt(TCHAR *ext, TCHAR *ful
|
|||||||
|
|
||||||
int NppParameters::getExternalLangIndexFromName(const TCHAR* externalLangName) const
|
int NppParameters::getExternalLangIndexFromName(const TCHAR* externalLangName) const
|
||||||
{
|
{
|
||||||
|
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
|
||||||
for (int i = 0 ; i < _nbExternalLang ; ++i)
|
for (int i = 0 ; i < _nbExternalLang ; ++i)
|
||||||
{
|
{
|
||||||
if (!lstrcmp(externalLangName, _externalLangArray[i]->_name))
|
if (!lstrcmp(externalLangName, wmc.char2wchar(_externalLangArray[i]->_name.c_str(), CP_ACP)))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include "ILexer.h"
|
||||||
|
#include "Lexilla.h"
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
|
||||||
@ -1072,23 +1074,21 @@ private:
|
|||||||
friend class StylerDlg;
|
friend class StylerDlg;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_EXTERNAL_LEXER_NAME_LEN 16
|
#define MAX_EXTERNAL_LEXER_NAME_LEN 128
|
||||||
#define MAX_EXTERNAL_LEXER_DESC_LEN 32
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ExternalLangContainer final
|
class ExternalLangContainer final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TCHAR _name[MAX_EXTERNAL_LEXER_NAME_LEN];
|
// Mandatory for Lexilla
|
||||||
TCHAR _desc[MAX_EXTERNAL_LEXER_DESC_LEN];
|
std::string _name;
|
||||||
ExternalLexerAutoIndentMode _autoIndentMode = ExternalLexerAutoIndentMode::Standard;
|
Lexilla::CreateLexerFn fnCL = nullptr;
|
||||||
|
//Lexilla::GetLibraryPropertyNamesFn fnGLPN = nullptr;
|
||||||
|
//Lexilla::SetLibraryPropertyFn fnSLP = nullptr;
|
||||||
|
|
||||||
ExternalLangContainer(const TCHAR* name, const TCHAR* desc)
|
// For Notepad++
|
||||||
{
|
ExternalLexerAutoIndentMode _autoIndentMode = ExternalLexerAutoIndentMode::Standard;
|
||||||
generic_strncpy(_name, name, MAX_EXTERNAL_LEXER_NAME_LEN);
|
|
||||||
generic_strncpy(_desc, desc, MAX_EXTERNAL_LEXER_DESC_LEN);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1437,7 +1437,7 @@ public:
|
|||||||
int addUserLangToEnd(const UserLangContainer & userLang, const TCHAR *newName);
|
int addUserLangToEnd(const UserLangContainer & userLang, const TCHAR *newName);
|
||||||
void removeUserLang(size_t index);
|
void removeUserLang(size_t index);
|
||||||
|
|
||||||
bool isExistingExternalLangName(const TCHAR *newName) const;
|
bool isExistingExternalLangName(const char* newName) const;
|
||||||
|
|
||||||
int addExternalLangToEnd(ExternalLangContainer * externalLang);
|
int addExternalLangToEnd(ExternalLangContainer * externalLang);
|
||||||
|
|
||||||
|
@ -1066,7 +1066,10 @@ const TCHAR * AutoCompletion::getApiFileName()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_curLang >= L_EXTERNAL && _curLang < NppParameters::getInstance().L_END)
|
if (_curLang >= L_EXTERNAL && _curLang < NppParameters::getInstance().L_END)
|
||||||
return NppParameters::getInstance().getELCFromIndex(_curLang - L_EXTERNAL)._name;
|
{
|
||||||
|
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
|
||||||
|
return wmc.char2wchar(NppParameters::getInstance().getELCFromIndex(_curLang - L_EXTERNAL)._name.c_str(), CP_ACP);
|
||||||
|
}
|
||||||
|
|
||||||
if (_curLang > L_EXTERNAL)
|
if (_curLang > L_EXTERNAL)
|
||||||
_curLang = L_TEXT;
|
_curLang = L_TEXT;
|
||||||
|
@ -1456,10 +1456,10 @@ bool FileManager::loadFileData(Document doc, int64_t fileSize, const TCHAR * fil
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
int id = fileFormat._language - L_EXTERNAL;
|
int id = fileFormat._language - L_EXTERNAL;
|
||||||
TCHAR * name = nppParam.getELCFromIndex(id)._name;
|
ExternalLangContainer& externalLexer = nppParam.getELCFromIndex(id);
|
||||||
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
|
const char* lexerName = externalLexer._name.c_str();
|
||||||
const char *pName = wmc.wchar2char(name, CP_ACP);
|
if (externalLexer.fnCL)
|
||||||
_pscratchTilla->execute(SCI_SETILEXER, 0, reinterpret_cast<LPARAM>(CreateLexer(pName)));
|
_pscratchTilla->execute(SCI_SETILEXER, 0, reinterpret_cast<LPARAM>(externalLexer.fnCL(lexerName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileFormat._encoding != -1)
|
if (fileFormat._encoding != -1)
|
||||||
|
@ -880,14 +880,18 @@ void ScintillaEditView::setUserLexer(const TCHAR *userLangName)
|
|||||||
void ScintillaEditView::setExternalLexer(LangType typeDoc)
|
void ScintillaEditView::setExternalLexer(LangType typeDoc)
|
||||||
{
|
{
|
||||||
int id = typeDoc - L_EXTERNAL;
|
int id = typeDoc - L_EXTERNAL;
|
||||||
TCHAR * name = NppParameters::getInstance().getELCFromIndex(id)._name;
|
|
||||||
|
ExternalLangContainer& externalLexer = NppParameters::getInstance().getELCFromIndex(id);
|
||||||
|
if (!externalLexer.fnCL)
|
||||||
|
return;
|
||||||
|
ILexer5* iLex5 = externalLexer.fnCL(externalLexer._name.c_str());
|
||||||
|
if (!iLex5)
|
||||||
|
return;
|
||||||
|
execute(SCI_SETILEXER, 0, reinterpret_cast<LPARAM>(iLex5));
|
||||||
|
|
||||||
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
|
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
|
||||||
const char *pName = wmc.wchar2char(name, CP_ACP);
|
const wchar_t* lexerNameW = wmc.char2wchar(externalLexer._name.c_str(), CP_ACP);
|
||||||
|
LexerStyler *pStyler = (NppParameters::getInstance().getLStylerArray()).getLexerStylerByName(lexerNameW);
|
||||||
execute(SCI_SETILEXER, 0, reinterpret_cast<LPARAM>(CreateLexer(pName)));
|
|
||||||
|
|
||||||
LexerStyler *pStyler = (NppParameters::getInstance().getLStylerArray()).getLexerStylerByName(name);
|
|
||||||
if (pStyler)
|
if (pStyler)
|
||||||
{
|
{
|
||||||
for (const Style & style : *pStyler)
|
for (const Style & style : *pStyler)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user