diff -r 054b1d99cb9a lexers/LexCPP.cxx
--- a/lexers/LexCPP.cxx	Thu Jun 22 18:04:29 2017 +1000
+++ b/lexers/LexCPP.cxx	Tue Jun 27 11:18:49 2017 +1000
@@ -22,6 +22,7 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "StringCopy.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
@@ -432,6 +433,38 @@
 
 const char styleSubable[] = {SCE_C_IDENTIFIER, SCE_C_COMMENTDOCKEYWORD, 0};
 
+LexicalClass lexicalClasses[] = {
+	// Lexer Cpp SCLEX_CPP SCE_C_:
+	0, "SCE_C_DEFAULT", "default", "White space",
+	1, "SCE_C_COMMENT", "comment", "Comment: /* */.",
+	2, "SCE_C_COMMENTLINE", "comment line", "Line Comment: //.",
+	3, "SCE_C_COMMENTDOC", "comment documentation", "Doc comment: block comments beginning with /** or /*!",
+	4, "SCE_C_NUMBER", "literal numeric", "Number",
+	5, "SCE_C_WORD", "keyword", "Keyword",
+	6, "SCE_C_STRING", "literal string", "Double quoted string",
+	7, "SCE_C_CHARACTER", "literal string character", "Single quoted string",
+	8, "SCE_C_UUID", "literal uuid", "UUIDs (only in IDL)",
+	9, "SCE_C_PREPROCESSOR", "preprocessor", "Preprocessor",
+	10, "SCE_C_OPERATOR", "operator", "Operators",
+	11, "SCE_C_IDENTIFIER", "identifier", "Identifiers",
+	12, "SCE_C_STRINGEOL", "error literal string", "End of line where string is not closed",
+	13, "SCE_C_VERBATIM", "literal string multiline raw", "Verbatim strings for C#",
+	14, "SCE_C_REGEX", "literal regex", "Regular expressions for JavaScript",
+	15, "SCE_C_COMMENTLINEDOC", "comment documentation line", "Doc Comment Line: line comments beginning with /// or //!.",
+	16, "SCE_C_WORD2", "identifier", "Keywords2",
+	17, "SCE_C_COMMENTDOCKEYWORD", "comment documentation keyword", "Comment keyword",
+	18, "SCE_C_COMMENTDOCKEYWORDERROR", "error comment documentation keyword", "Comment keyword error",
+	19, "SCE_C_GLOBALCLASS", "identifier", "Global class",
+	20, "SCE_C_STRINGRAW", "literal string multiline raw", "Raw strings for C++0x",
+	21, "SCE_C_TRIPLEVERBATIM", "literal string multiline raw", "Triple-quoted strings for Vala",
+	22, "SCE_C_HASHQUOTEDSTRING", "literal string", "Hash-quoted strings for Pike",
+	23, "SCE_C_PREPROCESSORCOMMENT", "comment preprocessor", "Preprocessor stream comment",
+	24, "SCE_C_PREPROCESSORCOMMENTDOC", "comment preprocessor documentation", "Preprocessor stream doc comment",
+	25, "SCE_C_USERLITERAL", "literal", "User defined literals",
+	26, "SCE_C_TASKMARKER", "comment taskmarker", "Task Marker",
+	27, "SCE_C_ESCAPESEQUENCE", "literal string escapesequence", "Escape sequence",
+};
+
 }
 
 class LexerCPP : public ILexer4 {
@@ -546,16 +579,16 @@
 		return styleSubable;
 	}
 	int SCI_METHOD NamedStyles() {
-		return 0;
+		return ELEMENTS(lexicalClasses);
 	}
-	const char * SCI_METHOD NameOfStyle(int) {
-		return "";
+	const char * SCI_METHOD NameOfStyle(int style) {
+		return (style < NamedStyles()) ? lexicalClasses[style].name : "";
 	}
-	const char * SCI_METHOD TagsOfStyle(int) {
-		return "";
+	const char * SCI_METHOD TagsOfStyle(int style) {
+		return (style < NamedStyles()) ? lexicalClasses[style].tags : "";
 	}
-	const char * SCI_METHOD DescriptionOfStyle(int) {
-		return "";
+	const char * SCI_METHOD DescriptionOfStyle(int style) {
+		return (style < NamedStyles()) ? lexicalClasses[style].description : "";
 	}
 
 	static ILexer4 *LexerFactoryCPP() {
diff -r 054b1d99cb9a lexers/LexHTML.cxx
--- a/lexers/LexHTML.cxx	Thu Jun 22 18:04:29 2017 +1000
+++ b/lexers/LexHTML.cxx	Tue Jun 27 11:18:49 2017 +1000
@@ -2198,6 +2198,178 @@
 	0,
 };
 
-LexerModule lmHTML(SCLEX_HTML, ColouriseHTMLDoc, "hypertext", 0, htmlWordListDesc);
-LexerModule lmXML(SCLEX_XML, ColouriseXMLDoc, "xml", 0, htmlWordListDesc);
+namespace {
+
+LexicalClass lexicalClassesHTML[] = {
+	// Lexer HTML SCLEX_HTML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_:
+	0, "SCE_H_DEFAULT", "default", "Text",
+	1, "SCE_H_TAG", "tag", "Tags",
+	2, "SCE_H_ERRORTAGUNKNOWN", "error tag", "Unknown Tags",
+	3, "SCE_H_ATTRIBUTE", "attribute", "Attributes",
+	4, "SCE_H_ATTRIBUTEUNKNOWN", "error attribute", "Unknown Attributes",
+	5, "SCE_H_NUMBER", "literal numeric", "Numbers",
+	6, "SCE_H_DOUBLESTRING", "literal string", "Double quoted strings",
+	7, "SCE_H_SINGLESTRING", "literal string", "Single quoted strings",
+	8, "SCE_H_OTHER", "", "Other inside tag",
+	9, "SCE_H_COMMENT", "comment", "Comment",
+	10, "SCE_H_ENTITY", "literal", "Entities",
+	11, "SCE_H_TAGEND", "tag", "XML style tag ends '/>'",
+	12, "SCE_H_XMLSTART", "identifier", "XML identifier start '<?'",
+	13, "SCE_H_XMLEND", "identifier", "XML identifier end '?>'",
+	14, "SCE_H_SCRIPT", "", "SCRIPT",
+	15, "SCE_H_ASP", "preprocessor", "ASP <% ... %>",
+	16, "SCE_H_ASPAT", "preprocessor", "ASP <% ... %>",
+	17, "SCE_H_CDATA", "literal", "CDATA",
+	18, "SCE_H_QUESTION", "preprocessor", "PHP",
+	19, "SCE_H_VALUE", "literal string", "Unquoted values",
+	20, "SCE_H_XCCOMMENT", "comment", "JSP Comment <%-- ... --%>",
+	21, "SCE_H_SGML_DEFAULT", "default", "SGML tags <! ... >",
+	22, "SCE_H_SGML_COMMAND", "preprocessor", "SGML command",
+	23, "SCE_H_SGML_1ST_PARAM", "preprocessor", "SGML 1st param",
+	24, "SCE_H_SGML_DOUBLESTRING", "literal string", "SGML double string",
+	25, "SCE_H_SGML_SIMPLESTRING", "literal string", "SGML single string",
+	26, "SCE_H_SGML_ERROR", "error", "SGML error",
+	27, "SCE_H_SGML_SPECIAL", "", "SGML special (#xxxx type)",
+	28, "SCE_H_SGML_ENTITY", "literal", "SGML entity",
+	29, "SCE_H_SGML_COMMENT", "comment", "SGML comment",
+	30, "SCE_H_SGML_1ST_PARAM_COMMENT", "error comment", "SGML first parameter - lexer internal. It is an error if any text is in this style.",
+	31, "SCE_H_SGML_BLOCK_DEFAULT", "default", "SGML block",
+	32, "", "predefined", "",
+	33, "", "predefined", "",
+	34, "", "predefined", "",
+	35, "", "predefined", "",
+	36, "", "predefined", "",
+	37, "", "predefined", "",
+	38, "", "predefined", "",
+	39, "", "predefined", "",
+	40, "SCE_HJ_START", "default", "JS Start - allows eol filled background to not start on same line as SCRIPT tag",
+	41, "SCE_HJ_DEFAULT", "default", "JS Default",
+	42, "SCE_HJ_COMMENT", "comment", "JS Comment",
+	43, "SCE_HJ_COMMENTLINE", "comment line", "JS Line Comment",
+	44, "SCE_HJ_COMMENTDOC", "comment documentation", "JS Doc comment",
+	45, "SCE_HJ_NUMBER", "literal numeric", "JS Number",
+	46, "SCE_HJ_WORD", "identifier", "JS Word",
+	47, "SCE_HJ_KEYWORD", "keyword", "JS Keyword",
+	48, "SCE_HJ_DOUBLESTRING", "literal string", "JS Double quoted string",
+	49, "SCE_HJ_SINGLESTRING", "literal string", "JS Single quoted string",
+	50, "SCE_HJ_SYMBOLS", "operator", "JS Symbols",
+	51, "SCE_HJ_STRINGEOL", "error literal string", "JavaScript EOL",
+	52, "SCE_HJ_REGEX", "literal regex", "JavaScript RegEx",
+	53, "", "unused", "",
+	54, "", "unused", "",
+	55, "SCE_HJA_START", "default", "JS Start - allows eol filled background to not start on same line as SCRIPT tag",
+	56, "SCE_HJA_DEFAULT", "default", "JS Default",
+	57, "SCE_HJA_COMMENT", "comment", "JS Comment",
+	58, "SCE_HJA_COMMENTLINE", "comment line", "JS Line Comment",
+	59, "SCE_HJA_COMMENTDOC", "comment documentation", "JS Doc comment",
+	60, "SCE_HJA_NUMBER", "literal numeric", "JS Number",
+	61, "SCE_HJA_WORD", "identifier", "JS Word",
+	62, "SCE_HJA_KEYWORD", "keyword", "JS Keyword",
+	63, "SCE_HJA_DOUBLESTRING", "literal string", "JS Double quoted string",
+	64, "SCE_HJA_SINGLESTRING", "literal string", "JS Single quoted string",
+	65, "SCE_HJA_SYMBOLS", "operator", "JS Symbols",
+	66, "SCE_HJA_STRINGEOL", "error literal string", "JavaScript EOL",
+	67, "SCE_HJA_REGEX", "literal regex", "JavaScript RegEx",
+	68, "", "unused", "",
+	69, "", "unused", "",
+	70, "SCE_HB_START", "default", "Start",
+	71, "SCE_HB_DEFAULT", "default", "Default",
+	72, "SCE_HB_COMMENTLINE", "comment line", "Comment",
+	73, "SCE_HB_NUMBER", "literal numeric", "Number",
+	74, "SCE_HB_WORD", "keyword", "KeyWord",
+	75, "SCE_HB_STRING", "literal string", "String",
+	76, "SCE_HB_IDENTIFIER", "identifier", "Identifier",
+	77, "SCE_HB_STRINGEOL", "literal string", "Unterminated string",
+	78, "", "unused", "",
+	79, "", "unused", "",
+	80, "SCE_HBA_START", "default", "Start",
+	81, "SCE_HBA_DEFAULT", "default", "Default",
+	82, "SCE_HBA_COMMENTLINE", "comment line", "Comment",
+	83, "SCE_HBA_NUMBER", "literal numeric", "Number",
+	84, "SCE_HBA_WORD", "keyword", "KeyWord",
+	85, "SCE_HBA_STRING", "literal string", "String",
+	86, "SCE_HBA_IDENTIFIER", "identifier", "Identifier",
+	87, "SCE_HBA_STRINGEOL", "literal string", "Unterminated string",
+	88, "", "unused", "",
+	89, "", "unused", "",
+	90, "SCE_HP_START", "default", "Embedded Python",
+	91, "SCE_HP_DEFAULT", "default", "Embedded Python",
+	92, "SCE_HP_COMMENTLINE", "comment line", "Comment",
+	93, "SCE_HP_NUMBER", "literal numeric", "Number",
+	94, "SCE_HP_STRING", "literal string", "String",
+	95, "SCE_HP_CHARACTER", "literal string character", "Single quoted string",
+	96, "SCE_HP_WORD", "keyword", "Keyword",
+	97, "SCE_HP_TRIPLE", "literal string", "Triple quotes",
+	98, "SCE_HP_TRIPLEDOUBLE", "literal string", "Triple double quotes",
+	99, "SCE_HP_CLASSNAME", "identifier", "Class name definition",
+	100, "SCE_HP_DEFNAME", "identifier", "Function or method name definition",
+	101, "SCE_HP_OPERATOR", "operator", "Operators",
+	102, "SCE_HP_IDENTIFIER", "identifier", "Identifiers",
+	103, "", "unused", "",
+	104, "SCE_HPHP_COMPLEX_VARIABLE", "identifier", "PHP complex variable",
+	105, "SCE_HPA_START", "default", "ASP Python",
+	106, "SCE_HPA_DEFAULT", "default", "ASP Python",
+	107, "SCE_HPA_COMMENTLINE", "comment line", "Comment",
+	108, "SCE_HPA_NUMBER", "literal numeric", "Number",
+	109, "SCE_HPA_STRING", "literal string", "String",
+	110, "SCE_HPA_CHARACTER", "literal string character", "Single quoted string",
+	111, "SCE_HPA_WORD", "keyword", "Keyword",
+	112, "SCE_HPA_TRIPLE", "literal string", "Triple quotes",
+	113, "SCE_HPA_TRIPLEDOUBLE", "literal string", "Triple double quotes",
+	114, "SCE_HPA_CLASSNAME", "identifier", "Class name definition",
+	115, "SCE_HPA_DEFNAME", "identifier", "Function or method name definition",
+	116, "SCE_HPA_OPERATOR", "operator", "Operators",
+	117, "SCE_HPA_IDENTIFIER", "identifier", "Identifiers",
+	118, "SCE_HPHP_DEFAULT", "default", "Default",
+	119, "SCE_HPHP_HSTRING", "literal string", "Double quoted String",
+	120, "SCE_HPHP_SIMPLESTRING", "literal string", "Single quoted string",
+	121, "SCE_HPHP_WORD", "keyword", "Keyword",
+	122, "SCE_HPHP_NUMBER", "literal numeric", "Number",
+	123, "SCE_HPHP_VARIABLE", "identifier", "Variable",
+	124, "SCE_HPHP_COMMENT", "comment", "Comment",
+	125, "SCE_HPHP_COMMENTLINE", "comment line", "One line comment",
+	126, "SCE_HPHP_HSTRING_VARIABLE", "literal string identifier", "PHP variable in double quoted string",
+	127, "SCE_HPHP_OPERATOR", "operator", "PHP operator",
+};
+
+LexicalClass lexicalClassesXML[] = {
+	// Lexer.Secondary XML SCLEX_XML SCE_H_:
+	0, "SCE_H_DEFAULT", "default", "Default",
+	1, "SCE_H_TAG", "tag", "Tags",
+	2, "SCE_H_TAGUNKNOWN", "error tag", "Unknown Tags",
+	3, "SCE_H_ATTRIBUTE", "attribute", "Attributes",
+	4, "SCE_H_ERRORATTRIBUTEUNKNOWN", "error attribute", "Unknown Attributes",
+	5, "SCE_H_NUMBER", "literal numeric", "Numbers",
+	6, "SCE_H_DOUBLESTRING", "literal string", "Double quoted strings",
+	7, "SCE_H_SINGLESTRING", "literal string", "Single quoted strings",
+	8, "SCE_H_OTHER", "", "Other inside tag",
+	9, "SCE_H_COMMENT", "comment", "Comment",
+	10, "SCE_H_ENTITY", "literal", "Entities",
+	11, "SCE_H_TAGEND", "tag", "XML style tag ends '/>'",
+	12, "SCE_H_XMLSTART", "identifier", "XML identifier start '<?'",
+	13, "SCE_H_XMLEND", "identifier", "XML identifier end '?>'",
+	14, "", "unused", "",
+	15, "", "unused", "",
+	16, "", "unused", "",
+	17, "SCE_H_CDATA", "literal", "CDATA",
+	18, "SCE_H_QUESTION", "preprocessor", "Question",
+	19, "SCE_H_VALUE", "literal string", "Unquoted Value",
+	20, "", "unused", "",
+	21, "SCE_H_SGML_DEFAULT", "default", "SGML tags <! ... >",
+	22, "SCE_H_SGML_COMMAND", "preprocessor", "SGML command",
+	23, "SCE_H_SGML_1ST_PARAM", "preprocessor", "SGML 1st param",
+	24, "SCE_H_SGML_DOUBLESTRING", "literal string", "SGML double string",
+	25, "SCE_H_SGML_SIMPLESTRING", "literal string", "SGML single string",
+	26, "SCE_H_SGML_ERROR", "error", "SGML error",
+	27, "SCE_H_SGML_SPECIAL", "", "SGML special (#xxxx type)",
+	28, "SCE_H_SGML_ENTITY", "literal", "SGML entity",
+	29, "SCE_H_SGML_COMMENT", "comment", "SGML comment",
+	30, "", "unsued", "",
+	31, "SCE_H_SGML_BLOCK_DEFAULT", "default", "SGML block",
+};
+
+}
+
+LexerModule lmHTML(SCLEX_HTML, ColouriseHTMLDoc, "hypertext", 0, htmlWordListDesc, lexicalClassesHTML, ELEMENTS(lexicalClassesHTML));
+LexerModule lmXML(SCLEX_XML, ColouriseXMLDoc, "xml", 0, htmlWordListDesc, lexicalClassesXML, ELEMENTS(lexicalClassesXML));
 LexerModule lmPHPSCRIPT(SCLEX_PHPSCRIPT, ColourisePHPScriptDoc, "phpscript", 0, phpscriptWordListDesc);
diff -r 054b1d99cb9a lexers/LexLua.cxx
--- a/lexers/LexLua.cxx	Thu Jun 22 18:04:29 2017 +1000
+++ b/lexers/LexLua.cxx	Tue Jun 27 11:18:49 2017 +1000
@@ -18,6 +18,7 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "StringCopy.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
@@ -433,4 +434,33 @@
 	0
 };
 
-LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc, luaWordListDesc);
+namespace {
+
+LexicalClass lexicalClasses[] = {
+	// Lexer Lua SCLEX_LUA SCE_LUA_:
+	0, "SCE_LUA_DEFAULT", "default", "White space: Visible only in View Whitespace mode (or if it has a back colour)",
+	1, "SCE_LUA_COMMENT", "comment", "Block comment (Lua 5.0)",
+	2, "SCE_LUA_COMMENTLINE", "comment line", "Line comment",
+	3, "SCE_LUA_COMMENTDOC", "comment documentation", "Doc comment -- Not used in Lua (yet?)",
+	4, "SCE_LUA_NUMBER", "literal numeric", "Number",
+	5, "SCE_LUA_WORD", "keyword", "Keyword",
+	6, "SCE_LUA_STRING", "literal string", "(Double quoted) String",
+	7, "SCE_LUA_CHARACTER", "literal string character", "Character (Single quoted string)",
+	8, "SCE_LUA_LITERALSTRING", "literal string", "Literal string",
+	9, "SCE_LUA_PREPROCESSOR", "preprocessor", "Preprocessor (obsolete in Lua 4.0 and up)",
+	10, "SCE_LUA_OPERATOR", "operator", "Operators",
+	11, "SCE_LUA_IDENTIFIER", "identifier", "Identifier (everything else...)",
+	12, "SCE_LUA_STRINGEOL", "error literal string", "End of line where string is not closed",
+	13, "SCE_LUA_WORD2", "identifier", "Other keywords",
+	14, "SCE_LUA_WORD3", "identifier", "Other keywords",
+	15, "SCE_LUA_WORD4", "identifier", "Other keywords",
+	16, "SCE_LUA_WORD5", "identifier", "Other keywords",
+	17, "SCE_LUA_WORD6", "identifier", "Other keywords",
+	18, "SCE_LUA_WORD7", "identifier", "Other keywords",
+	19, "SCE_LUA_WORD8", "identifier", "Other keywords",
+	20, "SCE_LUA_LABEL", "label", "Labels",
+};
+
+}
+
+LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc, luaWordListDesc, lexicalClasses, ELEMENTS(lexicalClasses));
diff -r 054b1d99cb9a lexers/LexPython.cxx
--- a/lexers/LexPython.cxx	Thu Jun 22 18:04:29 2017 +1000
+++ b/lexers/LexPython.cxx	Tue Jun 27 11:18:49 2017 +1000
@@ -309,6 +309,30 @@
 
 const char styleSubable[] = { SCE_P_IDENTIFIER, 0 };
 
+LexicalClass lexicalClasses[] = {
+	// Lexer Python SCLEX_PYTHON SCE_P_:
+	0, "SCE_P_DEFAULT", "default", "White space",
+	1, "SCE_P_COMMENTLINE", "comment line", "Comment",
+	2, "SCE_P_NUMBER", "literal numeric", "Number",
+	3, "SCE_P_STRING", "literal string", "String",
+	4, "SCE_P_CHARACTER", "literal string", "Single quoted string",
+	5, "SCE_P_WORD", "keyword", "Keyword",
+	6, "SCE_P_TRIPLE", "literal string", "Triple quotes",
+	7, "SCE_P_TRIPLEDOUBLE", "literal string", "Triple double quotes",
+	8, "SCE_P_CLASSNAME", "identifier", "Class name definition",
+	9, "SCE_P_DEFNAME", "identifier", "Function or method name definition",
+	10, "SCE_P_OPERATOR", "operator", "Operators",
+	11, "SCE_P_IDENTIFIER", "identifier", "Identifiers",
+	12, "SCE_P_COMMENTBLOCK", "comment", "Comment-blocks",
+	13, "SCE_P_STRINGEOL", "error literal string", "End of line where string is not closed",
+	14, "SCE_P_WORD2", "identifier", "Highlighted identifiers",
+	15, "SCE_P_DECORATOR", "preprocessor", "Decorators",
+	16, "SCE_P_FSTRING", "literal string interpolated", "F-String",
+	17, "SCE_P_FCHARACTER", "literal string interpolated", "Single quoted f-string",
+	18, "SCE_P_FTRIPLE", "literal string interpolated", "Triple quoted f-string",
+	19, "SCE_P_FTRIPLEDOUBLE", "literal string interpolated", "Triple double quoted f-string",
+};
+
 }
 
 class LexerPython : public DefaultLexer {
@@ -321,6 +345,7 @@
 	std::map<int, std::vector<SingleFStringExpState> > ftripleStateAtEol;
 public:
 	explicit LexerPython() :
+		DefaultLexer(lexicalClasses, ELEMENTS(lexicalClasses)),
 		subStyles(styleSubable, 0x80, 0x40, 0) {
 	}
 	virtual ~LexerPython() {
