~ubuntu-branches/ubuntu/wily/geany/wily

« back to all changes in this revision

Viewing changes to scintilla/lexers/LexLisp.cxx

  • Committer: Package Import Robot
  • Author(s): Chow Loong Jin
  • Date: 2011-12-10 07:43:26 UTC
  • mfrom: (3.3.7 sid)
  • Revision ID: package-import@ubuntu.com-20111210074326-s8yqbew5i20h33tf
Tags: 0.21-1ubuntu1
* Merge from Debian Unstable, remaining changes:
  - debian/patches/20_use_evince_viewer.patch:
     + use evince as viewer for pdf and dvi files
  - debian/patches/20_use_x_terminal_emulator.patch:
     + use x-terminal-emulator as terminal
  - debian/control
     + Add breaks on geany-plugins-common << 0.20
* Also fixes bugs:
  - Filter for MATLAB/Octave files filters everythign (LP: 885505)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Scintilla source code edit control
 
2
/** @file LexLisp.cxx
 
3
 ** Lexer for Lisp.
 
4
 ** Written by Alexey Yutkin.
 
5
 **/
 
6
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 
7
// The License.txt file describes the conditions under which this software may be distributed.
 
8
 
 
9
#include <stdlib.h>
 
10
#include <string.h>
 
11
#include <stdio.h>
 
12
#include <stdarg.h>
 
13
#include <assert.h>
 
14
#include <ctype.h>
 
15
 
 
16
#include "ILexer.h"
 
17
#include "Scintilla.h"
 
18
#include "SciLexer.h"
 
19
 
 
20
#include "WordList.h"
 
21
#include "LexAccessor.h"
 
22
#include "Accessor.h"
 
23
#include "StyleContext.h"
 
24
#include "CharacterSet.h"
 
25
#include "LexerModule.h"
 
26
 
 
27
#ifdef SCI_NAMESPACE
 
28
using namespace Scintilla;
 
29
#endif
 
30
 
 
31
#define SCE_LISP_CHARACTER 29
 
32
#define SCE_LISP_MACRO 30
 
33
#define SCE_LISP_MACRO_DISPATCH 31
 
34
 
 
35
static inline bool isLispoperator(char ch) {
 
36
        if (isascii(ch) && isalnum(ch))
 
37
                return false;
 
38
        if (ch == '\'' || ch == '`' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '{' || ch == '}')
 
39
                return true;
 
40
        return false;
 
41
}
 
42
 
 
43
static inline bool isLispwordstart(char ch) {
 
44
        return isascii(ch) && ch != ';'  && !isspacechar(ch) && !isLispoperator(ch) &&
 
45
                ch != '\n' && ch != '\r' &&  ch != '\"';
 
46
}
 
47
 
 
48
 
 
49
static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, WordList &keywords_kw, Accessor &styler) {
 
50
        assert(end >= start);
 
51
        char s[100];
 
52
        unsigned int i;
 
53
        bool digit_flag = true;
 
54
        for (i = 0; (i < end - start + 1) && (i < 99); i++) {
 
55
                s[i] = styler[start + i];
 
56
                s[i + 1] = '\0';
 
57
                if (!isdigit(s[i]) && (s[i] != '.')) digit_flag = false;
 
58
        }
 
59
        char chAttr = SCE_LISP_IDENTIFIER;
 
60
 
 
61
        if(digit_flag) chAttr = SCE_LISP_NUMBER;
 
62
        else {
 
63
                if (keywords.InList(s)) {
 
64
                        chAttr = SCE_LISP_KEYWORD;
 
65
                } else if (keywords_kw.InList(s)) {
 
66
                        chAttr = SCE_LISP_KEYWORD_KW;
 
67
                } else if ((s[0] == '*' && s[i-1] == '*') ||
 
68
                           (s[0] == '+' && s[i-1] == '+')) {
 
69
                        chAttr = SCE_LISP_SPECIAL;
 
70
                }
 
71
        }
 
72
        styler.ColourTo(end, chAttr);
 
73
        return;
 
74
}
 
75
 
 
76
 
 
77
static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
 
78
                            Accessor &styler) {
 
79
 
 
80
        WordList &keywords = *keywordlists[0];
 
81
        WordList &keywords_kw = *keywordlists[1];
 
82
 
 
83
        styler.StartAt(startPos);
 
84
 
 
85
        int state = initStyle, radix = -1;
 
86
        char chNext = styler[startPos];
 
87
        unsigned int lengthDoc = startPos + length;
 
88
        styler.StartSegment(startPos);
 
89
        for (unsigned int i = startPos; i < lengthDoc; i++) {
 
90
                char ch = chNext;
 
91
                chNext = styler.SafeGetCharAt(i + 1);
 
92
 
 
93
                bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 
94
 
 
95
                if (styler.IsLeadByte(ch)) {
 
96
                        chNext = styler.SafeGetCharAt(i + 2);
 
97
                        i += 1;
 
98
                        continue;
 
99
                }
 
100
 
 
101
                if (state == SCE_LISP_DEFAULT) {
 
102
                        if (ch == '#') {
 
103
                                styler.ColourTo(i - 1, state);
 
104
                                radix = -1;
 
105
                                state = SCE_LISP_MACRO_DISPATCH;
 
106
                        } else if (ch == ':' && isLispwordstart(chNext)) {
 
107
                                styler.ColourTo(i - 1, state);
 
108
                                state = SCE_LISP_SYMBOL;
 
109
                        } else if (isLispwordstart(ch)) {
 
110
                                styler.ColourTo(i - 1, state);
 
111
                                state = SCE_LISP_IDENTIFIER;
 
112
                        }
 
113
                        else if (ch == ';') {
 
114
                                styler.ColourTo(i - 1, state);
 
115
                                state = SCE_LISP_COMMENT;
 
116
                        }
 
117
                        else if (isLispoperator(ch) || ch=='\'') {
 
118
                                styler.ColourTo(i - 1, state);
 
119
                                styler.ColourTo(i, SCE_LISP_OPERATOR);
 
120
                                if (ch=='\'' && isLispwordstart(chNext)) {
 
121
                                        state = SCE_LISP_SYMBOL;
 
122
                                }
 
123
                        }
 
124
                        else if (ch == '\"') {
 
125
                                styler.ColourTo(i - 1, state);
 
126
                                state = SCE_LISP_STRING;
 
127
                        }
 
128
                } else if (state == SCE_LISP_IDENTIFIER || state == SCE_LISP_SYMBOL) {
 
129
                        if (!isLispwordstart(ch)) {
 
130
                                if (state == SCE_LISP_IDENTIFIER) {
 
131
                                        classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, keywords_kw, styler);
 
132
                                } else {
 
133
                                        styler.ColourTo(i - 1, state);
 
134
                                }
 
135
                                state = SCE_LISP_DEFAULT;
 
136
                        } /*else*/
 
137
                        if (isLispoperator(ch) || ch=='\'') {
 
138
                                styler.ColourTo(i - 1, state);
 
139
                                styler.ColourTo(i, SCE_LISP_OPERATOR);
 
140
                                if (ch=='\'' && isLispwordstart(chNext)) {
 
141
                                        state = SCE_LISP_SYMBOL;
 
142
                                }
 
143
                        }
 
144
                } else if (state == SCE_LISP_MACRO_DISPATCH) {
 
145
                        if (!(isascii(ch) && isdigit(ch))) {
 
146
                                if (ch != 'r' && ch != 'R' && (i - styler.GetStartSegment()) > 1) {
 
147
                                        state = SCE_LISP_DEFAULT;
 
148
                                } else {
 
149
                                        switch (ch) {
 
150
                                                case '|': state = SCE_LISP_MULTI_COMMENT; break;
 
151
                                                case 'o':
 
152
                                                case 'O': radix = 8; state = SCE_LISP_MACRO; break;
 
153
                                                case 'x':
 
154
                                                case 'X': radix = 16; state = SCE_LISP_MACRO; break;
 
155
                                                case 'b':
 
156
                                                case 'B': radix = 2; state = SCE_LISP_MACRO; break;
 
157
                                                case '\\': state = SCE_LISP_CHARACTER; break;
 
158
                                                case ':':
 
159
                                                case '-':
 
160
                                                case '+': state = SCE_LISP_MACRO; break;
 
161
                                                case '\'': if (isLispwordstart(chNext)) {
 
162
                                                                   state = SCE_LISP_SPECIAL;
 
163
                                                           } else {
 
164
                                                                   styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
 
165
                                                                   styler.ColourTo(i, SCE_LISP_OPERATOR);
 
166
                                                                   state = SCE_LISP_DEFAULT;
 
167
                                                           }
 
168
                                                           break;
 
169
                                                default: if (isLispoperator(ch)) {
 
170
                                                                 styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
 
171
                                                                 styler.ColourTo(i, SCE_LISP_OPERATOR);
 
172
                                                         }
 
173
                                                         state = SCE_LISP_DEFAULT;
 
174
                                                         break;
 
175
                                        }
 
176
                                }
 
177
                        }
 
178
                } else if (state == SCE_LISP_MACRO) {
 
179
                        if (isLispwordstart(ch) && (radix == -1 || IsADigit(ch, radix))) {
 
180
                                state = SCE_LISP_SPECIAL;
 
181
                        } else {
 
182
                                state = SCE_LISP_DEFAULT;
 
183
                        }
 
184
                } else if (state == SCE_LISP_CHARACTER) {
 
185
                        if (isLispoperator(ch)) {
 
186
                                styler.ColourTo(i, SCE_LISP_SPECIAL);
 
187
                                state = SCE_LISP_DEFAULT;
 
188
                        } else if (isLispwordstart(ch)) {
 
189
                                styler.ColourTo(i, SCE_LISP_SPECIAL);
 
190
                                state = SCE_LISP_SPECIAL;
 
191
                        } else {
 
192
                                state = SCE_LISP_DEFAULT;
 
193
                        }
 
194
                } else if (state == SCE_LISP_SPECIAL) {
 
195
                        if (!isLispwordstart(ch) || (radix != -1 && !IsADigit(ch, radix))) {
 
196
                                styler.ColourTo(i - 1, state);
 
197
                                state = SCE_LISP_DEFAULT;
 
198
                        }
 
199
                        if (isLispoperator(ch) || ch=='\'') {
 
200
                                styler.ColourTo(i - 1, state);
 
201
                                styler.ColourTo(i, SCE_LISP_OPERATOR);
 
202
                                if (ch=='\'' && isLispwordstart(chNext)) {
 
203
                                        state = SCE_LISP_SYMBOL;
 
204
                                }
 
205
                        }
 
206
                } else {
 
207
                        if (state == SCE_LISP_COMMENT) {
 
208
                                if (atEOL) {
 
209
                                        styler.ColourTo(i - 1, state);
 
210
                                        state = SCE_LISP_DEFAULT;
 
211
                                }
 
212
                        } else if (state == SCE_LISP_MULTI_COMMENT) {
 
213
                                if (ch == '|' && chNext == '#') {
 
214
                                        i++;
 
215
                                        chNext = styler.SafeGetCharAt(i + 1);
 
216
                                        styler.ColourTo(i, state);
 
217
                                        state = SCE_LISP_DEFAULT;
 
218
                                }
 
219
                        } else if (state == SCE_LISP_STRING) {
 
220
                                if (ch == '\\') {
 
221
                                        if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
 
222
                                                i++;
 
223
                                                chNext = styler.SafeGetCharAt(i + 1);
 
224
                                        }
 
225
                                } else if (ch == '\"') {
 
226
                                        styler.ColourTo(i, state);
 
227
                                        state = SCE_LISP_DEFAULT;
 
228
                                }
 
229
                        }
 
230
                }
 
231
 
 
232
        }
 
233
        styler.ColourTo(lengthDoc - 1, state);
 
234
}
 
235
 
 
236
static void FoldLispDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
 
237
                            Accessor &styler) {
 
238
        unsigned int lengthDoc = startPos + length;
 
239
        int visibleChars = 0;
 
240
        int lineCurrent = styler.GetLine(startPos);
 
241
        int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 
242
        int levelCurrent = levelPrev;
 
243
        char chNext = styler[startPos];
 
244
        int styleNext = styler.StyleAt(startPos);
 
245
        for (unsigned int i = startPos; i < lengthDoc; i++) {
 
246
                char ch = chNext;
 
247
                chNext = styler.SafeGetCharAt(i + 1);
 
248
                int style = styleNext;
 
249
                styleNext = styler.StyleAt(i + 1);
 
250
                bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 
251
                if (style == SCE_LISP_OPERATOR) {
 
252
                        if (ch == '(' || ch == '[' || ch == '{') {
 
253
                                levelCurrent++;
 
254
                        } else if (ch == ')' || ch == ']' || ch == '}') {
 
255
                                levelCurrent--;
 
256
                        }
 
257
                }
 
258
                if (atEOL) {
 
259
                        int lev = levelPrev;
 
260
                        if (visibleChars == 0)
 
261
                                lev |= SC_FOLDLEVELWHITEFLAG;
 
262
                        if ((levelCurrent > levelPrev) && (visibleChars > 0))
 
263
                                lev |= SC_FOLDLEVELHEADERFLAG;
 
264
                        if (lev != styler.LevelAt(lineCurrent)) {
 
265
                                styler.SetLevel(lineCurrent, lev);
 
266
                        }
 
267
                        lineCurrent++;
 
268
                        levelPrev = levelCurrent;
 
269
                        visibleChars = 0;
 
270
                }
 
271
                if (!isspacechar(ch))
 
272
                        visibleChars++;
 
273
        }
 
274
        // Fill in the real level of the next line, keeping the current flags as they will be filled in later
 
275
        int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 
276
        styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 
277
}
 
278
 
 
279
static const char * const lispWordListDesc[] = {
 
280
        "Functions and special operators",
 
281
        "Keywords",
 
282
        0
 
283
};
 
284
 
 
285
LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc, lispWordListDesc);