1 // Scintilla source code edit control 2 /** @file LexerModule.cxx 3 ** Colourise for particular languages. 4 **/ 5 // Copyright 1998-2010 by Neil Hodgson <[email protected]> 6 // The License.txt file describes the conditions under which this software may be distributed. 7 8 #include <cstdlib> 9 #include <cassert> 10 11 #include <string> 12 13 #include "ILexer.h" 14 #include "Scintilla.h" 15 #include "SciLexer.h" 16 17 #include "PropSetSimple.h" 18 #include "WordList.h" 19 #include "LexAccessor.h" 20 #include "Accessor.h" 21 #include "LexerModule.h" 22 #include "LexerBase.h" 23 #include "LexerSimple.h" 24 25 using namespace Scintilla; 26 27 LexerModule::LexerModule(int language_, 28 LexerFunction fnLexer_, 29 const char *languageName_, 30 LexerFunction fnFolder_, 31 const char *const wordListDescriptions_[], 32 const LexicalClass *lexClasses_, 33 size_t nClasses_) noexcept : 34 language(language_), 35 fnLexer(fnLexer_), 36 fnFolder(fnFolder_), 37 fnFactory(nullptr), 38 wordListDescriptions(wordListDescriptions_), 39 lexClasses(lexClasses_), 40 nClasses(nClasses_), 41 languageName(languageName_) { 42 } 43 44 LexerModule::LexerModule(int language_, 45 LexerFactoryFunction fnFactory_, 46 const char *languageName_, 47 const char * const wordListDescriptions_[]) noexcept : 48 language(language_), 49 fnLexer(nullptr), 50 fnFolder(nullptr), 51 fnFactory(fnFactory_), 52 wordListDescriptions(wordListDescriptions_), 53 lexClasses(nullptr), 54 nClasses(0), 55 languageName(languageName_) { 56 } 57 58 int LexerModule::GetLanguage() const noexcept { 59 return language; 60 } 61 62 int LexerModule::GetNumWordLists() const noexcept { 63 if (!wordListDescriptions) { 64 return -1; 65 } else { 66 int numWordLists = 0; 67 68 while (wordListDescriptions[numWordLists]) { 69 ++numWordLists; 70 } 71 72 return numWordLists; 73 } 74 } 75 76 const char *LexerModule::GetWordListDescription(int index) const noexcept { 77 assert(index < GetNumWordLists()); 78 if (!wordListDescriptions || (index >= GetNumWordLists())) { 79 return ""; 80 } else { 81 return wordListDescriptions[index]; 82 } 83 } 84 85 const LexicalClass *LexerModule::LexClasses() const noexcept { 86 return lexClasses; 87 } 88 89 size_t LexerModule::NamedStyles() const noexcept { 90 return nClasses; 91 } 92 93 ILexer5 *LexerModule::Create() const { 94 if (fnFactory) 95 return fnFactory(); 96 else 97 return new LexerSimple(this); 98 } 99 100 void LexerModule::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, 101 WordList *keywordlists[], Accessor &styler) const { 102 if (fnLexer) 103 fnLexer(startPos, lengthDoc, initStyle, keywordlists, styler); 104 } 105 106 void LexerModule::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, 107 WordList *keywordlists[], Accessor &styler) const { 108 if (fnFolder) { 109 Sci_Position lineCurrent = styler.GetLine(startPos); 110 // Move back one line in case deletion wrecked current line fold state 111 if (lineCurrent > 0) { 112 lineCurrent--; 113 const Sci_Position newStartPos = styler.LineStart(lineCurrent); 114 lengthDoc += startPos - newStartPos; 115 startPos = newStartPos; 116 initStyle = 0; 117 if (startPos > 0) { 118 initStyle = styler.StyleAt(startPos - 1); 119 } 120 } 121 fnFolder(startPos, lengthDoc, initStyle, keywordlists, styler); 122 } 123 } 124