Avelino 2018-05-30 11:26:52 -03:00
parent 3dd38f1ca5
commit b8cf0d688f
7 changed files with 395 additions and 113 deletions

View file

@ -0,0 +1,18 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { registerLanguage } from '../_.contribution';
// Allow for running under nodejs/requirejs in tests
const _monaco: typeof monaco =
typeof monaco === 'undefined' ? (<any>self).monaco : monaco;
registerLanguage({
id: 'clojure',
extensions: ['.clj', '.clojure'],
aliases: ['clojure', 'Clojure'],
loader: () => _monaco.Promise.wrap(import('./clojure')),
});

View file

@ -0,0 +1,96 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { testTokenization } from '../test/testRunner';
testTokenization('clojure', [
// Keywords
[
{
line: 'defmacro some',
tokens: [
{ startIndex: 0, type: 'keyword.clj' },
{ startIndex: 8, type: 'white.clj' },
{ startIndex: 9, type: 'variable.clj' },
],
},
{
line: 'comment "text comment"',
tokens: [
{ startIndex: 0, type: 'keyword.clj' },
{ startIndex: 7, type: 'white.clj'},
{ startIndex: 8, type: 'string.clj'},
],
},
],
// comments
[
{
line: ';; comment',
tokens: [{ startIndex: 0, type: 'comment.clj' }],
},
],
[
{
line: '(comment',
tokens: [{ startIndex: 0, type: 'comment.clj' }],
},
{
line: '(comment let',
tokens: [
{ startIndex: 0, type: 'comment.clj' },
{ startIndex: 8, type: 'white.clj' },
{ startIndex: 9, type: 'keyword.clj' },
],
},
],
// strings
[
{
line: '"\\n string "',
tokens: [
{ startIndex: 0, type: 'string.clj' },
{ startIndex: 1, type: 'string.escape.clj' },
{ startIndex: 3, type: 'string.clj' },
],
},
],
[
{
line: '" string \\',
tokens: [{ startIndex: 0, type: 'string.clj' }],
},
{
line: 'multiline',
tokens: [{ startIndex: 0, type: 'string.clj' }],
},
{
line: ' ',
tokens: [
// previous line needs to be terminated with \
{ startIndex: 0, type: 'white.clj' },
],
},
],
// numbers
[
{
line: '1e2',
tokens: [{ startIndex: 0, type: 'number.float.clj' }],
},
],
[
{
line: '#x03BB',
tokens: [{ startIndex: 0, type: 'number.hex.clj' }],
},
],
]);

165
src/clojure/clojure.ts Normal file
View file

@ -0,0 +1,165 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import IRichLanguageConfiguration = monaco.languages.LanguageConfiguration;
import ILanguage = monaco.languages.IMonarchLanguage;
export const conf: IRichLanguageConfiguration = {
comments: {
lineComment: ';;',
blockComment: ['(comment', ')'],
},
brackets: [['(', ')'], ['{', '}'], ['[', ']']],
autoClosingPairs: [
{ open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
{ open: '"', close: '"' },
],
surroundingPairs: [
{ open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
{ open: '"', close: '"' },
],
};
export const language = <ILanguage>{
defaultToken: '',
ignoreCase: true,
tokenPostfix: '.clj',
brackets: [
{ open: '(', close: ')', token: 'delimiter.parenthesis' },
{ open: '{', close: '}', token: 'delimiter.curly' },
{ open: '[', close: ']', token: 'delimiter.square' },
],
keywords: [
'ns',
'ns-unmap',
'fn',
'def',
'defn',
'defmacro',
'defmulti',
'defonce',
'bound\\-fn',
'if',
'if\\-not',
'case,',
'cond',
'condp',
'cond\\-\\>',
'cond\\-\\>\\>',
'when',
'while',
'when\\-not',
'when\\-first',
'do',
'future',
'comment',
'doto',
'locking',
'proxy',
'as\\-\\>',
'reify',
'deftype',
'defrecord',
'defprotocol',
'extend',
'extend-protocol',
'extend-type',
'specify',
'specify\\!',
'try',
'catch',
'finally',
'let',
'letfn',
'binding',
'loop',
'for',
'doseq',
'dotimes',
'when\\-let',
'if\\-let',
'when\\-some',
'if\\-some',
'this\\-as',
'defmethod',
'testing',
'deftest',
'are',
'use\\-fixtures',
'run',
'run\\*',
'fresh',
'alt!',
'alt!!',
'go',
'go\\-loop',
'thread',
],
constants: ['true', 'false', 'nil'],
operators: ['=', 'not=', '<', '<=', '>', '>=', 'and', 'or', 'not', 'inc', 'dec', 'max', 'min', 'rem', 'bit-and', 'bit-or', 'bit-xor', 'bit-not'],
tokenizer: {
root: [
[/#[xXoObB][0-9a-fA-F]+/, 'number.hex'],
[/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?/, 'number.float'],
[/(?:\b(?:(def|defn|defmacro|defmulti|defonce|ns|ns-unmap|fn))\b)(\s+)((?:\w|\-|\!|\?)*)/, ['keyword', 'white', 'variable']],
[
/[a-zA-Z_#][a-zA-Z0-9_\-\?\!\*]*/,
{
cases: {
'@keywords': 'keyword',
'@constants': 'constant',
'@operators': 'operators',
'@default': 'identifier',
},
},
],
{ include: '@whitespace' },
{ include: '@strings' },
],
comment: [
[/[^\(comment]+/, 'comment'],
[/\)/, 'comment', '@push'],
[/\(comment/, 'comment', '@pop'],
[/[\)]/, 'comment'],
],
whitespace: [
[/[ \t\r\n]+/, 'white'],
[/\(comment/, 'comment', '@comment'],
[/;;.*$/, 'comment'],
],
strings: [
[/"$/, 'string', '@popall'],
[/"(?=.)/, 'string', '@multiLineString'],
],
multiLineString: [
[/\\./, 'string.escape'],
[/"/, 'string', '@popall'],
[/.(?=.*")/, 'string'],
[/.*\\$/, 'string'],
[/.*$/, 'string', '@popall'],
],
},
};