Notepad Style System Notes - wnewbery/npp-languages GitHub Wiki
Notes on how Notepad++ styles get from the XML config files, to the Scintilla control
Based on observations from the code explain below:
- An external lexer has no control over how Notepad++ sets up the editor control.
- Notepad++ enforces a limit on the number of extra languages / style sets
- Each language can only have 30 of its own styles, but the builtin languages that combine several sets can exceed this.
Most of the relevant files have an almost complete lack of comments, so this is some basic info for the relevant ones starting with where Notepad++ sets the editor controls language/lexer.
Stores all the language styles for Notepad++. There is an upper limit of MAX_LEXER_STYLE (80), after which loading styles will fail.
Styles are added to the array by LexerStylerArray::addLexerStyler, which is only called by NppParameters::feedStylerArray(TiXmlNode *node), which loads the styles from XML.
LexerStyler : public StyleArray
Contains the list of styles for a single language/lexer. This is a fixed size array of SCE_STYLE_ARRAY_SIZE (30), limiting any single language to at most that many styles of its own.
This Notepad++ class provides a lot of the functionality on stop of the Scintilla editor control, such as determining the final styles. It then eventually sends window messages to the control to configure it via _pScintillaFunc which stores a window procedure function and bypass the normal Win32 PostMessage, SendMessage, etc. API layers. This caching happens immediately after the creation of the control in ScintillaEditView::init.
This sets up the Scintilla control for a language, defined using an enumeration. External plugin languages get given ID's above LC_EXTERNAL, but all builtin languages have their own ID.
- If there is a default style set (
STYLE_DEFAULT, 32), passes it tosetStyleafter forcingCOLORSTYLE_ALL. - Sends the
SCI_STYLECLEARALLmessage.
Misleadingly, especially given the order, this actually clears every style except 32 by setting them to the current style 32. - Sets some other global styles such as indicators and highlights (the user can configure most of these in the "Global Styles" language, rather than per language).
- Does a special, non-english document
SCI_SETCODEPAGEifisCJK(codepage left untouched otherwise), with either_codepage, or for css, caml, asm or matlab (hardcoded list),CP_ACP. - Shows the margin for all languages except Ascii, batch, text, makefile, asm, haskell, propers, smalltalk, kix and ada (hard coded list).
- Sets the lexer, styles and keywords for each builtin language using a hard coded switch statement and functions. For example HTML, XML, PHP, ASP, and JSP all use
setXmlLexer. The user defined language usessetUserLexer, and plugin languages must usesetExternalLexer(hardcoded, no plugin API).
For `L_TEXT` or unknown languages there is a strange and undocumented `execute(SCI_SETLEXER, (_codepage == CP_CHINESE_TRADITIONAL)?SCLEX_MAKEFILE:SCLEX_NULL);`.
Sets the styles for L_XML via a normal makeStyle(L_XML), and equally for L_HTML, L_PHP, L_ASP and LJSP by makeStyle(L_HTML), setEmbeddedJSLexer(), setEmbeddedPhpLexer() and setEmbeddedAspLexer(). Then sets from properties:
execute(SCI_SETPROPERTY, reinterpret_cast<WPARAM>("fold"), reinterpret_cast<LPARAM>("1"));
execute(SCI_SETPROPERTY, reinterpret_cast<WPARAM>("fold.compact"), reinterpret_cast<LPARAM>("0"));
execute(SCI_SETPROPERTY, reinterpret_cast<WPARAM>("fold.html"), reinterpret_cast<LPARAM>("1"));
// This allow to fold comment strem in php/javascript code
execute(SCI_SETPROPERTY, reinterpret_cast<WPARAM>("fold.hypertext.comment"), reinterpret_cast<LPARAM>("1"));
Adds L_JS styles and keywords in addition to the others and sends some special messages:
execute(SCI_STYLESETEOLFILLED, SCE_HJ_DEFAULT, true);
execute(SCI_STYLESETEOLFILLED, SCE_HJ_COMMENT, true);
execute(SCI_STYLESETEOLFILLED, SCE_HJ_COMMENTDOC, true);
Adds L_PHP styles, keywords, and sends some special messages:
execute(SCI_STYLESETEOLFILLED, SCE_HPHP_DEFAULT, true);
execute(SCI_STYLESETEOLFILLED, SCE_HPHP_COMMENT, true);
Adds L_ASP styles, keywords, and sends a special message:
execute(SCI_STYLESETEOLFILLED, SCE_HBA_DEFAULT, true);
This is the setting for any plugin-defined languages.
It just sets the styles and keywords defined directly by that language. Unlike the custom built in languages, there is no functionality to set the additional styles, or to set any of the additional configurations.
This function directly invokes SCI_SETLEXERLANGUAGE before setting any styles though (as a directly invoked message, it is likely not practical to intercept this). Scintilla will create the instance of a custom lexer at this point if its not the current lexer, which does give external Notepad++ lexers some opportunity to make customisations, as long as any following setStyle or SCI_SEETKEYWORDS would not undo them.
Sets all the styles for built in languages.
The language is converted from the enum to its name by static LanguageName ScintillaEditView::langNames[L_EXTERNAL+1].
This name then gets the LexerStyler from LexerStylerArray, and sets each of its styles using setStyle.
struct LanguageName {
const TCHAR * lexerName; //Lowercase name such as "objc" or "javascript" used in the XML etc.
const TCHAR * shortName; //English full name displayed in menus etc. e.g. "Objective-C", "JavaScript"
const TCHAR * longName; //Long name, etc. "Hyper Text Markup Language file"
LangType LangID; //Unique enumeration value for builtin languages
int lexerID; //The Lexer defined by Scintilla to use. Note that many Notepad++ languages use some lexers. E.g. many of the C-style ones such a C++, C# and Java, use `SCLEX_CPP`. The differences are in the keywords.
};Takes a Notepad++ Style object (note, defined in Parameters.h) and modifies it with any of the global override styles (the one named "Global override" in the "Global Styles" language).
It then calls setSpecialStyle with the modified style object.
Takes a Notepad++ Style object (note, defined in Parameters.h) and adds it to the control via a series of direct messages.
The array of styles for the exit control is stored by std::vector<Style> ViewStyle::styles. This is a mostly public struct, where void ViewStyle::EnsureStyle(size_t index) grows it as needed.
Editor::StyleSetMessage actually sets the styles uisng a window message, with wParam being the styleId and lParam the style value.