1
// Scintilla source code edit control
2
/** @file LexMatlab.cxx
4
** Written by Josļæ½ Fonseca
6
** Changes by Christoph Dalitz 2003/12/04:
7
** - added support for Octave
8
** - Strings can now be included both in single or double quotes
10
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
11
// The License.txt file describes the conditions under which this software may be distributed.
21
#include "Scintilla.h"
25
#include "LexAccessor.h"
27
#include "StyleContext.h"
28
#include "CharacterSet.h"
29
#include "LexerModule.h"
32
using namespace Scintilla;
35
static bool IsMatlabCommentChar(int c) {
39
static bool IsOctaveCommentChar(int c) {
40
return (c == '%' || c == '#') ;
43
static bool IsMatlabComment(Accessor &styler, int pos, int len) {
44
return len > 0 && IsMatlabCommentChar(styler[pos]) ;
47
static bool IsOctaveComment(Accessor &styler, int pos, int len) {
48
return len > 0 && IsOctaveCommentChar(styler[pos]) ;
51
static inline bool IsAWordChar(const int ch) {
52
return (ch < 0x80) && (isalnum(ch) || ch == '_');
55
static inline bool IsAWordStart(const int ch) {
56
return (ch < 0x80) && (isalnum(ch) || ch == '_');
59
static void ColouriseMatlabOctaveDoc(
60
unsigned int startPos, int length, int initStyle,
61
WordList *keywordlists[], Accessor &styler,
62
bool (*IsCommentChar)(int)) {
64
WordList &keywords = *keywordlists[0];
66
styler.StartAt(startPos);
68
bool transpose = false;
70
StyleContext sc(startPos, length, initStyle, styler);
72
for (; sc.More(); sc.Forward()) {
74
if (sc.state == SCE_MATLAB_OPERATOR) {
75
if (sc.chPrev == '.') {
76
if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') {
77
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
79
} else if (sc.ch == '\'') {
80
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
83
sc.SetState(SCE_MATLAB_DEFAULT);
86
sc.SetState(SCE_MATLAB_DEFAULT);
88
} else if (sc.state == SCE_MATLAB_KEYWORD) {
89
if (!isalnum(sc.ch) && sc.ch != '_') {
91
sc.GetCurrentLowered(s, sizeof(s));
92
if (keywords.InList(s)) {
93
sc.SetState(SCE_MATLAB_DEFAULT);
96
sc.ChangeState(SCE_MATLAB_IDENTIFIER);
97
sc.SetState(SCE_MATLAB_DEFAULT);
101
} else if (sc.state == SCE_MATLAB_NUMBER) {
102
if (!isdigit(sc.ch) && sc.ch != '.'
103
&& !(sc.ch == 'e' || sc.ch == 'E')
104
&& !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))) {
105
sc.SetState(SCE_MATLAB_DEFAULT);
108
} else if (sc.state == SCE_MATLAB_STRING) {
110
if (sc.chNext == '\'') {
113
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
116
} else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
118
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
121
} else if (sc.ch == '\"') {
122
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
124
} else if (sc.state == SCE_MATLAB_COMMENT || sc.state == SCE_MATLAB_COMMAND) {
126
sc.SetState(SCE_MATLAB_DEFAULT);
131
if (sc.state == SCE_MATLAB_DEFAULT) {
132
if (IsCommentChar(sc.ch)) {
133
sc.SetState(SCE_MATLAB_COMMENT);
134
} else if (sc.ch == '!' && sc.chNext != '=' ) {
135
sc.SetState(SCE_MATLAB_COMMAND);
136
} else if (sc.ch == '\'') {
138
sc.SetState(SCE_MATLAB_OPERATOR);
140
sc.SetState(SCE_MATLAB_STRING);
142
} else if (sc.ch == '"') {
143
sc.SetState(SCE_MATLAB_DOUBLEQUOTESTRING);
144
} else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
145
sc.SetState(SCE_MATLAB_NUMBER);
146
} else if (isalpha(sc.ch)) {
147
sc.SetState(SCE_MATLAB_KEYWORD);
148
} else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\') {
149
if (sc.ch == ')' || sc.ch == ']') {
154
sc.SetState(SCE_MATLAB_OPERATOR);
163
static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle,
164
WordList *keywordlists[], Accessor &styler) {
165
ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar);
168
static void ColouriseOctaveDoc(unsigned int startPos, int length, int initStyle,
169
WordList *keywordlists[], Accessor &styler) {
170
ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar);
173
static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int,
174
WordList *[], Accessor &styler,
175
bool (*IsComment)(Accessor&, int, int)) {
177
int endPos = startPos + length;
179
// Backtrack to previous line in case need to fix its fold status
180
int lineCurrent = styler.GetLine(startPos);
182
if (lineCurrent > 0) {
184
startPos = styler.LineStart(lineCurrent);
188
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsComment);
189
char chNext = styler[startPos];
190
for (int i = startPos; i < endPos; i++) {
192
chNext = styler.SafeGetCharAt(i + 1);
194
if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
195
int lev = indentCurrent;
196
int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsComment);
197
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
198
// Only non whitespace lines can be headers
199
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
200
lev |= SC_FOLDLEVELHEADERFLAG;
201
} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
202
// Line after is blank so check the next - maybe should continue further?
204
int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsComment);
205
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
206
lev |= SC_FOLDLEVELHEADERFLAG;
210
indentCurrent = indentNext;
211
styler.SetLevel(lineCurrent, lev);
217
static void FoldMatlabDoc(unsigned int startPos, int length, int initStyle,
218
WordList *keywordlists[], Accessor &styler) {
219
FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabComment);
222
static void FoldOctaveDoc(unsigned int startPos, int length, int initStyle,
223
WordList *keywordlists[], Accessor &styler) {
224
FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveComment);
227
static const char * const matlabWordListDesc[] = {
232
static const char * const octaveWordListDesc[] = {
237
LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc);
239
LexerModule lmOctave(SCLEX_OCTAVE, ColouriseOctaveDoc, "octave", FoldOctaveDoc, octaveWordListDesc);