import { inherit } from './utils.js';
import * as regex from './regex.js';
export const MATCH_NOTHING_RE = /\b\B/;
export const IDENT_RE = '[a-zA-Z]\\w*';
export const UNDERSCORE_IDENT_RE = '[a-zA-Z_]\\w*';
export const NUMBER_RE = '\\b\\d+(\\.\\d+)?';
export const C_NUMBER_RE = '(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)';
export const BINARY_NUMBER_RE = '\\b(0b[01]+)';
export const RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~';
export const SHEBANG = (opts = {}) => {
const beginShebang = /^#![ ]*\//;
if (opts.binary) {
opts.begin = regex.concat(
beginShebang,
/.*\b/,
opts.binary,
/\b.*/);
}
return inherit({
scope: 'meta',
begin: beginShebang,
end: /$/,
relevance: 0,
"on:begin": (m, resp) => {
if (m.index !== 0) resp.ignoreMatch();
}
}, opts);
};
export const BACKSLASH_ESCAPE = {
begin: '\\\\[\\s\\S]', relevance: 0
};
export const APOS_STRING_MODE = {
scope: 'string',
begin: '\'',
end: '\'',
illegal: '\\n',
contains: [BACKSLASH_ESCAPE]
};
export const QUOTE_STRING_MODE = {
scope: 'string',
begin: '"',
end: '"',
illegal: '\\n',
contains: [BACKSLASH_ESCAPE]
};
export const PHRASAL_WORDS_MODE = {
begin: /\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/
};
export const COMMENT = function(begin, end, modeOptions = {}) {
const mode = inherit(
{
scope: 'comment',
begin,
end,
contains: []
},
modeOptions
);
mode.contains.push({
scope: 'doctag',
begin: '[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)',
end: /(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,
excludeBegin: true,
relevance: 0
});
const ENGLISH_WORD = regex.either(
"I",
"a",
"is",
"so",
"us",
"to",
"at",
"if",
"in",
"it",
"on",
/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,
/[A-Za-z]+[-][a-z]+/,
/[A-Za-z][a-z]{2,}/
);
mode.contains.push(
{
begin: regex.concat(
/[ ]+/,
'(',
ENGLISH_WORD,
/[.]?[:]?([.][ ]|[ ])/,
'){3}')
}
);
return mode;
};
export const C_LINE_COMMENT_MODE = COMMENT('//', '$');
export const C_BLOCK_COMMENT_MODE = COMMENT('/\\*', '\\*/');
export const HASH_COMMENT_MODE = COMMENT('#', '$');
export const NUMBER_MODE = {
scope: 'number',
begin: NUMBER_RE,
relevance: 0
};
export const C_NUMBER_MODE = {
scope: 'number',
begin: C_NUMBER_RE,
relevance: 0
};
export const BINARY_NUMBER_MODE = {
scope: 'number',
begin: BINARY_NUMBER_RE,
relevance: 0
};
export const REGEXP_MODE = {
begin: /(?=\/[^/\n]*\/)/,
contains: [{
scope: 'regexp',
begin: /\//,
end: /\/[gimuy]*/,
illegal: /\n/,
contains: [
BACKSLASH_ESCAPE,
{
begin: /\[/,
end: /\]/,
relevance: 0,
contains: [BACKSLASH_ESCAPE]
}
]
}]
};
export const TITLE_MODE = {
scope: 'title',
begin: IDENT_RE,
relevance: 0
};
export const UNDERSCORE_TITLE_MODE = {
scope: 'title',
begin: UNDERSCORE_IDENT_RE,
relevance: 0
};
export const METHOD_GUARD = {
begin: '\\.\\s*' + UNDERSCORE_IDENT_RE,
relevance: 0
};
export const END_SAME_AS_BEGIN = function(mode) {
return Object.assign(mode,
{
'on:begin': (m, resp) => { resp.data._beginMatch = m[1]; },
'on:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch(); }
});
};