chore: bump scintilla and lexilla version
This commit is contained in:
494
3rdparty/lexilla545/lexilla/lexers/LexCoffeeScript.cxx
vendored
Normal file
494
3rdparty/lexilla545/lexilla/lexers/LexCoffeeScript.cxx
vendored
Normal file
@ -0,0 +1,494 @@
|
||||
// Scintilla source code edit control
|
||||
/** @file LexCoffeeScript.cxx
|
||||
** Lexer for CoffeeScript.
|
||||
**/
|
||||
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
|
||||
// Based on the Scintilla C++ Lexer
|
||||
// Written by Eric Promislow <ericp@activestate.com> in 2011 for the Komodo IDE
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
using namespace Lexilla;
|
||||
|
||||
static bool IsSpaceEquiv(int state) {
|
||||
return (state == SCE_COFFEESCRIPT_DEFAULT
|
||||
|| state == SCE_COFFEESCRIPT_COMMENTLINE
|
||||
|| state == SCE_COFFEESCRIPT_COMMENTBLOCK
|
||||
|| state == SCE_COFFEESCRIPT_VERBOSE_REGEX
|
||||
|| state == SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT
|
||||
|| state == SCE_COFFEESCRIPT_WORD
|
||||
|| state == SCE_COFFEESCRIPT_REGEX);
|
||||
}
|
||||
|
||||
// Store the current lexer state and brace count prior to starting a new
|
||||
// `#{}` interpolation level.
|
||||
// Based on LexRuby.cxx.
|
||||
static void enterInnerExpression(int *p_inner_string_types,
|
||||
int *p_inner_expn_brace_counts,
|
||||
int& inner_string_count,
|
||||
int state,
|
||||
int& brace_counts
|
||||
) {
|
||||
p_inner_string_types[inner_string_count] = state;
|
||||
p_inner_expn_brace_counts[inner_string_count] = brace_counts;
|
||||
brace_counts = 0;
|
||||
++inner_string_count;
|
||||
}
|
||||
|
||||
// Restore the lexer state and brace count for the previous `#{}` interpolation
|
||||
// level upon returning to it.
|
||||
// Note the previous lexer state is the return value and needs to be restored
|
||||
// manually by the StyleContext.
|
||||
// Based on LexRuby.cxx.
|
||||
static int exitInnerExpression(int *p_inner_string_types,
|
||||
int *p_inner_expn_brace_counts,
|
||||
int& inner_string_count,
|
||||
int& brace_counts
|
||||
) {
|
||||
--inner_string_count;
|
||||
brace_counts = p_inner_expn_brace_counts[inner_string_count];
|
||||
return p_inner_string_types[inner_string_count];
|
||||
}
|
||||
|
||||
// Preconditions: sc.currentPos points to a character after '+' or '-'.
|
||||
// The test for pos reaching 0 should be redundant,
|
||||
// and is in only for safety measures.
|
||||
// Limitation: this code will give the incorrect answer for code like
|
||||
// a = b+++/ptn/...
|
||||
// Putting a space between the '++' post-inc operator and the '+' binary op
|
||||
// fixes this, and is highly recommended for readability anyway.
|
||||
static bool FollowsPostfixOperator(StyleContext &sc, Accessor &styler) {
|
||||
Sci_Position pos = (Sci_Position) sc.currentPos;
|
||||
while (--pos > 0) {
|
||||
char ch = styler[pos];
|
||||
if (ch == '+' || ch == '-') {
|
||||
return styler[pos - 1] == ch;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool followsKeyword(StyleContext &sc, Accessor &styler) {
|
||||
Sci_Position pos = (Sci_Position) sc.currentPos;
|
||||
Sci_Position currentLine = styler.GetLine(pos);
|
||||
Sci_Position lineStartPos = styler.LineStart(currentLine);
|
||||
while (--pos > lineStartPos) {
|
||||
char ch = styler.SafeGetCharAt(pos);
|
||||
if (ch != ' ' && ch != '\t') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
styler.Flush();
|
||||
return styler.StyleAt(pos) == SCE_COFFEESCRIPT_WORD;
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#if __has_warning("-Wunused-but-set-variable")
|
||||
// Disable warning for visibleChars
|
||||
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void ColouriseCoffeeScriptDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
|
||||
Accessor &styler) {
|
||||
|
||||
WordList &keywords = *keywordlists[0];
|
||||
WordList &keywords2 = *keywordlists[1];
|
||||
WordList &keywords4 = *keywordlists[3];
|
||||
|
||||
CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-");
|
||||
CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-");
|
||||
|
||||
CharacterSet setWordStart(CharacterSet::setAlpha, "_$@", 0x80, true);
|
||||
CharacterSet setWord(CharacterSet::setAlphaNum, "._$", 0x80, true);
|
||||
|
||||
int chPrevNonWhite = ' ';
|
||||
int visibleChars = 0;
|
||||
|
||||
// String/Regex interpolation variables, based on LexRuby.cxx.
|
||||
// In most cases a value of 2 should be ample for the code the user is
|
||||
// likely to enter. For example,
|
||||
// "Filling the #{container} with #{liquid}..."
|
||||
// from the CoffeeScript homepage nests to a level of 2
|
||||
// If the user actually hits a 6th occurrence of '#{' in a double-quoted
|
||||
// string (including regexes), it will stay as a string. The problem with
|
||||
// this is that quotes might flip, a 7th '#{' will look like a comment,
|
||||
// and code-folding might be wrong.
|
||||
#define INNER_STRINGS_MAX_COUNT 5
|
||||
// These vars track our instances of "...#{,,,'..#{,,,}...',,,}..."
|
||||
int inner_string_types[INNER_STRINGS_MAX_COUNT];
|
||||
// Track # braces when we push a new #{ thing
|
||||
int inner_expn_brace_counts[INNER_STRINGS_MAX_COUNT];
|
||||
int inner_string_count = 0;
|
||||
int brace_counts = 0; // Number of #{ ... } things within an expression
|
||||
for (int i = 0; i < INNER_STRINGS_MAX_COUNT; i++) {
|
||||
inner_string_types[i] = 0;
|
||||
inner_expn_brace_counts[i] = 0;
|
||||
}
|
||||
|
||||
// look back to set chPrevNonWhite properly for better regex colouring
|
||||
Sci_Position endPos = startPos + length;
|
||||
if (startPos > 0 && IsSpaceEquiv(initStyle)) {
|
||||
Sci_PositionU back = startPos;
|
||||
styler.Flush();
|
||||
while (back > 0 && IsSpaceEquiv(styler.StyleAt(--back)))
|
||||
;
|
||||
if (styler.StyleAt(back) == SCE_COFFEESCRIPT_OPERATOR) {
|
||||
chPrevNonWhite = styler.SafeGetCharAt(back);
|
||||
}
|
||||
if (startPos != back) {
|
||||
initStyle = styler.StyleAt(back);
|
||||
if (IsSpaceEquiv(initStyle)) {
|
||||
initStyle = SCE_COFFEESCRIPT_DEFAULT;
|
||||
}
|
||||
}
|
||||
startPos = back;
|
||||
}
|
||||
|
||||
StyleContext sc(startPos, endPos - startPos, initStyle, styler);
|
||||
|
||||
for (; sc.More();) {
|
||||
|
||||
if (sc.atLineStart) {
|
||||
// Reset states to beginning of colourise so no surprises
|
||||
// if different sets of lines lexed.
|
||||
visibleChars = 0;
|
||||
}
|
||||
|
||||
// Determine if the current state should terminate.
|
||||
switch (sc.state) {
|
||||
case SCE_COFFEESCRIPT_OPERATOR:
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_NUMBER:
|
||||
// We accept almost anything because of hex. and number suffixes
|
||||
if (!setWord.Contains(sc.ch) || sc.Match('.', '.')) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_IDENTIFIER:
|
||||
if (!setWord.Contains(sc.ch) || (sc.ch == '.') || (sc.ch == '$')) {
|
||||
char s[1000];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
if (keywords.InList(s)) {
|
||||
sc.ChangeState(SCE_COFFEESCRIPT_WORD);
|
||||
} else if (keywords2.InList(s)) {
|
||||
sc.ChangeState(SCE_COFFEESCRIPT_WORD2);
|
||||
} else if (keywords4.InList(s)) {
|
||||
sc.ChangeState(SCE_COFFEESCRIPT_GLOBALCLASS);
|
||||
} else if (sc.LengthCurrent() > 0 && s[0] == '@') {
|
||||
sc.ChangeState(SCE_COFFEESCRIPT_INSTANCEPROPERTY);
|
||||
}
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_WORD:
|
||||
case SCE_COFFEESCRIPT_WORD2:
|
||||
case SCE_COFFEESCRIPT_GLOBALCLASS:
|
||||
case SCE_COFFEESCRIPT_INSTANCEPROPERTY:
|
||||
if (!setWord.Contains(sc.ch)) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_COMMENTLINE:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_STRING:
|
||||
if (sc.ch == '\\') {
|
||||
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
|
||||
sc.Forward();
|
||||
}
|
||||
} else if (sc.ch == '\"') {
|
||||
sc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
} else if (sc.ch == '#' && sc.chNext == '{' && inner_string_count < INNER_STRINGS_MAX_COUNT) {
|
||||
// process interpolated code #{ ... }
|
||||
enterInnerExpression(inner_string_types,
|
||||
inner_expn_brace_counts,
|
||||
inner_string_count,
|
||||
sc.state,
|
||||
brace_counts);
|
||||
sc.SetState(SCE_COFFEESCRIPT_OPERATOR);
|
||||
sc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_CHARACTER:
|
||||
if (sc.ch == '\\') {
|
||||
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
|
||||
sc.Forward();
|
||||
}
|
||||
} else if (sc.ch == '\'') {
|
||||
sc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_REGEX:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
} else if (sc.ch == '/') {
|
||||
sc.Forward();
|
||||
while ((sc.ch < 0x80) && islower(sc.ch))
|
||||
sc.Forward(); // gobble regex flags
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
} else if (sc.ch == '\\') {
|
||||
// Gobble up the quoted character
|
||||
if (sc.chNext == '\\' || sc.chNext == '/') {
|
||||
sc.Forward();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_STRINGEOL:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_COMMENTBLOCK:
|
||||
if (sc.Match("###")) {
|
||||
sc.Forward();
|
||||
sc.Forward();
|
||||
sc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
} else if (sc.ch == '\\') {
|
||||
sc.Forward();
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_VERBOSE_REGEX:
|
||||
if (sc.Match("///")) {
|
||||
sc.Forward();
|
||||
sc.Forward();
|
||||
sc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
} else if (sc.Match('#')) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT);
|
||||
} else if (sc.ch == '\\') {
|
||||
sc.Forward();
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Determine if a new state should be entered.
|
||||
if (sc.state == SCE_COFFEESCRIPT_DEFAULT) {
|
||||
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_NUMBER);
|
||||
} else if (setWordStart.Contains(sc.ch)) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_IDENTIFIER);
|
||||
} else if (sc.Match("///")) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX);
|
||||
sc.Forward();
|
||||
sc.Forward();
|
||||
} else if (sc.ch == '/'
|
||||
&& (setOKBeforeRE.Contains(chPrevNonWhite)
|
||||
|| followsKeyword(sc, styler))
|
||||
&& (!setCouldBePostOp.Contains(chPrevNonWhite)
|
||||
|| !FollowsPostfixOperator(sc, styler))) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_REGEX); // JavaScript's RegEx
|
||||
} else if (sc.ch == '\"') {
|
||||
sc.SetState(SCE_COFFEESCRIPT_STRING);
|
||||
} else if (sc.ch == '\'') {
|
||||
sc.SetState(SCE_COFFEESCRIPT_CHARACTER);
|
||||
} else if (sc.ch == '#') {
|
||||
if (sc.Match("###")) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_COMMENTBLOCK);
|
||||
sc.Forward();
|
||||
sc.Forward();
|
||||
} else {
|
||||
sc.SetState(SCE_COFFEESCRIPT_COMMENTLINE);
|
||||
}
|
||||
} else if (isoperator(static_cast<char>(sc.ch))) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_OPERATOR);
|
||||
// Handle '..' and '...' operators correctly.
|
||||
if (sc.ch == '.') {
|
||||
for (int i = 0; i < 2 && sc.chNext == '.'; i++, sc.Forward()) ;
|
||||
} else if (sc.ch == '{') {
|
||||
++brace_counts;
|
||||
} else if (sc.ch == '}' && --brace_counts <= 0 && inner_string_count > 0) {
|
||||
// Return to previous state before #{ ... }
|
||||
sc.ForwardSetState(exitInnerExpression(inner_string_types,
|
||||
inner_expn_brace_counts,
|
||||
inner_string_count,
|
||||
brace_counts));
|
||||
continue; // skip sc.Forward() at loop end
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) {
|
||||
chPrevNonWhite = sc.ch;
|
||||
visibleChars++;
|
||||
}
|
||||
sc.Forward();
|
||||
}
|
||||
sc.Complete();
|
||||
}
|
||||
|
||||
static bool IsCommentLine(Sci_Position line, Accessor &styler) {
|
||||
Sci_Position pos = styler.LineStart(line);
|
||||
Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
|
||||
for (Sci_Position i = pos; i < eol_pos; i++) {
|
||||
char ch = styler[i];
|
||||
if (ch == '#')
|
||||
return true;
|
||||
else if (ch != ' ' && ch != '\t')
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void FoldCoffeeScriptDoc(Sci_PositionU startPos, Sci_Position length, int,
|
||||
WordList *[], Accessor &styler) {
|
||||
// A simplified version of FoldPyDoc
|
||||
const Sci_Position maxPos = startPos + length;
|
||||
const Sci_Position maxLines = styler.GetLine(maxPos - 1); // Requested last line
|
||||
const Sci_Position docLines = styler.GetLine(styler.Length() - 1); // Available last line
|
||||
|
||||
// property fold.coffeescript.comment
|
||||
// Set to 1 to allow folding of comment blocks in CoffeeScript.
|
||||
const bool foldComment = styler.GetPropertyInt("fold.coffeescript.comment") != 0;
|
||||
|
||||
const bool foldCompact = styler.GetPropertyInt("fold.compact") != 0;
|
||||
|
||||
// Backtrack to previous non-blank line so we can determine indent level
|
||||
// for any white space lines
|
||||
// and so we can fix any preceding fold level (which is why we go back
|
||||
// at least one line in all cases)
|
||||
int spaceFlags = 0;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
|
||||
while (lineCurrent > 0) {
|
||||
lineCurrent--;
|
||||
indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
|
||||
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)
|
||||
&& !IsCommentLine(lineCurrent, styler))
|
||||
break;
|
||||
}
|
||||
int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
|
||||
|
||||
// Set up initial loop state
|
||||
int prevComment = 0;
|
||||
if (lineCurrent >= 1)
|
||||
prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);
|
||||
|
||||
// Process all characters to end of requested range
|
||||
// or comment that hangs over the end of the range. Cap processing in all cases
|
||||
// to end of document (in case of comment at end).
|
||||
while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevComment)) {
|
||||
|
||||
// Gather info
|
||||
int lev = indentCurrent;
|
||||
Sci_Position lineNext = lineCurrent + 1;
|
||||
int indentNext = indentCurrent;
|
||||
if (lineNext <= docLines) {
|
||||
// Information about next line is only available if not at end of document
|
||||
indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
|
||||
}
|
||||
const int comment = foldComment && IsCommentLine(lineCurrent, styler);
|
||||
const int comment_start = (comment && !prevComment && (lineNext <= docLines) &&
|
||||
IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE));
|
||||
const int comment_continue = (comment && prevComment);
|
||||
if (!comment)
|
||||
indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
|
||||
if (indentNext & SC_FOLDLEVELWHITEFLAG)
|
||||
indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
|
||||
|
||||
if (comment_start) {
|
||||
// Place fold point at start of a block of comments
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
} else if (comment_continue) {
|
||||
// Add level to rest of lines in the block
|
||||
lev = lev + 1;
|
||||
}
|
||||
|
||||
// Skip past any blank lines for next indent level info; we skip also
|
||||
// comments (all comments, not just those starting in column 0)
|
||||
// which effectively folds them into surrounding code rather
|
||||
// than screwing up folding.
|
||||
|
||||
while ((lineNext < docLines) &&
|
||||
((indentNext & SC_FOLDLEVELWHITEFLAG) ||
|
||||
(lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
|
||||
|
||||
lineNext++;
|
||||
indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
|
||||
}
|
||||
|
||||
const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
|
||||
const int levelBeforeComments = std::max(indentCurrentLevel,levelAfterComments);
|
||||
|
||||
// Now set all the indent levels on the lines we skipped
|
||||
// Do this from end to start. Once we encounter one line
|
||||
// which is indented more than the line after the end of
|
||||
// the comment-block, use the level of the block before
|
||||
|
||||
Sci_Position skipLine = lineNext;
|
||||
int skipLevel = levelAfterComments;
|
||||
|
||||
while (--skipLine > lineCurrent) {
|
||||
int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
|
||||
|
||||
if (foldCompact) {
|
||||
if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
|
||||
skipLevel = levelBeforeComments;
|
||||
|
||||
int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
|
||||
|
||||
styler.SetLevel(skipLine, skipLevel | whiteFlag);
|
||||
} else {
|
||||
if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments &&
|
||||
!(skipLineIndent & SC_FOLDLEVELWHITEFLAG) &&
|
||||
!IsCommentLine(skipLine, styler))
|
||||
skipLevel = levelBeforeComments;
|
||||
|
||||
styler.SetLevel(skipLine, skipLevel);
|
||||
}
|
||||
}
|
||||
|
||||
// Set fold header on non-comment line
|
||||
if (!comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
|
||||
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
}
|
||||
|
||||
// Keep track of block comment state of previous line
|
||||
prevComment = comment_start || comment_continue;
|
||||
|
||||
// Set fold level for this line and move to next line
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
indentCurrent = indentNext;
|
||||
lineCurrent = lineNext;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *const csWordLists[] = {
|
||||
"Keywords",
|
||||
"Secondary keywords",
|
||||
"Unused",
|
||||
"Global classes",
|
||||
0,
|
||||
};
|
||||
|
||||
extern const LexerModule lmCoffeeScript(SCLEX_COFFEESCRIPT, ColouriseCoffeeScriptDoc, "coffeescript", FoldCoffeeScriptDoc, csWordLists);
|
Reference in New Issue
Block a user