When using an external lexer and listening for messages (ie NPPN_FILEOPENED, or even SCN_MODIFIED) how can filtering be done so actions are only taken for languages that that specific lexer plugin is made to handle?
For example, with our Powershe11 lexer plugin, we need to be able to identify when a powershell file is first opened or changed; yet NPPM_GETCURRENTLANGTYPE only reports it as an external, and SCI_GETLEXER reports the language ID number but neither reveals the language name to match against the languages being styled by the plugin, or a way to determine the language ID associated with the lexer plugins languages. I imagine this is OK when there aren't many external lexers in use but what about when then are multiple ones?
I've been able to identify a few ways to 'closely' accomplish this, but something along the lines of a GETCURRENTLANGNAME and then iterating through the plugins styled languages would be of great benefit.
Thanks,
almostautomated
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
> I've been able to identify a few ways to 'closely' accomplish this
What's your approach?
> but something along the lines of a GETCURRENTLANGNAME and then
> iterating through the plugins styled languages would be of great benefit.
In the current implementation, GETCURRENTLANGNAME can work with internal language, but not with external lexer.
If your approach work, then great, otherwise I'll find a solution.
Don
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
in the initial call to the exported Lex()
if(lexer == 0) {
if(!SCEXT_POWERSHELL_LANGID) {
SCEXT_POWERSHELL_LANGID = messageProc(SCI_GETLEXER, 0, 0);
// If the lexer uses indicators that depend on styler stylat calls the whole doc may need lexing first.
bInitializeLexing = true;
}
InternalLexOrFold(0, startPos, length, initStyle, words, window, props);
}
in beNotified:
case NPPN_FILEOPENED:
{
// Force lexing from start of doc to full length for proper initialization of indicators
int langID = ::SendMessage(hCurrentLexerView, SCI_GETLEXER, 0, 0);
if (langID == SCEXT_POWERSHELL_LANGID) {
bInitializeLexing = true;
}
break;
}
This looks to be working. No new messages needed :)
Unfortunately this approach doesn't work so good with NPPN_BEFFERLANGCHANGED since that message is sent AFTER the call to the Lex() routine; so to handle that case:
case NPPN_LANGCHANGED:
{
// Catch buffer language changes to ensure proper indicator initialization
int langID = ::SendMessage(hCurrentLexerView, SCI_GETLEXER, 0, 0);
if (langID == SCEXT_POWERSHELL_LANGID) {
bLanguageChanged = true;
::SendMessage(hCurrentLexerView, SCI_STARTSTYLING, 0, 0);
}
break;
}
almostautomated
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
When using an external lexer and listening for messages (ie NPPN_FILEOPENED, or even SCN_MODIFIED) how can filtering be done so actions are only taken for languages that that specific lexer plugin is made to handle?
For example, with our Powershe11 lexer plugin, we need to be able to identify when a powershell file is first opened or changed; yet NPPM_GETCURRENTLANGTYPE only reports it as an external, and SCI_GETLEXER reports the language ID number but neither reveals the language name to match against the languages being styled by the plugin, or a way to determine the language ID associated with the lexer plugins languages. I imagine this is OK when there aren't many external lexers in use but what about when then are multiple ones?
I've been able to identify a few ways to 'closely' accomplish this, but something along the lines of a GETCURRENTLANGNAME and then iterating through the plugins styled languages would be of great benefit.
Thanks,
almostautomated
Use SCI_GETLEXER to get your lexer ID is a better approach than getting lexer name, since the ID is uniq.
In NPPN_LANGCHANGED case, you should get your SCEXT_POWERSHELL_LANGID ID if a document power shell is switched in.
So I don't see the problem and I don't think you need getLexerName message.
Do I miss something?
Don
Nope, you hit the nail on the head. Using the GETLEXER to filter message handling actions reduced overhead dramatically!
> I've been able to identify a few ways to 'closely' accomplish this
What's your approach?
> but something along the lines of a GETCURRENTLANGNAME and then
> iterating through the plugins styled languages would be of great benefit.
In the current implementation, GETCURRENTLANGNAME can work with internal language, but not with external lexer.
If your approach work, then great, otherwise I'll find a solution.
Don
Don,
Here's what I ended up doing...
in the initial call to the exported Lex()
if(lexer == 0) {
if(!SCEXT_POWERSHELL_LANGID) {
SCEXT_POWERSHELL_LANGID = messageProc(SCI_GETLEXER, 0, 0);
// If the lexer uses indicators that depend on styler stylat calls the whole doc may need lexing first.
bInitializeLexing = true;
}
InternalLexOrFold(0, startPos, length, initStyle, words, window, props);
}
in beNotified:
case NPPN_FILEOPENED:
{
// Force lexing from start of doc to full length for proper initialization of indicators
int langID = ::SendMessage(hCurrentLexerView, SCI_GETLEXER, 0, 0);
if (langID == SCEXT_POWERSHELL_LANGID) {
bInitializeLexing = true;
}
break;
}
This looks to be working. No new messages needed :)
Unfortunately this approach doesn't work so good with NPPN_BEFFERLANGCHANGED since that message is sent AFTER the call to the Lex() routine; so to handle that case:
case NPPN_LANGCHANGED:
{
// Catch buffer language changes to ensure proper indicator initialization
int langID = ::SendMessage(hCurrentLexerView, SCI_GETLEXER, 0, 0);
if (langID == SCEXT_POWERSHELL_LANGID) {
bLanguageChanged = true;
::SendMessage(hCurrentLexerView, SCI_STARTSTYLING, 0, 0);
}
break;
}
almostautomated