You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
4.8 KiB
197 lines
4.8 KiB
(function (Prism) { |
|
/** |
|
* Functions to construct regular expressions |
|
* e.g. (interactive ... or (interactive) |
|
* |
|
* @param {string} name |
|
* @returns {RegExp} |
|
*/ |
|
function simple_form(name) { |
|
return RegExp(/(\()/.source + '(?:' + name + ')' + /(?=[\s\)])/.source); |
|
} |
|
/** |
|
* booleans and numbers |
|
* |
|
* @param {string} pattern |
|
* @returns {RegExp} |
|
*/ |
|
function primitive(pattern) { |
|
return RegExp(/([\s([])/.source + '(?:' + pattern + ')' + /(?=[\s)])/.source); |
|
} |
|
|
|
// Patterns in regular expressions |
|
|
|
// Symbol name. See https://www.gnu.org/software/emacs/manual/html_node/elisp/Symbol-Type.html |
|
// & and : are excluded as they are usually used for special purposes |
|
var symbol = /(?!\d)[-+*/~!@$%^=<>{}\w]+/.source; |
|
// symbol starting with & used in function arguments |
|
var marker = '&' + symbol; |
|
// Open parenthesis for look-behind |
|
var par = '(\\()'; |
|
var endpar = '(?=\\))'; |
|
// End the pattern with look-ahead space |
|
var space = '(?=\\s)'; |
|
var nestedPar = /(?:[^()]|\((?:[^()]|\((?:[^()]|\((?:[^()]|\((?:[^()]|\([^()]*\))*\))*\))*\))*\))*/.source; |
|
|
|
var language = { |
|
// Three or four semicolons are considered a heading. |
|
// See https://www.gnu.org/software/emacs/manual/html_node/elisp/Comment-Tips.html |
|
heading: { |
|
pattern: /;;;.*/, |
|
alias: ['comment', 'title'] |
|
}, |
|
comment: /;.*/, |
|
string: { |
|
pattern: /"(?:[^"\\]|\\.)*"/, |
|
greedy: true, |
|
inside: { |
|
argument: /[-A-Z]+(?=[.,\s])/, |
|
symbol: RegExp('`' + symbol + "'") |
|
} |
|
}, |
|
'quoted-symbol': { |
|
pattern: RegExp("#?'" + symbol), |
|
alias: ['variable', 'symbol'] |
|
}, |
|
'lisp-property': { |
|
pattern: RegExp(':' + symbol), |
|
alias: 'property' |
|
}, |
|
splice: { |
|
pattern: RegExp(',@?' + symbol), |
|
alias: ['symbol', 'variable'] |
|
}, |
|
keyword: [ |
|
{ |
|
pattern: RegExp( |
|
par + |
|
'(?:and|(?:cl-)?letf|cl-loop|cond|cons|error|if|(?:lexical-)?let\\*?|message|not|null|or|provide|require|setq|unless|use-package|when|while)' + |
|
space |
|
), |
|
lookbehind: true |
|
}, |
|
{ |
|
pattern: RegExp( |
|
par + '(?:append|by|collect|concat|do|finally|for|in|return)' + space |
|
), |
|
lookbehind: true |
|
}, |
|
], |
|
declare: { |
|
pattern: simple_form(/declare/.source), |
|
lookbehind: true, |
|
alias: 'keyword' |
|
}, |
|
interactive: { |
|
pattern: simple_form(/interactive/.source), |
|
lookbehind: true, |
|
alias: 'keyword' |
|
}, |
|
boolean: { |
|
pattern: primitive(/nil|t/.source), |
|
lookbehind: true |
|
}, |
|
number: { |
|
pattern: primitive(/[-+]?\d+(?:\.\d*)?/.source), |
|
lookbehind: true |
|
}, |
|
defvar: { |
|
pattern: RegExp(par + 'def(?:const|custom|group|var)\\s+' + symbol), |
|
lookbehind: true, |
|
inside: { |
|
keyword: /^def[a-z]+/, |
|
variable: RegExp(symbol) |
|
} |
|
}, |
|
defun: { |
|
pattern: RegExp(par + /(?:cl-)?(?:defmacro|defun\*?)\s+/.source + symbol + /\s+\(/.source + nestedPar + /\)/.source), |
|
lookbehind: true, |
|
greedy: true, |
|
inside: { |
|
keyword: /^(?:cl-)?def\S+/, |
|
// See below, this property needs to be defined later so that it can |
|
// reference the language object. |
|
arguments: null, |
|
function: { |
|
pattern: RegExp('(^\\s)' + symbol), |
|
lookbehind: true |
|
}, |
|
punctuation: /[()]/ |
|
} |
|
}, |
|
lambda: { |
|
pattern: RegExp(par + 'lambda\\s+\\(\\s*(?:&?' + symbol + '(?:\\s+&?' + symbol + ')*\\s*)?\\)'), |
|
lookbehind: true, |
|
greedy: true, |
|
inside: { |
|
keyword: /^lambda/, |
|
// See below, this property needs to be defined later so that it can |
|
// reference the language object. |
|
arguments: null, |
|
punctuation: /[()]/ |
|
} |
|
}, |
|
car: { |
|
pattern: RegExp(par + symbol), |
|
lookbehind: true |
|
}, |
|
punctuation: [ |
|
// open paren, brackets, and close paren |
|
/(?:['`,]?\(|[)\[\]])/, |
|
// cons |
|
{ |
|
pattern: /(\s)\.(?=\s)/, |
|
lookbehind: true |
|
}, |
|
] |
|
}; |
|
|
|
var arg = { |
|
'lisp-marker': RegExp(marker), |
|
'varform': { |
|
pattern: RegExp(/\(/.source + symbol + /\s+(?=\S)/.source + nestedPar + /\)/.source), |
|
inside: language |
|
}, |
|
'argument': { |
|
pattern: RegExp(/(^|[\s(])/.source + symbol), |
|
lookbehind: true, |
|
alias: 'variable' |
|
}, |
|
rest: language |
|
}; |
|
|
|
var forms = '\\S+(?:\\s+\\S+)*'; |
|
|
|
var arglist = { |
|
pattern: RegExp(par + nestedPar + endpar), |
|
lookbehind: true, |
|
inside: { |
|
'rest-vars': { |
|
pattern: RegExp('&(?:body|rest)\\s+' + forms), |
|
inside: arg |
|
}, |
|
'other-marker-vars': { |
|
pattern: RegExp('&(?:aux|optional)\\s+' + forms), |
|
inside: arg |
|
}, |
|
keys: { |
|
pattern: RegExp('&key\\s+' + forms + '(?:\\s+&allow-other-keys)?'), |
|
inside: arg |
|
}, |
|
argument: { |
|
pattern: RegExp(symbol), |
|
alias: 'variable' |
|
}, |
|
punctuation: /[()]/ |
|
} |
|
}; |
|
|
|
language['lambda'].inside.arguments = arglist; |
|
language['defun'].inside.arguments = Prism.util.clone(arglist); |
|
language['defun'].inside.arguments.inside.sublist = arglist; |
|
|
|
Prism.languages.lisp = language; |
|
Prism.languages.elisp = language; |
|
Prism.languages.emacs = language; |
|
Prism.languages['emacs-lisp'] = language; |
|
}(Prism));
|
|
|