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