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 "resource.h"
|
||||
#include "pluginsAdmin.h"
|
||||
#include "ILexer.h"
|
||||
#include "Lexilla.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -169,39 +171,57 @@ int PluginsManager::loadPlugin(const TCHAR *pluginFilePath)
|
|||
|
||||
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
|
||||
if (GetLexerCount)
|
||||
{
|
||||
GetLexerNameFn GetLexerName = (GetLexerNameFn)::GetProcAddress(pi->_hLib, "GetLexerName");
|
||||
Lexilla::GetLexerNameFn GetLexerName = (Lexilla::GetLexerNameFn)::GetProcAddress(pi->_hLib, LEXILLA_GETLEXERNAME);
|
||||
if (!GetLexerName)
|
||||
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)
|
||||
throw generic_string(TEXT("Loading GetLexerStatusText function failed."));
|
||||
Lexilla::CreateLexerFn CreateLexer = (Lexilla::CreateLexerFn)::GetProcAddress(pi->_hLib, LEXILLA_CREATELEXER);
|
||||
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.
|
||||
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];
|
||||
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);
|
||||
if (!nppParams.isExistingExternalLangName(lexName) && nppParams.ExternalLangHasRoom())
|
||||
{
|
||||
containers[x] = new ExternalLangContainer;
|
||||
containers[x]->_name = lexName;
|
||||
containers[x]->fnCL = CreateLexer;
|
||||
//containers[x]->fnGLPN = GetLibraryPropertyNames;
|
||||
//containers[x]->fnSLP = SetLibraryProperty;
|
||||
}
|
||||
else
|
||||
{
|
||||
containers[x] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TCHAR xmlPath[MAX_PATH];
|
||||
|
@ -243,9 +263,12 @@ int PluginsManager::loadPlugin(const TCHAR *pluginFilePath)
|
|||
|
||||
nppParams.getExternalLexerFromXmlTree(pXmlDoc);
|
||||
nppParams.getExternalLexerDoc()->push_back(pXmlDoc);
|
||||
|
||||
|
||||
//const char *pDllName = wmc.wchar2char(pluginFilePath, CP_ACP);
|
||||
//::SendMessage(_nppData._scintillaMainHandle, SCI_LOADLEXERLIBRARY, 0, reinterpret_cast<LPARAM>(pDllName));
|
||||
|
||||
|
||||
}
|
||||
addInLoadedDlls(pluginFilePath, pluginFileName);
|
||||
_pluginInfos.push_back(pi);
|
||||
|
|
|
@ -157,10 +157,3 @@ private:
|
|||
_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
|
||||
HMENU hLangMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_LANGUAGE);
|
||||
|
||||
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
|
||||
// Add external languages to menu
|
||||
for (int i = 0; i < nppParam.getNbExternalLang(); ++i)
|
||||
{
|
||||
|
@ -475,14 +476,15 @@ LRESULT Notepad_plus::init(HWND hwnd)
|
|||
int numLangs = ::GetMenuItemCount(hLangMenu);
|
||||
const int bufferSize = 100;
|
||||
TCHAR buffer[bufferSize];
|
||||
const TCHAR* lexerNameW = wmc.char2wchar(externalLangContainer._name.c_str(), CP_ACP);
|
||||
|
||||
int x;
|
||||
for (x = 0; (x == 0 || lstrcmp(externalLangContainer._name, buffer) > 0) && x < numLangs; ++x)
|
||||
int x = 0;
|
||||
for (; (x == 0 || lstrcmp(lexerNameW, buffer) > 0) && x < numLangs; ++x)
|
||||
{
|
||||
::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)
|
||||
|
@ -2363,10 +2365,9 @@ generic_string Notepad_plus::getLangDesc(LangType langType, bool getName)
|
|||
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);
|
||||
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
|
||||
const TCHAR* lexerNameW = wmc.char2wchar(elc._name.c_str(), CP_ACP);
|
||||
return generic_string(lexerNameW);
|
||||
}
|
||||
|
||||
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]))
|
||||
return true;
|
||||
|
||||
for (int i = 0 ; i < _nbExternalLang ; ++i)
|
||||
{
|
||||
if (!lstrcmp(_externalLangArray[i]->_name, newName))
|
||||
if (_externalLangArray[i]->_name == newName)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1645,9 +1645,10 @@ const TCHAR* NppParameters::getUserDefinedLangNameFromExt(TCHAR *ext, TCHAR *ful
|
|||
|
||||
int NppParameters::getExternalLangIndexFromName(const TCHAR* externalLangName) const
|
||||
{
|
||||
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
|
||||
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 -1;
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include <assert.h>
|
||||
#include <tchar.h>
|
||||
#include <map>
|
||||
#include "ILexer.h"
|
||||
#include "Lexilla.h"
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
|
@ -1072,23 +1074,21 @@ private:
|
|||
friend class StylerDlg;
|
||||
};
|
||||
|
||||
#define MAX_EXTERNAL_LEXER_NAME_LEN 16
|
||||
#define MAX_EXTERNAL_LEXER_DESC_LEN 32
|
||||
#define MAX_EXTERNAL_LEXER_NAME_LEN 128
|
||||
|
||||
|
||||
|
||||
class ExternalLangContainer final
|
||||
{
|
||||
public:
|
||||
TCHAR _name[MAX_EXTERNAL_LEXER_NAME_LEN];
|
||||
TCHAR _desc[MAX_EXTERNAL_LEXER_DESC_LEN];
|
||||
ExternalLexerAutoIndentMode _autoIndentMode = ExternalLexerAutoIndentMode::Standard;
|
||||
// Mandatory for Lexilla
|
||||
std::string _name;
|
||||
Lexilla::CreateLexerFn fnCL = nullptr;
|
||||
//Lexilla::GetLibraryPropertyNamesFn fnGLPN = nullptr;
|
||||
//Lexilla::SetLibraryPropertyFn fnSLP = nullptr;
|
||||
|
||||
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);
|
||||
}
|
||||
// For Notepad++
|
||||
ExternalLexerAutoIndentMode _autoIndentMode = ExternalLexerAutoIndentMode::Standard;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1437,7 +1437,7 @@ public:
|
|||
int addUserLangToEnd(const UserLangContainer & userLang, const TCHAR *newName);
|
||||
void removeUserLang(size_t index);
|
||||
|
||||
bool isExistingExternalLangName(const TCHAR *newName) const;
|
||||
bool isExistingExternalLangName(const char* newName) const;
|
||||
|
||||
int addExternalLangToEnd(ExternalLangContainer * externalLang);
|
||||
|
||||
|
|
|
@ -1066,7 +1066,10 @@ const TCHAR * AutoCompletion::getApiFileName()
|
|||
}
|
||||
|
||||
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)
|
||||
_curLang = L_TEXT;
|
||||
|
|
|
@ -1456,10 +1456,10 @@ bool FileManager::loadFileData(Document doc, int64_t fileSize, const TCHAR * fil
|
|||
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<LPARAM>(CreateLexer(pName)));
|
||||
ExternalLangContainer& externalLexer = nppParam.getELCFromIndex(id);
|
||||
const char* lexerName = externalLexer._name.c_str();
|
||||
if (externalLexer.fnCL)
|
||||
_pscratchTilla->execute(SCI_SETILEXER, 0, reinterpret_cast<LPARAM>(externalLexer.fnCL(lexerName)));
|
||||
}
|
||||
|
||||
if (fileFormat._encoding != -1)
|
||||
|
|
|
@ -880,14 +880,18 @@ void ScintillaEditView::setUserLexer(const TCHAR *userLangName)
|
|||
void ScintillaEditView::setExternalLexer(LangType typeDoc)
|
||||
{
|
||||
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();
|
||||
const char *pName = wmc.wchar2char(name, CP_ACP);
|
||||
|
||||
execute(SCI_SETILEXER, 0, reinterpret_cast<LPARAM>(CreateLexer(pName)));
|
||||
|
||||
LexerStyler *pStyler = (NppParameters::getInstance().getLStylerArray()).getLexerStylerByName(name);
|
||||
const wchar_t* lexerNameW = wmc.char2wchar(externalLexer._name.c_str(), CP_ACP);
|
||||
LexerStyler *pStyler = (NppParameters::getInstance().getLStylerArray()).getLexerStylerByName(lexerNameW);
|
||||
if (pStyler)
|
||||
{
|
||||
for (const Style & style : *pStyler)
|
||||
|
|
Loading…
Reference in New Issue